Bug Summary

File:src/xkb/XKBBind.c
Location:line 288, column 5
Description:Value stored to 'col' is never read

Annotated Source Code

1/*
2
3Copyright 1985, 1987, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from 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
52static int _XkbLoadDpy(
53 Display *dpy
54);
55
56struct _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
66KeySym
67XkbKeycodeToKeysym(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
102KeySym
103XKeycodeToKeysym(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
153KeyCode
154XKeysymToKeycode(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
178static int
179_XkbComputeModmap(Display *dpy)
180{
181register 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
189unsigned
190XkbKeysymToModifiers(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
218KeySym
219XLookupKeysym(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 */
233int
234XkbTranslateKey( register Display * dpy,
235 KeyCode key,
236 register unsigned int mods,
237 unsigned int * mods_rtrn,
238 KeySym * keysym_rtrn);
239int
240XkbTranslateKey( 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
249Boolint
250XkbLookupKeySym( 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
263Boolint
264XkbTranslateKeyCode( 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
342Statusint
343XkbRefreshKeyboardMapping(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
383int
384XRefreshKeyboardMapping(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
492static 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
529void
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
572int
573XkbTranslateKeySym( 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
651int
652XLookupString ( 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
809int
810XkbLookupKeyBinding( 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
837char
838XkbToControl( 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}