File indexing completed on 2025-01-05 05:09:30
0001 /* 0002 SPDX-FileCopyrightText: 2010-2018 Daniel Nicoletti <dantti12@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KCUPSCONNECTION_H 0008 #define KCUPSCONNECTION_H 0009 0010 #include <QMetaMethod> 0011 #include <QMutex> 0012 #include <QStringList> 0013 #include <QThread> 0014 #include <QTimer> 0015 #include <QUrl> 0016 #include <QVariantMap> 0017 #include <QWidget> 0018 0019 #include <kcupslib_export.h> 0020 0021 #include <cups/cups.h> 0022 0023 #define KCUPS_DEVICE_CLASS QLatin1String("device-class") 0024 #define KCUPS_DEVICE_ID QLatin1String("device-id") 0025 #define KCUPS_DEVICE_INFO QLatin1String("device-info") 0026 #define KCUPS_DEVICE_MAKE_AND_MODEL QLatin1String("device-make-and-model") 0027 #define KCUPS_DEVICE_LOCATION QLatin1String("device-location") 0028 #define KCUPS_DEVICE_URI QLatin1String("device-uri") 0029 0030 #define KCUPS_PRINTER_NAME QLatin1String("printer-name") 0031 #define KCUPS_PRINTER_LOCATION QLatin1String("printer-location") 0032 #define KCUPS_PRINTER_INFO QLatin1String("printer-info") 0033 #define KCUPS_PRINTER_URI QLatin1String("printer-uri") 0034 #define KCUPS_PRINTER_MAKE_AND_MODEL QLatin1String("printer-make-and-model") 0035 #define KCUPS_PRINTER_STATE QLatin1String("printer-state") 0036 #define KCUPS_PRINTER_STATE_MESSAGE QLatin1String("printer-state-message") 0037 #define KCUPS_PRINTER_IS_SHARED QLatin1String("printer-is-shared") 0038 #define KCUPS_PRINTER_IS_ACCEPTING_JOBS QLatin1String("printer-is-accepting-jobs") 0039 #define KCUPS_PRINTER_TYPE QLatin1String("printer-type") 0040 #define KCUPS_PRINTER_TYPE_MASK QLatin1String("printer-type-mask") 0041 #define KCUPS_PRINTER_COMMANDS QLatin1String("printer-commands") 0042 #define KCUPS_PRINTER_URI_SUPPORTED QLatin1String("printer-uri-supported") 0043 #define KCUPS_PRINTER_ERROR_POLICY QLatin1String("printer-error-policy") 0044 #define KCUPS_PRINTER_ERROR_POLICY_SUPPORTED QLatin1String("printer-error-policy-supported") 0045 #define KCUPS_PRINTER_OP_POLICY QLatin1String("printer-op-policy") 0046 #define KCUPS_PRINTER_OP_POLICY_SUPPORTED QLatin1String("printer-op-policy-supported") 0047 0048 #define KCUPS_MEMBER_URIS QLatin1String("member-uris") 0049 #define KCUPS_MEMBER_NAMES QLatin1String("member-names") 0050 0051 #define KCUPS_MARKER_CHANGE_TIME QLatin1String("marker-change-time") 0052 #define KCUPS_MARKER_COLORS QLatin1String("marker-colors") 0053 #define KCUPS_MARKER_LEVELS QLatin1String("marker-levels") 0054 #define KCUPS_MARKER_HIGH_LEVELS "marker-high-levels" 0055 #define KCUPS_MARKER_LOW_LEVELS "marker-low-levels" 0056 #define KCUPS_MARKER_NAMES QLatin1String("marker-names") 0057 #define KCUPS_MARKER_TYPES QLatin1String("marker-types") 0058 #define KCUPS_MARKER_MESSAGE "marker-message" 0059 0060 #define KCUPS_JOB_ID QLatin1String("job-id") 0061 #define KCUPS_JOB_NAME QLatin1String("job-name") 0062 #define KCUPS_JOB_K_OCTETS QLatin1String("job-k-octets") 0063 #define KCUPS_JOB_K_OCTETS_PROCESSED QLatin1String("job-k-octets-processed") 0064 #define KCUPS_JOB_PRINTER_URI QLatin1String("job-printer-uri") 0065 #define KCUPS_JOB_PRINTER_STATE_MESSAGE QLatin1String("job-printer-state-message") 0066 #define KCUPS_JOB_ORIGINATING_USER_NAME QLatin1String("job-originating-user-name") 0067 #define KCUPS_JOB_ORIGINATING_HOST_NAME QLatin1String("job-originating-host-name") 0068 #define KCUPS_JOB_MEDIA_PROGRESS QLatin1String("job-media-progress") 0069 #define KCUPS_JOB_MEDIA_SHEETS QLatin1String("job-media-sheets") 0070 #define KCUPS_JOB_MEDIA_SHEETS_COMPLETED QLatin1String("job-media-sheets-completed") 0071 #define KCUPS_JOB_PRESERVED QLatin1String("job-preserved") 0072 #define KCUPS_JOB_STATE QLatin1String("job-state") 0073 #define KCUPS_JOB_STATE_REASONS QLatin1String("job-state-reasons") 0074 #define KCUPS_JOB_HOLD_UNTIL QLatin1String("job-hold-until") 0075 #define KCUPS_JOB_SHEETS_DEFAULT QLatin1String("job-sheets-default") 0076 #define KCUPS_JOB_SHEETS_SUPPORTED QLatin1String("job-sheets-supported") 0077 #define KCUPS_JOB_SHEETS_DEFAULT QLatin1String("job-sheets-default") 0078 #define KCUPS_JOB_SHEETS_SUPPORTED QLatin1String("job-sheets-supported") 0079 0080 #define KCUPS_MY_JOBS QLatin1String("my-jobs") 0081 #define KCUPS_WHICH_JOBS QLatin1String("which-jobs") 0082 0083 #define KCUPS_TIME_AT_COMPLETED QLatin1String("time-at-completed") 0084 #define KCUPS_TIME_AT_CREATION QLatin1String("time-at-creation") 0085 #define KCUPS_TIME_AT_PROCESSING QLatin1String("time-at-processing") 0086 0087 #define KCUPS_REQUESTED_ATTRIBUTES QLatin1String("requested-attributes") 0088 0089 #define KCUPS_REQUESTING_USER_NAME QLatin1String("requesting-user-name") 0090 #define KCUPS_REQUESTING_USER_NAME_ALLOWED QLatin1String("requesting-user-name-allowed") 0091 #define KCUPS_REQUESTING_USER_NAME_DENIED QLatin1String("requesting-user-name-denied") 0092 0093 #define KCUPS_PPD_MAKE_AND_MODEL QLatin1String("ppd-make-and-model") 0094 0095 #define KCUPS_NOTIFY_EVENTS QLatin1String("notify-events") 0096 #define KCUPS_NOTIFY_PULL_METHOD QLatin1String("notify-pull-method") 0097 #define KCUPS_NOTIFY_RECIPIENT_URI QLatin1String("notify-recipient-uri") 0098 #define KCUPS_NOTIFY_LEASE_DURATION QLatin1String("notify-lease-duration") 0099 #define KCUPS_NOTIFY_SUBSCRIPTION_ID QLatin1String("notify-subscription-id") 0100 0101 #define KCUPS_AUTH_INFO QLatin1String("auth-info") 0102 #define KCUPS_AUTH_INFO_REQUIRED QLatin1String("auth-info-required") 0103 0104 typedef QList<QVariantMap> ReturnArguments; 0105 0106 class KIppRequest; 0107 class KCupsPasswordDialog; 0108 class KCUPSLIB_EXPORT KCupsConnection : public QThread 0109 { 0110 Q_OBJECT 0111 public: 0112 /** 0113 * This is the main Cups class @author Daniel Nicoletti <dantti12@gmail.com> 0114 * 0115 * By calling KCupsConnection::global() you have access to it. 0116 * Due to cups architecture, this class has to live on a 0117 * separate thread so we avoid blocking the user interface when 0118 * the cups call blocks. 0119 * 0120 * It is IMPORTANT that we do not create several thread 0121 * for each cups request, doing so is a valid but breaks our 0122 * authentication. We could tho store the user information an 0123 * set the user/password every time it was needed. But I am not 0124 * sure this is safe. 0125 * 0126 * Extending this means either adding methods to the KCupsRequest 0127 * class which will move to this thread and then run. 0128 */ 0129 static KCupsConnection *global(); 0130 0131 /** 0132 * @brief KCupsConnection 0133 * @param parent 0134 * 0135 * This is the default constructor that connects to the default server 0136 * If you don't have any special reason for creating a connection 0137 * on your own consider calling global() 0138 */ 0139 explicit KCupsConnection(QObject *parent = nullptr); 0140 explicit KCupsConnection(const QUrl &server, QObject *parent = nullptr); 0141 ~KCupsConnection() override; 0142 0143 void setPasswordMainWindow(WId mainwindow); 0144 0145 Q_SIGNALS: 0146 /** 0147 * emitted when "server-started" is registered 0148 */ 0149 void serverStarted(const QString &text); 0150 0151 /** 0152 * emitted when "server-stopped" is registered 0153 */ 0154 void serverStopped(const QString &text); 0155 0156 /** 0157 * emitted when "server-restarted" is registered 0158 */ 0159 void serverRestarted(const QString &text); 0160 0161 /** 0162 * emitted when "server-audit" is registered 0163 */ 0164 void serverAudit(const QString &text); 0165 0166 /** 0167 * emitted when "printer-added" is registered 0168 */ 0169 void printerAdded(const QString &text, 0170 const QString &printerUri, 0171 const QString &printerName, 0172 uint printerState, 0173 const QString &printerStateReasons, 0174 bool printerIsAcceptingJobs); 0175 0176 /** 0177 * emitted when "printer-modified" is registered 0178 */ 0179 void printerModified(const QString &text, 0180 const QString &printerUri, 0181 const QString &printerName, 0182 uint printerState, 0183 const QString &printerStateReasons, 0184 bool printerIsAcceptingJobs); 0185 0186 /** 0187 * emitted when "printer-deleted" is registered 0188 */ 0189 void printerDeleted(const QString &text, 0190 const QString &printerUri, 0191 const QString &printerName, 0192 uint printerState, 0193 const QString &printerStateReasons, 0194 bool printerIsAcceptingJobs); 0195 0196 /** 0197 * emitted when "printer-state-changed" is registered 0198 */ 0199 void printerStateChanged(const QString &text, 0200 const QString &printerUri, 0201 const QString &printerName, 0202 uint printerState, 0203 const QString &printerStateReasons, 0204 bool printerIsAcceptingJobs); 0205 0206 /** 0207 * emitted when "printer-stopped" is registered 0208 */ 0209 void printerStopped(const QString &text, 0210 const QString &printerUri, 0211 const QString &printerName, 0212 uint printerState, 0213 const QString &printerStateReasons, 0214 bool printerIsAcceptingJobs); 0215 0216 /** 0217 * emitted when "printer-restarted" is registered 0218 */ 0219 void printerRestarted(const QString &text, 0220 const QString &printerUri, 0221 const QString &printerName, 0222 uint printerState, 0223 const QString &printerStateReasons, 0224 bool printerIsAcceptingJobs); 0225 0226 /** 0227 * emitted when "printer-shutdown" is registered 0228 */ 0229 void printerShutdown(const QString &text, 0230 const QString &printerUri, 0231 const QString &printerName, 0232 uint printerState, 0233 const QString &printerStateReasons, 0234 bool printerIsAcceptingJobs); 0235 0236 /** 0237 * emitted when "printer-media-changed" is registered 0238 */ 0239 void printerMediaChanged(const QString &text, 0240 const QString &printerUri, 0241 const QString &printerName, 0242 uint printerState, 0243 const QString &printerStateReasons, 0244 bool printerIsAcceptingJobs); 0245 0246 /** 0247 * emitted when "printer-finishings-changed" is registered 0248 */ 0249 void printerFinishingsChanged(const QString &text, 0250 const QString &printerUri, 0251 const QString &printerName, 0252 uint printerState, 0253 const QString &printerStateReasons, 0254 bool printerIsAcceptingJobs); 0255 0256 /** 0257 * emitted when "job-state-changed" is registered 0258 */ 0259 void jobState(const QString &text, 0260 const QString &printerUri, 0261 const QString &printerName, 0262 uint printerState, 0263 const QString &printerStateReasons, 0264 bool printerIsAcceptingJobs, 0265 uint jobId, 0266 uint jobState, 0267 const QString &jobStateReasons, 0268 const QString &jobName, 0269 uint jobImpressionsCompleted); 0270 0271 /** 0272 * emitted when "job-created" is registered 0273 */ 0274 void jobCreated(const QString &text, 0275 const QString &printerUri, 0276 const QString &printerName, 0277 uint printerState, 0278 const QString &printerStateReasons, 0279 bool printerIsAcceptingJobs, 0280 uint jobId, 0281 uint jobState, 0282 const QString &jobStateReasons, 0283 const QString &jobName, 0284 uint jobImpressionsCompleted); 0285 0286 /** 0287 * emitted when "job-stopped" is registered 0288 */ 0289 void jobStopped(const QString &text, 0290 const QString &printerUri, 0291 const QString &printerName, 0292 uint printerState, 0293 const QString &printerStateReasons, 0294 bool printerIsAcceptingJobs, 0295 uint jobId, 0296 uint jobState, 0297 const QString &jobStateReasons, 0298 const QString &jobName, 0299 uint jobImpressionsCompleted); 0300 0301 /** 0302 * emitted when "job-config-changed" is registered 0303 */ 0304 void jobConfigChanged(const QString &text, 0305 const QString &printerUri, 0306 const QString &printerName, 0307 uint printerState, 0308 const QString &printerStateReasons, 0309 bool printerIsAcceptingJobs, 0310 uint jobId, 0311 uint jobState, 0312 const QString &jobStateReasons, 0313 const QString &jobName, 0314 uint jobImpressionsCompleted); 0315 0316 /** 0317 * emitted when "job-progress" is registered 0318 */ 0319 void jobProgress(const QString &text, 0320 const QString &printerUri, 0321 const QString &printerName, 0322 uint printerState, 0323 const QString &printerStateReasons, 0324 bool printerIsAcceptingJobs, 0325 uint jobId, 0326 uint jobState, 0327 const QString &jobStateReasons, 0328 const QString &jobName, 0329 uint jobImpressionsCompleted); 0330 0331 /** 0332 * emitted when "job-completed" is registered 0333 */ 0334 void jobCompleted(const QString &text, 0335 const QString &printerUri, 0336 const QString &printerName, 0337 uint printerState, 0338 const QString &printerStateReasons, 0339 bool printerIsAcceptingJobs, 0340 uint jobId, 0341 uint jobState, 0342 const QString &jobStateReasons, 0343 const QString &jobName, 0344 uint jobImpressionsCompleted); 0345 0346 void rhPrinterAdded(const QString &queueName); 0347 void rhPrinterRemoved(const QString &queueName); 0348 void rhQueueChanged(const QString &queueName); 0349 void rhJobQueuedLocal(const QString &queueName, uint jobId, const QString &jobOwner); 0350 void rhJobStartedLocal(const QString &queueName, uint jobId, const QString &jobOwner); 0351 0352 protected: 0353 friend class KCupsRequest; 0354 0355 virtual void run() override; 0356 bool readyToStart(); 0357 bool retry(const char *resource, int operation) const; 0358 ReturnArguments request(const KIppRequest &request, ipp_tag_t groupTag = IPP_TAG_ZERO) const; 0359 0360 private slots: 0361 void updateSubscription(); 0362 void renewDBusSubscription(); 0363 void cancelDBusSubscription(); 0364 0365 protected: 0366 virtual void connectNotify(const QMetaMethod &signal) override; 0367 virtual void disconnectNotify(const QMetaMethod &signal) override; 0368 QString eventForSignal(const QMetaMethod &signal) const; 0369 0370 private: 0371 void init(); 0372 0373 int renewDBusSubscription(int subscriptionId, int leaseDuration, const QStringList &events = QStringList()); 0374 0375 void notifierConnect(const QString &signal, QObject *receiver, const char *slot); 0376 0377 static ReturnArguments parseIPPVars(ipp_t *response, ipp_tag_t group_tag); 0378 static QVariant ippAttrToVariant(ipp_attribute_t *attr); 0379 0380 static KCupsConnection *m_instance; 0381 0382 bool m_inited = false; 0383 KCupsPasswordDialog *m_passwordDialog; 0384 QUrl m_serverUrl; 0385 0386 QTimer *m_subscriptionTimer; 0387 QTimer *m_renewTimer; 0388 QStringList m_connectedEvents; // note this updated in another thread. Always guard with m_mutex 0389 QStringList m_requestedDBusEvents; 0390 int m_subscriptionId = -1; 0391 QMutex m_mutex; 0392 }; 0393 0394 #endif // KCUPSCONNECTION_H