diff options
author | rws <empty> | 1993-09-28 00:01:37 +0000 |
---|---|---|
committer | rws <empty> | 1993-09-28 00:01:37 +0000 |
commit | 2ff3b5887796a2477292f121fa903f8b2104a997 (patch) | |
tree | 2867c01e13f9a6b1afc7af5b5f34e45c54ce25b2 /xc/lib/X11/XKB.c | |
parent | c8d5e87efee9962059e1ae8e63a2d9c0a8f09083 (diff) |
Initial revision
Diffstat (limited to 'xc/lib/X11/XKB.c')
-rw-r--r-- | xc/lib/X11/XKB.c | 2395 |
1 files changed, 2395 insertions, 0 deletions
diff --git a/xc/lib/X11/XKB.c b/xc/lib/X11/XKB.c new file mode 100644 index 000000000..5697c1bf4 --- /dev/null +++ b/xc/lib/X11/XKB.c @@ -0,0 +1,2395 @@ +/* $XConsortium$ */ +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#include <stdio.h> +#define NEED_REPLIES +#define NEED_EVENTS +#include "Xlibint.h" +#include <X11/extensions/XKBstr.h> +#include "XKBlibint.h" + +#include <malloc.h> /* for struct mallinfo for SGIMallocInfo */ + +Bool _XkbIgnoreExtension = False; + +/***====================================================================***/ + +static void +mergePendingMaps(xkb,new) + XkbInfoPtr xkb; + xkbMapNotify *new; +{ + XkbMapChangesRec *old = &xkb->changes; + int first,oldLast,newLast; + + if (new->changed&XkbKeyTypesMask) { + if (old->changed&XkbKeyTypesMask) { + first = old->firstKeyType; + oldLast = old->firstKeyType+old->nKeyTypes-1; + newLast = new->firstKeyType+new->nKeyTypes-1; + + if (new->firstKeyType<first) + first = new->firstKeyType; + old->firstKeyType = first; + old->nKeyTypes = newLast-first+1; + } + else { + old->firstKeyType= new->firstKeyType; + old->nKeyTypes = new->nKeyTypes; + } + } + if (new->changed&XkbKeySymsMask) { + if (old->changed&XkbKeySymsMask) { + first = old->firstKeySym; + oldLast = old->firstKeySym+old->nKeySyms-1; + newLast = new->firstKeySym+new->nKeySyms-1; + + if (new->firstKeySym<first) + first = new->firstKeySym; + if (oldLast>oldLast) + newLast= oldLast; + old->firstKeySym = first; + old->nKeySyms = newLast-first+1; + } + else { + old->firstKeySym = new->firstKeySym; + old->nKeySyms = new->nKeySyms; + } + } + old->changed|= new->changed; + return; +} + +static Bool +wire_to_event(dpy,re,event) + Display *dpy; + XEvent *re; + xEvent *event; +{ + xkbEvent *xkbevent= (xkbEvent *)event; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + xkbi = dpy->xkb_info; + if (((event->u.u.type&0x7f)-xkbi->xkb_ext_event_base)!=XkbEventCode) + return False; + + switch (xkbevent->u.any.minor&0x7f) { + case XkbStateNotify: + { + xkbStateNotify *sn = (xkbStateNotify *)event; + if ( xkbi->xkb_selected_events&XkbStateNotifyMask ) { + XkbStateNotifyEvent *sev=(XkbStateNotifyEvent *)re; + sev->type = XkbEventCode+xkbi->xkb_ext_event_base; + sev->xkbType = XkbStateNotify; + sev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + sev->send_event = ((event->u.u.type & 0x80) != 0); + sev->display = dpy; + sev->time = sn->time; + sev->device = sn->deviceID; + sev->keycode = sn->keycode; + sev->eventType = sn->eventType; + sev->requestMajor = sn->requestMajor; + sev->requestMinor = sn->requestMinor; + sev->changed = sn->changed; + sev->group = sn->group; + sev->baseGroup = sn->baseGroup; + sev->latchedGroup = sn->latchedGroup; + sev->lockedGroup = sn->lockedGroup; + sev->mods = sn->mods; + sev->baseMods = sn->baseMods; + sev->latchedMods = sn->latchedMods; + sev->lockedMods = sn->lockedMods; + sev->compatState = sn->compatState; + sev->unlockedMods = sn->unlockedMods; + sev->groupsUnlocked = sn->groupsUnlocked; + return True; + } + } + break; + case XkbMapNotify: + { + xkbMapNotify *mn = (xkbMapNotify *)event; + if ((xkbi->desc!=NULL)&& + (mn->deviceID==xkbi->desc->deviceSpec)) { + mergePendingMaps(xkbi,mn); + } + if (xkbi->xkb_selected_events&XkbMapNotifyMask) { + XkbMapNotifyEvent *mev; + mev =(XkbMapNotifyEvent *)re; + mev->type = XkbEventCode+xkbi->xkb_ext_event_base; + mev->xkbType = XkbMapNotify; + mev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + mev->send_event = ((event->u.u.type&0x80)!=0); + mev->display = dpy; + mev->time = mn->time; + mev->device = mn->deviceID; + mev->changed = mn->changed; + mev->firstKeyType = mn->firstKeyType; + mev->nKeyTypes = mn->nKeyTypes; + mev->firstKeySym = mn->firstKeySym; + mev->nKeySyms = mn->nKeySyms; + mev->firstKeyAction = mn->firstKeyAction; + mev->nKeyActions = mn->nKeyActions; + mev->firstKeyBehavior = mn->firstKeyBehavior; + mev->nKeyBehaviors = mn->nKeyBehaviors; + return True; + } + else if (mn->nKeySyms>0) { + register XMappingEvent *ev = (XMappingEvent *)re; + ev->type = MappingNotify; + ev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + ev->send_event = ((event->u.u.type&0x80)!=0); + ev->display = dpy; + ev->window = 0; + ev->first_keycode = mn->firstKeySym; + ev->request = MappingKeyboard; + ev->count = mn->nKeySyms; + return True; + } + else if (mn->nKeyActions>0) { + register XMappingEvent *ev = (XMappingEvent *)re; + ev->type = MappingNotify; + ev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + ev->send_event = ((event->u.u.type&0x80)!=0); + ev->display = dpy; + ev->window = 0; + ev->first_keycode = mn->firstKeySym; + ev->request = MappingModifier; + ev->count = mn->nKeySyms; + return True; + } + } + break; + case XkbControlsNotify: + { + if (xkbi->xkb_selected_events&XkbControlsNotifyMask) { + xkbControlsNotify *cn =(xkbControlsNotify *)event; + XkbControlsNotifyEvent *cev; + cev =(XkbControlsNotifyEvent *)re; + cev->type = XkbEventCode+xkbi->xkb_ext_event_base; + cev->xkbType = XkbControlsNotify; + cev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + cev->send_event = ((event->u.u.type&0x80)!=0); + cev->display = dpy; + cev->time = cn->time; + cev->device = cn->deviceID; + cev->changedControls = cn->changedControls; + cev->enabledControlChanges = cn->enabledControlChanges; + cev->enabledControls = cn->enabledControls; + cev->keycode = cn->keycode; + cev->eventType = cn->eventType; + cev->requestMajor = cn->requestMajor; + cev->requestMinor = cn->requestMinor; + return True; + } + return False; + } + break; + case XkbIndicatorNotify: + { + if (xkbi->xkb_selected_events&XkbIndicatorNotifyMask) { + xkbIndicatorNotify *in =(xkbIndicatorNotify *)event; + XkbIndicatorNotifyEvent *iev; + iev =(XkbIndicatorNotifyEvent *)re; + iev->type = XkbEventCode+xkbi->xkb_ext_event_base; + iev->xkbType = XkbIndicatorNotify; + iev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + iev->send_event = ((event->u.u.type&0x80)!=0); + iev->display = dpy; + iev->time = in->time; + iev->device = in->deviceID; + iev->stateChanged = in->stateChanged; + iev->state= in->state; + iev->mapChanged = in->mapChanged; + return True; + } + return False; + } + break; + case XkbBellNotify: + { + if (xkbi->xkb_selected_events&XkbBellNotifyMask) { + xkbBellNotify *bn =(xkbBellNotify *)event; + XkbBellNotifyEvent *bev; + bev =(XkbBellNotifyEvent *)re; + bev->type = XkbEventCode+xkbi->xkb_ext_event_base; + bev->xkbType = XkbBellNotify; + bev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + bev->send_event = ((event->u.u.type&0x80)!=0); + bev->display = dpy; + bev->time = bn->time; + bev->device = bn->deviceID; + bev->percent = bn->percent; + bev->pitch = bn->percent; + bev->duration = bn->duration; + bev->bellClass = bn->bellClass; + bev->bellID = bn->bellID; + bev->name = bn->name; + return True; + } + return False; + } + break; + case XkbSlowKeyNotify: + { + if (xkbi->xkb_selected_events&XkbSlowKeyNotifyMask) { + xkbSlowKeyNotify *skn =(xkbSlowKeyNotify *)event; + XkbSlowKeyNotifyEvent *skev; + skev =(XkbSlowKeyNotifyEvent *)re; + skev->type = XkbEventCode+xkbi->xkb_ext_event_base; + skev->xkbType = XkbSlowKeyNotify; + skev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + skev->send_event = ((event->u.u.type&0x80)!=0); + skev->display = dpy; + skev->time = skn->time; + skev->device = skn->deviceID; + skev->slowKeyType = skn->slowKeyType; + skev->keycode = skn->keycode; + skev->delay = skn->delay; + return True; + } + return False; + } + break; + case XkbNamesNotify: + { + if (xkbi->xkb_selected_events&XkbNamesNotifyMask) { + xkbNamesNotify *nn =(xkbNamesNotify *)event; + XkbNamesNotifyEvent *nev; + nev =(XkbNamesNotifyEvent *)re; + nev->type = XkbEventCode+xkbi->xkb_ext_event_base; + nev->xkbType = XkbNamesNotify; + nev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + nev->send_event = ((event->u.u.type&0x80)!=0); + nev->display = dpy; + nev->time = nn->time; + nev->device = nn->deviceID; + nev->changed = nn->changed; + nev->firstKeyType = nn->firstKeyType; + nev->nKeyTypes = nn->nKeyTypes; + nev->firstLevel = nn->firstLevelName; + nev->nLevels = nn->nLevelNames; + nev->nRadioGroups = nn->nRadioGroups; + nev->nCharSets = nn->nCharSets; + nev->changedMods = nn->changedMods; + nev->changedIndicators = nn->changedIndicators; + return True; + } + return False; + } + break; + case XkbCompatMapNotify: + { + if (xkbi->xkb_selected_events&XkbCompatMapNotifyMask) { + xkbCompatMapNotify *cmn =(xkbCompatMapNotify *)event; + XkbCompatMapNotifyEvent *cmev; + cmev =(XkbCompatMapNotifyEvent *)re; + cmev->type = XkbEventCode+xkbi->xkb_ext_event_base; + cmev->xkbType = XkbCompatMapNotify; + cmev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + cmev->send_event = ((event->u.u.type&0x80)!=0); + cmev->display = dpy; + cmev->time = cmn->time; + cmev->device = cmn->deviceID; + cmev->changedMods = cmn->changedMods; + cmev->firstSym = cmn->firstSym; + cmev->nSyms = cmn->nSyms; + cmev->nTotalSyms = cmn->nTotalSyms; + return True; + } + return False; + } + break; + case XkbAlternateSymsNotify: + { + if (xkbi->xkb_selected_events&XkbAlternateSymsNotifyMask) { + xkbAlternateSymsNotify *asn=(xkbAlternateSymsNotify *)event; + XkbAlternateSymsNotifyEvent *asev; + asev =(XkbAlternateSymsNotifyEvent *)re; + asev->type = XkbEventCode+xkbi->xkb_ext_event_base; + asev->xkbType = XkbAlternateSymsNotify; + asev->serial = _XSetLastRequestRead(dpy, + (xGenericReply *)event); + asev->send_event = ((event->u.u.type&0x80)!=0); + asev->display = dpy; + asev->time = asn->time; + asev->device = asn->deviceID; + asev->altSymsID = asn->altSymsID; + asev->firstKey = asn->firstKey; + asev->nKeys = asn->nKeys; + return True; + } + return False; + } + break; + default: + fprintf(stderr,"Got unknown Xkb event (%d, base=%d)\n",re->type, + xkbi->xkb_ext_event_base); + break; + } + return False; +} + +Bool +XkbIgnoreExtension(ignore) + Bool ignore; +{ + _XkbIgnoreExtension = ignore; + return True; +} + +Bool +XkbQueryExtension(dpy,eventBaseReturn,errorBaseReturn) + Display *dpy; + int *eventBaseReturn; + int *errorBaseReturn; +{ + int maj,evBase,erBase; + XkbInfoPtr xkbi = dpy->xkb_info; + + if (dpy->flags & XlibDisplayNoXkb) + return False; + if ( dpy->xkb_info && (dpy->xkb_info->xkb_flags&XKB_PRESENT) ) { + maj = xkbi->xkb_ext_major_opcode; + evBase = xkbi->xkb_ext_event_base; + erBase = xkbi->xkb_ext_error_base; + } + else { + if (!XQueryExtension(dpy,XKBNAME,&maj,&evBase,&erBase)) { + LockDisplay(dpy); + dpy->flags|= XlibDisplayNoXkb; + UnlockDisplay(dpy); + return False; + } + } + + if (eventBaseReturn) + *eventBaseReturn = evBase; + if (errorBaseReturn) + *errorBaseReturn = erBase; + return True; +} + +Bool +XkbUseExtension(dpy,srvMajorRtrn,srvMinorRtrn) + Display *dpy; + int *srvMajorRtrn; + int *srvMinorRtrn; +{ + xkbUseExtensionReply rep; + register xkbUseExtensionReq *req; + XExtCodes *codes; + int ev_base; + XkbInfoPtr xkbi = dpy->xkb_info; + + if ( xkbi->xkb_flags&XKB_ABSENT ) + return False; + else if (xkbi->xkb_flags&XKB_IN_USE) { + if ( srvMajorRtrn ) + *srvMajorRtrn = xkbi->xkb_srv_major; + if ( srvMinorRtrn ) + *srvMinorRtrn = xkbi->xkb_srv_minor; + return True; + } + + if ((!(xkbi->xkb_flags&XKB_PRESENT))&&(!XkbQueryExtension(dpy,NULL,NULL))) + return False; + + if ( (codes=XInitExtension(dpy,XKBNAME))==NULL ) { + LockDisplay(dpy); + xkbi->xkb_flags= XKB_ABSENT; + UnlockDisplay(dpy); + return 0; + } + LockDisplay(dpy); + xkbi->xkb_ext_number = codes->extension; + xkbi->xkb_ext_major_opcode = codes->major_opcode; + xkbi->xkb_ext_event_base = codes->first_event; + xkbi->xkb_ext_error_base = codes->first_error; + + GetReq(kbUseExtension, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbUseExtension; + req->wantedMajor = XKB_MAJOR_VERSION; + req->wantedMinor = XKB_MINOR_VERSION; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + /* could theoretically try for an older version here */ + xkbi->xkb_flags = XKB_ABSENT; + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + xkbi->xkb_srv_major= rep.serverMajor; + xkbi->xkb_srv_minor= rep.serverMinor; + if ( srvMajorRtrn ) + *srvMajorRtrn = rep.serverMajor; + if ( srvMinorRtrn ) + *srvMinorRtrn = rep.serverMinor; + + if (rep.supported) { + xkbi->xkb_flags|= XKB_IN_USE; + ev_base = codes->first_event; + XESetWireToEvent(dpy,ev_base+XkbEventCode,wire_to_event); + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.supported; +} + +Status XkbLibraryVersion(libMajorRtrn,libMinorRtrn) + int *libMajorRtrn; + int *libMinorRtrn; +{ +int supported; + + if (*libMajorRtrn != XKB_MAJOR_VERSION) + supported = False; +#if XKB_MAJOR_VERSION==0 + else if (*libMinorRtrn != XKB_MINOR_VERSION) + supported = False; +#endif + else supported = True; + + *libMajorRtrn = XKB_MAJOR_VERSION; + *libMinorRtrn = XKB_MINOR_VERSION; + return supported; +} + +Status XkbSetAutoRepeatRate(dpy, deviceSpec, timeout, interval) + Display *dpy; + unsigned int deviceSpec; + unsigned int timeout; + unsigned int interval; +{ + register xkbSetControlsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetControls, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetControls; + req->deviceSpec = deviceSpec; + req->affectInternalMods = req->internalMods = 0; + req->affectIgnoreLockMods = req->ignoreLockMods = 0; + req->affectEnabledControls = req->enabledControls = 0; + req->changeControls = XkbRepeatKeysMask; + req->repeatDelay = timeout; + req->repeatInterval = interval; + req->slowKeysDelay = 0; + req->debounceDelay = 0; + req->mouseKeysDelay = 0; + req->mouseKeysInterval = 0; + req->mouseKeysTimeToMax = 0; + req->mouseKeysCurve = 0; + req->accessXTimeout = 0; + req->mouseKeysDfltBtn = 0; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +Bool XkbGetAutoRepeatRate(dpy, deviceSpec, timeoutp, intervalp) + Display *dpy; + unsigned int deviceSpec; + unsigned int *timeoutp; + unsigned int *intervalp; +{ + register xkbGetControlsReq *req; + xkbGetControlsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetControls; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, + (sizeof(xkbGetControlsReply)-sizeof(xReply))>>2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *timeoutp = rep.repeatDelay; + *intervalp = rep.repeatInterval; + return True; +} + +Bool +XkbDeviceBell(dpy,deviceID,bellClass,bellID,percent,name) + Display *dpy; + int deviceID; + int bellClass; + int bellID; + int percent; + Atom name; +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell,req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->bellClass = bellClass; + req->bellID = bellID; + req->percent = percent; + req->name = name; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbBell(dpy,percent,name) + Display *dpy; + int percent; + Atom name; +{ + /* class 0 = KbdFeedbackClass (X Input Extension) */ + return XkbDeviceBell(dpy,XKB_USE_CORE_KBD,0,0,percent,name); +} + + +Bool +XkbSelectEvents(dpy,deviceSpec,affect,which) + Display *dpy; + unsigned int deviceSpec; + unsigned long int affect; + unsigned long int which; +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + xkbi->xkb_selected_events&= ~affect; + xkbi->xkb_selected_events|= (affect&which); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + if (affect&XkbStateNotifyMask) { + req->affectState = XkbAllStateComponentsMask; + if (which&XkbStateNotifyMask) + req->state = XkbAllStateComponentsMask; + else req->state = 0; + } + if (affect&XkbMapNotifyMask) { + req->affectMap = XkbAllMapComponentsMask; + if (which&XkbMapNotifyMask) + req->map = XkbAllMapComponentsMask; + else req->map = 0; + } + if (affect&XkbControlsNotifyMask) { + req->affectControls = XkbAllControlsMask; + if (which&XkbControlsNotifyMask) + req->controls = XkbAllControlsMask; + else req->controls = 0; + } + if (affect&XkbNamesNotifyMask) { + req->affectNames = XkbAllNamesMask; + if (which&XkbNamesNotifyMask) + req->names = XkbAllNamesMask; + else req->names = 0; + } + if (affect&XkbCompatMapNotifyMask) { + req->affectCompatMap = XkbAllCompatMask; + if (which&XkbCompatMapNotifyMask) + req->compatMap = XkbAllCompatMask; + else req->compatMap = 0; + } + if (affect&XkbBellNotifyMask) { + req->affectBell = True; + req->bell = ((which&XkbBellNotifyMask)?True:False); + } + if (affect&XkbSlowKeyNotifyMask) { + req->affectSlowKey = XkbSKAllEventsMask; + if (which&XkbSlowKeyNotifyMask) + req->slowKey = XkbSKAllEventsMask; + else req->slowKey = 0; + } + if (affect&XkbIndicatorNotifyMask) { + req->affectIndicatorState = 0xffffffff; + req->affectIndicatorMap = 0xffffffff; + if (which&XkbIndicatorNotifyMask) { + req->indicatorState = 0xffffffff; + req->indicatorMap = 0xffffffff; + } + else { + req->indicatorState = 0; + req->indicatorMap = 0; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbSelectEventDetails(dpy,deviceSpec,eventType,affect,details) + Display *dpy; + unsigned deviceSpec; + unsigned eventType; + unsigned long int affect; + unsigned long int details; +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (affect&details) xkbi->xkb_selected_events|= (1<<eventType); + else xkbi->xkb_selected_events&= ~(1<<eventType); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + if (eventType==XkbStateNotify) { + req->affectState = affect; + req->state = details; + } + else req->affectState = req->state = 0; + if (eventType==XkbMapNotify) { + req->affectMap = affect; + req->map = details; + } + else req->affectMap = req->map = 0; + if (eventType==XkbControlsNotify) { + req->affectControls = affect; + req->controls = details; + } + else req->affectControls = req->controls = 0; + if (eventType==XkbNamesNotify) { + req->affectNames = affect; + req->names = details; + } + else req->affectNames = req->names = 0; + if (eventType==XkbCompatMapNotify) { + req->affectCompatMap = affect; + req->compatMap = details; + } + else req->affectCompatMap = req->compatMap = 0; + if (eventType==XkbBellNotify) { + req->affectBell = (affect!=0); + req->bell = (details!=0); + } + else req->affectBell = req->bell = False; + if (eventType==XkbSlowKeyNotify) { + req->affectSlowKey = affect; + req->slowKey = details; + } + else req->affectSlowKey = req->slowKey = 0; + if (eventType==XkbIndicatorNotify) { + req->affectIndicatorState = affect; + req->indicatorState = details; + req->affectIndicatorMap = affect; + req->indicatorMap = details; + } + else { + req->affectIndicatorState = req->indicatorState = 0; + req->affectIndicatorMap = req->indicatorMap = 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbLockModifiers(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int values; +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + req->affectModLocks= affect; + req->modLocks = values; + req->lockGroup = False; + req->groupLock = 0; + + req->affectModLatches = req->modLatches = 0; + req->latchGroup = False; + req->groupLatch = 0; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +Status +XkbLatchModifiers(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int values; +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + + req->affectModLatches= affect; + req->modLatches = values; + req->latchGroup = False; + req->groupLatch = 0; + + req->affectModLocks = req->modLocks = 0; + req->lockGroup = False; + req->groupLock = 0; + + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +Status +XkbSetServerInternalMods(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned deviceSpec; + unsigned affect; + unsigned values; +{ + register xkbSetControlsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetControls, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetControls; + req->deviceSpec = deviceSpec; + req->affectInternalMods = affect; + req->internalMods = values; + req->affectIgnoreLockMods = req->ignoreLockMods = 0; + req->affectEnabledControls = req->enabledControls = 0; + req->changeControls = XkbRepeatKeysMask; + req->repeatDelay = 0; + req->repeatInterval = 0; + req->slowKeysDelay = 0; + req->debounceDelay = 0; + req->mouseKeysDelay = 0; + req->mouseKeysInterval = 0; + req->mouseKeysTimeToMax = 0; + req->mouseKeysCurve = 0; + req->mouseKeysDfltBtn = 0; + req->accessXTimeout = 0; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +Status +XkbSetKeyOnlyMods(dpy,deviceSpec,affect,values) + Display *dpy; + unsigned int deviceSpec; + unsigned int affect; + unsigned int values; +{ + register xkbSetControlsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetControls, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetControls; + req->deviceSpec = deviceSpec; + req->affectInternalMods = req->internalMods = 0; + req->affectIgnoreLockMods = affect; + req->ignoreLockMods = values; + req->affectEnabledControls = req->enabledControls = 0; + req->changeControls = XkbRepeatKeysMask; + req->repeatDelay = 0; + req->repeatInterval = 0; + req->slowKeysDelay = 0; + req->debounceDelay = 0; + req->mouseKeysDelay = 0; + req->mouseKeysInterval = 0; + req->mouseKeysTimeToMax = 0; + req->mouseKeysCurve = 0; + req->mouseKeysDfltBtn = 0; + req->accessXTimeout = 0; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +Status +XkbSetDebuggingFlags(dpy,flags) + Display *dpy; + unsigned int flags; +{ + register xkbSetDebuggingFlagsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDebuggingFlags, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetDebuggingFlags; + req->flags = flags; + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +/***====================================================================***/ + +/* 8/16/94 (ef) -- XXX! Every place that calls this function should deal */ +/* with failure */ + +static Bool +_XkbInitServerMap(xkb) + XkbDescRec *xkb; +{ +int size; +XkbServerMapRec *map; + + if ((!xkb)||(xkb->server)||(xkb->maxKeyCode<8)) + return True; + size= sizeof(XkbServerMapRec)+((xkb->maxKeyCode+1)*sizeof(XkbAction)); + size+= (((((xkb->maxKeyCode+1)*sizeof(CARD16))+3)/4)*4); + xkb->server= map=(XkbServerMapRec *)Xmalloc(size); + if (map) { + bzero((char *)&map[1],size-sizeof(XkbServerMapRec)); + map->nActions = 1; + map->szActions = 32; + map->actions= (XkbAction *)Xmalloc(map->szActions*sizeof(XkbAction)); + map->actions[0].type = XKB_SA_NO_ACTION; + + map->keyBehaviors= (XkbAction *)&map[1]; + map->keyActions= (CARD16 *)&map->keyBehaviors[xkb->maxKeyCode]; + return True; + } + return False; +} + +/***====================================================================***/ + +KeySym * +XkbEnlargeKeySymbols(xkb,key,needed) + XkbDescRec *xkb; + int key; + int needed; +{ +register int i,nSyms; +KeySym *newSyms; + + if (XkbKeyNumSyms(xkb,key)>=needed) { + return XkbKeySymsPtr(xkb,key); + } + if (xkb->map->szSyms-xkb->map->nSyms>=needed) { + bcopy(XkbKeySymsPtr(xkb,key),&xkb->map->syms[xkb->map->nSyms], + XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); + xkb->map->keySymMap[key].offset = xkb->map->nSyms; + xkb->map->nSyms+= needed; + return &xkb->map->syms[xkb->map->keySymMap[key].offset]; + } + xkb->map->szSyms+= 128; + newSyms = (KeySym *)Xmalloc(xkb->map->szSyms*sizeof(KeySym)); + nSyms = 1; + for (i=xkb->minKeyCode;i<=xkb->maxKeyCode;i++) { + bcopy(XkbKeySymsPtr(xkb,i),&newSyms[nSyms], + XkbKeyNumSyms(xkb,i)*sizeof(KeySym)); + xkb->map->keySymMap[i].offset = nSyms; + if (i!=key) nSyms+= XkbKeyNumSyms(xkb,i); + else nSyms+= needed; + } + free(xkb->map->syms); + xkb->map->syms = newSyms; + xkb->map->nSyms = nSyms; + return &xkb->map->syms[xkb->map->keySymMap[key].offset]; +} + +XkbAction * +XkbEnlargeKeyActions(xkb,key,needed) + XkbDescRec *xkb; + int key; + int needed; +{ +register int i,nActs; +XkbAction *newActs; + + if ((xkb->server->keyActions[key]!=0)&&(XkbKeyNumSyms(xkb,key)>=needed)) { + return XkbKeyActionsPtr(xkb,key); + } + if (xkb->server->szActions-xkb->server->nActions>=needed) { + xkb->server->keyActions[key]= xkb->server->nActions; + xkb->server->nActions+= needed; + return &xkb->server->actions[xkb->server->keyActions[key]]; + } + xkb->server->szActions+= 32; + newActs = (XkbAction *)Xmalloc(xkb->server->szActions*sizeof(XkbAction)); + newActs[0].type = XKB_SA_NO_ACTION; + nActs = 1; + for (i=xkb->minKeyCode;i<=xkb->maxKeyCode;i++) { + if (xkb->server->keyActions[i]!=0) { + bcopy(XkbKeyActionsPtr(xkb,i),&newActs[nActs], + XkbKeyNumActions(xkb,i)*sizeof(XkbAction)); + xkb->server->keyActions[i]= nActs; + if (i!=key) nActs+= XkbKeyNumActions(xkb,i); + else nActs+= needed; + } + } + free(xkb->server->actions); + xkb->server->actions = newActs; + xkb->server->nActions= nActs; + return &xkb->server->actions[xkb->server->keyActions[key]]; +} + +static int +_XkbReadKeyTypes(dpy,info,rep,replace) + Display *dpy; + XkbDescRec *info; + xkbGetMapReply *rep; + int replace; +{ +int len; +int i,last; +XkbKeyTypeRec *map; + + if ( rep->nKeyTypes>0 ) { + len = 0; + last = rep->firstKeyType+rep->nKeyTypes-1; + if ( info->map->nKeyTypes==0 ) { + info->map->nKeyTypes = last+1; + info->map->keyTypes= + (XkbKeyTypeRec *)Xmalloc((last+1)*sizeof(XkbKeyTypeRec)); + /* 4/5/93 (ef) -- XXX! deal with alloc failure? */ + bzero(info->map->keyTypes, + info->map->nKeyTypes*sizeof(XkbKeyTypeRec)); + } + else if ( last >= info->map->nKeyTypes ) { + info->map->keyTypes=(XkbKeyTypeRec *)Xrealloc(info->map->keyTypes, + (last+1)*sizeof(XkbKeyTypeRec)); + /* 4/5/93 (ef) -- XXX! deal with realloc failure? */ + bzero(&info->map->keyTypes[info->map->nKeyTypes], + (rep->nKeyTypes)*sizeof(XkbKeyTypeRec)); + info->map->nKeyTypes = last+1; + } + else if ( replace && rep->firstKeyType==0 ) { + info->map->nKeyTypes = last+1; + } + + map = &info->map->keyTypes[rep->firstKeyType]; + for (i=0;i<rep->nKeyTypes;i++,map++) { + xkbKeyTypeWireDesc desc; + _XRead(dpy, (char *)&desc, sizeof(xkbKeyTypeWireDesc)); + len+= sizeof(xkbKeyTypeWireDesc); + + if ( (!(desc.flags&xkb_KTHasPreserve)) && map->preserve ) { + if (!map->flags&XKB_KT_DONT_FREE_PRESERVE) + Xfree(map->preserve); + map->preserve= NULL; + } + if ( (map->map==NULL) || (desc.mapWidth > XkbKTMapWidth(map)) ) { + if ( map->map ) { + map->map = Xrealloc(map->map,desc.mapWidth); + if ( map->preserve ) + map->preserve = Xrealloc(map->preserve,desc.mapWidth); + } + else map->map = Xmalloc(desc.mapWidth); + /* 4/5/93 (ef) -- XXX! deal with realloc failure? */ + /* 8/10/93 (ef) -- XXX! resize symbol lists for keys */ + } + if (( desc.flags&xkb_KTHasPreserve) && (!map->preserve)) + map->preserve = Xmalloc(desc.mapWidth); + + map->flags = XKB_KT_DONT_FREE_MAP; + map->mask = desc.mask; + map->groupWidth = desc.groupWidth; + _XRead(dpy, (char *)map->map, desc.mapWidth); + len+= desc.mapWidth; + last = (((desc.mapWidth+3)/4)*4)-desc.mapWidth; + if ( last ) { + _XEatData(dpy, last); + len+= last; + } + if (desc.flags&xkb_KTHasPreserve) { + if ( map->preserve ) { + _XRead(dpy, (char *)map->preserve, desc.mapWidth); + _XEatData(dpy, last); + } + else _XEatData(dpy,desc.mapWidth+last); + len+= desc.mapWidth+last; + } + } + return len; + } + return 0; +} + +static int +_XkbReadKeySyms(dpy,xkb,rep,replace) + Display *dpy; + XkbDescRec *xkb; + xkbGetMapReply *rep; + int replace; +{ +register int i; + + if (xkb->map->keySymMap==NULL) { + register int offset; + XkbSymMapRec *oldMap; + xkb->map->keySymMap = (XkbSymMapRec *)Xmalloc((xkb->maxKeyCode+1)* + sizeof(XkbSymMapRec)); + if (!xkb->map->keySymMap) + return 0; + if (!xkb->map->syms) { + int sz = ((rep->totalSyms+128)/128)*128; + xkb->map->syms = Xmalloc(sz*sizeof(KeySym)); + if (!xkb->map->syms) + return 1; + xkb->map->szSyms = sz; + } + offset = 1; + oldMap = &xkb->map->keySymMap[rep->firstKeySym]; + for (i=0;i<rep->nKeySyms;i++,oldMap++) { + register int tmp; + _XRead(dpy,(char *)oldMap,sizeof(XkbSymMapRec)); + tmp = oldMap->offset; + oldMap->offset = offset; + _XRead(dpy,(char *)&xkb->map->syms[offset],tmp*sizeof(KeySym)); + offset+= tmp; + } + xkb->map->nSyms= offset; + } + else { + xkbSymMapWireDesc newMap; + XkbSymMapRec *oldMap; + KeySym *newSyms; + oldMap = &xkb->map->keySymMap[rep->firstKeySym]; + for (i=0;i<rep->nKeySyms;i++,oldMap++) { + _XRead(dpy,(char *)&newMap,sizeof(XkbSymMapRec)); + newSyms = XkbEnlargeKeySymbols(xkb,i+rep->firstKeySym,newMap.nSyms); + _XRead(dpy,(char *)newSyms,newMap.nSyms*sizeof(KeySym)); + oldMap->ktIndex = newMap.ktIndex; + oldMap->groupInfo = newMap.groupInfo; + } + } + return (rep->nKeySyms*sizeof(XkbSymMapRec))+(rep->totalSyms*sizeof(KeySym)); +} + +static int +_XkbReadKeyActions(dpy,info,rep,replace) + Display *dpy; + XkbDescRec *info; + xkbGetMapReply *rep; + int replace; +{ +int len; +int i,last; +CARD8 numDesc[248]; +XkbAction *actDesc; + + if ( rep->nKeyActions>0 ) { + XkbSymMapRec *symMap; + _XRead(dpy, (char *)numDesc, rep->nKeyActions); + len = rep->nKeyActions; + i= ((len+3)/4)*4; + if (i>len) { + _XEatData(dpy,i-len); + len = i; + } + symMap = &info->map->keySymMap[rep->firstKeyAction]; + for (i=0;i<rep->nKeyActions;i++,symMap++) { + if (numDesc[i]==0) { + info->server->keyActions[i+rep->firstKeyAction]= 0; + } + else { + XkbAction *newActs; + /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ + /* either zero or XkbKeyNumSyms(info,key) */ + newActs=XkbEnlargeKeyActions(info,i+rep->firstKeyAction, + numDesc[i]); + _XRead(dpy,(char *)newActs,numDesc[i]*sizeof(XkbAction)); + len+= numDesc[i]*sizeof(XkbAction); + } + } + return len; + } + return 0; +} + +static int +_XkbReadKeyBehaviors(dpy,xkb,rep) + Display *dpy; + XkbDescRec *xkb; + xkbGetMapReply *rep; +{ +int len; + + if ( rep->nKeyBehaviors>0 ) { + len = 0; + if ( xkb->server->keyBehaviors == NULL ) { + int size = xkb->maxKeyCode+1; + xkb->server->keyBehaviors = Xmalloc(size*sizeof(XkbAction)); + /* 4/5/93 (ef) -- XXX! deal with alloc failure? */ + bzero(xkb->server->keyBehaviors,(size*sizeof(XkbAction))); + } + _XRead(dpy, (char *)&xkb->server->keyBehaviors[rep->firstKeyBehavior], + rep->nKeyBehaviors*sizeof(XkbAction)); + len+= rep->nKeyBehaviors*sizeof(XkbAction); + return len; + } + return 0; +} + +Status +XkbGetUpdatedMap(dpy,which,xkb) + Display *dpy; + unsigned which; + XkbDescRec *xkb; +{ + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if (which) { + register xkbGetMapReq *req; + xkbGetMapReply rep; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = xkb->deviceSpec; + req->full = which; + req->partial = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + + if ((which&XkbFullServerInfoMask)&&(!xkb->server)) + _XkbInitServerMap(xkb); + + nRead= _XkbReadKeyTypes(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeySyms(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeyActions(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeyBehaviors(dpy,xkb,&rep)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"GetMap! bad reply length (got %d, not %d)\n", + nRead, rep.length); + } + UnlockDisplay(dpy); + SyncHandle(); + } + return True; +} + +XkbDescRec * +XkbGetMap(dpy,which,deviceSpec) + Display *dpy; + unsigned which; + unsigned deviceSpec; +{ +XkbDescRec *xkb; + + xkb = (XkbDescRec *)Xmalloc(sizeof(XkbDescRec)+sizeof(XkbClientMapRec)); + if (xkb) { + bzero(xkb,sizeof(XkbDescRec)); + xkb->deviceSpec = deviceSpec; + xkb->map = (XkbClientMapRec *)&xkb[1]; + bzero(xkb->map,sizeof(XkbClientMapRec)); + if ((which)&&(!XkbGetUpdatedMap(dpy,which,xkb))) { + Xfree(xkb); + xkb= NULL; + } + } + return xkb; +} + +Status +XkbGetKeyTypes(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescRec *xkb; +{ + register xkbGetMapReq *req; + xkbGetMapReply rep; + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = XKB_USE_CORE_KBD; + req->full = 0; + req->partial = XkbKeyTypesMask; + req->firstKeyType = first; + req->nKeyTypes = num; + req->firstKeySym = req->nKeySyms = 0; + req->firstKeyAction = req->nKeyActions = 0; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + + nRead= _XkbReadKeyTypes(dpy,xkb,&rep,0)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"GetKeyTypes! wrong length (read %d, expected %d)\n", + nRead, rep.length); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbGetKeyActions(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescRec *xkb; +{ + register xkbGetMapReq *req; + xkbGetMapReply rep; + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = XKB_USE_CORE_KBD; + req->full = 0; + req->partial = XkbKeyActionsMask; + req->firstKeyType = req->nKeyTypes = 0; + req->firstKeySym = req->nKeySyms = 0; + req->firstKeyAction = first; + req->nKeyActions = num; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + if (!xkb->server) + _XkbInitServerMap(xkb); + + nRead= _XkbReadKeyActions(dpy,xkb,&rep,0)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"GetKeyActions! bad length (read %d, expected %d)\n", + nRead, rep.length); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbGetKeySyms(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescRec *xkb; +{ + register xkbGetMapReq *req; + xkbGetMapReply rep; + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = XKB_USE_CORE_KBD; + req->full = 0; + req->partial = XkbKeySymsMask; + req->firstKeyType = req->nKeyTypes = 0; + req->firstKeySym = first; + req->nKeySyms = num; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + req->firstKeyAction = req->nKeyActions = 0; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + nRead= _XkbReadKeySyms(dpy,xkb,&rep,0)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"GetKeySyms! bad length (read %d, expected %d)\n", + nRead, rep.length); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbGetKeyBehaviors(dpy,first,num,xkb) + Display *dpy; + unsigned first; + unsigned num; + XkbDescRec *xkb; +{ + register xkbGetMapReq *req; + xkbGetMapReply rep; + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = XKB_USE_CORE_KBD; + req->full = 0; + req->partial = XkbKeyBehaviorsMask; + req->firstKeyType = req->nKeyTypes = 0; + req->firstKeySym = req->nKeySyms = 0; + req->firstKeyAction = req->nKeyActions = 0; + req->firstKeyBehavior = first; + req->nKeyBehaviors = num; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + if (!xkb->server) + _XkbInitServerMap(xkb); + + nRead= _XkbReadKeyBehaviors(dpy,xkb,&rep)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"GetKeyBehaviors! bad length (read %d, expected %d)\n", + nRead, rep.length); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XkbGetControls(dpy, which, desc) + Display *dpy; + unsigned long which; + XkbDescRec *desc; +{ + register xkbGetControlsReq *req; + xkbGetControlsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if ((!desc) || (!which)) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + if (!desc->controls) { + desc->controls = (XkbControlsRec *)Xmalloc(sizeof(XkbControlsRec)); + if (!desc->controls) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + bzero(desc->controls,sizeof(XkbControlsRec)); + } + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetControls; + req->deviceSpec = desc->deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, + (sizeof(xkbGetControlsReply)-sizeof(xReply))>>2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + desc->controls->enabledControls = rep.enabledControls; + if (which&XkbKeyboardGroupsMask) + desc->controls->numGroups= rep.numGroups; + if (which&XkbInternalModsMask) + desc->controls->internalMods = rep.internalMods; + if (which&XkbIgnoreLockModsMask) + desc->controls->ignoreLockMods = rep.ignoreLockMods; + if (which&XkbRepeatKeysMask) { + desc->controls->repeatDelay = rep.repeatDelay; + desc->controls->repeatInterval = rep.repeatInterval; + } + if (which&XkbSlowKeysMask) + desc->controls->slowKeysDelay = rep.slowKeysDelay; + if (which&XkbBounceKeysMask) + desc->controls->debounceDelay = rep.debounceDelay; + if (which&XkbMouseKeysMask) { + desc->controls->mouseKeysDfltBtn = rep.mouseKeysDfltBtn; + desc->controls->mouseKeysDelay = rep.mouseKeysDelay; + desc->controls->mouseKeysInterval = rep.mouseKeysInterval; + } + if (which&XkbMouseKeysAccelMask) { + desc->controls->mouseKeysTimeToMax = rep.mouseKeysTimeToMax; + desc->controls->mouseKeysMaxSpeed = rep.mouseKeysMaxSpeed; + desc->controls->mouseKeysCurve = rep.mouseKeysCurve; + } + if (which&XkbAccessXTimeoutMask) { + desc->controls->accessXTimeout = rep.accessXTimeout; + desc->controls->accessXTimeoutMask = rep.accessXTimeoutMask; + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XkbSetControls(dpy, which, desc) + Display *dpy; + unsigned long which; + XkbDescRec *desc; +{ + register xkbSetControlsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if ((!desc)||(!desc->controls)) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetControls, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetControls; + req->deviceSpec = desc->deviceSpec; + req->changeControls = which; + if (which&XkbInternalModsMask) { + req->affectInternalMods= 0xff; + req->internalMods= desc->controls->internalMods; + } + else { + req->affectInternalMods = req->internalMods = 0; + } + if (which&XkbIgnoreLockModsMask) { + req->affectIgnoreLockMods= 0xff; + req->ignoreLockMods= desc->controls->ignoreLockMods; + } + else { + req->affectIgnoreLockMods = req->ignoreLockMods = 0; + } + if (which&XkbControlsEnabledMask) { + req->affectEnabledControls= XkbAllControlsMask; + req->enabledControls= desc->controls->enabledControls; + } + else { + req->affectEnabledControls = req->enabledControls = 0; + } + if (which&XkbRepeatKeysMask) { + req->repeatDelay = desc->controls->repeatDelay; + req->repeatInterval = desc->controls->repeatInterval; + } + else req->repeatDelay= req->repeatInterval= 0; + if (which&XkbSlowKeysMask) + req->slowKeysDelay = desc->controls->slowKeysDelay; + else req->slowKeysDelay = 0; + if (which&XkbBounceKeysMask) + req->debounceDelay = desc->controls->debounceDelay; + else req->debounceDelay = 0; + if (which&XkbMouseKeysMask) { + req->mouseKeysDfltBtn = desc->controls->mouseKeysDfltBtn; + req->mouseKeysDelay = desc->controls->mouseKeysDelay; + req->mouseKeysInterval = desc->controls->mouseKeysInterval; + req->mouseKeysTimeToMax = desc->controls->mouseKeysTimeToMax; + req->mouseKeysCurve = 0; + } + else { + req->mouseKeysDfltBtn = 0; + req->mouseKeysDelay = req->mouseKeysInterval = 0; + req->mouseKeysTimeToMax = 0; + req->mouseKeysCurve = 0; + } + if (which&XkbAccessXTimeoutMask) { + req->accessXTimeout = desc->controls->accessXTimeout; + req->accessXTimeoutMask = desc->controls->accessXTimeoutMask; + } + else { + req->accessXTimeout = 0; + req->accessXTimeoutMask = 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return 1; +} + +/***====================================================================***/ + +static Status +_XkbReadGetNamesReply(dpy,rep,pMap) + Display *dpy; + xkbGetNamesReply *rep; + XkbDescRec *pMap; +{ + int i,len; + char *start,*desc; + + if ( pMap->deviceSpec == XKB_USE_CORE_KBD ) + pMap->deviceSpec = rep->deviceID; + + if (rep->which&XkbKeycodesNameMask) + pMap->names->keycodes= rep->keycodes; + if (rep->which&XkbGeometryNameMask) + pMap->names->geometry= rep->geometry; + + start = desc = Xmalloc(rep->length*4); + if (desc==NULL) { + return False; + } + _XRead(dpy, (char *)desc, rep->length*4); + if ( rep->which & XkbKeyTypeNamesMask ) { + len = pMap->map->nKeyTypes*sizeof(Atom); + if (!pMap->names->keyTypes) { + pMap->names->keyTypes = (Atom *)Xmalloc(len); + if (!pMap->names->keyTypes) { + Xfree(start); + return False; + } + } + len= rep->nKeyTypes*sizeof(Atom); + bcopy(desc,(char *)pMap->names->keyTypes,len); + desc+= len; + } + if ( rep->which&XkbKTLevelNamesMask ) { + char *nLevels; + Atom *levelNames; + + len= sizeof(Atom *)*pMap->map->nKeyTypes; + if (!pMap->names->levels) { + pMap->names->levels= (Atom **)Xmalloc(len); + if (!pMap->names->levels) { + Xfree(start); + return False; + } + bzero((char *)pMap->names->levels,len); + } + nLevels = desc; + desc+= ((rep->nKeyTypes+3)/4)*4; + for (i=0;i<rep->nKeyTypes;i++) { + if (nLevels[i]!=pMap->map->keyTypes[i].groupWidth) { + fprintf(stderr,"groupWidth in names doesn't match key types\n"); + Xfree(start); + return False; + } + } + for (i=0;i<pMap->map->nKeyTypes;i++) { + len = sizeof(Atom)*nLevels[i]; + levelNames = (Atom *)desc; + if (pMap->names->levels[i]==NULL) + pMap->names->levels[i]=(Atom *)Xmalloc(len); + if (pMap->names->levels[i]) + bcopy(levelNames,pMap->names->levels[i],len); + else { + Xfree(start); + return False; + } + desc+= len; + } + } + if ( rep->which&XkbRGNamesMask ) { + if (rep->nRadioGroups>0) { + len= sizeof(Atom)*rep->nRadioGroups; + if (pMap->names->radioGroups==NULL) { + pMap->names->radioGroups = (Atom *)Xmalloc(len); + } + else if (pMap->names->nRadioGroups<rep->nRadioGroups) { + pMap->names->radioGroups = (Atom *) + Xrealloc(pMap->names->radioGroups,len); + } + if (!pMap->names->radioGroups) { + fprintf(stderr,"Couldn't allocate radio group names\n"); + Xfree(start); + return False; + } + bcopy(desc,(char *)pMap->names->radioGroups,len); + pMap->names->nRadioGroups= rep->nRadioGroups; + desc+= len; + } + else { + } + } + if (rep->which & XkbIndicatorNamesMask) { + bcopy(desc,pMap->names->indicators,XKB_NUM_INDICATORS*sizeof(Atom)); + desc+= XKB_NUM_INDICATORS*sizeof(Atom); + } + if ( rep->which&XkbModifierNamesMask ) { + bcopy(desc,&pMap->names->modifiers[0],8*sizeof(Atom)); + desc+= (8*sizeof(Atom)); + } + if ( (rep->which&XkbCharSetsMask)&&(rep->nCharSets>0) ) { + len= rep->nCharSets*sizeof(Atom); + if (pMap->names->charSets) { + if (pMap->names->nCharSets<rep->nCharSets) { + Xfree(pMap->names->charSets); + pMap->names->charSets= NULL; + pMap->names->nCharSets= 0; + } + } + if (!pMap->names->charSets) { + pMap->names->charSets= (Atom *)Xmalloc(len); + if (!pMap->names->charSets) { + fprintf(stderr,"Couldn't allocate char set names\n"); + Xfree(start); + return False; + } + bcopy(desc,(char*)pMap->names->charSets,len); + pMap->names->nCharSets= rep->nCharSets; + desc+= len; + } + } + if (((desc-start)>>2)!=rep->length) { + fprintf(stderr,"Warning! Bad length (got %d, not %d) in XkbGetNames\n", + (desc-start)>>2,rep->length); + } + Xfree(start); + return True; +} + +Status +XkbGetNames(dpy,which,pMap) + Display *dpy; + unsigned which; + XkbDescRec *pMap; +{ + register xkbGetNamesReq *req; + xkbGetNamesReply rep; + Status ok; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (!pMap->names) { + pMap->names = (XkbNamesRec *)Xmalloc(sizeof(XkbNamesRec)); + if (pMap->names) + bzero(pMap->names,sizeof(XkbNamesRec)); + else { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + } + GetReq(kbGetNames, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetNames; + req->deviceSpec = pMap->deviceSpec; + req->which = which; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + ok = _XkbReadGetNamesReply(dpy,&rep,pMap); + UnlockDisplay(dpy); + SyncHandle(); + return ok; +} + +Status +XkbSetNames(dpy,which,firstKeyType,nKeyTypes,pMap) + Display *dpy; + unsigned which; + unsigned firstKeyType; + unsigned nKeyTypes; + XkbDescRec *pMap; +{ + register xkbSetNamesReq *req; + int nNames; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if ((!pMap)||(!pMap->names)) + return False; + if (which&XkbKTLevelNamesMask) { + register int i; + if((!pMap->names->levels)||(pMap->map->keyTypes==NULL)||(nKeyTypes==0)|| + (firstKeyType+nKeyTypes>pMap->map->nKeyTypes)) + return False; + for (i=nNames=0;i<nKeyTypes;i++) { + if (pMap->names->levels[i+firstKeyType]==NULL) + return False; + nNames+= pMap->map->keyTypes[i+firstKeyType].groupWidth; + } + } + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNames, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetNames; + req->deviceSpec = pMap->deviceSpec; + req->which = which; + req->keycodes = pMap->names->keycodes; + req->geometry = pMap->names->geometry; + req->firstKeyType = firstKeyType; + req->nKeyTypes = nKeyTypes; + if (which&XkbModifierNamesMask) + req->length+= (8*sizeof(Atom))/4; + if (which&XkbKTLevelNamesMask) + req->length+= ((((nKeyTypes+3)/4)*4)+(nNames*sizeof(Atom)))/4; + + if (which&XkbModifierNamesMask) { + char *buf; + BufAlloc(char *,buf,8*sizeof(Atom)); + bcopy(pMap->names->modifiers,buf,8*sizeof(Atom)); + } + if (which&XkbKTLevelNamesMask) { + XkbKeyTypeRec *pKeyType; + char *buf,*tmp; + int i,sz; + sz = ((nKeyTypes+3)/4)*4+(nNames*sizeof(Atom)); + BufAlloc(char *,buf,sz); + tmp = buf; + pKeyType = &pMap->map->keyTypes[firstKeyType]; + for (i=0;i<nKeyTypes;i++,pKeyType++) { + *tmp++ = pKeyType->groupWidth; + } + tmp = &buf[((nKeyTypes+3)/4)*4]; + pKeyType = &pMap->map->keyTypes[firstKeyType]; + for (i=0;i<nKeyTypes;i++,pKeyType++) { + bcopy(pMap->names->levels[i+firstKeyType],tmp, + pKeyType->groupWidth*sizeof(Atom)); + tmp+= pKeyType->groupWidth*sizeof(Atom); + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbGetState(dpy,deviceSpec,rtrn) + Display *dpy; + unsigned deviceSpec; + XkbStateRec *rtrn; +{ + register xkbGetStateReq *req; + xkbGetStateReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetState, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetState; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + rtrn->mods= rep.mods; + rtrn->baseMods= rep.baseMods; + rtrn->latchedMods= rep.latchedMods; + rtrn->lockedMods= rep.lockedMods; + rtrn->group= rep.group; + rtrn->baseGroup = rep.baseGroup; + rtrn->latchedGroup= rep.latchedGroup; + rtrn->lockedGroup = rep.lockedGroup; + rtrn->compatState= rep.compatState; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +/***====================================================================***/ + +static int +XkbSizeKeyTypes(xkb,firstKeyType,nKeyTypes) + XkbDescRec *xkb; + unsigned firstKeyType; + unsigned nKeyTypes; +{ + XkbKeyTypeRec *map; + int i,len; + + len= 0; + map= &xkb->map->keyTypes[firstKeyType]; + for (i=0;i<nKeyTypes;i++,map++){ + len+= sizeof(xkbKeyTypeWireDesc)+(((XkbKTMapWidth(map)+3)/4)*4); + if (map->preserve) + len+= (((XkbKTMapWidth(map)+3)/4)*4); + } + return len; +} + +static void +XkbWriteKeyTypes(dpy,xkb,firstKeyType,nKeyTypes) + Display *dpy; + XkbDescRec *xkb; + unsigned firstKeyType; + unsigned nKeyTypes; +{ + char *buf; + XkbKeyTypeRec *map; + int i,sz; + xkbKeyTypeWireDesc *desc; + + map= &xkb->map->keyTypes[firstKeyType]; + for (i=0;i<nKeyTypes;i++,map++) { + sz= (((XkbKTMapWidth(map)*(map->preserve?2:1))+3)/4)*4; + BufAlloc(xkbKeyTypeWireDesc *,desc,sz+sizeof(xkbKeyTypeWireDesc)); + desc->flags = (map->preserve?xkb_KTHasPreserve:0); + desc->mask = map->mask; + desc->groupWidth = map->groupWidth; + desc->mapWidth = XkbKTMapWidth(map); + buf= (char *)&desc[1]; + bcopy(map->map,buf,XkbKTMapWidth(map)); + buf+= XkbKTMapWidth(map); + if (map->preserve) { + bcopy(map->preserve,buf,XkbKTMapWidth(map)); + } + buf+= sz-XkbKTMapWidth(map); + } + return; +} + +static int +XkbSizeKeySyms(xkb,firstKey,nKeys,nSymsRtrn) + XkbDescRec *xkb; + unsigned firstKey; + unsigned nKeys; + CARD16 *nSymsRtrn; +{ + XkbSymMapRec *symMap; + XkbKeyTypeRec *keyType; + int i,len; + unsigned nSyms; + + len= nKeys*sizeof(XkbSymMapRec); + symMap = &xkb->map->keySymMap[firstKey]; + for (i=nSyms=0;i<nKeys;i++,symMap++) { + keyType = &xkb->map->keyTypes[symMap->ktIndex]; + nSyms+= XkbNumGroups(symMap->groupInfo)*keyType->groupWidth; + } + len+= nSyms*sizeof(KeySym); + *nSymsRtrn = nSyms; + return len; +} + +static void +XkbWriteKeySyms(dpy,xkb,firstKeySym,nKeySyms,totalSyms) + Display *dpy; + XkbDescRec *xkb; + unsigned firstKeySym; + unsigned nKeySyms; + unsigned totalSyms; +{ +register KeySym *pSym,*outSym; +XkbSymMapRec *symMap; +XkbKeyTypeRec *keyType; +xkbSymMapWireDesc *desc; +register int i; + + i= (nKeySyms*sizeof(xkbSymMapWireDesc))+(totalSyms*sizeof(KeySym)); + BufAlloc(xkbSymMapWireDesc *,desc,i); + symMap = &xkb->map->keySymMap[firstKeySym]; + for (i=0;i<nKeySyms;i++,symMap++) { + keyType = &xkb->map->keyTypes[symMap->ktIndex]; + desc->ktIndex = symMap->ktIndex; + desc->groupInfo = symMap->groupInfo; + desc->nSyms = XkbNumGroups(symMap->groupInfo)*keyType->groupWidth; + outSym = (KeySym *)&desc[1]; + pSym = &xkb->map->syms[symMap->offset]; + bcopy(pSym,outSym,desc->nSyms*sizeof(KeySym)); + desc = (xkbSymMapWireDesc *)&outSym[desc->nSyms]; + } + return; +} + +static int +XkbSizeKeyActions(xkb,firstKey,nKeys,nActsRtrn) + XkbDescRec *xkb; + unsigned firstKey; + unsigned nKeys; + CARD16 *nActsRtrn; +{ + int i,len,nActs; + unsigned nSyms; + + for (nActs=i=0;i<nKeys;i++) { + if (xkb->server->keyActions[i+firstKey]!=0) + nActs+= XkbKeyNumActions(xkb,i+firstKey); + } + len= (((nKeys+3)/4)*4)+(nActs*sizeof(XkbAction)); + *nActsRtrn = nActs; + return len; +} + +static void +XkbWriteKeyActions(dpy,xkb,firstKey,nKeys,totalActs) + Display *dpy; + XkbDescRec *xkb; + unsigned firstKey; + unsigned nKeys; + unsigned totalActs; +{ + register int i; + int n; + CARD8 *numDesc; + XkbAction *actDesc; + + n = (((nKeys+3)/4)*4)+totalActs*sizeof(XkbAction); + BufAlloc(CARD8 *,numDesc,n); + for (i=0;i<nKeys;i++) { + if (xkb->server->keyActions[i+firstKey]==0) + numDesc[i] = 0; + else numDesc[i] = XkbKeyNumActions(xkb,(i+firstKey)); + } + actDesc = (XkbAction *)&numDesc[(((nKeys)+3)/4)*4]; + for (i=0;i<nKeys;i++) { + if (xkb->server->keyActions[i+firstKey]!=0) { + n = XkbKeyNumActions(xkb,(i+firstKey)); + bcopy(XkbKeyActionsPtr(xkb,(i+firstKey)),actDesc, + n*sizeof(XkbAction)); + actDesc+= n; + } + } + return; +} + +static void +SendSetMap(dpy,xkb,req) + Display *dpy; + XkbDescRec *xkb; + xkbSetMapReq *req; +{ +xkbSetMapReq tmp; + + req->length+= XkbSizeKeyTypes(xkb,req->firstKeyType,req->nKeyTypes)/4; + req->length+= XkbSizeKeySyms(xkb,req->firstKeySym,req->nKeySyms, + &req->totalSyms)/4; + req->length+= XkbSizeKeyActions(xkb,req->firstKeyAction,req->nKeyActions, + &req->totalActions)/4; + req->length+= (req->nKeyBehaviors*sizeof(XkbAction))/4; + + tmp= *req; + if ( tmp.nKeyTypes>0 ) + XkbWriteKeyTypes(dpy,xkb,tmp.firstKeyType,tmp.nKeyTypes); + if ( tmp.nKeySyms>0 ) + XkbWriteKeySyms(dpy,xkb,tmp.firstKeySym,tmp.nKeySyms,tmp.totalSyms); + if ( tmp.nKeyActions ) + XkbWriteKeyActions(dpy,xkb,tmp.firstKeyAction,tmp.nKeyActions, + tmp.totalActions); + if ( tmp.nKeyBehaviors>0 ) { + register int sz; + char *buf; + + sz = tmp.nKeyBehaviors*sizeof(XkbAction); + BufAlloc(char *,buf,sz); + bcopy(&xkb->server->keyBehaviors[tmp.firstKeyBehavior],buf,sz); + } + return; +} + +Status +XkbSetMap(dpy,which,xkb) + Display *dpy; + unsigned which; + XkbDescRec *xkb; +{ + register xkbSetMapReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + + if (((which&XkbKeyTypesMask)&&(!xkb->map->keyTypes))|| + ((which&XkbKeySymsMask)&&((!xkb->map->syms)||(!xkb->map->keySymMap)))|| + ((which&XkbKeyActionsMask)&& + ((!xkb->server)||(!xkb->server->keyActions)))|| + ((which&XkbKeyBehaviorsMask)&& + ((!xkb->server)||(!xkb->server->keyBehaviors)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->deviceSpec; + req->present = which; + req->resize = which&XkbResizableInfoMask; + req->firstKeyType = 0; + if (which&XkbKeyTypesMask) req->nKeyTypes = xkb->map->nKeyTypes; + else req->nKeyTypes = 0; + req->firstKeySym = 0; + if (which&XkbKeySymsMask) { + req->firstKeySym = xkb->minKeyCode; + req->nKeySyms = xkb->maxKeyCode-xkb->minKeyCode+1; + } + if (which&XkbKeyActionsMask) { + req->firstKeyAction = xkb->minKeyCode; + req->nKeyActions = xkb->maxKeyCode-xkb->minKeyCode+1; + } + if (which&XkbKeyBehaviorsMask) { + req->firstKeyBehavior = xkb->minKeyCode; + req->nKeyBehaviors = xkb->maxKeyCode-xkb->minKeyCode+1; + } + SendSetMap(dpy,xkb,req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbChangeMap(dpy,xkb,changes) + Display *dpy; + XkbDescRec *xkb; + XkbMapChangesRec *changes; +{ + register xkbSetMapReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + + if (((changes->changed&XkbKeyTypesMask)&&(!xkb->map->keyTypes))|| + ((changes->changed&XkbKeySymsMask)&&((!xkb->map->syms)|| + (!xkb->map->keySymMap)))|| + ((changes->changed&XkbKeyActionsMask)&& + ((!xkb->server)||(!xkb->server->keyActions)))|| + ((changes->changed&XkbKeyBehaviorsMask)&& + ((!xkb->server)||(!xkb->server->keyBehaviors)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->deviceSpec; + req->present = changes->changed; + req->resize = 0; + req->firstKeyType = changes->firstKeyType; + req->nKeyTypes = changes->nKeyTypes; + req->firstKeySym = changes->firstKeySym; + req->nKeySyms = changes->nKeySyms; + req->firstKeyAction = changes->firstKeyAction; + req->nKeyActions = changes->nKeyActions; + req->firstKeyBehavior = changes->firstKeyBehavior; + req->nKeyBehaviors = changes->nKeyBehaviors; + SendSetMap(dpy,xkb,req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +/***====================================================================***/ + +Status +XkbGetIndicatorState(dpy,deviceSpec,pStateRtrn) + Display *dpy; + unsigned int deviceSpec; + CARD32 *pStateRtrn; +{ + register xkbGetIndicatorStateReq *req; + xkbGetIndicatorStateReply rep; + XkbInfoPtr xkbi; + + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetIndicatorState, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetIndicatorState; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (pStateRtrn) + *pStateRtrn= rep.state; + return True; +} + +Status +XkbGetIndicatorMap(dpy,which,xkb) + Display *dpy; + unsigned long which; + XkbDescRec *xkb; +{ + register xkbGetIndicatorMapReq *req; + XkbIndicatorRec *leds; + xkbGetIndicatorMapReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if ((!which)||(!xkb)) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetIndicatorMap, req); + if (!xkb->indicators) { + xkb->indicators = (XkbIndicatorRec *)Xmalloc(sizeof(XkbIndicatorRec)); + if (xkb->indicators) + bzero(xkb->indicators,sizeof(XkbIndicatorRec)); + } + leds = xkb->indicators; + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetIndicatorMap; + req->deviceSpec = xkb->deviceSpec; + req->which = which; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + leds->nRealIndicators = rep.nRealIndicators; + if (rep.which) { + register int i,bit,left; + left= which; + for (i=0,bit=1;(i<32)&&(left);i++,bit<<=1) { + if (left&bit) { + _XRead(dpy,(char *)&leds->maps[i],sizeof(XkbIndicatorMapRec)); + left&= ~bit; + } + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbSetIndicatorMap(dpy,which,xkb) + Display *dpy; + unsigned long which; + XkbDescRec *xkb; +{ + register xkbSetIndicatorMapReq *req; + register int i,bit; + int nMaps; + xkbIndicatorMapWireDesc *wire; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + if ((!xkb)||(!which)||(!xkb->indicators)) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetIndicatorMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbSetIndicatorMap; + req->deviceSpec = xkb->deviceSpec; + req->which = which; + for (i=0,bit=1;i<32;i++,bit<<=1) { + if (which&bit) + nMaps++; + } + req->length+= (nMaps*sizeof(XkbIndicatorMapRec))/4; + BufAlloc(xkbIndicatorMapWireDesc *,wire,(nMaps*sizeof(XkbIndicatorMapRec))); + for (i=0,bit=1;i<32;i++,bit<<=1) { + if (which&bit) { + wire->whichMods= xkb->indicators->maps[i].whichMods; + wire->mods= xkb->indicators->maps[i].mods; + wire->whichGroups= xkb->indicators->maps[i].whichGroups; + wire->groups= xkb->indicators->maps[i].groups; + wire->controls= xkb->indicators->maps[i].controls; + wire++; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +/***====================================================================***/ + +Status +XkbRefreshMap(dpy,xkb,changes) + Display *dpy; + XkbDescRec *xkb; + XkbMapChangesRec *changes; +{ + xkbGetMapReq *req; + xkbGetMapReply rep; + int nRead; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !_XkbInitializeDpy(dpy))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (changes->changed) { + GetReq(kbGetMap, req); + req->reqType = xkbi->xkb_ext_major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = XKB_USE_CORE_KBD; + req->full = 0; + req->partial = changes->changed; + req->firstKeyType = changes->firstKeyType; + req->nKeyTypes = changes->nKeyTypes; + req->firstKeySym = changes->firstKeySym; + req->nKeySyms = changes->nKeySyms; + req->firstKeyAction = changes->firstKeyAction; + req->nKeyActions = changes->nKeyActions; + req->firstKeyBehavior = changes->firstKeyBehavior; + req->nKeyBehaviors = changes->nKeyBehaviors; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if ( xkb->deviceSpec == XKB_USE_CORE_KBD ) + xkb->deviceSpec = rep.deviceID; + xkb->minKeyCode = dpy->min_keycode; + xkb->maxKeyCode = dpy->max_keycode; + + nRead= _XkbReadKeyTypes(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeySyms(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeyActions(dpy,xkb,&rep,1)/4; + nRead+= _XkbReadKeyBehaviors(dpy,xkb,&rep,1)/4; + if ( nRead!=rep.length ) { + fprintf(stderr,"XkbRefresh! wrong length (read %d, expected %d)\n", + nRead, rep.length); + } + SyncHandle(); + UnlockDisplay(dpy); + } + return True; +} |