VirtualBox

Ticket #2302: keyboard-scancode-remapper.diff

File keyboard-scancode-remapper.diff, 13.2 KB (added by Clemens Fruhwirth, 15 years ago)

Remapper for the X11keycodes->scancodes table using GUI/RemapScancodes

  • src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h

     
    3939
    4040#ifdef Q_WS_X11
    4141# include <sys/wait.h>
     42# include "XKeyboard.h"
    4243#endif
    4344
    4445class QAction;
     
    10011002    bool     mInverted;
    10021003};
    10031004
     1005#ifdef Q_WS_X11
     1006void initMappedX11Keyboard();
     1007#endif
     1008
    10041009#endif /* __VBoxGlobal_h__ */
  • src/VBox/Frontends/VirtualBox/include/XKeyboard.h

     
    2424#define __XKeyboard_h__
    2525
    2626// initialize the X keyboard subsystem
    27 bool initXKeyboard(Display *dpy);
     27bool initXKeyboard(Display *dpy, int (*scancodes)[2]);
    2828// our custom keyboard handler
    2929unsigned handleXKeyEvent(XEvent *event);
    3030// returns the number of keysyms per keycode (only valid after initXKeyboard())
  • src/VBox/Frontends/VirtualBox/include/VBoxGlobalSettings.h

     
    4646    QString guiFeatures;
    4747    QString languageId;
    4848    QString maxGuestRes;
     49    QString remapScancodes;
    4950    bool trayIconEnabled;
    5051    bool dockPreviewEnabled;
    5152
     
    6263    Q_PROPERTY (QString guiFeatures READ guiFeatures WRITE setGuiFeatures)
    6364    Q_PROPERTY (QString languageId READ languageId WRITE setLanguageId)
    6465    Q_PROPERTY (QString maxGuestRes READ maxGuestRes WRITE setMaxGuestRes)
     66    Q_PROPERTY (QString remapScancodes READ remapScancodes WRITE setRemapScancodes)
    6567    Q_PROPERTY (bool trayIconEnabled READ trayIconEnabled WRITE setTrayIconEnabled)
    6668    Q_PROPERTY (bool dockPreviewEnabled READ dockPreviewEnabled WRITE setDockPreviewEnabled)
    6769
     
    106108        mData()->maxGuestRes = aMaxGuestRes;
    107109    }
    108110
     111    QString remapScancodes() const { return data()->remapScancodes; }
     112    void setRemapScancodes (const QString &aRemapScancodes)
     113    {
     114        mData()->remapScancodes = aRemapScancodes;
     115    }
     116
     117
    109118    bool trayIconEnabled() const { return data()->trayIconEnabled; }
    110119    void setTrayIconEnabled (bool enabled)
    111120    {
  • src/VBox/Frontends/VirtualBox/src/VBoxGlobalSettings.cpp

     
    5959    guiFeatures = QString::null;
    6060    languageId  = QString::null;
    6161    maxGuestRes = "auto";
     62    remapScancodes = QString::null;
    6263    trayIconEnabled = false;
    6364    dockPreviewEnabled = true;
    6465}
     
    7071    guiFeatures = that.guiFeatures;
    7172    languageId  = that.languageId;
    7273    maxGuestRes = that.maxGuestRes;
     74    remapScancodes = that.remapScancodes;
    7375    trayIconEnabled = that.trayIconEnabled;
    7476    dockPreviewEnabled = that.dockPreviewEnabled;
    7577}
     
    8688         guiFeatures == that.guiFeatures &&
    8789         languageId  == that.languageId &&
    8890         maxGuestRes == that.maxGuestRes &&
     91         remapScancodes == that.remapScancodes &&
    8992         trayIconEnabled == that.trayIconEnabled
    9093         && dockPreviewEnabled == that.dockPreviewEnabled
    9194        );
     
    114117    { "GUI/Customizations",                        "guiFeatures",        "\\S+", true },
    115118    { "GUI/LanguageID",                            "languageId",         gVBoxLangIDRegExp, true },
    116119    { "GUI/MaxGuestResolution",                    "maxGuestRes",        "\\d*[1-9]\\d*,\\d*[1-9]\\d*|any|auto", true },
     120    { "GUI/RemapScancodes",                        "remapScancodes",     "(\\d+=\\d+,)*\\d+=\\d+", true },
    117121    { "GUI/TrayIcon/Enabled",                      "trayIconEnabled",    "true|false", true },
    118122#ifdef Q_WS_MAC
    119123    { VBoxDefs::GUI_RealtimeDockIconUpdateEnabled, "dockPreviewEnabled", "true|false", true }
  • src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

     
    810810
    811811#ifdef Q_WS_X11
    812812    /* initialize the X keyboard subsystem */
    813     initXKeyboard (QX11Info::display());
     813    initMappedX11Keyboard();
    814814#endif
    815815
    816816    ::memset (mPressedKeys, 0, sizeof (mPressedKeys));
  • src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

     
    49414941    mAction->setText (text);
    49424942}
    49434943
     4944#ifdef Q_WS_X11
     4945/**
     4946 * Initialize X11 keyboard including the remapping specified in the
     4947 * global property GUI/RemapScancodes. This property is a string of
     4948 * comma-seperated x=y pairs, where x is the X11 keycode and y is the
     4949 * keyboard scancode that is emitted when the key attached to the X11
     4950 * keycode is pressed.
     4951 */
     4952void initMappedX11Keyboard() {
     4953    int (*scancodes)[2] = NULL;
     4954    int (*scancodesTail)[2] = NULL;
     4955    QString remapScancodes = vboxGlobal().settings().publicProperty ("GUI/RemapScancodes");
     4956
     4957    if(remapScancodes != QString::null) {
     4958        QStringList tuples = remapScancodes.split(",", QString::SkipEmptyParts);
     4959        scancodes = scancodesTail = new int [tuples.size()+1][2];
     4960        for (int i = 0; i < tuples.size(); ++i) {
     4961            QStringList keyc2scan = tuples.at(i).split("=");
     4962            (*scancodesTail)[0] = keyc2scan.at(0).toUInt();
     4963            (*scancodesTail)[1] = keyc2scan.at(1).toUInt();
     4964            /* Do not advance on (ignore) identity mappings as this is
     4965               the stop signal to initXKeyboard and friends */
     4966            if((*scancodesTail)[0] != (*scancodesTail)[1])
     4967                scancodesTail++;
     4968        }
     4969        (*scancodesTail)[0] = (*scancodesTail)[1] = 0;
     4970    }
     4971    /* initialize the X keyboard subsystem */
     4972    initXKeyboard (QX11Info::display(),scancodes);
     4973
     4974    if(scancodes) delete scancodes;
     4975}
     4976#endif
  • src/VBox/Frontends/VirtualBox/src/X11/XKeyboard-new.cpp

     
    186186 * X server, find the PC layout which is closest to it and remember the
    187187 * mappings.
    188188 */
    189 bool initXKeyboard(Display *dpy)
     189bool initXKeyboard(Display *dpy, int (*remapScancodes)[2])
    190190{
    191     X11DRV_InitKeyboard(dpy, &gfByLayoutOK, &gfByTypeOK);
     191    X11DRV_InitKeyboard(dpy, &gfByLayoutOK, &gfByTypeOK, remapScancodes);
    192192    /* It will almost always work to some extent */
    193193    return true;
    194194}
     
    202202        dumpLayout(dpy);
    203203    if ((1 == gfByLayoutOK) && (gfByTypeOK != 1))
    204204        dumpType(dpy);
    205     if ((gfByLayoutOK != 1) && (gfByTypeOK != 1))
     205    if ((gfByLayoutOK != 1) && (gfByTypeOK != 1)) {
    206206        LogRel(("Failed to recognize the keyboard mapping or to guess it based on\n"
    207207                "the keyboard layout.  It is very likely that some keys will not\n"
    208208                "work correctly in the guest.  If you would like to help us improve\n"
    209209                "the product, please submit a bug report, giving us information\n"
    210210                "about your keyboard type, its layout and other relevant\n"
    211211                "information such as whether you are using a remote X server or\n"
    212                 "something similar.\n"));
     212                "something similar. \n"));
     213        unsigned *keyc2scan=X11DRV_getKeyc2scan();
     214
     215        LogRel(("The keycode-to-scancode table is: %d=%d",0,keyc2scan[0]));
     216        for(int i=1; i<256; i++)
     217            LogRel((",%d=%d",i,keyc2scan[i]));
     218        LogRel(("\n"));
     219    }
    213220}
    214221
    215222/*
  • src/VBox/Frontends/VirtualBox/src/X11/keyboard.h

     
    4343# define CCALL
    4444#endif
    4545#ifdef VBOX_HAVE_VISIBILITY_HIDDEN
    46 extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK);
     46extern CCALL __attribute__((visibility("default"))) unsigned *X11DRV_getKeyc2scan();
     47extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK, int (*remapScancodes)[2]);
    4748extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_KeyEvent(Display *dpy, KeyCode code);
    4849#else
    49 extern CCALL unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK);
     50extern CCALL unsigned *X11DRV_getKeyc2scan();
     51extern CCALL unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK, int (*remapScancodes)[2]);
    5052extern CCALL unsigned X11DRV_KeyEvent(Display *dpy, KeyCode code);
    5153#endif
    5254
  • src/VBox/Frontends/VirtualBox/src/X11/keyboard-new.c

     
    5454#include <stdlib.h>
    5555#include <stdio.h>
    5656
     57#define KEYC2SCAN_SIZE 256
     58
    5759/**
    5860 * Array containing the current mapping of keycodes to scan codes, detected
    5961 * using the keyboard layout algorithm in X11DRV_InitKeyboardByLayout.
    6062 */
    61 static unsigned keyc2scan[256];
    62 /**
    63  * Whether a keyboard was detected with a well-known keycode to scan code
    64  * mapping.
    65  */
    66 static unsigned use_builtin_table = 0;
    67 /** The index of the well-known keycode to scan code mapping in our table. */
    68 static unsigned builtin_table_number;
     63static unsigned keyc2scan[KEYC2SCAN_SIZE];
    6964/** Whether to output basic debugging information to standard output */
    7065static int log_kb_1 = 0;
    7166/** Whether to output verbose debugging information to standard output */
     
    125120            scan = 0x138;
    126121    }
    127122    if (keysym != 0 && scan == 0)
    128     {
    129         if (use_builtin_table != 0)
    130             scan = main_keyboard_type_scans[builtin_table_number][code];
    131         else
    132123            scan = keyc2scan[code];
    133     }
     124
    134125    return scan;
    135126}
    136127
     
    439430            && (XKeysymToKeycode(display, XK_F8)        == main_keyboard_type_list[i].f8)
    440431           )
    441432            found = 1;
    442     use_builtin_table = found;
    443433    if (found != 0)
    444         builtin_table_number = i - 1;
     434        memcpy(keyc2scan, main_keyboard_type_scans[i - 1], KEYC2SCAN_SIZE);
    445435    return found;
    446436}
    447437
     
    463453 * @warning not re-entrant
    464454 * @returns 1 if the layout found was optimal, 0 if it was not.  This is
    465455 *          for diagnostic purposes
    466  * @param   display     a pointer to the X11 display
    467  * @param   byLayoutOK  diagnostic - set to one if detection by layout
    468  *                      succeeded, and to 0 otherwise
    469  * @param   byTypeOK    diagnostic - set to one if detection by type
    470  *                      succeeded, and to 0 otherwise
     456 * @param   display          a pointer to the X11 display
     457 * @param   byLayoutOK       diagnostic - set to one if detection by layout
     458 *                           succeeded, and to 0 otherwise
     459 * @param   byTypeOK         diagnostic - set to one if detection by type
     460 *                           succeeded, and to 0 otherwise
     461 * @param   remapScancode    array of tuples that remap the keycode (first
     462 *                           part) to a scancode (second part)
    471463 */
    472 unsigned X11DRV_InitKeyboard(Display *display, unsigned *byLayoutOK, unsigned *byTypeOK)
     464unsigned X11DRV_InitKeyboard(Display *display, unsigned *byLayoutOK, unsigned *byTypeOK, int (*remapScancodes)[2])
    473465{
    474     unsigned byLayout = X11DRV_InitKeyboardByLayout(display);
    475     unsigned byType   = X11DRV_InitKeyboardByType(display);
     466    unsigned byLayout;
     467    unsigned byType;
     468
     469    byLayout = X11DRV_InitKeyboardByLayout(display);
    476470    *byLayoutOK = byLayout;
    477     *byTypeOK   = byType;
     471
     472    byType = X11DRV_InitKeyboardByType(display);
     473    *byTypeOK = byType;
     474
     475    /* Remap keycodes after initialization. Remapping stops after an
     476       identity mapping is seen */
     477    if(remapScancodes != NULL)
     478        for(; (*remapScancodes)[0] != (*remapScancodes)[1]; remapScancodes++)
     479            keyc2scan[(*remapScancodes)[0]] = (*remapScancodes)[1];
     480
    478481    return (byLayout || byType) ? 1 : 0;
    479482}
     483
     484/**
     485 * Returns the keycode to scancode array
     486 */
     487unsigned *X11DRV_getKeyc2scan()
     488{
     489    return keyc2scan;
     490}
  • src/VBox/Frontends/VirtualBox/src/QIHotKeyEdit.cpp

     
    2222
    2323#include "QIHotKeyEdit.h"
    2424#include "VBoxDefs.h"
     25#include "VBoxGlobal.h"
    2526
    2627/* Qt includes */
    2728#include <QApplication>
     
    118119{
    119120#ifdef Q_WS_X11
    120121    /* Initialize the X keyboard subsystem */
    121     initXKeyboard (QX11Info::display());
     122    initMappedX11Keyboard();
    122123#endif
    123124
    124125    clear();

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