VirtualBox

Changeset 71540 in vbox


Ignore:
Timestamp:
Mar 28, 2018 3:12:45 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
121519
Message:

FE/Qt: bugref:9049: Heavy cleanup for XKeyboard stuff.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/platform/x11
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard-new.cpp

    r69500 r71540  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3434
    3535/* GUI includes: */
    36 #include <XKeyboard.h>
     36#include "XKeyboard.h"
    3737
    3838/* Other VBox includes: */
    39 #include <VBox/VBoxKeyboard.h>
     39#include "VBox/VBoxKeyboard.h"
    4040
    4141/* External includes: */
     
    4444
    4545
    46 /* VBoxKeyboard uses the deprecated XKeycodeToKeysym(3) API, but uses it safely.
    47  */
     46/* VBoxKeyboard uses the deprecated XKeycodeToKeysym(3) API, but uses it safely. */
    4847#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    4948
     
    5251static unsigned gfByXkbOK = 1;
    5352
    54 /**
    55  * DEBUG function
    56  * Print a key to the release log in the format needed for the Wine
    57  * layout tables.
    58  */
    59 static void printKey(Display *display, int keyc)
    60 {
    61     bool was_escape = false;
     53/** Prints a key to the release log in the format needed for the Wine layout tables. */
     54static void printKey(Display *pDisplay, int cKeys)
     55{
     56    bool fWasEscape = false;
    6257
    6358    for (int i = 0; i < 2; ++i)
    6459    {
    65         int keysym = XKeycodeToKeysym (display, keyc, i);
    66 
    67         int val = keysym & 0xff;
    68         if ('\\' == val)
     60        int iKeySym = XKeycodeToKeysym(pDisplay, cKeys, i);
     61
     62        int iValue = iKeySym & 0xff;
     63        if ('\\' == iValue)
    6964        {
    7065            LogRel(("\\\\"));
    7166        }
    72         else if ('"' == val)
     67        else if ('"' == iValue)
    7368        {
    7469            LogRel(("\\\""));
    7570        }
    76         else if ((val > 32) && (val < 127))
    77         {
    78             if (
    79                    was_escape
    80                 && (
    81                        ((val >= '0') && (val <= '9'))
    82                     || ((val >= 'A') && (val <= 'F'))
    83                     || ((val >= 'a') && (val <= 'f'))
    84                    )
    85                )
     71        else if ((iValue > 32) && (iValue < 127))
     72        {
     73            if (   fWasEscape
     74                && (   ((iValue >= '0') && (iValue <= '9'))
     75                    || ((iValue >= 'A') && (iValue <= 'F'))
     76                    || ((iValue >= 'a') && (iValue <= 'f'))))
    8677            {
    8778                LogRel(("\"\""));
    8879            }
    89             LogRel(("%c", (char) val));
     80            LogRel(("%c", (char)iValue));
    9081        }
    9182        else
    9283        {
    93             LogRel(("\\x%x", val));
    94             was_escape = true;
    95         }
    96     }
    97 }
    98 
    99 /**
    100  * DEBUG function
    101  * Dump the keyboard layout to the release log.
    102  */
    103 static void dumpLayout(Display *display)
     84            LogRel(("\\x%x", iValue));
     85            fWasEscape = true;
     86        }
     87    }
     88}
     89
     90/** Dumps the keyboard layout to the release log. */
     91static void dumpLayout(Display *pDisplay)
    10492{
    10593    LogRel(("Your keyboard layout does not appear to be fully supported by\n"
     
    11098    /* First, build up a table of scan-to-key code mappings */
    11199    unsigned scanToKeycode[512] = { 0 };
    112     int minKey, maxKey;
    113     XDisplayKeycodes(display, &minKey, &maxKey);
    114     for (int i = minKey; i < maxKey; ++i)
    115         scanToKeycode[X11DRV_KeyEvent(display, i)] = i;
    116     LogRel(("\""));
    117     printKey(display, scanToKeycode[0x29]); /* `~ */
     100    int iMinKey, iMaxKey;
     101    XDisplayKeycodes(pDisplay, &iMinKey, &iMaxKey);
     102    for (int i = iMinKey; i < iMaxKey; ++i)
     103        scanToKeycode[X11DRV_KeyEvent(pDisplay, i)] = i;
     104    LogRel(("\""));
     105    printKey(pDisplay, scanToKeycode[0x29]); /* `~ */
    118106    for (int i = 2; i <= 0xd; ++i) /* 1! - =+ */
    119107    {
    120108        LogRel(("\",\""));
    121         printKey(display, scanToKeycode[i]);
     109        printKey(pDisplay, scanToKeycode[i]);
    122110    }
    123111    LogRel(("\",\n"));
    124112    LogRel(("\""));
    125     printKey(display, scanToKeycode[0x10]); /* qQ */
     113    printKey(pDisplay, scanToKeycode[0x10]); /* qQ */
    126114    for (int i = 0x11; i <= 0x1b; ++i) /* wW - ]} */
    127115    {
    128116        LogRel(("\",\""));
    129         printKey(display, scanToKeycode[i]);
     117        printKey(pDisplay, scanToKeycode[i]);
    130118    }
    131119    LogRel(("\",\n"));
    132120    LogRel(("\""));
    133     printKey(display, scanToKeycode[0x1e]); /* aA */
     121    printKey(pDisplay, scanToKeycode[0x1e]); /* aA */
    134122    for (int i = 0x1f; i <= 0x28; ++i) /* sS - '" */
    135123    {
    136124        LogRel(("\",\""));
    137         printKey(display, scanToKeycode[i]);
    138     }
    139     LogRel(("\",\""));
    140     printKey(display, scanToKeycode[0x2b]); /* \| */
     125        printKey(pDisplay, scanToKeycode[i]);
     126    }
     127    LogRel(("\",\""));
     128    printKey(pDisplay, scanToKeycode[0x2b]); /* \| */
    141129    LogRel(("\",\n"));
    142130    LogRel(("\""));
    143     printKey(display, scanToKeycode[0x2c]); /* zZ */
     131    printKey(pDisplay, scanToKeycode[0x2c]); /* zZ */
    144132    for (int i = 0x2d; i <= 0x35; ++i) /* xX - /? */
    145133    {
    146134        LogRel(("\",\""));
    147         printKey(display, scanToKeycode[i]);
    148     }
    149     LogRel(("\",\""));
    150     printKey(display, scanToKeycode[0x56]); /* The 102nd key */
    151     LogRel(("\",\""));
    152     printKey(display, scanToKeycode[0x73]); /* The Brazilian key */
    153     LogRel(("\",\""));
    154     printKey(display, scanToKeycode[0x7d]); /* The Yen key */
     135        printKey(pDisplay, scanToKeycode[i]);
     136    }
     137    LogRel(("\",\""));
     138    printKey(pDisplay, scanToKeycode[0x56]); /* The 102nd key */
     139    LogRel(("\",\""));
     140    printKey(pDisplay, scanToKeycode[0x73]); /* The Brazilian key */
     141    LogRel(("\",\""));
     142    printKey(pDisplay, scanToKeycode[0x7d]); /* The Yen key */
    155143    LogRel(("\"\n\n"));
    156144}
    157145
    158 /**
    159  * DEBUG function
    160  * Dump the keyboard type tables to the release log.
    161  */
    162 static void dumpType(Display *display)
     146/** Dumps the keyboard type tables to the release log. */
     147static void dumpType(Display *pDisplay)
    163148{
    164149    LogRel(("Your keyboard type does not appear to be known to VirtualBox. If\n"
     
    170155    for (unsigned i = 0; i < 256; ++i)
    171156    {
    172         LogRel(("0x%x", X11DRV_KeyEvent(display, i)));
     157        LogRel(("0x%x", X11DRV_KeyEvent(pDisplay, i)));
    173158        if (i < 255)
    174159            LogRel((", "));
     
    178163    LogRel(("and\n"));
    179164    LogRel(("NULL, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x,\n0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
    180             XKeysymToKeycode(display, XK_Control_L),
    181             XKeysymToKeycode(display, XK_Shift_L),
    182             XKeysymToKeycode(display, XK_Caps_Lock),
    183             XKeysymToKeycode(display, XK_Tab),
    184             XKeysymToKeycode(display, XK_Escape),
    185             XKeysymToKeycode(display, XK_Return),
    186             XKeysymToKeycode(display, XK_Up),
    187             XKeysymToKeycode(display, XK_Down),
    188             XKeysymToKeycode(display, XK_Left),
    189             XKeysymToKeycode(display, XK_Right),
    190             XKeysymToKeycode(display, XK_F1),
    191             XKeysymToKeycode(display, XK_F2),
    192             XKeysymToKeycode(display, XK_F3),
    193             XKeysymToKeycode(display, XK_F4),
    194             XKeysymToKeycode(display, XK_F5),
    195             XKeysymToKeycode(display, XK_F6),
    196             XKeysymToKeycode(display, XK_F7),
    197             XKeysymToKeycode(display, XK_F8)));
    198 }
    199 
    200 /*
    201  * This function builds a table mapping the X server's scan codes to PC
    202  * keyboard scan codes.  The logic of the function is that while the
    203  * X server may be using a different set of scan codes (if for example
    204  * it is running on a non-PC machine), the keyboard layout should be similar
    205  * to a PC layout.  So we look at the symbols attached to each key on the
    206  * X server, find the PC layout which is closest to it and remember the
    207  * mappings.
    208  */
    209 bool initXKeyboard(Display *dpy, int (*remapScancodes)[2])
    210 {
    211     X11DRV_InitKeyboard(dpy, &gfByLayoutOK, &gfByTypeOK, &gfByXkbOK,
    212                         remapScancodes);
    213     /* It will almost always work to some extent */
     165            XKeysymToKeycode(pDisplay, XK_Control_L),
     166            XKeysymToKeycode(pDisplay, XK_Shift_L),
     167            XKeysymToKeycode(pDisplay, XK_Caps_Lock),
     168            XKeysymToKeycode(pDisplay, XK_Tab),
     169            XKeysymToKeycode(pDisplay, XK_Escape),
     170            XKeysymToKeycode(pDisplay, XK_Return),
     171            XKeysymToKeycode(pDisplay, XK_Up),
     172            XKeysymToKeycode(pDisplay, XK_Down),
     173            XKeysymToKeycode(pDisplay, XK_Left),
     174            XKeysymToKeycode(pDisplay, XK_Right),
     175            XKeysymToKeycode(pDisplay, XK_F1),
     176            XKeysymToKeycode(pDisplay, XK_F2),
     177            XKeysymToKeycode(pDisplay, XK_F3),
     178            XKeysymToKeycode(pDisplay, XK_F4),
     179            XKeysymToKeycode(pDisplay, XK_F5),
     180            XKeysymToKeycode(pDisplay, XK_F6),
     181            XKeysymToKeycode(pDisplay, XK_F7),
     182            XKeysymToKeycode(pDisplay, XK_F8)));
     183}
     184
     185/** Builds a table mapping the X server's scan codes to PC keyboard scan codes.
     186  * The logic of the function is that while the X server may be using a different
     187  * set of scan codes (if for example it is running on a non-PC machine), the
     188  * keyboard layout should be similar to a PC layout.  So we look at the symbols
     189  * attached to each key on the X server, find the PC layout which is closest to
     190  * it and remember the mappings. */
     191bool initXKeyboard(Display *pDisplay, int (*remapScancodes)[2])
     192{
     193    X11DRV_InitKeyboard(pDisplay, &gfByLayoutOK, &gfByTypeOK, &gfByXkbOK, remapScancodes);
     194
     195    /* It will almost always work to some extent.. */
    214196    return true;
    215197}
    216198
    217 /**
    218  * Do deferred logging after initialisation
    219  */
    220 void doXKeyboardLogging(Display *dpy)
     199void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes)
     200{
     201    /* Initialize X11 keyboard including the remapping specified in the
     202     * global property GUI/RemapScancodes. This property is a string of
     203     * comma-separated x=y pairs, where x is the X11 keycode and y is the
     204     * keyboard scancode that is emitted when the key attached to the X11
     205     * keycode is pressed. */
     206
     207    int (*scancodes)[2] = NULL;
     208    int (*scancodesTail)[2] = NULL;
     209
     210    if (remapScancodes != QString())
     211    {
     212        QStringList tuples = remapScancodes.split(",", QString::SkipEmptyParts);
     213        scancodes = scancodesTail = new int [tuples.size()+1][2];
     214        for (int i = 0; i < tuples.size(); ++i)
     215        {
     216            QStringList keyc2scan = tuples.at(i).split("=");
     217            (*scancodesTail)[0] = keyc2scan.at(0).toUInt();
     218            (*scancodesTail)[1] = keyc2scan.at(1).toUInt();
     219            /* Do not advance on (ignore) identity mappings as this
     220             * is the stop signal to initXKeyboard and friends: */
     221            if ((*scancodesTail)[0] != (*scancodesTail)[1])
     222                ++scancodesTail;
     223        }
     224        (*scancodesTail)[0] = (*scancodesTail)[1] = 0;
     225    }
     226
     227    /* Initialize the X keyboard subsystem: */
     228    initXKeyboard(pDisplay, scancodes);
     229
     230    if (scancodes)
     231        delete scancodes;
     232}
     233
     234unsigned handleXKeyEvent(Display *pDisplay, unsigned int iDetail)
     235{
     236    /* Call the WINE event handler: */
     237    unsigned iKey = X11DRV_KeyEvent(pDisplay, iDetail);
     238    LogRel3(("VBoxKeyboard: converting keycode %d to scancode %s0x%x\n",
     239             iDetail, iKey > 0x100 ? "0xe0 " : "", iKey & 0xff));
     240    return iKey;
     241}
     242
     243void doXKeyboardLogging(Display *pDisplay)
    221244{
    222245    if (((1 == gfByTypeOK) || (1 == gfByXkbOK)) && (gfByLayoutOK != 1))
    223         dumpLayout(dpy);
     246        dumpLayout(pDisplay);
    224247    if (((1 == gfByLayoutOK) || (1 == gfByXkbOK)) && (gfByTypeOK != 1))
    225         dumpType(dpy);
     248        dumpType(pDisplay);
    226249    if ((gfByLayoutOK != 1) && (gfByTypeOK != 1) && (gfByXkbOK != 1))
    227250    {
     
    240263    }
    241264    LogRel(("X Server details: vendor: %s, release: %d, protocol version: %d.%d, display string: %s\n",
    242             ServerVendor(dpy), VendorRelease(dpy), ProtocolVersion(dpy),
    243             ProtocolRevision(dpy), DisplayString(dpy)));
     265            ServerVendor(pDisplay), VendorRelease(pDisplay), ProtocolVersion(pDisplay),
     266            ProtocolRevision(pDisplay), DisplayString(pDisplay)));
    244267    LogRel(("Using %s for keycode to scan code conversion\n",
    245268              gfByXkbOK ? "XKB"
     
    248271}
    249272
    250 /*
    251  * Translate an X server scancode to a PC keyboard scancode.
    252  */
    253 unsigned handleXKeyEvent(Display *pDisplay, unsigned int iDetail)
    254 {
    255     // call the WINE event handler
    256     unsigned key = X11DRV_KeyEvent(pDisplay, iDetail);
    257     LogRel3(("VBoxKeyboard: converting keycode %d to scancode %s0x%x\n",
    258              iDetail, key > 0x100 ? "0xe0 " : "", key & 0xff));
    259     return key;
    260 }
    261 
    262 /**
    263  * Initialize X11 keyboard including the remapping specified in the
    264  * global property GUI/RemapScancodes. This property is a string of
    265  * comma-separated x=y pairs, where x is the X11 keycode and y is the
    266  * keyboard scancode that is emitted when the key attached to the X11
    267  * keycode is pressed.
    268  */
    269 void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes)
    270 {
    271     int (*scancodes)[2] = NULL;
    272     int (*scancodesTail)[2] = NULL;
    273 
    274     if (remapScancodes != QString::null)
    275     {
    276         QStringList tuples = remapScancodes.split(",", QString::SkipEmptyParts);
    277         scancodes = scancodesTail = new int [tuples.size()+1][2];
    278         for (int i = 0; i < tuples.size(); ++i)
    279         {
    280             QStringList keyc2scan = tuples.at(i).split("=");
    281             (*scancodesTail)[0] = keyc2scan.at(0).toUInt();
    282             (*scancodesTail)[1] = keyc2scan.at(1).toUInt();
    283             /* Do not advance on (ignore) identity mappings as this is
    284                the stop signal to initXKeyboard and friends */
    285             if ((*scancodesTail)[0] != (*scancodesTail)[1])
    286                 scancodesTail++;
    287         }
    288         (*scancodesTail)[0] = (*scancodesTail)[1] = 0;
    289     }
    290     /* initialize the X keyboard subsystem */
    291     initXKeyboard (pDisplay ,scancodes);
    292 
    293     if (scancodes)
    294         delete scancodes;
    295 }
    296 
    297273unsigned long wrapXkbKeycodeToKeysym(Display *pDisplay, unsigned char cCode,
    298274                                     unsigned int cGroup, unsigned int cIndex)
     
    303279    return XKeycodeToKeysym(pDisplay, cCode, cGroup * 2 + cIndex % 2);
    304280}
     281
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard.h

    r69500 r71540  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __XKeyboard_h__
    19 #define __XKeyboard_h__
     18#ifndef ___XKeyboard_h___
     19#define ___XKeyboard_h___
    2020
    2121/* Forward declarations: */
     
    2323typedef struct _XDisplay Display;
    2424
     25/** Initializes the X keyboard subsystem. */
     26void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes);
    2527
    26 // initialize the X keyboard subsystem
    27 void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes);
    28 // our custom keyboard handler
     28/** Handles native XKey events. */
    2929unsigned handleXKeyEvent(Display *pDisplay, unsigned int iDetail);
    30 // Called after release logging is started, in case initXKeyboard wishes to log
    31 // anything
    32 void doXKeyboardLogging(Display *dpy);
    33 // Wrapper for the XkbKeycodeToKeysym(3) API which falls back to the deprecated
    34 // XKeycodeToKeysym(3) if it is unavailable.
     30
     31/** Handles log requests from initXKeyboard after release logging is started. */
     32void doXKeyboardLogging(Display *pDisplay);
     33
     34/** Wraps for the XkbKeycodeToKeysym(3) API which falls back to the deprecated XKeycodeToKeysym(3) if it is unavailable. */
    3535unsigned long wrapXkbKeycodeToKeysym(Display *pDisplay, unsigned char cCode,
    3636                                     unsigned int cGroup, unsigned int cIndex);
    3737
    38 #endif // __XKeyboard_h__
     38#endif /* !___XKeyboard_h___ */
    3939
Note: See TracChangeset for help on using the changeset viewer.

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