diff options
Diffstat (limited to 'nx-X11/lib/X11/XKBExtDev.c')
-rw-r--r-- | nx-X11/lib/X11/XKBExtDev.c | 823 |
1 files changed, 823 insertions, 0 deletions
diff --git a/nx-X11/lib/X11/XKBExtDev.c b/nx-X11/lib/X11/XKBExtDev.c new file mode 100644 index 000000000..34558e476 --- /dev/null +++ b/nx-X11/lib/X11/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; +} |