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