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