2
* Copyright (c) 2008 NVIDIA, Corporation
4
* Permission is hereby granted, free of charge, to any person obtaining a copy
5
* of this software and associated documentation files (the "Software"), to deal
6
* in the Software without restriction, including without limitation the rights
7
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
* copies of the Software, and to permit persons to whom the Software is
9
* furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
#include <X11/Xlibint.h>
31
#include <X11/Xutil.h>
32
#include <X11/extensions/Xext.h>
33
#include <X11/extensions/extutil.h>
34
#include "va_nvctrl.h"
36
#define NV_CONTROL_ERRORS 0
37
#define NV_CONTROL_EVENTS 5
38
#define NV_CONTROL_NAME "NV-CONTROL"
40
#define NV_CTRL_TARGET_TYPE_X_SCREEN 0
41
#define NV_CTRL_TARGET_TYPE_GPU 1
42
#define NV_CTRL_TARGET_TYPE_FRAMELOCK 2
43
#define NV_CTRL_TARGET_TYPE_VCSC 3 /* Visual Computing System */
45
#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R--G */
47
#define X_nvCtrlQueryExtension 0
48
#define X_nvCtrlIsNv 1
49
#define X_nvCtrlQueryStringAttribute 4
55
} xnvCtrlQueryExtensionReq;
56
#define sz_xnvCtrlQueryExtensionReq 4
59
BYTE type; /* X_Reply */
61
CARD16 sequenceNumber B16;
70
} xnvCtrlQueryExtensionReply;
71
#define sz_xnvCtrlQueryExtensionReply 32
79
#define sz_xnvCtrlIsNvReq 8
82
BYTE type; /* X_Reply */
84
CARD16 sequenceNumber B16;
93
#define sz_xnvCtrlIsNvReply 32
99
CARD16 target_id B16; /* X screen number or GPU number */
100
CARD16 target_type B16; /* X screen or GPU */
101
CARD32 display_mask B32;
102
CARD32 attribute B32;
103
} xnvCtrlQueryStringAttributeReq;
104
#define sz_xnvCtrlQueryStringAttributeReq 16
109
CARD16 sequenceNumber B16;
112
CARD32 n B32; /* Length of string */
117
} xnvCtrlQueryStringAttributeReply;
118
#define sz_xnvCtrlQueryStringAttributeReply 32
120
#define NVCTRL_EXT_NEED_CHECK (XPointer)(~0)
121
#define NVCTRL_EXT_NEED_NOTHING (XPointer)(0)
122
#define NVCTRL_EXT_NEED_TARGET_SWAP (XPointer)(1)
124
static XExtensionInfo _nvctrl_ext_info_data;
125
static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data;
126
static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME;
128
#define XNVCTRLCheckExtension(dpy,i,val) \
129
XextCheckExtension (dpy, i, nvctrl_extension_name, val)
130
#define XNVCTRLSimpleCheckExtension(dpy,i) \
131
XextSimpleCheckExtension (dpy, i, nvctrl_extension_name)
133
static int close_display();
134
static /* const */ XExtensionHooks nvctrl_extension_hooks = {
135
NULL, /* create_gc */
139
NULL, /* create_font */
140
NULL, /* free_font */
141
close_display, /* close_display */
142
NULL, /* wire_to_event */
143
NULL, /* event_to_wire */
145
NULL, /* error_string */
148
static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info,
149
nvctrl_extension_name,
150
&nvctrl_extension_hooks,
151
NV_CONTROL_EVENTS, NVCTRL_EXT_NEED_CHECK)
153
static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info)
155
static Bool XNVCTRLQueryVersion (Display *dpy, int *major, int *minor);
158
* NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id
159
* fields in reversed order. In order to talk to one of these servers,
160
* we need to swap these fields.
162
static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info,
163
int *target_type, int *target_id)
165
/* Find out what the server's NV-CONTROL version is and
166
* setup for swapping if we need to.
168
if (info->data == NVCTRL_EXT_NEED_CHECK) {
171
if (XNVCTRLQueryVersion(dpy, &major, &minor)) {
173
(minor == 8 || minor == 9)) {
174
info->data = NVCTRL_EXT_NEED_TARGET_SWAP;
176
info->data = NVCTRL_EXT_NEED_NOTHING;
179
info->data = NVCTRL_EXT_NEED_NOTHING;
183
/* We need to swap the target_type and target_id */
184
if (info->data == NVCTRL_EXT_NEED_TARGET_SWAP) {
187
*target_type = *target_id;
193
static Bool XNVCTRLQueryExtension (
198
XExtDisplayInfo *info = find_display (dpy);
200
if (XextHasExtension(info)) {
201
if (event_basep) *event_basep = info->codes->first_event;
202
if (error_basep) *error_basep = info->codes->first_error;
210
static Bool XNVCTRLQueryVersion (
215
XExtDisplayInfo *info = find_display (dpy);
216
xnvCtrlQueryExtensionReply rep;
217
xnvCtrlQueryExtensionReq *req;
219
if(!XextHasExtension(info))
222
XNVCTRLCheckExtension (dpy, info, False);
225
GetReq (nvCtrlQueryExtension, req);
226
req->reqType = info->codes->major_opcode;
227
req->nvReqType = X_nvCtrlQueryExtension;
228
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
233
if (major) *major = rep.major;
234
if (minor) *minor = rep.minor;
241
static Bool XNVCTRLIsNvScreen (
245
XExtDisplayInfo *info = find_display (dpy);
246
xnvCtrlIsNvReply rep;
250
if(!XextHasExtension(info))
253
XNVCTRLCheckExtension (dpy, info, False);
256
GetReq (nvCtrlIsNv, req);
257
req->reqType = info->codes->major_opcode;
258
req->nvReqType = X_nvCtrlIsNv;
259
req->screen = screen;
260
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
272
static Bool XNVCTRLQueryTargetStringAttribute (
276
unsigned int display_mask,
277
unsigned int attribute,
280
XExtDisplayInfo *info = find_display (dpy);
281
xnvCtrlQueryStringAttributeReply rep;
282
xnvCtrlQueryStringAttributeReq *req;
284
int length, numbytes, slop;
286
if (!ptr) return False;
288
if(!XextHasExtension(info))
291
XNVCTRLCheckExtension (dpy, info, False);
292
XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id);
295
GetReq (nvCtrlQueryStringAttribute, req);
296
req->reqType = info->codes->major_opcode;
297
req->nvReqType = X_nvCtrlQueryStringAttribute;
298
req->target_type = target_type;
299
req->target_id = target_id;
300
req->display_mask = display_mask;
301
req->attribute = attribute;
302
if (!_XReply (dpy, (xReply *) &rep, 0, False)) {
310
*ptr = (char *) Xmalloc(numbytes);
312
_XEatData(dpy, length);
317
_XRead(dpy, (char *) *ptr, numbytes);
318
if (slop) _XEatData(dpy, 4-slop);
326
static Bool XNVCTRLQueryStringAttribute (
329
unsigned int display_mask,
330
unsigned int attribute,
333
return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN,
334
screen, display_mask,
339
Bool VA_NVCTRLQueryDirectRenderingCapable( Display *dpy, int screen,
348
if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base))
351
if (isCapable && XNVCTRLIsNvScreen(dpy, screen))
357
Bool VA_NVCTRLGetClientDriverName( Display *dpy, int screen,
358
int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
359
int *ddxDriverPatchVersion, char **clientDriverName )
361
if (ddxDriverMajorVersion)
362
*ddxDriverMajorVersion = 0;
363
if (ddxDriverMinorVersion)
364
*ddxDriverMinorVersion = 0;
365
if (ddxDriverPatchVersion)
366
*ddxDriverPatchVersion = 0;
367
if (clientDriverName)
368
*clientDriverName = NULL;
370
char *nvidia_driver_version = NULL;
371
if (!XNVCTRLQueryStringAttribute(dpy, screen, 0, NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &nvidia_driver_version))
374
char *end, *str = nvidia_driver_version;
375
unsigned long v = strtoul(str, &end, 10);
376
if (end && end != str) {
377
if (ddxDriverMajorVersion)
378
*ddxDriverMajorVersion = v;
379
if (*(str = end) == '.') {
380
v = strtoul(str + 1, &end, 10);
381
if (end && end != str && (*end == '.' || *end == '\0')) {
382
if (ddxDriverMinorVersion)
383
*ddxDriverMinorVersion = v;
384
if (*(str = end) == '.') {
385
v = strtoul(str + 1, &end, 10);
386
if (end && end != str && *end == '\0') {
387
if (ddxDriverPatchVersion)
388
*ddxDriverPatchVersion = v;
394
Xfree(nvidia_driver_version);
396
if (clientDriverName)
397
*clientDriverName = strdup("nvidia");