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
keyboardHasKanaLockKey()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
keysymToAWTKeyCode(KeySym x11Key,jint * keycode,Boolean * mapsToUnicodeChar,jint * keyLocation)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
awt_getX11KeySym(jint awtKey)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
handleVendorKeySyms(XEvent * event,KeySym * keysym)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
adjustKeySym(XEvent * event,KeySym * keysym)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
isXsunServer(XEvent * event)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
isXKBenabled(Display * display)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 static Boolean
isKPevent(XEvent * event)822 isKPevent(XEvent *event)
823 {
824 /*
825 * Xlib manual, ch 12.7 says, as a first rule for choice of keysym:
826 * The numlock modifier is on and the second KeySym is a keypad KeySym. In this case,
827 * if the Shift modifier is on, or if the Lock modifier is on and is interpreted as ShiftLock,
828 * then the first KeySym is used, otherwise the second KeySym is used.
829 *
830 * However, Xsun server does ignore ShiftLock and always takes 3-rd element from an array.
831 *
832 * So, is it a keypad keysym?
833 */
834 Boolean bsun = isXsunServer( event );
835 Boolean bxkb = isXKBenabled( event->xkey.display );
836 return IsKeypadKey( XKeycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) );
837 }
838 static void
dumpKeysymArray(XEvent * event)839 dumpKeysymArray(XEvent *event) {
840 printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
841 printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
842 printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
843 printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
844 }
845 /*
846 * In a next redesign, get rid of this code altogether.
847 *
848 */
849 static void
handleKeyEventWithNumLockMask_New(XEvent * event,KeySym * keysym)850 handleKeyEventWithNumLockMask_New(XEvent *event, KeySym *keysym)
851 {
852 KeySym originalKeysym = *keysym;
853 if( !isKPevent( event ) ) {
854 return;
855 }
856 if( isXsunServer( event ) && !awt_UseXKB) {
857 if( (event->xkey.state & ShiftMask) ) { // shift modifier is on
858 *keysym = XKeycodeToKeysym(event->xkey.display,
859 event->xkey.keycode, 3);
860 }else {
861 *keysym = XKeycodeToKeysym(event->xkey.display,
862 event->xkey.keycode, 2);
863 }
864 } else {
865 if( (event->xkey.state & ShiftMask) || // shift modifier is on
866 ((event->xkey.state & LockMask) && // lock modifier is on
867 (awt_ModLockIsShiftLock)) ) { // it is interpreted as ShiftLock
868 *keysym = XKeycodeToKeysym(event->xkey.display,
869 event->xkey.keycode, 0);
870 }else{
871 *keysym = XKeycodeToKeysym(event->xkey.display,
872 event->xkey.keycode, 1);
873 }
874 }
875 }
876
877 /* Called from handleKeyEvent.
878 * The purpose of this function is to make some adjustments to keysyms
879 * that have been found to be necessary when the NumLock mask is set.
880 * They come from various bug fixes and rearchitectures.
881 * This function is meant to be called when
882 * (event->xkey.state & awt_NumLockMask) is TRUE.
883 */
884 static void
handleKeyEventWithNumLockMask(XEvent * event,KeySym * keysym)885 handleKeyEventWithNumLockMask(XEvent *event, KeySym *keysym)
886 {
887 KeySym originalKeysym = *keysym;
888
889 #if !defined(__linux__) && !defined(_ALLBSD_SOURCE)
890 /* The following code on Linux will cause the keypad keys
891 * not to echo on JTextField when the NumLock is on. The
892 * keysyms will be 0, because the last parameter 2 is not defined.
893 * See Xlib Programming Manual, O'Reilly & Associates, Section
894 * 9.1.5 "Other Keyboard-handling Routines", "The meaning of
895 * the keysym list beyond the first two (unmodified, Shift or
896 * Shift Lock) is not defined."
897 */
898
899 /* Translate again with NumLock as modifier. */
900 /* ECH - I wonder why we think that NumLock corresponds to 2?
901 On Linux, we've seen xmodmap -pm yield mod2 as NumLock,
902 but I don't know that it will be for every configuration.
903 Perhaps using the index (modn in awt_MToolkit.c:setup_modifier_map)
904 would be more correct.
905 */
906 *keysym = XKeycodeToKeysym(event->xkey.display,
907 event->xkey.keycode, 2);
908 if (originalKeysym != *keysym) {
909 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x",
910 "In handleKeyEventWithNumLockMask ifndef linux:",
911 originalKeysym, *keysym);
912 }
913 #endif
914
915 /* Note: the XK_R? key assignments are for Type 4 kbds */
916 switch (*keysym) {
917 case XK_R13:
918 *keysym = XK_KP_1;
919 break;
920 case XK_R14:
921 *keysym = XK_KP_2;
922 break;
923 case XK_R15:
924 *keysym = XK_KP_3;
925 break;
926 case XK_R10:
927 *keysym = XK_KP_4;
928 break;
929 case XK_R11:
930 *keysym = XK_KP_5;
931 break;
932 case XK_R12:
933 *keysym = XK_KP_6;
934 break;
935 case XK_R7:
936 *keysym = XK_KP_7;
937 break;
938 case XK_R8:
939 *keysym = XK_KP_8;
940 break;
941 case XK_R9:
942 *keysym = XK_KP_9;
943 break;
944 case XK_KP_Insert:
945 *keysym = XK_KP_0;
946 break;
947 case XK_KP_Delete:
948 *keysym = XK_KP_Decimal;
949 break;
950 case XK_R4:
951 *keysym = XK_KP_Equal; /* Type 4 kbd */
952 break;
953 case XK_R5:
954 *keysym = XK_KP_Divide;
955 break;
956 case XK_R6:
957 *keysym = XK_KP_Multiply;
958 break;
959 /*
960 * Need the following keysym changes for Linux key releases.
961 * Sometimes the modifier state gets messed up, so we get a
962 * KP_Left when we should get a KP_4, for example.
963 * XK_KP_Insert and XK_KP_Delete were already handled above.
964 */
965 case XK_KP_Left:
966 *keysym = XK_KP_4;
967 break;
968 case XK_KP_Up:
969 *keysym = XK_KP_8;
970 break;
971 case XK_KP_Right:
972 *keysym = XK_KP_6;
973 break;
974 case XK_KP_Down:
975 *keysym = XK_KP_2;
976 break;
977 case XK_KP_Home:
978 *keysym = XK_KP_7;
979 break;
980 case XK_KP_End:
981 *keysym = XK_KP_1;
982 break;
983 case XK_KP_Page_Up:
984 *keysym = XK_KP_9;
985 break;
986 case XK_KP_Page_Down:
987 *keysym = XK_KP_3;
988 break;
989 case XK_KP_Begin:
990 *keysym = XK_KP_5;
991 break;
992 default:
993 break;
994 }
995
996 if (originalKeysym != *keysym) {
997 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x",
998 "In handleKeyEventWithNumLockMask:", originalKeysym, *keysym);
999 }
1000 }
1001
1002
1003 /* This function is called as the keyChar parameter of a call to
1004 * awt_post_java_key_event. It depends on being called after adjustKeySym.
1005 *
1006 * This function just handles a few values where we know that the
1007 * keysym is not the same as the unicode value. For values that
1008 * we don't handle explicitly, we just cast the keysym to a jchar.
1009 * Most of the real mapping work that gets the correct keysym is handled
1010 * in the mapping table, adjustKeySym, etc.
1011 *
1012 * XXX
1013 * Maybe we should enumerate the keysyms for which we have a mapping
1014 * in the keyMap, but that don't map to unicode chars, and return
1015 * CHAR_UNDEFINED? Then use the buffer value from XLookupString
1016 * instead of the keysym as the keychar when posting. Then we don't
1017 * need to test using mapsToUnicodeChar. That way, we would post keyTyped
1018 * for all the chars that generate unicode chars, including LATIN2-4, etc.
1019 * Note: what does the buffer from XLookupString contain when
1020 * the character is a non-printable unicode character like Cancel or Delete?
1021 */
1022 jchar
keySymToUnicodeCharacter(KeySym keysym)1023 keySymToUnicodeCharacter(KeySym keysym) {
1024 jchar unicodeValue = (jchar) keysym;
1025
1026 switch (keysym) {
1027 case XK_BackSpace:
1028 case XK_Tab:
1029 case XK_Linefeed:
1030 case XK_Escape:
1031 case XK_Delete:
1032 /* Strip off highorder bits defined in xkeysymdef.h
1033 * I think doing this converts them to values that
1034 * we can cast to jchars and use as java keychars.
1035 */
1036 unicodeValue = (jchar) (keysym & 0x007F);
1037 break;
1038 case XK_Return:
1039 unicodeValue = (jchar) 0x000a; /* the unicode char for Linefeed */
1040 break;
1041 case XK_Cancel:
1042 unicodeValue = (jchar) 0x0018; /* the unicode char for Cancel */
1043 break;
1044 default:
1045 break;
1046 }
1047
1048 if (unicodeValue != (jchar)keysym) {
1049 DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x",
1050 "In keysymToUnicode:", keysym, unicodeValue);
1051 }
1052
1053 return unicodeValue;
1054 }
1055
1056
1057 void
awt_post_java_key_event(JNIEnv * env,jobject peer,jint id,jlong when,jint keyCode,jchar keyChar,jint keyLocation,jint state,XEvent * event)1058 awt_post_java_key_event(JNIEnv *env, jobject peer, jint id,
1059 jlong when, jint keyCode, jchar keyChar, jint keyLocation, jint state, XEvent * event)
1060 {
1061 JNU_CallMethodByName(env, NULL, peer, "postKeyEvent", "(IJICIIJI)V", id,
1062 when, keyCode, keyChar, keyLocation, state, ptr_to_jlong(event), (jint)sizeof(XEvent));
1063 } /* awt_post_java_key_event() */
1064
1065
1066
1067 JNIEXPORT jint JNICALL
Java_sun_awt_X11_XWindow_getAWTKeyCodeForKeySym(JNIEnv * env,jclass clazz,jint keysym)1068 Java_sun_awt_X11_XWindow_getAWTKeyCodeForKeySym(JNIEnv *env, jclass clazz, jint keysym) {
1069 jint keycode = java_awt_event_KeyEvent_VK_UNDEFINED;
1070 Boolean mapsToUnicodeChar;
1071 jint keyLocation;
1072 keysymToAWTKeyCode(keysym, &keycode, &mapsToUnicodeChar, &keyLocation);
1073 return keycode;
1074 }
1075
Java_sun_awt_X11_XWindow_haveCurrentX11InputMethodInstance(JNIEnv * env,jobject object)1076 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XWindow_haveCurrentX11InputMethodInstance
1077 (JNIEnv *env, jobject object) {
1078 /*printf("Java_sun_awt_X11_XWindow_haveCurrentX11InputMethodInstance: %s\n", (currentX11InputMethodInstance==NULL? "NULL":" notnull"));
1079 */
1080 return currentX11InputMethodInstance != NULL ? JNI_TRUE : JNI_FALSE;
1081 }
1082
Java_sun_awt_X11_XWindow_x11inputMethodLookupString(JNIEnv * env,jobject object,jlong event,jlongArray keysymArray)1083 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XWindow_x11inputMethodLookupString
1084 (JNIEnv *env, jobject object, jlong event, jlongArray keysymArray) {
1085 KeySym keysym = NoSymbol;
1086 Boolean boo;
1087 /* keysymArray (and testbuf[]) have dimension 2 because we put there two
1088 * perhaps different values of keysyms.
1089 * XXX: not anymore at the moment, but I'll still keep them as arrays
1090 * for a while. If in the course of testing we will be satisfied with
1091 * a current single result from awt_x11inputmethod_lookupString, we'll
1092 * change this.
1093 */
1094 jlong testbuf[2];
1095
1096 testbuf[1]=0;
1097
1098 boo = awt_x11inputmethod_lookupString((XKeyPressedEvent*)jlong_to_ptr(event), &keysym);
1099 testbuf[0] = keysym;
1100
1101 (*env)->SetLongArrayRegion(env, keysymArray, 0, 2, (jlong *)(testbuf));
1102 return boo ? JNI_TRUE : JNI_FALSE;
1103 }
1104
1105
1106 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
1107
1108 /*
1109 * Class: Java_sun_awt_X11_XWindow_getNativeColor
1110 * Method: getNativeColor
1111 * Signature (Ljava/awt/Color;Ljava/awt/GraphicsConfiguration;)I
1112 */
Java_sun_awt_X11_XWindow_getNativeColor(JNIEnv * env,jobject this,jobject color,jobject gc_object)1113 JNIEXPORT jint JNICALL Java_sun_awt_X11_XWindow_getNativeColor
1114 (JNIEnv *env, jobject this, jobject color, jobject gc_object) {
1115 AwtGraphicsConfigDataPtr adata;
1116 /* fire warning because JNU_GetLongFieldAsPtr casts jlong to (void *) */
1117 adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, gc_object, x11GraphicsConfigIDs.aData);
1118 return awtJNI_GetColorForVis(env, color, adata);
1119 }
1120
1121 /* syncTopLevelPos() is necessary to insure that the window manager has in
1122 * fact moved us to our final position relative to the reParented WM window.
1123 * We have noted a timing window which our shell has not been moved so we
1124 * screw up the insets thinking they are 0,0. Wait (for a limited period of
1125 * time to let the WM hava a chance to move us
1126 */
syncTopLevelPos(Display * d,Window w,XWindowAttributes * winAttr)1127 void syncTopLevelPos( Display *d, Window w, XWindowAttributes *winAttr ) {
1128 int32_t i = 0;
1129 do {
1130 XGetWindowAttributes( d, w, winAttr );
1131 /* Sometimes we get here before the WM has updated the
1132 ** window data struct with the correct position. Loop
1133 ** until we get a non-zero position.
1134 */
1135 if ((winAttr->x != 0) || (winAttr->y != 0)) {
1136 break;
1137 }
1138 else {
1139 /* What we really want here is to sync with the WM,
1140 ** but there's no explicit way to do this, so we
1141 ** call XSync for a delay.
1142 */
1143 XSync(d, False);
1144 }
1145 } while (i++ < 50);
1146 }
1147
getTopWindow(Window win,Window * rootWin)1148 static Window getTopWindow(Window win, Window *rootWin)
1149 {
1150 Window root=None, current_window=win, parent=None, *ignore_children=NULL;
1151 Window prev_window=None;
1152 unsigned int ignore_uint=0;
1153 Status status = 0;
1154
1155 if (win == None) return None;
1156 do {
1157 status = XQueryTree(awt_display,
1158 current_window,
1159 &root,
1160 &parent,
1161 &ignore_children,
1162 &ignore_uint);
1163 XFree(ignore_children);
1164 if (status == 0) return None;
1165 prev_window = current_window;
1166 current_window = parent;
1167 } while (parent != root);
1168 *rootWin = root;
1169 return prev_window;
1170 }
1171
Java_sun_awt_X11_XWindow_getTopWindow(JNIEnv * env,jclass clazz,jlong win,jlong rootWin)1172 JNIEXPORT jlong JNICALL Java_sun_awt_X11_XWindow_getTopWindow
1173 (JNIEnv *env, jclass clazz, jlong win, jlong rootWin) {
1174 return getTopWindow((Window) win, (Window*) jlong_to_ptr(rootWin));
1175 }
1176
1177 static void
getWMInsets(Window window,int * left,int * top,int * right,int * bottom,int * border)1178 getWMInsets
1179 (Window window, int *left, int *top, int *right, int *bottom, int *border) {
1180 // window is event->xreparent.window
1181 Window topWin = None, rootWin = None, containerWindow = None;
1182 XWindowAttributes winAttr, topAttr;
1183 int screenX, screenY;
1184 topWin = getTopWindow(window, &rootWin);
1185 syncTopLevelPos(awt_display, topWin, &topAttr);
1186 // (screenX, screenY) is (0,0) of the reparented window
1187 // converted to screen coordinates.
1188 XTranslateCoordinates(awt_display, window, rootWin,
1189 0,0, &screenX, &screenY, &containerWindow);
1190 *left = screenX - topAttr.x - topAttr.border_width;
1191 *top = screenY - topAttr.y - topAttr.border_width;
1192 XGetWindowAttributes(awt_display, window, &winAttr);
1193 *right = topAttr.width - ((winAttr.width) + *left);
1194 *bottom = topAttr.height - ((winAttr.height) + *top);
1195 *border = topAttr.border_width;
1196 }
1197
Java_sun_awt_X11_XWindow_getWMInsets(JNIEnv * env,jclass clazz,jlong window,jlong left,jlong top,jlong right,jlong bottom,jlong border)1198 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_getWMInsets
1199 (JNIEnv *env, jclass clazz, jlong window, jlong left, jlong top, jlong right, jlong bottom, jlong border) {
1200 getWMInsets((Window) window,
1201 (int*) jlong_to_ptr(left),
1202 (int*) jlong_to_ptr(top),
1203 (int*) jlong_to_ptr(right),
1204 (int*) jlong_to_ptr(bottom),
1205 (int*) jlong_to_ptr(border));
1206 }
1207
1208 static void
getWindowBounds(Window window,int * x,int * y,int * width,int * height)1209 getWindowBounds
1210 (Window window, int *x, int *y, int *width, int *height) {
1211 XWindowAttributes winAttr;
1212 XSync(awt_display, False);
1213 XGetWindowAttributes(awt_display, window, &winAttr);
1214 *x = winAttr.x;
1215 *y = winAttr.y;
1216 *width = winAttr.width;
1217 *height = winAttr.height;
1218 }
1219
Java_sun_awt_X11_XWindow_getWindowBounds(JNIEnv * env,jclass clazz,jlong window,jlong x,jlong y,jlong width,jlong height)1220 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_getWindowBounds
1221 (JNIEnv *env, jclass clazz, jlong window, jlong x, jlong y, jlong width, jlong height) {
1222 getWindowBounds((Window) window, (int*) jlong_to_ptr(x), (int*) jlong_to_ptr(y),
1223 (int*) jlong_to_ptr(width), (int*) jlong_to_ptr(height));
1224 }
1225
Java_sun_awt_X11_XWindow_setSizeHints(JNIEnv * env,jclass clazz,jlong window,jlong x,jlong y,jlong width,jlong height)1226 JNIEXPORT void JNICALL Java_sun_awt_X11_XWindow_setSizeHints
1227 (JNIEnv *env, jclass clazz, jlong window, jlong x, jlong y, jlong width, jlong height) {
1228 XSizeHints *size_hints = XAllocSizeHints();
1229 size_hints->flags = USPosition | PPosition | PSize;
1230 size_hints->x = (int)x;
1231 size_hints->y = (int)y;
1232 size_hints->width = (int)width;
1233 size_hints->height = (int)height;
1234 XSetWMNormalHints(awt_display, (Window)window, size_hints);
1235 XFree((char*)size_hints);
1236 }
1237
1238
1239 JNIEXPORT void JNICALL
Java_sun_awt_X11_XWindow_initIDs(JNIEnv * env,jclass clazz)1240 Java_sun_awt_X11_XWindow_initIDs
1241 (JNIEnv *env, jclass clazz)
1242 {
1243 char *ptr = NULL;
1244 windowID = (*env)->GetFieldID(env, clazz, "window", "J");
1245 CHECK_NULL(windowID);
1246 targetID = (*env)->GetFieldID(env, clazz, "target", "Ljava/awt/Component;");
1247 CHECK_NULL(targetID);
1248 graphicsConfigID = (*env)->GetFieldID(env, clazz, "graphicsConfig", "Lsun/awt/X11GraphicsConfig;");
1249 CHECK_NULL(graphicsConfigID);
1250 drawStateID = (*env)->GetFieldID(env, clazz, "drawState", "I");
1251 CHECK_NULL(drawStateID);
1252 ptr = getenv("_AWT_USE_TYPE4_PATCH");
1253 if( ptr != NULL && ptr[0] != 0 ) {
1254 if( strncmp("true", ptr, 4) == 0 ) {
1255 awt_UseType4Patch = True;
1256 }else if( strncmp("false", ptr, 5) == 0 ) {
1257 awt_UseType4Patch = False;
1258 }
1259 }
1260 }
1261
1262 JNIEXPORT jint JNICALL
Java_sun_awt_X11_XWindow_getKeySymForAWTKeyCode(JNIEnv * env,jclass clazz,jint keycode)1263 Java_sun_awt_X11_XWindow_getKeySymForAWTKeyCode(JNIEnv* env, jclass clazz, jint keycode) {
1264 return awt_getX11KeySym(keycode);
1265 }
1266