File indexing completed on 2024-04-21 15:12:13

0001 /************************************************************************
0002  *                                  *
0003  *  This file is part of Kooka, a scanning/OCR application using    *
0004  *  Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>.  *
0005  *                                  *
0006  *  Copyright (C) 2009-2016 Jonathan Marten <jjm@keelhaul.me.uk>    *
0007  *                                  *
0008  *  Kooka is free software; you can redistribute it and/or modify it    *
0009  *  under the terms of the GNU Library General Public License as    *
0010  *  published by the Free Software Foundation and appearing in the  *
0011  *  file COPYING included in the packaging of this file;  either    *
0012  *  version 2 of the License, or (at your option) any later version.    *
0013  *                                  *
0014  *  As a special exception, permission is given to link this program    *
0015  *  with any version of the KADMOS OCR/ICR engine (a product of     *
0016  *  reRecognition GmbH, Kreuzlingen), and distribute the resulting  *
0017  *  executable without including the source code for KADMOS in the  *
0018  *  source distribution.                        *
0019  *                                  *
0020  *  This program is distributed in the hope that it will be useful, *
0021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *
0022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *
0023  *  GNU General Public License for more details.            *
0024  *                                  *
0025  *  You should have received a copy of the GNU General Public       *
0026  *  License along with this program;  see the file COPYING.  If     *
0027  *  not, see <http://www.gnu.org/licenses/>.                *
0028  *                                  *
0029  ************************************************************************/
0030 
0031 #include "scanglobal.h"
0032 
0033 #include <klocalizedstring.h>
0034 
0035 #include "kscandevice.h"
0036 #include "scansettings.h"
0037 
0038 #include "libkookascan_logging.h"
0039 
0040 extern "C" {
0041 #include <sane/sane.h>
0042 }
0043 
0044 
0045 static ScanGlobal *sInstance = nullptr;
0046 static KScanDevice *sScanDevice = nullptr;
0047 
0048 ScanGlobal *ScanGlobal::self()
0049 {
0050     if (sInstance == nullptr) {
0051         sInstance = new ScanGlobal();
0052     }
0053     return (sInstance);
0054 }
0055 
0056 ScanGlobal::ScanGlobal()
0057 {
0058     qCDebug(LIBKOOKASCAN_LOG);
0059 
0060     mSaneInitDone = false;
0061     mSaneInitError = false;
0062 }
0063 
0064 ScanGlobal::~ScanGlobal()
0065 {
0066     if (mSaneInitDone) {
0067         qCDebug(LIBKOOKASCAN_LOG) << "calling sane_exit()";
0068         sane_exit();
0069     }
0070 }
0071 
0072 //  SANE authorisation callback for scanner access.
0073 //
0074 //  The scanner device in use (a KScanDevice) must have been set using
0075 //  setScanDevice() before any SANE function that can request authentication
0076 //  is called.  If no scanner device has been set, nothing is called and
0077 //  the authentication will fail.
0078 //
0079 //  In theory, the 'resource' parameter here should be the scanner device
0080 //  name for which authentication is required.  But sometimes it doesn't seem
0081 //  to correspond and is in a rather cryptic format, e.g. trying to open the
0082 //  device "net:localhost:hpaio:/net/Officejet_Pro_L7600?ip=***.***.***.***"
0083 //  passes a 'resource' such as "net:localhost:hpaio$MD5$6f034bceede4608f95f8".
0084 //  So the parameter is ignored and KScanDevice prompts using its own
0085 //  internal scanner name.
0086 
0087 extern "C" void authCallback(SANE_String_Const resource,
0088                              SANE_Char username[SANE_MAX_USERNAME_LEN],
0089                              SANE_Char password[SANE_MAX_PASSWORD_LEN])
0090 {
0091     qCDebug(LIBKOOKASCAN_LOG) << "for resource" << resource;
0092 
0093     if (sScanDevice == nullptr) {          // no device set
0094         qCWarning(LIBKOOKASCAN_LOG) << "cannot authenticate, no device";
0095         return;
0096     }
0097 
0098     QByteArray user;
0099     QByteArray pass;
0100     if (sScanDevice->authenticate(&user, &pass)) {
0101         qstrncpy(username, user.constData(), SANE_MAX_USERNAME_LEN);
0102         qstrncpy(password, pass.constData(), SANE_MAX_PASSWORD_LEN);
0103     }
0104 }
0105 
0106 void ScanGlobal::setScanDevice(KScanDevice *device)
0107 {
0108     sScanDevice = device;
0109 }
0110 
0111 bool ScanGlobal::init()
0112 {
0113     if (mSaneInitDone) {
0114         return (true);    // already done, no more to do
0115     }
0116     if (mSaneInitError) {
0117         return (false);    // error happened, no point
0118     }
0119 
0120     qCDebug(LIBKOOKASCAN_LOG) << "calling sane_init()";
0121     SANE_Status status = sane_init(nullptr, &authCallback);
0122     if (status != SANE_STATUS_GOOD) {
0123         mSaneInitError = true;
0124         qCWarning(LIBKOOKASCAN_LOG) << "sane_init() failed, status" << status;
0125     } else {
0126         mSaneInitDone = true;
0127     }
0128 
0129     return (mSaneInitDone);
0130 }
0131 
0132 bool ScanGlobal::available() const
0133 {
0134     return (mSaneInitDone && !mSaneInitError);
0135 }