Path: blob/main_old/src/third_party/libXNVCtrl/NVCtrl.c
1693 views
/*1* Copyright (c) 2008 NVIDIA, Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a copy4* of this software and associated documentation files (the "Software"), to deal5* in the Software without restriction, including without limitation the rights6* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell7* copies of the Software, and to permit persons to whom the Software is8* furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE17* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*/2223/*24* Make sure that XTHREADS is defined, so that the25* LockDisplay/UnlockDisplay macros are expanded properly and the26* libXNVCtrl library properly protects the Display connection.27*/2829#if !defined(XTHREADS)30#define XTHREADS31#endif /* XTHREADS */3233#define NEED_EVENTS34#define NEED_REPLIES35#include <stdint.h>36#include <stdlib.h>37#include <X11/Xlibint.h>38#include <X11/Xutil.h>39#include <X11/extensions/Xext.h>40#include <X11/extensions/extutil.h>41#include "NVCtrlLib.h"42#include "nv_control.h"4344#define NVCTRL_EXT_EXISTS 145#define NVCTRL_EXT_NEED_TARGET_SWAP 246#define NVCTRL_EXT_64_BIT_ATTRIBUTES 447#define NVCTRL_EXT_NEED_CHECK (1 << (sizeof(XPointer) - 1))4849static XExtensionInfo _nvctrl_ext_info_data;50static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data;51static const char *nvctrl_extension_name = NV_CONTROL_NAME;5253#define XNVCTRLCheckExtension(dpy,i,val) \54XextCheckExtension (dpy, i, nvctrl_extension_name, val)55#define XNVCTRLSimpleCheckExtension(dpy,i) \56XextSimpleCheckExtension (dpy, i, nvctrl_extension_name)5758static int close_display();59static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info);60static Bool wire_to_event();61static /* const */ XExtensionHooks nvctrl_extension_hooks = {62NULL, /* create_gc */63NULL, /* copy_gc */64NULL, /* flush_gc */65NULL, /* free_gc */66NULL, /* create_font */67NULL, /* free_font */68close_display, /* close_display */69wire_to_event, /* wire_to_event */70NULL, /* event_to_wire */71NULL, /* error */72NULL, /* error_string */73};7475static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info,76nvctrl_extension_name,77&nvctrl_extension_hooks,78NV_CONTROL_EVENTS,79(XPointer)NVCTRL_EXT_NEED_CHECK)8081static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info)8283/*84* NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id85* fields in reversed order. In order to talk to one of these servers,86* we need to swap these fields.87*/8889static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info,90int *target_type, int *target_id)91{92uintptr_t flags = version_flags(dpy, info);9394/* We need to swap the target_type and target_id */95if (flags & NVCTRL_EXT_NEED_TARGET_SWAP) {96int tmp;97tmp = *target_type;98*target_type = *target_id;99*target_id = tmp;100}101}102103104Bool XNVCTRLQueryExtension (105Display *dpy,106int *event_basep,107int *error_basep108){109XExtDisplayInfo *info = find_display (dpy);110111if (XextHasExtension(info)) {112if (event_basep) *event_basep = info->codes->first_event;113if (error_basep) *error_basep = info->codes->first_error;114return True;115} else {116return False;117}118}119120/*121* Retrieve any cached flags that depend on the version of the NV-CONTROL122* extension.123*/124125static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info)126{127uintptr_t data = (uintptr_t)info->data;128129/* If necessary, determine the NV-CONTROL version */130if (data & NVCTRL_EXT_NEED_CHECK) {131int major, minor;132data = 0;133if (XNVCTRLQueryVersion(dpy, &major, &minor)) {134data |= NVCTRL_EXT_EXISTS;135if (major == 1 && (minor == 8 || minor == 9)) {136data |= NVCTRL_EXT_NEED_TARGET_SWAP;137}138if ((major > 1) || ((major == 1) && (minor > 20))) {139data |= NVCTRL_EXT_64_BIT_ATTRIBUTES;140}141}142143info->data = (XPointer)data;144}145146return data;147}148149Bool XNVCTRLQueryVersion (150Display *dpy,151int *major,152int *minor153){154XExtDisplayInfo *info = find_display (dpy);155xnvCtrlQueryExtensionReply rep;156xnvCtrlQueryExtensionReq *req;157158if(!XextHasExtension(info))159return False;160161XNVCTRLCheckExtension (dpy, info, False);162163LockDisplay (dpy);164GetReq (nvCtrlQueryExtension, req);165req->reqType = info->codes->major_opcode;166req->nvReqType = X_nvCtrlQueryExtension;167if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {168UnlockDisplay (dpy);169SyncHandle ();170return False;171}172if (major) *major = rep.major;173if (minor) *minor = rep.minor;174UnlockDisplay (dpy);175SyncHandle ();176return True;177}178179180Bool XNVCTRLIsNvScreen (181Display *dpy,182int screen183){184XExtDisplayInfo *info = find_display (dpy);185xnvCtrlIsNvReply rep;186xnvCtrlIsNvReq *req;187Bool isnv;188189if(!XextHasExtension(info))190return False;191192XNVCTRLCheckExtension (dpy, info, False);193194LockDisplay (dpy);195GetReq (nvCtrlIsNv, req);196req->reqType = info->codes->major_opcode;197req->nvReqType = X_nvCtrlIsNv;198req->screen = screen;199if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {200UnlockDisplay (dpy);201SyncHandle ();202return False;203}204isnv = rep.isnv;205UnlockDisplay (dpy);206SyncHandle ();207return isnv;208}209210211Bool XNVCTRLQueryTargetCount (212Display *dpy,213int target_type,214int *value215){216XExtDisplayInfo *info = find_display (dpy);217xnvCtrlQueryTargetCountReply rep;218xnvCtrlQueryTargetCountReq *req;219220if(!XextHasExtension(info))221return False;222223XNVCTRLCheckExtension (dpy, info, False);224225LockDisplay (dpy);226GetReq (nvCtrlQueryTargetCount, req);227req->reqType = info->codes->major_opcode;228req->nvReqType = X_nvCtrlQueryTargetCount;229req->target_type = target_type;230if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {231UnlockDisplay (dpy);232SyncHandle ();233return False;234}235if (value) *value = rep.count;236UnlockDisplay (dpy);237SyncHandle ();238return True;239}240241242void XNVCTRLSetTargetAttribute (243Display *dpy,244int target_type,245int target_id,246unsigned int display_mask,247unsigned int attribute,248int value249){250XExtDisplayInfo *info = find_display (dpy);251xnvCtrlSetAttributeReq *req;252253XNVCTRLSimpleCheckExtension (dpy, info);254XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);255256LockDisplay (dpy);257GetReq (nvCtrlSetAttribute, req);258req->reqType = info->codes->major_opcode;259req->nvReqType = X_nvCtrlSetAttribute;260req->target_type = target_type;261req->target_id = target_id;262req->display_mask = display_mask;263req->attribute = attribute;264req->value = value;265UnlockDisplay (dpy);266SyncHandle ();267}268269void XNVCTRLSetAttribute (270Display *dpy,271int screen,272unsigned int display_mask,273unsigned int attribute,274int value275){276XNVCTRLSetTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen,277display_mask, attribute, value);278}279280281Bool XNVCTRLSetTargetAttributeAndGetStatus (282Display *dpy,283int target_type,284int target_id,285unsigned int display_mask,286unsigned int attribute,287int value288){289XExtDisplayInfo *info = find_display (dpy);290xnvCtrlSetAttributeAndGetStatusReq *req;291xnvCtrlSetAttributeAndGetStatusReply rep;292Bool success;293294if(!XextHasExtension(info))295return False;296297XNVCTRLCheckExtension (dpy, info, False);298299LockDisplay (dpy);300GetReq (nvCtrlSetAttributeAndGetStatus, req);301req->reqType = info->codes->major_opcode;302req->nvReqType = X_nvCtrlSetAttributeAndGetStatus;303req->target_type = target_type;304req->target_id = target_id;305req->display_mask = display_mask;306req->attribute = attribute;307req->value = value;308if (!_XReply (dpy, (xReply *) &rep, 0, False)) {309UnlockDisplay (dpy);310SyncHandle ();311return False;312}313UnlockDisplay (dpy);314SyncHandle ();315316success = rep.flags;317return success;318}319320Bool XNVCTRLSetAttributeAndGetStatus (321Display *dpy,322int screen,323unsigned int display_mask,324unsigned int attribute,325int value326){327return XNVCTRLSetTargetAttributeAndGetStatus(dpy,328NV_CTRL_TARGET_TYPE_X_SCREEN,329screen, display_mask,330attribute, value);331}332333334Bool XNVCTRLQueryTargetAttribute (335Display *dpy,336int target_type,337int target_id,338unsigned int display_mask,339unsigned int attribute,340int *value341){342XExtDisplayInfo *info = find_display (dpy);343xnvCtrlQueryAttributeReply rep;344xnvCtrlQueryAttributeReq *req;345Bool exists;346347if(!XextHasExtension(info))348return False;349350XNVCTRLCheckExtension (dpy, info, False);351XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);352353LockDisplay (dpy);354GetReq (nvCtrlQueryAttribute, req);355req->reqType = info->codes->major_opcode;356req->nvReqType = X_nvCtrlQueryAttribute;357req->target_type = target_type;358req->target_id = target_id;359req->display_mask = display_mask;360req->attribute = attribute;361if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {362UnlockDisplay (dpy);363SyncHandle ();364return False;365}366exists = rep.flags;367if (exists && value) *value = rep.value;368UnlockDisplay (dpy);369SyncHandle ();370return exists;371}372373Bool XNVCTRLQueryAttribute (374Display *dpy,375int screen,376unsigned int display_mask,377unsigned int attribute,378int *value379){380return XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,381screen, display_mask, attribute, value);382}383384385Bool XNVCTRLQueryTargetAttribute64 (386Display *dpy,387int target_type,388int target_id,389unsigned int display_mask,390unsigned int attribute,391int64_t *value392){393XExtDisplayInfo *info = find_display(dpy);394xnvCtrlQueryAttribute64Reply rep;395xnvCtrlQueryAttributeReq *req;396Bool exists;397398if (!XextHasExtension(info))399return False;400401XNVCTRLCheckExtension(dpy, info, False);402XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);403404LockDisplay(dpy);405GetReq(nvCtrlQueryAttribute, req);406req->reqType = info->codes->major_opcode;407req->nvReqType = X_nvCtrlQueryAttribute64;408req->target_type = target_type;409req->target_id = target_id;410req->display_mask = display_mask;411req->attribute = attribute;412if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {413UnlockDisplay(dpy);414SyncHandle();415return False;416}417exists = rep.flags;418if (exists && value) *value = rep.value_64;419UnlockDisplay(dpy);420SyncHandle();421return exists;422}423424425Bool XNVCTRLQueryTargetStringAttribute (426Display *dpy,427int target_type,428int target_id,429unsigned int display_mask,430unsigned int attribute,431char **ptr432){433XExtDisplayInfo *info = find_display (dpy);434xnvCtrlQueryStringAttributeReply rep;435xnvCtrlQueryStringAttributeReq *req;436Bool exists;437int length, numbytes, slop;438439if (!ptr) return False;440441if(!XextHasExtension(info))442return False;443444XNVCTRLCheckExtension (dpy, info, False);445XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);446447LockDisplay (dpy);448GetReq (nvCtrlQueryStringAttribute, req);449req->reqType = info->codes->major_opcode;450req->nvReqType = X_nvCtrlQueryStringAttribute;451req->target_type = target_type;452req->target_id = target_id;453req->display_mask = display_mask;454req->attribute = attribute;455if (!_XReply (dpy, (xReply *) &rep, 0, False)) {456UnlockDisplay (dpy);457SyncHandle ();458return False;459}460length = rep.length;461numbytes = rep.n;462slop = numbytes & 3;463exists = rep.flags;464if (exists) {465*ptr = (char *) Xmalloc(numbytes);466}467if (!exists || !*ptr) {468_XEatData(dpy, length);469UnlockDisplay (dpy);470SyncHandle ();471return False;472} else {473_XRead(dpy, (char *) *ptr, numbytes);474if (slop) _XEatData(dpy, 4-slop);475}476UnlockDisplay (dpy);477SyncHandle ();478return exists;479}480481Bool XNVCTRLQueryStringAttribute (482Display *dpy,483int screen,484unsigned int display_mask,485unsigned int attribute,486char **ptr487){488return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,489screen, display_mask,490attribute, ptr);491}492493494Bool XNVCTRLSetTargetStringAttribute (495Display *dpy,496int target_type,497int target_id,498unsigned int display_mask,499unsigned int attribute,500char *ptr501){502XExtDisplayInfo *info = find_display (dpy);503xnvCtrlSetStringAttributeReq *req;504xnvCtrlSetStringAttributeReply rep;505int size;506Bool success;507508if(!XextHasExtension(info))509return False;510511XNVCTRLCheckExtension (dpy, info, False);512513size = strlen(ptr)+1;514515LockDisplay (dpy);516GetReq (nvCtrlSetStringAttribute, req);517req->reqType = info->codes->major_opcode;518req->nvReqType = X_nvCtrlSetStringAttribute;519req->target_type = target_type;520req->target_id = target_id;521req->display_mask = display_mask;522req->attribute = attribute;523req->length += ((size + 3) & ~3) >> 2;524req->num_bytes = size;525Data(dpy, ptr, size);526527if (!_XReply (dpy, (xReply *) &rep, 0, False)) {528UnlockDisplay (dpy);529SyncHandle ();530return False;531}532UnlockDisplay (dpy);533SyncHandle ();534535success = rep.flags;536return success;537}538539Bool XNVCTRLSetStringAttribute (540Display *dpy,541int screen,542unsigned int display_mask,543unsigned int attribute,544char *ptr545){546return XNVCTRLSetTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,547screen, display_mask,548attribute, ptr);549}550551552static Bool XNVCTRLQueryValidTargetAttributeValues32 (553Display *dpy,554XExtDisplayInfo *info,555int target_type,556int target_id,557unsigned int display_mask,558unsigned int attribute,559NVCTRLAttributeValidValuesRec *values560){561xnvCtrlQueryValidAttributeValuesReply rep;562xnvCtrlQueryValidAttributeValuesReq *req;563Bool exists;564565LockDisplay (dpy);566GetReq (nvCtrlQueryValidAttributeValues, req);567req->reqType = info->codes->major_opcode;568req->nvReqType = X_nvCtrlQueryValidAttributeValues;569req->target_type = target_type;570req->target_id = target_id;571req->display_mask = display_mask;572req->attribute = attribute;573if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {574UnlockDisplay (dpy);575SyncHandle ();576return False;577}578exists = rep.flags;579if (exists) {580values->type = rep.attr_type;581if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) {582values->u.range.min = rep.min;583values->u.range.max = rep.max;584}585if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) {586values->u.bits.ints = rep.bits;587}588values->permissions = rep.perms;589}590UnlockDisplay (dpy);591SyncHandle ();592return exists;593}594595596Bool XNVCTRLQueryValidTargetStringAttributeValues (597Display *dpy,598int target_type,599int target_id,600unsigned int display_mask,601unsigned int attribute,602NVCTRLAttributeValidValuesRec *values603){604XExtDisplayInfo *info = find_display(dpy);605Bool exists;606xnvCtrlQueryValidAttributeValuesReply rep;607xnvCtrlQueryValidAttributeValuesReq *req;608609if (!values) return False;610611if (!XextHasExtension(info))612return False;613614XNVCTRLCheckExtension(dpy, info, False);615616LockDisplay(dpy);617GetReq (nvCtrlQueryValidAttributeValues, req);618req->reqType = info->codes->major_opcode;619req->nvReqType = X_nvCtrlQueryValidStringAttributeValues;620req->target_type = target_type;621req->target_id = target_id;622req->display_mask = display_mask;623req->attribute = attribute;624if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) {625UnlockDisplay(dpy);626SyncHandle();627return False;628}629exists = rep.flags;630if (exists) {631values->type = rep.attr_type;632values->permissions = rep.perms;633}634UnlockDisplay(dpy);635SyncHandle();636return exists;637}638639640static Bool XNVCTRLQueryValidTargetAttributeValues64 (641Display *dpy,642XExtDisplayInfo *info,643int target_type,644int target_id,645unsigned int display_mask,646unsigned int attribute,647NVCTRLAttributeValidValuesRec *values648){649xnvCtrlQueryValidAttributeValues64Reply rep;650xnvCtrlQueryValidAttributeValuesReq *req;651Bool exists;652653LockDisplay(dpy);654GetReq(nvCtrlQueryValidAttributeValues, req);655req->reqType = info->codes->major_opcode;656req->nvReqType = X_nvCtrlQueryValidAttributeValues64;657req->target_type = target_type;658req->target_id = target_id;659req->display_mask = display_mask;660req->attribute = attribute;661if (!_XReply(dpy, (xReply *)&rep,662sz_xnvCtrlQueryValidAttributeValues64Reply_extra,663xTrue)) {664UnlockDisplay(dpy);665SyncHandle();666return False;667}668exists = rep.flags;669if (exists) {670values->type = rep.attr_type;671if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) {672values->u.range.min = rep.min_64;673values->u.range.max = rep.max_64;674}675if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) {676values->u.bits.ints = rep.bits_64;677}678values->permissions = rep.perms;679}680UnlockDisplay(dpy);681SyncHandle();682return exists;683}684685Bool XNVCTRLQueryValidTargetAttributeValues (686Display *dpy,687int target_type,688int target_id,689unsigned int display_mask,690unsigned int attribute,691NVCTRLAttributeValidValuesRec *values692){693XExtDisplayInfo *info = find_display(dpy);694Bool exists;695uintptr_t flags;696697if (!values) return False;698699if (!XextHasExtension(info))700return False;701702XNVCTRLCheckExtension(dpy, info, False);703XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);704705flags = version_flags(dpy,info);706707if (!(flags & NVCTRL_EXT_EXISTS))708return False;709710if (flags & NVCTRL_EXT_64_BIT_ATTRIBUTES) {711exists = XNVCTRLQueryValidTargetAttributeValues64(dpy, info,712target_type,713target_id,714display_mask,715attribute,716values);717} else {718exists = XNVCTRLQueryValidTargetAttributeValues32(dpy, info,719target_type,720target_id,721display_mask,722attribute,723values);724}725return exists;726}727728729Bool XNVCTRLQueryValidAttributeValues (730Display *dpy,731int screen,732unsigned int display_mask,733unsigned int attribute,734NVCTRLAttributeValidValuesRec *values735){736return XNVCTRLQueryValidTargetAttributeValues(dpy,737NV_CTRL_TARGET_TYPE_X_SCREEN,738screen, display_mask,739attribute, values);740}741742743static Bool QueryAttributePermissionsInternal (744Display *dpy,745unsigned int attribute,746NVCTRLAttributePermissionsRec *permissions,747unsigned int reqType748){749XExtDisplayInfo *info = find_display (dpy);750xnvCtrlQueryAttributePermissionsReply rep;751xnvCtrlQueryAttributePermissionsReq *req;752Bool exists;753754if(!XextHasExtension(info))755return False;756757XNVCTRLCheckExtension (dpy, info, False);758759LockDisplay(dpy);760GetReq(nvCtrlQueryAttributePermissions, req);761req->reqType = info->codes->major_opcode;762req->nvReqType = reqType;763req->attribute = attribute;764if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {765UnlockDisplay (dpy);766SyncHandle();767return False;768}769exists = rep.flags;770if (exists && permissions) {771permissions->type = rep.attr_type;772permissions->permissions = rep.perms;773}774UnlockDisplay(dpy);775SyncHandle();776return exists;777}778779780Bool XNVCTRLQueryAttributePermissions (781Display *dpy,782unsigned int attribute,783NVCTRLAttributePermissionsRec *permissions784){785return QueryAttributePermissionsInternal(dpy,786attribute,787permissions,788X_nvCtrlQueryAttributePermissions);789}790791792Bool XNVCTRLQueryStringAttributePermissions (793Display *dpy,794unsigned int attribute,795NVCTRLAttributePermissionsRec *permissions796){797return QueryAttributePermissionsInternal(dpy,798attribute,799permissions,800X_nvCtrlQueryStringAttributePermissions);801}802803804Bool XNVCTRLQueryBinaryDataAttributePermissions (805Display *dpy,806unsigned int attribute,807NVCTRLAttributePermissionsRec *permissions808){809return QueryAttributePermissionsInternal(dpy,810attribute,811permissions,812X_nvCtrlQueryBinaryDataAttributePermissions);813}814815816Bool XNVCTRLQueryStringOperationAttributePermissions (817Display *dpy,818unsigned int attribute,819NVCTRLAttributePermissionsRec *permissions820){821return QueryAttributePermissionsInternal(dpy,822attribute,823permissions,824X_nvCtrlQueryStringOperationAttributePermissions);825}826827828void XNVCTRLSetGvoColorConversion (829Display *dpy,830int screen,831float colorMatrix[3][3],832float colorOffset[3],833float colorScale[3]834){835XExtDisplayInfo *info = find_display (dpy);836xnvCtrlSetGvoColorConversionReq *req;837838XNVCTRLSimpleCheckExtension (dpy, info);839840LockDisplay (dpy);841GetReq (nvCtrlSetGvoColorConversion, req);842req->reqType = info->codes->major_opcode;843req->nvReqType = X_nvCtrlSetGvoColorConversion;844req->screen = screen;845846req->cscMatrix_y_r = colorMatrix[0][0];847req->cscMatrix_y_g = colorMatrix[0][1];848req->cscMatrix_y_b = colorMatrix[0][2];849850req->cscMatrix_cr_r = colorMatrix[1][0];851req->cscMatrix_cr_g = colorMatrix[1][1];852req->cscMatrix_cr_b = colorMatrix[1][2];853854req->cscMatrix_cb_r = colorMatrix[2][0];855req->cscMatrix_cb_g = colorMatrix[2][1];856req->cscMatrix_cb_b = colorMatrix[2][2];857858req->cscOffset_y = colorOffset[0];859req->cscOffset_cr = colorOffset[1];860req->cscOffset_cb = colorOffset[2];861862req->cscScale_y = colorScale[0];863req->cscScale_cr = colorScale[1];864req->cscScale_cb = colorScale[2];865866UnlockDisplay (dpy);867SyncHandle ();868}869870871Bool XNVCTRLQueryGvoColorConversion (872Display *dpy,873int screen,874float colorMatrix[3][3],875float colorOffset[3],876float colorScale[3]877){878XExtDisplayInfo *info = find_display (dpy);879xnvCtrlQueryGvoColorConversionReply rep;880xnvCtrlQueryGvoColorConversionReq *req;881882if(!XextHasExtension(info))883return False;884885XNVCTRLCheckExtension (dpy, info, False);886887LockDisplay (dpy);888889GetReq (nvCtrlQueryGvoColorConversion, req);890req->reqType = info->codes->major_opcode;891req->nvReqType = X_nvCtrlQueryGvoColorConversion;892req->screen = screen;893894if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {895UnlockDisplay (dpy);896SyncHandle ();897return False;898}899900_XRead(dpy, (char *)(colorMatrix), 36);901_XRead(dpy, (char *)(colorOffset), 12);902_XRead(dpy, (char *)(colorScale), 12);903904UnlockDisplay (dpy);905SyncHandle ();906907return True;908}909910911Bool XNVCtrlSelectTargetNotify (912Display *dpy,913int target_type,914int target_id,915int notify_type,916Bool onoff917){918XExtDisplayInfo *info = find_display (dpy);919xnvCtrlSelectTargetNotifyReq *req;920921if(!XextHasExtension (info))922return False;923924XNVCTRLCheckExtension (dpy, info, False);925926LockDisplay (dpy);927GetReq (nvCtrlSelectTargetNotify, req);928req->reqType = info->codes->major_opcode;929req->nvReqType = X_nvCtrlSelectTargetNotify;930req->target_type = target_type;931req->target_id = target_id;932req->notifyType = notify_type;933req->onoff = onoff;934UnlockDisplay (dpy);935SyncHandle ();936937return True;938}939940941Bool XNVCtrlSelectNotify (942Display *dpy,943int screen,944int type,945Bool onoff946){947XExtDisplayInfo *info = find_display (dpy);948xnvCtrlSelectNotifyReq *req;949950if(!XextHasExtension (info))951return False;952953XNVCTRLCheckExtension (dpy, info, False);954955LockDisplay (dpy);956GetReq (nvCtrlSelectNotify, req);957req->reqType = info->codes->major_opcode;958req->nvReqType = X_nvCtrlSelectNotify;959req->screen = screen;960req->notifyType = type;961req->onoff = onoff;962UnlockDisplay (dpy);963SyncHandle ();964965return True;966}967968Bool XNVCTRLQueryTargetBinaryData (969Display *dpy,970int target_type,971int target_id,972unsigned int display_mask,973unsigned int attribute,974unsigned char **ptr,975int *len976){977XExtDisplayInfo *info = find_display (dpy);978xnvCtrlQueryBinaryDataReply rep;979xnvCtrlQueryBinaryDataReq *req;980Bool exists;981int length, numbytes, slop;982983if (!ptr) return False;984985if(!XextHasExtension(info))986return False;987988XNVCTRLCheckExtension (dpy, info, False);989XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);990991LockDisplay (dpy);992GetReq (nvCtrlQueryBinaryData, req);993req->reqType = info->codes->major_opcode;994req->nvReqType = X_nvCtrlQueryBinaryData;995req->target_type = target_type;996req->target_id = target_id;997req->display_mask = display_mask;998req->attribute = attribute;999if (!_XReply (dpy, (xReply *) &rep, 0, False)) {1000UnlockDisplay (dpy);1001SyncHandle ();1002return False;1003}1004length = rep.length;1005numbytes = rep.n;1006slop = numbytes & 3;1007exists = rep.flags;1008if (exists) {1009*ptr = (unsigned char *) Xmalloc(numbytes);1010}1011if (!exists || !*ptr) {1012_XEatData(dpy, length);1013UnlockDisplay (dpy);1014SyncHandle ();1015return False;1016} else {1017_XRead(dpy, (char *) *ptr, numbytes);1018if (slop) _XEatData(dpy, 4-slop);1019}1020if (len) *len = numbytes;1021UnlockDisplay (dpy);1022SyncHandle ();1023return exists;1024}10251026Bool XNVCTRLQueryBinaryData (1027Display *dpy,1028int screen,1029unsigned int display_mask,1030unsigned int attribute,1031unsigned char **ptr,1032int *len1033){1034return XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,1035screen, display_mask,1036attribute, ptr, len);1037}10381039Bool XNVCTRLStringOperation (1040Display *dpy,1041int target_type,1042int target_id,1043unsigned int display_mask,1044unsigned int attribute,1045char *pIn,1046char **ppOut1047) {1048XExtDisplayInfo *info = find_display(dpy);1049xnvCtrlStringOperationReq *req;1050xnvCtrlStringOperationReply rep;1051Bool ret;1052int inSize, outSize, length, slop;10531054if (!XextHasExtension(info))1055return False;10561057if (!ppOut)1058return False;10591060*ppOut = NULL;10611062XNVCTRLCheckExtension(dpy, info, False);1063XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);10641065if (pIn) {1066inSize = strlen(pIn) + 1;1067} else {1068inSize = 0;1069}10701071LockDisplay(dpy);1072GetReq(nvCtrlStringOperation, req);10731074req->reqType = info->codes->major_opcode;1075req->nvReqType = X_nvCtrlStringOperation;1076req->target_type = target_type;1077req->target_id = target_id;1078req->display_mask = display_mask;1079req->attribute = attribute;10801081req->length += ((inSize + 3) & ~3) >> 2;1082req->num_bytes = inSize;10831084if (pIn) {1085Data(dpy, pIn, inSize);1086}10871088if (!_XReply (dpy, (xReply *) &rep, 0, False)) {1089UnlockDisplay(dpy);1090SyncHandle();1091return False;1092}10931094length = rep.length;1095outSize = rep.num_bytes;1096slop = outSize & 3;10971098if (outSize) *ppOut = (char *) Xmalloc(outSize);10991100if (!*ppOut) {1101_XEatData(dpy, length);1102} else {1103_XRead(dpy, (char *) *ppOut, outSize);1104if (slop) _XEatData(dpy, 4-slop);1105}11061107ret = rep.ret;11081109UnlockDisplay(dpy);1110SyncHandle();11111112return ret;1113}111411151116static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire)1117{1118XExtDisplayInfo *info = find_display (dpy);1119XNVCtrlEvent *re;1120xnvctrlEvent *event;1121XNVCtrlEventTarget *reTarget;1122xnvctrlEventTarget *eventTarget;1123XNVCtrlEventTargetAvailability *reTargetAvailability;1124XNVCtrlStringEventTarget *reTargetString;1125XNVCtrlBinaryEventTarget *reTargetBinary;11261127XNVCTRLCheckExtension (dpy, info, False);11281129switch ((wire->u.u.type & 0x7F) - info->codes->first_event) {1130case ATTRIBUTE_CHANGED_EVENT:1131re = (XNVCtrlEvent *) host;1132event = (xnvctrlEvent *) wire;1133re->attribute_changed.type = event->u.u.type & 0x7F;1134re->attribute_changed.serial =1135_XSetLastRequestRead(dpy, (xGenericReply*) event);1136re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0);1137re->attribute_changed.display = dpy;1138re->attribute_changed.time = event->u.attribute_changed.time;1139re->attribute_changed.screen = event->u.attribute_changed.screen;1140re->attribute_changed.display_mask =1141event->u.attribute_changed.display_mask;1142re->attribute_changed.attribute = event->u.attribute_changed.attribute;1143re->attribute_changed.value = event->u.attribute_changed.value;1144break;1145case TARGET_ATTRIBUTE_CHANGED_EVENT:1146reTarget = (XNVCtrlEventTarget *) host;1147eventTarget = (xnvctrlEventTarget *) wire;1148reTarget->attribute_changed.type = eventTarget->u.u.type & 0x7F;1149reTarget->attribute_changed.serial =1150_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);1151reTarget->attribute_changed.send_event =1152((eventTarget->u.u.type & 0x80) != 0);1153reTarget->attribute_changed.display = dpy;1154reTarget->attribute_changed.time =1155eventTarget->u.attribute_changed.time;1156reTarget->attribute_changed.target_type =1157eventTarget->u.attribute_changed.target_type;1158reTarget->attribute_changed.target_id =1159eventTarget->u.attribute_changed.target_id;1160reTarget->attribute_changed.display_mask =1161eventTarget->u.attribute_changed.display_mask;1162reTarget->attribute_changed.attribute =1163eventTarget->u.attribute_changed.attribute;1164reTarget->attribute_changed.value =1165eventTarget->u.attribute_changed.value;1166break;1167case TARGET_ATTRIBUTE_AVAILABILITY_CHANGED_EVENT:1168reTargetAvailability = (XNVCtrlEventTargetAvailability *) host;1169eventTarget = (xnvctrlEventTarget *) wire;1170reTargetAvailability->attribute_changed.type =1171eventTarget->u.u.type & 0x7F;1172reTargetAvailability->attribute_changed.serial =1173_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);1174reTargetAvailability->attribute_changed.send_event =1175((eventTarget->u.u.type & 0x80) != 0);1176reTargetAvailability->attribute_changed.display = dpy;1177reTargetAvailability->attribute_changed.time =1178eventTarget->u.availability_changed.time;1179reTargetAvailability->attribute_changed.target_type =1180eventTarget->u.availability_changed.target_type;1181reTargetAvailability->attribute_changed.target_id =1182eventTarget->u.availability_changed.target_id;1183reTargetAvailability->attribute_changed.display_mask =1184eventTarget->u.availability_changed.display_mask;1185reTargetAvailability->attribute_changed.attribute =1186eventTarget->u.availability_changed.attribute;1187reTargetAvailability->attribute_changed.availability =1188eventTarget->u.availability_changed.availability;1189reTargetAvailability->attribute_changed.value =1190eventTarget->u.availability_changed.value;1191break;1192case TARGET_STRING_ATTRIBUTE_CHANGED_EVENT:1193reTargetString = (XNVCtrlStringEventTarget *) host;1194eventTarget = (xnvctrlEventTarget *) wire;1195reTargetString->attribute_changed.type = eventTarget->u.u.type & 0x7F;1196reTargetString->attribute_changed.serial =1197_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);1198reTargetString->attribute_changed.send_event =1199((eventTarget->u.u.type & 0x80) != 0);1200reTargetString->attribute_changed.display = dpy;1201reTargetString->attribute_changed.time =1202eventTarget->u.attribute_changed.time;1203reTargetString->attribute_changed.target_type =1204eventTarget->u.attribute_changed.target_type;1205reTargetString->attribute_changed.target_id =1206eventTarget->u.attribute_changed.target_id;1207reTargetString->attribute_changed.display_mask =1208eventTarget->u.attribute_changed.display_mask;1209reTargetString->attribute_changed.attribute =1210eventTarget->u.attribute_changed.attribute;1211break;1212case TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT:1213reTargetBinary = (XNVCtrlBinaryEventTarget *) host;1214eventTarget = (xnvctrlEventTarget *) wire;1215reTargetBinary->attribute_changed.type = eventTarget->u.u.type & 0x7F;1216reTargetBinary->attribute_changed.serial =1217_XSetLastRequestRead(dpy, (xGenericReply*) eventTarget);1218reTargetBinary->attribute_changed.send_event =1219((eventTarget->u.u.type & 0x80) != 0);1220reTargetBinary->attribute_changed.display = dpy;1221reTargetBinary->attribute_changed.time =1222eventTarget->u.attribute_changed.time;1223reTargetBinary->attribute_changed.target_type =1224eventTarget->u.attribute_changed.target_type;1225reTargetBinary->attribute_changed.target_id =1226eventTarget->u.attribute_changed.target_id;1227reTargetBinary->attribute_changed.display_mask =1228eventTarget->u.attribute_changed.display_mask;1229reTargetBinary->attribute_changed.attribute =1230eventTarget->u.attribute_changed.attribute;1231break;12321233default:1234return False;1235}12361237return True;1238}1239124012411242