- Timestamp:
- Aug 1, 2007 6:33:03 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/linux/keyboard.c
r3945 r3976 87 87 unsigned long lp2; 88 88 } KEYLP; 89 #endif /* OUTOFWINE not defined */90 91 89 92 90 /* key state table bits: … … 97 95 BYTE key_state_table[256]; 98 96 99 #ifndef OUTOFWINE100 97 static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP 101 98 or a WM_KEYUP message */ … … 103 100 104 101 static int min_keycode, max_keycode, keysyms_per_keycode; 102 103 #ifndef OUTOFWINE 105 104 static WORD keyc2vkey[256], keyc2scan[256]; 106 105 107 106 static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */ 108 107 static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */ 108 #else 109 static WORD keyc2scan[256]; 110 #endif 109 111 110 112 static char KEYBOARD_MapDeadKeysym(KeySym keysym); 111 112 #ifdef OUTOFWINE113 /* Global variable to store the current display pointer which is defined114 * and updated in XKeyboard.cpp.115 * The wine keyboard handler isn't reentrant anyway... */116 Display *dpy_global;117 118 inline static Display *thread_display(void) { return dpy_global; }119 /* @@@AH without this, the event time calculations are all wrong. To fix it,120 * we also gotta supply GetCurrentTime */121 unsigned int X11DRV_server_startticks = 0;122 static WINEKEYBOARDINFO *wineKeyboardInfo = NULL;123 #endif124 113 125 114 /* Keyboard translation tables */ … … 1010 999 for PrtScn key ... GA */ 1011 1000 1001 #ifndef OUTOFWINE 1012 1002 static const WORD nonchar_key_vkey[256] = 1013 1003 { … … 1049 1039 VK_F1, VK_F2, 1050 1040 VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ 1051 VK_F11, VK_F12, VK_LWIN /* VK_F13 */, VK_RWIN /* VK_F14 */, 1052 VK_F15, VK_F16, 0, 0, /* FFC8 */ 1041 VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, 0, 0, /* FFC8 */ 1053 1042 0, 0, 0, 0, 0, 0, 0, 0, /* FFD0 */ 1054 1043 0, 0, 0, 0, 0, 0, 0, 0, /* FFD8 */ … … 1060 1049 0, 0, 0, 0, 0, 0, 0, VK_DELETE /* FFF8 */ 1061 1050 }; 1051 #endif /* OUTOFWINE not defined */ 1062 1052 1063 1053 static const WORD nonchar_key_scan[256] = … … 1096 1086 0x3B, 0x3C, 1097 1087 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */ 1098 0x57, 0x58, 0x 15B, 0x15C, 0x00, 0x00, 0x00, 0x00, /* FFC8 */1088 0x57, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFC8 */ 1099 1089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD0 */ 1100 1090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD8 */ 1101 1091 /* modifier keys */ 1102 1092 0x00, 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0x00, 0x38, /* FFE0 */ 1103 0x138, 0x38, 0x138, 0x 00, 0x00, 0x00, 0x00, 0x00, /* FFE8 */1093 0x138, 0x38, 0x138, 0x15B, 0x15C, 0x00, 0x00, 0x00, /* FFE8 */ 1104 1094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFF0 */ 1105 1095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x153 /* FFF8 */ … … 1146 1136 }; 1147 1137 1138 #ifndef OUTOFWINE 1148 1139 /* Returns the Windows virtual key code associated with the X event <e> */ 1149 1140 /* x11 lock must be held */ … … 1172 1163 } 1173 1164 1174 #ifndef OUTOFWINE1175 1165 static BOOL NumState=FALSE, CapsState=FALSE; 1176 #endif1177 1166 1178 1167 … … 1180 1169 * X11DRV_send_keyboard_input 1181 1170 */ 1182 staticvoid X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,1171 void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time, 1183 1172 DWORD dwExtraInfo, UINT injected_flags ) 1184 1173 { 1185 #ifndef OUTOFWINE1186 1174 UINT message; 1187 1175 KEYLP keylp; … … 1270 1258 } 1271 1259 SERVER_END_REQ; 1272 #else /* OUTOFWINE defined */1273 /* fill out our global structure */1274 wineKeyboardInfo->wVk = wVk;1275 wineKeyboardInfo->wScan = wScan;1276 wineKeyboardInfo->dwFlags = dwFlags;1277 wineKeyboardInfo->time = time;1278 #endif /* OUTOFWINE defined */1279 1260 } 1280 1261 1281 1262 1282 #ifndef OUTOFWINE1283 1263 /********************************************************************** 1284 1264 * KEYBOARD_GenerateMsg … … 1327 1307 } 1328 1308 } 1329 #endif /* OUTOFWINE not defined */1330 1309 1331 1310 /*********************************************************************** … … 1350 1329 } 1351 1330 1352 #ifndef OUTOFWINE1353 1331 /*********************************************************************** 1354 1332 * X11DRV_KeymapNotify … … 1387 1365 KEYBOARD_UpdateOneState( VK_SHIFT, shift, time ); 1388 1366 } 1389 #endif /* OUTOFWINE defined */1390 1367 1391 1368 /*********************************************************************** … … 1394 1371 * Handle a X key event 1395 1372 */ 1396 #ifndef OUTOFWINE1397 1373 void X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) 1398 #else /* OUTOFWINE defined */1399 void X11DRV_KeyEvent(Display *dpy, XEvent *xev, WINEKEYBOARDINFO *wKbInfo)1400 #endif /* OUTOFWINE defined */1401 1374 { 1402 1375 XKeyEvent *event = &xev->xkey; … … 1406 1379 DWORD dwFlags; 1407 1380 int ascii_chars; 1408 #ifndef OUTOFWINE1409 1381 XIC xic = X11DRV_get_ic( hwnd ); 1410 1382 DWORD event_time = EVENT_x11_time_to_win32_time(event->time); 1411 1383 Status status = 0; 1412 #else /* OUTOFWINE defined */1413 Status status = 0;1414 /* @@@AH do we need support for XIM? */1415 XIC xic = 0;1416 /* We don't use this anyway. */1417 DWORD event_time = 0;1418 dpy_global = dpy;1419 /* set our global pointer for the return data structure1420 * and initialize it with zeroes for the case of early return1421 * (this will mean that the event cannot be converted to a scancode) */1422 wineKeyboardInfo = wKbInfo;1423 memset( wineKeyboardInfo, 0, sizeof( wineKeyboardInfo ) );1424 #endif /* OUTOFWINE defined */1425 1384 1426 1385 TRACE_(key)("type %d, window %lx, state 0x%04x, keycode 0x%04x\n", … … 1440 1399 ERR("Buffer Overflow need %i!\n",ascii_chars); 1441 1400 1442 #ifndef OUTOFWINE1443 1401 if (status == XLookupChars) 1444 1402 { … … 1446 1404 return; 1447 1405 } 1448 #endif /* OUTOFWINE not defined */1449 1406 1450 1407 /* If XKB extensions are used, the state mask for AltGr will use the group … … 1485 1442 if (vkey) 1486 1443 { 1487 /** @todo (dmik): 1488 * KEYBOARD_GenerateMsg() does not work property because 1489 * send_keyboard_input() modifies our static WINEKEYBOARDINFO struct 1490 * directly, w/o any buffering. Moreover the purpose of 1491 * KEYBOARD_GenerateMsg() is not completely clear for me; in our case 1492 * it seems to be unnecessary, so disable the code below. */ 1493 #ifndef OUTOFWINE 1494 switch (vkey & 0xff) 1495 { 1496 case VK_NUMLOCK: 1497 KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time ); 1498 break; 1499 case VK_CAPITAL: 1500 TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,key_state_table[vkey]); 1501 KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time ); 1502 TRACE("State after : %#.2x\n",key_state_table[vkey]); 1503 break; 1504 default: 1505 /* Adjust the NUMLOCK state if it has been changed outside wine */ 1506 if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask)) 1507 { 1444 switch (vkey & 0xff) 1445 { 1446 case VK_NUMLOCK: 1447 KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time ); 1448 break; 1449 case VK_CAPITAL: 1450 TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,key_state_table[vkey]); 1451 KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time ); 1452 TRACE("State after : %#.2x\n",key_state_table[vkey]); 1453 break; 1454 default: 1455 /* Adjust the NUMLOCK state if it has been changed outside wine */ 1456 if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask)) 1457 { 1508 1458 TRACE("Adjusting NumLock state.\n"); 1509 1459 KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time ); … … 1511 1461 } 1512 1462 /* Adjust the CAPSLOCK state if it has been changed outside wine */ 1513 1463 if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask)) 1514 1464 { 1515 1465 TRACE("Adjusting Caps Lock state.\n"); … … 1517 1467 KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_time ); 1518 1468 } 1519 /* Not Num nor Caps : end of intermediary states for both. */ 1520 NumState = FALSE; 1521 CapsState = FALSE; 1522 #endif /* OUTOFWINE not defined */ 1469 /* Not Num nor Caps : end of intermediary states for both. */ 1470 NumState = FALSE; 1471 CapsState = FALSE; 1523 1472 1524 1473 bScan = keyc2scan[event->keycode] & 0xFF; … … 1530 1479 1531 1480 X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 ); 1532 #ifndef OUTOFWINE 1533 } 1534 #endif 1481 } 1535 1482 } 1536 1483 } 1484 1485 #else /* OUTOFWINE defined */ 1486 1487 void X11DRV_KeyEvent(Display *dpy, XEvent *xev, WINEKEYBOARDINFO *wKbInfo) 1488 { 1489 XKeyEvent *event = &xev->xkey; 1490 wKbInfo->wScan = keyc2scan[event->keycode] & 0xFF; 1491 wKbInfo->dwFlags = keyc2scan[event->keycode] >> 8; 1492 } 1493 1494 #endif /* OUTOFWINE defined */ 1537 1495 1538 1496 /********************************************************************** … … 1544 1502 * X11 lock must be held. 1545 1503 */ 1504 #ifndef OUTOFWINE 1546 1505 static void 1547 1506 X11DRV_KEYBOARD_DetectLayout (void) 1548 { 1507 #else 1508 static void 1509 X11DRV_KEYBOARD_DetectLayout (Display *display) 1510 #endif 1511 { 1512 #ifndef OUTOFWINE 1549 1513 Display *display = thread_display(); 1514 #endif 1550 1515 unsigned current, match, mismatch, seq, i, syms; 1551 1516 int score, keyc, key, pkey, ok; … … 1654 1619 * X11DRV_InitKeyboard 1655 1620 */ 1621 #ifndef OUTOFWINE 1622 void X11DRV_InitKeyboard(void) 1623 #else 1656 1624 void X11DRV_InitKeyboard(Display *display) 1657 { 1625 #endif 1626 { 1627 #ifndef OUTOFWINE 1628 Display *display = thread_display(); 1658 1629 KeySym *ksp; 1659 1630 XModifierKeymap *mmp; … … 1662 1633 XKeyEvent e2; 1663 1634 WORD scan, vkey, OEMvkey; 1635 #else 1636 KeySym *ksp; 1637 KeySym keysym; 1638 XKeyEvent e2; 1639 WORD scan; 1640 #endif 1664 1641 int keyc, i, keyn, syms; 1665 1642 char ckey[4]={0,0,0,0}; 1666 1643 const char (*lkey)[MAIN_LEN][4]; 1644 #ifndef OUTOFWINE 1667 1645 char vkey_used[256] = { 0 }; 1668 1669 dpy_global = display; 1646 #endif 1647 1670 1648 wine_tsx11_lock(); 1671 1649 XDisplayKeycodes(display, &min_keycode, &max_keycode); … … 1676 1654 XFree(ksp); 1677 1655 1656 #ifndef OUTOFWINE 1678 1657 mmp = XGetModifierMapping(display); 1679 1658 kcp = mmp->modifiermap; … … 1699 1678 /* Detect the keyboard layout */ 1700 1679 X11DRV_KEYBOARD_DetectLayout(); 1680 #else 1681 /* Detect the keyboard layout */ 1682 X11DRV_KEYBOARD_DetectLayout(display); 1683 #endif 1701 1684 lkey = main_key_tab[kbd_layout].key; 1702 1685 syms = (keysyms_per_keycode > 4) ? 4 : keysyms_per_keycode; … … 1709 1692 e2.state = 0; 1710 1693 1694 #ifndef OUTOFWINE 1711 1695 OEMvkey = VK_OEM_8; /* next is available. */ 1712 1696 memset(keyc2vkey, 0, sizeof(keyc2vkey)); 1697 #endif 1713 1698 for (keyc = min_keycode; keyc <= max_keycode; keyc++) 1714 1699 { … … 1719 1704 e2.keycode = (KeyCode)keyc; 1720 1705 have_chars = XLookupString(&e2, buf, sizeof(buf), &keysym, NULL); 1706 #ifndef OUTOFWINE 1721 1707 vkey = 0; scan = 0; 1708 #else 1709 scan = 0; 1710 #endif 1722 1711 if (keysym) /* otherwise, keycode not used */ 1723 1712 { 1724 1713 if ((keysym >> 8) == 0xFF) /* non-character key */ 1725 1714 { 1715 #ifndef OUTOFWINE 1726 1716 vkey = nonchar_key_vkey[keysym & 0xff]; 1717 #endif 1727 1718 scan = nonchar_key_scan[keysym & 0xff]; 1728 1719 /* set extended bit when necessary */ 1720 #ifndef OUTOFWINE 1729 1721 if (scan & 0x100) vkey |= 0x100; 1722 #endif 1730 1723 } else if ((keysym >> 8) == 0x1008FF) { /* XFree86 vendor keys */ 1724 #ifndef OUTOFWINE 1731 1725 vkey = xfree86_vendor_key_vkey[keysym & 0xff]; 1732 1726 /* All vendor keys are extended with a scan code of 0 per testing on WinXP */ 1733 1727 scan = 0x100; 1734 1728 vkey |= 0x100; 1729 #else 1730 /* @michael: this needs to be investigated and improved on. */ 1731 scan = 0x100; 1732 #endif 1735 1733 } else if (keysym == 0x20) { /* Spacebar */ 1734 #ifndef OUTOFWINE 1736 1735 vkey = VK_SPACE; 1736 #endif 1737 1737 scan = 0x39; 1738 #ifdef OUTOFWINE 1739 } else if (keysym == 0xFE03) { /* ISO level3 shift, aka AltGr */ 1740 scan = 0x138; 1741 #endif /* OUTOFWINE defined */ 1738 1742 } else if (have_chars) { 1739 1743 /* we seem to need to search the layout-dependent scancodes */ … … 1769 1773 if (maxval>=0) { 1770 1774 /* got it */ 1775 #ifndef OUTOFWINE 1771 1776 const WORD (*lscan)[MAIN_LEN] = main_key_tab[kbd_layout].scan; 1772 1777 const WORD (*lvkey)[MAIN_LEN] = main_key_tab[kbd_layout].vkey; 1773 1778 scan = (*lscan)[maxval]; 1774 1779 vkey = (*lvkey)[maxval]; 1780 #else 1781 const WORD (*lscan)[MAIN_LEN] = main_key_tab[kbd_layout].scan; 1782 scan = (*lscan)[maxval]; 1783 #endif 1775 1784 } 1776 1785 } 1777 1786 } 1787 #ifndef OUTOFWINE 1778 1788 TRACE("keycode %04x => vkey %04x\n", e2.keycode, vkey); 1779 1789 keyc2vkey[e2.keycode] = vkey; … … 1782 1792 WARN("vkey %04x is being used by more than one keycode\n", vkey); 1783 1793 vkey_used[(vkey & 0xff)] = 1; 1794 #else 1795 keyc2scan[e2.keycode] = scan; 1796 #endif 1784 1797 } /* for */ 1785 1798 1799 #ifndef OUTOFWINE 1786 1800 #define VKEY_IF_NOT_USED(vkey) (vkey_used[(vkey)] ? 0 : (vkey_used[(vkey)] = 1, (vkey))) 1787 1801 for (keyc = min_keycode; keyc <= max_keycode; keyc++) … … 1828 1842 if (!vkey) 1829 1843 { 1830 /* @@@AH VBOX hack for AltGr */1831 if (e2.keycode == 0x71)1832 {1833 TRACE("VBOX HACK, mapping keycode 0x71 to scancode %X\n", VK_MENU);1834 vkey = VK_MENU | 0x100;1835 } else {1836 1844 /* Others keys: let's assign OEM virtual key codes in the allowed range, 1837 1845 * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */ 1838 do 1846 do 1847 { 1848 switch (++OEMvkey) 1839 1849 { 1840 switch (++OEMvkey) 1841 { 1842 case 0xc1 : OEMvkey=0xdb; break; 1843 case 0xe5 : OEMvkey=0xe9; break; 1844 case 0xf6 : OEMvkey=0xf5; WARN("No more OEM vkey available!\n"); 1845 } 1846 } while (OEMvkey < 0xf5 && vkey_used[OEMvkey]); 1847 1848 vkey = VKEY_IF_NOT_USED(OEMvkey); 1849 1850 if (TRACE_ON(keyboard)) 1850 case 0xc1 : OEMvkey=0xdb; break; 1851 case 0xe5 : OEMvkey=0xe9; break; 1852 case 0xf6 : OEMvkey=0xf5; WARN("No more OEM vkey available!\n"); 1853 } 1854 } while (OEMvkey < 0xf5 && vkey_used[OEMvkey]); 1855 1856 vkey = VKEY_IF_NOT_USED(OEMvkey); 1857 1858 if (TRACE_ON(keyboard)) 1859 { 1860 TRACE("OEM specific virtual key %X assigned to keycode %X:\n", 1861 OEMvkey, e2.keycode); 1862 TRACE("("); 1863 for (i = 0; i < keysyms_per_keycode; i += 1) 1851 1864 { 1852 TRACE("OEM specific virtual key %X assigned to keycode %X:\n", 1853 OEMvkey, e2.keycode); 1854 TRACE("("); 1855 for (i = 0; i < keysyms_per_keycode; i += 1) 1856 { 1857 const char *ksname; 1858 1859 keysym = XLookupKeysym(&e2, i); 1860 ksname = XKeysymToString(keysym); 1861 if (!ksname) 1862 ksname = "NoSymbol"; 1863 TRACE( "%lX (%s) ", keysym, ksname); 1864 } 1865 TRACE(")\n"); 1865 const char *ksname; 1866 1867 keysym = XLookupKeysym(&e2, i); 1868 ksname = XKeysymToString(keysym); 1869 if (!ksname) 1870 ksname = "NoSymbol"; 1871 TRACE( "%lX (%s) ", keysym, ksname); 1866 1872 } 1873 TRACE(")\n"); 1867 1874 } 1868 1875 } … … 1884 1891 if (!ksname) ksname = "NoSymbol"; 1885 1892 1886 /* @@@AH VBOX hack for AltGr */1887 if (keyc == 0x71)1888 {1889 TRACE("VBOX HACK for AltGr: mapping 0x71 to scancode 0x38");1890 keyc2scan[keyc] = 0x38;1891 } else1892 {1893 1894 1893 /* should make sure the scancode is unassigned here, but >=0x60 currently always is */ 1895 1894 … … 1897 1896 keyc2scan[keyc]=scan++; 1898 1897 } 1899 }1900 1898 1901 1899 /* Now store one keycode for each modifier. Used to simulate keypresses. */ … … 1906 1904 kcNumLock = XKeysymToKeycode(display, XK_Num_Lock); 1907 1905 kcCapsLock = XKeysymToKeycode(display, XK_Caps_Lock); 1906 #endif /* OUTOFWINE not defined */ 1908 1907 wine_tsx11_unlock(); 1909 1908 }
Note:
See TracChangeset
for help on using the changeset viewer.