Changeset 89935 in vbox for trunk/src/VBox
- Timestamp:
- Jun 29, 2021 6:38:48 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145393
- Location:
- trunk/src/VBox
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DevPS2.h
r83443 r89935 89 89 /** The size of an array needed to store all USB usage codes */ 90 90 #define VBOX_USB_USAGE_ARRAY_SIZE (VBOX_USB_MAX_USAGE_CODE + 1) 91 /** USB HID Keyboard Usage Page. */92 #define USB_HID_KB_PAGE 793 /** USB HID Consumer Control Usage Page. */94 #define USB_HID_CC_PAGE 1295 91 /** @} */ 96 92 -
trunk/src/VBox/Devices/Input/DevPS2K.cpp
r89812 r89935 373 373 }; 374 374 375 /* USB to PS/2 conversion table for Generic Desktop Control keys (HID Usage Page 1). */ 376 /* This usage page is tiny. */ 377 static const ext_key_def aPS2DCKeys[] = { 378 {0x81, {0x5E, 0x37, UNKN, KF_E0, T_U}}, /* System Power */ 379 {0x82, {0x5F, 0x3F, UNKN, KF_E0, T_U}}, /* System Sleep */ 380 {0x83, {0x63, 0x5E, UNKN, KF_E0, T_U}}, /* System Wake */ 381 }; 382 383 /* We somehow need to keep track of depressed keys. To keep the array size 384 * under control, and because the number of defined keys isn't massive, we'd 385 * like to use an 8-bit index into the array. 386 * For the main USB HID usage page 7 (keyboard), we deal with 8-bit HID codes 387 * in the range from 0 to 0xE7, and use the HID codes directly. 388 * There's a convenient gap in the 0xA5-0xDF range. We use that to stuff the 389 * USB HID usage page 12 (consumer control) into the gap starting at 0xC0; 390 * the consumer control codes are from 0xB5 to 0x22A, but very sparse, with 391 * only 24 codes defined. We use the aPS2CCKeys array to generate our own 392 * code in the 0xC0-0xD7 range. 393 * For the tiny USB HID usage page 1 (generic desktop system) we use a similar 394 * approach, translating these to codes 0xB0 to 0xB2. 395 */ 396 397 #define PS2K_PAGE_DC_START 0xb0 398 #define PS2K_PAGE_DC_END (PS2K_PAGE_DC_START + RT_ELEMENTS(aPS2DCKeys)) 399 #define PS2K_PAGE_CC_START 0xc0 400 #define PS2K_PAGE_CC_END (PS2K_PAGE_CC_START + RT_ELEMENTS(aPS2CCKeys)) 401 402 AssertCompile(RT_ELEMENTS(aPS2CCKeys) <= 0x20); /* Must fit between 0xC0-0xDF. */ 403 AssertCompile(RT_ELEMENTS(aPS2DCKeys) <= 0x10); /* Must fit between 0xB0-0xBF. */ 404 375 405 #endif /* IN_RING3 */ 376 406 … … 681 711 #ifdef IN_RING3 682 712 713 static int ps2kR3HidToInternalCode(uint32_t u32HidCode, key_def const **ppKeyDef) 714 { 715 uint8_t u8HidPage; 716 uint16_t u16HidUsage; 717 int iKeyIndex = -1; 718 key_def const *pKeyDef = &aPS2Keys[0]; /* Dummy no-event key. */; 719 720 u8HidPage = RT_LOBYTE(RT_HIWORD(u32HidCode)); 721 u16HidUsage = RT_LOWORD(u32HidCode); 722 723 if (u8HidPage == USB_HID_KB_PAGE) 724 { 725 if (u16HidUsage <= VBOX_USB_MAX_USAGE_CODE) 726 { 727 iKeyIndex = u16HidUsage; /* Direct mapping. */ 728 pKeyDef = iKeyIndex >= HID_MODIFIER_FIRST ? &aPS2ModKeys[iKeyIndex - HID_MODIFIER_FIRST] : &aPS2Keys[iKeyIndex]; 729 } 730 else 731 AssertMsgFailed(("u16HidUsage out of range! (%04X)\n", u16HidUsage)); 732 } 733 else if (u8HidPage == USB_HID_CC_PAGE) 734 { 735 for (int i = 0; i < RT_ELEMENTS(aPS2CCKeys); ++i) 736 if (aPS2CCKeys[i].usageId == u16HidUsage) 737 { 738 pKeyDef = &aPS2CCKeys[i].kdef; 739 iKeyIndex = PS2K_PAGE_CC_START + i; 740 break; 741 } 742 AssertMsg(iKeyIndex > -1, ("Unsupported code in USB_HID_CC_PAGE! (%04X)\n", u16HidUsage)); 743 } 744 else if (u8HidPage == USB_HID_DC_PAGE) 745 { 746 for (int i = 0; i < RT_ELEMENTS(aPS2DCKeys); ++i) 747 if (aPS2CCKeys[i].usageId == u16HidUsage) 748 { 749 pKeyDef = &aPS2DCKeys[i].kdef; 750 iKeyIndex = PS2K_PAGE_DC_START + i; 751 break; 752 } 753 AssertMsg(iKeyIndex > -1, ("Unsupported code in USB_HID_DC_PAGE! (%04X)\n", u16HidUsage)); 754 } 755 else 756 { 757 AssertMsgFailed(("Unsupported u8HidPage! (%02X)\n", u8HidPage)); 758 } 759 760 if (ppKeyDef) 761 *ppKeyDef = pKeyDef; 762 763 return iKeyIndex; 764 } 765 766 static uint32_t ps2kR3InternalCodeToHid(int iKeyCode) 767 { 768 uint16_t u16HidUsage; 769 uint32_t u32HidCode = 0; 770 771 if ((iKeyCode >= PS2K_PAGE_DC_START) && (iKeyCode <= PS2K_PAGE_DC_END)) 772 { 773 u16HidUsage = aPS2DCKeys[iKeyCode - PS2K_PAGE_DC_START].usageId; 774 u32HidCode = RT_MAKE_U32(u16HidUsage, USB_HID_DC_PAGE); 775 } 776 else if ((iKeyCode >= PS2K_PAGE_CC_START) && (iKeyCode <= PS2K_PAGE_CC_END)) 777 { 778 u16HidUsage = aPS2CCKeys[iKeyCode - PS2K_PAGE_CC_START].usageId; 779 u32HidCode = RT_MAKE_U32(u16HidUsage, USB_HID_CC_PAGE); 780 } 781 else /* Must be the keyboard usage page. */ 782 { 783 if (iKeyCode <= VBOX_USB_MAX_USAGE_CODE) 784 u32HidCode = RT_MAKE_U32(iKeyCode, USB_HID_KB_PAGE); 785 else 786 AssertMsgFailed(("iKeyCode out of range! (%d)\n", iKeyCode)); 787 } 788 789 return u32HidCode; 790 } 791 683 792 static int ps2kR3ProcessKeyEvent(PPDMDEVINS pDevIns, PPS2K pThis, uint32_t u32HidCode, bool fKeyDown) 684 793 { … … 689 798 uint8_t abScan[2]; 690 799 uint8_t u8HidPage; 691 uint8_t u8HidCode;692 800 uint16_t u16HidUsage; 693 801 694 802 u8HidPage = RT_LOBYTE(RT_HIWORD(u32HidCode)); 695 803 u16HidUsage = RT_LOWORD(u32HidCode); 696 /* For the keyboard usage page (7) we use a 8-bit code. For other pages we use the full 16-bit ID. */697 u8HidCode = (u8HidPage == USB_HID_KB_PAGE) ? RT_LOBYTE(u32HidCode) : 0;698 804 699 805 LogFlowFunc(("key %s: page 0x%02x ID 0x%04x (set %d)\n", fKeyDown ? "down" : "up", u8HidPage, u16HidUsage, pThis->u8ScanSet)); 700 806 701 /* Find the key definition in somewhat sparse storage. */ 702 if (u8HidPage == USB_HID_KB_PAGE) 703 /* For the standard keyboard usage page, thre are just two arrays. */ 704 pKeyDef = u8HidCode >= HID_MODIFIER_FIRST ? &aPS2ModKeys[u8HidCode - HID_MODIFIER_FIRST] : &aPS2Keys[u8HidCode]; 705 else if (u8HidPage == USB_HID_CC_PAGE) 706 { 707 /* For the consumer control usage page, we need to search. */ 708 unsigned i; 709 710 pKeyDef = &aPS2Keys[0]; /* Dummy no-event key. */ 711 for (i = 0; i < RT_ELEMENTS(aPS2CCKeys); ++i) 712 { 713 if (aPS2CCKeys[i].usageId == u16HidUsage) 714 { 715 pKeyDef = &aPS2CCKeys[i].kdef; 716 break; 717 } 718 } 719 } 720 else 721 { 722 LogFlow(("Unsupported HID usage page, ignoring key.\n")); 723 return VINF_SUCCESS; 724 } 807 ps2kR3HidToInternalCode(u32HidCode, &pKeyDef); 725 808 726 809 /* Some keys are not processed at all; early return. */ … … 734 817 * of their state in addition to sending the scan code. 735 818 */ 736 if (u8HidCode >= HID_MODIFIER_FIRST) 737 { 738 unsigned mod_bit = 1 << (u8HidCode - HID_MODIFIER_FIRST); 739 740 Assert((u8HidPage == USB_HID_KB_PAGE)); 741 Assert((u8HidCode <= HID_MODIFIER_LAST)); 819 if ((u8HidPage == USB_HID_KB_PAGE) && (u16HidUsage >= HID_MODIFIER_FIRST)) 820 { 821 unsigned mod_bit = 1 << (u16HidUsage - HID_MODIFIER_FIRST); 822 823 Assert((u16HidUsage <= HID_MODIFIER_LAST)); 742 824 if (fKeyDown) 743 825 pThis->u8Modifiers |= mod_bit; … … 1038 1120 LogFlowFunc(("Releasing keys...\n")); 1039 1121 1040 for ( unsigned uKey = 0; uKey < sizeof(pThis->abDepressedKeys); ++uKey)1041 if (pThis->abDepressedKeys[ uKey])1122 for (int iKey = 0; iKey < sizeof(pThis->abDepressedKeys); ++iKey) 1123 if (pThis->abDepressedKeys[iKey]) 1042 1124 { 1043 ps2kR3ProcessKeyEvent(pDevIns, pThis, RT_MAKE_U32(USB_HID_KB_PAGE, uKey), false /* key up */);1044 pThis->abDepressedKeys[ uKey] = 0;1125 ps2kR3ProcessKeyEvent(pDevIns, pThis, ps2kR3InternalCodeToHid(iKey), false /* key up */); 1126 pThis->abDepressedKeys[iKey] = 0; 1045 1127 } 1046 1128 LogFlowFunc(("Done releasing keys\n")); … … 1092 1174 { 1093 1175 uint32_t u32HidCode; 1094 uint8_t u8KeyCode;1095 uint8_t u8HidPage;1096 1176 bool fKeyDown; 1097 1177 bool fHaveEvent = true; 1178 int iKeyCode; 1098 1179 int rc = VINF_SUCCESS; 1099 1180 1100 1181 /* Extract the usage page and ID and ensure it's valid. */ 1101 fKeyDown = !(idUsage & UINT32_C(0x80000000));1182 fKeyDown = !(idUsage & PDMIKBDPORT_KEY_UP); 1102 1183 u32HidCode = idUsage & 0xFFFFFF; 1103 u8HidPage = RT_LOBYTE(RT_HIWORD(idUsage)); 1104 u8KeyCode = RT_LOBYTE(idUsage); 1105 if (u8HidPage == USB_HID_KB_PAGE) 1106 AssertReturn(u8KeyCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 1107 else 1108 AssertReturn(u8HidPage == USB_HID_CC_PAGE, VERR_INTERNAL_ERROR); 1184 1185 iKeyCode = ps2kR3HidToInternalCode(u32HidCode, NULL); 1186 AssertReturn(iKeyCode > 0 && iKeyCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 1109 1187 1110 1188 if (fKeyDown) … … 1112 1190 /* Due to host key repeat, we can get key events for keys which are 1113 1191 * already depressed. We need to ignore those. */ 1114 if (pThis->abDepressedKeys[ u8KeyCode])1192 if (pThis->abDepressedKeys[iKeyCode]) 1115 1193 fHaveEvent = false; 1116 pThis->abDepressedKeys[ u8KeyCode] = 1;1194 pThis->abDepressedKeys[iKeyCode] = 1; 1117 1195 } 1118 1196 else … … 1121 1199 * That is unlikely to happen and should not cause trouble. 1122 1200 */ 1123 pThis->abDepressedKeys[ u8KeyCode] = 0;1201 pThis->abDepressedKeys[iKeyCode] = 0; 1124 1202 } 1125 1203 … … 1153 1231 * key is allowed to use this scancode. 1154 1232 */ 1155 if (RT_LIKELY( idUsage != KRSP_BAT_FAIL))1233 if (RT_LIKELY(!(idUsage & PDMIKBDPORT_RELEASE_KEYS))) 1156 1234 ps2kR3PutEventWorker(pDevIns, pThis, idUsage); 1157 1235 else … … 1291 1369 pHlp->pfnSSMGetU8(pSSM, &u8); 1292 1370 /* Reconstruct the 32-bit code from the 8-bit value in saved state. */ 1293 pThis->u32TypematicKey = u8 ? RT_MAKE_U32(USB_HID_KB_PAGE,u8) : 0;1371 pThis->u32TypematicKey = u8 ? ps2kR3InternalCodeToHid(u8) : 0; 1294 1372 pHlp->pfnSSMGetU8(pSSM, &pThis->u8Modifiers); 1295 1373 pHlp->pfnSSMGetU8(pSSM, &pThis->u8ScanSet); -
trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
r89831 r89935 32 32 *********************************************************************************************************************************/ 33 33 /** Keyboard usage page bits to be OR-ed into the code. */ 34 #define HID_PG_KB_BITS 0x070000 35 34 #define HID_PG_KB_BITS RT_MAKE_U32(0, USB_HID_KB_PAGE) 36 35 37 36 /********************************************************************************************************************************* … … 152 151 153 152 /* Isolate the scan code and key break flag. */ 154 keyUp = (scanCode & 0x80) << 24;153 keyUp = (scanCode & 0x80) ? PDMIKBDPORT_KEY_UP : 0; 155 154 156 155 switch (state) { … … 237 236 * key up into a key up/key down sequence. 238 237 */ 239 if (idUsage == UINT32_C( 0x80000090) || idUsage == UINT32_C(0x80000091))238 if (idUsage == UINT32_C(PDMIKBDPORT_KEY_UP | 0x90) || idUsage == UINT32_C(PDMIKBDPORT_KEY_UP & 0x91)) 240 239 { 241 240 PDRVKBDQUEUEITEM pItem2 = (PDRVKBDQUEUEITEM)PDMQueueAlloc(pDrv->pQueue); … … 247 246 { 248 247 /* Manufacture a key down event. */ 249 pItem2->idUsage = idUsage & ~ UINT32_C(0x80000000);248 pItem2->idUsage = idUsage & ~PDMIKBDPORT_KEY_UP; 250 249 PDMQueueInsert(pDrv->pQueue, &pItem2->Core); 251 250 } … … 289 288 if (!pDrv->fSuspended) 290 289 AssertMsgFailed(("drvKbdQueuePutEventHid: Queue is full!!!!\n")); 290 return VERR_PDM_NO_QUEUE_ITEMS; 291 } 292 293 294 /** 295 * @interface_method_impl{PDMIKEYBOARDPORT,pfnReleaseKeys} 296 * 297 * Because of the event queueing the EMT context requirement is lifted. 298 * @thread Any thread. 299 */ 300 static DECLCALLBACK(int) drvKbdQueueReleaseKeys(PPDMIKEYBOARDPORT pInterface) 301 { 302 PDRVKBDQUEUE pDrv = IKEYBOARDPORT_2_DRVKBDQUEUE(pInterface); 303 304 /* Ignore any attempt to send events if queue is inactive. */ 305 if (pDrv->fInactive) 306 return VINF_SUCCESS; 307 308 PDRVKBDQUEUEITEM pItem = (PDRVKBDQUEUEITEM)PDMQueueAlloc(pDrv->pQueue); 309 if (pItem) 310 { 311 /* Send a special key event that forces all keys to be released. 312 * Goes through the queue so that it would take effect only after 313 * any key events that might already be queued up. 314 */ 315 pItem->idUsage = PDMIKBDPORT_RELEASE_KEYS | HID_PG_KB_BITS; 316 PDMQueueInsert(pDrv->pQueue, &pItem->Core); 317 318 return VINF_SUCCESS; 319 } 320 if (!pDrv->fSuspended) 321 AssertMsgFailed(("drvKbdQueueReleaseKeys: Queue is full!!!!\n")); 291 322 return VERR_PDM_NO_QUEUE_ITEMS; 292 323 } … … 457 488 pDrv->IPort.pfnPutEventScan = drvKbdQueuePutEventScan; 458 489 pDrv->IPort.pfnPutEventHid = drvKbdQueuePutEventHid; 490 pDrv->IPort.pfnReleaseKeys = drvKbdQueueReleaseKeys; 459 491 460 492 /* -
trunk/src/VBox/Devices/Input/UsbKbd.cpp
r82968 r89935 381 381 382 382 383 /** 384 * Conversion table for consumer control keys (HID Usage Page 12). 385 * Used to 'compress' the USB HID usage code into a single 8-bit 386 * value. See also PS2CCKeys in the PS/2 keyboard emulation. 387 */ 388 static const uint16_t aHidCCKeys[] = { 389 0x00B5, /* Scan Next Track */ 390 0x00B6, /* Scan Previous Track */ 391 0x00B7, /* Stop */ 392 0x00CD, /* Play/Pause */ 393 0x00E2, /* Mute */ 394 0x00E5, /* Bass Boost */ 395 0x00E7, /* Loudness */ 396 0x00E9, /* Volume Up */ 397 0x00EA, /* Volume Down */ 398 0x0152, /* Bass Up */ 399 0x0153, /* Bass Down */ 400 0x0154, /* Treble Up */ 401 0x0155, /* Treble Down */ 402 0x0183, /* Media Select */ 403 0x018A, /* Mail */ 404 0x0192, /* Calculator */ 405 0x0194, /* My Computer */ 406 0x0221, /* WWW Search */ 407 0x0223, /* WWW Home */ 408 0x0224, /* WWW Back */ 409 0x0225, /* WWW Forward */ 410 0x0226, /* WWW Stop */ 411 0x0227, /* WWW Refresh */ 412 0x022A, /* WWW Favorites */ 413 }; 414 415 /** 416 * Conversion table for generic desktop control keys (HID Usage Page 1). 417 * Used to 'compress' the USB HID usage code into a single 8-bit 418 * value. See also PS2DCKeys in the PS/2 keyboard emulation. 419 */ 420 static const uint16_t aHidDCKeys[] = { 421 0x81, /* System Power */ 422 0x82, /* System Sleep */ 423 0x83, /* System Wake */ 424 }; 425 426 #define USBHID_PAGE_DC_START 0xb0 427 #define USBHID_PAGE_DC_END (USBHID_PAGE_DC_START + RT_ELEMENTS(aHidDCKeys)) 428 #define USBHID_PAGE_CC_START 0xc0 429 #define USBHID_PAGE_CC_END (USBHID_PAGE_CC_START + RT_ELEMENTS(aHidCCKeys)) 430 431 AssertCompile(RT_ELEMENTS(aHidCCKeys) <= 0x20); /* Must fit between 0xC0-0xDF. */ 432 AssertCompile(RT_ELEMENTS(aHidDCKeys) <= 0x10); /* Must fit between 0xB0-0xBF. */ 433 434 383 435 /********************************************************************************************************************************* 384 436 * Internal Functions * 385 437 *********************************************************************************************************************************/ 438 439 440 /** 441 * Converts a 32-bit USB HID code to an internal 8-bit value. 442 * 443 * @returns 8-bit internal key code/index. -1 if not found. 444 * @param u32HidCode 32-bit USB HID code. 445 */ 446 static int usbHidToInternalCode(uint32_t u32HidCode) 447 { 448 uint8_t u8HidPage; 449 uint16_t u16HidUsage; 450 int iKeyIndex = -1; 451 452 u8HidPage = RT_LOBYTE(RT_HIWORD(u32HidCode)); 453 u16HidUsage = RT_LOWORD(u32HidCode); 454 455 if (u8HidPage == USB_HID_KB_PAGE) 456 { 457 if (u16HidUsage <= VBOX_USB_MAX_USAGE_CODE) 458 iKeyIndex = u16HidUsage; /* Direct mapping. */ 459 else 460 AssertMsgFailed(("u16HidUsage out of range! (%04X)\n", u16HidUsage)); 461 } 462 else if (u8HidPage == USB_HID_CC_PAGE) 463 { 464 for (int i = 0; i < RT_ELEMENTS(aHidCCKeys); ++i) 465 if (aHidCCKeys[i] == u16HidUsage) 466 { 467 iKeyIndex = USBHID_PAGE_CC_START + i; 468 break; 469 } 470 AssertMsg(iKeyIndex > -1, ("Unsupported code in USB_HID_CC_PAGE! (%04X)\n", u16HidUsage)); 471 } 472 else if (u8HidPage == USB_HID_DC_PAGE) 473 { 474 for (int i = 0; i < RT_ELEMENTS(aHidDCKeys); ++i) 475 if (aHidCCKeys[i] == u16HidUsage) 476 { 477 iKeyIndex = USBHID_PAGE_DC_START + i; 478 break; 479 } 480 AssertMsg(iKeyIndex > -1, ("Unsupported code in USB_HID_DC_PAGE! (%04X)\n", u16HidUsage)); 481 } 482 else 483 { 484 AssertMsgFailed(("Unsupported u8HidPage! (%02X)\n", u8HidPage)); 485 } 486 487 /** @todo: We can currently only report the standard HID keyboard page.*/ 488 if (u8HidPage != USB_HID_KB_PAGE) 489 return -1; 490 491 return iKeyIndex; 492 } 493 494 495 /** 496 * Converts an internal 8-bit key index back to a 32-bit USB HID code. 497 * 498 * @returns 32-bit USB HID code. Zero if not found. 499 * @param u32HidCode 32-bit USB HID code. 500 */ 501 static uint32_t usbInternalCodeToHid(int iKeyCode) 502 { 503 uint16_t u16HidUsage; 504 uint32_t u32HidCode = 0; 505 506 if ((iKeyCode >= USBHID_PAGE_DC_START) && (iKeyCode <= USBHID_PAGE_DC_END)) 507 { 508 u16HidUsage = aHidDCKeys[iKeyCode - USBHID_PAGE_DC_START]; 509 u32HidCode = RT_MAKE_U32(u16HidUsage, USB_HID_DC_PAGE); 510 } 511 else if ((iKeyCode >= USBHID_PAGE_CC_START) && (iKeyCode <= USBHID_PAGE_CC_END)) 512 { 513 u16HidUsage = aHidCCKeys[iKeyCode - USBHID_PAGE_CC_START]; 514 u32HidCode = RT_MAKE_U32(u16HidUsage, USB_HID_CC_PAGE); 515 } 516 else /* Must be the keyboard usage page. */ 517 { 518 if (iKeyCode <= VBOX_USB_MAX_USAGE_CODE) 519 u32HidCode = RT_MAKE_U32(iKeyCode, USB_HID_KB_PAGE); 520 else 521 AssertMsgFailed(("iKeyCode out of range! (%d)\n", iKeyCode)); 522 } 523 524 return u32HidCode; 525 } 386 526 387 527 … … 629 769 else 630 770 { 631 pReport->aKeys[iBuf] = iKey; 632 ++iBuf; 771 /* Key index back to 32-bit HID code. */ 772 uint32_t u32HidCode = usbInternalCodeToHid(iKey); 773 uint8_t u8HidPage = RT_LOBYTE(RT_HIWORD(u32HidCode)); 774 uint8_t u16HidUsage = RT_LOWORD(u32HidCode); 775 776 if (u8HidPage == USB_HID_KB_PAGE) 777 { 778 pReport->aKeys[iBuf] = (uint8_t)u16HidUsage; 779 ++iBuf; 780 } 633 781 } 634 782 } … … 696 844 } 697 845 698 /* See the PS2K device. */699 #define KRSP_BAT_FAIL 0xFC /* Also a 'release keys' signal. */700 701 846 /** 702 847 * @interface_method_impl{PDMIKEYBOARDPORT,pfnPutEventHid} … … 705 850 { 706 851 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 707 uint8_t u8HidCode;708 852 bool fKeyDown; 709 853 bool fHaveEvent = true; 710 854 int rc = VINF_SUCCESS; 855 int iKeyCode; 711 856 712 857 /* Let's see what we got... */ 713 fKeyDown = !(idUsage & UINT32_C(0x80000000)); 714 u8HidCode = idUsage & 0xFF; 715 AssertReturn(u8HidCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 858 fKeyDown = !(idUsage & PDMIKBDPORT_KEY_UP); 859 860 iKeyCode = usbHidToInternalCode(idUsage); 861 AssertReturn(iKeyCode > 0 && iKeyCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 716 862 717 863 RTCritSectEnter(&pThis->CritSect); 718 864 719 LogFlowFunc(("key %s: 0x%x\n", fKeyDown ? "down" : "up", u8HidCode));865 LogFlowFunc(("key %s: %08X (iKeyCode 0x%x)\n", fKeyDown ? "down" : "up", idUsage, iKeyCode)); 720 866 721 867 /* … … 723 869 * already depressed. Drop those right here. 724 870 */ 725 if (fKeyDown && pThis->abDepressedKeys[ u8HidCode])871 if (fKeyDown && pThis->abDepressedKeys[iKeyCode]) 726 872 fHaveEvent = false; 727 873 … … 733 879 else if (fHaveEvent) 734 880 { 735 if (RT_LIKELY( idUsage != KRSP_BAT_FAIL))881 if (RT_LIKELY(!(idUsage & PDMIKBDPORT_RELEASE_KEYS))) 736 882 { 737 883 /* Regular key event - update keyboard state. */ 738 884 if (fKeyDown) 739 pThis->abDepressedKeys[ u8HidCode] = 1;885 pThis->abDepressedKeys[iKeyCode] = 1; 740 886 else 741 pThis->abDepressedKeys[ u8HidCode] = 0;887 pThis->abDepressedKeys[iKeyCode] = 0; 742 888 } 743 889 else -
trunk/src/VBox/Main/src-client/KeyboardImpl.cpp
r85300 r89935 296 296 HRESULT Keyboard::releaseKeys() 297 297 { 298 std::vector<LONG> scancodes; 299 scancodes.resize(1); 300 scancodes[0] = 0xFC; /* Magic scancode, see PS/2 and USB keyboard devices. */ 301 return putScancodes(scancodes, NULL); 298 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 299 300 /* Release all keys on the active keyboard in order to start with a clean slate. 301 * Note that this should mirror the logic in Keyboard::putScancodes() when choosing 302 * which keyboard to send the release event to. 303 */ 304 PPDMIKEYBOARDPORT pUpPort = NULL; 305 for (int i = KEYBOARD_MAX_DEVICES - 1; i >= 0 ; --i) 306 { 307 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & KEYBOARD_DEVCAP_ENABLED)) 308 { 309 pUpPort = mpDrv[i]->pUpPort; 310 break; 311 } 312 } 313 314 if (pUpPort) 315 { 316 int rc = pUpPort->pfnReleaseKeys(pUpPort); 317 if (RT_FAILURE(rc)) 318 AssertMsgFailed(("Failed to release keys on all keyboards! rc=%Rrc\n", rc)); 319 } 320 321 return S_OK; 302 322 } 303 323 … … 352 372 { 353 373 PDRVMAINKEYBOARD pDrv = RT_FROM_MEMBER(pInterface, DRVMAINKEYBOARD, IConnector); 374 375 // Before activating a different keyboard, release all keys on the currently active one. 376 if (fActive) 377 pDrv->pKeyboard->releaseKeys(); 378 354 379 if (fActive) 355 380 pDrv->u32DevCaps |= KEYBOARD_DEVCAP_ENABLED;
Note:
See TracChangeset
for help on using the changeset viewer.