1 /* 2 * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* Note that the contents of this file were taken from canvas.c 27 * in the old motif-based AWT. 28 */ 29 30 #ifdef HEADLESS 31 #error This file should not be included in headless library 32 #endif 33 34 #include <X11/Xlib.h> 35 #include <X11/Xutil.h> 36 #include <X11/Xos.h> 37 #include <X11/Xatom.h> 38 #include <ctype.h> 39 40 #include <jvm.h> 41 #include <jni.h> 42 #include <jlong.h> 43 #include <jni_util.h> 44 45 #include "sun_awt_X11_XWindow.h" 46 47 #include "awt_p.h" 48 #include "awt_GraphicsEnv.h" 49 #include "awt_AWTEvent.h" 50 51 #define XK_KATAKANA 52 #include <X11/keysym.h> /* standard X keysyms */ 53 #include <X11/DECkeysym.h> /* DEC vendor-specific */ 54 #include <X11/Sunkeysym.h> /* Sun vendor-specific */ 55 #include <X11/ap_keysym.h> /* Apollo (HP) vendor-specific */ 56 /* 57 * HPKeysym.h is used not only for the hp keysyms, but also to 58 * give us the osf keysyms that are also defined in HPkeysym.h. 59 * However, HPkeysym.h is missing a couple of osf keysyms, 60 * so I have #defined them below. 61 */ 62 #include <X11/HPkeysym.h> /* HP vendor-specific */ 63 64 #include "java_awt_event_KeyEvent.h" 65 #include "java_awt_event_InputEvent.h" 66 #include "java_awt_event_MouseEvent.h" 67 #include "java_awt_event_MouseWheelEvent.h" 68 #include "java_awt_AWTEvent.h" 69 70 /* 71 * Two osf keys are not defined in standard keysym.h, 72 * /Xm/VirtKeys.h, or HPkeysym.h, so I added them below. 73 * I found them in /usr/openwin/lib/X11/XKeysymDB 74 */ 75 #ifndef osfXK_Prior 76 #define osfXK_Prior 0x1004FF55 77 #endif 78 #ifndef osfXK_Next 79 #define osfXK_Next 0x1004FF56 80 #endif 81 82 jfieldID windowID; 83 jfieldID drawStateID; 84 jfieldID targetID; 85 jfieldID graphicsConfigID; 86 87 extern jobject currentX11InputMethodInstance; 88 extern Boolean awt_x11inputmethod_lookupString(XKeyPressedEvent *, KeySym *); 89 Boolean awt_UseType4Patch = False; 90 /* how about HEADLESS */ 91 Boolean awt_ServerDetected = False; 92 Boolean awt_XKBDetected = False; 93 Boolean awt_IsXsun = False; 94 Boolean awt_UseXKB = False; 95 96 typedef struct KEYMAP_ENTRY { 97 jint awtKey; 98 KeySym x11Key; 99 Boolean mapsToUnicodeChar; 100 jint keyLocation; 101 } KeymapEntry; 102 103 /* NB: XK_R? keysyms are for Type 4 keyboards. 104 * The corresponding XK_F? keysyms are for Type 5 105 * 106 * Note: this table must be kept in sorted order, since it is traversed 107 * according to both Java keycode and X keysym. There are a number of 108 * keycodes that map to more than one corresponding keysym, and we need 109 * to choose the right one. Unfortunately, there are some keysyms that 110 * can map to more than one keycode, depending on what kind of keyboard 111 * is in use (e.g. F11 and F12). 112 */ 113 114 KeymapEntry keymapTable[] = 115 { 116 {java_awt_event_KeyEvent_VK_A, XK_a, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 117 {java_awt_event_KeyEvent_VK_B, XK_b, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 118 {java_awt_event_KeyEvent_VK_C, XK_c, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 119 {java_awt_event_KeyEvent_VK_D, XK_d, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 120 {java_awt_event_KeyEvent_VK_E, XK_e, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 121 {java_awt_event_KeyEvent_VK_F, XK_f, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 122 {java_awt_event_KeyEvent_VK_G, XK_g, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 123 {java_awt_event_KeyEvent_VK_H, XK_h, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 124 {java_awt_event_KeyEvent_VK_I, XK_i, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 125 {java_awt_event_KeyEvent_VK_J, XK_j, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 126 {java_awt_event_KeyEvent_VK_K, XK_k, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 127 {java_awt_event_KeyEvent_VK_L, XK_l, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 128 {java_awt_event_KeyEvent_VK_M, XK_m, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 129 {java_awt_event_KeyEvent_VK_N, XK_n, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 130 {java_awt_event_KeyEvent_VK_O, XK_o, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 131 {java_awt_event_KeyEvent_VK_P, XK_p, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 132 {java_awt_event_KeyEvent_VK_Q, XK_q, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 133 {java_awt_event_KeyEvent_VK_R, XK_r, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 134 {java_awt_event_KeyEvent_VK_S, XK_s, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 135 {java_awt_event_KeyEvent_VK_T, XK_t, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 136 {java_awt_event_KeyEvent_VK_U, XK_u, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 137 {java_awt_event_KeyEvent_VK_V, XK_v, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 138 {java_awt_event_KeyEvent_VK_W, XK_w, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 139 {java_awt_event_KeyEvent_VK_X, XK_x, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 140 {java_awt_event_KeyEvent_VK_Y, XK_y, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 141 {java_awt_event_KeyEvent_VK_Z, XK_z, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 142 143 /* TTY Function keys */ 144 {java_awt_event_KeyEvent_VK_BACK_SPACE, XK_BackSpace, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 145 {java_awt_event_KeyEvent_VK_TAB, XK_Tab, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 146 {java_awt_event_KeyEvent_VK_TAB, XK_ISO_Left_Tab, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 147 {java_awt_event_KeyEvent_VK_CLEAR, XK_Clear, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 148 {java_awt_event_KeyEvent_VK_ENTER, XK_Return, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 149 {java_awt_event_KeyEvent_VK_ENTER, XK_Linefeed, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 150 {java_awt_event_KeyEvent_VK_PAUSE, XK_Pause, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 151 {java_awt_event_KeyEvent_VK_PAUSE, XK_F21, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 152 {java_awt_event_KeyEvent_VK_PAUSE, XK_R1, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 153 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, XK_Scroll_Lock, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 154 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, XK_F23, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 155 {java_awt_event_KeyEvent_VK_SCROLL_LOCK, XK_R3, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 156 {java_awt_event_KeyEvent_VK_ESCAPE, XK_Escape, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 157 158 /* Other vendor-specific versions of TTY Function keys */ 159 {java_awt_event_KeyEvent_VK_BACK_SPACE, osfXK_BackSpace, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 160 {java_awt_event_KeyEvent_VK_CLEAR, osfXK_Clear, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 161 {java_awt_event_KeyEvent_VK_ESCAPE, osfXK_Escape, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 162 163 /* Modifier keys */ 164 {java_awt_event_KeyEvent_VK_SHIFT, XK_Shift_L, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_LEFT}, 165 {java_awt_event_KeyEvent_VK_SHIFT, XK_Shift_R, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_RIGHT}, 166 {java_awt_event_KeyEvent_VK_CONTROL, XK_Control_L, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_LEFT}, 167 {java_awt_event_KeyEvent_VK_CONTROL, XK_Control_R, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_RIGHT}, 168 {java_awt_event_KeyEvent_VK_ALT, XK_Alt_L, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_LEFT}, 169 {java_awt_event_KeyEvent_VK_ALT, XK_Alt_R, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_RIGHT}, 170 {java_awt_event_KeyEvent_VK_META, XK_Meta_L, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_LEFT}, 171 {java_awt_event_KeyEvent_VK_META, XK_Meta_R, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_RIGHT}, 172 {java_awt_event_KeyEvent_VK_CAPS_LOCK, XK_Caps_Lock, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 173 {java_awt_event_KeyEvent_VK_CAPS_LOCK, XK_Shift_Lock, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 174 175 /* Misc Functions */ 176 {java_awt_event_KeyEvent_VK_PRINTSCREEN, XK_Print, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 177 {java_awt_event_KeyEvent_VK_PRINTSCREEN, XK_F22, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 178 {java_awt_event_KeyEvent_VK_PRINTSCREEN, XK_R2, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 179 {java_awt_event_KeyEvent_VK_CANCEL, XK_Cancel, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 180 {java_awt_event_KeyEvent_VK_HELP, XK_Help, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 181 {java_awt_event_KeyEvent_VK_NUM_LOCK, XK_Num_Lock, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 182 183 /* Other vendor-specific versions of Misc Functions */ 184 {java_awt_event_KeyEvent_VK_CANCEL, osfXK_Cancel, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 185 {java_awt_event_KeyEvent_VK_HELP, osfXK_Help, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 186 187 /* Rectangular Navigation Block */ 188 {java_awt_event_KeyEvent_VK_HOME, XK_Home, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 189 {java_awt_event_KeyEvent_VK_HOME, XK_R7, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 190 {java_awt_event_KeyEvent_VK_PAGE_UP, XK_Page_Up, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 191 {java_awt_event_KeyEvent_VK_PAGE_UP, XK_Prior, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 192 {java_awt_event_KeyEvent_VK_PAGE_UP, XK_R9, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 193 {java_awt_event_KeyEvent_VK_PAGE_DOWN, XK_Page_Down, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 194 {java_awt_event_KeyEvent_VK_PAGE_DOWN, XK_Next, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 195 {java_awt_event_KeyEvent_VK_PAGE_DOWN, XK_R15, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 196 {java_awt_event_KeyEvent_VK_END, XK_End, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 197 {java_awt_event_KeyEvent_VK_END, XK_R13, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 198 {java_awt_event_KeyEvent_VK_INSERT, XK_Insert, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 199 {java_awt_event_KeyEvent_VK_DELETE, XK_Delete, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 200 201 /* Keypad equivalents of Rectangular Navigation Block */ 202 {java_awt_event_KeyEvent_VK_HOME, XK_KP_Home, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 203 {java_awt_event_KeyEvent_VK_PAGE_UP, XK_KP_Page_Up, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 204 {java_awt_event_KeyEvent_VK_PAGE_UP, XK_KP_Prior, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 205 {java_awt_event_KeyEvent_VK_PAGE_DOWN, XK_KP_Page_Down, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 206 {java_awt_event_KeyEvent_VK_PAGE_DOWN, XK_KP_Next, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 207 {java_awt_event_KeyEvent_VK_END, XK_KP_End, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 208 {java_awt_event_KeyEvent_VK_INSERT, XK_KP_Insert, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 209 {java_awt_event_KeyEvent_VK_DELETE, XK_KP_Delete, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 210 211 /* Other vendor-specific Rectangular Navigation Block */ 212 {java_awt_event_KeyEvent_VK_PAGE_UP, osfXK_PageUp, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 213 {java_awt_event_KeyEvent_VK_PAGE_UP, osfXK_Prior, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 214 {java_awt_event_KeyEvent_VK_PAGE_DOWN, osfXK_PageDown, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 215 {java_awt_event_KeyEvent_VK_PAGE_DOWN, osfXK_Next, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 216 {java_awt_event_KeyEvent_VK_END, osfXK_EndLine, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 217 {java_awt_event_KeyEvent_VK_INSERT, osfXK_Insert, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 218 {java_awt_event_KeyEvent_VK_DELETE, osfXK_Delete, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 219 220 /* Triangular Navigation Block */ 221 {java_awt_event_KeyEvent_VK_LEFT, XK_Left, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 222 {java_awt_event_KeyEvent_VK_UP, XK_Up, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 223 {java_awt_event_KeyEvent_VK_RIGHT, XK_Right, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 224 {java_awt_event_KeyEvent_VK_DOWN, XK_Down, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 225 226 /* Keypad equivalents of Triangular Navigation Block */ 227 {java_awt_event_KeyEvent_VK_KP_LEFT, XK_KP_Left, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 228 {java_awt_event_KeyEvent_VK_KP_UP, XK_KP_Up, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 229 {java_awt_event_KeyEvent_VK_KP_RIGHT, XK_KP_Right, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 230 {java_awt_event_KeyEvent_VK_KP_DOWN, XK_KP_Down, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 231 232 /* Other vendor-specific Triangular Navigation Block */ 233 {java_awt_event_KeyEvent_VK_LEFT, osfXK_Left, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 234 {java_awt_event_KeyEvent_VK_UP, osfXK_Up, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 235 {java_awt_event_KeyEvent_VK_RIGHT, osfXK_Right, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 236 {java_awt_event_KeyEvent_VK_DOWN, osfXK_Down, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 237 238 /* Remaining Cursor control & motion */ 239 {java_awt_event_KeyEvent_VK_BEGIN, XK_Begin, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 240 {java_awt_event_KeyEvent_VK_BEGIN, XK_KP_Begin, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 241 242 {java_awt_event_KeyEvent_VK_0, XK_0, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 243 {java_awt_event_KeyEvent_VK_1, XK_1, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 244 {java_awt_event_KeyEvent_VK_2, XK_2, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 245 {java_awt_event_KeyEvent_VK_3, XK_3, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 246 {java_awt_event_KeyEvent_VK_4, XK_4, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 247 {java_awt_event_KeyEvent_VK_5, XK_5, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 248 {java_awt_event_KeyEvent_VK_6, XK_6, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 249 {java_awt_event_KeyEvent_VK_7, XK_7, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 250 {java_awt_event_KeyEvent_VK_8, XK_8, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 251 {java_awt_event_KeyEvent_VK_9, XK_9, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 252 253 {java_awt_event_KeyEvent_VK_SPACE, XK_space, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 254 {java_awt_event_KeyEvent_VK_EXCLAMATION_MARK, XK_exclam, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 255 {java_awt_event_KeyEvent_VK_QUOTEDBL, XK_quotedbl, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 256 {java_awt_event_KeyEvent_VK_NUMBER_SIGN, XK_numbersign, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 257 {java_awt_event_KeyEvent_VK_DOLLAR, XK_dollar, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 258 {java_awt_event_KeyEvent_VK_AMPERSAND, XK_ampersand, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 259 {java_awt_event_KeyEvent_VK_QUOTE, XK_apostrophe, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 260 {java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS, XK_parenleft, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 261 {java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS, XK_parenright, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 262 {java_awt_event_KeyEvent_VK_ASTERISK, XK_asterisk, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 263 {java_awt_event_KeyEvent_VK_PLUS, XK_plus, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 264 {java_awt_event_KeyEvent_VK_COMMA, XK_comma, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 265 {java_awt_event_KeyEvent_VK_MINUS, XK_minus, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 266 {java_awt_event_KeyEvent_VK_PERIOD, XK_period, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 267 {java_awt_event_KeyEvent_VK_SLASH, XK_slash, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 268 269 {java_awt_event_KeyEvent_VK_COLON, XK_colon, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 270 {java_awt_event_KeyEvent_VK_SEMICOLON, XK_semicolon, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 271 {java_awt_event_KeyEvent_VK_LESS, XK_less, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 272 {java_awt_event_KeyEvent_VK_EQUALS, XK_equal, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 273 {java_awt_event_KeyEvent_VK_GREATER, XK_greater, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 274 275 {java_awt_event_KeyEvent_VK_AT, XK_at, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 276 277 {java_awt_event_KeyEvent_VK_OPEN_BRACKET, XK_bracketleft, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 278 {java_awt_event_KeyEvent_VK_BACK_SLASH, XK_backslash, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 279 {java_awt_event_KeyEvent_VK_CLOSE_BRACKET, XK_bracketright, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 280 {java_awt_event_KeyEvent_VK_CIRCUMFLEX, XK_asciicircum, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 281 {java_awt_event_KeyEvent_VK_UNDERSCORE, XK_underscore, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 282 {java_awt_event_KeyEvent_VK_BACK_QUOTE, XK_grave, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 283 284 {java_awt_event_KeyEvent_VK_BRACELEFT, XK_braceleft, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 285 {java_awt_event_KeyEvent_VK_BRACERIGHT, XK_braceright, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 286 287 {java_awt_event_KeyEvent_VK_INVERTED_EXCLAMATION_MARK, XK_exclamdown, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 288 289 /* Remaining Numeric Keypad Keys */ 290 {java_awt_event_KeyEvent_VK_NUMPAD0, XK_KP_0, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 291 {java_awt_event_KeyEvent_VK_NUMPAD1, XK_KP_1, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 292 {java_awt_event_KeyEvent_VK_NUMPAD2, XK_KP_2, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 293 {java_awt_event_KeyEvent_VK_NUMPAD3, XK_KP_3, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 294 {java_awt_event_KeyEvent_VK_NUMPAD4, XK_KP_4, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 295 {java_awt_event_KeyEvent_VK_NUMPAD5, XK_KP_5, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 296 {java_awt_event_KeyEvent_VK_NUMPAD6, XK_KP_6, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 297 {java_awt_event_KeyEvent_VK_NUMPAD7, XK_KP_7, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 298 {java_awt_event_KeyEvent_VK_NUMPAD8, XK_KP_8, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 299 {java_awt_event_KeyEvent_VK_NUMPAD9, XK_KP_9, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 300 {java_awt_event_KeyEvent_VK_SPACE, XK_KP_Space, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 301 {java_awt_event_KeyEvent_VK_TAB, XK_KP_Tab, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 302 {java_awt_event_KeyEvent_VK_ENTER, XK_KP_Enter, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 303 {java_awt_event_KeyEvent_VK_EQUALS, XK_KP_Equal, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 304 {java_awt_event_KeyEvent_VK_EQUALS, XK_R4, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 305 {java_awt_event_KeyEvent_VK_MULTIPLY, XK_KP_Multiply, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 306 {java_awt_event_KeyEvent_VK_MULTIPLY, XK_F26, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 307 {java_awt_event_KeyEvent_VK_MULTIPLY, XK_R6, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 308 {java_awt_event_KeyEvent_VK_ADD, XK_KP_Add, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 309 {java_awt_event_KeyEvent_VK_SEPARATOR, XK_KP_Separator, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 310 {java_awt_event_KeyEvent_VK_SUBTRACT, XK_KP_Subtract, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 311 {java_awt_event_KeyEvent_VK_SUBTRACT, XK_F24, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 312 {java_awt_event_KeyEvent_VK_DECIMAL, XK_KP_Decimal, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 313 {java_awt_event_KeyEvent_VK_DIVIDE, XK_KP_Divide, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 314 {java_awt_event_KeyEvent_VK_DIVIDE, XK_F25, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 315 {java_awt_event_KeyEvent_VK_DIVIDE, XK_R5, TRUE, java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD}, 316 317 /* Function Keys */ 318 {java_awt_event_KeyEvent_VK_F1, XK_F1, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 319 {java_awt_event_KeyEvent_VK_F2, XK_F2, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 320 {java_awt_event_KeyEvent_VK_F3, XK_F3, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 321 {java_awt_event_KeyEvent_VK_F4, XK_F4, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 322 {java_awt_event_KeyEvent_VK_F5, XK_F5, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 323 {java_awt_event_KeyEvent_VK_F6, XK_F6, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 324 {java_awt_event_KeyEvent_VK_F7, XK_F7, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 325 {java_awt_event_KeyEvent_VK_F8, XK_F8, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 326 {java_awt_event_KeyEvent_VK_F9, XK_F9, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 327 {java_awt_event_KeyEvent_VK_F10, XK_F10, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 328 {java_awt_event_KeyEvent_VK_F11, XK_F11, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 329 {java_awt_event_KeyEvent_VK_F12, XK_F12, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 330 331 /* Sun vendor-specific version of F11 and F12 */ 332 {java_awt_event_KeyEvent_VK_F11, SunXK_F36, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 333 {java_awt_event_KeyEvent_VK_F12, SunXK_F37, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 334 335 /* X11 keysym names for input method related keys don't always 336 * match keytop engravings or Java virtual key names, so here we 337 * only map constants that we've found on real keyboards. 338 */ 339 /* Type 5c Japanese keyboard: kakutei */ 340 {java_awt_event_KeyEvent_VK_ACCEPT, XK_Execute, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 341 /* Type 5c Japanese keyboard: henkan */ 342 {java_awt_event_KeyEvent_VK_CONVERT, XK_Kanji, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 343 /* Type 5c Japanese keyboard: nihongo */ 344 {java_awt_event_KeyEvent_VK_INPUT_METHOD_ON_OFF, XK_Henkan_Mode, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 345 /* VK_KANA_LOCK is handled separately because it generates the 346 * same keysym as ALT_GRAPH in spite of its different behavior. 347 */ 348 349 {java_awt_event_KeyEvent_VK_ALL_CANDIDATES, XK_Zen_Koho, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 350 {java_awt_event_KeyEvent_VK_ALPHANUMERIC, XK_Eisu_Shift, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 351 {java_awt_event_KeyEvent_VK_ALPHANUMERIC, XK_Eisu_toggle, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 352 {java_awt_event_KeyEvent_VK_CODE_INPUT, XK_Kanji_Bangou, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 353 {java_awt_event_KeyEvent_VK_FULL_WIDTH, XK_Zenkaku, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 354 {java_awt_event_KeyEvent_VK_HALF_WIDTH, XK_Hankaku, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 355 {java_awt_event_KeyEvent_VK_HIRAGANA, XK_Hiragana, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 356 {java_awt_event_KeyEvent_VK_JAPANESE_HIRAGANA, XK_Hiragana, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 357 {java_awt_event_KeyEvent_VK_KATAKANA, XK_Katakana, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 358 {java_awt_event_KeyEvent_VK_JAPANESE_KATAKANA, XK_Katakana, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 359 {java_awt_event_KeyEvent_VK_JAPANESE_ROMAN, XK_Romaji, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 360 {java_awt_event_KeyEvent_VK_KANA, XK_Kana_Shift, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 361 {java_awt_event_KeyEvent_VK_KANA_LOCK, XK_Kana_Lock, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 362 {java_awt_event_KeyEvent_VK_KANJI, XK_Kanji, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 363 {java_awt_event_KeyEvent_VK_NONCONVERT, XK_Muhenkan, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 364 {java_awt_event_KeyEvent_VK_PREVIOUS_CANDIDATE, XK_Mae_Koho, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 365 {java_awt_event_KeyEvent_VK_ROMAN_CHARACTERS, XK_Romaji, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 366 367 {java_awt_event_KeyEvent_VK_COMPOSE, XK_Multi_key, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 368 {java_awt_event_KeyEvent_VK_ALT_GRAPH, XK_ISO_Level3_Shift, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 369 370 /* Editing block */ 371 {java_awt_event_KeyEvent_VK_AGAIN, XK_Redo, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 372 {java_awt_event_KeyEvent_VK_AGAIN, XK_L2, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 373 {java_awt_event_KeyEvent_VK_UNDO, XK_Undo, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 374 {java_awt_event_KeyEvent_VK_UNDO, XK_L4, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 375 {java_awt_event_KeyEvent_VK_COPY, XK_L6, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 376 {java_awt_event_KeyEvent_VK_PASTE, XK_L8, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 377 {java_awt_event_KeyEvent_VK_CUT, XK_L10, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 378 {java_awt_event_KeyEvent_VK_FIND, XK_Find, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 379 {java_awt_event_KeyEvent_VK_FIND, XK_L9, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 380 {java_awt_event_KeyEvent_VK_PROPS, XK_L3, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 381 {java_awt_event_KeyEvent_VK_STOP, XK_L1, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 382 383 /* Sun vendor-specific versions for editing block */ 384 {java_awt_event_KeyEvent_VK_AGAIN, SunXK_Again, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 385 {java_awt_event_KeyEvent_VK_UNDO, SunXK_Undo, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 386 {java_awt_event_KeyEvent_VK_COPY, SunXK_Copy, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 387 {java_awt_event_KeyEvent_VK_PASTE, SunXK_Paste, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 388 {java_awt_event_KeyEvent_VK_CUT, SunXK_Cut, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 389 {java_awt_event_KeyEvent_VK_FIND, SunXK_Find, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 390 {java_awt_event_KeyEvent_VK_PROPS, SunXK_Props, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 391 {java_awt_event_KeyEvent_VK_STOP, SunXK_Stop, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 392 393 /* Apollo (HP) vendor-specific versions for editing block */ 394 {java_awt_event_KeyEvent_VK_COPY, apXK_Copy, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 395 {java_awt_event_KeyEvent_VK_CUT, apXK_Cut, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 396 {java_awt_event_KeyEvent_VK_PASTE, apXK_Paste, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 397 398 /* Other vendor-specific versions for editing block */ 399 {java_awt_event_KeyEvent_VK_COPY, osfXK_Copy, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 400 {java_awt_event_KeyEvent_VK_CUT, osfXK_Cut, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 401 {java_awt_event_KeyEvent_VK_PASTE, osfXK_Paste, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 402 {java_awt_event_KeyEvent_VK_UNDO, osfXK_Undo, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 403 404 /* Dead key mappings (for European keyboards) */ 405 {java_awt_event_KeyEvent_VK_DEAD_GRAVE, XK_dead_grave, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 406 {java_awt_event_KeyEvent_VK_DEAD_ACUTE, XK_dead_acute, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 407 {java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX, XK_dead_circumflex, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 408 {java_awt_event_KeyEvent_VK_DEAD_TILDE, XK_dead_tilde, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 409 {java_awt_event_KeyEvent_VK_DEAD_MACRON, XK_dead_macron, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 410 {java_awt_event_KeyEvent_VK_DEAD_BREVE, XK_dead_breve, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 411 {java_awt_event_KeyEvent_VK_DEAD_ABOVEDOT, XK_dead_abovedot, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 412 {java_awt_event_KeyEvent_VK_DEAD_DIAERESIS, XK_dead_diaeresis, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 413 {java_awt_event_KeyEvent_VK_DEAD_ABOVERING, XK_dead_abovering, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 414 {java_awt_event_KeyEvent_VK_DEAD_DOUBLEACUTE, XK_dead_doubleacute, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 415 {java_awt_event_KeyEvent_VK_DEAD_CARON, XK_dead_caron, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 416 {java_awt_event_KeyEvent_VK_DEAD_CEDILLA, XK_dead_cedilla, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 417 {java_awt_event_KeyEvent_VK_DEAD_OGONEK, XK_dead_ogonek, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 418 {java_awt_event_KeyEvent_VK_DEAD_IOTA, XK_dead_iota, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 419 {java_awt_event_KeyEvent_VK_DEAD_VOICED_SOUND, XK_dead_voiced_sound, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 420 {java_awt_event_KeyEvent_VK_DEAD_SEMIVOICED_SOUND, XK_dead_semivoiced_sound, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 421 422 /* Sun vendor-specific dead key mappings (for European keyboards) */ 423 {java_awt_event_KeyEvent_VK_DEAD_GRAVE, SunXK_FA_Grave, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 424 {java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX, SunXK_FA_Circum, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 425 {java_awt_event_KeyEvent_VK_DEAD_TILDE, SunXK_FA_Tilde, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 426 {java_awt_event_KeyEvent_VK_DEAD_ACUTE, SunXK_FA_Acute, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 427 {java_awt_event_KeyEvent_VK_DEAD_DIAERESIS, SunXK_FA_Diaeresis, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 428 {java_awt_event_KeyEvent_VK_DEAD_CEDILLA, SunXK_FA_Cedilla, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 429 430 /* DEC vendor-specific dead key mappings (for European keyboards) */ 431 {java_awt_event_KeyEvent_VK_DEAD_ABOVERING, DXK_ring_accent, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 432 {java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX, DXK_circumflex_accent, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 433 {java_awt_event_KeyEvent_VK_DEAD_CEDILLA, DXK_cedilla_accent, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 434 {java_awt_event_KeyEvent_VK_DEAD_ACUTE, DXK_acute_accent, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 435 {java_awt_event_KeyEvent_VK_DEAD_GRAVE, DXK_grave_accent, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 436 {java_awt_event_KeyEvent_VK_DEAD_TILDE, DXK_tilde, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 437 {java_awt_event_KeyEvent_VK_DEAD_DIAERESIS, DXK_diaeresis, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 438 439 /* Other vendor-specific dead key mappings (for European keyboards) */ 440 {java_awt_event_KeyEvent_VK_DEAD_ACUTE, hpXK_mute_acute, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 441 {java_awt_event_KeyEvent_VK_DEAD_GRAVE, hpXK_mute_grave, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 442 {java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX, hpXK_mute_asciicircum, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 443 {java_awt_event_KeyEvent_VK_DEAD_DIAERESIS, hpXK_mute_diaeresis, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 444 {java_awt_event_KeyEvent_VK_DEAD_TILDE, hpXK_mute_asciitilde, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_STANDARD}, 445 446 {java_awt_event_KeyEvent_VK_UNDEFINED, NoSymbol, FALSE, java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN} 447 }; 448 449 static Boolean 450 keyboardHasKanaLockKey() 451 { 452 static Boolean haveResult = FALSE; 453 static Boolean result = FALSE; 454 455 int32_t minKeyCode, maxKeyCode, keySymsPerKeyCode; 456 KeySym *keySyms, *keySymsStart, keySym; 457 int32_t i; 458 int32_t kanaCount = 0; 459 460 // Solaris doesn't let you swap keyboards without rebooting, 461 // so there's no need to check for the kana lock key more than once. 462 if (haveResult) { 463 return result; 464 } 465 466 // There's no direct way to determine whether the keyboard has 467 // a kana lock key. From available keyboard mapping tables, it looks 468 // like only keyboards with the kana lock key can produce keysyms 469 // for kana characters. So, as an indirect test, we check for those. 470 XDisplayKeycodes(awt_display, &minKeyCode, &maxKeyCode); 471 keySyms = XGetKeyboardMapping(awt_display, minKeyCode, maxKeyCode - minKeyCode + 1, &keySymsPerKeyCode); 472 keySymsStart = keySyms; 473 for (i = 0; i < (maxKeyCode - minKeyCode + 1) * keySymsPerKeyCode; i++) { 474 keySym = *keySyms++; 475 if ((keySym & 0xff00) == 0x0400) { 476 kanaCount++; 477 } 478 } 479 XFree(keySymsStart); 480 481 // use a (somewhat arbitrary) minimum so we don't get confused by a stray function key 482 result = kanaCount > 10; 483 haveResult = TRUE; 484 return result; 485 } 486 487 static void 488 keysymToAWTKeyCode(KeySym x11Key, jint *keycode, Boolean *mapsToUnicodeChar, 489 jint *keyLocation) 490 { 491 int32_t i; 492 493 // Solaris uses XK_Mode_switch for both the non-locking AltGraph 494 // and the locking Kana key, but we want to keep them separate for 495 // KeyEvent. 496 if (x11Key == XK_Mode_switch && keyboardHasKanaLockKey()) { 497 *keycode = java_awt_event_KeyEvent_VK_KANA_LOCK; 498 *mapsToUnicodeChar = FALSE; 499 *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN; 500 return; 501 } 502 503 for (i = 0; 504 keymapTable[i].awtKey != java_awt_event_KeyEvent_VK_UNDEFINED; 505 i++) 506 { 507 if (keymapTable[i].x11Key == x11Key) { 508 *keycode = keymapTable[i].awtKey; 509 *mapsToUnicodeChar = keymapTable[i].mapsToUnicodeChar; 510 *keyLocation = keymapTable[i].keyLocation; 511 return; 512 } 513 } 514 515 *keycode = java_awt_event_KeyEvent_VK_UNDEFINED; 516 *mapsToUnicodeChar = FALSE; 517 *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN; 518 519 DTRACE_PRINTLN1("keysymToAWTKeyCode: no key mapping found: keysym = 0x%x", x11Key); 520 } 521 522 KeySym 523 awt_getX11KeySym(jint awtKey) 524 { 525 int32_t i; 526 527 if (awtKey == java_awt_event_KeyEvent_VK_KANA_LOCK && keyboardHasKanaLockKey()) { 528 return XK_Mode_switch; 529 } 530 531 for (i = 0; keymapTable[i].awtKey != 0; i++) { 532 if (keymapTable[i].awtKey == awtKey) { 533 return keymapTable[i].x11Key; 534 } 535 } 536 537 DTRACE_PRINTLN1("awt_getX11KeySym: no key mapping found: awtKey = 0x%x", awtKey); 538 return NoSymbol; 539 } 540 541 /* Called from handleKeyEvent. The purpose of this function is 542 * to check for a list of vendor-specific keysyms, most of which 543 * have values greater than 0xFFFF. Most of these keys don't map 544 * to unicode characters, but some do. 545 * 546 * For keys that don't map to unicode characters, the keysym 547 * is irrelevant at this point. We set the keysym to zero 548 * to ensure that the switch statement immediately below 549 * this function call (in adjustKeySym) won't incorrectly act 550 * on them after the high bits are stripped off. 551 * 552 * For keys that do map to unicode characters, we change the keysym 553 * to the equivalent that is < 0xFFFF 554 */ 555 static void 556 handleVendorKeySyms(XEvent *event, KeySym *keysym) 557 { 558 KeySym originalKeysym = *keysym; 559 560 switch (*keysym) { 561 /* Apollo (HP) vendor-specific from <X11/ap_keysym.h> */ 562 case apXK_Copy: 563 case apXK_Cut: 564 case apXK_Paste: 565 /* DEC vendor-specific from <X11/DECkeysym.h> */ 566 case DXK_ring_accent: /* syn usldead_ring */ 567 case DXK_circumflex_accent: 568 case DXK_cedilla_accent: /* syn usldead_cedilla */ 569 case DXK_acute_accent: 570 case DXK_grave_accent: 571 case DXK_tilde: 572 case DXK_diaeresis: 573 /* Sun vendor-specific from <X11/Sunkeysym.h> */ 574 case SunXK_FA_Grave: 575 case SunXK_FA_Circum: 576 case SunXK_FA_Tilde: 577 case SunXK_FA_Acute: 578 case SunXK_FA_Diaeresis: 579 case SunXK_FA_Cedilla: 580 case SunXK_F36: /* Labeled F11 */ 581 case SunXK_F37: /* Labeled F12 */ 582 case SunXK_Props: 583 case SunXK_Copy: 584 case SunXK_Open: 585 case SunXK_Paste: 586 case SunXK_Cut: 587 /* Other vendor-specific from HPkeysym.h */ 588 case hpXK_mute_acute: /* syn usldead_acute */ 589 case hpXK_mute_grave: /* syn usldead_grave */ 590 case hpXK_mute_asciicircum: /* syn usldead_asciicircum */ 591 case hpXK_mute_diaeresis: /* syn usldead_diaeresis */ 592 case hpXK_mute_asciitilde: /* syn usldead_asciitilde */ 593 case osfXK_Copy: 594 case osfXK_Cut: 595 case osfXK_Paste: 596 case osfXK_PageUp: 597 case osfXK_PageDown: 598 case osfXK_EndLine: 599 case osfXK_Clear: 600 case osfXK_Left: 601 case osfXK_Up: 602 case osfXK_Right: 603 case osfXK_Down: 604 case osfXK_Prior: 605 case osfXK_Next: 606 case osfXK_Insert: 607 case osfXK_Undo: 608 case osfXK_Help: 609 *keysym = 0; 610 break; 611 /* 612 * The rest DO map to unicode characters, so translate them 613 */ 614 case osfXK_BackSpace: 615 *keysym = XK_BackSpace; 616 break; 617 case osfXK_Escape: 618 *keysym = XK_Escape; 619 break; 620 case osfXK_Cancel: 621 *keysym = XK_Cancel; 622 break; 623 case osfXK_Delete: 624 *keysym = XK_Delete; 625 break; 626 default: 627 break; 628 } 629 630 if (originalKeysym != *keysym) { 631 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x", 632 "In handleVendorKeySyms:", originalKeysym, *keysym); 633 } 634 } 635 636 /* Called from handleKeyEvent. 637 * The purpose of this function is to adjust the keysym and XEvent 638 * keycode for a key event. This is basically a conglomeration of 639 * bugfixes that require these adjustments. 640 * Note that none of the keysyms in this function are less than 256. 641 */ 642 static void 643 adjustKeySym(XEvent *event, KeySym *keysym) 644 { 645 KeySym originalKeysym = *keysym; 646 KeyCode originalKeycode = event->xkey.keycode; 647 648 /* We have seen bits set in the high two bytes on Linux, 649 * which prevents this switch statement from executing 650 * correctly. Strip off the high order bits. 651 */ 652 *keysym &= 0x0000FFFF; 653 654 switch (*keysym) { 655 case XK_ISO_Left_Tab: /* shift-tab on Linux */ 656 *keysym = XK_Tab; 657 break; 658 case XK_KP_Decimal: 659 *keysym = '.'; 660 break; 661 case XK_KP_Add: 662 *keysym = '+'; 663 break; 664 case XK_F24: /* NumLock off */ 665 case XK_KP_Subtract: /* NumLock on */ 666 *keysym = '-'; 667 break; 668 case XK_F25: /* NumLock off */ 669 case XK_KP_Divide: /* NumLock on */ 670 *keysym = '/'; 671 break; 672 case XK_F26: /* NumLock off */ 673 case XK_KP_Multiply: /* NumLock on */ 674 *keysym = '*'; 675 break; 676 case XK_KP_Equal: 677 *keysym = '='; 678 break; 679 case XK_KP_0: 680 *keysym = '0'; 681 break; 682 case XK_KP_1: 683 *keysym = '1'; 684 break; 685 case XK_KP_2: 686 *keysym = '2'; 687 break; 688 case XK_KP_3: 689 *keysym = '3'; 690 break; 691 case XK_KP_4: 692 *keysym = '4'; 693 break; 694 case XK_KP_5: 695 *keysym = '5'; 696 break; 697 case XK_KP_6: 698 *keysym = '6'; 699 break; 700 case XK_KP_7: 701 *keysym = '7'; 702 break; 703 case XK_KP_8: 704 *keysym = '8'; 705 break; 706 case XK_KP_9: 707 *keysym = '9'; 708 break; 709 case XK_KP_Left: /* Bug 4350175 */ 710 *keysym = XK_Left; 711 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 712 break; 713 case XK_KP_Up: 714 *keysym = XK_Up; 715 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 716 break; 717 case XK_KP_Right: 718 *keysym = XK_Right; 719 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 720 break; 721 case XK_KP_Down: 722 *keysym = XK_Down; 723 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 724 break; 725 case XK_KP_Home: 726 *keysym = XK_Home; 727 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 728 break; 729 case XK_KP_End: 730 *keysym = XK_End; 731 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 732 break; 733 case XK_KP_Page_Up: 734 *keysym = XK_Page_Up; 735 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 736 break; 737 case XK_KP_Page_Down: 738 *keysym = XK_Page_Down; 739 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 740 break; 741 case XK_KP_Begin: 742 *keysym = XK_Begin; 743 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 744 break; 745 case XK_KP_Insert: 746 *keysym = XK_Insert; 747 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 748 break; 749 case XK_KP_Delete: 750 *keysym = XK_Delete; 751 event->xkey.keycode = XKeysymToKeycode(awt_display, *keysym); 752 break; 753 case XK_KP_Enter: 754 *keysym = XK_Linefeed; 755 event->xkey.keycode = XKeysymToKeycode(awt_display, XK_Return); 756 break; 757 default: 758 break; 759 } 760 761 if (originalKeysym != *keysym) { 762 DTRACE_PRINTLN2("In adjustKeySym: originalKeysym=0x%x, keysym=0x%x", 763 originalKeysym, *keysym); 764 } 765 if (originalKeycode != event->xkey.keycode) { 766 DTRACE_PRINTLN2("In adjustKeySym: originalKeycode=0x%x, keycode=0x%x", 767 originalKeycode, event->xkey.keycode); 768 } 769 } 770 771 /* 772 * What a sniffer sez? 773 * Xsun and Xorg if NumLock is on do two thing different: 774 * keep Keypad key in different places of keysyms array and 775 * ignore/obey "ModLock is ShiftLock", so we should choose. 776 * People say, it's right to use behavior and not Vendor tags to decide. 777 * Maybe. But why these tags were invented, then? 778 * TODO: use behavior, not tags. Maybe. 779 */ 780 static Boolean 781 isXsunServer(XEvent *event) { 782 if( awt_ServerDetected ) return awt_IsXsun; 783 if( (strncmp( ServerVendor( event->xkey.display ), "Sun Microsystems, Inc.", 22) != 0) && 784 (strncmp( ServerVendor( event->xkey.display ), "Oracle Corporation", 18) != 0) ) 785 { 786 awt_ServerDetected = True; 787 awt_IsXsun = False; 788 return False; 789 } 790 // Now, it's Sun. It still may be Xorg though, eg on Solaris 10, x86. 791 // Today (2005), VendorRelease of Xorg is a Big Number unlike Xsun. 792 if( VendorRelease( event->xkey.display ) > 10000 ) { 793 awt_ServerDetected = True; 794 awt_IsXsun = False; 795 return False; 796 } 797 awt_ServerDetected = True; 798 awt_IsXsun = True; 799 return True; 800 } 801 /* 802 * +kb or -kb ? 803 */ 804 static Boolean 805 isXKBenabled(Display *display) { 806 int mop, beve, berr; 807 if( !awt_XKBDetected ) { 808 /* 809 * NB: TODO: hope it will return False if XkbIgnoreExtension was called! 810 */ 811 awt_UseXKB = XQueryExtension(display, "XKEYBOARD", &mop, &beve, &berr); 812 awt_XKBDetected = True; 813 } 814 return awt_UseXKB; 815 } 816 817 /* 818 * Map a keycode to the corresponding keysym. 819 * This replaces the deprecated X11 function XKeycodeToKeysym 820 */ 821 KeySym 822 keycodeToKeysym(Display *display, KeyCode keycode, int index) { 823 static int min_kc = -1; 824 static int max_kc; 825 if (min_kc == -1) { 826 (void) XDisplayKeycodes(display, &min_kc, &max_kc); 827 } 828 if (keycode < min_kc || keycode > max_kc || index < 0) { 829 return NoSymbol; 830 } 831 int num_syms; 832 KeySym *key_syms = XGetKeyboardMapping(display, keycode, 1, &num_syms); 833 if (index >= num_syms) { 834 XFree(key_syms); 835 return NoSymbol; 836 } 837 KeySym ks = key_syms[index]; 838 XFree(key_syms); 839 return ks; 840 } 841 842 static Boolean 843 isKPevent(XEvent *event) 844 { 845 /* 846 * Xlib manual, ch 12.7 says, as a first rule for choice of keysym: 847 * The numlock modifier is on and the second KeySym is a keypad KeySym. In this case, 848 * if the Shift modifier is on, or if the Lock modifier is on and is interpreted as ShiftLock, 849 * then the first KeySym is used, otherwise the second KeySym is used. 850 * 851 * However, Xsun server does ignore ShiftLock and always takes 3-rd element from an array. 852 * 853 * So, is it a keypad keysym? 854 */ 855 Boolean bsun = isXsunServer( event ); 856 Boolean bxkb = isXKBenabled( event->xkey.display ); 857 return IsKeypadKey( keycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) ); 858 } 859 static void 860 dumpKeysymArray(XEvent *event) { 861 printf(" 0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 0)); 862 printf(" 0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 1)); 863 printf(" 0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 2)); 864 printf(" 0x%lX\n", (unsigned long)keycodeToKeysym(event->xkey.display, event->xkey.keycode, 3)); 865 } 866 /* 867 * In a next redesign, get rid of this code altogether. 868 * 869 */ 870 static void 871 handleKeyEventWithNumLockMask_New(XEvent *event, KeySym *keysym) 872 { 873 KeySym originalKeysym = *keysym; 874 if( !isKPevent( event ) ) { 875 return; 876 } 877 if( isXsunServer( event ) && !awt_UseXKB) { 878 if( (event->xkey.state & ShiftMask) ) { // shift modifier is on 879 *keysym = keycodeToKeysym(event->xkey.display, 880 event->xkey.keycode, 3); 881 }else { 882 *keysym = keycodeToKeysym(event->xkey.display, 883 event->xkey.keycode, 2); 884 } 885 } else { 886 if( (event->xkey.state & ShiftMask) || // shift modifier is on 887 ((event->xkey.state & LockMask) && // lock modifier is on 888 (awt_ModLockIsShiftLock)) ) { // it is interpreted as ShiftLock 889 *keysym = keycodeToKeysym(event->xkey.display, 890 event->xkey.keycode, 0); 891 }else{ 892 *keysym = keycodeToKeysym(event->xkey.display, 893 event->xkey.keycode, 1); 894 } 895 } 896 } 897 898 /* Called from handleKeyEvent. 899 * The purpose of this function is to make some adjustments to keysyms 900 * that have been found to be necessary when the NumLock mask is set. 901 * They come from various bug fixes and rearchitectures. 902 * This function is meant to be called when 903 * (event->xkey.state & awt_NumLockMask) is TRUE. 904 */ 905 static void 906 handleKeyEventWithNumLockMask(XEvent *event, KeySym *keysym) 907 { 908 KeySym originalKeysym = *keysym; 909 910 #if !defined(__linux__) && !defined(MACOSX) 911 /* The following code on Linux will cause the keypad keys 912 * not to echo on JTextField when the NumLock is on. The 913 * keysyms will be 0, because the last parameter 2 is not defined. 914 * See Xlib Programming Manual, O'Reilly & Associates, Section 915 * 9.1.5 "Other Keyboard-handling Routines", "The meaning of 916 * the keysym list beyond the first two (unmodified, Shift or 917 * Shift Lock) is not defined." 918 */ 919 920 /* Translate again with NumLock as modifier. */ 921 /* ECH - I wonder why we think that NumLock corresponds to 2? 922 On Linux, we've seen xmodmap -pm yield mod2 as NumLock, 923 but I don't know that it will be for every configuration. 924 Perhaps using the index (modn in awt_MToolkit.c:setup_modifier_map) 925 would be more correct. 926 */ 927 *keysym = keycodeToKeysym(event->xkey.display, 928 event->xkey.keycode, 2); 929 if (originalKeysym != *keysym) { 930 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x", 931 "In handleKeyEventWithNumLockMask ifndef linux:", 932 originalKeysym, *keysym); 933 } 934 #endif 935 936 /* Note: the XK_R? key assignments are for Type 4 kbds */ 937 switch (*keysym) { 938 case XK_R13: 939 *keysym = XK_KP_1; 940 break; 941 case XK_R14: 942 *keysym = XK_KP_2; 943 break; 944 case XK_R15: 945 *keysym = XK_KP_3; 946 break; 947 case XK_R10: 948 *keysym = XK_KP_4; 949 break; 950 case XK_R11: 951 *keysym = XK_KP_5; 952 break; 953 case XK_R12: 954 *keysym = XK_KP_6; 955 break; 956 case XK_R7: 957 *keysym = XK_KP_7; 958 break; 959 case XK_R8: 960 *keysym = XK_KP_8; 961 break; 962 case XK_R9: 963 *keysym = XK_KP_9; 964 break; 965 case XK_KP_Insert: 966 *keysym = XK_KP_0; 967 break; 968 case XK_KP_Delete: 969 *keysym = XK_KP_Decimal; 970 break; 971 case XK_R4: 972 *keysym = XK_KP_Equal; /* Type 4 kbd */ 973 break; 974 case XK_R5: 975 *keysym = XK_KP_Divide; 976 break; 977 case XK_R6: 978 *keysym = XK_KP_Multiply; 979 break; 980 /* 981 * Need the following keysym changes for Linux key releases. 982 * Sometimes the modifier state gets messed up, so we get a 983 * KP_Left when we should get a KP_4, for example. 984 * XK_KP_Insert and XK_KP_Delete were already handled above. 985 */ 986 case XK_KP_Left: 987 *keysym = XK_KP_4; 988 break; 989 case XK_KP_Up: 990 *keysym = XK_KP_8; 991 break; 992 case XK_KP_Right: 993 *keysym = XK_KP_6; 994 break; 995 case XK_KP_Down: 996 *keysym = XK_KP_2; 997 break; 998 case XK_KP_Home: 999 *keysym = XK_KP_7; 1000 break; 1001 case XK_KP_End: 1002 *keysym = XK_KP_1; 1003 break; 1004 case XK_KP_Page_Up: 1005 *keysym = XK_KP_9; 1006 break; 1007 case XK_KP_Page_Down: 1008 *keysym = XK_KP_3; 1009 break; 1010 case XK_KP_Begin: 1011 *keysym = XK_KP_5; 1012 break; 1013 default: 1014 break; 1015 } 1016 1017 if (originalKeysym != *keysym) { 1018 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x", 1019 "In handleKeyEventWithNumLockMask:", originalKeysym, *keysym); 1020 } 1021 } 1022 1023 /* This function is called as the keyChar parameter of a call to 1024 * awt_post_java_key_event. It depends on being called after adjustKeySym. 1025 * 1026 * This function just handles a few values where we know that the 1027 * keysym is not the same as the unicode value. For values that 1028 * we don't handle explicitly, we just cast the keysym to a jchar. 1029 * Most of the real mapping work that gets the correct keysym is handled 1030 * in the mapping table, adjustKeySym, etc. 1031 * 1032 * XXX 1033 * Maybe we should enumerate the keysyms for which we have a mapping 1034 * in the keyMap, but that don't map to unicode chars, and return 1035 * CHAR_UNDEFINED? Then use the buffer value from XLookupString 1036 * instead of the keysym as the keychar when posting. Then we don't 1037 * need to test using mapsToUnicodeChar. That way, we would post keyTyped 1038 * for all the chars that generate unicode chars, including LATIN2-4, etc. 1039 * Note: what does the buffer from XLookupString contain when 1040 * the character is a non-printable unicode character like Cancel or Delete? 1041 */ 1042 jchar 1043 keySymToUnicodeCharacter(KeySym keysym) { 1044 jchar unicodeValue = (jchar) keysym; 1045 1046 switch (keysym) { 1047 case XK_BackSpace: 1048 case XK_Tab: 1049 case XK_Linefeed: 1050 case XK_Escape: 1051 case XK_Delete: 1052 /* Strip off highorder bits defined in xkeysymdef.h 1053 * I think doing this converts them to values that 1054 * we can cast to jchars and use as java keychars. 1055 */ 1056 unicodeValue = (jchar) (keysym & 0x007F); 1057 break; 1058 case XK_Return: 1059 unicodeValue = (jchar) 0x000a; /* the unicode char for Linefeed */ 1060 break; 1061 case XK_Cancel: 1062 unicodeValue = (jchar) 0x0018; /* the unicode char for Cancel */ 1063 break; 1064 default: 1065 break; 1066 } 1067 1068 if (unicodeValue != (jchar)keysym) { 1069 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x", 1070 "In keysymToUnicode:", keysym, unicodeValue); 1071 } 1072 1073 return unicodeValue; 1074 } 1075 1076 1077 void 1078 awt_post_java_key_event(JNIEnv *env, jobject peer, jint id, 1079 jlong when, jint keyCode, jchar keyChar, jint keyLocation, jint state, XEvent * event) 1080 { 1081 JNU_CallMethodByName(env, NULL, peer, "postKeyEvent", "(IJICIIJI)V", id, 1082 when, keyCode, keyChar, keyLocation, state, ptr_to_jlong(event), (jint)sizeof(XEvent)); 1083 } /* awt_post_java_key_event() */ 1084 1085 1086 1087 JNIEXPORT jint JNICALL 1088 Java_sun_awt_X11_XWindow_getAWTKeyCodeForKeySym(JNIEnv *env, jclass clazz, jint keysym) { 1089 jint keycode = java_awt_event_KeyEvent_VK_UNDEFINED; 1090 Boolean mapsToUnicodeChar; 1091 jint keyLocation; 1092 keysymToAWTKeyCode(keysym, &keycode, &mapsToUnicodeChar, &keyLocation); 1093 return keycode; 1094 } 1095 1096 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XWindow_haveCurrentX11InputMethodInstance 1097 (JNIEnv *env, jobject object) { 1098 /*printf("Java_sun_awt_X11_XWindow_haveCurrentX11InputMethodInstance: %s\n", (currentX11InputMethodInstance==NULL? "NULL":" notnull")); 1099 */ 1100 return currentX11InputMethodInstance != NULL ? JNI_TRUE : JNI_FALSE; 1101 } 1102 1103 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XWindow_x11inputMethodLookupString 1104 (JNIEnv *env, jobject object, jlong event, jlongArray keysymArray) { 1105 KeySym keysym = NoSymbol; 1106 Boolean boo; 1107 /* keysymArray (and testbuf[]) have dimension 2 because we put there two 1108 * perhaps different values of keysyms. 1109 * XXX: not anymore at the moment, but I'll still keep them as arrays 1110 * for a while. If in the course of testing we will be satisfied with 1111 * a current single result from awt_x11inputmethod_lookupString, we'll 1112 * change this. 1113 */ 1114 jlong testbuf[2]; 1115 1116 testbuf[1]=0; 1117 1118 boo = awt_x11inputmethod_lookupString((XKeyPressedEvent*)jlong_to_ptr(event), &keysym); 1119 testbuf[0] = keysym; 1120 1121 (*env)->SetLongArrayRegion(env, keysymArray, 0, 2, (jlong *)(testbuf)); 1122 return boo ? JNI_TRUE : JNI_FALSE; 1123 } 1124 1125 1126 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; 1127 1128 /* 1129 * Class: Java_sun_awt_X11_XWindow_getNativeColor 1130 * Method: getNativeColor 1131 * Signature (Ljava/awt/Color;Ljava/awt/GraphicsConfiguration;)I 1132 */ 1133 JNIEXPORT jint JNICALL Java_sun_awt_X11_XWindow_getNativeColor 1134 (JNIEnv *env, jobject this, jobject color, jobject gc_object) { 1135 AwtGraphicsConfigDataPtr adata; 1136 /* fire warning because JNU_GetLongFieldAsPtr casts jlong to (void *) */ 1137 adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, gc_object, x11GraphicsConfigIDs.aData); 1138 return awtJNI_GetColorForVis(env, color, adata); 1139 } 1140 1141 /* syncTopLevelPos() is necessary to insure that the window manager has in 1142 * fact moved us to our final position relative to the reParented WM window. 1143 * We have noted a timing window which our shell has not been moved so we 1144 * screw up the insets thinking they are 0,0. Wait (for a limited period of 1145 * time to let the WM hava a chance to move us 1146 */ 1147 void syncTopLevelPos( Display *d, Window w, XWindowAttributes *winAttr ) { 1148 int32_t i = 0; 1149 do { 1150 XGetWindowAttributes( d, w, winAttr ); 1151 /* Sometimes we get here before the WM has updated the 1152 ** window data struct with the correct position. Loop 1153 ** until we get a non-zero position. 1154 */ 1155 if ((winAttr->x != 0) || (winAttr->y != 0)) { 1156 break; 1157 } 1158 else { 1159 /* What we really want here is to sync with the WM, 1160 ** but there's no explicit way to do this, so we 1161 ** call XSync for a delay. 1162 */ 1163 XSync(d, False); 1164 } 1165 } while (i++ < 50); 1166 } 1167 1168 static Window getTopWindow(Window win, Window *rootWin) 1169 { 1170 Window root=None, current_window=win, parent=None, *ignore_children=NULL; 1171 Window prev_window=None; 1172 unsigned int ignore_uint=0; 1173 Status status = 0; 1174 1175 if (win == None) return None; 1176 do { 1177 status = XQueryTree(awt_display, 1178 current_window, 1179 &root, 1180 &parent, 1181 &ignore_children, 1182 &ignore_uint); 1183 XFree(ignore_children); 1184 if (status == 0) return None; 1185 prev_window = current_window; 1186 current_window = parent; 1187 } while (parent != root); 1188 *rootWin = root; 1189 return prev_window; 1190 } 1191 1192 JNIEXPORT jlong JNICALL Java_sun_awt_X11_XWindow_getTopWindow 1193 (JNIEnv *env, jclass clazz, jlong win, jlong rootWin) { 1194 return getTopWindow((Window) win, (Window*) jlong_to_ptr(rootWin)); 1195 } 1196 1197 static void 1198 getWMInsets 1199 (Window window, int *left, int *top, int *right, int *bottom, int *border) { 1200 // window is event->xreparent.window 1201 Window topWin = None, rootWin = None, containerWindow = None; 1202 XWindowAttributes winAttr, topAttr; 1203 int screenX, screenY; 1204 topWin = getTopWindow(window, &rootWin); 1205 syncTopLevelPos(awt_display, topWin, &topAttr); 1206 // (screenX, screenY) is (0,0) of the reparented window 1207 // converted to screen coordinates. 1208 XTranslateCoordinates(awt_display, window, rootWin, 1209 0,0, &screenX, &screenY, &containerWindow); 1210 *left = screenX - topAttr.x - topAttr.border_width; 1211 *top = screenY - topAttr.y - topAttr.border_width; 1212 XGetWindowAttributes(awt_display, window, &winAttr); 1213 *right = topAttr.width - ((winAttr.width) + *left); 1214 *bottom = topAttr.height - ((winAttr.height) + *top); 1215 *border = topAttr.border_width; 1216 } 1217 1218 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_getWMInsets 1219 (JNIEnv *env, jclass clazz, jlong window, jlong left, jlong top, jlong right, jlong bottom, jlong border) { 1220 getWMInsets((Window) window, 1221 (int*) jlong_to_ptr(left), 1222 (int*) jlong_to_ptr(top), 1223 (int*) jlong_to_ptr(right), 1224 (int*) jlong_to_ptr(bottom), 1225 (int*) jlong_to_ptr(border)); 1226 } 1227 1228 static void 1229 getWindowBounds 1230 (Window window, int *x, int *y, int *width, int *height) { 1231 XWindowAttributes winAttr; 1232 XSync(awt_display, False); 1233 XGetWindowAttributes(awt_display, window, &winAttr); 1234 *x = winAttr.x; 1235 *y = winAttr.y; 1236 *width = winAttr.width; 1237 *height = winAttr.height; 1238 } 1239 1240 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_getWindowBounds 1241 (JNIEnv *env, jclass clazz, jlong window, jlong x, jlong y, jlong width, jlong height) { 1242 getWindowBounds((Window) window, (int*) jlong_to_ptr(x), (int*) jlong_to_ptr(y), 1243 (int*) jlong_to_ptr(width), (int*) jlong_to_ptr(height)); 1244 } 1245 1246 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_setSizeHints 1247 (JNIEnv *env, jclass clazz, jlong window, jlong x, jlong y, jlong width, jlong height) { 1248 XSizeHints *size_hints = XAllocSizeHints(); 1249 size_hints->flags = USPosition | PPosition | PSize; 1250 size_hints->x = (int)x; 1251 size_hints->y = (int)y; 1252 size_hints->width = (int)width; 1253 size_hints->height = (int)height; 1254 XSetWMNormalHints(awt_display, (Window)window, size_hints); 1255 XFree((char*)size_hints); 1256 } 1257 1258 1259 JNIEXPORT void JNICALL 1260 Java_sun_awt_X11_XWindow_initIDs 1261 (JNIEnv *env, jclass clazz) 1262 { 1263 char *ptr = NULL; 1264 windowID = (*env)->GetFieldID(env, clazz, "window", "J"); 1265 CHECK_NULL(windowID); 1266 targetID = (*env)->GetFieldID(env, clazz, "target", "Ljava/awt/Component;"); 1267 CHECK_NULL(targetID); 1268 graphicsConfigID = (*env)->GetFieldID(env, clazz, "graphicsConfig", "Lsun/awt/X11GraphicsConfig;"); 1269 CHECK_NULL(graphicsConfigID); 1270 drawStateID = (*env)->GetFieldID(env, clazz, "drawState", "I"); 1271 CHECK_NULL(drawStateID); 1272 ptr = getenv("_AWT_USE_TYPE4_PATCH"); 1273 if( ptr != NULL && ptr[0] != 0 ) { 1274 if( strncmp("true", ptr, 4) == 0 ) { 1275 awt_UseType4Patch = True; 1276 }else if( strncmp("false", ptr, 5) == 0 ) { 1277 awt_UseType4Patch = False; 1278 } 1279 } 1280 } 1281 1282 JNIEXPORT jint JNICALL 1283 Java_sun_awt_X11_XWindow_getKeySymForAWTKeyCode(JNIEnv* env, jclass clazz, jint keycode) { 1284 return awt_getX11KeySym(keycode); 1285 }