1
0
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:
Tim Jansen 2003-01-25 17:31:36 +00:00
parent 6adcc3aa08
commit 60f6e1f35e
6 changed files with 59 additions and 20 deletions

1
TODO
View File

@ -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,

View File

@ -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);
}

View File

@ -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:

View File

@ -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 */

View File

@ -329,6 +329,7 @@ typedef struct {
#define rfbEncodingSoftCursor 0xFFFFFF12
#define rfbEncodingLastRect 0xFFFFFF20
#define rfbEncodingBackground 0xFFFFFF25
#define rfbEncodingQualityLevel0 0xFFFFFFE0
#define rfbEncodingQualityLevel1 0xFFFFFFE1

View File

@ -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;
}