/*
* 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;
}