VirtualBox

Changeset 3976 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Aug 1, 2007 6:33:03 PM (17 years ago)
Author:
vboxsync
Message:

Did a major clean-up of the Wine-based keyboard library

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/linux/keyboard.c

    r3945 r3976  
    8787    unsigned long lp2;
    8888} KEYLP;
    89 #endif /* OUTOFWINE not defined */
    90 
    9189
    9290/* key state table bits:
     
    9795BYTE key_state_table[256];
    9896
    99 #ifndef OUTOFWINE
    10097static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
    10198                                or a WM_KEYUP message */
     
    103100
    104101static int min_keycode, max_keycode, keysyms_per_keycode;
     102
     103#ifndef OUTOFWINE
    105104static WORD keyc2vkey[256], keyc2scan[256];
    106105
    107106static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */
    108107static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */
     108#else
     109static WORD keyc2scan[256];
     110#endif
    109111
    110112static char KEYBOARD_MapDeadKeysym(KeySym keysym);
    111 
    112 #ifdef OUTOFWINE
    113 /* Global variable to store the current display pointer which is defined
    114  * 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 #endif
    124113
    125114/* Keyboard translation tables */
     
    1010999                   for PrtScn key ... GA */
    10111000
     1001#ifndef OUTOFWINE
    10121002static const WORD nonchar_key_vkey[256] =
    10131003{
     
    10491039    VK_F1, VK_F2,
    10501040    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 */
    10531042    0, 0, 0, 0, 0, 0, 0, 0,                                     /* FFD0 */
    10541043    0, 0, 0, 0, 0, 0, 0, 0,                                     /* FFD8 */
     
    10601049    0, 0, 0, 0, 0, 0, 0, VK_DELETE                              /* FFF8 */
    10611050};
     1051#endif /* OUTOFWINE not defined */
    10621052
    10631053static const WORD nonchar_key_scan[256] =
     
    10961086    0x3B, 0x3C,
    10971087    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,              /* FFC0 */
    1098     0x57, 0x58, 0x15B, 0x15C, 0x00, 0x00, 0x00, 0x00,              /* FFC8 */
     1088    0x57, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,              /* FFC8 */
    10991089    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,              /* FFD0 */
    11001090    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,              /* FFD8 */
    11011091    /* modifier keys */
    11021092    0x00, 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0x00, 0x38,             /* FFE0 */
    1103     0x138, 0x38, 0x138, 0x00, 0x00, 0x00, 0x00, 0x00,            /* FFE8 */
     1093    0x138, 0x38, 0x138, 0x15B, 0x15C, 0x00, 0x00, 0x00,            /* FFE8 */
    11041094    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,              /* FFF0 */
    11051095    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x153              /* FFF8 */
     
    11461136};
    11471137
     1138#ifndef OUTOFWINE
    11481139/* Returns the Windows virtual key code associated with the X event <e> */
    11491140/* x11 lock must be held */
     
    11721163}
    11731164
    1174 #ifndef OUTOFWINE
    11751165static BOOL NumState=FALSE, CapsState=FALSE;
    1176 #endif
    11771166
    11781167
     
    11801169 *           X11DRV_send_keyboard_input
    11811170 */
    1182 static void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
     1171void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
    11831172                                 DWORD dwExtraInfo, UINT injected_flags )
    11841173{
    1185 #ifndef OUTOFWINE
    11861174    UINT message;
    11871175    KEYLP keylp;
     
    12701258    }
    12711259    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 */
    12791260}
    12801261
    12811262
    1282 #ifndef OUTOFWINE
    12831263/**********************************************************************
    12841264 *              KEYBOARD_GenerateMsg
     
    13271307    }
    13281308}
    1329 #endif /* OUTOFWINE not defined */
    13301309
    13311310/***********************************************************************
     
    13501329}
    13511330
    1352 #ifndef OUTOFWINE
    13531331/***********************************************************************
    13541332 *           X11DRV_KeymapNotify
     
    13871365    KEYBOARD_UpdateOneState( VK_SHIFT, shift, time );
    13881366}
    1389 #endif /* OUTOFWINE defined */
    13901367
    13911368/***********************************************************************
     
    13941371 * Handle a X key event
    13951372 */
    1396 #ifndef OUTOFWINE
    13971373void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
    1398 #else /* OUTOFWINE defined */
    1399 void X11DRV_KeyEvent(Display *dpy, XEvent *xev, WINEKEYBOARDINFO *wKbInfo)
    1400 #endif /* OUTOFWINE defined */
    14011374{
    14021375    XKeyEvent *event = &xev->xkey;
     
    14061379    DWORD dwFlags;
    14071380    int ascii_chars;
    1408 #ifndef OUTOFWINE
    14091381    XIC xic = X11DRV_get_ic( hwnd );
    14101382    DWORD event_time = EVENT_x11_time_to_win32_time(event->time);
    14111383    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 structure
    1420      * and initialize it with zeroes for the case of early return
    1421      * (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 */
    14251384
    14261385    TRACE_(key)("type %d, window %lx, state 0x%04x, keycode 0x%04x\n",
     
    14401399        ERR("Buffer Overflow need %i!\n",ascii_chars);
    14411400
    1442 #ifndef OUTOFWINE
    14431401    if (status == XLookupChars)
    14441402    {
     
    14461404        return;
    14471405    }
    1448 #endif /* OUTOFWINE not defined */
    14491406
    14501407    /* If XKB extensions are used, the state mask for AltGr will use the group
     
    14851442   if (vkey)
    14861443   {
    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          {
    15081458            TRACE("Adjusting NumLock state.\n");
    15091459            KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time );
     
    15111461          }
    15121462        /* Adjust the CAPSLOCK state if it has been changed outside wine */
    1513           if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
     1463        if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
    15141464          {
    15151465              TRACE("Adjusting Caps Lock state.\n");
     
    15171467            KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_time );
    15181468          }
    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;
    15231472
    15241473        bScan = keyc2scan[event->keycode] & 0xFF;
     
    15301479
    15311480        X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 );
    1532 #ifndef OUTOFWINE
    1533       }
    1534 #endif
     1481    }
    15351482   }
    15361483}
     1484
     1485#else /* OUTOFWINE defined */
     1486
     1487void 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 */
    15371495
    15381496/**********************************************************************
     
    15441502 * X11 lock must be held.
    15451503 */
     1504#ifndef OUTOFWINE
    15461505static void
    15471506X11DRV_KEYBOARD_DetectLayout (void)
    1548 {
     1507#else
     1508static void
     1509X11DRV_KEYBOARD_DetectLayout (Display *display)
     1510#endif
     1511{
     1512#ifndef OUTOFWINE
    15491513  Display *display = thread_display();
     1514#endif
    15501515  unsigned current, match, mismatch, seq, i, syms;
    15511516  int score, keyc, key, pkey, ok;
     
    16541619 *              X11DRV_InitKeyboard
    16551620 */
     1621#ifndef OUTOFWINE
     1622void X11DRV_InitKeyboard(void)
     1623#else
    16561624void X11DRV_InitKeyboard(Display *display)
    1657 {
     1625#endif
     1626{
     1627#ifndef OUTOFWINE
     1628    Display *display = thread_display();
    16581629    KeySym *ksp;
    16591630    XModifierKeymap *mmp;
     
    16621633    XKeyEvent e2;
    16631634    WORD scan, vkey, OEMvkey;
     1635#else
     1636    KeySym *ksp;
     1637    KeySym keysym;
     1638    XKeyEvent e2;
     1639    WORD scan;
     1640#endif
    16641641    int keyc, i, keyn, syms;
    16651642    char ckey[4]={0,0,0,0};
    16661643    const char (*lkey)[MAIN_LEN][4];
     1644#ifndef OUTOFWINE
    16671645    char vkey_used[256] = { 0 };
    1668 
    1669     dpy_global = display;
     1646#endif
     1647
    16701648    wine_tsx11_lock();
    16711649    XDisplayKeycodes(display, &min_keycode, &max_keycode);
     
    16761654    XFree(ksp);
    16771655
     1656#ifndef OUTOFWINE
    16781657    mmp = XGetModifierMapping(display);
    16791658    kcp = mmp->modifiermap;
     
    16991678    /* Detect the keyboard layout */
    17001679    X11DRV_KEYBOARD_DetectLayout();
     1680#else
     1681    /* Detect the keyboard layout */
     1682    X11DRV_KEYBOARD_DetectLayout(display);
     1683#endif
    17011684    lkey = main_key_tab[kbd_layout].key;
    17021685    syms = (keysyms_per_keycode > 4) ? 4 : keysyms_per_keycode;
     
    17091692    e2.state = 0;
    17101693
     1694#ifndef OUTOFWINE
    17111695    OEMvkey = VK_OEM_8; /* next is available.  */
    17121696    memset(keyc2vkey, 0, sizeof(keyc2vkey));
     1697#endif
    17131698    for (keyc = min_keycode; keyc <= max_keycode; keyc++)
    17141699    {
     
    17191704        e2.keycode = (KeyCode)keyc;
    17201705        have_chars = XLookupString(&e2, buf, sizeof(buf), &keysym, NULL);
     1706#ifndef OUTOFWINE
    17211707        vkey = 0; scan = 0;
     1708#else
     1709        scan = 0;
     1710#endif
    17221711        if (keysym)  /* otherwise, keycode not used */
    17231712        {
    17241713            if ((keysym >> 8) == 0xFF)         /* non-character key */
    17251714            {
     1715#ifndef OUTOFWINE
    17261716                vkey = nonchar_key_vkey[keysym & 0xff];
     1717#endif
    17271718                scan = nonchar_key_scan[keysym & 0xff];
    17281719                /* set extended bit when necessary */
     1720#ifndef OUTOFWINE
    17291721                if (scan & 0x100) vkey |= 0x100;
     1722#endif
    17301723            } else if ((keysym >> 8) == 0x1008FF) { /* XFree86 vendor keys */
     1724#ifndef OUTOFWINE
    17311725                vkey = xfree86_vendor_key_vkey[keysym & 0xff];
    17321726                /* All vendor keys are extended with a scan code of 0 per testing on WinXP */
    17331727                scan = 0x100;
    17341728                vkey |= 0x100;
     1729#else
     1730                /* @michael: this needs to be investigated and improved on. */
     1731                scan = 0x100;
     1732#endif
    17351733            } else if (keysym == 0x20) {                 /* Spacebar */
     1734#ifndef OUTOFWINE
    17361735                vkey = VK_SPACE;
     1736#endif
    17371737                scan = 0x39;
     1738#ifdef OUTOFWINE
     1739            } else if (keysym == 0xFE03) {               /* ISO level3 shift, aka AltGr */
     1740                scan = 0x138;
     1741#endif /* OUTOFWINE defined */
    17381742            } else if (have_chars) {
    17391743              /* we seem to need to search the layout-dependent scancodes */
     
    17691773              if (maxval>=0) {
    17701774                /* got it */
     1775#ifndef OUTOFWINE
    17711776                const WORD (*lscan)[MAIN_LEN] = main_key_tab[kbd_layout].scan;
    17721777                const WORD (*lvkey)[MAIN_LEN] = main_key_tab[kbd_layout].vkey;
    17731778                scan = (*lscan)[maxval];
    17741779                vkey = (*lvkey)[maxval];
     1780#else
     1781                const WORD (*lscan)[MAIN_LEN] = main_key_tab[kbd_layout].scan;
     1782                scan = (*lscan)[maxval];
     1783#endif
    17751784              }
    17761785            }
    17771786        }
     1787#ifndef OUTOFWINE
    17781788        TRACE("keycode %04x => vkey %04x\n", e2.keycode, vkey);
    17791789        keyc2vkey[e2.keycode] = vkey;
     
    17821792            WARN("vkey %04x is being used by more than one keycode\n", vkey);
    17831793        vkey_used[(vkey & 0xff)] = 1;
     1794#else
     1795        keyc2scan[e2.keycode] = scan;
     1796#endif
    17841797    } /* for */
    17851798
     1799#ifndef OUTOFWINE
    17861800#define VKEY_IF_NOT_USED(vkey) (vkey_used[(vkey)] ? 0 : (vkey_used[(vkey)] = 1, (vkey)))
    17871801    for (keyc = min_keycode; keyc <= max_keycode; keyc++)
     
    18281842        if (!vkey)
    18291843        {
    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 {
    18361844            /* Others keys: let's assign OEM virtual key codes in the allowed range,
    18371845             * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */
    1838                 do
     1846            do
     1847            {
     1848                switch (++OEMvkey)
    18391849                {
    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)
    18511864                {
    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);
    18661872                }
     1873                TRACE(")\n");
    18671874            }
    18681875        }
     
    18841891        if (!ksname) ksname = "NoSymbol";
    18851892
    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     } else
    1892     {
    1893 
    18941893        /* should make sure the scancode is unassigned here, but >=0x60 currently always is */
    18951894
     
    18971896        keyc2scan[keyc]=scan++;
    18981897      }
    1899     }
    19001898
    19011899    /* Now store one keycode for each modifier. Used to simulate keypresses. */
     
    19061904    kcNumLock = XKeysymToKeycode(display, XK_Num_Lock);
    19071905    kcCapsLock = XKeysymToKeycode(display, XK_Caps_Lock);
     1906#endif /* OUTOFWINE not defined */
    19081907    wine_tsx11_unlock();
    19091908}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette