diff options
Diffstat (limited to 'src/Xrandr.c')
-rw-r--r-- | src/Xrandr.c | 506 |
1 files changed, 99 insertions, 407 deletions
diff --git a/src/Xrandr.c b/src/Xrandr.c index 7f256a7..f8bdf02 100644 --- a/src/Xrandr.c +++ b/src/Xrandr.c @@ -42,8 +42,6 @@ char XRRExtensionName[] = RANDR_NAME; static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire); static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire); -static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window); - static int XRRCloseDisplay (Display *dpy, XExtCodes *codes); @@ -64,19 +62,16 @@ static /* const */ XExtensionHooks rr_extension_hooks = { static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = XRRFindDisplay(dpy); - XRRScreenChangeNotifyEvent *aevent; - xRRScreenChangeNotifyEvent *awire; RRCheckExtension(dpy, info, False); switch ((wire->u.u.type & 0x7F) - info->codes->first_event) { - case RRScreenChangeNotify: - awire = (xRRScreenChangeNotifyEvent *) wire; - aevent = (XRRScreenChangeNotifyEvent *) event; + case RRScreenChangeNotify: { + XRRScreenChangeNotifyEvent *aevent= (XRRScreenChangeNotifyEvent *) event; + xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire; aevent->type = awire->type & 0x7F; - aevent->serial = _XSetLastRequestRead(dpy, - (xGenericReply *) wire); + aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); aevent->send_event = (awire->type & 0x80) != 0; aevent->display = dpy; aevent->window = awire->window; @@ -91,6 +86,53 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire) aevent->mwidth = awire->widthInMillimeters; aevent->mheight = awire->heightInMillimeters; return True; + } + case RRNotify: { + XRRNotifyEvent *aevent = (XRRNotifyEvent *) event; + xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; + aevent->type = awire->type & 0x7F; + aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); + aevent->send_event = (awire->type & 0x80) != 0; + aevent->display = dpy; + aevent->window = awire->window; + aevent->subtype = awire->subCode; + switch (aevent->subtype) { + case RRNotify_OutputChange: { + XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event; + xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire; + aevent->output = awire->output; + aevent->crtc = awire->crtc; + aevent->mode = awire->mode; + aevent->rotation = awire->rotation; + aevent->connection = awire->connection; + aevent->subpixel_order = awire->subpixelOrder; + return True; + } + case RRNotify_CrtcChange: { + XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event; + xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; + aevent->crtc = awire->crtc; + aevent->mode = awire->mode; + aevent->rotation = awire->rotation; + aevent->x = awire->x; + aevent->y = awire->y; + aevent->width = awire->height; + aevent->height = awire->height; + return True; + } + case RRNotify_OutputProperty: { + XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event; + xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire; + aevent->output = awire->output; + aevent->property = awire->atom; + aevent->timestamp = awire->timestamp; + aevent->state = awire->state; + return True; + } + + break; + } + } } return False; @@ -99,16 +141,14 @@ static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire) static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = XRRFindDisplay(dpy); - XRRScreenChangeNotifyEvent *aevent; - xRRScreenChangeNotifyEvent *awire; RRCheckExtension(dpy, info, False); switch ((event->type & 0x7F) - info->codes->first_event) { - case RRScreenChangeNotify: - awire = (xRRScreenChangeNotifyEvent *) wire; - aevent = (XRRScreenChangeNotifyEvent *) event; + case RRScreenChangeNotify: { + xRRScreenChangeNotifyEvent *awire = (xRRScreenChangeNotifyEvent *) wire; + XRRScreenChangeNotifyEvent *aevent = (XRRScreenChangeNotifyEvent *) event; awire->type = aevent->type | (aevent->send_event ? 0x80 : 0); awire->rotation = (CARD8) aevent->rotation; awire->sequenceNumber = aevent->serial & 0xFFFF; @@ -123,6 +163,49 @@ static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire) awire->widthInMillimeters = aevent->mwidth; awire->heightInMillimeters = aevent->mheight; return True; + } + case RRNotify: { + xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; + XRRNotifyEvent *aevent = (XRRNotifyEvent *) event; + awire->type = aevent->type | (aevent->send_event ? 0x80 : 0); + awire->sequenceNumber = aevent->serial & 0xFFFF; + awire->window = aevent->window; + awire->subCode = aevent->subtype; + switch (aevent->subtype) { + case RRNotify_OutputChange: { + xRROutputChangeNotifyEvent *awire = (xRROutputChangeNotifyEvent *) wire; + XRROutputChangeNotifyEvent *aevent = (XRROutputChangeNotifyEvent *) event; + awire->output = aevent->output; + awire->crtc = aevent->crtc; + awire->mode = aevent->mode; + awire->rotation = aevent->rotation; + awire->connection = aevent->connection; + awire->subpixelOrder = aevent->subpixel_order; + return True; + } + case RRNotify_CrtcChange: { + xRRCrtcChangeNotifyEvent *awire = (xRRCrtcChangeNotifyEvent *) wire; + XRRCrtcChangeNotifyEvent *aevent = (XRRCrtcChangeNotifyEvent *) event; + awire->crtc = aevent->crtc; + awire->mode = aevent->mode; + awire->rotation = aevent->rotation; + awire->x = aevent->x; + awire->y = aevent->y; + awire->width = aevent->height; + awire->height = aevent->height; + return True; + } + case RRNotify_OutputProperty: { + xRROutputPropertyNotifyEvent *awire = (xRROutputPropertyNotifyEvent *) wire; + XRROutputPropertyNotifyEvent *aevent = (XRROutputPropertyNotifyEvent *) event; + awire->output = aevent->output; + awire->atom = aevent->property; + awire->timestamp = aevent->timestamp; + awire->state = aevent->state; + return True; + } + } + } } return False; } @@ -178,157 +261,6 @@ XRRCloseDisplay (Display *dpy, XExtCodes *codes) UnlockDisplay(dpy); return XextRemoveDisplay (&XRRExtensionInfo, dpy); } - - -Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation) -{ - *current_rotation = config->current_rotation; - return config->rotations; -} - -XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes) -{ - *nsizes = config->nsizes; - return config->sizes; -} - -short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates) -{ - short *r = config->rates; - int nents = config->nrates; - - /* Skip over the intervening rate lists */ - while (sizeID > 0 && nents > 0) - { - int i = (*r + 1); - r += i; - nents -= i; - sizeID--; - } - if (!nents) - { - *nrates = 0; - return 0; - } - *nrates = (int) *r; - return r + 1; -} - -Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp) -{ - *config_timestamp = config->config_timestamp; - return config->timestamp; -} - - -SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config, - Rotation *rotation) -{ - *rotation = (Rotation) config->current_rotation; - return (SizeID) config->current_size; -} - -short XRRConfigCurrentRate (XRRScreenConfiguration *config) -{ - return config->current_rate; -} - -/* - * Go get the screen configuration data and salt it away for future use; - * returns NULL if extension not supported - */ -static XRRScreenConfiguration *_XRRValidateCache (Display *dpy, int screen) -{ - XExtDisplayInfo *info = XRRFindDisplay (dpy); - XRRScreenConfiguration **configs; - XRandRInfo *xrri; - - if (XextHasExtension(info)) { - xrri = (XRandRInfo *) info->data; - configs = xrri->config; - - if (configs[screen] == NULL) - configs[screen] = _XRRGetScreenInfo (dpy, RootWindow(dpy, screen)); - return configs[screen]; - } else { - return NULL; - } -} - -/* given a screen, return the information from the (possibly) cached data */ -Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation) -{ - XRRScreenConfiguration *config; - Rotation cr; - LockDisplay(dpy); - if ((config = _XRRValidateCache(dpy, screen))) { - *current_rotation = config->current_rotation; - cr = config->rotations; - UnlockDisplay(dpy); - return cr; - } - else { - UnlockDisplay(dpy); - *current_rotation = RR_Rotate_0; - return 0; /* no rotations supported */ - } -} - -/* given a screen, return the information from the (possibly) cached data */ -XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes) -{ - XRRScreenConfiguration *config; - XRRScreenSize *sizes; - - LockDisplay(dpy); - if ((config = _XRRValidateCache(dpy, screen))) { - *nsizes = config->nsizes; - sizes = config->sizes; - UnlockDisplay(dpy); - return sizes; - } - else { - UnlockDisplay(dpy); - *nsizes = 0; - return NULL; - } -} - -short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates) -{ - XRRScreenConfiguration *config; - short *rates; - - LockDisplay(dpy); - if ((config = _XRRValidateCache(dpy, screen))) { - rates = XRRConfigRates (config, sizeID, nrates); - UnlockDisplay(dpy); - return rates; - } - else { - UnlockDisplay(dpy); - *nrates = 0; - return NULL; - } -} - -/* given a screen, return the information from the (possibly) cached data */ -Time XRRTimes (Display *dpy, int screen, Time *config_timestamp) -{ - XRRScreenConfiguration *config; - Time ts; - - LockDisplay(dpy); - if ((config = _XRRValidateCache(dpy, screen))) { - *config_timestamp = config->config_timestamp; - ts = config->timestamp; - UnlockDisplay(dpy); - return ts; - } else { - UnlockDisplay(dpy); - return CurrentTime; - } -} int XRRRootToScreen(Display *dpy, Window root) { @@ -353,7 +285,7 @@ Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep) } } -static Bool +Bool _XRRHasRates (int major, int minor) { return major > 1 || (major == 1 && minor >= 1); @@ -398,14 +330,7 @@ Status XRRQueryVersion (Display *dpy, return 1; } -typedef struct _randrVersionState { - unsigned long version_seq; - Bool error; - int major_version; - int minor_version; -} _XRRVersionState; - -static Bool +Bool _XRRVersionHandler (Display *dpy, xReply *rep, char *buf, @@ -431,167 +356,6 @@ _XRRVersionHandler (Display *dpy, state->minor_version = repl->minorVersion; return True; } -/* need a version that does not hold the display lock */ -static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window) -{ - XExtDisplayInfo *info = XRRFindDisplay(dpy); - xRRGetScreenInfoReply rep; - xRRGetScreenInfoReq *req; - _XAsyncHandler async; - _XRRVersionState async_state; - int nbytes, nbytesRead, rbytes; - int i; - xScreenSizes size; - struct _XRRScreenConfiguration *scp; - XRRScreenSize *ssp; - short *rates; - xRRQueryVersionReq *vreq; - XRandRInfo *xrri; - Bool getting_version = False; - - RRCheckExtension (dpy, info, 0); - - xrri = (XRandRInfo *) info->data; - - if (xrri->major_version == -1) - { - /* hide a version query in the request */ - GetReq (RRQueryVersion, vreq); - vreq->reqType = info->codes->major_opcode; - vreq->randrReqType = X_RRQueryVersion; - vreq->majorVersion = RANDR_MAJOR; - vreq->minorVersion = RANDR_MINOR; - - async_state.version_seq = dpy->request; - async_state.error = False; - async.next = dpy->async_handlers; - async.handler = _XRRVersionHandler; - async.data = (XPointer) &async_state; - dpy->async_handlers = &async; - - getting_version = True; - } - - GetReq (RRGetScreenInfo, req); - req->reqType = info->codes->major_opcode; - req->randrReqType = X_RRGetScreenInfo; - req->window = window; - - if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) - { - if (getting_version) - DeqAsyncHandler (dpy, &async); - SyncHandle (); - return NULL; - } - if (getting_version) - { - DeqAsyncHandler (dpy, &async); - if (async_state.error) - { - SyncHandle(); - } - xrri->major_version = async_state.major_version; - xrri->minor_version = async_state.minor_version; - xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version); - } - - /* - * Make the reply compatible with v1.1 - */ - if (!xrri->has_rates) - { - rep.rate = 0; - rep.nrateEnts = 0; - } - - nbytes = (long) rep.length << 2; - - nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) + - ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */); - - /* - * first we must compute how much space to allocate for - * randr library's use; we'll allocate the structures in a single - * allocation, on cleanlyness grounds. - */ - - rbytes = sizeof (XRRScreenConfiguration) + - (rep.nSizes * sizeof (XRRScreenSize) + - rep.nrateEnts * sizeof (int)); - - scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes); - if (scp == NULL) { - _XEatData (dpy, (unsigned long) nbytes); - SyncHandle (); - return NULL; - } - - - ssp = (XRRScreenSize *)(scp + 1); - rates = (short *) (ssp + rep.nSizes); - - /* set up the screen configuration structure */ - scp->screen = - ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root)); - - scp->sizes = ssp; - scp->rates = rates; - scp->rotations = rep.setOfRotations; - scp->current_size = rep.sizeID; - scp->current_rate = rep.rate; - scp->current_rotation = rep.rotation; - scp->timestamp = rep.timestamp; - scp->config_timestamp = rep.configTimestamp; - scp->nsizes = rep.nSizes; - scp->nrates = rep.nrateEnts; - - /* - * Time to unpack the data from the server. - */ - - /* - * First the size information - */ - for (i = 0; i < rep.nSizes; i++) { - _XReadPad (dpy, (char *) &size, SIZEOF (xScreenSizes)); - - ssp[i].width = size.widthInPixels; - ssp[i].height = size.heightInPixels; - ssp[i].mwidth = size.widthInMillimeters; - ssp[i].mheight = size.heightInMillimeters; - } - /* - * And the rates - */ - _XRead16Pad (dpy, rates, 2 /* SIZEOF (CARD16) */ * rep.nrateEnts); - - /* - * Skip any extra data - */ - if (nbytes > nbytesRead) - _XEatData (dpy, (unsigned long) (nbytes - nbytesRead)); - - return (XRRScreenConfiguration *)(scp); -} - -XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window) -{ - XRRScreenConfiguration *config; - XRRFindDisplay(dpy); - LockDisplay (dpy); - config = _XRRGetScreenInfo(dpy, window); - UnlockDisplay (dpy); - SyncHandle (); - return config; -} - - -void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config) -{ - Xfree (config); -} - /* * in protocol version 0.1, routine added to allow selecting for new events. @@ -616,78 +380,6 @@ void XRRSelectInput (Display *dpy, Window window, int mask) return; } -Status XRRSetScreenConfigAndRate (Display *dpy, - XRRScreenConfiguration *config, - Drawable draw, - int size_index, - Rotation rotation, - short rate, - Time timestamp) -{ - XExtDisplayInfo *info = XRRFindDisplay (dpy); - xRRSetScreenConfigReply rep; - XRandRInfo *xrri; - int major, minor; - - RRCheckExtension (dpy, info, 0); - - /* Make sure has_rates is set */ - if (!XRRQueryVersion (dpy, &major, &minor)) - return 0; - - LockDisplay (dpy); - xrri = (XRandRInfo *) info->data; - if (xrri->has_rates) - { - xRRSetScreenConfigReq *req; - GetReq (RRSetScreenConfig, req); - req->reqType = info->codes->major_opcode; - req->randrReqType = X_RRSetScreenConfig; - req->drawable = draw; - req->sizeID = size_index; - req->rotation = rotation; - req->timestamp = timestamp; - req->configTimestamp = config->config_timestamp; - req->rate = rate; - } - else - { - xRR1_0SetScreenConfigReq *req; - GetReq (RR1_0SetScreenConfig, req); - req->reqType = info->codes->major_opcode; - req->randrReqType = X_RRSetScreenConfig; - req->drawable = draw; - req->sizeID = size_index; - req->rotation = rotation; - req->timestamp = timestamp; - req->configTimestamp = config->config_timestamp; - } - - (void) _XReply (dpy, (xReply *) &rep, 0, xTrue); - - if (rep.status == RRSetConfigSuccess) { - /* if we succeed, set our view of reality to what we set it to */ - config->config_timestamp = rep.newConfigTimestamp; - config->timestamp = rep.newTimestamp; - config->screen = ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root)); - config->current_size = size_index; - config->current_rotation = rotation; - } - UnlockDisplay (dpy); - SyncHandle (); - return(rep.status); -} - -Status XRRSetScreenConfig (Display *dpy, - XRRScreenConfiguration *config, - Drawable draw, - int size_index, - Rotation rotation, Time timestamp) -{ - return XRRSetScreenConfigAndRate (dpy, config, draw, size_index, - rotation, 0, timestamp); -} - int XRRUpdateConfiguration(XEvent *event) { XRRScreenChangeNotifyEvent *scevent; |