File: | src/KeyBind.c |
Location: | line 1019, column 5 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | ||||
2 | |||||
3 | Copyright 1985, 1987, 1998 The Open Group | ||||
4 | |||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | ||||
6 | documentation for any purpose is hereby granted without fee, provided that | ||||
7 | the above copyright notice appear in all copies and that both that | ||||
8 | copyright notice and this permission notice appear in supporting | ||||
9 | documentation. | ||||
10 | |||||
11 | The above copyright notice and this permission notice shall be included in | ||||
12 | all copies or substantial portions of the Software. | ||||
13 | |||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | ||||
18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
20 | |||||
21 | Except as contained in this notice, the name of The Open Group shall not be | ||||
22 | used in advertising or otherwise to promote the sale, use or other dealings | ||||
23 | in this Software without prior written authorization from The Open Group. | ||||
24 | |||||
25 | */ | ||||
26 | |||||
27 | /* Beware, here be monsters (still under construction... - JG */ | ||||
28 | |||||
29 | #ifdef HAVE_CONFIG_H1 | ||||
30 | #include <config.h> | ||||
31 | #endif | ||||
32 | #include <X11/Xlibint.h> | ||||
33 | #include <X11/Xutil.h> | ||||
34 | #define XK_MISCELLANY | ||||
35 | #define XK_LATIN1 | ||||
36 | #define XK_LATIN2 | ||||
37 | #define XK_LATIN3 | ||||
38 | #define XK_LATIN4 | ||||
39 | #define XK_LATIN8 | ||||
40 | #define XK_LATIN9 | ||||
41 | #define XK_CYRILLIC | ||||
42 | #define XK_GREEK | ||||
43 | #define XK_ARMENIAN | ||||
44 | #define XK_CAUCASUS | ||||
45 | #define XK_VIETNAMESE | ||||
46 | #define XK_XKB_KEYS | ||||
47 | #define XK_SINHALA | ||||
48 | #include <X11/keysymdef.h> | ||||
49 | #include <stdio.h> | ||||
50 | |||||
51 | #ifdef USE_OWN_COMPOSE | ||||
52 | #include "imComp.h" | ||||
53 | |||||
54 | #endif | ||||
55 | |||||
56 | #include "Xresource.h" | ||||
57 | #include "Key.h" | ||||
58 | |||||
59 | #ifdef XKB1 | ||||
60 | #include "XKBlib.h" | ||||
61 | #include "XKBlibint.h" | ||||
62 | #define XKeycodeToKeysym_XKeycodeToKeysym _XKeycodeToKeysym | ||||
63 | #define XKeysymToKeycode_XKeysymToKeycode _XKeysymToKeycode | ||||
64 | #define XLookupKeysym_XLookupKeysym _XLookupKeysym | ||||
65 | #define XRefreshKeyboardMapping_XRefreshKeyboardMapping _XRefreshKeyboardMapping | ||||
66 | #define XLookupString_XLookupString _XLookupString | ||||
67 | /* XKBBind.c */ | ||||
68 | #else | ||||
69 | #define XkbKeysymToModifiers _XKeysymToModifiers | ||||
70 | #endif | ||||
71 | |||||
72 | #define AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7)) (ShiftMask(1<<0)|LockMask(1<<1)|ControlMask(1<<2)| \ | ||||
73 | Mod1Mask(1<<3)|Mod2Mask(1<<4)|Mod3Mask(1<<5)|Mod4Mask(1<<6)|Mod5Mask(1<<7)) | ||||
74 | |||||
75 | static void | ||||
76 | ComputeMaskFromKeytrans( | ||||
77 | Display *dpy, | ||||
78 | register struct _XKeytrans *p); | ||||
79 | |||||
80 | struct _XKeytrans { | ||||
81 | struct _XKeytrans *next;/* next on list */ | ||||
82 | char *string; /* string to return when the time comes */ | ||||
83 | int len; /* length of string (since NULL is legit)*/ | ||||
84 | KeySym key; /* keysym rebound */ | ||||
85 | unsigned int state; /* modifier state */ | ||||
86 | KeySym *modifiers; /* modifier keysyms you want */ | ||||
87 | int mlen; /* length of modifier list */ | ||||
88 | }; | ||||
89 | |||||
90 | static KeySym | ||||
91 | KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col) | ||||
92 | { | ||||
93 | register int per = dpy->keysyms_per_keycode; | ||||
94 | register KeySym *syms; | ||||
95 | KeySym lsym, usym; | ||||
96 | |||||
97 | if ((col < 0) || ((col >= per) && (col > 3)) || | ||||
98 | ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) | ||||
99 | return NoSymbol0L; | ||||
100 | |||||
101 | syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; | ||||
102 | if (col < 4) { | ||||
103 | if (col > 1) { | ||||
104 | while ((per > 2) && (syms[per - 1] == NoSymbol0L)) | ||||
105 | per--; | ||||
106 | if (per < 3) | ||||
107 | col -= 2; | ||||
108 | } | ||||
109 | if ((per <= (col|1)) || (syms[col|1] == NoSymbol0L)) { | ||||
110 | XConvertCase(syms[col&~1], &lsym, &usym); | ||||
111 | if (!(col & 1)) | ||||
112 | return lsym; | ||||
113 | else if (usym == lsym) | ||||
114 | return NoSymbol0L; | ||||
115 | else | ||||
116 | return usym; | ||||
117 | } | ||||
118 | } | ||||
119 | return syms[col]; | ||||
120 | } | ||||
121 | |||||
122 | KeySym | ||||
123 | XKeycodeToKeysym_XKeycodeToKeysym(Display *dpy, | ||||
124 | #if NeedWidePrototypes0 | ||||
125 | unsigned int kc, | ||||
126 | #else | ||||
127 | KeyCode kc, | ||||
128 | #endif | ||||
129 | int col) | ||||
130 | { | ||||
131 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | ||||
132 | return NoSymbol0L; | ||||
133 | return KeyCodetoKeySym(dpy, kc, col); | ||||
134 | } | ||||
135 | |||||
136 | KeyCode | ||||
137 | XKeysymToKeycode_XKeysymToKeycode( | ||||
138 | Display *dpy, | ||||
139 | KeySym ks) | ||||
140 | { | ||||
141 | register int i, j; | ||||
142 | |||||
143 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | ||||
144 | return (KeyCode) 0; | ||||
145 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | ||||
146 | for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { | ||||
147 | if (KeyCodetoKeySym(dpy, (KeyCode) i, j) == ks) | ||||
148 | return i; | ||||
149 | } | ||||
150 | } | ||||
151 | return 0; | ||||
152 | } | ||||
153 | |||||
154 | KeySym | ||||
155 | XLookupKeysym_XLookupKeysym( | ||||
156 | register XKeyEvent *event, | ||||
157 | int col) | ||||
158 | { | ||||
159 | if ((! event->display->keysyms) && (! _XKeyInitialize(event->display))) | ||||
160 | return NoSymbol0L; | ||||
161 | return KeyCodetoKeySym(event->display, event->keycode, col); | ||||
162 | } | ||||
163 | |||||
164 | static void | ||||
165 | ResetModMap( | ||||
166 | Display *dpy) | ||||
167 | { | ||||
168 | register XModifierKeymap *map; | ||||
169 | register int i, j, n; | ||||
170 | KeySym sym; | ||||
171 | register struct _XKeytrans *p; | ||||
172 | |||||
173 | map = dpy->modifiermap; | ||||
174 | /* If any Lock key contains Caps_Lock, then interpret as Caps_Lock, | ||||
175 | * else if any contains Shift_Lock, then interpret as Shift_Lock, | ||||
176 | * else ignore Lock altogether. | ||||
177 | */ | ||||
178 | dpy->lock_meaning = NoSymbol0L; | ||||
179 | /* Lock modifiers are in the second row of the matrix */ | ||||
180 | n = 2 * map->max_keypermod; | ||||
181 | for (i = map->max_keypermod; i < n; i++) { | ||||
182 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | ||||
183 | sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); | ||||
184 | if (sym == XK_Caps_Lock0xffe5) { | ||||
185 | dpy->lock_meaning = XK_Caps_Lock0xffe5; | ||||
186 | break; | ||||
187 | } else if (sym == XK_Shift_Lock0xffe6) { | ||||
188 | dpy->lock_meaning = XK_Shift_Lock0xffe6; | ||||
189 | } | ||||
190 | else if (sym == XK_ISO_Lock0xfe01) { | ||||
191 | dpy->lock_meaning = XK_Caps_Lock0xffe5; | ||||
192 | break; | ||||
193 | } | ||||
194 | } | ||||
195 | } | ||||
196 | /* Now find any Mod<n> modifier acting as the Group or Numlock modifier */ | ||||
197 | dpy->mode_switch = 0; | ||||
198 | dpy->num_lock = 0; | ||||
199 | n *= 4; | ||||
200 | for (i = 3*map->max_keypermod; i < n; i++) { | ||||
201 | for (j = 0; j < dpy->keysyms_per_keycode; j++) { | ||||
202 | sym = KeyCodetoKeySym(dpy, map->modifiermap[i], j); | ||||
203 | if (sym == XK_Mode_switch0xff7e) | ||||
204 | dpy->mode_switch |= 1 << (i / map->max_keypermod); | ||||
205 | if (sym == XK_Num_Lock0xff7f) | ||||
206 | dpy->num_lock |= 1 << (i / map->max_keypermod); | ||||
207 | } | ||||
208 | } | ||||
209 | for (p = dpy->key_bindings; p; p = p->next) | ||||
210 | ComputeMaskFromKeytrans(dpy, p); | ||||
211 | } | ||||
212 | |||||
213 | static int | ||||
214 | InitModMap( | ||||
215 | Display *dpy) | ||||
216 | { | ||||
217 | register XModifierKeymap *map; | ||||
218 | |||||
219 | if (! (map = XGetModifierMapping(dpy))) | ||||
220 | return 0; | ||||
221 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
222 | if (dpy->modifiermap) | ||||
223 | XFreeModifiermap(dpy->modifiermap); | ||||
224 | dpy->modifiermap = map; | ||||
225 | dpy->free_funcs->modifiermap = XFreeModifiermap; | ||||
226 | if (dpy->keysyms) | ||||
227 | ResetModMap(dpy); | ||||
228 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
229 | return 1; | ||||
230 | } | ||||
231 | |||||
232 | int | ||||
233 | XRefreshKeyboardMapping_XRefreshKeyboardMapping(register XMappingEvent *event) | ||||
234 | { | ||||
235 | |||||
236 | if(event->request == MappingKeyboard1) { | ||||
237 | /* XXX should really only refresh what is necessary | ||||
238 | * for now, make initialize test fail | ||||
239 | */ | ||||
240 | LockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->lock_display)(event->display); | ||||
241 | if (event->display->keysyms) { | ||||
242 | Xfree ((char *)event->display->keysyms)free(((char *)event->display->keysyms)); | ||||
243 | event->display->keysyms = NULL((void*)0); | ||||
244 | } | ||||
245 | UnlockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->unlock_display)(event->display); | ||||
246 | } | ||||
247 | if(event->request == MappingModifier0) { | ||||
248 | LockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->lock_display)(event->display); | ||||
249 | if (event->display->modifiermap) { | ||||
250 | XFreeModifiermap(event->display->modifiermap); | ||||
251 | event->display->modifiermap = NULL((void*)0); | ||||
252 | } | ||||
253 | UnlockDisplay(event->display)if ((event->display)->lock_fns) (*(event->display)-> lock_fns->unlock_display)(event->display); | ||||
254 | /* go ahead and get it now, since initialize test may not fail */ | ||||
255 | if (event->display->keysyms) | ||||
256 | (void) InitModMap(event->display); | ||||
257 | } | ||||
258 | return 1; | ||||
259 | } | ||||
260 | |||||
261 | int | ||||
262 | _XKeyInitialize( | ||||
263 | Display *dpy) | ||||
264 | { | ||||
265 | int per, n; | ||||
266 | KeySym *keysyms; | ||||
267 | |||||
268 | /* | ||||
269 | * lets go get the keysyms from the server. | ||||
270 | */ | ||||
271 | if (!dpy->keysyms) { | ||||
272 | n = dpy->max_keycode - dpy->min_keycode + 1; | ||||
273 | keysyms = XGetKeyboardMapping (dpy, (KeyCode) dpy->min_keycode, | ||||
274 | n, &per); | ||||
275 | /* keysyms may be NULL */ | ||||
276 | if (! keysyms) return 0; | ||||
277 | |||||
278 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
279 | if (dpy->keysyms) | ||||
280 | Xfree ((char *)dpy->keysyms)free(((char *)dpy->keysyms)); | ||||
281 | dpy->keysyms = keysyms; | ||||
282 | dpy->keysyms_per_keycode = per; | ||||
283 | if (dpy->modifiermap) | ||||
284 | ResetModMap(dpy); | ||||
285 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
286 | } | ||||
287 | if (!dpy->modifiermap) | ||||
288 | return InitModMap(dpy); | ||||
289 | return 1; | ||||
290 | } | ||||
291 | |||||
292 | static void | ||||
293 | UCSConvertCase( register unsigned code, | ||||
294 | KeySym *lower, | ||||
295 | KeySym *upper ) | ||||
296 | { | ||||
297 | /* Case conversion for UCS, as in Unicode Data version 4.0.0 */ | ||||
298 | /* NB: Only converts simple one-to-one mappings. */ | ||||
299 | |||||
300 | /* Tables are used where they take less space than */ | ||||
301 | /* the code to work out the mappings. Zero values mean */ | ||||
302 | /* undefined code points. */ | ||||
303 | |||||
304 | static unsigned short const IPAExt_upper_mapping[] = { /* part only */ | ||||
305 | 0x0181, 0x0186, 0x0255, 0x0189, 0x018A, | ||||
306 | 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F, | ||||
307 | 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, | ||||
308 | 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C, | ||||
309 | 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277, | ||||
310 | 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, | ||||
311 | 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287, | ||||
312 | 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F, | ||||
313 | 0x0290, 0x0291, 0x01B7 | ||||
314 | }; | ||||
315 | |||||
316 | static unsigned short const LatinExtB_upper_mapping[] = { /* first part only */ | ||||
317 | 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, | ||||
318 | 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F, | ||||
319 | 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197, | ||||
320 | 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F, | ||||
321 | 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7, | ||||
322 | 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF, | ||||
323 | 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7, | ||||
324 | 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7, | ||||
325 | 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7, | ||||
326 | 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA | ||||
327 | }; | ||||
328 | |||||
329 | static unsigned short const LatinExtB_lower_mapping[] = { /* first part only */ | ||||
330 | 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, | ||||
331 | 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, | ||||
332 | 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, | ||||
333 | 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, | ||||
334 | 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, | ||||
335 | 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, | ||||
336 | 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, | ||||
337 | 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, | ||||
338 | 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, | ||||
339 | 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC | ||||
340 | }; | ||||
341 | |||||
342 | static unsigned short const Greek_upper_mapping[] = { | ||||
343 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, | ||||
344 | 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, | ||||
345 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387, | ||||
346 | 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F, | ||||
347 | 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, | ||||
348 | 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, | ||||
349 | 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, | ||||
350 | 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A, | ||||
351 | 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, | ||||
352 | 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, | ||||
353 | 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, | ||||
354 | 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000, | ||||
355 | 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7, | ||||
356 | 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE, | ||||
357 | 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6, | ||||
358 | 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE, | ||||
359 | 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7, | ||||
360 | 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000 | ||||
361 | }; | ||||
362 | |||||
363 | static unsigned short const Greek_lower_mapping[] = { | ||||
364 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, | ||||
365 | 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, | ||||
366 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387, | ||||
367 | 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, | ||||
368 | 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, | ||||
369 | 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, | ||||
370 | 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, | ||||
371 | 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, | ||||
372 | 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, | ||||
373 | 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, | ||||
374 | 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, | ||||
375 | 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, | ||||
376 | 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, | ||||
377 | 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, | ||||
378 | 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, | ||||
379 | 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, | ||||
380 | 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8, | ||||
381 | 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000 | ||||
382 | }; | ||||
383 | |||||
384 | static unsigned short const GreekExt_lower_mapping[] = { | ||||
385 | 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, | ||||
386 | 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, | ||||
387 | 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, | ||||
388 | 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, | ||||
389 | 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, | ||||
390 | 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, | ||||
391 | 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, | ||||
392 | 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, | ||||
393 | 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, | ||||
394 | 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, | ||||
395 | 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, | ||||
396 | 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57, | ||||
397 | 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, | ||||
398 | 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, | ||||
399 | 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, | ||||
400 | 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000, | ||||
401 | 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, | ||||
402 | 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, | ||||
403 | 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, | ||||
404 | 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, | ||||
405 | 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, | ||||
406 | 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, | ||||
407 | 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, | ||||
408 | 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF, | ||||
409 | 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, | ||||
410 | 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, | ||||
411 | 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, | ||||
412 | 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, | ||||
413 | 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, | ||||
414 | 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, | ||||
415 | 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, | ||||
416 | 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000 | ||||
417 | }; | ||||
418 | |||||
419 | static unsigned short const GreekExt_upper_mapping[] = { | ||||
420 | 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, | ||||
421 | 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, | ||||
422 | 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, | ||||
423 | 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, | ||||
424 | 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, | ||||
425 | 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, | ||||
426 | 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, | ||||
427 | 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, | ||||
428 | 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, | ||||
429 | 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, | ||||
430 | 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F, | ||||
431 | 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, | ||||
432 | 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, | ||||
433 | 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, | ||||
434 | 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, | ||||
435 | 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000, | ||||
436 | 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, | ||||
437 | 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, | ||||
438 | 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, | ||||
439 | 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, | ||||
440 | 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, | ||||
441 | 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, | ||||
442 | 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, | ||||
443 | 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF, | ||||
444 | 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, | ||||
445 | 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF, | ||||
446 | 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, | ||||
447 | 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, | ||||
448 | 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7, | ||||
449 | 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF, | ||||
450 | 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, | ||||
451 | 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000 | ||||
452 | }; | ||||
453 | |||||
454 | *lower = code; | ||||
455 | *upper = code; | ||||
456 | |||||
457 | /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */ | ||||
458 | if (code <= 0x00ff) { | ||||
459 | if (code >= 0x0041 && code <= 0x005a) /* A-Z */ | ||||
460 | *lower += 0x20; | ||||
461 | else if (code >= 0x0061 && code <= 0x007a) /* a-z */ | ||||
462 | *upper -= 0x20; | ||||
463 | else if ( (code >= 0x00c0 && code <= 0x00d6) || | ||||
464 | (code >= 0x00d8 && code <= 0x00de) ) | ||||
465 | *lower += 0x20; | ||||
466 | else if ( (code >= 0x00e0 && code <= 0x00f6) || | ||||
467 | (code >= 0x00f8 && code <= 0x00fe) ) | ||||
468 | *upper -= 0x20; | ||||
469 | else if (code == 0x00ff) /* y with diaeresis */ | ||||
470 | *upper = 0x0178; | ||||
471 | else if (code == 0x00b5) /* micro sign */ | ||||
472 | *upper = 0x039c; | ||||
473 | return; | ||||
474 | } | ||||
475 | |||||
476 | /* Latin Extended-A, U+0100 to U+017F */ | ||||
477 | if (code >= 0x0100 && code <= 0x017f) { | ||||
478 | if ( (code >= 0x0100 && code <= 0x012f) || | ||||
479 | (code >= 0x0132 && code <= 0x0137) || | ||||
480 | (code >= 0x014a && code <= 0x0177) ) { | ||||
481 | *upper = code & ~1; | ||||
482 | *lower = code | 1; | ||||
483 | } | ||||
484 | else if ( (code >= 0x0139 && code <= 0x0148) || | ||||
485 | (code >= 0x0179 && code <= 0x017e) ) { | ||||
486 | if (code & 1) | ||||
487 | *lower += 1; | ||||
488 | else | ||||
489 | *upper -= 1; | ||||
490 | } | ||||
491 | else if (code == 0x0130) | ||||
492 | *lower = 0x0069; | ||||
493 | else if (code == 0x0131) | ||||
494 | *upper = 0x0049; | ||||
495 | else if (code == 0x0178) | ||||
496 | *lower = 0x00ff; | ||||
497 | else if (code == 0x017f) | ||||
498 | *upper = 0x0053; | ||||
499 | return; | ||||
500 | } | ||||
501 | |||||
502 | /* Latin Extended-B, U+0180 to U+024F */ | ||||
503 | if (code >= 0x0180 && code <= 0x024f) { | ||||
504 | if (code >= 0x01cd && code <= 0x01dc) { | ||||
505 | if (code & 1) | ||||
506 | *lower += 1; | ||||
507 | else | ||||
508 | *upper -= 1; | ||||
509 | } | ||||
510 | else if ( (code >= 0x01de && code <= 0x01ef) || | ||||
511 | (code >= 0x01f4 && code <= 0x01f5) || | ||||
512 | (code >= 0x01f8 && code <= 0x021f) || | ||||
513 | (code >= 0x0222 && code <= 0x0233) ) { | ||||
514 | *lower |= 1; | ||||
515 | *upper &= ~1; | ||||
516 | } | ||||
517 | else if (code >= 0x0180 && code <= 0x01cc) { | ||||
518 | *lower = LatinExtB_lower_mapping[code - 0x0180]; | ||||
519 | *upper = LatinExtB_upper_mapping[code - 0x0180]; | ||||
520 | } | ||||
521 | else if (code == 0x01dd) | ||||
522 | *upper = 0x018e; | ||||
523 | else if (code == 0x01f1 || code == 0x01f2) { | ||||
524 | *lower = 0x01f3; | ||||
525 | *upper = 0x01f1; | ||||
526 | } | ||||
527 | else if (code == 0x01f3) | ||||
528 | *upper = 0x01f1; | ||||
529 | else if (code == 0x01f6) | ||||
530 | *lower = 0x0195; | ||||
531 | else if (code == 0x01f7) | ||||
532 | *lower = 0x01bf; | ||||
533 | else if (code == 0x0220) | ||||
534 | *lower = 0x019e; | ||||
535 | return; | ||||
536 | } | ||||
537 | |||||
538 | /* IPA Extensions, U+0250 to U+02AF */ | ||||
539 | if (code >= 0x0253 && code <= 0x0292) { | ||||
540 | *upper = IPAExt_upper_mapping[code - 0x0253]; | ||||
541 | } | ||||
542 | |||||
543 | /* Combining Diacritical Marks, U+0300 to U+036F */ | ||||
544 | if (code == 0x0345) { | ||||
545 | *upper = 0x0399; | ||||
546 | } | ||||
547 | |||||
548 | /* Greek and Coptic, U+0370 to U+03FF */ | ||||
549 | if (code >= 0x0370 && code <= 0x03ff) { | ||||
550 | *lower = Greek_lower_mapping[code - 0x0370]; | ||||
551 | *upper = Greek_upper_mapping[code - 0x0370]; | ||||
552 | if (*upper == 0) | ||||
553 | *upper = code; | ||||
554 | if (*lower == 0) | ||||
555 | *lower = code; | ||||
556 | } | ||||
557 | |||||
558 | /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */ | ||||
559 | if ( (code >= 0x0400 && code <= 0x04ff) || | ||||
560 | (code >= 0x0500 && code <= 0x052f) ) { | ||||
561 | if (code >= 0x0400 && code <= 0x040f) | ||||
562 | *lower += 0x50; | ||||
563 | else if (code >= 0x0410 && code <= 0x042f) | ||||
564 | *lower += 0x20; | ||||
565 | else if (code >= 0x0430 && code <= 0x044f) | ||||
566 | *upper -= 0x20; | ||||
567 | else if (code >= 0x0450 && code <= 0x045f) | ||||
568 | *upper -= 0x50; | ||||
569 | else if ( (code >= 0x0460 && code <= 0x0481) || | ||||
570 | (code >= 0x048a && code <= 0x04bf) || | ||||
571 | (code >= 0x04d0 && code <= 0x04f5) || | ||||
572 | (code >= 0x04f8 && code <= 0x04f9) || | ||||
573 | (code >= 0x0500 && code <= 0x050f) ) { | ||||
574 | *upper &= ~1; | ||||
575 | *lower |= 1; | ||||
576 | } | ||||
577 | else if (code >= 0x04c1 && code <= 0x04ce) { | ||||
578 | if (code & 1) | ||||
579 | *lower += 1; | ||||
580 | else | ||||
581 | *upper -= 1; | ||||
582 | } | ||||
583 | } | ||||
584 | |||||
585 | /* Armenian, U+0530 to U+058F */ | ||||
586 | if (code >= 0x0530 && code <= 0x058f) { | ||||
587 | if (code >= 0x0531 && code <= 0x0556) | ||||
588 | *lower += 0x30; | ||||
589 | else if (code >=0x0561 && code <= 0x0586) | ||||
590 | *upper -= 0x30; | ||||
591 | } | ||||
592 | |||||
593 | /* Latin Extended Additional, U+1E00 to U+1EFF */ | ||||
594 | if (code >= 0x1e00 && code <= 0x1eff) { | ||||
595 | if ( (code >= 0x1e00 && code <= 0x1e95) || | ||||
596 | (code >= 0x1ea0 && code <= 0x1ef9) ) { | ||||
597 | *upper &= ~1; | ||||
598 | *lower |= 1; | ||||
599 | } | ||||
600 | else if (code == 0x1e9b) | ||||
601 | *upper = 0x1e60; | ||||
602 | } | ||||
603 | |||||
604 | /* Greek Extended, U+1F00 to U+1FFF */ | ||||
605 | if (code >= 0x1f00 && code <= 0x1fff) { | ||||
606 | *lower = GreekExt_lower_mapping[code - 0x1f00]; | ||||
607 | *upper = GreekExt_upper_mapping[code - 0x1f00]; | ||||
608 | if (*upper == 0) | ||||
609 | *upper = code; | ||||
610 | if (*lower == 0) | ||||
611 | *lower = code; | ||||
612 | } | ||||
613 | |||||
614 | /* Letterlike Symbols, U+2100 to U+214F */ | ||||
615 | if (code >= 0x2100 && code <= 0x214f) { | ||||
616 | switch (code) { | ||||
617 | case 0x2126: *lower = 0x03c9; break; | ||||
618 | case 0x212a: *lower = 0x006b; break; | ||||
619 | case 0x212b: *lower = 0x00e5; break; | ||||
620 | } | ||||
621 | } | ||||
622 | /* Number Forms, U+2150 to U+218F */ | ||||
623 | else if (code >= 0x2160 && code <= 0x216f) | ||||
624 | *lower += 0x10; | ||||
625 | else if (code >= 0x2170 && code <= 0x217f) | ||||
626 | *upper -= 0x10; | ||||
627 | /* Enclosed Alphanumerics, U+2460 to U+24FF */ | ||||
628 | else if (code >= 0x24b6 && code <= 0x24cf) | ||||
629 | *lower += 0x1a; | ||||
630 | else if (code >= 0x24d0 && code <= 0x24e9) | ||||
631 | *upper -= 0x1a; | ||||
632 | /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */ | ||||
633 | else if (code >= 0xff21 && code <= 0xff3a) | ||||
634 | *lower += 0x20; | ||||
635 | else if (code >= 0xff41 && code <= 0xff5a) | ||||
636 | *upper -= 0x20; | ||||
637 | /* Deseret, U+10400 to U+104FF */ | ||||
638 | else if (code >= 0x10400 && code <= 0x10427) | ||||
639 | *lower += 0x28; | ||||
640 | else if (code >= 0x10428 && code <= 0x1044f) | ||||
641 | *upper -= 0x28; | ||||
642 | } | ||||
643 | |||||
644 | void | ||||
645 | XConvertCase( | ||||
646 | register KeySym sym, | ||||
647 | KeySym *lower, | ||||
648 | KeySym *upper) | ||||
649 | { | ||||
650 | /* Latin 1 keysym */ | ||||
651 | if (sym < 0x100) { | ||||
652 | UCSConvertCase(sym, lower, upper); | ||||
653 | return; | ||||
654 | } | ||||
655 | |||||
656 | /* Unicode keysym */ | ||||
657 | if ((sym & 0xff000000) == 0x01000000) { | ||||
658 | UCSConvertCase((sym & 0x00ffffff), lower, upper); | ||||
659 | *upper |= 0x01000000; | ||||
660 | *lower |= 0x01000000; | ||||
661 | return; | ||||
662 | } | ||||
663 | |||||
664 | /* Legacy keysym */ | ||||
665 | |||||
666 | *lower = sym; | ||||
667 | *upper = sym; | ||||
668 | |||||
669 | switch(sym >> 8) { | ||||
670 | case 1: /* Latin 2 */ | ||||
671 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | ||||
672 | if (sym == XK_Aogonek0x01a1) | ||||
673 | *lower = XK_aogonek0x01b1; | ||||
674 | else if (sym >= XK_Lstroke0x01a3 && sym <= XK_Sacute0x01a6) | ||||
675 | *lower += (XK_lstroke0x01b3 - XK_Lstroke0x01a3); | ||||
676 | else if (sym >= XK_Scaron0x01a9 && sym <= XK_Zacute0x01ac) | ||||
677 | *lower += (XK_scaron0x01b9 - XK_Scaron0x01a9); | ||||
678 | else if (sym >= XK_Zcaron0x01ae && sym <= XK_Zabovedot0x01af) | ||||
679 | *lower += (XK_zcaron0x01be - XK_Zcaron0x01ae); | ||||
680 | else if (sym == XK_aogonek0x01b1) | ||||
681 | *upper = XK_Aogonek0x01a1; | ||||
682 | else if (sym >= XK_lstroke0x01b3 && sym <= XK_sacute0x01b6) | ||||
683 | *upper -= (XK_lstroke0x01b3 - XK_Lstroke0x01a3); | ||||
684 | else if (sym >= XK_scaron0x01b9 && sym <= XK_zacute0x01bc) | ||||
685 | *upper -= (XK_scaron0x01b9 - XK_Scaron0x01a9); | ||||
686 | else if (sym >= XK_zcaron0x01be && sym <= XK_zabovedot0x01bf) | ||||
687 | *upper -= (XK_zcaron0x01be - XK_Zcaron0x01ae); | ||||
688 | else if (sym >= XK_Racute0x01c0 && sym <= XK_Tcedilla0x01de) | ||||
689 | *lower += (XK_racute0x01e0 - XK_Racute0x01c0); | ||||
690 | else if (sym >= XK_racute0x01e0 && sym <= XK_tcedilla0x01fe) | ||||
691 | *upper -= (XK_racute0x01e0 - XK_Racute0x01c0); | ||||
692 | break; | ||||
693 | case 2: /* Latin 3 */ | ||||
694 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | ||||
695 | if (sym >= XK_Hstroke0x02a1 && sym <= XK_Hcircumflex0x02a6) | ||||
696 | *lower += (XK_hstroke0x02b1 - XK_Hstroke0x02a1); | ||||
697 | else if (sym >= XK_Gbreve0x02ab && sym <= XK_Jcircumflex0x02ac) | ||||
698 | *lower += (XK_gbreve0x02bb - XK_Gbreve0x02ab); | ||||
699 | else if (sym >= XK_hstroke0x02b1 && sym <= XK_hcircumflex0x02b6) | ||||
700 | *upper -= (XK_hstroke0x02b1 - XK_Hstroke0x02a1); | ||||
701 | else if (sym >= XK_gbreve0x02bb && sym <= XK_jcircumflex0x02bc) | ||||
702 | *upper -= (XK_gbreve0x02bb - XK_Gbreve0x02ab); | ||||
703 | else if (sym >= XK_Cabovedot0x02c5 && sym <= XK_Scircumflex0x02de) | ||||
704 | *lower += (XK_cabovedot0x02e5 - XK_Cabovedot0x02c5); | ||||
705 | else if (sym >= XK_cabovedot0x02e5 && sym <= XK_scircumflex0x02fe) | ||||
706 | *upper -= (XK_cabovedot0x02e5 - XK_Cabovedot0x02c5); | ||||
707 | break; | ||||
708 | case 3: /* Latin 4 */ | ||||
709 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | ||||
710 | if (sym >= XK_Rcedilla0x03a3 && sym <= XK_Tslash0x03ac) | ||||
711 | *lower += (XK_rcedilla0x03b3 - XK_Rcedilla0x03a3); | ||||
712 | else if (sym >= XK_rcedilla0x03b3 && sym <= XK_tslash0x03bc) | ||||
713 | *upper -= (XK_rcedilla0x03b3 - XK_Rcedilla0x03a3); | ||||
714 | else if (sym == XK_ENG0x03bd) | ||||
715 | *lower = XK_eng0x03bf; | ||||
716 | else if (sym == XK_eng0x03bf) | ||||
717 | *upper = XK_ENG0x03bd; | ||||
718 | else if (sym >= XK_Amacron0x03c0 && sym <= XK_Umacron0x03de) | ||||
719 | *lower += (XK_amacron0x03e0 - XK_Amacron0x03c0); | ||||
720 | else if (sym >= XK_amacron0x03e0 && sym <= XK_umacron0x03fe) | ||||
721 | *upper -= (XK_amacron0x03e0 - XK_Amacron0x03c0); | ||||
722 | break; | ||||
723 | case 6: /* Cyrillic */ | ||||
724 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | ||||
725 | if (sym >= XK_Serbian_DJE0x06b1 && sym <= XK_Serbian_DZE0x06bf) | ||||
726 | *lower -= (XK_Serbian_DJE0x06b1 - XK_Serbian_dje0x06a1); | ||||
727 | else if (sym >= XK_Serbian_dje0x06a1 && sym <= XK_Serbian_dze0x06af) | ||||
728 | *upper += (XK_Serbian_DJE0x06b1 - XK_Serbian_dje0x06a1); | ||||
729 | else if (sym >= XK_Cyrillic_YU0x06e0 && sym <= XK_Cyrillic_HARDSIGN0x06ff) | ||||
730 | *lower -= (XK_Cyrillic_YU0x06e0 - XK_Cyrillic_yu0x06c0); | ||||
731 | else if (sym >= XK_Cyrillic_yu0x06c0 && sym <= XK_Cyrillic_hardsign0x06df) | ||||
732 | *upper += (XK_Cyrillic_YU0x06e0 - XK_Cyrillic_yu0x06c0); | ||||
733 | break; | ||||
734 | case 7: /* Greek */ | ||||
735 | /* Assume the KeySym is a legal value (ignore discontinuities) */ | ||||
736 | if (sym >= XK_Greek_ALPHAaccent0x07a1 && sym <= XK_Greek_OMEGAaccent0x07ab) | ||||
737 | *lower += (XK_Greek_alphaaccent0x07b1 - XK_Greek_ALPHAaccent0x07a1); | ||||
738 | else if (sym >= XK_Greek_alphaaccent0x07b1 && sym <= XK_Greek_omegaaccent0x07bb && | ||||
739 | sym != XK_Greek_iotaaccentdieresis0x07b6 && | ||||
740 | sym != XK_Greek_upsilonaccentdieresis0x07ba) | ||||
741 | *upper -= (XK_Greek_alphaaccent0x07b1 - XK_Greek_ALPHAaccent0x07a1); | ||||
742 | else if (sym >= XK_Greek_ALPHA0x07c1 && sym <= XK_Greek_OMEGA0x07d9) | ||||
743 | *lower += (XK_Greek_alpha0x07e1 - XK_Greek_ALPHA0x07c1); | ||||
744 | else if (sym >= XK_Greek_alpha0x07e1 && sym <= XK_Greek_omega0x07f9 && | ||||
745 | sym != XK_Greek_finalsmallsigma0x07f3) | ||||
746 | *upper -= (XK_Greek_alpha0x07e1 - XK_Greek_ALPHA0x07c1); | ||||
747 | break; | ||||
748 | case 0x13: /* Latin 9 */ | ||||
749 | if (sym == XK_OE0x13bc) | ||||
750 | *lower = XK_oe0x13bd; | ||||
751 | else if (sym == XK_oe0x13bd) | ||||
752 | *upper = XK_OE0x13bc; | ||||
753 | else if (sym == XK_Ydiaeresis0x13be) | ||||
754 | *lower = XK_ydiaeresis0x00ff; | ||||
755 | break; | ||||
756 | } | ||||
757 | } | ||||
758 | |||||
759 | int | ||||
760 | _XTranslateKey( register Display *dpy, | ||||
761 | KeyCode keycode, | ||||
762 | register unsigned int modifiers, | ||||
763 | unsigned int *modifiers_return, | ||||
764 | KeySym *keysym_return) | ||||
765 | { | ||||
766 | int per; | ||||
767 | register KeySym *syms; | ||||
768 | KeySym sym, lsym, usym; | ||||
769 | |||||
770 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | ||||
771 | return 0; | ||||
772 | *modifiers_return = ((ShiftMask(1<<0)|LockMask(1<<1)) | ||||
773 | | dpy->mode_switch | dpy->num_lock); | ||||
774 | if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) | ||||
775 | { | ||||
776 | *keysym_return = NoSymbol0L; | ||||
777 | return 1; | ||||
778 | } | ||||
779 | per = dpy->keysyms_per_keycode; | ||||
780 | syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; | ||||
781 | while ((per > 2) && (syms[per - 1] == NoSymbol0L)) | ||||
782 | per--; | ||||
783 | if ((per > 2) && (modifiers & dpy->mode_switch)) { | ||||
784 | syms += 2; | ||||
785 | per -= 2; | ||||
786 | } | ||||
787 | if ((modifiers & dpy->num_lock) && | ||||
788 | (per > 1 && (IsKeypadKey(syms[1])(((KeySym)(syms[1]) >= 0xff80) && ((KeySym)(syms[1 ]) <= 0xffbd)) || IsPrivateKeypadKey(syms[1])(((KeySym)(syms[1]) >= 0x11000000) && ((KeySym)(syms [1]) <= 0x1100FFFF))))) { | ||||
789 | if ((modifiers & ShiftMask(1<<0)) || | ||||
790 | ((modifiers & LockMask(1<<1)) && (dpy->lock_meaning == XK_Shift_Lock0xffe6))) | ||||
791 | *keysym_return = syms[0]; | ||||
792 | else | ||||
793 | *keysym_return = syms[1]; | ||||
794 | } else if (!(modifiers & ShiftMask(1<<0)) && | ||||
795 | (!(modifiers & LockMask(1<<1)) || (dpy->lock_meaning == NoSymbol0L))) { | ||||
796 | if ((per == 1) || (syms[1] == NoSymbol0L)) | ||||
797 | XConvertCase(syms[0], keysym_return, &usym); | ||||
798 | else | ||||
799 | *keysym_return = syms[0]; | ||||
800 | } else if (!(modifiers & LockMask(1<<1)) || | ||||
801 | (dpy->lock_meaning != XK_Caps_Lock0xffe5)) { | ||||
802 | if ((per == 1) || ((usym = syms[1]) == NoSymbol0L)) | ||||
803 | XConvertCase(syms[0], &lsym, &usym); | ||||
804 | *keysym_return = usym; | ||||
805 | } else { | ||||
806 | if ((per == 1) || ((sym = syms[1]) == NoSymbol0L)) | ||||
807 | sym = syms[0]; | ||||
808 | XConvertCase(sym, &lsym, &usym); | ||||
809 | if (!(modifiers & ShiftMask(1<<0)) && (sym != syms[0]) && | ||||
810 | ((sym != usym) || (lsym == usym))) | ||||
811 | XConvertCase(syms[0], &lsym, &usym); | ||||
812 | *keysym_return = usym; | ||||
813 | } | ||||
814 | if (*keysym_return == XK_VoidSymbol0xffffff) | ||||
815 | *keysym_return = NoSymbol0L; | ||||
816 | return 1; | ||||
817 | } | ||||
818 | |||||
819 | int | ||||
820 | _XTranslateKeySym( | ||||
821 | Display *dpy, | ||||
822 | register KeySym symbol, | ||||
823 | unsigned int modifiers, | ||||
824 | char *buffer, | ||||
825 | int nbytes) | ||||
826 | { | ||||
827 | register struct _XKeytrans *p; | ||||
828 | int length; | ||||
829 | unsigned long hiBytes; | ||||
830 | register unsigned char c; | ||||
831 | |||||
832 | if (!symbol) | ||||
833 | return 0; | ||||
834 | /* see if symbol rebound, if so, return that string. */ | ||||
835 | for (p = dpy->key_bindings; p; p = p->next) { | ||||
836 | if (((modifiers & AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))) == p->state) && (symbol == p->key)) { | ||||
837 | length = p->len; | ||||
838 | if (length > nbytes) length = nbytes; | ||||
839 | memcpy (buffer, p->string, length); | ||||
840 | return length; | ||||
841 | } | ||||
842 | } | ||||
843 | /* try to convert to Latin-1, handling control */ | ||||
844 | hiBytes = symbol >> 8; | ||||
845 | if (!(nbytes && | ||||
846 | ((hiBytes == 0) || | ||||
847 | ((hiBytes == 0xFF) && | ||||
848 | (((symbol >= XK_BackSpace0xff08) && (symbol <= XK_Clear0xff0b)) || | ||||
849 | (symbol == XK_Return0xff0d) || | ||||
850 | (symbol == XK_Escape0xff1b) || | ||||
851 | (symbol == XK_KP_Space0xff80) || | ||||
852 | (symbol == XK_KP_Tab0xff89) || | ||||
853 | (symbol == XK_KP_Enter0xff8d) || | ||||
854 | ((symbol >= XK_KP_Multiply0xffaa) && (symbol <= XK_KP_90xffb9)) || | ||||
855 | (symbol == XK_KP_Equal0xffbd) || | ||||
856 | (symbol == XK_Delete0xffff)))))) | ||||
857 | return 0; | ||||
858 | |||||
859 | /* if X keysym, convert to ascii by grabbing low 7 bits */ | ||||
860 | if (symbol == XK_KP_Space0xff80) | ||||
861 | c = XK_space0x0020 & 0x7F; /* patch encoding botch */ | ||||
862 | else if (hiBytes == 0xFF) | ||||
863 | c = symbol & 0x7F; | ||||
864 | else | ||||
865 | c = symbol & 0xFF; | ||||
866 | /* only apply Control key if it makes sense, else ignore it */ | ||||
867 | if (modifiers & ControlMask(1<<2)) { | ||||
868 | if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; | ||||
869 | else if (c == '2') c = '\000'; | ||||
870 | else if (c >= '3' && c <= '7') c -= ('3' - '\033'); | ||||
871 | else if (c == '8') c = '\177'; | ||||
872 | else if (c == '/') c = '_' & 0x1F; | ||||
873 | } | ||||
874 | buffer[0] = c; | ||||
875 | return 1; | ||||
876 | } | ||||
877 | |||||
878 | /*ARGSUSED*/ | ||||
879 | int | ||||
880 | XLookupString_XLookupString ( | ||||
881 | register XKeyEvent *event, | ||||
882 | char *buffer, /* buffer */ | ||||
883 | int nbytes, /* space in buffer for characters */ | ||||
884 | KeySym *keysym, | ||||
885 | XComposeStatus *status) /* not implemented */ | ||||
886 | { | ||||
887 | unsigned int modifiers; | ||||
888 | KeySym symbol; | ||||
889 | |||||
890 | if (! _XTranslateKey(event->display, event->keycode, event->state, | ||||
891 | &modifiers, &symbol)) | ||||
892 | return 0; | ||||
893 | |||||
894 | #ifdef USE_OWN_COMPOSE | ||||
895 | if ( status ) { | ||||
896 | static int been_here= 0; | ||||
897 | if ( !been_here ) { | ||||
898 | XimCompInitTables(); | ||||
899 | been_here = 1; | ||||
900 | } | ||||
901 | if ( !XimCompLegalStatus(status) ) { | ||||
902 | status->compose_ptr = NULL((void*)0); | ||||
903 | status->chars_matched = 0; | ||||
904 | } | ||||
905 | if ( ((status->chars_matched>0)&&(status->compose_ptr!=NULL((void*)0))) || | ||||
906 | XimCompIsComposeKey(symbol,event->keycode,status) ) { | ||||
907 | XimCompRtrn rtrn; | ||||
908 | switch (XimCompProcessSym(status,symbol,&rtrn)) { | ||||
909 | case XIM_COMP_IGNORE: | ||||
910 | break; | ||||
911 | case XIM_COMP_IN_PROGRESS: | ||||
912 | if ( keysym!=NULL((void*)0) ) | ||||
913 | *keysym = NoSymbol0L; | ||||
914 | return 0; | ||||
915 | case XIM_COMP_FAIL: | ||||
916 | { | ||||
917 | int n = 0, len= 0; | ||||
918 | for (n=len=0;rtrn.sym[n]!=XK_VoidSymbol0xffffff;n++) { | ||||
919 | if ( nbytes-len > 0 ) { | ||||
920 | len+= _XTranslateKeySym(event->display,rtrn.sym[n], | ||||
921 | event->state, | ||||
922 | buffer+len,nbytes-len); | ||||
923 | } | ||||
924 | } | ||||
925 | if ( keysym!=NULL((void*)0) ) { | ||||
926 | if ( n==1 ) *keysym = rtrn.sym[0]; | ||||
927 | else *keysym = NoSymbol0L; | ||||
928 | } | ||||
929 | return len; | ||||
930 | } | ||||
931 | case XIM_COMP_SUCCEED: | ||||
932 | { | ||||
933 | int len,n = 0; | ||||
934 | |||||
935 | symbol = rtrn.matchSym; | ||||
936 | if ( keysym!=NULL((void*)0) ) *keysym = symbol; | ||||
937 | if ( rtrn.str[0]!='\0' ) { | ||||
938 | strncpy(buffer,rtrn.str,nbytes-1); | ||||
939 | buffer[nbytes-1]= '\0'; | ||||
940 | len = strlen(buffer); | ||||
941 | } | ||||
942 | else { | ||||
943 | len = _XTranslateKeySym(event->display,symbol, | ||||
944 | event->state, | ||||
945 | buffer,nbytes); | ||||
946 | } | ||||
947 | for (n=0;rtrn.sym[n]!=XK_VoidSymbol0xffffff;n++) { | ||||
948 | if ( nbytes-len > 0 ) { | ||||
949 | len+= _XTranslateKeySym(event->display,rtrn.sym[n], | ||||
950 | event->state, | ||||
951 | buffer+len,nbytes-len); | ||||
952 | } | ||||
953 | } | ||||
954 | return len; | ||||
955 | } | ||||
956 | } | ||||
957 | } | ||||
958 | } | ||||
959 | #endif | ||||
960 | |||||
961 | if (keysym) | ||||
962 | *keysym = symbol; | ||||
963 | /* arguable whether to use (event->state & ~modifiers) here */ | ||||
964 | return _XTranslateKeySym(event->display, symbol, event->state, | ||||
965 | buffer, nbytes); | ||||
966 | } | ||||
967 | |||||
968 | static void | ||||
969 | _XFreeKeyBindings( | ||||
970 | Display *dpy) | ||||
971 | { | ||||
972 | register struct _XKeytrans *p, *np; | ||||
973 | |||||
974 | for (p = dpy->key_bindings; p; p = np) { | ||||
975 | np = p->next; | ||||
976 | Xfree(p->string)free((p->string)); | ||||
977 | Xfree((char *)p->modifiers)free(((char *)p->modifiers)); | ||||
978 | Xfree((char *)p)free(((char *)p)); | ||||
979 | } | ||||
980 | } | ||||
981 | |||||
982 | int | ||||
983 | XRebindKeysym ( | ||||
984 | Display *dpy, | ||||
985 | KeySym keysym, | ||||
986 | KeySym *mlist, | ||||
987 | int nm, /* number of modifiers in mlist */ | ||||
988 | _Xconstconst unsigned char *str, | ||||
989 | int nbytes) | ||||
990 | { | ||||
991 | register struct _XKeytrans *tmp, *p; | ||||
992 | int nb; | ||||
993 | |||||
994 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | ||||
| |||||
995 | return 0; | ||||
996 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); | ||||
997 | tmp = dpy->key_bindings; | ||||
998 | nb = sizeof(KeySym) * nm; | ||||
999 | |||||
1000 | if ((! (p = (struct _XKeytrans *) Xcalloc( 1, sizeof(struct _XKeytrans))calloc(((1) == 0 ? 1 : (1)), (sizeof(struct _XKeytrans))))) || | ||||
| |||||
| |||||
1001 | ((! (p->string = (char *) Xmalloc( (unsigned) nbytes)malloc((((unsigned) nbytes) == 0 ? 1 : ((unsigned) nbytes))))) && | ||||
| |||||
| |||||
1002 | (nbytes > 0)) || | ||||
1003 | ((! (p->modifiers = (KeySym *) Xmalloc( (unsigned) nb)malloc((((unsigned) nb) == 0 ? 1 : ((unsigned) nb))))) && | ||||
| |||||
| |||||
1004 | (nb > 0))) { | ||||
1005 | if (p) { | ||||
1006 | if (p->string) Xfree(p->string)free((p->string)); | ||||
1007 | if (p->modifiers) Xfree((char *) p->modifiers)free(((char *) p->modifiers)); | ||||
1008 | Xfree((char *) p)free(((char *) p)); | ||||
1009 | } | ||||
1010 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
1011 | return 0; | ||||
1012 | } | ||||
1013 | |||||
1014 | dpy->key_bindings = p; | ||||
1015 | dpy->free_funcs->key_bindings = _XFreeKeyBindings; | ||||
1016 | p->next = tmp; /* chain onto list */ | ||||
1017 | memcpy (p->string, (char *) str, nbytes); | ||||
1018 | p->len = nbytes; | ||||
1019 | memcpy ((char *) p->modifiers, (char *) mlist, nb); | ||||
| |||||
1020 | p->key = keysym; | ||||
1021 | p->mlen = nm; | ||||
1022 | ComputeMaskFromKeytrans(dpy, p); | ||||
1023 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); | ||||
1024 | return 0; | ||||
1025 | } | ||||
1026 | |||||
1027 | unsigned | ||||
1028 | _XKeysymToModifiers( | ||||
1029 | Display *dpy, | ||||
1030 | KeySym ks) | ||||
1031 | { | ||||
1032 | CARD8 code,mods; | ||||
1033 | register KeySym *kmax; | ||||
1034 | register KeySym *k; | ||||
1035 | register XModifierKeymap *m; | ||||
1036 | |||||
1037 | if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) | ||||
1038 | return 0; | ||||
1039 | kmax = dpy->keysyms + | ||||
1040 | (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; | ||||
1041 | k = dpy->keysyms; | ||||
1042 | m = dpy->modifiermap; | ||||
1043 | mods= 0; | ||||
1044 | while (k<kmax) { | ||||
1045 | if (*k == ks ) { | ||||
1046 | register int j = m->max_keypermod<<3; | ||||
1047 | |||||
1048 | code=(((k-dpy->keysyms)/dpy->keysyms_per_keycode)+dpy->min_keycode); | ||||
1049 | |||||
1050 | while (--j >= 0) { | ||||
1051 | if (code == m->modifiermap[j]) | ||||
1052 | mods|= (1<<(j/m->max_keypermod)); | ||||
1053 | } | ||||
1054 | } | ||||
1055 | k++; | ||||
1056 | } | ||||
1057 | return mods; | ||||
1058 | } | ||||
1059 | |||||
1060 | /* | ||||
1061 | * given a list of modifiers, computes the mask necessary for later matching. | ||||
1062 | * This routine must lookup the key in the Keymap and then search to see | ||||
1063 | * what modifier it is bound to, if any. Sets the AnyModifier bit if it | ||||
1064 | * can't map some keysym to a modifier. | ||||
1065 | */ | ||||
1066 | static void | ||||
1067 | ComputeMaskFromKeytrans( | ||||
1068 | Display *dpy, | ||||
1069 | register struct _XKeytrans *p) | ||||
1070 | { | ||||
1071 | register int i; | ||||
1072 | |||||
1073 | p->state = AnyModifier(1<<15); | ||||
1074 | for (i = 0; i < p->mlen; i++) { | ||||
1075 | p->state|= XkbKeysymToModifiers(dpy,p->modifiers[i]); | ||||
1076 | } | ||||
1077 | p->state &= AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7)); | ||||
1078 | } |