XKBUse.c revision d4a3aaf4
11ab64890Smrg/************************************************************
21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
31ab64890Smrg
41ab64890SmrgPermission to use, copy, modify, and distribute this
51ab64890Smrgsoftware and its documentation for any purpose and without
61ab64890Smrgfee is hereby granted, provided that the above copyright
71ab64890Smrgnotice appear in all copies and that both that copyright
81ab64890Smrgnotice and this permission notice appear in supporting
961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1061b2299dSmrgused in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific prior written permission.
1261b2299dSmrgSilicon Graphics makes no representation about the suitability
131ab64890Smrgof this software for any purpose. It is provided "as is"
141ab64890Smrgwithout any express or implied warranty.
151ab64890Smrg
1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg
251ab64890Smrg********************************************************/
261ab64890Smrg
271ab64890Smrg#ifdef HAVE_CONFIG_H
281ab64890Smrg#include <config.h>
291ab64890Smrg#endif
301ab64890Smrg#include <stdio.h>
311ab64890Smrg#include <ctype.h>
321ab64890Smrg#include "Xlibint.h"
331ab64890Smrg#include <X11/extensions/XKBproto.h>
341ab64890Smrg#include "XKBlibint.h"
351ab64890Smrg
36818534a1Smrgstatic Bool _XkbIgnoreExtension = False;
371ab64890Smrg
381ab64890Smrgvoid
39818534a1SmrgXkbNoteMapChanges(XkbMapChangesPtr old,
40818534a1Smrg                  XkbMapNotifyEvent *new,
41818534a1Smrg                  unsigned wanted)
421ab64890Smrg{
43818534a1Smrg    int first, oldLast, newLast;
44818534a1Smrg
45818534a1Smrg    wanted &= new->changed;
46818534a1Smrg
47818534a1Smrg    if (wanted & XkbKeyTypesMask) {
48818534a1Smrg        if (old->changed & XkbKeyTypesMask) {
49818534a1Smrg            first = old->first_type;
50818534a1Smrg            oldLast = old->first_type + old->num_types - 1;
51818534a1Smrg            newLast = new->first_type + new->num_types - 1;
52818534a1Smrg
53818534a1Smrg            if (new->first_type < first)
54818534a1Smrg                first = new->first_type;
55818534a1Smrg            if (oldLast > newLast)
56818534a1Smrg                newLast = oldLast;
57818534a1Smrg            old->first_type = first;
58818534a1Smrg            old->num_types = newLast - first + 1;
59818534a1Smrg        }
60818534a1Smrg        else {
61818534a1Smrg            old->first_type = new->first_type;
62818534a1Smrg            old->num_types = new->num_types;
63818534a1Smrg        }
64818534a1Smrg    }
65818534a1Smrg    if (wanted & XkbKeySymsMask) {
66818534a1Smrg        if (old->changed & XkbKeySymsMask) {
67818534a1Smrg            first = old->first_key_sym;
68818534a1Smrg            oldLast = old->first_key_sym + old->num_key_syms - 1;
69818534a1Smrg            newLast = new->first_key_sym + new->num_key_syms - 1;
70818534a1Smrg
71818534a1Smrg            if (new->first_key_sym < first)
72818534a1Smrg                first = new->first_key_sym;
73818534a1Smrg            if (oldLast > newLast)
74818534a1Smrg                newLast = oldLast;
75818534a1Smrg            old->first_key_sym = first;
76818534a1Smrg            old->num_key_syms = newLast - first + 1;
77818534a1Smrg        }
78818534a1Smrg        else {
79818534a1Smrg            old->first_key_sym = new->first_key_sym;
80818534a1Smrg            old->num_key_syms = new->num_key_syms;
81818534a1Smrg        }
82818534a1Smrg    }
83818534a1Smrg    if (wanted & XkbKeyActionsMask) {
84818534a1Smrg        if (old->changed & XkbKeyActionsMask) {
85818534a1Smrg            first = old->first_key_act;
86818534a1Smrg            oldLast = old->first_key_act + old->num_key_acts - 1;
87818534a1Smrg            newLast = new->first_key_act + new->num_key_acts - 1;
88818534a1Smrg
89818534a1Smrg            if (new->first_key_act < first)
90818534a1Smrg                first = new->first_key_act;
91818534a1Smrg            if (oldLast > newLast)
92818534a1Smrg                newLast = oldLast;
93818534a1Smrg            old->first_key_act = first;
94818534a1Smrg            old->num_key_acts = newLast - first + 1;
95818534a1Smrg        }
96818534a1Smrg        else {
97818534a1Smrg            old->first_key_act = new->first_key_act;
98818534a1Smrg            old->num_key_acts = new->num_key_acts;
99818534a1Smrg        }
100818534a1Smrg    }
101818534a1Smrg    if (wanted & XkbKeyBehaviorsMask) {
102818534a1Smrg        if (old->changed & XkbKeyBehaviorsMask) {
103818534a1Smrg            first = old->first_key_behavior;
104818534a1Smrg            oldLast = old->first_key_behavior + old->num_key_behaviors - 1;
105818534a1Smrg            newLast = new->first_key_behavior + new->num_key_behaviors - 1;
106818534a1Smrg
107818534a1Smrg            if (new->first_key_behavior < first)
108818534a1Smrg                first = new->first_key_behavior;
109818534a1Smrg            if (oldLast > newLast)
110818534a1Smrg                newLast = oldLast;
111818534a1Smrg            old->first_key_behavior = first;
112818534a1Smrg            old->num_key_behaviors = newLast - first + 1;
113818534a1Smrg        }
114818534a1Smrg        else {
115818534a1Smrg            old->first_key_behavior = new->first_key_behavior;
116818534a1Smrg            old->num_key_behaviors = new->num_key_behaviors;
117818534a1Smrg        }
118818534a1Smrg    }
119818534a1Smrg    if (wanted & XkbVirtualModsMask) {
120818534a1Smrg        old->vmods |= new->vmods;
121818534a1Smrg    }
122818534a1Smrg    if (wanted & XkbExplicitComponentsMask) {
123818534a1Smrg        if (old->changed & XkbExplicitComponentsMask) {
124818534a1Smrg            first = old->first_key_explicit;
125818534a1Smrg            oldLast = old->first_key_explicit + old->num_key_explicit - 1;
126818534a1Smrg            newLast = new->first_key_explicit + new->num_key_explicit - 1;
127818534a1Smrg
128818534a1Smrg            if (new->first_key_explicit < first)
129818534a1Smrg                first = new->first_key_explicit;
130818534a1Smrg            if (oldLast > newLast)
131818534a1Smrg                newLast = oldLast;
132818534a1Smrg            old->first_key_explicit = first;
133818534a1Smrg            old->num_key_explicit = newLast - first + 1;
134818534a1Smrg        }
135818534a1Smrg        else {
136818534a1Smrg            old->first_key_explicit = new->first_key_explicit;
137818534a1Smrg            old->num_key_explicit = new->num_key_explicit;
138818534a1Smrg        }
139818534a1Smrg    }
140818534a1Smrg    if (wanted & XkbModifierMapMask) {
141818534a1Smrg        if (old->changed & XkbModifierMapMask) {
142818534a1Smrg            first = old->first_modmap_key;
143818534a1Smrg            oldLast = old->first_modmap_key + old->num_modmap_keys - 1;
144818534a1Smrg            newLast = new->first_modmap_key + new->num_modmap_keys - 1;
145818534a1Smrg
146818534a1Smrg            if (new->first_modmap_key < first)
147818534a1Smrg                first = new->first_modmap_key;
148818534a1Smrg            if (oldLast > newLast)
149818534a1Smrg                newLast = oldLast;
150818534a1Smrg            old->first_modmap_key = first;
151818534a1Smrg            old->num_modmap_keys = newLast - first + 1;
152818534a1Smrg        }
153818534a1Smrg        else {
154818534a1Smrg            old->first_modmap_key = new->first_modmap_key;
155818534a1Smrg            old->num_modmap_keys = new->num_modmap_keys;
156818534a1Smrg        }
157818534a1Smrg    }
158818534a1Smrg    if (wanted & XkbVirtualModMapMask) {
159818534a1Smrg        if (old->changed & XkbVirtualModMapMask) {
160818534a1Smrg            first = old->first_vmodmap_key;
161818534a1Smrg            oldLast = old->first_vmodmap_key + old->num_vmodmap_keys - 1;
162818534a1Smrg            newLast = new->first_vmodmap_key + new->num_vmodmap_keys - 1;
163818534a1Smrg
164818534a1Smrg            if (new->first_vmodmap_key < first)
165818534a1Smrg                first = new->first_vmodmap_key;
166818534a1Smrg            if (oldLast > newLast)
167818534a1Smrg                newLast = oldLast;
168818534a1Smrg            old->first_vmodmap_key = first;
169818534a1Smrg            old->num_vmodmap_keys = newLast - first + 1;
170818534a1Smrg        }
171818534a1Smrg        else {
172818534a1Smrg            old->first_vmodmap_key = new->first_vmodmap_key;
173818534a1Smrg            old->num_vmodmap_keys = new->num_vmodmap_keys;
174818534a1Smrg        }
175818534a1Smrg    }
176818534a1Smrg    old->changed |= wanted;
1771ab64890Smrg    return;
1781ab64890Smrg}
1791ab64890Smrg
1801ab64890Smrgvoid
181818534a1Smrg_XkbNoteCoreMapChanges(XkbMapChangesPtr old,
182818534a1Smrg                       XMappingEvent *new,
183818534a1Smrg                       unsigned int wanted)
1841ab64890Smrg{
185818534a1Smrg    int first, oldLast, newLast;
186818534a1Smrg
187818534a1Smrg    if ((new->request == MappingKeyboard) && (wanted & XkbKeySymsMask)) {
188818534a1Smrg        if (old->changed & XkbKeySymsMask) {
189818534a1Smrg            first = old->first_key_sym;
190818534a1Smrg            oldLast = old->first_key_sym + old->num_key_syms - 1;
191818534a1Smrg            newLast = new->first_keycode + new->count - 1;
192818534a1Smrg
193818534a1Smrg            if (new->first_keycode < first)
194818534a1Smrg                first = new->first_keycode;
195818534a1Smrg            if (oldLast > newLast)
196818534a1Smrg                newLast = oldLast;
197818534a1Smrg            old->first_key_sym = first;
198818534a1Smrg            old->num_key_syms = newLast - first + 1;
199818534a1Smrg        }
200818534a1Smrg        else {
201818534a1Smrg            old->changed |= XkbKeySymsMask;
202818534a1Smrg            old->first_key_sym = new->first_keycode;
203818534a1Smrg            old->num_key_syms = new->count;
204818534a1Smrg        }
2051ab64890Smrg    }
2061ab64890Smrg    return;
2071ab64890Smrg}
2081ab64890Smrg
2091ab64890Smrgstatic Bool
210818534a1Smrgwire_to_event(Display *dpy, XEvent *re, xEvent *event)
2111ab64890Smrg{
212818534a1Smrg    xkbEvent *xkbevent = (xkbEvent *) event;
2131ab64890Smrg    XkbInfoPtr xkbi;
2141ab64890Smrg
2151ab64890Smrg    if ((dpy->flags & XlibDisplayNoXkb) ||
216818534a1Smrg        (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
217818534a1Smrg        return False;
2181ab64890Smrg    xkbi = dpy->xkb_info;
219818534a1Smrg    if (((event->u.u.type & 0x7f) - xkbi->codes->first_event) != XkbEventCode)
220818534a1Smrg        return False;
2211ab64890Smrg
2221ab64890Smrg    switch (xkbevent->u.any.xkbType) {
223818534a1Smrg    case XkbStateNotify:
224818534a1Smrg    {
225818534a1Smrg        xkbStateNotify *sn = (xkbStateNotify *) event;
226818534a1Smrg
227818534a1Smrg        if (xkbi->selected_events & XkbStateNotifyMask) {
228818534a1Smrg            XkbStateNotifyEvent *sev = (XkbStateNotifyEvent *) re;
229818534a1Smrg
230818534a1Smrg            sev->type = XkbEventCode + xkbi->codes->first_event;
231818534a1Smrg            sev->xkb_type = XkbStateNotify;
232818534a1Smrg            sev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
233818534a1Smrg            sev->send_event = ((event->u.u.type & 0x80) != 0);
234818534a1Smrg            sev->display = dpy;
235818534a1Smrg            sev->time = sn->time;
236818534a1Smrg            sev->device = sn->deviceID;
237818534a1Smrg            sev->keycode = sn->keycode;
238818534a1Smrg            sev->event_type = sn->eventType;
239818534a1Smrg            sev->req_major = sn->requestMajor;
240818534a1Smrg            sev->req_minor = sn->requestMinor;
241818534a1Smrg            sev->changed = sn->changed;
242818534a1Smrg            sev->group = sn->group;
243818534a1Smrg            sev->base_group = sn->baseGroup;
244818534a1Smrg            sev->latched_group = sn->latchedGroup;
245818534a1Smrg            sev->locked_group = sn->lockedGroup;
246818534a1Smrg            sev->mods = sn->mods;
247818534a1Smrg            sev->base_mods = sn->baseMods;
248818534a1Smrg            sev->latched_mods = sn->latchedMods;
249818534a1Smrg            sev->locked_mods = sn->lockedMods;
250818534a1Smrg            sev->compat_state = sn->compatState;
251818534a1Smrg            sev->grab_mods = sn->grabMods;
252818534a1Smrg            sev->compat_grab_mods = sn->compatGrabMods;
253818534a1Smrg            sev->lookup_mods = sn->lookupMods;
254818534a1Smrg            sev->compat_lookup_mods = sn->compatLookupMods;
255818534a1Smrg            sev->ptr_buttons = sn->ptrBtnState;
256818534a1Smrg            return True;
257818534a1Smrg        }
258818534a1Smrg    }
259818534a1Smrg        break;
260818534a1Smrg    case XkbMapNotify:
261818534a1Smrg    {
262818534a1Smrg        xkbMapNotify *mn = (xkbMapNotify *) event;
263818534a1Smrg
264818534a1Smrg        if ((xkbi->selected_events & XkbMapNotifyMask) &&
265818534a1Smrg            (xkbi->selected_map_details & mn->changed)) {
266818534a1Smrg            XkbMapNotifyEvent *mev = (XkbMapNotifyEvent *) re;
267818534a1Smrg
268818534a1Smrg            mev->type = XkbEventCode + xkbi->codes->first_event;
269818534a1Smrg            mev->xkb_type = XkbMapNotify;
270818534a1Smrg            mev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
271818534a1Smrg            mev->send_event = ((event->u.u.type & 0x80) != 0);
272818534a1Smrg            mev->display = dpy;
273818534a1Smrg            mev->time = mn->time;
274818534a1Smrg            mev->device = mn->deviceID;
275818534a1Smrg            mev->changed = mn->changed;
276818534a1Smrg            mev->min_key_code = mn->minKeyCode;
277818534a1Smrg            mev->max_key_code = mn->maxKeyCode;
278818534a1Smrg            mev->first_type = mn->firstType;
279818534a1Smrg            mev->num_types = mn->nTypes;
280818534a1Smrg            mev->first_key_sym = mn->firstKeySym;
281818534a1Smrg            mev->num_key_syms = mn->nKeySyms;
282818534a1Smrg            mev->first_key_act = mn->firstKeyAct;
283818534a1Smrg            mev->num_key_acts = mn->nKeyActs;
284818534a1Smrg            mev->first_key_behavior = mn->firstKeyBehavior;
285818534a1Smrg            mev->num_key_behaviors = mn->nKeyBehaviors;
286818534a1Smrg            mev->vmods = mn->virtualMods;
287818534a1Smrg            mev->first_key_explicit = mn->firstKeyExplicit;
288818534a1Smrg            mev->num_key_explicit = mn->nKeyExplicit;
289818534a1Smrg            mev->first_modmap_key = mn->firstModMapKey;
290818534a1Smrg            mev->num_modmap_keys = mn->nModMapKeys;
291818534a1Smrg            mev->first_vmodmap_key = mn->firstVModMapKey;
292818534a1Smrg            mev->num_vmodmap_keys = mn->nVModMapKeys;
293818534a1Smrg            XkbNoteMapChanges(&xkbi->changes, mev, XKB_XLIB_MAP_MASK);
294818534a1Smrg            if (xkbi->changes.changed)
295818534a1Smrg                xkbi->flags |= XkbMapPending;
296818534a1Smrg            return True;
297818534a1Smrg        }
298818534a1Smrg        else if (mn->nKeySyms > 0) {
299818534a1Smrg            register XMappingEvent *ev = (XMappingEvent *) re;
300818534a1Smrg
301818534a1Smrg            ev->type = MappingNotify;
302818534a1Smrg            ev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
303818534a1Smrg            ev->send_event = ((event->u.u.type & 0x80) != 0);
304818534a1Smrg            ev->display = dpy;
305818534a1Smrg            ev->window = 0;
306818534a1Smrg            ev->first_keycode = mn->firstKeySym;
307818534a1Smrg            ev->request = MappingKeyboard;
308818534a1Smrg            ev->count = mn->nKeySyms;
309818534a1Smrg            _XkbNoteCoreMapChanges(&xkbi->changes, ev, XKB_XLIB_MAP_MASK);
310818534a1Smrg            if (xkbi->changes.changed)
311818534a1Smrg                xkbi->flags |= XkbMapPending;
312818534a1Smrg            return True;
313818534a1Smrg        }
314818534a1Smrg    }
315818534a1Smrg        break;
316818534a1Smrg    case XkbControlsNotify:
317818534a1Smrg    {
318818534a1Smrg        if (xkbi->selected_events & XkbControlsNotifyMask) {
319818534a1Smrg            xkbControlsNotify *cn = (xkbControlsNotify *) event;
320818534a1Smrg            XkbControlsNotifyEvent *cev = (XkbControlsNotifyEvent *) re;
321818534a1Smrg
322818534a1Smrg            cev->type = XkbEventCode + xkbi->codes->first_event;
323818534a1Smrg            cev->xkb_type = XkbControlsNotify;
324818534a1Smrg            cev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
325818534a1Smrg            cev->send_event = ((event->u.u.type & 0x80) != 0);
326818534a1Smrg            cev->display = dpy;
327818534a1Smrg            cev->time = cn->time;
328818534a1Smrg            cev->device = cn->deviceID;
329818534a1Smrg            cev->changed_ctrls = cn->changedControls;
330818534a1Smrg            cev->enabled_ctrls = cn->enabledControls;
331818534a1Smrg            cev->enabled_ctrl_changes = cn->enabledControlChanges;
332818534a1Smrg            cev->keycode = cn->keycode;
333818534a1Smrg            cev->num_groups = cn->numGroups;
334818534a1Smrg            cev->event_type = cn->eventType;
335818534a1Smrg            cev->req_major = cn->requestMajor;
336818534a1Smrg            cev->req_minor = cn->requestMinor;
337818534a1Smrg            return True;
338818534a1Smrg        }
339818534a1Smrg    }
340818534a1Smrg        break;
341818534a1Smrg    case XkbIndicatorMapNotify:
342818534a1Smrg    {
343818534a1Smrg        if (xkbi->selected_events & XkbIndicatorMapNotifyMask) {
344818534a1Smrg            xkbIndicatorNotify *in = (xkbIndicatorNotify *) event;
345818534a1Smrg            XkbIndicatorNotifyEvent *iev = (XkbIndicatorNotifyEvent *) re;
346818534a1Smrg
347818534a1Smrg            iev->type = XkbEventCode + xkbi->codes->first_event;
348818534a1Smrg            iev->xkb_type = XkbIndicatorMapNotify;
349818534a1Smrg            iev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
350818534a1Smrg            iev->send_event = ((event->u.u.type & 0x80) != 0);
351818534a1Smrg            iev->display = dpy;
352818534a1Smrg            iev->time = in->time;
353818534a1Smrg            iev->device = in->deviceID;
354818534a1Smrg            iev->changed = in->changed;
355818534a1Smrg            iev->state = in->state;
356818534a1Smrg            return True;
357818534a1Smrg        }
358818534a1Smrg    }
359818534a1Smrg        break;
360818534a1Smrg    case XkbIndicatorStateNotify:
361818534a1Smrg    {
362818534a1Smrg        if (xkbi->selected_events & XkbIndicatorStateNotifyMask) {
363818534a1Smrg            xkbIndicatorNotify *in = (xkbIndicatorNotify *) event;
364818534a1Smrg            XkbIndicatorNotifyEvent *iev = (XkbIndicatorNotifyEvent *) re;
365818534a1Smrg
366818534a1Smrg            iev->type = XkbEventCode + xkbi->codes->first_event;
367818534a1Smrg            iev->xkb_type = XkbIndicatorStateNotify;
368818534a1Smrg            iev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
369818534a1Smrg            iev->send_event = ((event->u.u.type & 0x80) != 0);
370818534a1Smrg            iev->display = dpy;
371818534a1Smrg            iev->time = in->time;
372818534a1Smrg            iev->device = in->deviceID;
373818534a1Smrg            iev->changed = in->changed;
374818534a1Smrg            iev->state = in->state;
375818534a1Smrg            return True;
376818534a1Smrg        }
377818534a1Smrg    }
378818534a1Smrg        break;
379818534a1Smrg    case XkbBellNotify:
380818534a1Smrg    {
381818534a1Smrg        if (xkbi->selected_events & XkbBellNotifyMask) {
382818534a1Smrg            xkbBellNotify *bn = (xkbBellNotify *) event;
383818534a1Smrg            XkbBellNotifyEvent *bev = (XkbBellNotifyEvent *) re;
384818534a1Smrg
385818534a1Smrg            bev->type = XkbEventCode + xkbi->codes->first_event;
386818534a1Smrg            bev->xkb_type = XkbBellNotify;
387818534a1Smrg            bev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
388818534a1Smrg            bev->send_event = ((event->u.u.type & 0x80) != 0);
389818534a1Smrg            bev->display = dpy;
390818534a1Smrg            bev->time = bn->time;
391818534a1Smrg            bev->device = bn->deviceID;
392818534a1Smrg            bev->percent = bn->percent;
393818534a1Smrg            bev->pitch = bn->pitch;
394818534a1Smrg            bev->duration = bn->duration;
395818534a1Smrg            bev->bell_class = bn->bellClass;
396818534a1Smrg            bev->bell_id = bn->bellID;
397818534a1Smrg            bev->name = bn->name;
398818534a1Smrg            bev->window = bn->window;
399818534a1Smrg            bev->event_only = bn->eventOnly;
400818534a1Smrg            return True;
401818534a1Smrg        }
402818534a1Smrg    }
403818534a1Smrg        break;
404818534a1Smrg    case XkbAccessXNotify:
405818534a1Smrg    {
406818534a1Smrg        if (xkbi->selected_events & XkbAccessXNotifyMask) {
407818534a1Smrg            xkbAccessXNotify *axn = (xkbAccessXNotify *) event;
408818534a1Smrg            XkbAccessXNotifyEvent *axev = (XkbAccessXNotifyEvent *) re;
409818534a1Smrg
410818534a1Smrg            axev->type = XkbEventCode + xkbi->codes->first_event;
411818534a1Smrg            axev->xkb_type = XkbAccessXNotify;
412818534a1Smrg            axev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
413818534a1Smrg            axev->send_event = ((event->u.u.type & 0x80) != 0);
414818534a1Smrg            axev->display = dpy;
415818534a1Smrg            axev->time = axn->time;
416818534a1Smrg            axev->device = axn->deviceID;
417818534a1Smrg            axev->detail = axn->detail;
418818534a1Smrg            axev->keycode = axn->keycode;
419818534a1Smrg            axev->sk_delay = axn->slowKeysDelay;
420818534a1Smrg            axev->debounce_delay = axn->debounceDelay;
421818534a1Smrg            return True;
422818534a1Smrg        }
423818534a1Smrg    }
424818534a1Smrg        break;
425818534a1Smrg    case XkbNamesNotify:
426818534a1Smrg    {
427818534a1Smrg        if (xkbi->selected_events & XkbNamesNotifyMask) {
428818534a1Smrg            xkbNamesNotify *nn = (xkbNamesNotify *) event;
429818534a1Smrg            XkbNamesNotifyEvent *nev = (XkbNamesNotifyEvent *) re;
430818534a1Smrg
431818534a1Smrg            nev->type = XkbEventCode + xkbi->codes->first_event;
432818534a1Smrg            nev->xkb_type = XkbNamesNotify;
433818534a1Smrg            nev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
434818534a1Smrg            nev->send_event = ((event->u.u.type & 0x80) != 0);
435818534a1Smrg            nev->display = dpy;
436818534a1Smrg            nev->time = nn->time;
437818534a1Smrg            nev->device = nn->deviceID;
438818534a1Smrg            nev->changed = nn->changed;
439818534a1Smrg            nev->first_type = nn->firstType;
440818534a1Smrg            nev->num_types = nn->nTypes;
441818534a1Smrg            nev->first_lvl = nn->firstLevelName;
442818534a1Smrg            nev->num_lvls = nn->nLevelNames;
443818534a1Smrg            nev->num_aliases = nn->nAliases;
444818534a1Smrg            nev->num_radio_groups = nn->nRadioGroups;
445818534a1Smrg            nev->changed_vmods = nn->changedVirtualMods;
446818534a1Smrg            nev->changed_groups = nn->changedGroupNames;
447818534a1Smrg            nev->changed_indicators = nn->changedIndicators;
448818534a1Smrg            nev->first_key = nn->firstKey;
449818534a1Smrg            nev->num_keys = nn->nKeys;
450818534a1Smrg            return True;
451818534a1Smrg        }
452818534a1Smrg    }
453818534a1Smrg        break;
454818534a1Smrg    case XkbCompatMapNotify:
455818534a1Smrg    {
456818534a1Smrg        if (xkbi->selected_events & XkbCompatMapNotifyMask) {
457818534a1Smrg            xkbCompatMapNotify *cmn = (xkbCompatMapNotify *) event;
458818534a1Smrg            XkbCompatMapNotifyEvent *cmev = (XkbCompatMapNotifyEvent *) re;
459818534a1Smrg
460818534a1Smrg            cmev->type = XkbEventCode + xkbi->codes->first_event;
461818534a1Smrg            cmev->xkb_type = XkbCompatMapNotify;
462818534a1Smrg            cmev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
463818534a1Smrg            cmev->send_event = ((event->u.u.type & 0x80) != 0);
464818534a1Smrg            cmev->display = dpy;
465818534a1Smrg            cmev->time = cmn->time;
466818534a1Smrg            cmev->device = cmn->deviceID;
467818534a1Smrg            cmev->changed_groups = cmn->changedGroups;
468818534a1Smrg            cmev->first_si = cmn->firstSI;
469818534a1Smrg            cmev->num_si = cmn->nSI;
470818534a1Smrg            cmev->num_total_si = cmn->nTotalSI;
471818534a1Smrg            return True;
472818534a1Smrg        }
473818534a1Smrg    }
474818534a1Smrg        break;
475818534a1Smrg    case XkbActionMessage:
476818534a1Smrg    {
477818534a1Smrg        if (xkbi->selected_events & XkbActionMessageMask) {
478818534a1Smrg            xkbActionMessage *am = (xkbActionMessage *) event;
479818534a1Smrg            XkbActionMessageEvent *amev = (XkbActionMessageEvent *) re;
480818534a1Smrg
481818534a1Smrg            amev->type = XkbEventCode + xkbi->codes->first_event;
482818534a1Smrg            amev->xkb_type = XkbActionMessage;
483818534a1Smrg            amev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
484818534a1Smrg            amev->send_event = ((event->u.u.type & 0x80) != 0);
485818534a1Smrg            amev->display = dpy;
486818534a1Smrg            amev->time = am->time;
487818534a1Smrg            amev->device = am->deviceID;
488818534a1Smrg            amev->keycode = am->keycode;
489818534a1Smrg            amev->press = am->press;
490818534a1Smrg            amev->key_event_follows = am->keyEventFollows;
491818534a1Smrg            amev->group = am->group;
492818534a1Smrg            amev->mods = am->mods;
493818534a1Smrg            memcpy(amev->message, am->message, XkbActionMessageLength);
494818534a1Smrg            amev->message[XkbActionMessageLength] = '\0';
495818534a1Smrg            return True;
496818534a1Smrg        }
497818534a1Smrg    }
498818534a1Smrg        break;
499818534a1Smrg    case XkbExtensionDeviceNotify:
500818534a1Smrg    {
501818534a1Smrg        if (xkbi->selected_events & XkbExtensionDeviceNotifyMask) {
502818534a1Smrg            xkbExtensionDeviceNotify *ed = (xkbExtensionDeviceNotify *) event;
503818534a1Smrg            XkbExtensionDeviceNotifyEvent *edev
504818534a1Smrg                = (XkbExtensionDeviceNotifyEvent *) re;
505818534a1Smrg
506818534a1Smrg            edev->type = XkbEventCode + xkbi->codes->first_event;
507818534a1Smrg            edev->xkb_type = XkbExtensionDeviceNotify;
508818534a1Smrg            edev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
509818534a1Smrg            edev->send_event = ((event->u.u.type & 0x80) != 0);
510818534a1Smrg            edev->display = dpy;
511818534a1Smrg            edev->time = ed->time;
512818534a1Smrg            edev->device = ed->deviceID;
513818534a1Smrg            edev->led_class = ed->ledClass;
514818534a1Smrg            edev->led_id = ed->ledID;
515818534a1Smrg            edev->reason = ed->reason;
516818534a1Smrg            edev->supported = ed->supported;
517818534a1Smrg            edev->leds_defined = ed->ledsDefined;
518818534a1Smrg            edev->led_state = ed->ledState;
519818534a1Smrg            edev->first_btn = ed->firstBtn;
520818534a1Smrg            edev->num_btns = ed->nBtns;
521818534a1Smrg            edev->unsupported = ed->unsupported;
522818534a1Smrg            return True;
523818534a1Smrg        }
524818534a1Smrg    }
525818534a1Smrg        break;
526818534a1Smrg    case XkbNewKeyboardNotify:
527818534a1Smrg    {
528818534a1Smrg        xkbNewKeyboardNotify *nkn = (xkbNewKeyboardNotify *) event;
529818534a1Smrg
530818534a1Smrg        if ((xkbi->selected_events & XkbNewKeyboardNotifyMask) &&
531818534a1Smrg            (xkbi->selected_nkn_details & nkn->changed)) {
532818534a1Smrg            XkbNewKeyboardNotifyEvent *nkev = (XkbNewKeyboardNotifyEvent *) re;
533818534a1Smrg
534818534a1Smrg            nkev->type = XkbEventCode + xkbi->codes->first_event;
535818534a1Smrg            nkev->xkb_type = XkbNewKeyboardNotify;
536818534a1Smrg            nkev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
537818534a1Smrg            nkev->send_event = ((event->u.u.type & 0x80) != 0);
538818534a1Smrg            nkev->display = dpy;
539818534a1Smrg            nkev->time = nkn->time;
540818534a1Smrg            nkev->device = nkn->deviceID;
541818534a1Smrg            nkev->old_device = nkn->oldDeviceID;
542818534a1Smrg            nkev->min_key_code = nkn->minKeyCode;
543818534a1Smrg            nkev->max_key_code = nkn->maxKeyCode;
544818534a1Smrg            nkev->old_min_key_code = nkn->oldMinKeyCode;
545818534a1Smrg            nkev->old_max_key_code = nkn->oldMaxKeyCode;
546818534a1Smrg            nkev->req_major = nkn->requestMajor;
547818534a1Smrg            nkev->req_minor = nkn->requestMinor;
548818534a1Smrg            nkev->changed = nkn->changed;
549818534a1Smrg            if ((xkbi->desc) && (nkev->send_event == 0) &&
550818534a1Smrg                ((xkbi->desc->device_spec == nkev->old_device) ||
551818534a1Smrg                 (nkev->device != nkev->old_device))) {
552818534a1Smrg                xkbi->flags = XkbMapPending | XkbXlibNewKeyboard;
553818534a1Smrg            }
554818534a1Smrg            return True;
555818534a1Smrg        }
556818534a1Smrg        else if (nkn->changed & (XkbNKN_KeycodesMask | XkbNKN_DeviceIDMask)) {
557818534a1Smrg            register XMappingEvent *ev = (XMappingEvent *) re;
558818534a1Smrg
559818534a1Smrg            ev->type = MappingNotify;
560818534a1Smrg            ev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
561818534a1Smrg            ev->send_event = ((event->u.u.type & 0x80) != 0);
562818534a1Smrg            ev->display = dpy;
563818534a1Smrg            ev->window = 0;
564818534a1Smrg            ev->first_keycode = dpy->min_keycode;
565818534a1Smrg            ev->request = MappingKeyboard;
566818534a1Smrg            ev->count = (dpy->max_keycode - dpy->min_keycode) + 1;
567818534a1Smrg            if ((xkbi->desc) && (ev->send_event == 0) &&
568818534a1Smrg                ((xkbi->desc->device_spec == nkn->oldDeviceID) ||
569818534a1Smrg                 (nkn->deviceID != nkn->oldDeviceID))) {
570818534a1Smrg                xkbi->flags |= XkbMapPending | XkbXlibNewKeyboard;
571818534a1Smrg            }
572818534a1Smrg            return True;
573818534a1Smrg        }
574818534a1Smrg    }
575818534a1Smrg        break;
576818534a1Smrg    default:
5771ab64890Smrg#ifdef DEBUG
578818534a1Smrg        fprintf(stderr, "Got unknown XKEYBOARD event (%d, base=%d)\n",
579818534a1Smrg                re->type, xkbi->codes->first_event);
5801ab64890Smrg#endif
581818534a1Smrg        break;
5821ab64890Smrg    }
5831ab64890Smrg    return False;
5841ab64890Smrg}
5851ab64890Smrg
5861ab64890SmrgBool
5871ab64890SmrgXkbIgnoreExtension(Bool ignore)
5881ab64890Smrg{
589818534a1Smrg    if (getenv("XKB_FORCE") != NULL) {
5901ab64890Smrg#ifdef DEBUG
591818534a1Smrg        fprintf(stderr,
592818534a1Smrg                "Forcing use of XKEYBOARD (overriding an IgnoreExtensions)\n");
5931ab64890Smrg#endif
594818534a1Smrg        return False;
5951ab64890Smrg    }
5961ab64890Smrg#ifdef DEBUG
597818534a1Smrg    else if (getenv("XKB_DEBUG") != NULL) {
598818534a1Smrg        fprintf(stderr, "Explicitly %signoring XKEYBOARD\n",
599818534a1Smrg                ignore ? "" : "not ");
6001ab64890Smrg    }
6011ab64890Smrg#endif
6021ab64890Smrg    _XkbIgnoreExtension = ignore;
6031ab64890Smrg    return True;
6041ab64890Smrg}
6051ab64890Smrg
6061ab64890Smrgstatic void
6071ab64890Smrg_XkbFreeInfo(Display *dpy)
6081ab64890Smrg{
6091ab64890Smrg    XkbInfoPtr xkbi = dpy->xkb_info;
610818534a1Smrg
6111ab64890Smrg    if (xkbi) {
612818534a1Smrg        if (xkbi->desc)
613818534a1Smrg            XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, True);
614818534a1Smrg        Xfree(xkbi);
615d4a3aaf4Smrg        dpy->xkb_info = NULL;
616818534a1Smrg    }
6171ab64890Smrg}
6181ab64890Smrg
6191ab64890SmrgBool
620818534a1SmrgXkbUseExtension(Display *dpy, int *major_rtrn, int *minor_rtrn)
6211ab64890Smrg{
6221ab64890Smrg    xkbUseExtensionReply rep;
6231ab64890Smrg    register xkbUseExtensionReq *req;
624818534a1Smrg    XExtCodes *codes;
625818534a1Smrg    int ev_base, forceIgnore;
6261ab64890Smrg    XkbInfoPtr xkbi;
627818534a1Smrg    char *str;
6281ab64890Smrg    static int debugMsg;
629818534a1Smrg    static int been_here = 0;
630818534a1Smrg
631818534a1Smrg    if (dpy->xkb_info && !(dpy->flags & XlibDisplayNoXkb)) {
632818534a1Smrg        if (major_rtrn)
633818534a1Smrg            *major_rtrn = dpy->xkb_info->srv_major;
634818534a1Smrg        if (minor_rtrn)
635818534a1Smrg            *minor_rtrn = dpy->xkb_info->srv_minor;
636818534a1Smrg        return True;
6371ab64890Smrg    }
6381ab64890Smrg    if (!been_here) {
639818534a1Smrg        debugMsg = (getenv("XKB_DEBUG") != NULL);
640818534a1Smrg        been_here = 1;
6411ab64890Smrg    }
6421ab64890Smrg
643818534a1Smrg    if (major_rtrn)
644818534a1Smrg        *major_rtrn = 0;
645818534a1Smrg    if (minor_rtrn)
646818534a1Smrg        *minor_rtrn = 0;
6471ab64890Smrg
6481ab64890Smrg    if (!dpy->xkb_info) {
6491ab64890Smrg        xkbi = _XkbTypedCalloc(1, XkbInfoRec);
650818534a1Smrg        if (!xkbi)
651818534a1Smrg            return False;
6521ab64890Smrg        dpy->xkb_info = xkbi;
6531ab64890Smrg        dpy->free_funcs->xkb = _XkbFreeInfo;
6541ab64890Smrg
655818534a1Smrg        xkbi->xlib_ctrls |= (XkbLC_ControlFallback | XkbLC_ConsumeLookupMods);
656818534a1Smrg        if ((str = getenv("_XKB_OPTIONS_ENABLE")) != NULL) {
657818534a1Smrg            if ((str = getenv("_XKB_LATIN1_LOOKUP")) != NULL) {
658818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
659818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_ForceLatin1Lookup;
660818534a1Smrg                else
661818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_ForceLatin1Lookup;
662818534a1Smrg            }
663818534a1Smrg            if ((str = getenv("_XKB_CONSUME_LOOKUP_MODS")) != NULL) {
664818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
665818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_ConsumeLookupMods;
666818534a1Smrg                else
667818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_ConsumeLookupMods;
668818534a1Smrg            }
669818534a1Smrg            if ((str = getenv("_XKB_CONSUME_SHIFT_AND_LOCK")) != NULL) {
670818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
671818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_AlwaysConsumeShiftAndLock;
672818534a1Smrg                else
673818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_AlwaysConsumeShiftAndLock;
674818534a1Smrg            }
675818534a1Smrg            if ((str = getenv("_XKB_IGNORE_NEW_KEYBOARDS")) != NULL) {
676818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
677818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_IgnoreNewKeyboards;
678818534a1Smrg                else
679818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_IgnoreNewKeyboards;
680818534a1Smrg            }
681818534a1Smrg            if ((str = getenv("_XKB_CONTROL_FALLBACK")) != NULL) {
682818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
683818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_ControlFallback;
684818534a1Smrg                else
685818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_ControlFallback;
686818534a1Smrg            }
687818534a1Smrg            if ((str = getenv("_XKB_COMP_LED")) != NULL) {
688818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
689818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_ComposeLED;
690818534a1Smrg                else {
691818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_ComposeLED;
692818534a1Smrg                    if (strlen(str) > 0)
693818534a1Smrg                        xkbi->composeLED = XInternAtom(dpy, str, False);
694818534a1Smrg                }
695818534a1Smrg            }
696818534a1Smrg            if ((str = getenv("_XKB_COMP_FAIL_BEEP")) != NULL) {
697818534a1Smrg                if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0))
698818534a1Smrg                    xkbi->xlib_ctrls &= ~XkbLC_BeepOnComposeFail;
699818534a1Smrg                else
700818534a1Smrg                    xkbi->xlib_ctrls |= XkbLC_BeepOnComposeFail;
701818534a1Smrg            }
702818534a1Smrg        }
703818534a1Smrg        if ((xkbi->composeLED == None) &&
704818534a1Smrg            ((xkbi->xlib_ctrls & XkbLC_ComposeLED) != 0))
705818534a1Smrg            xkbi->composeLED = XInternAtom(dpy, "Compose", False);
7061ab64890Smrg#ifdef DEBUG
7071ab64890Smrg        if (debugMsg) {
708818534a1Smrg            register unsigned c = xkbi->xlib_ctrls;
709818534a1Smrg
710818534a1Smrg            fprintf(stderr,
711818534a1Smrg                    "XKEYBOARD compose: beep on failure is %s, LED is %s\n",
712818534a1Smrg                    ((c & XkbLC_BeepOnComposeFail) ? "on" : "off"),
713818534a1Smrg                    ((c & XkbLC_ComposeLED) ? "on" : "off"));
714818534a1Smrg            fprintf(stderr,
715818534a1Smrg                    "XKEYBOARD XLookupString: %slatin-1, %s lookup modifiers\n",
716818534a1Smrg                    ((c & XkbLC_ForceLatin1Lookup) ? "allow non-" : "force "),
717818534a1Smrg                    ((c & XkbLC_ConsumeLookupMods) ? "consume" : "re-use"));
718818534a1Smrg            fprintf(stderr,
719818534a1Smrg                    "XKEYBOARD XLookupString: %sconsume shift and lock, %scontrol fallback\n",
720818534a1Smrg                    ((c & XkbLC_AlwaysConsumeShiftAndLock) ? "always " :
721818534a1Smrg                     "don't "), ((c & XkbLC_ControlFallback) ? "" : "no "));
7221ab64890Smrg
7231ab64890Smrg        }
7241ab64890Smrg#endif
725818534a1Smrg    }
726818534a1Smrg    else
7271ab64890Smrg        xkbi = dpy->xkb_info;
7281ab64890Smrg
729818534a1Smrg    forceIgnore = (dpy->flags & XlibDisplayNoXkb) || dpy->keysyms;
730818534a1Smrg    forceIgnore = forceIgnore && (major_rtrn == NULL) && (minor_rtrn == NULL);
731818534a1Smrg    if (forceIgnore || _XkbIgnoreExtension || getenv("XKB_DISABLE")) {
732818534a1Smrg        LockDisplay(dpy);
733818534a1Smrg        dpy->flags |= XlibDisplayNoXkb;
734818534a1Smrg        UnlockDisplay(dpy);
735818534a1Smrg        if (debugMsg)
736818534a1Smrg            fprintf(stderr, "XKEYBOARD extension disabled or missing\n");
737818534a1Smrg        return False;
738818534a1Smrg    }
739818534a1Smrg
740818534a1Smrg    if ((codes = XInitExtension(dpy, XkbName)) == NULL) {
741818534a1Smrg        LockDisplay(dpy);
742818534a1Smrg        dpy->flags |= XlibDisplayNoXkb;
743818534a1Smrg        UnlockDisplay(dpy);
744818534a1Smrg        if (debugMsg)
745818534a1Smrg            fprintf(stderr, "XKEYBOARD extension not present\n");
746818534a1Smrg        return False;
7471ab64890Smrg    }
7481ab64890Smrg    xkbi->codes = codes;
7491ab64890Smrg    LockDisplay(dpy);
7501ab64890Smrg
7511ab64890Smrg    GetReq(kbUseExtension, req);
7521ab64890Smrg    req->reqType = xkbi->codes->major_opcode;
7531ab64890Smrg    req->xkbReqType = X_kbUseExtension;
7541ab64890Smrg    req->wantedMajor = XkbMajorVersion;
7551ab64890Smrg    req->wantedMinor = XkbMinorVersion;
756818534a1Smrg    if (!_XReply(dpy, (xReply *) &rep, 0, xFalse) || !rep.supported) {
757818534a1Smrg        Bool fail = True;
758818534a1Smrg
759818534a1Smrg        if (debugMsg)
760818534a1Smrg            fprintf(stderr,
761818534a1Smrg                    "XKEYBOARD version mismatch (want %d.%02d, got %d.%02d)\n",
762818534a1Smrg                    XkbMajorVersion, XkbMinorVersion,
763818534a1Smrg                    rep.serverMajor, rep.serverMinor);
764818534a1Smrg
765818534a1Smrg        /* pre-release 0.65 is very close to 1.00 */
766818534a1Smrg        if ((rep.serverMajor == 0) && (rep.serverMinor == 65)) {
767818534a1Smrg            if (debugMsg)
768818534a1Smrg                fprintf(stderr, "Trying to fall back to version 0.65...");
769818534a1Smrg            GetReq(kbUseExtension, req);
770818534a1Smrg            req->reqType = xkbi->codes->major_opcode;
771818534a1Smrg            req->xkbReqType = X_kbUseExtension;
772818534a1Smrg            req->wantedMajor = 0;
773818534a1Smrg            req->wantedMinor = 65;
774818534a1Smrg            if (_XReply(dpy, (xReply *) &rep, 0, xFalse) && rep.supported) {
775818534a1Smrg                if (debugMsg)
776818534a1Smrg                    fprintf(stderr, "succeeded\n");
777818534a1Smrg                fail = False;
778818534a1Smrg            }
779818534a1Smrg            else if (debugMsg)
780818534a1Smrg                fprintf(stderr, "failed\n");
781818534a1Smrg        }
782818534a1Smrg        if (fail) {
783818534a1Smrg            dpy->flags |= XlibDisplayNoXkb;
784818534a1Smrg            UnlockDisplay(dpy);
785818534a1Smrg            SyncHandle();
786818534a1Smrg            if (major_rtrn)
787818534a1Smrg                *major_rtrn = rep.serverMajor;
788818534a1Smrg            if (minor_rtrn)
789818534a1Smrg                *minor_rtrn = rep.serverMinor;
790818534a1Smrg            return False;
791818534a1Smrg        }
7921ab64890Smrg    }
7931ab64890Smrg#ifdef DEBUG
794818534a1Smrg    else if (forceIgnore) {
795818534a1Smrg        fprintf(stderr,
796818534a1Smrg                "Internal Error!  XkbUseExtension succeeded with forceIgnore set\n");
7971ab64890Smrg    }
7981ab64890Smrg#endif
7991ab64890Smrg    UnlockDisplay(dpy);
800818534a1Smrg    xkbi->srv_major = rep.serverMajor;
801818534a1Smrg    xkbi->srv_minor = rep.serverMinor;
802818534a1Smrg    if (major_rtrn)
803818534a1Smrg        *major_rtrn = rep.serverMajor;
804818534a1Smrg    if (minor_rtrn)
805818534a1Smrg        *minor_rtrn = rep.serverMinor;
8061ab64890Smrg    if (debugMsg)
807818534a1Smrg        fprintf(stderr, "XKEYBOARD (version %d.%02d/%d.%02d) OK!\n",
808818534a1Smrg                XkbMajorVersion, XkbMinorVersion,
809818534a1Smrg                rep.serverMajor, rep.serverMinor);
8101ab64890Smrg
8111ab64890Smrg    ev_base = codes->first_event;
812818534a1Smrg    XESetWireToEvent(dpy, ev_base + XkbEventCode, wire_to_event);
8131ab64890Smrg    SyncHandle();
8141ab64890Smrg    return True;
8151ab64890Smrg}
816