Changeset 71540 in vbox
- Timestamp:
- Mar 28, 2018 3:12:45 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121519
- 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 5 5 6 6 /* 7 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 34 34 35 35 /* GUI includes: */ 36 #include <XKeyboard.h>36 #include "XKeyboard.h" 37 37 38 38 /* Other VBox includes: */ 39 #include <VBox/VBoxKeyboard.h>39 #include "VBox/VBoxKeyboard.h" 40 40 41 41 /* External includes: */ … … 44 44 45 45 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. */ 48 47 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 49 48 … … 52 51 static unsigned gfByXkbOK = 1; 53 52 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. */ 54 static void printKey(Display *pDisplay, int cKeys) 55 { 56 bool fWasEscape = false; 62 57 63 58 for (int i = 0; i < 2; ++i) 64 59 { 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) 69 64 { 70 65 LogRel(("\\\\")); 71 66 } 72 else if ('"' == val)67 else if ('"' == iValue) 73 68 { 74 69 LogRel(("\\\"")); 75 70 } 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')))) 86 77 { 87 78 LogRel(("\"\"")); 88 79 } 89 LogRel(("%c", (char) val));80 LogRel(("%c", (char)iValue)); 90 81 } 91 82 else 92 83 { 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. */ 91 static void dumpLayout(Display *pDisplay) 104 92 { 105 93 LogRel(("Your keyboard layout does not appear to be fully supported by\n" … … 110 98 /* First, build up a table of scan-to-key code mappings */ 111 99 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]); /* `~ */ 118 106 for (int i = 2; i <= 0xd; ++i) /* 1! - =+ */ 119 107 { 120 108 LogRel(("\",\"")); 121 printKey( display, scanToKeycode[i]);109 printKey(pDisplay, scanToKeycode[i]); 122 110 } 123 111 LogRel(("\",\n")); 124 112 LogRel(("\"")); 125 printKey( display, scanToKeycode[0x10]); /* qQ */113 printKey(pDisplay, scanToKeycode[0x10]); /* qQ */ 126 114 for (int i = 0x11; i <= 0x1b; ++i) /* wW - ]} */ 127 115 { 128 116 LogRel(("\",\"")); 129 printKey( display, scanToKeycode[i]);117 printKey(pDisplay, scanToKeycode[i]); 130 118 } 131 119 LogRel(("\",\n")); 132 120 LogRel(("\"")); 133 printKey( display, scanToKeycode[0x1e]); /* aA */121 printKey(pDisplay, scanToKeycode[0x1e]); /* aA */ 134 122 for (int i = 0x1f; i <= 0x28; ++i) /* sS - '" */ 135 123 { 136 124 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]); /* \| */ 141 129 LogRel(("\",\n")); 142 130 LogRel(("\"")); 143 printKey( display, scanToKeycode[0x2c]); /* zZ */131 printKey(pDisplay, scanToKeycode[0x2c]); /* zZ */ 144 132 for (int i = 0x2d; i <= 0x35; ++i) /* xX - /? */ 145 133 { 146 134 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 */ 155 143 LogRel(("\"\n\n")); 156 144 } 157 145 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. */ 147 static void dumpType(Display *pDisplay) 163 148 { 164 149 LogRel(("Your keyboard type does not appear to be known to VirtualBox. If\n" … … 170 155 for (unsigned i = 0; i < 256; ++i) 171 156 { 172 LogRel(("0x%x", X11DRV_KeyEvent( display, i)));157 LogRel(("0x%x", X11DRV_KeyEvent(pDisplay, i))); 173 158 if (i < 255) 174 159 LogRel((", ")); … … 178 163 LogRel(("and\n")); 179 164 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. */ 191 bool 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.. */ 214 196 return true; 215 197 } 216 198 217 /** 218 * Do deferred logging after initialisation 219 */ 220 void doXKeyboardLogging(Display *dpy) 199 void 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 234 unsigned 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 243 void doXKeyboardLogging(Display *pDisplay) 221 244 { 222 245 if (((1 == gfByTypeOK) || (1 == gfByXkbOK)) && (gfByLayoutOK != 1)) 223 dumpLayout( dpy);246 dumpLayout(pDisplay); 224 247 if (((1 == gfByLayoutOK) || (1 == gfByXkbOK)) && (gfByTypeOK != 1)) 225 dumpType( dpy);248 dumpType(pDisplay); 226 249 if ((gfByLayoutOK != 1) && (gfByTypeOK != 1) && (gfByXkbOK != 1)) 227 250 { … … 240 263 } 241 264 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))); 244 267 LogRel(("Using %s for keycode to scan code conversion\n", 245 268 gfByXkbOK ? "XKB" … … 248 271 } 249 272 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 handler256 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 the264 * global property GUI/RemapScancodes. This property is a string of265 * comma-separated x=y pairs, where x is the X11 keycode and y is the266 * keyboard scancode that is emitted when the key attached to the X11267 * 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 is284 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 297 273 unsigned long wrapXkbKeycodeToKeysym(Display *pDisplay, unsigned char cCode, 298 274 unsigned int cGroup, unsigned int cIndex) … … 303 279 return XKeycodeToKeysym(pDisplay, cCode, cGroup * 2 + cIndex % 2); 304 280 } 281 -
trunk/src/VBox/Frontends/VirtualBox/src/platform/x11/XKeyboard.h
r69500 r71540 5 5 6 6 /* 7 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #ifndef __ XKeyboard_h__19 #define __ XKeyboard_h__18 #ifndef ___XKeyboard_h___ 19 #define ___XKeyboard_h___ 20 20 21 21 /* Forward declarations: */ … … 23 23 typedef struct _XDisplay Display; 24 24 25 /** Initializes the X keyboard subsystem. */ 26 void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes); 25 27 26 // initialize the X keyboard subsystem 27 void initMappedX11Keyboard(Display *pDisplay, const QString &remapScancodes); 28 // our custom keyboard handler 28 /** Handles native XKey events. */ 29 29 unsigned handleXKeyEvent(Display *pDisplay, unsigned int iDetail); 30 // Called after release logging is started, in case initXKeyboard wishes to log 31 / / anything32 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. */ 32 void doXKeyboardLogging(Display *pDisplay); 33 34 /** Wraps for the XkbKeycodeToKeysym(3) API which falls back to the deprecated XKeycodeToKeysym(3) if it is unavailable. */ 35 35 unsigned long wrapXkbKeycodeToKeysym(Display *pDisplay, unsigned char cCode, 36 36 unsigned int cGroup, unsigned int cIndex); 37 37 38 #endif / / __XKeyboard_h__38 #endif /* !___XKeyboard_h___ */ 39 39
Note:
See TracChangeset
for help on using the changeset viewer.