aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/src/xkb/XKBNames.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/src/xkb/XKBNames.c')
-rw-r--r--nx-X11/lib/src/xkb/XKBNames.c879
1 files changed, 879 insertions, 0 deletions
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;
+}