File indexing completed on 2024-04-21 04:58:36
0001 /* 0002 SPDX-FileCopyrightText: 2007-2013 Urs Wolfer <uwolfer@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef VNCCLIENTTHREAD_H 0008 #define VNCCLIENTTHREAD_H 0009 0010 #ifdef QTONLY 0011 #define i18n tr 0012 #else 0013 #include <KLocalizedString> 0014 #endif 0015 0016 #include "remoteview.h" 0017 0018 #include <QImage> 0019 #include <QMutex> 0020 #include <QQueue> 0021 #include <QThread> 0022 0023 extern "C" { 0024 #include <rfb/rfbclient.h> 0025 } 0026 0027 class ClientEvent 0028 { 0029 public: 0030 virtual ~ClientEvent(); 0031 0032 virtual void fire(rfbClient *) = 0; 0033 }; 0034 0035 class ReconfigureEvent : public ClientEvent 0036 { 0037 public: 0038 void fire(rfbClient *) override; 0039 }; 0040 0041 class KeyClientEvent : public ClientEvent 0042 { 0043 public: 0044 KeyClientEvent(int key, int pressed) 0045 : m_key(key) 0046 , m_pressed(pressed) 0047 { 0048 } 0049 0050 void fire(rfbClient *) override; 0051 0052 private: 0053 int m_key; 0054 int m_pressed; 0055 }; 0056 0057 class PointerClientEvent : public ClientEvent 0058 { 0059 public: 0060 PointerClientEvent(int x, int y, int buttonMask) 0061 : m_x(x) 0062 , m_y(y) 0063 , m_buttonMask(buttonMask) 0064 { 0065 } 0066 0067 void fire(rfbClient *) override; 0068 0069 private: 0070 int m_x; 0071 int m_y; 0072 int m_buttonMask; 0073 }; 0074 0075 class ClientCutEvent : public ClientEvent 0076 { 0077 public: 0078 explicit ClientCutEvent(const QString &text) 0079 : text(text) 0080 { 0081 } 0082 0083 void fire(rfbClient *) override; 0084 0085 private: 0086 QString text; 0087 }; 0088 0089 class VncClientThread : public QThread 0090 { 0091 Q_OBJECT 0092 0093 public: 0094 enum ColorDepth { 0095 bpp32, 0096 bpp16, 0097 bpp8, 0098 }; 0099 Q_ENUM(ColorDepth) 0100 0101 explicit VncClientThread(QObject *parent = nullptr); 0102 ~VncClientThread() override; 0103 const QImage image(int x = 0, int y = 0, int w = 0, int h = 0); 0104 void setImage(const QImage &img); 0105 void emitUpdated(int x, int y, int w, int h); 0106 void emitGotCut(const QString &text); 0107 void stop(); 0108 void setHost(const QString &host); 0109 void setPort(int port); 0110 void setQuality(RemoteView::Quality quality); 0111 void setDevicePixelRatio(qreal dpr); 0112 void setPassword(const QString &password) 0113 { 0114 m_password = password; 0115 } 0116 void setShowLocalCursor(bool show); 0117 const QString password() const 0118 { 0119 return m_password; 0120 } 0121 void setUsername(const QString &username) 0122 { 0123 m_username = username; 0124 } 0125 const QString username() const 0126 { 0127 return m_username; 0128 } 0129 0130 RemoteView::Quality quality() const; 0131 ColorDepth colorDepth() const; 0132 uint8_t *frameBuffer; 0133 0134 Q_SIGNALS: 0135 void imageUpdated(int x, int y, int w, int h); 0136 void gotCut(const QString &text); 0137 void gotCursor(const QCursor &cursor); 0138 void passwordRequest(bool includingUsername = false); 0139 void outputErrorMessage(const QString &message); 0140 0141 /** 0142 * When we connect/disconnect/reconnect/etc., this signal will be emitted. 0143 * 0144 * @param status Is the client connected? 0145 * @param details A sentence describing what happened. 0146 */ 0147 void clientStateChanged(RemoteView::RemoteStatus status, const QString &details); 0148 0149 public Q_SLOTS: 0150 void mouseEvent(int x, int y, int buttonMask); 0151 void keyEvent(int key, bool pressed); 0152 void clientCut(const QString &text); 0153 0154 protected: 0155 void run() override; 0156 0157 private: 0158 void setClientColorDepth(rfbClient *cl, ColorDepth cd); 0159 void setColorDepth(ColorDepth colorDepth); 0160 0161 // These static methods are callback functions for libvncclient. Each 0162 // of them calls back into the corresponding member function via some 0163 // TLS-based logic. 0164 static rfbBool newclientStatic(rfbClient *cl); 0165 static void updatefbStaticPartial(rfbClient *cl, int x, int y, int w, int h); 0166 static void updateFbStaticFinished(rfbClient *cl); 0167 static void cuttextStatic(rfbClient *cl, const char *text, int textlen); 0168 static char *passwdHandlerStatic(rfbClient *cl); 0169 static rfbCredential *credentialHandlerStatic(rfbClient *cl, int credentialType); 0170 static void outputHandlerStatic(const char *format, ...); 0171 static void cursorShapeHandlerStatic(rfbClient *cl, int xhot, int yhot, int width, int height, int bpp); 0172 0173 // Member functions corresponding to the above static methods. 0174 rfbBool newclient(); 0175 void updatefbPartial(int x, int y, int w, int h); 0176 void updatefbFinished(); 0177 void cuttext(const char *text, int textlen); 0178 char *passwdHandler(); 0179 rfbCredential *credentialHandler(int credentialType); 0180 void outputHandler(const char *format, va_list args); 0181 0182 QImage m_image; 0183 rfbClient *cl; 0184 QString m_host; 0185 QString m_password; 0186 QString m_username; 0187 int m_port; 0188 bool m_showLocalCursor; 0189 QMutex mutex; 0190 RemoteView::Quality m_quality; 0191 qreal m_devicePixelRatio; 0192 ColorDepth m_colorDepth; 0193 QQueue<ClientEvent *> m_eventQueue; 0194 // color table for 8bit indexed colors 0195 QVector<QRgb> m_colorTable; 0196 QString outputErrorMessageString; 0197 0198 QRect m_dirtyRect; 0199 0200 volatile bool m_stopped; 0201 volatile bool m_passwordError; 0202 0203 /** 0204 * Connection keepalive/reconnection support. 0205 */ 0206 struct { 0207 /** 0208 * Number of seconds between probes. If zero, we will not attempt 0209 * to enable it. 0210 */ 0211 int intervalSeconds; 0212 /** 0213 * Number of failed probes required to recognise a disconnect. 0214 */ 0215 int failedProbes; 0216 /** 0217 * Was keepalive successfully set? 0218 */ 0219 bool set; 0220 /** 0221 * Did keepalive detect a disconnect? 0222 */ 0223 volatile bool failed; 0224 } m_keepalive; 0225 0226 // Initialise the VNC client library object. 0227 bool clientCreate(bool reinitialising); 0228 0229 // Uninitialise the VNC client library object. 0230 void clientDestroy(); 0231 0232 // Turn on keepalive support. 0233 void clientSetKeepalive(); 0234 0235 // Record a state change. 0236 void clientStateChange(RemoteView::RemoteStatus status, const QString &details); 0237 QString m_previousDetails; 0238 0239 private Q_SLOTS: 0240 void checkOutputErrorMessage(); 0241 }; 0242 0243 #endif