Changeset 81214 in vbox
- Timestamp:
- Oct 10, 2019 1:20:41 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 133878
- Location:
- trunk/src/VBox/Devices/Input
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
r79675 r81214 27 27 #include "VBoxDD.h" 28 28 29 30 /********************************************************************************************************************************* 31 * Defined Constants And Macros * 32 *********************************************************************************************************************************/ 33 /** Keyboard usage page bits to be OR-ed into the code. */ 34 #define HID_PG_KB_BITS 0x070000 29 35 30 36 … … 156 162 } else { 157 163 usage = aScancode2Hid[scanCode & 0x7F]; 158 *pUsage = usage | keyUp ;164 *pUsage = usage | keyUp | HID_PG_KB_BITS; 159 165 /* Remain in SS_IDLE state. */ 160 166 } … … 162 168 case SS_EXT: 163 169 usage = aExtScan2Hid[scanCode & 0x7F]; 164 *pUsage = usage | keyUp ;170 *pUsage = usage | keyUp | HID_PG_KB_BITS; 165 171 state = SS_IDLE; 166 172 break; … … 170 176 */ 171 177 if ((scanCode & 0x7F) == 0x45) { 172 *pUsage = 0x48 ;178 *pUsage = 0x48 | HID_PG_KB_BITS; 173 179 if (scanCode == 0xC5) 174 180 *pUsage |= keyUp; -
trunk/src/VBox/Devices/Input/PS2K.cpp
r76553 r81214 98 98 /** The size of an array needed to store all USB usage codes */ 99 99 #define VBOX_USB_USAGE_ARRAY_SIZE (VBOX_USB_MAX_USAGE_CODE + 1) 100 /** USB HID Keyboard Usage Page. */ 101 #define USB_HID_KB_PAGE 7 102 /** USB HID Consumer Control Usage Page. */ 103 #define USB_HID_CC_PAGE 12 100 104 /** @} */ 101 105 … … 158 162 { 159 163 /** Pointer to parent device (keyboard controller). */ 160 R3PTRTYPE(void *) 164 R3PTRTYPE(void *) pParent; 161 165 /** Set if keyboard is enabled ('scans' for input). */ 162 166 bool fScanning; … … 174 178 uint8_t u8TypematicCfg; 175 179 /** Usage code of current typematic key, if any. */ 176 uint 8_t u8TypematicKey;180 uint32_t u32TypematicKey; 177 181 /** Current typematic repeat state. */ 178 182 tmatic_state_t enmTypematicState; … … 277 281 *********************************************************************************************************************************/ 278 282 #ifdef IN_RING3 279 /* USB to PS/2 conversion table for regular keys . */283 /* USB to PS/2 conversion table for regular keys (HID Usage Page 7). */ 280 284 static const key_def aPS2Keys[] = { 281 285 /* 00 */ {NONE, NONE, NONE, KF_NB, T_U }, /* Key N/A: No Event */ … … 459 463 */ 460 464 461 /* USB to PS/2 conversion table for modifier keys . */465 /* USB to PS/2 conversion table for modifier keys (HID Usage Page 7). */ 462 466 static const key_def aPS2ModKeys[] = { 463 467 /* E0 */ {0x1D, 0x14, 0x11, 0, T_B }, /* Key 58: Left Control */ … … 471 475 }; 472 476 477 /* Extended key definition for sparse mapping. */ 478 typedef struct { 479 uint16_t usageId; 480 key_def kdef; 481 } ext_key_def; 482 483 484 /* USB to PS/2 conversion table for consumer control keys (HID Usage Page 12). */ 485 /* This usage page is very sparse so we'll just search through it. */ 486 static const ext_key_def aPS2CCKeys[] = { 487 0x00B5, {0x19, 0x4D, UNKN, KF_E0, T_U }, /* Scan Next Track */ 488 0x00B6, {0x10, 0x15, UNKN, KF_E0, T_U }, /* Scan Previous Track */ 489 0x00B7, {0x24, 0x3B, UNKN, KF_E0, T_U }, /* Stop */ 490 0x00CD, {0x22, 0x34, UNKN, KF_E0, T_U }, /* Play/Pause */ 491 0x00E2, {0x20, 0x23, UNKN, KF_E0, T_U }, /* Mute */ 492 0x00E5, {UNAS, UNAS, UNAS, 0, T_U }, /* Bass Boost */ 493 0x00E7, {UNAS, UNAS, UNAS, 0, T_U }, /* Loudness */ 494 0x00E9, {0x30, 0x32, UNKN, KF_E0, T_U }, /* Volume Up */ 495 0x00EA, {0x2E, 0x21, UNKN, KF_E0, T_U }, /* Volume Down */ 496 0x0152, {UNAS, UNAS, UNAS, 0, T_U }, /* Bass Up */ 497 0x0153, {UNAS, UNAS, UNAS, 0, T_U }, /* Bass Down */ 498 0x0154, {UNAS, UNAS, UNAS, 0, T_U }, /* Treble Up */ 499 0x0155, {UNAS, UNAS, UNAS, 0, T_U }, /* Treble Down */ 500 0x0183, {0x6D, 0x50, UNKN, KF_E0, T_U }, /* Media Select */ 501 0x018A, {0x6C, 0x48, UNKN, KF_E0, T_U }, /* Mail */ 502 0x0192, {0x21, 0x2B, UNKN, KF_E0, T_U }, /* Calculator */ 503 0x0194, {0x6B, 0x40, UNKN, KF_E0, T_U }, /* My Computer */ 504 0x0221, {0x65, 0x10, UNKN, KF_E0, T_U }, /* WWW Search */ 505 0x0223, {0x32, 0x3A, UNKN, KF_E0, T_U }, /* WWW Home */ 506 0x0224, {0x6A, 0x38, UNKN, KF_E0, T_U }, /* WWW Back */ 507 0x0225, {0x69, 0x30, UNKN, KF_E0, T_U }, /* WWW Forward */ 508 0x0226, {0x68, 0x28, UNKN, KF_E0, T_U }, /* WWW Stop */ 509 0x0227, {0x67, 0x20, UNKN, KF_E0, T_U }, /* WWW Refresh */ 510 0x022A, {0x66, 0x18, UNKN, KF_E0, T_U }, /* WWW Favorites */ 511 }; 512 473 513 #endif /* IN_RING3 */ 474 514 … … 661 701 static void ps2kStopTypematicRepeat(PPS2K pThis) 662 702 { 663 if (pThis->u 8TypematicKey)664 { 665 LogFunc(("Typematic key %0 2X\n", pThis->u8TypematicKey));703 if (pThis->u32TypematicKey) 704 { 705 LogFunc(("Typematic key %08X\n", pThis->u32TypematicKey)); 666 706 pThis->enmTypematicState = KBD_TMS_IDLE; 667 pThis->u 8TypematicKey = 0;707 pThis->u32TypematicKey = 0; 668 708 TMTimerStop(pThis->CTX_SUFF(pKbdTypematicTimer)); 669 709 } … … 866 906 #ifdef IN_RING3 867 907 868 static int ps2kProcessKeyEvent(PPS2K pThis, uint 8_t u8HidCode, bool fKeyDown)908 static int ps2kProcessKeyEvent(PPS2K pThis, uint32_t u32HidCode, bool fKeyDown) 869 909 { 870 910 key_def const *pKeyDef; … … 873 913 size_t cbLeft; 874 914 uint8_t abScan[2]; 875 876 LogFlowFunc(("key %s: 0x%02x (set %d)\n", fKeyDown ? "down" : "up", u8HidCode, pThis->u8ScanSet)); 915 uint8_t u8HidPage; 916 uint8_t u8HidCode; 917 uint16_t u16HidUsage; 918 919 u8HidPage = RT_LOBYTE(RT_HIWORD(u32HidCode)); 920 u16HidUsage = RT_LOWORD(u32HidCode); 921 /* For the keyboard usage page (7) we use a 8-bit code. For other pages we use the full 16-bit ID. */ 922 u8HidCode = (u8HidPage == USB_HID_KB_PAGE) ? RT_LOBYTE(u32HidCode) : 0; 923 924 LogFlowFunc(("key %s: page 0x%02x ID 0x%04x (set %d)\n", fKeyDown ? "down" : "up", u8HidPage, u16HidUsage, pThis->u8ScanSet)); 877 925 878 926 /* Find the key definition in somewhat sparse storage. */ 879 pKeyDef = u8HidCode >= HID_MODIFIER_FIRST ? &aPS2ModKeys[u8HidCode - HID_MODIFIER_FIRST] : &aPS2Keys[u8HidCode]; 927 if (u8HidPage == USB_HID_KB_PAGE) 928 /* For the standard keyboard usage page, thre are just two arrays. */ 929 pKeyDef = u8HidCode >= HID_MODIFIER_FIRST ? &aPS2ModKeys[u8HidCode - HID_MODIFIER_FIRST] : &aPS2Keys[u8HidCode]; 930 else if (u8HidPage == USB_HID_CC_PAGE) 931 { 932 /* For the consumer control usage page, we need to search. */ 933 int i; 934 935 pKeyDef = &aPS2Keys[0]; /* Dummy no-event key. */ 936 for (i = 0; i < RT_ELEMENTS(aPS2CCKeys); ++i) 937 { 938 if (aPS2CCKeys[i].usageId == u16HidUsage) 939 { 940 pKeyDef = &aPS2CCKeys[i].kdef; 941 break; 942 } 943 } 944 } 945 else 946 { 947 LogFlow(("Unsupported HID usage page, ignoring key.\n")); 948 return VINF_SUCCESS; 949 } 880 950 881 951 /* Some keys are not processed at all; early return. */ … … 893 963 unsigned mod_bit = 1 << (u8HidCode - HID_MODIFIER_FIRST); 894 964 965 Assert((u8HidPage == USB_HID_KB_PAGE)); 895 966 Assert((u8HidCode <= HID_MODIFIER_LAST)); 896 967 if (fKeyDown) … … 1060 1131 } 1061 1132 1062 /* Set up or cancel typematic key repeat. */1063 if ( fKeyDown)1064 { 1065 if ( pThis->u8TypematicKey != u8HidCode)1133 /* Set up or cancel typematic key repeat. For keyboard usage page only. */ 1134 if (u8HidPage == USB_HID_KB_PAGE) 1135 { 1136 if (fKeyDown) 1066 1137 { 1067 pThis->enmTypematicState = KBD_TMS_DELAY; 1068 pThis->u8TypematicKey = u8HidCode; 1069 TMTimerSetMillies(pThis->CTX_SUFF(pKbdTypematicTimer), pThis->uTypematicDelay); 1070 Log(("Typematic delay %u ms, key %02X\n", pThis->uTypematicDelay, u8HidCode)); 1138 if (pThis->u32TypematicKey != u32HidCode) 1139 { 1140 pThis->enmTypematicState = KBD_TMS_DELAY; 1141 pThis->u32TypematicKey = u32HidCode; 1142 TMTimerSetMillies(pThis->CTX_SUFF(pKbdTypematicTimer), pThis->uTypematicDelay); 1143 Log(("Typematic delay %u ms, key %08X\n", pThis->uTypematicDelay, u32HidCode)); 1144 } 1071 1145 } 1072 } 1073 else 1074 { 1075 /* "Typematic operation stops when the last key pressed is released, even 1076 * if other keys are still held down." (IBM PS/2 Tech Ref). The last key pressed 1077 * is the one that's being repeated. 1078 */ 1079 if (pThis->u8TypematicKey == u8HidCode) 1146 else 1080 1147 { 1081 /* This disables the typematic repeat. */ 1082 pThis->u8TypematicKey = 0; 1083 pThis->enmTypematicState = KBD_TMS_IDLE; 1084 /* For good measure, we cancel the timer, too. */ 1085 TMTimerStop(pThis->CTX_SUFF(pKbdTypematicTimer)); 1086 Log(("Typematic action cleared for key %02X\n", u8HidCode)); 1148 /* "Typematic operation stops when the last key pressed is released, even 1149 * if other keys are still held down." (IBM PS/2 Tech Ref). The last key pressed 1150 * is the one that's being repeated. 1151 */ 1152 if (pThis->u32TypematicKey == u32HidCode) 1153 { 1154 /* This disables the typematic repeat. */ 1155 pThis->u32TypematicKey = 0; 1156 pThis->enmTypematicState = KBD_TMS_IDLE; 1157 /* For good measure, we cancel the timer, too. */ 1158 TMTimerStop(pThis->CTX_SUFF(pKbdTypematicTimer)); 1159 Log(("Typematic action cleared for key %08X\n", u32HidCode)); 1160 } 1087 1161 } 1088 1162 } … … 1134 1208 RT_NOREF2(pDevIns, pTimer); 1135 1209 PPS2K pThis = (PS2K *)pvUser; 1136 LogFlowFunc(("Typematic state=%d, key %0 2X\n", pThis->enmTypematicState, pThis->u8TypematicKey));1210 LogFlowFunc(("Typematic state=%d, key %08X\n", pThis->enmTypematicState, pThis->u32TypematicKey)); 1137 1211 1138 1212 /* If the current typematic key is zero, the repeat was canceled just when 1139 1213 * the timer was about to run. In that case, do nothing. 1140 1214 */ 1141 if (pThis->u 8TypematicKey)1215 if (pThis->u32TypematicKey) 1142 1216 { 1143 1217 if (pThis->enmTypematicState == KBD_TMS_DELAY) … … 1146 1220 if (pThis->enmTypematicState == KBD_TMS_REPEAT) 1147 1221 { 1148 ps2kProcessKeyEvent(pThis, pThis->u 8TypematicKey, true /* Key down */ );1222 ps2kProcessKeyEvent(pThis, pThis->u32TypematicKey, true /* Key down */ ); 1149 1223 TMTimerSetMillies(pThis->CTX_SUFF(pKbdTypematicTimer), pThis->uTypematicRepeat); 1150 1224 } … … 1183 1257 if (pThis->abDepressedKeys[uKey]) 1184 1258 { 1185 ps2kProcessKeyEvent(pThis, uKey, false /* key up */);1259 ps2kProcessKeyEvent(pThis, RT_MAKE_U32(USB_HID_KB_PAGE, uKey), false /* key up */); 1186 1260 pThis->abDepressedKeys[uKey] = 0; 1187 1261 } … … 1214 1288 pThis->keyQ.cUsed, pThis->keyQ.cSize); 1215 1289 if (pThis->enmTypematicState != KBD_TMS_IDLE) 1216 pHlp->pfnPrintf(pHlp, "Active typematic key %0 2X (%s)\n", pThis->u8TypematicKey,1290 pHlp->pfnPrintf(pHlp, "Active typematic key %08X (%s)\n", pThis->u32TypematicKey, 1217 1291 pThis->enmTypematicState == KBD_TMS_DELAY ? "delay" : "repeat"); 1218 1292 } … … 1244 1318 static int ps2kPutEventWorker(PPS2K pThis, uint32_t u32Usage) 1245 1319 { 1246 uint8_t u8HidCode; 1320 uint32_t u32HidCode; 1321 uint8_t u8KeyCode; 1322 uint8_t u8HidPage; 1247 1323 bool fKeyDown; 1248 1324 bool fHaveEvent = true; 1249 1325 int rc = VINF_SUCCESS; 1250 1326 1251 /* Extract the usage code and ensure it's valid. */ 1252 fKeyDown = !(u32Usage & 0x80000000); 1253 u8HidCode = u32Usage & 0xFF; 1254 AssertReturn(u8HidCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 1327 /* Extract the usage page and ID and ensure it's valid. */ 1328 fKeyDown = !(u32Usage & 0x80000000); 1329 u32HidCode = u32Usage & 0xFFFFFF; 1330 u8HidPage = RT_LOBYTE(RT_HIWORD(u32Usage)); 1331 u8KeyCode = RT_LOBYTE(u32Usage); 1332 if (u8HidPage == USB_HID_KB_PAGE) 1333 AssertReturn(u8KeyCode <= VBOX_USB_MAX_USAGE_CODE, VERR_INTERNAL_ERROR); 1334 else 1335 AssertReturn(u8HidPage == USB_HID_CC_PAGE, VERR_INTERNAL_ERROR); 1255 1336 1256 1337 if (fKeyDown) … … 1258 1339 /* Due to host key repeat, we can get key events for keys which are 1259 1340 * already depressed. We need to ignore those. */ 1260 if (pThis->abDepressedKeys[u8 HidCode])1341 if (pThis->abDepressedKeys[u8KeyCode]) 1261 1342 fHaveEvent = false; 1262 pThis->abDepressedKeys[u8 HidCode] = 1;1343 pThis->abDepressedKeys[u8KeyCode] = 1; 1263 1344 } 1264 1345 else … … 1267 1348 * That is unlikely to happen and should not cause trouble. 1268 1349 */ 1269 pThis->abDepressedKeys[u8 HidCode] = 0;1350 pThis->abDepressedKeys[u8KeyCode] = 0; 1270 1351 } 1271 1352 … … 1276 1357 AssertReleaseRC(rc); 1277 1358 1278 rc = ps2kProcessKeyEvent(pThis, u 8HidCode, fKeyDown);1359 rc = ps2kProcessKeyEvent(pThis, u32HidCode, fKeyDown); 1279 1360 1280 1361 PDMCritSectLeave(pThis->pCritSectR3); … … 1371 1452 SSMR3PutU8(pSSM, pThis->u8LEDs); 1372 1453 SSMR3PutU8(pSSM, pThis->u8TypematicCfg); 1373 SSMR3PutU8(pSSM, pThis->u8TypematicKey);1454 SSMR3PutU8(pSSM, (uint8_t)pThis->u32TypematicKey); 1374 1455 SSMR3PutU8(pSSM, pThis->u8Modifiers); 1375 1456 SSMR3PutU8(pSSM, pThis->u8ScanSet); … … 1419 1500 SSMR3GetU8(pSSM, &pThis->u8LEDs); 1420 1501 SSMR3GetU8(pSSM, &pThis->u8TypematicCfg); 1421 SSMR3GetU8(pSSM, &pThis->u8TypematicKey); 1502 SSMR3GetU8(pSSM, &u8); 1503 /* Reconstruct the 32-bit code from the 8-bit value in saved state. */ 1504 pThis->u32TypematicKey = u8 ? RT_MAKE_U32(USB_HID_KB_PAGE, u8) : 0; 1422 1505 SSMR3GetU8(pSSM, &pThis->u8Modifiers); 1423 1506 SSMR3GetU8(pSSM, &pThis->u8ScanSet); … … 1489 1572 pThis->u8CurrCmd = 0; 1490 1573 pThis->u8Modifiers = 0; 1491 pThis->u 8TypematicKey= 0;1574 pThis->u32TypematicKey = 0; 1492 1575 pThis->enmTypematicState = KBD_TMS_IDLE; 1493 1576
Note:
See TracChangeset
for help on using the changeset viewer.