Changeset 9991 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Jun 27, 2008 11:58:47 AM (16 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r9209 r9991 129 129 src/linux/keyboard-list.h \ 130 130 src/linux/keyboard-tables.h \ 131 src/linux/keyboard-types.h \ 131 132 src/linux/Makefile 132 133 VBoxKeyboard_LIBS = X11 -
trunk/src/VBox/Frontends/VirtualBox/src/linux/XKeyboard-new.cpp
r8155 r9991 24 24 25 25 #include <X11/Xlib.h> 26 #include <X11/keysym.h> 26 27 #include <XKeyboard.h> 27 28 #include <VBox/log.h> 28 29 #include "keyboard.h" 29 30 30 static bool gInitStatus = false; 31 static unsigned gfByLayoutOK = 1; 32 static unsigned gfByTypeOK = 1; 31 33 32 34 /** … … 77 79 /** 78 80 * DEBUG function 79 * Dump the keyboard layout to the release log. The result will only make 80 * sense if the user is using an X.org or XFree86 server locally. 81 * Dump the keyboard layout to the release log. 81 82 */ 82 83 static void dumpLayout(Display *display) 83 84 { 84 LogRel(("Your keyboard layout does not appear to fully supported by VirtualBox. " 85 "If you would like to help us improve the product, please submit a " 86 "bug report and attach this logfile. Please note that the following " 87 "table will only be valid if you are using an X.org or XFree86 server " 88 "locally.\n\nThe correct table for your layout is:\n")); 89 LogRel(("\"")); 90 printKey(display, 49); 91 for (int i = 10; i <= 21; ++i) 92 { 93 LogRel(("\",\"")); 94 printKey(display, i); 85 LogRel(("Your keyboard layout does not appear to fully supported by\n" 86 "VirtualBox. If you would like to help us improve the product,\n" 87 "please submit a bug report and attach this logfile.\n\n" 88 "The correct table for your layout is:\n")); 89 /* First, build up a table of scan-to-key code mappings */ 90 unsigned scanToKeycode[512] = { 0 }; 91 int minKey, maxKey; 92 XDisplayKeycodes(display, &minKey, &maxKey); 93 for (int i = minKey; i < maxKey; ++i) 94 scanToKeycode[X11DRV_KeyEvent(i)] = i; 95 LogRel(("\"")); 96 printKey(display, scanToKeycode[0x29]); /* `~ */ 97 for (int i = 2; i <= 0xd; ++i) /* 1! - =+ */ 98 { 99 LogRel(("\",\"")); 100 printKey(display, scanToKeycode[i]); 95 101 } 96 102 LogRel(("\",\n")); 97 103 LogRel(("\"")); 98 printKey(display, 24);99 for (int i = 25; i <= 35; ++i)100 { 101 LogRel(("\",\"")); 102 printKey(display, i);104 printKey(display, scanToKeycode[0x10]); /* qQ */ 105 for (int i = 0x11; i <= 0x1b; ++i) /* wW - ]} */ 106 { 107 LogRel(("\",\"")); 108 printKey(display, scanToKeycode[i]); 103 109 } 104 110 LogRel(("\",\n")); 105 111 LogRel(("\"")); 106 printKey(display, 38);107 for (int i = 39; i <= 48; ++i)108 { 109 LogRel(("\",\"")); 110 printKey(display, i);111 } 112 LogRel(("\",\"")); 113 printKey(display, 51);112 printKey(display, scanToKeycode[0x1e]); /* aA */ 113 for (int i = 0x1f; i <= 0x28; ++i) /* sS - '" */ 114 { 115 LogRel(("\",\"")); 116 printKey(display, scanToKeycode[i]); 117 } 118 LogRel(("\",\"")); 119 printKey(display, scanToKeycode[0x2b]); /* \| */ 114 120 LogRel(("\",\n")); 115 121 LogRel(("\"")); 116 printKey(display, 52);117 for (int i = 53; i <= 61; ++i)118 { 119 LogRel(("\",\"")); 120 printKey(display, i);121 } 122 LogRel(("\",\"")); 123 printKey(display, 94); /* The 102nd key */124 LogRel(("\",\"")); 125 printKey(display, 211); /* The Brazilian key */126 LogRel(("\",\"")); 127 printKey(display, 133); /* The Yen key */122 printKey(display, scanToKeycode[0x2c]); /* zZ */ 123 for (int i = 0x2d; i <= 0x35; ++i) /* xX - /? */ 124 { 125 LogRel(("\",\"")); 126 printKey(display, scanToKeycode[i]); 127 } 128 LogRel(("\",\"")); 129 printKey(display, scanToKeycode[0x56]); /* The 102nd key */ 130 LogRel(("\",\"")); 131 printKey(display, scanToKeycode[0x73]); /* The Brazilian key */ 132 LogRel(("\",\"")); 133 printKey(display, scanToKeycode[0x7d]); /* The Yen key */ 128 134 LogRel(("\"\n\n")); 135 } 136 137 /** 138 * DEBUG function 139 * Dump the keyboard type tables to the release log. 140 */ 141 static void dumpType(Display *display) 142 { 143 LogRel(("Your keyboard type does not appear to be known to VirtualBox. If\n" 144 "you would like to help us improve the product, please submit a bug\n" 145 "report, attach this logfile and provide information about what type\n" 146 "of keyboard you have and whether you are using a remote X server or\n" 147 "something similar.\n\n" 148 "The tables for your keyboard are:\n")); 149 for (unsigned i = 0; i < 256; ++i) 150 { 151 LogRel(("0x%x", X11DRV_KeyEvent(i))); 152 if (i < 255) 153 LogRel((", ")); 154 if (15 == (i % 16)) 155 LogRel(("\n")); 156 } 157 LogRel(("and\n")); 158 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", 159 XKeysymToKeycode(display, XK_Control_L), 160 XKeysymToKeycode(display, XK_Shift_L), 161 XKeysymToKeycode(display, XK_Caps_Lock), 162 XKeysymToKeycode(display, XK_Tab), 163 XKeysymToKeycode(display, XK_Escape), 164 XKeysymToKeycode(display, XK_Return), 165 XKeysymToKeycode(display, XK_Up), 166 XKeysymToKeycode(display, XK_Down), 167 XKeysymToKeycode(display, XK_Left), 168 XKeysymToKeycode(display, XK_Right), 169 XKeysymToKeycode(display, XK_F1), 170 XKeysymToKeycode(display, XK_F2), 171 XKeysymToKeycode(display, XK_F3), 172 XKeysymToKeycode(display, XK_F4), 173 XKeysymToKeycode(display, XK_F5), 174 XKeysymToKeycode(display, XK_F6), 175 XKeysymToKeycode(display, XK_F7), 176 XKeysymToKeycode(display, XK_F8))); 129 177 } 130 178 … … 140 188 bool initXKeyboard(Display *dpy) 141 189 { 142 if (0 != X11DRV_InitKeyboard(dpy)) 143 { 144 /* The layout found was optimal. */ 145 gInitStatus = true; 146 } 190 X11DRV_InitKeyboard(dpy, &gfByLayoutOK, &gfByTypeOK); 191 /* It will almost always work to some extent */ 147 192 return true; 148 193 } … … 153 198 void doXKeyboardLogging(Display *dpy) 154 199 { 155 if (!gInitStatus) 156 { 200 if ((gfByLayoutOK != 1) && (1 == gfByTypeOK)) 157 201 dumpLayout(dpy); 158 } 202 if ((1 == gfByLayoutOK) && (gfByTypeOK != 1)) 203 dumpType(dpy); 204 if ((gfByLayoutOK != 1) && (gfByTypeOK != 1)) 205 LogRel(("Failed to recognize the keyboard mapping or to guess it based on\n" 206 "the keyboard layout. It is very likely that some keys will not\n" 207 "work correctly in the guest. If you would like to help us improve\n" 208 "the product, please submit a bug report, giving us information\n" 209 "about your keyboard type, its layout and other relevant\n" 210 "information such as whether you are using a remote X server or\n" 211 "something similar.\n")); 159 212 } 160 213 -
trunk/src/VBox/Frontends/VirtualBox/src/linux/keyboard-new.c
r8916 r9991 46 46 #include <stdio.h> 47 47 48 /** 49 * Array containing the current mapping of keycodes to scan codes, detected 50 * using the keyboard layout algorithm in X11DRV_InitKeyboardByLayout. 51 */ 48 52 static unsigned keyc2scan[256]; 53 /** 54 * Whether a keyboard was detected with a well-known keycode to scan code 55 * mapping. 56 */ 57 static unsigned use_builtin_table = 0; 58 /** The index of the well-known keycode to scan code mapping in our table. */ 59 static unsigned builtin_table_number; 60 /** Whether to output basic debugging information to standard output */ 49 61 static int log_kb_1 = 0; 62 /** Whether to output verbose debugging information to standard output */ 50 63 static int log_kb_2 = 0; 51 64 65 /** Output basic debugging information if wished */ 52 66 #define LOG_KB_1(a) \ 53 67 do { \ … … 57 71 } while (0) 58 72 73 /** Output verbose debugging information if wished */ 59 74 #define LOG_KB_2(a) \ 60 75 do { \ … … 64 79 } while (0) 65 80 66 /* Keyboard layout tables for guessing the current keyboard layout. */81 /** Keyboard layout tables for guessing the current keyboard layout. */ 67 82 #include "keyboard-tables.h" 68 83 84 /** Tables of keycode to scan code mappings for well-known keyboard types. */ 85 #include "keyboard-types.h" 86 69 87 /** 70 * Translate a keycode in a key event to a scan code, using the lookup 71 * table which we constructed earlier. 88 * Translate a keycode in a key event to a scan code, using the lookup table 89 * which we constructed earlier or a well-known mapping from our mapping 90 * table. 72 91 * 73 * @returns the scan code number 92 * @returns the scan code number, with 0x100 added for extended scan codes 74 93 * @param code the X11 key code to be looked up 75 94 */ … … 77 96 unsigned X11DRV_KeyEvent(KeyCode code) 78 97 { 79 return keyc2scan[code]; 98 unsigned key; 99 if (use_builtin_table != 0) 100 key = main_keyboard_type_scans[builtin_table_number][code]; 101 else 102 key = keyc2scan[code]; 103 return key; 80 104 } 81 105 82 /********************************************************************** 83 * X11DRV_KEYBOARD_DetectLayout 84 * 85 * Called from X11DRV_InitKeyboard 86 * This routine walks through the defined keyboard layouts and selects 87 * whichever matches most closely. 106 /** 107 * Called from X11DRV_InitKeyboardByLayout 108 * See the comments for that function for a description what this function 109 * does. 88 110 * 89 111 * @returns an index into the table of keyboard layouts, or 0 if absolutely … … 214 236 215 237 /** 216 * Initialise the X11 keyboard driver. In practice, this means building 217 * up an internal table to map X11 keycodes to their equivalent PC scan 218 * codes. 238 * Initialise the X11 keyboard driver by building up a table to convert X11 239 * keycodes to scan codes using a heuristic based on comparing the current 240 * keyboard map to known international keyboard layouts. 241 * The basic idea is to examine each key in the current layout to see which 242 * characters it produces in its normal and its "shifted" state, and to look 243 * for known keyboard layouts which it could belong to. We then guess the 244 * current layout based on the number of matches we find. 245 * One difficulty with this approach is so-called Dvorak layouts, which are 246 * identical to non-Dvorak layouts, but with the keys in a different order. 247 * To deal with this, we compare the different candidate layouts to see in 248 * which one the X11 keycodes would be most sequential and hope that they 249 * really are layed out more or less sequentially. 250 * 251 * The actual detection of the current layout is done in the sub-function 252 * X11DRV_KEYBOARD_DetectLayout. Once we have determined the layout, since we 253 * know which PC scan code corresponds to each key in the layout, we can use 254 * this information to associate the scan code with an X11 keycode, which is 255 * what the rest of this function does. 219 256 * 220 257 * @warning not re-entrant … … 223 260 * @param display a pointer to the X11 display 224 261 */ 225 int X11DRV_InitKeyboard(Display *display) 262 static unsigned 263 X11DRV_InitKeyboardByLayout(Display *display) 226 264 { 227 265 KeySym keysym; … … 332 370 return 1; 333 371 } 372 373 static unsigned 374 X11DRV_InitKeyboardByType(Display *display) 375 { 376 unsigned i = 0, found = 0; 377 378 for (; (main_keyboard_type_list[i].comment != NULL) && (0 == found); ++i) 379 if ( (XKeysymToKeycode(display, XK_Control_L) == main_keyboard_type_list[i].lctrl) 380 && (XKeysymToKeycode(display, XK_Shift_L) == main_keyboard_type_list[i].lshift) 381 && (XKeysymToKeycode(display, XK_Caps_Lock) == main_keyboard_type_list[i].capslock) 382 && (XKeysymToKeycode(display, XK_Tab) == main_keyboard_type_list[i].tab) 383 && (XKeysymToKeycode(display, XK_Escape) == main_keyboard_type_list[i].esc) 384 && (XKeysymToKeycode(display, XK_Return) == main_keyboard_type_list[i].enter) 385 && (XKeysymToKeycode(display, XK_Up) == main_keyboard_type_list[i].up) 386 && (XKeysymToKeycode(display, XK_Down) == main_keyboard_type_list[i].down) 387 && (XKeysymToKeycode(display, XK_Left) == main_keyboard_type_list[i].left) 388 && (XKeysymToKeycode(display, XK_Right) == main_keyboard_type_list[i].right) 389 && (XKeysymToKeycode(display, XK_F1) == main_keyboard_type_list[i].f1) 390 && (XKeysymToKeycode(display, XK_F2) == main_keyboard_type_list[i].f2) 391 && (XKeysymToKeycode(display, XK_F3) == main_keyboard_type_list[i].f3) 392 && (XKeysymToKeycode(display, XK_F4) == main_keyboard_type_list[i].f4) 393 && (XKeysymToKeycode(display, XK_F5) == main_keyboard_type_list[i].f5) 394 && (XKeysymToKeycode(display, XK_F6) == main_keyboard_type_list[i].f6) 395 && (XKeysymToKeycode(display, XK_F7) == main_keyboard_type_list[i].f7) 396 && (XKeysymToKeycode(display, XK_F8) == main_keyboard_type_list[i].f8) 397 ) 398 found = 1; 399 use_builtin_table = found; 400 if (found != 0) 401 builtin_table_number = i - 1; 402 return found; 403 } 404 405 /** 406 * Initialise the X11 keyboard driver by finding which X11 keycodes correspond 407 * to which PC scan codes. If the keyboard being used is not a PC keyboard, 408 * the X11 keycodes will be mapped to the scan codes which the equivalent keys 409 * on a PC keyboard would use. 410 * 411 * We use two algorithms to try to determine the mapping. See the comments 412 * attached to the two algorithm functions (X11DRV_InitKeyboardByLayout and 413 * X11DRV_InitKeyboardByType) for descriptions of the algorithms used. Both 414 * functions tell us on return whether they think that they have correctly 415 * determined the mapping. If both functions claim to have determined the 416 * mapping correctly, we prefer the second (ByType). However, if neither does 417 * then we prefer the first (ByLayout), as it produces a fuzzy result which is 418 * still likely to be partially correct. 419 * 420 * @warning not re-entrant 421 * @returns 1 if the layout found was optimal, 0 if it was not. This is 422 * for diagnostic purposes 423 * @param display a pointer to the X11 display 424 * @param byLayoutOK diagnostic - set to one if detection by layout 425 * succeeded, and to 0 otherwise 426 * @param byTypeOK diagnostic - set to one if detection by type 427 * succeeded, and to 0 otherwise 428 */ 429 unsigned X11DRV_InitKeyboard(Display *display, unsigned *byLayoutOK, unsigned *byTypeOK) 430 { 431 unsigned byLayout = X11DRV_InitKeyboardByLayout(display); 432 unsigned byType = X11DRV_InitKeyboardByType(display); 433 *byLayoutOK = byLayout; 434 *byTypeOK = byType; 435 return (byLayout || byType) ? 1 : 0; 436 } -
trunk/src/VBox/Frontends/VirtualBox/src/linux/keyboard.h
r8214 r9991 35 35 #endif 36 36 #ifdef VBOX_HAVE_VISIBILITY_HIDDEN 37 extern CCALL __attribute__((visibility("default"))) int X11DRV_InitKeyboard(Display *dpy);37 extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK); 38 38 extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_KeyEvent(KeyCode code); 39 39 #else 40 extern CCALL int X11DRV_InitKeyboard(Display *dpy);40 extern CCALL unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK); 41 41 extern CCALL unsigned X11DRV_KeyEvent(KeyCode code); 42 42 #endif
Note:
See TracChangeset
for help on using the changeset viewer.