XKBExtDev.c revision 61b2299d
1/* $Xorg: XKBExtDev.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */ 2/************************************************************ 3Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 4 5Permission to use, copy, modify, and distribute this 6software and its documentation for any purpose and without 7fee is hereby granted, provided that the above copyright 8notice appear in all copies and that both that copyright 9notice and this permission notice appear in supporting 10documentation, and that the name of Silicon Graphics not be 11used in advertising or publicity pertaining to distribution 12of the software without specific prior written permission. 13Silicon Graphics makes no representation about the suitability 14of this software for any purpose. It is provided "as is" 15without any express or implied warranty. 16 17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26********************************************************/ 27/* $XFree86: xc/lib/X11/XKBExtDev.c,v 3.4 2001/10/28 03:32:33 tsi Exp $ */ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <stdio.h> 33#define NEED_REPLIES 34#define NEED_EVENTS 35#define NEED_MAP_READERS 36#include "Xlibint.h" 37#include <X11/extensions/XKBproto.h> 38#include "XKBlibint.h" 39#include <X11/extensions/XI.h> 40 41/***====================================================================***/ 42 43extern void 44XkbNoteDeviceChanges( XkbDeviceChangesPtr old, 45 XkbExtensionDeviceNotifyEvent * new, 46 unsigned int wanted) 47{ 48 if ((!old)||(!new)||(!wanted)||((new->reason&wanted)==0)) 49 return; 50 if ((wanted&new->reason)&XkbXI_ButtonActionsMask) { 51 if (old->changed&XkbXI_ButtonActionsMask) { 52 int first,last,newLast; 53 if (new->first_btn<old->first_btn) 54 first= new->first_btn; 55 else first= old->first_btn; 56 last= old->first_btn+old->num_btns-1; 57 newLast= new->first_btn+new->num_btns-1; 58 if (newLast>last) 59 last= newLast; 60 old->first_btn= first; 61 old->num_btns= (last-first)+1; 62 } 63 else { 64 old->changed|= XkbXI_ButtonActionsMask; 65 old->first_btn= new->first_btn; 66 old->num_btns= new->num_btns; 67 } 68 } 69 if ((wanted&new->reason)&XkbXI_IndicatorsMask) { 70 XkbDeviceLedChangesPtr this; 71 if (old->changed&XkbXI_IndicatorsMask) { 72 XkbDeviceLedChangesPtr found; 73 found= NULL; 74 for (this= &old->leds;this&&(!found);this=this->next) { 75 if ((this->led_class==new->led_class)&& 76 (this->led_id==new->led_id)) { 77 found= this; 78 } 79 } 80 if (!found) { 81 found= _XkbTypedCalloc(1,XkbDeviceLedChangesRec); 82 if (!found) 83 return; 84 found->next= old->leds.next; 85 found->led_class= new->led_class; 86 found->led_id= new->led_id; 87 old->leds.next= found; 88 } 89 if ((wanted&new->reason)&XkbXI_IndicatorNamesMask) 90 found->defined= new->leds_defined; 91 } 92 else { 93 old->changed|= ((wanted&new->reason)&XkbXI_IndicatorsMask); 94 old->leds.led_class= new->led_class; 95 old->leds.led_id= new->led_id; 96 old->leds.defined= new->leds_defined; 97 if (old->leds.next) { 98 XkbDeviceLedChangesPtr next; 99 for (this=old->leds.next;this;this=next) { 100 next= this->next; 101 _XkbFree(this); 102 } 103 old->leds.next= NULL; 104 } 105 } 106 } 107 return; 108} 109 110/***====================================================================***/ 111 112static Status 113_XkbReadDeviceLedInfo( XkbReadBufferPtr buf, 114 unsigned present, 115 XkbDeviceInfoPtr devi) 116{ 117register unsigned i,bit; 118XkbDeviceLedInfoPtr devli; 119xkbDeviceLedsWireDesc * wireli; 120 121 wireli= _XkbGetTypedRdBufPtr(buf,1,xkbDeviceLedsWireDesc); 122 if (!wireli) 123 return BadLength; 124 devli= XkbAddDeviceLedInfo(devi,wireli->ledClass,wireli->ledID); 125 if (!devli) 126 return BadAlloc; 127 devli->phys_indicators= wireli->physIndicators; 128 129 if (present&XkbXI_IndicatorStateMask) 130 devli->state= wireli->state; 131 132 if (present&XkbXI_IndicatorNamesMask) { 133 devli->names_present= wireli->namesPresent; 134 if (devli->names_present) { 135 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 136 if (wireli->namesPresent&bit) { 137 if (!_XkbCopyFromReadBuffer(buf,(char *)&devli->names[i],4)) 138 return BadLength; 139 } 140 } 141 } 142 } 143 144 if (present&XkbXI_IndicatorMapsMask) { 145 devli->maps_present= wireli->mapsPresent; 146 if (devli->maps_present) { 147 XkbIndicatorMapPtr im; 148 xkbIndicatorMapWireDesc * wireim; 149 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 150 if (wireli->mapsPresent&bit) { 151 wireim= _XkbGetTypedRdBufPtr(buf,1,xkbIndicatorMapWireDesc); 152 if (!wireim) 153 return BadAlloc; 154 im= &devli->maps[i]; 155 im->flags= wireim->flags; 156 im->which_groups= wireim->whichGroups; 157 im->groups= wireim->groups; 158 im->which_mods= wireim->whichMods; 159 im->mods.mask= wireim->mods; 160 im->mods.real_mods= wireim->realMods; 161 im->mods.vmods= wireim->virtualMods; 162 im->ctrls= wireim->ctrls; 163 } 164 } 165 } 166 } 167 return Success; 168} 169 170static Status 171_XkbReadGetDeviceInfoReply( Display * dpy, 172 xkbGetDeviceInfoReply * rep, 173 XkbDeviceInfoPtr devi) 174{ 175XkbReadBufferRec buf; 176XkbAction * act; 177int tmp; 178 179 if (!_XkbInitReadBuffer(dpy,&buf,(int)rep->length*4)) 180 return BadAlloc; 181 182 if ((rep->totalBtns>0)&&(rep->totalBtns!=devi->num_btns)) { 183 tmp= XkbResizeDeviceButtonActions(devi,rep->totalBtns); 184 if (tmp!=Success) 185 return tmp; 186 } 187 if (rep->nBtnsWanted>0) { 188 act= &devi->btn_acts[rep->firstBtnWanted]; 189 bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); 190 } 191 if (devi->name!=NULL) 192 _XkbFree(devi->name); 193 if (!_XkbGetReadBufferCountedString(&buf,&devi->name)) 194 goto BAILOUT; 195 if (rep->nBtnsRtrn>0) { 196 int size; 197 act= &devi->btn_acts[rep->firstBtnRtrn]; 198 size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); 199 if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) 200 goto BAILOUT; 201 } 202 if (rep->nDeviceLedFBs>0) { 203 register int i; 204 for (i=0;i<rep->nDeviceLedFBs;i++) { 205 if ((tmp= _XkbReadDeviceLedInfo(&buf,rep->present,devi))!=Success) 206 return tmp; 207 } 208 } 209 tmp= _XkbFreeReadBuffer(&buf); 210 if (tmp) 211 fprintf(stderr,"GetDeviceInfo! Bad length (%d extra bytes)\n",tmp); 212 if (tmp || buf.error) 213 return BadLength; 214 return Success; 215BAILOUT: 216 _XkbFreeReadBuffer(&buf); 217 return BadLength; 218} 219 220XkbDeviceInfoPtr 221XkbGetDeviceInfo( Display * dpy, 222 unsigned which, 223 unsigned deviceSpec, 224 unsigned class, 225 unsigned id) 226{ 227 register xkbGetDeviceInfoReq * req; 228 xkbGetDeviceInfoReply rep; 229 Status status; 230 XkbDeviceInfoPtr devi; 231 232 if ((dpy->flags & XlibDisplayNoXkb) || 233 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 234 return NULL; 235 LockDisplay(dpy); 236 GetReq(kbGetDeviceInfo, req); 237 req->reqType = dpy->xkb_info->codes->major_opcode; 238 req->xkbReqType = X_kbGetDeviceInfo; 239 req->deviceSpec = deviceSpec; 240 req->wanted= which; 241 req->allBtns= ((which&XkbXI_ButtonActionsMask)!=0); 242 req->firstBtn= req->nBtns= 0; 243 req->ledClass= class; 244 req->ledID= id; 245 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 246 UnlockDisplay(dpy); 247 SyncHandle(); 248 return NULL; 249 } 250 devi= XkbAllocDeviceInfo(rep.deviceID,rep.totalBtns,rep.nDeviceLedFBs); 251 if (devi) { 252 devi->supported= rep.supported; 253 devi->unsupported= rep.unsupported; 254 devi->type= rep.devType; 255 devi->has_own_state= rep.hasOwnState; 256 devi->dflt_kbd_fb = rep.dfltKbdFB; 257 devi->dflt_led_fb = rep.dfltLedFB; 258 status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 259 if (status!=Success) { 260 XkbFreeDeviceInfo(devi,XkbXI_AllDeviceFeaturesMask,True); 261 devi= NULL; 262 } 263 } 264 UnlockDisplay(dpy); 265 SyncHandle(); 266 return devi; 267} 268 269Status 270XkbGetDeviceInfoChanges( Display * dpy, 271 XkbDeviceInfoPtr devi, 272 XkbDeviceChangesPtr changes) 273{ 274 register xkbGetDeviceInfoReq * req; 275 xkbGetDeviceInfoReply rep; 276 Status status; 277 278 if ((dpy->flags & XlibDisplayNoXkb) || 279 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 280 return BadMatch; 281 if ((changes->changed&XkbXI_AllDeviceFeaturesMask)==0) 282 return Success; 283 changes->changed&= ~XkbXI_AllDeviceFeaturesMask; 284 status= Success; 285 LockDisplay(dpy); 286 while ((changes->changed)&&(status==Success)) { 287 GetReq(kbGetDeviceInfo, req); 288 req->reqType = dpy->xkb_info->codes->major_opcode; 289 req->xkbReqType = X_kbGetDeviceInfo; 290 req->deviceSpec = devi->device_spec; 291 req->wanted= changes->changed; 292 req->allBtns= False; 293 if (changes->changed&XkbXI_ButtonActionsMask) { 294 req->firstBtn= changes->first_btn; 295 req->nBtns= changes->num_btns; 296 changes->changed&= ~XkbXI_ButtonActionsMask; 297 } 298 else req->firstBtn= req->nBtns= 0; 299 if (changes->changed&XkbXI_IndicatorsMask) { 300 req->ledClass= changes->leds.led_class; 301 req->ledID= changes->leds.led_id; 302 if (changes->leds.next==NULL) 303 changes->changed&= ~XkbXI_IndicatorsMask; 304 else { 305 XkbDeviceLedChangesPtr next; 306 next= changes->leds.next; 307 changes->leds= *next; 308 _XkbFree(next); 309 } 310 } 311 else { 312 req->ledClass= XkbDfltXIClass; 313 req->ledID= XkbDfltXIId; 314 } 315 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 316 status= BadLength; 317 break; 318 } 319 devi->supported|= rep.supported; 320 devi->unsupported|= rep.unsupported; 321 devi->type= rep.devType; 322 status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 323 } 324 UnlockDisplay(dpy); 325 SyncHandle(); 326 return status; 327} 328 329Status 330XkbGetDeviceButtonActions( Display * dpy, 331 XkbDeviceInfoPtr devi, 332 Bool all, 333 unsigned int first, 334 unsigned int num) 335{ 336 register xkbGetDeviceInfoReq * req; 337 xkbGetDeviceInfoReply rep; 338 Status status; 339 340 if ((dpy->flags & XlibDisplayNoXkb) || 341 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 342 return BadMatch; 343 if (!devi) 344 return BadValue; 345 LockDisplay(dpy); 346 GetReq(kbGetDeviceInfo, req); 347 req->reqType = dpy->xkb_info->codes->major_opcode; 348 req->xkbReqType = X_kbGetDeviceInfo; 349 req->deviceSpec = devi->device_spec; 350 req->wanted= XkbXI_ButtonActionsMask; 351 req->allBtns= all; 352 req->firstBtn= first; 353 req->nBtns= num; 354 req->ledClass= XkbDfltXIClass; 355 req->ledID= XkbDfltXIId; 356 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 357 UnlockDisplay(dpy); 358 SyncHandle(); 359 return BadLength; 360 } 361 devi->type= rep.devType; 362 devi->supported= rep.supported; 363 devi->unsupported= rep.unsupported; 364 status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 365 UnlockDisplay(dpy); 366 SyncHandle(); 367 return status; 368} 369 370Status 371XkbGetDeviceLedInfo( Display * dpy, 372 XkbDeviceInfoPtr devi, 373 unsigned int ledClass, 374 unsigned int ledId, 375 unsigned int which) 376{ 377 register xkbGetDeviceInfoReq * req; 378 xkbGetDeviceInfoReply rep; 379 Status status; 380 381 if ((dpy->flags & XlibDisplayNoXkb) || 382 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 383 return BadMatch; 384 if (((which&XkbXI_IndicatorsMask)==0)||(which&(~XkbXI_IndicatorsMask))) 385 return BadMatch; 386 if (!devi) 387 return BadValue; 388 LockDisplay(dpy); 389 GetReq(kbGetDeviceInfo, req); 390 req->reqType = dpy->xkb_info->codes->major_opcode; 391 req->xkbReqType = X_kbGetDeviceInfo; 392 req->deviceSpec = devi->device_spec; 393 req->wanted= which; 394 req->allBtns= False; 395 req->firstBtn= req->nBtns= 0; 396 req->ledClass= ledClass; 397 req->ledID= ledId; 398 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 399 UnlockDisplay(dpy); 400 SyncHandle(); 401 return BadLength; 402 } 403 devi->type= rep.devType; 404 devi->supported= rep.supported; 405 devi->unsupported= rep.unsupported; 406 status= _XkbReadGetDeviceInfoReply(dpy,&rep,devi); 407 UnlockDisplay(dpy); 408 SyncHandle(); 409 return status; 410} 411 412/***====================================================================***/ 413 414typedef struct _LedInfoStuff { 415 Bool used; 416 XkbDeviceLedInfoPtr devli; 417} LedInfoStuff; 418 419typedef struct _SetLedStuff { 420 unsigned wanted; 421 int num_info; 422 int dflt_class; 423 LedInfoStuff * dflt_kbd_fb; 424 LedInfoStuff * dflt_led_fb; 425 LedInfoStuff * info; 426} SetLedStuff; 427 428static void 429_InitLedStuff(SetLedStuff *stuff,unsigned wanted,XkbDeviceInfoPtr devi) 430{ 431int i; 432register XkbDeviceLedInfoPtr devli; 433 434 bzero(stuff,sizeof(SetLedStuff)); 435 stuff->wanted= wanted; 436 stuff->dflt_class= XkbXINone; 437 if ((devi->num_leds<1)||((wanted&XkbXI_IndicatorsMask)==0)) 438 return; 439 stuff->info= _XkbTypedCalloc(devi->num_leds,LedInfoStuff); 440 if (!stuff->info) 441 return; 442 stuff->num_info= devi->num_leds; 443 for (devli=&devi->leds[0],i=0;i<devi->num_leds;i++,devli++) { 444 stuff->info[i].devli= devli; 445 if (devli->led_class==KbdFeedbackClass) { 446 stuff->dflt_class= KbdFeedbackClass; 447 if (stuff->dflt_kbd_fb==NULL) 448 stuff->dflt_kbd_fb= &stuff->info[i]; 449 } 450 else if (devli->led_class==LedFeedbackClass) { 451 if (stuff->dflt_class==XkbXINone) 452 stuff->dflt_class= LedFeedbackClass; 453 if (stuff->dflt_led_fb==NULL) 454 stuff->dflt_led_fb= &stuff->info[i]; 455 } 456 } 457 return; 458} 459 460static void 461_FreeLedStuff(SetLedStuff *stuff) 462{ 463 if ((stuff->num_info>0)&&(stuff->info!=NULL)) 464 _XkbFree(stuff->info); 465 bzero(stuff,sizeof(SetLedStuff)); 466 return; 467} 468 469static int 470_XkbSizeLedInfo(unsigned changed,XkbDeviceLedInfoPtr devli) 471{ 472register int i,size; 473register unsigned bit,namesNeeded,mapsNeeded; 474 475 size= SIZEOF(xkbDeviceLedsWireDesc); 476 namesNeeded= mapsNeeded= 0; 477 if (changed&XkbXI_IndicatorNamesMask) 478 namesNeeded= devli->names_present; 479 if (changed&XkbXI_IndicatorMapsMask) 480 mapsNeeded= devli->maps_present; 481 if ((namesNeeded)||(mapsNeeded)) { 482 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 483 if (namesNeeded&bit) 484 size+= 4; /* atoms are 4 bytes on the wire */ 485 if (mapsNeeded&bit) 486 size+= SIZEOF(xkbIndicatorMapWireDesc); 487 } 488 } 489 return size; 490} 491 492static Bool 493_SizeMatches( SetLedStuff * stuff, 494 XkbDeviceLedChangesPtr changes, 495 int * sz_rtrn, 496 int * nleds_rtrn) 497{ 498int i,nMatch,class,id; 499LedInfoStuff * linfo; 500Bool match; 501 502 nMatch= 0; 503 class= changes->led_class; 504 id= changes->led_id; 505 if (class==XkbDfltXIClass) 506 class= stuff->dflt_class; 507 for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { 508 XkbDeviceLedInfoPtr devli; 509 LedInfoStuff * dflt; 510 511 devli= linfo->devli; 512 match= ((class==devli->led_class)||(class==XkbAllXIClasses)); 513 if (devli->led_class==KbdFeedbackClass) dflt= stuff->dflt_kbd_fb; 514 else dflt= stuff->dflt_led_fb; 515 match = (match && (id == devli->led_id)) || 516 (id == XkbAllXIIds) || 517 ((id == XkbDfltXIId) && 518 (linfo == dflt)); 519 if (match) { 520 if (!linfo->used) { 521 *sz_rtrn+= _XkbSizeLedInfo(stuff->wanted,devli); 522 *nleds_rtrn+= 1; 523 linfo->used= True; 524 if ((class!=XkbAllXIClasses)&&(id!=XkbAllXIIds)) 525 return True; 526 } 527 nMatch++; 528 linfo->used= True; 529 } 530 } 531 return (nMatch>0); 532} 533 534/***====================================================================***/ 535 536 537static Status 538_XkbSetDeviceInfoSize( XkbDeviceInfoPtr devi, 539 XkbDeviceChangesPtr changes, 540 SetLedStuff * stuff, 541 int * sz_rtrn, 542 int * num_leds_rtrn) 543{ 544 *sz_rtrn= 0; 545 if ((changes->changed&XkbXI_ButtonActionsMask)&&(changes->num_btns>0)) { 546 if (!XkbXI_LegalDevBtn(devi,(changes->first_btn+changes->num_btns-1))) 547 return BadMatch; 548 *sz_rtrn+= changes->num_btns*SIZEOF(xkbActionWireDesc); 549 } 550 else { 551 changes->changed&= ~XkbXI_ButtonActionsMask; 552 changes->first_btn= changes->num_btns= 0; 553 } 554 if ((changes->changed&XkbXI_IndicatorsMask)&& 555 XkbLegalXILedClass(changes->leds.led_class)) { 556 XkbDeviceLedChangesPtr leds; 557 558 for (leds=&changes->leds;leds!=NULL;leds= leds->next) { 559 if (!_SizeMatches(stuff,leds,sz_rtrn,num_leds_rtrn)) 560 return BadMatch; 561 } 562 } 563 else { 564 changes->changed&= ~XkbXI_IndicatorsMask; 565 *num_leds_rtrn= 0; 566 } 567 return Success; 568} 569 570static char * 571_XkbWriteLedInfo(char *wire,unsigned changed,XkbDeviceLedInfoPtr devli) 572{ 573register int i; 574register unsigned bit,namesNeeded,mapsNeeded; 575xkbDeviceLedsWireDesc * lwire; 576 577 namesNeeded= mapsNeeded= 0; 578 if (changed&XkbXI_IndicatorNamesMask) 579 namesNeeded= devli->names_present; 580 if (changed&XkbXI_IndicatorMapsMask) 581 mapsNeeded= devli->maps_present; 582 583 lwire= (xkbDeviceLedsWireDesc *)wire; 584 lwire->ledClass= devli->led_class; 585 lwire->ledID= devli->led_id; 586 lwire->namesPresent= namesNeeded; 587 lwire->mapsPresent= mapsNeeded; 588 lwire->physIndicators= devli->phys_indicators; 589 lwire->state= devli->state; 590 wire= (char *)&lwire[1]; 591 if (namesNeeded) { 592 CARD32 *awire; 593 awire= (CARD32 *)wire; 594 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 595 if (namesNeeded&bit) { 596 *awire= (CARD32)devli->names[i]; 597 awire++; 598 } 599 } 600 wire= (char *)awire; 601 } 602 if (mapsNeeded) { 603 xkbIndicatorMapWireDesc *mwire; 604 605 mwire= (xkbIndicatorMapWireDesc *)wire; 606 for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 607 if (mapsNeeded&bit) { 608 XkbIndicatorMapPtr map; 609 map= &devli->maps[i]; 610 mwire->flags= map->flags; 611 mwire->whichGroups= map->which_groups; 612 mwire->groups= map->groups; 613 mwire->whichMods= map->which_mods; 614 mwire->mods= map->mods.mask; 615 mwire->realMods= map->mods.real_mods; 616 mwire->virtualMods= map->mods.vmods; 617 mwire->ctrls= map->ctrls; 618 mwire++; 619 } 620 } 621 wire= (char *)mwire; 622 } 623 return wire; 624} 625 626 627static int 628_XkbWriteSetDeviceInfo( char * wire, 629 XkbDeviceChangesPtr changes, 630 SetLedStuff * stuff, 631 XkbDeviceInfoPtr devi) 632{ 633char *start; 634 635 start= wire; 636 if (changes->changed&XkbXI_ButtonActionsMask) { 637 int size; 638 size= changes->num_btns*SIZEOF(xkbActionWireDesc); 639 memcpy(wire,(char *)&devi->btn_acts[changes->first_btn],size); 640 wire+= size; 641 } 642 if (changes->changed&XkbXI_IndicatorsMask) { 643 register int i; 644 register LedInfoStuff *linfo; 645 646 for (i=0,linfo=&stuff->info[0];i<stuff->num_info;i++,linfo++) { 647 if (linfo->used) { 648 register char *new_wire; 649 new_wire= _XkbWriteLedInfo(wire,stuff->wanted,linfo->devli); 650 if (!new_wire) 651 return wire-start; 652 wire= new_wire; 653 } 654 } 655 } 656 return wire-start; 657} 658 659Bool 660XkbSetDeviceInfo( Display * dpy, 661 unsigned which, 662 XkbDeviceInfoPtr devi) 663{ 664 register xkbSetDeviceInfoReq *req; 665 Status ok = 0; 666 int size,nLeds; 667 XkbInfoPtr xkbi; 668 XkbDeviceChangesRec changes; 669 SetLedStuff lstuff; 670 671 if ((dpy->flags & XlibDisplayNoXkb) || 672 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 673 return False; 674 if ((!devi) || (which&(~XkbXI_AllDeviceFeaturesMask)) || 675 ((which&XkbXI_ButtonActionsMask)&&(!XkbXI_DevHasBtnActs(devi)))|| 676 ((which&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) 677 return False; 678 679 bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); 680 changes.changed= which; 681 changes.first_btn= 0; 682 changes.num_btns= devi->num_btns; 683 changes.leds.led_class= XkbAllXIClasses; 684 changes.leds.led_id= XkbAllXIIds; 685 changes.leds.defined= 0; 686 size= nLeds= 0; 687 _InitLedStuff(&lstuff,changes.changed,devi); 688 if (_XkbSetDeviceInfoSize(devi,&changes,&lstuff,&size,&nLeds)!=Success) 689 return False; 690 LockDisplay(dpy); 691 xkbi = dpy->xkb_info; 692 GetReq(kbSetDeviceInfo, req); 693 req->length+= size/4; 694 req->reqType= xkbi->codes->major_opcode; 695 req->xkbReqType= X_kbSetDeviceInfo; 696 req->deviceSpec= devi->device_spec; 697 req->firstBtn= changes.first_btn; 698 req->nBtns= changes.num_btns; 699 req->change= changes.changed; 700 req->nDeviceLedFBs= nLeds; 701 if (size>0) { 702 char * wire; 703 BufAlloc(char *,wire,size); 704 ok= (wire!=NULL)&& 705 (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); 706 } 707 UnlockDisplay(dpy); 708 SyncHandle(); 709 _FreeLedStuff(&lstuff); 710 /* 12/11/95 (ef) -- XXX!! should clear changes here */ 711 return ok; 712} 713 714Bool 715XkbChangeDeviceInfo( Display * dpy, 716 XkbDeviceInfoPtr devi, 717 XkbDeviceChangesPtr changes) 718{ 719 register xkbSetDeviceInfoReq *req; 720 Status ok = 0; 721 int size,nLeds; 722 XkbInfoPtr xkbi; 723 SetLedStuff lstuff; 724 725 if ((dpy->flags & XlibDisplayNoXkb) || 726 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 727 return False; 728 if ((!devi) || (changes->changed&(~XkbXI_AllDeviceFeaturesMask)) || 729 ((changes->changed&XkbXI_ButtonActionsMask)&& 730 (!XkbXI_DevHasBtnActs(devi)))|| 731 ((changes->changed&XkbXI_IndicatorsMask)&&(!XkbXI_DevHasLeds(devi)))) 732 return False; 733 734 size= nLeds= 0; 735 _InitLedStuff(&lstuff,changes->changed,devi); 736 if (_XkbSetDeviceInfoSize(devi,changes,&lstuff,&size,&nLeds)!=Success) 737 return False; 738 LockDisplay(dpy); 739 xkbi = dpy->xkb_info; 740 GetReq(kbSetDeviceInfo, req); 741 req->length+= size/4; 742 req->reqType= xkbi->codes->major_opcode; 743 req->xkbReqType= X_kbSetDeviceInfo; 744 req->deviceSpec= devi->device_spec; 745 req->firstBtn= changes->first_btn; 746 req->nBtns= changes->num_btns; 747 req->change= changes->changed; 748 req->nDeviceLedFBs= nLeds; 749 if (size>0) { 750 char * wire; 751 BufAlloc(char *,wire,size); 752 ok= (wire!=NULL)&& 753 (_XkbWriteSetDeviceInfo(wire,changes,&lstuff,devi)==size); 754 } 755 UnlockDisplay(dpy); 756 SyncHandle(); 757 _FreeLedStuff(&lstuff); 758 /* 12/11/95 (ef) -- XXX!! should clear changes here */ 759 return ok; 760} 761 762Bool 763XkbSetDeviceLedInfo( Display * dpy, 764 XkbDeviceInfoPtr devi, 765 unsigned ledClass, 766 unsigned ledID, 767 unsigned which) 768{ 769 return False; 770} 771 772Bool 773XkbSetDeviceButtonActions( Display * dpy, 774 XkbDeviceInfoPtr devi, 775 unsigned int first, 776 unsigned int nBtns) 777{ 778 register xkbSetDeviceInfoReq *req; 779 Status ok = 0; 780 int size,nLeds; 781 XkbInfoPtr xkbi; 782 XkbDeviceChangesRec changes; 783 SetLedStuff lstuff; 784 785 if ((dpy->flags & XlibDisplayNoXkb) || 786 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))) 787 return False; 788 if ((!devi)||(!XkbXI_DevHasBtnActs(devi))||(first+nBtns>devi->num_btns)) 789 return False; 790 if (nBtns==0) 791 return True; 792 793 bzero((char *)&changes,sizeof(XkbDeviceChangesRec)); 794 changes.changed= XkbXI_ButtonActionsMask; 795 changes.first_btn= first; 796 changes.num_btns= nBtns; 797 changes.leds.led_class= XkbXINone; 798 changes.leds.led_id= XkbXINone; 799 changes.leds.defined= 0; 800 size= nLeds= 0; 801 if (_XkbSetDeviceInfoSize(devi,&changes,NULL,&size,&nLeds)!=Success) 802 return False; 803 LockDisplay(dpy); 804 xkbi = dpy->xkb_info; 805 GetReq(kbSetDeviceInfo, req); 806 req->length+= size/4; 807 req->reqType= xkbi->codes->major_opcode; 808 req->xkbReqType= X_kbSetDeviceInfo; 809 req->deviceSpec= devi->device_spec; 810 req->firstBtn= changes.first_btn; 811 req->nBtns= changes.num_btns; 812 req->change= changes.changed; 813 req->nDeviceLedFBs= nLeds; 814 if (size>0) { 815 char * wire; 816 BufAlloc(char *,wire,size); 817 ok= (wire!=NULL)&& 818 (_XkbWriteSetDeviceInfo(wire,&changes,&lstuff,devi)==size); 819 } 820 UnlockDisplay(dpy); 821 SyncHandle(); 822 return ok; 823} 824