From c712df73eeb0cb84aad6a0bec2be0f480418c217 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Sep 2006 00:42:49 -0700 Subject: Start update to 1.2, splitting code across multiple files. --- configure.ac | 2 +- include/X11/extensions/Xrandr.h | 247 ++++++++++++++++++-- src/.gitignore | 1 + src/Makefile.am | 9 +- src/Xrandr.c | 506 ++++++++-------------------------------- src/Xrandrint.h | 16 ++ src/XrrConfig.c | 423 +++++++++++++++++++++++++++++++++ src/XrrCrtc.c | 75 ++++++ src/XrrMode.c | 63 +++++ src/XrrOutput.c | 149 ++++++++++++ src/XrrScreen.c | 190 +++++++++++++++ 11 files changed, 1254 insertions(+), 427 deletions(-) create mode 100644 src/XrrConfig.c create mode 100644 src/XrrCrtc.c create mode 100644 src/XrrMode.c create mode 100644 src/XrrOutput.c create mode 100644 src/XrrScreen.c diff --git a/configure.ac b/configure.ac index 6305696..8caa6f7 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,7 @@ dnl try to keep these the same. Note that the library has an extra dnl digit in the version number to track changes which don't affect the dnl protocol, so Xrandr version l.n.m corresponds to protocol version l.n dnl -AC_INIT(libXrandr, 1.1.0.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXrandr) +AC_INIT(libXrandr, 1.2.0.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXrandr) AC_CONFIG_AUX_DIR(.) AM_INIT_AUTOMAKE([dist-bzip2]) AM_MAINTAINER_MODE diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index 6a4d7fe..795649a 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -1,27 +1,28 @@ /* - * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.9 2002/09/29 23:39:44 keithp Exp $ - * * Copyright © 2000 Compaq Computer Corporation, Inc. * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright © 2006 Intel Corporation * * 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 Compaq not be used in advertising or + * 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. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * 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. * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ - * 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. + * 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: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation */ #ifndef _XRANDR_H_ @@ -33,7 +34,10 @@ _XFUNCPROTOBEGIN - +typedef XID RROutput; +typedef XID RRCrtc; +typedef XID RRMode; + typedef struct { int width, height; int mwidth, mheight; @@ -61,6 +65,56 @@ typedef struct { int mheight; } XRRScreenChangeNotifyEvent; +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_ subtype */ +} XRRNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputChange */ + RROutput output; /* affected output */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + Connection connection; /* current connection status */ + SubpixelOrder subpixel_order; +} XRROutputChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_CrtcChange */ + RRCrtc crtc; /* current crtc (or None) */ + RRMode mode; /* current mode (or None) */ + Rotation rotation; /* current rotation of associated crtc */ + int x, y; /* position */ + unsigned int width, height; /* size */ +} XRRCrtcChangeNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* window which selected for this event */ + int subtype; /* RRNotify_OutputProperty */ + RROutput output; /* related output */ + Atom property; /* changed property */ + Time timestamp; /* time of change */ + int state; /* NewValue, Deleted */ +} XRROutputPropertyNotifyEvent; /* internal representation is private to the library */ typedef struct _XRRScreenConfiguration XRRScreenConfiguration; @@ -71,7 +125,7 @@ Status XRRQueryVersion (Display *dpy, int *minor_versionp); XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, - Drawable draw); + Window window); void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config); @@ -139,6 +193,165 @@ short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates); Time XRRTimes (Display *dpy, int screen, Time *config_timestamp); +/* Version 1.2 additions */ + +void +XRRGetScreenSizeRange (Display *dpy, Window window, + int *minWidth, int *minHeight, + int *maxWidth, int *maxHeight); + +void +XRRSetScreenSize (Display *dpy, Window window, + int width, int height, + int mmWidth, int mmHeight); + +typedef unsigned long XRRModeFlags; + +typedef struct _XRRModeInfo { + RRMode id; + unsigned int width; + unsigned int height; + unsigned long mmWidth; + unsigned long mmHeight; + unsigned long dotClock; + unsigned int hSyncStart; + unsigned int hSyncEnd; + unsigned int hTotal; + unsigned int hSkew; + unsigned int vSyncStart; + unsigned int vSyncEnd; + unsigned int vTotal; + char *name; + unsigned int nameLength; + XRRModeFlags modeFlags; +} XRRModeInfo; + +typedef struct _XRRScreenResources { + Time timestamp; + Time configTimestamp; + int ncrtc; + RRCrtc *crtcs; + int noutput; + RROutput *outputs; + int nmode; + XRRModeInfo *modes; +} XRRScreenResources; + +XRRScreenResources * +XRRGetScreenResources (Display *dpy, Window window); + +void +XRRFreeScreenResources (XRRScreenResources *resources); + +typedef struct _XRROutputInfo { + Time timestamp; + RRCrtc crtc; + char *name; + int nameLen; + Connection connection; + SubpixelOrder subpixel_order; + int ncrtc; + RRCrtc *crtcs; + int nclone; + RROutput *clones; + int nmode; + RRMode *modes; +} XRROutputInfo; + +XRROutputInfo * +XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output); + +void +XRRFreeOutputInfo (XRROutputInfo *outputInfo); + +Atom * +XRRListOutputProperties (Display *dpy, RROutput output, int *nprop); + +void +XRRChangeOutputProperty (Display *dpy, RROutput output, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements); + +void +XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property); + +int +XRRGetOutputProperty (Display *dpy, RROutput output, + Atom property, long offset, long length, + Bool delete, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop); + +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); + +typedef struct _XRRCrtcInfo { + Time timestamp; + int x, y; + unsigned int width, height; + RRMode mode; + Rotation rotation; + int noutput; + RROutput *outputs; + Rotation rotations; + int npossible; + RROutput *possible; +} XRRCrtcInfo; + +XRRCrtcInfo * +XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo); + +Status +XRRSetCrtc (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + RRMode mode, + Rotation rotation, + RROutput *outputs, + int noutputs); + +int +XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc); + +typedef struct _XRRCrtcGamma { + int size; + CARD16 *red; + CARD16 *green; + CARD16 *blue; +} XRRCrtcGamma; + +XRRCrtcGamma * +XRRGetCrtcGamma (Display *dpy, RRCrtc crtc); + +XRRCrtcGamma * +XRRAllocGamma (int size); + +void +XRRSetCrtcGamma (Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma); + +void +XRRFreeGamma (XRRCrtcGamma *gamma); + /* * intended to take RRScreenChangeNotify, or * ConfigureNotify (on the root window) 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..5bd0936 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,14 +2,19 @@ lib_LTLIBRARIES = libXrandr.la libXrandr_la_SOURCES = \ Xrandr.c \ - Xrandrint.h + Xrandrint.h \ + XrrConfig.c \ + XrrCrtc.c \ + XrrMode.c \ + XrrOutput.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 32537b4..577a6dd 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..443a77b --- /dev/null +++ b/src/XrrConfig.c @@ -0,0 +1,423 @@ +/* + * 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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#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) + { + 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); +} + +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..9d46668 --- /dev/null +++ b/src/XrrCrtc.c @@ -0,0 +1,75 @@ +/* + * 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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#include "Xrandrint.h" + +XRRCrtcInfo * +XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); + +void +XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo); + +Status +XRRSetCrtc (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + RRMode mode, + Rotation rotation, + RROutput *outputs, + int noutputs) +{ +} + +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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#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..f06e329 --- /dev/null +++ b/src/XrrOutput.c @@ -0,0 +1,149 @@ +/* + * 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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#include "Xrandrint.h" + +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); + + 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, 0, xFalse)) + { + SyncHandle (); + return NULL; + } + + nbytes = (long) rep.length << 2; + + 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); + SyncHandle (); + return NULL; + } + + xoi->timestamp = rep.timestamp; + xoi->crtc = rep.crtc; + xoi->connection = rep.connection; + xoi->subpixel_order = rep.subpixelOrder; + xoi->ncrtc = rep.nCrtcs; + xoi->crtcs = (RRCrtc *) (xoi + 1); + xoi->nmode = rep.nModes; + 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 + */ + _XRead (dpy, xoi->name, rep.nameLength); + xoi->name[rep.nameLength] = '\0'; + + /* + * Skip any extra data + */ + if (nbytes > nbytesRead) + _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); + + return (XRROutputInfo *) xoi; +} + +void +XRRFreeOutputInfo (XRROutputInfo *outputInfo) +{ + Xfree (outputInfo); +} + +Atom * +XRRListOutputProperties (Display *dpy, RROutput output, int *nprop) +{ +} + +void +XRRChangeOutputProperty (Display *dpy, RROutput output, + Atom property, Atom type, + int format, int mode, + _Xconst unsigned char *data, int nelements) +{ +} + +void +XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property) +{ +} + +int +XRRGetOutputProperty (Display *dpy, RROutput output, + Atom property, long offset, long length, + Bool delete, Atom req_type, + Atom *actual_type, int *actual_format, + unsigned long *nitems, unsigned long *bytes_after, + unsigned char **prop) +{ +} diff --git a/src/XrrScreen.c b/src/XrrScreen.c new file mode 100644 index 0000000..53c1dde --- /dev/null +++ b/src/XrrScreen.c @@ -0,0 +1,190 @@ +/* + * 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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#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); + + 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); + 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); + } + + 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); + 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].mmWidth = modeInfo.mmWidth; + xrsr->modes[i].mmHeight = modeInfo.mmHeight; + 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 + */ + _XRead (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)); + + return (XRRScreenResources *) xrsr; +} + +void +XRRFreeScreenResources (XRRScreenResources *resources) +{ + Xfree (resources); +} + -- cgit v1.2.1 From cb1dbb7c2446ddf514ee709fba940cc4e75438a0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 20:00:57 -0700 Subject: XRRGetScreenSizeRange returns Status. Lots more requests added. XRRGetCrtcInfo XRRSetCrtcConfig XRRGetScreenSizeRange XRRSetScreenSize properties still to do. --- include/X11/extensions/Xrandr.h | 18 +++--- src/XrrConfig.c | 19 ++++--- src/XrrCrtc.c | 121 +++++++++++++++++++++++++++++++++++++--- src/XrrOutput.c | 7 ++- src/XrrScreen.c | 62 +++++++++++++++++++- 5 files changed, 198 insertions(+), 29 deletions(-) diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index 795649a..f56331c 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -195,7 +195,7 @@ Time XRRTimes (Display *dpy, int screen, Time *config_timestamp); /* Version 1.2 additions */ -void +Status XRRGetScreenSizeRange (Display *dpy, Window window, int *minWidth, int *minHeight, int *maxWidth, int *maxHeight); @@ -322,13 +322,15 @@ void XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo); Status -XRRSetCrtc (Display *dpy, - XRRScreenResources *resources, - RRCrtc crtc, - RRMode mode, - Rotation rotation, - RROutput *outputs, - int noutputs); +XRRSetCrtcConfig (Display *dpy, + XRRScreenResources *resources, + RRCrtc crtc, + Time timestamp, + int x, int y, + RRMode mode, + Rotation rotation, + RROutput *outputs, + int noutputs); int XRRGetCrtcGammaSize (Display *dpy, RRCrtc crtc); diff --git a/src/XrrConfig.c b/src/XrrConfig.c index 443a77b..577ccd6 100644 --- a/src/XrrConfig.c +++ b/src/XrrConfig.c @@ -247,7 +247,9 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window) DeqAsyncHandler (dpy, &async); if (async_state.error) { - SyncHandle(); + UnlockDisplay (dpy); + SyncHandle(); + LockDisplay (dpy); } xrri->major_version = async_state.major_version; xrri->minor_version = async_state.minor_version; @@ -281,7 +283,6 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window) scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); if (scp == NULL) { _XEatData (dpy, (unsigned long) nbytes); - SyncHandle (); return NULL; } @@ -335,13 +336,13 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window) XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window) { - XRRScreenConfiguration *config; - XRRFindDisplay(dpy); - LockDisplay (dpy); - config = _XRRGetScreenInfo(dpy, window); - UnlockDisplay (dpy); - SyncHandle (); - return config; + XRRScreenConfiguration *config; + XRRFindDisplay(dpy); + LockDisplay (dpy); + config = _XRRGetScreenInfo(dpy, window); + UnlockDisplay (dpy); + SyncHandle (); + return config; } diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c index 9d46668..a1372a1 100644 --- a/src/XrrCrtc.c +++ b/src/XrrCrtc.c @@ -33,20 +33,123 @@ #include "Xrandrint.h" XRRCrtcInfo * -XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc); +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); +XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo) +{ + Xfree (crtcInfo); +} Status -XRRSetCrtc (Display *dpy, - XRRScreenResources *resources, - RRCrtc crtc, - RRMode mode, - Rotation rotation, - RROutput *outputs, - int noutputs) +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 diff --git a/src/XrrOutput.c b/src/XrrOutput.c index f06e329..1c93660 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -45,6 +45,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) RRCheckExtension (dpy, info, 0); + LockDisplay (dpy); GetReq (RRGetOutputInfo, req); req->reqType = info->codes->major_opcode; req->randrReqType = X_RRGetOutputInfo; @@ -53,6 +54,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay (dpy); SyncHandle (); return NULL; } @@ -79,6 +81,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) xoi = (XRROutputInfo *) Xmalloc(rbytes); if (xoi == NULL) { _XEatData (dpy, (unsigned long) nbytes); + UnlockDisplay (dpy); SyncHandle (); return NULL; } @@ -102,7 +105,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) /* * Read name and '\0' terminate */ - _XRead (dpy, xoi->name, rep.nameLength); + _XReadPad (dpy, xoi->name, rep.nameLength); xoi->name[rep.nameLength] = '\0'; /* @@ -111,6 +114,8 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) if (nbytes > nbytesRead) _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); + UnlockDisplay (dpy); + SyncHandle (); return (XRROutputInfo *) xoi; } diff --git a/src/XrrScreen.c b/src/XrrScreen.c index 53c1dde..1b79c8f 100644 --- a/src/XrrScreen.c +++ b/src/XrrScreen.c @@ -51,6 +51,7 @@ XRRGetScreenResources (Display *dpy, Window window) RRCheckExtension (dpy, info, 0); + LockDisplay (dpy); xrri = (XRandRInfo *) info->data; if (xrri->major_version == -1) @@ -81,6 +82,7 @@ XRRGetScreenResources (Display *dpy, Window window) { if (getting_version) DeqAsyncHandler (dpy, &async); + UnlockDisplay (dpy); SyncHandle (); return NULL; } @@ -89,7 +91,9 @@ XRRGetScreenResources (Display *dpy, Window window) DeqAsyncHandler (dpy, &async); if (async_state.error) { - SyncHandle(); + UnlockDisplay (dpy); + SyncHandle(); + LockDisplay (dpy); } xrri->major_version = async_state.major_version; xrri->minor_version = async_state.minor_version; @@ -121,6 +125,7 @@ XRRGetScreenResources (Display *dpy, Window window) if (xrsr) Xfree (xrsr); if (wire_names) Xfree (wire_names); _XEatData (dpy, (unsigned long) nbytes); + UnlockDisplay (dpy); SyncHandle (); return NULL; } @@ -162,7 +167,7 @@ XRRGetScreenResources (Display *dpy, Window window) /* * Read names and '\0' pad each one */ - _XRead (dpy, wire_names, rep.nbytesNames); + _XReadPad (dpy, wire_names, rep.nbytesNames); wire_name = wire_names; for (i = 0; i < rep.nModes; i++) { xrsr->modes[i].name = names; @@ -179,6 +184,8 @@ XRRGetScreenResources (Display *dpy, Window window) if (nbytes > nbytesRead) _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); + UnlockDisplay (dpy); + SyncHandle(); return (XRRScreenResources *) xrsr; } @@ -188,3 +195,54 @@ 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 (); +} -- cgit v1.2.1 From dd0fb435a0168d4041ecd81024d6493295651c61 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Oct 2006 21:03:10 -0700 Subject: Add mode origins and output options. --- include/X11/extensions/Xrandr.h | 12 +++++++++++- src/XrrCrtc.c | 6 +++--- src/XrrOutput.c | 8 ++++++-- src/XrrScreen.c | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index f56331c..827dcdc 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -206,6 +206,8 @@ XRRSetScreenSize (Display *dpy, Window window, int mmWidth, int mmHeight); typedef unsigned long XRRModeFlags; +typedef unsigned int XRRModeOrigin; +typedef unsigned int XRROutputOptions; typedef struct _XRRModeInfo { RRMode id; @@ -224,8 +226,14 @@ typedef struct _XRRModeInfo { char *name; unsigned int nameLength; XRRModeFlags modeFlags; + XRRModeOrigin origin; } XRRModeInfo; +typedef struct _XRROutputConfig { + RROutput output; + XRROutputOptions options; +} XRROutputConfig; + typedef struct _XRRScreenResources { Time timestamp; Time configTimestamp; @@ -248,8 +256,10 @@ typedef struct _XRROutputInfo { RRCrtc crtc; char *name; int nameLen; + XRROutputOptions current_options; Connection connection; SubpixelOrder subpixel_order; + XRROutputOptions possible_options; int ncrtc; RRCrtc *crtcs; int nclone; @@ -329,7 +339,7 @@ XRRSetCrtcConfig (Display *dpy, int x, int y, RRMode mode, Rotation rotation, - RROutput *outputs, + XRROutputConfig *outputs, int noutputs); int diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c index a1372a1..535327e 100644 --- a/src/XrrCrtc.c +++ b/src/XrrCrtc.c @@ -121,7 +121,7 @@ XRRSetCrtcConfig (Display *dpy, int x, int y, RRMode mode, Rotation rotation, - RROutput *outputs, + XRROutputConfig *outputs, int noutputs) { XExtDisplayInfo *info = XRRFindDisplay(dpy); @@ -135,7 +135,7 @@ XRRSetCrtcConfig (Display *dpy, GetReq (RRSetCrtcConfig, req); req->reqType = info->codes->major_opcode; req->randrReqType = X_RRSetCrtcConfig; - req->length += noutputs; + req->length += noutputs << 1; req->crtc = crtc; req->timestamp = timestamp; req->configTimestamp = resources->configTimestamp; @@ -143,7 +143,7 @@ XRRSetCrtcConfig (Display *dpy, req->y = y; req->mode = mode; req->rotation = rotation; - Data32 (dpy, outputs, noutputs << 2); + Data32 (dpy, outputs, noutputs << 3); if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) rep.status = RRSetConfigFailed; diff --git a/src/XrrOutput.c b/src/XrrOutput.c index 1c93660..872a83a 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -32,6 +32,8 @@ #include #include "Xrandrint.h" +#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) + XRROutputInfo * XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) { @@ -52,14 +54,14 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) req->output = output; req->configTimestamp = resources->configTimestamp; - if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) + if (!_XReply (dpy, (xReply *) &rep, OutputInfoExtra >> 2, xFalse)) { UnlockDisplay (dpy); SyncHandle (); return NULL; } - nbytes = (long) rep.length << 2; + nbytes = ((long) (rep.length) << 2) - OutputInfoExtra; nbytesRead = (long) (rep.nCrtcs * 4 + rep.nModes * 4 + @@ -88,8 +90,10 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) xoi->timestamp = rep.timestamp; xoi->crtc = rep.crtc; + xoi->current_options = rep.currentOptions; xoi->connection = rep.connection; xoi->subpixel_order = rep.subpixelOrder; + xoi->possible_options = rep.possibleOptions; xoi->ncrtc = rep.nCrtcs; xoi->crtcs = (RRCrtc *) (xoi + 1); xoi->nmode = rep.nModes; diff --git a/src/XrrScreen.c b/src/XrrScreen.c index 1b79c8f..37e3aed 100644 --- a/src/XrrScreen.c +++ b/src/XrrScreen.c @@ -162,6 +162,7 @@ XRRGetScreenResources (Display *dpy, Window window) xrsr->modes[i].vTotal = modeInfo.vTotal; xrsr->modes[i].nameLength = modeInfo.nameLength; xrsr->modes[i].modeFlags = modeInfo.modeFlags; + xrsr->modes[i].origin = modeInfo.origin; } /* -- cgit v1.2.1 From ab4207db14d70384f017cc2a22379d7c358b60e0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 4 Oct 2006 20:04:09 -0700 Subject: Remove mode origins. Add preferred mode count. --- include/X11/extensions/Xrandr.h | 3 +-- src/XrrOutput.c | 1 + src/XrrScreen.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index 827dcdc..418e97c 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -206,7 +206,6 @@ XRRSetScreenSize (Display *dpy, Window window, int mmWidth, int mmHeight); typedef unsigned long XRRModeFlags; -typedef unsigned int XRRModeOrigin; typedef unsigned int XRROutputOptions; typedef struct _XRRModeInfo { @@ -226,7 +225,6 @@ typedef struct _XRRModeInfo { char *name; unsigned int nameLength; XRRModeFlags modeFlags; - XRRModeOrigin origin; } XRRModeInfo; typedef struct _XRROutputConfig { @@ -265,6 +263,7 @@ typedef struct _XRROutputInfo { int nclone; RROutput *clones; int nmode; + int npreferred; RRMode *modes; } XRROutputInfo; diff --git a/src/XrrOutput.c b/src/XrrOutput.c index 872a83a..8ae3efa 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -97,6 +97,7 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) 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); diff --git a/src/XrrScreen.c b/src/XrrScreen.c index 37e3aed..1b79c8f 100644 --- a/src/XrrScreen.c +++ b/src/XrrScreen.c @@ -162,7 +162,6 @@ XRRGetScreenResources (Display *dpy, Window window) xrsr->modes[i].vTotal = modeInfo.vTotal; xrsr->modes[i].nameLength = modeInfo.nameLength; xrsr->modes[i].modeFlags = modeInfo.modeFlags; - xrsr->modes[i].origin = modeInfo.origin; } /* -- cgit v1.2.1 From 6676505b6012c97d2f711a84237fa14a62d1d33d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 1 Nov 2006 00:25:45 -0800 Subject: Moving physical size from mode to output. Follows protocol change which places physical size information in the output rather than (inappropriately) in each mode line. --- include/X11/extensions/Xrandr.h | 4 ++-- src/XrrOutput.c | 2 ++ src/XrrScreen.c | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index 418e97c..de0739d 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -212,8 +212,6 @@ typedef struct _XRRModeInfo { RRMode id; unsigned int width; unsigned int height; - unsigned long mmWidth; - unsigned long mmHeight; unsigned long dotClock; unsigned int hSyncStart; unsigned int hSyncEnd; @@ -255,6 +253,8 @@ typedef struct _XRROutputInfo { char *name; int nameLen; XRROutputOptions current_options; + unsigned long mm_width; + unsigned long mm_height; Connection connection; SubpixelOrder subpixel_order; XRROutputOptions possible_options; diff --git a/src/XrrOutput.c b/src/XrrOutput.c index 8ae3efa..a497457 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -91,6 +91,8 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) xoi->timestamp = rep.timestamp; xoi->crtc = rep.crtc; xoi->current_options = rep.currentOptions; + xoi->mm_width = rep.mmWidth; + xoi->mm_height = rep.mmHeight; xoi->connection = rep.connection; xoi->subpixel_order = rep.subpixelOrder; xoi->possible_options = rep.possibleOptions; diff --git a/src/XrrScreen.c b/src/XrrScreen.c index 1b79c8f..c9f5204 100644 --- a/src/XrrScreen.c +++ b/src/XrrScreen.c @@ -150,8 +150,6 @@ XRRGetScreenResources (Display *dpy, Window window) xrsr->modes[i].id = modeInfo.id; xrsr->modes[i].width = modeInfo.width; xrsr->modes[i].height = modeInfo.height; - xrsr->modes[i].mmWidth = modeInfo.mmWidth; - xrsr->modes[i].mmHeight = modeInfo.mmHeight; xrsr->modes[i].dotClock = modeInfo.dotClock; xrsr->modes[i].hSyncStart = modeInfo.hSyncStart; xrsr->modes[i].hSyncEnd = modeInfo.hSyncEnd; -- cgit v1.2.1 From b49342b58d17267fae81205f1a89263ec4d3d114 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 9 Nov 2006 17:07:55 -0800 Subject: Add support for various output property requests. These should be reviewed by someone with proto clue, which I'm generally lacking. --- src/XrrOutput.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/src/XrrOutput.c b/src/XrrOutput.c index a497457..e59af15 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -135,6 +135,49 @@ XRRFreeOutputInfo (XRROutputInfo *outputInfo) 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, nbytes); + UnlockDisplay (dpy); + SyncHandle (); + *nprop = 0; + return NULL; + } + + _XRead32 (dpy, props, nbytes); + } + + *nprop = rep.nProperties; + UnlockDisplay (dpy); + SyncHandle (); + return props; } void @@ -143,11 +186,80 @@ XRRChangeOutputProperty (Display *dpy, RROutput output, 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 @@ -158,4 +270,91 @@ XRRGetOutputProperty (Display *dpy, RROutput output, 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; + + 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.type; + *actual_format = rep.format; + *nitems = rep.nItems; + *bytes_after = rep.bytesAfter; + UnlockDisplay (dpy); + SyncHandle (); + + return Success; } -- cgit v1.2.1 From 7ac8dba76fe33b13620e023699bf971fe8c99fb2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 9 Nov 2006 20:26:33 -0800 Subject: Return the right actual property type for XRRGetOutputProperty. --- src/XrrOutput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/XrrOutput.c b/src/XrrOutput.c index e59af15..ce25bb3 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -349,7 +349,7 @@ XRRGetOutputProperty (Display *dpy, RROutput output, (*prop)[nbytes] = '\0'; } - *actual_type = rep.type; + *actual_type = rep.propertyType; *actual_format = rep.format; *nitems = rep.nItems; *bytes_after = rep.bytesAfter; -- cgit v1.2.1 From 8edabfeba65562f026111b35ec14a9801b4b6a5c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Nov 2006 13:35:46 -0800 Subject: Remove RandR output options. Options are to be implemented as properties instead. --- include/X11/extensions/Xrandr.h | 10 +--------- src/XrrCrtc.c | 6 +++--- src/XrrOutput.c | 2 -- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index de0739d..c1de54a 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -206,7 +206,6 @@ XRRSetScreenSize (Display *dpy, Window window, int mmWidth, int mmHeight); typedef unsigned long XRRModeFlags; -typedef unsigned int XRROutputOptions; typedef struct _XRRModeInfo { RRMode id; @@ -225,11 +224,6 @@ typedef struct _XRRModeInfo { XRRModeFlags modeFlags; } XRRModeInfo; -typedef struct _XRROutputConfig { - RROutput output; - XRROutputOptions options; -} XRROutputConfig; - typedef struct _XRRScreenResources { Time timestamp; Time configTimestamp; @@ -252,12 +246,10 @@ typedef struct _XRROutputInfo { RRCrtc crtc; char *name; int nameLen; - XRROutputOptions current_options; unsigned long mm_width; unsigned long mm_height; Connection connection; SubpixelOrder subpixel_order; - XRROutputOptions possible_options; int ncrtc; RRCrtc *crtcs; int nclone; @@ -338,7 +330,7 @@ XRRSetCrtcConfig (Display *dpy, int x, int y, RRMode mode, Rotation rotation, - XRROutputConfig *outputs, + RROutput *outputs, int noutputs); int diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c index 535327e..a1372a1 100644 --- a/src/XrrCrtc.c +++ b/src/XrrCrtc.c @@ -121,7 +121,7 @@ XRRSetCrtcConfig (Display *dpy, int x, int y, RRMode mode, Rotation rotation, - XRROutputConfig *outputs, + RROutput *outputs, int noutputs) { XExtDisplayInfo *info = XRRFindDisplay(dpy); @@ -135,7 +135,7 @@ XRRSetCrtcConfig (Display *dpy, GetReq (RRSetCrtcConfig, req); req->reqType = info->codes->major_opcode; req->randrReqType = X_RRSetCrtcConfig; - req->length += noutputs << 1; + req->length += noutputs; req->crtc = crtc; req->timestamp = timestamp; req->configTimestamp = resources->configTimestamp; @@ -143,7 +143,7 @@ XRRSetCrtcConfig (Display *dpy, req->y = y; req->mode = mode; req->rotation = rotation; - Data32 (dpy, outputs, noutputs << 3); + Data32 (dpy, outputs, noutputs << 2); if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) rep.status = RRSetConfigFailed; diff --git a/src/XrrOutput.c b/src/XrrOutput.c index ce25bb3..c908bbc 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -90,12 +90,10 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output) xoi->timestamp = rep.timestamp; xoi->crtc = rep.crtc; - xoi->current_options = rep.currentOptions; xoi->mm_width = rep.mmWidth; xoi->mm_height = rep.mmHeight; xoi->connection = rep.connection; xoi->subpixel_order = rep.subpixelOrder; - xoi->possible_options = rep.possibleOptions; xoi->ncrtc = rep.nCrtcs; xoi->crtcs = (RRCrtc *) (xoi + 1); xoi->nmode = rep.nModes; -- cgit v1.2.1 From 0dba1be7969aa56f934d93889cbd589b3dafd3d4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 20 Nov 2006 20:59:18 -0800 Subject: Change properties to have a pending value and report valid values. Pending values are transferred to current values at mode set, allowing a queue of values to accrue in preparation for the modeset operation while still reporting valid 'current' values for applications. The set of valid values is also available so applications can present a reasonable list to the user during configuration. --- include/X11/extensions/Xrandr.h | 18 ++- src/Makefile.am | 1 + src/XrrOutput.c | 227 -------------------------- src/XrrProperty.c | 344 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 362 insertions(+), 228 deletions(-) create mode 100644 src/XrrProperty.c diff --git a/include/X11/extensions/Xrandr.h b/include/X11/extensions/Xrandr.h index c1de54a..bd64e84 100644 --- a/include/X11/extensions/Xrandr.h +++ b/include/X11/extensions/Xrandr.h @@ -268,6 +268,22 @@ XRRFreeOutputInfo (XRROutputInfo *outputInfo); Atom * XRRListOutputProperties (Display *dpy, RROutput output, int *nprop); +typedef struct { + Bool pending; + Bool range; + Bool immutable; + int num_values; + long *values; +} XRRPropertyInfo; + +XRRPropertyInfo * +XRRQueryOutputProperty (Display *dpy, RROutput output, Atom property); + +void +XRRConfigureOutputProperty (Display *dpy, RROutput output, Atom property, + Bool pending, Bool range, int num_values, + long *values); + void XRRChangeOutputProperty (Display *dpy, RROutput output, Atom property, Atom type, @@ -280,7 +296,7 @@ XRRDeleteOutputProperty (Display *dpy, RROutput output, Atom property); int XRRGetOutputProperty (Display *dpy, RROutput output, Atom property, long offset, long length, - Bool delete, Atom req_type, + Bool delete, Bool pending, Atom req_type, Atom *actual_type, int *actual_format, unsigned long *nitems, unsigned long *bytes_after, unsigned char **prop); diff --git a/src/Makefile.am b/src/Makefile.am index 5bd0936..b884a39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ libXrandr_la_SOURCES = \ XrrCrtc.c \ XrrMode.c \ XrrOutput.c \ + XrrProperty.c \ XrrScreen.c libXrandr_la_LIBADD = @X_LIBS@ @RANDR_LIBS@ diff --git a/src/XrrOutput.c b/src/XrrOutput.c index c908bbc..1fe03ae 100644 --- a/src/XrrOutput.c +++ b/src/XrrOutput.c @@ -129,230 +129,3 @@ XRRFreeOutputInfo (XRROutputInfo *outputInfo) { Xfree (outputInfo); } - -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, nbytes); - UnlockDisplay (dpy); - SyncHandle (); - *nprop = 0; - return NULL; - } - - _XRead32 (dpy, props, nbytes); - } - - *nprop = rep.nProperties; - UnlockDisplay (dpy); - SyncHandle (); - return props; -} - -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, 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; - - 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/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 +#endif + +#include +#include +/* we need to be able to manipulate the Display structure on events */ +#include +#include +#include +#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; +} -- cgit v1.2.1