XKBExtDev.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */ 21ab64890Smrg/************************************************************ 31ab64890SmrgCopyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 41ab64890Smrg 51ab64890SmrgPermission to use, copy, modify, and distribute this 61ab64890Smrgsoftware and its documentation for any purpose and without 71ab64890Smrgfee is hereby granted, provided that the above copyright 81ab64890Smrgnotice appear in all copies and that both that copyright 91ab64890Smrgnotice and this permission notice appear in supporting 1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1161b2299dSmrgused in advertising or publicity pertaining to distribution 121ab64890Smrgof the software without specific prior written permission. 1361b2299dSmrgSilicon Graphics makes no representation about the suitability 141ab64890Smrgof this software for any purpose. It is provided "as is" 151ab64890Smrgwithout any express or implied warranty. 161ab64890Smrg 1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 251ab64890Smrg 261ab64890Smrg********************************************************/ 271ab64890Smrg/* $XFree86: xc/lib/X11/XKBExtDev.c,v 3.4 2001/10/28 03:32:33 tsi Exp $ */ 281ab64890Smrg 291ab64890Smrg#ifdef HAVE_CONFIG_H 301ab64890Smrg#include <config.h> 311ab64890Smrg#endif 321ab64890Smrg#include <stdio.h> 331ab64890Smrg#define NEED_REPLIES 341ab64890Smrg#define NEED_EVENTS 351ab64890Smrg#define NEED_MAP_READERS 361ab64890Smrg#include "Xlibint.h" 371ab64890Smrg#include <X11/extensions/XKBproto.h> 381ab64890Smrg#include "XKBlibint.h" 391ab64890Smrg#include <X11/extensions/XI.h> 401ab64890Smrg 411ab64890Smrg/***====================================================================***/ 421ab64890Smrg 431ab64890Smrgextern void 441ab64890SmrgXkbNoteDeviceChanges( XkbDeviceChangesPtr old, 451ab64890Smrg XkbExtensionDeviceNotifyEvent * new, 461ab64890Smrg unsigned int wanted) 471ab64890Smrg{ 481ab64890Smrg if ((!old)||(!new)||(!wanted)||((new->reason&wanted)==0)) 491ab64890Smrg return; 501ab64890Smrg if ((wanted&new->reason)&XkbXI_ButtonActionsMask) { 511ab64890Smrg if (old->changed&XkbXI_ButtonActionsMask) { 521ab64890Smrg int first,last,newLast; 531ab64890Smrg if (new->first_btn<old->first_btn) 541ab64890Smrg first= new->first_btn; 551ab64890Smrg else first= old->first_btn; 561ab64890Smrg last= old->first_btn+old->num_btns-1; 571ab64890Smrg newLast= new->first_btn+new->num_btns-1; 581ab64890Smrg if (newLast>last) 591ab64890Smrg last= newLast; 601ab64890Smrg old->first_btn= first; 611ab64890Smrg old->num_btns= (last-first)+1; 621ab64890Smrg } 631ab64890Smrg else { 641ab64890Smrg old->changed|= XkbXI_ButtonActionsMask; 651ab64890Smrg old->first_btn= new->first_btn; 661ab64890Smrg old->num_btns= new->num_btns; 671ab64890Smrg } 681ab64890Smrg } 691ab64890Smrg if ((wanted&new->reason)&XkbXI_IndicatorsMask) { 701ab64890Smrg XkbDeviceLedChangesPtr this; 711ab64890Smrg if (old->changed&XkbXI_IndicatorsMask) { 721ab64890Smrg XkbDeviceLedChangesPtr found; 731ab64890Smrg found= NULL; 741ab64890Smrg for (this= &old->leds;this&&(!found);this=this->next) { 751ab64890Smrg if ((this->led_class==new->led_class)&& 761ab64890Smrg (this->led_id==new->led_id)) { 771ab64890Smrg found= this; 781ab64890Smrg } 791ab64890Smrg } 801ab64890Smrg if (!found) { 811ab64890Smrg found= _XkbTypedCalloc(1,XkbDeviceLedChangesRec); 821ab64890Smrg if (!found) 831ab64890Smrg return; 841ab64890Smrg found->next= old->leds.next; 851ab64890Smrg found->led_class= new->led_class; 861ab64890Smrg found->led_id= new->led_id; 871ab64890Smrg old->leds.next= found; 881ab64890Smrg } 891ab64890Smrg if ((wanted&new->reason)&XkbXI_IndicatorNamesMask) 901ab64890Smrg found->defined= new->leds_defined; 911ab64890Smrg } 921ab64890Smrg else { 931ab64890Smrg old->changed|= ((wanted&new->reason)&XkbXI_IndicatorsMask); 941ab64890Smrg old->leds.led_class= new->led_class; 951ab64890Smrg old->leds.led_id= new->led_id; 961ab64890Smrg old->leds.defined= new->leds_defined; 971ab64890Smrg if (old->leds.next) { 981ab64890Smrg XkbDeviceLedChangesPtr next; 991ab64890Smrg for (this=old->leds.next;this;this=next) { 1001ab64890Smrg next= this->next; 1011ab64890Smrg _XkbFree(this); 1021ab64890Smrg } 1031ab64890Smrg old->leds.next= NULL; 1041ab64890Smrg } 1051ab64890Smrg } 1061ab64890Smrg } 1071ab64890Smrg return; 1081ab64890Smrg} 1091ab64890Smrg 1101ab64890Smrg/***====================================================================***/ 1111ab64890Smrg 1121ab64890Smrgstatic Status 1131ab64890Smrg_XkbReadDeviceLedInfo( XkbReadBufferPtr buf, 1141ab64890Smrg unsigned present, 1151ab64890Smrg XkbDeviceInfoPtr devi) 1161ab64890Smrg{ 1171ab64890Smrgregister unsigned i,bit; 1181ab64890SmrgXkbDeviceLedInfoPtr devli; 1191ab64890SmrgxkbDeviceLedsWireDesc * wireli; 1201ab64890Smrg 1211ab64890Smrg wireli= _XkbGetTypedRdBufPtr(buf,1,xkbDeviceLedsWireDesc); 1221ab64890Smrg if (!wireli) 1231ab64890Smrg return BadLength; 1241ab64890Smrg devli= XkbAddDeviceLedInfo(devi,wireli->ledClass,wireli->ledID); 1251ab64890Smrg if (!devli) 1261ab64890Smrg return BadAlloc; 1271ab64890Smrg devli->phys_indicators= wireli->physIndicators; 1281ab64890Smrg 1291ab64890Smrg if (present&XkbXI_IndicatorStateMask) 1301ab64890Smrg devli->state= wireli->state; 1311ab64890Smrg 1321ab64890Smrg if (present&XkbXI_IndicatorNamesMask) { 1331ab64890Smrg devli->names_present= wireli->namesPresent; 1341ab64890Smrg if (devli->names_present) { 1351ab64890Smrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 1361ab64890Smrg if (wireli->namesPresent&bit) { 1371ab64890Smrg if (!_XkbCopyFromReadBuffer(buf,(char *)&devli->names[i],4)) 1381ab64890Smrg return BadLength; 1391ab64890Smrg } 1401ab64890Smrg } 1411ab64890Smrg } 1421ab64890Smrg } 1431ab64890Smrg 1441ab64890Smrg if (present&XkbXI_IndicatorMapsMask) { 1451ab64890Smrg devli->maps_present= wireli->mapsPresent; 1461ab64890Smrg if (devli->maps_present) { 1471ab64890Smrg XkbIndicatorMapPtr im; 1481ab64890Smrg xkbIndicatorMapWireDesc * wireim; 1491ab64890Smrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 1501ab64890Smrg if (wireli->mapsPresent&bit) { 1511ab64890Smrg wireim= _XkbGetTypedRdBufPtr(buf,1,xkbIndicatorMapWireDesc); 1521ab64890Smrg if (!wireim) 1531ab64890Smrg return BadAlloc; 1541ab64890Smrg im= &devli->maps[i]; 1551ab64890Smrg im->flags= wireim->flags; 1561ab64890Smrg im->which_groups= wireim->whichGroups; 1571ab64890Smrg im->groups= wireim->groups; 1581ab64890Smrg im->which_mods= wireim->whichMods; 1591ab64890Smrg im->mods.mask= wireim->mods; 1601ab64890Smrg im->mods.real_mods= wireim->realMods; 1611ab64890Smrg im->mods.vmods= wireim->virtualMods; 1621ab64890Smrg im->ctrls= wireim->ctrls; 1631ab64890Smrg } 1641ab64890Smrg } 1651ab64890Smrg } 1661ab64890Smrg } 1671ab64890Smrg return Success; 1681ab64890Smrg} 1691ab64890Smrg 1701ab64890Smrgstatic Status 1711ab64890Smrg_XkbReadGetDeviceInfoReply( Display * dpy, 1721ab64890Smrg xkbGetDeviceInfoReply * rep, 1731ab64890Smrg XkbDeviceInfoPtr devi) 1741ab64890Smrg{ 1751ab64890SmrgXkbReadBufferRec buf; 1761ab64890SmrgXkbAction * act; 1771ab64890Smrgint tmp; 1781ab64890Smrg 17961b2299dSmrg if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 1801ab64890Smrg return BadAlloc; 1811ab64890Smrg 1821ab64890Smrg if ((rep->totalBtns>0)&&(rep->totalBtns!=devi->num_btns)) { 1831ab64890Smrg tmp= XkbResizeDeviceButtonActions(devi,rep->totalBtns); 1841ab64890Smrg if (tmp!=Success) 1851ab64890Smrg return tmp; 1861ab64890Smrg } 1871ab64890Smrg if (rep->nBtnsWanted>0) { 1881ab64890Smrg act= &devi->btn_acts[rep->firstBtnWanted]; 1891ab64890Smrg bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); 1901ab64890Smrg } 1911ab64890Smrg if (devi->name!=NULL) 1921ab64890Smrg _XkbFree(devi->name); 1931ab64890Smrg if (!_XkbGetReadBufferCountedString(&buf,&devi->name)) 1941ab64890Smrg goto BAILOUT; 1951ab64890Smrg if (rep->nBtnsRtrn>0) { 1961ab64890Smrg int size; 1971ab64890Smrg act= &devi->btn_acts[rep->firstBtnRtrn]; 1981ab64890Smrg size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); 1991ab64890Smrg if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) 2001ab64890Smrg goto BAILOUT; 2011ab64890Smrg } 2021ab64890Smrg if (rep->nDeviceLedFBs>0) { 2031ab64890Smrg register int i; 2041ab64890Smrg for (i=0;i<rep->nDeviceLedFBs;i++) { 2051ab64890Smrg if ((tmp= _XkbReadDeviceLedInfo(&buf,rep->present,devi))!=Success) 2061ab64890Smrg return tmp; 2071ab64890Smrg } 2081ab64890Smrg } 2091ab64890Smrg tmp= _XkbFreeReadBuffer(&buf); 21061b2299dSmrg if (tmp) 2111ab64890Smrg fprintf(stderr,"GetDeviceInfo! Bad length (%d extra bytes)\n",tmp); 2121ab64890Smrg if (tmp || buf.error) 2131ab64890Smrg return BadLength; 2141ab64890Smrg return Success; 2151ab64890SmrgBAILOUT: 2161ab64890Smrg _XkbFreeReadBuffer(&buf); 2171ab64890Smrg return BadLength; 2181ab64890Smrg} 2191ab64890Smrg 2201ab64890SmrgXkbDeviceInfoPtr 2211ab64890SmrgXkbGetDeviceInfo( Display * dpy, 2221ab64890Smrg unsigned which, 2231ab64890Smrg unsigned deviceSpec, 2241ab64890Smrg unsigned class, 2251ab64890Smrg unsigned id) 2261ab64890Smrg{ 2271ab64890Smrg register xkbGetDeviceInfoReq * req; 2281ab64890Smrg xkbGetDeviceInfoReply rep; 2291ab64890Smrg Status status; 2301ab64890Smrg XkbDeviceInfoPtr devi; 2311ab64890Smrg 2321ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 2331ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 2341ab64890Smrg return NULL; 2351ab64890Smrg LockDisplay(dpy); 2361ab64890Smrg GetReq(kbGetDeviceInfo, req); 2371ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 2381ab64890Smrg req->xkbReqType = X_kbGetDeviceInfo; 2391ab64890Smrg req->deviceSpec = deviceSpec; 2401ab64890Smrg req->wanted= which; 2411ab64890Smrg req->allBtns= ((which&XkbXI_ButtonActionsMask)!=0); 2421ab64890Smrg req->firstBtn= req->nBtns= 0; 2431ab64890Smrg req->ledClass= class; 2441ab64890Smrg req->ledID= id; 2451ab64890Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 2461ab64890Smrg UnlockDisplay(dpy); 2471ab64890Smrg SyncHandle(); 2481ab64890Smrg return NULL; 2491ab64890Smrg } 2501ab64890Smrg devi= XkbAllocDeviceInfo(rep.deviceID,rep.totalBtns,rep.nDeviceLedFBs); 2511ab64890Smrg if (devi) { 2521ab64890Smrg devi->supported= rep.supported; 2531ab64890Smrg devi->unsupported= rep.unsupported; 2541ab64890Smrg devi->type= rep.devType; 2551ab64890Smrg devi->has_own_state= rep.hasOwnState; 2561ab64890Smrg devi->dflt_kbd_fb = rep.dfltKbdFB; 2571ab64890Smrg devi->dflt_led_fb = rep.dfltLedFB; 2581ab64890Smrg status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 2591ab64890Smrg if (status!=Success) { 2601ab64890Smrg XkbFreeDeviceInfo(devi,XkbXI_AllDeviceFeaturesMask,True); 2611ab64890Smrg devi= NULL; 2621ab64890Smrg } 2631ab64890Smrg } 2641ab64890Smrg UnlockDisplay(dpy); 2651ab64890Smrg SyncHandle(); 2661ab64890Smrg return devi; 2671ab64890Smrg} 2681ab64890Smrg 2691ab64890SmrgStatus 2701ab64890SmrgXkbGetDeviceInfoChanges( Display * dpy, 2711ab64890Smrg XkbDeviceInfoPtr devi, 2721ab64890Smrg XkbDeviceChangesPtr changes) 2731ab64890Smrg{ 2741ab64890Smrg register xkbGetDeviceInfoReq * req; 2751ab64890Smrg xkbGetDeviceInfoReply rep; 2761ab64890Smrg Status status; 2771ab64890Smrg 2781ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 2791ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 2801ab64890Smrg return BadMatch; 2811ab64890Smrg if ((changes->changed&XkbXI_AllDeviceFeaturesMask)==0) 2821ab64890Smrg return Success; 2831ab64890Smrg changes->changed&= ~XkbXI_AllDeviceFeaturesMask; 2841ab64890Smrg status= Success; 2851ab64890Smrg LockDisplay(dpy); 2861ab64890Smrg while ((changes->changed)&&(status==Success)) { 2871ab64890Smrg GetReq(kbGetDeviceInfo, req); 2881ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 2891ab64890Smrg req->xkbReqType = X_kbGetDeviceInfo; 2901ab64890Smrg req->deviceSpec = devi->device_spec; 2911ab64890Smrg req->wanted= changes->changed; 2921ab64890Smrg req->allBtns= False; 2931ab64890Smrg if (changes->changed&XkbXI_ButtonActionsMask) { 2941ab64890Smrg req->firstBtn= changes->first_btn; 2951ab64890Smrg req->nBtns= changes->num_btns; 2961ab64890Smrg changes->changed&= ~XkbXI_ButtonActionsMask; 2971ab64890Smrg } 2981ab64890Smrg else req->firstBtn= req->nBtns= 0; 2991ab64890Smrg if (changes->changed&XkbXI_IndicatorsMask) { 3001ab64890Smrg req->ledClass= changes->leds.led_class; 3011ab64890Smrg req->ledID= changes->leds.led_id; 3021ab64890Smrg if (changes->leds.next==NULL) 3031ab64890Smrg changes->changed&= ~XkbXI_IndicatorsMask; 3041ab64890Smrg else { 3051ab64890Smrg XkbDeviceLedChangesPtr next; 3061ab64890Smrg next= changes->leds.next; 3071ab64890Smrg changes->leds= *next; 3081ab64890Smrg _XkbFree(next); 3091ab64890Smrg } 3101ab64890Smrg } 3111ab64890Smrg else { 3121ab64890Smrg req->ledClass= XkbDfltXIClass; 3131ab64890Smrg req->ledID= XkbDfltXIId; 3141ab64890Smrg } 3151ab64890Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 3161ab64890Smrg status= BadLength; 3171ab64890Smrg break; 3181ab64890Smrg } 3191ab64890Smrg devi->supported|= rep.supported; 3201ab64890Smrg devi->unsupported|= rep.unsupported; 3211ab64890Smrg devi->type= rep.devType; 3221ab64890Smrg status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 3231ab64890Smrg } 3241ab64890Smrg UnlockDisplay(dpy); 3251ab64890Smrg SyncHandle(); 3261ab64890Smrg return status; 3271ab64890Smrg} 3281ab64890Smrg 3291ab64890SmrgStatus 3301ab64890SmrgXkbGetDeviceButtonActions( Display * dpy, 3311ab64890Smrg XkbDeviceInfoPtr devi, 3321ab64890Smrg Bool all, 3331ab64890Smrg unsigned int first, 3341ab64890Smrg unsigned int num) 3351ab64890Smrg{ 3361ab64890Smrg register xkbGetDeviceInfoReq * req; 3371ab64890Smrg xkbGetDeviceInfoReply rep; 3381ab64890Smrg Status status; 3391ab64890Smrg 34061b2299dSmrg if ((dpy->flags & XlibDisplayNoXkb) || 3411ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 3421ab64890Smrg return BadMatch; 3431ab64890Smrg if (!devi) 3441ab64890Smrg return BadValue; 3451ab64890Smrg LockDisplay(dpy); 3461ab64890Smrg GetReq(kbGetDeviceInfo, req); 3471ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 3481ab64890Smrg req->xkbReqType = X_kbGetDeviceInfo; 3491ab64890Smrg req->deviceSpec = devi->device_spec; 3501ab64890Smrg req->wanted= XkbXI_ButtonActionsMask; 3511ab64890Smrg req->allBtns= all; 3521ab64890Smrg req->firstBtn= first; 3531ab64890Smrg req->nBtns= num; 3541ab64890Smrg req->ledClass= XkbDfltXIClass; 3551ab64890Smrg req->ledID= XkbDfltXIId; 3561ab64890Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 3571ab64890Smrg UnlockDisplay(dpy); 3581ab64890Smrg SyncHandle(); 3591ab64890Smrg return BadLength; 3601ab64890Smrg } 3611ab64890Smrg devi->type= rep.devType; 3621ab64890Smrg devi->supported= rep.supported; 3631ab64890Smrg devi->unsupported= rep.unsupported; 3641ab64890Smrg status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 3651ab64890Smrg UnlockDisplay(dpy); 3661ab64890Smrg SyncHandle(); 3671ab64890Smrg return status; 3681ab64890Smrg} 3691ab64890Smrg 3701ab64890SmrgStatus 3711ab64890SmrgXkbGetDeviceLedInfo( Display * dpy, 3721ab64890Smrg XkbDeviceInfoPtr devi, 3731ab64890Smrg unsigned int ledClass, 3741ab64890Smrg unsigned int ledId, 3751ab64890Smrg unsigned int which) 3761ab64890Smrg{ 3771ab64890Smrg register xkbGetDeviceInfoReq * req; 3781ab64890Smrg xkbGetDeviceInfoReply rep; 3791ab64890Smrg Status status; 3801ab64890Smrg 38161b2299dSmrg if ((dpy->flags & XlibDisplayNoXkb) || 3821ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 3831ab64890Smrg return BadMatch; 3841ab64890Smrg if (((which&XkbXI_IndicatorsMask)==0)||(which&(~XkbXI_IndicatorsMask))) 3851ab64890Smrg return BadMatch; 3861ab64890Smrg if (!devi) 3871ab64890Smrg return BadValue; 3881ab64890Smrg LockDisplay(dpy); 3891ab64890Smrg GetReq(kbGetDeviceInfo, req); 3901ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 3911ab64890Smrg req->xkbReqType = X_kbGetDeviceInfo; 3921ab64890Smrg req->deviceSpec = devi->device_spec; 3931ab64890Smrg req->wanted= which; 3941ab64890Smrg req->allBtns= False; 3951ab64890Smrg req->firstBtn= req->nBtns= 0; 3961ab64890Smrg req->ledClass= ledClass; 3971ab64890Smrg req->ledID= ledId; 3981ab64890Smrg if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 3991ab64890Smrg UnlockDisplay(dpy); 4001ab64890Smrg SyncHandle(); 4011ab64890Smrg return BadLength; 40261b2299dSmrg } 4031ab64890Smrg devi->type= rep.devType; 4041ab64890Smrg devi->supported= rep.supported; 4051ab64890Smrg devi->unsupported= rep.unsupported; 4061ab64890Smrg status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 4071ab64890Smrg UnlockDisplay(dpy); 4081ab64890Smrg SyncHandle(); 4091ab64890Smrg return status; 4101ab64890Smrg} 4111ab64890Smrg 4121ab64890Smrg/***====================================================================***/ 4131ab64890Smrg 4141ab64890Smrgtypedef struct _LedInfoStuff { 4151ab64890Smrg Bool used; 4161ab64890Smrg XkbDeviceLedInfoPtr devli; 4171ab64890Smrg} LedInfoStuff; 4181ab64890Smrg 4191ab64890Smrgtypedef struct _SetLedStuff { 4201ab64890Smrg unsigned wanted; 4211ab64890Smrg int num_info; 4221ab64890Smrg int dflt_class; 4231ab64890Smrg LedInfoStuff * dflt_kbd_fb; 4241ab64890Smrg LedInfoStuff * dflt_led_fb; 4251ab64890Smrg LedInfoStuff * info; 4261ab64890Smrg} SetLedStuff; 4271ab64890Smrg 4281ab64890Smrgstatic void 4291ab64890Smrg_InitLedStuff(SetLedStuff *stuff,unsigned wanted,XkbDeviceInfoPtr devi) 4301ab64890Smrg{ 4311ab64890Smrgint i; 4321ab64890Smrgregister XkbDeviceLedInfoPtr devli; 4331ab64890Smrg 4341ab64890Smrg bzero(stuff,sizeof(SetLedStuff)); 4351ab64890Smrg stuff->wanted= wanted; 4361ab64890Smrg stuff->dflt_class= XkbXINone; 4371ab64890Smrg if ((devi->num_leds<1)||((wanted&XkbXI_IndicatorsMask)==0)) 4381ab64890Smrg return; 4391ab64890Smrg stuff->info= _XkbTypedCalloc(devi->num_leds,LedInfoStuff); 4401ab64890Smrg if (!stuff->info) 4411ab64890Smrg return; 4421ab64890Smrg stuff->num_info= devi->num_leds; 4431ab64890Smrg for (devli=&devi->leds[0],i=0;i<devi->num_leds;i++,devli++) { 4441ab64890Smrg stuff->info[i].devli= devli; 4451ab64890Smrg if (devli->led_class==KbdFeedbackClass) { 4461ab64890Smrg stuff->dflt_class= KbdFeedbackClass; 4471ab64890Smrg if (stuff->dflt_kbd_fb==NULL) 4481ab64890Smrg stuff->dflt_kbd_fb= &stuff->info[i]; 4491ab64890Smrg } 4501ab64890Smrg else if (devli->led_class==LedFeedbackClass) { 4511ab64890Smrg if (stuff->dflt_class==XkbXINone) 4521ab64890Smrg stuff->dflt_class= LedFeedbackClass; 4531ab64890Smrg if (stuff->dflt_led_fb==NULL) 4541ab64890Smrg stuff->dflt_led_fb= &stuff->info[i]; 4551ab64890Smrg } 4561ab64890Smrg } 4571ab64890Smrg return; 4581ab64890Smrg} 4591ab64890Smrg 4601ab64890Smrgstatic void 4611ab64890Smrg_FreeLedStuff(SetLedStuff *stuff) 4621ab64890Smrg{ 4631ab64890Smrg if ((stuff->num_info>0)&&(stuff->info!=NULL)) 4641ab64890Smrg _XkbFree(stuff->info); 4651ab64890Smrg bzero(stuff,sizeof(SetLedStuff)); 4661ab64890Smrg return; 4671ab64890Smrg} 4681ab64890Smrg 4691ab64890Smrgstatic int 4701ab64890Smrg_XkbSizeLedInfo(unsigned changed,XkbDeviceLedInfoPtr devli) 4711ab64890Smrg{ 4721ab64890Smrgregister int i,size; 4731ab64890Smrgregister unsigned bit,namesNeeded,mapsNeeded; 4741ab64890Smrg 4751ab64890Smrg size= SIZEOF(xkbDeviceLedsWireDesc); 4761ab64890Smrg namesNeeded= mapsNeeded= 0; 4771ab64890Smrg if (changed&XkbXI_IndicatorNamesMask) 4781ab64890Smrg namesNeeded= devli->names_present; 4791ab64890Smrg if (changed&XkbXI_IndicatorMapsMask) 4801ab64890Smrg mapsNeeded= devli->maps_present; 4811ab64890Smrg if ((namesNeeded)||(mapsNeeded)) { 4821ab64890Smrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 4831ab64890Smrg if (namesNeeded&bit) 4841ab64890Smrg size+= 4; /* atoms are 4 bytes on the wire */ 4851ab64890Smrg if (mapsNeeded&bit) 4861ab64890Smrg size+= SIZEOF(xkbIndicatorMapWireDesc); 4871ab64890Smrg } 4881ab64890Smrg } 4891ab64890Smrg return size; 4901ab64890Smrg} 4911ab64890Smrg 4921ab64890Smrgstatic Bool 4931ab64890Smrg_SizeMatches( SetLedStuff * stuff, 4941ab64890Smrg XkbDeviceLedChangesPtr changes, 4951ab64890Smrg int * sz_rtrn, 4961ab64890Smrg int * nleds_rtrn) 4971ab64890Smrg{ 4981ab64890Smrgint i,nMatch,class,id; 4991ab64890SmrgLedInfoStuff * linfo; 5001ab64890SmrgBool match; 5011ab64890Smrg 5021ab64890Smrg nMatch= 0; 5031ab64890Smrg class= changes->led_class; 5041ab64890Smrg id= changes->led_id; 5051ab64890Smrg if (class==XkbDfltXIClass) 5061ab64890Smrg class= stuff->dflt_class; 5071ab64890Smrg for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { 5081ab64890Smrg XkbDeviceLedInfoPtr devli; 5091ab64890Smrg LedInfoStuff * dflt; 5101ab64890Smrg 5111ab64890Smrg devli= linfo->devli; 5121ab64890Smrg match= ((class==devli->led_class)||(class==XkbAllXIClasses)); 5131ab64890Smrg if (devli->led_class==KbdFeedbackClass) dflt= stuff->dflt_kbd_fb; 5141ab64890Smrg else dflt= stuff->dflt_led_fb; 5151ab64890Smrg match = (match && (id == devli->led_id)) || 5161ab64890Smrg (id == XkbAllXIIds) || 5171ab64890Smrg ((id == XkbDfltXIId) && 5181ab64890Smrg (linfo == dflt)); 5191ab64890Smrg if (match) { 5201ab64890Smrg if (!linfo->used) { 5211ab64890Smrg *sz_rtrn+= _XkbSizeLedInfo(stuff->wanted,devli); 5221ab64890Smrg *nleds_rtrn+= 1; 5231ab64890Smrg linfo->used= True; 5241ab64890Smrg if ((class!=XkbAllXIClasses)&&(id!=XkbAllXIIds)) 5251ab64890Smrg return True; 5261ab64890Smrg } 5271ab64890Smrg nMatch++; 5281ab64890Smrg linfo->used= True; 5291ab64890Smrg } 5301ab64890Smrg } 5311ab64890Smrg return (nMatch>0); 5321ab64890Smrg} 5331ab64890Smrg 5341ab64890Smrg/***====================================================================***/ 5351ab64890Smrg 5361ab64890Smrg 5371ab64890Smrgstatic Status 5381ab64890Smrg_XkbSetDeviceInfoSize( XkbDeviceInfoPtr devi, 5391ab64890Smrg XkbDeviceChangesPtr changes, 5401ab64890Smrg SetLedStuff * stuff, 5411ab64890Smrg int * sz_rtrn, 5421ab64890Smrg int * num_leds_rtrn) 5431ab64890Smrg{ 5441ab64890Smrg *sz_rtrn= 0; 5451ab64890Smrg if ((changes->changed&XkbXI_ButtonActionsMask)&&(changes->num_btns>0)) { 5461ab64890Smrg if (!XkbXI_LegalDevBtn(devi,(changes->first_btn+changes->num_btns-1))) 5471ab64890Smrg return BadMatch; 5481ab64890Smrg *sz_rtrn+= changes->num_btns*SIZEOF(xkbActionWireDesc); 5491ab64890Smrg } 5501ab64890Smrg else { 5511ab64890Smrg changes->changed&= ~XkbXI_ButtonActionsMask; 5521ab64890Smrg changes->first_btn= changes->num_btns= 0; 5531ab64890Smrg } 5541ab64890Smrg if ((changes->changed&XkbXI_IndicatorsMask)&& 5551ab64890Smrg XkbLegalXILedClass(changes->leds.led_class)) { 5561ab64890Smrg XkbDeviceLedChangesPtr leds; 5571ab64890Smrg 5581ab64890Smrg for (leds=&changes->leds;leds!=NULL;leds= leds->next) { 5591ab64890Smrg if (!_SizeMatches(stuff,leds,sz_rtrn,num_leds_rtrn)) 5601ab64890Smrg return BadMatch; 5611ab64890Smrg } 5621ab64890Smrg } 5631ab64890Smrg else { 5641ab64890Smrg changes->changed&= ~XkbXI_IndicatorsMask; 5651ab64890Smrg *num_leds_rtrn= 0; 5661ab64890Smrg } 5671ab64890Smrg return Success; 5681ab64890Smrg} 5691ab64890Smrg 5701ab64890Smrgstatic char * 5711ab64890Smrg_XkbWriteLedInfo(char *wire,unsigned changed,XkbDeviceLedInfoPtr devli) 5721ab64890Smrg{ 5731ab64890Smrgregister int i; 5741ab64890Smrgregister unsigned bit,namesNeeded,mapsNeeded; 5751ab64890SmrgxkbDeviceLedsWireDesc * lwire; 5761ab64890Smrg 5771ab64890Smrg namesNeeded= mapsNeeded= 0; 5781ab64890Smrg if (changed&XkbXI_IndicatorNamesMask) 5791ab64890Smrg namesNeeded= devli->names_present; 5801ab64890Smrg if (changed&XkbXI_IndicatorMapsMask) 5811ab64890Smrg mapsNeeded= devli->maps_present; 5821ab64890Smrg 5831ab64890Smrg lwire= (xkbDeviceLedsWireDesc *)wire; 5841ab64890Smrg lwire->ledClass= devli->led_class; 5851ab64890Smrg lwire->ledID= devli->led_id; 5861ab64890Smrg lwire->namesPresent= namesNeeded; 5871ab64890Smrg lwire->mapsPresent= mapsNeeded; 5881ab64890Smrg lwire->physIndicators= devli->phys_indicators; 5891ab64890Smrg lwire->state= devli->state; 5901ab64890Smrg wire= (char *)&lwire[1]; 5911ab64890Smrg if (namesNeeded) { 5921ab64890Smrg CARD32 *awire; 5931ab64890Smrg awire= (CARD32 *)wire; 5941ab64890Smrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 5951ab64890Smrg if (namesNeeded&bit) { 5961ab64890Smrg *awire= (CARD32)devli->names[i]; 5971ab64890Smrg awire++; 5981ab64890Smrg } 5991ab64890Smrg } 6001ab64890Smrg wire= (char *)awire; 6011ab64890Smrg } 6021ab64890Smrg if (mapsNeeded) { 6031ab64890Smrg xkbIndicatorMapWireDesc *mwire; 6041ab64890Smrg 6051ab64890Smrg mwire= (xkbIndicatorMapWireDesc *)wire; 6061ab64890Smrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 6071ab64890Smrg if (mapsNeeded&bit) { 6081ab64890Smrg XkbIndicatorMapPtr map; 6091ab64890Smrg map= &devli->maps[i]; 6101ab64890Smrg mwire->flags= map->flags; 6111ab64890Smrg mwire->whichGroups= map->which_groups; 6121ab64890Smrg mwire->groups= map->groups; 6131ab64890Smrg mwire->whichMods= map->which_mods; 6141ab64890Smrg mwire->mods= map->mods.mask; 6151ab64890Smrg mwire->realMods= map->mods.real_mods; 6161ab64890Smrg mwire->virtualMods= map->mods.vmods; 6171ab64890Smrg mwire->ctrls= map->ctrls; 6181ab64890Smrg mwire++; 6191ab64890Smrg } 6201ab64890Smrg } 6211ab64890Smrg wire= (char *)mwire; 6221ab64890Smrg } 6231ab64890Smrg return wire; 6241ab64890Smrg} 6251ab64890Smrg 6261ab64890Smrg 6271ab64890Smrgstatic int 6281ab64890Smrg_XkbWriteSetDeviceInfo( char * wire, 6291ab64890Smrg XkbDeviceChangesPtr changes, 6301ab64890Smrg SetLedStuff * stuff, 6311ab64890Smrg XkbDeviceInfoPtr devi) 6321ab64890Smrg{ 6331ab64890Smrgchar *start; 6341ab64890Smrg 6351ab64890Smrg start= wire; 6361ab64890Smrg if (changes->changed&XkbXI_ButtonActionsMask) { 6371ab64890Smrg int size; 6381ab64890Smrg size= changes->num_btns*SIZEOF(xkbActionWireDesc); 6391ab64890Smrg memcpy(wire,(char *)&devi->btn_acts[changes->first_btn],size); 6401ab64890Smrg wire+= size; 6411ab64890Smrg } 6421ab64890Smrg if (changes->changed&XkbXI_IndicatorsMask) { 6431ab64890Smrg register int i; 6441ab64890Smrg register LedInfoStuff *linfo; 6451ab64890Smrg 6461ab64890Smrg for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { 6471ab64890Smrg if (linfo->used) { 6481ab64890Smrg register char *new_wire; 6491ab64890Smrg new_wire= _XkbWriteLedInfo(wire,stuff->wanted,linfo->devli); 6501ab64890Smrg if (!new_wire) 6511ab64890Smrg return wire-start; 6521ab64890Smrg wire= new_wire; 6531ab64890Smrg } 6541ab64890Smrg } 6551ab64890Smrg } 6561ab64890Smrg return wire-start; 6571ab64890Smrg} 6581ab64890Smrg 6591ab64890SmrgBool 6601ab64890SmrgXkbSetDeviceInfo( Display * dpy, 6611ab64890Smrg unsigned which, 6621ab64890Smrg XkbDeviceInfoPtr devi) 6631ab64890Smrg{ 6641ab64890Smrg register xkbSetDeviceInfoReq *req; 6651ab64890Smrg Status ok = 0; 6661ab64890Smrg int size,nLeds; 6671ab64890Smrg XkbInfoPtr xkbi; 6681ab64890Smrg XkbDeviceChangesRec changes; 6691ab64890Smrg SetLedStuff lstuff; 6701ab64890Smrg 6711ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 6721ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 6731ab64890Smrg return False; 6741ab64890Smrg if ((!devi) || (which&(~XkbXI_AllDeviceFeaturesMask)) || 6751ab64890Smrg ((which&XkbXI_ButtonActionsMask)&&(!XkbXI_DevHasBtnActs(devi)))|| 6761ab64890Smrg ((which&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) 6771ab64890Smrg return False; 6781ab64890Smrg 6791ab64890Smrg bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); 6801ab64890Smrg changes.changed= which; 6811ab64890Smrg changes.first_btn= 0; 6821ab64890Smrg changes.num_btns= devi->num_btns; 6831ab64890Smrg changes.leds.led_class= XkbAllXIClasses; 6841ab64890Smrg changes.leds.led_id= XkbAllXIIds; 6851ab64890Smrg changes.leds.defined= 0; 6861ab64890Smrg size= nLeds= 0; 6871ab64890Smrg _InitLedStuff(&lstuff,changes.changed,devi); 6881ab64890Smrg if (_XkbSetDeviceInfoSize(devi,&changes,&lstuff,&size,&nLeds)!=Success) 6891ab64890Smrg return False; 6901ab64890Smrg LockDisplay(dpy); 6911ab64890Smrg xkbi = dpy->xkb_info; 6921ab64890Smrg GetReq(kbSetDeviceInfo, req); 6931ab64890Smrg req->length+= size/4; 6941ab64890Smrg req->reqType= xkbi->codes->major_opcode; 6951ab64890Smrg req->xkbReqType= X_kbSetDeviceInfo; 6961ab64890Smrg req->deviceSpec= devi->device_spec; 6971ab64890Smrg req->firstBtn= changes.first_btn; 6981ab64890Smrg req->nBtns= changes.num_btns; 6991ab64890Smrg req->change= changes.changed; 7001ab64890Smrg req->nDeviceLedFBs= nLeds; 7011ab64890Smrg if (size>0) { 7021ab64890Smrg char * wire; 7031ab64890Smrg BufAlloc(char *,wire,size); 7041ab64890Smrg ok= (wire!=NULL)&& 7051ab64890Smrg (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); 7061ab64890Smrg } 7071ab64890Smrg UnlockDisplay(dpy); 7081ab64890Smrg SyncHandle(); 7091ab64890Smrg _FreeLedStuff(&lstuff); 7101ab64890Smrg /* 12/11/95 (ef) -- XXX!! should clear changes here */ 7111ab64890Smrg return ok; 7121ab64890Smrg} 7131ab64890Smrg 7141ab64890SmrgBool 7151ab64890SmrgXkbChangeDeviceInfo( Display * dpy, 7161ab64890Smrg XkbDeviceInfoPtr devi, 7171ab64890Smrg XkbDeviceChangesPtr changes) 7181ab64890Smrg{ 7191ab64890Smrg register xkbSetDeviceInfoReq *req; 7201ab64890Smrg Status ok = 0; 7211ab64890Smrg int size,nLeds; 7221ab64890Smrg XkbInfoPtr xkbi; 7231ab64890Smrg SetLedStuff lstuff; 7241ab64890Smrg 7251ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 7261ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 7271ab64890Smrg return False; 7281ab64890Smrg if ((!devi) || (changes->changed&(~XkbXI_AllDeviceFeaturesMask)) || 7291ab64890Smrg ((changes->changed&XkbXI_ButtonActionsMask)&& 7301ab64890Smrg (!XkbXI_DevHasBtnActs(devi)))|| 7311ab64890Smrg ((changes->changed&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) 7321ab64890Smrg return False; 7331ab64890Smrg 7341ab64890Smrg size= nLeds= 0; 7351ab64890Smrg _InitLedStuff(&lstuff,changes->changed,devi); 7361ab64890Smrg if (_XkbSetDeviceInfoSize(devi,changes,&lstuff,&size,&nLeds)!=Success) 7371ab64890Smrg return False; 7381ab64890Smrg LockDisplay(dpy); 7391ab64890Smrg xkbi = dpy->xkb_info; 7401ab64890Smrg GetReq(kbSetDeviceInfo, req); 7411ab64890Smrg req->length+= size/4; 7421ab64890Smrg req->reqType= xkbi->codes->major_opcode; 7431ab64890Smrg req->xkbReqType= X_kbSetDeviceInfo; 7441ab64890Smrg req->deviceSpec= devi->device_spec; 7451ab64890Smrg req->firstBtn= changes->first_btn; 7461ab64890Smrg req->nBtns= changes->num_btns; 7471ab64890Smrg req->change= changes->changed; 7481ab64890Smrg req->nDeviceLedFBs= nLeds; 7491ab64890Smrg if (size>0) { 7501ab64890Smrg char * wire; 7511ab64890Smrg BufAlloc(char *,wire,size); 7521ab64890Smrg ok= (wire!=NULL)&& 7531ab64890Smrg (_XkbWriteSetDeviceInfo(wire,changes,&lstuff,devi)==size); 7541ab64890Smrg } 7551ab64890Smrg UnlockDisplay(dpy); 7561ab64890Smrg SyncHandle(); 7571ab64890Smrg _FreeLedStuff(&lstuff); 7581ab64890Smrg /* 12/11/95 (ef) -- XXX!! should clear changes here */ 7591ab64890Smrg return ok; 7601ab64890Smrg} 7611ab64890Smrg 76261b2299dSmrgBool 7631ab64890SmrgXkbSetDeviceLedInfo( Display * dpy, 7641ab64890Smrg XkbDeviceInfoPtr devi, 7651ab64890Smrg unsigned ledClass, 7661ab64890Smrg unsigned ledID, 7671ab64890Smrg unsigned which) 7681ab64890Smrg{ 7691ab64890Smrg return False; 7701ab64890Smrg} 7711ab64890Smrg 77261b2299dSmrgBool 7731ab64890SmrgXkbSetDeviceButtonActions( Display * dpy, 7741ab64890Smrg XkbDeviceInfoPtr devi, 7751ab64890Smrg unsigned int first, 7761ab64890Smrg unsigned int nBtns) 7771ab64890Smrg{ 7781ab64890Smrg register xkbSetDeviceInfoReq *req; 7791ab64890Smrg Status ok = 0; 7801ab64890Smrg int size,nLeds; 7811ab64890Smrg XkbInfoPtr xkbi; 7821ab64890Smrg XkbDeviceChangesRec changes; 7831ab64890Smrg SetLedStuff lstuff; 7841ab64890Smrg 7851ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 7861ab64890Smrg (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 7871ab64890Smrg return False; 7881ab64890Smrg if ((!devi)||(!XkbXI_DevHasBtnActs(devi))||(first+nBtns>devi->num_btns)) 7891ab64890Smrg return False; 7901ab64890Smrg if (nBtns==0) 7911ab64890Smrg return True; 7921ab64890Smrg 7931ab64890Smrg bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); 7941ab64890Smrg changes.changed= XkbXI_ButtonActionsMask; 7951ab64890Smrg changes.first_btn= first; 7961ab64890Smrg changes.num_btns= nBtns; 7971ab64890Smrg changes.leds.led_class= XkbXINone; 7981ab64890Smrg changes.leds.led_id= XkbXINone; 7991ab64890Smrg changes.leds.defined= 0; 8001ab64890Smrg size= nLeds= 0; 8011ab64890Smrg if (_XkbSetDeviceInfoSize(devi,&changes,NULL,&size,&nLeds)!=Success) 8021ab64890Smrg return False; 8031ab64890Smrg LockDisplay(dpy); 8041ab64890Smrg xkbi = dpy->xkb_info; 8051ab64890Smrg GetReq(kbSetDeviceInfo, req); 8061ab64890Smrg req->length+= size/4; 8071ab64890Smrg req->reqType= xkbi->codes->major_opcode; 8081ab64890Smrg req->xkbReqType= X_kbSetDeviceInfo; 8091ab64890Smrg req->deviceSpec= devi->device_spec; 8101ab64890Smrg req->firstBtn= changes.first_btn; 8111ab64890Smrg req->nBtns= changes.num_btns; 8121ab64890Smrg req->change= changes.changed; 8131ab64890Smrg req->nDeviceLedFBs= nLeds; 8141ab64890Smrg if (size>0) { 8151ab64890Smrg char * wire; 8161ab64890Smrg BufAlloc(char *,wire,size); 8171ab64890Smrg ok= (wire!=NULL)&& 8181ab64890Smrg (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); 8191ab64890Smrg } 8201ab64890Smrg UnlockDisplay(dpy); 8211ab64890Smrg SyncHandle(); 8221ab64890Smrg return ok; 8231ab64890Smrg} 824