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>
* classes/ssl: patch to tightvnc Java viewer for SSL support
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) {
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__
#define LOG_TO_FILE
#endif
......@@ -203,6 +209,8 @@ int main(int argc,char** argv) {
cl=rfbGetClient(8,3,4);
cl->MallocFrameBuffer=resize;
cl->GotFrameBufferUpdate=update;
cl->HandleKeyboardLedState=kbd_leds;
if(!rfbInitClient(cl,&argc,argv))
return 1;
......
......@@ -521,6 +521,7 @@ SetFormatAndEncodings(rfbClient* client)
rfbEncodingQualityLevel0);
}
if (client->appData.useRemoteCursor) {
if (se->nEncodings < MAX_ENCODINGS)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
......@@ -530,6 +531,11 @@ SetFormatAndEncodings(rfbClient* client)
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) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
}
......@@ -586,6 +592,11 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
}
/* Keyboard State Encodings */
if (se->nEncodings < MAX_ENCODINGS) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
}
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
}
......@@ -786,6 +797,16 @@ HandleRFBServerMessage(rfbClient* client)
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) ||
(rect.r.y + rect.r.h > client->si.framebufferHeight))
{
......
......@@ -117,6 +117,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->serverHost="";
client->serverPort=5900;
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = DummyPoint;
client->format.bitsPerPixel = bytesPerPixel*8;
client->format.depth = bitsPerSample*samplesPerPixel;
client->appData.requestedDepth=client->format.depth;
......@@ -171,6 +174,8 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->GetPassword = ReadPassword;
client->MallocFrameBuffer = MallocFrameBuffer;
client->Bell = Dummy;
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = DummyPoint;
return client;
}
......
......@@ -854,6 +854,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->setTranslateFunction = rfbSetTranslateFunction;
screen->newClientHook = rfbDefaultNewClientHook;
screen->displayHook = NULL;
screen->getKeyboardLedStateHook = NULL;
/* initialize client list and iterator mutex */
rfbClientListInit(screen);
......
......@@ -348,6 +348,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->enableCursorPosUpdates = FALSE;
cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->lastKeyboardLedState = -1;
cl->cursorX = rfbScreen->cursorX;
cl->cursorY = rfbScreen->cursorY;
cl->useNewFBSize = FALSE;
......@@ -729,6 +731,40 @@ static rfbBool rectSwapIfLEAndClip(uint16_t* x,uint16_t* y,uint16_t* w,uint16_t*
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
* protocol message.
......@@ -911,6 +947,13 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->useNewFBSize = TRUE;
}
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
case rfbEncodingZRLE:
if (cl->preferredEncoding == -1) {
......@@ -1175,8 +1218,10 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
int dx, dy;
rfbBool sendCursorShape = FALSE;
rfbBool sendCursorPos = FALSE;
rfbBool sendKeyboardLedState = FALSE;
rfbBool result = TRUE;
if(cl->screen->displayHook)
cl->screen->displayHook(cl);
......@@ -1216,6 +1261,21 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
if (cl->enableCursorPosUpdates && cl->cursorWasMoved)
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);
/*
......@@ -1259,7 +1319,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
sraRgnEmpty(updateRegion) &&
(cl->enableCursorShapeUpdates ||
(cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) &&
!sendCursorShape && !sendCursorPos) {
!sendCursorShape && !sendCursorPos && !sendKeyboardLedState) {
sraRgnDestroy(updateRegion);
UNLOCK(cl->updateMutex);
return TRUE;
......@@ -1395,7 +1455,7 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
}
fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) +
nUpdateRegionRects +
!!sendCursorShape + !!sendCursorPos));
!!sendCursorShape + !!sendCursorPos + !!sendKeyboardLedState));
} else {
fu->nRects = 0xFFFF;
}
......@@ -1413,6 +1473,11 @@ rfbSendFramebufferUpdate(rfbClientPtr cl,
goto updateFailed;
}
if (sendKeyboardLedState) {
if (!rfbSendKeyboardLedState(cl))
goto updateFailed;
}
if (!sraRgnEmpty(updateCopyRegion)) {
if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy))
goto updateFailed;
......
......@@ -135,6 +135,9 @@ typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(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 {
uint32_t count;
......@@ -295,6 +298,9 @@ typedef struct _rfbScreenInfo
/* displayHook is called just before a frame buffer update */
rfbDisplayHookPtr displayHook;
/* These hooks are called to pass keyboard state back to the client */
rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook;
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
MUTEX(cursorMutex);
rfbBool backgroundLoop;
......@@ -478,7 +484,8 @@ typedef struct _rfbClientRec {
int tightQualityLevel;
#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 enableCursorShapeUpdates; /* client supports cursor shape updates */
rfbBool enableCursorPosUpdates; /* client supports cursor position updates */
......
......@@ -94,6 +94,7 @@ typedef struct {
struct _rfbClient;
typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad);
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 (*SoftCursorUnlockScreenProc)(struct _rfbClient* client);
......@@ -196,7 +197,12 @@ typedef struct _rfbClient {
rfbVNCRec* vncRec;
/* Keyboard State support (is 'Caps Lock' set on the remote display???) */
int KeyboardLedStateEnabled;
int CurrentKeyboardLedState;
/* hooks */
HandleKeyboardLedStateProc HandleKeyboardLedState;
HandleCursorPosProc HandleCursorPos;
SoftCursorLockAreaProc SoftCursorLockArea;
SoftCursorUnlockScreenProc SoftCursorUnlockScreen;
......
......@@ -445,6 +445,7 @@ typedef struct {
#define rfbEncodingXCursor 0xFFFFFF10
#define rfbEncodingRichCursor 0xFFFFFF11
#define rfbEncodingPointerPos 0xFFFFFF18
#define rfbEncodingKeyboardLedState 0xFFFFFF19
#define rfbEncodingLastRect 0xFFFFFF20
#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