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
XEXT_GENERATE_CLOSE_DISPLAY(close_display,nvctrl_ext_info)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
XNVCTRLQueryExtension(Display * dpy,int * event_basep,int * error_basep)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
version_flags(Display * dpy,XExtDisplayInfo * info)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
XNVCTRLQueryVersion(Display * dpy,int * major,int * minor)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
XNVCTRLIsNvScreen(Display * dpy,int screen)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
XNVCTRLQueryTargetCount(Display * dpy,int target_type,int * value)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
XNVCTRLSetTargetAttribute(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,int value)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
XNVCTRLSetAttribute(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,int value)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
XNVCTRLSetTargetAttributeAndGetStatus(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,int value)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
XNVCTRLSetAttributeAndGetStatus(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,int value)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
XNVCTRLQueryTargetAttribute(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,int * value)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
XNVCTRLQueryAttribute(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,int * value)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
XNVCTRLQueryTargetAttribute64(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,int64_t * value)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
XNVCTRLQueryTargetStringAttribute(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,char ** ptr)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
XNVCTRLQueryStringAttribute(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,char ** ptr)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
XNVCTRLSetTargetStringAttribute(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,char * ptr)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
XNVCTRLSetStringAttribute(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,char * ptr)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
XNVCTRLQueryValidTargetAttributeValues32(Display * dpy,XExtDisplayInfo * info,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,NVCTRLAttributeValidValuesRec * values)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
XNVCTRLQueryValidTargetStringAttributeValues(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,NVCTRLAttributeValidValuesRec * values)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
XNVCTRLQueryValidTargetAttributeValues64(Display * dpy,XExtDisplayInfo * info,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,NVCTRLAttributeValidValuesRec * values)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
XNVCTRLQueryValidTargetAttributeValues(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,NVCTRLAttributeValidValuesRec * values)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
XNVCTRLQueryValidAttributeValues(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,NVCTRLAttributeValidValuesRec * values)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
QueryAttributePermissionsInternal(Display * dpy,unsigned int attribute,NVCTRLAttributePermissionsRec * permissions,unsigned int reqType)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
XNVCTRLQueryAttributePermissions(Display * dpy,unsigned int attribute,NVCTRLAttributePermissionsRec * permissions)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
XNVCTRLQueryStringAttributePermissions(Display * dpy,unsigned int attribute,NVCTRLAttributePermissionsRec * permissions)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
XNVCTRLQueryBinaryDataAttributePermissions(Display * dpy,unsigned int attribute,NVCTRLAttributePermissionsRec * permissions)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
XNVCTRLQueryStringOperationAttributePermissions(Display * dpy,unsigned int attribute,NVCTRLAttributePermissionsRec * permissions)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
XNVCTRLSetGvoColorConversion(Display * dpy,int screen,float colorMatrix[3][3],float colorOffset[3],float colorScale[3])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
XNVCTRLQueryGvoColorConversion(Display * dpy,int screen,float colorMatrix[3][3],float colorOffset[3],float colorScale[3])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
XNVCtrlSelectTargetNotify(Display * dpy,int target_type,int target_id,int notify_type,Bool onoff)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
XNVCtrlSelectNotify(Display * dpy,int screen,int type,Bool onoff)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
XNVCTRLQueryTargetBinaryData(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,unsigned char ** ptr,int * len)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
XNVCTRLQueryBinaryData(Display * dpy,int screen,unsigned int display_mask,unsigned int attribute,unsigned char ** ptr,int * len)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
XNVCTRLStringOperation(Display * dpy,int target_type,int target_id,unsigned int display_mask,unsigned int attribute,char * pIn,char ** ppOut)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
wire_to_event(Display * dpy,XEvent * host,xEvent * wire)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