62
62
void (* XRRSelectInput)
63
63
(Display *dpy, Window window, int mask);
65
XRRScreenConfiguration * (* XRRGetScreenInfo)
66
(Display *dpy, Drawable draw);
68
SizeID (* XRRConfigCurrentConfiguration)
69
(XRRScreenConfiguration *config, Rotation *rotation);
71
short (* XRRConfigCurrentRate)
72
(XRRScreenConfiguration *config);
74
Rotation (* XRRConfigRotations)
75
(XRRScreenConfiguration *config, Rotation *rotation);
77
XRRScreenSize * (* XRRConfigSizes)
78
(XRRScreenConfiguration *config, int *nsizes);
80
short * (* XRRConfigRates)
81
(XRRScreenConfiguration *config, int size_index, int *nrates);
83
Status (* XRRSetScreenConfig)
84
(Display *dpy, XRRScreenConfiguration *config, Drawable draw,
85
int size_index, Rotation rotation, Time timestamp);
87
Status (* XRRSetScreenConfigAndRate)
88
(Display *dpy, XRRScreenConfiguration *config, Drawable draw,
89
int size_index, Rotation rotation, short rate, Time timestamp);
91
void (* XRRFreeScreenConfigInfo)
92
(XRRScreenConfiguration *);
145
116
NV_DLSYM(__libXrandr->handle, "XRRSelectInput");
146
117
if ((error_str = dlerror()) != NULL) goto fail;
148
__libXrandr->XRRGetScreenInfo =
149
NV_DLSYM(__libXrandr->handle, "XRRGetScreenInfo");
150
if ((error_str = dlerror()) != NULL) goto fail;
152
__libXrandr->XRRConfigCurrentConfiguration =
153
NV_DLSYM(__libXrandr->handle, "XRRConfigCurrentConfiguration");
154
if ((error_str = dlerror()) != NULL) goto fail;
156
__libXrandr->XRRConfigCurrentRate =
157
NV_DLSYM(__libXrandr->handle, "XRRConfigCurrentRate");
158
if ((error_str = dlerror()) != NULL) goto fail;
160
__libXrandr->XRRConfigRotations =
161
NV_DLSYM(__libXrandr->handle, "XRRConfigRotations");
162
if ((error_str = dlerror()) != NULL) goto fail;
164
__libXrandr->XRRConfigSizes =
165
NV_DLSYM(__libXrandr->handle, "XRRConfigSizes");
166
if ((error_str = dlerror()) != NULL) goto fail;
168
__libXrandr->XRRConfigRates =
169
NV_DLSYM(__libXrandr->handle, "XRRConfigRates");
170
if ((error_str = dlerror()) != NULL) goto fail;
172
__libXrandr->XRRSetScreenConfig =
173
NV_DLSYM(__libXrandr->handle, "XRRSetScreenConfig");
174
if ((error_str = dlerror()) != NULL) goto fail;
176
__libXrandr->XRRSetScreenConfigAndRate =
177
NV_DLSYM(__libXrandr->handle, "XRRSetScreenConfigAndRate");
178
if ((error_str = dlerror()) != NULL) goto fail;
180
__libXrandr->XRRFreeScreenConfigInfo =
181
NV_DLSYM(__libXrandr->handle, "XRRFreeScreenConfigInfo");
182
if ((error_str = dlerror()) != NULL) goto fail;
185
120
/* Up the ref count */
186
121
__libXrandr->ref_count++;
235
170
/******************************************************************************
237
* Some XR&R functions fails on XFree86 4.3.0 with BadImplementation if the
238
* screen resolution is not the one the server started with. We work around
239
* that by temporarily installing an error handler, trying the call, and then
240
* disabling the rotation page if it fails.
244
static int errors = 0;
245
static int (*old_error_handler)(Display *, XErrorEvent *);
248
error_handler (Display *dpy, XErrorEvent *err)
253
} /* error_handler() */
257
/******************************************************************************
259
172
* Initializes the NvCtrlXrandrAttributes Extension by linking the
260
173
* libXrandr.so.2 library and resolving functions used.
371
/******************************************************************************
373
* Retrieves XRandR integer attributes
378
NvCtrlXrandrGetAttribute (NvCtrlAttributePrivateHandle *h,
381
XRRScreenConfiguration *sc;
382
Rotation rotation, rotations;
386
if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
387
return NvCtrlBadHandle;
389
if ( !h->xrandr || !__libXrandr ) {
390
return NvCtrlMissingExtension;
393
return NvCtrlBadArgument;
397
/* Get current screen configuration information */
398
sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
403
rotations = __libXrandr->XRRConfigRotations(sc, &rotation);
404
__libXrandr->XRRFreeScreenConfigInfo(sc);
407
/* Fetch right attribute */
410
case NV_CTRL_ATTR_XRANDR_ROTATION_SUPPORTED:
411
/* For rotation to be supported, there must
412
* be at least 2 orientations
414
*val = ( rotations != 1 && rotations != 2 &&
415
rotations != 4 && rotations != 8 ) ? 1 : 0;
418
case NV_CTRL_ATTR_XRANDR_ROTATIONS:
419
/* Return the available rotations */
423
case NV_CTRL_ATTR_XRANDR_ROTATION:
424
/* Return the current rotation */
425
*val = (int)rotation;
429
return NvCtrlNoAttribute;
431
} /* Done fetching attribute */
434
return NvCtrlSuccess;
436
} /* NvCtrlXrandrGetAttribute */
440
/******************************************************************************
442
* Sets XRandR integer attributes
447
set_rotation(NvCtrlAttributePrivateHandle *h, Rotation rotation)
449
XRRScreenConfiguration *sc;
450
Rotation cur_rotation, rotations;
455
assert(h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN);
457
/* Get current screen configuration information */
458
sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
463
cur_size = __libXrandr->XRRConfigCurrentConfiguration(sc, &cur_rotation);
464
rotations = __libXrandr->XRRConfigRotations(sc, &cur_rotation);
467
/* Check orientation we want is supported */
468
if ( !(rotations & rotation) ) {
469
__libXrandr->XRRFreeScreenConfigInfo(sc);
470
return NvCtrlBadArgument;
474
/* Set the orientation */
475
ret = __libXrandr->XRRSetScreenConfig(h->dpy, sc,
476
RootWindow(h->dpy, h->target_id),
477
cur_size, rotation, CurrentTime);
478
__libXrandr->XRRFreeScreenConfigInfo(sc);
480
return ( ret == Success )?NvCtrlSuccess:NvCtrlError;
482
} /* set_rotation() */
486
NvCtrlXrandrSetAttribute (NvCtrlAttributePrivateHandle *h,
490
if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
491
return NvCtrlBadHandle;
493
if ( !h->xrandr || !__libXrandr ) {
494
return NvCtrlMissingExtension;
498
/* Set right attribute */
501
case NV_CTRL_ATTR_XRANDR_ROTATION_SUPPORTED:
502
return NvCtrlReadOnlyAttribute;
505
case NV_CTRL_ATTR_XRANDR_ROTATIONS:
506
return NvCtrlReadOnlyAttribute;
509
case NV_CTRL_ATTR_XRANDR_ROTATION:
510
return set_rotation(h, (Rotation)val);
514
return NvCtrlNoAttribute;
518
return NvCtrlSuccess;
520
} /* NvCtrlXrandrSetAttribute */
524
259
* Get Xrandr String Attribute Values
549
284
return NvCtrlNoAttribute;
551
286
} /* NvCtrlXrandrGetStringAttribute() */
554
/******************************************************************************
556
* Sets XRandR size and refresh rate.
561
NvCtrlXrandrSetScreenMagicMode (NvCtrlAttributePrivateHandle *h,
562
int width, int height, int magic_ref_rate)
564
XRRScreenConfiguration *sc;
565
Rotation cur_rotation;
567
XRRScreenSize *sizes;
574
if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
575
return NvCtrlBadHandle;
578
if ( !h->xrandr || !__libXrandr ) {
579
return NvCtrlMissingExtension;
583
/* Get current screen configuration information */
584
sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
589
__libXrandr->XRRConfigRotations(sc, &cur_rotation);
592
/* Look for size that has matching refresh rate */
593
sizes = __libXrandr->XRRConfigSizes(sc, &nsizes);
594
while ( --nsizes >= 0 ) {
596
/* Must match in size */
597
if ( sizes[nsizes].width != width ||
598
sizes[nsizes].height != height ) {
602
rates = __libXrandr->XRRConfigRates(sc, nsizes, &nrates);
603
while ( --nrates >= 0 ) {
605
/* Set the mode if we found the rate */
606
if ( *rates == magic_ref_rate ) {
607
ret = __libXrandr->XRRSetScreenConfigAndRate
608
(h->dpy, sc, RootWindow(h->dpy, h->target_id), nsizes,
609
cur_rotation, magic_ref_rate, CurrentTime);
611
__libXrandr->XRRFreeScreenConfigInfo(sc);
612
return (ret == Success)?NvCtrlSuccess:NvCtrlError;
618
/* If we are here, then we could not find the correct mode to set */
619
__libXrandr->XRRFreeScreenConfigInfo(sc);
622
} /* NvCtrlXrandrSetScreenMagicMode */
626
/******************************************************************************
628
* Gets XRandR size and refresh rate.
633
NvCtrlXrandrGetScreenMagicMode (NvCtrlAttributePrivateHandle *h,
634
int *width, int *height, int *magic_ref_rate)
636
XRRScreenConfiguration *sc;
637
Rotation cur_rotation;
639
XRRScreenSize *sizes;
645
if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
646
return NvCtrlBadHandle;
649
if ( !h->xrandr || !__libXrandr ) {
650
return NvCtrlMissingExtension;
654
/* Get current screen configuration information */
655
sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
660
cur_size = __libXrandr->XRRConfigCurrentConfiguration(sc, &cur_rotation);
661
cur_rate = __libXrandr->XRRConfigCurrentRate(sc);
662
sizes = __libXrandr->XRRConfigSizes(sc, &nsizes);
663
if (cur_size >= nsizes) {
664
__libXrandr->XRRFreeScreenConfigInfo(sc);
669
/* Get the width & height from the size information */
670
*width = sizes[cur_size].width;
671
*height = sizes[cur_size].height;
672
*magic_ref_rate = (int)cur_rate;
674
__libXrandr->XRRFreeScreenConfigInfo(sc);
675
return NvCtrlSuccess;
677
} /* NvCtrlXrandrGetScreenMagicMode */