1 /* 2 * Copyright (c) 2008 NVIDIA, Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 */ 23 24 /* 25 * Make sure that XTHREADS is defined, so that the 26 * LockDisplay/UnlockDisplay macros are expanded properly and the 27 * libXNVCtrl library properly protects the Display connection. 28 */ 29 30 #if !defined(XTHREADS) 31 #define XTHREADS 32 #endif /* XTHREADS */ 33 34 #define NEED_EVENTS 35 #define NEED_REPLIES 36 #include <stdint.h> 37 #include <stdlib.h> 38 #include <X11/Xlibint.h> 39 #include <X11/Xutil.h> 40 #include <X11/extensions/Xext.h> 41 #include <X11/extensions/extutil.h> 42 #include "NVCtrlLib.h" 43 #include "nv_control.h" 44 45 #define NVCTRL_EXT_EXISTS 1 46 #define NVCTRL_EXT_NEED_TARGET_SWAP 2 47 #define NVCTRL_EXT_64_BIT_ATTRIBUTES 4 48 #define NVCTRL_EXT_NEED_CHECK (1 << (sizeof(XPointer) - 1)) 49 50 static XExtensionInfo _nvctrl_ext_info_data; 51 static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; 52 static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME; 53 54 #define XNVCTRLCheckExtension(dpy,i,val) \ 55 XextCheckExtension (dpy, i, nvctrl_extension_name, val) 56 #define XNVCTRLSimpleCheckExtension(dpy,i) \ 57 XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) 58 59 static int close_display(); 60 static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info); 61 static Bool wire_to_event(); 62 static /* const */ XExtensionHooks nvctrl_extension_hooks = { 63 NULL, /* create_gc */ 64 NULL, /* copy_gc */ 65 NULL, /* flush_gc */ 66 NULL, /* free_gc */ 67 NULL, /* create_font */ 68 NULL, /* free_font */ 69 close_display, /* close_display */ 70 wire_to_event, /* wire_to_event */ 71 NULL, /* event_to_wire */ 72 NULL, /* error */ 73 NULL, /* error_string */ 74 }; 75 76 static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, 77 nvctrl_extension_name, 78 &nvctrl_extension_hooks, 79 NV_CONTROL_EVENTS, 80 (XPointer)NVCTRL_EXT_NEED_CHECK) 81 82 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) 83 84 /* 85 * NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id 86 * fields in reversed order. In order to talk to one of these servers, 87 * we need to swap these fields. 88 */ 89 90 static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info, 91 int *target_type, int *target_id) 92 { 93 uintptr_t flags = version_flags(dpy, info); 94 95 /* We need to swap the target_type and target_id */ 96 if (flags & NVCTRL_EXT_NEED_TARGET_SWAP) { 97 int tmp; 98 tmp = *target_type; 99 *target_type = *target_id; 100 *target_id = tmp; 101 } 102 } 103 104 105 Bool XNVCTRLQueryExtension ( 106 Display *dpy, 107 int *event_basep, 108 int *error_basep 109 ){ 110 XExtDisplayInfo *info = find_display (dpy); 111 112 if (XextHasExtension(info)) { 113 if (event_basep) *event_basep = info->codes->first_event; 114 if (error_basep) *error_basep = info->codes->first_error; 115 return True; 116 } else { 117 return False; 118 } 119 } 120 121 /* 122 * Retrieve any cached flags that depend on the version of the NV-CONTROL 123 * extension. 124 */ 125 126 static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info) 127 { 128 uintptr_t data = (uintptr_t)info->data; 129 130 /* If necessary, determine the NV-CONTROL version */ 131 if (data & NVCTRL_EXT_NEED_CHECK) { 132 int major, minor; 133 data = 0; 134 if (XNVCTRLQueryVersion(dpy, &major, &minor)) { 135 data |= NVCTRL_EXT_EXISTS; 136 if (major == 1 && (minor == 8 || minor == 9)) { 137 data |= NVCTRL_EXT_NEED_TARGET_SWAP; 138 } 139 if ((major > 1) || ((major == 1) && (minor > 20))) { 140 data |= NVCTRL_EXT_64_BIT_ATTRIBUTES; 141 } 142 } 143 144 info->data = (XPointer)data; 145 } 146 147 return data; 148 } 149 150 Bool XNVCTRLQueryVersion ( 151 Display *dpy, 152 int *major, 153 int *minor 154 ){ 155 XExtDisplayInfo *info = find_display (dpy); 156 xnvCtrlQueryExtensionReply rep; 157 xnvCtrlQueryExtensionReq *req; 158 159 if(!XextHasExtension(info)) 160 return False; 161 162 XNVCTRLCheckExtension (dpy, info, False); 163 164 LockDisplay (dpy); 165 GetReq (nvCtrlQueryExtension, req); 166 req->reqType = info->codes->major_opcode; 167 req->nvReqType = X_nvCtrlQueryExtension; 168 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 169 UnlockDisplay (dpy); 170 SyncHandle (); 171 return False; 172 } 173 if (major) *major = rep.major; 174 if (minor) *minor = rep.minor; 175 UnlockDisplay (dpy); 176 SyncHandle (); 177 return True; 178 } 179 180 181 Bool XNVCTRLIsNvScreen ( 182 Display *dpy, 183 int screen 184 ){ 185 XExtDisplayInfo *info = find_display (dpy); 186 xnvCtrlIsNvReply rep; 187 xnvCtrlIsNvReq *req; 188 Bool isnv; 189 190 if(!XextHasExtension(info)) 191 return False; 192 193 XNVCTRLCheckExtension (dpy, info, False); 194 195 LockDisplay (dpy); 196 GetReq (nvCtrlIsNv, req); 197 req->reqType = info->codes->major_opcode; 198 req->nvReqType = X_nvCtrlIsNv; 199 req->screen = screen; 200 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 201 UnlockDisplay (dpy); 202 SyncHandle (); 203 return False; 204 } 205 isnv = rep.isnv; 206 UnlockDisplay (dpy); 207 SyncHandle (); 208 return isnv; 209 } 210 211 212 Bool XNVCTRLQueryTargetCount ( 213 Display *dpy, 214 int target_type, 215 int *value 216 ){ 217 XExtDisplayInfo *info = find_display (dpy); 218 xnvCtrlQueryTargetCountReply rep; 219 xnvCtrlQueryTargetCountReq *req; 220 221 if(!XextHasExtension(info)) 222 return False; 223 224 XNVCTRLCheckExtension (dpy, info, False); 225 226 LockDisplay (dpy); 227 GetReq (nvCtrlQueryTargetCount, req); 228 req->reqType = info->codes->major_opcode; 229 req->nvReqType = X_nvCtrlQueryTargetCount; 230 req->target_type = target_type; 231 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 232 UnlockDisplay (dpy); 233 SyncHandle (); 234 return False; 235 } 236 if (value) *value = rep.count; 237 UnlockDisplay (dpy); 238 SyncHandle (); 239 return True; 240 } 241 242 243 void XNVCTRLSetTargetAttribute ( 244 Display *dpy, 245 int target_type, 246 int target_id, 247 unsigned int display_mask, 248 unsigned int attribute, 249 int value 250 ){ 251 XExtDisplayInfo *info = find_display (dpy); 252 xnvCtrlSetAttributeReq *req; 253 254 XNVCTRLSimpleCheckExtension (dpy, info); 255 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 256 257 LockDisplay (dpy); 258 GetReq (nvCtrlSetAttribute, req); 259 req->reqType = info->codes->major_opcode; 260 req->nvReqType = X_nvCtrlSetAttribute; 261 req->target_type = target_type; 262 req->target_id = target_id; 263 req->display_mask = display_mask; 264 req->attribute = attribute; 265 req->value = value; 266 UnlockDisplay (dpy); 267 SyncHandle (); 268 } 269 270 void XNVCTRLSetAttribute ( 271 Display *dpy, 272 int screen, 273 unsigned int display_mask, 274 unsigned int attribute, 275 int value 276 ){ 277 XNVCTRLSetTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 278 display_mask, attribute, value); 279 } 280 281 282 Bool XNVCTRLSetTargetAttributeAndGetStatus ( 283 Display *dpy, 284 int target_type, 285 int target_id, 286 unsigned int display_mask, 287 unsigned int attribute, 288 int value 289 ){ 290 XExtDisplayInfo *info = find_display (dpy); 291 xnvCtrlSetAttributeAndGetStatusReq *req; 292 xnvCtrlSetAttributeAndGetStatusReply rep; 293 Bool success; 294 295 if(!XextHasExtension(info)) 296 return False; 297 298 XNVCTRLCheckExtension (dpy, info, False); 299 300 LockDisplay (dpy); 301 GetReq (nvCtrlSetAttributeAndGetStatus, req); 302 req->reqType = info->codes->major_opcode; 303 req->nvReqType = X_nvCtrlSetAttributeAndGetStatus; 304 req->target_type = target_type; 305 req->target_id = target_id; 306 req->display_mask = display_mask; 307 req->attribute = attribute; 308 req->value = value; 309 if (!_XReply (dpy, (xReply *) &rep, 0, False)) { 310 UnlockDisplay (dpy); 311 SyncHandle (); 312 return False; 313 } 314 UnlockDisplay (dpy); 315 SyncHandle (); 316 317 success = rep.flags; 318 return success; 319 } 320 321 Bool XNVCTRLSetAttributeAndGetStatus ( 322 Display *dpy, 323 int screen, 324 unsigned int display_mask, 325 unsigned int attribute, 326 int value 327 ){ 328 return XNVCTRLSetTargetAttributeAndGetStatus(dpy, 329 NV_CTRL_TARGET_TYPE_X_SCREEN, 330 screen, display_mask, 331 attribute, value); 332 } 333 334 335 Bool XNVCTRLQueryTargetAttribute ( 336 Display *dpy, 337 int target_type, 338 int target_id, 339 unsigned int display_mask, 340 unsigned int attribute, 341 int *value 342 ){ 343 XExtDisplayInfo *info = find_display (dpy); 344 xnvCtrlQueryAttributeReply rep; 345 xnvCtrlQueryAttributeReq *req; 346 Bool exists; 347 348 if(!XextHasExtension(info)) 349 return False; 350 351 XNVCTRLCheckExtension (dpy, info, False); 352 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 353 354 LockDisplay (dpy); 355 GetReq (nvCtrlQueryAttribute, req); 356 req->reqType = info->codes->major_opcode; 357 req->nvReqType = X_nvCtrlQueryAttribute; 358 req->target_type = target_type; 359 req->target_id = target_id; 360 req->display_mask = display_mask; 361 req->attribute = attribute; 362 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 363 UnlockDisplay (dpy); 364 SyncHandle (); 365 return False; 366 } 367 exists = rep.flags; 368 if (exists && value) *value = rep.value; 369 UnlockDisplay (dpy); 370 SyncHandle (); 371 return exists; 372 } 373 374 Bool XNVCTRLQueryAttribute ( 375 Display *dpy, 376 int screen, 377 unsigned int display_mask, 378 unsigned int attribute, 379 int *value 380 ){ 381 return XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 382 screen, display_mask, attribute, value); 383 } 384 385 386 Bool XNVCTRLQueryTargetAttribute64 ( 387 Display *dpy, 388 int target_type, 389 int target_id, 390 unsigned int display_mask, 391 unsigned int attribute, 392 int64_t *value 393 ){ 394 XExtDisplayInfo *info = find_display(dpy); 395 xnvCtrlQueryAttribute64Reply rep; 396 xnvCtrlQueryAttributeReq *req; 397 Bool exists; 398 399 if (!XextHasExtension(info)) 400 return False; 401 402 XNVCTRLCheckExtension(dpy, info, False); 403 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 404 405 LockDisplay(dpy); 406 GetReq(nvCtrlQueryAttribute, req); 407 req->reqType = info->codes->major_opcode; 408 req->nvReqType = X_nvCtrlQueryAttribute64; 409 req->target_type = target_type; 410 req->target_id = target_id; 411 req->display_mask = display_mask; 412 req->attribute = attribute; 413 if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) { 414 UnlockDisplay(dpy); 415 SyncHandle(); 416 return False; 417 } 418 exists = rep.flags; 419 if (exists && value) *value = rep.value_64; 420 UnlockDisplay(dpy); 421 SyncHandle(); 422 return exists; 423 } 424 425 426 Bool XNVCTRLQueryTargetStringAttribute ( 427 Display *dpy, 428 int target_type, 429 int target_id, 430 unsigned int display_mask, 431 unsigned int attribute, 432 char **ptr 433 ){ 434 XExtDisplayInfo *info = find_display (dpy); 435 xnvCtrlQueryStringAttributeReply rep; 436 xnvCtrlQueryStringAttributeReq *req; 437 Bool exists; 438 int length, numbytes, slop; 439 440 if (!ptr) return False; 441 442 if(!XextHasExtension(info)) 443 return False; 444 445 XNVCTRLCheckExtension (dpy, info, False); 446 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 447 448 LockDisplay (dpy); 449 GetReq (nvCtrlQueryStringAttribute, req); 450 req->reqType = info->codes->major_opcode; 451 req->nvReqType = X_nvCtrlQueryStringAttribute; 452 req->target_type = target_type; 453 req->target_id = target_id; 454 req->display_mask = display_mask; 455 req->attribute = attribute; 456 if (!_XReply (dpy, (xReply *) &rep, 0, False)) { 457 UnlockDisplay (dpy); 458 SyncHandle (); 459 return False; 460 } 461 length = rep.length; 462 numbytes = rep.n; 463 slop = numbytes & 3; 464 exists = rep.flags; 465 if (exists) { 466 *ptr = (char *) Xmalloc(numbytes); 467 } 468 if (!exists || !*ptr) { 469 _XEatData(dpy, length); 470 UnlockDisplay (dpy); 471 SyncHandle (); 472 return False; 473 } else { 474 _XRead(dpy, (char *) *ptr, numbytes); 475 if (slop) _XEatData(dpy, 4-slop); 476 } 477 UnlockDisplay (dpy); 478 SyncHandle (); 479 return exists; 480 } 481 482 Bool XNVCTRLQueryStringAttribute ( 483 Display *dpy, 484 int screen, 485 unsigned int display_mask, 486 unsigned int attribute, 487 char **ptr 488 ){ 489 return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 490 screen, display_mask, 491 attribute, ptr); 492 } 493 494 495 Bool XNVCTRLSetTargetStringAttribute ( 496 Display *dpy, 497 int target_type, 498 int target_id, 499 unsigned int display_mask, 500 unsigned int attribute, 501 char *ptr 502 ){ 503 XExtDisplayInfo *info = find_display (dpy); 504 xnvCtrlSetStringAttributeReq *req; 505 xnvCtrlSetStringAttributeReply rep; 506 int size; 507 Bool success; 508 509 if(!XextHasExtension(info)) 510 return False; 511 512 XNVCTRLCheckExtension (dpy, info, False); 513 514 size = strlen(ptr)+1; 515 516 LockDisplay (dpy); 517 GetReq (nvCtrlSetStringAttribute, req); 518 req->reqType = info->codes->major_opcode; 519 req->nvReqType = X_nvCtrlSetStringAttribute; 520 req->target_type = target_type; 521 req->target_id = target_id; 522 req->display_mask = display_mask; 523 req->attribute = attribute; 524 req->length += ((size + 3) & ~3) >> 2; 525 req->num_bytes = size; 526 Data(dpy, ptr, size); 527 528 if (!_XReply (dpy, (xReply *) &rep, 0, False)) { 529 UnlockDisplay (dpy); 530 SyncHandle (); 531 return False; 532 } 533 UnlockDisplay (dpy); 534 SyncHandle (); 535 536 success = rep.flags; 537 return success; 538 } 539 540 Bool XNVCTRLSetStringAttribute ( 541 Display *dpy, 542 int screen, 543 unsigned int display_mask, 544 unsigned int attribute, 545 char *ptr 546 ){ 547 return XNVCTRLSetTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 548 screen, display_mask, 549 attribute, ptr); 550 } 551 552 553 static Bool XNVCTRLQueryValidTargetAttributeValues32 ( 554 Display *dpy, 555 XExtDisplayInfo *info, 556 int target_type, 557 int target_id, 558 unsigned int display_mask, 559 unsigned int attribute, 560 NVCTRLAttributeValidValuesRec *values 561 ){ 562 xnvCtrlQueryValidAttributeValuesReply rep; 563 xnvCtrlQueryValidAttributeValuesReq *req; 564 Bool exists; 565 566 LockDisplay (dpy); 567 GetReq (nvCtrlQueryValidAttributeValues, req); 568 req->reqType = info->codes->major_opcode; 569 req->nvReqType = X_nvCtrlQueryValidAttributeValues; 570 req->target_type = target_type; 571 req->target_id = target_id; 572 req->display_mask = display_mask; 573 req->attribute = attribute; 574 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 575 UnlockDisplay (dpy); 576 SyncHandle (); 577 return False; 578 } 579 exists = rep.flags; 580 if (exists) { 581 values->type = rep.attr_type; 582 if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { 583 values->u.range.min = rep.min; 584 values->u.range.max = rep.max; 585 } 586 if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { 587 values->u.bits.ints = rep.bits; 588 } 589 values->permissions = rep.perms; 590 } 591 UnlockDisplay (dpy); 592 SyncHandle (); 593 return exists; 594 } 595 596 597 Bool XNVCTRLQueryValidTargetStringAttributeValues ( 598 Display *dpy, 599 int target_type, 600 int target_id, 601 unsigned int display_mask, 602 unsigned int attribute, 603 NVCTRLAttributeValidValuesRec *values 604 ){ 605 XExtDisplayInfo *info = find_display(dpy); 606 Bool exists; 607 xnvCtrlQueryValidAttributeValuesReply rep; 608 xnvCtrlQueryValidAttributeValuesReq *req; 609 610 if (!values) return False; 611 612 if (!XextHasExtension(info)) 613 return False; 614 615 XNVCTRLCheckExtension(dpy, info, False); 616 617 LockDisplay(dpy); 618 GetReq (nvCtrlQueryValidAttributeValues, req); 619 req->reqType = info->codes->major_opcode; 620 req->nvReqType = X_nvCtrlQueryValidStringAttributeValues; 621 req->target_type = target_type; 622 req->target_id = target_id; 623 req->display_mask = display_mask; 624 req->attribute = attribute; 625 if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) { 626 UnlockDisplay(dpy); 627 SyncHandle(); 628 return False; 629 } 630 exists = rep.flags; 631 if (exists) { 632 values->type = rep.attr_type; 633 values->permissions = rep.perms; 634 } 635 UnlockDisplay(dpy); 636 SyncHandle(); 637 return exists; 638 } 639 640 641 static Bool XNVCTRLQueryValidTargetAttributeValues64 ( 642 Display *dpy, 643 XExtDisplayInfo *info, 644 int target_type, 645 int target_id, 646 unsigned int display_mask, 647 unsigned int attribute, 648 NVCTRLAttributeValidValuesRec *values 649 ){ 650 xnvCtrlQueryValidAttributeValues64Reply rep; 651 xnvCtrlQueryValidAttributeValuesReq *req; 652 Bool exists; 653 654 LockDisplay(dpy); 655 GetReq(nvCtrlQueryValidAttributeValues, req); 656 req->reqType = info->codes->major_opcode; 657 req->nvReqType = X_nvCtrlQueryValidAttributeValues64; 658 req->target_type = target_type; 659 req->target_id = target_id; 660 req->display_mask = display_mask; 661 req->attribute = attribute; 662 if (!_XReply(dpy, (xReply *)&rep, 663 sz_xnvCtrlQueryValidAttributeValues64Reply_extra, 664 xTrue)) { 665 UnlockDisplay(dpy); 666 SyncHandle(); 667 return False; 668 } 669 exists = rep.flags; 670 if (exists) { 671 values->type = rep.attr_type; 672 if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { 673 values->u.range.min = rep.min_64; 674 values->u.range.max = rep.max_64; 675 } 676 if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { 677 values->u.bits.ints = rep.bits_64; 678 } 679 values->permissions = rep.perms; 680 } 681 UnlockDisplay(dpy); 682 SyncHandle(); 683 return exists; 684 } 685 686 Bool XNVCTRLQueryValidTargetAttributeValues ( 687 Display *dpy, 688 int target_type, 689 int target_id, 690 unsigned int display_mask, 691 unsigned int attribute, 692 NVCTRLAttributeValidValuesRec *values 693 ){ 694 XExtDisplayInfo *info = find_display(dpy); 695 Bool exists; 696 uintptr_t flags; 697 698 if (!values) return False; 699 700 if (!XextHasExtension(info)) 701 return False; 702 703 XNVCTRLCheckExtension(dpy, info, False); 704 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 705 706 flags = version_flags(dpy,info); 707 708 if (!(flags & NVCTRL_EXT_EXISTS)) 709 return False; 710 711 if (flags & NVCTRL_EXT_64_BIT_ATTRIBUTES) { 712 exists = XNVCTRLQueryValidTargetAttributeValues64(dpy, info, 713 target_type, 714 target_id, 715 display_mask, 716 attribute, 717 values); 718 } else { 719 exists = XNVCTRLQueryValidTargetAttributeValues32(dpy, info, 720 target_type, 721 target_id, 722 display_mask, 723 attribute, 724 values); 725 } 726 return exists; 727 } 728 729 730 Bool XNVCTRLQueryValidAttributeValues ( 731 Display *dpy, 732 int screen, 733 unsigned int display_mask, 734 unsigned int attribute, 735 NVCTRLAttributeValidValuesRec *values 736 ){ 737 return XNVCTRLQueryValidTargetAttributeValues(dpy, 738 NV_CTRL_TARGET_TYPE_X_SCREEN, 739 screen, display_mask, 740 attribute, values); 741 } 742 743 744 static Bool QueryAttributePermissionsInternal ( 745 Display *dpy, 746 unsigned int attribute, 747 NVCTRLAttributePermissionsRec *permissions, 748 unsigned int reqType 749 ){ 750 XExtDisplayInfo *info = find_display (dpy); 751 xnvCtrlQueryAttributePermissionsReply rep; 752 xnvCtrlQueryAttributePermissionsReq *req; 753 Bool exists; 754 755 if(!XextHasExtension(info)) 756 return False; 757 758 XNVCTRLCheckExtension (dpy, info, False); 759 760 LockDisplay(dpy); 761 GetReq(nvCtrlQueryAttributePermissions, req); 762 req->reqType = info->codes->major_opcode; 763 req->nvReqType = reqType; 764 req->attribute = attribute; 765 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 766 UnlockDisplay (dpy); 767 SyncHandle(); 768 return False; 769 } 770 exists = rep.flags; 771 if (exists && permissions) { 772 permissions->type = rep.attr_type; 773 permissions->permissions = rep.perms; 774 } 775 UnlockDisplay(dpy); 776 SyncHandle(); 777 return exists; 778 } 779 780 781 Bool XNVCTRLQueryAttributePermissions ( 782 Display *dpy, 783 unsigned int attribute, 784 NVCTRLAttributePermissionsRec *permissions 785 ){ 786 return QueryAttributePermissionsInternal(dpy, 787 attribute, 788 permissions, 789 X_nvCtrlQueryAttributePermissions); 790 } 791 792 793 Bool XNVCTRLQueryStringAttributePermissions ( 794 Display *dpy, 795 unsigned int attribute, 796 NVCTRLAttributePermissionsRec *permissions 797 ){ 798 return QueryAttributePermissionsInternal(dpy, 799 attribute, 800 permissions, 801 X_nvCtrlQueryStringAttributePermissions); 802 } 803 804 805 Bool XNVCTRLQueryBinaryDataAttributePermissions ( 806 Display *dpy, 807 unsigned int attribute, 808 NVCTRLAttributePermissionsRec *permissions 809 ){ 810 return QueryAttributePermissionsInternal(dpy, 811 attribute, 812 permissions, 813 X_nvCtrlQueryBinaryDataAttributePermissions); 814 } 815 816 817 Bool XNVCTRLQueryStringOperationAttributePermissions ( 818 Display *dpy, 819 unsigned int attribute, 820 NVCTRLAttributePermissionsRec *permissions 821 ){ 822 return QueryAttributePermissionsInternal(dpy, 823 attribute, 824 permissions, 825 X_nvCtrlQueryStringOperationAttributePermissions); 826 } 827 828 829 void XNVCTRLSetGvoColorConversion ( 830 Display *dpy, 831 int screen, 832 float colorMatrix[3][3], 833 float colorOffset[3], 834 float colorScale[3] 835 ){ 836 XExtDisplayInfo *info = find_display (dpy); 837 xnvCtrlSetGvoColorConversionReq *req; 838 839 XNVCTRLSimpleCheckExtension (dpy, info); 840 841 LockDisplay (dpy); 842 GetReq (nvCtrlSetGvoColorConversion, req); 843 req->reqType = info->codes->major_opcode; 844 req->nvReqType = X_nvCtrlSetGvoColorConversion; 845 req->screen = screen; 846 847 req->cscMatrix_y_r = colorMatrix[0][0]; 848 req->cscMatrix_y_g = colorMatrix[0][1]; 849 req->cscMatrix_y_b = colorMatrix[0][2]; 850 851 req->cscMatrix_cr_r = colorMatrix[1][0]; 852 req->cscMatrix_cr_g = colorMatrix[1][1]; 853 req->cscMatrix_cr_b = colorMatrix[1][2]; 854 855 req->cscMatrix_cb_r = colorMatrix[2][0]; 856 req->cscMatrix_cb_g = colorMatrix[2][1]; 857 req->cscMatrix_cb_b = colorMatrix[2][2]; 858 859 req->cscOffset_y = colorOffset[0]; 860 req->cscOffset_cr = colorOffset[1]; 861 req->cscOffset_cb = colorOffset[2]; 862 863 req->cscScale_y = colorScale[0]; 864 req->cscScale_cr = colorScale[1]; 865 req->cscScale_cb = colorScale[2]; 866 867 UnlockDisplay (dpy); 868 SyncHandle (); 869 } 870 871 872 Bool XNVCTRLQueryGvoColorConversion ( 873 Display *dpy, 874 int screen, 875 float colorMatrix[3][3], 876 float colorOffset[3], 877 float colorScale[3] 878 ){ 879 XExtDisplayInfo *info = find_display (dpy); 880 xnvCtrlQueryGvoColorConversionReply rep; 881 xnvCtrlQueryGvoColorConversionReq *req; 882 883 if(!XextHasExtension(info)) 884 return False; 885 886 XNVCTRLCheckExtension (dpy, info, False); 887 888 LockDisplay (dpy); 889 890 GetReq (nvCtrlQueryGvoColorConversion, req); 891 req->reqType = info->codes->major_opcode; 892 req->nvReqType = X_nvCtrlQueryGvoColorConversion; 893 req->screen = screen; 894 895 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 896 UnlockDisplay (dpy); 897 SyncHandle (); 898 return False; 899 } 900 901 _XRead(dpy, (char *)(colorMatrix), 36); 902 _XRead(dpy, (char *)(colorOffset), 12); 903 _XRead(dpy, (char *)(colorScale), 12); 904 905 UnlockDisplay (dpy); 906 SyncHandle (); 907 908 return True; 909 } 910 911 912 Bool XNVCtrlSelectTargetNotify ( 913 Display *dpy, 914 int target_type, 915 int target_id, 916 int notify_type, 917 Bool onoff 918 ){ 919 XExtDisplayInfo *info = find_display (dpy); 920 xnvCtrlSelectTargetNotifyReq *req; 921 922 if(!XextHasExtension (info)) 923 return False; 924 925 XNVCTRLCheckExtension (dpy, info, False); 926 927 LockDisplay (dpy); 928 GetReq (nvCtrlSelectTargetNotify, req); 929 req->reqType = info->codes->major_opcode; 930 req->nvReqType = X_nvCtrlSelectTargetNotify; 931 req->target_type = target_type; 932 req->target_id = target_id; 933 req->notifyType = notify_type; 934 req->onoff = onoff; 935 UnlockDisplay (dpy); 936 SyncHandle (); 937 938 return True; 939 } 940 941 942 Bool XNVCtrlSelectNotify ( 943 Display *dpy, 944 int screen, 945 int type, 946 Bool onoff 947 ){ 948 XExtDisplayInfo *info = find_display (dpy); 949 xnvCtrlSelectNotifyReq *req; 950 951 if(!XextHasExtension (info)) 952 return False; 953 954 XNVCTRLCheckExtension (dpy, info, False); 955 956 LockDisplay (dpy); 957 GetReq (nvCtrlSelectNotify, req); 958 req->reqType = info->codes->major_opcode; 959 req->nvReqType = X_nvCtrlSelectNotify; 960 req->screen = screen; 961 req->notifyType = type; 962 req->onoff = onoff; 963 UnlockDisplay (dpy); 964 SyncHandle (); 965 966 return True; 967 } 968 969 Bool XNVCTRLQueryTargetBinaryData ( 970 Display *dpy, 971 int target_type, 972 int target_id, 973 unsigned int display_mask, 974 unsigned int attribute, 975 unsigned char **ptr, 976 int *len 977 ){ 978 XExtDisplayInfo *info = find_display (dpy); 979 xnvCtrlQueryBinaryDataReply rep; 980 xnvCtrlQueryBinaryDataReq *req; 981 Bool exists; 982 int length, numbytes, slop; 983 984 if (!ptr) return False; 985 986 if(!XextHasExtension(info)) 987 return False; 988 989 XNVCTRLCheckExtension (dpy, info, False); 990 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 991 992 LockDisplay (dpy); 993 GetReq (nvCtrlQueryBinaryData, req); 994 req->reqType = info->codes->major_opcode; 995 req->nvReqType = X_nvCtrlQueryBinaryData; 996 req->target_type = target_type; 997 req->target_id = target_id; 998 req->display_mask = display_mask; 999 req->attribute = attribute; 1000 if (!_XReply (dpy, (xReply *) &rep, 0, False)) { 1001 UnlockDisplay (dpy); 1002 SyncHandle (); 1003 return False; 1004 } 1005 length = rep.length; 1006 numbytes = rep.n; 1007 slop = numbytes & 3; 1008 exists = rep.flags; 1009 if (exists) { 1010 *ptr = (unsigned char *) Xmalloc(numbytes); 1011 } 1012 if (!exists || !*ptr) { 1013 _XEatData(dpy, length); 1014 UnlockDisplay (dpy); 1015 SyncHandle (); 1016 return False; 1017 } else { 1018 _XRead(dpy, (char *) *ptr, numbytes); 1019 if (slop) _XEatData(dpy, 4-slop); 1020 } 1021 if (len) *len = numbytes; 1022 UnlockDisplay (dpy); 1023 SyncHandle (); 1024 return exists; 1025 } 1026 1027 Bool XNVCTRLQueryBinaryData ( 1028 Display *dpy, 1029 int screen, 1030 unsigned int display_mask, 1031 unsigned int attribute, 1032 unsigned char **ptr, 1033 int *len 1034 ){ 1035 return XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, 1036 screen, display_mask, 1037 attribute, ptr, len); 1038 } 1039 1040 Bool XNVCTRLStringOperation ( 1041 Display *dpy, 1042 int target_type, 1043 int target_id, 1044 unsigned int display_mask, 1045 unsigned int attribute, 1046 char *pIn, 1047 char **ppOut 1048 ) { 1049 XExtDisplayInfo *info = find_display(dpy); 1050 xnvCtrlStringOperationReq *req; 1051 xnvCtrlStringOperationReply rep; 1052 Bool ret; 1053 int inSize, outSize, length, slop; 1054 1055 if (!XextHasExtension(info)) 1056 return False; 1057 1058 if (!ppOut) 1059 return False; 1060 1061 *ppOut = NULL; 1062 1063 XNVCTRLCheckExtension(dpy, info, False); 1064 XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); 1065 1066 if (pIn) { 1067 inSize = strlen(pIn) + 1; 1068 } else { 1069 inSize = 0; 1070 } 1071 1072 LockDisplay(dpy); 1073 GetReq(nvCtrlStringOperation, req); 1074 1075 req->reqType = info->codes->major_opcode; 1076 req->nvReqType = X_nvCtrlStringOperation; 1077 req->target_type = target_type; 1078 req->target_id = target_id; 1079 req->display_mask = display_mask; 1080 req->attribute = attribute; 1081 1082 req->length += ((inSize + 3) & ~3) >> 2; 1083 req->num_bytes = inSize; 1084 1085 if (pIn) { 1086 Data(dpy, pIn, inSize); 1087 } 1088 1089 if (!_XReply (dpy, (xReply *) &rep, 0, False)) { 1090 UnlockDisplay(dpy); 1091 SyncHandle(); 1092 return False; 1093 } 1094 1095 length = rep.length; 1096 outSize = rep.num_bytes; 1097 slop = outSize & 3; 1098 1099 if (outSize) *ppOut = (char *) Xmalloc(outSize); 1100 1101 if (!*ppOut) { 1102 _XEatData(dpy, length); 1103 } else { 1104 _XRead(dpy, (char *) *ppOut, outSize); 1105 if (slop) _XEatData(dpy, 4-slop); 1106 } 1107 1108 ret = rep.ret; 1109 1110 UnlockDisplay(dpy); 1111 SyncHandle(); 1112 1113 return ret; 1114 } 1115 1116 1117 static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire) 1118 { 1119 XExtDisplayInfo *info = find_display (dpy); 1120 XNVCtrlEvent *re; 1121 xnvctrlEvent *event; 1122 XNVCtrlEventTarget *reTarget; 1123 xnvctrlEventTarget *eventTarget; 1124 XNVCtrlEventTargetAvailability *reTargetAvailability; 1125 XNVCtrlStringEventTarget *reTargetString; 1126 XNVCtrlBinaryEventTarget *reTargetBinary; 1127 1128 XNVCTRLCheckExtension (dpy, info, False); 1129 1130 switch ((wire->u.u.type & 0x7F) - info->codes->first_event) { 1131 case ATTRIBUTE_CHANGED_EVENT: 1132 re = (XNVCtrlEvent *) host; 1133 event = (xnvctrlEvent *) wire; 1134 re->attribute_changed.type = event->u.u.type & 0x7F; 1135 re->attribute_changed.serial = 1136 _XSetLastRequestRead(dpy, (xGenericReply*) event); 1137 re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0); 1138 re->attribute_changed.display = dpy; 1139 re->attribute_changed.time = event->u.attribute_changed.time; 1140 re->attribute_changed.screen = event->u.attribute_changed.screen; 1141 re->attribute_changed.display_mask = 1142 event->u.attribute_changed.display_mask; 1143 re->attribute_changed.attribute = event->u.attribute_changed.attribute; 1144 re->attribute_changed.value = event->u.attribute_changed.value; 1145 break; 1146 case TARGET_ATTRIBUTE_CHANGED_EVENT: 1147 reTarget = (XNVCtrlEventTarget *) host; 1148 eventTarget = (xnvctrlEventTarget *) wire; 1149 reTarget->attribute_changed.type = eventTarget->u.u.type & 0x7F; 1150 reTarget->attribute_changed.serial = 1151 _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); 1152 reTarget->attribute_changed.send_event = 1153 ((eventTarget->u.u.type & 0x80) != 0); 1154 reTarget->attribute_changed.display = dpy; 1155 reTarget->attribute_changed.time = 1156 eventTarget->u.attribute_changed.time; 1157 reTarget->attribute_changed.target_type = 1158 eventTarget->u.attribute_changed.target_type; 1159 reTarget->attribute_changed.target_id = 1160 eventTarget->u.attribute_changed.target_id; 1161 reTarget->attribute_changed.display_mask = 1162 eventTarget->u.attribute_changed.display_mask; 1163 reTarget->attribute_changed.attribute = 1164 eventTarget->u.attribute_changed.attribute; 1165 reTarget->attribute_changed.value = 1166 eventTarget->u.attribute_changed.value; 1167 break; 1168 case TARGET_ATTRIBUTE_AVAILABILITY_CHANGED_EVENT: 1169 reTargetAvailability = (XNVCtrlEventTargetAvailability *) host; 1170 eventTarget = (xnvctrlEventTarget *) wire; 1171 reTargetAvailability->attribute_changed.type = 1172 eventTarget->u.u.type & 0x7F; 1173 reTargetAvailability->attribute_changed.serial = 1174 _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); 1175 reTargetAvailability->attribute_changed.send_event = 1176 ((eventTarget->u.u.type & 0x80) != 0); 1177 reTargetAvailability->attribute_changed.display = dpy; 1178 reTargetAvailability->attribute_changed.time = 1179 eventTarget->u.availability_changed.time; 1180 reTargetAvailability->attribute_changed.target_type = 1181 eventTarget->u.availability_changed.target_type; 1182 reTargetAvailability->attribute_changed.target_id = 1183 eventTarget->u.availability_changed.target_id; 1184 reTargetAvailability->attribute_changed.display_mask = 1185 eventTarget->u.availability_changed.display_mask; 1186 reTargetAvailability->attribute_changed.attribute = 1187 eventTarget->u.availability_changed.attribute; 1188 reTargetAvailability->attribute_changed.availability = 1189 eventTarget->u.availability_changed.availability; 1190 reTargetAvailability->attribute_changed.value = 1191 eventTarget->u.availability_changed.value; 1192 break; 1193 case TARGET_STRING_ATTRIBUTE_CHANGED_EVENT: 1194 reTargetString = (XNVCtrlStringEventTarget *) host; 1195 eventTarget = (xnvctrlEventTarget *) wire; 1196 reTargetString->attribute_changed.type = eventTarget->u.u.type & 0x7F; 1197 reTargetString->attribute_changed.serial = 1198 _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); 1199 reTargetString->attribute_changed.send_event = 1200 ((eventTarget->u.u.type & 0x80) != 0); 1201 reTargetString->attribute_changed.display = dpy; 1202 reTargetString->attribute_changed.time = 1203 eventTarget->u.attribute_changed.time; 1204 reTargetString->attribute_changed.target_type = 1205 eventTarget->u.attribute_changed.target_type; 1206 reTargetString->attribute_changed.target_id = 1207 eventTarget->u.attribute_changed.target_id; 1208 reTargetString->attribute_changed.display_mask = 1209 eventTarget->u.attribute_changed.display_mask; 1210 reTargetString->attribute_changed.attribute = 1211 eventTarget->u.attribute_changed.attribute; 1212 break; 1213 case TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT: 1214 reTargetBinary = (XNVCtrlBinaryEventTarget *) host; 1215 eventTarget = (xnvctrlEventTarget *) wire; 1216 reTargetBinary->attribute_changed.type = eventTarget->u.u.type & 0x7F; 1217 reTargetBinary->attribute_changed.serial = 1218 _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); 1219 reTargetBinary->attribute_changed.send_event = 1220 ((eventTarget->u.u.type & 0x80) != 0); 1221 reTargetBinary->attribute_changed.display = dpy; 1222 reTargetBinary->attribute_changed.time = 1223 eventTarget->u.attribute_changed.time; 1224 reTargetBinary->attribute_changed.target_type = 1225 eventTarget->u.attribute_changed.target_type; 1226 reTargetBinary->attribute_changed.target_id = 1227 eventTarget->u.attribute_changed.target_id; 1228 reTargetBinary->attribute_changed.display_mask = 1229 eventTarget->u.attribute_changed.display_mask; 1230 reTargetBinary->attribute_changed.attribute = 1231 eventTarget->u.attribute_changed.attribute; 1232 break; 1233 1234 default: 1235 return False; 1236 } 1237 1238 return True; 1239 } 1240 1241