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