summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-11-27 15:41:03 -0800
committerEric Anholt <eric@anholt.net>2006-11-27 15:41:03 -0800
commit7fcdcbb0f9c4736bd678be7f9bf76d472293233f (patch)
treed04fbf955a483508874f8d0981293791de538587 /src
parent875867f275803682e58f0649f054a83293c6e02c (diff)
parent0dba1be7969aa56f934d93889cbd589b3dafd3d4 (diff)
Merge branch 'randr-1.2'
Conflicts: configure.ac
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am10
-rw-r--r--src/Xrandr.c506
-rw-r--r--src/Xrandrint.h16
-rw-r--r--src/XrrConfig.c424
-rw-r--r--src/XrrCrtc.c178
-rw-r--r--src/XrrMode.c63
-rw-r--r--src/XrrOutput.c131
-rw-r--r--src/XrrProperty.c344
-rw-r--r--src/XrrScreen.c246
10 files changed, 1510 insertions, 409 deletions
diff --git a/src/.gitignore b/src/.gitignore
index a947c47..00409a0 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -2,5 +2,6 @@
.libs
libXrandr.la
*.lo
+*.o
Makefile
Makefile.in
diff --git a/src/Makefile.am b/src/Makefile.am
index dce56e4..b884a39 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,14 +2,20 @@ lib_LTLIBRARIES = libXrandr.la
libXrandr_la_SOURCES = \
Xrandr.c \
- Xrandrint.h
+ Xrandrint.h \
+ XrrConfig.c \
+ XrrCrtc.c \
+ XrrMode.c \
+ XrrOutput.c \
+ XrrProperty.c \
+ XrrScreen.c
libXrandr_la_LIBADD = @X_LIBS@ @RANDR_LIBS@
AM_CFLAGS = @X_CFLAGS@ @RANDR_CFLAGS@ @MALLOC_ZERO_CFLAGS@
INCLUDES = -I$(top_srcdir)/include/X11/extensions
-libXrandr_la_LDFLAGS = -version-number 2:0:0 -no-undefined
+libXrandr_la_LDFLAGS = -version-number 2:1:0 -no-undefined
libXrandrincludedir = $(includedir)/X11/extensions
libXrandrinclude_HEADERS = $(top_srcdir)/include/X11/extensions/Xrandr.h
diff --git a/src/Xrandr.c b/src/Xrandr.c
index 7f256a7..f8bdf02 100644
--- a/src/Xrandr.c
+++ b/src/Xrandr.c
@@ -42,8 +42,6 @@ char XRRExtensionName[] = RANDR_NAME;
static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire);
-static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window);
-
static int
XRRCloseDisplay (Display *dpy, XExtCodes *codes);
@@ -64,19 +62,16 @@ static /* const */ XExtensionHooks rr_extension_hooks = {
static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = XRRFindDisplay(dpy);
- XRRScreenChangeNotifyEvent *aevent;
- xRRScreenChangeNotifyEvent *awire;
RRCheckExtension(dpy, info, False);
switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
{
- case RRScreenChangeNotify:
- awire = (xRRScreenChangeNotifyEvent *) wire;
- aevent = (XRRScreenChangeNotifyEvent *) event;
+ case RRScreenChangeNotify: {
+ XRRScreenChangeNotifyEvent *aevent= (XRRScreenChangeNotifyEvent *) event;
+ xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire;
aevent->type = awire->type & 0x7F;
- aevent->serial = _XSetLastRequestRead(dpy,
- (xGenericReply *) wire);
+ aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
aevent->send_event = (awire->type & 0x80) != 0;
aevent->display = dpy;
aevent->window = awire->window;
@@ -91,6 +86,53 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
aevent->mwidth = awire->widthInMillimeters;
aevent->mheight = awire->heightInMillimeters;
return True;
+ }
+ case RRNotify: {
+ XRRNotifyEvent *aevent = (XRRNotifyEvent *) event;
+ xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire;
+ aevent->type = awire->type & 0x7F;
+ aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+ aevent->send_event = (awire->type & 0x80) != 0;
+ aevent->display = dpy;
+ aevent->window = awire->window;
+ aevent->subtype = awire->subCode;
+ switch (aevent->subtype) {
+ case RRNotify_OutputChange: {
+ XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event;
+ xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire;
+ aevent->output = awire->output;
+ aevent->crtc = awire->crtc;
+ aevent->mode = awire->mode;
+ aevent->rotation = awire->rotation;
+ aevent->connection = awire->connection;
+ aevent->subpixel_order = awire->subpixelOrder;
+ return True;
+ }
+ case RRNotify_CrtcChange: {
+ XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event;
+ xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire;
+ aevent->crtc = awire->crtc;
+ aevent->mode = awire->mode;
+ aevent->rotation = awire->rotation;
+ aevent->x = awire->x;
+ aevent->y = awire->y;
+ aevent->width = awire->height;
+ aevent->height = awire->height;
+ return True;
+ }
+ case RRNotify_OutputProperty: {
+ XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event;
+ xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire;
+ aevent->output = awire->output;
+ aevent->property = awire->atom;
+ aevent->timestamp = awire->timestamp;
+ aevent->state = awire->state;
+ return True;
+ }
+
+ break;
+ }
+ }
}
return False;
@@ -99,16 +141,14 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = XRRFindDisplay(dpy);
- XRRScreenChangeNotifyEvent *aevent;
- xRRScreenChangeNotifyEvent *awire;
RRCheckExtension(dpy, info, False);
switch ((event->type & 0x7F) - info->codes->first_event)
{
- case RRScreenChangeNotify:
- awire = (xRRScreenChangeNotifyEvent *) wire;
- aevent = (XRRScreenChangeNotifyEvent *) event;
+ case RRScreenChangeNotify: {
+ xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire;
+ XRRScreenChangeNotifyEvent *aevent = (XRRScreenChangeNotifyEvent *) event;
awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
awire->rotation = (CARD8) aevent->rotation;
awire->sequenceNumber = aevent->serial & 0xFFFF;
@@ -123,6 +163,49 @@ static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire)
awire->widthInMillimeters = aevent->mwidth;
awire->heightInMillimeters = aevent->mheight;
return True;
+ }
+ case RRNotify: {
+ xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire;
+ XRRNotifyEvent *aevent = (XRRNotifyEvent *) event;
+ awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
+ awire->sequenceNumber = aevent->serial & 0xFFFF;
+ awire->window = aevent->window;
+ awire->subCode = aevent->subtype;
+ switch (aevent->subtype) {
+ case RRNotify_OutputChange: {
+ xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire;
+ XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event;
+ awire->output = aevent->output;
+ awire->crtc = aevent->crtc;
+ awire->mode = aevent->mode;
+ awire->rotation = aevent->rotation;
+ awire->connection = aevent->connection;
+ awire->subpixelOrder = aevent->subpixel_order;
+ return True;
+ }
+ case RRNotify_CrtcChange: {
+ xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire;
+ XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event;
+ awire->crtc = aevent->crtc;
+ awire->mode = aevent->mode;
+ awire->rotation = aevent->rotation;
+ awire->x = aevent->x;
+ awire->y = aevent->y;
+ awire->width = aevent->height;
+ awire->height = aevent->height;
+ return True;
+ }
+ case RRNotify_OutputProperty: {
+ xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire;
+ XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event;
+ awire->output = aevent->output;
+ awire->atom = aevent->property;
+ awire->timestamp = aevent->timestamp;
+ awire->state = aevent->state;
+ return True;
+ }
+ }
+ }
}
return False;
}
@@ -178,157 +261,6 @@ XRRCloseDisplay (Display *dpy, XExtCodes *codes)
UnlockDisplay(dpy);
return XextRemoveDisplay (&XRRExtensionInfo, dpy);
}
-
-
-Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation)
-{
- *current_rotation = config->current_rotation;
- return config->rotations;
-}
-
-XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes)
-{
- *nsizes = config->nsizes;
- return config->sizes;
-}
-
-short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates)
-{
- short *r = config->rates;
- int nents = config->nrates;
-
- /* Skip over the intervening rate lists */
- while (sizeID > 0 && nents > 0)
- {
- int i = (*r + 1);
- r += i;
- nents -= i;
- sizeID--;
- }
- if (!nents)
- {
- *nrates = 0;
- return 0;
- }
- *nrates = (int) *r;
- return r + 1;
-}
-
-Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp)
-{
- *config_timestamp = config->config_timestamp;
- return config->timestamp;
-}
-
-
-SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config,
- Rotation *rotation)
-{
- *rotation = (Rotation) config->current_rotation;
- return (SizeID) config->current_size;
-}
-
-short XRRConfigCurrentRate (XRRScreenConfiguration *config)
-{
- return config->current_rate;
-}
-
-/*
- * Go get the screen configuration data and salt it away for future use;
- * returns NULL if extension not supported
- */
-static XRRScreenConfiguration *_XRRValidateCache (Display *dpy, int screen)
-{
- XExtDisplayInfo *info = XRRFindDisplay (dpy);
- XRRScreenConfiguration **configs;
- XRandRInfo *xrri;
-
- if (XextHasExtension(info)) {
- xrri = (XRandRInfo *) info->data;
- configs = xrri->config;
-
- if (configs[screen] == NULL)
- configs[screen] = _XRRGetScreenInfo (dpy, RootWindow(dpy, screen));
- return configs[screen];
- } else {
- return NULL;
- }
-}
-
-/* given a screen, return the information from the (possibly) cached data */
-Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation)
-{
- XRRScreenConfiguration *config;
- Rotation cr;
- LockDisplay(dpy);
- if ((config = _XRRValidateCache(dpy, screen))) {
- *current_rotation = config->current_rotation;
- cr = config->rotations;
- UnlockDisplay(dpy);
- return cr;
- }
- else {
- UnlockDisplay(dpy);
- *current_rotation = RR_Rotate_0;
- return 0; /* no rotations supported */
- }
-}
-
-/* given a screen, return the information from the (possibly) cached data */
-XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes)
-{
- XRRScreenConfiguration *config;
- XRRScreenSize *sizes;
-
- LockDisplay(dpy);
- if ((config = _XRRValidateCache(dpy, screen))) {
- *nsizes = config->nsizes;
- sizes = config->sizes;
- UnlockDisplay(dpy);
- return sizes;
- }
- else {
- UnlockDisplay(dpy);
- *nsizes = 0;
- return NULL;
- }
-}
-
-short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates)
-{
- XRRScreenConfiguration *config;
- short *rates;
-
- LockDisplay(dpy);
- if ((config = _XRRValidateCache(dpy, screen))) {
- rates = XRRConfigRates (config, sizeID, nrates);
- UnlockDisplay(dpy);
- return rates;
- }
- else {
- UnlockDisplay(dpy);
- *nrates = 0;
- return NULL;
- }
-}
-
-/* given a screen, return the information from the (possibly) cached data */
-Time XRRTimes (Display *dpy, int screen, Time *config_timestamp)
-{
- XRRScreenConfiguration *config;
- Time ts;
-
- LockDisplay(dpy);
- if ((config = _XRRValidateCache(dpy, screen))) {
- *config_timestamp = config->config_timestamp;
- ts = config->timestamp;
- UnlockDisplay(dpy);
- return ts;
- } else {
- UnlockDisplay(dpy);
- return CurrentTime;
- }
-}
int XRRRootToScreen(Display *dpy, Window root)
{
@@ -353,7 +285,7 @@ Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep)
}
}
-static Bool
+Bool
_XRRHasRates (int major, int minor)
{
return major > 1 || (major == 1 && minor >= 1);
@@ -398,14 +330,7 @@ Status XRRQueryVersion (Display *dpy,
return 1;
}
-typedef struct _randrVersionState {
- unsigned long version_seq;
- Bool error;
- int major_version;
- int minor_version;
-} _XRRVersionState;
-
-static Bool
+Bool
_XRRVersionHandler (Display *dpy,
xReply *rep,
char *buf,
@@ -431,167 +356,6 @@ _XRRVersionHandler (Display *dpy,
state->minor_version = repl->minorVersion;
return True;
}
-/* need a version that does not hold the display lock */
-static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window)
-{
- XExtDisplayInfo *info = XRRFindDisplay(dpy);
- xRRGetScreenInfoReply rep;
- xRRGetScreenInfoReq *req;
- _XAsyncHandler async;
- _XRRVersionState async_state;
- int nbytes, nbytesRead, rbytes;
- int i;
- xScreenSizes size;
- struct _XRRScreenConfiguration *scp;
- XRRScreenSize *ssp;
- short *rates;
- xRRQueryVersionReq *vreq;
- XRandRInfo *xrri;
- Bool getting_version = False;
-
- RRCheckExtension (dpy, info, 0);
-
- xrri = (XRandRInfo *) info->data;
-
- if (xrri->major_version == -1)
- {
- /* hide a version query in the request */
- GetReq (RRQueryVersion, vreq);
- vreq->reqType = info->codes->major_opcode;
- vreq->randrReqType = X_RRQueryVersion;
- vreq->majorVersion = RANDR_MAJOR;
- vreq->minorVersion = RANDR_MINOR;
-
- async_state.version_seq = dpy->request;
- async_state.error = False;
- async.next = dpy->async_handlers;
- async.handler = _XRRVersionHandler;
- async.data = (XPointer) &async_state;
- dpy->async_handlers = &async;
-
- getting_version = True;
- }
-
- GetReq (RRGetScreenInfo, req);
- req->reqType = info->codes->major_opcode;
- req->randrReqType = X_RRGetScreenInfo;
- req->window = window;
-
- if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
- {
- if (getting_version)
- DeqAsyncHandler (dpy, &async);
- SyncHandle ();
- return NULL;
- }
- if (getting_version)
- {
- DeqAsyncHandler (dpy, &async);
- if (async_state.error)
- {
- SyncHandle();
- }
- xrri->major_version = async_state.major_version;
- xrri->minor_version = async_state.minor_version;
- xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
- }
-
- /*
- * Make the reply compatible with v1.1
- */
- if (!xrri->has_rates)
- {
- rep.rate = 0;
- rep.nrateEnts = 0;
- }
-
- nbytes = (long) rep.length << 2;
-
- nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
- ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */);
-
- /*
- * first we must compute how much space to allocate for
- * randr library's use; we'll allocate the structures in a single
- * allocation, on cleanlyness grounds.
- */
-
- rbytes = sizeof (XRRScreenConfiguration) +
- (rep.nSizes * sizeof (XRRScreenSize) +
- rep.nrateEnts * sizeof (int));
-
- scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
- if (scp == NULL) {
- _XEatData (dpy, (unsigned long) nbytes);
- SyncHandle ();
- return NULL;
- }
-
-
- ssp = (XRRScreenSize *)(scp + 1);
- rates = (short *) (ssp + rep.nSizes);
-
- /* set up the screen configuration structure */
- scp->screen =
- ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
-
- scp->sizes = ssp;
- scp->rates = rates;
- scp->rotations = rep.setOfRotations;
- scp->current_size = rep.sizeID;
- scp->current_rate = rep.rate;
- scp->current_rotation = rep.rotation;
- scp->timestamp = rep.timestamp;
- scp->config_timestamp = rep.configTimestamp;
- scp->nsizes = rep.nSizes;
- scp->nrates = rep.nrateEnts;
-
- /*
- * Time to unpack the data from the server.
- */
-
- /*
- * First the size information
- */
- for (i = 0; i < rep.nSizes; i++) {
- _XReadPad (dpy, (char *) &size, SIZEOF (xScreenSizes));
-
- ssp[i].width = size.widthInPixels;
- ssp[i].height = size.heightInPixels;
- ssp[i].mwidth = size.widthInMillimeters;
- ssp[i].mheight = size.heightInMillimeters;
- }
- /*
- * And the rates
- */
- _XRead16Pad (dpy, rates, 2 /* SIZEOF (CARD16) */ * rep.nrateEnts);
-
- /*
- * Skip any extra data
- */
- if (nbytes > nbytesRead)
- _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
-
- return (XRRScreenConfiguration *)(scp);
-}
-
-XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window)
-{
- XRRScreenConfiguration *config;
- XRRFindDisplay(dpy);
- LockDisplay (dpy);
- config = _XRRGetScreenInfo(dpy, window);
- UnlockDisplay (dpy);
- SyncHandle ();
- return config;
-}
-
-
-void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config)
-{
- Xfree (config);
-}
-
/*
* in protocol version 0.1, routine added to allow selecting for new events.
@@ -616,78 +380,6 @@ void XRRSelectInput (Display *dpy, Window window, int mask)
return;
}
-Status XRRSetScreenConfigAndRate (Display *dpy,
- XRRScreenConfiguration *config,
- Drawable draw,
- int size_index,
- Rotation rotation,
- short rate,
- Time timestamp)
-{
- XExtDisplayInfo *info = XRRFindDisplay (dpy);
- xRRSetScreenConfigReply rep;
- XRandRInfo *xrri;
- int major, minor;
-
- RRCheckExtension (dpy, info, 0);
-
- /* Make sure has_rates is set */
- if (!XRRQueryVersion (dpy, &major, &minor))
- return 0;
-
- LockDisplay (dpy);
- xrri = (XRandRInfo *) info->data;
- if (xrri->has_rates)
- {
- xRRSetScreenConfigReq *req;
- GetReq (RRSetScreenConfig, req);
- req->reqType = info->codes->major_opcode;
- req->randrReqType = X_RRSetScreenConfig;
- req->drawable = draw;
- req->sizeID = size_index;
- req->rotation = rotation;
- req->timestamp = timestamp;
- req->configTimestamp = config->config_timestamp;
- req->rate = rate;
- }
- else
- {
- xRR1_0SetScreenConfigReq *req;
- GetReq (RR1_0SetScreenConfig, req);
- req->reqType = info->codes->major_opcode;
- req->randrReqType = X_RRSetScreenConfig;
- req->drawable = draw;
- req->sizeID = size_index;
- req->rotation = rotation;
- req->timestamp = timestamp;
- req->configTimestamp = config->config_timestamp;
- }
-
- (void) _XReply (dpy, (xReply *) &rep, 0, xTrue);
-
- if (rep.status == RRSetConfigSuccess) {
- /* if we succeed, set our view of reality to what we set it to */
- config->config_timestamp = rep.newConfigTimestamp;
- config->timestamp = rep.newTimestamp;
- config->screen = ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
- config->current_size = size_index;
- config->current_rotation = rotation;
- }
- UnlockDisplay (dpy);
- SyncHandle ();
- return(rep.status);
-}
-
-Status XRRSetScreenConfig (Display *dpy,
- XRRScreenConfiguration *config,
- Drawable draw,
- int size_index,
- Rotation rotation, Time timestamp)
-{
- return XRRSetScreenConfigAndRate (dpy, config, draw, size_index,
- rotation, 0, timestamp);
-}
-
int XRRUpdateConfiguration(XEvent *event)
{
XRRScreenChangeNotifyEvent *scevent;
diff --git a/src/Xrandrint.h b/src/Xrandrint.h
index 78a8fcf..14675bd 100644
--- a/src/Xrandrint.h
+++ b/src/Xrandrint.h
@@ -84,4 +84,20 @@ typedef struct _XRandRInfo {
Bool has_rates; /* Server supports refresh rates */
} XRandRInfo;
+typedef struct _randrVersionState {
+ unsigned long version_seq;
+ Bool error;
+ int major_version;
+ int minor_version;
+} _XRRVersionState;
+
+extern char XRRExtensionName[];
+
+Bool
+_XRRVersionHandler (Display *dpy,
+ xReply *rep,
+ char *buf,
+ int len,
+ XPointer data);
+
#endif /* _XRANDRINT_H_ */
diff --git a/src/XrrConfig.c b/src/XrrConfig.c
new file mode 100644
index 0000000..577ccd6
--- /dev/null
+++ b/src/XrrConfig.c
@@ -0,0 +1,424 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett Packard Company, Inc.
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, HP Labs, HP.
+ * Author: Keith Packard, Intel Corporation
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window);
+
+Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation)
+{
+ *current_rotation = config->current_rotation;
+ return config->rotations;
+}
+
+XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes)
+{
+ *nsizes = config->nsizes;
+ return config->sizes;
+}
+
+short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates)
+{
+ short *r = config->rates;
+ int nents = config->nrates;
+
+ /* Skip over the intervening rate lists */
+ while (sizeID > 0 && nents > 0)
+ {
+ int i = (*r + 1);
+ r += i;
+ nents -= i;
+ sizeID--;
+ }
+ if (!nents)
+ {
+ *nrates = 0;
+ return 0;
+ }
+ *nrates = (int) *r;
+ return r + 1;
+}
+
+Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp)
+{
+ *config_timestamp = config->config_timestamp;
+ return config->timestamp;
+}
+
+
+SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config,
+ Rotation *rotation)
+{
+ *rotation = (Rotation) config->current_rotation;
+ return (SizeID) config->current_size;
+}
+
+short XRRConfigCurrentRate (XRRScreenConfiguration *config)
+{
+ return config->current_rate;
+}
+
+/*
+ * Go get the screen configuration data and salt it away for future use;
+ * returns NULL if extension not supported
+ */
+static XRRScreenConfiguration *_XRRValidateCache (Display *dpy, int screen)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ XRRScreenConfiguration **configs;
+ XRandRInfo *xrri;
+
+ if (XextHasExtension(info)) {
+ xrri = (XRandRInfo *) info->data;
+ configs = xrri->config;
+
+ if (configs[screen] == NULL)
+ configs[screen] = _XRRGetScreenInfo (dpy, RootWindow(dpy, screen));
+ return configs[screen];
+ } else {
+ return NULL;
+ }
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation)
+{
+ XRRScreenConfiguration *config;
+ Rotation cr;
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, screen))) {
+ *current_rotation = config->current_rotation;
+ cr = config->rotations;
+ UnlockDisplay(dpy);
+ return cr;
+ }
+ else {
+ UnlockDisplay(dpy);
+ *current_rotation = RR_Rotate_0;
+ return 0; /* no rotations supported */
+ }
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes)
+{
+ XRRScreenConfiguration *config;
+ XRRScreenSize *sizes;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, screen))) {
+ *nsizes = config->nsizes;
+ sizes = config->sizes;
+ UnlockDisplay(dpy);
+ return sizes;
+ }
+ else {
+ UnlockDisplay(dpy);
+ *nsizes = 0;
+ return NULL;
+ }
+}
+
+short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates)
+{
+ XRRScreenConfiguration *config;
+ short *rates;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, screen))) {
+ rates = XRRConfigRates (config, sizeID, nrates);
+ UnlockDisplay(dpy);
+ return rates;
+ }
+ else {
+ UnlockDisplay(dpy);
+ *nrates = 0;
+ return NULL;
+ }
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+Time XRRTimes (Display *dpy, int screen, Time *config_timestamp)
+{
+ XRRScreenConfiguration *config;
+ Time ts;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, screen))) {
+ *config_timestamp = config->config_timestamp;
+ ts = config->timestamp;
+ UnlockDisplay(dpy);
+ return ts;
+ } else {
+ UnlockDisplay(dpy);
+ return CurrentTime;
+ }
+}
+
+/* need a version that does not hold the display lock */
+static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetScreenInfoReply rep;
+ xRRGetScreenInfoReq *req;
+ _XAsyncHandler async;
+ _XRRVersionState async_state;
+ int nbytes, nbytesRead, rbytes;
+ int i;
+ xScreenSizes size;
+ struct _XRRScreenConfiguration *scp;
+ XRRScreenSize *ssp;
+ short *rates;
+ xRRQueryVersionReq *vreq;
+ XRandRInfo *xrri;
+ Bool getting_version = False;
+
+ RRCheckExtension (dpy, info, 0);
+
+ xrri = (XRandRInfo *) info->data;
+
+ if (xrri->major_version == -1)
+ {
+ /* hide a version query in the request */
+ GetReq (RRQueryVersion, vreq);
+ vreq->reqType = info->codes->major_opcode;
+ vreq->randrReqType = X_RRQueryVersion;
+ vreq->majorVersion = RANDR_MAJOR;
+ vreq->minorVersion = RANDR_MINOR;
+
+ async_state.version_seq = dpy->request;
+ async_state.error = False;
+ async.next = dpy->async_handlers;
+ async.handler = _XRRVersionHandler;
+ async.data = (XPointer) &async_state;
+ dpy->async_handlers = &async;
+
+ getting_version = True;
+ }
+
+ GetReq (RRGetScreenInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetScreenInfo;
+ req->window = window;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ if (getting_version)
+ DeqAsyncHandler (dpy, &async);
+ SyncHandle ();
+ return NULL;
+ }
+ if (getting_version)
+ {
+ DeqAsyncHandler (dpy, &async);
+ if (async_state.error)
+ {
+ UnlockDisplay (dpy);
+ SyncHandle();
+ LockDisplay (dpy);
+ }
+ xrri->major_version = async_state.major_version;
+ xrri->minor_version = async_state.minor_version;
+ xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
+ }
+
+ /*
+ * Make the reply compatible with v1.1
+ */
+ if (!xrri->has_rates)
+ {
+ rep.rate = 0;
+ rep.nrateEnts = 0;
+ }
+
+ nbytes = (long) rep.length << 2;
+
+ nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
+ ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */);
+
+ /*
+ * first we must compute how much space to allocate for
+ * randr library's use; we'll allocate the structures in a single
+ * allocation, on cleanlyness grounds.
+ */
+
+ rbytes = sizeof (XRRScreenConfiguration) +
+ (rep.nSizes * sizeof (XRRScreenSize) +
+ rep.nrateEnts * sizeof (int));
+
+ scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
+ if (scp == NULL) {
+ _XEatData (dpy, (unsigned long) nbytes);
+ return NULL;
+ }
+
+
+ ssp = (XRRScreenSize *)(scp + 1);
+ rates = (short *) (ssp + rep.nSizes);
+
+ /* set up the screen configuration structure */
+ scp->screen =
+ ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
+
+ scp->sizes = ssp;
+ scp->rates = rates;
+ scp->rotations = rep.setOfRotations;
+ scp->current_size = rep.sizeID;
+ scp->current_rate = rep.rate;
+ scp->current_rotation = rep.rotation;
+ scp->timestamp = rep.timestamp;
+ scp->config_timestamp = rep.configTimestamp;
+ scp->nsizes = rep.nSizes;
+ scp->nrates = rep.nrateEnts;
+
+ /*
+ * Time to unpack the data from the server.
+ */
+
+ /*
+ * First the size information
+ */
+ for (i = 0; i < rep.nSizes; i++) {
+ _XReadPad (dpy, (char *) &size, SIZEOF (xScreenSizes));
+
+ ssp[i].width = size.widthInPixels;
+ ssp[i].height = size.heightInPixels;
+ ssp[i].mwidth = size.widthInMillimeters;
+ ssp[i].mheight = size.heightInMillimeters;
+ }
+ /*
+ * And the rates
+ */
+ _XRead16Pad (dpy, rates, 2 /* SIZEOF (CARD16) */ * rep.nrateEnts);
+
+ /*
+ * Skip any extra data
+ */
+ if (nbytes > nbytesRead)
+ _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+ return (XRRScreenConfiguration *)(scp);
+}
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window)
+{
+ XRRScreenConfiguration *config;
+ XRRFindDisplay(dpy);
+ LockDisplay (dpy);
+ config = _XRRGetScreenInfo(dpy, window);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return config;
+}
+
+
+void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config)
+{
+ Xfree (config);
+}
+
+Status XRRSetScreenConfigAndRate (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ Rotation rotation,
+ short rate,
+ Time timestamp)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ xRRSetScreenConfigReply rep;
+ XRandRInfo *xrri;
+ int major, minor;
+
+ RRCheckExtension (dpy, info, 0);
+
+ /* Make sure has_rates is set */
+ if (!XRRQueryVersion (dpy, &major, &minor))
+ return 0;
+
+ LockDisplay (dpy);
+ xrri = (XRandRInfo *) info->data;
+ if (xrri->has_rates)
+ {
+ xRRSetScreenConfigReq *req;
+ GetReq (RRSetScreenConfig, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetScreenConfig;
+ req->drawable = draw;
+ req->sizeID = size_index;
+ req->rotation = rotation;
+ req->timestamp = timestamp;
+ req->configTimestamp = config->config_timestamp;
+ req->rate = rate;
+ }
+ else
+ {
+ xRR1_0SetScreenConfigReq *req;
+ GetReq (RR1_0SetScreenConfig, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetScreenConfig;
+ req->drawable = draw;
+ req->sizeID = size_index;
+ req->rotation = rotation;
+ req->timestamp = timestamp;
+ req->configTimestamp = config->config_timestamp;
+ }
+
+ (void) _XReply (dpy, (xReply *) &rep, 0, xTrue);
+
+ if (rep.status == RRSetConfigSuccess) {
+ /* if we succeed, set our view of reality to what we set it to */
+ config->config_timestamp = rep.newConfigTimestamp;
+ config->timestamp = rep.newTimestamp;
+ config->screen = ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
+ config->current_size = size_index;
+ config->current_rotation = rotation;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return(rep.status);
+}
+
+Status XRRSetScreenConfig (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ Rotation rotation, Time timestamp)
+{
+ return XRRSetScreenConfigAndRate (dpy, config, draw, size_index,
+ rotation, 0, timestamp);
+}
diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c
new file mode 100644
index 0000000..a1372a1
--- /dev/null
+++ b/src/XrrCrtc.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+XRRCrtcInfo *
+XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetCrtcInfoReply rep;
+ xRRGetCrtcInfoReq *req;
+ int nbytes, nbytesRead, rbytes;
+ int i;
+ XRRCrtcInfo *xci;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRGetCrtcInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetCrtcInfo;
+ req->crtc = crtc;
+ req->configTimestamp = resources->configTimestamp;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ nbytes = (long) rep.length << 2;
+
+ nbytesRead = (long) (rep.nOutput * 4 +
+ rep.nPossibleOutput * 4);
+
+ /*
+ * first we must compute how much space to allocate for
+ * randr library's use; we'll allocate the structures in a single
+ * allocation, on cleanlyness grounds.
+ */
+
+ rbytes = (sizeof (XRRCrtcInfo) +
+ rep.nOutput * sizeof (RROutput) +
+ rep.nPossibleOutput * sizeof (RROutput));
+
+ xci = (XRRCrtcInfo *) Xmalloc(rbytes);
+ if (xci == NULL) {
+ _XEatData (dpy, (unsigned long) nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ xci->timestamp = rep.timestamp;
+ xci->x = rep.x;
+ xci->y = rep.y;
+ xci->width = rep.width;
+ xci->height = rep.height;
+ xci->mode = rep.mode;
+ xci->rotation = rep.rotation;
+ xci->noutput = rep.nOutput;
+ xci->outputs = (RROutput *) (xci + 1);
+ xci->npossible = rep.nPossibleOutput;
+ xci->possible = (RROutput *) (xci->outputs + rep.nOutput);
+
+ _XRead32 (dpy, xci->outputs, rep.nOutput << 2);
+ _XRead32 (dpy, xci->possible, rep.nPossibleOutput << 2);
+
+ /*
+ * Skip any extra data
+ */
+ if (nbytes > nbytesRead)
+ _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return (XRRCrtcInfo *) xci;
+}
+
+void
+XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo)
+{
+ Xfree (crtcInfo);
+}
+
+Status
+XRRSetCrtcConfig (Display *dpy,
+ XRRScreenResources *resources,
+ RRCrtc crtc,
+ Time timestamp,
+ int x, int y,
+ RRMode mode,
+ Rotation rotation,
+ RROutput *outputs,
+ int noutputs)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRSetCrtcConfigReply rep;
+ xRRSetCrtcConfigReq *req;
+ int i;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq (RRSetCrtcConfig, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetCrtcConfig;
+ req->length += noutputs;
+ req->crtc = crtc;
+ req->timestamp = timestamp;
+ req->configTimestamp = resources->configTimestamp;
+ req->x = x;
+ req->y = y;
+ req->mode = mode;
+ req->rotation = rotation;
+ Data32 (dpy, outputs, noutputs << 2);
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ rep.status = RRSetConfigFailed;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return rep.status;
+}
+
+int
+XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc)
+{
+}
+
+XRRCrtcGamma *
+XRRGetCrtcGamma (Display *dpy, RRCrtc crtc)
+{
+}
+
+XRRCrtcGamma *
+XRRAllocGamma (int size)
+{
+}
+
+void
+XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma)
+{
+}
+
+void
+XRRFreeGamma (XRRCrtcGamma *gamma)
+{
+}
diff --git a/src/XrrMode.c b/src/XrrMode.c
new file mode 100644
index 0000000..65b60f9
--- /dev/null
+++ b/src/XrrMode.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+XRRModeInfo *
+XRRAllocModeInfo (char *name, int nameLength)
+{
+}
+
+RRMode
+XRRCreateMode (Display *dpy, Window window, XRRModeInfo *modeInfo)
+{
+}
+
+void
+XRRDestroyMode (Display *dpy, RRMode mode)
+{
+}
+
+void
+XRRAddOutputMode (Display *dpy, RROutput output, RRMode mode)
+{
+}
+
+void
+XRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode)
+{
+}
+
+void
+XRRFreeModeInfo (XRRModeInfo *modeInfo)
+{
+}
diff --git a/src/XrrOutput.c b/src/XrrOutput.c
new file mode 100644
index 0000000..1fe03ae
--- /dev/null
+++ b/src/XrrOutput.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
+
+XRROutputInfo *
+XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetOutputInfoReply rep;
+ xRRGetOutputInfoReq *req;
+ int nbytes, nbytesRead, rbytes;
+ int i;
+ xRRQueryVersionReq *vreq;
+ XRROutputInfo *xoi;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRGetOutputInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetOutputInfo;
+ req->output = output;
+ req->configTimestamp = resources->configTimestamp;
+
+ if (!_XReply (dpy, (xReply *) &rep, OutputInfoExtra >> 2, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ nbytes = ((long) (rep.length) << 2) - OutputInfoExtra;
+
+ nbytesRead = (long) (rep.nCrtcs * 4 +
+ rep.nModes * 4 +
+ rep.nClones * 4 +
+ ((rep.nameLength + 3) & ~3));
+
+ /*
+ * first we must compute how much space to allocate for
+ * randr library's use; we'll allocate the structures in a single
+ * allocation, on cleanlyness grounds.
+ */
+
+ rbytes = (sizeof (XRROutputInfo) +
+ rep.nCrtcs * sizeof (RRCrtc) +
+ rep.nModes * sizeof (RRMode) +
+ rep.nClones * sizeof (RROutput) +
+ rep.nameLength + 1); /* '\0' terminate name */
+
+ xoi = (XRROutputInfo *) Xmalloc(rbytes);
+ if (xoi == NULL) {
+ _XEatData (dpy, (unsigned long) nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ xoi->timestamp = rep.timestamp;
+ xoi->crtc = rep.crtc;
+ xoi->mm_width = rep.mmWidth;
+ xoi->mm_height = rep.mmHeight;
+ xoi->connection = rep.connection;
+ xoi->subpixel_order = rep.subpixelOrder;
+ xoi->ncrtc = rep.nCrtcs;
+ xoi->crtcs = (RRCrtc *) (xoi + 1);
+ xoi->nmode = rep.nModes;
+ xoi->npreferred = rep.nPreferred;
+ xoi->modes = (RRMode *) (xoi->crtcs + rep.nCrtcs);
+ xoi->nclone = rep.nClones;
+ xoi->clones = (RROutput *) (xoi->modes + rep.nModes);
+ xoi->name = (char *) (xoi->clones + rep.nClones);
+
+ _XRead32 (dpy, xoi->crtcs, rep.nCrtcs << 2);
+ _XRead32 (dpy, xoi->modes, rep.nModes << 2);
+ _XRead32 (dpy, xoi->clones, rep.nClones << 2);
+
+ /*
+ * Read name and '\0' terminate
+ */
+ _XReadPad (dpy, xoi->name, rep.nameLength);
+ xoi->name[rep.nameLength] = '\0';
+
+ /*
+ * Skip any extra data
+ */
+ if (nbytes > nbytesRead)
+ _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return (XRROutputInfo *) xoi;
+}
+
+void
+XRRFreeOutputInfo (XRROutputInfo *outputInfo)
+{
+ Xfree (outputInfo);
+}
diff --git a/src/XrrProperty.c b/src/XrrProperty.c
new file mode 100644
index 0000000..3b16491
--- /dev/null
+++ b/src/XrrProperty.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+Atom *
+XRRListOutputProperties (Display *dpy, RROutput output, int *nprop)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRListOutputPropertiesReply rep;
+ xRRListOutputPropertiesReq *req;
+ int nbytes, nbytesRead, netbytes;
+ int i;
+ xRRQueryVersionReq *vreq;
+ Atom *props;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRListOutputProperties, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRListOutputProperties;
+ req->output = output;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *nprop = 0;
+ return NULL;
+ }
+
+ if (rep.nProperties) {
+ nbytes = rep.nProperties * sizeof (Atom);
+ netbytes = rep.nProperties << 2;
+
+ props = (Atom *) Xmalloc (nbytes);
+ if (props == NULL) {
+ _XEatData (dpy, netbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *nprop = 0;
+ return NULL;
+ }
+
+ _XRead32 (dpy, props, nbytes);
+ }
+
+ *nprop = rep.nProperties;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return props;
+}
+
+XRRPropertyInfo *
+XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRQueryOutputPropertyReply rep;
+ xRRQueryOutputPropertyReq *req;
+ int nbytes, nbytesRead, netbytes;
+ int i;
+ xRRQueryVersionReq *vreq;
+ XRRPropertyInfo *prop_info;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRQueryOutputProperty, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRQueryOutputProperty;
+ req->output = output;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ if (rep.length) {
+ nbytes = rep.length * sizeof (long);
+ netbytes = rep.length << 2;
+
+ prop_info = (XRRPropertyInfo *) Xmalloc (nbytes +
+ sizeof (XRRPropertyInfo));
+ if (prop_info == NULL) {
+ _XEatData (dpy, netbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ prop_info->pending = rep.pending;
+ prop_info->range = rep.range;
+ prop_info->immutable = rep.immutable;
+ prop_info->num_values = rep.length;
+ prop_info->values = (long *) (prop_info + 1);
+
+ _XRead32 (dpy, prop_info->values, nbytes);
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return prop_info;
+}
+
+void
+XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property,
+ Bool pending, Bool range, int num_values,
+ long *values)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRConfigureOutputPropertyReq *req;
+ xRRQueryVersionReq *vreq;
+ long len;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRConfigureOutputProperty, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRConfigureOutputProperty;
+ req->output = output;
+ req->property = property;
+ req->pending = pending;
+ req->range = range;
+
+ len = num_values;
+ if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+ SetReqLen(req, len, len);
+ len = (long)num_values << 2;
+ Data32 (dpy, values, len);
+ } /* else force BadLength */
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void
+XRRChangeOutputProperty (Display *dpy, RROutput output,
+ Atom property, Atom type,
+ int format, int mode,
+ _Xconst unsigned char *data, int nelements)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRChangeOutputPropertyReq *req;
+ xRRQueryVersionReq *vreq;
+ long len;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRChangeOutputProperty, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRChangeOutputProperty;
+ req->output = output;
+ req->property = property;
+ req->type = type;
+ req->mode = mode;
+ if (nelements < 0) {
+ req->nUnits = 0;
+ req->format = 0; /* ask for garbage, get garbage */
+ } else {
+ req->nUnits = nelements;
+ req->format = format;
+ }
+
+ switch (req->format) {
+ case 8:
+ len = ((long)nelements + 3) >> 2;
+ if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+ SetReqLen(req, len, len);
+ Data (dpy, (char *)data, nelements);
+ } /* else force BadLength */
+ break;
+
+ case 16:
+ len = ((long)nelements + 1) >> 1;
+ if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+ SetReqLen(req, len, len);
+ len = (long)nelements << 1;
+ Data16 (dpy, (short *) data, len);
+ } /* else force BadLength */
+ break;
+
+ case 32:
+ len = nelements;
+ if (dpy->bigreq_size || req->length + len <= (unsigned) 65535) {
+ SetReqLen(req, len, len);
+ len = (long)nelements << 2;
+ Data32 (dpy, (long *) data, len);
+ } /* else force BadLength */
+ break;
+
+ default:
+ /* BadValue will be generated */ ;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void
+XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRDeleteOutputPropertyReq *req;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq(RRDeleteOutputProperty, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRDeleteOutputProperty;
+ req->output = output;
+ req->property = property;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+int
+XRRGetOutputProperty (Display *dpy, RROutput output,
+ Atom property, long offset, long length,
+ Bool delete, Bool pending, Atom req_type,
+ Atom *actual_type, int *actual_format,
+ unsigned long *nitems, unsigned long *bytes_after,
+ unsigned char **prop)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetOutputPropertyReply rep;
+ xRRGetOutputPropertyReq *req;
+ int nbytes, nbytesRead;
+ int i;
+ xRRQueryVersionReq *vreq;
+
+ RRCheckExtension (dpy, info, 1);
+
+ LockDisplay (dpy);
+ GetReq (RRGetOutputProperty, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetOutputProperty;
+ req->output = output;
+ req->property = property;
+ req->type = req_type;
+ req->longOffset = offset;
+ req->longLength = length;
+ req->delete = delete;
+ req->pending = pending;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 1;
+ }
+
+ *prop = (unsigned char *) NULL;
+ if (rep.propertyType != None) {
+ long nbytes, netbytes;
+ /*
+ * One extra byte is malloced than is needed to contain the property
+ * data, but this last byte is null terminated and convenient for
+ * returning string properties, so the client doesn't then have to
+ * recopy the string to make it null terminated.
+ */
+ switch (rep.format) {
+ case 8:
+ nbytes = netbytes = rep.nItems;
+ if (nbytes + 1 > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
+ _XReadPad (dpy, (char *) *prop, netbytes);
+ break;
+
+ case 16:
+ nbytes = rep.nItems * sizeof (short);
+ netbytes = rep.nItems << 1;
+ if (nbytes + 1 > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
+ _XRead16Pad (dpy, (short *) *prop, netbytes);
+ break;
+
+ case 32:
+ nbytes = rep.nItems * sizeof (long);
+ netbytes = rep.nItems << 2;
+ if (nbytes + 1 > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
+ _XRead32 (dpy, (long *) *prop, netbytes);
+ break;
+
+ default:
+ /*
+ * This part of the code should never be reached. If it is,
+ * the server sent back a property with an invalid format.
+ */
+ _XEatData(dpy, (unsigned long) netbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(BadImplementation);
+ }
+ if (! *prop) {
+ _XEatData(dpy, (unsigned long) netbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(BadAlloc);
+ }
+ (*prop)[nbytes] = '\0';
+ }
+
+ *actual_type = rep.propertyType;
+ *actual_format = rep.format;
+ *nitems = rep.nItems;
+ *bytes_after = rep.bytesAfter;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ return Success;
+}
diff --git a/src/XrrScreen.c b/src/XrrScreen.c
new file mode 100644
index 0000000..c9f5204
--- /dev/null
+++ b/src/XrrScreen.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+#include "Xrandrint.h"
+
+XRRScreenResources *
+XRRGetScreenResources (Display *dpy, Window window)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetScreenResourcesReply rep;
+ xRRGetScreenResourcesReq *req;
+ _XAsyncHandler async;
+ _XRRVersionState async_state;
+ int nbytes, nbytesRead, rbytes;
+ int i;
+ xRRQueryVersionReq *vreq;
+ XRRScreenResources *xrsr;
+ char *names;
+ char *wire_names, *wire_name;
+ Bool getting_version = False;
+ XRandRInfo *xrri;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ xrri = (XRandRInfo *) info->data;
+
+ if (xrri->major_version == -1)
+ {
+ /* hide a version query in the request */
+ GetReq (RRQueryVersion, vreq);
+ vreq->reqType = info->codes->major_opcode;
+ vreq->randrReqType = X_RRQueryVersion;
+ vreq->majorVersion = RANDR_MAJOR;
+ vreq->minorVersion = RANDR_MINOR;
+
+ async_state.version_seq = dpy->request;
+ async_state.error = False;
+ async.next = dpy->async_handlers;
+ async.handler = _XRRVersionHandler;
+ async.data = (XPointer) &async_state;
+ dpy->async_handlers = &async;
+
+ getting_version = True;
+ }
+
+ GetReq (RRGetScreenResources, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetScreenResources;
+ req->window = window;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ if (getting_version)
+ DeqAsyncHandler (dpy, &async);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ if (getting_version)
+ {
+ DeqAsyncHandler (dpy, &async);
+ if (async_state.error)
+ {
+ UnlockDisplay (dpy);
+ SyncHandle();
+ LockDisplay (dpy);
+ }
+ xrri->major_version = async_state.major_version;
+ xrri->minor_version = async_state.minor_version;
+ xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
+ }
+
+ nbytes = (long) rep.length << 2;
+
+ nbytesRead = (long) (rep.nCrtcs * 4 +
+ rep.nOutputs * 4 +
+ rep.nModes * SIZEOF (xRRModeInfo) +
+ ((rep.nbytesNames + 3) & ~3));
+
+ /*
+ * first we must compute how much space to allocate for
+ * randr library's use; we'll allocate the structures in a single
+ * allocation, on cleanlyness grounds.
+ */
+
+ rbytes = (sizeof (XRRScreenResources) +
+ rep.nCrtcs * sizeof (RRCrtc) +
+ rep.nOutputs * sizeof (RROutput) +
+ rep.nModes * sizeof (XRRModeInfo) +
+ rep.nbytesNames + rep.nModes); /* '\0' terminate names */
+
+ xrsr = (XRRScreenResources *) Xmalloc(rbytes);
+ wire_names = (char *) Xmalloc (rep.nbytesNames);
+ if (xrsr == NULL || wire_names == NULL) {
+ if (xrsr) Xfree (xrsr);
+ if (wire_names) Xfree (wire_names);
+ _XEatData (dpy, (unsigned long) nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ xrsr->timestamp = rep.timestamp;
+ xrsr->configTimestamp = rep.configTimestamp;
+ xrsr->ncrtc = rep.nCrtcs;
+ xrsr->crtcs = (RRCrtc *) (xrsr + 1);
+ xrsr->noutput = rep.nOutputs;
+ xrsr->outputs = (RROutput *) (xrsr->crtcs + rep.nCrtcs);
+ xrsr->nmode = rep.nModes;
+ xrsr->modes = (XRRModeInfo *) (xrsr->outputs + rep.nOutputs);
+ names = (char *) (xrsr->modes + rep.nModes);
+
+ _XRead32 (dpy, xrsr->crtcs, rep.nCrtcs << 2);
+ _XRead32 (dpy, xrsr->outputs, rep.nOutputs << 2);
+
+ for (i = 0; i < rep.nModes; i++) {
+ xRRModeInfo modeInfo;
+
+ _XReadPad (dpy, (char *) &modeInfo, SIZEOF (xRRModeInfo));
+ xrsr->modes[i].id = modeInfo.id;
+ xrsr->modes[i].width = modeInfo.width;
+ xrsr->modes[i].height = modeInfo.height;
+ xrsr->modes[i].dotClock = modeInfo.dotClock;
+ xrsr->modes[i].hSyncStart = modeInfo.hSyncStart;
+ xrsr->modes[i].hSyncEnd = modeInfo.hSyncEnd;
+ xrsr->modes[i].hTotal = modeInfo.hTotal;
+ xrsr->modes[i].hSkew = modeInfo.hSkew;
+ xrsr->modes[i].vSyncStart = modeInfo.vSyncStart;
+ xrsr->modes[i].vSyncEnd = modeInfo.vSyncEnd;
+ xrsr->modes[i].vTotal = modeInfo.vTotal;
+ xrsr->modes[i].nameLength = modeInfo.nameLength;
+ xrsr->modes[i].modeFlags = modeInfo.modeFlags;
+ }
+
+ /*
+ * Read names and '\0' pad each one
+ */
+ _XReadPad (dpy, wire_names, rep.nbytesNames);
+ wire_name = wire_names;
+ for (i = 0; i < rep.nModes; i++) {
+ xrsr->modes[i].name = names;
+ memcpy (names, wire_name, xrsr->modes[i].nameLength);
+ names[xrsr->modes[i].nameLength] = '\0';
+ names += xrsr->modes[i].nameLength + 1;
+ wire_name += xrsr->modes[i].nameLength;
+ }
+ Xfree (wire_names);
+
+ /*
+ * Skip any extra data
+ */
+ if (nbytes > nbytesRead)
+ _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+ UnlockDisplay (dpy);
+ SyncHandle();
+ return (XRRScreenResources *) xrsr;
+}
+
+void
+XRRFreeScreenResources (XRRScreenResources *resources)
+{
+ Xfree (resources);
+}
+
+Status
+XRRGetScreenSizeRange (Display *dpy, Window window,
+ int *minWidth, int *minHeight,
+ int *maxWidth, int *maxHeight)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetScreenSizeRangeReq *req;
+ xRRGetScreenSizeRangeReply rep;
+
+ RRCheckExtension (dpy, info, 0);
+ LockDisplay (dpy);
+ GetReq (RRGetScreenSizeRange, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetScreenSizeRange;
+ req->window = window;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *minWidth = rep.minWidth;
+ *minHeight = rep.minHeight;
+ *maxWidth = rep.maxWidth;
+ *maxHeight = rep.maxHeight;
+ return True;
+}
+
+void
+XRRSetScreenSize (Display *dpy, Window window,
+ int width, int height,
+ int mmWidth, int mmHeight)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRSetScreenSizeReq *req;
+
+ RRSimpleCheckExtension (dpy, info);
+ LockDisplay (dpy);
+ GetReq (RRSetScreenSize, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetScreenSize;
+ req->window = window;
+ req->width = width;
+ req->height = height;
+ req->widthInMillimeters = mmWidth;
+ req->heightInMillimeters = mmHeight;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}