summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2007-11-24 16:39:05 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2007-11-24 16:39:05 +0000
commitd8474a3fc236623553ca085c3f2024f7cfa33ba7 (patch)
treef8b2eaf7fd9efe4c05d2b914fd3bcd6a2ebaf172
parent960e67eeb3a9026994d08dddfa645bd3db4e27d0 (diff)
libXrandr 1.2.2
-rw-r--r--lib/libXrandr/src/XrrConfig.c433
-rw-r--r--lib/libXrandr/src/XrrCrtc.c272
-rw-r--r--lib/libXrandr/src/XrrMode.c150
-rw-r--r--lib/libXrandr/src/XrrOutput.c131
-rw-r--r--lib/libXrandr/src/XrrProperty.c347
-rw-r--r--lib/libXrandr/src/XrrScreen.c246
6 files changed, 1579 insertions, 0 deletions
diff --git a/lib/libXrandr/src/XrrConfig.c b/lib/libXrandr/src/XrrConfig.c
new file mode 100644
index 000000000..778422747
--- /dev/null
+++ b/lib/libXrandr/src/XrrConfig.c
@@ -0,0 +1,433 @@
+/*
+ * 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,
+ XExtDisplayInfo *info,
+ 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,
+ XExtDisplayInfo *info,
+ int screen)
+{
+ XRRScreenConfiguration **configs;
+ XRandRInfo *xrri;
+
+ if (XextHasExtension(info)) {
+ xrri = (XRandRInfo *) info->data;
+ configs = xrri->config;
+
+ if (configs[screen] == NULL)
+ configs[screen] = _XRRGetScreenInfo (dpy, info, 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;
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ Rotation cr;
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, info, 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;
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ XRRScreenSize *sizes;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, info, 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;
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ short *rates;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, info, 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;
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ Time ts;
+
+ LockDisplay(dpy);
+ if ((config = _XRRValidateCache(dpy, info, 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,
+ XExtDisplayInfo *info,
+ Window window)
+{
+ 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;
+
+ xrri = (XRandRInfo *) info->data;
+ if (!xrri)
+ return NULL;
+
+ 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;
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ XRRFindDisplay(dpy);
+ LockDisplay (dpy);
+ config = _XRRGetScreenInfo(dpy, info, 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/lib/libXrandr/src/XrrCrtc.c b/lib/libXrandr/src/XrrCrtc.c
new file mode 100644
index 000000000..5e5c8136d
--- /dev/null
+++ b/lib/libXrandr/src/XrrCrtc.c
@@ -0,0 +1,272 @@
+/*
+ * 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->rotations = rep.rotations;
+ 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)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetCrtcGammaSizeReply rep;
+ xRRGetCrtcGammaSizeReq *req;
+ int i;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq (RRGetCrtcGammaSize, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetCrtcGammaSize;
+ req->crtc = crtc;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ rep.status = RRSetConfigFailed;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return rep.size;
+}
+
+XRRCrtcGamma *
+XRRGetCrtcGamma (Display *dpy, RRCrtc crtc)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetCrtcGammaReply rep;
+ xRRGetCrtcGammaReq *req;
+ int i;
+ XRRCrtcGamma *crtc_gamma;
+ long nbytes;
+ long nbytesRead;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay(dpy);
+ GetReq (RRGetCrtcGamma, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetCrtcGamma;
+ req->crtc = crtc;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ rep.status = RRSetConfigFailed;
+
+ nbytes = (long) rep.length << 2;
+
+ /* three channels of CARD16 data */
+ nbytesRead = (rep.size * 2 * 3);
+
+ crtc_gamma = XRRAllocGamma (rep.size);
+
+ if (!crtc_gamma)
+ {
+ _XEatData (dpy, (unsigned long) nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ _XRead16 (dpy, crtc_gamma->red, rep.size * 2);
+ _XRead16 (dpy, crtc_gamma->green, rep.size * 2);
+ _XRead16 (dpy, crtc_gamma->blue, rep.size * 2);
+
+ if (nbytes > nbytesRead)
+ _XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return crtc_gamma;
+}
+
+XRRCrtcGamma *
+XRRAllocGamma (int size)
+{
+ XRRCrtcGamma *crtc_gamma;
+
+ crtc_gamma = Xmalloc (sizeof (XRRCrtcGamma) +
+ sizeof (crtc_gamma->red[0]) * size * 3);
+ if (!crtc_gamma)
+ return NULL;
+ crtc_gamma->size = size;
+ crtc_gamma->red = (unsigned short *) (crtc_gamma + 1);
+ crtc_gamma->green = crtc_gamma->red + size;
+ crtc_gamma->blue = crtc_gamma->green + size;
+ return crtc_gamma;
+}
+
+void
+XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *crtc_gamma)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRSetCrtcGammaReq *req;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRSetCrtcGamma, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetCrtcGamma;
+ req->crtc = crtc;
+ req->size = crtc_gamma->size;
+ req->length += (crtc_gamma->size * 2 * 3 + 3) >> 2;
+ /*
+ * Note this assumes the structure was allocated with XRRAllocGamma,
+ * otherwise the channels might not be contiguous
+ */
+ Data16 (dpy, crtc_gamma->red, crtc_gamma->size * 2 * 3);
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XRRFreeGamma (XRRCrtcGamma *crtc_gamma)
+{
+ Xfree (crtc_gamma);
+}
diff --git a/lib/libXrandr/src/XrrMode.c b/lib/libXrandr/src/XrrMode.c
new file mode 100644
index 000000000..fc624e1c0
--- /dev/null
+++ b/lib/libXrandr/src/XrrMode.c
@@ -0,0 +1,150 @@
+/*
+ * 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)
+{
+ XRRModeInfo *mode_info;
+
+ mode_info = Xmalloc (sizeof (XRRModeInfo) + nameLength + 1);
+ if (!mode_info)
+ return NULL;
+ memset (mode_info, '\0', sizeof (XRRModeInfo));
+ mode_info->nameLength = nameLength;
+ mode_info->name = (char *) (mode_info + 1);
+ memcpy (mode_info->name, name, nameLength);
+ mode_info->name[nameLength] = '\0';
+ return mode_info;
+}
+
+RRMode
+XRRCreateMode (Display *dpy, Window window, XRRModeInfo *mode_info)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRCreateModeReq *req;
+ xRRCreateModeReply rep;
+ long channelSize;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRCreateMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRCreateMode;
+ req->length += (mode_info->nameLength + 3) >> 2;
+
+ req->window = window;
+
+ req->modeInfo.id = 0;
+ req->modeInfo.width = mode_info->width;
+ req->modeInfo.height = mode_info->height;
+ req->modeInfo.dotClock = mode_info->dotClock;
+ req->modeInfo.hSyncStart = mode_info->hSyncStart;
+ req->modeInfo.hSyncEnd = mode_info->hSyncEnd;
+ req->modeInfo.hTotal = mode_info->hTotal;
+ req->modeInfo.hSkew = mode_info->hSkew;
+ req->modeInfo.vSyncStart = mode_info->vSyncStart;
+ req->modeInfo.vSyncEnd = mode_info->vSyncEnd;
+ req->modeInfo.vTotal = mode_info->vTotal;
+ req->modeInfo.nameLength = mode_info->nameLength;
+ req->modeInfo.modeFlags = mode_info->modeFlags;
+
+ Data (dpy, mode_info->name, mode_info->nameLength);
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return None;
+ }
+
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return rep.mode;
+}
+
+void
+XRRDestroyMode (Display *dpy, RRMode mode)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRDestroyModeReq *req;
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRDestroyMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRDestroyMode;
+ req->mode = mode;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XRRAddOutputMode (Display *dpy, RROutput output, RRMode mode)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRAddOutputModeReq *req;
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRAddOutputMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRAddOutputMode;
+ req->output = output;
+ req->mode = mode;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XRRDeleteOutputMode (Display *dpy, RROutput output, RRMode mode)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRDeleteOutputModeReq *req;
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay(dpy);
+ GetReq (RRDeleteOutputMode, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRDeleteOutputMode;
+ req->output = output;
+ req->mode = mode;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XRRFreeModeInfo (XRRModeInfo *modeInfo)
+{
+ Xfree (modeInfo);
+}
diff --git a/lib/libXrandr/src/XrrOutput.c b/lib/libXrandr/src/XrrOutput.c
new file mode 100644
index 000000000..1fe03ae7c
--- /dev/null
+++ b/lib/libXrandr/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/lib/libXrandr/src/XrrProperty.c b/lib/libXrandr/src/XrrProperty.c
new file mode 100644
index 000000000..8377fff61
--- /dev/null
+++ b/lib/libXrandr/src/XrrProperty.c
@@ -0,0 +1,347 @@
+/*
+ * 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, rbytes;
+ 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.nAtoms) {
+ rbytes = rep.nAtoms * sizeof (Atom);
+ nbytes = rep.nAtoms << 2;
+
+ props = (Atom *) Xmalloc (rbytes);
+ if (props == NULL) {
+ _XEatData (dpy, nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ *nprop = 0;
+ return NULL;
+ }
+
+ _XRead32 (dpy, props, nbytes);
+ }
+
+ *nprop = rep.nAtoms;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return props;
+}
+
+XRRPropertyInfo *
+XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRQueryOutputPropertyReply rep;
+ xRRQueryOutputPropertyReq *req;
+ int rbytes, nbytes;
+ 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;
+ req->property = property;
+
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+
+ rbytes = sizeof (XRRPropertyInfo) + rep.length * sizeof (long);
+ nbytes = rep.length << 2;
+
+ prop_info = (XRRPropertyInfo *) Xmalloc (rbytes);
+ if (prop_info == NULL) {
+ _XEatData (dpy, nbytes);
+ 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;
+ if (rep.length != 0) {
+ prop_info->values = (long *) (prop_info + 1);
+ _XRead32 (dpy, prop_info->values, nbytes);
+ } else {
+ prop_info->values = NULL;
+ }
+
+ 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;
+ long nbytes, rbytes, 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) {
+ /*
+ * 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 = rep.nItems;
+ rbytes = rep.nItems + 1;
+ if (rbytes > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+ _XReadPad (dpy, (char *) *prop, nbytes);
+ break;
+
+ case 16:
+ nbytes = rep.nItems << 1;
+ rbytes = rep.nItems * sizeof (short) + 1;
+ if (rbytes > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+ _XRead16Pad (dpy, (short *) *prop, nbytes);
+ break;
+
+ case 32:
+ nbytes = rep.nItems << 2;
+ rbytes = rep.nItems * sizeof (long) + 1;
+ if (rbytes > 0 &&
+ (*prop = (unsigned char *) Xmalloc ((unsigned)rbytes)))
+ _XRead32 (dpy, (long *) *prop, nbytes);
+ break;
+
+ default:
+ /*
+ * This part of the code should never be reached. If it is,
+ * the server sent back a property with an invalid format.
+ */
+ nbytes = rep.length << 2;
+ _XEatData(dpy, (unsigned long) nbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(BadImplementation);
+ }
+ if (! *prop) {
+ _XEatData(dpy, (unsigned long) nbytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return(BadAlloc);
+ }
+ (*prop)[rbytes - 1] = '\0';
+ }
+
+ *actual_type = rep.propertyType;
+ *actual_format = rep.format;
+ *nitems = rep.nItems;
+ *bytes_after = rep.bytesAfter;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ return Success;
+}
diff --git a/lib/libXrandr/src/XrrScreen.c b/lib/libXrandr/src/XrrScreen.c
new file mode 100644
index 000000000..c9f520439
--- /dev/null
+++ b/lib/libXrandr/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 ();
+}