diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2017-07-21 12:31:09 +0200 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2017-08-25 10:06:49 +0200 |
commit | c350873c7c977efe5210484f04160be45f84ba7e (patch) | |
tree | 717d33eb315f4def1307d65108d14715696cd5cf /nx-X11/lib/src/xkb | |
parent | 1472e7e37838f17b7ed948fa206e8c3434a9d346 (diff) | |
download | nx-libs-c350873c7c977efe5210484f04160be45f84ba7e.tar.gz nx-libs-c350873c7c977efe5210484f04160be45f84ba7e.tar.bz2 nx-libs-c350873c7c977efe5210484f04160be45f84ba7e.zip |
Convert nx-X11/lib/ build flow from imake to autotools.
Diffstat (limited to 'nx-X11/lib/src/xkb')
-rw-r--r-- | nx-X11/lib/src/xkb/Makefile.am | 46 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKB.c | 771 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBAlloc.c | 495 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBBell.c | 179 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBBind.c | 784 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBCompat.c | 252 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBCtrls.c | 351 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBCvt.c | 341 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBExtDev.c | 843 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBGAlloc.c | 994 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBGeom.c | 724 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBGetByName.c | 226 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBGetMap.c | 882 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBList.c | 256 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBMAlloc.c | 1016 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBMisc.c | 1021 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBNames.c | 879 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBRdBuf.c | 203 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBSetGeom.c | 478 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBSetMap.c | 598 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBUse.c | 814 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBleds.c | 338 | ||||
-rw-r--r-- | nx-X11/lib/src/xkb/XKBlibint.h | 337 |
23 files changed, 12828 insertions, 0 deletions
diff --git a/nx-X11/lib/src/xkb/Makefile.am b/nx-X11/lib/src/xkb/Makefile.am new file mode 100644 index 000000000..b22eb9fad --- /dev/null +++ b/nx-X11/lib/src/xkb/Makefile.am @@ -0,0 +1,46 @@ +NULL = + +noinst_LTLIBRARIES = libxkb.la + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/include/X11 \ + -I$(top_builddir)/include \ + -I$(top_builddir)/include/X11 \ + -I$(top_srcdir)/src/xcms \ + -I$(top_srcdir)/src/xkb \ + -I$(top_srcdir)/src/xlibi18n \ + -I$(top_srcdir)/../exports/include \ + -D_GNU_SOURCE \ + $(NULL) + +AM_CFLAGS = \ + $(X11_CFLAGS) \ + $(BIGFONT_CFLAGS) \ + $(XMALLOC_ZERO_CFLAGS) \ + $(CWARNFLAGS) \ + $(NULL) + +libxkb_la_SOURCES = \ + XKB.c \ + XKBBind.c \ + XKBCompat.c \ + XKBCtrls.c \ + XKBCvt.c \ + XKBGetMap.c \ + XKBGetByName.c \ + XKBNames.c \ + XKBRdBuf.c \ + XKBSetMap.c \ + XKBUse.c \ + XKBleds.c \ + XKBBell.c \ + XKBGeom.c \ + XKBSetGeom.c \ + XKBExtDev.c \ + XKBList.c \ + XKBMisc.c \ + XKBMAlloc.c \ + XKBGAlloc.c \ + XKBAlloc.c \ + $(NULL) diff --git a/nx-X11/lib/src/xkb/XKB.c b/nx-X11/lib/src/xkb/XKB.c new file mode 100644 index 000000000..6df9c3ebc --- /dev/null +++ b/nx-X11/lib/src/xkb/XKB.c @@ -0,0 +1,771 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +XkbInternAtomFunc _XkbInternAtomFunc = XInternAtom; +XkbGetAtomNameFunc _XkbGetAtomNameFunc = XGetAtomName; + +Bool +XkbQueryExtension(Display *dpy, + int *opcodeReturn, + int *eventBaseReturn, + int *errorBaseReturn, + int *majorReturn, + int *minorReturn) +{ + if (!XkbUseExtension(dpy, majorReturn, minorReturn)) + return False; + if (opcodeReturn) + *opcodeReturn = dpy->xkb_info->codes->major_opcode; + if (eventBaseReturn) + *eventBaseReturn = dpy->xkb_info->codes->first_event; + if (errorBaseReturn) + *errorBaseReturn = dpy->xkb_info->codes->first_error; + if (majorReturn) + *majorReturn = dpy->xkb_info->srv_major; + if (minorReturn) + *minorReturn = dpy->xkb_info->srv_minor; + return True; +} + +Bool +XkbLibraryVersion(int *libMajorRtrn, int *libMinorRtrn) +{ + int supported; + + if (*libMajorRtrn != XkbMajorVersion) { + /* version 0.65 is (almost) compatible with 1.00 */ + if ((XkbMajorVersion == 1) && + (((*libMajorRtrn) == 0) && ((*libMinorRtrn) == 65))) + supported = True; + else + supported = False; + } + else { + supported = True; + } + + *libMajorRtrn = XkbMajorVersion; + *libMinorRtrn = XkbMinorVersion; + return supported; +} + +Bool +XkbSelectEvents(Display *dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int selectAll) +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + xkbi->selected_events &= ~affect; + xkbi->selected_events |= (affect & selectAll); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + req->affectWhich = (CARD16) affect; + req->clear = affect & (~selectAll); + req->selectAll = affect & selectAll; + if (affect & XkbMapNotifyMask) { + req->affectMap = XkbAllMapComponentsMask; + /* the implicit support needs the client info */ + /* even if the client itself doesn't want it */ + if (selectAll & XkbMapNotifyMask) + req->map = XkbAllMapEventsMask; + else + req->map = XkbAllClientInfoMask; + if (selectAll & XkbMapNotifyMask) + xkbi->selected_map_details = XkbAllMapEventsMask; + else + xkbi->selected_map_details = 0; + } + if (affect & XkbNewKeyboardNotifyMask) { + if (selectAll & XkbNewKeyboardNotifyMask) + xkbi->selected_nkn_details = XkbAllNewKeyboardEventsMask; + else + xkbi->selected_nkn_details = 0; + if (!(xkbi->xlib_ctrls & XkbLC_IgnoreNewKeyboards)) { + /* we want it, even if the client doesn't. Don't mess */ + /* around with details -- ask for all of them and throw */ + /* away the ones we don't need */ + req->selectAll |= XkbNewKeyboardNotifyMask; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbSelectEventDetails(Display *dpy, + unsigned deviceSpec, + unsigned eventType, + unsigned long int affect, + unsigned long int details) +{ + register xkbSelectEventsReq *req; + XkbInfoPtr xkbi; + int size = 0; + char *out; + union { + CARD8 *c8; + CARD16 *c16; + CARD32 *c32; + } u; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (affect & details) + xkbi->selected_events |= (1 << eventType); + else + xkbi->selected_events &= ~(1 << eventType); + GetReq(kbSelectEvents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSelectEvents; + req->deviceSpec = deviceSpec; + req->clear = req->selectAll = 0; + if (eventType == XkbMapNotify) { + /* we need all of the client info, even if the application */ + /* doesn't. Make sure that we always request the stuff */ + /* that the implicit support needs, and just filter out anything */ + /* the client doesn't want later */ + req->affectMap = (CARD16) affect; + req->map = (CARD16) details | (XkbAllClientInfoMask & affect); + req->affectWhich = XkbMapNotifyMask; + xkbi->selected_map_details &= ~affect; + xkbi->selected_map_details |= (details & affect); + } + else { + req->affectMap = req->map = 0; + req->affectWhich = (1 << eventType); + switch (eventType) { + case XkbNewKeyboardNotify: + xkbi->selected_nkn_details &= ~affect; + xkbi->selected_nkn_details |= (details & affect); + if (!(xkbi->xlib_ctrls & XkbLC_IgnoreNewKeyboards)) + details = (affect & XkbAllNewKeyboardEventsMask); + case XkbStateNotify: + case XkbNamesNotify: + case XkbAccessXNotify: + case XkbExtensionDeviceNotify: + size = 2; + req->length += 1; + break; + case XkbControlsNotify: + case XkbIndicatorStateNotify: + case XkbIndicatorMapNotify: + size = 4; + req->length += 2; + break; + case XkbBellNotify: + case XkbActionMessage: + case XkbCompatMapNotify: + size = 1; + req->length += 1; + break; + } + BufAlloc(char *, out, (((size * 2) + (unsigned) 3) / 4) * 4); + + u.c8 = (CARD8 *) out; + if (size == 2) { + u.c16[0] = (CARD16) affect; + u.c16[1] = (CARD16) details; + } + else if (size == 4) { + u.c32[0] = (CARD32) affect; + u.c32[1] = (CARD32) details; + } + else { + u.c8[0] = (CARD8) affect; + u.c8[1] = (CARD8) details; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbLockModifiers(Display *dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int values) +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->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 True; +} + +Bool +XkbLatchModifiers(Display *dpy, + unsigned int deviceSpec, + unsigned int affect, + unsigned int values) +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->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 True; +} + +Bool +XkbLockGroup(Display *dpy, unsigned int deviceSpec, unsigned int group) +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + req->affectModLocks = 0; + req->modLocks = 0; + req->lockGroup = True; + req->groupLock = group; + + req->affectModLatches = req->modLatches = 0; + req->latchGroup = False; + req->groupLatch = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbLatchGroup(Display *dpy, unsigned int deviceSpec, unsigned int group) +{ + register xkbLatchLockStateReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbLatchLockState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbLatchLockState; + req->deviceSpec = deviceSpec; + + req->affectModLatches = 0; + req->modLatches = 0; + req->latchGroup = True; + req->groupLatch = group; + + req->affectModLocks = req->modLocks = 0; + req->lockGroup = False; + req->groupLock = 0; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +unsigned +XkbSetXlibControls(Display *dpy, unsigned affect, unsigned values) +{ + if (!dpy->xkb_info) + XkbUseExtension(dpy, NULL, NULL); + if (!dpy->xkb_info) + return 0; + affect &= XkbLC_AllControls; + dpy->xkb_info->xlib_ctrls &= ~affect; + dpy->xkb_info->xlib_ctrls |= (affect & values); + return dpy->xkb_info->xlib_ctrls; +} + +unsigned +XkbGetXlibControls(Display *dpy) +{ + if (!dpy->xkb_info) + XkbUseExtension(dpy, NULL, NULL); + if (!dpy->xkb_info) + return 0; + return dpy->xkb_info->xlib_ctrls; +} + +unsigned int +XkbXlibControlsImplemented(void) +{ + return XkbLC_AllControls & ~XkbLC_AllComposeControls; +} + +Bool +XkbSetDebuggingFlags(Display *dpy, + unsigned int mask, + unsigned int flags, + char *msg, + unsigned int ctrls_mask, + unsigned int ctrls, + unsigned int *rtrn_flags, + unsigned int *rtrn_ctrls) +{ + register xkbSetDebuggingFlagsReq *req; + xkbSetDebuggingFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDebuggingFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetDebuggingFlags; + req->affectFlags = mask; + req->flags = flags; + req->affectCtrls = ctrls_mask; + req->ctrls = ctrls; + + if (msg) { + char *out; + + req->msgLength = (unsigned short) strlen(msg) + 1; + req->length += (req->msgLength + (unsigned) 3) >> 2; + BufAlloc(char *, out, ((req->msgLength + (unsigned) 3) / 4) * 4); + memcpy(out, msg, req->msgLength); + } + else + req->msgLength = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (rtrn_flags) + *rtrn_flags = rep.currentFlags; + if (rtrn_ctrls) + *rtrn_ctrls = rep.currentCtrls; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbComputeEffectiveMap(XkbDescPtr xkb, + XkbKeyTypePtr type, + unsigned char *map_rtrn) +{ + register int i; + unsigned tmp; + XkbKTMapEntryPtr entry = NULL; + + if ((!xkb) || (!type) || (!xkb->server)) + return False; + + if (type->mods.vmods != 0) { + if (!XkbVirtualModsToReal(xkb, type->mods.vmods, &tmp)) + return False; + + type->mods.mask = tmp | type->mods.real_mods; + entry = type->map; + for (i = 0; i < type->map_count; i++, entry++) { + tmp = 0; + if (entry->mods.vmods != 0) { + if (!XkbVirtualModsToReal(xkb, entry->mods.vmods, &tmp)) + return False; + if (tmp == 0) { + entry->active = False; + continue; + } + } + entry->active = True; + entry->mods.mask = (entry->mods.real_mods | tmp) & type->mods.mask; + } + } + else { + type->mods.mask = type->mods.real_mods; + } + if (map_rtrn != NULL) { + bzero(map_rtrn, type->mods.mask + 1); + for (i = 0; i < type->map_count; i++) { + if (entry && entry->active) { + map_rtrn[type->map[i].mods.mask] = type->map[i].level; + } + } + } + return True; +} + +Status +XkbGetState(Display *dpy, unsigned deviceSpec, XkbStatePtr rtrn) +{ + register xkbGetStateReq *req; + xkbGetStateReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetState; + req->deviceSpec = deviceSpec; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + rtrn->mods = rep.mods; + rtrn->base_mods = rep.baseMods; + rtrn->latched_mods = rep.latchedMods; + rtrn->locked_mods = rep.lockedMods; + rtrn->group = rep.group; + rtrn->base_group = rep.baseGroup; + rtrn->latched_group = rep.latchedGroup; + rtrn->locked_group = rep.lockedGroup; + rtrn->compat_state = rep.compatState; + rtrn->grab_mods = rep.grabMods; + rtrn->compat_grab_mods = rep.compatGrabMods; + rtrn->lookup_mods = rep.lookupMods; + rtrn->compat_lookup_mods = rep.compatLookupMods; + rtrn->ptr_buttons = rep.ptrBtnState; + UnlockDisplay(dpy); + SyncHandle(); + return Success; +} + +Bool +XkbSetDetectableAutoRepeat(Display *dpy, Bool detectable, Bool *supported) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = XkbPCF_DetectableAutoRepeatMask; + if (detectable) + req->value = XkbPCF_DetectableAutoRepeatMask; + else + req->value = 0; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (supported != NULL) + *supported = ((rep.supported & XkbPCF_DetectableAutoRepeatMask) != 0); + return ((rep.value & XkbPCF_DetectableAutoRepeatMask) != 0); +} + +Bool +XkbGetDetectableAutoRepeat(Display *dpy, Bool *supported) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (supported != NULL) + *supported = ((rep.supported & XkbPCF_DetectableAutoRepeatMask) != 0); + return ((rep.value & XkbPCF_DetectableAutoRepeatMask) != 0); +} + +Bool +XkbSetAutoResetControls(Display *dpy, + unsigned changes, + unsigned *auto_ctrls, + unsigned *auto_values) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->change = XkbPCF_AutoResetControlsMask; + req->deviceSpec = XkbUseCoreKbd; + req->value = XkbPCF_AutoResetControlsMask; + req->ctrlsToChange = changes; + req->autoCtrls = *auto_ctrls; + req->autoCtrlValues = *auto_values; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *auto_ctrls = rep.autoCtrls; + *auto_values = rep.autoCtrlValues; + return ((rep.value & XkbPCF_AutoResetControlsMask) != 0); +} + +Bool +XkbGetAutoResetControls(Display *dpy, + unsigned *auto_ctrls, + unsigned *auto_ctrl_values) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (auto_ctrls) + *auto_ctrls = rep.autoCtrls; + if (auto_ctrl_values) + *auto_ctrl_values = rep.autoCtrlValues; + return ((rep.value & XkbPCF_AutoResetControlsMask) != 0); +} + +Bool +XkbSetPerClientControls(Display *dpy, unsigned change, unsigned *values) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + unsigned value_hold = *values; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || + (change & ~(XkbPCF_GrabsUseXKBStateMask | + XkbPCF_LookupStateWhenGrabbed | + XkbPCF_SendEventUsesXKBState))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->change = change; + req->deviceSpec = XkbUseCoreKbd; + req->value = *values; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *values = rep.value; + return ((rep.value & value_hold) != 0); +} + +Bool +XkbGetPerClientControls(Display *dpy, unsigned *ctrls) +{ + register xkbPerClientFlagsReq *req; + xkbPerClientFlagsReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || + (ctrls == NULL)) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbPerClientFlags, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbPerClientFlags; + req->deviceSpec = XkbUseCoreKbd; + req->change = 0; + req->value = 0; + req->ctrlsToChange = req->autoCtrls = req->autoCtrlValues = 0; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *ctrls = (rep.value & (XkbPCF_GrabsUseXKBStateMask | + XkbPCF_LookupStateWhenGrabbed | + XkbPCF_SendEventUsesXKBState)); + return (True); +} + +Display * +XkbOpenDisplay(char *name, + int *ev_rtrn, + int *err_rtrn, + int *major_rtrn, + int *minor_rtrn, + int *reason) +{ + Display *dpy; + int major_num, minor_num; + + if ((major_rtrn != NULL) && (minor_rtrn != NULL)) { + if (!XkbLibraryVersion(major_rtrn, minor_rtrn)) { + if (reason != NULL) + *reason = XkbOD_BadLibraryVersion; + return NULL; + } + } + else { + major_num = XkbMajorVersion; + minor_num = XkbMinorVersion; + major_rtrn = &major_num; + minor_rtrn = &minor_num; + } + dpy = XOpenDisplay(name); + if (dpy == NULL) { + if (reason != NULL) + *reason = XkbOD_ConnectionRefused; + return NULL; + } + if (!XkbQueryExtension(dpy, NULL, ev_rtrn, err_rtrn, + major_rtrn, minor_rtrn)) { + if (reason != NULL) { + if ((*major_rtrn != 0) || (*minor_rtrn != 0)) + *reason = XkbOD_BadServerVersion; + else + *reason = XkbOD_NonXkbServer; + } + XCloseDisplay(dpy); + return NULL; + } + if (reason != NULL) + *reason = XkbOD_Success; + return dpy; +} + +void +XkbSetAtomFuncs(XkbInternAtomFunc getAtom, XkbGetAtomNameFunc getName) +{ + _XkbInternAtomFunc = (getAtom ? getAtom : XInternAtom); + _XkbGetAtomNameFunc = (getName ? getName : XGetAtomName); + return; +} diff --git a/nx-X11/lib/src/xkb/XKBAlloc.c b/nx-X11/lib/src/xkb/XKBAlloc.c new file mode 100644 index 000000000..9c3430c1a --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBAlloc.c @@ -0,0 +1,495 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + + +#include <stdio.h> +#include "Xlibint.h" +#include "XKBlibint.h" +#include <nx-X11/extensions/XKBgeom.h> +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +/***===================================================================***/ + +/*ARGSUSED*/ +Status +XkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI) +{ + XkbCompatMapPtr compat; + XkbSymInterpretRec *prev_interpret; + + if (!xkb) + return BadMatch; + if (xkb->compat) { + if (xkb->compat->size_si >= nSI) + return Success; + compat = xkb->compat; + compat->size_si = nSI; + if (compat->sym_interpret == NULL) + compat->num_si = 0; + prev_interpret = compat->sym_interpret; + compat->sym_interpret = _XkbTypedRealloc(compat->sym_interpret, + nSI, XkbSymInterpretRec); + if (compat->sym_interpret == NULL) { + _XkbFree(prev_interpret); + compat->size_si = compat->num_si = 0; + return BadAlloc; + } + if (compat->num_si != 0) { + _XkbClearElems(compat->sym_interpret, compat->num_si, + compat->size_si - 1, XkbSymInterpretRec); + } + return Success; + } + compat = _XkbTypedCalloc(1, XkbCompatMapRec); + if (compat == NULL) + return BadAlloc; + if (nSI > 0) { + compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec); + if (!compat->sym_interpret) { + _XkbFree(compat); + return BadAlloc; + } + } + compat->size_si = nSI; + compat->num_si = 0; + bzero((char *) &compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); + xkb->compat = compat; + return Success; +} + + +void +XkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) +{ + register XkbCompatMapPtr compat; + + if ((xkb == NULL) || (xkb->compat == NULL)) + return; + compat = xkb->compat; + if (freeMap) + which = XkbAllCompatMask; + if (which & XkbGroupCompatMask) + bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); + if (which & XkbSymInterpMask) { + if ((compat->sym_interpret) && (compat->size_si > 0)) + _XkbFree(compat->sym_interpret); + compat->size_si = compat->num_si = 0; + compat->sym_interpret = NULL; + } + if (freeMap) { + _XkbFree(compat); + xkb->compat = NULL; + } + return; +} + +/***===================================================================***/ + +Status +XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) +{ + XkbNamesPtr names; + + if (xkb == NULL) + return BadMatch; + if (xkb->names == NULL) { + xkb->names = _XkbTypedCalloc(1, XkbNamesRec); + if (xkb->names == NULL) + return BadAlloc; + } + names = xkb->names; + if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && + (xkb->map->types != NULL)) { + register int i; + XkbKeyTypePtr type = xkb->map->types; + + for (i = 0; i < xkb->map->num_types; i++, type++) { + if (type->level_names == NULL) { + type->level_names = _XkbTypedCalloc(type->num_levels, Atom); + if (type->level_names == NULL) + return BadAlloc; + } + } + } + if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadValue; + names->keys = _XkbTypedCalloc((xkb->max_key_code + 1), XkbKeyNameRec); + if (names->keys == NULL) + return BadAlloc; + } + if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { + if (names->key_aliases == NULL) { + names->key_aliases = _XkbTypedCalloc(nTotalAliases, XkbKeyAliasRec); + } + else if (nTotalAliases > names->num_key_aliases) { + XkbKeyAliasRec *prev_aliases = names->key_aliases; + + names->key_aliases = _XkbTypedRealloc(names->key_aliases, + nTotalAliases, + XkbKeyAliasRec); + if (names->key_aliases != NULL) { + _XkbClearElems(names->key_aliases, names->num_key_aliases, + nTotalAliases - 1, XkbKeyAliasRec); + } + else { + _XkbFree(prev_aliases); + } + } + if (names->key_aliases == NULL) { + names->num_key_aliases = 0; + return BadAlloc; + } + names->num_key_aliases = nTotalAliases; + } + if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { + if (names->radio_groups == NULL) { + names->radio_groups = _XkbTypedCalloc(nTotalRG, Atom); + } + else if (nTotalRG > names->num_rg) { + Atom *prev_radio_groups = names->radio_groups; + + names->radio_groups = + _XkbTypedRealloc(names->radio_groups, nTotalRG, Atom); + if (names->radio_groups != NULL) { + _XkbClearElems(names->radio_groups, names->num_rg, nTotalRG - 1, + Atom); + } + else { + _XkbFree(prev_radio_groups); + } + } + if (names->radio_groups == NULL) + return BadAlloc; + names->num_rg = nTotalRG; + } + return Success; +} + +void +XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) +{ + XkbNamesPtr names; + + if ((xkb == NULL) || (xkb->names == NULL)) + return; + names = xkb->names; + if (freeMap) + which = XkbAllNamesMask; + if (which & XkbKTLevelNamesMask) { + XkbClientMapPtr map = xkb->map; + + if ((map != NULL) && (map->types != NULL)) { + register int i; + register XkbKeyTypePtr type; + + type = map->types; + for (i = 0; i < map->num_types; i++, type++) { + if (type->level_names != NULL) { + _XkbFree(type->level_names); + type->level_names = NULL; + } + } + } + } + if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { + _XkbFree(names->keys); + names->keys = NULL; + names->num_keys = 0; + } + if ((which & XkbKeyAliasesMask) && (names->key_aliases)) { + _XkbFree(names->key_aliases); + names->key_aliases = NULL; + names->num_key_aliases = 0; + } + if ((which & XkbRGNamesMask) && (names->radio_groups)) { + _XkbFree(names->radio_groups); + names->radio_groups = NULL; + names->num_rg = 0; + } + if (freeMap) { + _XkbFree(names); + xkb->names = NULL; + } + return; +} + +/***===================================================================***/ + +/*ARGSUSED*/ +Status +XkbAllocControls(XkbDescPtr xkb, unsigned which) +{ + if (xkb == NULL) + return BadMatch; + + if (xkb->ctrls == NULL) { + xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); + if (!xkb->ctrls) + return BadAlloc; + } + return Success; +} + +/*ARGSUSED*/ +void +XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) +{ + if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { + _XkbFree(xkb->ctrls); + xkb->ctrls = NULL; + } + return; +} + +/***===================================================================***/ + +Status +XkbAllocIndicatorMaps(XkbDescPtr xkb) +{ + if (xkb == NULL) + return BadMatch; + if (xkb->indicators == NULL) { + xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); + if (!xkb->indicators) + return BadAlloc; + } + return Success; +} + +void +XkbFreeIndicatorMaps(XkbDescPtr xkb) +{ + if ((xkb != NULL) && (xkb->indicators != NULL)) { + _XkbFree(xkb->indicators); + xkb->indicators = NULL; + } + return; +} + +/***====================================================================***/ + +XkbDescRec * +XkbAllocKeyboard(void) +{ + XkbDescRec *xkb; + + xkb = _XkbTypedCalloc(1, XkbDescRec); + if (xkb) + xkb->device_spec = XkbUseCoreKbd; + return xkb; +} + +void +XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) +{ + if (xkb == NULL) + return; + if (freeAll) + which = XkbAllComponentsMask; + if (which & XkbClientMapMask) + XkbFreeClientMap(xkb, XkbAllClientInfoMask, True); + if (which & XkbServerMapMask) + XkbFreeServerMap(xkb, XkbAllServerInfoMask, True); + if (which & XkbCompatMapMask) + XkbFreeCompatMap(xkb, XkbAllCompatMask, True); + if (which & XkbIndicatorMapMask) + XkbFreeIndicatorMaps(xkb); + if (which & XkbNamesMask) + XkbFreeNames(xkb, XkbAllNamesMask, True); + if ((which & XkbGeometryMask) && (xkb->geom != NULL)) + XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); + if (which & XkbControlsMask) + XkbFreeControls(xkb, XkbAllControlsMask, True); + if (freeAll) + _XkbFree(xkb); + return; +} + +/***====================================================================***/ + +XkbDeviceLedInfoPtr +XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) +{ + XkbDeviceLedInfoPtr devli; + register int i; + + if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) + return NULL; + for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { + if ((devli->led_class == ledClass) && (devli->led_id == ledId)) + return devli; + } + if (devi->num_leds >= devi->sz_leds) { + XkbDeviceLedInfoRec *prev_leds = devi->leds; + + if (devi->sz_leds > 0) + devi->sz_leds *= 2; + else + devi->sz_leds = 1; + devi->leds = _XkbTypedRealloc(devi->leds, devi->sz_leds, + XkbDeviceLedInfoRec); + if (!devi->leds) { + _XkbFree(prev_leds); + devi->sz_leds = devi->num_leds = 0; + return NULL; + } + i = devi->num_leds; + for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { + bzero(devli, sizeof(XkbDeviceLedInfoRec)); + devli->led_class = XkbXINone; + devli->led_id = XkbXINone; + } + } + devli = &devi->leds[devi->num_leds++]; + bzero(devli, sizeof(XkbDeviceLedInfoRec)); + devli->led_class = ledClass; + devli->led_id = ledId; + return devli; +} + +Status +XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) +{ + XkbAction *prev_btn_acts; + + if ((!devi) || (newTotal > 255)) + return BadValue; + if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) + return Success; + if (newTotal == 0) { + if (devi->btn_acts != NULL) { + _XkbFree(devi->btn_acts); + devi->btn_acts = NULL; + } + devi->num_btns = 0; + return Success; + } + prev_btn_acts = devi->btn_acts; + devi->btn_acts = _XkbTypedRealloc(devi->btn_acts, newTotal, XkbAction); + if (devi->btn_acts == NULL) { + _XkbFree(prev_btn_acts); + devi->num_btns = 0; + return BadAlloc; + } + if (newTotal > devi->num_btns) { + XkbAction *act; + + act = &devi->btn_acts[devi->num_btns]; + bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); + } + devi->num_btns = newTotal; + return Success; +} + +/*ARGSUSED*/ +XkbDeviceInfoPtr +XkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) +{ + XkbDeviceInfoPtr devi; + + devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); + if (devi != NULL) { + devi->device_spec = deviceSpec; + devi->has_own_state = False; + devi->num_btns = 0; + devi->btn_acts = NULL; + if (nButtons > 0) { + devi->num_btns = nButtons; + devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); + if (!devi->btn_acts) { + _XkbFree(devi); + return NULL; + } + } + devi->dflt_kbd_fb = XkbXINone; + devi->dflt_led_fb = XkbXINone; + devi->num_leds = 0; + devi->sz_leds = 0; + devi->leds = NULL; + if (szLeds > 0) { + devi->sz_leds = szLeds; + devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); + if (!devi->leds) { + _XkbFree(devi->btn_acts); + _XkbFree(devi); + return NULL; + } + } + } + return devi; +} + + +void +XkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) +{ + if (devi) { + if (freeDevI) { + which = XkbXI_AllDeviceFeaturesMask; + if (devi->name) { + _XkbFree(devi->name); + devi->name = NULL; + } + } + if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { + _XkbFree(devi->btn_acts); + devi->num_btns = 0; + devi->btn_acts = NULL; + } + if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { + register int i; + + if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { + _XkbFree(devi->leds); + devi->sz_leds = devi->num_leds = 0; + devi->leds = NULL; + } + else { + XkbDeviceLedInfoPtr devli; + + for (i = 0, devli = devi->leds; i < devi->num_leds; + i++, devli++) { + if (which & XkbXI_IndicatorMapsMask) + bzero((char *) &devli->maps[0], sizeof(devli->maps)); + else + bzero((char *) &devli->names[0], sizeof(devli->names)); + } + } + } + if (freeDevI) + _XkbFree(devi); + } + return; +} diff --git a/nx-X11/lib/src/xkb/XKBBell.c b/nx-X11/lib/src/xkb/XKBBell.c new file mode 100644 index 000000000..d3e3a57ff --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBBell.c @@ -0,0 +1,179 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +Bool +XkbDeviceBell(Display *dpy, + Window window, + int deviceID, + int bellClass, + int bellID, + int percent, + Atom name) +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32) window; + req->bellClass = (CARD16) bellClass; + req->bellID = (CARD16) bellID; + req->percent = percent; + req->forceSound = False; + req->eventOnly = False; + req->pitch = 0; + req->duration = 0; + req->name = (CARD32) name; + req->pad1 = 0; + req->pad2 = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbForceDeviceBell(Display *dpy, + int deviceID, + int bellClass, + int bellID, + int percent) +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32) None; + req->bellClass = (CARD16) bellClass; + req->bellID = (CARD16) bellID; + req->percent = percent; + req->forceSound = True; + req->eventOnly = False; + req->pitch = 0; + req->duration = 0; + req->name = None; + req->pad1 = 0; + req->pad2 = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbDeviceBellEvent(Display *dpy, + Window window, + int deviceID, + int bellClass, + int bellID, + int percent, + Atom name) +{ + register xkbBellReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbBell, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbBell; + req->deviceSpec = deviceID; + req->window = (CARD32) window; + req->bellClass = (CARD16) bellClass; + req->bellID = (CARD16) bellID; + req->percent = percent; + req->forceSound = False; + req->eventOnly = True; + req->pitch = 0; + req->duration = 0; + req->name = (CARD32) name; + req->pad1 = 0; + req->pad2 = 0; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbBell(Display *dpy, Window window, int percent, Atom name) +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) { + XBell(dpy, percent); + return False; + } + return XkbDeviceBell(dpy, window, XkbUseCoreKbd, + XkbDfltXIClass, XkbDfltXIId, percent, name); +} + +Bool +XkbForceBell(Display *dpy, int percent) +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) { + XBell(dpy, percent); + return False; + } + return XkbForceDeviceBell(dpy, XkbUseCoreKbd, XkbDfltXIClass, XkbDfltXIId, + percent); +} + +Bool +XkbBellEvent(Display *dpy, Window window, int percent, Atom name) +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) { + return False; + } + /* class 0 = KbdFeedbackClass (X Input Extension) */ + return XkbDeviceBellEvent(dpy, window, XkbUseCoreKbd, + XkbDfltXIClass, XkbDfltXIId, percent, name); +} diff --git a/nx-X11/lib/src/xkb/XKBBind.c b/nx-X11/lib/src/xkb/XKBBind.c new file mode 100644 index 000000000..c679dc552 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBBind.c @@ -0,0 +1,784 @@ +/* + +Copyright 1985, 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + + /* the new monsters ate the old ones */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "XKBlib.h" +#include <nx-X11/Xlibint.h> +#include <nx-X11/Xutil.h> +#include <nx-X11/keysym.h> +#include <stdio.h> +#include <ctype.h> + +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +#define AllMods (ShiftMask|LockMask|ControlMask| \ + Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) + +static int _XkbLoadDpy(Display *dpy); + +struct _XKeytrans { + struct _XKeytrans *next; /* next on list */ + char *string; /* string to return when the time comes */ + int len; /* length of string (since NULL is legit) */ + KeySym key; /* keysym rebound */ + unsigned int state; /* modifier state */ + KeySym *modifiers; /* modifier keysyms you want */ + int mlen; /* length of modifier list */ +}; + +KeySym +XkbKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int group, + int level) +{ + XkbDescRec *xkb; + + if (_XkbUnavailable(dpy)) + return NoSymbol; + + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + + xkb = dpy->xkb_info->desc; + if ((kc < xkb->min_key_code) || (kc > xkb->max_key_code)) + return NoSymbol; + + if ((group < 0) || (level < 0) || (group >= XkbKeyNumGroups(xkb, kc))) + return NoSymbol; + if (level >= XkbKeyGroupWidth(xkb, kc, group)) { + /* for compatibility with the core protocol, _always_ allow */ + /* two symbols in the first two groups. If either of the */ + /* two is of type ONE_LEVEL, just replicate the first symbol */ + if ((group > XkbGroup2Index) || (XkbKeyGroupWidth(xkb, kc, group) != 1) + || (level != 1)) { + return NoSymbol; + } + level = 0; + } + return XkbKeySymEntry(xkb, kc, level, group); +} + +KeySym +XKeycodeToKeysym(Display *dpy, +#if NeedWidePrototypes + unsigned int kc, +#else + KeyCode kc, +#endif + int col) +{ + XkbDescRec *xkb; + + if (_XkbUnavailable(dpy)) + return _XKeycodeToKeysym(dpy, kc, col); + + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + + xkb = dpy->xkb_info->desc; + if ((kc < xkb->min_key_code) || (kc > xkb->max_key_code)) + return NoSymbol; + + if (col > 3) { + int lastSym, tmp, nGrp; + + lastSym = 3; + nGrp = XkbKeyNumGroups(xkb, kc); + if ((nGrp > 0) && + ((tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup1Index)) > 2)) { + if (col <= (lastSym + tmp - 2)) + return XkbKeycodeToKeysym(dpy, kc, XkbGroup1Index, + col - lastSym + 2); + lastSym += tmp - 2; + } + if ((nGrp > 1) && + ((tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup2Index)) > 2)) { + if (col <= (lastSym + tmp - 2)) + return XkbKeycodeToKeysym(dpy, kc, XkbGroup2Index, + col - lastSym + 2); + lastSym += tmp - 2; + } + if (nGrp > 2) { + tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup3Index); + if (col <= lastSym + tmp) + return XkbKeycodeToKeysym(dpy, kc, XkbGroup3Index, + col - lastSym); + lastSym += tmp; + } + if (nGrp > 3) { + tmp = XkbKeyGroupWidth(xkb, kc, XkbGroup4Index); + if (col <= lastSym + tmp) + return XkbKeycodeToKeysym(dpy, kc, XkbGroup4Index, + col - lastSym); + } + return NoSymbol; + } + return XkbKeycodeToKeysym(dpy, kc, (col >> 1), (col & 1)); +} + +KeyCode +XKeysymToKeycode(Display *dpy, KeySym ks) +{ + register int i, j, gotOne; + + if (_XkbUnavailable(dpy)) + return _XKeysymToKeycode(dpy, ks); + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + + j = 0; + do { + register XkbDescRec *xkb = dpy->xkb_info->desc; + gotOne = 0; + for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { + if (j < (int) XkbKeyNumSyms(xkb, i)) { + gotOne = 1; + if ((XkbKeySym(xkb, i, j) == ks)) + return i; + } + } + j++; + } while (gotOne); + return 0; +} + +static int +_XkbComputeModmap(Display *dpy) +{ + register XkbDescPtr xkb; + + xkb = dpy->xkb_info->desc; + if (XkbGetUpdatedMap(dpy, XkbModifierMapMask, xkb) == Success) + return 1; + return 0; +} + +unsigned +XkbKeysymToModifiers(Display *dpy, KeySym ks) +{ + XkbDescRec *xkb; + register int i, j; + register KeySym *pSyms; + CARD8 mods; + + if (_XkbUnavailable(dpy)) + return _XKeysymToModifiers(dpy, ks); + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + + if (_XkbNeedModmap(dpy->xkb_info) && (!_XkbComputeModmap(dpy))) + return _XKeysymToModifiers(dpy, ks); + + xkb = dpy->xkb_info->desc; + mods = 0; + for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { + pSyms = XkbKeySymsPtr(xkb, i); + for (j = XkbKeyNumSyms(xkb, i) - 1; j >= 0; j--) { + if (pSyms[j] == ks) { + mods |= xkb->map->modmap[i]; + break; + } + } + } + return mods; +} + +KeySym +XLookupKeysym(register XKeyEvent * event, int col) +{ + Display *dpy = event->display; + + if (_XkbUnavailable(dpy)) + return _XLookupKeysym(event, col); + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + return XKeycodeToKeysym(dpy, event->keycode, col); +} + + /* + * Not a public entry point -- XkbTranslateKey is an obsolete name + * that is preserved here so that functions linked against the old + * version will continue to work in a shared library environment. + */ +int +XkbTranslateKey(register Display *dpy, + KeyCode key, + register unsigned int mods, + unsigned int *mods_rtrn, + KeySym *keysym_rtrn); + +int +XkbTranslateKey(register Display *dpy, + KeyCode key, + register unsigned int mods, + unsigned int *mods_rtrn, + KeySym *keysym_rtrn) +{ + return XkbLookupKeySym(dpy, key, mods, mods_rtrn, keysym_rtrn); +} + +Bool +XkbLookupKeySym(register Display *dpy, + KeyCode key, + register unsigned int mods, + unsigned int *mods_rtrn, + KeySym *keysym_rtrn) +{ + if (_XkbUnavailable(dpy)) + return _XTranslateKey(dpy, key, mods, mods_rtrn, keysym_rtrn); + _XkbCheckPendingRefresh(dpy, dpy->xkb_info); + return XkbTranslateKeyCode(dpy->xkb_info->desc, key, mods, mods_rtrn, + keysym_rtrn); +} + +Bool +XkbTranslateKeyCode(register XkbDescPtr xkb, + KeyCode key, + register unsigned int mods, + unsigned int *mods_rtrn, + KeySym *keysym_rtrn) +{ + XkbKeyTypeRec *type; + int col, nKeyGroups; + unsigned preserve, effectiveGroup; + KeySym *syms; + + if (mods_rtrn != NULL) + *mods_rtrn = 0; + + nKeyGroups = XkbKeyNumGroups(xkb, key); + if ((!XkbKeycodeInRange(xkb, key)) || (nKeyGroups == 0)) { + if (keysym_rtrn != NULL) + *keysym_rtrn = NoSymbol; + return False; + } + + syms = XkbKeySymsPtr(xkb, key); + + /* find the offset of the effective group */ + col = 0; + effectiveGroup = XkbGroupForCoreState(mods); + if (effectiveGroup >= nKeyGroups) { + unsigned groupInfo = XkbKeyGroupInfo(xkb, key); + + switch (XkbOutOfRangeGroupAction(groupInfo)) { + default: + effectiveGroup %= nKeyGroups; + break; + case XkbClampIntoRange: + effectiveGroup = nKeyGroups - 1; + break; + case XkbRedirectIntoRange: + effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); + if (effectiveGroup >= nKeyGroups) + effectiveGroup = 0; + break; + } + } + col = effectiveGroup * XkbKeyGroupsWidth(xkb, key); + type = XkbKeyKeyType(xkb, key, effectiveGroup); + + preserve = 0; + if (type->map) { /* find the column (shift level) within the group */ + register int i; + register XkbKTMapEntryPtr entry; + + for (i = 0, entry = type->map; i < type->map_count; i++, entry++) { + if ((entry->active) && + ((mods & type->mods.mask) == entry->mods.mask)) { + col += entry->level; + if (type->preserve) + preserve = type->preserve[i].mask; + break; + } + } + } + + if (keysym_rtrn != NULL) + *keysym_rtrn = syms[col]; + if (mods_rtrn) { + *mods_rtrn = type->mods.mask & (~preserve); + /* The Motif VTS doesn't get the help callback called if help + * is bound to Shift+<whatever>, and it appears as though it + * is XkbTranslateKeyCode that is causing the problem. The + * core X version of XTranslateKey always OR's in ShiftMask + * and LockMask for mods_rtrn, so this "fix" keeps this behavior + * and solves the VTS problem. + */ + if ((xkb->dpy) && (xkb->dpy->xkb_info) && + (xkb->dpy->xkb_info-> + xlib_ctrls & XkbLC_AlwaysConsumeShiftAndLock)) { + *mods_rtrn |= (ShiftMask | LockMask); + } + } + return (syms[col] != NoSymbol); +} + +Status +XkbRefreshKeyboardMapping(register XkbMapNotifyEvent * event) +{ + Display *dpy = event->display; + XkbInfoPtr xkbi; + + if (_XkbUnavailable(dpy)) { + _XRefreshKeyboardMapping((XMappingEvent *) event); + return Success; + } + xkbi = dpy->xkb_info; + + if (((event->type & 0x7f) - xkbi->codes->first_event) != XkbEventCode) + return BadMatch; + if (event->xkb_type == XkbNewKeyboardNotify) { + _XkbReloadDpy(dpy); + return Success; + } + if (event->xkb_type == XkbMapNotify) { + XkbMapChangesRec changes; + Status rtrn; + + if (xkbi->flags & XkbMapPending) + changes = xkbi->changes; + else + bzero(&changes, sizeof(changes)); + XkbNoteMapChanges(&changes, event, XKB_XLIB_MAP_MASK); + if ((rtrn = XkbGetMapChanges(dpy, xkbi->desc, &changes)) != Success) { +#ifdef DEBUG + fprintf(stderr, "Internal Error! XkbGetMapChanges failed:\n"); +#endif + xkbi->changes = changes; + } + else if (xkbi->flags & XkbMapPending) { + xkbi->flags &= ~XkbMapPending; + bzero(&xkbi->changes, sizeof(XkbMapChangesRec)); + } + return rtrn; + } + return BadMatch; +} + +int +XRefreshKeyboardMapping(register XMappingEvent * event) +{ + XkbEvent *xkbevent = (XkbEvent *) event; + Display *dpy = event->display; + XkbMapChangesRec changes; + XkbInfoPtr xkbi; + + /* always do this for input methods, which still use the old keymap */ + (void) _XRefreshKeyboardMapping(event); + + if (_XkbUnavailable(dpy)) + return 1; + + xkbi = dpy->xkb_info; + + if (((event->type & 0x7f) - xkbi->codes->first_event) == XkbEventCode) + return XkbRefreshKeyboardMapping(&xkbevent->map); + + if (xkbi->flags & XkbXlibNewKeyboard) { + _XkbReloadDpy(dpy); + return 1; + } + + if ((xkbi->flags & XkbMapPending) || (event->request == MappingKeyboard)) { + if (xkbi->flags & XkbMapPending) { + changes = xkbi->changes; + _XkbNoteCoreMapChanges(&changes, event, XKB_XLIB_MAP_MASK); + } + else { + bzero(&changes, sizeof(changes)); + changes.changed = XkbKeySymsMask; + if (xkbi->desc->min_key_code < xkbi->desc->max_key_code) { + changes.first_key_sym = xkbi->desc->min_key_code; + changes.num_key_syms = xkbi->desc->max_key_code - + xkbi->desc->min_key_code + 1; + } + else { + changes.first_key_sym = event->first_keycode; + changes.num_key_syms = event->count; + } + } + + if (XkbGetMapChanges(dpy, xkbi->desc, &changes) != Success) { +#ifdef DEBUG + fprintf(stderr, "Internal Error! XkbGetMapChanges failed:\n"); + if (changes.changed & XkbKeyTypesMask) { + int first = changes.first_type; + int last = changes.first_type + changes.num_types - 1; + + fprintf(stderr, " types: %d..%d\n", first, last); + } + if (changes.changed & XkbKeySymsMask) { + int first = changes.first_key_sym; + int last = changes.first_key_sym + changes.num_key_syms - 1; + + fprintf(stderr, " symbols: %d..%d\n", first, last); + } + if (changes.changed & XkbKeyActionsMask) { + int first = changes.first_key_act; + int last = changes.first_key_act + changes.num_key_acts - 1; + + fprintf(stderr, " acts: %d..%d\n", first, last); + } + if (changes.changed & XkbKeyBehaviorsMask) { + int first = changes.first_key_behavior; + int last = first + changes.num_key_behaviors - 1; + + fprintf(stderr, " behaviors: %d..%d\n", first, last); + } + if (changes.changed & XkbVirtualModsMask) { + fprintf(stderr, "virtual mods: 0x%04x\n", changes.vmods); + } + if (changes.changed & XkbExplicitComponentsMask) { + int first = changes.first_key_explicit; + int last = first + changes.num_key_explicit - 1; + + fprintf(stderr, " explicit: %d..%d\n", first, last); + } +#endif + } + LockDisplay(dpy); + if (xkbi->flags & XkbMapPending) { + xkbi->flags &= ~XkbMapPending; + bzero(&xkbi->changes, sizeof(XkbMapChangesRec)); + } + UnlockDisplay(dpy); + } + if (event->request == MappingModifier) { + LockDisplay(dpy); + if (xkbi->desc->map->modmap) { + _XkbFree(xkbi->desc->map->modmap); + xkbi->desc->map->modmap = NULL; + } + if (dpy->key_bindings) { + register struct _XKeytrans *p; + + for (p = dpy->key_bindings; p; p = p->next) { + register int i; + + p->state = 0; + if (p->mlen > 0) { + for (i = 0; i < p->mlen; i++) { + p->state |= XkbKeysymToModifiers(dpy, p->modifiers[i]); + } + if (p->state) + p->state &= AllMods; + else + p->state = AnyModifier; + } + } + } + UnlockDisplay(dpy); + } + return 1; +} + +static int +_XkbLoadDpy(Display *dpy) +{ + XkbInfoPtr xkbi; + unsigned query, oldEvents; + XkbDescRec *desc; + + if (!XkbUseExtension(dpy, NULL, NULL)) + return 0; + + xkbi = dpy->xkb_info; + query = XkbAllClientInfoMask; + desc = XkbGetMap(dpy, query, XkbUseCoreKbd); + if (!desc) { +#ifdef DEBUG + fprintf(stderr, "Warning! XkbGetMap failed!\n"); +#endif + return 0; + } + LockDisplay(dpy); + xkbi->desc = desc; + + UnlockDisplay(dpy); + oldEvents = xkbi->selected_events; + if (!(xkbi->xlib_ctrls & XkbLC_IgnoreNewKeyboards)) { + XkbSelectEventDetails(dpy, xkbi->desc->device_spec, + XkbNewKeyboardNotify, + XkbNKN_KeycodesMask | XkbNKN_DeviceIDMask, + XkbNKN_KeycodesMask | XkbNKN_DeviceIDMask); + } + XkbSelectEventDetails(dpy, xkbi->desc->device_spec, XkbMapNotify, + XkbAllClientInfoMask, XkbAllClientInfoMask); + LockDisplay(dpy); + xkbi->selected_events = oldEvents; + UnlockDisplay(dpy); + return 1; +} + +void +_XkbReloadDpy(Display *dpy) +{ + XkbInfoPtr xkbi; + XkbDescRec *desc; + unsigned oldDeviceID; + + if (_XkbUnavailable(dpy)) + return; + + xkbi = dpy->xkb_info; + LockDisplay(dpy); + if (xkbi->desc) { + oldDeviceID = xkbi->desc->device_spec; + XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, True); + xkbi->desc = NULL; + xkbi->flags &= ~(XkbMapPending | XkbXlibNewKeyboard); + xkbi->changes.changed = 0; + } + else + oldDeviceID = XkbUseCoreKbd; + UnlockDisplay(dpy); + desc = XkbGetMap(dpy, XkbAllClientInfoMask, XkbUseCoreKbd); + if (!desc) + return; + LockDisplay(dpy); + xkbi->desc = desc; + UnlockDisplay(dpy); + + if (desc->device_spec != oldDeviceID) { + /* transfer(?) event masks here */ +#ifdef NOTYET + unsigned oldEvents; + + oldEvents = xkbi->selected_events; + XkbSelectEventDetails(dpy, xkbi->desc->device_spec, XkbMapNotify, + XkbAllMapComponentsMask, XkbAllClientInfoMask); + LockDisplay(dpy); + xkbi->selected_events = oldEvents; + UnlockDisplay(dpy); +#endif + } + return; +} + +int +XkbTranslateKeySym(register Display *dpy, + register KeySym *sym_rtrn, + unsigned int mods, + char *buffer, + int nbytes, + int *extra_rtrn) +{ + register XkbInfoPtr xkb; + XkbKSToMBFunc cvtr; + XPointer priv; + char tmp[4]; + int n; + + xkb = dpy->xkb_info; + if (!xkb->cvt.KSToMB) { + _XkbGetConverters(_XkbGetCharset(), &xkb->cvt); + _XkbGetConverters("ISO8859-1", &xkb->latin1cvt); + } + + if (extra_rtrn) + *extra_rtrn = 0; + + if ((buffer == NULL) || (nbytes == 0)) { + buffer = tmp; + nbytes = 4; + } + + /* see if symbol rebound, if so, return that string. */ + n = XkbLookupKeyBinding(dpy, *sym_rtrn, mods, buffer, nbytes, extra_rtrn); + if (n) + return n; + + if (nbytes > 0) + buffer[0] = '\0'; + + if (xkb->cvt.KSToUpper && (mods & LockMask)) { + *sym_rtrn = (*xkb->cvt.KSToUpper) (*sym_rtrn); + } + if (xkb->xlib_ctrls & XkbLC_ForceLatin1Lookup) { + cvtr = xkb->latin1cvt.KSToMB; + priv = xkb->latin1cvt.KSToMBPriv; + } + else { + cvtr = xkb->cvt.KSToMB; + priv = xkb->cvt.KSToMBPriv; + } + + n = (*cvtr) (priv, *sym_rtrn, buffer, nbytes, extra_rtrn); + + if ((!xkb->cvt.KSToUpper) && (mods & LockMask)) { + register int i; + int change; + + for (i = change = 0; i < n; i++) { + char ch = toupper(buffer[i]); + change = (change || (buffer[i] != ch)); + buffer[i] = ch; + } + if (change) { + if (n == 1) + *sym_rtrn = + (*xkb->cvt.MBToKS) (xkb->cvt.MBToKSPriv, buffer, n, NULL); + else + *sym_rtrn = NoSymbol; + } + } + + if (mods & ControlMask) { + if (n == 1) { + buffer[0] = XkbToControl(buffer[0]); + if (nbytes > 1) + buffer[1] = '\0'; + return 1; + } + if (nbytes > 0) + buffer[0] = '\0'; + return 0; + } + return n; +} + +int +XLookupString(register XKeyEvent *event, + char *buffer, + int nbytes, + KeySym *keysym, + XComposeStatus *status) +{ + KeySym dummy; + int rtrnLen; + unsigned int new_mods; + Display *dpy = event->display; + + if (keysym == NULL) + keysym = &dummy; + if (!XkbLookupKeySym(dpy, event->keycode, event->state, &new_mods, keysym)) + return 0; + new_mods = (event->state & (~new_mods)); + + /* find the group where a symbol can be converted to control one */ + if (new_mods & ControlMask && *keysym > 0x7F && + (dpy->xkb_info->xlib_ctrls & XkbLC_ControlFallback)) { + XKeyEvent tmp_ev = *event; + KeySym tmp_keysym; + unsigned int tmp_new_mods; + + if (_XkbUnavailable(dpy)) { + tmp_ev.state = event->state ^ dpy->mode_switch; + if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, + &tmp_new_mods, &tmp_keysym) && + tmp_keysym != NoSymbol && tmp_keysym < 0x80) { + *keysym = tmp_keysym; + } + } + else { + int n = XkbKeyNumGroups(dpy->xkb_info->desc, tmp_ev.keycode); + int i; + + for (i = 0; i < n; i++) { + if (XkbGroupForCoreState(event->state) == i) + continue; + tmp_ev.state = XkbBuildCoreState(tmp_ev.state, i); + if (XkbLookupKeySym(dpy, tmp_ev.keycode, tmp_ev.state, + &tmp_new_mods, &tmp_keysym) && + tmp_keysym != NoSymbol && tmp_keysym < 0x80) { + *keysym = tmp_keysym; + new_mods = (event->state & (~tmp_new_mods)); + break; + } + } + } + } + + /* We *should* use the new_mods (which does not contain any modifiers */ + /* that were used to compute the symbol here, but pre-XKB XLookupString */ + /* did not and we have to remain compatible. Sigh. */ + if (_XkbUnavailable(dpy) || + (dpy->xkb_info->xlib_ctrls & XkbLC_ConsumeLookupMods) == 0) + new_mods = event->state; + + rtrnLen = XkbLookupKeyBinding(dpy, *keysym, new_mods, buffer, nbytes, NULL); + if (rtrnLen > 0) + return rtrnLen; + + return XkbTranslateKeySym(dpy, keysym, new_mods, buffer, nbytes, NULL); +} + + +int +XkbLookupKeyBinding(Display *dpy, + register KeySym sym, + unsigned int mods, + char *buffer, + int nbytes, + int *extra_rtrn) +{ + register struct _XKeytrans *p; + + if (extra_rtrn) + *extra_rtrn = 0; + for (p = dpy->key_bindings; p; p = p->next) { + if (((mods & AllMods) == p->state) && (sym == p->key)) { + int tmp = p->len; + + if (tmp > nbytes) { + if (extra_rtrn) + *extra_rtrn = (tmp - nbytes); + tmp = nbytes; + } + memcpy(buffer, p->string, tmp); + if (tmp < nbytes) + buffer[tmp] = '\0'; + return tmp; + } + } + return 0; +} + +char +XkbToControl(char ch) +{ + register char c = ch; + + if ((c >= '@' && c < '\177') || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if (c >= '3' && c <= '7') + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + return c; +} diff --git a/nx-X11/lib/src/xkb/XKBCompat.c b/nx-X11/lib/src/xkb/XKBCompat.c new file mode 100644 index 000000000..a5222b56e --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBCompat.c @@ -0,0 +1,252 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +Status +_XkbReadGetCompatMapReply(Display *dpy, + xkbGetCompatMapReply *rep, + XkbDescPtr xkb, + int *nread_rtrn) +{ + register int i; + XkbReadBufferRec buf; + + if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) + return BadAlloc; + + if (nread_rtrn) + *nread_rtrn = (int) rep->length * 4; + + i = rep->firstSI + rep->nSI; + if ((!xkb->compat) && + (XkbAllocCompatMap(xkb, XkbAllCompatMask, i) != Success)) + return BadAlloc; + + if (rep->nSI != 0) { + XkbSymInterpretRec *syms; + xkbSymInterpretWireDesc *wire; + + wire = (xkbSymInterpretWireDesc *) _XkbGetReadBufferPtr(&buf, + rep->nSI * SIZEOF (xkbSymInterpretWireDesc)); + if (wire == NULL) + goto BAILOUT; + syms = &xkb->compat->sym_interpret[rep->firstSI]; + + for (i = 0; i < rep->nSI; i++, syms++, wire++) { + syms->sym = wire->sym; + syms->mods = wire->mods; + syms->match = wire->match; + syms->virtual_mod = wire->virtualMod; + syms->flags = wire->flags; + syms->act = *((XkbAnyAction *) &wire->act); + } + xkb->compat->num_si += rep->nSI; + } + + if (rep->groups & XkbAllGroupsMask) { + register unsigned bit, nGroups; + xkbModsWireDesc *wire; + + for (i = 0, nGroups = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { + if (rep->groups & bit) + nGroups++; + } + wire = (xkbModsWireDesc *) + _XkbGetReadBufferPtr(&buf, nGroups * SIZEOF(xkbModsWireDesc)); + if (wire == NULL) + goto BAILOUT; + for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { + if ((rep->groups & bit) == 0) + continue; + xkb->compat->groups[i].mask = wire->mask; + xkb->compat->groups[i].real_mods = wire->realMods; + xkb->compat->groups[i].vmods = wire->virtualMods; + wire++; + } + } + i = _XkbFreeReadBuffer(&buf); + if (i) + fprintf(stderr, "CompatMapReply! Bad length (%d extra bytes)\n", i); + if (i || buf.error) + return BadLength; + return Success; + BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +Status +XkbGetCompatMap(Display *dpy, unsigned which, XkbDescPtr xkb) +{ + register xkbGetCompatMapReq *req; + xkbGetCompatMapReply rep; + Status status; + XkbInfoPtr xkbi; + + if ((!dpy) || (!xkb) || (dpy->flags & XlibDisplayNoXkb) || + ((xkb->dpy != NULL) && (xkb->dpy != dpy)) || + (!dpy->xkb_info && (!XkbUseExtension(dpy, NULL, NULL)))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetCompatMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetCompatMap; + req->deviceSpec = xkb->device_spec; + if (which & XkbSymInterpMask) + req->getAllSI = True; + else + req->getAllSI = False; + req->firstSI = req->nSI = 0; + + if (which & XkbGroupCompatMask) + req->groups = XkbAllGroupsMask; + else + req->groups = 0; + + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + if (xkb->dpy == NULL) + xkb->dpy = dpy; + if (xkb->device_spec == XkbUseCoreKbd) + xkb->device_spec = rep.deviceID; + + status = _XkbReadGetCompatMapReply(dpy, &rep, xkb, NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +static Bool +_XkbWriteSetCompatMap(Display *dpy, xkbSetCompatMapReq *req, XkbDescPtr xkb) +{ + CARD16 firstSI; + CARD16 nSI; + int size; + register int i, nGroups; + register unsigned bit; + unsigned groups; + char *buf; + + firstSI = req->firstSI; + nSI = req->nSI; + size = nSI * SIZEOF(xkbSymInterpretWireDesc); + nGroups = 0; + groups = req->groups; + if (groups & XkbAllGroupsMask) { + for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { + if (groups & bit) + nGroups++; + } + size += SIZEOF(xkbModsWireDesc) * nGroups; + } + req->length += size / 4; + BufAlloc(char *, buf, size); + + if (!buf) + return False; + + if (nSI) { + XkbSymInterpretPtr sym = &xkb->compat->sym_interpret[firstSI]; + xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) buf; + + for (i = 0; i < nSI; i++, wire++, sym++) { + wire->sym = (CARD32) sym->sym; + wire->mods = sym->mods; + wire->match = sym->match; + wire->flags = sym->flags; + wire->virtualMod = sym->virtual_mod; + memcpy(&wire->act, &sym->act, sz_xkbActionWireDesc); + } + buf += nSI * SIZEOF(xkbSymInterpretWireDesc); + } + if (groups & XkbAllGroupsMask) { + xkbModsWireDesc *out = (xkbModsWireDesc *) buf; + + for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { + if ((groups & bit) != 0) { + out->mask = xkb->compat->groups[i].mask; + out->realMods = xkb->compat->groups[i].real_mods; + out->virtualMods = xkb->compat->groups[i].vmods; + out++; + } + } + buf += nGroups * SIZEOF(xkbModsWireDesc); + } + return True; +} + +Bool +XkbSetCompatMap(Display *dpy, unsigned which, XkbDescPtr xkb, + Bool updateActions) +{ + register xkbSetCompatMapReq *req; + Status ok; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (dpy != xkb->dpy) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!xkb->compat) || + ((which & XkbSymInterpMask) && (!xkb->compat->sym_interpret))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetCompatMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetCompatMap; + req->deviceSpec = xkb->device_spec; + req->recomputeActions = updateActions; + if (which & XkbSymInterpMask) { + req->truncateSI = True; + req->firstSI = 0; + req->nSI = xkb->compat->num_si; + } + else { + req->truncateSI = False; + req->firstSI = 0; + req->nSI = 0; + } + if (which & XkbGroupCompatMask) + req->groups = XkbAllGroupsMask; + else + req->groups = 0; + ok = _XkbWriteSetCompatMap(dpy, req, xkb); + UnlockDisplay(dpy); + SyncHandle(); + return ok; +} diff --git a/nx-X11/lib/src/xkb/XKBCtrls.c b/nx-X11/lib/src/xkb/XKBCtrls.c new file mode 100644 index 000000000..2e8546d92 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBCtrls.c @@ -0,0 +1,351 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +static xkbSetControlsReq * +_XkbGetSetControlsReq(Display *dpy, XkbInfoPtr xkbi, unsigned int deviceSpec) +{ + xkbSetControlsReq *req; + + GetReq(kbSetControls, req); + bzero(req, SIZEOF(xkbSetControlsReq)); + req->reqType = xkbi->codes->major_opcode; + req->length = (SIZEOF(xkbSetControlsReq) >> 2); + req->xkbReqType = X_kbSetControls; + req->deviceSpec = deviceSpec; + return req; +} + +Bool +XkbSetAutoRepeatRate(Display *dpy, + unsigned int deviceSpec, + unsigned int timeout, + unsigned int interval) +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec); + req->changeCtrls = XkbRepeatKeysMask; + req->repeatDelay = timeout; + req->repeatInterval = interval; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbGetAutoRepeatRate(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 && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + req->reqType = xkbi->codes->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 +XkbSetServerInternalMods(Display *dpy, + unsigned deviceSpec, + unsigned affectReal, + unsigned realValues, + unsigned affectVirtual, + unsigned virtualValues) +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec); + req->affectInternalMods = affectReal; + req->internalMods = realValues; + req->affectInternalVMods = affectVirtual; + req->internalVMods = virtualValues; + req->changeCtrls = XkbInternalModsMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbSetIgnoreLockMods(Display *dpy, + unsigned int deviceSpec, + unsigned affectReal, + unsigned realValues, + unsigned affectVirtual, + unsigned virtualValues) +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec); + req->affectIgnoreLockMods = affectReal; + req->ignoreLockMods = realValues; + req->affectIgnoreLockVMods = affectVirtual; + req->ignoreLockVMods = virtualValues; + req->changeCtrls = XkbIgnoreLockModsMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbChangeEnabledControls(Display *dpy, + unsigned deviceSpec, + unsigned affect, + unsigned values) +{ + register xkbSetControlsReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, deviceSpec); + req->affectEnabledCtrls = affect; + req->enabledCtrls = (affect & values); + req->changeCtrls = XkbControlsEnabledMask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Status +XkbGetControls(Display *dpy, unsigned long which, XkbDescPtr xkb) +{ + register xkbGetControlsReq *req; + xkbGetControlsReply rep; + XkbControlsPtr ctrls; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + if ((!xkb) || (!which)) + return BadMatch; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetControls, req); + if (!xkb->ctrls) { + xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); + if (!xkb->ctrls) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetControls; + req->deviceSpec = xkb->device_spec; + if (!_XReply(dpy, (xReply *) &rep, + (SIZEOF(xkbGetControlsReply) - SIZEOF(xReply)) >> 2, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + if (xkb->device_spec == XkbUseCoreKbd) + xkb->device_spec = rep.deviceID; + ctrls = xkb->ctrls; + if (which & XkbControlsEnabledMask) + ctrls->enabled_ctrls = rep.enabledCtrls; + ctrls->num_groups = rep.numGroups; + if (which & XkbGroupsWrapMask) + ctrls->groups_wrap = rep.groupsWrap; + if (which & XkbInternalModsMask) { + ctrls->internal.mask = rep.internalMods; + ctrls->internal.real_mods = rep.internalRealMods; + ctrls->internal.vmods = rep.internalVMods; + } + if (which & XkbIgnoreLockModsMask) { + ctrls->ignore_lock.mask = rep.ignoreLockMods; + ctrls->ignore_lock.real_mods = rep.ignoreLockRealMods; + ctrls->ignore_lock.vmods = rep.ignoreLockVMods; + } + if (which & XkbRepeatKeysMask) { + ctrls->repeat_delay = rep.repeatDelay; + ctrls->repeat_interval = rep.repeatInterval; + } + if (which & XkbSlowKeysMask) + ctrls->slow_keys_delay = rep.slowKeysDelay; + if (which & XkbBounceKeysMask) + ctrls->debounce_delay = rep.debounceDelay; + if (which & XkbMouseKeysMask) { + ctrls->mk_dflt_btn = rep.mkDfltBtn; + } + if (which & XkbMouseKeysAccelMask) { + ctrls->mk_delay = rep.mkDelay; + ctrls->mk_interval = rep.mkInterval; + ctrls->mk_time_to_max = rep.mkTimeToMax; + ctrls->mk_max_speed = rep.mkMaxSpeed; + ctrls->mk_curve = rep.mkCurve; + } + if (which & XkbAccessXKeysMask) + ctrls->ax_options = rep.axOptions; + if (which & XkbStickyKeysMask) { + ctrls->ax_options &= ~XkbAX_SKOptionsMask; + ctrls->ax_options |= rep.axOptions & XkbAX_SKOptionsMask; + } + if (which & XkbAccessXFeedbackMask) { + ctrls->ax_options &= ~XkbAX_FBOptionsMask; + ctrls->ax_options |= rep.axOptions & XkbAX_FBOptionsMask; + } + if (which & XkbAccessXTimeoutMask) { + ctrls->ax_timeout = rep.axTimeout; + ctrls->axt_ctrls_mask = rep.axtCtrlsMask; + ctrls->axt_ctrls_values = rep.axtCtrlsValues; + ctrls->axt_opts_mask = rep.axtOptsMask; + ctrls->axt_opts_values = rep.axtOptsValues; + } + if (which & XkbPerKeyRepeatMask) { + memcpy(ctrls->per_key_repeat, rep.perKeyRepeat, XkbPerKeyBitArraySize); + } + UnlockDisplay(dpy); + SyncHandle(); + return Success; +} + +Bool +XkbSetControls(Display *dpy, unsigned long which, XkbDescPtr xkb) +{ + register xkbSetControlsReq *req; + XkbControlsPtr ctrls; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!xkb) || (!xkb->ctrls)) + return False; + + ctrls = xkb->ctrls; + LockDisplay(dpy); + req = _XkbGetSetControlsReq(dpy, dpy->xkb_info, xkb->device_spec); + req->changeCtrls = (CARD32) which; + if (which & XkbInternalModsMask) { + req->affectInternalMods = ~0; + req->internalMods = ctrls->internal.real_mods; + req->affectInternalVMods = ~0; + req->internalVMods = ctrls->internal.vmods; + } + if (which & XkbIgnoreLockModsMask) { + req->affectIgnoreLockMods = ~0; + req->ignoreLockMods = ctrls->ignore_lock.real_mods; + req->affectIgnoreLockVMods = ~0; + req->ignoreLockVMods = ctrls->ignore_lock.vmods; + } + if (which & XkbControlsEnabledMask) { + req->affectEnabledCtrls = XkbAllBooleanCtrlsMask; + req->enabledCtrls = ctrls->enabled_ctrls; + } + if (which & XkbRepeatKeysMask) { + req->repeatDelay = ctrls->repeat_delay; + req->repeatInterval = ctrls->repeat_interval; + } + if (which & XkbSlowKeysMask) + req->slowKeysDelay = ctrls->slow_keys_delay; + if (which & XkbBounceKeysMask) + req->debounceDelay = ctrls->debounce_delay; + if (which & XkbMouseKeysMask) { + req->mkDfltBtn = ctrls->mk_dflt_btn; + } + if (which & XkbGroupsWrapMask) + req->groupsWrap = ctrls->groups_wrap; + if (which & + (XkbAccessXKeysMask | XkbStickyKeysMask | XkbAccessXFeedbackMask)) + req->axOptions = ctrls->ax_options; + if (which & XkbMouseKeysAccelMask) { + req->mkDelay = ctrls->mk_delay; + req->mkInterval = ctrls->mk_interval; + req->mkTimeToMax = ctrls->mk_time_to_max; + req->mkMaxSpeed = ctrls->mk_max_speed; + req->mkCurve = ctrls->mk_curve; + } + if (which & XkbAccessXTimeoutMask) { + req->axTimeout = ctrls->ax_timeout; + req->axtCtrlsMask = ctrls->axt_ctrls_mask; + req->axtCtrlsValues = ctrls->axt_ctrls_values; + req->axtOptsMask = ctrls->axt_opts_mask; + req->axtOptsValues = ctrls->axt_opts_values; + } + if (which & XkbPerKeyRepeatMask) { + memcpy(req->perKeyRepeat, ctrls->per_key_repeat, XkbPerKeyBitArraySize); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +/***====================================================================***/ + +void +XkbNoteControlsChanges(XkbControlsChangesPtr old, + XkbControlsNotifyEvent *new, + unsigned int wanted) +{ + old->changed_ctrls |= (new->changed_ctrls & wanted); + if (new->changed_ctrls & XkbControlsEnabledMask & wanted) + old->enabled_ctrls_changes ^= new->enabled_ctrl_changes; + /* num_groups_changed?? */ + return; +} diff --git a/nx-X11/lib/src/xkb/XKBCvt.c b/nx-X11/lib/src/xkb/XKBCvt.c new file mode 100644 index 000000000..c42c3af1c --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBCvt.c @@ -0,0 +1,341 @@ +/* + +Copyright 1988, 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <nx-X11/X.h> +#include <nx-X11/Xlib.h> +#include "Xlibint.h" +#include "Xlcint.h" +#include "XlcPubI.h" +#include "Ximint.h" +#include <nx-X11/Xutil.h> +#include <nx-X11/Xmd.h> +#define XK_LATIN1 +#define XK_PUBLISHING +#include <nx-X11/keysym.h> +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" +#include <nx-X11/Xlocale.h> +#include <ctype.h> +#include <nx-X11/Xos.h> + +static int +_XkbHandleSpecialSym(KeySym keysym, char *buffer, int nbytes, int *extra_rtrn) +{ + + /* try to convert to Latin-1, handling ctrl */ + if (!(((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) || + (keysym == XK_Return) || (keysym == XK_Escape) || + (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) || + (keysym == XK_KP_Enter) || + ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) || + (keysym == XK_KP_Equal) || (keysym == XK_Delete))) + return 0; + + if (nbytes < 1) { + if (extra_rtrn) + *extra_rtrn = 1; + return 0; + } + /* if X keysym, convert to ascii by grabbing low 7 bits */ + if (keysym == XK_KP_Space) + buffer[0] = XK_space & 0x7F; /* patch encoding botch */ + else if (keysym == XK_hyphen) + buffer[0] = (char) (XK_minus & 0xFF); /* map to equiv character */ + else + buffer[0] = (char) (keysym & 0x7F); + return 1; +} + +/*ARGSUSED*/ +static int +_XkbKSToKnownSet(XPointer priv, + KeySym keysym, + char *buffer, + int nbytes, + int *extra_rtrn) +{ + char tbuf[8], *buf; + + if (extra_rtrn) + *extra_rtrn = 0; + + /* convert "dead" diacriticals for dumb applications */ + if ((keysym & 0xffffff00) == 0xfe00) { + switch (keysym) { + case XK_dead_grave: keysym = XK_grave; break; + case XK_dead_acute: keysym = XK_acute; break; + case XK_dead_circumflex: keysym = XK_asciicircum; break; + case XK_dead_tilde: keysym = XK_asciitilde; break; + case XK_dead_macron: keysym = XK_macron; break; + case XK_dead_breve: keysym = XK_breve; break; + case XK_dead_abovedot: keysym = XK_abovedot; break; + case XK_dead_diaeresis: keysym = XK_diaeresis; break; + case XK_dead_abovering: keysym = XK_degree; break; + case XK_dead_doubleacute: keysym = XK_doubleacute; break; + case XK_dead_caron: keysym = XK_caron; break; + case XK_dead_cedilla: keysym = XK_cedilla; break; + case XK_dead_ogonek: keysym = XK_ogonek; break; + case XK_dead_iota: keysym = XK_Greek_iota; break; +#ifdef XK_KATAKANA + case XK_dead_voiced_sound: keysym = XK_voicedsound; break; + case XK_dead_semivoiced_sound: keysym = XK_semivoicedsound; break; +#endif + } + } + + if (nbytes < 1) + buf = tbuf; + else + buf = buffer; + + if ((keysym & 0xffffff00) == 0xff00) { + return _XkbHandleSpecialSym(keysym, buf, nbytes, extra_rtrn); + } + return _XimGetCharCode(priv, keysym, (unsigned char *) buf, nbytes); +} + +typedef struct _XkbToKS { + unsigned prefix; + char *map; +} XkbToKS; + +/*ARGSUSED*/ +static KeySym +_XkbKnownSetToKS(XPointer priv, char *buffer, int nbytes, Status *status) +{ + if (nbytes != 1) + return NoSymbol; + if (((buffer[0] & 0x80) == 0) && (buffer[0] >= 32)) + return buffer[0]; + else if ((buffer[0] & 0x7f) >= 32) { + XkbToKS *map = (XkbToKS *) priv; + + if (map) { + if (map->map) + return map->prefix | map->map[buffer[0] & 0x7f]; + else + return map->prefix | buffer[0]; + } + return buffer[0]; + } + return NoSymbol; +} + +static KeySym +__XkbDefaultToUpper(KeySym sym) +{ + KeySym lower, upper; + + XConvertCase(sym, &lower, &upper); + return upper; +} + +#ifdef XKB_EXTEND_LOOKUP_STRING +static int +Strcmp(char *str1, char *str2) +{ + char str[256]; + char c, *s; + + /* + * unchecked strings from the environment can end up here, so check + * the length before copying. + */ + if (strlen(str1) >= sizeof(str)) /* almost certain it's a mismatch */ + return 1; + + for (s = str; (c = *str1++);) { + if (isupper(c)) + c = tolower(c); + *s++ = c; + } + *s = '\0'; + return (strcmp(str, str2)); +} +#endif + +int +_XkbGetConverters(const char *encoding_name, XkbConverters * cvt_rtrn) +{ + if (!cvt_rtrn) + return 0; + + cvt_rtrn->KSToMB = _XkbKSToKnownSet; + cvt_rtrn->KSToMBPriv = _XimGetLocaleCode(encoding_name); + cvt_rtrn->MBToKS = _XkbKnownSetToKS; + cvt_rtrn->MBToKSPriv = NULL; + cvt_rtrn->KSToUpper = __XkbDefaultToUpper; + return 1; +} + +/***====================================================================***/ + +/* + * The function _XkbGetCharset seems to be missnamed as what it seems to + * be used for is to determine the encoding-name for the locale. ??? + */ + +#ifdef XKB_EXTEND_LOOKUP_STRING + +/* + * XKB_EXTEND_LOOKUP_STRING is not used by the SI. It is used by various + * X Consortium/X Project Team members, so we leave it in the source as + * an simplify integration by these companies. + */ + +#define CHARSET_FILE "/usr/lib/X11/input/charsets" +static char *_XkbKnownLanguages = + "c=ascii:da,de,en,es,fr,is,it,nl,no,pt,sv=iso8859-1:hu,pl,cs=iso8859-2:" + "eo=iso8859-3:sp=iso8859-5:ar,ara=iso8859-6:el=iso8859-7:he=iso8859-8:" + "tr=iso8859-9:lt,lv=iso8859-13:et,fi=iso8859-15:ru=koi8-r:uk=koi8-u:" + "th,th_TH,th_TH.iso8859-11=iso8859-11:th_TH.TIS620=tis620:hy=armscii-8:" + "vi=tcvn-5712:ka=georgian-academy:be,bg=microsoft-cp1251"; + +char * +_XkbGetCharset(void) +{ + /* + * PAGE USAGE TUNING: explicitly initialize to move these to data + * instead of bss + */ + static char buf[100] = { 0 }; + char lang[256]; + char *start, *tmp, *end, *next, *set; + char *country, *charset; + char *locale; + + tmp = getenv("_XKB_CHARSET"); + if (tmp) + return tmp; + locale = setlocale(LC_CTYPE, NULL); + + if (locale == NULL) + return NULL; + + if (strlen(locale) >= sizeof(lang)) + return NULL; + + for (tmp = lang; *tmp = *locale++; tmp++) { + if (isupper(*tmp)) + *tmp = tolower(*tmp); + } + country = strchr(lang, '_'); + if (country) { + *country++ = '\0'; + charset = strchr(country, '.'); + if (charset) + *charset++ = '\0'; + if (charset) { + strncpy(buf, charset, 99); + buf[99] = '\0'; + return buf; + } + } + else { + charset = NULL; + } + + if ((tmp = getenv("_XKB_LOCALE_CHARSETS")) != NULL) { + start = _XkbAlloc(strlen(tmp) + 1); + strcpy(start, tmp); + tmp = start; + } + else { + struct stat sbuf; + FILE *file; + char *cf = CHARSET_FILE; + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + + if ((stat(cf, &sbuf) == 0) && S_ISREG(sbuf.st_mode) && + (file = fopen(cf, "r"))) { + tmp = _XkbAlloc(sbuf.st_size + 1); + if (tmp != NULL) { + sbuf.st_size = (long) fread(tmp, 1, sbuf.st_size, file); + tmp[sbuf.st_size] = '\0'; + } + fclose(file); + } + } + + if (tmp == NULL) { + tmp = _XkbAlloc(strlen(_XkbKnownLanguages) + 1); + if (!tmp) + return NULL; + strcpy(tmp, _XkbKnownLanguages); + } + start = tmp; + do { + if ((set = strchr(tmp, '=')) == NULL) + break; + *set++ = '\0'; + if ((next = strchr(set, ':')) != NULL) + *next++ = '\0'; + while (tmp && *tmp) { + if ((end = strchr(tmp, ',')) != NULL) + *end++ = '\0'; + if (Strcmp(tmp, lang) == 0) { + strncpy(buf, set, 100); + buf[99] = '\0'; + Xfree(start); + return buf; + } + tmp = end; + } + tmp = next; + } while (tmp && *tmp); + Xfree(start); + return NULL; +} +#else +char * +_XkbGetCharset(void) +{ + char *tmp; + XLCd lcd; + + tmp = getenv("_XKB_CHARSET"); + if (tmp) + return tmp; + + lcd = _XlcCurrentLC(); + if (lcd) + return XLC_PUBLIC(lcd, encoding_name); + + return NULL; +} +#endif diff --git a/nx-X11/lib/src/xkb/XKBExtDev.c b/nx-X11/lib/src/xkb/XKBExtDev.c new file mode 100644 index 000000000..cb40ecd04 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBExtDev.c @@ -0,0 +1,843 @@ +/************************************************************ +Copyright (c) 1995 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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" +#include <nx-X11/extensions/XI.h> + +/***====================================================================***/ + +void +XkbNoteDeviceChanges(XkbDeviceChangesPtr old, + XkbExtensionDeviceNotifyEvent *new, + unsigned int wanted) +{ + if ((!old) || (!new) || (!wanted) || ((new->reason & wanted) == 0)) + return; + if ((wanted & new->reason) & XkbXI_ButtonActionsMask) { + if (old->changed & XkbXI_ButtonActionsMask) { + int first, last, newLast; + + if (new->first_btn < old->first_btn) + first = new->first_btn; + else + first = old->first_btn; + last = old->first_btn + old->num_btns - 1; + newLast = new->first_btn + new->num_btns - 1; + if (newLast > last) + last = newLast; + old->first_btn = first; + old->num_btns = (last - first) + 1; + } + else { + old->changed |= XkbXI_ButtonActionsMask; + old->first_btn = new->first_btn; + old->num_btns = new->num_btns; + } + } + if ((wanted & new->reason) & XkbXI_IndicatorsMask) { + XkbDeviceLedChangesPtr this; + + if (old->changed & XkbXI_IndicatorsMask) { + XkbDeviceLedChangesPtr found = NULL; + + for (this = &old->leds; this && (!found); this = this->next) { + if ((this->led_class == new->led_class) && + (this->led_id == new->led_id)) { + found = this; + } + } + if (!found) { + found = _XkbTypedCalloc(1, XkbDeviceLedChangesRec); + if (!found) + return; + found->next = old->leds.next; + found->led_class = new->led_class; + found->led_id = new->led_id; + old->leds.next = found; + } + if ((wanted & new->reason) & XkbXI_IndicatorNamesMask) + found->defined = new->leds_defined; + } + else { + old->changed |= ((wanted & new->reason) & XkbXI_IndicatorsMask); + old->leds.led_class = new->led_class; + old->leds.led_id = new->led_id; + old->leds.defined = new->leds_defined; + if (old->leds.next) { + XkbDeviceLedChangesPtr next; + + for (this = old->leds.next; this; this = next) { + next = this->next; + _XkbFree(this); + } + old->leds.next = NULL; + } + } + } + return; +} + +/***====================================================================***/ + +static Status +_XkbReadDeviceLedInfo(XkbReadBufferPtr buf, + unsigned present, + XkbDeviceInfoPtr devi) +{ + register unsigned i, bit; + XkbDeviceLedInfoPtr devli; + xkbDeviceLedsWireDesc *wireli; + + wireli = _XkbGetTypedRdBufPtr(buf, 1, xkbDeviceLedsWireDesc); + if (!wireli) + return BadLength; + devli = XkbAddDeviceLedInfo(devi, wireli->ledClass, wireli->ledID); + if (!devli) + return BadAlloc; + devli->phys_indicators = wireli->physIndicators; + + if (present & XkbXI_IndicatorStateMask) + devli->state = wireli->state; + + if (present & XkbXI_IndicatorNamesMask) { + devli->names_present = wireli->namesPresent; + if (devli->names_present) { + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { + if (wireli->namesPresent & bit) { + if (!_XkbCopyFromReadBuffer(buf, + (char *) &devli->names[i], 4)) + return BadLength; + } + } + } + } + + if (present & XkbXI_IndicatorMapsMask) { + devli->maps_present = wireli->mapsPresent; + if (devli->maps_present) { + XkbIndicatorMapPtr im; + xkbIndicatorMapWireDesc *wireim; + + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { + if (wireli->mapsPresent & bit) { + wireim = + _XkbGetTypedRdBufPtr(buf, 1, xkbIndicatorMapWireDesc); + if (!wireim) + return BadAlloc; + im = &devli->maps[i]; + im->flags = wireim->flags; + im->which_groups = wireim->whichGroups; + im->groups = wireim->groups; + im->which_mods = wireim->whichMods; + im->mods.mask = wireim->mods; + im->mods.real_mods = wireim->realMods; + im->mods.vmods = wireim->virtualMods; + im->ctrls = wireim->ctrls; + } + } + } + } + return Success; +} + +static Status +_XkbReadGetDeviceInfoReply(Display *dpy, + xkbGetDeviceInfoReply *rep, + XkbDeviceInfoPtr devi) +{ + XkbReadBufferRec buf; + XkbAction *act; + int tmp; + + if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) + return BadAlloc; + + if ((rep->totalBtns > 0) && (rep->totalBtns != devi->num_btns)) { + tmp = XkbResizeDeviceButtonActions(devi, rep->totalBtns); + if (tmp != Success) + return tmp; + } + if (rep->nBtnsWanted > 0) { + if (((unsigned short) rep->firstBtnWanted + rep->nBtnsWanted) + >= devi->num_btns) + goto BAILOUT; + act = &devi->btn_acts[rep->firstBtnWanted]; + bzero((char *) act, (rep->nBtnsWanted * sizeof(XkbAction))); + } + + _XkbFree(devi->name); + if (!_XkbGetReadBufferCountedString(&buf, &devi->name)) + goto BAILOUT; + if (rep->nBtnsRtrn > 0) { + int size; + + if (((unsigned short) rep->firstBtnRtrn + rep->nBtnsRtrn) + >= devi->num_btns) + goto BAILOUT; + act = &devi->btn_acts[rep->firstBtnRtrn]; + size = rep->nBtnsRtrn * SIZEOF(xkbActionWireDesc); + if (!_XkbCopyFromReadBuffer(&buf, (char *) act, size)) + goto BAILOUT; + } + if (rep->nDeviceLedFBs > 0) { + register int i; + + for (i = 0; i < rep->nDeviceLedFBs; i++) { + if ((tmp = _XkbReadDeviceLedInfo(&buf, rep->present, devi)) + != Success) + return tmp; + } + } + tmp = _XkbFreeReadBuffer(&buf); + if (tmp) + fprintf(stderr, "GetDeviceInfo! Bad length (%d extra bytes)\n", tmp); + if (tmp || buf.error) + return BadLength; + return Success; + BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +XkbDeviceInfoPtr +XkbGetDeviceInfo(Display *dpy, + unsigned which, + unsigned deviceSpec, + unsigned class, + unsigned id) +{ + register xkbGetDeviceInfoReq *req; + xkbGetDeviceInfoReply rep; + Status status; + XkbDeviceInfoPtr devi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return NULL; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = deviceSpec; + req->wanted = which; + req->allBtns = ((which & XkbXI_ButtonActionsMask) != 0); + req->firstBtn = req->nBtns = 0; + req->ledClass = class; + req->ledID = id; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + devi = XkbAllocDeviceInfo(rep.deviceID, rep.totalBtns, rep.nDeviceLedFBs); + if (devi) { + devi->supported = rep.supported; + devi->unsupported = rep.unsupported; + devi->type = rep.devType; + devi->has_own_state = rep.hasOwnState; + devi->dflt_kbd_fb = rep.dfltKbdFB; + devi->dflt_led_fb = rep.dfltLedFB; + status = _XkbReadGetDeviceInfoReply(dpy, &rep, devi); + if (status != Success) { + XkbFreeDeviceInfo(devi, XkbXI_AllDeviceFeaturesMask, True); + devi = NULL; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return devi; +} + +Status +XkbGetDeviceInfoChanges(Display *dpy, + XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes) +{ + register xkbGetDeviceInfoReq *req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadMatch; + if ((changes->changed & XkbXI_AllDeviceFeaturesMask) == 0) + return Success; + changes->changed &= ~XkbXI_AllDeviceFeaturesMask; + status = Success; + LockDisplay(dpy); + while ((changes->changed) && (status == Success)) { + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted = changes->changed; + req->allBtns = False; + if (changes->changed & XkbXI_ButtonActionsMask) { + req->firstBtn = changes->first_btn; + req->nBtns = changes->num_btns; + changes->changed &= ~XkbXI_ButtonActionsMask; + } + else + req->firstBtn = req->nBtns = 0; + if (changes->changed & XkbXI_IndicatorsMask) { + req->ledClass = changes->leds.led_class; + req->ledID = changes->leds.led_id; + if (changes->leds.next == NULL) + changes->changed &= ~XkbXI_IndicatorsMask; + else { + XkbDeviceLedChangesPtr next; + + next = changes->leds.next; + changes->leds = *next; + _XkbFree(next); + } + } + else { + req->ledClass = XkbDfltXIClass; + req->ledID = XkbDfltXIId; + } + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + status = BadLength; + break; + } + devi->supported |= rep.supported; + devi->unsupported |= rep.unsupported; + devi->type = rep.devType; + status = _XkbReadGetDeviceInfoReply(dpy, &rep, devi); + } + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetDeviceButtonActions(Display *dpy, + XkbDeviceInfoPtr devi, + Bool all, + unsigned int first, + unsigned int num) +{ + register xkbGetDeviceInfoReq *req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadMatch; + if (!devi) + return BadValue; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted = XkbXI_ButtonActionsMask; + req->allBtns = all; + req->firstBtn = first; + req->nBtns = num; + req->ledClass = XkbDfltXIClass; + req->ledID = XkbDfltXIId; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + devi->type = rep.devType; + devi->supported = rep.supported; + devi->unsupported = rep.unsupported; + status = _XkbReadGetDeviceInfoReply(dpy, &rep, devi); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetDeviceLedInfo(Display *dpy, + XkbDeviceInfoPtr devi, + unsigned int ledClass, + unsigned int ledId, + unsigned int which) +{ + register xkbGetDeviceInfoReq *req; + xkbGetDeviceInfoReply rep; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadMatch; + if (((which & XkbXI_IndicatorsMask) == 0) || + (which & (~XkbXI_IndicatorsMask))) + return BadMatch; + if (!devi) + return BadValue; + LockDisplay(dpy); + GetReq(kbGetDeviceInfo, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->wanted = which; + req->allBtns = False; + req->firstBtn = req->nBtns = 0; + req->ledClass = ledClass; + req->ledID = ledId; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadLength; + } + devi->type = rep.devType; + devi->supported = rep.supported; + devi->unsupported = rep.unsupported; + status = _XkbReadGetDeviceInfoReply(dpy, &rep, devi); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +/***====================================================================***/ + +typedef struct _LedInfoStuff { + Bool used; + XkbDeviceLedInfoPtr devli; +} LedInfoStuff; + +typedef struct _SetLedStuff { + unsigned wanted; + int num_info; + int dflt_class; + LedInfoStuff *dflt_kbd_fb; + LedInfoStuff *dflt_led_fb; + LedInfoStuff *info; +} SetLedStuff; + +static void +_InitLedStuff(SetLedStuff *stuff, unsigned wanted, XkbDeviceInfoPtr devi) +{ + int i; + register XkbDeviceLedInfoPtr devli; + + bzero(stuff, sizeof(SetLedStuff)); + stuff->wanted = wanted; + stuff->dflt_class = XkbXINone; + if ((devi->num_leds < 1) || ((wanted & XkbXI_IndicatorsMask) == 0)) + return; + stuff->info = _XkbTypedCalloc(devi->num_leds, LedInfoStuff); + if (!stuff->info) + return; + stuff->num_info = devi->num_leds; + for (devli = &devi->leds[0], i = 0; i < devi->num_leds; i++, devli++) { + stuff->info[i].devli = devli; + if (devli->led_class == KbdFeedbackClass) { + stuff->dflt_class = KbdFeedbackClass; + if (stuff->dflt_kbd_fb == NULL) + stuff->dflt_kbd_fb = &stuff->info[i]; + } + else if (devli->led_class == LedFeedbackClass) { + if (stuff->dflt_class == XkbXINone) + stuff->dflt_class = LedFeedbackClass; + if (stuff->dflt_led_fb == NULL) + stuff->dflt_led_fb = &stuff->info[i]; + } + } + return; +} + +static void +_FreeLedStuff(SetLedStuff * stuff) +{ + if (stuff->num_info > 0) + _XkbFree(stuff->info); + bzero(stuff, sizeof(SetLedStuff)); + return; +} + +static int +_XkbSizeLedInfo(unsigned changed, XkbDeviceLedInfoPtr devli) +{ + register int i, size; + register unsigned bit, namesNeeded, mapsNeeded; + + size = SIZEOF(xkbDeviceLedsWireDesc); + namesNeeded = mapsNeeded = 0; + if (changed & XkbXI_IndicatorNamesMask) + namesNeeded = devli->names_present; + if (changed & XkbXI_IndicatorMapsMask) + mapsNeeded = devli->maps_present; + if ((namesNeeded) || (mapsNeeded)) { + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { + if (namesNeeded & bit) + size += 4; /* atoms are 4 bytes on the wire */ + if (mapsNeeded & bit) + size += SIZEOF(xkbIndicatorMapWireDesc); + } + } + return size; +} + +static Bool +_SizeMatches(SetLedStuff *stuff, + XkbDeviceLedChangesPtr changes, + int *sz_rtrn, + int *nleds_rtrn) +{ + int i, nMatch, class, id; + LedInfoStuff *linfo; + Bool match; + + nMatch = 0; + class = changes->led_class; + id = changes->led_id; + if (class == XkbDfltXIClass) + class = stuff->dflt_class; + for (i = 0, linfo = &stuff->info[0]; i < stuff->num_info; i++, linfo++) { + XkbDeviceLedInfoPtr devli; + LedInfoStuff *dflt; + + devli = linfo->devli; + match = ((class == devli->led_class) || (class == XkbAllXIClasses)); + if (devli->led_class == KbdFeedbackClass) + dflt = stuff->dflt_kbd_fb; + else + dflt = stuff->dflt_led_fb; + match = (match && (id == devli->led_id)) || + (id == XkbAllXIIds) || + ((id == XkbDfltXIId) && (linfo == dflt)); + if (match) { + if (!linfo->used) { + *sz_rtrn += _XkbSizeLedInfo(stuff->wanted, devli); + *nleds_rtrn += 1; + linfo->used = True; + if ((class != XkbAllXIClasses) && (id != XkbAllXIIds)) + return True; + } + nMatch++; + linfo->used = True; + } + } + return (nMatch > 0); +} + +/***====================================================================***/ + + +static Status +_XkbSetDeviceInfoSize(XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes, + SetLedStuff *stuff, + int *sz_rtrn, + int *num_leds_rtrn) +{ + *sz_rtrn = 0; + if ((changes->changed & XkbXI_ButtonActionsMask) && (changes->num_btns > 0)) { + if (!XkbXI_LegalDevBtn + (devi, (changes->first_btn + changes->num_btns - 1))) + return BadMatch; + *sz_rtrn += changes->num_btns * SIZEOF(xkbActionWireDesc); + } + else { + changes->changed &= ~XkbXI_ButtonActionsMask; + changes->first_btn = changes->num_btns = 0; + } + if ((changes->changed & XkbXI_IndicatorsMask) && + XkbLegalXILedClass(changes->leds.led_class)) { + XkbDeviceLedChangesPtr leds; + + for (leds = &changes->leds; leds != NULL; leds = leds->next) { + if (!_SizeMatches(stuff, leds, sz_rtrn, num_leds_rtrn)) + return BadMatch; + } + } + else { + changes->changed &= ~XkbXI_IndicatorsMask; + *num_leds_rtrn = 0; + } + return Success; +} + +static char * +_XkbWriteLedInfo(char *wire, unsigned changed, XkbDeviceLedInfoPtr devli) +{ + register int i; + register unsigned bit, namesNeeded, mapsNeeded; + xkbDeviceLedsWireDesc *lwire; + + namesNeeded = mapsNeeded = 0; + if (changed & XkbXI_IndicatorNamesMask) + namesNeeded = devli->names_present; + if (changed & XkbXI_IndicatorMapsMask) + mapsNeeded = devli->maps_present; + + lwire = (xkbDeviceLedsWireDesc *) wire; + lwire->ledClass = devli->led_class; + lwire->ledID = devli->led_id; + lwire->namesPresent = namesNeeded; + lwire->mapsPresent = mapsNeeded; + lwire->physIndicators = devli->phys_indicators; + lwire->state = devli->state; + wire = (char *) &lwire[1]; + if (namesNeeded) { + CARD32 *awire = (CARD32 *) wire; + + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { + if (namesNeeded & bit) { + *awire = (CARD32) devli->names[i]; + awire++; + } + } + wire = (char *) awire; + } + if (mapsNeeded) { + xkbIndicatorMapWireDesc *mwire = (xkbIndicatorMapWireDesc *) wire; + + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { + if (mapsNeeded & bit) { + XkbIndicatorMapPtr map = &devli->maps[i]; + + mwire->flags = map->flags; + mwire->whichGroups = map->which_groups; + mwire->groups = map->groups; + mwire->whichMods = map->which_mods; + mwire->mods = map->mods.mask; + mwire->realMods = map->mods.real_mods; + mwire->virtualMods = map->mods.vmods; + mwire->ctrls = map->ctrls; + mwire++; + } + } + wire = (char *) mwire; + } + return wire; +} + + +static int +_XkbWriteSetDeviceInfo(char *wire, + XkbDeviceChangesPtr changes, + SetLedStuff *stuff, + XkbDeviceInfoPtr devi) +{ + char *start = wire; + + if (changes->changed & XkbXI_ButtonActionsMask) { + int size = changes->num_btns * SIZEOF(xkbActionWireDesc); + + memcpy(wire, (char *) &devi->btn_acts[changes->first_btn], size); + wire += size; + } + if (changes->changed & XkbXI_IndicatorsMask) { + register int i; + register LedInfoStuff *linfo; + + for (i = 0, linfo = &stuff->info[0]; i < stuff->num_info; i++, linfo++) { + if (linfo->used) { + register char *new_wire; + + new_wire = _XkbWriteLedInfo(wire, stuff->wanted, linfo->devli); + if (!new_wire) + return wire - start; + wire = new_wire; + } + } + } + return wire - start; +} + +Bool +XkbSetDeviceInfo(Display *dpy, unsigned which, XkbDeviceInfoPtr devi) +{ + register xkbSetDeviceInfoReq *req; + Status ok = 0; + int size, nLeds; + XkbInfoPtr xkbi; + XkbDeviceChangesRec changes; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!devi) || (which & (~XkbXI_AllDeviceFeaturesMask)) || + ((which & XkbXI_ButtonActionsMask) && (!XkbXI_DevHasBtnActs(devi))) || + ((which & XkbXI_IndicatorsMask) && (!XkbXI_DevHasLeds(devi)))) + return False; + + bzero((char *) &changes, sizeof(XkbDeviceChangesRec)); + changes.changed = which; + changes.first_btn = 0; + changes.num_btns = devi->num_btns; + changes.leds.led_class = XkbAllXIClasses; + changes.leds.led_id = XkbAllXIIds; + changes.leds.defined = 0; + size = nLeds = 0; + _InitLedStuff(&lstuff, changes.changed, devi); + if (_XkbSetDeviceInfoSize(devi, &changes, &lstuff, &size, &nLeds) != + Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length += size / 4; + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->firstBtn = changes.first_btn; + req->nBtns = changes.num_btns; + req->change = changes.changed; + req->nDeviceLedFBs = nLeds; + if (size > 0) { + char *wire; + + BufAlloc(char *, wire, size); + ok = (wire != NULL) && + (_XkbWriteSetDeviceInfo(wire, &changes, &lstuff, devi) == size); + } + UnlockDisplay(dpy); + SyncHandle(); + _FreeLedStuff(&lstuff); + /* 12/11/95 (ef) -- XXX!! should clear changes here */ + return ok; +} + +Bool +XkbChangeDeviceInfo(Display *dpy, + XkbDeviceInfoPtr devi, + XkbDeviceChangesPtr changes) +{ + register xkbSetDeviceInfoReq *req; + Status ok = 0; + int size, nLeds; + XkbInfoPtr xkbi; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!devi) || (changes->changed & (~XkbXI_AllDeviceFeaturesMask)) || + ((changes->changed & XkbXI_ButtonActionsMask) && + (!XkbXI_DevHasBtnActs(devi))) || + ((changes->changed & XkbXI_IndicatorsMask) && + (!XkbXI_DevHasLeds(devi)))) + return False; + + size = nLeds = 0; + _InitLedStuff(&lstuff, changes->changed, devi); + if (_XkbSetDeviceInfoSize(devi, changes, &lstuff, &size, &nLeds) != Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length += size / 4; + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->firstBtn = changes->first_btn; + req->nBtns = changes->num_btns; + req->change = changes->changed; + req->nDeviceLedFBs = nLeds; + if (size > 0) { + char *wire; + + BufAlloc(char *, wire, size); + ok = (wire != NULL) && + (_XkbWriteSetDeviceInfo(wire, changes, &lstuff, devi) == size); + } + UnlockDisplay(dpy); + SyncHandle(); + _FreeLedStuff(&lstuff); + /* 12/11/95 (ef) -- XXX!! should clear changes here */ + return ok; +} + +Bool +XkbSetDeviceLedInfo(Display *dpy, + XkbDeviceInfoPtr devi, + unsigned ledClass, + unsigned ledID, + unsigned which) +{ + return False; +} + +Bool +XkbSetDeviceButtonActions(Display *dpy, + XkbDeviceInfoPtr devi, + unsigned int first, + unsigned int nBtns) +{ + register xkbSetDeviceInfoReq *req; + Status ok = 0; + int size, nLeds; + XkbInfoPtr xkbi; + XkbDeviceChangesRec changes; + SetLedStuff lstuff; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!devi) || (!XkbXI_DevHasBtnActs(devi)) || + (first + nBtns > devi->num_btns)) + return False; + if (nBtns == 0) + return True; + + bzero((char *) &changes, sizeof(XkbDeviceChangesRec)); + changes.changed = XkbXI_ButtonActionsMask; + changes.first_btn = first; + changes.num_btns = nBtns; + changes.leds.led_class = XkbXINone; + changes.leds.led_id = XkbXINone; + changes.leds.defined = 0; + size = nLeds = 0; + if (_XkbSetDeviceInfoSize(devi, &changes, NULL, &size, &nLeds) != Success) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetDeviceInfo, req); + req->length += size / 4; + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetDeviceInfo; + req->deviceSpec = devi->device_spec; + req->firstBtn = changes.first_btn; + req->nBtns = changes.num_btns; + req->change = changes.changed; + req->nDeviceLedFBs = nLeds; + if (size > 0) { + char *wire; + + BufAlloc(char *, wire, size); + ok = (wire != NULL) && + (_XkbWriteSetDeviceInfo(wire, &changes, &lstuff, devi) == size); + } + UnlockDisplay(dpy); + SyncHandle(); + return ok; +} diff --git a/nx-X11/lib/src/xkb/XKBGAlloc.c b/nx-X11/lib/src/xkb/XKBGAlloc.c new file mode 100644 index 000000000..ab05f8d88 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBGAlloc.c @@ -0,0 +1,994 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + + +#include <stdio.h> +#include "Xlibint.h" +#include "XKBlibint.h" +#include <nx-X11/extensions/XKBgeom.h> +#include <nx-X11/extensions/XKBproto.h> + +/***====================================================================***/ + +static void +_XkbFreeGeomLeafElems(Bool freeAll, + int first, + int count, + unsigned short *num_inout, + unsigned short *sz_inout, + char **elems, + unsigned int elem_sz) +{ + if ((freeAll) || (*elems == NULL)) { + *num_inout = *sz_inout = 0; + if (*elems != NULL) { + _XkbFree(*elems); + *elems = NULL; + } + return; + } + + if ((first >= (*num_inout)) || (first < 0) || (count < 1)) + return; + + if (first + count >= (*num_inout)) { + /* truncating the array is easy */ + (*num_inout) = first; + } + else { + char *ptr; + int extra; + + ptr = *elems; + extra = ((*num_inout) - (first + count)) * elem_sz; + if (extra > 0) + memmove(&ptr[first * elem_sz], &ptr[(first + count) * elem_sz], + extra); + (*num_inout) -= count; + } + return; +} + +typedef void (*ContentsClearFunc) ( + char * /* priv */ +); + +static void +_XkbFreeGeomNonLeafElems(Bool freeAll, + int first, + int count, + unsigned short *num_inout, + unsigned short *sz_inout, + char **elems, + unsigned int elem_sz, + ContentsClearFunc freeFunc) +{ + register int i; + register char *ptr; + + if (freeAll) { + first = 0; + count = (*num_inout); + } + else if ((first >= (*num_inout)) || (first < 0) || (count < 1)) + return; + else if (first + count > (*num_inout)) + count = (*num_inout) - first; + if (*elems == NULL) + return; + + if (freeFunc) { + ptr = *elems; + ptr += first * elem_sz; + for (i = 0; i < count; i++) { + (*freeFunc) (ptr); + ptr += elem_sz; + } + } + if (freeAll) { + (*num_inout) = (*sz_inout) = 0; + if (*elems) { + _XkbFree(*elems); + *elems = NULL; + } + } + else if (first + count >= (*num_inout)) + *num_inout = first; + else { + i = ((*num_inout) - (first + count)) * elem_sz; + ptr = *elems; + memmove(&ptr[first * elem_sz], &ptr[(first + count) * elem_sz], i); + (*num_inout) -= count; + } + return; +} + +/***====================================================================***/ + +static void +_XkbClearProperty(char *prop_in) +{ + XkbPropertyPtr prop = (XkbPropertyPtr) prop_in; + + if (prop->name) { + _XkbFree(prop->name); + prop->name = NULL; + } + if (prop->value) { + _XkbFree(prop->value); + prop->value = NULL; + } + return; +} + +void +XkbFreeGeomProperties(XkbGeometryPtr geom, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &geom->num_properties, &geom->sz_properties, + (char **) &geom->properties, + sizeof(XkbPropertyRec), _XkbClearProperty); + return; +} + +/***====================================================================***/ + +void +XkbFreeGeomKeyAliases(XkbGeometryPtr geom, int first, int count, Bool freeAll) +{ + _XkbFreeGeomLeafElems(freeAll, first, count, + &geom->num_key_aliases, &geom->sz_key_aliases, + (char **) &geom->key_aliases, + sizeof(XkbKeyAliasRec)); + return; +} + +/***====================================================================***/ + +static void +_XkbClearColor(char *color_in) +{ + XkbColorPtr color = (XkbColorPtr) color_in; + + _XkbFree(color->spec); + return; +} + +void +XkbFreeGeomColors(XkbGeometryPtr geom, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &geom->num_colors, &geom->sz_colors, + (char **) &geom->colors, + sizeof(XkbColorRec), _XkbClearColor); + return; +} + +/***====================================================================***/ + +void +XkbFreeGeomPoints(XkbOutlinePtr outline, int first, int count, Bool freeAll) +{ + _XkbFreeGeomLeafElems(freeAll, first, count, + &outline->num_points, &outline->sz_points, + (char **) &outline->points, + sizeof(XkbPointRec)); + return; +} + +/***====================================================================***/ + +static void +_XkbClearOutline(char *outline_in) +{ + XkbOutlinePtr outline = (XkbOutlinePtr) outline_in; + + if (outline->points != NULL) + XkbFreeGeomPoints(outline, 0, outline->num_points, True); + return; +} + +void +XkbFreeGeomOutlines(XkbShapePtr shape, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &shape->num_outlines, &shape->sz_outlines, + (char **) &shape->outlines, + sizeof(XkbOutlineRec), _XkbClearOutline); + + return; +} + +/***====================================================================***/ + +static void +_XkbClearShape(char *shape_in) +{ + XkbShapePtr shape = (XkbShapePtr) shape_in; + + if (shape->outlines) + XkbFreeGeomOutlines(shape, 0, shape->num_outlines, True); + return; +} + +void +XkbFreeGeomShapes(XkbGeometryPtr geom, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &geom->num_shapes, &geom->sz_shapes, + (char **) &geom->shapes, + sizeof(XkbShapeRec), _XkbClearShape); + return; +} + +/***====================================================================***/ + +void +XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row, int first, int count, Bool freeAll) +{ + _XkbFreeGeomLeafElems(freeAll, first, count, + &row->num_keys, &row->sz_keys, + (char **) &row->keys, + sizeof(XkbOverlayKeyRec)); + return; +} + +/***====================================================================***/ + +static void +_XkbClearOverlayRow(char *row_in) +{ + XkbOverlayRowPtr row = (XkbOverlayRowPtr) row_in; + + if (row->keys != NULL) + XkbFreeGeomOverlayKeys(row, 0, row->num_keys, True); + return; +} + +void +XkbFreeGeomOverlayRows(XkbOverlayPtr overlay, int first, int count, + Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &overlay->num_rows, &overlay->sz_rows, + (char **) &overlay->rows, + sizeof(XkbOverlayRowRec), _XkbClearOverlayRow); + return; +} + +/***====================================================================***/ + +static void +_XkbClearOverlay(char *overlay_in) +{ + XkbOverlayPtr overlay = (XkbOverlayPtr) overlay_in; + + if (overlay->rows != NULL) + XkbFreeGeomOverlayRows(overlay, 0, overlay->num_rows, True); + return; +} + +void +XkbFreeGeomOverlays(XkbSectionPtr section, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + §ion->num_overlays, §ion->sz_overlays, + (char **) §ion->overlays, + sizeof(XkbOverlayRec), _XkbClearOverlay); + return; +} + +/***====================================================================***/ + +void +XkbFreeGeomKeys(XkbRowPtr row, int first, int count, Bool freeAll) +{ + _XkbFreeGeomLeafElems(freeAll, first, count, + &row->num_keys, &row->sz_keys, + (char **) &row->keys, + sizeof(XkbKeyRec)); + return; +} + +/***====================================================================***/ + +static void +_XkbClearRow(char *row_in) +{ + XkbRowPtr row = (XkbRowPtr) row_in; + + if (row->keys != NULL) + XkbFreeGeomKeys(row, 0, row->num_keys, True); + return; +} + +void +XkbFreeGeomRows(XkbSectionPtr section, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + §ion->num_rows, §ion->sz_rows, + (char **) §ion->rows, + sizeof(XkbRowRec), _XkbClearRow); +} + +/***====================================================================***/ + +static void +_XkbClearSection(char *section_in) +{ + XkbSectionPtr section = (XkbSectionPtr) section_in; + + if (section->rows != NULL) + XkbFreeGeomRows(section, 0, section->num_rows, True); + if (section->doodads != NULL) { + XkbFreeGeomDoodads(section->doodads, section->num_doodads, True); + section->doodads = NULL; + } + return; +} + +void +XkbFreeGeomSections(XkbGeometryPtr geom, int first, int count, Bool freeAll) +{ + _XkbFreeGeomNonLeafElems(freeAll, first, count, + &geom->num_sections, &geom->sz_sections, + (char **) &geom->sections, + sizeof(XkbSectionRec), _XkbClearSection); + return; +} + +/***====================================================================***/ + +static void +_XkbClearDoodad(char *doodad_in) +{ + XkbDoodadPtr doodad = (XkbDoodadPtr) doodad_in; + + switch (doodad->any.type) { + case XkbTextDoodad: + { + if (doodad->text.text != NULL) { + _XkbFree(doodad->text.text); + doodad->text.text = NULL; + } + if (doodad->text.font != NULL) { + _XkbFree(doodad->text.font); + doodad->text.font = NULL; + } + } + break; + case XkbLogoDoodad: + { + if (doodad->logo.logo_name != NULL) { + _XkbFree(doodad->logo.logo_name); + doodad->logo.logo_name = NULL; + } + } + break; + } + return; +} + +void +XkbFreeGeomDoodads(XkbDoodadPtr doodads, int nDoodads, Bool freeAll) +{ + register int i; + register XkbDoodadPtr doodad; + + if (doodads) { + for (i = 0, doodad = doodads; i < nDoodads; i++, doodad++) { + _XkbClearDoodad((char *) doodad); + } + if (freeAll) + _XkbFree(doodads); + } + return; +} + +void +XkbFreeGeometry(XkbGeometryPtr geom, unsigned which, Bool freeMap) +{ + if (geom == NULL) + return; + if (freeMap) + which = XkbGeomAllMask; + if ((which & XkbGeomPropertiesMask) && (geom->properties != NULL)) + XkbFreeGeomProperties(geom, 0, geom->num_properties, True); + if ((which & XkbGeomColorsMask) && (geom->colors != NULL)) + XkbFreeGeomColors(geom, 0, geom->num_colors, True); + if ((which & XkbGeomShapesMask) && (geom->shapes != NULL)) + XkbFreeGeomShapes(geom, 0, geom->num_shapes, True); + if ((which & XkbGeomSectionsMask) && (geom->sections != NULL)) + XkbFreeGeomSections(geom, 0, geom->num_sections, True); + if ((which & XkbGeomDoodadsMask) && (geom->doodads != NULL)) { + XkbFreeGeomDoodads(geom->doodads, geom->num_doodads, True); + geom->doodads = NULL; + geom->num_doodads = geom->sz_doodads = 0; + } + if ((which & XkbGeomKeyAliasesMask) && (geom->key_aliases != NULL)) + XkbFreeGeomKeyAliases(geom, 0, geom->num_key_aliases, True); + if (freeMap) { + if (geom->label_font != NULL) { + _XkbFree(geom->label_font); + geom->label_font = NULL; + } + _XkbFree(geom); + } + return; +} + +/***====================================================================***/ + +static Status +_XkbGeomAlloc(XPointer *old, + unsigned short *num, + unsigned short *total, + int num_new, + size_t sz_elem) +{ + if (num_new < 1) + return Success; + if ((*old) == NULL) + *num = *total = 0; + + if ((*num) + num_new <= (*total)) + return Success; + + *total = (*num) + num_new; + if ((*old) != NULL) + (*old) = (XPointer) _XkbRealloc((*old), (*total) * sz_elem); + else + (*old) = (XPointer) _XkbCalloc((*total), sz_elem); + if ((*old) == NULL) { + *total = *num = 0; + return BadAlloc; + } + + if (*num > 0) { + char *tmp = (char *) (*old); + bzero(&tmp[sz_elem * (*num)], (num_new * sz_elem)); + } + return Success; +} + +#define _XkbAllocProps(g, n) _XkbGeomAlloc((XPointer *)&(g)->properties, \ + &(g)->num_properties, &(g)->sz_properties, \ + (n), sizeof(XkbPropertyRec)) +#define _XkbAllocColors(g, n) _XkbGeomAlloc((XPointer *)&(g)->colors, \ + &(g)->num_colors, &(g)->sz_colors, \ + (n), sizeof(XkbColorRec)) +#define _XkbAllocShapes(g, n) _XkbGeomAlloc((XPointer *)&(g)->shapes, \ + &(g)->num_shapes, &(g)->sz_shapes, \ + (n), sizeof(XkbShapeRec)) +#define _XkbAllocSections(g, n) _XkbGeomAlloc((XPointer *)&(g)->sections, \ + &(g)->num_sections, &(g)->sz_sections, \ + (n), sizeof(XkbSectionRec)) +#define _XkbAllocDoodads(g, n) _XkbGeomAlloc((XPointer *)&(g)->doodads, \ + &(g)->num_doodads, &(g)->sz_doodads, \ + (n), sizeof(XkbDoodadRec)) +#define _XkbAllocKeyAliases(g, n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases, \ + &(g)->num_key_aliases, &(g)->sz_key_aliases, \ + (n), sizeof(XkbKeyAliasRec)) + +#define _XkbAllocOutlines(s, n) _XkbGeomAlloc((XPointer *)&(s)->outlines, \ + &(s)->num_outlines, &(s)->sz_outlines, \ + (n), sizeof(XkbOutlineRec)) +#define _XkbAllocRows(s, n) _XkbGeomAlloc((XPointer *)&(s)->rows, \ + &(s)->num_rows, &(s)->sz_rows, \ + (n), sizeof(XkbRowRec)) +#define _XkbAllocPoints(o, n) _XkbGeomAlloc((XPointer *)&(o)->points, \ + &(o)->num_points, &(o)->sz_points, \ + (n), sizeof(XkbPointRec)) +#define _XkbAllocKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \ + &(r)->num_keys, &(r)->sz_keys, \ + (n), sizeof(XkbKeyRec)) +#define _XkbAllocOverlays(s, n) _XkbGeomAlloc((XPointer *)&(s)->overlays, \ + &(s)->num_overlays, &(s)->sz_overlays, \ + (n), sizeof(XkbOverlayRec)) +#define _XkbAllocOverlayRows(o, n) _XkbGeomAlloc((XPointer *)&(o)->rows, \ + &(o)->num_rows, &(o)->sz_rows, \ + (n), sizeof(XkbOverlayRowRec)) +#define _XkbAllocOverlayKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \ + &(r)->num_keys, &(r)->sz_keys, \ + (n), sizeof(XkbOverlayKeyRec)) + +Status +XkbAllocGeomProps(XkbGeometryPtr geom, int nProps) +{ + return _XkbAllocProps(geom, nProps); +} + +Status +XkbAllocGeomColors(XkbGeometryPtr geom, int nColors) +{ + return _XkbAllocColors(geom, nColors); +} + +Status +XkbAllocGeomKeyAliases(XkbGeometryPtr geom, int nKeyAliases) +{ + return _XkbAllocKeyAliases(geom, nKeyAliases); +} + +Status +XkbAllocGeomShapes(XkbGeometryPtr geom, int nShapes) +{ + return _XkbAllocShapes(geom, nShapes); +} + +Status +XkbAllocGeomSections(XkbGeometryPtr geom, int nSections) +{ + return _XkbAllocSections(geom, nSections); +} + +Status +XkbAllocGeomOverlays(XkbSectionPtr section, int nOverlays) +{ + return _XkbAllocOverlays(section, nOverlays); +} + +Status +XkbAllocGeomOverlayRows(XkbOverlayPtr overlay, int nRows) +{ + return _XkbAllocOverlayRows(overlay, nRows); +} + +Status +XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row, int nKeys) +{ + return _XkbAllocOverlayKeys(row, nKeys); +} + +Status +XkbAllocGeomDoodads(XkbGeometryPtr geom, int nDoodads) +{ + return _XkbAllocDoodads(geom, nDoodads); +} + +Status +XkbAllocGeomSectionDoodads(XkbSectionPtr section, int nDoodads) +{ + return _XkbAllocDoodads(section, nDoodads); +} + +Status +XkbAllocGeomOutlines(XkbShapePtr shape, int nOL) +{ + return _XkbAllocOutlines(shape, nOL); +} + +Status +XkbAllocGeomRows(XkbSectionPtr section, int nRows) +{ + return _XkbAllocRows(section, nRows); +} + +Status +XkbAllocGeomPoints(XkbOutlinePtr ol, int nPts) +{ + return _XkbAllocPoints(ol, nPts); +} + +Status +XkbAllocGeomKeys(XkbRowPtr row, int nKeys) +{ + return _XkbAllocKeys(row, nKeys); +} + +Status +XkbAllocGeometry(XkbDescPtr xkb, XkbGeometrySizesPtr sizes) +{ + XkbGeometryPtr geom; + Status rtrn; + + if (xkb->geom == NULL) { + xkb->geom = _XkbTypedCalloc(1, XkbGeometryRec); + if (!xkb->geom) + return BadAlloc; + } + geom = xkb->geom; + if ((sizes->which & XkbGeomPropertiesMask) && + ((rtrn = _XkbAllocProps(geom, sizes->num_properties)) != Success)) { + goto BAIL; + } + if ((sizes->which & XkbGeomColorsMask) && + ((rtrn = _XkbAllocColors(geom, sizes->num_colors)) != Success)) { + goto BAIL; + } + if ((sizes->which & XkbGeomShapesMask) && + ((rtrn = _XkbAllocShapes(geom, sizes->num_shapes)) != Success)) { + goto BAIL; + } + if ((sizes->which & XkbGeomSectionsMask) && + ((rtrn = _XkbAllocSections(geom, sizes->num_sections)) != Success)) { + goto BAIL; + } + if ((sizes->which & XkbGeomDoodadsMask) && + ((rtrn = _XkbAllocDoodads(geom, sizes->num_doodads)) != Success)) { + goto BAIL; + } + if ((sizes->which & XkbGeomKeyAliasesMask) && + ((rtrn = _XkbAllocKeyAliases(geom, sizes->num_key_aliases)) + != Success)) { + goto BAIL; + } + return Success; + BAIL: + XkbFreeGeometry(geom, XkbGeomAllMask, True); + xkb->geom = NULL; + return rtrn; +} + +/***====================================================================***/ + +XkbPropertyPtr +XkbAddGeomProperty(XkbGeometryPtr geom, char *name, char *value) +{ + register int i; + register XkbPropertyPtr prop; + + if ((!geom) || (!name) || (!value)) + return NULL; + for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { + if ((prop->name) && (strcmp(name, prop->name) == 0)) { + _XkbFree(prop->value); + prop->value = strdup(value); + return prop; + } + } + if ((geom->num_properties >= geom->sz_properties) && + (_XkbAllocProps(geom, 1) != Success)) { + return NULL; + } + prop = &geom->properties[geom->num_properties]; + prop->name = strdup(name); + if (!prop->name) + return NULL; + prop->value = strdup(value); + if (!prop->value) { + _XkbFree(prop->name); + prop->name = NULL; + return NULL; + } + geom->num_properties++; + return prop; +} + +XkbKeyAliasPtr +XkbAddGeomKeyAlias(XkbGeometryPtr geom, char *aliasStr, char *realStr) +{ + register int i; + register XkbKeyAliasPtr alias; + + if ((!geom) || (!aliasStr) || (!realStr) || (!aliasStr[0]) || (!realStr[0])) + return NULL; + for (i = 0, alias = geom->key_aliases; i < geom->num_key_aliases; + i++, alias++) { + if (strncmp(alias->alias, aliasStr, XkbKeyNameLength) == 0) { + bzero(alias->real, XkbKeyNameLength); + strncpy(alias->real, realStr, XkbKeyNameLength); + return alias; + } + } + if ((geom->num_key_aliases >= geom->sz_key_aliases) && + (_XkbAllocKeyAliases(geom, 1) != Success)) { + return NULL; + } + alias = &geom->key_aliases[geom->num_key_aliases]; + bzero(alias, sizeof(XkbKeyAliasRec)); + strncpy(alias->alias, aliasStr, XkbKeyNameLength); + strncpy(alias->real, realStr, XkbKeyNameLength); + geom->num_key_aliases++; + return alias; +} + +XkbColorPtr +XkbAddGeomColor(XkbGeometryPtr geom, char *spec, unsigned int pixel) +{ + register int i; + register XkbColorPtr color; + + if ((!geom) || (!spec)) + return NULL; + for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { + if ((color->spec) && (strcmp(color->spec, spec) == 0)) { + color->pixel = pixel; + return color; + } + } + if ((geom->num_colors >= geom->sz_colors) && + (_XkbAllocColors(geom, 1) != Success)) { + return NULL; + } + color = &geom->colors[geom->num_colors]; + color->pixel = pixel; + color->spec = strdup(spec); + if (!color->spec) + return NULL; + geom->num_colors++; + return color; +} + +XkbOutlinePtr +XkbAddGeomOutline(XkbShapePtr shape, int sz_points) +{ + XkbOutlinePtr outline; + + if ((!shape) || (sz_points < 0)) + return NULL; + if ((shape->num_outlines >= shape->sz_outlines) && + (_XkbAllocOutlines(shape, 1) != Success)) { + return NULL; + } + outline = &shape->outlines[shape->num_outlines]; + bzero(outline, sizeof(XkbOutlineRec)); + if ((sz_points > 0) && (_XkbAllocPoints(outline, sz_points) != Success)) + return NULL; + shape->num_outlines++; + return outline; +} + +XkbShapePtr +XkbAddGeomShape(XkbGeometryPtr geom, Atom name, int sz_outlines) +{ + XkbShapePtr shape; + register int i; + + if ((!geom) || (!name) || (sz_outlines < 0)) + return NULL; + if (geom->num_shapes > 0) { + for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) { + if (name == shape->name) + return shape; + } + } + if ((geom->num_shapes >= geom->sz_shapes) && + (_XkbAllocShapes(geom, 1) != Success)) + return NULL; + shape = &geom->shapes[geom->num_shapes]; + bzero(shape, sizeof(XkbShapeRec)); + if ((sz_outlines > 0) && (_XkbAllocOutlines(shape, sz_outlines) != Success)) + return NULL; + shape->name = name; + shape->primary = shape->approx = NULL; + geom->num_shapes++; + return shape; +} + +XkbKeyPtr +XkbAddGeomKey(XkbRowPtr row) +{ + XkbKeyPtr key; + + if (!row) + return NULL; + if ((row->num_keys >= row->sz_keys) && (_XkbAllocKeys(row, 1) != Success)) + return NULL; + key = &row->keys[row->num_keys++]; + bzero(key, sizeof(XkbKeyRec)); + return key; +} + +XkbRowPtr +XkbAddGeomRow(XkbSectionPtr section, int sz_keys) +{ + XkbRowPtr row; + + if ((!section) || (sz_keys < 0)) + return NULL; + if ((section->num_rows >= section->sz_rows) && + (_XkbAllocRows(section, 1) != Success)) + return NULL; + row = §ion->rows[section->num_rows]; + bzero(row, sizeof(XkbRowRec)); + if ((sz_keys > 0) && (_XkbAllocKeys(row, sz_keys) != Success)) + return NULL; + section->num_rows++; + return row; +} + +XkbSectionPtr +XkbAddGeomSection(XkbGeometryPtr geom, + Atom name, + int sz_rows, + int sz_doodads, + int sz_over) +{ + register int i; + XkbSectionPtr section; + + if ((!geom) || (name == None) || (sz_rows < 0)) + return NULL; + for (i = 0, section = geom->sections; i < geom->num_sections; + i++, section++) { + if (section->name != name) + continue; + if (((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) || + ((sz_doodads > 0) && + (_XkbAllocDoodads(section, sz_doodads) != Success)) || + ((sz_over > 0) && (_XkbAllocOverlays(section, sz_over) != Success))) + return NULL; + return section; + } + if ((geom->num_sections >= geom->sz_sections) && + (_XkbAllocSections(geom, 1) != Success)) + return NULL; + section = &geom->sections[geom->num_sections]; + if ((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) + return NULL; + if ((sz_doodads > 0) && (_XkbAllocDoodads(section, sz_doodads) != Success)) { + if (section->rows) { + _XkbFree(section->rows); + section->rows = NULL; + section->sz_rows = section->num_rows = 0; + } + return NULL; + } + section->name = name; + geom->num_sections++; + return section; +} + +XkbDoodadPtr +XkbAddGeomDoodad(XkbGeometryPtr geom, XkbSectionPtr section, Atom name) +{ + XkbDoodadPtr old, doodad; + register int i, nDoodads; + + if ((!geom) || (name == None)) + return NULL; + if ((section != NULL) && (section->num_doodads > 0)) { + old = section->doodads; + nDoodads = section->num_doodads; + } + else { + old = geom->doodads; + nDoodads = geom->num_doodads; + } + for (i = 0, doodad = old; i < nDoodads; i++, doodad++) { + if (doodad->any.name == name) + return doodad; + } + if (section) { + if ((section->num_doodads >= geom->sz_doodads) && + (_XkbAllocDoodads(section, 1) != Success)) { + return NULL; + } + doodad = §ion->doodads[section->num_doodads++]; + } + else { + if ((geom->num_doodads >= geom->sz_doodads) && + (_XkbAllocDoodads(geom, 1) != Success)) + return NULL; + doodad = &geom->doodads[geom->num_doodads++]; + } + bzero(doodad, sizeof(XkbDoodadRec)); + doodad->any.name = name; + return doodad; +} + +XkbOverlayKeyPtr +XkbAddGeomOverlayKey(XkbOverlayPtr overlay, + XkbOverlayRowPtr row, + char *over, + char *under) +{ + register int i; + XkbOverlayKeyPtr key; + XkbSectionPtr section; + XkbRowPtr row_under; + Bool found; + + if ((!overlay) || (!row) || (!over) || (!under)) + return NULL; + section = overlay->section_under; + if (row->row_under >= section->num_rows) + return NULL; + row_under = §ion->rows[row->row_under]; + for (i = 0, found = False; i < row_under->num_keys; i++) { + if (strncmp(under, row_under->keys[i].name.name, XkbKeyNameLength) == 0) { + found = True; + break; + } + } + if (!found) + return NULL; + if ((row->num_keys >= row->sz_keys) && + (_XkbAllocOverlayKeys(row, 1) != Success)) + return NULL; + key = &row->keys[row->num_keys]; + strncpy(key->under.name, under, XkbKeyNameLength); + strncpy(key->over.name, over, XkbKeyNameLength); + row->num_keys++; + return key; +} + +XkbOverlayRowPtr +XkbAddGeomOverlayRow(XkbOverlayPtr overlay, int row_under, int sz_keys) +{ + register int i; + XkbOverlayRowPtr row; + + if ((!overlay) || (sz_keys < 0)) + return NULL; + if (row_under >= overlay->section_under->num_rows) + return NULL; + for (i = 0; i < overlay->num_rows; i++) { + if (overlay->rows[i].row_under == row_under) { + row = &overlay->rows[i]; + if ((row->sz_keys < sz_keys) && + (_XkbAllocOverlayKeys(row, sz_keys) != Success)) { + return NULL; + } + return &overlay->rows[i]; + } + } + if ((overlay->num_rows >= overlay->sz_rows) && + (_XkbAllocOverlayRows(overlay, 1) != Success)) + return NULL; + row = &overlay->rows[overlay->num_rows]; + bzero(row, sizeof(XkbOverlayRowRec)); + if ((sz_keys > 0) && (_XkbAllocOverlayKeys(row, sz_keys) != Success)) + return NULL; + row->row_under = row_under; + overlay->num_rows++; + return row; +} + +XkbOverlayPtr +XkbAddGeomOverlay(XkbSectionPtr section, Atom name, int sz_rows) +{ + register int i; + XkbOverlayPtr overlay; + + if ((!section) || (name == None) || (sz_rows == 0)) + return NULL; + + for (i = 0, overlay = section->overlays; i < section->num_overlays; + i++, overlay++) { + if (overlay->name == name) { + if ((sz_rows > 0) && + (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) + return NULL; + return overlay; + } + } + if ((section->num_overlays >= section->sz_overlays) && + (_XkbAllocOverlays(section, 1) != Success)) + return NULL; + overlay = §ion->overlays[section->num_overlays]; + if ((sz_rows > 0) && (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) + return NULL; + overlay->name = name; + overlay->section_under = section; + section->num_overlays++; + return overlay; +} diff --git a/nx-X11/lib/src/xkb/XKBGeom.c b/nx-X11/lib/src/xkb/XKBGeom.c new file mode 100644 index 000000000..f57fe7cf6 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBGeom.c @@ -0,0 +1,724 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef DEBUG +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#endif + +#define NEED_MAP_READERS +#include "Xlibint.h" +#include <nx-X11/extensions/XKBgeom.h> +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +/***====================================================================***/ + +static void +_XkbCheckBounds(XkbBoundsPtr bounds, int x, int y) +{ + if (x < bounds->x1) + bounds->x1 = x; + if (x > bounds->x2) + bounds->x2 = x; + if (y < bounds->y1) + bounds->y1 = y; + if (y > bounds->y2) + bounds->y2 = y; + return; +} + +Bool +XkbComputeShapeBounds(XkbShapePtr shape) +{ + register int o, p; + XkbOutlinePtr outline; + XkbPointPtr pt; + + if ((!shape) || (shape->num_outlines < 1)) + return False; + shape->bounds.x1 = shape->bounds.y1 = MAXSHORT; + shape->bounds.x2 = shape->bounds.y2 = MINSHORT; + for (outline = shape->outlines, o = 0; o < shape->num_outlines; + o++, outline++) { + for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++) { + _XkbCheckBounds(&shape->bounds, pt->x, pt->y); + } + if (outline->num_points < 2) { + _XkbCheckBounds(&shape->bounds, 0, 0); + } + } + return True; +} + +Bool +XkbComputeShapeTop(XkbShapePtr shape, XkbBoundsPtr bounds) +{ + register int p; + XkbOutlinePtr outline; + XkbPointPtr pt; + + if ((!shape) || (shape->num_outlines < 1)) + return False; + if (shape->approx) + outline = shape->approx; + else + outline = &shape->outlines[shape->num_outlines - 1]; + if (outline->num_points < 2) { + bounds->x1 = bounds->y1 = 0; + bounds->x2 = bounds->y2 = 0; + } + else { + bounds->x1 = bounds->y1 = MAXSHORT; + bounds->x2 = bounds->y2 = MINSHORT; + } + for (pt = outline->points, p = 0; p < outline->num_points; p++, pt++) { + _XkbCheckBounds(bounds, pt->x, pt->y); + } + return True; +} + +Bool +XkbComputeRowBounds(XkbGeometryPtr geom, XkbSectionPtr section, XkbRowPtr row) +{ + register int k, pos; + XkbKeyPtr key; + XkbBoundsPtr bounds, sbounds; + + if ((!geom) || (!section) || (!row)) + return False; + bounds = &row->bounds; + bzero(bounds, sizeof(XkbBoundsRec)); + for (key = row->keys, pos = k = 0; k < row->num_keys; k++, key++) { + sbounds = &XkbKeyShape(geom, key)->bounds; + _XkbCheckBounds(bounds, pos, 0); + if (!row->vertical) { + if (key->gap != 0) { + pos += key->gap; + _XkbCheckBounds(bounds, pos, 0); + } + _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1); + _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2); + pos += sbounds->x2; + } + else { + if (key->gap != 0) { + pos += key->gap; + _XkbCheckBounds(bounds, 0, pos); + } + _XkbCheckBounds(bounds, pos + sbounds->x1, sbounds->y1); + _XkbCheckBounds(bounds, pos + sbounds->x2, sbounds->y2); + pos += sbounds->y2; + } + } + return True; +} + +Bool +XkbComputeSectionBounds(XkbGeometryPtr geom, XkbSectionPtr section) +{ + register int i; + XkbShapePtr shape; + XkbRowPtr row; + XkbDoodadPtr doodad; + XkbBoundsPtr bounds, rbounds; + + if ((!geom) || (!section)) + return False; + bounds = §ion->bounds; + bzero(bounds, sizeof(XkbBoundsRec)); + for (i = 0, row = section->rows; i < section->num_rows; i++, row++) { + if (!XkbComputeRowBounds(geom, section, row)) + return False; + rbounds = &row->bounds; + _XkbCheckBounds(bounds, row->left + rbounds->x1, + row->top + rbounds->y1); + _XkbCheckBounds(bounds, row->left + rbounds->x2, + row->top + rbounds->y2); + } + for (i = 0, doodad = section->doodads; i < section->num_doodads; + i++, doodad++) { + static XkbBoundsRec tbounds; + + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + shape = XkbShapeDoodadShape(geom, &doodad->shape); + rbounds = &shape->bounds; + break; + case XkbTextDoodad: + tbounds.x1 = doodad->text.left; + tbounds.y1 = doodad->text.top; + tbounds.x2 = tbounds.x1 + doodad->text.width; + tbounds.y2 = tbounds.y1 + doodad->text.height; + rbounds = &tbounds; + break; + case XkbIndicatorDoodad: + shape = XkbIndicatorDoodadShape(geom, &doodad->indicator); + rbounds = &shape->bounds; + break; + case XkbLogoDoodad: + shape = XkbLogoDoodadShape(geom, &doodad->logo); + rbounds = &shape->bounds; + break; + default: + tbounds.x1 = tbounds.x2 = doodad->any.left; + tbounds.y1 = tbounds.y2 = doodad->any.top; + rbounds = &tbounds; + break; + } + _XkbCheckBounds(bounds, rbounds->x1, rbounds->y1); + _XkbCheckBounds(bounds, rbounds->x2, rbounds->y2); + } + return True; +} + +/***====================================================================***/ + +char * +XkbFindOverlayForKey(XkbGeometryPtr geom, XkbSectionPtr wanted, char *under) +{ + int s; + XkbSectionPtr section; + + if ((geom == NULL) || (under == NULL) || (geom->num_sections < 1)) + return NULL; + + if (wanted) + section = wanted; + else + section = geom->sections; + + for (s = 0; s < geom->num_sections; s++, section++) { + XkbOverlayPtr ol; + int o; + + if (section->num_overlays < 1) + continue; + for (o = 0, ol = section->overlays; o < section->num_overlays; + o++, ol++) { + XkbOverlayRowPtr row; + int r; + + for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { + XkbOverlayKeyPtr key; + int k; + + for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { + if (strncmp(under, key->under.name, XkbKeyNameLength) == 0) + return key->over.name; + } + } + } + if (wanted != NULL) + break; + } + return NULL; +} + +/***====================================================================***/ + +static Status +_XkbReadGeomProperties(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + Status rtrn; + + if (rep->nProperties < 1) + return Success; + if ((rtrn = XkbAllocGeomProps(geom, rep->nProperties)) == Success) { + register int i; + register Bool ok = True; + + for (i = 0; (i < rep->nProperties) && ok; i++) { + char *name = NULL; + char *value = NULL; + ok = _XkbGetReadBufferCountedString(buf, &name) && ok; + ok = _XkbGetReadBufferCountedString(buf, &value) && ok; + ok = ok && (XkbAddGeomProperty(geom, name, value) != NULL); + + _XkbFree(name); + _XkbFree(value); + } + if (ok) + rtrn = Success; + else + rtrn = BadLength; + } + return rtrn; +} + +static Status +_XkbReadGeomKeyAliases(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + Status rtrn; + + if (rep->nKeyAliases < 1) + return Success; + if ((rtrn = XkbAllocGeomKeyAliases(geom, rep->nKeyAliases)) == Success) { + if (!_XkbCopyFromReadBuffer(buf, (char *) geom->key_aliases, + (rep->nKeyAliases * XkbKeyNameLength * 2))) + return BadLength; + geom->num_key_aliases = rep->nKeyAliases; + return Success; + } + else { /* alloc failed, just skip the aliases */ + _XkbSkipReadBufferData(buf, (rep->nKeyAliases * XkbKeyNameLength * 2)); + } + return rtrn; +} + +static Status +_XkbReadGeomColors(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + Status rtrn; + + if (rep->nColors < 1) + return Success; + if ((rtrn = XkbAllocGeomColors(geom, rep->nColors)) == Success) { + register int i; + + for (i = 0; i < rep->nColors; i++) { + char *spec = NULL; + if (!_XkbGetReadBufferCountedString(buf, &spec)) + rtrn = BadLength; + else if (XkbAddGeomColor(geom, spec, geom->num_colors) == NULL) + rtrn = BadAlloc; + + _XkbFree(spec); + if (rtrn != Success) + return rtrn; + } + return Success; + } + return rtrn; +} + +static Status +_XkbReadGeomShapes(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + register int i; + Status rtrn; + + if (rep->nShapes < 1) + return Success; + if ((rtrn = XkbAllocGeomShapes(geom, rep->nShapes)) != Success) + return rtrn; + for (i = 0; i < rep->nShapes; i++) { + xkbShapeWireDesc *shapeWire; + XkbShapePtr shape; + register int o; + + shapeWire = (xkbShapeWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbShapeWireDesc)); + if (!shapeWire) + return BadLength; + shape = XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); + if (!shape) + return BadAlloc; + for (o = 0; o < shapeWire->nOutlines; o++) { + xkbOutlineWireDesc *olWire; + XkbOutlinePtr ol; + register int p; + XkbPointPtr pt; + + olWire = (xkbOutlineWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbOutlineWireDesc)); + if (!olWire) + return BadLength; + ol = XkbAddGeomOutline(shape, olWire->nPoints); + if (!ol) + return BadAlloc; + ol->corner_radius = olWire->cornerRadius; + for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { + xkbPointWireDesc *ptWire; + + ptWire = (xkbPointWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbPointWireDesc)); + if (!ptWire) + return BadLength; + pt->x = ptWire->x; + pt->y = ptWire->y; + } + ol->num_points = olWire->nPoints; + } + if ((shapeWire->primaryNdx != XkbNoShape) && + (shapeWire->primaryNdx < shapeWire->nOutlines)) + shape->primary = &shape->outlines[shapeWire->primaryNdx]; + else + shape->primary = NULL; + if ((shapeWire->approxNdx != XkbNoShape) && + (shapeWire->approxNdx < shapeWire->nOutlines)) + shape->approx = &shape->outlines[shapeWire->approxNdx]; + else + shape->approx = NULL; + XkbComputeShapeBounds(shape); + } + return Success; +} + +static Status +_XkbReadGeomDoodad(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ + XkbDoodadPtr doodad; + xkbDoodadWireDesc *doodadWire; + + doodadWire = (xkbDoodadWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbDoodadWireDesc)); + if (!doodadWire) + return BadLength; + doodad = XkbAddGeomDoodad(geom, section, doodadWire->any.name); + if (!doodad) + return BadAlloc; + doodad->any.type = doodadWire->any.type; + doodad->any.priority = doodadWire->any.priority; + doodad->any.top = doodadWire->any.top; + doodad->any.left = doodadWire->any.left; + doodad->any.angle = doodadWire->any.angle; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodad->shape.color_ndx = doodadWire->shape.colorNdx; + doodad->shape.shape_ndx = doodadWire->shape.shapeNdx; + break; + case XkbTextDoodad: + doodad->text.width = doodadWire->text.width; + doodad->text.height = doodadWire->text.height; + doodad->text.color_ndx = doodadWire->text.colorNdx; + if (!_XkbGetReadBufferCountedString(buf, &doodad->text.text)) + return BadLength; + if (!_XkbGetReadBufferCountedString(buf, &doodad->text.font)) + return BadLength; + break; + case XkbIndicatorDoodad: + doodad->indicator.shape_ndx = doodadWire->indicator.shapeNdx; + doodad->indicator.on_color_ndx = doodadWire->indicator.onColorNdx; + doodad->indicator.off_color_ndx = doodadWire->indicator.offColorNdx; + break; + case XkbLogoDoodad: + doodad->logo.color_ndx = doodadWire->logo.colorNdx; + doodad->logo.shape_ndx = doodadWire->logo.shapeNdx; + if (!_XkbGetReadBufferCountedString(buf, &doodad->logo.logo_name)) + return BadLength; + break; + default: + return BadValue; + } + return Success; +} + +static Status +_XkbReadGeomOverlay(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + XkbSectionPtr section) +{ + XkbOverlayPtr ol; + xkbOverlayWireDesc *olWire; + register int r; + + olWire = (xkbOverlayWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbOverlayWireDesc)); + if (olWire == NULL) + return BadLength; + ol = XkbAddGeomOverlay(section, olWire->name, olWire->nRows); + if (ol == NULL) + return BadLength; + for (r = 0; r < olWire->nRows; r++) { + register int k; + XkbOverlayRowPtr row; + xkbOverlayRowWireDesc *rowWire; + xkbOverlayKeyWireDesc *keyWire; + + rowWire = (xkbOverlayRowWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbOverlayRowWireDesc)); + if (rowWire == NULL) + return BadLength; + row = XkbAddGeomOverlayRow(ol, rowWire->rowUnder, rowWire->nKeys); + if (!row) + return BadAlloc; + row->row_under = rowWire->rowUnder; + if (rowWire->nKeys < 1) + continue; + keyWire = (xkbOverlayKeyWireDesc *) + _XkbGetReadBufferPtr(buf, + SIZEOF(xkbOverlayKeyWireDesc) * rowWire->nKeys); + if (keyWire == NULL) + return BadLength; + for (k = 0; k < rowWire->nKeys; k++, keyWire++, row->num_keys++) { + memcpy(row->keys[row->num_keys].over.name, keyWire->over, + XkbKeyNameLength); + memcpy(row->keys[row->num_keys].under.name, keyWire->under, + XkbKeyNameLength); + } + } + return Success; +} + +static Status +_XkbReadGeomSections(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + register int s; + XkbSectionPtr section; + xkbSectionWireDesc *sectionWire; + Status rtrn; + + if (rep->nSections < 1) + return Success; + if ((rtrn = XkbAllocGeomSections(geom, rep->nSections)) != Success) + return rtrn; + for (s = 0; s < rep->nSections; s++) { + sectionWire = (xkbSectionWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbSectionWireDesc)); + if (!sectionWire) + return BadLength; + section = XkbAddGeomSection(geom, sectionWire->name, sectionWire->nRows, + sectionWire->nDoodads, + sectionWire->nOverlays); + if (!section) + return BadAlloc; + section->top = sectionWire->top; + section->left = sectionWire->left; + section->width = sectionWire->width; + section->height = sectionWire->height; + section->angle = sectionWire->angle; + section->priority = sectionWire->priority; + if (sectionWire->nRows > 0) { + register int r; + + for (r = 0; r < sectionWire->nRows; r++) { + XkbRowPtr row; + xkbRowWireDesc *rowWire; + + rowWire = (xkbRowWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbRowWireDesc)); + if (!rowWire) + return BadLength; + row = XkbAddGeomRow(section, rowWire->nKeys); + if (!row) + return BadAlloc; + row->top = rowWire->top; + row->left = rowWire->left; + row->vertical = rowWire->vertical; + if (rowWire->nKeys > 0) { + register int k; + + for (k = 0; k < rowWire->nKeys; k++) { + XkbKeyPtr key; + xkbKeyWireDesc *keyWire; + + keyWire = (xkbKeyWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyWireDesc)); + if (!keyWire) + return BadLength; + key = XkbAddGeomKey(row); + if (!key) + return BadAlloc; + memcpy(key->name.name, keyWire->name, XkbKeyNameLength); + key->gap = keyWire->gap; + key->shape_ndx = keyWire->shapeNdx; + key->color_ndx = keyWire->colorNdx; + } + } + } + } + if (sectionWire->nDoodads > 0) { + register int d; + + for (d = 0; d < sectionWire->nDoodads; d++) { + if ((rtrn = _XkbReadGeomDoodad(buf, geom, section)) != Success) + return rtrn; + } + } + if (sectionWire->nOverlays > 0) { + register int o; + + for (o = 0; o < sectionWire->nOverlays; o++) { + if ((rtrn = _XkbReadGeomOverlay(buf, geom, section)) != Success) + return rtrn; + } + } + } + return Success; +} + +static Status +_XkbReadGeomDoodads(XkbReadBufferPtr buf, + XkbGeometryPtr geom, + xkbGetGeometryReply *rep) +{ + register int d; + Status rtrn; + + if (rep->nDoodads < 1) + return Success; + if ((rtrn = XkbAllocGeomDoodads(geom, rep->nDoodads)) != Success) + return rtrn; + for (d = 0; d < rep->nDoodads; d++) { + if ((rtrn = _XkbReadGeomDoodad(buf, geom, NULL)) != Success) + return rtrn; + } + return Success; +} + +Status +_XkbReadGetGeometryReply(Display *dpy, + xkbGetGeometryReply *rep, + XkbDescPtr xkb, + int *nread_rtrn) +{ + XkbGeometryPtr geom; + + geom = _XkbTypedCalloc(1, XkbGeometryRec); + if (!geom) + return BadAlloc; + if (xkb->geom) + XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); + xkb->geom = geom; + + geom->name = rep->name; + geom->width_mm = rep->widthMM; + geom->height_mm = rep->heightMM; + if (rep->length) { + XkbReadBufferRec buf; + int left; + + if (_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) { + Status status = Success; + + if (nread_rtrn) + *nread_rtrn = (int) rep->length * 4; + if (!_XkbGetReadBufferCountedString(&buf, &geom->label_font)) + status = BadLength; + if (status == Success) + status = _XkbReadGeomProperties(&buf, geom, rep); + if (status == Success) + status = _XkbReadGeomColors(&buf, geom, rep); + if (status == Success) + status = _XkbReadGeomShapes(&buf, geom, rep); + if (status == Success) + status = _XkbReadGeomSections(&buf, geom, rep); + if (status == Success) + status = _XkbReadGeomDoodads(&buf, geom, rep); + if (status == Success) + status = _XkbReadGeomKeyAliases(&buf, geom, rep); + left = _XkbFreeReadBuffer(&buf); + if ((rep->baseColorNdx > geom->num_colors) || + (rep->labelColorNdx > geom->num_colors)) + status = BadLength; + if ((status != Success) || left || buf.error) { + if (status == Success) + status = BadLength; + XkbFreeGeometry(geom, XkbGeomAllMask, True); + xkb->geom = NULL; + return status; + } + geom->base_color = &geom->colors[rep->baseColorNdx]; + geom->label_color = &geom->colors[rep->labelColorNdx]; + } + else { + XkbFreeGeometry(geom, XkbGeomAllMask, True); + xkb->geom = NULL; + return BadAlloc; + } + } + return Success; +} + +Status +XkbGetGeometry(Display *dpy, XkbDescPtr xkb) +{ + xkbGetGeometryReq *req; + xkbGetGeometryReply rep; + Status status; + + if ((!xkb) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + LockDisplay(dpy); + GetReq(kbGetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetGeometry; + req->deviceSpec = xkb->device_spec; + req->name = None; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) + status = BadImplementation; + else if (!rep.found) + status = BadName; + else + status = _XkbReadGetGeometryReply(dpy, &rep, xkb, NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetNamedGeometry(Display *dpy, XkbDescPtr xkb, Atom name) +{ + xkbGetGeometryReq *req; + xkbGetGeometryReply rep; + Status status; + + if ((name == None) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + LockDisplay(dpy); + GetReq(kbGetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetGeometry; + req->deviceSpec = xkb->device_spec; + req->name = (CARD32) name; + if ((!_XReply(dpy, (xReply *) &rep, 0, xFalse)) || (!rep.found)) + status = BadImplementation; + else if (!rep.found) + status = BadName; + else + status = _XkbReadGetGeometryReply(dpy, &rep, xkb, NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} diff --git a/nx-X11/lib/src/xkb/XKBGetByName.c b/nx-X11/lib/src/xkb/XKBGetByName.c new file mode 100644 index 000000000..c673781ed --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBGetByName.c @@ -0,0 +1,226 @@ +/************************************************************ +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. + +********************************************************/ + +#define NEED_MAP_READERS +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +/***====================================================================***/ + +XkbDescPtr +XkbGetKeyboardByName(Display *dpy, + unsigned deviceSpec, + XkbComponentNamesPtr names, + unsigned want, + unsigned need, + Bool load) +{ + register xkbGetKbdByNameReq *req; + xkbGetKbdByNameReply rep; + int len, extraLen = 0; + char *str; + XkbDescPtr xkb; + int mapLen, codesLen, typesLen, compatLen; + int symsLen, geomLen; + XkbInfoPtr xkbi; + + if ((dpy == NULL) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return NULL; + + xkbi = dpy->xkb_info; + xkb = (XkbDescRec *) _XkbCalloc(1, sizeof(XkbDescRec)); + if (!xkb) + return NULL; + xkb->device_spec = deviceSpec; + xkb->map = (XkbClientMapRec *) _XkbCalloc(1, sizeof(XkbClientMapRec)); + xkb->dpy = dpy; + + LockDisplay(dpy); + GetReq(kbGetKbdByName, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetKbdByName; + req->deviceSpec = xkb->device_spec; + req->want = want; + req->need = need; + req->load = load; + + mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; + if (names) { + if (names->keymap) + mapLen = (int) strlen(names->keymap); + if (names->keycodes) + codesLen = (int) strlen(names->keycodes); + if (names->types) + typesLen = (int) strlen(names->types); + if (names->compat) + compatLen = (int) strlen(names->compat); + if (names->symbols) + symsLen = (int) strlen(names->symbols); + if (names->geometry) + geomLen = (int) strlen(names->geometry); + if (mapLen > 255) + mapLen = 255; + if (codesLen > 255) + codesLen = 255; + if (typesLen > 255) + typesLen = 255; + if (compatLen > 255) + compatLen = 255; + if (symsLen > 255) + symsLen = 255; + if (geomLen > 255) + geomLen = 255; + } + else + mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; + + len = mapLen + codesLen + typesLen + compatLen + symsLen + geomLen + 6; + len = XkbPaddedSize(len); + req->length += len / 4; + BufAlloc(char *, str, len); + + *str++ = mapLen; + if (mapLen > 0) { + memcpy(str, names->keymap, mapLen); + str += mapLen; + } + *str++ = codesLen; + if (codesLen > 0) { + memcpy(str, names->keycodes, codesLen); + str += codesLen; + } + *str++ = typesLen; + if (typesLen > 0) { + memcpy(str, names->types, typesLen); + str += typesLen; + } + *str++ = compatLen; + if (compatLen > 0) { + memcpy(str, names->compat, compatLen); + str += compatLen; + } + *str++ = symsLen; + if (symsLen > 0) { + memcpy(str, names->symbols, symsLen); + str += symsLen; + } + *str++ = geomLen; + if (geomLen > 0) { + memcpy(str, names->geometry, geomLen); + str += geomLen; + } + if ((!_XReply(dpy, (xReply *) &rep, 0, xFalse)) || (!rep.reported)) + goto BAILOUT; + extraLen = (int) rep.length * 4; + + xkb->device_spec = rep.deviceID; + xkb->min_key_code = rep.minKeyCode; + xkb->max_key_code = rep.maxKeyCode; + if (rep.reported & (XkbGBN_SymbolsMask | XkbGBN_TypesMask)) { + xkbGetMapReply mrep; + Status status; + int nread = 0; + + _XRead(dpy, (char *) &mrep, SIZEOF(xkbGetMapReply)); + extraLen -= SIZEOF(xkbGetMapReply); + status = _XkbReadGetMapReply(dpy, &mrep, xkb, &nread); + extraLen -= nread; + if (status != Success) + goto BAILOUT; + } + if (rep.reported & XkbGBN_CompatMapMask) { + xkbGetCompatMapReply crep; + Status status; + int nread = 0; + + _XRead(dpy, (char *) &crep, SIZEOF(xkbGetCompatMapReply)); + extraLen -= SIZEOF(xkbGetCompatMapReply); + status = _XkbReadGetCompatMapReply(dpy, &crep, xkb, &nread); + extraLen -= nread; + if (status != Success) + goto BAILOUT; + } + if (rep.reported & XkbGBN_IndicatorMapMask) { + xkbGetIndicatorMapReply irep; + Status status; + int nread = 0; + + _XRead(dpy, (char *) &irep, SIZEOF(xkbGetIndicatorMapReply)); + extraLen -= SIZEOF(xkbGetIndicatorMapReply); + status = _XkbReadGetIndicatorMapReply(dpy, &irep, xkb, &nread); + extraLen -= nread; + if (status != Success) + goto BAILOUT; + } + if (rep.reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask)) { + xkbGetNamesReply nrep; + Status status; + int nread = 0; + + _XRead(dpy, (char *) &nrep, SIZEOF(xkbGetNamesReply)); + extraLen -= SIZEOF(xkbGetNamesReply); + status = _XkbReadGetNamesReply(dpy, &nrep, xkb, &nread); + extraLen -= nread; + if (status != Success) + goto BAILOUT; + } + if (rep.reported & XkbGBN_GeometryMask) { + xkbGetGeometryReply grep; + Status status; + int nread = 0; + + _XRead(dpy, (char *) &grep, SIZEOF(xkbGetGeometryReply)); + extraLen -= SIZEOF(xkbGetGeometryReply); + status = _XkbReadGetGeometryReply(dpy, &grep, xkb, &nread); + extraLen -= nread; + if (status != Success) + goto BAILOUT; + } + if (extraLen > 0) + goto BAILOUT; + UnlockDisplay(dpy); + SyncHandle(); + return xkb; + BAILOUT: + if (xkb != NULL) + XkbFreeKeyboard(xkb, XkbAllComponentsMask, xTrue); + if (extraLen > 0) + _XEatData(dpy, extraLen); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +XkbDescPtr +XkbGetKeyboard(Display *dpy, unsigned which, unsigned deviceSpec) +{ + return XkbGetKeyboardByName(dpy, deviceSpec, NULL, which, which, False); +} diff --git a/nx-X11/lib/src/xkb/XKBGetMap.c b/nx-X11/lib/src/xkb/XKBGetMap.c new file mode 100644 index 000000000..6e3c74343 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBGetMap.c @@ -0,0 +1,882 @@ +/************************************************************ +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. + +********************************************************/ + +#define NEED_MAP_READERS +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +static Status +_XkbReadKeyTypes(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) +{ + int i, n, lastMapCount; + XkbKeyTypePtr type; + + if (rep->nTypes > 0) { + n = rep->firstType + rep->nTypes; + if (xkb->map->num_types >= n) + n = xkb->map->num_types; + else if (XkbAllocClientMap(xkb, XkbKeyTypesMask, n) != Success) + return BadAlloc; + + type = &xkb->map->types[rep->firstType]; + for (i = 0; i < (int) rep->nTypes; i++, type++) { + xkbKeyTypeWireDesc *desc; + register int ndx; + + ndx = i + rep->firstType; + if (ndx >= xkb->map->num_types) + xkb->map->num_types = ndx + 1; + + desc = (xkbKeyTypeWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyTypeWireDesc)); + if (desc == NULL) + return BadLength; + + lastMapCount = type->map_count; + if (desc->nMapEntries > 0) { + if ((type->map == NULL) || + (desc->nMapEntries > type->map_count)) { + XkbKTMapEntryRec *prev_map = type->map; + + type->map = _XkbTypedRealloc(type->map, desc->nMapEntries, + XkbKTMapEntryRec); + if (type->map == NULL) { + _XkbFree(prev_map); + return BadAlloc; + } + } + } + else if (type->map != NULL) { + Xfree(type->map); + type->map_count = 0; + type->map = NULL; + } + + if (desc->preserve && (desc->nMapEntries > 0)) { + if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) { + XkbModsRec *prev_preserve = type->preserve; + + type->preserve = _XkbTypedRealloc(type->preserve, + desc->nMapEntries, + XkbModsRec); + if (type->preserve == NULL) { + _XkbFree(prev_preserve); + return BadAlloc; + } + } + } + else if (type->preserve != NULL) { + Xfree(type->preserve); + type->preserve = NULL; + } + + type->mods.mask = desc->mask; + type->mods.real_mods = desc->realMods; + type->mods.vmods = desc->virtualMods; + type->num_levels = desc->numLevels; + type->map_count = desc->nMapEntries; + if (desc->nMapEntries > 0) { + register xkbKTMapEntryWireDesc *wire; + register XkbKTMapEntryPtr entry; + register int size; + + size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc); + wire = + (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size); + if (wire == NULL) + return BadLength; + entry = type->map; + for (n = 0; n < type->map_count; n++, wire++, entry++) { + entry->active = wire->active; + entry->level = wire->level; + entry->mods.mask = wire->mask; + entry->mods.real_mods = wire->realMods; + entry->mods.vmods = wire->virtualMods; + } + + if (desc->preserve) { + register xkbModsWireDesc *pwire; + register XkbModsPtr preserve; + register int sz; + + sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc); + pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz); + if (pwire == NULL) + return BadLength; + preserve = type->preserve; + for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) { + preserve->mask = pwire->mask; + preserve->vmods = pwire->virtualMods; + preserve->real_mods = pwire->realMods; + } + } + } + } + } + return Success; +} + +static Status +_XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) +{ + register int i; + XkbClientMapPtr map; + int size = xkb->max_key_code + 1; + + if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size) + return BadLength; + + map = xkb->map; + if (map->key_sym_map == NULL) { + register int offset; + XkbSymMapPtr oldMap; + xkbSymMapWireDesc *newMap; + + map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec); + if (map->key_sym_map == NULL) + return BadAlloc; + if (map->syms == NULL) { + int sz; + + sz = (rep->totalSyms * 12) / 10; + sz = ((sz + (unsigned) 128) / 128) * 128; + map->syms = _XkbTypedCalloc(sz, KeySym); + if (map->syms == NULL) + return BadAlloc; + map->size_syms = sz; + } + offset = 1; + oldMap = &map->key_sym_map[rep->firstKeySym]; + for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { + newMap = (xkbSymMapWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); + if (newMap == NULL) + return BadLength; + oldMap->kt_index[0] = newMap->ktIndex[0]; + oldMap->kt_index[1] = newMap->ktIndex[1]; + oldMap->kt_index[2] = newMap->ktIndex[2]; + oldMap->kt_index[3] = newMap->ktIndex[3]; + oldMap->group_info = newMap->groupInfo; + oldMap->width = newMap->width; + oldMap->offset = offset; + if (offset + newMap->nSyms >= map->size_syms) { + register int sz; + KeySym *prev_syms = map->syms; + + sz = map->size_syms + 128; + map->syms = _XkbTypedRealloc(map->syms, sz, KeySym); + if (map->syms == NULL) { + _XkbFree(prev_syms); + map->size_syms = 0; + return BadAlloc; + } + map->size_syms = sz; + } + if (newMap->nSyms > 0) { + _XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], + newMap->nSyms); + offset += newMap->nSyms; + } + else { + map->syms[offset] = 0; + } + } + map->num_syms = offset; + } + else { + XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym]; + + for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { + xkbSymMapWireDesc *newMap; + KeySym *newSyms; + int tmp; + + newMap = (xkbSymMapWireDesc *) + _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); + if (newMap == NULL) + return BadLength; + + if (newMap->nSyms > 0) + tmp = newMap->nSyms; + else + tmp = 0; + + newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp); + if (newSyms == NULL) + return BadAlloc; + if (newMap->nSyms > 0) + _XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms); + else + newSyms[0] = NoSymbol; + oldMap->kt_index[0] = newMap->ktIndex[0]; + oldMap->kt_index[1] = newMap->ktIndex[1]; + oldMap->kt_index[2] = newMap->ktIndex[2]; + oldMap->kt_index[3] = newMap->ktIndex[3]; + oldMap->group_info = newMap->groupInfo; + oldMap->width = newMap->width; + } + } + return Success; +} + +static Status +_XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep) +{ + int i; + CARD8 numDescBuf[248]; + CARD8 *numDesc = NULL; + register int nKeyActs; + Status ret = Success; + + if ((nKeyActs = rep->nKeyActs) > 0) { + XkbSymMapPtr symMap; + + if (nKeyActs < sizeof numDescBuf) + numDesc = numDescBuf; + else + numDesc = Xmalloc(nKeyActs * sizeof(CARD8)); + + if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) { + ret = BadLength; + goto done; + } + i = XkbPaddedSize(nKeyActs) - nKeyActs; + if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) { + ret = BadLength; + goto done; + } + symMap = &info->map->key_sym_map[rep->firstKeyAct]; + for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) { + if (numDesc[i] == 0) { + if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { + ret = BadLength; + goto done; + } + info->server->key_acts[i + rep->firstKeyAct] = 0; + } + else { + XkbAction *newActs; + + /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ + /* either zero or XkbKeyNumSyms(info,key) */ + newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct, + numDesc[i]); + if (newActs == NULL) { + ret = BadAlloc; + goto done; + } + if (!_XkbCopyFromReadBuffer(buf, (char *) newActs, + (int) (numDesc[i] * sizeof(XkbAction)))) { + ret = BadLength; + goto done; + } + } + } + } + done: + if (numDesc != NULL && numDesc != numDescBuf) + Xfree(numDesc); + return ret; +} + +static Status +_XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) +{ + register int i; + + if (rep->totalKeyBehaviors > 0) { + int size = xkb->max_key_code + 1; + + if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) + return BadLength; + if (xkb->server->behaviors == NULL) { + xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior); + if (xkb->server->behaviors == NULL) + return BadAlloc; + } + else { + bzero(&xkb->server->behaviors[rep->firstKeyBehavior], + (rep->nKeyBehaviors * sizeof(XkbBehavior))); + } + for (i = 0; i < rep->totalKeyBehaviors; i++) { + xkbBehaviorWireDesc *wire; + + wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf, + SIZEOF(xkbBehaviorWireDesc)); + if (wire == NULL || wire->key >= size) + return BadLength; + xkb->server->behaviors[wire->key].type = wire->type; + xkb->server->behaviors[wire->key].data = wire->data; + } + } + return Success; +} + +static Status +_XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) +{ + if (rep->virtualMods) { + register int i, bit, nVMods; + register char *data; + + for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if (rep->virtualMods & bit) + nVMods++; + } + data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods)); + if (data == NULL) + return BadLength; + for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0); + i++, bit <<= 1) { + if (rep->virtualMods & bit) { + xkb->server->vmods[i] = *data++; + nVMods--; + } + } + } + return Success; +} + +static Status +_XkbReadExplicitComponents(XkbReadBufferPtr buf, + XkbDescPtr xkb, + xkbGetMapReply *rep) +{ + register int i; + unsigned char *wire; + + if (rep->totalKeyExplicit > 0) { + int size = xkb->max_key_code + 1; + + if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) + return BadLength; + if (xkb->server->explicit == NULL) { + xkb->server->explicit = _XkbTypedCalloc(size, unsigned char); + + if (xkb->server->explicit == NULL) + return BadAlloc; + } + else { + bzero(&xkb->server->explicit[rep->firstKeyExplicit], + rep->nKeyExplicit); + } + i = XkbPaddedSize(2 * rep->totalKeyExplicit); + wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); + if (!wire) + return BadLength; + for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) { + if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) + return BadLength; + xkb->server->explicit[wire[0]] = wire[1]; + } + } + return Success; +} + +static Status +_XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) +{ + register int i; + unsigned char *wire; + + if (rep->totalModMapKeys > 0) { + if (((int) rep->firstModMapKey + rep->nModMapKeys) > + (xkb->max_key_code + 1)) + return BadLength; + if ((xkb->map->modmap == NULL) && + (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) { + return BadAlloc; + } + else { + bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys); + } + i = XkbPaddedSize(2 * rep->totalModMapKeys); + wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); + if (!wire) + return BadLength; + for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) { + if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) + return BadLength; + xkb->map->modmap[wire[0]] = wire[1]; + } + } + return Success; +} + +static Status +_XkbReadVirtualModMap(XkbReadBufferPtr buf, + XkbDescPtr xkb, + xkbGetMapReply *rep) +{ + register int i; + xkbVModMapWireDesc *wire; + XkbServerMapPtr srv; + + if (rep->totalVModMapKeys > 0) { + if (((int) rep->firstVModMapKey + rep->nVModMapKeys) + > xkb->max_key_code + 1) + return BadLength; + if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) && + (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) { + return BadAlloc; + } + else { + srv = xkb->server; + if (rep->nVModMapKeys > rep->firstVModMapKey) + bzero((char *) &srv->vmodmap[rep->firstVModMapKey], + (rep->nVModMapKeys - rep->firstVModMapKey) * + sizeof(unsigned short)); + } + srv = xkb->server; + i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); + wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i); + if (!wire) + return BadLength; + for (i = 0; i < rep->totalVModMapKeys; i++, wire++) { + if ((wire->key >= xkb->min_key_code) && + (wire->key <= xkb->max_key_code)) + srv->vmodmap[wire->key] = wire->vmods; + } + } + return Success; +} + +static xkbGetMapReq * +_XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb) +{ + xkbGetMapReq *req; + + GetReq(kbGetMap, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbGetMap; + req->deviceSpec = xkb->device_spec; + req->full = req->partial = 0; + req->firstType = req->nTypes = 0; + req->firstKeySym = req->nKeySyms = 0; + req->firstKeyAct = req->nKeyActs = 0; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + req->virtualMods = 0; + req->firstKeyExplicit = req->nKeyExplicit = 0; + req->firstModMapKey = req->nModMapKeys = 0; + req->firstVModMapKey = req->nVModMapKeys = 0; + return req; +} + +Status +_XkbReadGetMapReply(Display *dpy, + xkbGetMapReply *rep, + XkbDescPtr xkb, + int *nread_rtrn) +{ + int extraData; + unsigned mask; + + if (xkb->device_spec == XkbUseCoreKbd) + xkb->device_spec = rep->deviceID; + if (rep->maxKeyCode < rep->minKeyCode) + return BadImplementation; + xkb->min_key_code = rep->minKeyCode; + xkb->max_key_code = rep->maxKeyCode; + + if (!xkb->map) { + mask = rep->present & XkbAllClientInfoMask; + if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success)) + return BadAlloc; + } + if (!xkb->server) { + mask = rep->present & XkbAllServerInfoMask; + if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success)) + return BadAlloc; + } + extraData = (int) (rep->length * 4); + extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); + if (rep->length) { + XkbReadBufferRec buf; + int left; + + if (_XkbInitReadBuffer(dpy, &buf, extraData)) { + Status status = Success; + + if (nread_rtrn != NULL) + *nread_rtrn = extraData; + if (status == Success) + status = _XkbReadKeyTypes(&buf, xkb, rep); + if (status == Success) + status = _XkbReadKeySyms(&buf, xkb, rep); + if (status == Success) + status = _XkbReadKeyActions(&buf, xkb, rep); + if (status == Success) + status = _XkbReadKeyBehaviors(&buf, xkb, rep); + if (status == Success) + status = _XkbReadVirtualMods(&buf, xkb, rep); + if (status == Success) + status = _XkbReadExplicitComponents(&buf, xkb, rep); + if (status == Success) + status = _XkbReadModifierMap(&buf, xkb, rep); + if (status == Success) + status = _XkbReadVirtualModMap(&buf, xkb, rep); + left = _XkbFreeReadBuffer(&buf); + if (status != Success) + return status; + else if (left || buf.error) + return BadLength; + } + else + return BadAlloc; + } + return Success; +} + +static Status +_XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb) +{ + xkbGetMapReply rep; + + if (!_XReply(dpy, (xReply *) &rep, + ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2), + xFalse)) { + return BadImplementation; + } + return _XkbReadGetMapReply(dpy, &rep, xkb, NULL); +} + +Status +XkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb) +{ + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + if (which) { + register xkbGetMapReq *req; + Status status; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->full = which; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; + } + return Success; +} + +XkbDescPtr +XkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec) +{ + XkbDescPtr xkb; + + xkb = _XkbTypedCalloc(1, XkbDescRec); + if (xkb) { + xkb->device_spec = deviceSpec; + xkb->map = _XkbTypedCalloc(1, XkbClientMapRec); + if ((xkb->map == NULL) || + ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) { + if (xkb->map) { + Xfree(xkb->map); + xkb->map = NULL; + } + Xfree(xkb); + return NULL; + } + xkb->dpy = dpy; + } + return xkb; +} + +Status +XkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + if ((num < 1) || (num > XkbMaxKeyTypes)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstType = first; + req->nTypes = num; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyAct = first; + req->nKeyActs = num; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeySym = first; + req->nKeySyms = num; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + + return status; +} + +Status +XkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyBehavior = first; + req->nKeyBehaviors = num; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->virtualMods = which; + status = _XkbHandleGetMapReply(dpy, xkb); + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetKeyExplicitComponents(Display *dpy, + unsigned first, + unsigned num, + XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstKeyExplicit = first; + req->nKeyExplicit = num; + if ((xkb != NULL) && (xkb->server != NULL) && + (xkb->server->explicit != NULL)) { + if ((num > 0) && (first >= xkb->min_key_code) && + (first + num <= xkb->max_key_code)) + bzero(&xkb->server->explicit[first], num); + } + if (xkb) + status = _XkbHandleGetMapReply(dpy, xkb); + else + status = BadMatch; + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetKeyModifierMap(Display *dpy, + unsigned first, + unsigned num, + XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstModMapKey = first; + req->nModMapKeys = num; + if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { + if ((num > 0) && (first >= xkb->min_key_code) && + (first + num <= xkb->max_key_code)) + bzero(&xkb->map->modmap[first], num); + } + if (xkb) + status = _XkbHandleGetMapReply(dpy, xkb); + else + status = BadMatch; + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num, + XkbDescPtr xkb) +{ + register xkbGetMapReq *req; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + if ((num < 1) || (num > XkbMaxKeyCount)) + return BadValue; + + LockDisplay(dpy); + + req = _XkbGetGetMapReq(dpy, xkb); + req->firstVModMapKey = first; + req->nVModMapKeys = num; + if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { + if ((num > 0) && (first >= xkb->min_key_code) && + (first + num <= xkb->max_key_code)) + bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short)); + } + + if (xkb) + status = _XkbHandleGetMapReply(dpy, xkb); + else + status = BadMatch; + + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Status +XkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) +{ + xkbGetMapReq *req; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + LockDisplay(dpy); + if (changes->changed) { + Status status = Success; + + req = _XkbGetGetMapReq(dpy, xkb); + req->full = 0; + req->partial = changes->changed; + req->firstType = changes->first_type; + req->nTypes = changes->num_types; + req->firstKeySym = changes->first_key_sym; + req->nKeySyms = changes->num_key_syms; + req->firstKeyAct = changes->first_key_act; + req->nKeyActs = changes->num_key_acts; + req->firstKeyBehavior = changes->first_key_behavior; + req->nKeyBehaviors = changes->num_key_behaviors; + req->virtualMods = changes->vmods; + req->firstKeyExplicit = changes->first_key_explicit; + req->nKeyExplicit = changes->num_key_explicit; + req->firstModMapKey = changes->first_modmap_key; + req->nModMapKeys = changes->num_modmap_keys; + req->firstVModMapKey = changes->first_vmodmap_key; + req->nVModMapKeys = changes->num_vmodmap_keys; + status = _XkbHandleGetMapReply(dpy, xkb); + UnlockDisplay(dpy); + SyncHandle(); + return status; + } + UnlockDisplay(dpy); + return Success; +} diff --git a/nx-X11/lib/src/xkb/XKBList.c b/nx-X11/lib/src/xkb/XKBList.c new file mode 100644 index 000000000..d3d29e2a6 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBList.c @@ -0,0 +1,256 @@ +/************************************************************ +Copyright (c) 1995 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. + +********************************************************/ + +#define NEED_MAP_READERS +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +/***====================================================================***/ + +static void +_FreeComponentNames(int num, XkbComponentNamePtr names) +{ + int i; + XkbComponentNamePtr tmp; + + if ((num < 1) || (names == NULL)) + return; + for (i = 0, tmp = names; i < num; i++, tmp++) { + if (tmp->name) { + _XkbFree(tmp->name); + tmp->name = NULL; + } + } + _XkbFree(names); + return; +} + +/***====================================================================***/ + +static XkbComponentNamePtr +_ReadListing(XkbReadBufferPtr buf, int count, Status * status_rtrn) +{ + XkbComponentNamePtr first, this; + register int i; + CARD16 *flags; + int slen, wlen; + char *str; + + if (count < 1) + return NULL; + first = _XkbTypedCalloc(count, XkbComponentNameRec); + if (!first) + return NULL; + for (this = first, i = 0; i < count; i++, this++) { + flags = (CARD16 *) _XkbGetReadBufferPtr(buf, 2 * sizeof(CARD16)); + if (!flags) + goto BAILOUT; + this->flags = flags[0]; + slen = flags[1]; + wlen = ((slen + 1) / 2) * 2; /* pad to 2 byte boundary */ + this->name = _XkbTypedCalloc(slen + 1, char); + + if (!this->name) + goto BAILOUT; + str = (char *) _XkbGetReadBufferPtr(buf, wlen); + if (!str) + goto BAILOUT; + memcpy(this->name, str, slen); + } + return first; + BAILOUT: + *status_rtrn = BadAlloc; + _FreeComponentNames(i, first); + return NULL; +} + +/***====================================================================***/ + +XkbComponentListPtr +XkbListComponents(Display *dpy, + unsigned deviceSpec, + XkbComponentNamesPtr ptrns, + int *max_inout) +{ + register xkbListComponentsReq *req; + xkbListComponentsReply rep; + XkbInfoPtr xkbi; + XkbComponentListPtr list; + XkbReadBufferRec buf; + int left; + char *str; + int extraLen, len, mapLen, codesLen, typesLen, compatLen, symsLen, geomLen; + + if ((dpy == NULL) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || + (ptrns == NULL) || (max_inout == NULL)) + return NULL; + + xkbi = dpy->xkb_info; + LockDisplay(dpy); + GetReq(kbListComponents, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbListComponents; + req->deviceSpec = deviceSpec; + req->maxNames = *max_inout; + + mapLen = codesLen = typesLen = compatLen = symsLen = geomLen = 0; + if (ptrns->keymap) + mapLen = (int) strlen(ptrns->keymap); + if (ptrns->keycodes) + codesLen = (int) strlen(ptrns->keycodes); + if (ptrns->types) + typesLen = (int) strlen(ptrns->types); + if (ptrns->compat) + compatLen = (int) strlen(ptrns->compat); + if (ptrns->symbols) + symsLen = (int) strlen(ptrns->symbols); + if (ptrns->geometry) + geomLen = (int) strlen(ptrns->geometry); + if (mapLen > 255) + mapLen = 255; + if (codesLen > 255) + codesLen = 255; + if (typesLen > 255) + typesLen = 255; + if (compatLen > 255) + compatLen = 255; + if (symsLen > 255) + symsLen = 255; + if (geomLen > 255) + geomLen = 255; + + len = mapLen + codesLen + typesLen + compatLen + symsLen + geomLen + 6; + len = XkbPaddedSize(len); + req->length += len / 4; + BufAlloc(char *, str, len); + + *str++ = mapLen; + if (mapLen > 0) { + memcpy(str, ptrns->keymap, mapLen); + str += mapLen; + } + *str++ = codesLen; + if (codesLen > 0) { + memcpy(str, ptrns->keycodes, codesLen); + str += codesLen; + } + *str++ = typesLen; + if (typesLen > 0) { + memcpy(str, ptrns->types, typesLen); + str += typesLen; + } + *str++ = compatLen; + if (compatLen > 0) { + memcpy(str, ptrns->compat, compatLen); + str += compatLen; + } + *str++ = symsLen; + if (symsLen > 0) { + memcpy(str, ptrns->symbols, symsLen); + str += symsLen; + } + *str++ = geomLen; + if (geomLen > 0) { + memcpy(str, ptrns->geometry, geomLen); + str += geomLen; + } + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) + goto BAILOUT; + extraLen = (int) rep.length * 4; + *max_inout = rep.extra; + if (extraLen == 0) { /* no matches, but we don't want to report a failure */ + list = _XkbTypedCalloc(1, XkbComponentListRec); + UnlockDisplay(dpy); + SyncHandle(); + return list; + } + if (_XkbInitReadBuffer(dpy, &buf, extraLen)) { + Status status = Success; + + list = _XkbTypedCalloc(1, XkbComponentListRec); + if (!list) { + _XkbFreeReadBuffer(&buf); + goto BAILOUT; + } + list->num_keymaps = rep.nKeymaps; + list->num_keycodes = rep.nKeycodes; + list->num_types = rep.nTypes; + list->num_compat = rep.nCompatMaps; + list->num_symbols = rep.nSymbols; + list->num_geometry = rep.nGeometries; + if ((status == Success) && (list->num_keymaps > 0)) + list->keymaps = _ReadListing(&buf, list->num_keymaps, &status); + if ((status == Success) && (list->num_keycodes > 0)) + list->keycodes = _ReadListing(&buf, list->num_keycodes, &status); + if ((status == Success) && (list->num_types > 0)) + list->types = _ReadListing(&buf, list->num_types, &status); + if ((status == Success) && (list->num_compat > 0)) + list->compat = _ReadListing(&buf, list->num_compat, &status); + if ((status == Success) && (list->num_symbols > 0)) + list->symbols = _ReadListing(&buf, list->num_symbols, &status); + if ((status == Success) && (list->num_geometry > 0)) + list->geometry = _ReadListing(&buf, list->num_geometry, &status); + left = _XkbFreeReadBuffer(&buf); + if ((status != Success) || (buf.error) || (left > 2)) { + XkbFreeComponentList(list); + goto BAILOUT; + } + UnlockDisplay(dpy); + SyncHandle(); + return list; + } + BAILOUT: + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +void +XkbFreeComponentList(XkbComponentListPtr list) +{ + if (list) { + if (list->keymaps) + _FreeComponentNames(list->num_keymaps, list->keymaps); + if (list->keycodes) + _FreeComponentNames(list->num_keycodes, list->keycodes); + if (list->types) + _FreeComponentNames(list->num_types, list->types); + if (list->compat) + _FreeComponentNames(list->num_compat, list->compat); + if (list->symbols) + _FreeComponentNames(list->num_symbols, list->symbols); + if (list->geometry) + _FreeComponentNames(list->num_geometry, list->geometry); + bzero((char *) list, sizeof(XkbComponentListRec)); + _XkbFree(list); + } + return; +} diff --git a/nx-X11/lib/src/xkb/XKBMAlloc.c b/nx-X11/lib/src/xkb/XKBMAlloc.c new file mode 100644 index 000000000..2467a2024 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBMAlloc.c @@ -0,0 +1,1016 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + + +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include <nx-X11/keysym.h> +#include "XKBlibint.h" + + +/***====================================================================***/ + +Status +XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) +{ + register int i; + XkbClientMapPtr map; + + if ((xkb == NULL) || + ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes))) + return BadValue; + if ((which & XkbKeySymsMask) && + ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code))) { +#ifdef DEBUG + fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n", + xkb->min_key_code, xkb->max_key_code); +#endif + return BadValue; + } + + if (xkb->map == NULL) { + map = _XkbTypedCalloc(1, XkbClientMapRec); + if (map == NULL) + return BadAlloc; + xkb->map = map; + } + else + map = xkb->map; + + if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) { + if (map->types == NULL) { + map->types = _XkbTypedCalloc(nTotalTypes, XkbKeyTypeRec); + if (map->types == NULL) + return BadAlloc; + map->num_types = 0; + map->size_types = nTotalTypes; + } + else if (map->size_types < nTotalTypes) { + XkbKeyTypeRec *prev_types = map->types; + + map->types = + _XkbTypedRealloc(map->types, nTotalTypes, XkbKeyTypeRec); + if (map->types == NULL) { + _XkbFree(prev_types); + map->num_types = map->size_types = 0; + return BadAlloc; + } + map->size_types = nTotalTypes; + bzero(&map->types[map->num_types], + ((map->size_types - map->num_types) * sizeof(XkbKeyTypeRec))); + } + } + if (which & XkbKeySymsMask) { + int nKeys = XkbNumKeys(xkb); + + if (map->syms == NULL) { + map->size_syms = (nKeys * 15) / 10; + map->syms = _XkbTypedCalloc(map->size_syms, KeySym); + if (!map->syms) { + map->size_syms = 0; + return BadAlloc; + } + map->num_syms = 1; + map->syms[0] = NoSymbol; + } + if (map->key_sym_map == NULL) { + i = xkb->max_key_code + 1; + map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec); + if (map->key_sym_map == NULL) + return BadAlloc; + } + } + if (which & XkbModifierMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadMatch; + if (map->modmap == NULL) { + i = xkb->max_key_code + 1; + map->modmap = _XkbTypedCalloc(i, unsigned char); + if (map->modmap == NULL) + return BadAlloc; + } + } + return Success; +} + +Status +XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) +{ + register int i; + XkbServerMapPtr map; + + if (xkb == NULL) + return BadMatch; + if (xkb->server == NULL) { + map = _XkbTypedCalloc(1, XkbServerMapRec); + if (map == NULL) + return BadAlloc; + for (i = 0; i < XkbNumVirtualMods; i++) { + map->vmods[i] = XkbNoModifierMask; + } + xkb->server = map; + } + else + map = xkb->server; + if (which & XkbExplicitComponentsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadMatch; + if (map->explicit == NULL) { + i = xkb->max_key_code + 1; + map->explicit = _XkbTypedCalloc(i, unsigned char); + if (map->explicit == NULL) + return BadAlloc; + } + } + if (which & XkbKeyActionsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadMatch; + if (nNewActions < 1) + nNewActions = 1; + if (map->acts == NULL) { + map->acts = _XkbTypedCalloc((nNewActions + 1), XkbAction); + if (map->acts == NULL) + return BadAlloc; + map->num_acts = 1; + map->size_acts = nNewActions + 1; + } + else if ((map->size_acts - map->num_acts) < nNewActions) { + unsigned need; + XkbAction *prev_acts = map->acts; + + need = map->num_acts + nNewActions; + map->acts = _XkbTypedRealloc(map->acts, need, XkbAction); + if (map->acts == NULL) { + _XkbFree(prev_acts); + map->num_acts = map->size_acts = 0; + return BadAlloc; + } + map->size_acts = need; + bzero(&map->acts[map->num_acts], + ((map->size_acts - map->num_acts) * sizeof(XkbAction))); + } + if (map->key_acts == NULL) { + i = xkb->max_key_code + 1; + map->key_acts = _XkbTypedCalloc(i, unsigned short); + if (map->key_acts == NULL) + return BadAlloc; + } + } + if (which & XkbKeyBehaviorsMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadMatch; + if (map->behaviors == NULL) { + i = xkb->max_key_code + 1; + map->behaviors = _XkbTypedCalloc(i, XkbBehavior); + if (map->behaviors == NULL) + return BadAlloc; + } + } + if (which & XkbVirtualModMapMask) { + if ((!XkbIsLegalKeycode(xkb->min_key_code)) || + (!XkbIsLegalKeycode(xkb->max_key_code)) || + (xkb->max_key_code < xkb->min_key_code)) + return BadMatch; + if (map->vmodmap == NULL) { + i = xkb->max_key_code + 1; + map->vmodmap = _XkbTypedCalloc(i, unsigned short); + if (map->vmodmap == NULL) + return BadAlloc; + } + } + return Success; +} + +/***====================================================================***/ + +Status +XkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) +{ + if ((!from) || (!into)) + return BadMatch; + + _XkbFree(into->map); + into->map = NULL; + + _XkbFree(into->preserve); + into->preserve = NULL; + + _XkbFree(into->level_names); + into->level_names = NULL; + + *into = *from; + if ((from->map) && (into->map_count > 0)) { + into->map = _XkbTypedCalloc(into->map_count, XkbKTMapEntryRec); + if (!into->map) + return BadAlloc; + memcpy(into->map, from->map, + into->map_count * sizeof(XkbKTMapEntryRec)); + } + if ((from->preserve) && (into->map_count > 0)) { + into->preserve = _XkbTypedCalloc(into->map_count, XkbModsRec); + if (!into->preserve) + return BadAlloc; + memcpy(into->preserve, from->preserve, + into->map_count * sizeof(XkbModsRec)); + } + if ((from->level_names) && (into->num_levels > 0)) { + into->level_names = _XkbTypedCalloc(into->num_levels, Atom); + if (!into->level_names) + return BadAlloc; + memcpy(into->level_names, from->level_names, + into->num_levels * sizeof(Atom)); + } + return Success; +} + +Status +XkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) +{ + register int i, rtrn; + + if ((!from) || (!into) || (num_types < 0)) + return BadMatch; + for (i = 0; i < num_types; i++) { + if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) + return rtrn; + } + return Success; +} + +XkbKeyTypePtr +XkbAddKeyType(XkbDescPtr xkb, + Atom name, + int map_count, + Bool want_preserve, + int num_lvls) +{ + register int i; + unsigned tmp; + XkbKeyTypePtr type; + XkbClientMapPtr map; + + if ((!xkb) || (num_lvls < 1)) + return NULL; + map = xkb->map; + if ((map) && (map->types)) { + for (i = 0; i < map->num_types; i++) { + if (map->types[i].name == name) { + Status status = + XkbResizeKeyType(xkb, i, map_count, want_preserve, + num_lvls); + return (status == Success ? &map->types[i] : NULL); + } + } + } + if ((!map) || (!map->types) || (map->num_types < XkbNumRequiredTypes)) { + tmp = XkbNumRequiredTypes + 1; + if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success) + return NULL; + if (!map) + map = xkb->map; + tmp = 0; + if (map->num_types <= XkbKeypadIndex) + tmp |= XkbKeypadMask; + if (map->num_types <= XkbAlphabeticIndex) + tmp |= XkbAlphabeticMask; + if (map->num_types <= XkbTwoLevelIndex) + tmp |= XkbTwoLevelMask; + if (map->num_types <= XkbOneLevelIndex) + tmp |= XkbOneLevelMask; + if (XkbInitCanonicalKeyTypes(xkb, tmp, XkbNoModifier) == Success) { + for (i = 0; i < map->num_types; i++) { + Status status; + + if (map->types[i].name != name) + continue; + status = XkbResizeKeyType(xkb, i, map_count, want_preserve, + num_lvls); + return (status == Success ? &map->types[i] : NULL); + } + } + } + if ((map->num_types <= map->size_types) && + (XkbAllocClientMap(xkb, XkbKeyTypesMask, map->num_types + 1) != + Success)) { + return NULL; + } + type = &map->types[map->num_types]; + map->num_types++; + bzero((char *) type, sizeof(XkbKeyTypeRec)); + type->num_levels = num_lvls; + type->map_count = map_count; + type->name = name; + if (map_count > 0) { + type->map = _XkbTypedCalloc(map_count, XkbKTMapEntryRec); + if (!type->map) { + map->num_types--; + return NULL; + } + if (want_preserve) { + type->preserve = _XkbTypedCalloc(map_count, XkbModsRec); + if (!type->preserve) { + _XkbFree(type->map); + map->num_types--; + return NULL; + } + } + } + return type; +} + +Status +XkbResizeKeyType(XkbDescPtr xkb, + int type_ndx, + int map_count, + Bool want_preserve, + int new_num_lvls) +{ + XkbKeyTypePtr type; + KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; + + if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) + || (new_num_lvls < 1)) + return BadValue; + switch (type_ndx) { + case XkbOneLevelIndex: + if (new_num_lvls != 1) + return BadMatch; + break; + case XkbTwoLevelIndex: + case XkbAlphabeticIndex: + case XkbKeypadIndex: + if (new_num_lvls != 2) + return BadMatch; + break; + } + type = &xkb->map->types[type_ndx]; + if (map_count == 0) { + _XkbFree(type->map); + type->map = NULL; + _XkbFree(type->preserve); + type->preserve = NULL; + type->map_count = 0; + } + else { + XkbKTMapEntryRec *prev_map = type->map; + + if ((map_count > type->map_count) || (type->map == NULL)) + type->map = + _XkbTypedRealloc(type->map, map_count, XkbKTMapEntryRec); + if (!type->map) { + _XkbFree(prev_map); + return BadAlloc; + } + if (want_preserve) { + XkbModsRec *prev_preserve = type->preserve; + + if ((map_count > type->map_count) || (type->preserve == NULL)) { + type->preserve = _XkbTypedRealloc(type->preserve, map_count, + XkbModsRec); + } + if (!type->preserve) { + _XkbFree(prev_preserve); + return BadAlloc; + } + } + else { + _XkbFree(type->preserve); + type->preserve = NULL; + } + type->map_count = map_count; + } + + if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { + Atom *prev_level_names = type->level_names; + + type->level_names = + _XkbTypedRealloc(type->level_names, new_num_lvls, Atom); + if (!type->level_names) { + _XkbFree(prev_level_names); + return BadAlloc; + } + } + /* + * Here's the theory: + * If the width of the type changed, we might have to resize the symbol + * maps for any keys that use the type for one or more groups. This is + * expensive, so we'll try to cull out any keys that are obviously okay: + * In any case: + * - keys that have a group width <= the old width are okay (because + * they could not possibly have been associated with the old type) + * If the key type increased in size: + * - keys that already have a group width >= to the new width are okay + * + keys that have a group width >= the old width but < the new width + * might have to be enlarged. + * If the key type decreased in size: + * - keys that have a group width > the old width don't have to be + * resized (because they must have some other wider type associated + * with some group). + * + keys that have a group width == the old width might have to be + * shrunk. + * The possibilities marked with '+' require us to examine the key types + * associated with each group for the key. + */ + bzero(matchingKeys, XkbMaxKeyCount * sizeof(KeyCode)); + nMatchingKeys = 0; + if (new_num_lvls > type->num_levels) { + int nTotal; + KeySym *newSyms; + int width, match, nResize; + register int i, g, nSyms; + + nResize = 0; + for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { + width = XkbKeyGroupsWidth(xkb, i); + if (width < type->num_levels) + continue; + for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; + (g >= 0) && (!match); g--) { + if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { + matchingKeys[nMatchingKeys++] = i; + match = 1; + } + } + if ((!match) || (width >= new_num_lvls)) + nTotal += XkbKeyNumSyms(xkb, i); + else { + nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; + nResize++; + } + } + if (nResize > 0) { + int nextMatch; + + xkb->map->size_syms = (nTotal * 12) / 10; + newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); + if (newSyms == NULL) + return BadAlloc; + nextMatch = 0; + nSyms = 1; + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { + if (matchingKeys[nextMatch] == i) { + KeySym *pOld; + + nextMatch++; + width = XkbKeyGroupsWidth(xkb, i); + pOld = XkbKeySymsPtr(xkb, i); + for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { + memcpy(&newSyms[nSyms + (new_num_lvls * g)], + &pOld[width * g], width * sizeof(KeySym)); + } + xkb->map->key_sym_map[i].offset = nSyms; + nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; + } + else { + memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), + XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); + xkb->map->key_sym_map[i].offset = nSyms; + nSyms += XkbKeyNumSyms(xkb, i); + } + } + type->num_levels = new_num_lvls; + _XkbFree(xkb->map->syms); + xkb->map->syms = newSyms; + xkb->map->num_syms = nSyms; + return Success; + } + } + else if (new_num_lvls < type->num_levels) { + int width, match; + register int g, i; + + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { + width = XkbKeyGroupsWidth(xkb, i); + if (width < type->num_levels) + continue; + for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; + (g >= 0) && (!match); g--) { + if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { + matchingKeys[nMatchingKeys++] = i; + match = 1; + } + } + } + } + if (nMatchingKeys > 0) { + int key, firstClear; + register int i, g; + + if (new_num_lvls > type->num_levels) + firstClear = type->num_levels; + else + firstClear = new_num_lvls; + for (i = 0; i < nMatchingKeys; i++) { + KeySym *pSyms; + int width, nClear; + + key = matchingKeys[i]; + width = XkbKeyGroupsWidth(xkb, key); + nClear = width - firstClear; + pSyms = XkbKeySymsPtr(xkb, key); + for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { + if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { + if (nClear > 0) + bzero(&pSyms[g * width + firstClear], + nClear * sizeof(KeySym)); + } + } + } + } + type->num_levels = new_num_lvls; + return Success; +} + +KeySym * +XkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) +{ + register int i, nSyms, nKeySyms; + unsigned nOldSyms; + KeySym *newSyms; + + if (needed == 0) { + xkb->map->key_sym_map[key].offset = 0; + return xkb->map->syms; + } + nOldSyms = XkbKeyNumSyms(xkb, key); + if (nOldSyms >= (unsigned) needed) { + return XkbKeySymsPtr(xkb, key); + } + if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { + if (nOldSyms > 0) { + memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), + nOldSyms * sizeof(KeySym)); + } + if ((needed - nOldSyms) > 0) { + bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], + (needed - nOldSyms) * sizeof(KeySym)); + } + xkb->map->key_sym_map[key].offset = xkb->map->num_syms; + xkb->map->num_syms += needed; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; + } + xkb->map->size_syms += (needed > 32 ? needed : 32); + newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); + if (newSyms == NULL) + return NULL; + newSyms[0] = NoSymbol; + nSyms = 1; + for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { + int nCopy; + + nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); + if ((nKeySyms == 0) && (i != key)) + continue; + if (i == key) + nKeySyms = needed; + if (nCopy != 0) + memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), + nCopy * sizeof(KeySym)); + if (nKeySyms > nCopy) + bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); + xkb->map->key_sym_map[i].offset = nSyms; + nSyms += nKeySyms; + } + _XkbFree(xkb->map->syms); + xkb->map->syms = newSyms; + xkb->map->num_syms = nSyms; + return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; +} + +static unsigned +_ExtendRange(unsigned int old_flags, + unsigned int flag, + KeyCode newKC, + KeyCode *old_min, + unsigned char *old_num) +{ + if ((old_flags & flag) == 0) { + old_flags |= flag; + *old_min = newKC; + *old_num = 1; + } + else { + int last = (*old_min) + (*old_num) - 1; + + if (newKC < *old_min) { + *old_min = newKC; + *old_num = (last - newKC) + 1; + } + else if (newKC > last) { + *old_num = (newKC - (*old_min)) + 1; + } + } + return old_flags; +} + +Status +XkbChangeKeycodeRange(XkbDescPtr xkb, + int minKC, + int maxKC, + XkbChangesPtr changes) +{ + int tmp; + + if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) + return BadValue; + if (minKC > maxKC) + return BadMatch; + if (minKC < xkb->min_key_code) { + if (changes) + changes->map.min_key_code = minKC; + tmp = xkb->min_key_code - minKC; + if (xkb->map) { + if (xkb->map->key_sym_map) { + bzero((char *) &xkb->map->key_sym_map[minKC], + tmp * sizeof(XkbSymMapRec)); + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeySymsMask, minKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + bzero((char *) &xkb->map->modmap[minKC], tmp); + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbModifierMapMask, minKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + bzero((char *) &xkb->server->behaviors[minKC], + tmp * sizeof(XkbBehavior)); + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask, minKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + bzero((char *) &xkb->server->key_acts[minKC], + tmp * sizeof(unsigned short)); + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeyActionsMask, minKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + bzero((char *) &xkb->server->vmodmap[minKC], + tmp * sizeof(unsigned short)); + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbVirtualModMapMask, minKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names) && (xkb->names->keys)) { + bzero((char *) &xkb->names->keys[minKC], + tmp * sizeof(XkbKeyNameRec)); + if (changes) { + changes->names.changed = _ExtendRange(changes->names.changed, + XkbKeyNamesMask, minKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->min_key_code = minKC; + } + if (maxKC > xkb->max_key_code) { + if (changes) + changes->map.max_key_code = maxKC; + tmp = maxKC - xkb->max_key_code; + if (xkb->map) { + if (xkb->map->key_sym_map) { + XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; + + xkb->map->key_sym_map = _XkbTypedRealloc(xkb->map->key_sym_map, + (maxKC + 1), XkbSymMapRec); + if (!xkb->map->key_sym_map) { + _XkbFree(prev_key_sym_map); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->map->key_sym_map[xkb->max_key_code + 1], + tmp * sizeof(XkbSymMapRec)); +#else + bzero((char *) &xkb->map->key_sym_map[xkb->max_key_code], + tmp * sizeof(XkbSymMapRec)); +#endif + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeySymsMask, maxKC, + &changes->map.first_key_sym, + &changes->map.num_key_syms); + } + } + if (xkb->map->modmap) { + unsigned char *prev_modmap = xkb->map->modmap; + + xkb->map->modmap = _XkbTypedRealloc(xkb->map->modmap, + (maxKC + 1), unsigned char); + if (!xkb->map->modmap) { + _XkbFree(prev_modmap); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->map->modmap[xkb->max_key_code + 1], tmp); +#else + bzero((char *) &xkb->map->modmap[xkb->max_key_code], tmp); +#endif + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbModifierMapMask, maxKC, + &changes->map.first_modmap_key, + &changes->map.num_modmap_keys); + } + } + } + if (xkb->server) { + if (xkb->server->behaviors) { + XkbBehavior *prev_behaviors = xkb->server->behaviors; + + xkb->server->behaviors = + _XkbTypedRealloc(xkb->server->behaviors, (maxKC + 1), + XkbBehavior); + if (!xkb->server->behaviors) { + _XkbFree(prev_behaviors); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->server->behaviors[xkb->max_key_code + 1], + tmp * sizeof(XkbBehavior)); +#else + bzero((char *) &xkb->server->behaviors[xkb->max_key_code], + tmp * sizeof(XkbBehavior)); +#endif + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeyBehaviorsMask, maxKC, + &changes->map.first_key_behavior, + &changes->map.num_key_behaviors); + } + } + if (xkb->server->key_acts) { + unsigned short *prev_key_acts = xkb->server->key_acts; + + xkb->server->key_acts = _XkbTypedRealloc(xkb->server->key_acts, + (maxKC + 1), unsigned short); + if (!xkb->server->key_acts) { + _XkbFree(prev_key_acts); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->server->key_acts[xkb->max_key_code + 1], + tmp * sizeof(unsigned short)); +#else + bzero((char *) &xkb->server->key_acts[xkb->max_key_code], + tmp * sizeof(unsigned short)); +#endif + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbKeyActionsMask, maxKC, + &changes->map.first_key_act, + &changes->map.num_key_acts); + } + } + if (xkb->server->vmodmap) { + unsigned short *prev_vmodmap = xkb->server->vmodmap; + + xkb->server->vmodmap = _XkbTypedRealloc(xkb->server->vmodmap, + (maxKC + 1), unsigned short); + if (!xkb->server->vmodmap) { + _XkbFree(prev_vmodmap); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->server->vmodmap[xkb->max_key_code + 1], + tmp * sizeof(unsigned short)); +#else + bzero((char *) &xkb->server->vmodmap[xkb->max_key_code], + tmp * sizeof(unsigned short)); +#endif + if (changes) { + changes->map.changed = _ExtendRange(changes->map.changed, + XkbVirtualModMapMask, maxKC, + &changes->map.first_modmap_key, + &changes->map.num_vmodmap_keys); + } + } + } + if ((xkb->names) && (xkb->names->keys)) { + XkbKeyNameRec *prev_keys = xkb->names->keys; + + xkb->names->keys = _XkbTypedRealloc(xkb->names->keys, + (maxKC + 1), XkbKeyNameRec); + if (!xkb->names->keys) { + _XkbFree(prev_keys); + return BadAlloc; + } +#ifdef NXAGENT_SERVER + bzero((char *) &xkb->names->keys[xkb->max_key_code + 1], + tmp * sizeof(XkbKeyNameRec)); +#else + bzero((char *) &xkb->names->keys[xkb->max_key_code], + tmp * sizeof(XkbKeyNameRec)); +#endif + if (changes) { + changes->names.changed = _ExtendRange(changes->names.changed, + XkbKeyNamesMask, maxKC, + &changes->names.first_key, + &changes->names.num_keys); + } + } + xkb->max_key_code = maxKC; + } + return Success; +} + +XkbAction * +XkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) +{ + register int i, nActs; + XkbAction *newActs; + + if (needed == 0) { + xkb->server->key_acts[key] = 0; + return NULL; + } + if (XkbKeyHasActions(xkb, key) && + (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) + return XkbKeyActionsPtr(xkb, key); + if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { + xkb->server->key_acts[key] = xkb->server->num_acts; + xkb->server->num_acts += needed; + return &xkb->server->acts[xkb->server->key_acts[key]]; + } + xkb->server->size_acts = xkb->server->num_acts + needed + 8; + newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); + if (newActs == NULL) + return NULL; + newActs[0].type = XkbSA_NoAction; + nActs = 1; + for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { + int nKeyActs, nCopy; + + if ((xkb->server->key_acts[i] == 0) && (i != key)) + continue; + + nCopy = nKeyActs = XkbKeyNumActions(xkb, i); + if (i == key) { + nKeyActs = needed; + if (needed < nCopy) + nCopy = needed; + } + + if (nCopy > 0) + memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), + nCopy * sizeof(XkbAction)); + if (nCopy < nKeyActs) + bzero(&newActs[nActs + nCopy], + (nKeyActs - nCopy) * sizeof(XkbAction)); + xkb->server->key_acts[i] = nActs; + nActs += nKeyActs; + } + _XkbFree(xkb->server->acts); + xkb->server->acts = newActs; + xkb->server->num_acts = nActs; + return &xkb->server->acts[xkb->server->key_acts[key]]; +} + +void +XkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) +{ + XkbClientMapPtr map; + + if ((xkb == NULL) || (xkb->map == NULL)) + return; + if (freeMap) + what = XkbAllClientInfoMask; + map = xkb->map; + if (what & XkbKeyTypesMask) { + if (map->types != NULL) { + if (map->num_types > 0) { + register int i; + XkbKeyTypePtr type; + + for (i = 0, type = map->types; i < map->num_types; i++, type++) { + _XkbFree(type->map); + type->map = NULL; + + _XkbFree(type->preserve); + type->preserve = NULL; + + type->map_count = 0; + + _XkbFree(type->level_names); + type->level_names = NULL; + } + } + _XkbFree(map->types); + map->num_types = map->size_types = 0; + map->types = NULL; + } + } + if (what & XkbKeySymsMask) { + _XkbFree(map->key_sym_map); + map->key_sym_map = NULL; + + _XkbFree(map->syms); + map->size_syms = map->num_syms = 0; + map->syms = NULL; + } + if (what & XkbModifierMapMask) { + _XkbFree(map->modmap); + map->modmap = NULL; + } + if (freeMap) { + _XkbFree(xkb->map); + xkb->map = NULL; + } + return; +} + +void +XkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) +{ + XkbServerMapPtr map; + + if ((xkb == NULL) || (xkb->server == NULL)) + return; + if (freeMap) + what = XkbAllServerInfoMask; + map = xkb->server; + if (what & XkbExplicitComponentsMask) { + _XkbFree(map->explicit); + map->explicit = NULL; + } + if (what & XkbKeyActionsMask) { + _XkbFree(map->key_acts); + map->key_acts = NULL; + + _XkbFree(map->acts); + map->num_acts = map->size_acts = 0; + map->acts = NULL; + } + if (what & XkbKeyBehaviorsMask) { + _XkbFree(map->behaviors); + map->behaviors = NULL; + } + if (what & XkbVirtualModMapMask) { + _XkbFree(map->vmodmap); + map->vmodmap = NULL; + } + + if (freeMap) { + _XkbFree(xkb->server); + xkb->server = NULL; + } + return; +} diff --git a/nx-X11/lib/src/xkb/XKBMisc.c b/nx-X11/lib/src/xkb/XKBMisc.c new file mode 100644 index 000000000..ab48b6124 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBMisc.c @@ -0,0 +1,1021 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + + +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include <nx-X11/keysym.h> +#include "XKBlibint.h" + + +/***====================================================================***/ + +#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) +static XkbKTMapEntryRec map2Level[] = { + { True, ShiftMask, {1, ShiftMask, 0} } +}; + +static XkbKTMapEntryRec mapAlpha[] = { + { True, ShiftMask, {1, ShiftMask, 0} }, + { True, LockMask, {0, LockMask, 0} } +}; + +static XkbModsRec preAlpha[] = { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; + +#define NL_VMOD_MASK 0 +static XkbKTMapEntryRec mapKeypad[] = { + { True, ShiftMask, { 1, ShiftMask, 0 } }, + { False, 0, { 1, 0, NL_VMOD_MASK } } +}; + +static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { + { { 0, 0, 0 }, + 1, /* num_levels */ + 0, /* map_count */ + NULL, NULL, + None, NULL + }, + { { ShiftMask, ShiftMask, 0 }, + 2, /* num_levels */ + mapSize(map2Level), /* map_count */ + map2Level, NULL, + None, NULL + }, + { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, /* num_levels */ + mapSize(mapAlpha), /* map_count */ + mapAlpha, preAlpha, + None, NULL + }, + { { ShiftMask, ShiftMask, NL_VMOD_MASK }, + 2, /* num_levels */ + mapSize(mapKeypad), /* map_count */ + mapKeypad, NULL, + None, NULL + } +}; + +Status +XkbInitCanonicalKeyTypes(XkbDescPtr xkb, unsigned which, int keypadVMod) +{ + XkbClientMapPtr map; + XkbKeyTypePtr from, to; + Status rtrn; + + if (!xkb) + return BadMatch; + rtrn = XkbAllocClientMap(xkb, XkbKeyTypesMask, XkbNumRequiredTypes); + if (rtrn != Success) + return rtrn; + map = xkb->map; + if ((which & XkbAllRequiredTypes) == 0) + return Success; + rtrn = Success; + from = canonicalTypes; + to = map->types; + if (which & XkbOneLevelMask) + rtrn = XkbCopyKeyType(&from[XkbOneLevelIndex], &to[XkbOneLevelIndex]); + if ((which & XkbTwoLevelMask) && (rtrn == Success)) + rtrn = XkbCopyKeyType(&from[XkbTwoLevelIndex], &to[XkbTwoLevelIndex]); + if ((which & XkbAlphabeticMask) && (rtrn == Success)) + rtrn = + XkbCopyKeyType(&from[XkbAlphabeticIndex], &to[XkbAlphabeticIndex]); + if ((which & XkbKeypadMask) && (rtrn == Success)) { + XkbKeyTypePtr type; + + rtrn = XkbCopyKeyType(&from[XkbKeypadIndex], &to[XkbKeypadIndex]); + type = &to[XkbKeypadIndex]; + if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) && + (rtrn == Success)) { + type->mods.vmods = (1 << keypadVMod); + type->map[0].active = True; + type->map[0].mods.mask = ShiftMask; + type->map[0].mods.real_mods = ShiftMask; + type->map[0].mods.vmods = 0; + type->map[0].level = 1; + type->map[1].active = False; + type->map[1].mods.mask = 0; + type->map[1].mods.real_mods = 0; + type->map[1].mods.vmods = (1 << keypadVMod); + type->map[1].level = 1; + } + } + return Success; +} + +/***====================================================================***/ + +#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol) +#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l)) + +int +XkbKeyTypesForCoreSymbols(XkbDescPtr xkb, + int map_width, + KeySym *core_syms, + unsigned int protected, + int *types_inout, + KeySym *xkb_syms_rtrn) +{ + register int i; + unsigned int empty; + int nSyms[XkbNumKbdGroups]; + int nGroups, tmp, groupsWidth; + + /* Section 12.2 of the protocol describes this process in more detail */ + /* Step 1: find the # of symbols in the core mapping per group */ + groupsWidth = 2; + for (i = 0; i < XkbNumKbdGroups; i++) { + if ((protected & (1 << i)) && (types_inout[i] < xkb->map->num_types)) { + nSyms[i] = xkb->map->types[types_inout[i]].num_levels; + if (nSyms[i] > groupsWidth) + groupsWidth = nSyms[i]; + } + else { + types_inout[i] = XkbTwoLevelIndex; /* don't really know, yet */ + nSyms[i] = 2; + } + } + if (nSyms[XkbGroup1Index] < 2) + nSyms[XkbGroup1Index] = 2; + if (nSyms[XkbGroup2Index] < 2) + nSyms[XkbGroup2Index] = 2; + /* Step 2: Copy the symbols from the core ordering to XKB ordering */ + /* symbols in the core are in the order: */ + /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 0)] = CORE_SYM(0); + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 1)] = CORE_SYM(1); + for (i = 2; i < nSyms[XkbGroup1Index]; i++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, i)] = CORE_SYM(2 + i); + } + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 0)] = CORE_SYM(2); + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 1)] = CORE_SYM(3); + tmp = 2 + (nSyms[XkbGroup1Index] - 2); /* offset to extra group2 syms */ + for (i = 2; i < nSyms[XkbGroup2Index]; i++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, i)] = CORE_SYM(tmp + i); + } + tmp = nSyms[XkbGroup1Index] + nSyms[XkbGroup2Index]; + if ((tmp >= map_width) && + ((protected & (XkbExplicitKeyType3Mask | XkbExplicitKeyType4Mask)) == + 0)) { + nSyms[XkbGroup3Index] = 0; + nSyms[XkbGroup4Index] = 0; + nGroups = 2; + } + else { + nGroups = 3; + for (i = 0; i < nSyms[XkbGroup3Index]; i++, tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index, i)] = CORE_SYM(tmp); + } + if ((tmp < map_width) || (protected & XkbExplicitKeyType4Mask)) { + nGroups = 4; + for (i = 0; i < nSyms[XkbGroup4Index]; i++, tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index, i)] = CORE_SYM(tmp); + } + } + else { + nSyms[XkbGroup4Index] = 0; + } + } + /* steps 3&4: alphanumeric expansion, assign canonical types */ + empty = 0; + for (i = 0; i < nGroups; i++) { + KeySym *syms; + + syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)]; + if ((nSyms[i] > 1) && (syms[1] == NoSymbol) && (syms[0] != NoSymbol)) { + KeySym upper, lower; + + XConvertCase(syms[0], &lower, &upper); + if (upper != lower) { + xkb_syms_rtrn[XKB_OFFSET(i, 0)] = lower; + xkb_syms_rtrn[XKB_OFFSET(i, 1)] = upper; + if ((protected & (1 << i)) == 0) + types_inout[i] = XkbAlphabeticIndex; + } + else if ((protected & (1 << i)) == 0) { + types_inout[i] = XkbOneLevelIndex; + /* nSyms[i]= 1; */ + } + } + if (((protected & (1 << i)) == 0) && + (types_inout[i] == XkbTwoLevelIndex)) { + if (IsKeypadKey(syms[0]) || IsKeypadKey(syms[1])) + types_inout[i] = XkbKeypadIndex; + else { + KeySym upper, lower; + + XConvertCase(syms[0], &lower, &upper); + if ((syms[0] == lower) && (syms[1] == upper)) + types_inout[i] = XkbAlphabeticIndex; + } + } + if (syms[0] == NoSymbol) { + register int n; + Bool found; + + for (n = 1, found = False; (!found) && (n < nSyms[i]); n++) { + found = (syms[n] != NoSymbol); + } + if (!found) + empty |= (1 << i); + } + } + /* step 5: squoosh out empty groups */ + if (empty) { + for (i = nGroups - 1; i >= 0; i--) { + if (((empty & (1 << i)) == 0) || (protected & (1 << i))) + break; + nGroups--; + } + } + if (nGroups < 1) + return 0; + + /* step 6: replicate group 1 into group two, if necessary */ + if ((nGroups > 1) && + ((empty & (XkbGroup1Mask | XkbGroup2Mask)) == XkbGroup2Mask)) { + if ((protected & (XkbExplicitKeyType1Mask | XkbExplicitKeyType2Mask)) == + 0) { + nSyms[XkbGroup2Index] = nSyms[XkbGroup1Index]; + types_inout[XkbGroup2Index] = types_inout[XkbGroup1Index]; + memcpy((char *) &xkb_syms_rtrn[2], (char *) xkb_syms_rtrn, + 2 * sizeof(KeySym)); + } + else if (types_inout[XkbGroup1Index] == types_inout[XkbGroup2Index]) { + memcpy((char *) &xkb_syms_rtrn[nSyms[XkbGroup1Index]], + (char *) xkb_syms_rtrn, + nSyms[XkbGroup1Index] * sizeof(KeySym)); + } + } + + /* step 7: check for all groups identical or all width 1 */ + if (nGroups > 1) { + Bool sameType, allOneLevel; + + allOneLevel = (xkb->map->types[types_inout[0]].num_levels == 1); + for (i = 1, sameType = True; (allOneLevel || sameType) && (i < nGroups); + i++) { + sameType = (sameType && + (types_inout[i] == types_inout[XkbGroup1Index])); + if (allOneLevel) + allOneLevel = (xkb->map->types[types_inout[i]].num_levels == 1); + } + if ((sameType) && + (!(protected & + (XkbExplicitKeyTypesMask & ~XkbExplicitKeyType1Mask)))) { + register int s; + Bool identical; + + for (i = 1, identical = True; identical && (i < nGroups); i++) { + KeySym *syms; + + syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)]; + for (s = 0; identical && (s < nSyms[i]); s++) { + if (syms[s] != xkb_syms_rtrn[s]) + identical = False; + } + } + if (identical) + nGroups = 1; + } + if (allOneLevel && (nGroups > 1)) { + KeySym *syms; + + syms = &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; + nSyms[XkbGroup1Index] = 1; + for (i = 1; i < nGroups; i++) { + xkb_syms_rtrn[i] = syms[0]; + syms += nSyms[i]; + nSyms[i] = 1; + } + } + } + return nGroups; +} + +static XkbSymInterpretPtr +_XkbFindMatchingInterp(XkbDescPtr xkb, + KeySym sym, + unsigned int real_mods, + unsigned int level) +{ + register unsigned i; + XkbSymInterpretPtr interp, rtrn; + CARD8 mods; + + rtrn = NULL; + interp = xkb->compat->sym_interpret; + for (i = 0; i < xkb->compat->num_si; i++, interp++) { + if ((interp->sym == NoSymbol) || (sym == interp->sym)) { + int match; + + if ((level == 0) || ((interp->match & XkbSI_LevelOneOnly) == 0)) + mods = real_mods; + else + mods = 0; + switch (interp->match & XkbSI_OpMask) { + case XkbSI_NoneOf: + match = ((interp->mods & mods) == 0); + break; + case XkbSI_AnyOfOrNone: + match = ((mods == 0) || ((interp->mods & mods) != 0)); + break; + case XkbSI_AnyOf: + match = ((interp->mods & mods) != 0); + break; + case XkbSI_AllOf: + match = ((interp->mods & mods) == interp->mods); + break; + case XkbSI_Exactly: + match = (interp->mods == mods); + break; + default: + match = 0; + break; + } + if (match) { + if (interp->sym != NoSymbol) { + return interp; + } + else if (rtrn == NULL) { + rtrn = interp; + } + } + } + } + return rtrn; +} + +static void +_XkbAddKeyChange(KeyCode *pFirst, unsigned char *pNum, KeyCode newKey) +{ + KeyCode last; + + last = (*pFirst) + (*pNum); + if (newKey < *pFirst) { + *pFirst = newKey; + *pNum = (last - newKey) + 1; + } + else if (newKey > last) { + *pNum = (last - *pFirst) + 1; + } + return; +} + +static void +_XkbSetActionKeyMods(XkbDescPtr xkb, XkbAction *act, unsigned mods) +{ + unsigned tmp; + + switch (act->type) { + case XkbSA_SetMods: + case XkbSA_LatchMods: + case XkbSA_LockMods: + if (act->mods.flags & XkbSA_UseModMapMods) + act->mods.real_mods = act->mods.mask = mods; + if ((tmp = XkbModActionVMods(&act->mods)) != 0) { + XkbVirtualModsToReal(xkb, tmp, &tmp); + act->mods.mask |= tmp; + } + break; + case XkbSA_ISOLock: + if (act->iso.flags & XkbSA_UseModMapMods) + act->iso.real_mods = act->iso.mask = mods; + if ((tmp = XkbModActionVMods(&act->iso)) != 0) { + XkbVirtualModsToReal(xkb, tmp, &tmp); + act->iso.mask |= tmp; + } + break; + } + return; +} + +#define IBUF_SIZE 8 + +Bool +XkbApplyCompatMapToKey(XkbDescPtr xkb, KeyCode key, XkbChangesPtr changes) +{ + KeySym *syms; + unsigned char explicit, mods; + XkbSymInterpretPtr *interps, ibuf[IBUF_SIZE]; + int n, nSyms, found; + unsigned changed, tmp; + + if ((!xkb) || (!xkb->map) || (!xkb->map->key_sym_map) || + (!xkb->compat) || (!xkb->compat->sym_interpret) || + (key < xkb->min_key_code) || (key > xkb->max_key_code)) { + return False; + } + if (((!xkb->server) || (!xkb->server->key_acts)) && + (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 0) != Success)) { + return False; + } + changed = 0; /* keeps track of what has changed in _this_ call */ + explicit = xkb->server->explicit[key]; + if (explicit & XkbExplicitInterpretMask) /* nothing to do */ + return True; + mods = (xkb->map->modmap ? xkb->map->modmap[key] : 0); + nSyms = XkbKeyNumSyms(xkb, key); + syms = XkbKeySymsPtr(xkb, key); + if (nSyms > IBUF_SIZE) { + interps = _XkbTypedCalloc(nSyms, XkbSymInterpretPtr); + if (interps == NULL) { + interps = ibuf; + nSyms = IBUF_SIZE; + } + } + else { + interps = ibuf; + } + found = 0; + for (n = 0; n < nSyms; n++) { + unsigned level = (n % XkbKeyGroupsWidth(xkb, key)); + + interps[n] = NULL; + if (syms[n] != NoSymbol) { + interps[n] = _XkbFindMatchingInterp(xkb, syms[n], mods, level); + if (interps[n] && interps[n]->act.type != XkbSA_NoAction) + found++; + else + interps[n] = NULL; + } + } + /* 1/28/96 (ef) -- XXX! WORKING HERE */ + if (!found) { + if (xkb->server->key_acts[key] != 0) { + xkb->server->key_acts[key] = 0; + changed |= XkbKeyActionsMask; + } + } + else { + XkbAction *pActs; + unsigned int new_vmodmask; + + changed |= XkbKeyActionsMask; + pActs = XkbResizeKeyActions(xkb, key, nSyms); + if (!pActs) { + if (nSyms > IBUF_SIZE) + Xfree(interps); + return False; + } + new_vmodmask = 0; + for (n = 0; n < nSyms; n++) { + if (interps[n]) { + unsigned effMods; + + pActs[n] = *((XkbAction *) &interps[n]->act); + if ((n == 0) || ((interps[n]->match & XkbSI_LevelOneOnly) == 0)) { + effMods = mods; + if (interps[n]->virtual_mod != XkbNoModifier) + new_vmodmask |= (1 << interps[n]->virtual_mod); + } + else + effMods = 0; + _XkbSetActionKeyMods(xkb, &pActs[n], effMods); + } + else + pActs[n].type = XkbSA_NoAction; + } + if (((explicit & XkbExplicitVModMapMask) == 0) && + (xkb->server->vmodmap[key] != new_vmodmask)) { + changed |= XkbVirtualModMapMask; + xkb->server->vmodmap[key] = new_vmodmask; + } + if (interps[0]) { + if ((interps[0]->flags & XkbSI_LockingKey) && + ((explicit & XkbExplicitBehaviorMask) == 0)) { + xkb->server->behaviors[key].type = XkbKB_Lock; + changed |= XkbKeyBehaviorsMask; + } + if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) { + CARD8 old; + + old = xkb->ctrls->per_key_repeat[key / 8]; + if (interps[0]->flags & XkbSI_AutoRepeat) + xkb->ctrls->per_key_repeat[key / 8] |= (1 << (key % 8)); + else + xkb->ctrls->per_key_repeat[key / 8] &= ~(1 << (key % 8)); + if (changes && (old != xkb->ctrls->per_key_repeat[key / 8])) + changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask; + } + } + } + if ((!found) || (interps[0] == NULL)) { + if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) { + CARD8 old; + + old = xkb->ctrls->per_key_repeat[key / 8]; +#ifdef RETURN_SHOULD_REPEAT + if (*XkbKeySymsPtr(xkb, key) != XK_Return) +#endif + xkb->ctrls->per_key_repeat[key / 8] |= (1 << (key % 8)); + if (changes && (old != xkb->ctrls->per_key_repeat[key / 8])) + changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask; + } + if (((explicit & XkbExplicitBehaviorMask) == 0) && + (xkb->server->behaviors[key].type == XkbKB_Lock)) { + xkb->server->behaviors[key].type = XkbKB_Default; + changed |= XkbKeyBehaviorsMask; + } + } + if (changes) { + XkbMapChangesPtr mc; + + mc = &changes->map; + tmp = (changed & mc->changed); + if (tmp & XkbKeyActionsMask) + _XkbAddKeyChange(&mc->first_key_act, &mc->num_key_acts, key); + else if (changed & XkbKeyActionsMask) { + mc->changed |= XkbKeyActionsMask; + mc->first_key_act = key; + mc->num_key_acts = 1; + } + if (tmp & XkbKeyBehaviorsMask) { + _XkbAddKeyChange(&mc->first_key_behavior, &mc->num_key_behaviors, + key); + } + else if (changed & XkbKeyBehaviorsMask) { + mc->changed |= XkbKeyBehaviorsMask; + mc->first_key_behavior = key; + mc->num_key_behaviors = 1; + } + if (tmp & XkbVirtualModMapMask) + _XkbAddKeyChange(&mc->first_vmodmap_key, &mc->num_vmodmap_keys, + key); + else if (changed & XkbVirtualModMapMask) { + mc->changed |= XkbVirtualModMapMask; + mc->first_vmodmap_key = key; + mc->num_vmodmap_keys = 1; + } + mc->changed |= changed; + } + if (interps != ibuf) + _XkbFree(interps); + return True; +} + +Bool +XkbUpdateMapFromCore(XkbDescPtr xkb, + KeyCode first_key, + int num_keys, + int map_width, + KeySym *core_keysyms, + XkbChangesPtr changes) +{ + register int key, last_key; + KeySym *syms; + + syms = &core_keysyms[(first_key - xkb->min_key_code) * map_width]; + if (changes) { + if (changes->map.changed & XkbKeySymsMask) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms, first_key); + if (num_keys > 1) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms, + first_key + num_keys - 1); + } + } + else { + changes->map.changed |= XkbKeySymsMask; + changes->map.first_key_sym = first_key; + changes->map.num_key_syms = num_keys; + } + } + last_key = first_key + num_keys - 1; + for (key = first_key; key <= last_key; key++, syms += map_width) { + XkbMapChangesPtr mc; + unsigned explicit; + KeySym tsyms[XkbMaxSymsPerKey]; + int types[XkbNumKbdGroups]; + int nG; + + explicit = xkb->server->explicit[key] & XkbExplicitKeyTypesMask; + types[XkbGroup1Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup1Index); + types[XkbGroup2Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup2Index); + types[XkbGroup3Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup3Index); + types[XkbGroup4Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup4Index); + nG = XkbKeyTypesForCoreSymbols(xkb, map_width, syms, explicit, types, + tsyms); + if (changes) + mc = &changes->map; + else + mc = NULL; + XkbChangeTypesOfKey(xkb, key, nG, XkbAllGroupsMask, types, mc); + memcpy((char *) XkbKeySymsPtr(xkb, key), (char *) tsyms, + XkbKeyNumSyms(xkb, key) * sizeof(KeySym)); + XkbApplyCompatMapToKey(xkb, key, changes); + } + + if ((xkb->map->modmap != NULL) && (changes) && + (changes->map.changed & (XkbVirtualModMapMask | XkbModifierMapMask))) { + unsigned char newVMods[XkbNumVirtualMods]; + register unsigned bit, i; + unsigned present; + + bzero(newVMods, XkbNumVirtualMods); + present = 0; + for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { + if (xkb->server->vmodmap[key] == 0) + continue; + for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if (bit & xkb->server->vmodmap[key]) { + present |= bit; + newVMods[i] |= xkb->map->modmap[key]; + } + } + } + for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if ((bit & present) && (newVMods[i] != xkb->server->vmods[i])) { + changes->map.changed |= XkbVirtualModsMask; + changes->map.vmods |= bit; + xkb->server->vmods[i] = newVMods[i]; + } + } + } + if (changes && (changes->map.changed & XkbVirtualModsMask)) + XkbApplyVirtualModChanges(xkb, changes->map.vmods, changes); + return True; +} + +Status +XkbChangeTypesOfKey(XkbDescPtr xkb, + int key, + int nGroups, + unsigned groups, + int *newTypesIn, + XkbMapChangesPtr changes) +{ + XkbKeyTypePtr pOldType, pNewType; + register int i; + int width, nOldGroups, oldWidth, newTypes[XkbNumKbdGroups]; + + if ((!xkb) || (!XkbKeycodeInRange(xkb, key)) || (!xkb->map) || + (!xkb->map->types) || ((groups & XkbAllGroupsMask) == 0) || + (nGroups > XkbNumKbdGroups)) { + return BadMatch; + } + if (nGroups == 0) { + for (i = 0; i < XkbNumKbdGroups; i++) { + xkb->map->key_sym_map[key].kt_index[i] = XkbOneLevelIndex; + } + i = xkb->map->key_sym_map[key].group_info; + i = XkbSetNumGroups(i, 0); + xkb->map->key_sym_map[key].group_info = i; + XkbResizeKeySyms(xkb, key, 0); + return Success; + } + + nOldGroups = XkbKeyNumGroups(xkb, key); + oldWidth = XkbKeyGroupsWidth(xkb, key); + for (width = i = 0; i < nGroups; i++) { + if (groups & (1 << i)) + newTypes[i] = newTypesIn[i]; + else if (i < nOldGroups) + newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, i); + else if (nOldGroups > 0) + newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup1Index); + else + newTypes[i] = XkbTwoLevelIndex; + if (newTypes[i] > xkb->map->num_types) + return BadMatch; + pNewType = &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels > width) + width = pNewType->num_levels; + } + if ((xkb->ctrls) && (nGroups > xkb->ctrls->num_groups)) + xkb->ctrls->num_groups = nGroups; + if ((width != oldWidth) || (nGroups != nOldGroups)) { + KeySym oldSyms[XkbMaxSymsPerKey], *pSyms; + int nCopy; + + if (nOldGroups == 0) { + pSyms = XkbResizeKeySyms(xkb, key, width * nGroups); + if (pSyms != NULL) { + i = xkb->map->key_sym_map[key].group_info; + i = XkbSetNumGroups(i, nGroups); + xkb->map->key_sym_map[key].group_info = i; + xkb->map->key_sym_map[key].width = width; + for (i = 0; i < nGroups; i++) { + xkb->map->key_sym_map[key].kt_index[i] = newTypes[i]; + } + return Success; + } + return BadAlloc; + } + pSyms = XkbKeySymsPtr(xkb, key); + memcpy(oldSyms, pSyms, XkbKeyNumSyms(xkb, key) * sizeof(KeySym)); + pSyms = XkbResizeKeySyms(xkb, key, width * nGroups); + if (pSyms == NULL) + return BadAlloc; + bzero(pSyms, width * nGroups * sizeof(KeySym)); + for (i = 0; (i < nGroups) && (i < nOldGroups); i++) { + pOldType = XkbKeyKeyType(xkb, key, i); + pNewType = &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels > pOldType->num_levels) + nCopy = pOldType->num_levels; + else + nCopy = pNewType->num_levels; + memcpy(&pSyms[i * width], &oldSyms[i * oldWidth], + nCopy * sizeof(KeySym)); + } + if (XkbKeyHasActions(xkb, key)) { + XkbAction oldActs[XkbMaxSymsPerKey], *pActs; + + pActs = XkbKeyActionsPtr(xkb, key); + memcpy(oldActs, pActs, XkbKeyNumSyms(xkb, key) * sizeof(XkbAction)); + pActs = XkbResizeKeyActions(xkb, key, width * nGroups); + if (pActs == NULL) + return BadAlloc; + bzero(pActs, width * nGroups * sizeof(XkbAction)); + for (i = 0; (i < nGroups) && (i < nOldGroups); i++) { + pOldType = XkbKeyKeyType(xkb, key, i); + pNewType = &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels > pOldType->num_levels) + nCopy = pOldType->num_levels; + else + nCopy = pNewType->num_levels; + memcpy(&pActs[i * width], &oldActs[i * oldWidth], + nCopy * sizeof(XkbAction)); + } + } + i = xkb->map->key_sym_map[key].group_info; + i = XkbSetNumGroups(i, nGroups); + xkb->map->key_sym_map[key].group_info = i; + xkb->map->key_sym_map[key].width = width; + } + width = 0; + for (i = 0; i < nGroups; i++) { + xkb->map->key_sym_map[key].kt_index[i] = newTypes[i]; + if (xkb->map->types[newTypes[i]].num_levels > width) + width = xkb->map->types[newTypes[i]].num_levels; + } + xkb->map->key_sym_map[key].width = width; + if (changes != NULL) { + if (changes->changed & XkbKeySymsMask) { + _XkbAddKeyChange(&changes->first_key_sym, &changes->num_key_syms, + key); + } + else { + changes->changed |= XkbKeySymsMask; + changes->first_key_sym = key; + changes->num_key_syms = 1; + } + } + return Success; +} + +/***====================================================================***/ + +Bool +XkbVirtualModsToReal(XkbDescPtr xkb, unsigned virtual_mask, unsigned *mask_rtrn) +{ + register int i, bit; + register unsigned mask; + + if (xkb == NULL) + return False; + if (virtual_mask == 0) { + *mask_rtrn = 0; + return True; + } + if (xkb->server == NULL) + return False; + for (i = mask = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if (virtual_mask & bit) + mask |= xkb->server->vmods[i]; + } + *mask_rtrn = mask; + return True; +} + +/***====================================================================***/ + +Bool +XkbUpdateActionVirtualMods(XkbDescPtr xkb, XkbAction *act, unsigned changed) +{ + unsigned int tmp; + + switch (act->type) { + case XkbSA_SetMods: + case XkbSA_LatchMods: + case XkbSA_LockMods: + if (((tmp = XkbModActionVMods(&act->mods)) & changed) != 0) { + XkbVirtualModsToReal(xkb, tmp, &tmp); + act->mods.mask = act->mods.real_mods; + act->mods.mask |= tmp; + return True; + } + break; + case XkbSA_ISOLock: + if ((((tmp = XkbModActionVMods(&act->iso)) != 0) & changed) != 0) { + XkbVirtualModsToReal(xkb, tmp, &tmp); + act->iso.mask = act->iso.real_mods; + act->iso.mask |= tmp; + return True; + } + break; + } + return False; +} + +void +XkbUpdateKeyTypeVirtualMods(XkbDescPtr xkb, + XkbKeyTypePtr type, + unsigned int changed, + XkbChangesPtr changes) +{ + register unsigned int i; + unsigned int mask = 0; + + XkbVirtualModsToReal(xkb, type->mods.vmods, &mask); + type->mods.mask = type->mods.real_mods | mask; + if ((type->map_count > 0) && (type->mods.vmods != 0)) { + XkbKTMapEntryPtr entry; + + for (i = 0, entry = type->map; i < type->map_count; i++, entry++) { + if (entry->mods.vmods != 0) { + XkbVirtualModsToReal(xkb, entry->mods.vmods, &mask); + entry->mods.mask = entry->mods.real_mods | mask; + /* entry is active if vmods are bound */ + entry->active = (mask != 0); + } + else + entry->active = 1; + } + } + if (changes) { + int type_ndx; + + type_ndx = type - xkb->map->types; + if ((type_ndx < 0) || (type_ndx > xkb->map->num_types)) + return; + if (changes->map.changed & XkbKeyTypesMask) { + int last; + + last = changes->map.first_type + changes->map.num_types - 1; + if (type_ndx < changes->map.first_type) { + changes->map.first_type = type_ndx; + changes->map.num_types = (last - type_ndx) + 1; + } + else if (type_ndx > last) { + changes->map.num_types = + (type_ndx - changes->map.first_type) + 1; + } + } + else { + changes->map.changed |= XkbKeyTypesMask; + changes->map.first_type = type_ndx; + changes->map.num_types = 1; + } + } + return; +} + +Bool +XkbApplyVirtualModChanges(XkbDescPtr xkb, + unsigned changed, + XkbChangesPtr changes) +{ + register int i; + unsigned int checkState = 0; + + if ((!xkb) || (!xkb->map) || (changed == 0)) + return False; + for (i = 0; i < xkb->map->num_types; i++) { + if (xkb->map->types[i].mods.vmods & changed) + XkbUpdateKeyTypeVirtualMods(xkb, &xkb->map->types[i], changed, + changes); + } + if (changed & xkb->ctrls->internal.vmods) { + unsigned int newMask = 0; + + XkbVirtualModsToReal(xkb, xkb->ctrls->internal.vmods, &newMask); + newMask |= xkb->ctrls->internal.real_mods; + if (xkb->ctrls->internal.mask != newMask) { + xkb->ctrls->internal.mask = newMask; + if (changes) { + changes->ctrls.changed_ctrls |= XkbInternalModsMask; + checkState = True; + } + } + } + if (changed & xkb->ctrls->ignore_lock.vmods) { + unsigned int newMask = 0; + + XkbVirtualModsToReal(xkb, xkb->ctrls->ignore_lock.vmods, &newMask); + newMask |= xkb->ctrls->ignore_lock.real_mods; + if (xkb->ctrls->ignore_lock.mask != newMask) { + xkb->ctrls->ignore_lock.mask = newMask; + if (changes) { + changes->ctrls.changed_ctrls |= XkbIgnoreLockModsMask; + checkState = True; + } + } + } + if (xkb->indicators != NULL) { + XkbIndicatorMapPtr map; + + map = &xkb->indicators->maps[0]; + for (i = 0; i < XkbNumIndicators; i++, map++) { + if (map->mods.vmods & changed) { + unsigned int newMask = 0; + + XkbVirtualModsToReal(xkb, map->mods.vmods, &newMask); + newMask |= map->mods.real_mods; + if (newMask != map->mods.mask) { + map->mods.mask = newMask; + if (changes) { + changes->indicators.map_changes |= (1 << i); + checkState = True; + } + } + } + } + } + if (xkb->compat != NULL) { + XkbCompatMapPtr compat; + + compat = xkb->compat; + for (i = 0; i < XkbNumKbdGroups; i++) { + unsigned int newMask = 0; + + XkbVirtualModsToReal(xkb, compat->groups[i].vmods, &newMask); + newMask |= compat->groups[i].real_mods; + if (compat->groups[i].mask != newMask) { + compat->groups[i].mask = newMask; + if (changes) { + changes->compat.changed_groups |= (1 << i); + checkState = True; + } + } + } + } + if (xkb->map && xkb->server) { + int highChange = 0, lowChange = -1; + + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { + if (XkbKeyHasActions(xkb, i)) { + register XkbAction *pAct; + register int n; + + pAct = XkbKeyActionsPtr(xkb, i); + for (n = XkbKeyNumActions(xkb, i); n > 0; n--, pAct++) { + if ((pAct->type != XkbSA_NoAction) && + XkbUpdateActionVirtualMods(xkb, pAct, changed)) { + if (lowChange < 0) + lowChange = i; + highChange = i; + } + } + } + } + if (changes && (lowChange > 0)) { /* something changed */ + if (changes->map.changed & XkbKeyActionsMask) { + int last; + + if (changes->map.first_key_act < lowChange) + lowChange = changes->map.first_key_act; + last = + changes->map.first_key_act + changes->map.num_key_acts - 1; + if (last > highChange) + highChange = last; + } + changes->map.changed |= XkbKeyActionsMask; + changes->map.first_key_act = lowChange; + changes->map.num_key_acts = (highChange - lowChange) + 1; + } + } + return checkState; +} diff --git a/nx-X11/lib/src/xkb/XKBNames.c b/nx-X11/lib/src/xkb/XKBNames.c new file mode 100644 index 000000000..951fd1da8 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBNames.c @@ -0,0 +1,879 @@ +/************************************************************ +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. + +********************************************************/ + +#define NEED_MAP_READERS +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + + +static Status +_XkbReadAtoms(XkbReadBufferPtr buf, + Atom *atoms, + int maxAtoms, + CARD32 present) +{ + register int i, bit; + + for (i = 0, bit = 1; (i < maxAtoms) && (present); i++, bit <<= 1) { + if (present & bit) { + if (!_XkbReadBufferCopy32(buf, (long *) &atoms[i], 1)) + return BadLength; + present &= ~bit; + } + } + return Success; +} + +Status +_XkbReadGetNamesReply(Display *dpy, + xkbGetNamesReply *rep, + XkbDescPtr xkb, + int *nread_rtrn) +{ + int i, len; + XkbReadBufferRec buf; + register XkbNamesPtr names; + + if (xkb->device_spec == XkbUseCoreKbd) + xkb->device_spec = rep->deviceID; + + if ((xkb->names == NULL) && + (XkbAllocNames(xkb, rep->which, + rep->nRadioGroups, rep->nKeyAliases) != Success)) { + return BadAlloc; + } + names = xkb->names; + if (rep->length == 0) + return Success; + + if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) + return BadAlloc; + if (nread_rtrn) + *nread_rtrn = (int) rep->length * 4; + + if ((rep->which & XkbKeycodesNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->keycodes, 1))) + goto BAILOUT; + if ((rep->which & XkbGeometryNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->geometry, 1))) + goto BAILOUT; + if ((rep->which & XkbSymbolsNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->symbols, 1))) + goto BAILOUT; + if ((rep->which & XkbPhysSymbolsNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->phys_symbols, 1))) + goto BAILOUT; + if ((rep->which & XkbTypesNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->types, 1))) + goto BAILOUT; + if ((rep->which & XkbCompatNameMask) && + (!_XkbReadBufferCopy32(&buf, (long *) &names->compat, 1))) + goto BAILOUT; + + if (rep->which & XkbKeyTypeNamesMask) { + XkbClientMapPtr map = xkb->map; + XkbKeyTypePtr type; + + len = rep->nTypes * 4; + if (map != NULL) { + type = map->types; + for (i = 0; (i < map->num_types) && (i < rep->nTypes); i++, type++) { + if (!_XkbReadBufferCopy32(&buf, (long *) &type->name, 1)) + goto BAILOUT; + len -= 4; + } + } + if ((len > 0) && (!_XkbSkipReadBufferData(&buf, len))) + goto BAILOUT; + } + if (rep->which & XkbKTLevelNamesMask) { + CARD8 *nLevels; + XkbClientMapPtr map = xkb->map; + + nLevels = + (CARD8 *) _XkbGetReadBufferPtr(&buf, XkbPaddedSize(rep->nTypes)); + if (nLevels == NULL) + goto BAILOUT; + if (map != NULL) { + XkbKeyTypePtr type = map->types; + + for (i = 0; i < (int) rep->nTypes; i++, type++) { + if (i >= map->num_types) { + if (!_XkbSkipReadBufferData(&buf, nLevels[i] * 4)) + goto BAILOUT; + continue; + } + if ((nLevels[i] > 0) && (nLevels[i] != type->num_levels)) { + goto BAILOUT; + } + + Xfree(type->level_names); + if (nLevels[i] == 0) { + type->level_names = NULL; + continue; + } + type->level_names = _XkbTypedCalloc(nLevels[i], Atom); + if (type->level_names != NULL) { + if (!_XkbReadBufferCopy32(&buf, (long *) type->level_names, + nLevels[i])) + goto BAILOUT; + } + else { + _XkbSkipReadBufferData(&buf, nLevels[i] * 4); + } + } + } + else { + for (i = 0; i < (int) rep->nTypes; i++) { + _XkbSkipReadBufferData(&buf, nLevels[i] * 4); + } + } + } + if (rep->which & XkbIndicatorNamesMask) { + if (_XkbReadAtoms(&buf, names->indicators, XkbNumIndicators, + rep->indicators) != Success) + goto BAILOUT; + } + if (rep->which & XkbVirtualModNamesMask) { + if (_XkbReadAtoms(&buf, names->vmods, XkbNumVirtualMods, + (CARD32) rep->virtualMods) != Success) + goto BAILOUT; + } + if (rep->which & XkbGroupNamesMask) { + if (_XkbReadAtoms(&buf, names->groups, XkbNumKbdGroups, + (CARD32) rep->groupNames) != Success) + goto BAILOUT; + } + if (rep->which & XkbKeyNamesMask) { + if (names->keys == NULL) { + int nKeys; + + if (xkb->max_key_code == 0) { + xkb->min_key_code = rep->minKeyCode; + xkb->max_key_code = rep->maxKeyCode; + } + nKeys = xkb->max_key_code + 1; + names->keys = _XkbTypedCalloc(nKeys, XkbKeyNameRec); + } + if (((int) rep->firstKey + rep->nKeys) > xkb->max_key_code + 1) + goto BAILOUT; + if (names->keys != NULL) { + if (!_XkbCopyFromReadBuffer(&buf, + (char *) &names->keys[rep->firstKey], + rep->nKeys * XkbKeyNameLength)) + goto BAILOUT; + } + else + _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength); + } + if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) { + if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) != + Success) + goto BAILOUT; + if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases, + rep->nKeyAliases * XkbKeyNameLength * 2)) + goto BAILOUT; + } + if (rep->which & XkbRGNamesMask) { + if (rep->nRadioGroups > 0) { + Atom *rgNames; + + if (names->radio_groups == NULL) + names->radio_groups = _XkbTypedCalloc(rep->nRadioGroups, Atom); + else if (names->num_rg < rep->nRadioGroups) { + names->radio_groups = _XkbTypedRealloc(names->radio_groups, + rep->nRadioGroups, Atom); + } + rgNames = names->radio_groups; + if (!rgNames) { + goto BAILOUT; + } + if (!_XkbReadBufferCopy32 + (&buf, (long *) rgNames, rep->nRadioGroups)) + goto BAILOUT; + names->num_rg = rep->nRadioGroups; + } + else if (names->num_rg > 0) { + names->num_rg = 0; + Xfree(names->radio_groups); + } + } + len = _XkbFreeReadBuffer(&buf); + if (len != 0) + return BadLength; + else + return Success; + BAILOUT: + _XkbFreeReadBuffer(&buf); + return BadLength; +} + +Status +XkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb) +{ + register xkbGetNamesReq *req; + xkbGetNamesReply rep; + Status status; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (!xkb->names) { + xkb->names = _XkbTypedCalloc(1, XkbNamesRec); + if (!xkb->names) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + GetReq(kbGetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetNames; + req->deviceSpec = xkb->device_spec; + req->which = which; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadImplementation; + } + + status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +/***====================================================================***/ + +static int +_XkbCountBits(int nBitsMax, unsigned long mask) +{ + register unsigned long y, nBits; + + y = (mask >> 1) & 033333333333; + y = mask - y - ((y >> 1) & 033333333333); + nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); + + /* nBitsMax really means max+1 */ + return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); +} + +static CARD32 +_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) +{ + register unsigned int i, bit, nAtoms; + register CARD32 atomsPresent; + + for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { + if (atoms[i] != None) { + atomsPresent |= bit; + nAtoms++; + } + } + if (count) + *count = nAtoms; + return atomsPresent; +} + +static void +_XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms) +{ + register unsigned int i, bit; + + for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { + if (mask & bit) + Data32(dpy, &atoms[i], 4); + } + return; +} + +Bool +XkbSetNames(Display *dpy, + unsigned int which, + unsigned int firstType, + unsigned int nTypes, + XkbDescPtr xkb) +{ + register xkbSetNamesReq *req; + int nLvlNames = 0; + XkbInfoPtr xkbi; + XkbNamesPtr names; + unsigned firstLvlType, nLvlTypes; + int nVMods, nLEDs, nRG, nKA, nGroups; + int nKeys = 0, firstKey = 0, nAtoms; + CARD32 leds, vmods, groups; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!xkb) || (!xkb->names)) + return False; + firstLvlType = firstType; + nLvlTypes = nTypes; + if (nTypes < 1) + which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask); + else if (firstType <= XkbLastRequiredType) { + int adjust; + + adjust = XkbLastRequiredType - firstType + 1; + firstType += adjust; + nTypes -= adjust; + if (nTypes < 1) + which &= ~XkbKeyTypeNamesMask; + } + names = xkb->names; + if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { + register int i; + XkbKeyTypePtr type; + + if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || + (firstType + nTypes > xkb->map->num_types) || + (firstLvlType + nLvlTypes > xkb->map->num_types)) + return False; + if (which & XkbKTLevelNamesMask) { + type = &xkb->map->types[firstLvlType]; + for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { + if (type->level_names != NULL) + nLvlNames += type->num_levels; + } + } + } + + nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNames; + req->deviceSpec = xkb->device_spec; + req->firstType = firstType; + req->nTypes = nTypes; + req->firstKey = xkb->min_key_code; + req->nKeys = xkb->max_key_code - xkb->min_key_code + 1; + + if (which & XkbKeycodesNameMask) + nAtoms++; + if (which & XkbGeometryNameMask) + nAtoms++; + if (which & XkbSymbolsNameMask) + nAtoms++; + if (which & XkbPhysSymbolsNameMask) + nAtoms++; + if (which & XkbTypesNameMask) + nAtoms++; + if (which & XkbCompatNameMask) + nAtoms++; + if (which & XkbKeyTypeNamesMask) + nAtoms += nTypes; + if (which & XkbKTLevelNamesMask) { + req->firstKTLevel = firstLvlType; + req->nKTLevels = nLvlTypes; + req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ + nAtoms += nLvlNames; + } + else + req->firstKTLevel = req->nKTLevels = 0; + + if (which & XkbIndicatorNamesMask) { + req->indicators = leds = + _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs); + if (nLEDs > 0) + nAtoms += nLEDs; + else + which &= ~XkbIndicatorNamesMask; + } + else + req->indicators = leds = 0; + + if (which & XkbVirtualModNamesMask) { + vmods = req->virtualMods = (CARD16) + _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods); + if (nVMods > 0) + nAtoms += nVMods; + else + which &= ~XkbVirtualModNamesMask; + } + else + vmods = req->virtualMods = 0; + + if (which & XkbGroupNamesMask) { + groups = req->groupNames = (CARD8) + _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups); + if (nGroups > 0) + nAtoms += nGroups; + else + which &= ~XkbGroupNamesMask; + } + else + groups = req->groupNames = 0; + + if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { + firstKey = req->firstKey; + nKeys = req->nKeys; + nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ + } + else + which &= ~XkbKeyNamesMask; + + if (which & XkbKeyAliasesMask) { + nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); + if (nKA > 0) { + req->nKeyAliases = nKA; + nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ + } + else { + which &= ~XkbKeyAliasesMask; + req->nKeyAliases = 0; + } + } + else + req->nKeyAliases = 0; + + if (which & XkbRGNamesMask) { + nRG = names->num_rg; + if (nRG > 0) + nAtoms += nRG; + else + which &= ~XkbRGNamesMask; + } + + req->which = which; + req->nRadioGroups = nRG; + req->length += (nAtoms * 4) / 4; + + if (which & XkbKeycodesNameMask) + Data32(dpy, (long *) &names->keycodes, 4); + if (which & XkbGeometryNameMask) + Data32(dpy, (long *) &names->geometry, 4); + if (which & XkbSymbolsNameMask) + Data32(dpy, (long *) &names->symbols, 4); + if (which & XkbPhysSymbolsNameMask) + Data32(dpy, (long *) &names->phys_symbols, 4); + if (which & XkbTypesNameMask) + Data32(dpy, (long *) &names->types, 4); + if (which & XkbCompatNameMask) + Data32(dpy, (long *) &names->compat, 4); + if (which & XkbKeyTypeNamesMask) { + register int i; + register XkbKeyTypePtr type; + + type = &xkb->map->types[firstType]; + for (i = 0; i < nTypes; i++, type++) { + Data32(dpy, (long *) &type->name, 4); + } + } + if (which & XkbKTLevelNamesMask) { + XkbKeyTypePtr type; + int i; + char *tmp; + + BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); + type = &xkb->map->types[firstLvlType]; + for (i = 0; i < nLvlTypes; i++, type++) { + *tmp++ = type->num_levels; + } + type = &xkb->map->types[firstLvlType]; + for (i = 0; i < nLvlTypes; i++, type++) { + if (type->level_names != NULL) + Data32(dpy, (long *) type->level_names, type->num_levels * 4); + } + } + if (which & XkbIndicatorNamesMask) + _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); + if (which & XkbVirtualModNamesMask) + _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); + if (which & XkbGroupNamesMask) + _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); + if (which & XkbKeyNamesMask) { + Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); + } + if (which & XkbKeyAliasesMask) { + Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); + } + if (which & XkbRGNamesMask) { + Data32(dpy, (long *) names->radio_groups, nRG * 4); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes) +{ + register xkbSetNamesReq *req; + int nLvlNames = 0; + XkbInfoPtr xkbi; + XkbNamesPtr names; + unsigned which, firstType, nTypes; + unsigned firstLvlType, nLvlTypes; + int nVMods, nLEDs, nRG, nKA, nGroups; + int nKeys = 0, firstKey = 0, nAtoms; + CARD32 leds = 0, vmods = 0, groups = 0; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!xkb) || (!xkb->names) || (!changes)) + return False; + which = changes->changed; + firstType = changes->first_type; + nTypes = changes->num_types; + firstLvlType = changes->first_lvl; + nLvlTypes = changes->num_lvls; + if (which & XkbKeyTypeNamesMask) { + if (nTypes < 1) + which &= ~XkbKeyTypeNamesMask; + else if (firstType <= XkbLastRequiredType) { + int adjust; + + adjust = XkbLastRequiredType - firstType + 1; + firstType += adjust; + nTypes -= adjust; + if (nTypes < 1) + which &= ~XkbKeyTypeNamesMask; + } + } + else + firstType = nTypes = 0; + + if (which & XkbKTLevelNamesMask) { + if (nLvlTypes < 1) + which &= ~XkbKTLevelNamesMask; + } + else + firstLvlType = nLvlTypes = 0; + + names = xkb->names; + if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { + register int i; + + if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || + (firstType + nTypes > xkb->map->num_types) || + (firstLvlType + nLvlTypes > xkb->map->num_types)) + return False; + if (which & XkbKTLevelNamesMask) { + XkbKeyTypePtr type = &xkb->map->types[firstLvlType]; + + for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { + if (type->level_names != NULL) + nLvlNames += type->num_levels; + } + } + } + + if (changes->num_keys < 1) + which &= ~XkbKeyNamesMask; + if ((which & XkbKeyNamesMask) == 0) + changes->first_key = changes->num_keys = 0; + else if ((changes->first_key < xkb->min_key_code) || + (changes->first_key + changes->num_keys > xkb->max_key_code)) { + return False; + } + + if ((which & XkbVirtualModNamesMask) == 0) + changes->changed_vmods = 0; + else if (changes->changed_vmods == 0) + which &= ~XkbVirtualModNamesMask; + + if ((which & XkbIndicatorNamesMask) == 0) + changes->changed_indicators = 0; + else if (changes->changed_indicators == 0) + which &= ~XkbIndicatorNamesMask; + + if ((which & XkbGroupNamesMask) == 0) + changes->changed_groups = 0; + else if (changes->changed_groups == 0) + which &= ~XkbGroupNamesMask; + + nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNames, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNames; + req->deviceSpec = xkb->device_spec; + req->firstType = firstType; + req->nTypes = nTypes; + req->firstKey = changes->first_key; + req->nKeys = changes->num_keys; + + if (which & XkbKeycodesNameMask) + nAtoms++; + if (which & XkbGeometryNameMask) + nAtoms++; + if (which & XkbSymbolsNameMask) + nAtoms++; + if (which & XkbPhysSymbolsNameMask) + nAtoms++; + if (which & XkbTypesNameMask) + nAtoms++; + if (which & XkbCompatNameMask) + nAtoms++; + if (which & XkbKeyTypeNamesMask) + nAtoms += nTypes; + if (which & XkbKTLevelNamesMask) { + req->firstKTLevel = firstLvlType; + req->nKTLevels = nLvlTypes; + req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ + nAtoms += nLvlNames; + } + else + req->firstKTLevel = req->nKTLevels = 0; + + if (which & XkbIndicatorNamesMask) { + leds = req->indicators = (CARD32) changes->changed_indicators; + nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators); + if (nLEDs > 0) + nAtoms += nLEDs; + else + which &= ~XkbIndicatorNamesMask; + } + else + req->indicators = 0; + + if (which & XkbVirtualModNamesMask) { + vmods = req->virtualMods = changes->changed_vmods; + nVMods = _XkbCountBits(XkbNumVirtualMods, + (unsigned long) changes->changed_vmods); + if (nVMods > 0) + nAtoms += nVMods; + else + which &= ~XkbVirtualModNamesMask; + } + else + req->virtualMods = 0; + + if (which & XkbGroupNamesMask) { + groups = req->groupNames = changes->changed_groups; + nGroups = _XkbCountBits(XkbNumKbdGroups, + (unsigned long) changes->changed_groups); + if (nGroups > 0) + nAtoms += nGroups; + else + which &= ~XkbGroupNamesMask; + } + else + req->groupNames = 0; + + if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { + firstKey = req->firstKey; + nKeys = req->nKeys; + nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ + } + else + which &= ~XkbKeyNamesMask; + + if (which & XkbKeyAliasesMask) { + nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); + if (nKA > 0) + nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ + else + which &= ~XkbKeyAliasesMask; + } + + if (which & XkbRGNamesMask) { + nRG = names->num_rg; + if (nRG > 0) + nAtoms += nRG; + else + which &= ~XkbRGNamesMask; + } + + req->which = which; + req->nRadioGroups = nRG; + req->length += (nAtoms * 4) / 4; + + if (which & XkbKeycodesNameMask) + Data32(dpy, (long *) &names->keycodes, 4); + if (which & XkbGeometryNameMask) + Data32(dpy, (long *) &names->geometry, 4); + if (which & XkbSymbolsNameMask) + Data32(dpy, (long *) &names->symbols, 4); + if (which & XkbPhysSymbolsNameMask) + Data32(dpy, (long *) &names->phys_symbols, 4); + if (which & XkbTypesNameMask) + Data32(dpy, (long *) &names->types, 4); + if (which & XkbCompatNameMask) + Data32(dpy, (long *) &names->compat, 4); + if (which & XkbKeyTypeNamesMask) { + register int i; + register XkbKeyTypePtr type; + + type = &xkb->map->types[firstType]; + for (i = 0; i < nTypes; i++, type++) { + Data32(dpy, (long *) &type->name, 4); + } + } + if (which & XkbKTLevelNamesMask) { + XkbKeyTypePtr type; + int i; + char *tmp; + + BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); + type = &xkb->map->types[firstLvlType]; + for (i = 0; i < nLvlTypes; i++, type++) { + *tmp++ = type->num_levels; + } + type = &xkb->map->types[firstLvlType]; + for (i = 0; i < nLvlTypes; i++, type++) { + if (type->level_names != NULL) + Data32(dpy, (long *) type->level_names, type->num_levels * 4); + } + } + if (which & XkbIndicatorNamesMask) + _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); + if (which & XkbVirtualModNamesMask) + _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); + if (which & XkbGroupNamesMask) + _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); + if (which & XkbKeyNamesMask) { + Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); + } + if (which & XkbKeyAliasesMask) { + Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); + } + if (which & XkbRGNamesMask) { + Data32(dpy, (long *) names->radio_groups, nRG * 4); + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +void +XkbNoteNameChanges(XkbNameChangesPtr old, + XkbNamesNotifyEvent *new, + unsigned int wanted) +{ + int first, last, old_last, new_last; + + if ((old == NULL) || (new == NULL)) + return; + + wanted &= new->changed; + + if (wanted == 0) + return; + + if (wanted & XkbKeyTypeNamesMask) { + if (old->changed & XkbKeyTypeNamesMask) { + new_last = (new->first_type + new->num_types - 1); + old_last = (old->first_type + old->num_types - 1); + + if (new->first_type < old->first_type) + first = new->first_type; + else + first = old->first_type; + + if (old_last > new_last) + last = old_last; + else + last = new_last; + + old->first_type = first; + old->num_types = (last - first) + 1; + } + else { + old->first_type = new->first_type; + old->num_types = new->num_types; + } + } + if (wanted & XkbKTLevelNamesMask) { + if (old->changed & XkbKTLevelNamesMask) { + new_last = (new->first_lvl + new->num_lvls - 1); + old_last = (old->first_lvl + old->num_lvls - 1); + + if (new->first_lvl < old->first_lvl) + first = new->first_lvl; + else + first = old->first_lvl; + + if (old_last > new_last) + last = old_last; + else + last = new_last; + + old->first_lvl = first; + old->num_lvls = (last - first) + 1; + } + else { + old->first_lvl = new->first_lvl; + old->num_lvls = new->num_lvls; + } + } + if (wanted & XkbIndicatorNamesMask) { + if (old->changed & XkbIndicatorNamesMask) + old->changed_indicators |= new->changed_indicators; + else + old->changed_indicators = new->changed_indicators; + } + if (wanted & XkbKeyNamesMask) { + if (old->changed & XkbKeyNamesMask) { + new_last = (new->first_key + new->num_keys - 1); + old_last = (old->first_key + old->num_keys - 1); + + first = old->first_key; + + if (new->first_key < old->first_key) + first = new->first_key; + if (old_last > new_last) + new_last = old_last; + + old->first_key = first; + old->num_keys = (new_last - first) + 1; + } + else { + old->first_key = new->first_key; + old->num_keys = new->num_keys; + } + } + if (wanted & XkbVirtualModNamesMask) { + if (old->changed & XkbVirtualModNamesMask) + old->changed_vmods |= new->changed_vmods; + else + old->changed_vmods = new->changed_vmods; + } + if (wanted & XkbGroupNamesMask) { + if (old->changed & XkbGroupNamesMask) + old->changed_groups |= new->changed_groups; + else + old->changed_groups = new->changed_groups; + } + if (wanted & XkbRGNamesMask) + old->num_rg = new->num_radio_groups; + if (wanted & XkbKeyAliasesMask) + old->num_aliases = new->num_aliases; + old->changed |= wanted; + return; +} diff --git a/nx-X11/lib/src/xkb/XKBRdBuf.c b/nx-X11/lib/src/xkb/XKBRdBuf.c new file mode 100644 index 000000000..381f4c900 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBRdBuf.c @@ -0,0 +1,203 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include "XKBlibint.h" +#include <nx-X11/extensions/XKBproto.h> + +/***====================================================================***/ + +int +_XkbInitReadBuffer(Display *dpy, XkbReadBufferPtr buf, int size) +{ + if ((dpy != NULL) && (buf != NULL) && (size > 0)) { + buf->error = 0; + buf->size = size; + buf->start = buf->data = _XkbAlloc(size); + if (buf->start) { + _XRead(dpy, buf->start, size); + return 1; + } + } + return 0; +} + +#define _XkbReadBufferDataLeft(b) (((b)->size)-((b)->data-(b)->start)) + +int +_XkbSkipReadBufferData(XkbReadBufferPtr from, int size) +{ + if (size == 0) + return 1; + if ((from == NULL) || (from->error) || (size < 1) || + (_XkbReadBufferDataLeft(from) < size)) + return 0; + from->data += size; + return 1; +} + +int +_XkbCopyFromReadBuffer(XkbReadBufferPtr from, char *to, int size) +{ + if (size == 0) + return 1; + if ((from == NULL) || (from->error) || (to == NULL) || (size < 1) || + (_XkbReadBufferDataLeft(from) < size)) + return 0; + memcpy(to, from->data, size); + from->data += size; + return 1; +} + +#ifdef XKB_FORCE_INT_KEYSYM +int +_XkbReadCopyKeySyms(int *wire, KeySym * to, int num_words) +{ + while (num_words-- > 0) { + *to++ = *wire++; + } + return 1; +} + +int +_XkbReadBufferCopyKeySyms(XkbReadBufferPtr from, KeySym * to, int num_words) +{ + if ((unsigned) (num_words * 4) > _XkbReadBufferDataLeft(from)) + return 0; + _XkbReadCopyKeySyms((int *) from->data, to, num_words); + from->data += (4 * num_words); + return True; +} + +int +_XkbWriteCopyKeySyms(register KeySym * from, CARD32 *to, int len) +{ + while (len-- > 0) { + *to++ = (CARD32) *from++; + } + return True; +} +#endif + +#ifdef LONG64 +int +_XkbReadCopyData32(int *wire, long *to, int num_words) +{ + while (num_words-- > 0) { + *to++ = *wire++; + } + return 1; +} + +int +_XkbReadBufferCopy32(XkbReadBufferPtr from, long *to, int num_words) +{ + if ((unsigned) (num_words * 4) > _XkbReadBufferDataLeft(from)) + return 0; + _XkbReadCopyData32((int *) from->data, to, num_words); + from->data += (4 * num_words); + return True; +} + +int +_XkbWriteCopyData32(register unsigned long *from, CARD32 *to, int len) +{ + while (len-- > 0) { + *to++ = (CARD32) *from++; + } + return True; +} +#endif /* LONG64 */ + + +char * +_XkbPeekAtReadBuffer(XkbReadBufferPtr from, int size) +{ + if ((from == NULL) || (from->error) || (size < 1) || + (_XkbReadBufferDataLeft(from) < size)) + return NULL; + return from->data; +} + +char * +_XkbGetReadBufferPtr(XkbReadBufferPtr from, int size) +{ + char *ptr; + + if ((from == NULL) || (from->error) || (size < 1) || + (_XkbReadBufferDataLeft(from) < size)) + return NULL; + ptr = from->data; + from->data += size; + return ptr; +} + + +int +_XkbFreeReadBuffer(XkbReadBufferPtr buf) +{ + if ((buf != NULL) && (buf->start != NULL)) { + int left; + + left = (int) _XkbReadBufferDataLeft(buf); + + Xfree(buf->start); + buf->size = 0; + buf->start = buf->data = NULL; + return left; + } + return 0; +} + +Bool +_XkbGetReadBufferCountedString(XkbReadBufferPtr buf, char **rtrn) +{ + CARD16 len, *pLen; + int left; + char *str = NULL; + + if ((buf == NULL) || (buf->error) || + ((left = (int) _XkbReadBufferDataLeft(buf)) < 4)) + return False; + pLen = (CARD16 *) buf->data; + len = *pLen; + if (len > 0) { + if (XkbPaddedSize(len + 2) > left) + return False; + str = _XkbAlloc(len + 1); + if (str) { + memcpy(str, &buf->data[2], len); + str[len] = '\0'; + } + } + buf->data += XkbPaddedSize(len + 2); + *rtrn = str; + return True; +} diff --git a/nx-X11/lib/src/xkb/XKBSetGeom.c b/nx-X11/lib/src/xkb/XKBSetGeom.c new file mode 100644 index 000000000..ee254e0dc --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBSetGeom.c @@ -0,0 +1,478 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef DEBUG +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#endif + +#include "Xlibint.h" +#include "XKBlibint.h" +#include <nx-X11/extensions/XKBgeom.h> +#include <nx-X11/extensions/XKBproto.h> + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +/***====================================================================***/ + +#define _SizeCountedString(s) ((s)?XkbPaddedSize(2+strlen(s)):4) + +static char * +_WriteCountedString(char *wire, char *str) +{ + CARD16 len, *pLen; + + len = (str ? strlen(str) : 0); + pLen = (CARD16 *) wire; + *pLen = len; + if (len && str) + memcpy(&wire[2], str, len); + wire += XkbPaddedSize(len + 2); + return wire; +} + +static int +_SizeGeomProperties(XkbGeometryPtr geom) +{ + register int i, size; + XkbPropertyPtr prop; + + for (size = i = 0, prop = geom->properties; i < geom->num_properties; + i++, prop++) { + size += _SizeCountedString(prop->name); + size += _SizeCountedString(prop->value); + } + return size; +} + +static int +_SizeGeomColors(XkbGeometryPtr geom) +{ + register int i, size; + register XkbColorPtr color; + + for (i = size = 0, color = geom->colors; i < geom->num_colors; i++, color++) { + size += _SizeCountedString(color->spec); + } + return size; +} + +static int +_SizeGeomShapes(XkbGeometryPtr geom) +{ + register int i, size; + register XkbShapePtr shape; + + for (i = size = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { + register int n; + register XkbOutlinePtr ol; + + size += SIZEOF(xkbShapeWireDesc); + for (n = 0, ol = shape->outlines; n < shape->num_outlines; n++, ol++) { + size += SIZEOF(xkbOutlineWireDesc); + size += ol->num_points * SIZEOF(xkbPointWireDesc); + } + } + return size; +} + +static int +_SizeGeomDoodads(int num_doodads, XkbDoodadPtr doodad) +{ + register int i, size; + + for (i = size = 0; i < num_doodads; i++, doodad++) { + size += SIZEOF(xkbAnyDoodadWireDesc); + if (doodad->any.type == XkbTextDoodad) { + size += _SizeCountedString(doodad->text.text); + size += _SizeCountedString(doodad->text.font); + } + else if (doodad->any.type == XkbLogoDoodad) { + size += _SizeCountedString(doodad->logo.logo_name); + } + } + return size; +} + +static int +_SizeGeomSections(XkbGeometryPtr geom) +{ + register int i, size; + XkbSectionPtr section; + + for (i = size = 0, section = geom->sections; i < geom->num_sections; + i++, section++) { + size += SIZEOF(xkbSectionWireDesc); + if (section->rows) { + int r; + XkbRowPtr row; + + for (r = 0, row = section->rows; r < section->num_rows; row++, r++) { + size += SIZEOF(xkbRowWireDesc); + size += row->num_keys * SIZEOF(xkbKeyWireDesc); + } + } + if (section->doodads) + size += _SizeGeomDoodads(section->num_doodads, section->doodads); + if (section->overlays) { + int o; + XkbOverlayPtr ol; + + for (o = 0, ol = section->overlays; o < section->num_overlays; + o++, ol++) { + int r; + XkbOverlayRowPtr row; + + size += SIZEOF(xkbOverlayWireDesc); + for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { + size += SIZEOF(xkbOverlayRowWireDesc); + size += row->num_keys * SIZEOF(xkbOverlayKeyWireDesc); + } + } + } + } + return size; +} + +static int +_SizeGeomKeyAliases(XkbGeometryPtr geom) +{ + return geom->num_key_aliases * (2 * XkbKeyNameLength); +} + +/***====================================================================***/ + +static char * +_WriteGeomProperties(char *wire, XkbGeometryPtr geom) +{ + register int i; + register XkbPropertyPtr prop; + + for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { + wire = _WriteCountedString(wire, prop->name); + wire = _WriteCountedString(wire, prop->value); + } + return wire; +} + +static char * +_WriteGeomColors(char *wire, XkbGeometryPtr geom) +{ + register int i; + register XkbColorPtr color; + + for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { + wire = _WriteCountedString(wire, color->spec); + } + return wire; +} + +static char * +_WriteGeomShapes(char *wire, XkbGeometryPtr geom) +{ + int i; + XkbShapePtr shape; + xkbShapeWireDesc *shapeWire; + + for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { + register int o; + XkbOutlinePtr ol; + xkbOutlineWireDesc *olWire; + + shapeWire = (xkbShapeWireDesc *) wire; + shapeWire->name = shape->name; + shapeWire->nOutlines = shape->num_outlines; + if (shape->primary != NULL) + shapeWire->primaryNdx = XkbOutlineIndex(shape, shape->primary); + else + shapeWire->primaryNdx = XkbNoShape; + if (shape->approx != NULL) + shapeWire->approxNdx = XkbOutlineIndex(shape, shape->approx); + else + shapeWire->approxNdx = XkbNoShape; + wire = (char *) &shapeWire[1]; + for (o = 0, ol = shape->outlines; o < shape->num_outlines; o++, ol++) { + register int p; + XkbPointPtr pt; + xkbPointWireDesc *ptWire; + + olWire = (xkbOutlineWireDesc *) wire; + olWire->nPoints = ol->num_points; + olWire->cornerRadius = ol->corner_radius; + wire = (char *) &olWire[1]; + ptWire = (xkbPointWireDesc *) wire; + for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) { + ptWire[p].x = pt->x; + ptWire[p].y = pt->y; + } + wire = (char *) &ptWire[ol->num_points]; + } + } + return wire; +} + +static char * +_WriteGeomDoodads(char *wire, int num_doodads, XkbDoodadPtr doodad) +{ + register int i; + + for (i = 0; i < num_doodads; i++, doodad++) { + xkbDoodadWireDesc *doodadWire = (xkbDoodadWireDesc *) wire; + + wire = (char *) &doodadWire[1]; + bzero(doodadWire, SIZEOF(xkbDoodadWireDesc)); + doodadWire->any.name = doodad->any.name; + doodadWire->any.type = doodad->any.type; + doodadWire->any.priority = doodad->any.priority; + doodadWire->any.top = doodad->any.top; + doodadWire->any.left = doodad->any.left; + doodadWire->any.angle = doodad->any.angle; + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + doodadWire->shape.colorNdx = doodad->shape.color_ndx; + doodadWire->shape.shapeNdx = doodad->shape.shape_ndx; + break; + case XkbTextDoodad: + doodadWire->text.width = doodad->text.width; + doodadWire->text.height = doodad->text.height; + doodadWire->text.colorNdx = doodad->text.color_ndx; + wire = _WriteCountedString(wire, doodad->text.text); + wire = _WriteCountedString(wire, doodad->text.font); + break; + case XkbIndicatorDoodad: + doodadWire->indicator.shapeNdx = doodad->indicator.shape_ndx; + doodadWire->indicator.onColorNdx = doodad->indicator.on_color_ndx; + doodadWire->indicator.offColorNdx = doodad->indicator.off_color_ndx; + break; + case XkbLogoDoodad: + doodadWire->logo.colorNdx = doodad->logo.color_ndx; + doodadWire->logo.shapeNdx = doodad->logo.shape_ndx; + wire = _WriteCountedString(wire, doodad->logo.logo_name); + break; + default: + break; + } + } + return wire; +} + +static char * +_WriteGeomOverlay(char *wire, XkbOverlayPtr ol) +{ + register int r; + XkbOverlayRowPtr row; + xkbOverlayWireDesc *olWire = (xkbOverlayWireDesc *) wire; + + olWire->name = ol->name; + olWire->nRows = ol->num_rows; + wire = (char *) &olWire[1]; + for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { + unsigned int k; + XkbOverlayKeyPtr key; + xkbOverlayRowWireDesc *rowWire = (xkbOverlayRowWireDesc *) wire; + + rowWire->rowUnder = row->row_under; + rowWire->nKeys = row->num_keys; + wire = (char *) &rowWire[1]; + for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { + xkbOverlayKeyWireDesc *keyWire = (xkbOverlayKeyWireDesc *) wire; + + memcpy(keyWire->over, key->over.name, XkbKeyNameLength); + memcpy(keyWire->under, key->under.name, XkbKeyNameLength); + wire = (char *) &keyWire[1]; + } + } + return wire; +} + +static char * +_WriteGeomSections(char *wire, XkbGeometryPtr geom) +{ + register int i; + XkbSectionPtr section; + + for (i = 0, section = geom->sections; i < geom->num_sections; + i++, section++) { + xkbSectionWireDesc *sectionWire = (xkbSectionWireDesc *) wire; + + sectionWire->name = section->name; + sectionWire->top = section->top; + sectionWire->left = section->left; + sectionWire->width = section->width; + sectionWire->height = section->height; + sectionWire->angle = section->angle; + sectionWire->priority = section->priority; + sectionWire->nRows = section->num_rows; + sectionWire->nDoodads = section->num_doodads; + sectionWire->nOverlays = section->num_overlays; + sectionWire->pad = 0; + wire = (char *) §ionWire[1]; + if (section->rows) { + int r; + XkbRowPtr row; + + for (r = 0, row = section->rows; r < section->num_rows; r++, row++) { + xkbRowWireDesc *rowWire = (xkbRowWireDesc *) wire; + + rowWire->top = row->top; + rowWire->left = row->left; + rowWire->nKeys = row->num_keys; + rowWire->vertical = row->vertical; + rowWire->pad = 0; + wire = (char *) &rowWire[1]; + if (row->keys) { + int k; + XkbKeyPtr key; + xkbKeyWireDesc *keyWire = (xkbKeyWireDesc *) wire; + + for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { + memcpy(keyWire[k].name, key->name.name, + XkbKeyNameLength); + keyWire[k].gap = key->gap; + keyWire[k].shapeNdx = key->shape_ndx; + keyWire[k].colorNdx = key->color_ndx; + } + wire = (char *) &keyWire[row->num_keys]; + } + } + } + if (section->doodads) { + wire = _WriteGeomDoodads(wire, + section->num_doodads, section->doodads); + } + if (section->overlays) { + register int o; + + for (o = 0; o < section->num_overlays; o++) { + wire = _WriteGeomOverlay(wire, §ion->overlays[o]); + } + } + } + return wire; +} + +static char * +_WriteGeomKeyAliases(char *wire, XkbGeometryPtr geom) +{ + register int sz; + + sz = geom->num_key_aliases * (XkbKeyNameLength * 2); + if (sz > 0) { + memcpy(wire, (char *) geom->key_aliases, sz); + wire += sz; + } + return wire; +} + +/***====================================================================***/ + +static Status +_SendSetGeometry(Display *dpy, XkbGeometryPtr geom, xkbSetGeometryReq *req) +{ + int sz; + char *wire, *tbuf; + + sz = 0; + sz += _SizeCountedString(geom->label_font); + sz += _SizeGeomProperties(geom); + sz += _SizeGeomColors(geom); + sz += _SizeGeomShapes(geom); + sz += _SizeGeomSections(geom); + sz += _SizeGeomDoodads(geom->num_doodads, geom->doodads); + sz += _SizeGeomKeyAliases(geom); + req->length += (sz / 4); + if (sz < (dpy->bufmax - dpy->buffer)) { + BufAlloc(char *, wire, sz); + tbuf = NULL; + } + else { + tbuf = _XAllocTemp(dpy, sz); + if (!tbuf) + return BadAlloc; + wire = tbuf; + } + wire = _WriteCountedString(wire, geom->label_font); + if (geom->num_properties > 0) + wire = _WriteGeomProperties(wire, geom); + if (geom->num_colors > 0) + wire = _WriteGeomColors(wire, geom); + if (geom->num_shapes > 0) + wire = _WriteGeomShapes(wire, geom); + if (geom->num_sections > 0) + wire = _WriteGeomSections(wire, geom); + if (geom->num_doodads > 0) + wire = _WriteGeomDoodads(wire, geom->num_doodads, geom->doodads); + if (geom->num_key_aliases > 0) + wire = _WriteGeomKeyAliases(wire, geom); + if (tbuf != NULL) { + Data(dpy, tbuf, sz); + _XFreeTemp(dpy, tbuf, sz); + } + return Success; +} + +/***====================================================================***/ + +Status +XkbSetGeometry(Display *dpy, unsigned deviceSpec, XkbGeometryPtr geom) +{ + xkbSetGeometryReq *req; + Status ret; + + if ((!geom) || (dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + + LockDisplay(dpy); + GetReq(kbSetGeometry, req); + req->reqType = dpy->xkb_info->codes->major_opcode; + req->xkbReqType = X_kbSetGeometry; + req->deviceSpec = deviceSpec; + req->nShapes = geom->num_shapes; + req->nSections = geom->num_sections; + req->name = geom->name; + req->widthMM = geom->width_mm; + req->heightMM = geom->height_mm; + req->nProperties = geom->num_properties; + req->nColors = geom->num_colors; + req->nDoodads = geom->num_doodads; + req->nKeyAliases = geom->num_key_aliases; + req->baseColorNdx = (geom->base_color - geom->colors); + req->labelColorNdx = (geom->label_color - geom->colors); + + ret = _SendSetGeometry(dpy, geom, req); + UnlockDisplay(dpy); + SyncHandle(); + return ret; +} diff --git a/nx-X11/lib/src/xkb/XKBSetMap.c b/nx-X11/lib/src/xkb/XKBSetMap.c new file mode 100644 index 000000000..cb696105c --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBSetMap.c @@ -0,0 +1,598 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +static int +_XkbSizeKeyTypes(XkbDescPtr xkb, xkbSetMapReq *req) +{ + XkbKeyTypePtr map; + int i, len; + + if (((req->present & XkbKeyTypesMask) == 0) || (req->nTypes == 0)) { + req->present &= ~XkbKeyTypesMask; + req->firstType = req->nTypes = 0; + return 0; + } + len = 0; + map = &xkb->map->types[req->firstType]; + for (i = 0; i < req->nTypes; i++, map++) { + len += SIZEOF(xkbKeyTypeWireDesc); + len += map->map_count * SIZEOF(xkbKTSetMapEntryWireDesc); + if (map->preserve) + len += map->map_count * SIZEOF(xkbModsWireDesc); + } + return len; +} + +static void +_XkbWriteKeyTypes(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + char *buf; + XkbKeyTypePtr type; + int i, n; + xkbKeyTypeWireDesc *desc; + + if ((req->present & XkbKeyTypesMask) == 0) + return; + type = &xkb->map->types[req->firstType]; + for (i = 0; i < req->nTypes; i++, type++) { + int sz = SIZEOF(xkbKeyTypeWireDesc); + sz += type->map_count * SIZEOF(xkbKTSetMapEntryWireDesc); + if (type->preserve) + sz += type->map_count * SIZEOF(xkbModsWireDesc); + BufAlloc(xkbKeyTypeWireDesc *, desc, sz); + desc->mask = type->mods.mask; + desc->realMods = type->mods.real_mods; + desc->virtualMods = type->mods.vmods; + desc->numLevels = type->num_levels; + desc->nMapEntries = type->map_count; + desc->preserve = (type->preserve != NULL); + buf = (char *) &desc[1]; + if (desc->nMapEntries > 0) { + xkbKTSetMapEntryWireDesc *wire = (xkbKTSetMapEntryWireDesc *) buf; + + for (n = 0; n < type->map_count; n++, wire++) { + wire->level = type->map[n].level; + wire->realMods = type->map[n].mods.real_mods; + wire->virtualMods = type->map[n].mods.vmods; + } + buf = (char *) wire; + if (type->preserve) { + xkbModsWireDesc *pwire = (xkbModsWireDesc *) buf; + + for (n = 0; n < type->map_count; n++, pwire++) { + pwire->realMods = type->preserve[n].real_mods; + pwire->virtualMods = type->preserve[n].vmods; + } + } + } + } + return; +} + +static int +_XkbSizeKeySyms(XkbDescPtr xkb, xkbSetMapReq *req) +{ + int i, len; + unsigned nSyms; + + if (((req->present & XkbKeySymsMask) == 0) || (req->nKeySyms == 0)) { + req->present &= ~XkbKeySymsMask; + req->firstKeySym = req->nKeySyms = 0; + req->totalSyms = 0; + return 0; + } + len = (int) (req->nKeySyms * sizeof(XkbSymMapRec)); + for (i = nSyms = 0; i < req->nKeySyms; i++) { + nSyms += XkbKeyNumSyms(xkb, i + req->firstKeySym); + } + len += nSyms * sizeof(CARD32); + req->totalSyms = nSyms; + return len; +} + +static void +_XkbWriteKeySyms(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register KeySym *pSym; + CARD32 *outSym; + XkbSymMapPtr symMap; + xkbSymMapWireDesc *desc; + register int i; + + if ((req->present & XkbKeySymsMask) == 0) + return; + symMap = &xkb->map->key_sym_map[req->firstKeySym]; + for (i = 0; i < req->nKeySyms; i++, symMap++) { + BufAlloc(xkbSymMapWireDesc *, desc, + SIZEOF(xkbSymMapWireDesc) + + (XkbKeyNumSyms(xkb, i + req->firstKeySym) * sizeof(CARD32))); + desc->ktIndex[0] = symMap->kt_index[0]; + desc->ktIndex[1] = symMap->kt_index[1]; + desc->ktIndex[2] = symMap->kt_index[2]; + desc->ktIndex[3] = symMap->kt_index[3]; + desc->groupInfo = symMap->group_info; + desc->width = symMap->width; + desc->nSyms = XkbKeyNumSyms(xkb, i + req->firstKeySym); + outSym = (CARD32 *) &desc[1]; + if (desc->nSyms > 0) { + pSym = XkbKeySymsPtr(xkb, i + req->firstKeySym); + _XkbWriteCopyKeySyms(pSym, outSym, desc->nSyms); + } + } + return; +} + +static int +_XkbSizeKeyActions(XkbDescPtr xkb, xkbSetMapReq *req) +{ + int i, len, nActs; + + if (((req->present & XkbKeyActionsMask) == 0) || (req->nKeyActs == 0)) { + req->present &= ~XkbKeyActionsMask; + req->firstKeyAct = req->nKeyActs = 0; + req->totalActs = 0; + return 0; + } + for (nActs = i = 0; i < req->nKeyActs; i++) { + if (xkb->server->key_acts[i + req->firstKeyAct] != 0) + nActs += XkbKeyNumActions(xkb, i + req->firstKeyAct); + } + len = XkbPaddedSize(req->nKeyActs) + (nActs * SIZEOF(xkbActionWireDesc)); + req->totalActs = nActs; + return len; +} + +static void +_XkbWriteKeyActions(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i; + int n; + CARD8 *numDesc; + XkbAction *actDesc; + + if ((req->present & XkbKeyActionsMask) == 0) + return; + n = XkbPaddedSize(req->nKeyActs); + n += (req->totalActs * SIZEOF(xkbActionWireDesc)); + + BufAlloc(CARD8 *, numDesc, n); + for (i = 0; i < req->nKeyActs; i++) { + if (xkb->server->key_acts[i + req->firstKeyAct] == 0) + numDesc[i] = 0; + else + numDesc[i] = XkbKeyNumActions(xkb, (i + req->firstKeyAct)); + } + actDesc = (XkbAction *) &numDesc[XkbPaddedSize(req->nKeyActs)]; + for (i = 0; i < req->nKeyActs; i++) { + if (xkb->server->key_acts[i + req->firstKeyAct] != 0) { + n = XkbKeyNumActions(xkb, (i + req->firstKeyAct)); + memcpy(actDesc, XkbKeyActionsPtr(xkb, (i + req->firstKeyAct)), + n * SIZEOF(xkbActionWireDesc)); + actDesc += n; + } + } + return; +} + +static int +_XkbSizeKeyBehaviors(XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last, nFound; + + if (((req->present & XkbKeyBehaviorsMask) == 0) || (req->nKeyBehaviors < 1)) { + req->present &= ~XkbKeyBehaviorsMask; + req->firstKeyBehavior = req->nKeyBehaviors = 0; + req->totalKeyBehaviors = 0; + return 0; + } + first = req->firstKeyBehavior; + last = first + req->nKeyBehaviors - 1; + for (i = first, nFound = 0; i <= last; i++) { + if (xkb->server->behaviors[i].type != XkbKB_Default) + nFound++; + } + req->totalKeyBehaviors = nFound; + return (nFound * SIZEOF(xkbBehaviorWireDesc)); +} + +static void +_XkbWriteKeyBehaviors(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last; + xkbBehaviorWireDesc *wire; + char *buf; + + if ((req->present & XkbKeyBehaviorsMask) == 0) + return; + first = req->firstKeyBehavior; + last = first + req->nKeyBehaviors - 1; + + i = req->totalKeyBehaviors * SIZEOF(xkbBehaviorWireDesc); + BufAlloc(char *, buf, i); + wire = (xkbBehaviorWireDesc *) buf; + for (i = first; i <= last; i++) { + if (xkb->server->behaviors[i].type != XkbKB_Default) { + wire->key = i; + wire->type = xkb->server->behaviors[i].type; + wire->data = xkb->server->behaviors[i].data; + buf += SIZEOF(xkbBehaviorWireDesc); + wire = (xkbBehaviorWireDesc *) buf; + } + } + return; +} + +static unsigned +_XkbSizeVirtualMods(xkbSetMapReq *req) +{ + register int i, bit, nMods; + + if (((req->present & XkbVirtualModsMask) == 0) || (req->virtualMods == 0)) { + req->present &= ~XkbVirtualModsMask; + req->virtualMods = 0; + return 0; + } + for (i = nMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if (req->virtualMods & bit) + nMods++; + } + return XkbPaddedSize(nMods); +} + +static void +_XkbWriteVirtualMods(Display *dpy, + XkbDescPtr xkb, + xkbSetMapReq *req, + unsigned size) +{ + register int i, bit; + CARD8 *vmods; + + /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */ + if (((req->present & XkbVirtualModsMask) == 0) || (size < 1)) + return; + BufAlloc(CARD8 *, vmods, size); + for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { + if (req->virtualMods & bit) + *vmods++ = xkb->server->vmods[i]; + } + return; +} + +static int +_XkbSizeKeyExplicit(XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last, nFound; + + if (((req->present & XkbExplicitComponentsMask) == 0) || + (req->nKeyExplicit == 0)) { + req->present &= ~XkbExplicitComponentsMask; + req->firstKeyExplicit = req->nKeyExplicit = 0; + req->totalKeyExplicit = 0; + return 0; + } + first = req->firstKeyExplicit; + last = first + req->nKeyExplicit - 1; + + for (i = first, nFound = 0; i <= last; i++) { + if (xkb->server->explicit[i] != 0) + nFound++; + } + req->totalKeyExplicit = nFound; + return XkbPaddedSize((nFound * 2)); +} + +static void +_XkbWriteKeyExplicit(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last; + CARD8 *wire; + + if ((req->present & XkbExplicitComponentsMask) == 0) + return; + first = req->firstKeyExplicit; + last = first + req->nKeyExplicit - 1; + i = XkbPaddedSize((req->totalKeyExplicit * 2)); + BufAlloc(CARD8 *, wire, i); + for (i = first; i <= last; i++) { + if (xkb->server->explicit[i] != 0) { + wire[0] = i; + wire[1] = xkb->server->explicit[i]; + wire += 2; + } + } + return; +} + +static int +_XkbSizeModifierMap(XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last, nFound; + + if (((req->present & XkbModifierMapMask) == 0) || (req->nModMapKeys == 0)) { + req->present &= ~XkbModifierMapMask; + req->firstModMapKey = req->nModMapKeys = 0; + req->totalModMapKeys = 0; + return 0; + } + first = req->firstModMapKey; + last = first + req->nModMapKeys - 1; + + for (i = first, nFound = 0; i <= last; i++) { + if (xkb->map->modmap[i] != 0) + nFound++; + } + req->totalModMapKeys = nFound; + return XkbPaddedSize((nFound * 2)); +} + +static void +_XkbWriteModifierMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last; + CARD8 *wire; + + if ((req->present & XkbModifierMapMask) == 0) + return; + first = req->firstModMapKey; + last = first + req->nModMapKeys - 1; + if (req->totalModMapKeys > 0) { + i = XkbPaddedSize((req->totalModMapKeys * 2)); + BufAlloc(CARD8 *, wire, i); + + for (i = first; i <= last; i++) { + if (xkb->map->modmap[i] != 0) { + wire[0] = i; + wire[1] = xkb->map->modmap[i]; + wire += 2; + } + } + } + return; +} + +static int +_XkbSizeVirtualModMap(XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last, nFound; + + if (((req->present & XkbVirtualModMapMask) == 0) || + (req->nVModMapKeys == 0)) { + req->present &= ~XkbVirtualModMapMask; + req->firstVModMapKey = req->nVModMapKeys = 0; + req->totalVModMapKeys = 0; + return 0; + } + first = req->firstVModMapKey; + last = first + req->nVModMapKeys - 1; + + for (i = first, nFound = 0; i <= last; i++) { + if (xkb->server->vmodmap[i] != 0) + nFound++; + } + req->totalVModMapKeys = nFound; + return nFound * SIZEOF(xkbVModMapWireDesc); +} + +static void +_XkbWriteVirtualModMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + register int i, first, last; + xkbVModMapWireDesc *wire; + + if ((req->present & XkbVirtualModMapMask) == 0) + return; + first = req->firstVModMapKey; + last = first + req->nVModMapKeys - 1; + if (req->totalVModMapKeys > 0) { + i = req->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); + BufAlloc(xkbVModMapWireDesc *, wire, i); + for (i = first; i <= last; i++) { + if (xkb->server->vmodmap[i] != 0) { + wire->key = i; + wire->vmods = xkb->server->vmodmap[i]; + wire++; + } + } + } + return; +} + +static void +SendSetMap(Display *dpy, XkbDescPtr xkb, xkbSetMapReq *req) +{ + xkbSetMapReq tmp; + unsigned szMods; + + req->length += _XkbSizeKeyTypes(xkb, req) / 4; + req->length += _XkbSizeKeySyms(xkb, req) / 4; + req->length += _XkbSizeKeyActions(xkb, req) / 4; + req->length += _XkbSizeKeyBehaviors(xkb, req) / 4; + szMods = _XkbSizeVirtualMods(req); + req->length += szMods / 4; + req->length += _XkbSizeKeyExplicit(xkb, req) / 4; + req->length += _XkbSizeModifierMap(xkb, req) / 4; + req->length += _XkbSizeVirtualModMap(xkb, req) / 4; + + tmp = *req; + if (tmp.nTypes > 0) + _XkbWriteKeyTypes(dpy, xkb, &tmp); + if (tmp.nKeySyms > 0) + _XkbWriteKeySyms(dpy, xkb, &tmp); + if (tmp.nKeyActs) + _XkbWriteKeyActions(dpy, xkb, &tmp); + if (tmp.totalKeyBehaviors > 0) + _XkbWriteKeyBehaviors(dpy, xkb, &tmp); + if (tmp.virtualMods) + _XkbWriteVirtualMods(dpy, xkb, &tmp, szMods); + if (tmp.totalKeyExplicit > 0) + _XkbWriteKeyExplicit(dpy, xkb, &tmp); + if (tmp.totalModMapKeys > 0) + _XkbWriteModifierMap(dpy, xkb, &tmp); + if (tmp.totalVModMapKeys > 0) + _XkbWriteVirtualModMap(dpy, xkb, &tmp); + return; +} + +Bool +XkbSetMap(Display *dpy, unsigned which, XkbDescPtr xkb) +{ + register xkbSetMapReq *req; + XkbInfoPtr xkbi; + XkbServerMapPtr srv; + XkbClientMapPtr map; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || (!xkb)) + return False; + map = xkb->map; + srv = xkb->server; + + if (((which & XkbKeyTypesMask) && ((!map) || (!map->types))) || + ((which & XkbKeySymsMask) && + ((!map) || (!map->syms) || (!map->key_sym_map))) || + ((which & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts))) || + ((which & XkbKeyBehaviorsMask) && ((!srv) || (!srv->behaviors))) || + ((which & XkbVirtualModsMask) && (!srv)) || + ((which & XkbExplicitComponentsMask) && ((!srv) || (!srv->explicit))) || + ((which & XkbModifierMapMask) && ((!map) || (!map->modmap))) || + ((which & XkbVirtualModMapMask) && ((!srv) || (!srv->vmodmap)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->device_spec; + req->present = which; + req->flags = XkbSetMapAllFlags; + req->minKeyCode = xkb->min_key_code; + req->maxKeyCode = xkb->max_key_code; + req->firstType = 0; + if (which & XkbKeyTypesMask) + req->nTypes = map->num_types; + else + req->nTypes = 0; + if (which & XkbKeySymsMask) { + req->firstKeySym = xkb->min_key_code; + req->nKeySyms = XkbNumKeys(xkb); + } + if (which & XkbKeyActionsMask) { + req->firstKeyAct = xkb->min_key_code; + req->nKeyActs = XkbNumKeys(xkb); + } + if (which & XkbKeyBehaviorsMask) { + req->firstKeyBehavior = xkb->min_key_code; + req->nKeyBehaviors = XkbNumKeys(xkb); + } + if (which & XkbVirtualModsMask) + req->virtualMods = ~0; + if (which & XkbExplicitComponentsMask) { + req->firstKeyExplicit = xkb->min_key_code; + req->nKeyExplicit = XkbNumKeys(xkb); + } + if (which & XkbModifierMapMask) { + req->firstModMapKey = xkb->min_key_code; + req->nModMapKeys = XkbNumKeys(xkb); + } + if (which & XkbVirtualModMapMask) { + req->firstVModMapKey = xkb->min_key_code; + req->nVModMapKeys = XkbNumKeys(xkb); + } + SendSetMap(dpy, xkb, req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbChangeMap(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) +{ + register xkbSetMapReq *req; + XkbInfoPtr xkbi; + XkbServerMapPtr srv; + XkbClientMapPtr map; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)) || + (!xkb) || (!changes)) + return False; + srv = xkb->server; + map = xkb->map; + + if (((changes->changed & XkbKeyTypesMask) && ((!map) || (!map->types))) || + ((changes->changed & XkbKeySymsMask) && ((!map) || (!map->syms) || + (!map->key_sym_map))) || + ((changes->changed & XkbKeyActionsMask) && ((!srv) || (!srv->key_acts))) + || ((changes->changed & XkbKeyBehaviorsMask) && + ((!srv) || (!srv->behaviors))) || + ((changes->changed & XkbVirtualModsMask) && (!srv)) || + ((changes->changed & XkbExplicitComponentsMask) && + ((!srv) || (!srv->explicit))) || + ((changes->changed & XkbModifierMapMask) && ((!map) || (!map->modmap))) + || ((changes->changed & XkbVirtualModMapMask) && + ((!srv) || (!srv->vmodmap)))) + return False; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetMap; + req->deviceSpec = xkb->device_spec; + req->present = changes->changed; + req->flags = XkbSetMapRecomputeActions; + req->minKeyCode = xkb->min_key_code; + req->maxKeyCode = xkb->max_key_code; + req->firstType = changes->first_type; + req->nTypes = changes->num_types; + req->firstKeySym = changes->first_key_sym; + req->nKeySyms = changes->num_key_syms; + req->firstKeyAct = changes->first_key_act; + req->nKeyActs = changes->num_key_acts; + req->firstKeyBehavior = changes->first_key_behavior; + req->nKeyBehaviors = changes->num_key_behaviors; + req->virtualMods = changes->vmods; + req->firstKeyExplicit = changes->first_key_explicit; + req->nKeyExplicit = changes->num_key_explicit; + req->firstModMapKey = changes->first_modmap_key; + req->nModMapKeys = changes->num_modmap_keys; + req->firstVModMapKey = changes->first_vmodmap_key; + req->nVModMapKeys = changes->num_vmodmap_keys; + SendSetMap(dpy, xkb, req); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} diff --git a/nx-X11/lib/src/xkb/XKBUse.c b/nx-X11/lib/src/xkb/XKBUse.c new file mode 100644 index 000000000..cf6497551 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBUse.c @@ -0,0 +1,814 @@ +/************************************************************ +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. + +********************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <ctype.h> +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +static Bool _XkbIgnoreExtension = False; + +void +XkbNoteMapChanges(XkbMapChangesPtr old, + XkbMapNotifyEvent *new, + unsigned wanted) +{ + int first, oldLast, newLast; + + wanted &= new->changed; + + if (wanted & XkbKeyTypesMask) { + if (old->changed & XkbKeyTypesMask) { + first = old->first_type; + oldLast = old->first_type + old->num_types - 1; + newLast = new->first_type + new->num_types - 1; + + if (new->first_type < first) + first = new->first_type; + if (oldLast > newLast) + newLast = oldLast; + old->first_type = first; + old->num_types = newLast - first + 1; + } + else { + old->first_type = new->first_type; + old->num_types = new->num_types; + } + } + if (wanted & XkbKeySymsMask) { + if (old->changed & XkbKeySymsMask) { + first = old->first_key_sym; + oldLast = old->first_key_sym + old->num_key_syms - 1; + newLast = new->first_key_sym + new->num_key_syms - 1; + + if (new->first_key_sym < first) + first = new->first_key_sym; + if (oldLast > newLast) + newLast = oldLast; + old->first_key_sym = first; + old->num_key_syms = newLast - first + 1; + } + else { + old->first_key_sym = new->first_key_sym; + old->num_key_syms = new->num_key_syms; + } + } + if (wanted & XkbKeyActionsMask) { + if (old->changed & XkbKeyActionsMask) { + first = old->first_key_act; + oldLast = old->first_key_act + old->num_key_acts - 1; + newLast = new->first_key_act + new->num_key_acts - 1; + + if (new->first_key_act < first) + first = new->first_key_act; + if (oldLast > newLast) + newLast = oldLast; + old->first_key_act = first; + old->num_key_acts = newLast - first + 1; + } + else { + old->first_key_act = new->first_key_act; + old->num_key_acts = new->num_key_acts; + } + } + if (wanted & XkbKeyBehaviorsMask) { + if (old->changed & XkbKeyBehaviorsMask) { + first = old->first_key_behavior; + oldLast = old->first_key_behavior + old->num_key_behaviors - 1; + newLast = new->first_key_behavior + new->num_key_behaviors - 1; + + if (new->first_key_behavior < first) + first = new->first_key_behavior; + if (oldLast > newLast) + newLast = oldLast; + old->first_key_behavior = first; + old->num_key_behaviors = newLast - first + 1; + } + else { + old->first_key_behavior = new->first_key_behavior; + old->num_key_behaviors = new->num_key_behaviors; + } + } + if (wanted & XkbVirtualModsMask) { + old->vmods |= new->vmods; + } + if (wanted & XkbExplicitComponentsMask) { + if (old->changed & XkbExplicitComponentsMask) { + first = old->first_key_explicit; + oldLast = old->first_key_explicit + old->num_key_explicit - 1; + newLast = new->first_key_explicit + new->num_key_explicit - 1; + + if (new->first_key_explicit < first) + first = new->first_key_explicit; + if (oldLast > newLast) + newLast = oldLast; + old->first_key_explicit = first; + old->num_key_explicit = newLast - first + 1; + } + else { + old->first_key_explicit = new->first_key_explicit; + old->num_key_explicit = new->num_key_explicit; + } + } + if (wanted & XkbModifierMapMask) { + if (old->changed & XkbModifierMapMask) { + first = old->first_modmap_key; + oldLast = old->first_modmap_key + old->num_modmap_keys - 1; + newLast = new->first_modmap_key + new->num_modmap_keys - 1; + + if (new->first_modmap_key < first) + first = new->first_modmap_key; + if (oldLast > newLast) + newLast = oldLast; + old->first_modmap_key = first; + old->num_modmap_keys = newLast - first + 1; + } + else { + old->first_modmap_key = new->first_modmap_key; + old->num_modmap_keys = new->num_modmap_keys; + } + } + if (wanted & XkbVirtualModMapMask) { + if (old->changed & XkbVirtualModMapMask) { + first = old->first_vmodmap_key; + oldLast = old->first_vmodmap_key + old->num_vmodmap_keys - 1; + newLast = new->first_vmodmap_key + new->num_vmodmap_keys - 1; + + if (new->first_vmodmap_key < first) + first = new->first_vmodmap_key; + if (oldLast > newLast) + newLast = oldLast; + old->first_vmodmap_key = first; + old->num_vmodmap_keys = newLast - first + 1; + } + else { + old->first_vmodmap_key = new->first_vmodmap_key; + old->num_vmodmap_keys = new->num_vmodmap_keys; + } + } + old->changed |= wanted; + return; +} + +void +_XkbNoteCoreMapChanges(XkbMapChangesPtr old, + XMappingEvent *new, + unsigned int wanted) +{ + int first, oldLast, newLast; + + if ((new->request == MappingKeyboard) && (wanted & XkbKeySymsMask)) { + if (old->changed & XkbKeySymsMask) { + first = old->first_key_sym; + oldLast = old->first_key_sym + old->num_key_syms - 1; + newLast = new->first_keycode + new->count - 1; + + if (new->first_keycode < first) + first = new->first_keycode; + if (oldLast > newLast) + newLast = oldLast; + old->first_key_sym = first; + old->num_key_syms = newLast - first + 1; + } + else { + old->changed |= XkbKeySymsMask; + old->first_key_sym = new->first_keycode; + old->num_key_syms = new->count; + } + } + return; +} + +static Bool +wire_to_event(Display *dpy, XEvent *re, xEvent *event) +{ + xkbEvent *xkbevent = (xkbEvent *) event; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + xkbi = dpy->xkb_info; + if (((event->u.u.type & 0x7f) - xkbi->codes->first_event) != XkbEventCode) + return False; + + switch (xkbevent->u.any.xkbType) { + case XkbStateNotify: + { + xkbStateNotify *sn = (xkbStateNotify *) event; + + if (xkbi->selected_events & XkbStateNotifyMask) { + XkbStateNotifyEvent *sev = (XkbStateNotifyEvent *) re; + + sev->type = XkbEventCode + xkbi->codes->first_event; + sev->xkb_type = 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->event_type = sn->eventType; + sev->req_major = sn->requestMajor; + sev->req_minor = sn->requestMinor; + sev->changed = sn->changed; + sev->group = sn->group; + sev->base_group = sn->baseGroup; + sev->latched_group = sn->latchedGroup; + sev->locked_group = sn->lockedGroup; + sev->mods = sn->mods; + sev->base_mods = sn->baseMods; + sev->latched_mods = sn->latchedMods; + sev->locked_mods = sn->lockedMods; + sev->compat_state = sn->compatState; + sev->grab_mods = sn->grabMods; + sev->compat_grab_mods = sn->compatGrabMods; + sev->lookup_mods = sn->lookupMods; + sev->compat_lookup_mods = sn->compatLookupMods; + sev->ptr_buttons = sn->ptrBtnState; + return True; + } + } + break; + case XkbMapNotify: + { + xkbMapNotify *mn = (xkbMapNotify *) event; + + if ((xkbi->selected_events & XkbMapNotifyMask) && + (xkbi->selected_map_details & mn->changed)) { + XkbMapNotifyEvent *mev = (XkbMapNotifyEvent *) re; + + mev->type = XkbEventCode + xkbi->codes->first_event; + mev->xkb_type = 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->min_key_code = mn->minKeyCode; + mev->max_key_code = mn->maxKeyCode; + mev->first_type = mn->firstType; + mev->num_types = mn->nTypes; + mev->first_key_sym = mn->firstKeySym; + mev->num_key_syms = mn->nKeySyms; + mev->first_key_act = mn->firstKeyAct; + mev->num_key_acts = mn->nKeyActs; + mev->first_key_behavior = mn->firstKeyBehavior; + mev->num_key_behaviors = mn->nKeyBehaviors; + mev->vmods = mn->virtualMods; + mev->first_key_explicit = mn->firstKeyExplicit; + mev->num_key_explicit = mn->nKeyExplicit; + mev->first_modmap_key = mn->firstModMapKey; + mev->num_modmap_keys = mn->nModMapKeys; + mev->first_vmodmap_key = mn->firstVModMapKey; + mev->num_vmodmap_keys = mn->nVModMapKeys; + XkbNoteMapChanges(&xkbi->changes, mev, XKB_XLIB_MAP_MASK); + if (xkbi->changes.changed) + xkbi->flags |= XkbMapPending; + 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; + _XkbNoteCoreMapChanges(&xkbi->changes, ev, XKB_XLIB_MAP_MASK); + if (xkbi->changes.changed) + xkbi->flags |= XkbMapPending; + return True; + } + } + break; + case XkbControlsNotify: + { + if (xkbi->selected_events & XkbControlsNotifyMask) { + xkbControlsNotify *cn = (xkbControlsNotify *) event; + XkbControlsNotifyEvent *cev = (XkbControlsNotifyEvent *) re; + + cev->type = XkbEventCode + xkbi->codes->first_event; + cev->xkb_type = 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->changed_ctrls = cn->changedControls; + cev->enabled_ctrls = cn->enabledControls; + cev->enabled_ctrl_changes = cn->enabledControlChanges; + cev->keycode = cn->keycode; + cev->num_groups = cn->numGroups; + cev->event_type = cn->eventType; + cev->req_major = cn->requestMajor; + cev->req_minor = cn->requestMinor; + return True; + } + } + break; + case XkbIndicatorMapNotify: + { + if (xkbi->selected_events & XkbIndicatorMapNotifyMask) { + xkbIndicatorNotify *in = (xkbIndicatorNotify *) event; + XkbIndicatorNotifyEvent *iev = (XkbIndicatorNotifyEvent *) re; + + iev->type = XkbEventCode + xkbi->codes->first_event; + iev->xkb_type = XkbIndicatorMapNotify; + 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->changed = in->changed; + iev->state = in->state; + return True; + } + } + break; + case XkbIndicatorStateNotify: + { + if (xkbi->selected_events & XkbIndicatorStateNotifyMask) { + xkbIndicatorNotify *in = (xkbIndicatorNotify *) event; + XkbIndicatorNotifyEvent *iev = (XkbIndicatorNotifyEvent *) re; + + iev->type = XkbEventCode + xkbi->codes->first_event; + iev->xkb_type = XkbIndicatorStateNotify; + 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->changed = in->changed; + iev->state = in->state; + return True; + } + } + break; + case XkbBellNotify: + { + if (xkbi->selected_events & XkbBellNotifyMask) { + xkbBellNotify *bn = (xkbBellNotify *) event; + XkbBellNotifyEvent *bev = (XkbBellNotifyEvent *) re; + + bev->type = XkbEventCode + xkbi->codes->first_event; + bev->xkb_type = 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->pitch; + bev->duration = bn->duration; + bev->bell_class = bn->bellClass; + bev->bell_id = bn->bellID; + bev->name = bn->name; + bev->window = bn->window; + bev->event_only = bn->eventOnly; + return True; + } + } + break; + case XkbAccessXNotify: + { + if (xkbi->selected_events & XkbAccessXNotifyMask) { + xkbAccessXNotify *axn = (xkbAccessXNotify *) event; + XkbAccessXNotifyEvent *axev = (XkbAccessXNotifyEvent *) re; + + axev->type = XkbEventCode + xkbi->codes->first_event; + axev->xkb_type = XkbAccessXNotify; + axev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); + axev->send_event = ((event->u.u.type & 0x80) != 0); + axev->display = dpy; + axev->time = axn->time; + axev->device = axn->deviceID; + axev->detail = axn->detail; + axev->keycode = axn->keycode; + axev->sk_delay = axn->slowKeysDelay; + axev->debounce_delay = axn->debounceDelay; + return True; + } + } + break; + case XkbNamesNotify: + { + if (xkbi->selected_events & XkbNamesNotifyMask) { + xkbNamesNotify *nn = (xkbNamesNotify *) event; + XkbNamesNotifyEvent *nev = (XkbNamesNotifyEvent *) re; + + nev->type = XkbEventCode + xkbi->codes->first_event; + nev->xkb_type = 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->first_type = nn->firstType; + nev->num_types = nn->nTypes; + nev->first_lvl = nn->firstLevelName; + nev->num_lvls = nn->nLevelNames; + nev->num_aliases = nn->nAliases; + nev->num_radio_groups = nn->nRadioGroups; + nev->changed_vmods = nn->changedVirtualMods; + nev->changed_groups = nn->changedGroupNames; + nev->changed_indicators = nn->changedIndicators; + nev->first_key = nn->firstKey; + nev->num_keys = nn->nKeys; + return True; + } + } + break; + case XkbCompatMapNotify: + { + if (xkbi->selected_events & XkbCompatMapNotifyMask) { + xkbCompatMapNotify *cmn = (xkbCompatMapNotify *) event; + XkbCompatMapNotifyEvent *cmev = (XkbCompatMapNotifyEvent *) re; + + cmev->type = XkbEventCode + xkbi->codes->first_event; + cmev->xkb_type = 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->changed_groups = cmn->changedGroups; + cmev->first_si = cmn->firstSI; + cmev->num_si = cmn->nSI; + cmev->num_total_si = cmn->nTotalSI; + return True; + } + } + break; + case XkbActionMessage: + { + if (xkbi->selected_events & XkbActionMessageMask) { + xkbActionMessage *am = (xkbActionMessage *) event; + XkbActionMessageEvent *amev = (XkbActionMessageEvent *) re; + + amev->type = XkbEventCode + xkbi->codes->first_event; + amev->xkb_type = XkbActionMessage; + amev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); + amev->send_event = ((event->u.u.type & 0x80) != 0); + amev->display = dpy; + amev->time = am->time; + amev->device = am->deviceID; + amev->keycode = am->keycode; + amev->press = am->press; + amev->key_event_follows = am->keyEventFollows; + amev->group = am->group; + amev->mods = am->mods; + memcpy(amev->message, am->message, XkbActionMessageLength); + amev->message[XkbActionMessageLength] = '\0'; + return True; + } + } + break; + case XkbExtensionDeviceNotify: + { + if (xkbi->selected_events & XkbExtensionDeviceNotifyMask) { + xkbExtensionDeviceNotify *ed = (xkbExtensionDeviceNotify *) event; + XkbExtensionDeviceNotifyEvent *edev + = (XkbExtensionDeviceNotifyEvent *) re; + + edev->type = XkbEventCode + xkbi->codes->first_event; + edev->xkb_type = XkbExtensionDeviceNotify; + edev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); + edev->send_event = ((event->u.u.type & 0x80) != 0); + edev->display = dpy; + edev->time = ed->time; + edev->device = ed->deviceID; + edev->led_class = ed->ledClass; + edev->led_id = ed->ledID; + edev->reason = ed->reason; + edev->supported = ed->supported; + edev->leds_defined = ed->ledsDefined; + edev->led_state = ed->ledState; + edev->first_btn = ed->firstBtn; + edev->num_btns = ed->nBtns; + edev->unsupported = ed->unsupported; + return True; + } + } + break; + case XkbNewKeyboardNotify: + { + xkbNewKeyboardNotify *nkn = (xkbNewKeyboardNotify *) event; + + if ((xkbi->selected_events & XkbNewKeyboardNotifyMask) && + (xkbi->selected_nkn_details & nkn->changed)) { + XkbNewKeyboardNotifyEvent *nkev = (XkbNewKeyboardNotifyEvent *) re; + + nkev->type = XkbEventCode + xkbi->codes->first_event; + nkev->xkb_type = XkbNewKeyboardNotify; + nkev->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); + nkev->send_event = ((event->u.u.type & 0x80) != 0); + nkev->display = dpy; + nkev->time = nkn->time; + nkev->device = nkn->deviceID; + nkev->old_device = nkn->oldDeviceID; + nkev->min_key_code = nkn->minKeyCode; + nkev->max_key_code = nkn->maxKeyCode; + nkev->old_min_key_code = nkn->oldMinKeyCode; + nkev->old_max_key_code = nkn->oldMaxKeyCode; + nkev->req_major = nkn->requestMajor; + nkev->req_minor = nkn->requestMinor; + nkev->changed = nkn->changed; + if ((xkbi->desc) && (nkev->send_event == 0) && + ((xkbi->desc->device_spec == nkev->old_device) || + (nkev->device != nkev->old_device))) { + xkbi->flags = XkbMapPending | XkbXlibNewKeyboard; + } + return True; + } + else if (nkn->changed & (XkbNKN_KeycodesMask | XkbNKN_DeviceIDMask)) { + 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 = dpy->min_keycode; + ev->request = MappingKeyboard; + ev->count = (dpy->max_keycode - dpy->min_keycode) + 1; + if ((xkbi->desc) && (ev->send_event == 0) && + ((xkbi->desc->device_spec == nkn->oldDeviceID) || + (nkn->deviceID != nkn->oldDeviceID))) { + xkbi->flags |= XkbMapPending | XkbXlibNewKeyboard; + } + return True; + } + } + break; + default: +#ifdef DEBUG + fprintf(stderr, "Got unknown XKEYBOARD event (%d, base=%d)\n", + re->type, xkbi->codes->first_event); +#endif + break; + } + return False; +} + +Bool +XkbIgnoreExtension(Bool ignore) +{ + if (getenv("XKB_FORCE") != NULL) { +#ifdef DEBUG + fprintf(stderr, + "Forcing use of XKEYBOARD (overriding an IgnoreExtensions)\n"); +#endif + return False; + } +#ifdef DEBUG + else if (getenv("XKB_DEBUG") != NULL) { + fprintf(stderr, "Explicitly %signoring XKEYBOARD\n", + ignore ? "" : "not "); + } +#endif + _XkbIgnoreExtension = ignore; + return True; +} + +static void +_XkbFreeInfo(Display *dpy) +{ + XkbInfoPtr xkbi = dpy->xkb_info; + + if (xkbi) { + if (xkbi->desc) + XkbFreeKeyboard(xkbi->desc, XkbAllComponentsMask, True); + Xfree(xkbi); + } +} + +Bool +XkbUseExtension(Display *dpy, int *major_rtrn, int *minor_rtrn) +{ + xkbUseExtensionReply rep; + register xkbUseExtensionReq *req; + XExtCodes *codes; + int ev_base, forceIgnore; + XkbInfoPtr xkbi; + char *str; + static int debugMsg; + static int been_here = 0; + + if (dpy->xkb_info && !(dpy->flags & XlibDisplayNoXkb)) { + if (major_rtrn) + *major_rtrn = dpy->xkb_info->srv_major; + if (minor_rtrn) + *minor_rtrn = dpy->xkb_info->srv_minor; + return True; + } + if (!been_here) { + debugMsg = (getenv("XKB_DEBUG") != NULL); + been_here = 1; + } + + if (major_rtrn) + *major_rtrn = 0; + if (minor_rtrn) + *minor_rtrn = 0; + + if (!dpy->xkb_info) { + xkbi = _XkbTypedCalloc(1, XkbInfoRec); + if (!xkbi) + return False; + dpy->xkb_info = xkbi; + dpy->free_funcs->xkb = _XkbFreeInfo; + + xkbi->xlib_ctrls |= (XkbLC_ControlFallback | XkbLC_ConsumeLookupMods); + if ((str = getenv("_XKB_OPTIONS_ENABLE")) != NULL) { + if ((str = getenv("_XKB_LATIN1_LOOKUP")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_ForceLatin1Lookup; + else + xkbi->xlib_ctrls |= XkbLC_ForceLatin1Lookup; + } + if ((str = getenv("_XKB_CONSUME_LOOKUP_MODS")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_ConsumeLookupMods; + else + xkbi->xlib_ctrls |= XkbLC_ConsumeLookupMods; + } + if ((str = getenv("_XKB_CONSUME_SHIFT_AND_LOCK")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_AlwaysConsumeShiftAndLock; + else + xkbi->xlib_ctrls |= XkbLC_AlwaysConsumeShiftAndLock; + } + if ((str = getenv("_XKB_IGNORE_NEW_KEYBOARDS")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_IgnoreNewKeyboards; + else + xkbi->xlib_ctrls |= XkbLC_IgnoreNewKeyboards; + } + if ((str = getenv("_XKB_CONTROL_FALLBACK")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_ControlFallback; + else + xkbi->xlib_ctrls |= XkbLC_ControlFallback; + } + if ((str = getenv("_XKB_COMP_LED")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_ComposeLED; + else { + xkbi->xlib_ctrls |= XkbLC_ComposeLED; + if (strlen(str) > 0) + xkbi->composeLED = XInternAtom(dpy, str, False); + } + } + if ((str = getenv("_XKB_COMP_FAIL_BEEP")) != NULL) { + if ((strcmp(str, "off") == 0) || (strcmp(str, "0") == 0)) + xkbi->xlib_ctrls &= ~XkbLC_BeepOnComposeFail; + else + xkbi->xlib_ctrls |= XkbLC_BeepOnComposeFail; + } + } + if ((xkbi->composeLED == None) && + ((xkbi->xlib_ctrls & XkbLC_ComposeLED) != 0)) + xkbi->composeLED = XInternAtom(dpy, "Compose", False); +#ifdef DEBUG + if (debugMsg) { + register unsigned c = xkbi->xlib_ctrls; + + fprintf(stderr, + "XKEYBOARD compose: beep on failure is %s, LED is %s\n", + ((c & XkbLC_BeepOnComposeFail) ? "on" : "off"), + ((c & XkbLC_ComposeLED) ? "on" : "off")); + fprintf(stderr, + "XKEYBOARD XLookupString: %slatin-1, %s lookup modifiers\n", + ((c & XkbLC_ForceLatin1Lookup) ? "allow non-" : "force "), + ((c & XkbLC_ConsumeLookupMods) ? "consume" : "re-use")); + fprintf(stderr, + "XKEYBOARD XLookupString: %sconsume shift and lock, %scontrol fallback\n", + ((c & XkbLC_AlwaysConsumeShiftAndLock) ? "always " : + "don't "), ((c & XkbLC_ControlFallback) ? "" : "no ")); + + } +#endif + } + else + xkbi = dpy->xkb_info; + + forceIgnore = (dpy->flags & XlibDisplayNoXkb) || dpy->keysyms; + forceIgnore = forceIgnore && (major_rtrn == NULL) && (minor_rtrn == NULL); + if (forceIgnore || _XkbIgnoreExtension || getenv("XKB_DISABLE")) { + LockDisplay(dpy); + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + if (debugMsg) + fprintf(stderr, "XKEYBOARD extension disabled or missing\n"); + return False; + } + + if ((codes = XInitExtension(dpy, XkbName)) == NULL) { + LockDisplay(dpy); + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + if (debugMsg) + fprintf(stderr, "XKEYBOARD extension not present\n"); + return False; + } + xkbi->codes = codes; + LockDisplay(dpy); + + GetReq(kbUseExtension, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbUseExtension; + req->wantedMajor = XkbMajorVersion; + req->wantedMinor = XkbMinorVersion; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse) || !rep.supported) { + Bool fail = True; + + if (debugMsg) + fprintf(stderr, + "XKEYBOARD version mismatch (want %d.%02d, got %d.%02d)\n", + XkbMajorVersion, XkbMinorVersion, + rep.serverMajor, rep.serverMinor); + + /* pre-release 0.65 is very close to 1.00 */ + if ((rep.serverMajor == 0) && (rep.serverMinor == 65)) { + if (debugMsg) + fprintf(stderr, "Trying to fall back to version 0.65..."); + GetReq(kbUseExtension, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbUseExtension; + req->wantedMajor = 0; + req->wantedMinor = 65; + if (_XReply(dpy, (xReply *) &rep, 0, xFalse) && rep.supported) { + if (debugMsg) + fprintf(stderr, "succeeded\n"); + fail = False; + } + else if (debugMsg) + fprintf(stderr, "failed\n"); + } + if (fail) { + dpy->flags |= XlibDisplayNoXkb; + UnlockDisplay(dpy); + SyncHandle(); + if (major_rtrn) + *major_rtrn = rep.serverMajor; + if (minor_rtrn) + *minor_rtrn = rep.serverMinor; + return False; + } + } +#ifdef DEBUG + else if (forceIgnore) { + fprintf(stderr, + "Internal Error! XkbUseExtension succeeded with forceIgnore set\n"); + } +#endif + UnlockDisplay(dpy); + xkbi->srv_major = rep.serverMajor; + xkbi->srv_minor = rep.serverMinor; + if (major_rtrn) + *major_rtrn = rep.serverMajor; + if (minor_rtrn) + *minor_rtrn = rep.serverMinor; + if (debugMsg) + fprintf(stderr, "XKEYBOARD (version %d.%02d/%d.%02d) OK!\n", + XkbMajorVersion, XkbMinorVersion, + rep.serverMajor, rep.serverMinor); + + ev_base = codes->first_event; + XESetWireToEvent(dpy, ev_base + XkbEventCode, wire_to_event); + SyncHandle(); + return True; +} diff --git a/nx-X11/lib/src/xkb/XKBleds.c b/nx-X11/lib/src/xkb/XKBleds.c new file mode 100644 index 000000000..c098ee948 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBleds.c @@ -0,0 +1,338 @@ +/************************************************************ +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. + +********************************************************/ + +#define NEED_MAP_READERS +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include <nx-X11/extensions/XKBproto.h> +#include "XKBlibint.h" + +Status +XkbGetIndicatorState(Display *dpy, unsigned deviceSpec, unsigned *pStateRtrn) +{ + register xkbGetIndicatorStateReq *req; + xkbGetIndicatorStateReply rep; + XkbInfoPtr xkbi; + Bool ok; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetIndicatorState, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetIndicatorState; + req->deviceSpec = deviceSpec; + ok = _XReply(dpy, (xReply *) &rep, 0, xFalse); + if (ok && (pStateRtrn != NULL)) + *pStateRtrn = rep.state; + UnlockDisplay(dpy); + SyncHandle(); + return (ok ? Success : BadImplementation); +} + +Status +_XkbReadGetIndicatorMapReply(Display *dpy, + xkbGetIndicatorMapReply *rep, + XkbDescPtr xkb, + int *nread_rtrn) +{ + XkbIndicatorPtr leds; + XkbReadBufferRec buf; + + if ((!xkb->indicators) && (XkbAllocIndicatorMaps(xkb) != Success)) + return BadAlloc; + leds = xkb->indicators; + + leds->phys_indicators = rep->realIndicators; + if (rep->length > 0) { + register int left; + + if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) + return BadAlloc; + if (nread_rtrn) + *nread_rtrn = (int) rep->length * 4; + if (rep->which) { + register int i, bit; + + left = (int) rep->which; + for (i = 0, bit = 1; (i < XkbNumIndicators) && (left); + i++, bit <<= 1) { + if (left & bit) { + xkbIndicatorMapWireDesc *wire; + + wire = (xkbIndicatorMapWireDesc *) + _XkbGetReadBufferPtr(&buf, + SIZEOF(xkbIndicatorMapWireDesc)); + if (wire == NULL) { + _XkbFreeReadBuffer(&buf); + return BadAlloc; + } + leds->maps[i].flags = wire->flags; + leds->maps[i].which_groups = wire->whichGroups; + leds->maps[i].groups = wire->groups; + leds->maps[i].which_mods = wire->whichMods; + leds->maps[i].mods.mask = wire->mods; + leds->maps[i].mods.real_mods = wire->realMods; + leds->maps[i].mods.vmods = wire->virtualMods; + leds->maps[i].ctrls = wire->ctrls; + left &= ~bit; + } + } + } + left = _XkbFreeReadBuffer(&buf); + } + return Success; +} + +Bool +XkbGetIndicatorMap(Display *dpy, unsigned long which, XkbDescPtr xkb) +{ + register xkbGetIndicatorMapReq *req; + xkbGetIndicatorMapReply rep; + XkbInfoPtr xkbi; + Status status; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return BadAccess; + if ((!which) || (!xkb)) + return BadValue; + + LockDisplay(dpy); + xkbi = dpy->xkb_info; + if (!xkb->indicators) { + xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); + if (!xkb->indicators) { + UnlockDisplay(dpy); + SyncHandle(); + return BadAlloc; + } + } + GetReq(kbGetIndicatorMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetIndicatorMap; + req->deviceSpec = xkb->device_spec; + req->which = (CARD32) which; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return BadValue; + } + status = _XkbReadGetIndicatorMapReply(dpy, &rep, xkb, NULL); + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +Bool +XkbSetIndicatorMap(Display *dpy, unsigned long which, XkbDescPtr xkb) +{ + register xkbSetIndicatorMapReq *req; + register int i, bit; + int nMaps; + xkbIndicatorMapWireDesc *wire; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + if ((!xkb) || (!which) || (!xkb->indicators)) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetIndicatorMap, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetIndicatorMap; + req->deviceSpec = xkb->device_spec; + req->which = (CARD32) which; + for (i = nMaps = 0, bit = 1; i < 32; i++, bit <<= 1) { + if (which & bit) + nMaps++; + } + req->length += (nMaps * sizeof(XkbIndicatorMapRec)) / 4; + BufAlloc(xkbIndicatorMapWireDesc *, wire, + (nMaps * SIZEOF(xkbIndicatorMapWireDesc))); + for (i = 0, bit = 1; i < 32; i++, bit <<= 1) { + if (which & bit) { + wire->flags = xkb->indicators->maps[i].flags; + wire->whichGroups = xkb->indicators->maps[i].which_groups; + wire->groups = xkb->indicators->maps[i].groups; + wire->whichMods = xkb->indicators->maps[i].which_mods; + wire->mods = xkb->indicators->maps[i].mods.real_mods; + wire->virtualMods = xkb->indicators->maps[i].mods.vmods; + wire->ctrls = xkb->indicators->maps[i].ctrls; + wire++; + } + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbGetNamedDeviceIndicator(Display *dpy, + unsigned device, + unsigned class, + unsigned id, + Atom name, + int *pNdxRtrn, + Bool *pStateRtrn, + XkbIndicatorMapPtr pMapRtrn, + Bool *pRealRtrn) +{ + register xkbGetNamedIndicatorReq *req; + xkbGetNamedIndicatorReply rep; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (name == None) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbGetNamedIndicator, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbGetNamedIndicator; + req->deviceSpec = device; + req->ledClass = class; + req->ledID = id; + req->indicator = (CARD32) name; + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if ((!rep.found) || (!rep.supported)) + return False; + if (pNdxRtrn != NULL) + *pNdxRtrn = rep.ndx; + if (pStateRtrn != NULL) + *pStateRtrn = rep.on; + if (pMapRtrn != NULL) { + pMapRtrn->flags = rep.flags; + pMapRtrn->which_groups = rep.whichGroups; + pMapRtrn->groups = rep.groups; + pMapRtrn->which_mods = rep.whichMods; + pMapRtrn->mods.mask = rep.mods; + pMapRtrn->mods.real_mods = rep.realMods; + pMapRtrn->mods.vmods = rep.virtualMods; + pMapRtrn->ctrls = rep.ctrls; + } + if (pRealRtrn != NULL) + *pRealRtrn = rep.realIndicator; + return True; +} + +Bool +XkbGetNamedIndicator(Display *dpy, + Atom name, + int *pNdxRtrn, + Bool *pStateRtrn, + XkbIndicatorMapPtr pMapRtrn, + Bool *pRealRtrn) +{ + return XkbGetNamedDeviceIndicator(dpy, XkbUseCoreKbd, + XkbDfltXIClass, XkbDfltXIId, + name, pNdxRtrn, pStateRtrn, + pMapRtrn, pRealRtrn); +} + +Bool +XkbSetNamedDeviceIndicator(Display *dpy, + unsigned device, + unsigned class, + unsigned id, + Atom name, + Bool changeState, + Bool state, + Bool createNewMap, + XkbIndicatorMapPtr pMap) +{ + register xkbSetNamedIndicatorReq *req; + XkbInfoPtr xkbi; + + if ((dpy->flags & XlibDisplayNoXkb) || (name == None) || + (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) + return False; + LockDisplay(dpy); + xkbi = dpy->xkb_info; + GetReq(kbSetNamedIndicator, req); + req->reqType = xkbi->codes->major_opcode; + req->xkbReqType = X_kbSetNamedIndicator; + req->deviceSpec = device; + req->ledClass = class; + req->ledID = id; + req->indicator = (CARD32) name; + req->setState = changeState; + if (req->setState) + req->on = state; + else + req->on = False; + if (pMap != NULL) { + req->setMap = True; + req->createMap = createNewMap; + req->flags = pMap->flags; + req->whichGroups = pMap->which_groups; + req->groups = pMap->groups; + req->whichMods = pMap->which_mods; + req->realMods = pMap->mods.real_mods; + req->virtualMods = pMap->mods.vmods; + req->ctrls = pMap->ctrls; + } + else { + req->setMap = False; + req->createMap = False; + req->flags = 0; + req->whichGroups = 0; + req->groups = 0; + req->whichMods = 0; + req->realMods = 0; + req->virtualMods = 0; + req->ctrls = 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool +XkbSetNamedIndicator(Display *dpy, + Atom name, + Bool changeState, + Bool state, + Bool createNewMap, + XkbIndicatorMapPtr pMap) +{ + return XkbSetNamedDeviceIndicator(dpy, XkbUseCoreKbd, + XkbDfltXIClass, XkbDfltXIId, + name, changeState, state, + createNewMap, pMap); +} diff --git a/nx-X11/lib/src/xkb/XKBlibint.h b/nx-X11/lib/src/xkb/XKBlibint.h new file mode 100644 index 000000000..dad48b703 --- /dev/null +++ b/nx-X11/lib/src/xkb/XKBlibint.h @@ -0,0 +1,337 @@ +/************************************************************ +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. + +********************************************************/ + +#ifndef _XKBLIBINT_H_ +#define _XKBLIBINT_H_ + +#include <nx-X11/Xutil.h> +#include <nx-X11/XKBlib.h> + +#define XkbMapPending (1<<0) +#define XkbXlibNewKeyboard (1<<1) + +typedef int (*XkbKSToMBFunc)( + XPointer /* priv */, + KeySym /* sym */, + char * /* buf */, + int /* len */, + int * /* extra_rtrn */ +); + +typedef KeySym (*XkbMBToKSFunc)( + XPointer /* priv */, + char * /* buf */, + int /* len */, + Status * /* status */ +); + +typedef KeySym (*XkbToUpperFunc)( + KeySym /* sym */ +); + +typedef struct _XkbConverters { + XkbKSToMBFunc KSToMB; + XPointer KSToMBPriv; + XkbMBToKSFunc MBToKS; + XPointer MBToKSPriv; + XkbToUpperFunc KSToUpper; +} XkbConverters; + +extern XkbInternAtomFunc _XkbInternAtomFunc; +extern XkbGetAtomNameFunc _XkbGetAtomNameFunc; + +typedef struct _XkbInfoRec { + unsigned flags; + unsigned xlib_ctrls; + XExtCodes *codes; + int srv_major; + int srv_minor; + unsigned selected_events; + unsigned short selected_nkn_details; + unsigned short selected_map_details; + XkbDescRec *desc; + XkbMapChangesRec changes; + Atom composeLED; + XkbConverters cvt; + XkbConverters latin1cvt; +} XkbInfoRec, *XkbInfoPtr; + + +#define _XkbUnavailable(d) \ + (((d)->flags&XlibDisplayNoXkb) || \ + ((!(d)->xkb_info || (!(d)->xkb_info->desc)) && !_XkbLoadDpy(d))) + +#define _XkbCheckPendingRefresh(d,xi) { \ + if ((xi)->flags&XkbXlibNewKeyboard) \ + _XkbReloadDpy((d)); \ + else if ((xi)->flags&XkbMapPending) { \ + if (XkbGetMapChanges((d),(xi)->desc, &(xi)->changes)==Success) { \ + LockDisplay((d)); \ + (xi)->changes.changed= 0; \ + UnlockDisplay((d)); \ + } \ + } \ +} + +#define _XkbNeedModmap(i) ((!(i)->desc->map)||(!(i)->desc->map->modmap)) + + /* + * mask of the events that the "invisible" XKB support in Xlib needs + */ +#define XKB_XLIB_MAP_MASK (XkbAllClientInfoMask) + + /* + * Handy helper macros + */ + +typedef struct _XkbReadBuffer { + int error; + int size; + char *start; + char *data; +} XkbReadBufferRec, *XkbReadBufferPtr; + +#define _XkbAlloc(s) Xmalloc((s)) +#define _XkbCalloc(n,s) Xcalloc((n),(s)) +#define _XkbRealloc(o,s) Xrealloc((o),(s)) +#define _XkbTypedAlloc(t) ((t *)Xmalloc(sizeof(t))) +#define _XkbTypedCalloc(n,t) ((t *)Xcalloc((n),sizeof(t))) +#define _XkbTypedRealloc(o,n,t) \ + ((o) ? (t *)Xrealloc((o), (n)*sizeof(t)) : _XkbTypedCalloc(n,t)) +#define _XkbClearElems(a,f,l,t) bzero(&(a)[f], ((l)-(f)+1) * sizeof(t)) +#define _XkbFree(p) Xfree(p) + +_XFUNCPROTOBEGIN + +extern void _XkbReloadDpy( + Display * /* dpy */ +); + +extern KeySym _XKeycodeToKeysym( + Display * /* display */, +#if NeedWidePrototypes + unsigned int /* keycode */, +#else + KeyCode /* keycode */, +#endif + int /* index */ +); + +extern KeyCode _XKeysymToKeycode( + Display * /* display */, + KeySym /* keysym */ +); + +extern KeySym _XLookupKeysym( + XKeyEvent * /* key_event */, + int /* index */ +); + +extern int _XRefreshKeyboardMapping( + XMappingEvent * /* event_map */ +); + +extern unsigned _XKeysymToModifiers( + Display * /* dpy */, + KeySym /* ks */ +); + +extern int _XTranslateKey( + register Display * /* dpy */, + KeyCode /* keycode */, + register unsigned int /* modifiers */, + unsigned int * /* modifiers_return */, + KeySym * /* keysym_return */ +); + +extern int _XTranslateKeySym( + Display * /* dpy */, + register KeySym /* symbol */, + unsigned int /* modifiers */, + char * /* buffer */, + int /* nbytes */ +); + +extern int _XLookupString( + register XKeyEvent * /* event */, + char * /* buffer */, + int /* nbytes */, + KeySym * /* keysym */, + XComposeStatus * /* status */ +); + +extern void _XkbNoteCoreMapChanges( + XkbMapChangesRec * /* old */, + XMappingEvent * /* new */, + unsigned int /* wanted */ +); + +extern int _XkbInitReadBuffer( + Display * /* dpy */, + XkbReadBufferPtr /* buf */, + int /* size */ +); + +extern int _XkbSkipReadBufferData( + XkbReadBufferPtr /* from */, + int /* size */ +); + +extern int _XkbCopyFromReadBuffer( + XkbReadBufferPtr /* from */, + char * /* to */, + int /* size */ +); + + +#ifdef LONG64 +extern int _XkbReadCopyData32( + int * /* from */, + long * /* to */, + int /* num_words */ +); + +extern int _XkbWriteCopyData32( + unsigned long * /* from */, + CARD32 * /* to */, + int /* num_words */ +); + +extern int _XkbReadBufferCopy32( + XkbReadBufferPtr /* from */, + long * /* to */, + int /* size */ +); +#else +#define _XkbReadCopyData32(f,t,s) memcpy((char *)(t), (char *)(f), (s)*4) +#define _XkbWriteCopyData32(f,t,s) memcpy((char *)(t), (char *)(f), (s)*4) +#define _XkbReadBufferCopy32(f,t,s) _XkbCopyFromReadBuffer(f, (char *)t, (s)*4) +#endif + +#ifndef NO_DEC_BINARY_COMPATIBILITY +#define XKB_FORCE_INT_KEYSYM 1 +#endif + +#ifdef XKB_FORCE_INT_KEYSYM +extern int _XkbReadCopyKeySyms( + int * /* from */, + KeySym * /* to */, + int /* num_words */ +); + +extern int _XkbWriteCopyKeySyms( + KeySym * /* from */, + CARD32 * /* to */, + int /* num_words */ +); + +extern int _XkbReadBufferCopyKeySyms( + XkbReadBufferPtr /* from */, +#ifndef NO_DEC_BUG_FIX + KeySym * /* to */, +#else + long * /* to */, +#endif + int /* size */ +); +#else +#define _XkbReadCopyKeySyms(f,t,n) _XkbReadCopyData32(f,t,n) +#define _XkbWriteCopyKeySyms(f,t,n) _XkbWriteCopyData32(f,t,n) +#define _XkbReadBufferCopyKeySyms(f,t,s) _XkbReadBufferCopy32(f,t,s) +#endif + +extern char *_XkbPeekAtReadBuffer( + XkbReadBufferPtr /* from */, + int /* size */ +); + +extern char *_XkbGetReadBufferPtr( + XkbReadBufferPtr /* from */, + int /* size */ +); +#define _XkbGetTypedRdBufPtr(b,n,t) ((t *)_XkbGetReadBufferPtr(b,(n)*SIZEOF(t))) + +extern int _XkbFreeReadBuffer( + XkbReadBufferPtr /* buf */ +); + +extern Bool +_XkbGetReadBufferCountedString( + XkbReadBufferPtr /* buf */, + char ** /* rtrn */ +); + +extern char *_XkbGetCharset( + void +); + +extern int _XkbGetConverters( + const char * /* encoding_name */, + XkbConverters * /* cvt_rtrn */ +); + +#ifdef NEED_MAP_READERS + +extern Status _XkbReadGetMapReply( + Display * /* dpy */, + xkbGetMapReply * /* rep */, + XkbDescRec * /* xkb */, + int * /* nread_rtrn */ +); + +extern Status _XkbReadGetCompatMapReply( + Display * /* dpy */, + xkbGetCompatMapReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +); + +extern Status _XkbReadGetIndicatorMapReply( + Display * /* dpy */, + xkbGetIndicatorMapReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +); + +extern Status _XkbReadGetNamesReply( + Display * /* dpy */, + xkbGetNamesReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +); + +extern Status _XkbReadGetGeometryReply( + Display * /* dpy */, + xkbGetGeometryReply * /* rep */, + XkbDescPtr /* xkb */, + int * /* nread_rtrn */ +); + +#endif + +_XFUNCPROTOEND + +#endif /* _XKBLIBINT_H_ */ |