annotate src/solaris/native/sun/xawt/XWindow.c @ 381:b6d6877c1155

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