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