Changeset 27975 in vbox
- Timestamp:
- Apr 4, 2010 2:14:44 PM (15 years ago)
- Location:
- trunk/src/VBox/Frontends/VBoxHeadless
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.cpp
r27964 r27975 68 68 RTCritSectDelete(&mCritSect); 69 69 if (vncServer) { 70 71 72 73 74 75 70 if (vncServer->authPasswdData) { 71 char **papszPassword = (char **)vncServer->authPasswdData; 72 vncServer->authPasswdData = NULL; 73 RTMemFree(papszPassword[0]); 74 RTMemFree(papszPassword); 75 } 76 76 rfbScreenCleanup(vncServer); 77 77 } … … 93 93 94 94 if (mVncPassword) { 95 95 char **papszPasswords = (char **)RTMemAlloc(2 * sizeof(char **)); 96 96 papszPasswords[0] = RTStrDup(mVncPassword); 97 97 papszPasswords[1] = NULL; 98 98 vncServer->authPasswdData = papszPasswords; 99 99 vncServer->passwordCheck = rfbCheckPasswordByList; //Password list based authentication function 100 100 } else { 101 101 vncServer->authPasswdData = NULL; 102 102 } 103 103 … … 125 125 126 126 void VNCFB::vncMouseEvent(int buttonMask, int x, int y, rfbClientPtr cl) { 127 128 127 ((VNCFB*)(cl->screen->screenData))->handleVncMouseEvent(buttonMask, x, y); 128 rfbDefaultPtrAddEvent(buttonMask, x, y, cl); 129 129 } 130 130 131 131 void VNCFB::handleVncMouseEvent(int buttonMask, int x, int y) { 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 132 //RTPrintf("VNC mouse: button=%d x=%d y=%d\n", buttonMask, x, y); 133 if (!mMouse) { 134 this->mConsole->COMGETTER(Mouse)(mMouse.asOutParam()); 135 if (!mMouse) { 136 RTPrintf("Warning: could not get mouse object!\n"); 137 return; 138 } 139 } 140 int dz = 0, buttons = 0; 141 if (buttonMask & 16) dz = 1; else if (buttonMask & 8) dz = -1; 142 if (buttonMask & 1) buttons |= 1; 143 if (buttonMask & 2) buttons |= 4; 144 if (buttonMask & 4) buttons |= 2; 145 mMouse->PutMouseEvent(x - mouseX, y - mouseY, dz, 0, buttons); 146 //mMouse->PutMouseEventAbsolute(x + 1, y + 1, dz, 0, buttonMask); 147 mouseX = x; 148 mouseY = y; 149 149 } 150 150 151 151 void VNCFB::kbdPutCode(int code) { 152 152 mKeyboard->PutScancode(code); 153 153 } 154 154 void VNCFB::kbdSetShift(int state) { 155 156 157 158 159 160 161 155 if (state && !kbdShiftState) { 156 kbdPutCode(0x2a, 1); 157 kbdShiftState = 1; 158 } else if (!state && kbdShiftState) { 159 kbdPutCode(0x2a, 0); 160 kbdShiftState = 0; 161 } 162 162 } 163 163 void VNCFB::kbdPutCode(int code, int down) { 164 165 164 if (code & 0xff00) kbdPutCode((code >> 8) & 0xff); 165 kbdPutCode((code & 0xff) | (down ? 0 : 0x80)); 166 166 } 167 167 void VNCFB::kbdPutCodeShift(int shift, int code, int down) { 168 169 170 168 if (shift != kbdShiftState) kbdPutCode(0x2a, shift); 169 kbdPutCode(code, down); 170 if (shift != kbdShiftState) kbdPutCode(0x2a, kbdShiftState); 171 171 } 172 172 … … 176 176 * and a switch() block to handle some special keys. */ 177 177 void VNCFB::handleVncKeyboardEvent(int down, int keycode) { 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 178 //RTPrintf("VNC keyboard: down=%d code=%d -> ", down, keycode); 179 if (mKeyboard == NULL) { 180 this->mConsole->COMGETTER(Keyboard)(mKeyboard.asOutParam()); 181 if (!mKeyboard) { 182 RTPrintf("Warning: could not get keyboard object!\n"); 183 return; 184 } 185 } 186 /* Conversion table for key code range 32-127 (which happen to equal the ASCII codes) 187 * The values in the table differ slightly from the actual scancode values that will be sent, 188 * values 0xe0?? indicate that a 0xe0 scancode will be sent first (extended keys), then code ?? is sent 189 * values 0x01?? indicate that the shift key must be 'down', then ?? is sent 190 * values 0x00?? or 0x?? indicate that the shift key must be 'up', then ?? is sent 191 * values 0x02?? indicate that the shift key can be ignored, and scancode ?? is sent 192 * This is necessary because the VNC protocol sends a shift key sequence, but also 193 * sends the 'shifted' version of the characters. */ 194 static int codes_low[] = { //Conversion table for VNC key code range 32-127 195 0x0239, 0x0102, 0x0128, 0x0104, 0x0105, 0x0106, 0x0108, 0x0028, 0x010a, 0x010b, 0x0109, 0x010d, 0x0029, 0x000c, 0x0034, 0x0035, //space, !"#$%&'()*+`-./ 196 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, //0123456789 197 0x0127, 0x0027, 0x0133, 0x000d, 0x0134, 0x0135, 0x0103, //:;<=>?@ 198 0x11e, 0x130, 0x12e, 0x120, 0x112, 0x121, 0x122, 0x123, 0x117, 0x124, 0x125, 0x126, 0x132, 0x131, 0x118, 0x119, 0x110, 0x113, 0x11f, 0x114, 0x116, 0x12f, 0x111, 0x12d, 0x115, 0x12c, //A-Z 199 0x001a, 0x002b, 0x001b, 0x0107, 0x010c, 0x0029, //[\]^_` 200 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, //a-z 201 0x011a, 0x012b, 0x011b, 0x0129 //{|}~ 202 }; 203 int shift = -1, code = -1; 204 if (keycode < 32) { //ASCII control codes.. unused.. 205 } else if (keycode < 127) { //DEL is in high area 206 code = codes_low[keycode - 32]; 207 shift = (code >> 8) & 0x03; if (shift == 0x02 || code & 0xe000) shift = -1; 208 code = code & 0xe0ff; 209 } else if ((keycode & 0xFF00) != 0xFF00) { 210 } else { 211 switch(keycode) { 212 212 /*Numpad keys - these have to be implemented yet 213 213 Todo: numpad arrows, home, pageup, pagedown, end, insert, delete … … 231 231 65456 Numpad 0 232 232 */ 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 233 case 65288: code = 0x0e; break; //Backspace 234 case 65289: code = 0x0f; break; //Tab 235 236 case 65293: code = 0x1c; break; //Return 237 //case 65299: break; Pause/break 238 case 65307: code = 0x01; break; //Escape 239 240 case 65360: code = 0xe047; break; //Home 241 case 65361: code = 0xe04b; break; //Left 242 case 65362: code = 0xe048; break; //Up 243 case 65363: code = 0xe04d; break; //Right 244 case 65364: code = 0xe050; break; //Down 245 case 65365: code = 0xe049; break; //Page up 246 case 65366: code = 0xe051; break; //Page down 247 case 65367: code = 0xe04f; break; //End 248 249 //case 65377: break; //Print screen 250 case 65379: code = 0xe052; break; //Insert 251 252 case 65383: code = 0xe05d; break; //Menu 253 254 case 65470: code = 0x3b; break; //F1 255 case 65471: code = 0x3c; break; //F2 256 case 65472: code = 0x3d; break; //F3 257 case 65473: code = 0x3e; break; //F4 258 case 65474: code = 0x3f; break; //F5 259 case 65475: code = 0x40; break; //F6 260 case 65476: code = 0x41; break; //F7 261 case 65477: code = 0x42; break; //F8 262 case 65478: code = 0x43; break; //F9 263 case 65479: code = 0x44; break; //F10 264 case 65480: code = 0x57; break; //F11 265 case 65481: code = 0x58; break; //F12 266 267 case 65505: shift = down; break; //Shift (left + right) 268 case 65507: code = 0x1d; break; //Left ctrl 269 case 65508: code = 0xe01d; break; //Right ctrl 270 case 65513: code = 0x38; break; //Left Alt 271 case 65514: code = 0xe038; break; //Right Alt 272 case 65515: code = 0xe05b; break; //Left windows key 273 case 65516: code = 0xe05c; break; //Right windows key 274 case 65535: code = 0xe053; break; //Delete 275 default: RTPrintf("VNC unhandled keyboard code: down=%d code=%d\n", down, keycode); break; 276 } 277 } 278 //RTPrintf("down=%d shift=%d code=%d\n", down, shift, code); 279 if (shift != -1 && code != -1) { 280 kbdPutCodeShift(shift, code, down); 281 } else if (shift != -1) { 282 kbdSetShift(shift); 283 } else if (code != -1) { 284 kbdPutCode(code, down); 285 } 286 286 } 287 287 void VNCFB::handleVncKeyboardReleaseEvent() { 288 289 290 291 292 288 kbdSetShift(0); 289 kbdPutCode(0x1d, 0); //Left ctrl 290 kbdPutCode(0xe01d, 0); //Right ctrl 291 kbdPutCode(0x38, 0); //Left alt 292 kbdPutCode(0xe038, 0); //Right alt 293 293 } 294 294 295 295 void VNCFB::vncKeyboardEvent(rfbBool down, rfbKeySym keySym, rfbClientPtr cl) { 296 296 ((VNCFB*)(cl->screen->screenData))->handleVncKeyboardEvent(down, keySym); 297 297 } 298 298 void VNCFB::vncReleaseKeysEvent(rfbClientPtr cl) { //Release modifier keys 299 299 ((VNCFB*)(cl->screen->screenData))->handleVncKeyboardReleaseEvent(); 300 300 } 301 301 … … 332 332 ULONG bytesPerLine, 333 333 ULONG w, ULONG h, BOOL *finished) { 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 334 NOREF(aScreenId); 335 if (!finished) return E_POINTER; 336 337 /* For now, we are doing things synchronously */ 338 *finished = true; 339 340 if (mRGBBuffer) RTMemFree(mRGBBuffer); 341 342 mWidth = w; 343 mHeight = h; 344 345 if (pixelFormat == FramebufferPixelFormat_FOURCC_RGB && bitsPerPixel == 32) { 346 mPixelFormat = FramebufferPixelFormat_FOURCC_RGB; 347 mBufferAddress = reinterpret_cast<uint8_t *>(vram); 348 mBytesPerLine = bytesPerLine; 349 mBitsPerPixel = bitsPerPixel; 350 mRGBBuffer = NULL; 351 } else { 352 mPixelFormat = FramebufferPixelFormat_FOURCC_RGB; 353 mBytesPerLine = w * 4; 354 mBitsPerPixel = 32; 355 mRGBBuffer = reinterpret_cast<uint8_t *>(RTMemAlloc(mBytesPerLine * h)); 356 AssertReturn(mRGBBuffer != 0, E_OUTOFMEMORY); 357 mBufferAddress = mRGBBuffer; 358 } 359 360 uint8_t *oldBuffer = mScreenBuffer; 361 mScreenBuffer = reinterpret_cast<uint8_t *>(RTMemAlloc(mBytesPerLine * h)); 362 AssertReturn(mScreenBuffer != 0, E_OUTOFMEMORY); 363 364 for (ULONG i = 0; i < mBytesPerLine * h; i += 4) { 365 mScreenBuffer[i] = mBufferAddress[i+2]; 366 mScreenBuffer[i+1] = mBufferAddress[i+1]; 367 mScreenBuffer[i+2] = mBufferAddress[i]; 368 } 369 370 RTPrintf("Set framebuffer: buffer=%d w=%lu h=%lu bpp=%d\n", mBufferAddress, mWidth, mHeight, (int)mBitsPerPixel); 371 rfbNewFramebuffer(vncServer, (char*)mScreenBuffer, mWidth, mHeight, 8, 3, mBitsPerPixel / 8); 372 if (oldBuffer) RTMemFree(oldBuffer); 373 return S_OK; 374 374 } 375 375 376 376 //Guest framebuffer update notification 377 377 STDMETHODIMP VNCFB::NotifyUpdate(ULONG x, ULONG y, ULONG w, ULONG h) { 378 379 380 381 382 383 384 385 386 387 378 if (!mBufferAddress || !mScreenBuffer) return S_OK; 379 ULONG joff = y * mBytesPerLine + x * 4; 380 for (ULONG j = joff; j < joff + h * mBytesPerLine; j += mBytesPerLine) 381 for (ULONG i = j; i < j + w * 4; i += 4) { 382 mScreenBuffer[i] = mBufferAddress[i+2]; 383 mScreenBuffer[i+1] = mBufferAddress[i+1]; 384 mScreenBuffer[i+2] = mBufferAddress[i]; 385 } 386 rfbMarkRectAsModified(vncServer, x, y, x+w, y+h); 387 return S_OK; 388 388 } 389 389 -
trunk/src/VBox/Frontends/VBoxHeadless/FramebufferVNC.h
r27964 r27975 81 81 82 82 private: 83 84 85 86 87 88 83 /** Guest framebuffer pixel format */ 84 ULONG mPixelFormat; 85 /** Guest framebuffer color depth */ 86 ULONG mBitsPerPixel; 87 /** Guest framebuffer line length */ 88 ULONG mBytesPerLine; 89 89 90 91 92 93 94 95 90 //Our own framebuffer, in case we can't use the VRAM 91 uint8_t *mRGBBuffer; 92 //The source framebuffer (either our own mRGBBuffer or the guest VRAM) 93 uint8_t *mBufferAddress; 94 //VNC display framebuffer (RGB -> BGR converted) 95 uint8_t *mScreenBuffer; 96 96 97 97 int mVncPort; 98 98 99 100 101 99 ComPtr<IConsole> mConsole; 100 ComPtr<IKeyboard> mKeyboard; 101 ComPtr<IMouse> mMouse; 102 102 103 104 105 106 107 103 int kbdShiftState; 104 void kbdSetShift(int state); 105 void kbdPutCode(int code); 106 void kbdPutCode(int code, int down); 107 void kbdPutCodeShift(int shift, int code, int down); 108 108 109 109 ULONG mWidth, mHeight; 110 110 111 111 RTCRITSECT mCritSect; 112 112 113 114 113 rfbScreenInfoPtr vncServer; 114 RTTHREAD mVncThread; 115 115 static DECLCALLBACK(int) vncThreadFn(RTTHREAD hThreadSelf, void *pvUser); 116 116 /** The password that was passed to the constructor. NULL if no 117 117 * authentication required. */ 118 118 char const *mVncPassword; 119 119 120 121 122 120 static void vncKeyboardEvent(rfbBool down, rfbKeySym keySym, rfbClientPtr cl); 121 static void vncMouseEvent(int buttonMask, int x, int y, rfbClientPtr cl); 122 static void vncReleaseKeysEvent(rfbClientPtr cl); 123 123 124 125 126 124 void handleVncKeyboardEvent(int down, int keySym); 125 void handleVncMouseEvent(int buttonMask, int x, int y); 126 void handleVncKeyboardReleaseEvent(); 127 127 128 128 int mouseX, mouseY; 129 129 130 130 #ifndef VBOX_WITH_XPCOM 131 131 long refcnt; 132 132 #endif 133 133 };
Note:
See TracChangeset
for help on using the changeset viewer.