File indexing completed on 2025-01-19 12:59:20
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 }