aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/src/xkb
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-07-21 12:31:09 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-08-25 10:06:49 +0200
commitc350873c7c977efe5210484f04160be45f84ba7e (patch)
tree717d33eb315f4def1307d65108d14715696cd5cf /nx-X11/lib/src/xkb
parent1472e7e37838f17b7ed948fa206e8c3434a9d346 (diff)
downloadnx-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.am46
-rw-r--r--nx-X11/lib/src/xkb/XKB.c771
-rw-r--r--nx-X11/lib/src/xkb/XKBAlloc.c495
-rw-r--r--nx-X11/lib/src/xkb/XKBBell.c179
-rw-r--r--nx-X11/lib/src/xkb/XKBBind.c784
-rw-r--r--nx-X11/lib/src/xkb/XKBCompat.c252
-rw-r--r--nx-X11/lib/src/xkb/XKBCtrls.c351
-rw-r--r--nx-X11/lib/src/xkb/XKBCvt.c341
-rw-r--r--nx-X11/lib/src/xkb/XKBExtDev.c843
-rw-r--r--nx-X11/lib/src/xkb/XKBGAlloc.c994
-rw-r--r--nx-X11/lib/src/xkb/XKBGeom.c724
-rw-r--r--nx-X11/lib/src/xkb/XKBGetByName.c226
-rw-r--r--nx-X11/lib/src/xkb/XKBGetMap.c882
-rw-r--r--nx-X11/lib/src/xkb/XKBList.c256
-rw-r--r--nx-X11/lib/src/xkb/XKBMAlloc.c1016
-rw-r--r--nx-X11/lib/src/xkb/XKBMisc.c1021
-rw-r--r--nx-X11/lib/src/xkb/XKBNames.c879
-rw-r--r--nx-X11/lib/src/xkb/XKBRdBuf.c203
-rw-r--r--nx-X11/lib/src/xkb/XKBSetGeom.c478
-rw-r--r--nx-X11/lib/src/xkb/XKBSetMap.c598
-rw-r--r--nx-X11/lib/src/xkb/XKBUse.c814
-rw-r--r--nx-X11/lib/src/xkb/XKBleds.c338
-rw-r--r--nx-X11/lib/src/xkb/XKBlibint.h337
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,
+ &section->num_overlays, &section->sz_overlays,
+ (char **) &section->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,
+ &section->num_rows, &section->sz_rows,
+ (char **) &section->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 = &section->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 = &section->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 = &section->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 = &section->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 = &section->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 *) &sectionWire[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, &section->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_ */