Commit 1602b345 authored by dscho's avatar dscho

add KeyboardLedState extension

parent 5920dc18
2006-03-28 Steven Carr <scarr@jsa-usa.com>
* SDLvncviewer.c, rfbproto.c, vncviewer.c, main.c, rfbserver.c,
rfb.h, rfbclient.h, rfbproto.h: add new encoding: KeyboardLedState
2006-03-28 Karl Runge <runge@karlrunge.com> 2006-03-28 Karl Runge <runge@karlrunge.com>
* classes/ssl: patch to tightvnc Java viewer for SSL support * classes/ssl: patch to tightvnc Java viewer for SSL support
plus other fixes (richcursor colors, Tab keysym, etc). plus other fixes (richcursor colors, Tab keysym, etc).
......
...@@ -143,6 +143,12 @@ static void update(rfbClient* cl,int x,int y,int w,int h) { ...@@ -143,6 +143,12 @@ static void update(rfbClient* cl,int x,int y,int w,int h) {
SDL_UpdateRect(rfbClientGetClientData(cl, SDL_Init), x, y, w, h); SDL_UpdateRect(rfbClientGetClientData(cl, SDL_Init), x, y, w, h);
} }
static void kbd_leds(rfbClient* cl, int value, int pad) {
/* note: pad is for future expansion 0=unused */
fprintf(stderr,"Led State= 0x%02X\n", value);
fflush(stderr);
}
#ifdef __MINGW32__ #ifdef __MINGW32__
#define LOG_TO_FILE #define LOG_TO_FILE
#endif #endif
...@@ -203,6 +209,8 @@ int main(int argc,char** argv) { ...@@ -203,6 +209,8 @@ int main(int argc,char** argv) {
cl=rfbGetClient(8,3,4); cl=rfbGetClient(8,3,4);
cl->MallocFrameBuffer=resize; cl->MallocFrameBuffer=resize;
cl->GotFrameBufferUpdate=update; cl->GotFrameBufferUpdate=update;
cl->HandleKeyboardLedState=kbd_leds;
if(!rfbInitClient(cl,&argc,argv)) if(!rfbInitClient(cl,&argc,argv))
return 1; return 1;
......
...@@ -521,6 +521,7 @@ SetFormatAndEncodings(rfbClient* client) ...@@ -521,6 +521,7 @@ SetFormatAndEncodings(rfbClient* client)
rfbEncodingQualityLevel0); rfbEncodingQualityLevel0);
} }
if (client->appData.useRemoteCursor) { if (client->appData.useRemoteCursor) {
if (se->nEncodings < MAX_ENCODINGS) if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
...@@ -530,6 +531,11 @@ SetFormatAndEncodings(rfbClient* client) ...@@ -530,6 +531,11 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
} }
/* Let's receive keyboard state encoding if available */
if (se->nEncodings < MAX_ENCODINGS) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
}
if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
} }
...@@ -586,6 +592,11 @@ SetFormatAndEncodings(rfbClient* client) ...@@ -586,6 +592,11 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
} }
/* Keyboard State Encodings */
if (se->nEncodings < MAX_ENCODINGS) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
}
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
} }
...@@ -786,6 +797,16 @@ HandleRFBServerMessage(rfbClient* client) ...@@ -786,6 +797,16 @@ HandleRFBServerMessage(rfbClient* client)
continue; continue;
} }
if (rect.encoding == rfbEncodingKeyboardLedState) {
/* OK! We have received a keyboard state message!!! */
client->KeyboardLedStateEnabled = 1;
if (client->HandleKeyboardLedState!=NULL)
client->HandleKeyboardLedState(client, rect.r.x, 0);
// stash it for the future
client->CurrentKeyboardLedState = rect.r.x;
continue;
}
if ((rect.r.x + rect.r.w > client->si.framebufferWidth) || if ((rect.r.x + rect.r.w > client->si.framebufferWidth) ||
(rect.r.y + rect.r.h > client->si.framebufferHeight)) (rect.r.y + rect.r.h > client->si.framebufferHeight))
{ {
......
...@@ -117,6 +117,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, ...@@ -117,6 +117,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->serverHost=""; client->serverHost="";
client->serverPort=5900; client->serverPort=5900;
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = DummyPoint;
client->format.bitsPerPixel = bytesPerPixel*8; client->format.bitsPerPixel = bytesPerPixel*8;
client->format.depth = bitsPerSample*samplesPerPixel; client->format.depth = bitsPerSample*samplesPerPixel;
client->appData.requestedDepth=client->format.depth; client->appData.requestedDepth=client->format.depth;
...@@ -171,6 +174,8 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, ...@@ -171,6 +174,8 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->GetPassword = ReadPassword; client->GetPassword = ReadPassword;
client->MallocFrameBuffer = MallocFrameBuffer; client->MallocFrameBuffer = MallocFrameBuffer;
client->Bell = Dummy; client->Bell = Dummy;
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = DummyPoint;
return client; return client;
} }
......
...@@ -854,6 +854,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, ...@@ -854,6 +854,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->setTranslateFunction = rfbSetTranslateFunction; screen->setTranslateFunction = rfbSetTranslateFunction;
screen->newClientHook = rfbDefaultNewClientHook; screen->newClientHook = rfbDefaultNewClientHook;
screen->displayHook = NULL; screen->displayHook = NULL;
screen->getKeyboardLedStateHook = NULL;
/* initialize client list and iterator mutex */ /* initialize client list and iterator mutex */
rfbClientListInit(screen); rfbClientListInit(screen);
......
...@@ -348,6 +348,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, ...@@ -348,6 +348,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->enableCursorPosUpdates = FALSE; cl->enableCursorPosUpdates = FALSE;
cl->useRichCursorEncoding = FALSE; cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE; cl->enableLastRectEncoding = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->lastKeyboardLedState = -1;
cl->cursorX = rfbScreen->cursorX; cl->cursorX = rfbScreen->cursorX;
cl->cursorY = rfbScreen->cursorY; cl->cursorY = rfbScreen->cursorY;
cl->useNewFBSize = FALSE; cl->useNewFBSize = FALSE;
...@@ -729,6 +731,40 @@ static rfbBool rectSwapIfLEAndClip(uint16_t* x,uint16_t* y,uint16_t* w,uint16_t* ...@@ -729,6 +731,40 @@ static rfbBool rectSwapIfLEAndClip(uint16_t* x,uint16_t* y,uint16_t* w,uint16_t*
return TRUE; return TRUE;
} }
/*
* Send keyboard state (PointerPos pseudo-encoding).
*/
rfbBool
rfbSendKeyboardLedState(rfbClientPtr cl)
{
rfbFramebufferUpdateRectHeader rect;
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.encoding = Swap32IfLE(rfbEncodingKeyboardLedState);
rect.r.x = Swap16IfLE(cl->lastKeyboardLedState);
rect.r.y = 0;
rect.r.w = 0;
rect.r.h = 0;
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
cl->cursorPosBytesSent += sz_rfbFramebufferUpdateRectHeader;
cl->cursorPosUpdatesSent++;
if (!rfbSendUpdateBuf(cl))
return FALSE;
return TRUE;
}
/* /*
* rfbProcessClientNormalMessage is called when the client has sent a normal * rfbProcessClientNormalMessage is called when the client has sent a normal
* protocol message. * protocol message.
...@@ -911,6 +947,13 @@ rfbProcessClientNormalMessage(rfbClientPtr cl) ...@@ -911,6 +947,13 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->useNewFBSize = TRUE; cl->useNewFBSize = TRUE;
} }
break; break;
case rfbEncodingKeyboardLedState:
if (!cl->enableKeyboardLedState) {
rfbLog("Enabling KeyboardLedState protocol extension for client "
"%s\n", cl->host);
cl->enableKeyboardLedState = TRUE;
}
break;
#ifdef LIBVNCSERVER_HAVE_LIBZ #ifdef LIBVNCSERVER_HAVE_LIBZ
case rfbEncodingZRLE: case rfbEncodingZRLE:
if (cl->preferredEncoding == -1) { if (cl->preferredEncoding == -1) {
...@@ -1175,8 +1218,10 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, ...@@ -1175,8 +1218,10 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
int dx, dy; int dx, dy;
rfbBool sendCursorShape = FALSE; rfbBool sendCursorShape = FALSE;
rfbBool sendCursorPos = FALSE; rfbBool sendCursorPos = FALSE;
rfbBool sendKeyboardLedState = FALSE;
rfbBool result = TRUE; rfbBool result = TRUE;
if(cl->screen->displayHook) if(cl->screen->displayHook)
cl->screen->displayHook(cl); cl->screen->displayHook(cl);
...@@ -1216,6 +1261,21 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, ...@@ -1216,6 +1261,21 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
if (cl->enableCursorPosUpdates && cl->cursorWasMoved) if (cl->enableCursorPosUpdates && cl->cursorWasMoved)
sendCursorPos = TRUE; sendCursorPos = TRUE;
/*
* Do we plan to send a keyboard state update?
*/
if ((cl->enableKeyboardLedState) &&
(cl->screen->getKeyboardLedStateHook!=NULL))
{
int x;
x=cl->screen->getKeyboardLedStateHook(cl->screen);
if (x!=cl->lastKeyboardLedState)
{
sendKeyboardLedState = TRUE;
cl->lastKeyboardLedState=x;
}
}
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
/* /*
...@@ -1259,7 +1319,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, ...@@ -1259,7 +1319,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
sraRgnEmpty(updateRegion) && sraRgnEmpty(updateRegion) &&
(cl->enableCursorShapeUpdates || (cl->enableCursorShapeUpdates ||
(cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) && (cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) &&
!sendCursorShape && !sendCursorPos) { !sendCursorShape && !sendCursorPos && !sendKeyboardLedState) {
sraRgnDestroy(updateRegion); sraRgnDestroy(updateRegion);
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
return TRUE; return TRUE;
...@@ -1395,7 +1455,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, ...@@ -1395,7 +1455,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
} }
fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) + fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) +
nUpdateRegionRects + nUpdateRegionRects +
!!sendCursorShape + !!sendCursorPos)); !!sendCursorShape + !!sendCursorPos + !!sendKeyboardLedState));
} else { } else {
fu->nRects = 0xFFFF; fu->nRects = 0xFFFF;
} }
...@@ -1413,6 +1473,11 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, ...@@ -1413,6 +1473,11 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
goto updateFailed; goto updateFailed;
} }
if (sendKeyboardLedState) {
if (!rfbSendKeyboardLedState(cl))
goto updateFailed;
}
if (!sraRgnEmpty(updateCopyRegion)) { if (!sraRgnEmpty(updateCopyRegion)) {
if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy))
goto updateFailed; goto updateFailed;
......
...@@ -135,6 +135,9 @@ typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl); ...@@ -135,6 +135,9 @@ typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len); typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl); typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl); typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
/* support the capability to view the caps/num/scroll states of the X server */
typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
typedef struct { typedef struct {
uint32_t count; uint32_t count;
...@@ -295,6 +298,9 @@ typedef struct _rfbScreenInfo ...@@ -295,6 +298,9 @@ typedef struct _rfbScreenInfo
/* displayHook is called just before a frame buffer update */ /* displayHook is called just before a frame buffer update */
rfbDisplayHookPtr displayHook; rfbDisplayHookPtr displayHook;
/* These hooks are called to pass keyboard state back to the client */
rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook;
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
MUTEX(cursorMutex); MUTEX(cursorMutex);
rfbBool backgroundLoop; rfbBool backgroundLoop;
...@@ -478,7 +484,8 @@ typedef struct _rfbClientRec { ...@@ -478,7 +484,8 @@ typedef struct _rfbClientRec {
int tightQualityLevel; int tightQualityLevel;
#endif #endif
#endif #endif
int lastKeyboardLedState; /* keep track of last value so we can send *change* events */
rfbBool enableKeyboardLedState; /* client supports KeyboardState encoding */
rfbBool enableLastRectEncoding; /* client supports LastRect encoding */ rfbBool enableLastRectEncoding; /* client supports LastRect encoding */
rfbBool enableCursorShapeUpdates; /* client supports cursor shape updates */ rfbBool enableCursorShapeUpdates; /* client supports cursor shape updates */
rfbBool enableCursorPosUpdates; /* client supports cursor position updates */ rfbBool enableCursorPosUpdates; /* client supports cursor position updates */
......
...@@ -94,6 +94,7 @@ typedef struct { ...@@ -94,6 +94,7 @@ typedef struct {
struct _rfbClient; struct _rfbClient;
typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad);
typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y); typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y);
typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h); typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h);
typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client); typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client);
...@@ -196,7 +197,12 @@ typedef struct _rfbClient { ...@@ -196,7 +197,12 @@ typedef struct _rfbClient {
rfbVNCRec* vncRec; rfbVNCRec* vncRec;
/* Keyboard State support (is 'Caps Lock' set on the remote display???) */
int KeyboardLedStateEnabled;
int CurrentKeyboardLedState;
/* hooks */ /* hooks */
HandleKeyboardLedStateProc HandleKeyboardLedState;
HandleCursorPosProc HandleCursorPos; HandleCursorPosProc HandleCursorPos;
SoftCursorLockAreaProc SoftCursorLockArea; SoftCursorLockAreaProc SoftCursorLockArea;
SoftCursorUnlockScreenProc SoftCursorUnlockScreen; SoftCursorUnlockScreenProc SoftCursorUnlockScreen;
......
...@@ -445,6 +445,7 @@ typedef struct { ...@@ -445,6 +445,7 @@ typedef struct {
#define rfbEncodingXCursor 0xFFFFFF10 #define rfbEncodingXCursor 0xFFFFFF10
#define rfbEncodingRichCursor 0xFFFFFF11 #define rfbEncodingRichCursor 0xFFFFFF11
#define rfbEncodingPointerPos 0xFFFFFF18 #define rfbEncodingPointerPos 0xFFFFFF18
#define rfbEncodingKeyboardLedState 0xFFFFFF19
#define rfbEncodingLastRect 0xFFFFFF20 #define rfbEncodingLastRect 0xFFFFFF20
#define rfbEncodingNewFBSize 0xFFFFFF21 #define rfbEncodingNewFBSize 0xFFFFFF21
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment