mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
1241 lines
36 KiB
C
1241 lines
36 KiB
C
/*
|
|
* Copyright (c) 2008 NVIDIA, Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
/*
|
|
* Make sure that XTHREADS is defined, so that the
|
|
* LockDisplay/UnlockDisplay macros are expanded properly and the
|
|
* libXNVCtrl library properly protects the Display connection.
|
|
*/
|
|
|
|
#if !defined(XTHREADS)
|
|
#define XTHREADS
|
|
#endif /* XTHREADS */
|
|
|
|
#define NEED_EVENTS
|
|
#define NEED_REPLIES
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <X11/Xlibint.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/extensions/Xext.h>
|
|
#include <X11/extensions/extutil.h>
|
|
#include "NVCtrlLib.h"
|
|
#include "nv_control.h"
|
|
|
|
#define NVCTRL_EXT_EXISTS 1
|
|
#define NVCTRL_EXT_NEED_TARGET_SWAP 2
|
|
#define NVCTRL_EXT_64_BIT_ATTRIBUTES 4
|
|
#define NVCTRL_EXT_NEED_CHECK (1 << (sizeof(XPointer) - 1))
|
|
|
|
static XExtensionInfo _nvctrl_ext_info_data;
|
|
static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data;
|
|
static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME;
|
|
|
|
#define XNVCTRLCheckExtension(dpy,i,val) \
|
|
XextCheckExtension (dpy, i, nvctrl_extension_name, val)
|
|
#define XNVCTRLSimpleCheckExtension(dpy,i) \
|
|
XextSimpleCheckExtension (dpy, i, nvctrl_extension_name)
|
|
|
|
static int close_display();
|
|
static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info);
|
|
static Bool wire_to_event();
|
|
static /* const */ XExtensionHooks nvctrl_extension_hooks = {
|
|
NULL, /* create_gc */
|
|
NULL, /* copy_gc */
|
|
NULL, /* flush_gc */
|
|
NULL, /* free_gc */
|
|
NULL, /* create_font */
|
|
NULL, /* free_font */
|
|
close_display, /* close_display */
|
|
wire_to_event, /* wire_to_event */
|
|
NULL, /* event_to_wire */
|
|
NULL, /* error */
|
|
NULL, /* error_string */
|
|
};
|
|
|
|
static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info,
|
|
nvctrl_extension_name,
|
|
&nvctrl_extension_hooks,
|
|
NV_CONTROL_EVENTS,
|
|
(XPointer)NVCTRL_EXT_NEED_CHECK)
|
|
|
|
static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info)
|
|
|
|
/*
|
|
* NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id
|
|
* fields in reversed order. In order to talk to one of these servers,
|
|
* we need to swap these fields.
|
|
*/
|
|
|
|
static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info,
|
|
int *target_type, int *target_id)
|
|
{
|
|
uintptr_t flags = version_flags(dpy, info);
|
|
|
|
/* We need to swap the target_type and target_id */
|
|
if (flags & NVCTRL_EXT_NEED_TARGET_SWAP) {
|
|
int tmp;
|
|
tmp = *target_type;
|
|
*target_type = *target_id;
|
|
*target_id = tmp;
|
|
}
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryExtension (
|
|
Display *dpy,
|
|
int *event_basep,
|
|
int *error_basep
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
|
|
if (XextHasExtension(info)) {
|
|
if (event_basep) *event_basep = info->codes->first_event;
|
|
if (error_basep) *error_basep = info->codes->first_error;
|
|
return True;
|
|
} else {
|
|
return False;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Retrieve any cached flags that depend on the version of the NV-CONTROL
|
|
* extension.
|
|
*/
|
|
|
|
static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info)
|
|
{
|
|
uintptr_t data = (uintptr_t)info->data;
|
|
|
|
/* If necessary, determine the NV-CONTROL version */
|
|
if (data & NVCTRL_EXT_NEED_CHECK) {
|
|
int major, minor;
|
|
data = 0;
|
|
if (XNVCTRLQueryVersion(dpy, &major, &minor)) {
|
|
data |= NVCTRL_EXT_EXISTS;
|
|
if (major == 1 && (minor == 8 || minor == 9)) {
|
|
data |= NVCTRL_EXT_NEED_TARGET_SWAP;
|
|
}
|
|
if ((major > 1) || ((major == 1) && (minor > 20))) {
|
|
data |= NVCTRL_EXT_64_BIT_ATTRIBUTES;
|
|
}
|
|
}
|
|
|
|
info->data = (XPointer)data;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
Bool XNVCTRLQueryVersion (
|
|
Display *dpy,
|
|
int *major,
|
|
int *minor
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryExtensionReply rep;
|
|
xnvCtrlQueryExtensionReq *req;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryExtension, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryExtension;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
if (major) *major = rep.major;
|
|
if (minor) *minor = rep.minor;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return True;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLIsNvScreen (
|
|
Display *dpy,
|
|
int screen
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlIsNvReply rep;
|
|
xnvCtrlIsNvReq *req;
|
|
Bool isnv;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlIsNv, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlIsNv;
|
|
req->screen = screen;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
isnv = rep.isnv;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return isnv;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryTargetCount (
|
|
Display *dpy,
|
|
int target_type,
|
|
int *value
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryTargetCountReply rep;
|
|
xnvCtrlQueryTargetCountReq *req;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryTargetCount, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryTargetCount;
|
|
req->target_type = target_type;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
if (value) *value = rep.count;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return True;
|
|
}
|
|
|
|
|
|
void XNVCTRLSetTargetAttribute (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int value
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSetAttributeReq *req;
|
|
|
|
XNVCTRLSimpleCheckExtension (dpy, info);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSetAttribute, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSetAttribute;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
req->value = value;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
}
|
|
|
|
void XNVCTRLSetAttribute (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int value
|
|
){
|
|
XNVCTRLSetTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen,
|
|
display_mask, attribute, value);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLSetTargetAttributeAndGetStatus (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int value
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSetAttributeAndGetStatusReq *req;
|
|
xnvCtrlSetAttributeAndGetStatusReply rep;
|
|
Bool success;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSetAttributeAndGetStatus, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSetAttributeAndGetStatus;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
req->value = value;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
success = rep.flags;
|
|
return success;
|
|
}
|
|
|
|
Bool XNVCTRLSetAttributeAndGetStatus (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int value
|
|
){
|
|
return XNVCTRLSetTargetAttributeAndGetStatus(dpy,
|
|
NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask,
|
|
attribute, value);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryTargetAttribute (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int *value
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryAttributeReply rep;
|
|
xnvCtrlQueryAttributeReq *req;
|
|
Bool exists;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryAttribute, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryAttribute;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists && value) *value = rep.value;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return exists;
|
|
}
|
|
|
|
Bool XNVCTRLQueryAttribute (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int *value
|
|
){
|
|
return XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask, attribute, value);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryTargetAttribute64 (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
int64_t *value
|
|
){
|
|
XExtDisplayInfo *info = find_display(dpy);
|
|
xnvCtrlQueryAttribute64Reply rep;
|
|
xnvCtrlQueryAttributeReq *req;
|
|
Bool exists;
|
|
|
|
if (!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension(dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
LockDisplay(dpy);
|
|
GetReq(nvCtrlQueryAttribute, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryAttribute64;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists && value) *value = rep.value_64;
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return exists;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryTargetStringAttribute (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
char **ptr
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryStringAttributeReply rep;
|
|
xnvCtrlQueryStringAttributeReq *req;
|
|
Bool exists;
|
|
int length, numbytes, slop;
|
|
|
|
if (!ptr) return False;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryStringAttribute, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryStringAttribute;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
length = rep.length;
|
|
numbytes = rep.n;
|
|
slop = numbytes & 3;
|
|
exists = rep.flags;
|
|
if (exists) {
|
|
*ptr = (char *) Xmalloc(numbytes);
|
|
}
|
|
if (!exists || !*ptr) {
|
|
_XEatData(dpy, length);
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
} else {
|
|
_XRead(dpy, (char *) *ptr, numbytes);
|
|
if (slop) _XEatData(dpy, 4-slop);
|
|
}
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return exists;
|
|
}
|
|
|
|
Bool XNVCTRLQueryStringAttribute (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
char **ptr
|
|
){
|
|
return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask,
|
|
attribute, ptr);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLSetTargetStringAttribute (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
char *ptr
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSetStringAttributeReq *req;
|
|
xnvCtrlSetStringAttributeReply rep;
|
|
int size;
|
|
Bool success;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
size = strlen(ptr)+1;
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSetStringAttribute, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSetStringAttribute;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
req->length += ((size + 3) & ~3) >> 2;
|
|
req->num_bytes = size;
|
|
Data(dpy, ptr, size);
|
|
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
success = rep.flags;
|
|
return success;
|
|
}
|
|
|
|
Bool XNVCTRLSetStringAttribute (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
char *ptr
|
|
){
|
|
return XNVCTRLSetTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask,
|
|
attribute, ptr);
|
|
}
|
|
|
|
|
|
static Bool XNVCTRLQueryValidTargetAttributeValues32 (
|
|
Display *dpy,
|
|
XExtDisplayInfo *info,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
NVCTRLAttributeValidValuesRec *values
|
|
){
|
|
xnvCtrlQueryValidAttributeValuesReply rep;
|
|
xnvCtrlQueryValidAttributeValuesReq *req;
|
|
Bool exists;
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryValidAttributeValues, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryValidAttributeValues;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists) {
|
|
values->type = rep.attr_type;
|
|
if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) {
|
|
values->u.range.min = rep.min;
|
|
values->u.range.max = rep.max;
|
|
}
|
|
if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) {
|
|
values->u.bits.ints = rep.bits;
|
|
}
|
|
values->permissions = rep.perms;
|
|
}
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return exists;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryValidTargetStringAttributeValues (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
NVCTRLAttributeValidValuesRec *values
|
|
){
|
|
XExtDisplayInfo *info = find_display(dpy);
|
|
Bool exists;
|
|
xnvCtrlQueryValidAttributeValuesReply rep;
|
|
xnvCtrlQueryValidAttributeValuesReq *req;
|
|
|
|
if (!values) return False;
|
|
|
|
if (!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension(dpy, info, False);
|
|
|
|
LockDisplay(dpy);
|
|
GetReq (nvCtrlQueryValidAttributeValues, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryValidStringAttributeValues;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists) {
|
|
values->type = rep.attr_type;
|
|
values->permissions = rep.perms;
|
|
}
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return exists;
|
|
}
|
|
|
|
|
|
static Bool XNVCTRLQueryValidTargetAttributeValues64 (
|
|
Display *dpy,
|
|
XExtDisplayInfo *info,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
NVCTRLAttributeValidValuesRec *values
|
|
){
|
|
xnvCtrlQueryValidAttributeValues64Reply rep;
|
|
xnvCtrlQueryValidAttributeValuesReq *req;
|
|
Bool exists;
|
|
|
|
LockDisplay(dpy);
|
|
GetReq(nvCtrlQueryValidAttributeValues, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryValidAttributeValues64;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply(dpy, (xReply *)&rep,
|
|
sz_xnvCtrlQueryValidAttributeValues64Reply_extra,
|
|
xTrue)) {
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists) {
|
|
values->type = rep.attr_type;
|
|
if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) {
|
|
values->u.range.min = rep.min_64;
|
|
values->u.range.max = rep.max_64;
|
|
}
|
|
if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) {
|
|
values->u.bits.ints = rep.bits_64;
|
|
}
|
|
values->permissions = rep.perms;
|
|
}
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return exists;
|
|
}
|
|
|
|
Bool XNVCTRLQueryValidTargetAttributeValues (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
NVCTRLAttributeValidValuesRec *values
|
|
){
|
|
XExtDisplayInfo *info = find_display(dpy);
|
|
Bool exists;
|
|
uintptr_t flags;
|
|
|
|
if (!values) return False;
|
|
|
|
if (!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension(dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
flags = version_flags(dpy,info);
|
|
|
|
if (!(flags & NVCTRL_EXT_EXISTS))
|
|
return False;
|
|
|
|
if (flags & NVCTRL_EXT_64_BIT_ATTRIBUTES) {
|
|
exists = XNVCTRLQueryValidTargetAttributeValues64(dpy, info,
|
|
target_type,
|
|
target_id,
|
|
display_mask,
|
|
attribute,
|
|
values);
|
|
} else {
|
|
exists = XNVCTRLQueryValidTargetAttributeValues32(dpy, info,
|
|
target_type,
|
|
target_id,
|
|
display_mask,
|
|
attribute,
|
|
values);
|
|
}
|
|
return exists;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryValidAttributeValues (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
NVCTRLAttributeValidValuesRec *values
|
|
){
|
|
return XNVCTRLQueryValidTargetAttributeValues(dpy,
|
|
NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask,
|
|
attribute, values);
|
|
}
|
|
|
|
|
|
static Bool QueryAttributePermissionsInternal (
|
|
Display *dpy,
|
|
unsigned int attribute,
|
|
NVCTRLAttributePermissionsRec *permissions,
|
|
unsigned int reqType
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryAttributePermissionsReply rep;
|
|
xnvCtrlQueryAttributePermissionsReq *req;
|
|
Bool exists;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay(dpy);
|
|
GetReq(nvCtrlQueryAttributePermissions, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = reqType;
|
|
req->attribute = attribute;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle();
|
|
return False;
|
|
}
|
|
exists = rep.flags;
|
|
if (exists && permissions) {
|
|
permissions->type = rep.attr_type;
|
|
permissions->permissions = rep.perms;
|
|
}
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return exists;
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryAttributePermissions (
|
|
Display *dpy,
|
|
unsigned int attribute,
|
|
NVCTRLAttributePermissionsRec *permissions
|
|
){
|
|
return QueryAttributePermissionsInternal(dpy,
|
|
attribute,
|
|
permissions,
|
|
X_nvCtrlQueryAttributePermissions);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryStringAttributePermissions (
|
|
Display *dpy,
|
|
unsigned int attribute,
|
|
NVCTRLAttributePermissionsRec *permissions
|
|
){
|
|
return QueryAttributePermissionsInternal(dpy,
|
|
attribute,
|
|
permissions,
|
|
X_nvCtrlQueryStringAttributePermissions);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryBinaryDataAttributePermissions (
|
|
Display *dpy,
|
|
unsigned int attribute,
|
|
NVCTRLAttributePermissionsRec *permissions
|
|
){
|
|
return QueryAttributePermissionsInternal(dpy,
|
|
attribute,
|
|
permissions,
|
|
X_nvCtrlQueryBinaryDataAttributePermissions);
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryStringOperationAttributePermissions (
|
|
Display *dpy,
|
|
unsigned int attribute,
|
|
NVCTRLAttributePermissionsRec *permissions
|
|
){
|
|
return QueryAttributePermissionsInternal(dpy,
|
|
attribute,
|
|
permissions,
|
|
X_nvCtrlQueryStringOperationAttributePermissions);
|
|
}
|
|
|
|
|
|
void XNVCTRLSetGvoColorConversion (
|
|
Display *dpy,
|
|
int screen,
|
|
float colorMatrix[3][3],
|
|
float colorOffset[3],
|
|
float colorScale[3]
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSetGvoColorConversionReq *req;
|
|
|
|
XNVCTRLSimpleCheckExtension (dpy, info);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSetGvoColorConversion, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSetGvoColorConversion;
|
|
req->screen = screen;
|
|
|
|
req->cscMatrix_y_r = colorMatrix[0][0];
|
|
req->cscMatrix_y_g = colorMatrix[0][1];
|
|
req->cscMatrix_y_b = colorMatrix[0][2];
|
|
|
|
req->cscMatrix_cr_r = colorMatrix[1][0];
|
|
req->cscMatrix_cr_g = colorMatrix[1][1];
|
|
req->cscMatrix_cr_b = colorMatrix[1][2];
|
|
|
|
req->cscMatrix_cb_r = colorMatrix[2][0];
|
|
req->cscMatrix_cb_g = colorMatrix[2][1];
|
|
req->cscMatrix_cb_b = colorMatrix[2][2];
|
|
|
|
req->cscOffset_y = colorOffset[0];
|
|
req->cscOffset_cr = colorOffset[1];
|
|
req->cscOffset_cb = colorOffset[2];
|
|
|
|
req->cscScale_y = colorScale[0];
|
|
req->cscScale_cr = colorScale[1];
|
|
req->cscScale_cb = colorScale[2];
|
|
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
}
|
|
|
|
|
|
Bool XNVCTRLQueryGvoColorConversion (
|
|
Display *dpy,
|
|
int screen,
|
|
float colorMatrix[3][3],
|
|
float colorOffset[3],
|
|
float colorScale[3]
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryGvoColorConversionReply rep;
|
|
xnvCtrlQueryGvoColorConversionReq *req;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
|
|
GetReq (nvCtrlQueryGvoColorConversion, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryGvoColorConversion;
|
|
req->screen = screen;
|
|
|
|
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
|
|
_XRead(dpy, (char *)(colorMatrix), 36);
|
|
_XRead(dpy, (char *)(colorOffset), 12);
|
|
_XRead(dpy, (char *)(colorScale), 12);
|
|
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
return True;
|
|
}
|
|
|
|
|
|
Bool XNVCtrlSelectTargetNotify (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
int notify_type,
|
|
Bool onoff
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSelectTargetNotifyReq *req;
|
|
|
|
if(!XextHasExtension (info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSelectTargetNotify, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSelectTargetNotify;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->notifyType = notify_type;
|
|
req->onoff = onoff;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
return True;
|
|
}
|
|
|
|
|
|
Bool XNVCtrlSelectNotify (
|
|
Display *dpy,
|
|
int screen,
|
|
int type,
|
|
Bool onoff
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlSelectNotifyReq *req;
|
|
|
|
if(!XextHasExtension (info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlSelectNotify, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlSelectNotify;
|
|
req->screen = screen;
|
|
req->notifyType = type;
|
|
req->onoff = onoff;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
|
|
return True;
|
|
}
|
|
|
|
Bool XNVCTRLQueryTargetBinaryData (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
unsigned char **ptr,
|
|
int *len
|
|
){
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
xnvCtrlQueryBinaryDataReply rep;
|
|
xnvCtrlQueryBinaryDataReq *req;
|
|
Bool exists;
|
|
int length, numbytes, slop;
|
|
|
|
if (!ptr) return False;
|
|
|
|
if(!XextHasExtension(info))
|
|
return False;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
LockDisplay (dpy);
|
|
GetReq (nvCtrlQueryBinaryData, req);
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlQueryBinaryData;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
}
|
|
length = rep.length;
|
|
numbytes = rep.n;
|
|
slop = numbytes & 3;
|
|
exists = rep.flags;
|
|
if (exists) {
|
|
*ptr = (unsigned char *) Xmalloc(numbytes);
|
|
}
|
|
if (!exists || !*ptr) {
|
|
_XEatData(dpy, length);
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return False;
|
|
} else {
|
|
_XRead(dpy, (char *) *ptr, numbytes);
|
|
if (slop) _XEatData(dpy, 4-slop);
|
|
}
|
|
if (len) *len = numbytes;
|
|
UnlockDisplay (dpy);
|
|
SyncHandle ();
|
|
return exists;
|
|
}
|
|
|
|
Bool XNVCTRLQueryBinaryData (
|
|
Display *dpy,
|
|
int screen,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
unsigned char **ptr,
|
|
int *len
|
|
){
|
|
return XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
|
|
screen, display_mask,
|
|
attribute, ptr, len);
|
|
}
|
|
|
|
Bool XNVCTRLStringOperation (
|
|
Display *dpy,
|
|
int target_type,
|
|
int target_id,
|
|
unsigned int display_mask,
|
|
unsigned int attribute,
|
|
char *pIn,
|
|
char **ppOut
|
|
) {
|
|
XExtDisplayInfo *info = find_display(dpy);
|
|
xnvCtrlStringOperationReq *req;
|
|
xnvCtrlStringOperationReply rep;
|
|
Bool ret;
|
|
int inSize, outSize, length, slop;
|
|
|
|
if (!XextHasExtension(info))
|
|
return False;
|
|
|
|
if (!ppOut)
|
|
return False;
|
|
|
|
*ppOut = NULL;
|
|
|
|
XNVCTRLCheckExtension(dpy, info, False);
|
|
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
|
|
|
|
if (pIn) {
|
|
inSize = strlen(pIn) + 1;
|
|
} else {
|
|
inSize = 0;
|
|
}
|
|
|
|
LockDisplay(dpy);
|
|
GetReq(nvCtrlStringOperation, req);
|
|
|
|
req->reqType = info->codes->major_opcode;
|
|
req->nvReqType = X_nvCtrlStringOperation;
|
|
req->target_type = target_type;
|
|
req->target_id = target_id;
|
|
req->display_mask = display_mask;
|
|
req->attribute = attribute;
|
|
|
|
req->length += ((inSize + 3) & ~3) >> 2;
|
|
req->num_bytes = inSize;
|
|
|
|
if (pIn) {
|
|
Data(dpy, pIn, inSize);
|
|
}
|
|
|
|
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
return False;
|
|
}
|
|
|
|
length = rep.length;
|
|
outSize = rep.num_bytes;
|
|
slop = outSize & 3;
|
|
|
|
if (outSize) *ppOut = (char *) Xmalloc(outSize);
|
|
|
|
if (!*ppOut) {
|
|
_XEatData(dpy, length);
|
|
} else {
|
|
_XRead(dpy, (char *) *ppOut, outSize);
|
|
if (slop) _XEatData(dpy, 4-slop);
|
|
}
|
|
|
|
ret = rep.ret;
|
|
|
|
UnlockDisplay(dpy);
|
|
SyncHandle();
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire)
|
|
{
|
|
XExtDisplayInfo *info = find_display (dpy);
|
|
XNVCtrlEvent *re;
|
|
xnvctrlEvent *event;
|
|
XNVCtrlEventTarget *reTarget;
|
|
xnvctrlEventTarget *eventTarget;
|
|
XNVCtrlEventTargetAvailability *reTargetAvailability;
|
|
XNVCtrlStringEventTarget *reTargetString;
|
|
XNVCtrlBinaryEventTarget *reTargetBinary;
|
|
|
|
XNVCTRLCheckExtension (dpy, info, False);
|
|
|
|
switch ((wire->u.u.type & 0x7F) - info->codes->first_event) {
|
|
case ATTRIBUTE_CHANGED_EVENT:
|
|
re = (XNVCtrlEvent *) host;
|
|
event = (xnvctrlEvent *) wire;
|
|
re->attribute_changed.type = event->u.u.type & 0x7F;
|
|
re->attribute_changed.serial =
|
|
_XSetLastRequestRead(dpy, (xGenericReply*) event);
|
|
re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0);
|
|
re->attribute_changed.display = dpy;
|
|
re->attribute_changed.time = event->u.attribute_changed.time;
|
|
re->attribute_changed.screen = event->u.attribute_changed.screen;
|
|
re->attribute_changed.display_mask =
|
|
event->u.attribute_changed.display_mask;
|
|
re->attribute_changed.attribute = event->u.attribute_changed.attribute;
|
|
re->attribute_changed.value = event->u.attribute_changed.value;
|
|
break;
|
|
case TARGET_ATTRIBUTE_CHANGED_EVENT:
|
|
reTarget = (XNVCtrlEventTarget *) host;
|
|
eventTarget = (xnvctrlEventTarget *) wire;
|
|
reTarget->attribute_changed.type = eventTarget->u.u.type & 0x7F;
|
|
reTarget->attribute_changed.serial =
|
|
_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);
|
|
reTarget->attribute_changed.send_event =
|
|
((eventTarget->u.u.type & 0x80) != 0);
|
|
reTarget->attribute_changed.display = dpy;
|
|
reTarget->attribute_changed.time =
|
|
eventTarget->u.attribute_changed.time;
|
|
reTarget->attribute_changed.target_type =
|
|
eventTarget->u.attribute_changed.target_type;
|
|
reTarget->attribute_changed.target_id =
|
|
eventTarget->u.attribute_changed.target_id;
|
|
reTarget->attribute_changed.display_mask =
|
|
eventTarget->u.attribute_changed.display_mask;
|
|
reTarget->attribute_changed.attribute =
|
|
eventTarget->u.attribute_changed.attribute;
|
|
reTarget->attribute_changed.value =
|
|
eventTarget->u.attribute_changed.value;
|
|
break;
|
|
case TARGET_ATTRIBUTE_AVAILABILITY_CHANGED_EVENT:
|
|
reTargetAvailability = (XNVCtrlEventTargetAvailability *) host;
|
|
eventTarget = (xnvctrlEventTarget *) wire;
|
|
reTargetAvailability->attribute_changed.type =
|
|
eventTarget->u.u.type & 0x7F;
|
|
reTargetAvailability->attribute_changed.serial =
|
|
_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);
|
|
reTargetAvailability->attribute_changed.send_event =
|
|
((eventTarget->u.u.type & 0x80) != 0);
|
|
reTargetAvailability->attribute_changed.display = dpy;
|
|
reTargetAvailability->attribute_changed.time =
|
|
eventTarget->u.availability_changed.time;
|
|
reTargetAvailability->attribute_changed.target_type =
|
|
eventTarget->u.availability_changed.target_type;
|
|
reTargetAvailability->attribute_changed.target_id =
|
|
eventTarget->u.availability_changed.target_id;
|
|
reTargetAvailability->attribute_changed.display_mask =
|
|
eventTarget->u.availability_changed.display_mask;
|
|
reTargetAvailability->attribute_changed.attribute =
|
|
eventTarget->u.availability_changed.attribute;
|
|
reTargetAvailability->attribute_changed.availability =
|
|
eventTarget->u.availability_changed.availability;
|
|
reTargetAvailability->attribute_changed.value =
|
|
eventTarget->u.availability_changed.value;
|
|
break;
|
|
case TARGET_STRING_ATTRIBUTE_CHANGED_EVENT:
|
|
reTargetString = (XNVCtrlStringEventTarget *) host;
|
|
eventTarget = (xnvctrlEventTarget *) wire;
|
|
reTargetString->attribute_changed.type = eventTarget->u.u.type & 0x7F;
|
|
reTargetString->attribute_changed.serial =
|
|
_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);
|
|
reTargetString->attribute_changed.send_event =
|
|
((eventTarget->u.u.type & 0x80) != 0);
|
|
reTargetString->attribute_changed.display = dpy;
|
|
reTargetString->attribute_changed.time =
|
|
eventTarget->u.attribute_changed.time;
|
|
reTargetString->attribute_changed.target_type =
|
|
eventTarget->u.attribute_changed.target_type;
|
|
reTargetString->attribute_changed.target_id =
|
|
eventTarget->u.attribute_changed.target_id;
|
|
reTargetString->attribute_changed.display_mask =
|
|
eventTarget->u.attribute_changed.display_mask;
|
|
reTargetString->attribute_changed.attribute =
|
|
eventTarget->u.attribute_changed.attribute;
|
|
break;
|
|
case TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT:
|
|
reTargetBinary = (XNVCtrlBinaryEventTarget *) host;
|
|
eventTarget = (xnvctrlEventTarget *) wire;
|
|
reTargetBinary->attribute_changed.type = eventTarget->u.u.type & 0x7F;
|
|
reTargetBinary->attribute_changed.serial =
|
|
_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);
|
|
reTargetBinary->attribute_changed.send_event =
|
|
((eventTarget->u.u.type & 0x80) != 0);
|
|
reTargetBinary->attribute_changed.display = dpy;
|
|
reTargetBinary->attribute_changed.time =
|
|
eventTarget->u.attribute_changed.time;
|
|
reTargetBinary->attribute_changed.target_type =
|
|
eventTarget->u.attribute_changed.target_type;
|
|
reTargetBinary->attribute_changed.target_id =
|
|
eventTarget->u.attribute_changed.target_id;
|
|
reTargetBinary->attribute_changed.display_mask =
|
|
eventTarget->u.attribute_changed.display_mask;
|
|
reTargetBinary->attribute_changed.attribute =
|
|
eventTarget->u.attribute_changed.attribute;
|
|
break;
|
|
|
|
default:
|
|
return False;
|
|
}
|
|
|
|
return True;
|
|
}
|
|
|