File: | src/xkb/XKBBind.c |
Location: | line 289, column 5 |
Description: | Value stored to 'col' is never read |
1 | /* |
2 | |
3 | Copyright 1985, 1987, 1994, 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 |
12 | in all copies or substantial portions of the Software. |
13 | |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
17 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | OTHER DEALINGS IN THE SOFTWARE. |
21 | |
22 | Except as contained in this notice, the name of The Open Group shall |
23 | not be used in advertising or otherwise to promote the sale, use or |
24 | other dealings in this Software without prior written authorization |
25 | from The Open Group. |
26 | |
27 | */ |
28 | |
29 | /* the new monsters ate the old ones */ |
30 | |
31 | #ifdef HAVE_CONFIG_H1 |
32 | #include <config.h> |
33 | #endif |
34 | #include "XKBlib.h" |
35 | #include <X11/Xlibint.h> |
36 | #include <X11/Xutil.h> |
37 | #include <X11/keysym.h> |
38 | #include <stdio.h> |
39 | #include <ctype.h> |
40 | |
41 | #include <X11/extensions/XKBproto.h> |
42 | #include "XKBlibint.h" |
43 | |
44 | #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)| \ |
45 | Mod1Mask(1<<3)|Mod2Mask(1<<4)|Mod3Mask(1<<5)|Mod4Mask(1<<6)|Mod5Mask(1<<7)) |
46 | |
47 | static int _XkbLoadDpy(Display *dpy); |
48 | |
49 | struct _XKeytrans { |
50 | struct _XKeytrans *next; /* next on list */ |
51 | char *string; /* string to return when the time comes */ |
52 | int len; /* length of string (since NULL is legit) */ |
53 | KeySym key; /* keysym rebound */ |
54 | unsigned int state; /* modifier state */ |
55 | KeySym *modifiers; /* modifier keysyms you want */ |
56 | int mlen; /* length of modifier list */ |
57 | }; |
58 | |
59 | KeySym |
60 | XkbKeycodeToKeysym(Display *dpy, |
61 | #if NeedWidePrototypes1 |
62 | unsigned int kc, |
63 | #else |
64 | KeyCode kc, |
65 | #endif |
66 | int group, |
67 | int level) |
68 | { |
69 | XkbDescRec *xkb; |
70 | |
71 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
72 | return NoSymbol0L; |
73 | |
74 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
75 | |
76 | xkb = dpy->xkb_info->desc; |
77 | if ((kc < xkb->min_key_code) || (kc > xkb->max_key_code)) |
78 | return NoSymbol0L; |
79 | |
80 | if ((group < 0) || (level < 0) || (group >= XkbKeyNumGroups(xkb, kc)((((((xkb)->map)->key_sym_map[(kc)].group_info)&0x0f ))))) |
81 | return NoSymbol0L; |
82 | if (level >= XkbKeyGroupWidth(xkb, kc, group)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[group&0x3])])->num_levels))) { |
83 | /* for compatibility with the core protocol, _always_ allow */ |
84 | /* two symbols in the first two groups. If either of the */ |
85 | /* two is of type ONE_LEVEL, just replicate the first symbol */ |
86 | if ((group > XkbGroup2Index1) || (XkbKeyGroupWidth(xkb, kc, group)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[group&0x3])])->num_levels)) != 1) |
87 | || (level != 1)) { |
88 | return NoSymbol0L; |
89 | } |
90 | level = 0; |
91 | } |
92 | return XkbKeySymEntry(xkb, kc, level, group)((((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map [(kc)].offset)]))[((((((xkb)->map)->key_sym_map[kc].width ))*(group))+(level))])); |
93 | } |
94 | |
95 | KeySym |
96 | XKeycodeToKeysym(Display *dpy, |
97 | #if NeedWidePrototypes1 |
98 | unsigned int kc, |
99 | #else |
100 | KeyCode kc, |
101 | #endif |
102 | int col) |
103 | { |
104 | XkbDescRec *xkb; |
105 | |
106 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
107 | return _XKeycodeToKeysym(dpy, kc, col); |
108 | |
109 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
110 | |
111 | xkb = dpy->xkb_info->desc; |
112 | if ((kc < xkb->min_key_code) || (kc > xkb->max_key_code)) |
113 | return NoSymbol0L; |
114 | |
115 | if (col > 3) { |
116 | int lastSym, tmp, nGrp; |
117 | |
118 | lastSym = 3; |
119 | nGrp = XkbKeyNumGroups(xkb, kc)((((((xkb)->map)->key_sym_map[(kc)].group_info)&0x0f ))); |
120 | if ((nGrp > 0) && |
121 | ((tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup1Index)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[0&0x3])])->num_levels))) > 2)) { |
122 | if (col <= (lastSym + tmp - 2)) |
123 | return XkbKeycodeToKeysym(dpy, kc, XkbGroup1Index0, |
124 | col - lastSym + 2); |
125 | lastSym += tmp - 2; |
126 | } |
127 | if ((nGrp > 1) && |
128 | ((tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup2Index)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[1&0x3])])->num_levels))) > 2)) { |
129 | if (col <= (lastSym + tmp - 2)) |
130 | return XkbKeycodeToKeysym(dpy, kc, XkbGroup2Index1, |
131 | col - lastSym + 2); |
132 | lastSym += tmp - 2; |
133 | } |
134 | if (nGrp > 2) { |
135 | tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup3Index)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[2&0x3])])->num_levels)); |
136 | if (col <= lastSym + tmp) |
137 | return XkbKeycodeToKeysym(dpy, kc, XkbGroup3Index2, |
138 | col - lastSym); |
139 | lastSym += tmp; |
140 | } |
141 | if (nGrp > 3) { |
142 | tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup4Index)(((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [kc].kt_index[3&0x3])])->num_levels)); |
143 | if (col <= lastSym + tmp) |
144 | return XkbKeycodeToKeysym(dpy, kc, XkbGroup4Index3, |
145 | col - lastSym); |
146 | } |
147 | return NoSymbol0L; |
148 | } |
149 | return XkbKeycodeToKeysym(dpy, kc, (col >> 1), (col & 1)); |
150 | } |
151 | |
152 | KeyCode |
153 | XKeysymToKeycode(Display *dpy, KeySym ks) |
154 | { |
155 | register int i, j, gotOne; |
156 | |
157 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
158 | return _XKeysymToKeycode(dpy, ks); |
159 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
160 | |
161 | j = 0; |
162 | do { |
163 | register XkbDescRec *xkb = dpy->xkb_info->desc; |
164 | gotOne = 0; |
165 | for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { |
166 | if (j < (int) XkbKeyNumSyms(xkb, i)(((((xkb)->map)->key_sym_map[(i)].width)*(((((xkb)-> map)->key_sym_map[(i)].group_info)&0x0f))))) { |
167 | gotOne = 1; |
168 | if ((XkbKeySym(xkb, i, j)(((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map [(i)].offset)]))[j]) == ks)) |
169 | return i; |
170 | } |
171 | } |
172 | j++; |
173 | } while (gotOne); |
174 | return 0; |
175 | } |
176 | |
177 | static int |
178 | _XkbComputeModmap(Display *dpy) |
179 | { |
180 | register XkbDescPtr xkb; |
181 | |
182 | xkb = dpy->xkb_info->desc; |
183 | if (XkbGetUpdatedMap(dpy, XkbModifierMapMask(1<<2), xkb) == Success0) |
184 | return 1; |
185 | return 0; |
186 | } |
187 | |
188 | unsigned |
189 | XkbKeysymToModifiers(Display *dpy, KeySym ks) |
190 | { |
191 | XkbDescRec *xkb; |
192 | register int i, j; |
193 | register KeySym *pSyms; |
194 | CARD8 mods; |
195 | |
196 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
197 | return _XKeysymToModifiers(dpy, ks); |
198 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
199 | |
200 | if (_XkbNeedModmap(dpy->xkb_info)((!(dpy->xkb_info)->desc->map)||(!(dpy->xkb_info) ->desc->map->modmap)) && (!_XkbComputeModmap(dpy))) |
201 | return _XKeysymToModifiers(dpy, ks); |
202 | |
203 | xkb = dpy->xkb_info->desc; |
204 | mods = 0; |
205 | for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { |
206 | pSyms = XkbKeySymsPtr(xkb, i)((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map [(i)].offset)])); |
207 | for (j = XkbKeyNumSyms(xkb, i)(((((xkb)->map)->key_sym_map[(i)].width)*(((((xkb)-> map)->key_sym_map[(i)].group_info)&0x0f)))) - 1; j >= 0; j--) { |
208 | if (pSyms[j] == ks) { |
209 | mods |= xkb->map->modmap[i]; |
210 | break; |
211 | } |
212 | } |
213 | } |
214 | return mods; |
215 | } |
216 | |
217 | KeySym |
218 | XLookupKeysym(register XKeyEvent * event, int col) |
219 | { |
220 | Display *dpy = event->display; |
221 | |
222 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
223 | return _XLookupKeysym(event, col); |
224 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
225 | return XKeycodeToKeysym(dpy, event->keycode, col); |
226 | } |
227 | |
228 | /* |
229 | * Not a public entry point -- XkbTranslateKey is an obsolete name |
230 | * that is preserved here so that functions linked against the old |
231 | * version will continue to work in a shared library environment. |
232 | */ |
233 | int |
234 | XkbTranslateKey(register Display *dpy, |
235 | KeyCode key, |
236 | register unsigned int mods, |
237 | unsigned int *mods_rtrn, |
238 | KeySym *keysym_rtrn); |
239 | |
240 | int |
241 | XkbTranslateKey(register Display *dpy, |
242 | KeyCode key, |
243 | register unsigned int mods, |
244 | unsigned int *mods_rtrn, |
245 | KeySym *keysym_rtrn) |
246 | { |
247 | return XkbLookupKeySym(dpy, key, mods, mods_rtrn, keysym_rtrn); |
248 | } |
249 | |
250 | Boolint |
251 | XkbLookupKeySym(register Display *dpy, |
252 | KeyCode key, |
253 | register unsigned int mods, |
254 | unsigned int *mods_rtrn, |
255 | KeySym *keysym_rtrn) |
256 | { |
257 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
258 | return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn); |
259 | _XkbCheckPendingRefresh(dpy, dpy->xkb_info){ if ((dpy->xkb_info)->flags&(1<<1)) _XkbReloadDpy ((dpy)); else if ((dpy->xkb_info)->flags&(1<< 0)) { if (XkbGetMapChanges((dpy),(dpy->xkb_info)->desc, &(dpy->xkb_info)->changes)==0) { if (((dpy))->lock_fns ) (*((dpy))->lock_fns->lock_display)((dpy)); (dpy->xkb_info )->changes.changed= 0; if (((dpy))->lock_fns) (*((dpy)) ->lock_fns->unlock_display)((dpy)); } } }; |
260 | return XkbTranslateKeyCode(dpy->xkb_info->desc, key, mods, mods_rtrn, |
261 | keysym_rtrn); |
262 | } |
263 | |
264 | Boolint |
265 | XkbTranslateKeyCode(register XkbDescPtr xkb, |
266 | KeyCode key, |
267 | register unsigned int mods, |
268 | unsigned int *mods_rtrn, |
269 | KeySym *keysym_rtrn) |
270 | { |
271 | XkbKeyTypeRec *type; |
272 | int col, nKeyGroups; |
273 | unsigned preserve, effectiveGroup; |
274 | KeySym *syms; |
275 | |
276 | if (mods_rtrn != NULL((void*)0)) |
277 | *mods_rtrn = 0; |
278 | |
279 | nKeyGroups = XkbKeyNumGroups(xkb, key)((((((xkb)->map)->key_sym_map[(key)].group_info)&0x0f ))); |
280 | if ((!XkbKeycodeInRange(xkb, key)(((key)>=(xkb)->min_key_code)&& ((key)<=(xkb )->max_key_code))) || (nKeyGroups == 0)) { |
281 | if (keysym_rtrn != NULL((void*)0)) |
282 | *keysym_rtrn = NoSymbol0L; |
283 | return False0; |
284 | } |
285 | |
286 | syms = XkbKeySymsPtr(xkb, key)((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map [(key)].offset)])); |
287 | |
288 | /* find the offset of the effective group */ |
289 | col = 0; |
Value stored to 'col' is never read | |
290 | effectiveGroup = XkbGroupForCoreState(mods)(((mods)>>13)&0x3); |
291 | if (effectiveGroup >= nKeyGroups) { |
292 | unsigned groupInfo = XkbKeyGroupInfo(xkb, key)((((xkb)->map)->key_sym_map[(key)].group_info)); |
293 | |
294 | switch (XkbOutOfRangeGroupAction(groupInfo)((groupInfo)&0xc0)) { |
295 | default: |
296 | effectiveGroup %= nKeyGroups; |
297 | break; |
298 | case XkbClampIntoRange(0x40): |
299 | effectiveGroup = nKeyGroups - 1; |
300 | break; |
301 | case XkbRedirectIntoRange(0x80): |
302 | effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo)(((groupInfo)&0x30)>>4); |
303 | if (effectiveGroup >= nKeyGroups) |
304 | effectiveGroup = 0; |
305 | break; |
306 | } |
307 | } |
308 | col = effectiveGroup * XkbKeyGroupsWidth(xkb, key)((((xkb)->map)->key_sym_map[key].width)); |
309 | type = XkbKeyKeyType(xkb, key, effectiveGroup)((&((xkb)->map)->types[(((xkb)->map)->key_sym_map [key].kt_index[effectiveGroup&0x3])])); |
310 | |
311 | preserve = 0; |
312 | if (type->map) { /* find the column (shift level) within the group */ |
313 | register int i; |
314 | register XkbKTMapEntryPtr entry; |
315 | |
316 | for (i = 0, entry = type->map; i < type->map_count; i++, entry++) { |
317 | if ((entry->active) && |
318 | ((mods & type->mods.mask) == entry->mods.mask)) { |
319 | col += entry->level; |
320 | if (type->preserve) |
321 | preserve = type->preserve[i].mask; |
322 | break; |
323 | } |
324 | } |
325 | } |
326 | |
327 | if (keysym_rtrn != NULL((void*)0)) |
328 | *keysym_rtrn = syms[col]; |
329 | if (mods_rtrn) { |
330 | *mods_rtrn = type->mods.mask & (~preserve); |
331 | /* The Motif VTS doesn't get the help callback called if help |
332 | * is bound to Shift+<whatever>, and it appears as though it |
333 | * is XkbTranslateKeyCode that is causing the problem. The |
334 | * core X version of XTranslateKey always OR's in ShiftMask |
335 | * and LockMask for mods_rtrn, so this "fix" keeps this behavior |
336 | * and solves the VTS problem. |
337 | */ |
338 | if ((xkb->dpy) && (xkb->dpy->xkb_info) && |
339 | (xkb->dpy->xkb_info-> |
340 | xlib_ctrls & XkbLC_AlwaysConsumeShiftAndLock(1<<2))) { |
341 | *mods_rtrn |= (ShiftMask(1<<0) | LockMask(1<<1)); |
342 | } |
343 | } |
344 | return (syms[col] != NoSymbol0L); |
345 | } |
346 | |
347 | Statusint |
348 | XkbRefreshKeyboardMapping(register XkbMapNotifyEvent * event) |
349 | { |
350 | Display *dpy = event->display; |
351 | XkbInfoPtr xkbi; |
352 | |
353 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) { |
354 | _XRefreshKeyboardMapping((XMappingEvent *) event); |
355 | return Success0; |
356 | } |
357 | xkbi = dpy->xkb_info; |
358 | |
359 | if (((event->type & 0x7f) - xkbi->codes->first_event) != XkbEventCode0) |
360 | return BadMatch8; |
361 | if (event->xkb_type == XkbNewKeyboardNotify0) { |
362 | _XkbReloadDpy(dpy); |
363 | return Success0; |
364 | } |
365 | if (event->xkb_type == XkbMapNotify1) { |
366 | XkbMapChangesRec changes; |
367 | Statusint rtrn; |
368 | |
369 | if (xkbi->flags & XkbMapPending(1<<0)) |
370 | changes = xkbi->changes; |
371 | else |
372 | bzero(&changes, sizeof(changes))__builtin___memset_chk (&changes, 0, sizeof(changes), __builtin_object_size (&changes, 0)); |
373 | XkbNoteMapChanges(&changes, event, XKB_XLIB_MAP_MASK(((1<<0)|(1<<1)|(1<<2)))); |
374 | if ((rtrn = XkbGetMapChanges(dpy, xkbi->desc, &changes)) != Success0) { |
375 | #ifdef DEBUG |
376 | fprintf(stderr__stderrp, "Internal Error! XkbGetMapChanges failed:\n"); |
377 | #endif |
378 | xkbi->changes = changes; |
379 | } |
380 | else if (xkbi->flags & XkbMapPending(1<<0)) { |
381 | xkbi->flags &= ~XkbMapPending(1<<0); |
382 | bzero(&xkbi->changes, sizeof(XkbMapChangesRec))__builtin___memset_chk (&xkbi->changes, 0, sizeof(XkbMapChangesRec ), __builtin_object_size (&xkbi->changes, 0)); |
383 | } |
384 | return rtrn; |
385 | } |
386 | return BadMatch8; |
387 | } |
388 | |
389 | int |
390 | XRefreshKeyboardMapping(register XMappingEvent * event) |
391 | { |
392 | XkbEvent *xkbevent = (XkbEvent *) event; |
393 | Display *dpy = event->display; |
394 | XkbMapChangesRec changes; |
395 | XkbInfoPtr xkbi; |
396 | |
397 | /* always do this for input methods, which still use the old keymap */ |
398 | (void) _XRefreshKeyboardMapping(event); |
399 | |
400 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
401 | return 1; |
402 | |
403 | xkbi = dpy->xkb_info; |
404 | |
405 | if (((event->type & 0x7f) - xkbi->codes->first_event) == XkbEventCode0) |
406 | return XkbRefreshKeyboardMapping(&xkbevent->map); |
407 | |
408 | if (xkbi->flags & XkbXlibNewKeyboard(1<<1)) { |
409 | _XkbReloadDpy(dpy); |
410 | return 1; |
411 | } |
412 | |
413 | if ((xkbi->flags & XkbMapPending(1<<0)) || (event->request == MappingKeyboard1)) { |
414 | if (xkbi->flags & XkbMapPending(1<<0)) { |
415 | changes = xkbi->changes; |
416 | _XkbNoteCoreMapChanges(&changes, event, XKB_XLIB_MAP_MASK(((1<<0)|(1<<1)|(1<<2)))); |
417 | } |
418 | else { |
419 | bzero(&changes, sizeof(changes))__builtin___memset_chk (&changes, 0, sizeof(changes), __builtin_object_size (&changes, 0)); |
420 | changes.changed = XkbKeySymsMask(1<<1); |
421 | if (xkbi->desc->min_key_code < xkbi->desc->max_key_code) { |
422 | changes.first_key_sym = xkbi->desc->min_key_code; |
423 | changes.num_key_syms = xkbi->desc->max_key_code - |
424 | xkbi->desc->min_key_code + 1; |
425 | } |
426 | else { |
427 | changes.first_key_sym = event->first_keycode; |
428 | changes.num_key_syms = event->count; |
429 | } |
430 | } |
431 | |
432 | if (XkbGetMapChanges(dpy, xkbi->desc, &changes) != Success0) { |
433 | #ifdef DEBUG |
434 | fprintf(stderr__stderrp, "Internal Error! XkbGetMapChanges failed:\n"); |
435 | if (changes.changed & XkbKeyTypesMask(1<<0)) { |
436 | int first = changes.first_type; |
437 | int last = changes.first_type + changes.num_types - 1; |
438 | |
439 | fprintf(stderr__stderrp, " types: %d..%d\n", first, last); |
440 | } |
441 | if (changes.changed & XkbKeySymsMask(1<<1)) { |
442 | int first = changes.first_key_sym; |
443 | int last = changes.first_key_sym + changes.num_key_syms - 1; |
444 | |
445 | fprintf(stderr__stderrp, " symbols: %d..%d\n", first, last); |
446 | } |
447 | if (changes.changed & XkbKeyActionsMask(1<<4)) { |
448 | int first = changes.first_key_act; |
449 | int last = changes.first_key_act + changes.num_key_acts - 1; |
450 | |
451 | fprintf(stderr__stderrp, " acts: %d..%d\n", first, last); |
452 | } |
453 | if (changes.changed & XkbKeyBehaviorsMask(1<<5)) { |
454 | int first = changes.first_key_behavior; |
455 | int last = first + changes.num_key_behaviors - 1; |
456 | |
457 | fprintf(stderr__stderrp, " behaviors: %d..%d\n", first, last); |
458 | } |
459 | if (changes.changed & XkbVirtualModsMask(1<<6)) { |
460 | fprintf(stderr__stderrp, "virtual mods: 0x%04x\n", changes.vmods); |
461 | } |
462 | if (changes.changed & XkbExplicitComponentsMask(1<<3)) { |
463 | int first = changes.first_key_explicit; |
464 | int last = first + changes.num_key_explicit - 1; |
465 | |
466 | fprintf(stderr__stderrp, " explicit: %d..%d\n", first, last); |
467 | } |
468 | #endif |
469 | } |
470 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
471 | if (xkbi->flags & XkbMapPending(1<<0)) { |
472 | xkbi->flags &= ~XkbMapPending(1<<0); |
473 | bzero(&xkbi->changes, sizeof(XkbMapChangesRec))__builtin___memset_chk (&xkbi->changes, 0, sizeof(XkbMapChangesRec ), __builtin_object_size (&xkbi->changes, 0)); |
474 | } |
475 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
476 | } |
477 | if (event->request == MappingModifier0) { |
478 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
479 | if (xkbi->desc->map->modmap) { |
480 | _XkbFree(xkbi->desc->map->modmap)free((xkbi->desc->map->modmap)); |
481 | xkbi->desc->map->modmap = NULL((void*)0); |
482 | } |
483 | if (dpy->key_bindings) { |
484 | register struct _XKeytrans *p; |
485 | |
486 | for (p = dpy->key_bindings; p; p = p->next) { |
487 | register int i; |
488 | |
489 | p->state = 0; |
490 | if (p->mlen > 0) { |
491 | for (i = 0; i < p->mlen; i++) { |
492 | p->state |= XkbKeysymToModifiers(dpy, p->modifiers[i]); |
493 | } |
494 | if (p->state) |
495 | p->state &= AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7)); |
496 | else |
497 | p->state = AnyModifier(1<<15); |
498 | } |
499 | } |
500 | } |
501 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
502 | } |
503 | return 1; |
504 | } |
505 | |
506 | static int |
507 | _XkbLoadDpy(Display *dpy) |
508 | { |
509 | XkbInfoPtr xkbi; |
510 | unsigned query, oldEvents; |
511 | XkbDescRec *desc; |
512 | |
513 | if (!XkbUseExtension(dpy, NULL((void*)0), NULL((void*)0))) |
514 | return 0; |
515 | |
516 | xkbi = dpy->xkb_info; |
517 | query = XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2)); |
518 | desc = XkbGetMap(dpy, query, XkbUseCoreKbd0x0100); |
519 | if (!desc) { |
520 | #ifdef DEBUG |
521 | fprintf(stderr__stderrp, "Warning! XkbGetMap failed!\n"); |
522 | #endif |
523 | return 0; |
524 | } |
525 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
526 | xkbi->desc = desc; |
527 | |
528 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
529 | oldEvents = xkbi->selected_events; |
530 | if (!(xkbi->xlib_ctrls & XkbLC_IgnoreNewKeyboards(1<<3))) { |
531 | XkbSelectEventDetails(dpy, xkbi->desc->device_spec, |
532 | XkbNewKeyboardNotify0, |
533 | XkbNKN_KeycodesMask(1L << 0) | XkbNKN_DeviceIDMask(1L << 2), |
534 | XkbNKN_KeycodesMask(1L << 0) | XkbNKN_DeviceIDMask(1L << 2)); |
535 | } |
536 | XkbSelectEventDetails(dpy, xkbi->desc->device_spec, XkbMapNotify1, |
537 | XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2)), XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2))); |
538 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
539 | xkbi->selected_events = oldEvents; |
540 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
541 | return 1; |
542 | } |
543 | |
544 | void |
545 | _XkbReloadDpy(Display *dpy) |
546 | { |
547 | XkbInfoPtr xkbi; |
548 | XkbDescRec *desc; |
549 | unsigned oldDeviceID; |
550 | |
551 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) |
552 | return; |
553 | |
554 | xkbi = dpy->xkb_info; |
555 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
556 | if (xkbi->desc) { |
557 | oldDeviceID = xkbi->desc->device_spec; |
558 | XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask(0x7f), True1); |
559 | xkbi->desc = NULL((void*)0); |
560 | xkbi->flags &= ~(XkbMapPending(1<<0) | XkbXlibNewKeyboard(1<<1)); |
561 | xkbi->changes.changed = 0; |
562 | } |
563 | else |
564 | oldDeviceID = XkbUseCoreKbd0x0100; |
565 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
566 | desc = XkbGetMap(dpy, XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2)), XkbUseCoreKbd0x0100); |
567 | if (!desc) |
568 | return; |
569 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
570 | xkbi->desc = desc; |
571 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
572 | |
573 | if (desc->device_spec != oldDeviceID) { |
574 | /* transfer(?) event masks here */ |
575 | #ifdef NOTYET |
576 | unsigned oldEvents; |
577 | |
578 | oldEvents = xkbi->selected_events; |
579 | XkbSelectEventDetails(dpy, xkbi->desc->device_spec, XkbMapNotify1, |
580 | XkbAllMapComponentsMask(((1<<0)|(1<<1)|(1<<2))|((1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))), XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2))); |
581 | LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display )(dpy); |
582 | xkbi->selected_events = oldEvents; |
583 | UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display )(dpy); |
584 | #endif |
585 | } |
586 | return; |
587 | } |
588 | |
589 | int |
590 | XkbTranslateKeySym(register Display *dpy, |
591 | register KeySym *sym_rtrn, |
592 | unsigned int mods, |
593 | char *buffer, |
594 | int nbytes, |
595 | int *extra_rtrn) |
596 | { |
597 | register XkbInfoPtr xkb; |
598 | XkbKSToMBFunc cvtr; |
599 | XPointer priv; |
600 | char tmp[4]; |
601 | int n; |
602 | |
603 | xkb = dpy->xkb_info; |
604 | if (!xkb->cvt.KSToMB) { |
605 | _XkbGetConverters(_XkbGetCharset(), &xkb->cvt); |
606 | _XkbGetConverters("ISO8859-1", &xkb->latin1cvt); |
607 | } |
608 | |
609 | if (extra_rtrn) |
610 | *extra_rtrn = 0; |
611 | |
612 | if ((buffer == NULL((void*)0)) || (nbytes == 0)) { |
613 | buffer = tmp; |
614 | nbytes = 4; |
615 | } |
616 | |
617 | /* see if symbol rebound, if so, return that string. */ |
618 | n = XkbLookupKeyBinding(dpy, *sym_rtrn, mods, buffer, nbytes, extra_rtrn); |
619 | if (n) |
620 | return n; |
621 | |
622 | if (nbytes > 0) |
623 | buffer[0] = '\0'; |
624 | |
625 | if (xkb->cvt.KSToUpper && (mods & LockMask(1<<1))) { |
626 | *sym_rtrn = (*xkb->cvt.KSToUpper) (*sym_rtrn); |
627 | } |
628 | if (xkb->xlib_ctrls & XkbLC_ForceLatin1Lookup(1<<0)) { |
629 | cvtr = xkb->latin1cvt.KSToMB; |
630 | priv = xkb->latin1cvt.KSToMBPriv; |
631 | } |
632 | else { |
633 | cvtr = xkb->cvt.KSToMB; |
634 | priv = xkb->cvt.KSToMBPriv; |
635 | } |
636 | |
637 | n = (*cvtr) (priv, *sym_rtrn, buffer, nbytes, extra_rtrn); |
638 | |
639 | if ((!xkb->cvt.KSToUpper) && (mods & LockMask(1<<1))) { |
640 | register int i; |
641 | int change; |
642 | |
643 | for (i = change = 0; i < n; i++) { |
644 | char ch = toupper(buffer[i]); |
645 | change = (change || (buffer[i] != ch)); |
646 | buffer[i] = ch; |
647 | } |
648 | if (change) { |
649 | if (n == 1) |
650 | *sym_rtrn = |
651 | (*xkb->cvt.MBToKS) (xkb->cvt.MBToKSPriv, buffer, n, NULL((void*)0)); |
652 | else |
653 | *sym_rtrn = NoSymbol0L; |
654 | } |
655 | } |
656 | |
657 | if (mods & ControlMask(1<<2)) { |
658 | if (n == 1) { |
659 | buffer[0] = XkbToControl(buffer[0]); |
660 | if (nbytes > 1) |
661 | buffer[1] = '\0'; |
662 | return 1; |
663 | } |
664 | if (nbytes > 0) |
665 | buffer[0] = '\0'; |
666 | return 0; |
667 | } |
668 | return n; |
669 | } |
670 | |
671 | int |
672 | XLookupString(register XKeyEvent *event, |
673 | char *buffer, |
674 | int nbytes, |
675 | KeySym *keysym, |
676 | XComposeStatus *status) |
677 | { |
678 | KeySym dummy; |
679 | int rtrnLen; |
680 | unsigned int new_mods; |
681 | Display *dpy = event->display; |
682 | |
683 | if (keysym == NULL((void*)0)) |
684 | keysym = &dummy; |
685 | if (!XkbLookupKeySym(dpy, event->keycode, event->state, &new_mods, keysym)) |
686 | return 0; |
687 | new_mods = (event->state & (~new_mods)); |
688 | |
689 | /* find the group where a symbol can be converted to control one */ |
690 | if (new_mods & ControlMask(1<<2) && *keysym > 0x7F && |
691 | (dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback(1<<4))) { |
692 | XKeyEvent tmp_ev = *event; |
693 | KeySym tmp_keysym; |
694 | unsigned int tmp_new_mods; |
695 | |
696 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy )))) { |
697 | tmp_ev.state = event->state ^ dpy->mode_switch; |
698 | if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, |
699 | &tmp_new_mods, &tmp_keysym) && |
700 | tmp_keysym != NoSymbol0L && tmp_keysym < 0x80) { |
701 | *keysym = tmp_keysym; |
702 | } |
703 | } |
704 | else { |
705 | int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode)((((((dpy->xkb_info->desc)->map)->key_sym_map[(tmp_ev .keycode)].group_info)&0x0f))); |
706 | int i; |
707 | |
708 | for (i = 0; i < n; i++) { |
709 | if (XkbGroupForCoreState(event->state)(((event->state)>>13)&0x3) == i) |
710 | continue; |
711 | tmp_ev.state = XkbBuildCoreState(tmp_ev.state, i)((((i)&0x3)<<13)|((tmp_ev.state)&0xff)); |
712 | if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, |
713 | &tmp_new_mods, &tmp_keysym) && |
714 | tmp_keysym != NoSymbol0L && tmp_keysym < 0x80) { |
715 | *keysym = tmp_keysym; |
716 | new_mods = (event->state & (~tmp_new_mods)); |
717 | break; |
718 | } |
719 | } |
720 | } |
721 | } |
722 | |
723 | /* We *should* use the new_mods (which does not contain any modifiers */ |
724 | /* that were used to compute the symbol here, but pre-XKB XLookupString */ |
725 | /* did not and we have to remain compatible. Sigh. */ |
726 | if (_XkbUnavailable(dpy)(((dpy)->flags&(1L << 2)) || ((!(dpy)->xkb_info || (!(dpy)->xkb_info->desc)) && !_XkbLoadDpy(dpy ))) || |
727 | (dpy->xkb_info->xlib_ctrls & XkbLC_ConsumeLookupMods(1<<1)) == 0) |
728 | new_mods = event->state; |
729 | |
730 | rtrnLen = XkbLookupKeyBinding(dpy, *keysym, new_mods, buffer, nbytes, NULL((void*)0)); |
731 | if (rtrnLen > 0) |
732 | return rtrnLen; |
733 | |
734 | return XkbTranslateKeySym(dpy, keysym, new_mods, buffer, nbytes, NULL((void*)0)); |
735 | } |
736 | |
737 | |
738 | int |
739 | XkbLookupKeyBinding(Display *dpy, |
740 | register KeySym sym, |
741 | unsigned int mods, |
742 | char *buffer, |
743 | int nbytes, |
744 | int *extra_rtrn) |
745 | { |
746 | register struct _XKeytrans *p; |
747 | |
748 | if (extra_rtrn) |
749 | *extra_rtrn = 0; |
750 | for (p = dpy->key_bindings; p; p = p->next) { |
751 | if (((mods & AllMods((1<<0)|(1<<1)|(1<<2)| (1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))) == p->state) && (sym == p->key)) { |
752 | int tmp = p->len; |
753 | |
754 | if (tmp > nbytes) { |
755 | if (extra_rtrn) |
756 | *extra_rtrn = (tmp - nbytes); |
757 | tmp = nbytes; |
758 | } |
759 | memcpy(buffer, p->string, tmp)__builtin___memcpy_chk (buffer, p->string, tmp, __builtin_object_size (buffer, 0)); |
760 | if (tmp < nbytes) |
761 | buffer[tmp] = '\0'; |
762 | return tmp; |
763 | } |
764 | } |
765 | return 0; |
766 | } |
767 | |
768 | char |
769 | XkbToControl(char ch) |
770 | { |
771 | register char c = ch; |
772 | |
773 | if ((c >= '@' && c < '\177') || c == ' ') |
774 | c &= 0x1F; |
775 | else if (c == '2') |
776 | c = '\000'; |
777 | else if (c >= '3' && c <= '7') |
778 | c -= ('3' - '\033'); |
779 | else if (c == '8') |
780 | c = '\177'; |
781 | else if (c == '/') |
782 | c = '_' & 0x1F; |
783 | return c; |
784 | } |