diff options
Diffstat (limited to 'libX11/src/xkb/XKBExtDev.c')
-rw-r--r-- | libX11/src/xkb/XKBExtDev.c | 1640 |
1 files changed, 819 insertions, 821 deletions
diff --git a/libX11/src/xkb/XKBExtDev.c b/libX11/src/xkb/XKBExtDev.c index e8157b95b..b762747e6 100644 --- a/libX11/src/xkb/XKBExtDev.c +++ b/libX11/src/xkb/XKBExtDev.c @@ -1,821 +1,819 @@ -/************************************************************ -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_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; -} +/************************************************************
+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 <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;
+}
|