aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/xkb/XKBExtDev.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/xkb/XKBExtDev.c')
-rw-r--r--libX11/src/xkb/XKBExtDev.c823
1 files changed, 823 insertions, 0 deletions
diff --git a/libX11/src/xkb/XKBExtDev.c b/libX11/src/xkb/XKBExtDev.c
new file mode 100644
index 000000000..a22a29981
--- /dev/null
+++ b/libX11/src/xkb/XKBExtDev.c
@@ -0,0 +1,823 @@
+/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */
+/************************************************************
+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.
+
+********************************************************/
+/* $XFree86: xc/lib/X11/XKBExtDev.c,v 3.4 2001/10/28 03:32:33 tsi Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#define NEED_MAP_READERS
+#include "Xlibint.h"
+#include <X11/extensions/XKBproto.h>
+#include "XKBlibint.h"
+#include <X11/extensions/XI.h>
+
+/***====================================================================***/
+
+extern 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;
+ 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) {
+ act= &devi->btn_acts[rep->firstBtnWanted];
+ bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction)));
+ }
+ if (devi->name!=NULL)
+ _XkbFree(devi->name);
+ if (!_XkbGetReadBufferCountedString(&buf,&devi->name))
+ goto BAILOUT;
+ if (rep->nBtnsRtrn>0) {
+ int size;
+ 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)&&(stuff->info!=NULL))
+ _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;
+ 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;
+
+ mwire= (xkbIndicatorMapWireDesc *)wire;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (mapsNeeded&bit) {
+ XkbIndicatorMapPtr map;
+ 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;
+
+ start= wire;
+ if (changes->changed&XkbXI_ButtonActionsMask) {
+ int size;
+ 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;
+}