From a7971771a8ab6f6f76a2a8e482dbb3a30901af1c Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 25 Feb 2011 07:31:13 +0000 Subject: xserver randrproto mesa xkeyboard-config git update 25 Feb 2011 --- xorg-server/randr/Makefile.am | 62 +- xorg-server/randr/randr.c | 1019 +++++++------ xorg-server/randr/randrstr.h | 2099 ++++++++++++-------------- xorg-server/randr/rrcrtc.c | 3150 +++++++++++++++++---------------------- xorg-server/randr/rrdispatch.c | 462 +++--- xorg-server/randr/rrinfo.c | 682 ++++----- xorg-server/randr/rrscreen.c | 32 +- xorg-server/randr/rrsdispatch.c | 1138 +++++++------- xorg-server/randr/rrtransform.c | 620 ++++---- xorg-server/randr/rrtransform.h | 161 +- 10 files changed, 4286 insertions(+), 5139 deletions(-) (limited to 'xorg-server/randr') diff --git a/xorg-server/randr/Makefile.am b/xorg-server/randr/Makefile.am index 2b0b3a984..de338b972 100644 --- a/xorg-server/randr/Makefile.am +++ b/xorg-server/randr/Makefile.am @@ -1,33 +1,29 @@ -noinst_LTLIBRARIES = librandr.la - -AM_CFLAGS = $(DIX_CFLAGS) - -XINERAMA_SRCS = rrxinerama.c - -if XORG -sdk_HEADERS = randrstr.h rrtransform.h -endif - -librandr_la_SOURCES = \ - randr.c \ - randrstr.h \ - rrcrtc.c \ - rrdispatch.c \ - rrinfo.c \ - rrmode.c \ - rroutput.c \ - rrpixmap.c \ - rrpointer.c \ - rrproperty.c \ - rrscreen.c \ - rrsdispatch.c \ - rrsprite.c \ - rrtransform.h \ - rrtransform.c \ - mirrcrtc.c - - -if XINERAMA -librandr_la_SOURCES += ${XINERAMA_SRCS} -endif - +noinst_LTLIBRARIES = librandr.la + +AM_CFLAGS = $(DIX_CFLAGS) + +XINERAMA_SRCS = rrxinerama.c + +if XORG +sdk_HEADERS = randrstr.h rrtransform.h +endif + +librandr_la_SOURCES = \ + randr.c \ + randrstr.h \ + rrcrtc.c \ + rrdispatch.c \ + rrinfo.c \ + rrmode.c \ + rroutput.c \ + rrpointer.c \ + rrproperty.c \ + rrscreen.c \ + rrsdispatch.c \ + rrtransform.h \ + rrtransform.c + +if XINERAMA +librandr_la_SOURCES += ${XINERAMA_SRCS} +endif + diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c index 1346d1e9c..607770520 100644 --- a/xorg-server/randr/randr.c +++ b/xorg-server/randr/randr.c @@ -1,517 +1,502 @@ -/* - * Copyright © 2000 Compaq Computer Corporation - * Copyright © 2002 Hewlett-Packard Company - * 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 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, Hewlett-Packard Company, Inc. - * Keith Packard, Intel Corporation - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "randrstr.h" - -/* From render.h */ -#ifndef SubPixelUnknown -#define SubPixelUnknown 0 -#endif - -#define RR_VALIDATE -static int RRNScreens; - -#define wrap(priv,real,mem,func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv,real,mem) {\ - real->mem = priv->mem; \ -} - -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); - -int RREventBase; -int RRErrorBase; -RESTYPE RRClientType, RREventType; /* resource types for event masks */ -DevPrivateKeyRec RRClientPrivateKeyRec; - -DevPrivateKeyRec rrPrivKeyRec; - -static void -RRClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - rrClientPriv(pClient); - RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); - int i; - - pRRClient->major_version = 0; - pRRClient->minor_version = 0; - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - rrScrPriv(pScreen); - - if (pScrPriv) - { - pTimes[i].setTime = pScrPriv->lastSetTime; - pTimes[i].configTime = pScrPriv->lastConfigTime; - } - } -} - -static Bool -RRCloseScreen (int i, ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - int j; - - unwrap (pScrPriv, pScreen, CloseScreen); - for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) - RRCrtcDestroy (pScrPriv->crtcs[j]); - for (j = pScrPriv->numOutputs - 1; j >= 0; j--) - RROutputDestroy (pScrPriv->outputs[j]); - - free(pScrPriv->crtcs); - free(pScrPriv->outputs); - free(pScrPriv->scanout_info); - free(pScrPriv); - RRNScreens -= 1; /* ok, one fewer screen with RandR running */ - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, - xRRScreenChangeNotifyEvent *to) -{ - to->type = from->type; - to->rotation = from->rotation; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); - cpswapl(from->window, to->window); - cpswaps(from->sizeID, to->sizeID); - cpswaps(from->subpixelOrder, to->subpixelOrder); - cpswaps(from->widthInPixels, to->widthInPixels); - cpswaps(from->heightInPixels, to->heightInPixels); - cpswaps(from->widthInMillimeters, to->widthInMillimeters); - cpswaps(from->heightInMillimeters, to->heightInMillimeters); -} - -static void -SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from, - xRRCrtcChangeNotifyEvent *to) -{ - to->type = from->type; - to->subCode = from->subCode; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->window, to->window); - cpswapl(from->crtc, to->crtc); - cpswapl(from->mode, to->mode); - cpswaps(from->rotation, to->rotation); - /* pad1 */ - cpswaps(from->x, to->x); - cpswaps(from->y, to->y); - cpswaps(from->width, to->width); - cpswaps(from->height, to->height); -} - -static void -SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from, - xRROutputChangeNotifyEvent *to) -{ - to->type = from->type; - to->subCode = from->subCode; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->timestamp, to->timestamp); - cpswapl(from->configTimestamp, to->configTimestamp); - cpswapl(from->window, to->window); - cpswapl(from->output, to->output); - cpswapl(from->crtc, to->crtc); - cpswapl(from->mode, to->mode); - cpswaps(from->rotation, to->rotation); - to->connection = from->connection; - to->subpixelOrder = from->subpixelOrder; -} - -static void -SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from, - xRROutputPropertyNotifyEvent *to) -{ - to->type = from->type; - to->subCode = from->subCode; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->window, to->window); - cpswapl(from->output, to->output); - cpswapl(from->atom, to->atom); - cpswapl(from->timestamp, to->timestamp); - to->state = from->state; - /* pad1 */ - /* pad2 */ - /* pad3 */ - /* pad4 */ -} - -static void -SRRNotifyEvent (xEvent *from, - xEvent *to) -{ - switch (from->u.u.detail) { - case RRNotify_CrtcChange: - SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from, - (xRRCrtcChangeNotifyEvent *) to); - break; - case RRNotify_OutputChange: - SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from, - (xRROutputChangeNotifyEvent *) to); - break; - case RRNotify_OutputProperty: - SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from, - (xRROutputPropertyNotifyEvent *) to); - break; - default: - break; - } -} - -static int RRGeneration; - -Bool RRInit (void) -{ - if (RRGeneration != serverGeneration) - { - if (!RRModeInit ()) - return FALSE; - if (!RRCrtcInit ()) - return FALSE; - if (!RROutputInit ()) - return FALSE; - RRGeneration = serverGeneration; - } - if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - return TRUE; -} - -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (!RRInit ()) - return FALSE; - - pScrPriv = (rrScrPrivPtr) calloc(1, sizeof (rrScrPrivRec)); - if (!pScrPriv) - return FALSE; - - SetRRScreen(pScreen, pScrPriv); - - /* - * Calling function best set these function vectors - */ - pScrPriv->rrGetInfo = 0; - pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; - pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; - - pScrPriv->width = pScreen->width; - pScrPriv->height = pScreen->height; - pScrPriv->mmWidth = pScreen->mmWidth; - pScrPriv->mmHeight = pScreen->mmHeight; -#if RANDR_12_INTERFACE - pScrPriv->rrScreenSetSize = NULL; - pScrPriv->rrCrtcSet = NULL; - pScrPriv->rrCrtcSetGamma = NULL; -#endif - pScrPriv->scanout_info = NULL; - pScrPriv->n_scanout_info = 0; -#if RANDR_10_INTERFACE - pScrPriv->rrSetConfig = 0; - pScrPriv->rotations = RR_Rotate_0; - pScrPriv->reqWidth = pScreen->width; - pScrPriv->reqHeight = pScreen->height; - pScrPriv->nSizes = 0; - pScrPriv->pSizes = NULL; - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->rate = 0; - pScrPriv->size = 0; -#endif - - /* - * This value doesn't really matter -- any client must call - * GetScreenInfo before reading it which will automatically update - * the time - */ - pScrPriv->lastSetTime = currentTime; - pScrPriv->lastConfigTime = currentTime; - - wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - - pScrPriv->numOutputs = 0; - pScrPriv->outputs = NULL; - pScrPriv->numCrtcs = 0; - pScrPriv->crtcs = NULL; - - RRNScreens += 1; /* keep count of screens that implement randr */ - return TRUE; -} - -/*ARGSUSED*/ -static int -RRFreeClient (pointer data, XID id) -{ - RREventPtr pRREvent; - WindowPtr pWin; - RREventPtr *pHead, pCur, pPrev; - - pRREvent = (RREventPtr) data; - pWin = pRREvent->window; - dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - RREventType, serverClient, DixDestroyAccess); - if (pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pRREvent->next; - else - *pHead = pRREvent->next; - } - } - free((pointer) pRREvent); - return 1; -} - -/*ARGSUSED*/ -static int -RRFreeEvents (pointer data, XID id) -{ - RREventPtr *pHead, pCur, pNext; - - pHead = (RREventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, RRClientType); - free((pointer) pCur); - } - free((pointer) pHead); - return 1; -} - -void -RRExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (RRNScreens == 0) return; - - if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT, - sizeof (RRClientRec) + - screenInfo.numScreens * sizeof (RRTimesRec))) - return; - if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) - return; - - RRClientType = CreateNewResourceType(RRFreeClient, "RandRClient"); - if (!RRClientType) - return; - RREventType = CreateNewResourceType(RRFreeEvents, "RandREvent"); - if (!RREventType) - return; - extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, - ProcRRDispatch, SProcRRDispatch, - NULL, StandardMinorOpcode); - if (!extEntry) - return; - RRErrorBase = extEntry->errorBase; - RREventBase = extEntry->eventBase; - EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; - EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) - SRRNotifyEvent; - - RRModeInitErrorValue(); - RRCrtcInitErrorValue(); - RROutputInitErrorValue(); - -#ifdef PANORAMIX - RRXineramaExtensionInit(); -#endif -} - -static int -TellChanged (WindowPtr pWin, pointer value) -{ - RREventPtr *pHead, pRREvent; - ClientPtr client; - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv(pScreen); - int i; - - dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - RREventType, serverClient, DixReadAccess); - if (!pHead) - return WT_WALKCHILDREN; - - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - { - client = pRREvent->client; - if (client == serverClient || client->clientGone) - continue; - - if (pRREvent->mask & RRScreenChangeNotifyMask) - RRDeliverScreenEvent (client, pWin, pScreen); - - if (pRREvent->mask & RRCrtcChangeNotifyMask) - { - for (i = 0; i < pScrPriv->numCrtcs; i++) - { - RRCrtcPtr crtc = pScrPriv->crtcs[i]; - if (crtc->changed) - RRDeliverCrtcEvent (client, pWin, crtc); - } - } - - if (pRREvent->mask & RROutputChangeNotifyMask) - { - for (i = 0; i < pScrPriv->numOutputs; i++) - { - RROutputPtr output = pScrPriv->outputs[i]; - if (output->changed) - RRDeliverOutputEvent (client, pWin, output); - } - } - } - return WT_WALKCHILDREN; -} - -/* - * Something changed; send events and adjust pointer position - */ -void -RRTellChanged (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - int i; - - if (pScrPriv->changed) - { - UpdateCurrentTime (); - if (pScrPriv->configChanged) - { - pScrPriv->lastConfigTime = currentTime; - pScrPriv->configChanged = FALSE; - } - pScrPriv->changed = FALSE; - WalkTree (pScreen, TellChanged, (pointer) pScreen); - for (i = 0; i < pScrPriv->numOutputs; i++) - pScrPriv->outputs[i]->changed = FALSE; - for (i = 0; i < pScrPriv->numCrtcs; i++) - pScrPriv->crtcs[i]->changed = FALSE; - if (pScrPriv->layoutChanged) - { - pScrPriv->layoutChanged = FALSE; - RRPointerScreenConfigured (pScreen); - RRSendConfigNotify (pScreen); - } - } -} - -/* - * Return the first output which is connected to an active CRTC - * Used in emulating 1.0 behaviour - */ -RROutputPtr -RRFirstOutput (ScreenPtr pScreen) -{ - rrScrPriv(pScreen); - RROutputPtr output; - int i, j; - - if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) - return pScrPriv->primaryOutput; - - for (i = 0; i < pScrPriv->numCrtcs; i++) - { - RRCrtcPtr crtc = pScrPriv->crtcs[i]; - for (j = 0; j < pScrPriv->numOutputs; j++) - { - output = pScrPriv->outputs[j]; - if (output->crtc == crtc) - return output; - } - } - return NULL; -} - -CARD16 -RRVerticalRefresh (xRRModeInfo *mode) -{ - CARD32 refresh; - CARD32 dots = mode->hTotal * mode->vTotal; - if (!dots) - return 0; - refresh = (mode->dotClock + dots/2) / dots; - if (refresh > 0xffff) - refresh = 0xffff; - return (CARD16) refresh; -} - -RRScanoutPixmapInfo * -RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info) -{ - rrScrPriv(screen); - - if (!pScrPriv->scanout_info && pScrPriv->rrQueryScanoutPixmaps) - pScrPriv->scanout_info = pScrPriv->rrQueryScanoutPixmaps(screen, - &pScrPriv->n_scanout_info); - *n_info = pScrPriv->n_scanout_info; - return pScrPriv->scanout_info; -} - -static int -ProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) - return BadRequest; - return (*ProcRandrVector[stuff->data]) (client); -} - -static int -SProcRRDispatch (ClientPtr client) -{ - REQUEST(xReq); - if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) - return BadRequest; - return (*SProcRandrVector[stuff->data]) (client); -} - +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * 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 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, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "randrstr.h" + +/* From render.h */ +#ifndef SubPixelUnknown +#define SubPixelUnknown 0 +#endif + +#define RR_VALIDATE +static int RRNScreens; + +#define wrap(priv,real,mem,func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv,real,mem) {\ + real->mem = priv->mem; \ +} + +static int ProcRRDispatch (ClientPtr pClient); +static int SProcRRDispatch (ClientPtr pClient); + +int RREventBase; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ +DevPrivateKeyRec RRClientPrivateKeyRec; + +DevPrivateKeyRec rrPrivKeyRec; + +static void +RRClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + rrClientPriv(pClient); + RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1); + int i; + + pRRClient->major_version = 0; + pRRClient->minor_version = 0; + for (i = 0; i < screenInfo.numScreens; i++) + { + ScreenPtr pScreen = screenInfo.screens[i]; + rrScrPriv(pScreen); + + if (pScrPriv) + { + pTimes[i].setTime = pScrPriv->lastSetTime; + pTimes[i].configTime = pScrPriv->lastConfigTime; + } + } +} + +static Bool +RRCloseScreen (int i, ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + int j; + + unwrap (pScrPriv, pScreen, CloseScreen); + for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) + RRCrtcDestroy (pScrPriv->crtcs[j]); + for (j = pScrPriv->numOutputs - 1; j >= 0; j--) + RROutputDestroy (pScrPriv->outputs[j]); + + free(pScrPriv->crtcs); + free(pScrPriv->outputs); + free(pScrPriv); + RRNScreens -= 1; /* ok, one fewer screen with RandR running */ + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, + xRRScreenChangeNotifyEvent *to) +{ + to->type = from->type; + to->rotation = from->rotation; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->root, to->root); + cpswapl(from->window, to->window); + cpswaps(from->sizeID, to->sizeID); + cpswaps(from->subpixelOrder, to->subpixelOrder); + cpswaps(from->widthInPixels, to->widthInPixels); + cpswaps(from->heightInPixels, to->heightInPixels); + cpswaps(from->widthInMillimeters, to->widthInMillimeters); + cpswaps(from->heightInMillimeters, to->heightInMillimeters); +} + +static void +SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from, + xRRCrtcChangeNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->window, to->window); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswaps(from->rotation, to->rotation); + /* pad1 */ + cpswaps(from->x, to->x); + cpswaps(from->y, to->y); + cpswaps(from->width, to->width); + cpswaps(from->height, to->height); +} + +static void +SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from, + xRROutputChangeNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->timestamp, to->timestamp); + cpswapl(from->configTimestamp, to->configTimestamp); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswaps(from->rotation, to->rotation); + to->connection = from->connection; + to->subpixelOrder = from->subpixelOrder; +} + +static void +SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from, + xRROutputPropertyNotifyEvent *to) +{ + to->type = from->type; + to->subCode = from->subCode; + cpswaps(from->sequenceNumber, to->sequenceNumber); + cpswapl(from->window, to->window); + cpswapl(from->output, to->output); + cpswapl(from->atom, to->atom); + cpswapl(from->timestamp, to->timestamp); + to->state = from->state; + /* pad1 */ + /* pad2 */ + /* pad3 */ + /* pad4 */ +} + +static void +SRRNotifyEvent (xEvent *from, + xEvent *to) +{ + switch (from->u.u.detail) { + case RRNotify_CrtcChange: + SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from, + (xRRCrtcChangeNotifyEvent *) to); + break; + case RRNotify_OutputChange: + SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from, + (xRROutputChangeNotifyEvent *) to); + break; + case RRNotify_OutputProperty: + SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from, + (xRROutputPropertyNotifyEvent *) to); + break; + default: + break; + } +} + +static int RRGeneration; + +Bool RRInit (void) +{ + if (RRGeneration != serverGeneration) + { + if (!RRModeInit ()) + return FALSE; + if (!RRCrtcInit ()) + return FALSE; + if (!RROutputInit ()) + return FALSE; + RRGeneration = serverGeneration; + } + if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + return TRUE; +} + +Bool RRScreenInit(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRInit ()) + return FALSE; + + pScrPriv = (rrScrPrivPtr) calloc(1, sizeof (rrScrPrivRec)); + if (!pScrPriv) + return FALSE; + + SetRRScreen(pScreen, pScrPriv); + + /* + * Calling function best set these function vectors + */ + pScrPriv->rrGetInfo = 0; + pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; + pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->mmWidth = pScreen->mmWidth; + pScrPriv->mmHeight = pScreen->mmHeight; +#if RANDR_12_INTERFACE + pScrPriv->rrScreenSetSize = NULL; + pScrPriv->rrCrtcSet = NULL; + pScrPriv->rrCrtcSetGamma = NULL; +#endif +#if RANDR_10_INTERFACE + pScrPriv->rrSetConfig = 0; + pScrPriv->rotations = RR_Rotate_0; + pScrPriv->reqWidth = pScreen->width; + pScrPriv->reqHeight = pScreen->height; + pScrPriv->nSizes = 0; + pScrPriv->pSizes = NULL; + pScrPriv->rotation = RR_Rotate_0; + pScrPriv->rate = 0; + pScrPriv->size = 0; +#endif + + /* + * This value doesn't really matter -- any client must call + * GetScreenInfo before reading it which will automatically update + * the time + */ + pScrPriv->lastSetTime = currentTime; + pScrPriv->lastConfigTime = currentTime; + + wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); + + pScrPriv->numOutputs = 0; + pScrPriv->outputs = NULL; + pScrPriv->numCrtcs = 0; + pScrPriv->crtcs = NULL; + + RRNScreens += 1; /* keep count of screens that implement randr */ + return TRUE; +} + +/*ARGSUSED*/ +static int +RRFreeClient (pointer data, XID id) +{ + RREventPtr pRREvent; + WindowPtr pWin; + RREventPtr *pHead, pCur, pPrev; + + pRREvent = (RREventPtr) data; + pWin = pRREvent->window; + dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, + RREventType, serverClient, DixDestroyAccess); + if (pHead) { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) + { + if (pPrev) + pPrev->next = pRREvent->next; + else + *pHead = pRREvent->next; + } + } + free((pointer) pRREvent); + return 1; +} + +/*ARGSUSED*/ +static int +RRFreeEvents (pointer data, XID id) +{ + RREventPtr *pHead, pCur, pNext; + + pHead = (RREventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) { + pNext = pCur->next; + FreeResource (pCur->clientResource, RRClientType); + free((pointer) pCur); + } + free((pointer) pHead); + return 1; +} + +void +RRExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (RRNScreens == 0) return; + + if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT, + sizeof (RRClientRec) + + screenInfo.numScreens * sizeof (RRTimesRec))) + return; + if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) + return; + + RRClientType = CreateNewResourceType(RRFreeClient, "RandRClient"); + if (!RRClientType) + return; + RREventType = CreateNewResourceType(RRFreeEvents, "RandREvent"); + if (!RREventType) + return; + extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, + ProcRRDispatch, SProcRRDispatch, + NULL, StandardMinorOpcode); + if (!extEntry) + return; + RRErrorBase = extEntry->errorBase; + RREventBase = extEntry->eventBase; + EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) + SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; + + RRModeInitErrorValue(); + RRCrtcInitErrorValue(); + RROutputInitErrorValue(); + +#ifdef PANORAMIX + RRXineramaExtensionInit(); +#endif +} + +static int +TellChanged (WindowPtr pWin, pointer value) +{ + RREventPtr *pHead, pRREvent; + ClientPtr client; + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv(pScreen); + int i; + + dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, + RREventType, serverClient, DixReadAccess); + if (!pHead) + return WT_WALKCHILDREN; + + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + { + client = pRREvent->client; + if (client == serverClient || client->clientGone) + continue; + + if (pRREvent->mask & RRScreenChangeNotifyMask) + RRDeliverScreenEvent (client, pWin, pScreen); + + if (pRREvent->mask & RRCrtcChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (crtc->changed) + RRDeliverCrtcEvent (client, pWin, crtc); + } + } + + if (pRREvent->mask & RROutputChangeNotifyMask) + { + for (i = 0; i < pScrPriv->numOutputs; i++) + { + RROutputPtr output = pScrPriv->outputs[i]; + if (output->changed) + RRDeliverOutputEvent (client, pWin, output); + } + } + } + return WT_WALKCHILDREN; +} + +/* + * Something changed; send events and adjust pointer position + */ +void +RRTellChanged (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + int i; + + if (pScrPriv->changed) + { + UpdateCurrentTime (); + if (pScrPriv->configChanged) + { + pScrPriv->lastConfigTime = currentTime; + pScrPriv->configChanged = FALSE; + } + pScrPriv->changed = FALSE; + WalkTree (pScreen, TellChanged, (pointer) pScreen); + for (i = 0; i < pScrPriv->numOutputs; i++) + pScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pScrPriv->numCrtcs; i++) + pScrPriv->crtcs[i]->changed = FALSE; + if (pScrPriv->layoutChanged) + { + pScrPriv->layoutChanged = FALSE; + RRPointerScreenConfigured (pScreen); + RRSendConfigNotify (pScreen); + } + } +} + +/* + * Return the first output which is connected to an active CRTC + * Used in emulating 1.0 behaviour + */ +RROutputPtr +RRFirstOutput (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; + + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) + return pScrPriv->primaryOutput; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + for (j = 0; j < pScrPriv->numOutputs; j++) + { + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; + } + } + return NULL; +} + +CARD16 +RRVerticalRefresh (xRRModeInfo *mode) +{ + CARD32 refresh; + CARD32 dots = mode->hTotal * mode->vTotal; + if (!dots) + return 0; + refresh = (mode->dotClock + dots/2) / dots; + if (refresh > 0xffff) + refresh = 0xffff; + return (CARD16) refresh; +} + +static int +ProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*ProcRandrVector[stuff->data]) (client); +} + +static int +SProcRRDispatch (ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) + return BadRequest; + return (*SProcRandrVector[stuff->data]) (client); +} + diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h index ee208f569..7ea608003 100644 --- a/xorg-server/randr/randrstr.h +++ b/xorg-server/randr/randrstr.h @@ -1,1129 +1,970 @@ -/* - * Copyright © 2000 Compaq Computer Corporation - * Copyright © 2002 Hewlett-Packard Company - * Copyright © 2006 Intel Corporation - * Copyright © 2008 Red Hat, Inc. - * - * 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, Hewlett-Packard Company, Inc. - * Keith Packard, Intel Corporation - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#ifndef _RANDRSTR_H_ -#define _RANDRSTR_H_ - -#include -#include -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include "rrtransform.h" -#include -#include -#include /* we share subpixel order information */ -#include "picturestr.h" -#include - -/* required for ABI compatibility for now */ -#define RANDR_10_INTERFACE 1 -#define RANDR_12_INTERFACE 1 -#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ -#define RANDR_14_INTERFACE 1 /* requires RANDR_13_INTERFACE */ -#define RANDR_GET_CRTC_INTERFACE 1 - -#define RANDR_INTERFACE_VERSION 0x0104 - -typedef XID RRMode; -typedef XID RROutput; -typedef XID RRCrtc; - -extern _X_EXPORT int RREventBase, RRErrorBase; - -extern _X_EXPORT int (*ProcRandrVector[RRNumberRequests])(ClientPtr); -extern _X_EXPORT int (*SProcRandrVector[RRNumberRequests])(ClientPtr); - -/* - * Modeline for a monitor. Name follows directly after this struct - */ - -#define RRModeName(pMode) ((char *) (pMode + 1)) -typedef struct _rrMode RRModeRec, *RRModePtr; -typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; -typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; -typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; -typedef struct _rrScreenConfig RRScreenConfigRec, *RRScreenConfigPtr; -typedef struct _rrCrtcConfig RRCrtcConfigRec, *RRCrtcConfigPtr; -typedef struct _rrOutput RROutputRec, *RROutputPtr; - -struct _rrMode { - int refcnt; - xRRModeInfo mode; - char *name; - ScreenPtr userScreen; -}; - -struct _rrPropertyValue { - Atom type; /* ignored by server */ - short format; /* format of data for swapping - 8,16,32 */ - long size; /* size of data in (format/8) bytes */ - pointer data; /* private to client */ -}; - -struct _rrProperty { - RRPropertyPtr next; - ATOM propertyName; - Bool is_pending; - Bool range; - Bool immutable; - int num_valid; - INT32 *valid_values; - RRPropertyValueRec current, pending; -}; - -struct _rrCrtc { - RRCrtc id; - ScreenPtr pScreen; - RRModePtr mode; - int x, y; - Rotation rotation; - Rotation rotations; - Bool changed; - int numOutputs; - RROutputPtr *outputs; - int gammaSize; - CARD16 *gammaRed; - CARD16 *gammaBlue; - CARD16 *gammaGreen; - void *devPrivate; - Bool transforms; - PixmapPtr scanoutPixmap; - RRTransformRec client_pending_transform; - RRTransformRec client_current_transform; - PictTransform client_sprite_position_transform; - PictTransform client_sprite_image_transform; - struct pict_f_transform client_sprite_f_position_transform; - struct pict_f_transform client_sprite_f_image_transform; - - PictTransform transform; - struct pict_f_transform f_transform; - struct pict_f_transform f_inverse; - struct pict_f_transform f_sprite_position; /* crtc from screen */ - struct pict_f_transform f_sprite_image_inverse; /* image from crtc */ -}; - -struct _rrScreenConfig { - CARD16 screen_pixmap_width; - CARD16 screen_pixmap_height; - CARD16 screen_width; - CARD16 screen_height; - CARD32 mm_width; - CARD32 mm_height; -}; - -struct _rrCrtcConfig { - RRCrtcPtr crtc; - int x, y; - RRModePtr mode; - Rotation rotation; - int numOutputs; - RROutputPtr *outputs; - PictTransform sprite_position_transform; - PictTransform sprite_image_transform; - struct pict_f_transform sprite_position_f_transform; - struct pict_f_transform sprite_image_f_transform; - PixmapPtr pixmap; - int pixmap_x, pixmap_y; -}; - -struct _rrOutput { - RROutput id; - ScreenPtr pScreen; - char *name; - int nameLength; - CARD8 connection; - CARD8 subpixelOrder; - int mmWidth; - int mmHeight; - RRCrtcPtr crtc; - int numCrtcs; - RRCrtcPtr *crtcs; - int numClones; - RROutputPtr *clones; - int numModes; - int numPreferred; - RRModePtr *modes; - int numUserModes; - RRModePtr *userModes; - Bool changed; - RRPropertyPtr properties; - Bool pendingProperties; - void *devPrivate; -}; - -#if RANDR_12_INTERFACE -typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, - CARD16 width, - CARD16 height, - CARD16 pixWidth, - CARD16 pixHeight, - CARD32 mmWidth, - CARD32 mmHeight); - -typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, - RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - int numOutputs, - RROutputPtr *outputs, - PixmapPtr scanout_pixmap); - -typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, - RRCrtcPtr crtc); - -typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, - RRCrtcPtr crtc); - -typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, - RROutputPtr output, - Atom property, - RRPropertyValuePtr value); - -typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen, - RROutputPtr output, - RRModePtr mode); - -typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, - RRModePtr mode); - -#endif - -#if RANDR_13_INTERFACE -typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen, - RROutputPtr output, - Atom property); -typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn, - RRCrtcPtr crtc, - BoxPtr totalArea, - BoxPtr trackingArea, - INT16 *border); -typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn, - RRCrtcPtr crtc, - BoxPtr totalArea, - BoxPtr trackingArea, - INT16 *border); - -#endif /* RANDR_13_INTERFACE */ - -typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); -typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); - -/* These are for 1.0 compatibility */ - -typedef struct _rrRefresh { - CARD16 rate; - RRModePtr mode; -} RRScreenRate, *RRScreenRatePtr; - -typedef struct _rrScreenSize { - int id; - short width, height; - short mmWidth, mmHeight; - int nRates; - RRScreenRatePtr pRates; -} RRScreenSize, *RRScreenSizePtr; - -#ifdef RANDR_10_INTERFACE - -typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize); - -#endif - -typedef struct { - PictFormatPtr format; - int maxWidth, maxHeight; - int depth; - Rotation rotations; -} RRScanoutPixmapInfo; - -typedef RRScanoutPixmapInfo *(*RRQueryScanoutPixmapsPtr) (ScreenPtr pScreen, - int *num_info); - -typedef PixmapPtr (*RRCreateScanoutPixmapPtr) (ScreenPtr pScreen, - int width, int height, int depth, - Rotation rotations, - PictFormatPtr format); - -typedef void (*RRSetCrtcSpriteTransformPtr) (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - struct pict_f_transform *position_transform, - struct pict_f_transform *image_transform); - -typedef void (*RRGetCrtcSpriteTransformPtr) (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - struct pict_f_transform *position_transform, - struct pict_f_transform *image_transform); - -typedef Bool (*RRSetCrtcConfigsPtr) (ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs); - -typedef struct _rrScrPriv { - /* - * 'public' part of the structure; DDXen fill this in - * as they initialize - */ -#if RANDR_10_INTERFACE - RRSetConfigProcPtr rrSetConfig; -#endif - RRGetInfoProcPtr rrGetInfo; -#if RANDR_12_INTERFACE - RRScreenSetSizeProcPtr rrScreenSetSize; - RRCrtcSetProcPtr rrCrtcSet; - RRCrtcSetGammaProcPtr rrCrtcSetGamma; - RRCrtcGetGammaProcPtr rrCrtcGetGamma; - RROutputSetPropertyProcPtr rrOutputSetProperty; - RROutputValidateModeProcPtr rrOutputValidateMode; - RRModeDestroyProcPtr rrModeDestroy; -#endif -#if RANDR_13_INTERFACE - RROutputGetPropertyProcPtr rrOutputGetProperty; - RRGetPanningProcPtr rrGetPanning; - RRSetPanningProcPtr rrSetPanning; -#endif - RRQueryScanoutPixmapsPtr rrQueryScanoutPixmaps; - RRCreateScanoutPixmapPtr rrCreateScanoutPixmap; - RRSetCrtcSpriteTransformPtr rrSetCrtcSpriteTransform; - RRGetCrtcSpriteTransformPtr rrGetCrtcSpriteTransform; - RRSetCrtcConfigsPtr rrSetCrtcConfigs; - - /* - * Private part of the structure; not considered part of the ABI - */ - TimeStamp lastSetTime; /* last changed by client */ - TimeStamp lastConfigTime; /* possible configs changed */ - RRCloseScreenProcPtr CloseScreen; - - Bool changed; /* some config changed */ - Bool configChanged; /* configuration changed */ - Bool layoutChanged; /* screen layout changed */ - - CARD16 minWidth, minHeight; - CARD16 maxWidth, maxHeight; - CARD16 width, height; /* last known screen size */ - CARD16 mmWidth, mmHeight; /* last known screen size */ - - int numOutputs; - RROutputPtr *outputs; - RROutputPtr primaryOutput; - - int numCrtcs; - RRCrtcPtr *crtcs; - - /* Last known pointer position */ - RRCrtcPtr pointerCrtc; - - RRScanoutPixmapInfo *scanout_info; - int n_scanout_info; -#ifdef RANDR_10_INTERFACE - /* - * Configuration information - */ - Rotation rotations; - CARD16 reqWidth, reqHeight; - - int nSizes; - RRScreenSizePtr pSizes; - - Rotation rotation; - int rate; - int size; -#endif - -} rrScrPrivRec, *rrScrPrivPtr; - -extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec; -#define rrPrivKey (&rrPrivKeyRec) - -#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey)) -#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) -#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p) - -/* - * each window has a list of clients requesting - * RRNotify events. Each client has a resource - * for each window it selects RRNotify input for, - * this resource is used to delete the RRNotifyRec - * entry from the per-window queue. - */ - -typedef struct _RREvent *RREventPtr; - -typedef struct _RREvent { - RREventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; - int mask; -} RREventRec; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -extern _X_EXPORT RESTYPE RRClientType, RREventType; /* resource types for event masks */ -extern _X_EXPORT DevPrivateKeyRec RRClientPrivateKeyRec; -#define RRClientPrivateKey (&RRClientPrivateKeyRec) -extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType; - -#define VERIFY_RR_OUTPUT(id, ptr, a)\ - {\ - int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ - RROutputType, client, a);\ - if (rc != Success) {\ - client->errorValue = id;\ - return rc;\ - }\ - } - -#define VERIFY_RR_CRTC(id, ptr, a)\ - {\ - int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ - RRCrtcType, client, a);\ - if (rc != Success) {\ - client->errorValue = id;\ - return rc;\ - }\ - } - -#define VERIFY_RR_MODE(id, ptr, a)\ - {\ - int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ - RRModeType, client, a);\ - if (rc != Success) {\ - client->errorValue = id;\ - return rc;\ - }\ - } - -#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey)) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -/* Initialize the extension */ -extern _X_EXPORT void -RRExtensionInit (void); - -#ifdef RANDR_12_INTERFACE -/* - * Set the range of sizes for the screen - */ -extern _X_EXPORT void -RRScreenSetSizeRange (ScreenPtr pScreen, - CARD16 minWidth, - CARD16 minHeight, - CARD16 maxWidth, - CARD16 maxHeight); -#endif - -/* rrscreen.c */ -/* - * Notify the extension that the screen size has been changed. - * The driver is responsible for calling this whenever it has changed - * the size of the screen - */ -extern _X_EXPORT void -RRScreenSizeNotify (ScreenPtr pScreen); - -/* - * Request that the screen be resized - */ -extern _X_EXPORT Bool -RRScreenSizeSet (ScreenPtr pScreen, - CARD16 width, - CARD16 height, - CARD16 pixWidth, - CARD16 pixHeight, - CARD32 mmWidth, - CARD32 mmHeight); - -extern _X_EXPORT void -RRScreenCurrentConfig(ScreenPtr screen, - RRScreenConfigPtr screen_config); - -/* - * Send ConfigureNotify event to root window when 'something' happens - */ -extern _X_EXPORT void -RRSendConfigNotify (ScreenPtr pScreen); - -/* - * screen dispatch - */ -extern _X_EXPORT int -ProcRRGetScreenSizeRange (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetScreenSize (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetScreenResources (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetScreenResourcesCurrent (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetScreenConfig (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetScreenInfo (ClientPtr client); - -/* - * Deliver a ScreenNotify event - */ -extern _X_EXPORT void -RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen); - -/* randr.c */ -/* - * Send all pending events - */ -extern _X_EXPORT void -RRTellChanged (ScreenPtr pScreen); - -/* - * Poll the driver for changed information - */ -extern _X_EXPORT Bool -RRGetInfo (ScreenPtr pScreen, Bool force_query); - -extern _X_EXPORT Bool RRInit (void); - -extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen); - -extern _X_EXPORT RROutputPtr -RRFirstOutput (ScreenPtr pScreen); - -extern _X_EXPORT Rotation -RRGetRotation (ScreenPtr pScreen); - -extern _X_EXPORT CARD16 -RRVerticalRefresh (xRRModeInfo *mode); - -extern _X_EXPORT RRScanoutPixmapInfo * -RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info); - -#ifdef RANDR_10_INTERFACE -/* - * This is the old interface, deprecated but left - * around for compatibility - */ - -/* - * Then, register the specific size with the screen - */ - -extern _X_EXPORT RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight); - -extern _X_EXPORT Bool -RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate); - -/* - * Finally, set the current configuration of the screen - */ - -extern _X_EXPORT void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize); - -extern _X_EXPORT Bool RRScreenInit (ScreenPtr pScreen); - -extern _X_EXPORT Rotation -RRGetRotation (ScreenPtr pScreen); - -#endif - -/* rrcrtc.c */ - -/* - * Notify the CRTC of some change; layoutChanged indicates that - * some position or size element changed - */ -extern _X_EXPORT void -RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged); - -/* - * Create a CRTC - */ -extern _X_EXPORT RRCrtcPtr -RRCrtcCreate (ScreenPtr pScreen, void *devPrivate); - -/* - * Set the allowed rotations on a CRTC - */ -extern _X_EXPORT void -RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations); - -/* - * Set whether transforms are allowed on a CRTC - */ -extern _X_EXPORT void -RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms); - -/* - * Notify the extension that the Crtc has been reconfigured, - * the driver calls this whenever it has updated the mode - */ -extern _X_EXPORT Bool -RRCrtcNotify (RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - RRTransformPtr transform, - int numOutputs, - RROutputPtr *outputs, - PixmapPtr scanoutPixmap); - -extern _X_EXPORT void -RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); - -/* - * Request that the Crtc be reconfigured - */ -extern _X_EXPORT Bool -RRCrtcSet (RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - int numOutput, - RROutputPtr *outputs, - PixmapPtr scanout_pixmap); - -/* - * Request that the Crtc gamma be changed - */ - -extern _X_EXPORT Bool -RRCrtcGammaSet (RRCrtcPtr crtc, - CARD16 *red, - CARD16 *green, - CARD16 *blue); - -/* - * Request current gamma back from the DDX (if possible). - * This includes gamma size. - */ - -extern _X_EXPORT Bool -RRCrtcGammaGet(RRCrtcPtr crtc); - -/* - * Notify the extension that the Crtc gamma has been changed - * The driver calls this whenever it has changed the gamma values - * in the RRCrtcRec - */ - -extern _X_EXPORT Bool -RRCrtcGammaNotify (RRCrtcPtr crtc); - -void -RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform, - int *width, int *height); - -/* - * Set the size of the gamma table at server startup time - */ - -extern _X_EXPORT Bool -RRCrtcGammaSetSize (RRCrtcPtr crtc, - int size); - -/* - * Return the area of the frame buffer scanned out by the crtc, - * taking into account the current mode and rotation - */ - -extern _X_EXPORT void -RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); - -/* - * Return crtc transform - */ -extern _X_EXPORT RRTransformPtr -RRCrtcGetTransform (RRCrtcPtr crtc); - -/* - * Check whether the pending and current transforms are the same - */ -extern _X_EXPORT Bool -RRCrtcPendingTransform (RRCrtcPtr crtc); - -/* - * Destroy a Crtc at shutdown - */ -extern _X_EXPORT void -RRCrtcDestroy (RRCrtcPtr crtc); - - -/* - * Set the pending CRTC transformation - */ - -extern _X_EXPORT int -RRCrtcTransformSet (RRCrtcPtr crtc, - PictTransformPtr transform, - struct pict_f_transform *f_transform, - struct pict_f_transform *f_inverse, - char *filter, - int filter_len, - xFixed *params, - int nparams); - -/* - * Initialize crtc type - */ -extern _X_EXPORT Bool -RRCrtcInit (void); - -/* - * Initialize crtc type error value - */ -extern _X_EXPORT void -RRCrtcInitErrorValue (void); - -/* - * Free a set of crtc configs and their attached output arrays - */ -void -RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs); - -/* - * Convert the current crtc configuration into an RRCrtcConfig - */ -extern _X_EXPORT Bool -RRCrtcCurrentConfig(RRCrtcPtr crtc, - RRCrtcConfigPtr crtc_config); - -/* - * Figure out whether the specific crtc_config can fit - * within the screen_config - */ -Bool -RRScreenCoversCrtc(RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_config, - RRTransformPtr client_transform, - XID *errorValue); - -/* - * Set a screen and set of crtc configurations in one operation - */ -Bool -RRSetCrtcConfigs(ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs); - -/* - * Crtc dispatch - */ - -extern _X_EXPORT int -ProcRRGetCrtcInfo (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetCrtcConfig (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetCrtcGammaSize (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetCrtcGamma (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetCrtcGamma (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetCrtcTransform (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetCrtcTransform (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetCrtcConfigs (ClientPtr client); - -int -ProcRRGetPanning (ClientPtr client); - -int -ProcRRSetPanning (ClientPtr client); - -void -RRCrtcSpriteTransformSet(RRCrtcPtr crtc, - PictTransform *position_transform, - PictTransform *image_transform, - struct pict_f_transform *f_position_transform, - struct pict_f_transform *f_image_transform); - -int -ProcRRQueryScanoutPixmaps (ClientPtr client); - -int -ProcRRCreateScanoutPixmap (ClientPtr client); - -int -ProcRRSetCrtcPixmapConfig (ClientPtr client); - -int -ProcRRSetCrtcSpriteTransform (ClientPtr client); - -int -ProcRRGetCrtcSpriteTransform (ClientPtr client); - -int -ProcRRSetCrtcConfigs (ClientPtr client); - -/* rrdispatch.c */ -extern _X_EXPORT Bool -RRClientKnowsRates (ClientPtr pClient); - -/* rrmode.c */ -/* - * Find, and if necessary, create a mode - */ - -extern _X_EXPORT RRModePtr -RRModeGet (xRRModeInfo *modeInfo, - const char *name); - -/* - * Destroy a mode. - */ - -extern _X_EXPORT void -RRModeDestroy (RRModePtr mode); - -/* - * Return a list of modes that are valid for some output in pScreen - */ -extern _X_EXPORT RRModePtr * -RRModesForScreen (ScreenPtr pScreen, int *num_ret); - -/* - * Initialize mode type - */ -extern _X_EXPORT Bool -RRModeInit (void); - -/* - * Initialize mode type error value - */ -extern _X_EXPORT void -RRModeInitErrorValue (void); - -extern _X_EXPORT int -ProcRRCreateMode (ClientPtr client); - -extern _X_EXPORT int -ProcRRDestroyMode (ClientPtr client); - -extern _X_EXPORT int -ProcRRAddOutputMode (ClientPtr client); - -extern _X_EXPORT int -ProcRRDeleteOutputMode (ClientPtr client); - -/* rroutput.c */ - -/* - * Notify the output of some change. configChanged indicates whether - * any external configuration (mode list, clones, connected status) - * has changed, or whether the change was strictly internal - * (which crtc is in use) - */ -extern _X_EXPORT void -RROutputChanged (RROutputPtr output, Bool configChanged); - -/* - * Create an output - */ - -extern _X_EXPORT RROutputPtr -RROutputCreate (ScreenPtr pScreen, - const char *name, - int nameLength, - void *devPrivate); - -/* - * Notify extension that output parameters have been changed - */ -extern _X_EXPORT Bool -RROutputSetClones (RROutputPtr output, - RROutputPtr *clones, - int numClones); - -extern _X_EXPORT Bool -RROutputSetModes (RROutputPtr output, - RRModePtr *modes, - int numModes, - int numPreferred); - -extern _X_EXPORT int -RROutputAddUserMode (RROutputPtr output, - RRModePtr mode); - -extern _X_EXPORT int -RROutputDeleteUserMode (RROutputPtr output, - RRModePtr mode); - -extern _X_EXPORT Bool -RROutputSetCrtcs (RROutputPtr output, - RRCrtcPtr *crtcs, - int numCrtcs); - -extern _X_EXPORT Bool -RROutputSetConnection (RROutputPtr output, - CARD8 connection); - -extern _X_EXPORT Bool -RROutputSetSubpixelOrder (RROutputPtr output, - int subpixelOrder); - -extern _X_EXPORT Bool -RROutputSetPhysicalSize (RROutputPtr output, - int mmWidth, - int mmHeight); - -extern _X_EXPORT void -RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); - -extern _X_EXPORT void -RROutputDestroy (RROutputPtr output); - -extern _X_EXPORT int -ProcRRGetOutputInfo (ClientPtr client); - -extern _X_EXPORT int -ProcRRSetOutputPrimary (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetOutputPrimary (ClientPtr client); - -/* - * Initialize output type - */ -extern _X_EXPORT Bool -RROutputInit (void); - -/* - * Initialize output type error value - */ -extern _X_EXPORT void -RROutputInitErrorValue (void); - -/* rrpointer.c */ -extern _X_EXPORT void -RRPointerMoved (ScreenPtr pScreen, int x, int y); - -extern _X_EXPORT void -RRPointerScreenConfigured (ScreenPtr pScreen); - -/* rrproperty.c */ - -extern _X_EXPORT void -RRDeleteAllOutputProperties (RROutputPtr output); - -extern _X_EXPORT RRPropertyValuePtr -RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending); - -extern _X_EXPORT RRPropertyPtr -RRQueryOutputProperty (RROutputPtr output, Atom property); - -extern _X_EXPORT void -RRDeleteOutputProperty (RROutputPtr output, Atom property); - -extern _X_EXPORT Bool -RRPostPendingProperties (RROutputPtr output); - -extern _X_EXPORT int -RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, - int format, int mode, unsigned long len, - pointer value, Bool sendevent, Bool pending); - -extern _X_EXPORT int -RRConfigureOutputProperty (RROutputPtr output, Atom property, - Bool pending, Bool range, Bool immutable, - int num_values, INT32 *values); -extern _X_EXPORT int -ProcRRChangeOutputProperty (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetOutputProperty (ClientPtr client); - -extern _X_EXPORT int -ProcRRListOutputProperties (ClientPtr client); - -extern _X_EXPORT int -ProcRRQueryOutputProperty (ClientPtr client); - -extern _X_EXPORT int -ProcRRConfigureOutputProperty (ClientPtr client); - -extern _X_EXPORT int -ProcRRDeleteOutputProperty (ClientPtr client); - -/* rrsprite.c */ -extern _X_EXPORT int -ProcRRSetCrtcSpriteTransform (ClientPtr client); - -extern _X_EXPORT int -ProcRRGetCrtcSpriteTransform (ClientPtr client); - -/* rrxinerama.c */ -#ifdef XINERAMA -extern _X_EXPORT void -RRXineramaExtensionInit(void); -#endif - -/* mirrcrtc.c */ -Bool -miRRSetScreenConfig(ScreenPtr screen, - RRScreenConfigPtr screen_config); - -Bool -miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config); - -Bool -miRRDisableCrtc(RRCrtcPtr crtc); - -Bool -miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config, - RRCrtcConfigPtr old_crtc_config); - -Bool -miRRSetCrtcConfigs(ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs); - -#endif /* _RANDRSTR_H_ */ - -/* - -randr extension implementation structure - -Query state: - ProcRRGetScreenInfo/ProcRRGetScreenResources - RRGetInfo - - • Request configuration from driver, either 1.0 or 1.2 style - • These functions only record state changes, all - other actions are pended until RRTellChanged is called - - ->rrGetInfo - 1.0: - RRRegisterSize - RRRegisterRate - RRSetCurrentConfig - 1.2: - RRScreenSetSizeRange - RROutputSetCrtcs - RRModeGet - RROutputSetModes - RROutputSetConnection - RROutputSetSubpixelOrder - RROutputSetClones - RRCrtcNotify - - • Must delay scanning configuration until after ->rrGetInfo returns - because some drivers will call SetCurrentConfig in the middle - of the ->rrGetInfo operation. - - 1.0: - - • Scan old configuration, mirror to new structures - - RRScanOldConfig - RRCrtcCreate - RROutputCreate - RROutputSetCrtcs - RROutputSetConnection - RROutputSetSubpixelOrder - RROldModeAdd • This adds modes one-at-a-time - RRModeGet - RRCrtcNotify - - • send events, reset pointer if necessary - - RRTellChanged - WalkTree (sending events) - - • when layout has changed: - RRPointerScreenConfigured - RRSendConfigNotify - -Asynchronous state setting (1.2 only) - When setting state asynchronously, the driver invokes the - ->rrGetInfo function and then calls RRTellChanged to flush - the changes to the clients and reset pointer if necessary - -Set state - - ProcRRSetScreenConfig - RRCrtcSet - 1.2: - ->rrCrtcSet - RRCrtcNotify - 1.0: - ->rrSetConfig - RRCrtcNotify - RRTellChanged - */ +/* + * Copyright © 2000 Compaq Computer Corporation + * Copyright © 2002 Hewlett-Packard Company + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * 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, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifndef _RANDRSTR_H_ +#define _RANDRSTR_H_ + +#include +#include +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "servermd.h" +#include "rrtransform.h" +#include +#include +#include /* we share subpixel order information */ +#include "picturestr.h" +#include + +/* required for ABI compatibility for now */ +#define RANDR_10_INTERFACE 1 +#define RANDR_12_INTERFACE 1 +#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ +#define RANDR_GET_CRTC_INTERFACE 1 + +#define RANDR_INTERFACE_VERSION 0x0103 + +typedef XID RRMode; +typedef XID RROutput; +typedef XID RRCrtc; + +extern _X_EXPORT int RREventBase, RRErrorBase; + +extern _X_EXPORT int (*ProcRandrVector[RRNumberRequests])(ClientPtr); +extern _X_EXPORT int (*SProcRandrVector[RRNumberRequests])(ClientPtr); + +/* + * Modeline for a monitor. Name follows directly after this struct + */ + +#define RRModeName(pMode) ((char *) (pMode + 1)) +typedef struct _rrMode RRModeRec, *RRModePtr; +typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr; +typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr; +typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; +typedef struct _rrOutput RROutputRec, *RROutputPtr; + +struct _rrMode { + int refcnt; + xRRModeInfo mode; + char *name; + ScreenPtr userScreen; +}; + +struct _rrPropertyValue { + Atom type; /* ignored by server */ + short format; /* format of data for swapping - 8,16,32 */ + long size; /* size of data in (format/8) bytes */ + pointer data; /* private to client */ +}; + +struct _rrProperty { + RRPropertyPtr next; + ATOM propertyName; + Bool is_pending; + Bool range; + Bool immutable; + int num_valid; + INT32 *valid_values; + RRPropertyValueRec current, pending; +}; + +struct _rrCrtc { + RRCrtc id; + ScreenPtr pScreen; + RRModePtr mode; + int x, y; + Rotation rotation; + Rotation rotations; + Bool changed; + int numOutputs; + RROutputPtr *outputs; + int gammaSize; + CARD16 *gammaRed; + CARD16 *gammaBlue; + CARD16 *gammaGreen; + void *devPrivate; + Bool transforms; + RRTransformRec client_pending_transform; + RRTransformRec client_current_transform; + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; +}; + +struct _rrOutput { + RROutput id; + ScreenPtr pScreen; + char *name; + int nameLength; + CARD8 connection; + CARD8 subpixelOrder; + int mmWidth; + int mmHeight; + RRCrtcPtr crtc; + int numCrtcs; + RRCrtcPtr *crtcs; + int numClones; + RROutputPtr *clones; + int numModes; + int numPreferred; + RRModePtr *modes; + int numUserModes; + RRModePtr *userModes; + Bool changed; + RRPropertyPtr properties; + Bool pendingProperties; + void *devPrivate; +}; + +#if RANDR_12_INTERFACE +typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs); + +typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc); + +typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc); + +typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property, + RRPropertyValuePtr value); + +typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + RRModePtr mode); + +typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, + RRModePtr mode); + +#endif + +#if RANDR_13_INTERFACE +typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property); +typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn, + RRCrtcPtr crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border); +typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn, + RRCrtcPtr crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border); + +#endif /* RANDR_13_INTERFACE */ + +typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); +typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); + +/* These are for 1.0 compatibility */ + +typedef struct _rrRefresh { + CARD16 rate; + RRModePtr mode; +} RRScreenRate, *RRScreenRatePtr; + +typedef struct _rrScreenSize { + int id; + short width, height; + short mmWidth, mmHeight; + int nRates; + RRScreenRatePtr pRates; +} RRScreenSize, *RRScreenSizePtr; + +#ifdef RANDR_10_INTERFACE + +typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize); + +#endif + + +typedef struct _rrScrPriv { + /* + * 'public' part of the structure; DDXen fill this in + * as they initialize + */ +#if RANDR_10_INTERFACE + RRSetConfigProcPtr rrSetConfig; +#endif + RRGetInfoProcPtr rrGetInfo; +#if RANDR_12_INTERFACE + RRScreenSetSizeProcPtr rrScreenSetSize; + RRCrtcSetProcPtr rrCrtcSet; + RRCrtcSetGammaProcPtr rrCrtcSetGamma; + RRCrtcGetGammaProcPtr rrCrtcGetGamma; + RROutputSetPropertyProcPtr rrOutputSetProperty; + RROutputValidateModeProcPtr rrOutputValidateMode; + RRModeDestroyProcPtr rrModeDestroy; +#endif +#if RANDR_13_INTERFACE + RROutputGetPropertyProcPtr rrOutputGetProperty; + RRGetPanningProcPtr rrGetPanning; + RRSetPanningProcPtr rrSetPanning; +#endif + + /* + * Private part of the structure; not considered part of the ABI + */ + TimeStamp lastSetTime; /* last changed by client */ + TimeStamp lastConfigTime; /* possible configs changed */ + RRCloseScreenProcPtr CloseScreen; + + Bool changed; /* some config changed */ + Bool configChanged; /* configuration changed */ + Bool layoutChanged; /* screen layout changed */ + + CARD16 minWidth, minHeight; + CARD16 maxWidth, maxHeight; + CARD16 width, height; /* last known screen size */ + CARD16 mmWidth, mmHeight; /* last known screen size */ + + int numOutputs; + RROutputPtr *outputs; + RROutputPtr primaryOutput; + + int numCrtcs; + RRCrtcPtr *crtcs; + + /* Last known pointer position */ + RRCrtcPtr pointerCrtc; + +#ifdef RANDR_10_INTERFACE + /* + * Configuration information + */ + Rotation rotations; + CARD16 reqWidth, reqHeight; + + int nSizes; + RRScreenSizePtr pSizes; + + Rotation rotation; + int rate; + int size; +#endif +} rrScrPrivRec, *rrScrPrivPtr; + +extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec; +#define rrPrivKey (&rrPrivKeyRec) + +#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey)) +#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) +#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p) + +/* + * each window has a list of clients requesting + * RRNotify events. Each client has a resource + * for each window it selects RRNotify input for, + * this resource is used to delete the RRNotifyRec + * entry from the per-window queue. + */ + +typedef struct _RREvent *RREventPtr; + +typedef struct _RREvent { + RREventPtr next; + ClientPtr client; + WindowPtr window; + XID clientResource; + int mask; +} RREventRec; + +typedef struct _RRTimes { + TimeStamp setTime; + TimeStamp configTime; +} RRTimesRec, *RRTimesPtr; + +typedef struct _RRClient { + int major_version; + int minor_version; +/* RRTimesRec times[0]; */ +} RRClientRec, *RRClientPtr; + +extern _X_EXPORT RESTYPE RRClientType, RREventType; /* resource types for event masks */ +extern _X_EXPORT DevPrivateKeyRec RRClientPrivateKeyRec; +#define RRClientPrivateKey (&RRClientPrivateKeyRec) +extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType; + +#define VERIFY_RR_OUTPUT(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ + RROutputType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define VERIFY_RR_CRTC(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ + RRCrtcType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define VERIFY_RR_MODE(id, ptr, a)\ + {\ + int rc = dixLookupResourceByType((pointer *)&(ptr), id,\ + RRModeType, client, a);\ + if (rc != Success) {\ + client->errorValue = id;\ + return rc;\ + }\ + } + +#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey)) +#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) + +/* Initialize the extension */ +extern _X_EXPORT void +RRExtensionInit (void); + +#ifdef RANDR_12_INTERFACE +/* + * Set the range of sizes for the screen + */ +extern _X_EXPORT void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight); +#endif + +/* rrscreen.c */ +/* + * Notify the extension that the screen size has been changed. + * The driver is responsible for calling this whenever it has changed + * the size of the screen + */ +extern _X_EXPORT void +RRScreenSizeNotify (ScreenPtr pScreen); + +/* + * Request that the screen be resized + */ +extern _X_EXPORT Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +/* + * Send ConfigureNotify event to root window when 'something' happens + */ +extern _X_EXPORT void +RRSendConfigNotify (ScreenPtr pScreen); + +/* + * screen dispatch + */ +extern _X_EXPORT int +ProcRRGetScreenSizeRange (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetScreenSize (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetScreenResources (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetScreenResourcesCurrent (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetScreenConfig (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetScreenInfo (ClientPtr client); + +/* + * Deliver a ScreenNotify event + */ +extern _X_EXPORT void +RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen); + +/* randr.c */ +/* + * Send all pending events + */ +extern _X_EXPORT void +RRTellChanged (ScreenPtr pScreen); + +/* + * Poll the driver for changed information + */ +extern _X_EXPORT Bool +RRGetInfo (ScreenPtr pScreen, Bool force_query); + +extern _X_EXPORT Bool RRInit (void); + +extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen); + +extern _X_EXPORT RROutputPtr +RRFirstOutput (ScreenPtr pScreen); + +extern _X_EXPORT Rotation +RRGetRotation (ScreenPtr pScreen); + +extern _X_EXPORT CARD16 +RRVerticalRefresh (xRRModeInfo *mode); + +#ifdef RANDR_10_INTERFACE +/* + * This is the old interface, deprecated but left + * around for compatibility + */ + +/* + * Then, register the specific size with the screen + */ + +extern _X_EXPORT RRScreenSizePtr +RRRegisterSize (ScreenPtr pScreen, + short width, + short height, + short mmWidth, + short mmHeight); + +extern _X_EXPORT Bool +RRRegisterRate (ScreenPtr pScreen, + RRScreenSizePtr pSize, + int rate); + +/* + * Finally, set the current configuration of the screen + */ + +extern _X_EXPORT void +RRSetCurrentConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize); + +extern _X_EXPORT Bool RRScreenInit (ScreenPtr pScreen); + +extern _X_EXPORT Rotation +RRGetRotation (ScreenPtr pScreen); + +#endif + +/* rrcrtc.c */ + +/* + * Notify the CRTC of some change; layoutChanged indicates that + * some position or size element changed + */ +extern _X_EXPORT void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged); + +/* + * Create a CRTC + */ +extern _X_EXPORT RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate); + +/* + * Set the allowed rotations on a CRTC + */ +extern _X_EXPORT void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations); + +/* + * Set whether transforms are allowed on a CRTC + */ +extern _X_EXPORT void +RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms); + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ +extern _X_EXPORT Bool +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + RRTransformPtr transform, + int numOutputs, + RROutputPtr *outputs); + +extern _X_EXPORT void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); + +/* + * Request that the Crtc be reconfigured + */ +extern _X_EXPORT Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutput, + RROutputPtr *outputs); + +/* + * Request that the Crtc gamma be changed + */ + +extern _X_EXPORT Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue); + +/* + * Request current gamma back from the DDX (if possible). + * This includes gamma size. + */ + +extern _X_EXPORT Bool +RRCrtcGammaGet(RRCrtcPtr crtc); + +/* + * Notify the extension that the Crtc gamma has been changed + * The driver calls this whenever it has changed the gamma values + * in the RRCrtcRec + */ + +extern _X_EXPORT Bool +RRCrtcGammaNotify (RRCrtcPtr crtc); + +/* + * Set the size of the gamma table at server startup time + */ + +extern _X_EXPORT Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size); + +/* + * Return the area of the frame buffer scanned out by the crtc, + * taking into account the current mode and rotation + */ + +extern _X_EXPORT void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +extern _X_EXPORT Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse); + +/* + * Return crtc transform + */ +extern _X_EXPORT RRTransformPtr +RRCrtcGetTransform (RRCrtcPtr crtc); + +/* + * Check whether the pending and current transforms are the same + */ +extern _X_EXPORT Bool +RRCrtcPendingTransform (RRCrtcPtr crtc); + +/* + * Destroy a Crtc at shutdown + */ +extern _X_EXPORT void +RRCrtcDestroy (RRCrtcPtr crtc); + + +/* + * Set the pending CRTC transformation + */ + +extern _X_EXPORT int +RRCrtcTransformSet (RRCrtcPtr crtc, + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse, + char *filter, + int filter_len, + xFixed *params, + int nparams); + +/* + * Initialize crtc type + */ +extern _X_EXPORT Bool +RRCrtcInit (void); + +/* + * Initialize crtc type error value + */ +extern _X_EXPORT void +RRCrtcInitErrorValue (void); + +/* + * Crtc dispatch + */ + +extern _X_EXPORT int +ProcRRGetCrtcInfo (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetCrtcConfig (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetCrtcGammaSize (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetCrtcGamma (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetCrtcGamma (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetCrtcTransform (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetCrtcTransform (ClientPtr client); + +int +ProcRRGetPanning (ClientPtr client); + +int +ProcRRSetPanning (ClientPtr client); + +/* rrdispatch.c */ +extern _X_EXPORT Bool +RRClientKnowsRates (ClientPtr pClient); + +/* rrmode.c */ +/* + * Find, and if necessary, create a mode + */ + +extern _X_EXPORT RRModePtr +RRModeGet (xRRModeInfo *modeInfo, + const char *name); + +/* + * Destroy a mode. + */ + +extern _X_EXPORT void +RRModeDestroy (RRModePtr mode); + +/* + * Return a list of modes that are valid for some output in pScreen + */ +extern _X_EXPORT RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret); + +/* + * Initialize mode type + */ +extern _X_EXPORT Bool +RRModeInit (void); + +/* + * Initialize mode type error value + */ +extern _X_EXPORT void +RRModeInitErrorValue (void); + +extern _X_EXPORT int +ProcRRCreateMode (ClientPtr client); + +extern _X_EXPORT int +ProcRRDestroyMode (ClientPtr client); + +extern _X_EXPORT int +ProcRRAddOutputMode (ClientPtr client); + +extern _X_EXPORT int +ProcRRDeleteOutputMode (ClientPtr client); + +/* rroutput.c */ + +/* + * Notify the output of some change. configChanged indicates whether + * any external configuration (mode list, clones, connected status) + * has changed, or whether the change was strictly internal + * (which crtc is in use) + */ +extern _X_EXPORT void +RROutputChanged (RROutputPtr output, Bool configChanged); + +/* + * Create an output + */ + +extern _X_EXPORT RROutputPtr +RROutputCreate (ScreenPtr pScreen, + const char *name, + int nameLength, + void *devPrivate); + +/* + * Notify extension that output parameters have been changed + */ +extern _X_EXPORT Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones); + +extern _X_EXPORT Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes, + int numPreferred); + +extern _X_EXPORT int +RROutputAddUserMode (RROutputPtr output, + RRModePtr mode); + +extern _X_EXPORT int +RROutputDeleteUserMode (RROutputPtr output, + RRModePtr mode); + +extern _X_EXPORT Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs); + +extern _X_EXPORT Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection); + +extern _X_EXPORT Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder); + +extern _X_EXPORT Bool +RROutputSetPhysicalSize (RROutputPtr output, + int mmWidth, + int mmHeight); + +extern _X_EXPORT void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); + +extern _X_EXPORT void +RROutputDestroy (RROutputPtr output); + +extern _X_EXPORT int +ProcRRGetOutputInfo (ClientPtr client); + +extern _X_EXPORT int +ProcRRSetOutputPrimary (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetOutputPrimary (ClientPtr client); + +/* + * Initialize output type + */ +extern _X_EXPORT Bool +RROutputInit (void); + +/* + * Initialize output type error value + */ +extern _X_EXPORT void +RROutputInitErrorValue (void); + +/* rrpointer.c */ +extern _X_EXPORT void +RRPointerMoved (ScreenPtr pScreen, int x, int y); + +extern _X_EXPORT void +RRPointerScreenConfigured (ScreenPtr pScreen); + +/* rrproperty.c */ + +extern _X_EXPORT void +RRDeleteAllOutputProperties (RROutputPtr output); + +extern _X_EXPORT RRPropertyValuePtr +RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending); + +extern _X_EXPORT RRPropertyPtr +RRQueryOutputProperty (RROutputPtr output, Atom property); + +extern _X_EXPORT void +RRDeleteOutputProperty (RROutputPtr output, Atom property); + +extern _X_EXPORT Bool +RRPostPendingProperties (RROutputPtr output); + +extern _X_EXPORT int +RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, + int format, int mode, unsigned long len, + pointer value, Bool sendevent, Bool pending); + +extern _X_EXPORT int +RRConfigureOutputProperty (RROutputPtr output, Atom property, + Bool pending, Bool range, Bool immutable, + int num_values, INT32 *values); +extern _X_EXPORT int +ProcRRChangeOutputProperty (ClientPtr client); + +extern _X_EXPORT int +ProcRRGetOutputProperty (ClientPtr client); + +extern _X_EXPORT int +ProcRRListOutputProperties (ClientPtr client); + +extern _X_EXPORT int +ProcRRQueryOutputProperty (ClientPtr client); + +extern _X_EXPORT int +ProcRRConfigureOutputProperty (ClientPtr client); + +extern _X_EXPORT int +ProcRRDeleteOutputProperty (ClientPtr client); + +/* rrxinerama.c */ +#ifdef XINERAMA +extern _X_EXPORT void +RRXineramaExtensionInit(void); +#endif + +#endif /* _RANDRSTR_H_ */ + +/* + +randr extension implementation structure + +Query state: + ProcRRGetScreenInfo/ProcRRGetScreenResources + RRGetInfo + + • Request configuration from driver, either 1.0 or 1.2 style + • These functions only record state changes, all + other actions are pended until RRTellChanged is called + + ->rrGetInfo + 1.0: + RRRegisterSize + RRRegisterRate + RRSetCurrentConfig + 1.2: + RRScreenSetSizeRange + RROutputSetCrtcs + RRModeGet + RROutputSetModes + RROutputSetConnection + RROutputSetSubpixelOrder + RROutputSetClones + RRCrtcNotify + + • Must delay scanning configuration until after ->rrGetInfo returns + because some drivers will call SetCurrentConfig in the middle + of the ->rrGetInfo operation. + + 1.0: + + • Scan old configuration, mirror to new structures + + RRScanOldConfig + RRCrtcCreate + RROutputCreate + RROutputSetCrtcs + RROutputSetConnection + RROutputSetSubpixelOrder + RROldModeAdd • This adds modes one-at-a-time + RRModeGet + RRCrtcNotify + + • send events, reset pointer if necessary + + RRTellChanged + WalkTree (sending events) + + • when layout has changed: + RRPointerScreenConfigured + RRSendConfigNotify + +Asynchronous state setting (1.2 only) + When setting state asynchronously, the driver invokes the + ->rrGetInfo function and then calls RRTellChanged to flush + the changes to the clients and reset pointer if necessary + +Set state + + ProcRRSetScreenConfig + RRCrtcSet + 1.2: + ->rrCrtcSet + RRCrtcNotify + 1.0: + ->rrSetConfig + RRCrtcNotify + RRTellChanged + */ diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index 524fcd266..98206a2b9 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -1,1799 +1,1351 @@ -/* - * 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. - */ - -#include "randrstr.h" -#include "swaprep.h" - -RESTYPE RRCrtcType; - -/* - * Notify the CRTC of some change - */ -void -RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) -{ - ScreenPtr pScreen = crtc->pScreen; - - crtc->changed = TRUE; - if (pScreen) - { - rrScrPriv(pScreen); - - pScrPriv->changed = TRUE; - /* - * Send ConfigureNotify on any layout change - */ - if (layoutChanged) - pScrPriv->layoutChanged = TRUE; - } -} - -/* - * Create a CRTC - */ -RRCrtcPtr -RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) -{ - RRCrtcPtr crtc; - RRCrtcPtr *crtcs; - rrScrPrivPtr pScrPriv; - - if (!RRInit()) - return NULL; - - pScrPriv = rrGetScrPriv(pScreen); - - /* make space for the crtc pointer */ - if (pScrPriv->numCrtcs) - crtcs = realloc(pScrPriv->crtcs, - (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); - else - crtcs = malloc(sizeof (RRCrtcPtr)); - if (!crtcs) - return FALSE; - pScrPriv->crtcs = crtcs; - - crtc = calloc(1, sizeof (RRCrtcRec)); - if (!crtc) - return NULL; - crtc->id = FakeClientID (0); - crtc->pScreen = pScreen; - crtc->mode = NULL; - crtc->x = 0; - crtc->y = 0; - crtc->rotation = RR_Rotate_0; - crtc->rotations = RR_Rotate_0; - crtc->outputs = NULL; - crtc->numOutputs = 0; - crtc->gammaSize = 0; - crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; - crtc->changed = FALSE; - crtc->devPrivate = devPrivate; - RRTransformInit (&crtc->client_pending_transform); - RRTransformInit (&crtc->client_current_transform); - pixman_transform_init_identity (&crtc->client_sprite_position_transform); - pixman_transform_init_identity (&crtc->client_sprite_image_transform); - pixman_transform_init_identity (&crtc->transform); - pixman_f_transform_init_identity (&crtc->f_transform); - pixman_f_transform_init_identity (&crtc->f_inverse); - pixman_f_transform_init_identity (&crtc->f_sprite_position); - pixman_f_transform_init_identity (&crtc->f_sprite_image_inverse); - - if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) - return NULL; - - /* attach the screen and crtc together */ - crtc->pScreen = pScreen; - pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; - - return crtc; -} - -/* - * Set the allowed rotations on a CRTC - */ -void -RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) -{ - crtc->rotations = rotations; -} - -/* - * Set whether transforms are allowed on a CRTC - */ -void -RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms) -{ - crtc->transforms = transforms; -} - -/* - * Notify the extension that the Crtc has been reconfigured, - * the driver calls this whenever it has updated the mode - */ -Bool -RRCrtcNotify (RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - RRTransformPtr transform, - int numOutputs, - RROutputPtr *outputs, - PixmapPtr scanoutPixmap) -{ - int i, j; - - /* - * Check to see if any of the new outputs were - * not in the old list and mark them as changed - */ - for (i = 0; i < numOutputs; i++) - { - for (j = 0; j < crtc->numOutputs; j++) - if (outputs[i] == crtc->outputs[j]) - break; - if (j == crtc->numOutputs) - { - outputs[i]->crtc = crtc; - RROutputChanged (outputs[i], FALSE); - RRCrtcChanged (crtc, FALSE); - } - } - /* - * Check to see if any of the old outputs are - * not in the new list and mark them as changed - */ - for (j = 0; j < crtc->numOutputs; j++) - { - for (i = 0; i < numOutputs; i++) - if (outputs[i] == crtc->outputs[j]) - break; - if (i == numOutputs) - { - if (crtc->outputs[j]->crtc == crtc) - crtc->outputs[j]->crtc = NULL; - RROutputChanged (crtc->outputs[j], FALSE); - RRCrtcChanged (crtc, FALSE); - } - } - /* - * Reallocate the crtc output array if necessary - */ - if (numOutputs != crtc->numOutputs) - { - RROutputPtr *newoutputs; - - if (numOutputs) - { - if (crtc->numOutputs) - newoutputs = realloc(crtc->outputs, - numOutputs * sizeof (RROutputPtr)); - else - newoutputs = malloc(numOutputs * sizeof (RROutputPtr)); - if (!newoutputs) - return FALSE; - } - else - { - free(crtc->outputs); - newoutputs = NULL; - } - crtc->outputs = newoutputs; - crtc->numOutputs = numOutputs; - } - /* - * Copy the new list of outputs into the crtc - */ - memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)); - /* - * Update remaining crtc fields - */ - if (mode != crtc->mode) - { - if (crtc->mode) - RRModeDestroy (crtc->mode); - crtc->mode = mode; - if (mode != NULL) - mode->refcnt++; - RRCrtcChanged (crtc, TRUE); - } - if (x != crtc->x) - { - crtc->x = x; - RRCrtcChanged (crtc, TRUE); - } - if (y != crtc->y) - { - crtc->y = y; - RRCrtcChanged (crtc, TRUE); - } - if (rotation != crtc->rotation) - { - crtc->rotation = rotation; - RRCrtcChanged (crtc, TRUE); - } - if (!RRTransformEqual (transform, &crtc->client_current_transform)) { - RRTransformCopy (&crtc->client_current_transform, transform); - RRCrtcChanged (crtc, TRUE); - } - - if (scanoutPixmap != crtc->scanoutPixmap) - { - if (scanoutPixmap) - ++scanoutPixmap->refcnt; - if (crtc->scanoutPixmap) - (*crtc->scanoutPixmap->drawable.pScreen->DestroyPixmap) (crtc->scanoutPixmap); - crtc->scanoutPixmap = scanoutPixmap; - } - - if (crtc->changed && mode) - { - RRTransformCompute (x, y, - mode->mode.width, mode->mode.height, - rotation, - &crtc->client_current_transform, - &crtc->client_sprite_f_position_transform, - &crtc->client_sprite_f_image_transform, - &crtc->transform, &crtc->f_transform, - &crtc->f_inverse, &crtc->f_sprite_position, - &crtc->f_sprite_image_inverse, - NULL); - } - - return TRUE; -} - -void -RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - xRRCrtcChangeNotifyEvent ce; - RRModePtr mode = crtc->mode; - - ce.type = RRNotify + RREventBase; - ce.subCode = RRNotify_CrtcChange; - ce.timestamp = pScrPriv->lastSetTime.milliseconds; - ce.window = pWin->drawable.id; - ce.crtc = crtc->id; - ce.rotation = crtc->rotation; - if (mode) - { - ce.mode = mode->mode.id; - ce.x = crtc->x; - ce.y = crtc->y; - ce.width = mode->mode.width; - ce.height = mode->mode.height; - } - else - { - ce.mode = None; - ce.x = 0; - ce.y = 0; - ce.width = 0; - ce.height = 0; - } - WriteEventsToClient (client, 1, (xEvent *) &ce); -} - -static Bool -RRCrtcPendingProperties (RRCrtcPtr crtc) -{ - ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(pScreen); - int o; - - for (o = 0; o < pScrPriv->numOutputs; o++) - { - RROutputPtr output = pScrPriv->outputs[o]; - if (output->crtc == crtc && output->pendingProperties) - return TRUE; - } - return FALSE; -} - -/* - * Request that the Crtc be reconfigured - */ -Bool -RRCrtcSet (RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - int numOutputs, - RROutputPtr *outputs, - PixmapPtr scanout_pixmap) -{ - ScreenPtr pScreen = crtc->pScreen; - Bool ret = FALSE; - rrScrPriv(pScreen); - - /* See if nothing changed */ - if (crtc->mode == mode && - crtc->x == x && - crtc->y == y && - crtc->rotation == rotation && - crtc->numOutputs == numOutputs && - !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && - !RRCrtcPendingProperties (crtc) && - !RRCrtcPendingTransform (crtc) && - crtc->scanoutPixmap == scanout_pixmap) - { - ret = TRUE; - } - else - { -#if RANDR_12_INTERFACE - if (pScrPriv->rrCrtcSet) - { - ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, - rotation, numOutputs, outputs, scanout_pixmap); - } - else -#endif - { -#if RANDR_10_INTERFACE - if (pScrPriv->rrSetConfig) - { - RRScreenSize size; - RRScreenRate rate; - - if (!mode) - { - RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL, scanout_pixmap); - ret = TRUE; - } - else - { - size.width = mode->mode.width; - size.height = mode->mode.height; - if (outputs[0]->mmWidth && outputs[0]->mmHeight) - { - size.mmWidth = outputs[0]->mmWidth; - size.mmHeight = outputs[0]->mmHeight; - } - else - { - size.mmWidth = pScreen->mmWidth; - size.mmHeight = pScreen->mmHeight; - } - size.nRates = 1; - rate.rate = RRVerticalRefresh (&mode->mode); - size.pRates = &rate; - ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); - /* - * Old 1.0 interface tied screen size to mode size - */ - if (ret) - { - RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs, scanout_pixmap); - RRScreenSizeNotify (pScreen); - } - } - } -#endif - } - if (ret) - { - int o; - RRTellChanged (pScreen); - - for (o = 0; o < numOutputs; o++) - RRPostPendingProperties (outputs[o]); - } - } - return ret; -} - -void -RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs) -{ - int i; - - for (i = 0; i < num_configs; i++) - free(configs[i].outputs); - free(configs); -} - -Bool -RRCrtcCurrentConfig(RRCrtcPtr crtc, - RRCrtcConfigPtr crtc_config) -{ - crtc_config->crtc = crtc; - crtc_config->x = crtc->x; - crtc_config->y = crtc->y; - crtc_config->mode = crtc->mode; - crtc_config->rotation = crtc->rotation; - crtc_config->numOutputs = crtc->numOutputs; - crtc_config->outputs = calloc(crtc->numOutputs, sizeof (RROutputPtr)); - if (!crtc_config->outputs) - return FALSE; - memcpy(crtc_config->outputs, crtc->outputs, crtc->numOutputs * sizeof (RROutputPtr)); - crtc_config->sprite_position_transform = crtc->client_sprite_position_transform; - crtc_config->sprite_image_transform = crtc->client_sprite_image_transform; - crtc_config->sprite_position_f_transform = crtc->client_sprite_f_position_transform; - crtc_config->sprite_image_f_transform = crtc->client_sprite_f_image_transform; - - crtc_config->pixmap = crtc->scanoutPixmap; - crtc_config->pixmap_x = crtc->x; - crtc_config->pixmap_y = crtc->y; - return TRUE; -} - - -/* - * Request that a set of crtcs be configured at the same - * time on a single screen - */ - -Bool -RRSetCrtcConfigs(ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs) -{ - rrScrPrivPtr scr_priv = rrGetScrPriv(screen); - - if (!scr_priv) - return FALSE; - return (*scr_priv->rrSetCrtcConfigs)(screen, screen_config, crtc_configs, num_configs); -} - -/* - * Return crtc transform - */ -RRTransformPtr -RRCrtcGetTransform (RRCrtcPtr crtc) -{ - RRTransformPtr transform = &crtc->client_pending_transform; - - if (pixman_transform_is_identity (&transform->transform)) - return NULL; - return transform; -} - -/* - * Check whether the pending and current transforms are the same - */ -Bool -RRCrtcPendingTransform (RRCrtcPtr crtc) -{ - return memcmp (&crtc->client_current_transform.transform, - &crtc->client_pending_transform.transform, - sizeof (PictTransform)) != 0; -} - -/* - * Destroy a Crtc at shutdown - */ -void -RRCrtcDestroy (RRCrtcPtr crtc) -{ - FreeResource (crtc->id, 0); -} - -static int -RRCrtcDestroyResource (pointer value, XID pid) -{ - RRCrtcPtr crtc = (RRCrtcPtr) value; - ScreenPtr pScreen = crtc->pScreen; - - if (pScreen) - { - rrScrPriv(pScreen); - int i; - - for (i = 0; i < pScrPriv->numCrtcs; i++) - { - if (pScrPriv->crtcs[i] == crtc) - { - memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, - (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); - --pScrPriv->numCrtcs; - break; - } - } - } - free(crtc->gammaRed); - if (crtc->mode) - RRModeDestroy (crtc->mode); - free(crtc); - return 1; -} - -/* - * Request that the Crtc gamma be changed - */ - -Bool -RRCrtcGammaSet (RRCrtcPtr crtc, - CARD16 *red, - CARD16 *green, - CARD16 *blue) -{ - Bool ret = TRUE; -#if RANDR_12_INTERFACE - ScreenPtr pScreen = crtc->pScreen; -#endif - - memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); - memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); - memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); -#if RANDR_12_INTERFACE - if (pScreen) - { - rrScrPriv(pScreen); - if (pScrPriv->rrCrtcSetGamma) - ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc); - } -#endif - return ret; -} - -/* - * Request current gamma back from the DDX (if possible). - * This includes gamma size. - */ -Bool -RRCrtcGammaGet(RRCrtcPtr crtc) -{ - Bool ret = TRUE; -#if RANDR_12_INTERFACE - ScreenPtr pScreen = crtc->pScreen; -#endif - -#if RANDR_12_INTERFACE - if (pScreen) - { - rrScrPriv(pScreen); - if (pScrPriv->rrCrtcGetGamma) - ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc); - } -#endif - return ret; -} - -/* - * Notify the extension that the Crtc gamma has been changed - * The driver calls this whenever it has changed the gamma values - * in the RRCrtcRec - */ - -Bool -RRCrtcGammaNotify (RRCrtcPtr crtc) -{ - return TRUE; /* not much going on here */ -} - -/* - * Compute overall scanout buffer requirements for the specified mode - */ -void -RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform, - int *width, int *height) -{ - BoxRec box; - - if (mode == NULL) { - *width = 0; - *height = 0; - return; - } - - box.x1 = 0; - box.y1 = 0; - box.x2 = mode->mode.width; - box.y2 = mode->mode.height; - - pixman_f_transform_bounds (transform, &box); - *width = box.x2 - box.x1; - *height = box.y2 - box.y1; -} - -/** - * Returns the width/height that the crtc scans out from the framebuffer - */ -void -RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) -{ - RRModeGetScanoutSize (crtc->mode, &crtc->f_transform, width, height); -} - -/* - * Set the size of the gamma table at server startup time - */ - -Bool -RRCrtcGammaSetSize (RRCrtcPtr crtc, - int size) -{ - CARD16 *gamma; - - if (size == crtc->gammaSize) - return TRUE; - if (size) - { - gamma = malloc(size * 3 * sizeof (CARD16)); - if (!gamma) - return FALSE; - } - else - gamma = NULL; - free(crtc->gammaRed); - crtc->gammaRed = gamma; - crtc->gammaGreen = gamma + size; - crtc->gammaBlue = gamma + size*2; - crtc->gammaSize = size; - return TRUE; -} - -/* - * Set the pending CRTC transformation - */ - -int -RRCrtcTransformSet (RRCrtcPtr crtc, - PictTransformPtr transform, - struct pixman_f_transform *f_transform, - struct pixman_f_transform *f_inverse, - char *filter_name, - int filter_len, - xFixed *params, - int nparams) -{ - PictFilterPtr filter = NULL; - int width = 0, height = 0; - - if (!crtc->transforms) - return BadValue; - - if (filter_len) - { - filter = PictureFindFilter (crtc->pScreen, - filter_name, - filter_len); - if (!filter) - return BadName; - if (filter->ValidateParams) - { - if (!filter->ValidateParams (crtc->pScreen, filter->id, - params, nparams, &width, &height)) - return BadMatch; - } - else { - width = filter->width; - height = filter->height; - } - } - else - { - if (nparams) - return BadMatch; - } - if (!RRTransformSetFilter (&crtc->client_pending_transform, - filter, params, nparams, width, height)) - return BadAlloc; - - crtc->client_pending_transform.transform = *transform; - crtc->client_pending_transform.f_transform = *f_transform; - crtc->client_pending_transform.f_inverse = *f_inverse; - return Success; -} - -/* - * Figure out whether the specific crtc_config can fit - * within the screen_config - */ -Bool -RRScreenCoversCrtc(RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_config, - RRTransformPtr client_transform, - XID *errorValue) -{ - int source_width; - int source_height; - struct pixman_f_transform f_transform; - - RRTransformCompute (crtc_config->x, crtc_config->y, - crtc_config->mode->mode.width, crtc_config->mode->mode.height, - crtc_config->rotation, - client_transform, - &crtc_config->sprite_position_f_transform, - &crtc_config->sprite_image_f_transform, - NULL, &f_transform, NULL, NULL, NULL, NULL); - - RRModeGetScanoutSize (crtc_config->mode, &f_transform, - &source_width, &source_height); - if (crtc_config->x + source_width > screen_config->screen_pixmap_width) { - if (errorValue) - *errorValue = crtc_config->x; - return FALSE; - } - - if (crtc_config->y + source_height > screen_config->screen_pixmap_height) { - if (errorValue) - *errorValue = crtc_config->y; - return FALSE; - } - return TRUE; -} - -/* - * Initialize crtc type - */ -Bool -RRCrtcInit (void) -{ - RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC"); - if (!RRCrtcType) - return FALSE; - - return TRUE; -} - -/* - * Initialize crtc type error value - */ -void -RRCrtcInitErrorValue(void) -{ - SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc); -} - -int -ProcRRGetCrtcInfo (ClientPtr client) -{ - REQUEST(xRRGetCrtcInfoReq); - xRRGetCrtcInfoReply rep; - RRCrtcPtr crtc; - CARD8 *extra; - unsigned long extraLen; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRModePtr mode; - RROutput *outputs; - RROutput *possible; - int i, j, k, n; - int width, height; - BoxRec panned_area; - - REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - /* All crtcs must be associated with screens before client - * requests are processed - */ - pScreen = crtc->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - mode = crtc->mode; - - rep.type = X_Reply; - rep.status = RRSetConfigSuccess; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - if (pScrPriv->rrGetPanning && - pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) && - (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) - { - rep.x = panned_area.x1; - rep.y = panned_area.y1; - rep.width = panned_area.x2 - panned_area.x1; - rep.height = panned_area.y2 - panned_area.y1; - } - else - { - RRCrtcGetScanoutSize (crtc, &width, &height); - rep.x = crtc->x; - rep.y = crtc->y; - rep.width = width; - rep.height = height; - } - rep.mode = mode ? mode->mode.id : 0; - rep.rotation = crtc->rotation; - rep.rotations = crtc->rotations; - rep.nOutput = crtc->numOutputs; - k = 0; - for (i = 0; i < pScrPriv->numOutputs; i++) - for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) - if (pScrPriv->outputs[i]->crtcs[j] == crtc) - k++; - rep.nPossibleOutput = k; - - rep.length = rep.nOutput + rep.nPossibleOutput; - - extraLen = rep.length << 2; - if (extraLen) - { - extra = malloc(extraLen); - if (!extra) - return BadAlloc; - } - else - extra = NULL; - - outputs = (RROutput *) extra; - possible = (RROutput *) (outputs + rep.nOutput); - - for (i = 0; i < crtc->numOutputs; i++) - { - outputs[i] = crtc->outputs[i]->id; - if (client->swapped) - swapl (&outputs[i], n); - } - k = 0; - for (i = 0; i < pScrPriv->numOutputs; i++) - for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) - if (pScrPriv->outputs[i]->crtcs[j] == crtc) - { - possible[k] = pScrPriv->outputs[i]->id; - if (client->swapped) - swapl (&possible[k], n); - k++; - } - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.x, n); - swaps(&rep.y, n); - swaps(&rep.width, n); - swaps(&rep.height, n); - swapl(&rep.mode, n); - swaps(&rep.rotation, n); - swaps(&rep.rotations, n); - swaps(&rep.nOutput, n); - swaps(&rep.nPossibleOutput, n); - } - WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - free(extra); - } - - return Success; -} - -int -ProcRRSetCrtcConfig (ClientPtr client) -{ - REQUEST(xRRSetCrtcConfigReq); - xRRSetCrtcConfigReply rep; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtcPtr crtc; - RRModePtr mode; - int numOutputs; - RROutputPtr *outputs = NULL; - RROutput *outputIds; - TimeStamp configTime; - TimeStamp time; - Rotation rotation; - int rc, i, j; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq))); - - VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess); - - if (stuff->mode == None) - { - mode = NULL; - if (numOutputs > 0) - return BadMatch; - } - else - { - VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess); - if (numOutputs == 0) - return BadMatch; - } - if (numOutputs) - { - outputs = malloc(numOutputs * sizeof (RROutputPtr)); - if (!outputs) - return BadAlloc; - } - else - outputs = NULL; - - outputIds = (RROutput *) (stuff + 1); - for (i = 0; i < numOutputs; i++) - { - rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i], - RROutputType, client, DixSetAttrAccess); - if (rc != Success) - { - free(outputs); - return rc; - } - /* validate crtc for this output */ - for (j = 0; j < outputs[i]->numCrtcs; j++) - if (outputs[i]->crtcs[j] == crtc) - break; - if (j == outputs[i]->numCrtcs) - { - free(outputs); - return BadMatch; - } - /* validate mode for this output */ - for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) - { - RRModePtr m = (j < outputs[i]->numModes ? - outputs[i]->modes[j] : - outputs[i]->userModes[j - outputs[i]->numModes]); - if (m == mode) - break; - } - if (j == outputs[i]->numModes + outputs[i]->numUserModes) - { - free(outputs); - return BadMatch; - } - } - /* validate clones */ - for (i = 0; i < numOutputs; i++) - { - for (j = 0; j < numOutputs; j++) - { - int k; - if (i == j) - continue; - for (k = 0; k < outputs[i]->numClones; k++) - { - if (outputs[i]->clones[k] == outputs[j]) - break; - } - if (k == outputs[i]->numClones) - { - free(outputs); - return BadMatch; - } - } - } - - pScreen = crtc->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * Validate requested rotation - */ - rotation = (Rotation) stuff->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = stuff->rotation; - free(outputs); - return BadValue; - } - - if (mode) - { - if ((~crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - free(outputs); - return BadMatch; - } - -#ifdef RANDR_12_INTERFACE - /* - * Check screen size bounds if the DDX provides a 1.2 interface - * for setting screen size. Else, assume the CrtcSet sets - * the size along with the mode. If the driver supports transforms, - * then it must allow crtcs to display a subset of the screen, so - * only do this check for drivers without transform support. - */ - if (pScrPriv->rrScreenSetSize && !crtc->transforms) - { - int source_width; - int source_height; - PictTransform transform; - struct pixman_f_transform f_transform, f_inverse; - - RRTransformCompute (stuff->x, stuff->y, - mode->mode.width, mode->mode.height, - rotation, - &crtc->client_pending_transform, - &crtc->client_sprite_f_position_transform, - &crtc->client_sprite_f_image_transform, - &transform, &f_transform, &f_inverse, NULL, NULL, NULL); - - RRModeGetScanoutSize (mode, &f_transform, - &source_width, &source_height); - if (stuff->x + source_width > pScreen->width) - { - client->errorValue = stuff->x; - free(outputs); - return BadValue; - } - - if (stuff->y + source_height > pScreen->height) - { - client->errorValue = stuff->y; - free(outputs); - return BadValue; - } - } -#endif - } - - if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y, - rotation, numOutputs, outputs, NULL)) - { - rep.status = RRSetConfigFailed; - goto sendReply; - } - rep.status = RRSetConfigSuccess; - pScrPriv->lastSetTime = time; - -sendReply: - free(outputs); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - - if (client->swapped) - { - int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - } - WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); - - return Success; -} - -int -ProcRRGetPanning (ClientPtr client) -{ - REQUEST(xRRGetPanningReq); - xRRGetPanningReply rep; - RRCrtcPtr crtc; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - BoxRec total; - BoxRec tracking; - INT16 border[4]; - int n; - - REQUEST_SIZE_MATCH(xRRGetPanningReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - /* All crtcs must be associated with screens before client - * requests are processed - */ - pScreen = crtc->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - if (!pScrPriv) - return RRErrorBase + BadRRCrtc; - - memset(&rep, 0, sizeof(rep)); - rep.type = X_Reply; - rep.status = RRSetConfigSuccess; - rep.sequenceNumber = client->sequence; - rep.length = 1; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - - if (pScrPriv->rrGetPanning && - pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) { - rep.left = total.x1; - rep.top = total.y1; - rep.width = total.x2 - total.x1; - rep.height = total.y2 - total.y1; - rep.track_left = tracking.x1; - rep.track_top = tracking.y1; - rep.track_width = tracking.x2 - tracking.x1; - rep.track_height = tracking.y2 - tracking.y1; - rep.border_left = border[0]; - rep.border_top = border[1]; - rep.border_right = border[2]; - rep.border_bottom = border[3]; - } - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.timestamp, n); - swaps(&rep.left, n); - swaps(&rep.top, n); - swaps(&rep.width, n); - swaps(&rep.height, n); - swaps(&rep.track_left, n); - swaps(&rep.track_top, n); - swaps(&rep.track_width, n); - swaps(&rep.track_height, n); - swaps(&rep.border_left, n); - swaps(&rep.border_top, n); - swaps(&rep.border_right, n); - swaps(&rep.border_bottom, n); - } - WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep); - return Success; -} - -int -ProcRRSetPanning (ClientPtr client) -{ - REQUEST(xRRSetPanningReq); - xRRSetPanningReply rep; - RRCrtcPtr crtc; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp time; - BoxRec total; - BoxRec tracking; - INT16 border[4]; - int n; - - REQUEST_SIZE_MATCH(xRRSetPanningReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - /* All crtcs must be associated with screens before client - * requests are processed - */ - pScreen = crtc->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - if (!pScrPriv) { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - - time = ClientTimeToServerTime(stuff->timestamp); - - if (!pScrPriv->rrGetPanning) - return RRErrorBase + BadRRCrtc; - - total.x1 = stuff->left; - total.y1 = stuff->top; - total.x2 = total.x1 + stuff->width; - total.y2 = total.y1 + stuff->height; - tracking.x1 = stuff->track_left; - tracking.y1 = stuff->track_top; - tracking.x2 = tracking.x1 + stuff->track_width; - tracking.y2 = tracking.y1 + stuff->track_height; - border[0] = stuff->border_left; - border[1] = stuff->border_top; - border[2] = stuff->border_right; - border[3] = stuff->border_bottom; - - if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border)) - return BadMatch; - - pScrPriv->lastSetTime = time; - - rep.status = RRSetConfigSuccess; - -sendReply: - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.newTimestamp, n); - } - WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep); - return Success; -} - -int -ProcRRGetCrtcGammaSize (ClientPtr client) -{ - REQUEST(xRRGetCrtcGammaSizeReq); - xRRGetCrtcGammaSizeReply reply; - RRCrtcPtr crtc; - int n; - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - /* Gamma retrieval failed, any better error? */ - if (!RRCrtcGammaGet(crtc)) - return RRErrorBase + BadRRCrtc; - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = 0; - reply.size = crtc->gammaSize; - if (client->swapped) { - swaps (&reply.sequenceNumber, n); - swapl (&reply.length, n); - swaps (&reply.size, n); - } - WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply); - return Success; -} - -int -ProcRRGetCrtcGamma (ClientPtr client) -{ - REQUEST(xRRGetCrtcGammaReq); - xRRGetCrtcGammaReply reply; - RRCrtcPtr crtc; - int n; - unsigned long len; - char *extra = NULL; - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - /* Gamma retrieval failed, any better error? */ - if (!RRCrtcGammaGet(crtc)) - return RRErrorBase + BadRRCrtc; - - len = crtc->gammaSize * 3 * 2; - - if (crtc->gammaSize) { - extra = malloc(len); - if (!extra) - return BadAlloc; - } - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = bytes_to_int32(len); - reply.size = crtc->gammaSize; - if (client->swapped) { - swaps (&reply.sequenceNumber, n); - swapl (&reply.length, n); - swaps (&reply.size, n); - } - WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); - if (crtc->gammaSize) - { - memcpy(extra, crtc->gammaRed, len); - client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; - WriteSwappedDataToClient (client, len, extra); - free(extra); - } - return Success; -} - -int -ProcRRSetCrtcGamma (ClientPtr client) -{ - REQUEST(xRRSetCrtcGammaReq); - RRCrtcPtr crtc; - unsigned long len; - CARD16 *red, *green, *blue; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq)); - if (len < (stuff->size * 3 + 1) >> 1) - return BadLength; - - if (stuff->size != crtc->gammaSize) - return BadMatch; - - red = (CARD16 *) (stuff + 1); - green = red + crtc->gammaSize; - blue = green + crtc->gammaSize; - - RRCrtcGammaSet (crtc, red, green, blue); - - return Success; -} - -/* Version 1.3 additions */ - -int -ProcRRSetCrtcTransform (ClientPtr client) -{ - REQUEST(xRRSetCrtcTransformReq); - RRCrtcPtr crtc; - PictTransform transform; - struct pixman_f_transform f_transform, f_inverse; - char *filter; - int nbytes; - xFixed *params; - int nparams; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - PictTransform_from_xRenderTransform (&transform, &stuff->transform); - pixman_f_transform_from_pixman_transform (&f_transform, &transform); - if (!pixman_f_transform_invert (&f_inverse, &f_transform)) - return BadMatch; - - filter = (char *) (stuff + 1); - nbytes = stuff->nbytesFilter; - params = (xFixed *) (filter + pad_to_int32(nbytes)); - nparams = ((xFixed *) stuff + client->req_len) - params; - if (nparams < 0) - return BadLength; - - return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse, - filter, nbytes, params, nparams); -} - - -#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32) - -static int -transform_filter_length (RRTransformPtr transform) -{ - int nbytes, nparams; - - if (transform->filter == NULL) - return 0; - nbytes = strlen (transform->filter->name); - nparams = transform->nparams; - return pad_to_int32(nbytes) + (nparams * sizeof (xFixed)); -} - -static int -transform_filter_encode (ClientPtr client, char *output, - CARD16 *nbytesFilter, - CARD16 *nparamsFilter, - RRTransformPtr transform) -{ - int nbytes, nparams; - int n; - - if (transform->filter == NULL) { - *nbytesFilter = 0; - *nparamsFilter = 0; - return 0; - } - nbytes = strlen (transform->filter->name); - nparams = transform->nparams; - *nbytesFilter = nbytes; - *nparamsFilter = nparams; - memcpy (output, transform->filter->name, nbytes); - while ((nbytes & 3) != 0) - output[nbytes++] = 0; - memcpy (output + nbytes, transform->params, nparams * sizeof (xFixed)); - if (client->swapped) { - swaps (nbytesFilter, n); - swaps (nparamsFilter, n); - SwapLongs ((CARD32 *) (output + nbytes), nparams); - } - nbytes += nparams * sizeof (xFixed); - return nbytes; -} - -static void -transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict) -{ - xRenderTransform_from_PictTransform (wire, pict); - if (client->swapped) - SwapLongs ((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform))); -} - -int -ProcRRGetCrtcTransform (ClientPtr client) -{ - REQUEST(xRRGetCrtcTransformReq); - xRRGetCrtcTransformReply *reply; - RRCrtcPtr crtc; - int n, nextra; - RRTransformPtr current, pending; - char *extra; - - REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - pending = &crtc->client_pending_transform; - current = &crtc->client_current_transform; - - nextra = (transform_filter_length (pending) + - transform_filter_length (current)); - - reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra); - if (!reply) - return BadAlloc; - - extra = (char *) (reply + 1); - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = bytes_to_int32(CrtcTransformExtra + nextra); - - reply->hasTransforms = crtc->transforms; - - transform_encode (client, &reply->pendingTransform, &pending->transform); - extra += transform_filter_encode (client, extra, - &reply->pendingNbytesFilter, - &reply->pendingNparamsFilter, - pending); - - transform_encode (client, &reply->currentTransform, ¤t->transform); - extra += transform_filter_encode (client, extra, - &reply->currentNbytesFilter, - &reply->currentNparamsFilter, - current); - - if (client->swapped) { - swaps (&reply->sequenceNumber, n); - swapl (&reply->length, n); - } - WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply); - free(reply); - return Success; -} - -static int -RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr config, xRRCrtcConfig *x, - RROutput *outputIds) -{ - RRCrtcPtr crtc; - RROutputPtr *outputs; - rrScrPrivPtr scr_priv; - RRModePtr mode; - PixmapPtr pixmap; - int rc, i, j; - Rotation rotation; - - VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess); - - if (x->mode == None) - { - mode = NULL; - if (x->nOutput > 0) - return BadMatch; - } - else - { - VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess); - if (x->nOutput == 0) - return BadMatch; - } - if (x->nOutput) - { - outputs = malloc(x->nOutput * sizeof (RROutputPtr)); - if (!outputs) - return BadAlloc; - } - else - outputs = NULL; - - if (x->pixmap == None) - pixmap = NULL; - else if (x->pixmap == RR_CurrentScanoutPixmap) - pixmap = crtc->scanoutPixmap; - else - { - rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap, - RT_PIXMAP, client, DixWriteAccess); - if (rc != Success) { - free(outputs); - return rc; - } - /* XXX check to make sure this is a scanout pixmap */ - } - - for (i = 0; i < x->nOutput; i++) - { - rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i], - RROutputType, client, DixSetAttrAccess); - if (rc != Success) - { - free(outputs); - return rc; - } - /* validate crtc for this output */ - for (j = 0; j < outputs[i]->numCrtcs; j++) - if (outputs[i]->crtcs[j] == crtc) - break; - if (j == outputs[i]->numCrtcs) - { - free(outputs); - return BadMatch; - } - /* validate mode for this output */ - for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) - { - RRModePtr m = (j < outputs[i]->numModes ? - outputs[i]->modes[j] : - outputs[i]->userModes[j - outputs[i]->numModes]); - if (m == mode) - break; - } - if (j == outputs[i]->numModes + outputs[i]->numUserModes) - { - free(outputs); - return BadMatch; - } - } - /* validate clones */ - for (i = 0; i < x->nOutput; i++) - { - for (j = 0; j < x->nOutput; j++) - { - int k; - if (i == j) - continue; - for (k = 0; k < outputs[i]->numClones; k++) - { - if (outputs[i]->clones[k] == outputs[j]) - break; - } - if (k == outputs[i]->numClones) - { - free(outputs); - return BadMatch; - } - } - } - - if (crtc->pScreen != screen) - return BadMatch; - - scr_priv = rrGetScrPriv(screen); - - config->crtc = crtc; - config->x = x->x; - config->y = x->y; - config->mode = mode; - config->rotation = x->rotation; - config->numOutputs = x->nOutput; - config->outputs = outputs; - PictTransform_from_xRenderTransform(&config->sprite_position_transform, - &x->spritePositionTransform); - PictTransform_from_xRenderTransform(&config->sprite_image_transform, - &x->spriteImageTransform); - pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform, - &config->sprite_position_transform); - pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform, - &config->sprite_image_transform); - config->pixmap = pixmap; - config->pixmap_x = x->xPixmap; - config->pixmap_y = x->yPixmap; - - /* - * Validate requested rotation - */ - rotation = (Rotation) x->rotation; - - /* test the rotation bits only! */ - switch (rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_90: - case RR_Rotate_180: - case RR_Rotate_270: - break; - default: - /* - * Invalid rotation - */ - client->errorValue = x->rotation; - free(outputs); - return BadValue; - } - - if (mode) - { - if ((~crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = x->rotation; - free(outputs); - return BadMatch; - } - - /* - * If scanning out from another pixmap, make sure the mode - * fits - */ - if (pixmap) - { - if (x->xPixmap + mode->mode.width > pixmap->drawable.width) { - client->errorValue = x->xPixmap; - free(outputs); - return BadValue; - } - if (x->yPixmap + mode->mode.height > pixmap->drawable.height) { - client->errorValue = x->yPixmap; - free(outputs); - return BadValue; - } - } - /* - * Check screen size bounds if the DDX provides a 1.2 interface - * for setting screen size. Else, assume the CrtcSet sets - * the size along with the mode. If the driver supports transforms, - * then it must allow crtcs to display a subset of the screen, so - * only do this check for drivers without transform support. - */ - else if (scr_priv->rrScreenSetSize && !crtc->transforms) - { - if (!RRScreenCoversCrtc(screen_config, config, - &crtc->client_pending_transform, - &client->errorValue)) - { - free(outputs); - return BadValue; - } - } - } - - return Success; -} - -int -ProcRRSetCrtcConfigs (ClientPtr client) -{ - REQUEST(xRRSetCrtcConfigsReq); - xRRSetCrtcConfigsReply rep; - DrawablePtr drawable; - ScreenPtr screen; - rrScrPrivPtr scr_priv; - xRRCrtcConfig *x_configs; - RRScreenConfigRec screen_config; - RRCrtcConfigPtr configs = NULL; - RROutput *output_ids; - int num_configs = 0; - int rc, i; - int extra_len; - int num_output_ids; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq); - - extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq)); - - num_configs = stuff->nConfigs; - - /* Check request length against number of configs specified */ - if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len) - return BadLength; - - extra_len -= num_configs * (sizeof (xRRCrtcConfig) >> 2); - x_configs = (xRRCrtcConfig *) (stuff + 1); - - /* Check remaining request length against number of outputs */ - num_output_ids = 0; - for (i = 0; i < num_configs; i++) - num_output_ids += x_configs[i].nOutput; - - if (extra_len != num_output_ids) - return BadLength; - - rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); - if (rc != Success) - return rc; - - screen = drawable->pScreen; - - scr_priv = rrGetScrPriv(screen); - - if (!scr_priv) - { - rep.status = RRSetConfigFailed; - goto sendReply; - } - - if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) - { - client->errorValue = 0; - return BadValue; - } - - if (stuff->screenPixmapWidth < scr_priv->minWidth || - scr_priv->maxWidth < stuff->screenPixmapWidth) - { - client->errorValue = stuff->screenPixmapWidth; - return BadValue; - } - if (stuff->screenPixmapHeight < scr_priv->minHeight || - scr_priv->maxHeight < stuff->screenPixmapHeight) - { - client->errorValue = stuff->screenPixmapHeight; - return BadValue; - } - - screen_config.screen_pixmap_width = stuff->screenPixmapWidth; - screen_config.screen_pixmap_height = stuff->screenPixmapHeight; - screen_config.screen_width = stuff->screenWidth; - screen_config.screen_height = stuff->screenHeight; - screen_config.mm_width = stuff->widthInMillimeters; - screen_config.mm_height = stuff->heightInMillimeters; - - output_ids = (RROutput *) (x_configs + num_configs); - - /* - * Convert protocol crtc configurations into - * server crtc configurations - */ - configs = calloc(num_configs, sizeof (RRCrtcConfigRec)); - if (num_configs > 0 && configs == NULL) - return BadAlloc; - for (i = 0; i < num_configs; i++) { - rc = RRConvertCrtcConfig(client, screen, &screen_config, - &configs[i], - &x_configs[i], output_ids); - if (rc != Success) { - rep.status = RRSetConfigFailed; - goto sendReply; - } - output_ids += x_configs[i].nOutput; - } - - if (num_configs && - !RRSetCrtcConfigs (screen, &screen_config, configs, num_configs)) - { - rep.status = RRSetConfigFailed; - goto sendReply; - } - rep.status = RRSetConfigSuccess; - scr_priv->lastSetTime = currentTime; - -sendReply: - RRFreeCrtcConfigs(configs, num_configs); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (client->swapped) - { - int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - WriteToClient(client, sizeof(xRRSetCrtcConfigsReply), (char *)&rep); - - return Success; -} +/* + * 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. + */ + +#include "randrstr.h" +#include "swaprep.h" + +RESTYPE RRCrtcType; + +/* + * Notify the CRTC of some change + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) +{ + ScreenPtr pScreen = crtc->pScreen; + + crtc->changed = TRUE; + if (pScreen) + { + rrScrPriv(pScreen); + + pScrPriv->changed = TRUE; + /* + * Send ConfigureNotify on any layout change + */ + if (layoutChanged) + pScrPriv->layoutChanged = TRUE; + } +} + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) +{ + RRCrtcPtr crtc; + RRCrtcPtr *crtcs; + rrScrPrivPtr pScrPriv; + + if (!RRInit()) + return NULL; + + pScrPriv = rrGetScrPriv(pScreen); + + /* make space for the crtc pointer */ + if (pScrPriv->numCrtcs) + crtcs = realloc(pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = malloc(sizeof (RRCrtcPtr)); + if (!crtcs) + return FALSE; + pScrPriv->crtcs = crtcs; + + crtc = calloc(1, sizeof (RRCrtcRec)); + if (!crtc) + return NULL; + crtc->id = FakeClientID (0); + crtc->pScreen = pScreen; + crtc->mode = NULL; + crtc->x = 0; + crtc->y = 0; + crtc->rotation = RR_Rotate_0; + crtc->rotations = RR_Rotate_0; + crtc->outputs = NULL; + crtc->numOutputs = 0; + crtc->gammaSize = 0; + crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; + crtc->changed = FALSE; + crtc->devPrivate = devPrivate; + RRTransformInit (&crtc->client_pending_transform); + RRTransformInit (&crtc->client_current_transform); + pixman_transform_init_identity (&crtc->transform); + pixman_f_transform_init_identity (&crtc->f_transform); + pixman_f_transform_init_identity (&crtc->f_inverse); + + if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) + return NULL; + + /* attach the screen and crtc together */ + crtc->pScreen = pScreen; + pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + + return crtc; +} + +/* + * Set the allowed rotations on a CRTC + */ +void +RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) +{ + crtc->rotations = rotations; +} + +/* + * Set whether transforms are allowed on a CRTC + */ +void +RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms) +{ + crtc->transforms = transforms; +} + +/* + * Notify the extension that the Crtc has been reconfigured, + * the driver calls this whenever it has updated the mode + */ +Bool +RRCrtcNotify (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + RRTransformPtr transform, + int numOutputs, + RROutputPtr *outputs) +{ + int i, j; + + /* + * Check to see if any of the new outputs were + * not in the old list and mark them as changed + */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < crtc->numOutputs; j++) + if (outputs[i] == crtc->outputs[j]) + break; + if (j == crtc->numOutputs) + { + outputs[i]->crtc = crtc; + RROutputChanged (outputs[i], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Check to see if any of the old outputs are + * not in the new list and mark them as changed + */ + for (j = 0; j < crtc->numOutputs; j++) + { + for (i = 0; i < numOutputs; i++) + if (outputs[i] == crtc->outputs[j]) + break; + if (i == numOutputs) + { + if (crtc->outputs[j]->crtc == crtc) + crtc->outputs[j]->crtc = NULL; + RROutputChanged (crtc->outputs[j], FALSE); + RRCrtcChanged (crtc, FALSE); + } + } + /* + * Reallocate the crtc output array if necessary + */ + if (numOutputs != crtc->numOutputs) + { + RROutputPtr *newoutputs; + + if (numOutputs) + { + if (crtc->numOutputs) + newoutputs = realloc(crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + newoutputs = malloc(numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) + return FALSE; + } + else + { + free(crtc->outputs); + newoutputs = NULL; + } + crtc->outputs = newoutputs; + crtc->numOutputs = numOutputs; + } + /* + * Copy the new list of outputs into the crtc + */ + memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)); + /* + * Update remaining crtc fields + */ + if (mode != crtc->mode) + { + if (crtc->mode) + RRModeDestroy (crtc->mode); + crtc->mode = mode; + if (mode != NULL) + mode->refcnt++; + RRCrtcChanged (crtc, TRUE); + } + if (x != crtc->x) + { + crtc->x = x; + RRCrtcChanged (crtc, TRUE); + } + if (y != crtc->y) + { + crtc->y = y; + RRCrtcChanged (crtc, TRUE); + } + if (rotation != crtc->rotation) + { + crtc->rotation = rotation; + RRCrtcChanged (crtc, TRUE); + } + if (!RRTransformEqual (transform, &crtc->client_current_transform)) { + RRTransformCopy (&crtc->client_current_transform, transform); + RRCrtcChanged (crtc, TRUE); + } + if (crtc->changed && mode) + { + RRTransformCompute (x, y, + mode->mode.width, mode->mode.height, + rotation, + &crtc->client_current_transform, + &crtc->transform, &crtc->f_transform, + &crtc->f_inverse); + } + return TRUE; +} + +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + xRRCrtcChangeNotifyEvent ce; + RRModePtr mode = crtc->mode; + + ce.type = RRNotify + RREventBase; + ce.subCode = RRNotify_CrtcChange; + ce.timestamp = pScrPriv->lastSetTime.milliseconds; + ce.window = pWin->drawable.id; + ce.crtc = crtc->id; + ce.rotation = crtc->rotation; + if (mode) + { + ce.mode = mode->mode.id; + ce.x = crtc->x; + ce.y = crtc->y; + ce.width = mode->mode.width; + ce.height = mode->mode.height; + } + else + { + ce.mode = None; + ce.x = 0; + ce.y = 0; + ce.width = 0; + ce.height = 0; + } + WriteEventsToClient (client, 1, (xEvent *) &ce); +} + +static Bool +RRCrtcPendingProperties (RRCrtcPtr crtc) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + int o; + + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + if (output->crtc == crtc && output->pendingProperties) + return TRUE; + } + return FALSE; +} + +/* + * Request that the Crtc be reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutputs, + RROutputPtr *outputs) +{ + ScreenPtr pScreen = crtc->pScreen; + Bool ret = FALSE; + rrScrPriv(pScreen); + + /* See if nothing changed */ + if (crtc->mode == mode && + crtc->x == x && + crtc->y == y && + crtc->rotation == rotation && + crtc->numOutputs == numOutputs && + !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && + !RRCrtcPendingProperties (crtc) && + !RRCrtcPendingTransform (crtc)) + { + ret = TRUE; + } + else + { +#if RANDR_12_INTERFACE + if (pScrPriv->rrCrtcSet) + { + ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); + } + else +#endif + { +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + RRScreenSize size; + RRScreenRate rate; + + if (!mode) + { + RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL); + ret = TRUE; + } + else + { + size.width = mode->mode.width; + size.height = mode->mode.height; + if (outputs[0]->mmWidth && outputs[0]->mmHeight) + { + size.mmWidth = outputs[0]->mmWidth; + size.mmHeight = outputs[0]->mmHeight; + } + else + { + size.mmWidth = pScreen->mmWidth; + size.mmHeight = pScreen->mmHeight; + } + size.nRates = 1; + rate.rate = RRVerticalRefresh (&mode->mode); + size.pRates = &rate; + ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); + /* + * Old 1.0 interface tied screen size to mode size + */ + if (ret) + { + RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs); + RRScreenSizeNotify (pScreen); + } + } + } +#endif + } + if (ret) + { + int o; + RRTellChanged (pScreen); + + for (o = 0; o < numOutputs; o++) + RRPostPendingProperties (outputs[o]); + } + } + return ret; +} + +/* + * Return crtc transform + */ +RRTransformPtr +RRCrtcGetTransform (RRCrtcPtr crtc) +{ + RRTransformPtr transform = &crtc->client_pending_transform; + + if (pixman_transform_is_identity (&transform->transform)) + return NULL; + return transform; +} + +/* + * Check whether the pending and current transforms are the same + */ +Bool +RRCrtcPendingTransform (RRCrtcPtr crtc) +{ + return memcmp (&crtc->client_current_transform.transform, + &crtc->client_pending_transform.transform, + sizeof (PictTransform)) != 0; +} + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc) +{ + FreeResource (crtc->id, 0); +} + +static int +RRCrtcDestroyResource (pointer value, XID pid) +{ + RRCrtcPtr crtc = (RRCrtcPtr) value; + ScreenPtr pScreen = crtc->pScreen; + + if (pScreen) + { + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, + (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + break; + } + } + } + free(crtc->gammaRed); + if (crtc->mode) + RRModeDestroy (crtc->mode); + free(crtc); + return 1; +} + +/* + * Request that the Crtc gamma be changed + */ + +Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue) +{ + Bool ret = TRUE; +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + + memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16)); + memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16)); +#if RANDR_12_INTERFACE + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc); + } +#endif + return ret; +} + +/* + * Request current gamma back from the DDX (if possible). + * This includes gamma size. + */ +Bool +RRCrtcGammaGet(RRCrtcPtr crtc) +{ + Bool ret = TRUE; +#if RANDR_12_INTERFACE + ScreenPtr pScreen = crtc->pScreen; +#endif + +#if RANDR_12_INTERFACE + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcGetGamma) + ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc); + } +#endif + return ret; +} + +/* + * Notify the extension that the Crtc gamma has been changed + * The driver calls this whenever it has changed the gamma values + * in the RRCrtcRec + */ + +Bool +RRCrtcGammaNotify (RRCrtcPtr crtc) +{ + return TRUE; /* not much going on here */ +} + +static void +RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform, + int *width, int *height) +{ + BoxRec box; + + if (mode == NULL) { + *width = 0; + *height = 0; + return; + } + + box.x1 = 0; + box.y1 = 0; + box.x2 = mode->mode.width; + box.y2 = mode->mode.height; + + pixman_transform_bounds (transform, &box); + *width = box.x2 - box.x1; + *height = box.y2 - box.y1; +} + +/** + * Returns the width/height that the crtc scans out from the framebuffer + */ +void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) +{ + return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height); +} + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size) +{ + CARD16 *gamma; + + if (size == crtc->gammaSize) + return TRUE; + if (size) + { + gamma = malloc(size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + } + else + gamma = NULL; + free(crtc->gammaRed); + crtc->gammaRed = gamma; + crtc->gammaGreen = gamma + size; + crtc->gammaBlue = gamma + size*2; + crtc->gammaSize = size; + return TRUE; +} + +/* + * Set the pending CRTC transformation + */ + +int +RRCrtcTransformSet (RRCrtcPtr crtc, + PictTransformPtr transform, + struct pixman_f_transform *f_transform, + struct pixman_f_transform *f_inverse, + char *filter_name, + int filter_len, + xFixed *params, + int nparams) +{ + PictFilterPtr filter = NULL; + int width = 0, height = 0; + + if (!crtc->transforms) + return BadValue; + + if (filter_len) + { + filter = PictureFindFilter (crtc->pScreen, + filter_name, + filter_len); + if (!filter) + return BadName; + if (filter->ValidateParams) + { + if (!filter->ValidateParams (crtc->pScreen, filter->id, + params, nparams, &width, &height)) + return BadMatch; + } + else { + width = filter->width; + height = filter->height; + } + } + else + { + if (nparams) + return BadMatch; + } + if (!RRTransformSetFilter (&crtc->client_pending_transform, + filter, params, nparams, width, height)) + return BadAlloc; + + crtc->client_pending_transform.transform = *transform; + crtc->client_pending_transform.f_transform = *f_transform; + crtc->client_pending_transform.f_inverse = *f_inverse; + return Success; +} + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void) +{ + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC"); + if (!RRCrtcType) + return FALSE; + + return TRUE; +} + +/* + * Initialize crtc type error value + */ +void +RRCrtcInitErrorValue(void) +{ + SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc); +} + +int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + xRRGetCrtcInfoReply rep; + RRCrtcPtr crtc; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRModePtr mode; + RROutput *outputs; + RROutput *possible; + int i, j, k, n; + int width, height; + BoxRec panned_area; + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + mode = crtc->mode; + + rep.type = X_Reply; + rep.status = RRSetConfigSuccess; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + if (pScrPriv->rrGetPanning && + pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) && + (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) + { + rep.x = panned_area.x1; + rep.y = panned_area.y1; + rep.width = panned_area.x2 - panned_area.x1; + rep.height = panned_area.y2 - panned_area.y1; + } + else + { + RRCrtcGetScanoutSize (crtc, &width, &height); + rep.x = crtc->x; + rep.y = crtc->y; + rep.width = width; + rep.height = height; + } + rep.mode = mode ? mode->mode.id : 0; + rep.rotation = crtc->rotation; + rep.rotations = crtc->rotations; + rep.nOutput = crtc->numOutputs; + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + k++; + rep.nPossibleOutput = k; + + rep.length = rep.nOutput + rep.nPossibleOutput; + + extraLen = rep.length << 2; + if (extraLen) + { + extra = malloc(extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; + + outputs = (RROutput *) extra; + possible = (RROutput *) (outputs + rep.nOutput); + + for (i = 0; i < crtc->numOutputs; i++) + { + outputs[i] = crtc->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + k = 0; + for (i = 0; i < pScrPriv->numOutputs; i++) + for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++) + if (pScrPriv->outputs[i]->crtcs[j] == crtc) + { + possible[k] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&possible[k], n); + k++; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.x, n); + swaps(&rep.y, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swapl(&rep.mode, n); + swaps(&rep.rotation, n); + swaps(&rep.rotations, n); + swaps(&rep.nOutput, n); + swaps(&rep.nPossibleOutput, n); + } + WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + free(extra); + } + + return Success; +} + +int +ProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + xRRSetCrtcConfigReply rep; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + RRModePtr mode; + int numOutputs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + int rc, i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq))); + + VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess); + + if (stuff->mode == None) + { + mode = NULL; + if (numOutputs > 0) + return BadMatch; + } + else + { + VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess); + if (numOutputs == 0) + return BadMatch; + } + if (numOutputs) + { + outputs = malloc(numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i], + RROutputType, client, DixSetAttrAccess); + if (rc != Success) + { + free(outputs); + return rc; + } + /* validate crtc for this output */ + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) + break; + if (j == outputs[i]->numCrtcs) + { + free(outputs); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) + { + RRModePtr m = (j < outputs[i]->numModes ? + outputs[i]->modes[j] : + outputs[i]->userModes[j - outputs[i]->numModes]); + if (m == mode) + break; + } + if (j == outputs[i]->numModes + outputs[i]->numUserModes) + { + free(outputs); + return BadMatch; + } + } + /* validate clones */ + for (i = 0; i < numOutputs; i++) + { + for (j = 0; j < numOutputs; j++) + { + int k; + if (i == j) + continue; + for (k = 0; k < outputs[i]->numClones; k++) + { + if (outputs[i]->clones[k] == outputs[j]) + break; + } + if (k == outputs[i]->numClones) + { + free(outputs); + return BadMatch; + } + } + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + /* + * Validate requested rotation + */ + rotation = (Rotation) stuff->rotation; + + /* test the rotation bits only! */ + switch (rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_90: + case RR_Rotate_180: + case RR_Rotate_270: + break; + default: + /* + * Invalid rotation + */ + client->errorValue = stuff->rotation; + free(outputs); + return BadValue; + } + + if (mode) + { + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + free(outputs); + return BadMatch; + } + +#ifdef RANDR_12_INTERFACE + /* + * Check screen size bounds if the DDX provides a 1.2 interface + * for setting screen size. Else, assume the CrtcSet sets + * the size along with the mode. If the driver supports transforms, + * then it must allow crtcs to display a subset of the screen, so + * only do this check for drivers without transform support. + */ + if (pScrPriv->rrScreenSetSize && !crtc->transforms) + { + int source_width; + int source_height; + PictTransform transform; + struct pixman_f_transform f_transform, f_inverse; + + RRTransformCompute (stuff->x, stuff->y, + mode->mode.width, mode->mode.height, + rotation, + &crtc->client_pending_transform, + &transform, &f_transform, &f_inverse); + + RRModeGetScanoutSize (mode, &transform, &source_width, &source_height); + if (stuff->x + source_width > pScreen->width) + { + client->errorValue = stuff->x; + free(outputs); + return BadValue; + } + + if (stuff->y + source_height > pScreen->height) + { + client->errorValue = stuff->y; + free(outputs); + return BadValue; + } + } +#endif + } + + if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y, + rotation, numOutputs, outputs)) + { + rep.status = RRSetConfigFailed; + goto sendReply; + } + rep.status = RRSetConfigSuccess; + pScrPriv->lastSetTime = time; + +sendReply: + free(outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep); + + return Success; +} + +int +ProcRRGetPanning (ClientPtr client) +{ + REQUEST(xRRGetPanningReq); + xRRGetPanningReply rep; + RRCrtcPtr crtc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + BoxRec total; + BoxRec tracking; + INT16 border[4]; + int n; + + REQUEST_SIZE_MATCH(xRRGetPanningReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) + return RRErrorBase + BadRRCrtc; + + memset(&rep, 0, sizeof(rep)); + rep.type = X_Reply; + rep.status = RRSetConfigSuccess; + rep.sequenceNumber = client->sequence; + rep.length = 1; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + + if (pScrPriv->rrGetPanning && + pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) { + rep.left = total.x1; + rep.top = total.y1; + rep.width = total.x2 - total.x1; + rep.height = total.y2 - total.y1; + rep.track_left = tracking.x1; + rep.track_top = tracking.y1; + rep.track_width = tracking.x2 - tracking.x1; + rep.track_height = tracking.y2 - tracking.y1; + rep.border_left = border[0]; + rep.border_top = border[1]; + rep.border_right = border[2]; + rep.border_bottom = border[3]; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.timestamp, n); + swaps(&rep.left, n); + swaps(&rep.top, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + swaps(&rep.track_left, n); + swaps(&rep.track_top, n); + swaps(&rep.track_width, n); + swaps(&rep.track_height, n); + swaps(&rep.border_left, n); + swaps(&rep.border_top, n); + swaps(&rep.border_right, n); + swaps(&rep.border_bottom, n); + } + WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep); + return Success; +} + +int +ProcRRSetPanning (ClientPtr client) +{ + REQUEST(xRRSetPanningReq); + xRRSetPanningReply rep; + RRCrtcPtr crtc; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp time; + BoxRec total; + BoxRec tracking; + INT16 border[4]; + int n; + + REQUEST_SIZE_MATCH(xRRSetPanningReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* All crtcs must be associated with screens before client + * requests are processed + */ + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + if (!pScrPriv) { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + time = ClientTimeToServerTime(stuff->timestamp); + + if (!pScrPriv->rrGetPanning) + return RRErrorBase + BadRRCrtc; + + total.x1 = stuff->left; + total.y1 = stuff->top; + total.x2 = total.x1 + stuff->width; + total.y2 = total.y1 + stuff->height; + tracking.x1 = stuff->track_left; + tracking.y1 = stuff->track_top; + tracking.x2 = tracking.x1 + stuff->track_width; + tracking.y2 = tracking.y1 + stuff->track_height; + border[0] = stuff->border_left; + border[1] = stuff->border_top; + border[2] = stuff->border_right; + border[3] = stuff->border_bottom; + + if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border)) + return BadMatch; + + pScrPriv->lastSetTime = time; + + rep.status = RRSetConfigSuccess; + +sendReply: + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.newTimestamp, n); + } + WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep); + return Success; +} + +int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + xRRGetCrtcGammaSizeReply reply; + RRCrtcPtr crtc; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* Gamma retrieval failed, any better error? */ + if (!RRCrtcGammaGet(crtc)) + return RRErrorBase + BadRRCrtc; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = 0; + reply.size = crtc->gammaSize; + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swaps (&reply.size, n); + } + WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply); + return Success; +} + +int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + xRRGetCrtcGammaReply reply; + RRCrtcPtr crtc; + int n; + unsigned long len; + char *extra = NULL; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + /* Gamma retrieval failed, any better error? */ + if (!RRCrtcGammaGet(crtc)) + return RRErrorBase + BadRRCrtc; + + len = crtc->gammaSize * 3 * 2; + + if (crtc->gammaSize) { + extra = malloc(len); + if (!extra) + return BadAlloc; + } + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = bytes_to_int32(len); + reply.size = crtc->gammaSize; + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + swaps (&reply.size, n); + } + WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply); + if (crtc->gammaSize) + { + memcpy(extra, crtc->gammaRed, len); + client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; + WriteSwappedDataToClient (client, len, extra); + free(extra); + } + return Success; +} + +int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + RRCrtcPtr crtc; + unsigned long len; + CARD16 *red, *green, *blue; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq)); + if (len < (stuff->size * 3 + 1) >> 1) + return BadLength; + + if (stuff->size != crtc->gammaSize) + return BadMatch; + + red = (CARD16 *) (stuff + 1); + green = red + crtc->gammaSize; + blue = green + crtc->gammaSize; + + RRCrtcGammaSet (crtc, red, green, blue); + + return Success; +} + +/* Version 1.3 additions */ + +int +ProcRRSetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRSetCrtcTransformReq); + RRCrtcPtr crtc; + PictTransform transform; + struct pixman_f_transform f_transform, f_inverse; + char *filter; + int nbytes; + xFixed *params; + int nparams; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + PictTransform_from_xRenderTransform (&transform, &stuff->transform); + pixman_f_transform_from_pixman_transform (&f_transform, &transform); + if (!pixman_f_transform_invert (&f_inverse, &f_transform)) + return BadMatch; + + filter = (char *) (stuff + 1); + nbytes = stuff->nbytesFilter; + params = (xFixed *) (filter + pad_to_int32(nbytes)); + nparams = ((xFixed *) stuff + client->req_len) - params; + if (nparams < 0) + return BadLength; + + return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse, + filter, nbytes, params, nparams); +} + + +#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32) + +static int +transform_filter_length (RRTransformPtr transform) +{ + int nbytes, nparams; + + if (transform->filter == NULL) + return 0; + nbytes = strlen (transform->filter->name); + nparams = transform->nparams; + return pad_to_int32(nbytes) + (nparams * sizeof (xFixed)); +} + +static int +transform_filter_encode (ClientPtr client, char *output, + CARD16 *nbytesFilter, + CARD16 *nparamsFilter, + RRTransformPtr transform) +{ + int nbytes, nparams; + int n; + + if (transform->filter == NULL) { + *nbytesFilter = 0; + *nparamsFilter = 0; + return 0; + } + nbytes = strlen (transform->filter->name); + nparams = transform->nparams; + *nbytesFilter = nbytes; + *nparamsFilter = nparams; + memcpy (output, transform->filter->name, nbytes); + while ((nbytes & 3) != 0) + output[nbytes++] = 0; + memcpy (output + nbytes, transform->params, nparams * sizeof (xFixed)); + if (client->swapped) { + swaps (nbytesFilter, n); + swaps (nparamsFilter, n); + SwapLongs ((CARD32 *) (output + nbytes), nparams); + } + nbytes += nparams * sizeof (xFixed); + return nbytes; +} + +static void +transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict) +{ + xRenderTransform_from_PictTransform (wire, pict); + if (client->swapped) + SwapLongs ((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform))); +} + +int +ProcRRGetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRGetCrtcTransformReq); + xRRGetCrtcTransformReply *reply; + RRCrtcPtr crtc; + int n, nextra; + RRTransformPtr current, pending; + char *extra; + + REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq); + VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); + + pending = &crtc->client_pending_transform; + current = &crtc->client_current_transform; + + nextra = (transform_filter_length (pending) + + transform_filter_length (current)); + + reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra); + if (!reply) + return BadAlloc; + + extra = (char *) (reply + 1); + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(CrtcTransformExtra + nextra); + + reply->hasTransforms = crtc->transforms; + + transform_encode (client, &reply->pendingTransform, &pending->transform); + extra += transform_filter_encode (client, extra, + &reply->pendingNbytesFilter, + &reply->pendingNparamsFilter, + pending); + + transform_encode (client, &reply->currentTransform, ¤t->transform); + extra += transform_filter_encode (client, extra, + &reply->currentNbytesFilter, + &reply->currentNparamsFilter, + current); + + if (client->swapped) { + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + } + WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply); + free(reply); + return Success; +} diff --git a/xorg-server/randr/rrdispatch.c b/xorg-server/randr/rrdispatch.c index b9cbb5858..ac4d2acc1 100644 --- a/xorg-server/randr/rrdispatch.c +++ b/xorg-server/randr/rrdispatch.c @@ -1,234 +1,228 @@ -/* - * 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. - */ - -#include "randrstr.h" -#include "protocol-versions.h" - -Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep = {0}; - register int n; - REQUEST(xRRQueryVersionReq); - rrClientPriv(client); - - REQUEST_SIZE_MATCH(xRRQueryVersionReq); - pRRClient->major_version = stuff->majorVersion; - pRRClient->minor_version = stuff->minorVersion; - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if ((stuff->majorVersion * 1000 + stuff->minorVersion) < - (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION)) - { - rep.majorVersion = stuff->majorVersion; - rep.minorVersion = stuff->minorVersion; - } else - { - rep.majorVersion = SERVER_RANDR_MAJOR_VERSION; - rep.minorVersion = SERVER_RANDR_MINOR_VERSION; - } - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); - return Success; -} - -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, *pHead; - XID clientResource; - int rc; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); - if (rc != Success) - return rc; - rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - RREventType, client, DixWriteAccess); - if (rc != Success && rc != BadValue) - return rc; - - if (stuff->enable & (RRScreenChangeNotifyMask| - RRCrtcChangeNotifyMask| - RROutputChangeNotifyMask| - RROutputPropertyNotifyMask)) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - rrScrPriv (pScreen); - - pRREvent = NULL; - if (pHead) - { - /* check for existing entry. */ - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) - if (pRREvent->client == client) - break; - } - - if (!pRREvent) - { - /* build the entry */ - pRREvent = (RREventPtr) malloc(sizeof (RREventRec)); - if (!pRREvent) - return BadAlloc; - pRREvent->next = 0; - pRREvent->client = client; - pRREvent->window = pWin; - pRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pRREvent->clientResource = clientResource; - if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (RREventPtr *) malloc(sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pRREvent->next = *pHead; - *pHead = pRREvent; - } - /* - * Now see if the client needs an event - */ - if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) - { - pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; - if (CompareTimeStamps (pTimes->setTime, - pScrPriv->lastSetTime) != 0 || - CompareTimeStamps (pTimes->configTime, - pScrPriv->lastConfigTime) != 0) - { - RRDeliverScreenEvent (client, pWin, pScreen); - } - } - } - else if (stuff->enable == 0) - { - /* delete the interest */ - if (pHead) { - RREventPtr pNewRREvent = 0; - for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { - if (pRREvent->client == client) - break; - pNewRREvent = pRREvent; - } - if (pRREvent) { - FreeResource (pRREvent->clientResource, RRClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - free(pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - -int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { - ProcRRQueryVersion, /* 0 */ -/* we skip 1 to make old clients fail pretty immediately */ - NULL, /* 1 ProcRandrOldGetScreenInfo */ -/* V1.0 apps share the same set screen config request id */ - ProcRRSetScreenConfig, /* 2 */ - NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ -/* 3 used to be ScreenChangeSelectInput; deprecated */ - ProcRRSelectInput, /* 4 */ - ProcRRGetScreenInfo, /* 5 */ -/* V1.2 additions */ - ProcRRGetScreenSizeRange, /* 6 */ - ProcRRSetScreenSize, /* 7 */ - ProcRRGetScreenResources, /* 8 */ - ProcRRGetOutputInfo, /* 9 */ - ProcRRListOutputProperties, /* 10 */ - ProcRRQueryOutputProperty, /* 11 */ - ProcRRConfigureOutputProperty, /* 12 */ - ProcRRChangeOutputProperty, /* 13 */ - ProcRRDeleteOutputProperty, /* 14 */ - ProcRRGetOutputProperty, /* 15 */ - ProcRRCreateMode, /* 16 */ - ProcRRDestroyMode, /* 17 */ - ProcRRAddOutputMode, /* 18 */ - ProcRRDeleteOutputMode, /* 19 */ - ProcRRGetCrtcInfo, /* 20 */ - ProcRRSetCrtcConfig, /* 21 */ - ProcRRGetCrtcGammaSize, /* 22 */ - ProcRRGetCrtcGamma, /* 23 */ - ProcRRSetCrtcGamma, /* 24 */ -/* V1.3 additions */ - ProcRRGetScreenResourcesCurrent, /* 25 */ - ProcRRSetCrtcTransform, /* 26 */ - ProcRRGetCrtcTransform, /* 27 */ - ProcRRGetPanning, /* 28 */ - ProcRRSetPanning, /* 29 */ - ProcRRSetOutputPrimary, /* 30 */ - ProcRRGetOutputPrimary, /* 31 */ -/* V1.4 additions */ - ProcRRQueryScanoutPixmaps, /* 32 */ - ProcRRCreateScanoutPixmap, /* 33 */ - ProcRRSetCrtcSpriteTransform,/* 34 */ - ProcRRGetCrtcSpriteTransform,/* 35 */ - ProcRRSetCrtcConfigs, /* 36 */ -}; - +/* + * 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. + */ + +#include "randrstr.h" +#include "protocol-versions.h" + +Bool +RRClientKnowsRates (ClientPtr pClient) +{ + rrClientPriv(pClient); + + return (pRRClient->major_version > 1 || + (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); +} + +static int +ProcRRQueryVersion (ClientPtr client) +{ + xRRQueryVersionReply rep = {0}; + register int n; + REQUEST(xRRQueryVersionReq); + rrClientPriv(client); + + REQUEST_SIZE_MATCH(xRRQueryVersionReq); + pRRClient->major_version = stuff->majorVersion; + pRRClient->minor_version = stuff->minorVersion; + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if ((stuff->majorVersion * 1000 + stuff->minorVersion) < + (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION)) + { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else + { + rep.majorVersion = SERVER_RANDR_MAJOR_VERSION; + rep.minorVersion = SERVER_RANDR_MINOR_VERSION; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); + return Success; +} + +static int +ProcRRSelectInput (ClientPtr client) +{ + REQUEST(xRRSelectInputReq); + rrClientPriv(client); + RRTimesPtr pTimes; + WindowPtr pWin; + RREventPtr pRREvent, *pHead; + XID clientResource; + int rc; + + REQUEST_SIZE_MATCH(xRRSelectInputReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); + if (rc != Success) + return rc; + rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, + RREventType, client, DixWriteAccess); + if (rc != Success && rc != BadValue) + return rc; + + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask| + RROutputPropertyNotifyMask)) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + + pRREvent = NULL; + if (pHead) + { + /* check for existing entry. */ + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) + if (pRREvent->client == client) + break; + } + + if (!pRREvent) + { + /* build the entry */ + pRREvent = (RREventPtr) malloc(sizeof (RREventRec)); + if (!pRREvent) + return BadAlloc; + pRREvent->next = 0; + pRREvent->client = client; + pRREvent->window = pWin; + pRREvent->mask = stuff->enable; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pRREvent->clientResource = clientResource; + if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (RREventPtr *) malloc(sizeof (RREventPtr)); + if (!pHead || + !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pRREvent->next = *pHead; + *pHead = pRREvent; + } + /* + * Now see if the client needs an event + */ + if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) + { + pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; + if (CompareTimeStamps (pTimes->setTime, + pScrPriv->lastSetTime) != 0 || + CompareTimeStamps (pTimes->configTime, + pScrPriv->lastConfigTime) != 0) + { + RRDeliverScreenEvent (client, pWin, pScreen); + } + } + } + else if (stuff->enable == 0) + { + /* delete the interest */ + if (pHead) { + RREventPtr pNewRREvent = 0; + for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { + if (pRREvent->client == client) + break; + pNewRREvent = pRREvent; + } + if (pRREvent) { + FreeResource (pRREvent->clientResource, RRClientType); + if (pNewRREvent) + pNewRREvent->next = pRREvent->next; + else + *pHead = pRREvent->next; + free(pRREvent); + } + } + } + else + { + client->errorValue = stuff->enable; + return BadValue; + } + return Success; +} + +int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { + ProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 ProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + ProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + ProcRRSelectInput, /* 4 */ + ProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + ProcRRGetScreenSizeRange, /* 6 */ + ProcRRSetScreenSize, /* 7 */ + ProcRRGetScreenResources, /* 8 */ + ProcRRGetOutputInfo, /* 9 */ + ProcRRListOutputProperties, /* 10 */ + ProcRRQueryOutputProperty, /* 11 */ + ProcRRConfigureOutputProperty, /* 12 */ + ProcRRChangeOutputProperty, /* 13 */ + ProcRRDeleteOutputProperty, /* 14 */ + ProcRRGetOutputProperty, /* 15 */ + ProcRRCreateMode, /* 16 */ + ProcRRDestroyMode, /* 17 */ + ProcRRAddOutputMode, /* 18 */ + ProcRRDeleteOutputMode, /* 19 */ + ProcRRGetCrtcInfo, /* 20 */ + ProcRRSetCrtcConfig, /* 21 */ + ProcRRGetCrtcGammaSize, /* 22 */ + ProcRRGetCrtcGamma, /* 23 */ + ProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + ProcRRGetScreenResourcesCurrent, /* 25 */ + ProcRRSetCrtcTransform, /* 26 */ + ProcRRGetCrtcTransform, /* 27 */ + ProcRRGetPanning, /* 28 */ + ProcRRSetPanning, /* 29 */ + ProcRRSetOutputPrimary, /* 30 */ + ProcRRGetOutputPrimary, /* 31 */ +}; + diff --git a/xorg-server/randr/rrinfo.c b/xorg-server/randr/rrinfo.c index faac15afb..fdf372607 100644 --- a/xorg-server/randr/rrinfo.c +++ b/xorg-server/randr/rrinfo.c @@ -1,341 +1,341 @@ -/* - * 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. - */ - -#include "randrstr.h" - -#ifdef RANDR_10_INTERFACE -static RRModePtr -RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) -{ - ScreenPtr pScreen = output->pScreen; - rrScrPriv(pScreen); - xRRModeInfo modeInfo; - char name[100]; - RRModePtr mode; - int i; - RRModePtr *modes; - - memset (&modeInfo, '\0', sizeof (modeInfo)); - sprintf (name, "%dx%d", size->width, size->height); - - modeInfo.width = size->width; - modeInfo.height = size->height; - modeInfo.hTotal = size->width; - modeInfo.vTotal = size->height; - modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * - (CARD32) refresh); - modeInfo.nameLength = strlen (name); - mode = RRModeGet (&modeInfo, name); - if (!mode) - return NULL; - for (i = 0; i < output->numModes; i++) - if (output->modes[i] == mode) - { - RRModeDestroy (mode); - return mode; - } - - if (output->numModes) - modes = realloc(output->modes, - (output->numModes + 1) * sizeof (RRModePtr)); - else - modes = malloc(sizeof (RRModePtr)); - if (!modes) - { - RRModeDestroy (mode); - FreeResource (mode->mode.id, 0); - return NULL; - } - modes[output->numModes++] = mode; - output->modes = modes; - output->changed = TRUE; - pScrPriv->changed = TRUE; - pScrPriv->configChanged = TRUE; - return mode; -} - -static void -RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) -{ - rrScrPriv(pScreen); - RROutputPtr output; - RRCrtcPtr crtc; - RRModePtr mode, newMode = NULL; - int i; - CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; - CARD16 maxWidth = 0, maxHeight = 0; - - /* - * First time through, create a crtc and output and hook - * them together - */ - if (pScrPriv->numOutputs == 0 && - pScrPriv->numCrtcs == 0) - { - crtc = RRCrtcCreate (pScreen, NULL); - if (!crtc) - return; - output = RROutputCreate (pScreen, "default", 7, NULL); - if (!output) - return; - RROutputSetCrtcs (output, &crtc, 1); - RROutputSetConnection (output, RR_Connected); - RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); - } - - output = pScrPriv->outputs[0]; - if (!output) - return; - crtc = pScrPriv->crtcs[0]; - if (!crtc) - return; - - /* check rotations */ - if (rotations != crtc->rotations) - { - crtc->rotations = rotations; - crtc->changed = TRUE; - pScrPriv->changed = TRUE; - } - - /* regenerate mode list */ - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr size = &pScrPriv->pSizes[i]; - int r; - - if (size->nRates) - { - for (r = 0; r < size->nRates; r++) - { - mode = RROldModeAdd (output, size, size->pRates[r].rate); - if (i == pScrPriv->size && - size->pRates[r].rate == pScrPriv->rate) - { - newMode = mode; - } - } - free(size->pRates); - } - else - { - mode = RROldModeAdd (output, size, 0); - if (i == pScrPriv->size) - newMode = mode; - } - } - if (pScrPriv->nSizes) - free(pScrPriv->pSizes); - pScrPriv->pSizes = NULL; - pScrPriv->nSizes = 0; - - /* find size bounds */ - for (i = 0; i < output->numModes + output->numUserModes; i++) - { - RRModePtr mode = (i < output->numModes ? - output->modes[i] : - output->userModes[i-output->numModes]); - CARD16 width = mode->mode.width; - CARD16 height = mode->mode.height; - - if (width < minWidth) minWidth = width; - if (width > maxWidth) maxWidth = width; - if (height < minHeight) minHeight = height; - if (height > maxHeight) maxHeight = height; - } - - RRScreenSetSizeRange (pScreen, minWidth, minHeight, maxWidth, maxHeight); - - /* notice current mode */ - if (newMode) - RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, - NULL, 1, &output, NULL); -} -#endif - -/* - * Poll the driver for changed information - */ -Bool -RRGetInfo (ScreenPtr pScreen, Bool force_query) -{ - rrScrPriv (pScreen); - Rotation rotations; - int i; - - /* Return immediately if we don't need to re-query and we already have the - * information. - */ - if (!force_query) { - if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0) - return TRUE; - } - - for (i = 0; i < pScrPriv->numOutputs; i++) - pScrPriv->outputs[i]->changed = FALSE; - for (i = 0; i < pScrPriv->numCrtcs; i++) - pScrPriv->crtcs[i]->changed = FALSE; - - rotations = 0; - pScrPriv->changed = FALSE; - pScrPriv->configChanged = FALSE; - - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - -#if RANDR_10_INTERFACE - if (pScrPriv->nSizes) - RRScanOldConfig (pScreen, rotations); -#endif - RRTellChanged (pScreen); - return TRUE; -} - -/* - * Register the range of sizes for the screen - */ -void -RRScreenSetSizeRange (ScreenPtr pScreen, - CARD16 minWidth, - CARD16 minHeight, - CARD16 maxWidth, - CARD16 maxHeight) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight && - pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) - { - return; - } - - pScrPriv->minWidth = minWidth; - pScrPriv->minHeight = minHeight; - pScrPriv->maxWidth = maxWidth; - pScrPriv->maxHeight = maxHeight; - pScrPriv->changed = TRUE; - pScrPriv->configChanged = TRUE; -} - -#ifdef RANDR_10_INTERFACE -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) -{ - if (a->width != b->width) - return FALSE; - if (a->height != b->height) - return FALSE; - if (a->mmWidth != b->mmWidth) - return FALSE; - if (a->mmHeight != b->mmHeight) - return FALSE; - return TRUE; -} - -RRScreenSizePtr -RRRegisterSize (ScreenPtr pScreen, - short width, - short height, - short mmWidth, - short mmHeight) -{ - rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; - - if (!pScrPriv) - return 0; - - tmp.id = 0; - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) - return &pScrPriv->pSizes[i]; - pNew = realloc(pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; -} - -Bool RRRegisterRate (ScreenPtr pScreen, - RRScreenSizePtr pSize, - int rate) -{ - rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; - - if (!pScrPriv) - return FALSE; - - for (i = 0; i < pSize->nRates; i++) - if (pSize->pRates[i].rate == rate) - return TRUE; - - pNew = realloc(pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) - return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pSize->pRates = pNew; - return TRUE; -} - -Rotation -RRGetRotation(ScreenPtr pScreen) -{ - RROutputPtr output = RRFirstOutput (pScreen); - - if (!output) - return RR_Rotate_0; - - return output->crtc->rotation; -} - -void -RRSetCurrentConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPriv (pScreen); - - if (!pScrPriv) - return; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rotation = rotation; - pScrPriv->rate = rate; -} -#endif +/* + * 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. + */ + +#include "randrstr.h" + +#ifdef RANDR_10_INTERFACE +static RRModePtr +RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) +{ + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); + xRRModeInfo modeInfo; + char name[100]; + RRModePtr mode; + int i; + RRModePtr *modes; + + memset (&modeInfo, '\0', sizeof (modeInfo)); + sprintf (name, "%dx%d", size->width, size->height); + + modeInfo.width = size->width; + modeInfo.height = size->height; + modeInfo.hTotal = size->width; + modeInfo.vTotal = size->height; + modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * + (CARD32) refresh); + modeInfo.nameLength = strlen (name); + mode = RRModeGet (&modeInfo, name); + if (!mode) + return NULL; + for (i = 0; i < output->numModes; i++) + if (output->modes[i] == mode) + { + RRModeDestroy (mode); + return mode; + } + + if (output->numModes) + modes = realloc(output->modes, + (output->numModes + 1) * sizeof (RRModePtr)); + else + modes = malloc(sizeof (RRModePtr)); + if (!modes) + { + RRModeDestroy (mode); + FreeResource (mode->mode.id, 0); + return NULL; + } + modes[output->numModes++] = mode; + output->modes = modes; + output->changed = TRUE; + pScrPriv->changed = TRUE; + pScrPriv->configChanged = TRUE; + return mode; +} + +static void +RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) +{ + rrScrPriv(pScreen); + RROutputPtr output; + RRCrtcPtr crtc; + RRModePtr mode, newMode = NULL; + int i; + CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; + CARD16 maxWidth = 0, maxHeight = 0; + + /* + * First time through, create a crtc and output and hook + * them together + */ + if (pScrPriv->numOutputs == 0 && + pScrPriv->numCrtcs == 0) + { + crtc = RRCrtcCreate (pScreen, NULL); + if (!crtc) + return; + output = RROutputCreate (pScreen, "default", 7, NULL); + if (!output) + return; + RROutputSetCrtcs (output, &crtc, 1); + RROutputSetConnection (output, RR_Connected); + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); + } + + output = pScrPriv->outputs[0]; + if (!output) + return; + crtc = pScrPriv->crtcs[0]; + if (!crtc) + return; + + /* check rotations */ + if (rotations != crtc->rotations) + { + crtc->rotations = rotations; + crtc->changed = TRUE; + pScrPriv->changed = TRUE; + } + + /* regenerate mode list */ + for (i = 0; i < pScrPriv->nSizes; i++) + { + RRScreenSizePtr size = &pScrPriv->pSizes[i]; + int r; + + if (size->nRates) + { + for (r = 0; r < size->nRates; r++) + { + mode = RROldModeAdd (output, size, size->pRates[r].rate); + if (i == pScrPriv->size && + size->pRates[r].rate == pScrPriv->rate) + { + newMode = mode; + } + } + free(size->pRates); + } + else + { + mode = RROldModeAdd (output, size, 0); + if (i == pScrPriv->size) + newMode = mode; + } + } + if (pScrPriv->nSizes) + free(pScrPriv->pSizes); + pScrPriv->pSizes = NULL; + pScrPriv->nSizes = 0; + + /* find size bounds */ + for (i = 0; i < output->numModes + output->numUserModes; i++) + { + RRModePtr mode = (i < output->numModes ? + output->modes[i] : + output->userModes[i-output->numModes]); + CARD16 width = mode->mode.width; + CARD16 height = mode->mode.height; + + if (width < minWidth) minWidth = width; + if (width > maxWidth) maxWidth = width; + if (height < minHeight) minHeight = height; + if (height > maxHeight) maxHeight = height; + } + + RRScreenSetSizeRange (pScreen, minWidth, minHeight, maxWidth, maxHeight); + + /* notice current mode */ + if (newMode) + RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, + NULL, 1, &output); +} +#endif + +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen, Bool force_query) +{ + rrScrPriv (pScreen); + Rotation rotations; + int i; + + /* Return immediately if we don't need to re-query and we already have the + * information. + */ + if (!force_query) { + if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0) + return TRUE; + } + + for (i = 0; i < pScrPriv->numOutputs; i++) + pScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pScrPriv->numCrtcs; i++) + pScrPriv->crtcs[i]->changed = FALSE; + + rotations = 0; + pScrPriv->changed = FALSE; + pScrPriv->configChanged = FALSE; + + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return FALSE; + +#if RANDR_10_INTERFACE + if (pScrPriv->nSizes) + RRScanOldConfig (pScreen, rotations); +#endif + RRTellChanged (pScreen); + return TRUE; +} + +/* + * Register the range of sizes for the screen + */ +void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight) +{ + rrScrPriv (pScreen); + + if (!pScrPriv) + return; + if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight && + pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) + { + return; + } + + pScrPriv->minWidth = minWidth; + pScrPriv->minHeight = minHeight; + pScrPriv->maxWidth = maxWidth; + pScrPriv->maxHeight = maxHeight; + pScrPriv->changed = TRUE; + pScrPriv->configChanged = TRUE; +} + +#ifdef RANDR_10_INTERFACE +static Bool +RRScreenSizeMatches (RRScreenSizePtr a, + RRScreenSizePtr b) +{ + if (a->width != b->width) + return FALSE; + if (a->height != b->height) + return FALSE; + if (a->mmWidth != b->mmWidth) + return FALSE; + if (a->mmHeight != b->mmHeight) + return FALSE; + return TRUE; +} + +RRScreenSizePtr +RRRegisterSize (ScreenPtr pScreen, + short width, + short height, + short mmWidth, + short mmHeight) +{ + rrScrPriv (pScreen); + int i; + RRScreenSize tmp; + RRScreenSizePtr pNew; + + if (!pScrPriv) + return 0; + + tmp.id = 0; + tmp.width = width; + tmp.height= height; + tmp.mmWidth = mmWidth; + tmp.mmHeight = mmHeight; + tmp.pRates = 0; + tmp.nRates = 0; + for (i = 0; i < pScrPriv->nSizes; i++) + if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) + return &pScrPriv->pSizes[i]; + pNew = realloc(pScrPriv->pSizes, + (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); + if (!pNew) + return 0; + pNew[pScrPriv->nSizes++] = tmp; + pScrPriv->pSizes = pNew; + return &pNew[pScrPriv->nSizes-1]; +} + +Bool RRRegisterRate (ScreenPtr pScreen, + RRScreenSizePtr pSize, + int rate) +{ + rrScrPriv(pScreen); + int i; + RRScreenRatePtr pNew, pRate; + + if (!pScrPriv) + return FALSE; + + for (i = 0; i < pSize->nRates; i++) + if (pSize->pRates[i].rate == rate) + return TRUE; + + pNew = realloc(pSize->pRates, + (pSize->nRates + 1) * sizeof (RRScreenRate)); + if (!pNew) + return FALSE; + pRate = &pNew[pSize->nRates++]; + pRate->rate = rate; + pSize->pRates = pNew; + return TRUE; +} + +Rotation +RRGetRotation(ScreenPtr pScreen) +{ + RROutputPtr output = RRFirstOutput (pScreen); + + if (!output) + return RR_Rotate_0; + + return output->crtc->rotation; +} + +void +RRSetCurrentConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + rrScrPriv (pScreen); + + if (!pScrPriv) + return; + pScrPriv->size = pSize - pScrPriv->pSizes; + pScrPriv->rotation = rotation; + pScrPriv->rate = rate; +} +#endif diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c index 0efc62e87..1bc1a9ea1 100644 --- a/xorg-server/randr/rrscreen.c +++ b/xorg-server/randr/rrscreen.c @@ -168,8 +168,6 @@ Bool RRScreenSizeSet (ScreenPtr pScreen, CARD16 width, CARD16 height, - CARD16 pixWidth, - CARD16 pixHeight, CARD32 mmWidth, CARD32 mmHeight) { @@ -180,7 +178,6 @@ RRScreenSizeSet (ScreenPtr pScreen, { return (*pScrPriv->rrScreenSetSize) (pScreen, width, height, - pixWidth, pixHeight, mmWidth, mmHeight); } #endif @@ -193,24 +190,6 @@ RRScreenSizeSet (ScreenPtr pScreen, return FALSE; } -/* - * Compute an RRScreenConfig from the current screen information - */ -void -RRScreenCurrentConfig(ScreenPtr screen, - RRScreenConfigPtr screen_config) -{ - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - WindowPtr root = screen->root; - - screen_config->screen_pixmap_width = screen_pixmap->drawable.width; - screen_config->screen_pixmap_height = screen_pixmap->drawable.height; - screen_config->screen_width = root->drawable.width; - screen_config->screen_height = root->drawable.height; - screen_config->mm_width = screen->mmWidth; - screen_config->mm_height = screen->mmHeight; -} - /* * Retrieve valid screen size range */ @@ -320,7 +299,6 @@ ProcRRSetScreenSize (ClientPtr client) return BadValue; } if (!RRScreenSizeSet (pScreen, - stuff->width, stuff->height, stuff->width, stuff->height, stuff->widthInMillimeters, stuff->heightInMillimeters)) @@ -798,10 +776,8 @@ ProcRRSetScreenConfig (ClientPtr client) } rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess); - if (rc != Success) { - client->errorValue = stuff->drawable; + if (rc != Success) return rc; - } pScreen = pDraw->pScreen; @@ -958,14 +934,14 @@ ProcRRSetScreenConfig (ClientPtr client) for (c = 0; c < pScrPriv->numCrtcs; c++) { if (!RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0, - 0, NULL, NULL)) + 0, NULL)) { rep.status = RRSetConfigFailed; /* XXX recover from failure */ goto sendReply; } } - if (!RRScreenSizeSet (pScreen, width, height, width, height, + if (!RRScreenSizeSet (pScreen, width, height, pScreen->mmWidth, pScreen->mmHeight)) { rep.status = RRSetConfigFailed; @@ -974,7 +950,7 @@ ProcRRSetScreenConfig (ClientPtr client) } } - if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output, NULL)) + if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output)) rep.status = RRSetConfigFailed; else { pScrPriv->lastSetTime = time; diff --git a/xorg-server/randr/rrsdispatch.c b/xorg-server/randr/rrsdispatch.c index 5c6978aa1..e16090a41 100644 --- a/xorg-server/randr/rrsdispatch.c +++ b/xorg-server/randr/rrsdispatch.c @@ -1,635 +1,503 @@ -/* - * 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. - */ - -#include "randrstr.h" - -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetScreenConfig (ClientPtr client) -{ - register int n; - REQUEST(xRRSetScreenConfigReq); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - swaps (&stuff->rate, n); - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - } - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->sizeID, n); - swaps(&stuff->rotation, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swaps(&stuff->enable, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenSizeRange (ClientPtr client) -{ - int n; - REQUEST(xRRGetScreenSizeRangeReq); - - REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetScreenSize (ClientPtr client) -{ - int n; - REQUEST(xRRSetScreenSizeReq); - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swapl(&stuff->widthInMillimeters, n); - swapl(&stuff->heightInMillimeters, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetScreenResources (ClientPtr client) -{ - int n; - REQUEST(xRRGetScreenResourcesReq); - - REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetOutputInfo (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputInfoReq); - - REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->configTimestamp, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRListOutputProperties (ClientPtr client) -{ - int n; - REQUEST(xRRListOutputPropertiesReq); - - REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRQueryOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRQueryOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRConfigureOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRConfigureOutputPropertyReq); - - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - SwapRestL(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRChangeOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRChangeOutputPropertyReq); - - REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - swapl(&stuff->type, n); - swapl(&stuff->nUnits, n); - switch(stuff->format) { - case 8: - break; - case 16: - SwapRestS(stuff); - break; - case 32: - SwapRestL(stuff); - break; - default: - client->errorValue = stuff->format; - return BadValue; - } - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDeleteOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRDeleteOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetOutputProperty (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->property, n); - swapl(&stuff->type, n); - swapl(&stuff->longOffset, n); - swapl(&stuff->longLength, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRCreateMode (ClientPtr client) -{ - int n; - xRRModeInfo *modeinfo; - REQUEST(xRRCreateModeReq); - - REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - - modeinfo = &stuff->modeInfo; - swapl(&modeinfo->id, n); - swaps(&modeinfo->width, n); - swaps(&modeinfo->height, n); - swapl(&modeinfo->dotClock, n); - swaps(&modeinfo->hSyncStart, n); - swaps(&modeinfo->hSyncEnd, n); - swaps(&modeinfo->hTotal, n); - swaps(&modeinfo->vSyncStart, n); - swaps(&modeinfo->vSyncEnd, n); - swaps(&modeinfo->vTotal, n); - swaps(&modeinfo->nameLength, n); - swapl(&modeinfo->modeFlags, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDestroyMode (ClientPtr client) -{ - int n; - REQUEST(xRRDestroyModeReq); - - REQUEST_SIZE_MATCH(xRRDestroyModeReq); - swaps(&stuff->length, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRAddOutputMode (ClientPtr client) -{ - int n; - REQUEST(xRRAddOutputModeReq); - - REQUEST_SIZE_MATCH(xRRAddOutputModeReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRDeleteOutputMode (ClientPtr client) -{ - int n; - REQUEST(xRRDeleteOutputModeReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); - swaps(&stuff->length, n); - swapl(&stuff->output, n); - swapl(&stuff->mode, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcInfo (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcInfoReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->configTimestamp, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcConfig (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcConfigReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->timestamp, n); - swapl(&stuff->configTimestamp, n); - swaps(&stuff->x, n); - swaps(&stuff->y, n); - swapl(&stuff->mode, n); - swaps(&stuff->rotation, n); - SwapRestL(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcGammaSize (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcGammaSizeReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcGamma (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcGammaReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcGamma (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcGammaReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swaps(&stuff->size, n); - SwapRestS(stuff); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetCrtcTransform (ClientPtr client) -{ - int n, nparams; - char *filter; - CARD32 *params; - REQUEST(xRRSetCrtcTransformReq); - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform))); - swaps(&stuff->nbytesFilter, n); - filter = (char *)(stuff + 1); - params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter)); - nparams = ((CARD32 *) stuff + client->req_len) - params; - if (nparams < 0) - return BadLength; - - SwapLongs(params, nparams); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetCrtcTransform (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcTransformReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRGetPanning (ClientPtr client) -{ - int n; - REQUEST(xRRGetPanningReq); - - REQUEST_SIZE_MATCH(xRRGetPanningReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetPanning (ClientPtr client) -{ - int n; - REQUEST(xRRSetPanningReq); - - REQUEST_SIZE_MATCH(xRRSetPanningReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swapl(&stuff->timestamp, n); - swaps(&stuff->left, n); - swaps(&stuff->top, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swaps(&stuff->track_left, n); - swaps(&stuff->track_top, n); - swaps(&stuff->track_width, n); - swaps(&stuff->track_height, n); - swaps(&stuff->border_left, n); - swaps(&stuff->border_top, n); - swaps(&stuff->border_right, n); - swaps(&stuff->border_bottom, n); - return (*ProcRandrVector[stuff->randrReqType]) (client); -} - -static int -SProcRRSetOutputPrimary (ClientPtr client) -{ - int n; - REQUEST(xRRSetOutputPrimaryReq); - - REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swapl(&stuff->output, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRGetOutputPrimary (ClientPtr client) -{ - int n; - REQUEST(xRRGetOutputPrimaryReq); - - REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRQueryScanoutPixmaps (ClientPtr client) -{ - int n; - REQUEST(xRRQueryScanoutPixmapsReq); - - REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq); - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRCreateScanoutPixmap (ClientPtr client) -{ - int n; - REQUEST(xRRCreateScanoutPixmapReq); - - REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq); - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swapl(&stuff->drawable, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swapl(&stuff->format, n); - swaps(&stuff->rotations, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static void -swap_transform(xRenderTransform *t) -{ - int n; - swapl(&t->matrix11, n); - swapl(&t->matrix12, n); - swapl(&t->matrix13, n); - swapl(&t->matrix21, n); - swapl(&t->matrix22, n); - swapl(&t->matrix23, n); - swapl(&t->matrix31, n); - swapl(&t->matrix32, n); - swapl(&t->matrix33, n); -} - -static int -SProcRRSetCrtcSpriteTransform (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcSpriteTransformReq); - - REQUEST_SIZE_MATCH(xRRSetCrtcSpriteTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - swap_transform(&stuff->positionTransform); - swap_transform(&stuff->imageTransform); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRGetCrtcSpriteTransform (ClientPtr client) -{ - int n; - REQUEST(xRRGetCrtcSpriteTransformReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcSpriteTransformReq); - swaps(&stuff->length, n); - swapl(&stuff->crtc, n); - return ProcRandrVector[stuff->randrReqType](client); -} - -static int -SProcRRSetCrtcConfigs (ClientPtr client) -{ - int n; - REQUEST(xRRSetCrtcConfigsReq); - int c; - int extra_len; - int num_configs; - int num_output_ids; - xRRCrtcConfig *x_configs; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq); - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - swaps(&stuff->screenPixmapWidth, n); - swaps(&stuff->screenPixmapHeight, n); - swaps(&stuff->screenWidth, n); - swaps(&stuff->screenHeight, n); - swapl(&stuff->widthInMillimeters, n); - swapl(&stuff->heightInMillimeters, n); - swaps(&stuff->nConfigs, n); - - extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq)); - - num_configs = stuff->nConfigs; - - /* Check request length against number of configs specified */ - if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len) - return BadLength; - - x_configs = (xRRCrtcConfig *) (stuff + 1); - for (c = 0; c < num_configs; c++) { - swapl(&x_configs->crtc, n); - swaps(&x_configs->x, n); - swaps(&x_configs->y, n); - swapl(&x_configs->mode, n); - swaps(&x_configs->rotation, n); - swaps(&x_configs->nOutput, n); - swap_transform(&x_configs->spritePositionTransform); - swap_transform(&x_configs->spriteImageTransform); - swapl(&x_configs->pixmap, n); - swaps(&x_configs->xPixmap, n); - swaps(&x_configs->yPixmap, n); - x_configs++; - } - - /* Let the other dispatch function deal with verifying that - * the right number of output ids are present, just - * swap whatever is here - */ - num_output_ids = extra_len - (num_configs * (sizeof (xRRCrtcConfig)) >> 2); - SwapLongs((CARD32 *) x_configs, num_output_ids); - - return ProcRandrVector[stuff->randrReqType](client); -} - -int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { - SProcRRQueryVersion, /* 0 */ -/* we skip 1 to make old clients fail pretty immediately */ - NULL, /* 1 SProcRandrOldGetScreenInfo */ -/* V1.0 apps share the same set screen config request id */ - SProcRRSetScreenConfig, /* 2 */ - NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ -/* 3 used to be ScreenChangeSelectInput; deprecated */ - SProcRRSelectInput, /* 4 */ - SProcRRGetScreenInfo, /* 5 */ -/* V1.2 additions */ - SProcRRGetScreenSizeRange, /* 6 */ - SProcRRSetScreenSize, /* 7 */ - SProcRRGetScreenResources, /* 8 */ - SProcRRGetOutputInfo, /* 9 */ - SProcRRListOutputProperties,/* 10 */ - SProcRRQueryOutputProperty, /* 11 */ - SProcRRConfigureOutputProperty, /* 12 */ - SProcRRChangeOutputProperty,/* 13 */ - SProcRRDeleteOutputProperty,/* 14 */ - SProcRRGetOutputProperty, /* 15 */ - SProcRRCreateMode, /* 16 */ - SProcRRDestroyMode, /* 17 */ - SProcRRAddOutputMode, /* 18 */ - SProcRRDeleteOutputMode, /* 19 */ - SProcRRGetCrtcInfo, /* 20 */ - SProcRRSetCrtcConfig, /* 21 */ - SProcRRGetCrtcGammaSize, /* 22 */ - SProcRRGetCrtcGamma, /* 23 */ - SProcRRSetCrtcGamma, /* 24 */ -/* V1.3 additions */ - SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */ - SProcRRSetCrtcTransform, /* 26 */ - SProcRRGetCrtcTransform, /* 27 */ - SProcRRGetPanning, /* 28 */ - SProcRRSetPanning, /* 29 */ - SProcRRSetOutputPrimary, /* 30 */ - SProcRRGetOutputPrimary, /* 31 */ -/* V1.4 additions */ - SProcRRQueryScanoutPixmaps, /* 32 */ - SProcRRCreateScanoutPixmap, /* 33 */ - SProcRRSetCrtcSpriteTransform,/* 34 */ - SProcRRGetCrtcSpriteTransform,/* 35 */ - SProcRRSetCrtcConfigs, /* 36 */ -}; - +/* + * 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. + */ + +#include "randrstr.h" + +static int +SProcRRQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRRQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenInfo (ClientPtr client) +{ + register int n; + REQUEST(xRRGetScreenInfoReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenConfig (ClientPtr client) +{ + register int n; + REQUEST(xRRSetScreenConfigReq); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + swaps (&stuff->rate, n); + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + } + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->sizeID, n); + swaps(&stuff->rotation, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSelectInput (ClientPtr client) +{ + register int n; + REQUEST(xRRSelectInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->enable, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenSizeRange (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenSizeRangeReq); + + REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetScreenSize (ClientPtr client) +{ + int n; + REQUEST(xRRSetScreenSizeReq); + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swapl(&stuff->widthInMillimeters, n); + swapl(&stuff->heightInMillimeters, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenResources (ClientPtr client) +{ + int n; + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputInfoReq); + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRListOutputProperties (ClientPtr client) +{ + int n; + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRQueryOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRQueryOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRConfigureOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRConfigureOutputPropertyReq); + + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRChangeOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_AT_LEAST_SIZE (xRRChangeOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->nUnits, n); + switch(stuff->format) { + case 8: + break; + case 16: + SwapRestS(stuff); + break; + case 32: + SwapRestL(stuff); + break; + default: + client->errorValue = stuff->format; + return BadValue; + } + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetOutputProperty (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->property, n); + swapl(&stuff->type, n); + swapl(&stuff->longOffset, n); + swapl(&stuff->longLength, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRCreateMode (ClientPtr client) +{ + int n; + xRRModeInfo *modeinfo; + REQUEST(xRRCreateModeReq); + + REQUEST_AT_LEAST_SIZE(xRRCreateModeReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + + modeinfo = &stuff->modeInfo; + swapl(&modeinfo->id, n); + swaps(&modeinfo->width, n); + swaps(&modeinfo->height, n); + swapl(&modeinfo->dotClock, n); + swaps(&modeinfo->hSyncStart, n); + swaps(&modeinfo->hSyncEnd, n); + swaps(&modeinfo->hTotal, n); + swaps(&modeinfo->vSyncStart, n); + swaps(&modeinfo->vSyncEnd, n); + swaps(&modeinfo->vTotal, n); + swaps(&modeinfo->nameLength, n); + swapl(&modeinfo->modeFlags, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDestroyMode (ClientPtr client) +{ + int n; + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + swaps(&stuff->length, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRAddOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRDeleteOutputMode (ClientPtr client) +{ + int n; + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + swaps(&stuff->length, n); + swapl(&stuff->output, n); + swapl(&stuff->mode, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcInfo (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->configTimestamp, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcConfig (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcConfigReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swapl(&stuff->configTimestamp, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + swapl(&stuff->mode, n); + swaps(&stuff->rotation, n); + SwapRestL(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGammaSize (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcGamma (ClientPtr client) +{ + int n; + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swaps(&stuff->size, n); + SwapRestS(stuff); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetCrtcTransform (ClientPtr client) +{ + int n, nparams; + char *filter; + CARD32 *params; + REQUEST(xRRSetCrtcTransformReq); + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + SwapLongs((CARD32 *)&stuff->transform, bytes_to_int32(sizeof(xRenderTransform))); + swaps(&stuff->nbytesFilter, n); + filter = (char *)(stuff + 1); + params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter)); + nparams = ((CARD32 *) stuff + client->req_len) - params; + if (nparams < 0) + return BadLength; + + SwapLongs(params, nparams); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetCrtcTransform (ClientPtr client) +{ + int n; + REQUEST(xRRGetCrtcTransformReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetPanning (ClientPtr client) +{ + int n; + REQUEST(xRRGetPanningReq); + + REQUEST_SIZE_MATCH(xRRGetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetPanning (ClientPtr client) +{ + int n; + REQUEST(xRRSetPanningReq); + + REQUEST_SIZE_MATCH(xRRSetPanningReq); + swaps(&stuff->length, n); + swapl(&stuff->crtc, n); + swapl(&stuff->timestamp, n); + swaps(&stuff->left, n); + swaps(&stuff->top, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + swaps(&stuff->track_left, n); + swaps(&stuff->track_top, n); + swaps(&stuff->track_width, n); + swaps(&stuff->track_height, n); + swaps(&stuff->border_left, n); + swaps(&stuff->border_top, n); + swaps(&stuff->border_right, n); + swaps(&stuff->border_bottom, n); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRSetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRSetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->output, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +static int +SProcRRGetOutputPrimary (ClientPtr client) +{ + int n; + REQUEST(xRRGetOutputPrimaryReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq); + swaps(&stuff->length, n); + swapl(&stuff->window, n); + return ProcRandrVector[stuff->randrReqType](client); +} + +int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { + SProcRRQueryVersion, /* 0 */ +/* we skip 1 to make old clients fail pretty immediately */ + NULL, /* 1 SProcRandrOldGetScreenInfo */ +/* V1.0 apps share the same set screen config request id */ + SProcRRSetScreenConfig, /* 2 */ + NULL, /* 3 SProcRandrOldScreenChangeSelectInput */ +/* 3 used to be ScreenChangeSelectInput; deprecated */ + SProcRRSelectInput, /* 4 */ + SProcRRGetScreenInfo, /* 5 */ +/* V1.2 additions */ + SProcRRGetScreenSizeRange, /* 6 */ + SProcRRSetScreenSize, /* 7 */ + SProcRRGetScreenResources, /* 8 */ + SProcRRGetOutputInfo, /* 9 */ + SProcRRListOutputProperties,/* 10 */ + SProcRRQueryOutputProperty, /* 11 */ + SProcRRConfigureOutputProperty, /* 12 */ + SProcRRChangeOutputProperty,/* 13 */ + SProcRRDeleteOutputProperty,/* 14 */ + SProcRRGetOutputProperty, /* 15 */ + SProcRRCreateMode, /* 16 */ + SProcRRDestroyMode, /* 17 */ + SProcRRAddOutputMode, /* 18 */ + SProcRRDeleteOutputMode, /* 19 */ + SProcRRGetCrtcInfo, /* 20 */ + SProcRRSetCrtcConfig, /* 21 */ + SProcRRGetCrtcGammaSize, /* 22 */ + SProcRRGetCrtcGamma, /* 23 */ + SProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */ + SProcRRSetCrtcTransform, /* 26 */ + SProcRRGetCrtcTransform, /* 27 */ + SProcRRGetPanning, /* 28 */ + SProcRRSetPanning, /* 29 */ + SProcRRSetOutputPrimary, /* 30 */ + SProcRRGetOutputPrimary, /* 31 */ +}; + diff --git a/xorg-server/randr/rrtransform.c b/xorg-server/randr/rrtransform.c index f78d5f913..e1620498b 100644 --- a/xorg-server/randr/rrtransform.c +++ b/xorg-server/randr/rrtransform.c @@ -1,337 +1,283 @@ -/* - * Copyright © 2007 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. - */ - -#include "randrstr.h" -#include "rrtransform.h" - -void -RRTransformInit (RRTransformPtr transform) -{ - pixman_transform_init_identity (&transform->transform); - pixman_f_transform_init_identity (&transform->f_transform); - pixman_f_transform_init_identity (&transform->f_inverse); - transform->filter = NULL; - transform->params = NULL; - transform->nparams = 0; -} - -void -RRTransformFini (RRTransformPtr transform) -{ - free(transform->params); -} - -Bool -RRTransformEqual (RRTransformPtr a, RRTransformPtr b) -{ - if (a && pixman_transform_is_identity (&a->transform)) - a = NULL; - if (b && pixman_transform_is_identity (&b->transform)) - b = NULL; - if (a == NULL && b == NULL) - return TRUE; - if (a == NULL || b == NULL) - return FALSE; - if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0) - return FALSE; - if (a->filter != b->filter) - return FALSE; - if (a->nparams != b->nparams) - return FALSE; - if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0) - return FALSE; - return TRUE; -} - -Bool -RRTransformSetFilter (RRTransformPtr dst, - PictFilterPtr filter, - xFixed *params, - int nparams, - int width, - int height) -{ - xFixed *new_params; - - if (nparams) - { - new_params = malloc(nparams * sizeof (xFixed)); - if (!new_params) - return FALSE; - memcpy (new_params, params, nparams * sizeof (xFixed)); - } - else - new_params = NULL; - free(dst->params); - dst->filter = filter; - dst->params = new_params; - dst->nparams = nparams; - dst->width = width; - dst->height = height; - return TRUE; -} - -Bool -RRTransformCopy (RRTransformPtr dst, RRTransformPtr src) -{ - if (src && pixman_transform_is_identity (&src->transform)) - src = NULL; - - if (src) - { - if (!RRTransformSetFilter (dst, src->filter, - src->params, src->nparams, src->width, src->height)) - return FALSE; - dst->transform = src->transform; - dst->f_transform = src->f_transform; - dst->f_inverse = src->f_inverse; - } - else - { - if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0)) - return FALSE; - pixman_transform_init_identity (&dst->transform); - pixman_f_transform_init_identity (&dst->f_transform); - pixman_f_transform_init_identity (&dst->f_inverse); - } - return TRUE; -} - -#define F(x) IntToxFixed(x) - -static void -RRTransformRescale(struct pixman_f_transform *f_transform, double limit) -{ - double max = 0, v, scale; - int i, j; - - for (j = 0; j < 3; j++) - for (i = 0; i < 3; i++) - if ((v = abs (f_transform->m[j][i])) > max) - max = v; - scale = limit / max; - for (j = 0; j < 3; j++) - for (i = 0; i < 3; i++) - f_transform->m[j][i] *= scale; -} - -#define EPSILON (1e-20) -#define IS_F_SAME(a,b) (fabs((a)-(b)) < EPSILON) -#define IS_F_ZERO(a) (fabs(a) < EPSILON) - -static Bool -pict_f_transform_is_identity (const struct pixman_f_transform *t) -{ - return (IS_F_SAME (t->m[0][0], t->m[1][1]) && - IS_F_SAME (t->m[0][0], t->m[2][2]) && - !IS_F_ZERO (t->m[0][0]) && - IS_F_ZERO (t->m[0][1]) && - IS_F_ZERO (t->m[0][2]) && - IS_F_ZERO (t->m[1][0]) && - IS_F_ZERO (t->m[1][2]) && - IS_F_ZERO (t->m[2][0]) && - IS_F_ZERO (t->m[2][1])); -} - -/* - * Compute the complete transformation matrix including - * client-specified transform, rotation/reflection values and the crtc - * offset. - * - * Return TRUE if the resulting transform is not a simple translation. - */ -Bool -RRTransformCompute (int x, - int y, - int width, - int height, - Rotation rotation, - RRTransformPtr rr_transform, - struct pixman_f_transform *sprite_position_transform, - struct pixman_f_transform *sprite_image_transform, - - PictTransformPtr transform, - struct pixman_f_transform *f_transform, - struct pixman_f_transform *f_inverse, - struct pixman_f_transform *f_fb_to_sprite, - struct pixman_f_transform *f_sprite_to_image, - Bool *sprite_transform_in_use) -{ - PictTransform t_transform, inverse; - struct pixman_f_transform tf_transform, tf_inverse; - struct pixman_f_transform sf_position_transform, sf_image_transform; - struct pixman_f_transform f_image_to_sprite; - Bool overflow = FALSE; - Bool ret = TRUE; - - if (!transform) transform = &t_transform; - if (!f_transform) f_transform = &tf_transform; - if (!f_inverse) f_inverse = &tf_inverse; - if (!f_fb_to_sprite) f_fb_to_sprite = &sf_position_transform; - if (!f_sprite_to_image) f_sprite_to_image = &sf_image_transform; - - /* invert the sprite image transform to have it go from dest to source */ - if (!pixman_f_transform_invert (&f_image_to_sprite, f_sprite_to_image)) - pixman_f_transform_init_identity(&f_image_to_sprite); - - pixman_transform_init_identity (transform); - pixman_transform_init_identity (&inverse); - pixman_f_transform_init_identity (f_transform); - pixman_f_transform_init_identity (f_inverse); - pixman_f_transform_init_identity (f_fb_to_sprite); - pixman_f_transform_init_identity (f_sprite_to_image); - if (rotation != RR_Rotate_0) - { - double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; - double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy; - xFixed rot_cos, rot_sin, rot_dx, rot_dy; - xFixed scale_x, scale_y, scale_dx, scale_dy; - - /* rotation */ - switch (rotation & 0xf) { - default: - case RR_Rotate_0: - f_rot_cos = 1; f_rot_sin = 0; - f_rot_dx = 0; f_rot_dy = 0; - rot_cos = F ( 1); rot_sin = F ( 0); - rot_dx = F ( 0); rot_dy = F ( 0); - break; - case RR_Rotate_90: - f_rot_cos = 0; f_rot_sin = 1; - f_rot_dx = height; f_rot_dy = 0; - rot_cos = F ( 0); rot_sin = F ( 1); - rot_dx = F ( height); rot_dy = F (0); - break; - case RR_Rotate_180: - f_rot_cos = -1; f_rot_sin = 0; - f_rot_dx = width; f_rot_dy = height; - rot_cos = F (-1); rot_sin = F ( 0); - rot_dx = F (width); rot_dy = F ( height); - break; - case RR_Rotate_270: - f_rot_cos = 0; f_rot_sin = -1; - f_rot_dx = 0; f_rot_dy = width; - rot_cos = F ( 0); rot_sin = F (-1); - rot_dx = F ( 0); rot_dy = F ( width); - break; - } - - pixman_transform_rotate (transform, &inverse, rot_cos, rot_sin); - pixman_transform_translate (transform, &inverse, rot_dx, rot_dy); - pixman_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin); - pixman_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy); - - /* reflection */ - f_scale_x = 1; - f_scale_dx = 0; - f_scale_y = 1; - f_scale_dy = 0; - scale_x = F (1); - scale_dx = 0; - scale_y = F (1); - scale_dy = 0; - if (rotation & RR_Reflect_X) - { - f_scale_x = -1; - scale_x = F(-1); - if (rotation & (RR_Rotate_0|RR_Rotate_180)) { - f_scale_dx = width; - scale_dx = F(width); - } else { - f_scale_dx = height; - scale_dx = F(height); - } - } - if (rotation & RR_Reflect_Y) - { - f_scale_y = -1; - scale_y = F(-1); - if (rotation & (RR_Rotate_0|RR_Rotate_180)) { - f_scale_dy = height; - scale_dy = F(height); - } else { - f_scale_dy = width; - scale_dy = F(width); - } - } - - pixman_transform_scale (transform, &inverse, scale_x, scale_y); - pixman_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y); - pixman_transform_translate (transform, &inverse, scale_dx, scale_dy); - pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy); - } - - /* - * Sprite position is affected by the transform matrix, - * but the image is not - */ - pixman_f_transform_multiply(f_sprite_to_image, - f_transform, - &f_image_to_sprite); - - if (rr_transform) - { - if (!pixman_transform_multiply (transform, &rr_transform->transform, transform)) - overflow = TRUE; - pixman_f_transform_multiply (f_transform, &rr_transform->f_transform, f_transform); - pixman_f_transform_multiply (f_inverse, f_inverse, &rr_transform->f_inverse); - } - - /* - * Compute the class of the resulting transform - */ - if (!overflow && pixman_transform_is_identity (transform)) - { - pixman_transform_init_translate (transform, F ( x), F ( y)); - - pixman_f_transform_init_translate (f_transform, x, y); - pixman_f_transform_init_translate (f_inverse, -x, -y); - ret = FALSE; - } - else - { - pixman_f_transform_translate (f_transform, f_inverse, x, y); - if (!pixman_transform_translate (transform, &inverse, F(x), F(y))) - overflow = TRUE; - if (overflow) - { - struct pixman_f_transform f_scaled; - f_scaled = *f_transform; - RRTransformRescale(&f_scaled, 16384.0); - pixman_transform_from_pixman_f_transform(transform, &f_scaled); - } - ret = TRUE; - } - - /* - * Sprite position is affected by the transform matrix, - * but the image is not - */ - pixman_f_transform_multiply(f_fb_to_sprite, - f_inverse, - sprite_position_transform); - if (sprite_transform_in_use) - *sprite_transform_in_use = ret || !pict_f_transform_is_identity(f_fb_to_sprite); - return ret; -} - - +/* + * Copyright © 2007 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. + */ + +#include "randrstr.h" +#include "rrtransform.h" + +void +RRTransformInit (RRTransformPtr transform) +{ + pixman_transform_init_identity (&transform->transform); + pixman_f_transform_init_identity (&transform->f_transform); + pixman_f_transform_init_identity (&transform->f_inverse); + transform->filter = NULL; + transform->params = NULL; + transform->nparams = 0; +} + +void +RRTransformFini (RRTransformPtr transform) +{ + free(transform->params); +} + +Bool +RRTransformEqual (RRTransformPtr a, RRTransformPtr b) +{ + if (a && pixman_transform_is_identity (&a->transform)) + a = NULL; + if (b && pixman_transform_is_identity (&b->transform)) + b = NULL; + if (a == NULL && b == NULL) + return TRUE; + if (a == NULL || b == NULL) + return FALSE; + if (memcmp (&a->transform, &b->transform, sizeof (a->transform)) != 0) + return FALSE; + if (a->filter != b->filter) + return FALSE; + if (a->nparams != b->nparams) + return FALSE; + if (memcmp (a->params, b->params, a->nparams * sizeof (xFixed)) != 0) + return FALSE; + return TRUE; +} + +Bool +RRTransformSetFilter (RRTransformPtr dst, + PictFilterPtr filter, + xFixed *params, + int nparams, + int width, + int height) +{ + xFixed *new_params; + + if (nparams) + { + new_params = malloc(nparams * sizeof (xFixed)); + if (!new_params) + return FALSE; + memcpy (new_params, params, nparams * sizeof (xFixed)); + } + else + new_params = NULL; + free(dst->params); + dst->filter = filter; + dst->params = new_params; + dst->nparams = nparams; + dst->width = width; + dst->height = height; + return TRUE; +} + +Bool +RRTransformCopy (RRTransformPtr dst, RRTransformPtr src) +{ + if (src && pixman_transform_is_identity (&src->transform)) + src = NULL; + + if (src) + { + if (!RRTransformSetFilter (dst, src->filter, + src->params, src->nparams, src->width, src->height)) + return FALSE; + dst->transform = src->transform; + dst->f_transform = src->f_transform; + dst->f_inverse = src->f_inverse; + } + else + { + if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0)) + return FALSE; + pixman_transform_init_identity (&dst->transform); + pixman_f_transform_init_identity (&dst->f_transform); + pixman_f_transform_init_identity (&dst->f_inverse); + } + return TRUE; +} + +#define F(x) IntToxFixed(x) + +static void +RRTransformRescale(struct pixman_f_transform *f_transform, double limit) +{ + double max = 0, v, scale; + int i, j; + + for (j = 0; j < 3; j++) + for (i = 0; i < 3; i++) + if ((v = abs (f_transform->m[j][i])) > max) + max = v; + scale = limit / max; + for (j = 0; j < 3; j++) + for (i = 0; i < 3; i++) + f_transform->m[j][i] *= scale; +} + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + + PictTransformPtr transform, + struct pixman_f_transform *f_transform, + struct pixman_f_transform *f_inverse) +{ + PictTransform t_transform, inverse; + struct pixman_f_transform tf_transform, tf_inverse; + Bool overflow = FALSE; + + if (!transform) transform = &t_transform; + if (!f_transform) f_transform = &tf_transform; + if (!f_inverse) f_inverse = &tf_inverse; + + pixman_transform_init_identity (transform); + pixman_transform_init_identity (&inverse); + pixman_f_transform_init_identity (f_transform); + pixman_f_transform_init_identity (f_inverse); + if (rotation != RR_Rotate_0) + { + double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy; + double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy; + xFixed rot_cos, rot_sin, rot_dx, rot_dy; + xFixed scale_x, scale_y, scale_dx, scale_dy; + + /* rotation */ + switch (rotation & 0xf) { + default: + case RR_Rotate_0: + f_rot_cos = 1; f_rot_sin = 0; + f_rot_dx = 0; f_rot_dy = 0; + rot_cos = F ( 1); rot_sin = F ( 0); + rot_dx = F ( 0); rot_dy = F ( 0); + break; + case RR_Rotate_90: + f_rot_cos = 0; f_rot_sin = 1; + f_rot_dx = height; f_rot_dy = 0; + rot_cos = F ( 0); rot_sin = F ( 1); + rot_dx = F ( height); rot_dy = F (0); + break; + case RR_Rotate_180: + f_rot_cos = -1; f_rot_sin = 0; + f_rot_dx = width; f_rot_dy = height; + rot_cos = F (-1); rot_sin = F ( 0); + rot_dx = F (width); rot_dy = F ( height); + break; + case RR_Rotate_270: + f_rot_cos = 0; f_rot_sin = -1; + f_rot_dx = 0; f_rot_dy = width; + rot_cos = F ( 0); rot_sin = F (-1); + rot_dx = F ( 0); rot_dy = F ( width); + break; + } + + pixman_transform_rotate (transform, &inverse, rot_cos, rot_sin); + pixman_transform_translate (transform, &inverse, rot_dx, rot_dy); + pixman_f_transform_rotate (f_transform, f_inverse, f_rot_cos, f_rot_sin); + pixman_f_transform_translate (f_transform, f_inverse, f_rot_dx, f_rot_dy); + + /* reflection */ + f_scale_x = 1; + f_scale_dx = 0; + f_scale_y = 1; + f_scale_dy = 0; + scale_x = F (1); + scale_dx = 0; + scale_y = F (1); + scale_dy = 0; + if (rotation & RR_Reflect_X) + { + f_scale_x = -1; + scale_x = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) { + f_scale_dx = width; + scale_dx = F(width); + } else { + f_scale_dx = height; + scale_dx = F(height); + } + } + if (rotation & RR_Reflect_Y) + { + f_scale_y = -1; + scale_y = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) { + f_scale_dy = height; + scale_dy = F(height); + } else { + f_scale_dy = width; + scale_dy = F(width); + } + } + + pixman_transform_scale (transform, &inverse, scale_x, scale_y); + pixman_f_transform_scale (f_transform, f_inverse, f_scale_x, f_scale_y); + pixman_transform_translate (transform, &inverse, scale_dx, scale_dy); + pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy); + } + +#ifdef RANDR_12_INTERFACE + if (rr_transform) + { + if (!pixman_transform_multiply (transform, &rr_transform->transform, transform)) + overflow = TRUE; + pixman_f_transform_multiply (f_transform, &rr_transform->f_transform, f_transform); + pixman_f_transform_multiply (f_inverse, f_inverse, &rr_transform->f_inverse); + } +#endif + /* + * Compute the class of the resulting transform + */ + if (!overflow && pixman_transform_is_identity (transform)) + { + pixman_transform_init_translate (transform, F ( x), F ( y)); + + pixman_f_transform_init_translate (f_transform, x, y); + pixman_f_transform_init_translate (f_inverse, -x, -y); + return FALSE; + } + else + { + pixman_f_transform_translate (f_transform, f_inverse, x, y); + if (!pixman_transform_translate (transform, &inverse, F(x), F(y))) + overflow = TRUE; + if (overflow) + { + struct pixman_f_transform f_scaled; + f_scaled = *f_transform; + RRTransformRescale(&f_scaled, 16384.0); + pixman_transform_from_pixman_f_transform(transform, &f_scaled); + } + return TRUE; + } +} diff --git a/xorg-server/randr/rrtransform.h b/xorg-server/randr/rrtransform.h index eaced0d3e..561762dfe 100644 --- a/xorg-server/randr/rrtransform.h +++ b/xorg-server/randr/rrtransform.h @@ -1,86 +1,75 @@ -/* - * Copyright © 2007 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. - */ - -#ifndef _RRTRANSFORM_H_ -#define _RRTRANSFORM_H_ - -#include -#include "picturestr.h" - -typedef struct _rrTransform RRTransformRec, *RRTransformPtr; - -struct _rrTransform { - PictTransform transform; - struct pict_f_transform f_transform; - struct pict_f_transform f_inverse; - PictFilterPtr filter; - xFixed *params; - int nparams; - int width; - int height; -}; - -extern _X_EXPORT void -RRTransformInit (RRTransformPtr transform); - -extern _X_EXPORT void -RRTransformFini (RRTransformPtr transform); - -extern _X_EXPORT Bool -RRTransformEqual (RRTransformPtr a, RRTransformPtr b); - -extern _X_EXPORT Bool -RRTransformSetFilter (RRTransformPtr dst, - PictFilterPtr filter, - xFixed *params, - int nparams, - int width, - int height); - -extern _X_EXPORT Bool -RRTransformCopy (RRTransformPtr dst, RRTransformPtr src); - -/* - * Compute the complete transformation matrix including - * client-specified transform, rotation/reflection values and the crtc - * offset. - * - * Return TRUE if the resulting transform is not a simple translation. - */ -extern _X_EXPORT Bool -RRTransformCompute (int x, - int y, - int width, - int height, - Rotation rotation, - RRTransformPtr rr_transform, - struct pict_f_transform *sprite_position_transform, - struct pict_f_transform *sprite_image_transform, - - PictTransformPtr transform, - struct pict_f_transform *f_transform, - struct pict_f_transform *f_inverse, - struct pict_f_transform *f_fb_to_sprite, - struct pict_f_transform *f_sprite_to_image, - Bool *sprite_transform_in_use); - -#endif /* _RRTRANSFORM_H_ */ +/* + * Copyright © 2007 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. + */ + +#ifndef _RRTRANSFORM_H_ +#define _RRTRANSFORM_H_ + +#include +#include "picturestr.h" + +typedef struct _rrTransform RRTransformRec, *RRTransformPtr; + +struct _rrTransform { + PictTransform transform; + struct pict_f_transform f_transform; + struct pict_f_transform f_inverse; + PictFilterPtr filter; + xFixed *params; + int nparams; + int width; + int height; +}; + +extern _X_EXPORT void +RRTransformInit (RRTransformPtr transform); + +extern _X_EXPORT void +RRTransformFini (RRTransformPtr transform); + +extern _X_EXPORT Bool +RRTransformEqual (RRTransformPtr a, RRTransformPtr b); + +extern _X_EXPORT Bool +RRTransformSetFilter (RRTransformPtr dst, + PictFilterPtr filter, + xFixed *params, + int nparams, + int width, + int height); + +extern _X_EXPORT Bool +RRTransformCopy (RRTransformPtr dst, RRTransformPtr src); + +extern _X_EXPORT Bool +RRTransformCompute (int x, + int y, + int width, + int height, + Rotation rotation, + RRTransformPtr rr_transform, + + PictTransformPtr transform, + struct pict_f_transform *f_transform, + struct pict_f_transform *f_inverse); + + +#endif /* _RRTRANSFORM_H_ */ -- cgit v1.2.3 From 8268836508edd4ba2a3045c9ba937397df7bf2c5 Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 25 Feb 2011 07:48:53 +0000 Subject: Forgotten in previous commit --- xorg-server/randr/mirrcrtc.c | 174 ------------------------------------------- xorg-server/randr/rrpixmap.c | 154 -------------------------------------- xorg-server/randr/rrsprite.c | 104 -------------------------- 3 files changed, 432 deletions(-) delete mode 100644 xorg-server/randr/mirrcrtc.c delete mode 100644 xorg-server/randr/rrpixmap.c delete mode 100644 xorg-server/randr/rrsprite.c (limited to 'xorg-server/randr') diff --git a/xorg-server/randr/mirrcrtc.c b/xorg-server/randr/mirrcrtc.c deleted file mode 100644 index 812b2b68b..000000000 --- a/xorg-server/randr/mirrcrtc.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright © 2010 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. - */ - -#include "randrstr.h" - -Bool -miRRSetScreenConfig(ScreenPtr screen, - RRScreenConfigPtr screen_config) -{ - RRScreenConfigRec old_screen_config; - - RRScreenCurrentConfig(screen, &old_screen_config); - - /* Check and see if nothing has changed */ - if (old_screen_config.screen_width == screen_config->screen_width && - old_screen_config.screen_height == screen_config->screen_height && - old_screen_config.screen_pixmap_width == screen_config->screen_pixmap_width && - old_screen_config.screen_pixmap_height == screen_config->screen_pixmap_height && - old_screen_config.mm_width == screen_config->mm_width && - old_screen_config.mm_height == screen_config->mm_height) - return TRUE; - - return RRScreenSizeSet(screen, - screen_config->screen_width, - screen_config->screen_height, - screen_config->screen_pixmap_width, - screen_config->screen_pixmap_height, - screen_config->mm_width, - screen_config->mm_height); -} - -Bool -miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config) -{ - int x = crtc_config->x, y = crtc_config->y; - - if (crtc_config->pixmap) { - x = crtc_config->pixmap_x; - y = crtc_config->pixmap_y; - } - if (!RRCrtcSet(crtc_config->crtc, - crtc_config->mode, - x, - y, - crtc_config->rotation, - crtc_config->numOutputs, - crtc_config->outputs, - crtc_config->pixmap)) - return FALSE; - RRCrtcSpriteTransformSet(crtc_config->crtc, - &crtc_config->sprite_position_transform, - &crtc_config->sprite_image_transform, - &crtc_config->sprite_position_f_transform, - &crtc_config->sprite_image_f_transform); - return TRUE; -} - -Bool -miRRDisableCrtc(RRCrtcPtr crtc) -{ - RRCrtcConfigRec off_config; - - memset(&off_config, '\0', sizeof (RRCrtcConfigRec)); - off_config.crtc = crtc; - return miRRSetCrtcConfig(&off_config); -} - -/* - * If the current crtc configuration doesn't fit - * with the new screen config, disable it - */ -Bool -miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config, - RRCrtcConfigPtr old_crtc_config) -{ - RRCrtcPtr crtc = old_crtc_config->crtc; - - /* If it's already disabled, we're done */ - if (!old_crtc_config->mode) - return TRUE; - - /* If the crtc isn't scanning from the screen pixmap, - * we're done - */ - if (old_crtc_config->pixmap) - return TRUE; - - /* If the new screen configuration covers the existing CRTC space, - * we're done - */ - if (RRScreenCoversCrtc(new_screen_config, old_crtc_config, - &crtc->client_current_transform, NULL)) - return TRUE; - - /* Disable the crtc and let it get re-enabled */ - return miRRDisableCrtc(crtc); -} - -Bool -miRRSetCrtcConfigs(ScreenPtr screen, - RRScreenConfigPtr screen_config, - RRCrtcConfigPtr crtc_configs, - int num_configs) -{ - RRScreenConfigRec old_screen_config; - RRCrtcConfigPtr old_crtc_configs; - int i; - - /* - * Save existing state - */ - - RRScreenCurrentConfig(screen, &old_screen_config); - old_crtc_configs = calloc(num_configs, sizeof (RRCrtcConfigRec)); - if (!old_crtc_configs) - return FALSE; - - for (i = 0; i < num_configs; i++) - if (!RRCrtcCurrentConfig(crtc_configs[i].crtc, &old_crtc_configs[i])) - goto fail_save; - /* - * Set the new configuration. If anything goes wrong, - * bail and restore the old configuration - */ - for (i = 0; i < num_configs; i++) - if (!miRRCheckDisableCrtc(screen_config, &old_crtc_configs[i])) - goto fail_disable; - - if (!miRRSetScreenConfig(screen, screen_config)) - goto fail_set_screen; - - for (i = 0; i < num_configs; i++) - if (!miRRSetCrtcConfig(&crtc_configs[i])) - goto fail_set_crtc; - - RRFreeCrtcConfigs(old_crtc_configs, num_configs); - return TRUE; - -fail_set_crtc: - /* - * Restore the previous configuration. Ignore any errors - * as we just need to hope that the driver can manage to - * get back to the previous state without trouble. - */ - for (i = 0; i < num_configs; i++) - (void) miRRDisableCrtc(old_crtc_configs[i].crtc); - (void) miRRSetScreenConfig(screen, &old_screen_config); -fail_set_screen: -fail_disable: - for (i = 0; i < num_configs; i++) - (void) miRRSetCrtcConfig(&old_crtc_configs[i]); -fail_save: - RRFreeCrtcConfigs(old_crtc_configs, num_configs); - return FALSE; -} diff --git a/xorg-server/randr/rrpixmap.c b/xorg-server/randr/rrpixmap.c deleted file mode 100644 index 5949309c9..000000000 --- a/xorg-server/randr/rrpixmap.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright © 2010 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. - */ - -#include "randrstr.h" -#include "xace.h" - -int -ProcRRQueryScanoutPixmaps (ClientPtr client) -{ - REQUEST(xRRQueryScanoutPixmapsReq); - xRRQueryScanoutPixmapsReply rep; - RRScanoutPixmapInfo *info; - xRRScanoutPixmapInfo *x_info; - int n_info; - int rc; - DrawablePtr drawable; - ScreenPtr screen; - rrScrPrivPtr screen_priv; - int n, s; - - REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq); - rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); - if (rc != Success) { - client->errorValue = stuff->drawable; - return rc; - } - - screen = drawable->pScreen; - screen_priv = rrGetScrPriv(screen); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - info = RRQueryScanoutPixmapInfo(screen, &n_info); - x_info = calloc(n_info, sizeof (xRRScanoutPixmapInfo)); - if (n_info && !x_info) - return BadAlloc; - rep.length += (n_info * sizeof (xRRScanoutPixmapInfo)) >> 2; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - - for (s = 0; s < n_info; s++) { - x_info[s].format = info[s].format->id; - x_info[s].maxWidth = info[s].maxWidth; - x_info[s].maxHeight = info[s].maxHeight; - x_info[s].rotations = info[s].rotations; - if (client->swapped) { - swapl(&x_info[s].format, n); - swaps(&x_info[s].maxWidth, n); - swaps(&x_info[s].maxHeight, n); - swaps(&x_info[s].rotations, n); - } - } - - WriteToClient(client, sizeof(rep), (char *)&rep); - if (n_info) - WriteToClient(client, n_info * sizeof (xRRScanoutPixmapInfo), - (char *) x_info); - return Success; -} - -int -ProcRRCreateScanoutPixmap (ClientPtr client) -{ - REQUEST(xRRCreateScanoutPixmapReq); - int rc; - DrawablePtr drawable; - ScreenPtr screen; - rrScrPrivPtr screen_priv; - PixmapPtr pixmap; - int n_info; - RRScanoutPixmapInfo *info; - int s; - - REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq); - client->errorValue = stuff->pid; - LEGAL_NEW_RESOURCE(stuff->pid, client); - - rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess); - if (rc != Success) { - client->errorValue = stuff->drawable; - return rc; - } - screen = drawable->pScreen; - screen_priv = rrGetScrPriv(screen); - if (!screen_priv) - return BadValue; - - info = RRQueryScanoutPixmapInfo(screen, &n_info); - for (s = 0; s < n_info; s++) { - if (info[s].format->id == stuff->format) - break; - } - if (s == n_info || !screen_priv->rrCreateScanoutPixmap) { - client->errorValue = stuff->format; - return BadValue; - } - info = &info[s]; - if (!stuff->width || stuff->width > info->maxWidth) { - client->errorValue = stuff->width; - return BadValue; - } - if (!stuff->height || stuff->height > info->maxHeight) { - client->errorValue = stuff->height; - return BadValue; - } - if ((stuff->rotations & info->rotations) != stuff->rotations) { - client->errorValue = stuff->rotations; - return BadValue; - } - - pixmap = screen_priv->rrCreateScanoutPixmap (screen, - stuff->width, stuff->height, - info->depth, - stuff->rotations, - info->format); - if (!pixmap) - return BadAlloc; - - pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pixmap->drawable.id = stuff->pid; - rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, - pixmap, RT_NONE, NULL, DixCreateAccess); - if (rc != Success) { - screen->DestroyPixmap(pixmap); - return rc; - } - if (!AddResource(stuff->pid, RT_PIXMAP, pixmap)) - return BadAlloc; - return Success; -} diff --git a/xorg-server/randr/rrsprite.c b/xorg-server/randr/rrsprite.c deleted file mode 100644 index c441e0396..000000000 --- a/xorg-server/randr/rrsprite.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2010 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. - */ - -#include "randrstr.h" -#include "swaprep.h" - -void -RRCrtcSpriteTransformSet(RRCrtcPtr crtc, - PictTransform *position_transform, - PictTransform *image_transform, - struct pict_f_transform *f_position_transform, - struct pict_f_transform *f_image_transform) -{ - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - - pScreen = crtc->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - crtc->client_sprite_position_transform = *position_transform; - crtc->client_sprite_image_transform = *image_transform; - crtc->client_sprite_f_position_transform = *f_position_transform; - crtc->client_sprite_f_image_transform = *f_image_transform; - if (pScrPriv->rrSetCrtcSpriteTransform) - (*pScrPriv->rrSetCrtcSpriteTransform) (pScreen, crtc, - &crtc->client_sprite_f_position_transform, - &crtc->client_sprite_f_image_transform); -} - -int -ProcRRSetCrtcSpriteTransform (ClientPtr client) -{ - REQUEST(xRRSetCrtcSpriteTransformReq); - RRCrtcPtr crtc; - PictTransform position_transform, image_transform; - struct pixman_f_transform f_position_transform, f_image_transform; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcSpriteTransformReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - PictTransform_from_xRenderTransform (&position_transform, &stuff->positionTransform); - PictTransform_from_xRenderTransform (&image_transform, &stuff->imageTransform); - pixman_f_transform_from_pixman_transform (&f_position_transform, &position_transform); - pixman_f_transform_from_pixman_transform (&f_image_transform, &image_transform); - - RRCrtcSpriteTransformSet (crtc, &position_transform, &image_transform, - &f_position_transform, &f_image_transform); - return Success; -} - -#define CrtcSpriteTransformExtra (SIZEOF(xRRGetCrtcSpriteTransformReply) - 32) - -int -ProcRRGetCrtcSpriteTransform (ClientPtr client) -{ - REQUEST(xRRGetCrtcSpriteTransformReq); - xRRGetCrtcSpriteTransformReply *reply; - RRCrtcPtr crtc; - int n; - char *extra; - - REQUEST_SIZE_MATCH (xRRGetCrtcSpriteTransformReq); - VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess); - - reply = malloc(sizeof (xRRGetCrtcSpriteTransformReply)); - if (!reply) - return BadAlloc; - - extra = (char *) (reply + 1); - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = bytes_to_int32(CrtcSpriteTransformExtra); - - xRenderTransform_from_PictTransform(&reply->positionTransform, &crtc->client_sprite_position_transform); - xRenderTransform_from_PictTransform(&reply->imageTransform, &crtc->client_sprite_image_transform); - - if (client->swapped) { - swaps (&reply->sequenceNumber, n); - swapl (&reply->length, n); - SwapLongs((CARD32 *) &reply->positionTransform, bytes_to_int32(sizeof(xRenderTransform))); - SwapLongs((CARD32 *) &reply->imageTransform, bytes_to_int32(sizeof(xRenderTransform))); - } - WriteToClient (client, sizeof (xRRGetCrtcSpriteTransformReply), (char *) reply); - free(reply); - return Success; -} -- cgit v1.2.3