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