mirror of
https://invent.kde.org/network/krfb
synced 2024-06-26 05:02:13 +00:00
Extend VNC protocol to let the client enable/disable the background.
svn path=/trunk/kdenetwork/krfb/; revision=202747
This commit is contained in:
parent
6adcc3aa08
commit
60f6e1f35e
1
TODO
1
TODO
|
@ -2,7 +2,6 @@
|
|||
For 3.2:
|
||||
- write SLP service template for remote desktop protocols
|
||||
(documentation)
|
||||
- extend VNC to enable/disable desktop wallpaper
|
||||
- enhance RFB with SASL authentication (Kerberos)
|
||||
- encrypted connections (using SASL and/or SSL/TLS)
|
||||
- with kerberos/ssl: display name of remote user in connection dialog,
|
||||
|
|
|
@ -151,6 +151,11 @@ static void clientGoneHook(rfbClientPtr)
|
|||
self->handleClientGone();
|
||||
}
|
||||
|
||||
static void negotiationFinishedHook(rfbClientPtr cl)
|
||||
{
|
||||
self->handleNegotiationFinished(cl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ConnectionDialog::closeEvent(QCloseEvent *)
|
||||
|
@ -311,6 +316,8 @@ void SessionEstablishedEvent::exec() {
|
|||
RFBController::RFBController(Configuration *c) :
|
||||
allowDesktopControl(false),
|
||||
configuration(c),
|
||||
disableBackgroundPending(false),
|
||||
disableBackgroundState(false),
|
||||
closePending(false),
|
||||
forcedClose(false)
|
||||
{
|
||||
|
@ -370,9 +377,9 @@ void RFBController::startServer(int inetdFd, bool xtestGrab)
|
|||
|
||||
if ( server->rfbServerFormat.bitsPerPixel == 8 ) {
|
||||
server->rfbServerFormat.redShift = 0;
|
||||
server->rfbServerFormat.greenShift = 2;
|
||||
server->rfbServerFormat.blueShift = 5;
|
||||
server->rfbServerFormat.redMax = 3;
|
||||
server->rfbServerFormat.greenShift = 3;
|
||||
server->rfbServerFormat.blueShift = 6;
|
||||
server->rfbServerFormat.redMax = 7;
|
||||
server->rfbServerFormat.greenMax = 7;
|
||||
server->rfbServerFormat.blueMax = 3;
|
||||
} else {
|
||||
|
@ -485,6 +492,7 @@ void RFBController::refuseConnection()
|
|||
bool RFBController::checkAsyncEvents()
|
||||
{
|
||||
bool closed = false;
|
||||
bool backgroundActionRequired = false;
|
||||
asyncMutex.lock();
|
||||
VNCEvent *e;
|
||||
for (e = asyncQueue.first(); e; e = asyncQueue.next())
|
||||
|
@ -495,17 +503,25 @@ bool RFBController::checkAsyncEvents()
|
|||
closed = true;
|
||||
closePending = false;
|
||||
}
|
||||
if (disableBackgroundPending != disableBackgroundState)
|
||||
backgroundActionRequired = true;
|
||||
asyncMutex.unlock();
|
||||
|
||||
if (backgroundActionRequired && (!closed) && !configuration->disableBackground())
|
||||
disableBackground(disableBackgroundPending);
|
||||
|
||||
return closed;
|
||||
}
|
||||
|
||||
void RFBController::restoreBackground() {
|
||||
if (configuration->disableBackground()) {
|
||||
DCOPRef ref("kdesktop", "KBackgroundIface");
|
||||
ref.setDCOPClient(KApplication::dcopClient());
|
||||
void RFBController::disableBackground(bool state) {
|
||||
if (disableBackgroundState == state)
|
||||
return;
|
||||
|
||||
ref.send("setBackgroundEnabled(bool)", bool(true));
|
||||
}
|
||||
disableBackgroundState = state;
|
||||
DCOPRef ref("kdesktop", "KBackgroundIface");
|
||||
ref.setDCOPClient(KApplication::dcopClient());
|
||||
|
||||
ref.send("setBackgroundEnabled(bool)", bool(!state));
|
||||
}
|
||||
|
||||
void RFBController::connectionClosed()
|
||||
|
@ -515,7 +531,7 @@ void RFBController::connectionClosed()
|
|||
.arg(remoteIp));
|
||||
|
||||
idleTimer.stop();
|
||||
restoreBackground();
|
||||
disableBackground(false);
|
||||
state = RFB_WAITING;
|
||||
if (forcedClose)
|
||||
emit quitApp();
|
||||
|
@ -527,7 +543,7 @@ void RFBController::closeConnection()
|
|||
{
|
||||
forcedClose = true;
|
||||
if (state == RFB_CONNECTED) {
|
||||
restoreBackground();
|
||||
disableBackground(false);
|
||||
|
||||
if (!checkAsyncEvents()) {
|
||||
asyncMutex.lock();
|
||||
|
@ -571,7 +587,7 @@ void RFBController::idleSlot()
|
|||
defaultPtrAddEvent(0, p.x(),p.y(), server->rfbClientHead);
|
||||
asyncMutex.unlock();
|
||||
|
||||
checkAsyncEvents();
|
||||
checkAsyncEvents(); // check 2nd time (see 3rd line)
|
||||
}
|
||||
|
||||
void RFBController::dialogAccepted()
|
||||
|
@ -657,6 +673,7 @@ bool RFBController::handleCheckPassword(rfbClientPtr cl,
|
|||
enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl)
|
||||
{
|
||||
int socket = cl->sock;
|
||||
cl->negotiationFinishedHook = negotiationFinishedHook;
|
||||
|
||||
QString host, port;
|
||||
KSocketAddress *ksa = KExtendedSocket::peerAddress(socket);
|
||||
|
@ -712,6 +729,13 @@ void RFBController::handleClientGone()
|
|||
asyncMutex.unlock();
|
||||
}
|
||||
|
||||
void RFBController::handleNegotiationFinished(rfbClientPtr cl)
|
||||
{
|
||||
asyncMutex.lock();
|
||||
disableBackgroundPending = cl->disableBackground;
|
||||
asyncMutex.unlock();
|
||||
}
|
||||
|
||||
void RFBController::handleKeyEvent(bool down, KeySym keySym) {
|
||||
if (!allowDesktopControl)
|
||||
return;
|
||||
|
@ -747,12 +771,8 @@ void RFBController::sendKNotifyEvent(const QString &n, const QString &d)
|
|||
|
||||
void RFBController::sendSessionEstablished()
|
||||
{
|
||||
if (configuration->disableBackground()) {
|
||||
DCOPRef ref("kdesktop", "KBackgroundIface");
|
||||
ref.setDCOPClient(KApplication::dcopClient());
|
||||
|
||||
ref.send("setBackgroundEnabled(bool)", bool(false));
|
||||
}
|
||||
if (configuration->disableBackground())
|
||||
disableBackground(true);
|
||||
emit sessionEstablished(remoteIp);
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
void handlePointerEvent(int button_mask, int x, int y);
|
||||
enum rfbNewClientAction handleNewClient(rfbClientPtr cl);
|
||||
void handleClientGone();
|
||||
void handleNegotiationFinished(rfbClientPtr cl);
|
||||
int getPort();
|
||||
void startServer(int inetdFd = -1, bool xtestGrab = true);
|
||||
|
||||
|
@ -160,7 +161,7 @@ private:
|
|||
void sendKNotifyEvent(const QString &name, const QString &desc);
|
||||
bool checkAsyncEvents();
|
||||
void sendSessionEstablished();
|
||||
void restoreBackground();
|
||||
void disableBackground(bool state);
|
||||
|
||||
QString remoteIp;
|
||||
bool allowDesktopControl;
|
||||
|
@ -179,6 +180,8 @@ private:
|
|||
QMutex asyncMutex;
|
||||
QPtrList<VNCEvent> asyncQueue;
|
||||
|
||||
bool disableBackgroundPending; // background, as desired by libvncserver
|
||||
bool disableBackgroundState; // real background state
|
||||
bool closePending; // set when libvncserver detected close
|
||||
bool forcedClose; // set when user closed connection
|
||||
private slots:
|
||||
|
|
|
@ -391,6 +391,7 @@ typedef struct sraRegion* sraRegionPtr;
|
|||
*/
|
||||
|
||||
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
|
||||
typedef void (*NegotiationFinishedHookPtr)(struct _rfbClientRec* cl);
|
||||
|
||||
typedef struct _rfbClientRec {
|
||||
|
||||
|
@ -404,8 +405,12 @@ typedef struct _rfbClientRec {
|
|||
* This is useful if the IO functions have to behave client specific.
|
||||
*/
|
||||
void* clientData;
|
||||
|
||||
ClientGoneHookPtr clientGoneHook;
|
||||
|
||||
/* negotiationFinishedHook is called when the negotiation phase has ended */
|
||||
NegotiationFinishedHookPtr negotiationFinishedHook;
|
||||
|
||||
SOCKET sock;
|
||||
char *host;
|
||||
|
||||
|
@ -526,6 +531,7 @@ typedef struct _rfbClientRec {
|
|||
|
||||
Bool enableLastRectEncoding; /* client supports LastRect encoding */
|
||||
Bool enableSoftCursorUpdates; /* client supports softcursor updates */
|
||||
Bool disableBackground; /* client wants to disable background */
|
||||
Bool enableCursorShapeUpdates; /* client supports cursor shape updates */
|
||||
Bool useRichCursorEncoding; /* rfbEncodingRichCursor is preferred */
|
||||
Bool cursorWasChanged; /* cursor shape update should be sent */
|
||||
|
|
|
@ -329,6 +329,7 @@ typedef struct {
|
|||
#define rfbEncodingSoftCursor 0xFFFFFF12
|
||||
|
||||
#define rfbEncodingLastRect 0xFFFFFF20
|
||||
#define rfbEncodingBackground 0xFFFFFF25
|
||||
|
||||
#define rfbEncodingQualityLevel0 0xFFFFFFE0
|
||||
#define rfbEncodingQualityLevel1 0xFFFFFFE1
|
||||
|
|
|
@ -273,6 +273,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
|
|||
cl->enableCursorShapeUpdates = FALSE;
|
||||
cl->useRichCursorEncoding = FALSE;
|
||||
cl->enableLastRectEncoding = FALSE;
|
||||
cl->disableBackground = FALSE;
|
||||
|
||||
cl->compStreamInited = FALSE;
|
||||
cl->compStream.total_in = 0;
|
||||
|
@ -299,6 +300,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
|
|||
|
||||
cl->clientData = NULL;
|
||||
cl->clientGoneHook = doNothingWithClient;
|
||||
cl->negotiationFinishedHook = doNothingWithClient;
|
||||
switch (cl->screen->newClientHook(cl)) {
|
||||
case RFB_CLIENT_ON_HOLD:
|
||||
cl->onHold = TRUE;
|
||||
|
@ -663,6 +665,7 @@ rfbProcessClientNormalMessage(cl)
|
|||
cl->useCopyRect = FALSE;
|
||||
cl->enableCursorShapeUpdates = FALSE;
|
||||
cl->enableLastRectEncoding = FALSE;
|
||||
cl->disableBackground = FALSE;
|
||||
|
||||
for (i = 0; i < msg.se.nEncodings; i++) {
|
||||
if ((n = ReadExact(cl, (char *)&enc, 4)) <= 0) {
|
||||
|
@ -749,6 +752,11 @@ rfbProcessClientNormalMessage(cl)
|
|||
cl->enableLastRectEncoding = TRUE;
|
||||
}
|
||||
break;
|
||||
case rfbEncodingBackground:
|
||||
rfbLog("Disabling background for client "
|
||||
"%s\n", cl->host);
|
||||
cl->disableBackground = TRUE;
|
||||
break;
|
||||
#ifdef BACKCHANNEL
|
||||
case rfbEncodingBackChannel:
|
||||
if (!cl->enableBackChannel) {
|
||||
|
@ -780,6 +788,8 @@ rfbProcessClientNormalMessage(cl)
|
|||
cl->preferredEncoding = rfbEncodingRaw;
|
||||
}
|
||||
|
||||
cl->negotiationFinishedHook(cl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user