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