From d95c758630f4aacec339a7ec80d2c4a9d7de1e4a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Jul 2006 19:46:38 -0700 Subject: Preliminary RandR 1.2 work --- randr/mirandr.c | 85 +++++++++-------- randr/randr.c | 283 +++++++++++++++++++++++++++++++++++-------------------- randr/randrstr.h | 179 +++++++++++++++++++++++++---------- 3 files changed, 354 insertions(+), 193 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index 0954028d1..7bef02d29 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -1,36 +1,36 @@ /* - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. + * 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * 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. * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation */ - #ifdef HAVE_DIX_CONFIG_H #include #endif #include "scrnintstr.h" #include "mi.h" -#include #include "randrstr.h" #include @@ -48,26 +48,35 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) { int i; Bool setConfig = FALSE; + RRMonitorPtr pMonitor; - *rotations = RR_Rotate_0; + pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); for (i = 0; i < pScreen->numDepths; i++) { if (pScreen->allowedDepths[i].numVids) { - RRScreenSizePtr pSize; + xRRMonitorMode rrMode; + RRModePtr pMode; + char name[64]; - pSize = RRRegisterSize (pScreen, - pScreen->width, - pScreen->height, - pScreen->mmWidth, - pScreen->mmHeight); - if (!pSize) - return FALSE; - if (!setConfig) - { - RRSetCurrentConfig (pScreen, RR_Rotate_0, 0, pSize); - setConfig = TRUE; - } + sprintf (name, "%dx%d", pScreen->width, pScreen->height); + memset (&rrMode, '\0', sizeof (rrMode)); + rrMode.width = pScreen->width; + rrMode.height = pScreen->height; + rrMode.widthInMillimeters = pScreen->mmWidth; + rrMode.heightInMillimeters = pScreen->mmHeight; + pMonitor = RRRegisterMonitor (pScreen, RR_Rotate_0); + pMode = RRRegisterMode (pMonitor, + &rrMode, + name, + strlen (name)); + if (!pMode) + return FALSE; + if (!setConfig) + { + RRSetCurrentMode (pMonitor, pMode, 0, 0, RR_Rotate_0); + setConfig = TRUE; + } } } return TRUE; @@ -78,10 +87,10 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) * different here */ Bool -miRRSetConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) +miRRSetMode (ScreenPtr pScreen, + int monitor, + RRModePtr pMode, + Rotation rotation) { return TRUE; } @@ -96,6 +105,6 @@ miRandRInit (ScreenPtr pScreen) return FALSE; rp = rrGetScrPriv(pScreen); rp->rrGetInfo = miRRGetInfo; - rp->rrSetConfig = miRRSetConfig; + rp->rrSetMode = miRRSetMode; return TRUE; } diff --git a/randr/randr.c b/randr/randr.c index 946aad31d..1a9624a24 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -1,29 +1,30 @@ /* - * - * Copyright © 2000, Compaq Computer Corporation, - * Copyright © 2002, Hewlett Packard, Inc. + * 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 Compaq or HP not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. HP makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * 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. * - * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. * - * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Author: Jim Gettys, Hewlett-Packard Company, Inc. + * Keith Packard, Intel Corporation */ - #define NEED_REPLIES #define NEED_EVENTS #ifdef HAVE_DIX_CONFIG_H @@ -159,10 +160,21 @@ static Bool RRCloseScreen (int i, ScreenPtr pScreen) { rrScrPriv(pScreen); + RRMonitorPtr pMonitor; unwrap (pScrPriv, pScreen, CloseScreen); - if (pScrPriv->pSizes) - xfree (pScrPriv->pSizes); + while (pMonitor = pScrPriv->pMonitors) + { + RRModePtr pMode; + + pScrPriv->pMonitors = pMonitor->next; + while (pMode = pMonitor->pModes) + { + pMonitor->pModes = pMode->next; + xfree (pMode); + } + xfree (pMonitor); + } xfree (pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ return (*pScreen->CloseScreen) (i, pScreen); @@ -187,6 +199,25 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, cpswaps(from->subpixelOrder, to->subpixelOrder); } +static void +SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from, + xRRMonitorChangeNotifyEvent *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->root, to->root); + cpswapl(from->window, to->window); + cpswaps(from->monitor, to->monitor); + cpswaps(from->modeID, to->modeID); + cpswaps(from->rotation, to->rotation); + cpswaps(from->subpixelOrder, to->subpixelOrder); + cpswaps(from->x, to->x); + cpswaps(from->y, to->y); +} + Bool RRScreenInit(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; @@ -207,8 +238,12 @@ Bool RRScreenInit(ScreenPtr pScreen) /* * Calling function best set these function vectors */ - pScrPriv->rrSetConfig = 0; + pScrPriv->rrSetMode = 0; pScrPriv->rrGetInfo = 0; +#ifdef RANDR_SCREEN_INTERFACE + pScrPriv->rrSetConfig = 0; +#endif + /* * This value doesn't really matter -- any client must call * GetScreenInfo before reading it which will automatically update @@ -219,14 +254,7 @@ Bool RRScreenInit(ScreenPtr pScreen) wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - pScrPriv->rotations = RR_Rotate_0; - - pScrPriv->nSizes = 0; - pScrPriv->nSizesInUse = 0; - pScrPriv->pSizes = 0; - - pScrPriv->rotation = RR_Rotate_0; - pScrPriv->size = -1; + pScrPriv->pMonitors = NULL; RRNScreens += 1; /* keep count of screens that implement randr */ return TRUE; @@ -318,55 +346,96 @@ TellChanged (WindowPtr pWin, pointer value) RREventPtr *pHead, pRREvent; ClientPtr client; xRRScreenChangeNotifyEvent se; + xRRMonitorChangeNotifyEvent me; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - RRScreenSizePtr pSize; + RRMonitorPtr pMonitor = pScrPriv->pMonitors; + RRModePtr pMode; WindowPtr pRoot = WindowTable[pScreen->myNum]; + int i; pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); if (!pHead) return WT_WALKCHILDREN; - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; -#ifdef RENDER - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); -#else - se.subpixelOrder = SubPixelUnknown; -#endif - if (pScrPriv->size >= 0) - { - pSize = &pScrPriv->pSizes[pScrPriv->size]; - se.sizeID = pSize->id; - se.widthInPixels = pSize->width; - se.heightInPixels = pSize->height; - se.widthInMillimeters = pSize->mmWidth; - se.heightInMillimeters = pSize->mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { client = pRREvent->client; if (client == serverClient || client->clientGone) continue; - se.sequenceNumber = client->sequence; - if(pRREvent->mask & RRScreenChangeNotifyMask) - WriteEventsToClient (client, 1, (xEvent *) &se); + + if (pRREvent->mask & RRMonitorChangeNotifyMask)) + { + me.type = RRNotify + RREventBase; + me.subCode = RRNotify_MonitorChange; + me.timestamp = pScrPriv->lastSetTime.milliseconds; + me.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + me.root = pRoot->drawable.id; + me.window = pWin->drawable.id; +#ifdef RENDER + me.subpixelOrder = PictureGetSubpixelOrder (pScreen); +#else + me.subpixelOrder = SubPixelUnknown; +#endif + for (i = 0; i < pScrPriv->nMonitors; i++) + { + pMonitor = &pScrPriv->pMonitors[i]; + me.monitor = i; + if (pMonitor->mode >= 0) { + me.modeID = pMonitor->pMode[pMonitor->mode].id; + me.rotation = pMonitor->rotation; + me.x = pMonitor->x; + me.y = pMonitor->y; + } else { + me.modeID = 0xffff; + me.rotation = RR_Rotate_0; + me.x = 0; + me.y = 0; + } + WriteEventsToClient (client, 1, (xEvent *) &me); + } + } + if ((pRREvent->mask & RRScreenChangeNotifyMask) && + pScrPriv->nMonitors > 0) + { + se.type = RRScreenChangeNotify + RREventBase; + se.rotation = (CARD8) pScrPriv->rotation; + se.timestamp = pScrPriv->lastSetTime.milliseconds; + se.sequenceNumber = client->sequence; + se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + se.root = pRoot->drawable.id; + se.window = pWin->drawable.id; +#ifdef RENDER + se.subpixelOrder = PictureGetSubpixelOrder (pScreen); +#else + se.subpixelOrder = SubPixelUnknown; +#endif + + pMonitor = &pScrPriv->pMonitors[0]; + se.sequenceNumber = client->sequence; + if (pMonitor->mode >= 0) + { + pMode = &pMonitor->pModes[pMonitor->mode]; + se.sizeID = pMode->id; + se.widthInPixels = pMode->width; + se.heightInPixels = pMode->height; + se.widthInMillimeters = pMode->mmWidth; + se.heightInMillimeters = pMode->mmHeight; + } + else + { + /* + * This "shouldn't happen", but a broken DDX can + * forget to set the current configuration on GetInfo + */ + se.sizeID = 0xffff; + se.widthInPixels = 0; + se.heightInPixels = 0; + se.widthInMillimeters = 0; + se.heightInMillimeters = 0; + } + WriteEventsToClient (client, 1, (xEvent *) &se); + } } return WT_WALKCHILDREN; } @@ -375,59 +444,66 @@ static Bool RRGetInfo (ScreenPtr pScreen) { rrScrPriv (pScreen); - int i, j, k, l; + int m, s, n; Bool changed; Rotation rotations; - RRScreenSizePtr pSize; - RRScreenRatePtr pRate; + RRMonitorPtr pMonitor; + RRModePtr pMode; - for (i = 0; i < pScrPriv->nSizes; i++) + for (m = 0; m < pScrPriv->nMonitors; m++) { - pSize = &pScrPriv->pSizes[i]; - pSize->oldReferenced = pSize->referenced; - pSize->referenced = FALSE; - for (k = 0; k < pSize->nRates; k++) + pMonitor = &pScrPriv->pMonitors[m]; + pMonitor->oldReferenced = pMonitor->referenced; + pMonitor->referenced = FALSE; + for (s = 0; s < pMonitor->nModes; s++) { - pRate = &pSize->pRates[k]; - pRate->oldReferenced = pRate->referenced; - pRate->referenced = FALSE; + pMode = &pSize->pModes[s]; + pMode->oldReferenced = pMode->referenced; + pMode->referenced = FALSE; } } - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - changed = FALSE; - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->rotations) - { - pScrPriv->rotations = rotations; - changed = TRUE; + rotations = 0; + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return FALSE; + + /* Old GetInfo clients return rotations here */ + if (rotations && pScrPriv->nMonitors) { + /* + * Check whether anything changed and simultaneously generate + * the protocol id values for the objects + */ + if (rotations != pScrPriv->pMonitors[i].rotations) + { + pScrPriv->pMonitors[i].rotations = rotations; + changed = TRUE; + } } - - j = 0; - for (i = 0; i < pScrPriv->nSizes; i++) + + n = 0; + for (m = 0; m < pScrPriv->nMonitors; m++) { - pSize = &pScrPriv->pSizes[i]; - if (pSize->oldReferenced != pSize->referenced) + int modeid = 0; + + pMonitor = &pScrPriv->pMonitors[m]; + if (pMonitor->oldReferenced != pMonitor->referenced) changed = TRUE; - if (pSize->referenced) - pSize->id = j++; - l = 0; - for (k = 0; k < pSize->nRates; k++) + if (pMonitor->referenced) { - pRate = &pSize->pRates[k]; - if (pRate->oldReferenced != pRate->referenced) - changed = TRUE; - if (pRate->referenced) - l++; + for (s = 0; s < pMonitor->nModes; s++) + { + pMode = &pMonitor->pModes[s]; + if (pMode->oldReferenced != pMode->referenced) + changed = TRUE; + if (pMode->referenced) + pMode->id = modeid++; + } + n++; } - pSize->nRatesInUse = l; + pMonitor->nModesInUse = modeid; } - pScrPriv->nSizesInUse = j; + pScrPriv->nMonitorsInUse = n; if (changed) { UpdateCurrentTime (); @@ -1241,6 +1317,7 @@ RRRegisterSize (ScreenPtr pScreen, if (!pScrPriv) return 0; + tmp.id = -1; tmp.width = width; tmp.height= height; tmp.mmWidth = mmWidth; diff --git a/randr/randrstr.h b/randr/randrstr.h index 27ab61abb..07c6c3798 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -1,24 +1,28 @@ /* - * * 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 Compaq not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Compaq makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * 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. * - * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL COMPAQ BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * 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. + * 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 @@ -28,56 +32,83 @@ #ifndef _RANDRSTR_H_ #define _RANDRSTR_H_ -#include - -typedef struct _rrScreenRate { - int rate; - Bool referenced; - Bool oldReferenced; -} RRScreenRate, *RRScreenRatePtr; +#include -typedef struct _rrScreenSize { +typedef struct _rrMode { + struct _rrMode *next; int id; - short width, height; - short mmWidth, mmHeight; - RRScreenRatePtr pRates; - int nRates; - int nRatesInUse; Bool referenced; Bool oldReferenced; -} RRScreenSize, *RRScreenSizePtr; + xRRMonitorMode mode; +} RRMode, *RRModePtr; + +typedef struct _rrMonitor { + struct _rrMonitor *next; + ScreenPtr pScreen; + RRModePtr pModes; + void *identifier; /* made unique by DDX */ + Bool referenced; + + /* + * Current state + */ + int mode; + int x, y; + Rotation rotation; +} RRMonitor, *RRMonitorPtr; + +typedef Bool (*RRSetScreenSizeProcPtr) (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 widthInMM, + CARD32 heightInMM); + +typedef Bool (*RRSetModeProcPtr) (ScreenPtr pScreen, + int monitor, + RRModePtr pMode, + int x, + int y, + Rotation rotation); + +typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); +typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); + + +#ifdef RANDR_SCREEN_INTERFACE + +typedef void *RRScreenSizePtr; typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); -typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); -typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); +#endif + typedef struct _rrScrPriv { - RRSetConfigProcPtr rrSetConfig; + RRSetModeProcPtr rrSetMode; RRGetInfoProcPtr rrGetInfo; + RRCloseScreenProcPtr CloseScreen; TimeStamp lastSetTime; /* last changed by client */ TimeStamp lastConfigTime; /* possible configs changed */ - RRCloseScreenProcPtr CloseScreen; + /* + * monitor data + */ + RRMonitorPtr pMonitors; + +#ifdef RANDR_SCREEN_INTERFACE /* * Configuration information */ Rotation rotations; - int nSizes; - int nSizesInUse; - RRScreenSizePtr pSizes; + RRSetConfigProcPtr rrSetConfig; - /* - * Current state - */ Rotation rotation; - int size; - int rate; +#endif } rrScrPrivRec, *rrScrPrivPtr; extern int rrPrivIndex; @@ -90,6 +121,60 @@ extern int rrPrivIndex; void RRExtensionInit (void); +/* + * Then, register a monitor with the screen + */ + +RRMonitorPtr +RRRegisterMonitor (ScreenPtr pScreen, + void *identifier, + Rotation rotations); + +/* + * Next, register the list of modes with the monitor + */ + +RRModePtr +RRRegisterMode (RRMonitorPtr pMonitor, + xRRMonitorMode *pMode, + char *name, + int nameLength); + +/* + * Finally, set the current configuration of each monitor + */ + +void +RRSetCurrentMode (RRMonitorPtr pMonitor, + RRModePtr pMode, + Rotation rotation); + +Bool RRScreenInit(ScreenPtr pScreen); + +Rotation +RRGetRotation (ScreenPtr pScreen); + +Bool +miRandRInit (ScreenPtr pScreen); + +Bool +miRRGetInfo (ScreenPtr pScreen, Rotation *rotations); + +Bool +miRRGetScreenInfo (ScreenPtr pScreen); + +Bool +miRRSetMode (ScreenPtr pScreen, + int monitor, + RRModePtr pMode, + Rotation rotation); + +#ifdef RANDR_SCREEN_INTERFACE +/* + * This is the old interface, deprecated but left + * around for compatibility + */ + /* * Then, register the specific size with the screen */ @@ -105,6 +190,9 @@ Bool RRRegisterRate (ScreenPtr pScreen, RRScreenSizePtr pSize, int rate); +Bool RRRegisterRotation (ScreenPtr pScreen, + Rotation rotation); + /* * Finally, set the current configuration of the screen */ @@ -115,30 +203,17 @@ RRSetCurrentConfig (ScreenPtr pScreen, int rate, RRScreenSizePtr pSize); -Bool RRScreenInit(ScreenPtr pScreen); - -Rotation -RRGetRotation (ScreenPtr pScreen); - int RRSetScreenConfig (ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); -Bool -miRandRInit (ScreenPtr pScreen); - -Bool -miRRGetInfo (ScreenPtr pScreen, Rotation *rotations); - Bool miRRSetConfig (ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr size); -Bool -miRRGetScreenInfo (ScreenPtr pScreen); - +#endif #endif /* _RANDRSTR_H_ */ -- cgit v1.2.3 From cab3a0145f2483fe43b5db5f5dd2076db9757fe5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jul 2006 01:21:11 -0400 Subject: RandR: New data structure, old API. At least it compiles now --- randr/mirandr.c | 8 +- randr/randr.c | 697 +++++++++++++++++++++++++++++++++++++++++-------------- randr/randrstr.h | 51 +++- 3 files changed, 570 insertions(+), 186 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index 7bef02d29..e15213327 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -65,11 +65,11 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) rrMode.height = pScreen->height; rrMode.widthInMillimeters = pScreen->mmWidth; rrMode.heightInMillimeters = pScreen->mmHeight; - pMonitor = RRRegisterMonitor (pScreen, RR_Rotate_0); + rrMode.nameLength = strlen (name); + pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); pMode = RRRegisterMode (pMonitor, &rrMode, - name, - strlen (name)); + name); if (!pMode) return FALSE; if (!setConfig) @@ -90,6 +90,8 @@ Bool miRRSetMode (ScreenPtr pScreen, int monitor, RRModePtr pMode, + int x, + int y, Rotation rotation) { return TRUE; diff --git a/randr/randr.c b/randr/randr.c index 1a9624a24..4a5cd4e1d 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -163,12 +163,12 @@ RRCloseScreen (int i, ScreenPtr pScreen) RRMonitorPtr pMonitor; unwrap (pScrPriv, pScreen, CloseScreen); - while (pMonitor = pScrPriv->pMonitors) + while ((pMonitor = pScrPriv->pMonitors)) { RRModePtr pMode; pScrPriv->pMonitors = pMonitor->next; - while (pMode = pMonitor->pModes) + while ((pMode = pMonitor->pModes)) { pMonitor->pModes = pMode->next; xfree (pMode); @@ -218,6 +218,20 @@ SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from, cpswaps(from->y, to->y); } +static void +SRRNotifyEvent (xEvent *from, + xEvent *to) +{ + switch (from->u.u.detail) { + case RRNotify_MonitorChange: + SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from, + (xRRMonitorChangeNotifyEvent *) to); + break; + default: + break; + } +} + Bool RRScreenInit(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; @@ -336,6 +350,8 @@ RRExtensionInit (void) RREventBase = extEntry->eventBase; EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) SRRScreenChangeNotifyEvent; + EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) + SRRNotifyEvent; return; } @@ -349,8 +365,8 @@ TellChanged (WindowPtr pWin, pointer value) xRRMonitorChangeNotifyEvent me; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - RRMonitorPtr pMonitor = pScrPriv->pMonitors; RRModePtr pMode; + RRMonitorPtr pMonitor; WindowPtr pRoot = WindowTable[pScreen->myNum]; int i; @@ -364,7 +380,7 @@ TellChanged (WindowPtr pWin, pointer value) if (client == serverClient || client->clientGone) continue; - if (pRREvent->mask & RRMonitorChangeNotifyMask)) + if (pRREvent->mask & RRMonitorChangeNotifyMask) { me.type = RRNotify + RREventBase; me.subCode = RRNotify_MonitorChange; @@ -377,12 +393,13 @@ TellChanged (WindowPtr pWin, pointer value) #else me.subpixelOrder = SubPixelUnknown; #endif - for (i = 0; i < pScrPriv->nMonitors; i++) + for (pMonitor = pScrPriv->pMonitors, i = 0; + pMonitor; + pMonitor = pMonitor->next, i++) { - pMonitor = &pScrPriv->pMonitors[i]; me.monitor = i; - if (pMonitor->mode >= 0) { - me.modeID = pMonitor->pMode[pMonitor->mode].id; + if (pMonitor->pMode) { + me.modeID = pMonitor->pMode->id; me.rotation = pMonitor->rotation; me.x = pMonitor->x; me.y = pMonitor->y; @@ -396,10 +413,10 @@ TellChanged (WindowPtr pWin, pointer value) } } if ((pRREvent->mask & RRScreenChangeNotifyMask) && - pScrPriv->nMonitors > 0) + (pMonitor = pScrPriv->pMonitors)) { se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pScrPriv->rotation; + se.rotation = (CARD8) pMonitor->rotation; se.timestamp = pScrPriv->lastSetTime.milliseconds; se.sequenceNumber = client->sequence; se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; @@ -413,14 +430,14 @@ TellChanged (WindowPtr pWin, pointer value) pMonitor = &pScrPriv->pMonitors[0]; se.sequenceNumber = client->sequence; - if (pMonitor->mode >= 0) + if (pMonitor->pMode) { - pMode = &pMonitor->pModes[pMonitor->mode]; + pMode = pMonitor->pMode; se.sizeID = pMode->id; - se.widthInPixels = pMode->width; - se.heightInPixels = pMode->height; - se.widthInMillimeters = pMode->mmWidth; - se.heightInMillimeters = pMode->mmHeight; + se.widthInPixels = pMode->mode.width; + se.heightInPixels = pMode->mode.height; + se.widthInMillimeters = pMode->mode.widthInMillimeters; + se.heightInMillimeters = pMode->mode.heightInMillimeters; } else { @@ -440,70 +457,107 @@ TellChanged (WindowPtr pWin, pointer value) return WT_WALKCHILDREN; } +static void +RRFreeMode (RRModePtr pMode) +{ + xfree (pMode); +} + +static void +RRFreeModes (RRModePtr pHead) +{ + RRModePtr pMode; + while ((pMode = pHead)) + { + pHead = pMode->next; + RRFreeMode (pMode); + } +} + +static void +RRFreeMonitor (RRMonitorPtr pMonitor) +{ + RRFreeModes (pMonitor->pModes); + xfree (pMonitor); +} + + static Bool RRGetInfo (ScreenPtr pScreen) { rrScrPriv (pScreen); - int m, s, n; Bool changed; Rotation rotations; - RRMonitorPtr pMonitor; - RRModePtr pMode; + RRMonitorPtr pMonitor, *pPrevMon; + RRModePtr pMode, *pPrevMode; + int monitorid; - for (m = 0; m < pScrPriv->nMonitors; m++) + for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) { - pMonitor = &pScrPriv->pMonitors[m]; - pMonitor->oldReferenced = pMonitor->referenced; + pMonitor->oldReferenced = TRUE; pMonitor->referenced = FALSE; - for (s = 0; s < pMonitor->nModes; s++) + pMonitor->pMode = NULL; + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) { - pMode = &pSize->pModes[s]; - pMode->oldReferenced = pMode->referenced; + pMode->oldReferenced = TRUE; pMode->referenced = FALSE; } } - changed = FALSE; - rotations = 0; if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) return FALSE; + + changed = FALSE; /* Old GetInfo clients return rotations here */ - if (rotations && pScrPriv->nMonitors) { + if (rotations && pScrPriv->pMonitors) { /* * Check whether anything changed and simultaneously generate * the protocol id values for the objects */ - if (rotations != pScrPriv->pMonitors[i].rotations) + if (rotations != pScrPriv->pMonitors->rotations) { - pScrPriv->pMonitors[i].rotations = rotations; + pScrPriv->pMonitors->rotations = rotations; changed = TRUE; } } - n = 0; - for (m = 0; m < pScrPriv->nMonitors; m++) + /* + * Walk monitor and mode lists looking for updates + */ + monitorid = 0; + for (pPrevMon = &pScrPriv->pMonitors; (pMonitor = *pPrevMon);) { int modeid = 0; - pMonitor = &pScrPriv->pMonitors[m]; - if (pMonitor->oldReferenced != pMonitor->referenced) - changed = TRUE; if (pMonitor->referenced) { - for (s = 0; s < pMonitor->nModes; s++) + pMonitor->id = monitorid++; + if (!pMonitor->oldReferenced) + changed = TRUE; + for (pPrevMode = &pMonitor->pModes; (pMode = *pPrevMode);) { - pMode = &pMonitor->pModes[s]; - if (pMode->oldReferenced != pMode->referenced) - changed = TRUE; if (pMode->referenced) + { pMode->id = modeid++; + if (!pMode->oldReferenced) + changed = TRUE; + } + else + { + *pPrevMode = pMode->next; + changed = TRUE; + RRFreeMode (pMode); + } } - n++; } - pMonitor->nModesInUse = modeid; + else + { + *pPrevMon = pMonitor->next; + changed = TRUE; + RRFreeMonitor (pMonitor); + } } - pScrPriv->nMonitorsInUse = n; if (changed) { UpdateCurrentTime (); @@ -548,6 +602,10 @@ ProcRRQueryVersion (ClientPtr client) rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; + /* + * Report the current version; the current + * spec says they're all compatible after 1.0 + */ rep.majorVersion = RANDR_MAJOR; rep.minorVersion = RANDR_MINOR; if (client->swapped) { @@ -604,6 +662,100 @@ RREditConnectionInfo (ScreenPtr pScreen) root->mmHeight = pScreen->mmHeight; } +static int +RRNumModes (RRMonitorPtr pMonitor) +{ + int n = 0; + RRModePtr pMode; + + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + n++; + return n; +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +static CARD16 +RRVerticalRefresh (xRRMonitorMode *mode) +{ + CARD32 refresh; + if (!mode->hTotal || !mode->vTotal) + return 0; + refresh = mode->dotClock / (mode->hTotal * mode->vTotal); + if (refresh > 0xffff) + refresh = 0xffff; + return (CARD16) refresh; +} + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = RRNumModes (pMonitor); + int i; + int j; + RRRefreshPtr refresh; + CARD16 vRefresh; + RRModePtr pMode; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSizeRec) * nmode + + sizeof (RRRefreshRec) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRRefreshPtr) (size + nmode); + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + { + for (i = 0; i < data->nsize; i++) + if (pMode->mode.width == size[i].width && + pMode->mode.height == size[i].height) + break; + if (i == data->nsize) + { + size[i].width = pMode->mode.width; + size[i].height = pMode->mode.height; + size[i].mmWidth = pMode->mode.widthInMillimeters; + size[i].mmHeight = pMode->mode.heightInMillimeters; + size[i].nrefresh = 0; + size[i].refresh = &refresh[data->nrefresh]; + data->nsize++; + } + vRefresh = RRVerticalRefresh (&pMode->mode); + for (j = 0; j < size[i].nrefresh; j++) + if (vRefresh == size[i].refresh[j].refresh) + break; + if (j == size[i].nrefresh) + { + size[i].refresh[j].refresh = vRefresh; + size[i].refresh[j].pMode = pMode; + size[i].nrefresh++; + data->nrefresh++; + } + if (pMode == pMonitor->pMode) + { + data->size = i; + data->refresh = vRefresh; + } + } + return data; +} + static int ProcRRGetScreenInfo (ClientPtr client) { @@ -626,7 +778,11 @@ ProcRRGetScreenInfo (ClientPtr client) pScreen = pWin->drawable.pScreen; pScrPriv = rrGetScrPriv(pScreen); rep.pad = 0; - if (!pScrPriv) + + if (pScrPriv) + RRGetInfo (pScreen); + + if (!pScrPriv && !pScrPriv->pMonitors) { rep.type = X_Reply; rep.setOfRotations = RR_Rotate_0;; @@ -645,94 +801,82 @@ ProcRRGetScreenInfo (ClientPtr client) } else { + RRMonitorPtr pMonitor = pScrPriv->pMonitors; int i, j; xScreenSizes *size; CARD16 *rates; CARD8 *data8; Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; - RRGetInfo (pScreen); - + pData = RR10GetData (pScreen, pMonitor); + if (!pData) + return BadAlloc; + rep.type = X_Reply; - rep.setOfRotations = pScrPriv->rotations; + rep.setOfRotations = pMonitor->rotations; rep.sequenceNumber = client->sequence; rep.length = 0; rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = pScrPriv->rotation; - rep.nSizes = pScrPriv->nSizesInUse; - rep.rate = pScrPriv->rate; - rep.nrateEnts = 0; - if (has_rate) - { - for (i = 0; i < pScrPriv->nSizes; i++) - { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) - { - rep.nrateEnts += (1 + pSize->nRatesInUse); - } - } - } - - if (pScrPriv->size >= 0) - rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id; - else - return BadImplementation; + rep.rotation = pMonitor->rotation; + rep.nSizes = pData->nsize; + rep.nrateEnts = pData->nrefresh; + rep.sizeID = pData->size; + rep.rate = pData->refresh; extraLen = (rep.nSizes * sizeof (xScreenSizes) + rep.nrateEnts * sizeof (CARD16)); extra = (CARD8 *) xalloc (extraLen); if (!extra) + { + xfree (pData); return BadAlloc; + } /* * First comes the size information */ size = (xScreenSizes *) extra; rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pScrPriv->nSizes; i++) + for (i = 0; i < pData->nsize; i++) { - RRScreenSizePtr pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced) + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) { - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; + *rates = pSize->nrefresh; if (client->swapped) { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); + swaps (rates, n); } - size++; - if (has_rate) + rates++; + for (j = 0; j < pSize->nrefresh; j++) { - *rates = pSize->nRatesInUse; + *rates = pSize->refresh[j].refresh; if (client->swapped) { swaps (rates, n); } rates++; - for (j = 0; j < pSize->nRates; j++) - { - RRScreenRatePtr pRate = &pSize->pRates[j]; - if (pRate->referenced) - { - *rates = pRate->rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } } } } + xfree (pData); + data8 = (CARD8 *) rates; if (data8 - (CARD8 *) extra != extraLen) @@ -770,13 +914,16 @@ ProcRRSetScreenConfig (ClientPtr client) rrScrPrivPtr pScrPriv; TimeStamp configTime; TimeStamp time; - RRScreenSizePtr pSize; int i; Rotation rotation; int rate; short oldWidth, oldHeight; Bool has_rate; - + RRMonitorPtr pMonitor; + RRModePtr pMode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + UpdateCurrentTime (); if (RRClientKnowsRates (client)) @@ -812,6 +959,14 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRGetInfo (pScreen)) return BadAlloc; + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + /* * if the client's config timestamp is not the same as the last config * timestamp, then the config information isn't up-to-date and @@ -823,26 +978,20 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - /* - * Search for the requested size - */ - pSize = 0; - for (i = 0; i < pScrPriv->nSizes; i++) - { - pSize = &pScrPriv->pSizes[i]; - if (pSize->referenced && pSize->id == stuff->sizeID) - { - break; - } - } - if (i == pScrPriv->nSizes) + pData = RR10GetData (pScreen, pMonitor); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) { /* * Invalid size ID */ client->errorValue = stuff->sizeID; + xfree (pData); return BadValue; } + pSize = &pData->sizes[stuff->sizeID]; /* * Validate requested rotation @@ -861,15 +1010,17 @@ ProcRRSetScreenConfig (ClientPtr client) * Invalid rotation */ client->errorValue = stuff->rotation; + xfree (pData); return BadValue; } - if ((~pScrPriv->rotations) & rotation) + if ((~pMonitor->rotations) & rotation) { /* * requested rotation or reflection not supported by screen */ client->errorValue = stuff->rotation; + xfree (pData); return BadMatch; } @@ -883,21 +1034,24 @@ ProcRRSetScreenConfig (ClientPtr client) if (rate) { - for (i = 0; i < pSize->nRates; i++) + for (i = 0; i < pSize->nrefresh; i++) { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) + if (pSize->refresh[i].refresh == rate) break; } - if (i == pSize->nRates) + if (i == pSize->nrefresh) { /* * Invalid rate */ client->errorValue = rate; + xfree (pData); return BadValue; } + pMode = pSize->refresh[i].pMode; } + else + pMode = pSize->refresh[0].pMode; /* * Make sure the requested set-time is not older than @@ -912,9 +1066,51 @@ ProcRRSetScreenConfig (ClientPtr client) /* * call out to ddx routine to effect the change */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) + if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode) + { + xScreenSizes oldSize; + if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0)) + goto fail; + oldSize.widthInPixels = pScreen->width; + oldSize.heightInPixels = pScreen->width; + oldSize.widthInMillimeters = pScreen->mmWidth; + oldSize.heightInMillimeters = pScreen->mmHeight; + if (!(*pScrPriv->rrSetScreenSize) (pScreen, + pMode->mode.width, + pMode->mode.height, + pMode->mode.widthInMillimeters, + pMode->mode.heightInMillimeters)) + { + (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, + pMonitor->x, pMonitor->y, + pMonitor->rotation); + goto fail; + } + if (!(*pScrPriv->rrSetMode) (pScreen, 0, pMode, 0, 0, rotation)) + { + (void) (*pScrPriv->rrSetScreenSize) (pScreen, + oldSize.widthInPixels, + oldSize.heightInPixels, + oldSize.widthInMillimeters, + oldSize.heightInMillimeters); + (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, + pMonitor->x, pMonitor->y, + pMonitor->rotation); + goto fail; + } + } +#ifdef RANDR_SCREEN_INTERFACE + else if (pScrPriv->rrSetConfig) + { + if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, pSize)) + { + goto fail; + } + } +#endif + else { +fail: ; /* * unknown DDX failure, report to client */ @@ -925,7 +1121,7 @@ ProcRRSetScreenConfig (ClientPtr client) /* * set current extension configuration pointers */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); + RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); /* * Deliver ScreenChangeNotify events whenever @@ -954,6 +1150,9 @@ ProcRRSetScreenConfig (ClientPtr client) sendReply: + if (pData) + xfree (pData); + rep.type = X_Reply; /* rep.status has already been filled in */ rep.length = 0; @@ -1055,7 +1254,7 @@ RRSetScreenConfig (ScreenPtr pScreen, /* * set current extension configuration pointers */ - RRSetCurrentConfig (pScreen, rotation, rate, pSize); + RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); /* * Deliver ScreenChangeNotify events whenever @@ -1075,7 +1274,6 @@ RRSetScreenConfig (ScreenPtr pScreen, * Fix pointer bounds and location */ ScreenRestructured (pScreen); - return Success; } @@ -1286,22 +1484,114 @@ SProcRRDispatch (ClientPtr client) } } +/* + * Register a monitor for a screen. identifier is a unique identifier + * for the monitors of a particular screen. + */ +RRMonitorPtr +RRRegisterMonitor (ScreenPtr pScreen, + void *identifier, + Rotation rotations) +{ + rrScrPriv (pScreen); + RRMonitorPtr pMonitor, *pPrev, *pInsert; -static Bool -RRScreenSizeMatches (RRScreenSizePtr a, - RRScreenSizePtr b) + pInsert = NULL; + for (pPrev = &pScrPriv->pMonitors; (pMonitor = *pPrev); + pPrev = &(pMonitor)->next) + { + if (pMonitor->identifier == identifier) + { + pMonitor->referenced = TRUE; + return pMonitor; + } + if (!pMonitor->referenced) + pInsert = pPrev; + } + if (!pInsert) + pInsert = pPrev; + + /* + * New monitor, add before the first unreferenced monitor + */ + pMonitor = xalloc (sizeof (RRMonitor)); + if (!pMonitor) + return NULL; + pMonitor->pScreen = pScreen; + pMonitor->pModes = NULL; + pMonitor->identifier = identifier; + pMonitor->referenced = TRUE; + pMonitor->oldReferenced = FALSE; + pMonitor->rotations = RR_Rotate_0; + + pMonitor->pMode = NULL; + pMonitor->x = 0; + pMonitor->y = 0; + pMonitor->rotation = RR_Rotate_0; + pMonitor->next = *pInsert; + *pInsert = pMonitor; + return pMonitor; +} + +/* + * Register a mode for a monitor + */ + +RRModePtr +RRRegisterMode (RRMonitorPtr pMonitor, + xRRMonitorMode *pModeline, + char *name) { - 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; + RRModePtr pMode, *pPrev, *pInsert = NULL; + + /* + * Find existing mode with same modeline and name + */ + for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next)) + { + if (!memcmp (&pMode->mode, pModeline, sizeof (xRRMonitorMode)) && + pMode->mode.nameLength == pModeline->nameLength && + !memcmp (RRModeName(pMode), name, pModeline->nameLength)) + { + pMode->referenced = TRUE; + return pMode; + } + if (!pMode->referenced) + pInsert = pPrev; + } + + if (!pInsert) + pInsert = pPrev; + + /* + * Create a new mode, inserting before the first unreferenced mode + */ + pMode = xalloc (sizeof (RRMode) + pModeline->nameLength + 1); + pMode->referenced = TRUE; + pMode->oldReferenced = FALSE; + pMode->mode = *pModeline; + memcpy (RRModeName (pMode), name, pModeline->nameLength); + RRModeName(pMode)[pModeline->nameLength] = '\0'; + pMode->next = *pInsert; + *pInsert = pMode; + return pMode; +} + +void +RRSetCurrentMode (RRMonitorPtr pMonitor, + RRModePtr pMode, + int x, + int y, + Rotation rotation) +{ + pMonitor->pMode = pMode; + pMonitor->x = x; + pMonitor->y = y; + pMonitor->rotation = rotation; } +#ifdef RANDR_SCREEN_INTERFACE + RRScreenSizePtr RRRegisterSize (ScreenPtr pScreen, short width, @@ -1310,36 +1600,45 @@ RRRegisterSize (ScreenPtr pScreen, short mmHeight) { rrScrPriv (pScreen); - int i; - RRScreenSize tmp; - RRScreenSizePtr pNew; + xRRMonitorMode tmp; + RRMonitorPtr pMonitor; + RRModePtr pMode, *pPrev; + char name[100]; if (!pScrPriv) - return 0; + return NULL; + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + return NULL; - tmp.id = -1; - tmp.width = width; - tmp.height= height; - tmp.mmWidth = mmWidth; - tmp.mmHeight = mmHeight; - tmp.pRates = 0; - tmp.nRates = 0; - tmp.nRatesInUse = 0; - tmp.referenced = TRUE; - tmp.oldReferenced = FALSE; - for (i = 0; i < pScrPriv->nSizes; i++) - if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i])) + for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next)) + if (pMode->mode.width == width && + pMode->mode.height == height && + pMode->mode.widthInMillimeters == mmWidth && + pMode->mode.heightInMillimeters == mmHeight) { - pScrPriv->pSizes[i].referenced = TRUE; - return &pScrPriv->pSizes[i]; + pMode->referenced =TRUE; + return (void *) pMode; } - pNew = xrealloc (pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof (RRScreenSize)); - if (!pNew) - return 0; - pNew[pScrPriv->nSizes++] = tmp; - pScrPriv->pSizes = pNew; - return &pNew[pScrPriv->nSizes-1]; + memset (&tmp, '\0', sizeof (xRRMonitorMode)); + memset (name, '\0', sizeof (name)); + sprintf (name, "%dx%d", width, height); + tmp.width = width; + tmp.height= height; + tmp.widthInMillimeters = mmWidth; + tmp.heightInMillimeters = mmHeight; + tmp.nameLength = strlen (name) + 10; /* leave space for refresh */ + pMode = RRRegisterMode (pMonitor, &tmp, name); + return (void *) pMode; +} + +static Bool +RRModesMatchSize (RRModePtr a, RRModePtr b) +{ + return (a->mode.width == a->mode.width && + a->mode.height == b->mode.height && + a->mode.widthInMillimeters == b->mode.widthInMillimeters && + a->mode.heightInMillimeters == b->mode.heightInMillimeters); } Bool RRRegisterRate (ScreenPtr pScreen, @@ -1347,31 +1646,61 @@ Bool RRRegisterRate (ScreenPtr pScreen, int rate) { rrScrPriv(pScreen); - int i; - RRScreenRatePtr pNew, pRate; + RRMonitorPtr pMonitor; + RRModePtr pSizeMode = (RRModePtr) pSize; + RRModePtr pMode, *pPrev; + CARD16 width = pSizeMode->mode.width; + CARD16 height = pSizeMode->mode.height; + char name[100]; + xRRMonitorMode modeLine; if (!pScrPriv) return FALSE; - for (i = 0; i < pSize->nRates; i++) + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + return FALSE; + + for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &pMode->next) { - pRate = &pSize->pRates[i]; - if (pRate->rate == rate) + if (RRModesMatchSize (pMode, pSizeMode)) { - pRate->referenced = TRUE; - return TRUE; + if (pMode->mode.dotClock == 0) + { + /* + * First refresh for this size; reprogram this mode + * with the right refresh. + */ + pMode->mode.hSyncStart = width; + pMode->mode.hSyncEnd = width; + pMode->mode.hTotal = width; + pMode->mode.hSkew = 0; + pMode->mode.vSyncStart = height; + pMode->mode.vSyncEnd = height; + pMode->mode.vTotal = height; + pMode->mode.dotClock = width * height * rate; + sprintf ((char *) (pMode + 1), "%dx%d@%d", width, height, rate); + pMode->mode.modeFlags = 0; + pMode->mode.nameLength = strlen ((char *) (pMode + 1)); + pMode->referenced = TRUE; + return TRUE; + } + else if (rate == RRVerticalRefresh (&pMode->mode)) + { + pMode->referenced = TRUE; + return TRUE; + } } } - - pNew = xrealloc (pSize->pRates, - (pSize->nRates + 1) * sizeof (RRScreenRate)); - if (!pNew) + + sprintf (name, "%dx%d@%d", pSizeMode->mode.width, pSizeMode->mode.height, + rate); + modeLine = pSizeMode->mode; + modeLine.dotClock = rate * modeLine.vTotal * modeLine.hTotal; + modeLine.nameLength = strlen (name); + pMode = RRRegisterMode (pMonitor, &modeLine, name); + if (!pMode) return FALSE; - pRate = &pNew[pSize->nRates++]; - pRate->rate = rate; - pRate->referenced = TRUE; - pRate->oldReferenced = FALSE; - pSize->pRates = pNew; return TRUE; } @@ -1379,11 +1708,15 @@ Rotation RRGetRotation(ScreenPtr pScreen) { rrScrPriv (pScreen); + RRMonitorPtr pMonitor; if (!pScrPriv) return RR_Rotate_0; - return pScrPriv->rotation; + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + return RR_Rotate_0; + return pMonitor->rotation; } void @@ -1393,11 +1726,25 @@ RRSetCurrentConfig (ScreenPtr pScreen, RRScreenSizePtr pSize) { rrScrPriv (pScreen); + RRMonitorPtr pMonitor; + RRModePtr pMode; + RRModePtr pSizeMode = (RRModePtr) pSize; if (!pScrPriv) return; + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + return; - pScrPriv->rotation = rotation; - pScrPriv->size = pSize - pScrPriv->pSizes; - pScrPriv->rate = rate; + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + { + if (RRModesMatchSize (pMode, pSizeMode) && + RRVerticalRefresh (&pMode->mode) == rate) + break; + } + if (!pMode) + return; + + RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); } +#endif diff --git a/randr/randrstr.h b/randr/randrstr.h index 07c6c3798..3610274cc 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -34,11 +34,19 @@ #include +#define RANDR_SCREEN_INTERFACE 1 + +/* + * Modeline for a monitor. Name follows directly after this struct + */ + +#define RRModeName(pMode) ((char *) (pMode + 1)) + typedef struct _rrMode { struct _rrMode *next; - int id; Bool referenced; Bool oldReferenced; + int id; xRRMonitorMode mode; } RRMode, *RRModePtr; @@ -47,12 +55,15 @@ typedef struct _rrMonitor { ScreenPtr pScreen; RRModePtr pModes; void *identifier; /* made unique by DDX */ + int id; /* index in list of monitors */ Bool referenced; + Bool oldReferenced; + Rotation rotations; /* * Current state */ - int mode; + RRModePtr pMode; int x, y; Rotation rotation; } RRMonitor, *RRMonitorPtr; @@ -76,7 +87,18 @@ typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); #ifdef RANDR_SCREEN_INTERFACE -typedef void *RRScreenSizePtr; +typedef struct _rrRefresh { + CARD16 refresh; + RRModePtr pMode; +} RRRefreshRec, *RRRefreshPtr; + +typedef struct _rrScreenSize { + int id; + short width, height; + short mmWidth, mmHeight; + int nrefresh; + RRRefreshPtr refresh; +} RRScreenSizeRec, *RRScreenSizePtr; typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, Rotation rotation, @@ -87,12 +109,23 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, typedef struct _rrScrPriv { - RRSetModeProcPtr rrSetMode; + /* + * 'public' part of the structure; DDXen fill this in + * as they initialize + */ +#ifdef RANDR_SCREEN_INTERFACE + RRSetConfigProcPtr rrSetConfig; +#endif RRGetInfoProcPtr rrGetInfo; - RRCloseScreenProcPtr CloseScreen; + RRSetScreenSizeProcPtr rrSetScreenSize; + RRSetModeProcPtr rrSetMode; + /* + * Private part of the structure; not considered part of the ABI + */ TimeStamp lastSetTime; /* last changed by client */ TimeStamp lastConfigTime; /* possible configs changed */ + RRCloseScreenProcPtr CloseScreen; /* * monitor data @@ -105,7 +138,6 @@ typedef struct _rrScrPriv { */ Rotation rotations; - RRSetConfigProcPtr rrSetConfig; Rotation rotation; #endif @@ -137,8 +169,7 @@ RRRegisterMonitor (ScreenPtr pScreen, RRModePtr RRRegisterMode (RRMonitorPtr pMonitor, xRRMonitorMode *pMode, - char *name, - int nameLength); + char *name); /* * Finally, set the current configuration of each monitor @@ -147,6 +178,8 @@ RRRegisterMode (RRMonitorPtr pMonitor, void RRSetCurrentMode (RRMonitorPtr pMonitor, RRModePtr pMode, + int x, + int y, Rotation rotation); Bool RRScreenInit(ScreenPtr pScreen); @@ -167,6 +200,8 @@ Bool miRRSetMode (ScreenPtr pScreen, int monitor, RRModePtr pMode, + int x, + int y, Rotation rotation); #ifdef RANDR_SCREEN_INTERFACE -- cgit v1.2.3 From 8dec74321d916f204f8182f1b93a65defbe50e78 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 17 Jul 2006 14:43:07 -0400 Subject: Successful legacy RandR API/Protocol emulation for query. These changes clean up minor errors to make it possible to list the available modes for a monitor using legacy APIs in both the X server DDX and RandR protocol. Setting modes is untested, so it probably doesn't work. --- randr/randr.c | 331 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 178 insertions(+), 153 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 4a5cd4e1d..58d8f177f 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -542,6 +542,7 @@ RRGetInfo (ScreenPtr pScreen) pMode->id = modeid++; if (!pMode->oldReferenced) changed = TRUE; + pPrevMode = &pMode->next; } else { @@ -550,6 +551,7 @@ RRGetInfo (ScreenPtr pScreen) RRFreeMode (pMode); } } + pPrevMon = &pMonitor->next; } else { @@ -716,6 +718,7 @@ RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor) return NULL; size = (RRScreenSizePtr) (data + 1); refresh = (RRRefreshPtr) (size + nmode); + data->sizes = size; data->nsize = 0; data->nrefresh = 0; data->size = 0; @@ -728,6 +731,7 @@ RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor) break; if (i == data->nsize) { + size[i].id = i; size[i].width = pMode->mode.width; size[i].height = pMode->mode.height; size[i].mmWidth = pMode->mode.widthInMillimeters; @@ -823,7 +827,7 @@ ProcRRGetScreenInfo (ClientPtr client) rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; rep.rotation = pMonitor->rotation; rep.nSizes = pData->nsize; - rep.nrateEnts = pData->nrefresh; + rep.nrateEnts = pData->nrefresh + pData->nsize; rep.sizeID = pData->size; rep.rate = pData->refresh; @@ -903,6 +907,97 @@ ProcRRGetScreenInfo (ClientPtr client) return (client->noClientException); } +static int +RRMonitorSetMode (ScreenPtr pScreen, RRMonitorPtr pMonitor, + RRModePtr pMode, int x, int y, Rotation rotation, + TimeStamp time) +{ + rrScrPriv(pScreen); + short oldWidth, oldHeight; + + oldWidth = pScreen->width; + oldHeight = pScreen->height; + + /* + * call out to ddx routine to effect the change + */ + if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode) + { + xScreenSizes oldSize; + if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0)) + return RRSetConfigFailed; + oldSize.widthInPixels = pScreen->width; + oldSize.heightInPixels = pScreen->width; + oldSize.widthInMillimeters = pScreen->mmWidth; + oldSize.heightInMillimeters = pScreen->mmHeight; + if (!(*pScrPriv->rrSetScreenSize) (pScreen, + pMode->mode.width, + pMode->mode.height, + pMode->mode.widthInMillimeters, + pMode->mode.heightInMillimeters)) + { + (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, + pMonitor->x, pMonitor->y, + pMonitor->rotation); + return RRSetConfigFailed; + } + if (!(*pScrPriv->rrSetMode) (pScreen, 0, pMode, 0, 0, rotation)) + { + (void) (*pScrPriv->rrSetScreenSize) (pScreen, + oldSize.widthInPixels, + oldSize.heightInPixels, + oldSize.widthInMillimeters, + oldSize.heightInMillimeters); + (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, + pMonitor->x, pMonitor->y, + pMonitor->rotation); + return RRSetConfigFailed; + } + } +#ifdef RANDR_SCREEN_INTERFACE + else if (pScrPriv->rrSetConfig) + { + int rate = RRVerticalRefresh (&pMode->mode); + RRScreenSizeRec size; + + size.width = pMode->mode.width; + size.height = pMode->mode.height; + size.mmWidth = pMode->mode.widthInMillimeters; + size.mmHeight = pMode->mode.heightInMillimeters; + if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, &size)) + return RRSetConfigFailed; + } +#endif + else + return RRSetConfigFailed; + + /* + * set current extension configuration pointers + */ + RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); + + /* + * Deliver ScreenChangeNotify events whenever + * the configuration is updated + */ + WalkTree (pScreen, TellChanged, (pointer) pScreen); + + /* + * Deliver ConfigureNotify events when root changes + * pixel size + */ + if (oldWidth != pScreen->width || oldHeight != pScreen->height) + RRSendConfigNotify (pScreen); + RREditConnectionInfo (pScreen); + + /* + * Fix pointer bounds and location + */ + ScreenRestructured (pScreen); + pScrPriv->lastSetTime = time; + return RRSetConfigSuccess; +} + static int ProcRRSetScreenConfig (ClientPtr client) { @@ -917,7 +1012,6 @@ ProcRRSetScreenConfig (ClientPtr client) int i; Rotation rotation; int rate; - short oldWidth, oldHeight; Bool has_rate; RRMonitorPtr pMonitor; RRModePtr pMode; @@ -947,9 +1041,6 @@ ProcRRSetScreenConfig (ClientPtr client) time = ClientTimeToServerTime(stuff->timestamp); configTime = ClientTimeToServerTime(stuff->configTimestamp); - oldWidth = pScreen->width; - oldHeight = pScreen->height; - if (!pScrPriv) { time = currentTime; @@ -1063,90 +1154,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - /* - * call out to ddx routine to effect the change - */ - if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode) - { - xScreenSizes oldSize; - if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0)) - goto fail; - oldSize.widthInPixels = pScreen->width; - oldSize.heightInPixels = pScreen->width; - oldSize.widthInMillimeters = pScreen->mmWidth; - oldSize.heightInMillimeters = pScreen->mmHeight; - if (!(*pScrPriv->rrSetScreenSize) (pScreen, - pMode->mode.width, - pMode->mode.height, - pMode->mode.widthInMillimeters, - pMode->mode.heightInMillimeters)) - { - (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, - pMonitor->x, pMonitor->y, - pMonitor->rotation); - goto fail; - } - if (!(*pScrPriv->rrSetMode) (pScreen, 0, pMode, 0, 0, rotation)) - { - (void) (*pScrPriv->rrSetScreenSize) (pScreen, - oldSize.widthInPixels, - oldSize.heightInPixels, - oldSize.widthInMillimeters, - oldSize.heightInMillimeters); - (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, - pMonitor->x, pMonitor->y, - pMonitor->rotation); - goto fail; - } - } -#ifdef RANDR_SCREEN_INTERFACE - else if (pScrPriv->rrSetConfig) - { - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, pSize)) - { - goto fail; - } - } -#endif - else - { -fail: ; - /* - * unknown DDX failure, report to client - */ - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; - - /* - * Report Success - */ - rep.status = RRSetConfigSuccess; + rep.status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, rotation, time); sendReply: @@ -1182,11 +1190,20 @@ RRSetScreenConfig (ScreenPtr pScreen, RRScreenSizePtr pSize) { rrScrPrivPtr pScrPriv; - int i; + RRMonitorPtr pMonitor; short oldWidth, oldHeight; + RRModePtr pMode; + int status; pScrPriv = rrGetScrPriv(pScreen); + if (!pScrPriv) + return BadImplementation; + + pMonitor = pScrPriv->pMonitors; + if (!pMonitor) + return BadImplementation; + oldWidth = pScreen->width; oldHeight = pScreen->height; @@ -1219,61 +1236,24 @@ RRSetScreenConfig (ScreenPtr pScreen, return BadMatch; } - /* - * Validate requested refresh - */ - if (rate) + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) { - for (i = 0; i < pSize->nRates; i++) - { - RRScreenRatePtr pRate = &pSize->pRates[i]; - if (pRate->referenced && pRate->rate == rate) - break; - } - if (i == pSize->nRates) + if (pMode->mode.width == pSize->width && + pMode->mode.height == pSize->height && + pMode->mode.widthInMillimeters == pSize->mmWidth && + pMode->mode.heightInMillimeters == pSize->mmHeight && + (RRVerticalRefresh (&pMode->mode) == rate || rate == 0)) { - /* - * Invalid rate - */ - return BadValue; + break; } } - - /* - * call out to ddx routine to effect the change - */ - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, - pSize)) - { - /* - * unknown DDX failure, report to client - */ - return BadImplementation; - } - - /* - * set current extension configuration pointers - */ - RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); + if (!pMode) + return BadValue; - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); + status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, + rotation, currentTime); + if (status != RRSetConfigSuccess) + return BadImplementation; return Success; } @@ -1387,23 +1367,63 @@ ProcRRSelectInput (ClientPtr client) } +static int ProcRRGetScreenSizeRange (ClientPtr pClient) +{ + return BadImplementation; +} + +static int ProcRRSetScreenSize (ClientPtr pClient) +{ + return BadImplementation; +} + +static int ProcRRGetMonitorInfo (ClientPtr pClient) +{ + return BadImplementation; +} + +static int ProcRRAddMonitorMode (ClientPtr pClient) +{ + return BadImplementation; +} + +static int ProcRRDeleteMonitorMode (ClientPtr pClient) +{ + return BadImplementation; +} + +static int ProcRRSetMonitorConfig (ClientPtr pClient) +{ + return BadImplementation; +} + +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 */ + ProcRRGetMonitorInfo, /* 8 */ + ProcRRAddMonitorMode, /* 9 */ + ProcRRDeleteMonitorMode, /* 10 */ + ProcRRSetMonitorConfig, /* 11 */ +}; + + static int ProcRRDispatch (ClientPtr client) { REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return ProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return ProcRRSetScreenConfig(client); - case X_RRSelectInput: - return ProcRRSelectInput(client); - case X_RRGetScreenInfo: - return ProcRRGetScreenInfo(client); - default: + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; - } + return (*ProcRandrVector[stuff->data]) (client); } static int @@ -1609,7 +1629,12 @@ RRRegisterSize (ScreenPtr pScreen, return NULL; pMonitor = pScrPriv->pMonitors; if (!pMonitor) - return NULL; + { + pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); + if (!pMonitor) + return NULL; + } + pMonitor->referenced = TRUE; for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next)) if (pMode->mode.width == width && -- cgit v1.2.3 From d17fb9672e238a089e463ac74cc4cd3325b67e1f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Sep 2006 21:44:42 -0700 Subject: Start moving to new randr 1.2 definition --- randr/mirandr.c | 105 ++--- randr/randr.c | 1324 ++++++++++++++++++++++++++++++++++-------------------- randr/randrstr.h | 239 +++++++--- 3 files changed, 1057 insertions(+), 611 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index e15213327..5aea38d60 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -34,51 +34,9 @@ #include "randrstr.h" #include -/* - * This function assumes that only a single depth can be - * displayed at a time, but that all visuals of that depth - * can be displayed simultaneously. It further assumes that - * only a single size is available. Hardware providing - * additional capabilties should use different code. - * XXX what to do here.... - */ - Bool miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) { - int i; - Bool setConfig = FALSE; - RRMonitorPtr pMonitor; - - pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); - for (i = 0; i < pScreen->numDepths; i++) - { - if (pScreen->allowedDepths[i].numVids) - { - xRRMonitorMode rrMode; - RRModePtr pMode; - char name[64]; - - sprintf (name, "%dx%d", pScreen->width, pScreen->height); - memset (&rrMode, '\0', sizeof (rrMode)); - rrMode.width = pScreen->width; - rrMode.height = pScreen->height; - rrMode.widthInMillimeters = pScreen->mmWidth; - rrMode.heightInMillimeters = pScreen->mmHeight; - rrMode.nameLength = strlen (name); - pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); - pMode = RRRegisterMode (pMonitor, - &rrMode, - name); - if (!pMode) - return FALSE; - if (!setConfig) - { - RRSetCurrentMode (pMonitor, pMode, 0, 0, RR_Rotate_0); - setConfig = TRUE; - } - } - } return TRUE; } @@ -87,26 +45,73 @@ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations) * different here */ Bool -miRRSetMode (ScreenPtr pScreen, - int monitor, - RRModePtr pMode, +miRRCrtcSet (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, int x, int y, - Rotation rotation) + Rotation rotation, + int numOutput, + RROutputPtr *outputs) { return TRUE; } +/* + * This function assumes that only a single depth can be + * displayed at a time, but that all visuals of that depth + * can be displayed simultaneously. It further assumes that + * only a single size is available. Hardware providing + * additional capabilties should use different code. + * XXX what to do here.... + */ Bool miRandRInit (ScreenPtr pScreen) { - rrScrPrivPtr rp; + rrScrPrivPtr pScrPriv; + RRModePtr mode; + RRCrtcPtr crtc; + RROutputPtr output; + xRRModeInfo modeInfo; + char name[64]; if (!RRScreenInit (pScreen)) return FALSE; - rp = rrGetScrPriv(pScreen); - rp->rrGetInfo = miRRGetInfo; - rp->rrSetMode = miRRSetMode; + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = miRRGetInfo; + pScrPriv->rrCrtcSet = miRRCrtcSet; + + RRScreenSetSizeRange (pScreen, + pScreen->width, pScreen->height, + pScreen->width, pScreen->height); + + sprintf (name, "%dx%d", pScreen->width, pScreen->height); + memset (&modeInfo, '\0', sizeof (modeInfo)); + modeInfo.width = pScreen->width; + modeInfo.height = pScreen->height; + modeInfo.mmWidth = pScreen->mmWidth; + modeInfo.mmHeight = pScreen->mmHeight; + modeInfo.nameLength = strlen (name); + + mode = RRModeGet (pScreen, &modeInfo, name); + if (!mode) + return FALSE; + + crtc = RRCrtcCreate (pScreen, NULL); + if (!crtc) + return FALSE; + + output = RROutputCreate (pScreen, "screen", 6, NULL); + if (!output) + return FALSE; + if (!RROutputSet (output, + NULL, 0, /* clones */ + &mode, 1, /* modes */ + &crtc, 1, /* crtcs */ + RR_Connected)) + return FALSE; + if (!RRCrtcSet (crtc, mode, 0, 0, RR_Rotate_0, 1, &output)) + return FALSE; return TRUE; } diff --git a/randr/randr.c b/randr/randr.c index 58d8f177f..e34b82c2f 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -60,6 +60,8 @@ int RRGeneration; int RRNScreens; +static RESTYPE ModeType, CrtcType, OutputType; + static int ProcRRQueryVersion (ClientPtr pClient); static int ProcRRDispatch (ClientPtr pClient); static int SProcRRDispatch (ClientPtr pClient); @@ -160,21 +162,16 @@ static Bool RRCloseScreen (int i, ScreenPtr pScreen) { rrScrPriv(pScreen); - RRMonitorPtr pMonitor; + int j; unwrap (pScrPriv, pScreen, CloseScreen); - while ((pMonitor = pScrPriv->pMonitors)) - { - RRModePtr pMode; - - pScrPriv->pMonitors = pMonitor->next; - while ((pMode = pMonitor->pModes)) - { - pMonitor->pModes = pMode->next; - xfree (pMode); - } - xfree (pMonitor); - } + for (j = pScrPriv->numCrtcs - 1; j >= 0; j--) + RRCrtcDestroy (pScrPriv->crtcs[j]); + for (j = pScrPriv->numOutputs - 1; j >= 0; j--) + RROutputDestroy (pScrPriv->outputs[j]); + for (j = pScrPriv->numModes - 1; j >= 0; j--) + RRModeDestroy (pScrPriv->modes[j]); + xfree (pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ return (*pScreen->CloseScreen) (i, pScreen); @@ -199,6 +196,7 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, cpswaps(from->subpixelOrder, to->subpixelOrder); } +#if 0 static void SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from, xRRMonitorChangeNotifyEvent *to) @@ -217,30 +215,68 @@ SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from, cpswaps(from->x, to->x); cpswaps(from->y, to->y); } +#endif static void SRRNotifyEvent (xEvent *from, xEvent *to) { switch (from->u.u.detail) { +#if 0 case RRNotify_MonitorChange: SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from, (xRRMonitorChangeNotifyEvent *) to); break; +#endif default: break; } } +static int +RRModeDestroyResource (pointer value, XID pid) +{ + RRModeDestroy ((RRModePtr) value); + return 1; +} + +static int +RRCrtcDestroyResource (pointer value, XID pid) +{ + RRCrtcDestroy ((RRCrtcPtr) value); + return 1; +} + +static int +RROutputDestroyResource (pointer value, XID pid) +{ + RROutputDestroy ((RROutputPtr) value); + return 1; +} + Bool RRScreenInit(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; if (RRGeneration != serverGeneration) { + ModeType = CreateNewResourceType (RRModeDestroyResource); + if (!ModeType) + return FALSE; + CrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!ModeType) + return FALSE; + OutputType = CreateNewResourceType (RROutputDestroyResource); + if (!ModeType) + return FALSE; if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) return FALSE; RRGeneration = serverGeneration; +#ifdef XResExtension + RegisterResourceName (ModeType, "MODE"); + RegisterResourceName (CrtcType, "CRTC"); + RegisterResourceName (OutputType, "OUTPUT"); +#endif } pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); @@ -252,10 +288,14 @@ Bool RRScreenInit(ScreenPtr pScreen) /* * Calling function best set these function vectors */ - pScrPriv->rrSetMode = 0; + pScrPriv->rrCrtcSet = 0; pScrPriv->rrGetInfo = 0; + pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; + pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; #ifdef RANDR_SCREEN_INTERFACE pScrPriv->rrSetConfig = 0; + pScrPriv->reqWidth = pScreen->width; + pScrPriv->reqHeight = pScreen->height; #endif /* @@ -268,7 +308,12 @@ Bool RRScreenInit(ScreenPtr pScreen) wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - pScrPriv->pMonitors = NULL; + pScrPriv->numModes = 0; + pScrPriv->modes = NULL; + pScrPriv->numOutputs = 0; + pScrPriv->outputs = NULL; + pScrPriv->numCrtcs = 0; + pScrPriv->crtcs = NULL; RRNScreens += 1; /* keep count of screens that implement randr */ return TRUE; @@ -356,18 +401,77 @@ RRExtensionInit (void) return; } +static void +DeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + xRRScreenChangeNotifyEvent se; + RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL; + RROutputPtr output = pScrPriv->numOutputs ? pScrPriv->outputs[0] : NULL; + RRModePtr mode = crtc ? crtc->mode : NULL; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + int i; + + se.type = RRScreenChangeNotify + RREventBase; + se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0); + se.timestamp = pScrPriv->lastSetTime.milliseconds; + se.sequenceNumber = client->sequence; + se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + se.root = pRoot->drawable.id; + se.window = pWin->drawable.id; +#ifdef RENDER + se.subpixelOrder = PictureGetSubpixelOrder (pScreen); +#else + se.subpixelOrder = SubPixelUnknown; +#endif + + se.sequenceNumber = client->sequence; + if (mode) + { + se.sizeID = -1; + for (i = 0; i < output->numModes; i++) + if (mode == output->modes[i]) + { + se.sizeID = i; + break; + } + se.widthInPixels = mode->mode.width; + se.heightInPixels = mode->mode.height; + se.widthInMillimeters = mode->mode.mmWidth; + se.heightInMillimeters = mode->mode.mmHeight; + } + else + { + /* + * This "shouldn't happen", but a broken DDX can + * forget to set the current configuration on GetInfo + */ + se.sizeID = 0xffff; + se.widthInPixels = 0; + se.heightInPixels = 0; + se.widthInMillimeters = 0; + se.heightInMillimeters = 0; + } + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +static void +DeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) +{ +} + +static void +DeliverOutputEvent (ClientPtr client, WindowPtr pWin, RROutputPtr output) +{ +} + static int TellChanged (WindowPtr pWin, pointer value) { RREventPtr *pHead, pRREvent; ClientPtr client; - xRRScreenChangeNotifyEvent se; - xRRMonitorChangeNotifyEvent me; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); - RRModePtr pMode; - RRMonitorPtr pMonitor; - WindowPtr pRoot = WindowTable[pScreen->myNum]; int i; pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); @@ -380,192 +484,245 @@ TellChanged (WindowPtr pWin, pointer value) if (client == serverClient || client->clientGone) continue; - if (pRREvent->mask & RRMonitorChangeNotifyMask) + if (pRREvent->mask & RRScreenChangeNotifyMask) + DeliverScreenEvent (client, pWin, pScreen); + + if (pRREvent->mask & RRCrtcChangeNotifyMask) { - me.type = RRNotify + RREventBase; - me.subCode = RRNotify_MonitorChange; - me.timestamp = pScrPriv->lastSetTime.milliseconds; - me.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - me.root = pRoot->drawable.id; - me.window = pWin->drawable.id; -#ifdef RENDER - me.subpixelOrder = PictureGetSubpixelOrder (pScreen); -#else - me.subpixelOrder = SubPixelUnknown; -#endif - for (pMonitor = pScrPriv->pMonitors, i = 0; - pMonitor; - pMonitor = pMonitor->next, i++) + for (i = 0; i < pScrPriv->numCrtcs; i++) { - me.monitor = i; - if (pMonitor->pMode) { - me.modeID = pMonitor->pMode->id; - me.rotation = pMonitor->rotation; - me.x = pMonitor->x; - me.y = pMonitor->y; - } else { - me.modeID = 0xffff; - me.rotation = RR_Rotate_0; - me.x = 0; - me.y = 0; - } - WriteEventsToClient (client, 1, (xEvent *) &me); + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (crtc->changed) + DeliverCrtcEvent (client, pWin, crtc); } } - if ((pRREvent->mask & RRScreenChangeNotifyMask) && - (pMonitor = pScrPriv->pMonitors)) + + if (pRREvent->mask & RROutputChangeNotifyMask) { - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) pMonitor->rotation; - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.sequenceNumber = client->sequence; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; -#ifdef RENDER - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); -#else - se.subpixelOrder = SubPixelUnknown; -#endif - - pMonitor = &pScrPriv->pMonitors[0]; - se.sequenceNumber = client->sequence; - if (pMonitor->pMode) + for (i = 0; i < pScrPriv->numOutputs; i++) { - pMode = pMonitor->pMode; - se.sizeID = pMode->id; - se.widthInPixels = pMode->mode.width; - se.heightInPixels = pMode->mode.height; - se.widthInMillimeters = pMode->mode.widthInMillimeters; - se.heightInMillimeters = pMode->mode.heightInMillimeters; + RROutputPtr output = pScrPriv->outputs[i]; + if (output->changed) + DeliverOutputEvent (client, pWin, output); } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - WriteEventsToClient (client, 1, (xEvent *) &se); } } return WT_WALKCHILDREN; } -static void -RRFreeMode (RRModePtr pMode) +void +RRTellChanged (ScreenPtr pScreen) { - xfree (pMode); + rrScrPriv (pScreen); + int i; + + if (pScrPriv->changed) + { + UpdateCurrentTime (); + pScrPriv->lastConfigTime = currentTime; + WalkTree (pScreen, TellChanged, (pointer) pScreen); + pScrPriv->changed = FALSE; + for (i = 0; i < pScrPriv->numOutputs; i++) + pScrPriv->outputs[i]->changed = FALSE; + for (i = 0; i < pScrPriv->numCrtcs; i++) + pScrPriv->crtcs[i]->changed = FALSE; + } } -static void -RRFreeModes (RRModePtr pHead) +RRModePtr +RRModeGet (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + char *name) { - RRModePtr pMode; - while ((pMode = pHead)) + rrScrPriv (pScreen); + int i; + RRModePtr mode; + + for (i = 0; i < pScrPriv->numModes; i++) { - pHead = pMode->next; - RRFreeMode (pMode); + mode = pScrPriv->modes[i]; + if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && + !memcmp (name, mode->name, modeInfo->nameLength)) + { + ++mode->refcnt; + return mode; + } } + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + mode->refcnt = 1; + mode->mode = *modeInfo; + mode->name = (char *) (mode + 1); + memcpy (mode->name, name, modeInfo->nameLength); + mode->name[modeInfo->nameLength] = '\0'; + mode->id = FakeClientID(0); + if (!AddResource (mode->id, ModeType, (pointer) mode)) + return NULL; + ++mode->refcnt; + pScrPriv->changed = TRUE; + return mode; } -static void -RRFreeMonitor (RRMonitorPtr pMonitor) +void +RRModeDestroy (RRModePtr mode) { - RRFreeModes (pMonitor->pModes); - xfree (pMonitor); + if (--mode->refcnt > 0) + return; + xfree (mode); } - -static Bool -RRGetInfo (ScreenPtr pScreen) +/* + * Return the first output which is connected to an active CRTC + * Used in emulating 1.0 behaviour + */ +static RROutputPtr +RRFirstOutput (ScreenPtr pScreen) { - rrScrPriv (pScreen); - Bool changed; - Rotation rotations; - RRMonitorPtr pMonitor, *pPrevMon; - RRModePtr pMode, *pPrevMode; - int monitorid; - - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) + rrScrPriv(pScreen); + RROutputPtr output; + int i, j; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { - pMonitor->oldReferenced = TRUE; - pMonitor->referenced = FALSE; - pMonitor->pMode = NULL; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + for (j = 0; j < pScrPriv->numOutputs; j++) { - pMode->oldReferenced = TRUE; - pMode->referenced = FALSE; + output = pScrPriv->outputs[j]; + if (output->crtc == crtc) + return output; } } - rotations = 0; - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return NULL; +} + +#ifdef RANDR_SCREEN_INTERFACE + +static Bool +RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) +{ + 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.mmWidth = size->mmWidth; + modeInfo.mmHeight = size->mmHeight; + modeInfo.hTotal = size->width; + modeInfo.vTotal = size->height; + modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->width * + (CARD32) refresh); + modeInfo.nameLength = strlen (name); + mode = RRModeGet (output->pScreen, &modeInfo, name); + if (!mode) + return FALSE; + for (i = 0; i < output->numModes; i++) + if (output->modes[i] == mode) + return TRUE; + + if (output->numModes) + modes = xrealloc (output->modes, + (output->numModes + 1) * sizeof (RRModePtr)); + else + modes = xalloc (sizeof (RRModePtr)); + if (!modes) return FALSE; + modes[output->numModes++] = mode; + output->modes = modes; + output->changed = TRUE; + return TRUE; +} - changed = FALSE; +static void +RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) +{ + rrScrPriv(pScreen); + RROutputPtr output = RRFirstOutput (pScreen); + RRCrtcPtr crtc; + int i; + CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; + CARD16 maxWidth = 0, maxHeight = 0; - /* Old GetInfo clients return rotations here */ - if (rotations && pScrPriv->pMonitors) { - /* - * Check whether anything changed and simultaneously generate - * the protocol id values for the objects - */ - if (rotations != pScrPriv->pMonitors->rotations) - { - pScrPriv->pMonitors->rotations = rotations; - changed = TRUE; - } + if (!output) + return; + crtc = output->crtc; + + /* check rotations */ + if (rotations != crtc->rotations) + { + crtc->rotations = rotations; + crtc->changed = TRUE; + pScrPriv->changed = TRUE; } - /* - * Walk monitor and mode lists looking for updates - */ - monitorid = 0; - for (pPrevMon = &pScrPriv->pMonitors; (pMonitor = *pPrevMon);) + /* regenerate mode list */ + for (i = 0; i < pScrPriv->nSizes; i++) { - int modeid = 0; - - if (pMonitor->referenced) - { - pMonitor->id = monitorid++; - if (!pMonitor->oldReferenced) - changed = TRUE; - for (pPrevMode = &pMonitor->pModes; (pMode = *pPrevMode);) - { - if (pMode->referenced) - { - pMode->id = modeid++; - if (!pMode->oldReferenced) - changed = TRUE; - pPrevMode = &pMode->next; - } - else - { - *pPrevMode = pMode->next; - changed = TRUE; - RRFreeMode (pMode); - } - } - pPrevMon = &pMonitor->next; - } + RRScreenSizePtr size = &pScrPriv->pSizes[i]; + int r; + + if (size->nRates) + for (r = 0; r < size->nRates; r++) + RROldModeAdd (output, size, size->pRates[r].rate); else - { - *pPrevMon = pMonitor->next; - changed = TRUE; - RRFreeMonitor (pMonitor); - } + RROldModeAdd (output, size, 0); } - if (changed) + + /* find size bounds */ + for (i = 0; i < output->numModes; i++) { - UpdateCurrentTime (); - pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); + RRModePtr mode = output->modes[i]; + 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; + } + + if (minWidth != pScrPriv->minWidth) { + pScrPriv->minWidth = minWidth; pScrPriv->changed = TRUE; + } + if (maxWidth != pScrPriv->maxWidth) { + pScrPriv->maxWidth = maxWidth; pScrPriv->changed = TRUE; + } + if (minHeight != pScrPriv->minHeight) { + pScrPriv->minHeight = minHeight; pScrPriv->changed = TRUE; } + if (maxHeight != pScrPriv->maxHeight) { + pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE; + } +} +#endif + +static Bool +RRGetInfo (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + Rotation rotations; + int i; + + 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; + + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return FALSE; + +#if RANDR_SCREEN_INTERFACE + if (pScrPriv->nSizes) + RRScanOldConfig (pScreen, rotations); +#endif + RRTellChanged (pScreen); return TRUE; } @@ -664,17 +821,6 @@ RREditConnectionInfo (ScreenPtr pScreen) root->mmHeight = pScreen->mmHeight; } -static int -RRNumModes (RRMonitorPtr pMonitor) -{ - int n = 0; - RRModePtr pMode; - - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - n++; - return n; -} - typedef struct _RR10Data { RRScreenSizePtr sizes; int nsize; @@ -684,7 +830,7 @@ typedef struct _RR10Data { } RR10DataRec, *RR10DataPtr; static CARD16 -RRVerticalRefresh (xRRMonitorMode *mode) +RRVerticalRefresh (xRRModeInfo *mode) { CARD32 refresh; if (!mode->hTotal || !mode->vTotal) @@ -699,61 +845,61 @@ RRVerticalRefresh (xRRMonitorMode *mode) * Convert 1.2 monitor data into 1.0 screen data */ static RR10DataPtr -RR10GetData (ScreenPtr pScreen, RRMonitorPtr pMonitor) +RR10GetData (ScreenPtr pScreen, RROutputPtr output) { RR10DataPtr data; RRScreenSizePtr size; - int nmode = RRNumModes (pMonitor); - int i; - int j; - RRRefreshPtr refresh; + int nmode = output->numModes; + int i, j, k; + RRScreenRatePtr refresh; CARD16 vRefresh; - RRModePtr pMode; + RRModePtr mode; /* Make sure there is plenty of space for any combination */ data = malloc (sizeof (RR10DataRec) + - sizeof (RRScreenSizeRec) * nmode + - sizeof (RRRefreshRec) * nmode); + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode); if (!data) return NULL; size = (RRScreenSizePtr) (data + 1); - refresh = (RRRefreshPtr) (size + nmode); + refresh = (RRScreenRatePtr) (size + nmode); data->sizes = size; data->nsize = 0; data->nrefresh = 0; data->size = 0; data->refresh = 0; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + for (i = 0; i < output->numModes; i++) { - for (i = 0; i < data->nsize; i++) - if (pMode->mode.width == size[i].width && - pMode->mode.height == size[i].height) + mode = output->modes[i]; + for (j = 0; j < data->nsize; j++) + if (mode->mode.width == size[j].width && + mode->mode.height == size[j].height) break; - if (i == data->nsize) + if (j == data->nsize) { - size[i].id = i; - size[i].width = pMode->mode.width; - size[i].height = pMode->mode.height; - size[i].mmWidth = pMode->mode.widthInMillimeters; - size[i].mmHeight = pMode->mode.heightInMillimeters; - size[i].nrefresh = 0; - size[i].refresh = &refresh[data->nrefresh]; + size[j].id = j; + size[j].width = mode->mode.width; + size[j].height = mode->mode.height; + size[j].mmWidth = mode->mode.mmWidth; + size[j].mmHeight = mode->mode.mmHeight; + size[j].nRates = 0; + size[j].pRates = &refresh[data->nrefresh]; data->nsize++; } - vRefresh = RRVerticalRefresh (&pMode->mode); - for (j = 0; j < size[i].nrefresh; j++) - if (vRefresh == size[i].refresh[j].refresh) + vRefresh = RRVerticalRefresh (&mode->mode); + for (k = 0; k < size[j].nRates; k++) + if (vRefresh == size[j].pRates[k].rate) break; - if (j == size[i].nrefresh) + if (k == size[j].nRates) { - size[i].refresh[j].refresh = vRefresh; - size[i].refresh[j].pMode = pMode; - size[i].nrefresh++; + size[j].pRates[k].rate = vRefresh; + size[j].pRates[k].mode = mode; + size[j].nRates++; data->nrefresh++; } - if (pMode == pMonitor->pMode) + if (mode == output->crtc->mode) { - data->size = i; + data->size = j; data->refresh = vRefresh; } } @@ -771,6 +917,7 @@ ProcRRGetScreenInfo (ClientPtr client) rrScrPrivPtr pScrPriv; CARD8 *extra; unsigned long extraLen; + RROutputPtr output; REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, @@ -786,7 +933,9 @@ ProcRRGetScreenInfo (ClientPtr client) if (pScrPriv) RRGetInfo (pScreen); - if (!pScrPriv && !pScrPriv->pMonitors) + output = RRFirstOutput (pScreen); + + if (!pScrPriv || !output) { rep.type = X_Reply; rep.setOfRotations = RR_Rotate_0;; @@ -805,7 +954,6 @@ ProcRRGetScreenInfo (ClientPtr client) } else { - RRMonitorPtr pMonitor = pScrPriv->pMonitors; int i, j; xScreenSizes *size; CARD16 *rates; @@ -814,18 +962,18 @@ ProcRRGetScreenInfo (ClientPtr client) RR10DataPtr pData; RRScreenSizePtr pSize; - pData = RR10GetData (pScreen, pMonitor); + pData = RR10GetData (pScreen, output); if (!pData) return BadAlloc; rep.type = X_Reply; - rep.setOfRotations = pMonitor->rotations; + rep.setOfRotations = output->crtc->rotations; rep.sequenceNumber = client->sequence; rep.length = 0; rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = pMonitor->rotation; + rep.rotation = output->crtc->rotation; rep.nSizes = pData->nsize; rep.nrateEnts = pData->nrefresh + pData->nsize; rep.sizeID = pData->size; @@ -862,15 +1010,15 @@ ProcRRGetScreenInfo (ClientPtr client) size++; if (has_rate) { - *rates = pSize->nrefresh; + *rates = pSize->nRates; if (client->swapped) { swaps (rates, n); } rates++; - for (j = 0; j < pSize->nrefresh; j++) + for (j = 0; j < pSize->nRates; j++) { - *rates = pSize->refresh[j].refresh; + *rates = pSize->pRates[j].rate; if (client->swapped) { swaps (rates, n); @@ -907,6 +1055,7 @@ ProcRRGetScreenInfo (ClientPtr client) return (client->noClientException); } +#if 0 static int RRMonitorSetMode (ScreenPtr pScreen, RRMonitorPtr pMonitor, RRModePtr pMode, int x, int y, Rotation rotation, @@ -997,6 +1146,7 @@ RRMonitorSetMode (ScreenPtr pScreen, RRMonitorPtr pMonitor, pScrPriv->lastSetTime = time; return RRSetConfigSuccess; } +#endif static int ProcRRSetScreenConfig (ClientPtr client) @@ -1013,8 +1163,8 @@ ProcRRSetScreenConfig (ClientPtr client) Rotation rotation; int rate; Bool has_rate; - RRMonitorPtr pMonitor; - RRModePtr pMode; + RROutputPtr output; + RRModePtr mode; RR10DataPtr pData = NULL; RRScreenSizePtr pSize; @@ -1050,8 +1200,8 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRGetInfo (pScreen)) return BadAlloc; - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) + output = RRFirstOutput (pScreen); + if (!output) { time = currentTime; rep.status = RRSetConfigFailed; @@ -1069,7 +1219,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - pData = RR10GetData (pScreen, pMonitor); + pData = RR10GetData (pScreen, output); if (!pData) return BadAlloc; @@ -1105,7 +1255,7 @@ ProcRRSetScreenConfig (ClientPtr client) return BadValue; } - if ((~pMonitor->rotations) & rotation) + if ((~output->crtc->rotations) & rotation) { /* * requested rotation or reflection not supported by screen @@ -1125,12 +1275,12 @@ ProcRRSetScreenConfig (ClientPtr client) if (rate) { - for (i = 0; i < pSize->nrefresh; i++) + for (i = 0; i < pSize->nRates; i++) { - if (pSize->refresh[i].refresh == rate) + if (pSize->pRates[i].rate == rate) break; } - if (i == pSize->nrefresh) + if (i == pSize->nRates) { /* * Invalid rate @@ -1139,10 +1289,10 @@ ProcRRSetScreenConfig (ClientPtr client) xfree (pData); return BadValue; } - pMode = pSize->refresh[i].pMode; + mode = pSize->pRates[i].mode; } else - pMode = pSize->refresh[0].pMode; + mode = pSize->pRates[0].mode; /* * Make sure the requested set-time is not older than @@ -1154,7 +1304,8 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - rep.status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, rotation, time); + rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + 1, &output); sendReply: @@ -1183,6 +1334,7 @@ sendReply: return (client->noClientException); } +#if 0 int RRSetScreenConfig (ScreenPtr pScreen, Rotation rotation, @@ -1252,10 +1404,42 @@ RRSetScreenConfig (ScreenPtr pScreen, status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, rotation, currentTime); + if (status != RRSetConfigSuccess) return BadImplementation; return Success; } +#endif + +static Bool +RRSetScreenSize (ScreenPtr pScreen, + CARD16 width, CARD16 height, + CARD16 widthInMillimeters, CARD16 heightInMillimeters) +{ + rrScrPriv(pScreen); + + if (pScrPriv->rrScreenSetSize) + { + return (*pScrPriv->rrScreenSetSize) (pScreen, width, height, + widthInMillimeters, + heightInMillimeters); + } +#ifdef RANDR_SCREEN_INTERFACE + else + { + /* Pend the size change until we get the set mode request. + * Yes, this is 'illegal', but the best we can do until + * drivers are updated + */ + pScrPriv->reqWidth = width; + pScrPriv->reqHeight = height; + pScreen->mmWidth = widthInMillimeters; + pScreen->mmHeight = heightInMillimeters; + return TRUE; + } +#endif + return FALSE; +} static int ProcRRSelectInput (ClientPtr client) @@ -1264,7 +1448,7 @@ ProcRRSelectInput (ClientPtr client) rrClientPriv(client); RRTimesPtr pTimes; WindowPtr pWin; - RREventPtr pRREvent, pNewRREvent, *pHead; + RREventPtr pRREvent, *pHead; XID clientResource; REQUEST_SIZE_MATCH(xRRSelectInputReq); @@ -1275,58 +1459,64 @@ ProcRRSelectInput (ClientPtr client) pWin->drawable.id, EventType, SecurityWriteAccess); - if (stuff->enable & (RRScreenChangeNotifyMask)) + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask)) { 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) - return Success; + break; } - /* build the entry */ - pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec)); - if (!pNewRREvent) - return BadAlloc; - pNewRREvent->next = 0; - pNewRREvent->client = client; - pNewRREvent->window = pWin; - pNewRREvent->mask = stuff->enable; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewRREvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent)) - 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) + if (!pRREvent) { - pHead = (RREventPtr *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); + /* build the entry */ + pRREvent = (RREventPtr) xalloc (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, ClientType, (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 *) xalloc (sizeof (RREventPtr)); + if (!pHead || + !AddResource (pWin->drawable.id, EventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; } - *pHead = 0; + pRREvent->next = *pHead; + *pHead = pRREvent; } - pNewRREvent->next = *pHead; - *pHead = pNewRREvent; /* * Now see if the client needs an event */ - if (pScrPriv) + if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) { pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; if (CompareTimeStamps (pTimes->setTime, @@ -1334,15 +1524,15 @@ ProcRRSelectInput (ClientPtr client) CompareTimeStamps (pTimes->configTime, pScrPriv->lastConfigTime) != 0) { - TellChanged (pWin, (pointer) pScreen); + DeliverScreenEvent (client, pWin, pScreen); } } } - else if (stuff->enable == xFalse) + else if (stuff->enable == 0) { /* delete the interest */ if (pHead) { - pNewRREvent = 0; + RREventPtr pNewRREvent = 0; for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { if (pRREvent->client == client) break; @@ -1366,36 +1556,340 @@ ProcRRSelectInput (ClientPtr client) return Success; } - -static int ProcRRGetScreenSizeRange (ClientPtr pClient) +/* + * Retrieve valid screen size range + */ +static int ProcRRGetScreenSizeRange (ClientPtr client) { - return BadImplementation; + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.pad = 0; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + if (pScrPriv) + { + RRGetInfo (pScreen); + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); } -static int ProcRRSetScreenSize (ClientPtr pClient) +static int ProcRRSetScreenSize (ClientPtr client) { - return BadImplementation; + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + int i; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) { + crtc = pScrPriv->crtcs[i]; + if (crtc->mode && + (crtc->x + crtc->mode->mode.width > stuff->width || + crtc->y + crtc->mode->mode.height > stuff->height)) + return BadMatch; + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRSetScreenSize (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; } -static int ProcRRGetMonitorInfo (ClientPtr pClient) +#if 0 +static int ProcRRGetMonitorInfo (ClientPtr client) { - return BadImplementation; + REQUEST(xRRGetMonitorInfoReq); + xRRGetMonitorInfoReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRMonitorPtr pMonitor; + RRModePtr pMode; + int extraLen; + CARD8 *extra; + xRRMonitorInfo *monitor; + xRRMonitorMode *mode; + CARD8 *names; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.type = X_Reply; + rep.pad = 0; + rep.sequenceNumber = client->sequence; + rep.numMonitors = 0; + rep.numModes = 0; + rep.sizeNames = 0; + if (!pScrPriv) + { + extraLen = 0; + extra = NULL; + } + else + { + int i, m, b; + for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) + { + rep.numMonitors++; + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + { + rep.numModes++; + rep.sizeNames += (1 + pMode->mode.nameLength); + } + } + extraLen = (rep.numMonitors * sizeof (xRRMonitorInfo) + + rep.numModes * sizeof (xRRMonitorMode) + + rep.sizeNames + 3) & ~3; + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + return BadAlloc; + monitor = (xRRMonitorInfo *) extra; + mode = (xRRMonitorMode *) (monitor + rep.numMonitors); + names = (CARD8 *) (mode + rep.numModes); + i = 0; + m = 0; + b = 0; + for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) + { + monitor[i].timestamp = pScrPriv->lastSetTime; + monitor[i].configTimestamp = pScrPriv->lastConfigTime; + monitor[i].x = pMonitor->x; + monitor[i].y = pMonitor->y; + monitor[i].rotation = pMonitor->rotation; + monitor[i].mode = pMonitor->pMode->id; + monitor[i].defaultMode = 0; /* XXX */ + monitor[i].rotations = pMonitor->rotations; + monitor[i].firstMode = m; + monitor[i].numModes = 0; + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + { + monitor[i].numModes++; + mode[m] = pMode->mode; + names[b] = pMode->mode.nameLength; + b++; + memcpy (names + b, (char *) (pMode + 1), + pMode->mode.nameLength); + b += pMode->mode.nameLength; + m++; + } + i++; + } + if ((char *) (names + ((b + 3) & ~3)) != (char *) extra + extraLen) + FatalError ("RRGetMonitorInfo length mismatch\n"); + } + rep.length = extraLen >> 2; + + WriteToClient(client, sizeof(xRRGetMonitorInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + if (extra) + xfree (extra); + return (client->noClientException); } -static int ProcRRAddMonitorMode (ClientPtr pClient) +static int ProcRRAddMonitorMode (ClientPtr client) { return BadImplementation; } -static int ProcRRDeleteMonitorMode (ClientPtr pClient) +static int ProcRRDeleteMonitorMode (ClientPtr client) { return BadImplementation; } -static int ProcRRSetMonitorConfig (ClientPtr pClient) +static int ProcRRSetMonitorConfig (ClientPtr client) { - return BadImplementation; + REQUEST(xRRSetMonitorConfigReq); + xRRSetMonitorConfigReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRMonitorPtr pMonitor; + RRModePtr pMode; + TimeStamp configTime; + TimeStamp time; + Rotation rotation; + + REQUEST_SIZE_MATCH(xRRSetScreenConfigReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) + { + if (pMonitor->id == stuff->monitorIndex) + break; + } + if (!pMonitor) + { + client->errorValue = stuff->monitorIndex; + return BadValue; + } + + for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) + { + if (pMode->id == stuff->modeIndex) + break; + } + if (!pMode) + { + client->errorValue = stuff->modeIndex; + return BadValue; + } + + /* + * 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; + return BadValue; + } + + if ((~pMonitor->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + return BadMatch; + } + + if (stuff->x + pMode->mode.width > pScreen->width) + { + client->errorValue = stufff + stuff->y + pMode->mode.height > pScreen + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRMonitorSetMode (pScreen, pMonitor, + pMode, stuff->x, stuff->y, rotation, time); + + return client->noClientException; } +#endif int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRQueryVersion, /* 0 */ @@ -1408,12 +1902,14 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRSelectInput, /* 4 */ ProcRRGetScreenInfo, /* 5 */ /* V1.2 additions */ +#if 0 ProcRRGetScreenSizeRange, /* 6 */ ProcRRSetScreenSize, /* 7 */ ProcRRGetMonitorInfo, /* 8 */ ProcRRAddMonitorMode, /* 9 */ ProcRRDeleteMonitorMode, /* 10 */ ProcRRSetMonitorConfig, /* 11 */ +#endif }; @@ -1505,113 +2001,42 @@ SProcRRDispatch (ClientPtr client) } /* - * Register a monitor for a screen. identifier is a unique identifier - * for the monitors of a particular screen. + * Register the range of sizes for the screen */ -RRMonitorPtr -RRRegisterMonitor (ScreenPtr pScreen, - void *identifier, - Rotation rotations) +void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight) { rrScrPriv (pScreen); - RRMonitorPtr pMonitor, *pPrev, *pInsert; - pInsert = NULL; - for (pPrev = &pScrPriv->pMonitors; (pMonitor = *pPrev); - pPrev = &(pMonitor)->next) - { - if (pMonitor->identifier == identifier) - { - pMonitor->referenced = TRUE; - return pMonitor; - } - if (!pMonitor->referenced) - pInsert = pPrev; - } - if (!pInsert) - pInsert = pPrev; - - /* - * New monitor, add before the first unreferenced monitor - */ - pMonitor = xalloc (sizeof (RRMonitor)); - if (!pMonitor) - return NULL; - pMonitor->pScreen = pScreen; - pMonitor->pModes = NULL; - pMonitor->identifier = identifier; - pMonitor->referenced = TRUE; - pMonitor->oldReferenced = FALSE; - pMonitor->rotations = RR_Rotate_0; - - pMonitor->pMode = NULL; - pMonitor->x = 0; - pMonitor->y = 0; - pMonitor->rotation = RR_Rotate_0; - pMonitor->next = *pInsert; - *pInsert = pMonitor; - return pMonitor; + if (!pScrPriv) + return; + pScrPriv->minWidth = minWidth; + pScrPriv->minHeight = minHeight; + pScrPriv->maxWidth = maxWidth; + pScrPriv->maxHeight = maxHeight; } -/* - * Register a mode for a monitor - */ - -RRModePtr -RRRegisterMode (RRMonitorPtr pMonitor, - xRRMonitorMode *pModeline, - char *name) -{ - RRModePtr pMode, *pPrev, *pInsert = NULL; - - /* - * Find existing mode with same modeline and name - */ - for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next)) - { - if (!memcmp (&pMode->mode, pModeline, sizeof (xRRMonitorMode)) && - pMode->mode.nameLength == pModeline->nameLength && - !memcmp (RRModeName(pMode), name, pModeline->nameLength)) - { - pMode->referenced = TRUE; - return pMode; - } - if (!pMode->referenced) - pInsert = pPrev; - } - - if (!pInsert) - pInsert = pPrev; - - /* - * Create a new mode, inserting before the first unreferenced mode - */ - pMode = xalloc (sizeof (RRMode) + pModeline->nameLength + 1); - pMode->referenced = TRUE; - pMode->oldReferenced = FALSE; - pMode->mode = *pModeline; - memcpy (RRModeName (pMode), name, pModeline->nameLength); - RRModeName(pMode)[pModeline->nameLength] = '\0'; - pMode->next = *pInsert; - *pInsert = pMode; - return pMode; -} +#ifdef RANDR_SCREEN_INTERFACE -void -RRSetCurrentMode (RRMonitorPtr pMonitor, - RRModePtr pMode, - int x, - int y, - Rotation rotation) +static Bool +RRScreenSizeMatches (RRScreenSizePtr a, + RRScreenSizePtr b) { - pMonitor->pMode = pMode; - pMonitor->x = x; - pMonitor->y = y; - pMonitor->rotation = rotation; + 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; } -#ifdef RANDR_SCREEN_INTERFACE - RRScreenSizePtr RRRegisterSize (ScreenPtr pScreen, short width, @@ -1620,50 +2045,29 @@ RRRegisterSize (ScreenPtr pScreen, short mmHeight) { rrScrPriv (pScreen); - xRRMonitorMode tmp; - RRMonitorPtr pMonitor; - RRModePtr pMode, *pPrev; - char name[100]; + int i; + RRScreenSize tmp; + RRScreenSizePtr pNew; if (!pScrPriv) - return NULL; - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) - { - pMonitor = RRRegisterMonitor (pScreen, NULL, RR_Rotate_0); - if (!pMonitor) - return NULL; - } - pMonitor->referenced = TRUE; + return 0; - for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &(pMode->next)) - if (pMode->mode.width == width && - pMode->mode.height == height && - pMode->mode.widthInMillimeters == mmWidth && - pMode->mode.heightInMillimeters == mmHeight) - { - pMode->referenced =TRUE; - return (void *) pMode; - } - memset (&tmp, '\0', sizeof (xRRMonitorMode)); - memset (name, '\0', sizeof (name)); - sprintf (name, "%dx%d", width, height); tmp.width = width; tmp.height= height; - tmp.widthInMillimeters = mmWidth; - tmp.heightInMillimeters = mmHeight; - tmp.nameLength = strlen (name) + 10; /* leave space for refresh */ - pMode = RRRegisterMode (pMonitor, &tmp, name); - return (void *) pMode; -} - -static Bool -RRModesMatchSize (RRModePtr a, RRModePtr b) -{ - return (a->mode.width == a->mode.width && - a->mode.height == b->mode.height && - a->mode.widthInMillimeters == b->mode.widthInMillimeters && - a->mode.heightInMillimeters == b->mode.heightInMillimeters); + 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 = xrealloc (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, @@ -1671,77 +2075,35 @@ Bool RRRegisterRate (ScreenPtr pScreen, int rate) { rrScrPriv(pScreen); - RRMonitorPtr pMonitor; - RRModePtr pSizeMode = (RRModePtr) pSize; - RRModePtr pMode, *pPrev; - CARD16 width = pSizeMode->mode.width; - CARD16 height = pSizeMode->mode.height; - char name[100]; - xRRMonitorMode modeLine; + int i; + RRScreenRatePtr pNew, pRate; if (!pScrPriv) return FALSE; - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) - return FALSE; + for (i = 0; i < pSize->nRates; i++) + if (pSize->pRates[i].rate == rate) + return TRUE; - for (pPrev = &pMonitor->pModes; (pMode = *pPrev); pPrev = &pMode->next) - { - if (RRModesMatchSize (pMode, pSizeMode)) - { - if (pMode->mode.dotClock == 0) - { - /* - * First refresh for this size; reprogram this mode - * with the right refresh. - */ - pMode->mode.hSyncStart = width; - pMode->mode.hSyncEnd = width; - pMode->mode.hTotal = width; - pMode->mode.hSkew = 0; - pMode->mode.vSyncStart = height; - pMode->mode.vSyncEnd = height; - pMode->mode.vTotal = height; - pMode->mode.dotClock = width * height * rate; - sprintf ((char *) (pMode + 1), "%dx%d@%d", width, height, rate); - pMode->mode.modeFlags = 0; - pMode->mode.nameLength = strlen ((char *) (pMode + 1)); - pMode->referenced = TRUE; - return TRUE; - } - else if (rate == RRVerticalRefresh (&pMode->mode)) - { - pMode->referenced = TRUE; - return TRUE; - } - } - } - - sprintf (name, "%dx%d@%d", pSizeMode->mode.width, pSizeMode->mode.height, - rate); - modeLine = pSizeMode->mode; - modeLine.dotClock = rate * modeLine.vTotal * modeLine.hTotal; - modeLine.nameLength = strlen (name); - pMode = RRRegisterMode (pMonitor, &modeLine, name); - if (!pMode) + pNew = xrealloc (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) { - rrScrPriv (pScreen); - RRMonitorPtr pMonitor; + RROutputPtr output = RRFirstOutput (pScreen); - if (!pScrPriv) + if (!output) return RR_Rotate_0; - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) - return RR_Rotate_0; - return pMonitor->rotation; + return output->crtc->rotation; } void @@ -1751,25 +2113,11 @@ RRSetCurrentConfig (ScreenPtr pScreen, RRScreenSizePtr pSize) { rrScrPriv (pScreen); - RRMonitorPtr pMonitor; - RRModePtr pMode; - RRModePtr pSizeMode = (RRModePtr) pSize; if (!pScrPriv) return; - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) - return; - - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - if (RRModesMatchSize (pMode, pSizeMode) && - RRVerticalRefresh (&pMode->mode) == rate) - break; - } - if (!pMode) - return; - - RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); + pScrPriv->size = pSize - pScrPriv->pSizes; + pScrPriv->rotation = rotation; + pScrPriv->rate = rate; } #endif diff --git a/randr/randrstr.h b/randr/randrstr.h index 3610274cc..16945231a 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -34,71 +34,94 @@ #include +/* required for ABI compatibility for now */ #define RANDR_SCREEN_INTERFACE 1 +typedef XID RRMode; +typedef XID RROutput; +typedef XID RRCrtc; + /* * Modeline for a monitor. Name follows directly after this struct */ #define RRModeName(pMode) ((char *) (pMode + 1)) - -typedef struct _rrMode { - struct _rrMode *next; - Bool referenced; - Bool oldReferenced; - int id; - xRRMonitorMode mode; -} RRMode, *RRModePtr; - -typedef struct _rrMonitor { - struct _rrMonitor *next; +typedef struct _rrMode RRModeRec, *RRModePtr; +typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; +typedef struct _rrOutput RROutputRec, *RROutputPtr; + +struct _rrMode { + RRMode id; + int refcnt; + xRRModeInfo mode; + char *name; +}; + +struct _rrCrtc { + RRCrtc id; ScreenPtr pScreen; - RRModePtr pModes; - void *identifier; /* made unique by DDX */ - int id; /* index in list of monitors */ - Bool referenced; - Bool oldReferenced; - Rotation rotations; - - /* - * Current state - */ - RRModePtr pMode; + RRModePtr mode; int x, y; Rotation rotation; -} RRMonitor, *RRMonitorPtr; - -typedef Bool (*RRSetScreenSizeProcPtr) (ScreenPtr pScreen, + Rotation rotations; + int numPossibleOutputs; + RROutputPtr *possibleOutputs; + Bool changed; + void *devPrivate; +}; + +struct _rrOutput { + RROutput id; + ScreenPtr pScreen; + char *name; + int nameLength; + CARD8 connection; + CARD8 subpixelOrder; + RRCrtcPtr crtc; + int numCrtcs; + RRCrtcPtr *crtcs; + int numClones; + RROutputPtr *outputs; + int numModes; + RRModePtr *modes; + Bool changed; + void *devPrivate; +}; + +typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, CARD16 height, CARD32 widthInMM, CARD32 heightInMM); -typedef Bool (*RRSetModeProcPtr) (ScreenPtr pScreen, - int monitor, - RRModePtr pMode, +typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, int x, int y, - Rotation rotation); + Rotation rotation, + int numOutput, + RROutputPtr *outputs); typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); - -#ifdef RANDR_SCREEN_INTERFACE - +/* These are for 1.0 compatibility */ + typedef struct _rrRefresh { - CARD16 refresh; - RRModePtr pMode; -} RRRefreshRec, *RRRefreshPtr; + CARD16 rate; + RRModePtr mode; +} RRScreenRate, *RRScreenRatePtr; typedef struct _rrScreenSize { int id; short width, height; short mmWidth, mmHeight; - int nrefresh; - RRRefreshPtr refresh; -} RRScreenSizeRec, *RRScreenSizePtr; + int nRates; + RRScreenRatePtr pRates; +} RRScreenSize, *RRScreenSizePtr; + +#ifdef RANDR_SCREEN_INTERFACE typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, Rotation rotation, @@ -117,8 +140,8 @@ typedef struct _rrScrPriv { RRSetConfigProcPtr rrSetConfig; #endif RRGetInfoProcPtr rrGetInfo; - RRSetScreenSizeProcPtr rrSetScreenSize; - RRSetModeProcPtr rrSetMode; + RRScreenSetSizeProcPtr rrScreenSetSize; + RRCrtcSetProcPtr rrCrtcSet; /* * Private part of the structure; not considered part of the ABI @@ -126,20 +149,34 @@ typedef struct _rrScrPriv { TimeStamp lastSetTime; /* last changed by client */ TimeStamp lastConfigTime; /* possible configs changed */ RRCloseScreenProcPtr CloseScreen; + Bool changed; + CARD16 minWidth, minHeight; + CARD16 maxWidth, maxHeight; - /* - * monitor data - */ - RRMonitorPtr pMonitors; + /* modes, outputs and crtcs */ + int numModes; + RRModePtr *modes; + + int numOutputs; + RROutputPtr *outputs; + + int numCrtcs; + RRCrtcPtr *crtcs; #ifdef RANDR_SCREEN_INTERFACE /* * Configuration information */ Rotation rotations; + CARD16 reqWidth, reqHeight; - + int nSizes; + RRScreenSizePtr pSizes; + + RRScreenSizePtr pSize; Rotation rotation; + int rate; + int size; #endif } rrScrPrivRec, *rrScrPrivPtr; @@ -154,33 +191,91 @@ void RRExtensionInit (void); /* - * Then, register a monitor with the screen + * Set the range of sizes for the screen + */ +void +RRScreenSetSizeRange (ScreenPtr pScreen, + CARD16 minWidth, + CARD16 minHeight, + CARD16 maxWidth, + CARD16 maxHeight); + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, + void *devPrivate); + + +/* + * Use this value for any num parameter to indicate that + * the related data are unchanged */ +#define RR_NUM_UNCHANGED -1 -RRMonitorPtr -RRRegisterMonitor (ScreenPtr pScreen, - void *identifier, - Rotation rotations); +/* + * Notify the extension that the Crtc has been reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutput, + RROutputPtr *outputs); + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc); /* - * Next, register the list of modes with the monitor + * Find, and if necessary, create a mode */ RRModePtr -RRRegisterMode (RRMonitorPtr pMonitor, - xRRMonitorMode *pMode, - char *name); +RRModeGet (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + char *name); + +/* + * Destroy a mode. + */ + +void +RRModeDestroy (RRModePtr mode); /* - * Finally, set the current configuration of each monitor + * Create an output */ +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + char *name, + int nameLength, + void *devPrivate); + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSet (RROutputPtr output, + RROutputPtr *clones, + int numClones, + RRModePtr *modes, + int numModes, + RRCrtcPtr *crtcs, + int numCrtcs, + CARD8 connection); + +void +RROutputDestroy (RROutputPtr output); + void -RRSetCurrentMode (RRMonitorPtr pMonitor, - RRModePtr pMode, - int x, - int y, - Rotation rotation); +RRTellChanged (ScreenPtr pScreen); Bool RRScreenInit(ScreenPtr pScreen); @@ -197,12 +292,14 @@ Bool miRRGetScreenInfo (ScreenPtr pScreen); Bool -miRRSetMode (ScreenPtr pScreen, - int monitor, - RRModePtr pMode, +miRRCrtcSet (ScreenPtr pScreen, + RRCrtcPtr crtc, + RRModePtr mode, int x, int y, - Rotation rotation); + Rotation rotation, + int numOutput, + RROutputPtr *outputs); #ifdef RANDR_SCREEN_INTERFACE /* @@ -225,9 +322,6 @@ Bool RRRegisterRate (ScreenPtr pScreen, RRScreenSizePtr pSize, int rate); -Bool RRRegisterRotation (ScreenPtr pScreen, - Rotation rotation); - /* * Finally, set the current configuration of the screen */ @@ -238,17 +332,16 @@ RRSetCurrentConfig (ScreenPtr pScreen, int rate, RRScreenSizePtr pSize); +Bool RRScreenInit (ScreenPtr pScreen); + +Rotation +RRGetRotation (ScreenPtr pScreen); + int RRSetScreenConfig (ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); -Bool -miRRSetConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr size); - #endif #endif /* _RANDRSTR_H_ */ -- cgit v1.2.3 From 3e745745fecef1cb59e53bde52ded311b51e1dac Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 16 Sep 2006 23:21:37 -0700 Subject: Split RandR implementation into separate files. RandR is getting too big to live in one file; split into one file per object type (crtc, mode, screen), leaving the rest of the code in randr.c. Code is slowly approaching the point where it will drop-in as a replacement for the old 1.0 implementation. --- randr/Makefile.am | 6 +- randr/mirandr.c | 7 +- randr/randr.c | 419 +++++++++--------------------------------------------- randr/randrstr.h | 273 ++++++++++++++++++++++++----------- randr/rrcrtc.c | 238 +++++++++++++++++++++++++++++++ randr/rrmode.c | 85 +++++++++++ randr/rroutput.c | 56 ++++++++ randr/rrscreen.c | 205 ++++++++++++++++++++++++++ 8 files changed, 852 insertions(+), 437 deletions(-) create mode 100644 randr/rrcrtc.c create mode 100644 randr/rrmode.c create mode 100644 randr/rroutput.c create mode 100644 randr/rrscreen.c diff --git a/randr/Makefile.am b/randr/Makefile.am index bd30aed8a..868786ecb 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -9,4 +9,8 @@ endif librandr_la_SOURCES = \ mirandr.c \ randr.c \ - randrstr.h + randrstr.h \ + rrcrtc.c \ + rrmode.c \ + rroutput.c \ + rrscreen.c diff --git a/randr/mirandr.c b/randr/mirandr.c index 5aea38d60..a57a157ca 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -70,16 +70,19 @@ Bool miRandRInit (ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; +#if RANDR_12_INTERFACE RRModePtr mode; RRCrtcPtr crtc; RROutputPtr output; xRRModeInfo modeInfo; char name[64]; +#endif if (!RRScreenInit (pScreen)) return FALSE; pScrPriv = rrGetScrPriv(pScreen); pScrPriv->rrGetInfo = miRRGetInfo; +#if RANDR_12_INTERFACE pScrPriv->rrCrtcSet = miRRCrtcSet; RRScreenSetSizeRange (pScreen, @@ -111,7 +114,7 @@ miRandRInit (ScreenPtr pScreen) &crtc, 1, /* crtcs */ RR_Connected)) return FALSE; - if (!RRCrtcSet (crtc, mode, 0, 0, RR_Rotate_0, 1, &output)) - return FALSE; + RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); +#endif return TRUE; } diff --git a/randr/randr.c b/randr/randr.c index e34b82c2f..2305b6094 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -31,25 +31,7 @@ #include #endif -#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 -#include #include "randrstr.h" -#ifdef RENDER -#include /* we share subpixel order information */ -#include "picturestr.h" -#endif -#include /* From render.h */ #ifndef SubPixelUnknown @@ -60,8 +42,6 @@ int RRGeneration; int RRNScreens; -static RESTYPE ModeType, CrtcType, OutputType; - static int ProcRRQueryVersion (ClientPtr pClient); static int ProcRRDispatch (ClientPtr pClient); static int SProcRRDispatch (ClientPtr pClient); @@ -80,7 +60,7 @@ static int SProcRRQueryVersion (ClientPtr pClient); static CARD8 RRReqCode; static int RRErrBase; #endif -static int RREventBase; +int RREventBase; static RESTYPE ClientType, EventType; /* resource types for event masks */ static int RRClientPrivateIndex; @@ -233,50 +213,21 @@ SRRNotifyEvent (xEvent *from, } } -static int -RRModeDestroyResource (pointer value, XID pid) -{ - RRModeDestroy ((RRModePtr) value); - return 1; -} - -static int -RRCrtcDestroyResource (pointer value, XID pid) -{ - RRCrtcDestroy ((RRCrtcPtr) value); - return 1; -} - -static int -RROutputDestroyResource (pointer value, XID pid) -{ - RROutputDestroy ((RROutputPtr) value); - return 1; -} - Bool RRScreenInit(ScreenPtr pScreen) { rrScrPrivPtr pScrPriv; if (RRGeneration != serverGeneration) { - ModeType = CreateNewResourceType (RRModeDestroyResource); - if (!ModeType) + if (!RRModeInit ()) return FALSE; - CrtcType = CreateNewResourceType (RRCrtcDestroyResource); - if (!ModeType) + if (!RRCrtcInit ()) return FALSE; - OutputType = CreateNewResourceType (RROutputDestroyResource); - if (!ModeType) + if (!RROutputInit ()) return FALSE; if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) return FALSE; RRGeneration = serverGeneration; -#ifdef XResExtension - RegisterResourceName (ModeType, "MODE"); - RegisterResourceName (CrtcType, "CRTC"); - RegisterResourceName (OutputType, "OUTPUT"); -#endif } pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); @@ -288,14 +239,23 @@ Bool RRScreenInit(ScreenPtr pScreen) /* * Calling function best set these function vectors */ - pScrPriv->rrCrtcSet = 0; pScrPriv->rrGetInfo = 0; pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width; pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; -#ifdef RANDR_SCREEN_INTERFACE + +#if RANDR_12_INTERFACE + pScrPriv->rrCrtcSet = 0; +#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 /* @@ -400,61 +360,6 @@ RRExtensionInit (void) return; } - -static void -DeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - xRRScreenChangeNotifyEvent se; - RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL; - RROutputPtr output = pScrPriv->numOutputs ? pScrPriv->outputs[0] : NULL; - RRModePtr mode = crtc ? crtc->mode : NULL; - WindowPtr pRoot = WindowTable[pScreen->myNum]; - int i; - - se.type = RRScreenChangeNotify + RREventBase; - se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0); - se.timestamp = pScrPriv->lastSetTime.milliseconds; - se.sequenceNumber = client->sequence; - se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - se.root = pRoot->drawable.id; - se.window = pWin->drawable.id; -#ifdef RENDER - se.subpixelOrder = PictureGetSubpixelOrder (pScreen); -#else - se.subpixelOrder = SubPixelUnknown; -#endif - - se.sequenceNumber = client->sequence; - if (mode) - { - se.sizeID = -1; - for (i = 0; i < output->numModes; i++) - if (mode == output->modes[i]) - { - se.sizeID = i; - break; - } - se.widthInPixels = mode->mode.width; - se.heightInPixels = mode->mode.height; - se.widthInMillimeters = mode->mode.mmWidth; - se.heightInMillimeters = mode->mode.mmHeight; - } - else - { - /* - * This "shouldn't happen", but a broken DDX can - * forget to set the current configuration on GetInfo - */ - se.sizeID = 0xffff; - se.widthInPixels = 0; - se.heightInPixels = 0; - se.widthInMillimeters = 0; - se.heightInMillimeters = 0; - } - WriteEventsToClient (client, 1, (xEvent *) &se); -} - static void DeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) { @@ -485,7 +390,7 @@ TellChanged (WindowPtr pWin, pointer value) continue; if (pRREvent->mask & RRScreenChangeNotifyMask) - DeliverScreenEvent (client, pWin, pScreen); + RRDeliverScreenEvent (client, pWin, pScreen); if (pRREvent->mask & RRCrtcChangeNotifyMask) { @@ -529,47 +434,6 @@ RRTellChanged (ScreenPtr pScreen) } } -RRModePtr -RRModeGet (ScreenPtr pScreen, - xRRModeInfo *modeInfo, - char *name) -{ - rrScrPriv (pScreen); - int i; - RRModePtr mode; - - for (i = 0; i < pScrPriv->numModes; i++) - { - mode = pScrPriv->modes[i]; - if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && - !memcmp (name, mode->name, modeInfo->nameLength)) - { - ++mode->refcnt; - return mode; - } - } - mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); - mode->refcnt = 1; - mode->mode = *modeInfo; - mode->name = (char *) (mode + 1); - memcpy (mode->name, name, modeInfo->nameLength); - mode->name[modeInfo->nameLength] = '\0'; - mode->id = FakeClientID(0); - if (!AddResource (mode->id, ModeType, (pointer) mode)) - return NULL; - ++mode->refcnt; - pScrPriv->changed = TRUE; - return mode; -} - -void -RRModeDestroy (RRModePtr mode) -{ - if (--mode->refcnt > 0) - return; - xfree (mode); -} - /* * Return the first output which is connected to an active CRTC * Used in emulating 1.0 behaviour @@ -594,11 +458,13 @@ RRFirstOutput (ScreenPtr pScreen) return NULL; } -#ifdef RANDR_SCREEN_INTERFACE +#ifdef RANDR_10_INTERFACE -static Bool +static RRModePtr RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) { + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); xRRModeInfo modeInfo; char name[100]; RRModePtr mode; @@ -617,12 +483,15 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->width * (CARD32) refresh); modeInfo.nameLength = strlen (name); - mode = RRModeGet (output->pScreen, &modeInfo, name); + mode = RRModeGet (pScreen, &modeInfo, name); if (!mode) - return FALSE; + return NULL; for (i = 0; i < output->numModes; i++) if (output->modes[i] == mode) - return TRUE; + { + RRModeDestroy (mode); + return mode; + } if (output->numModes) modes = xrealloc (output->modes, @@ -630,11 +499,16 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) else modes = xalloc (sizeof (RRModePtr)); if (!modes) - return FALSE; + { + RRModeDestroy (mode); + FreeResource (mode->id, 0); + return NULL; + } modes[output->numModes++] = mode; output->modes = modes; output->changed = TRUE; - return TRUE; + pScrPriv->changed = TRUE; + return mode; } static void @@ -643,6 +517,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) rrScrPriv(pScreen); RROutputPtr output = RRFirstOutput (pScreen); RRCrtcPtr crtc; + RRModePtr mode, newMode = NULL; int i; CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; CARD16 maxWidth = 0, maxHeight = 0; @@ -666,11 +541,29 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) int r; if (size->nRates) + { for (r = 0; r < size->nRates; r++) - RROldModeAdd (output, size, size->pRates[r].rate); + { + mode = RROldModeAdd (output, size, size->pRates[r].rate); + if (i == pScrPriv->size && + size->pRates[r].rate == pScrPriv->rate) + { + newMode = mode; + } + } + xfree (size->pRates); + } else - RROldModeAdd (output, size, 0); + { + mode = RROldModeAdd (output, size, 0); + if (i == pScrPriv->size) + newMode = mode; + } } + if (pScrPriv->nSizes) + xfree (pScrPriv->pSizes); + pScrPriv->pSizes = NULL; + pScrPriv->nSizes = 0; /* find size bounds */ for (i = 0; i < output->numModes; i++) @@ -697,9 +590,17 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) if (maxHeight != pScrPriv->maxHeight) { pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE; } + + /* notice current mode */ + if (newMode) + RRCrtcSet (output->crtc, newMode, 0, 0, pScrPriv->rotation, + 1, &output); } #endif +/* + * Poll the driver for changed information + */ static Bool RRGetInfo (ScreenPtr pScreen) { @@ -718,7 +619,7 @@ RRGetInfo (ScreenPtr pScreen) if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) return FALSE; -#if RANDR_SCREEN_INTERFACE +#if RANDR_10_INTERFACE if (pScrPriv->nSizes) RRScanOldConfig (pScreen, rotations); #endif @@ -726,27 +627,6 @@ RRGetInfo (ScreenPtr pScreen) return TRUE; } -static void -RRSendConfigNotify (ScreenPtr pScreen) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - xEvent event; - - event.u.u.type = ConfigureNotify; - event.u.configureNotify.window = pWin->drawable.id; - event.u.configureNotify.aboveSibling = None; - event.u.configureNotify.x = 0; - event.u.configureNotify.y = 0; - - /* XXX xinerama stuff ? */ - - event.u.configureNotify.width = pWin->drawable.width; - event.u.configureNotify.height = pWin->drawable.height; - event.u.configureNotify.borderWidth = wBorderWidth (pWin); - event.u.configureNotify.override = pWin->overrideRedirect; - DeliverEvents(pWin, &event, 1, NullWindow); -} - static int ProcRRQueryVersion (ClientPtr client) { @@ -777,50 +657,6 @@ ProcRRQueryVersion (ClientPtr client) return (client->noClientException); } - -extern char *ConnectionInfo; - -static int padlength[4] = {0, 3, 2, 1}; - -static void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} - typedef struct _RR10Data { RRScreenSizePtr sizes; int nsize; @@ -829,7 +665,7 @@ typedef struct _RR10Data { CARD16 refresh; } RR10DataRec, *RR10DataPtr; -static CARD16 +CARD16 RRVerticalRefresh (xRRModeInfo *mode) { CARD32 refresh; @@ -1056,94 +892,6 @@ ProcRRGetScreenInfo (ClientPtr client) } #if 0 -static int -RRMonitorSetMode (ScreenPtr pScreen, RRMonitorPtr pMonitor, - RRModePtr pMode, int x, int y, Rotation rotation, - TimeStamp time) -{ - rrScrPriv(pScreen); - short oldWidth, oldHeight; - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - /* - * call out to ddx routine to effect the change - */ - if (pScrPriv->rrSetScreenSize && pScrPriv->rrSetMode) - { - xScreenSizes oldSize; - if (!(*pScrPriv->rrSetMode) (pScreen, 0, NULL, 0, 0, RR_Rotate_0)) - return RRSetConfigFailed; - oldSize.widthInPixels = pScreen->width; - oldSize.heightInPixels = pScreen->width; - oldSize.widthInMillimeters = pScreen->mmWidth; - oldSize.heightInMillimeters = pScreen->mmHeight; - if (!(*pScrPriv->rrSetScreenSize) (pScreen, - pMode->mode.width, - pMode->mode.height, - pMode->mode.widthInMillimeters, - pMode->mode.heightInMillimeters)) - { - (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, - pMonitor->x, pMonitor->y, - pMonitor->rotation); - return RRSetConfigFailed; - } - if (!(*pScrPriv->rrSetMode) (pScreen, 0, pMode, 0, 0, rotation)) - { - (void) (*pScrPriv->rrSetScreenSize) (pScreen, - oldSize.widthInPixels, - oldSize.heightInPixels, - oldSize.widthInMillimeters, - oldSize.heightInMillimeters); - (void) (*pScrPriv->rrSetMode) (pScreen, 0, pMonitor->pMode, - pMonitor->x, pMonitor->y, - pMonitor->rotation); - return RRSetConfigFailed; - } - } -#ifdef RANDR_SCREEN_INTERFACE - else if (pScrPriv->rrSetConfig) - { - int rate = RRVerticalRefresh (&pMode->mode); - RRScreenSizeRec size; - - size.width = pMode->mode.width; - size.height = pMode->mode.height; - size.mmWidth = pMode->mode.widthInMillimeters; - size.mmHeight = pMode->mode.heightInMillimeters; - if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate, &size)) - return RRSetConfigFailed; - } -#endif - else - return RRSetConfigFailed; - - /* - * set current extension configuration pointers - */ - RRSetCurrentMode (pMonitor, pMode, 0, 0, rotation); - - /* - * Deliver ScreenChangeNotify events whenever - * the configuration is updated - */ - WalkTree (pScreen, TellChanged, (pointer) pScreen); - - /* - * Deliver ConfigureNotify events when root changes - * pixel size - */ - if (oldWidth != pScreen->width || oldHeight != pScreen->height) - RRSendConfigNotify (pScreen); - RREditConnectionInfo (pScreen); - - /* - * Fix pointer bounds and location - */ - ScreenRestructured (pScreen); - pScrPriv->lastSetTime = time; return RRSetConfigSuccess; } #endif @@ -1411,36 +1159,6 @@ RRSetScreenConfig (ScreenPtr pScreen, } #endif -static Bool -RRSetScreenSize (ScreenPtr pScreen, - CARD16 width, CARD16 height, - CARD16 widthInMillimeters, CARD16 heightInMillimeters) -{ - rrScrPriv(pScreen); - - if (pScrPriv->rrScreenSetSize) - { - return (*pScrPriv->rrScreenSetSize) (pScreen, width, height, - widthInMillimeters, - heightInMillimeters); - } -#ifdef RANDR_SCREEN_INTERFACE - else - { - /* Pend the size change until we get the set mode request. - * Yes, this is 'illegal', but the best we can do until - * drivers are updated - */ - pScrPriv->reqWidth = width; - pScrPriv->reqHeight = height; - pScreen->mmWidth = widthInMillimeters; - pScreen->mmHeight = heightInMillimeters; - return TRUE; - } -#endif - return FALSE; -} - static int ProcRRSelectInput (ClientPtr client) { @@ -1524,7 +1242,7 @@ ProcRRSelectInput (ClientPtr client) CompareTimeStamps (pTimes->configTime, pScrPriv->lastConfigTime) != 0) { - DeliverScreenEvent (client, pWin, pScreen); + RRDeliverScreenEvent (client, pWin, pScreen); } } } @@ -1651,7 +1369,7 @@ static int ProcRRSetScreenSize (ClientPtr client) client->errorValue = 0; return BadValue; } - if (!RRSetScreenSize (pScreen, + if (!RRScreenSizeSet (pScreen, stuff->width, stuff->height, stuff->widthInMillimeters, stuff->heightInMillimeters)) @@ -2000,6 +1718,7 @@ SProcRRDispatch (ClientPtr client) } } +#if RANDR_12_INTERFACE /* * Register the range of sizes for the screen */ @@ -2019,8 +1738,9 @@ RRScreenSetSizeRange (ScreenPtr pScreen, pScrPriv->maxWidth = maxWidth; pScrPriv->maxHeight = maxHeight; } +#endif -#ifdef RANDR_SCREEN_INTERFACE +#ifdef RANDR_10_INTERFACE static Bool RRScreenSizeMatches (RRScreenSizePtr a, @@ -2052,6 +1772,7 @@ RRRegisterSize (ScreenPtr pScreen, if (!pScrPriv) return 0; + tmp.id = 0; tmp.width = width; tmp.height= height; tmp.mmWidth = mmWidth; diff --git a/randr/randrstr.h b/randr/randrstr.h index 16945231a..f323660d9 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -32,15 +32,35 @@ #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 #include +#ifdef RENDER +#include /* we share subpixel order information */ +#include "picturestr.h" +#endif +#include /* required for ABI compatibility for now */ -#define RANDR_SCREEN_INTERFACE 1 +#define RANDR_10_INTERFACE 1 +/* #define RANDR_12_INTERFACE 1 */ typedef XID RRMode; typedef XID RROutput; typedef XID RRCrtc; +extern int RREventBase; + /* * Modeline for a monitor. Name follows directly after this struct */ @@ -64,9 +84,9 @@ struct _rrCrtc { int x, y; Rotation rotation; Rotation rotations; - int numPossibleOutputs; - RROutputPtr *possibleOutputs; Bool changed; + int numOutputs; + RROutputPtr *outputs; void *devPrivate; }; @@ -88,11 +108,12 @@ struct _rrOutput { void *devPrivate; }; -typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, +#if RANDR_12_INTERFACE +typedef Bool (*RRScreentSizeSetProcPtr) (ScreenPtr pScreen, CARD16 width, CARD16 height, - CARD32 widthInMM, - CARD32 heightInMM); + CARD32 mmWidth, + CARD32 mmHeight); typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc, @@ -100,8 +121,9 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, int x, int y, Rotation rotation, - int numOutput, + int numOutputs, RROutputPtr *outputs); +#endif typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); @@ -121,7 +143,7 @@ typedef struct _rrScreenSize { RRScreenRatePtr pRates; } RRScreenSize, *RRScreenSizePtr; -#ifdef RANDR_SCREEN_INTERFACE +#ifdef RANDR_10_INTERFACE typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen, Rotation rotation, @@ -136,12 +158,14 @@ typedef struct _rrScrPriv { * 'public' part of the structure; DDXen fill this in * as they initialize */ -#ifdef RANDR_SCREEN_INTERFACE +#if RANDR_10_INTERFACE RRSetConfigProcPtr rrSetConfig; #endif RRGetInfoProcPtr rrGetInfo; - RRScreenSetSizeProcPtr rrScreenSetSize; +#if RANDR_12_INTERFACE + RRScreenSetSizeProcPtr rrScreenSizeSet; RRCrtcSetProcPtr rrCrtcSet; +#endif /* * Private part of the structure; not considered part of the ABI @@ -152,6 +176,7 @@ typedef struct _rrScrPriv { Bool changed; CARD16 minWidth, minHeight; CARD16 maxWidth, maxHeight; + CARD16 width, height; /* last known screen size */ /* modes, outputs and crtcs */ int numModes; @@ -163,7 +188,7 @@ typedef struct _rrScrPriv { int numCrtcs; RRCrtcPtr *crtcs; -#ifdef RANDR_SCREEN_INTERFACE +#ifdef RANDR_10_INTERFACE /* * Configuration information */ @@ -173,7 +198,6 @@ typedef struct _rrScrPriv { int nSizes; RRScreenSizePtr pSizes; - RRScreenSizePtr pSize; Rotation rotation; int rate; int size; @@ -190,6 +214,7 @@ extern int rrPrivIndex; void RRExtensionInit (void); +#ifdef RANDR_12_INTERFACE /* * Set the range of sizes for the screen */ @@ -199,89 +224,34 @@ RRScreenSetSizeRange (ScreenPtr pScreen, CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight); +#endif +/* rrscreen.c */ /* - * Create a CRTC - */ -RRCrtcPtr -RRCrtcCreate (ScreenPtr pScreen, - void *devPrivate); - - -/* - * Use this value for any num parameter to indicate that - * the related data are unchanged - */ -#define RR_NUM_UNCHANGED -1 - -/* - * Notify the extension that the Crtc has been reconfigured - */ -Bool -RRCrtcSet (RRCrtcPtr crtc, - RRModePtr mode, - int x, - int y, - Rotation rotation, - int numOutput, - RROutputPtr *outputs); - -/* - * Destroy a Crtc at shutdown - */ -void -RRCrtcDestroy (RRCrtcPtr crtc); - -/* - * Find, and if necessary, create a mode - */ - -RRModePtr -RRModeGet (ScreenPtr pScreen, - xRRModeInfo *modeInfo, - char *name); - -/* - * Destroy a mode. + * 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 */ - void -RRModeDestroy (RRModePtr mode); +RRScreenSizeNotify (ScreenPtr pScreen); /* - * Create an output + * Request that the screen be resized */ - -RROutputPtr -RROutputCreate (ScreenPtr pScreen, - char *name, - int nameLength, - void *devPrivate); +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); /* - * Notify extension that output parameters have been changed + * Deliver a ScreenNotify event */ -Bool -RROutputSet (RROutputPtr output, - RROutputPtr *clones, - int numClones, - RRModePtr *modes, - int numModes, - RRCrtcPtr *crtcs, - int numCrtcs, - CARD8 connection); - void -RROutputDestroy (RROutputPtr output); - -void -RRTellChanged (ScreenPtr pScreen); - -Bool RRScreenInit(ScreenPtr pScreen); - -Rotation -RRGetRotation (ScreenPtr pScreen); - +RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen); + +/* mirandr.c */ Bool miRandRInit (ScreenPtr pScreen); @@ -301,7 +271,22 @@ miRRCrtcSet (ScreenPtr pScreen, int numOutput, RROutputPtr *outputs); -#ifdef RANDR_SCREEN_INTERFACE +/* randr.c */ +/* + * Send all pending events + */ +void +RRTellChanged (ScreenPtr pScreen); + +Bool RRScreenInit(ScreenPtr pScreen); + +Rotation +RRGetRotation (ScreenPtr pScreen); + +CARD16 +RRVerticalRefresh (xRRModeInfo *mode); + +#ifdef RANDR_10_INTERFACE /* * This is the old interface, deprecated but left * around for compatibility @@ -344,4 +329,122 @@ RRSetScreenConfig (ScreenPtr pScreen, RRScreenSizePtr pSize); #endif + +/* rrcrtc.c */ +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, + void *devPrivate); + + +/* + * Use this value for any num parameter to indicate that + * the related data are unchanged + */ +#define RR_NUM_UNCHANGED -1 + +/* + * 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, + int numOutput, + RROutputPtr *outputs); + +/* + * Request that the Crtc be reconfigured + */ +Bool +RRCrtcSet (RRCrtcPtr crtc, + RRModePtr mode, + int x, + int y, + Rotation rotation, + int numOutput, + RROutputPtr *outputs); + +/* + * Destroy a Crtc at shutdown + */ +void +RRCrtcDestroy (RRCrtcPtr crtc); + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void); + +/* rrmode.c */ +/* + * Find, and if necessary, create a mode + */ + +RRModePtr +RRModeGet (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + char *name); + +/* + * Destroy a mode. + */ + +void +RRModeDestroy (RRModePtr mode); + +/* + * Initialize mode type + */ +Bool +RRModeInit (void); + +/* rroutput.c */ +/* + * Create an output + */ + +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + char *name, + int nameLength, + void *devPrivate); + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones); + +Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes); + +Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs); + +Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection); + +void +RROutputDestroy (RROutputPtr output); + +/* + * Initialize output type + */ +Bool +RROutputInit (void); + #endif /* _RANDRSTR_H_ */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c new file mode 100644 index 000000000..cc5b24d50 --- /dev/null +++ b/randr/rrcrtc.c @@ -0,0 +1,238 @@ +/* + * 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 RESTYPE CrtcType; + +/* + * Create a CRTC + */ +RRCrtcPtr +RRCrtcCreate (ScreenPtr pScreen, + void *devPrivate) +{ + rrScrPriv (pScreen); + RRCrtcPtr crtc; + RRCrtcPtr *crtcs; + + crtc = xalloc (sizeof (RRCrtcRec)); + if (!crtc) + return NULL; + if (pScrPriv->numCrtcs) + crtcs = xrealloc (pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = xalloc (sizeof (RRCrtcPtr)); + if (!crtcs) + { + xfree (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->changed = TRUE; + crtc->devPrivate = devPrivate; + pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + return crtc; +} + +/* + * 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, + int numOutputs, + RROutputPtr *outputs) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + int i, j; + int prevNumOutputs = crtc->numOutputs; + + if (numOutputs != prevNumOutputs) + { + RROutputPtr *outputs; + + if (crtc->numOutputs) + outputs = xrealloc (crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return FALSE; + crtc->outputs = outputs; + } + 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]->changed = TRUE; + crtc->changed = TRUE; + } + } + for (j = 0; j < crtc->numOutputs; j++) + { + for (i = 0; i < numOutputs; i++) + if (outputs[i] == crtc->outputs[j]) + break; + if (i != numOutputs) + { + crtc->outputs[j]->changed = TRUE; + crtc->changed = TRUE; + } + } + if (mode != crtc->mode) + { + if (crtc->mode) + RRModeDestroy (crtc->mode); + crtc->mode = mode; + mode->refcnt++; + crtc->changed = TRUE; + } + if (x != crtc->x) + { + crtc->x = x; + crtc->changed = TRUE; + } + if (y != crtc->y) + { + crtc->y = y; + crtc->changed = TRUE; + } + if (rotation != crtc->rotation) + { + crtc->rotation = rotation; + crtc->changed = TRUE; + } + if (crtc->changed) + pScrPriv->changed = TRUE; + return TRUE; +} + +/* + * 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; + rrScrPriv(pScreen); + +#if RANDR_12_INTERFACE + if (pScrPriv->rrCrtcSet) + { + return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); + } +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + RRScreenSize size; + RRScreenRate rate; + Bool ret; + + size.width = mode->mode.width; + size.height = mode->mode.height; + size.mmWidth = mode->mode.mmWidth; + size.mmHeight = mode->mode.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) + RRScreenSizeNotify (pScreen); + return ret; + } +#endif + return FALSE; +} + +/* + * 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; + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1, + (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + } + } + free (value); + return 1; +} + +/* + * Initialize crtc type + */ +Bool +RRCrtcInit (void) +{ + CrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!CrtcType) + return FALSE; +#ifdef XResExtension + RegisterResourceName (CrtcType, "CRTC"); +#endif + return TRUE; +} diff --git a/randr/rrmode.c b/randr/rrmode.c new file mode 100644 index 000000000..1eb53c388 --- /dev/null +++ b/randr/rrmode.c @@ -0,0 +1,85 @@ +/* + * 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 RESTYPE ModeType; + +RRModePtr +RRModeGet (ScreenPtr pScreen, + xRRModeInfo *modeInfo, + char *name) +{ + rrScrPriv (pScreen); + int i; + RRModePtr mode; + + for (i = 0; i < pScrPriv->numModes; i++) + { + mode = pScrPriv->modes[i]; + if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && + !memcmp (name, mode->name, modeInfo->nameLength)) + { + ++mode->refcnt; + return mode; + } + } + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + mode->refcnt = 1; + mode->mode = *modeInfo; + mode->name = (char *) (mode + 1); + memcpy (mode->name, name, modeInfo->nameLength); + mode->name[modeInfo->nameLength] = '\0'; + mode->id = FakeClientID(0); + if (!AddResource (mode->id, ModeType, (pointer) mode)) + return NULL; + ++mode->refcnt; + pScrPriv->changed = TRUE; + return mode; +} + +void +RRModeDestroy (RRModePtr mode) +{ + if (--mode->refcnt > 0) + return; + xfree (mode); +} + +static int +RRModeDestroyResource (pointer value, XID pid) +{ + RRModeDestroy ((RRModePtr) value); + return 1; +} + +Bool +RRModeInit (void) +{ + ModeType = CreateNewResourceType (RRModeDestroyResource); + if (!ModeType) + return FALSE; +#ifdef XResExtension + RegisterResourceName (ModeType, "MODE"); +#endif + return TRUE; +} diff --git a/randr/rroutput.c b/randr/rroutput.c new file mode 100644 index 000000000..c7e7995fc --- /dev/null +++ b/randr/rroutput.c @@ -0,0 +1,56 @@ +/* + * 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 RESTYPE OutputType; + +/* + * Destroy a Output at shutdown + */ +void +RROutputDestroy (RROutputPtr crtc) +{ + FreeResource (crtc->id, 0); +} + +static int +RROutputDestroyResource (pointer value, XID pid) +{ + free (value); + return 1; +} + +/* + * Initialize crtc type + */ +Bool +RROutputInit (void) +{ + OutputType = CreateNewResourceType (RROutputDestroyResource); + if (!OutputType) + return FALSE; +#ifdef XResExtension + RegisterResourceName (OutputType, "OUTPUT"); +#endif + return TRUE; +} diff --git a/randr/rrscreen.c b/randr/rrscreen.c new file mode 100644 index 000000000..47ba12d39 --- /dev/null +++ b/randr/rrscreen.c @@ -0,0 +1,205 @@ +/* + * 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" + +extern char *ConnectionInfo; + +static int padlength[4] = {0, 3, 2, 1}; + +/* + * Edit connection information block so that new clients + * see the current screen size on connect + */ +static void +RREditConnectionInfo (ScreenPtr pScreen) +{ + xConnSetup *connSetup; + char *vendor; + xPixmapFormat *formats; + xWindowRoot *root; + xDepth *depth; + xVisualType *visual; + int screen = 0; + int d; + + connSetup = (xConnSetup *) ConnectionInfo; + vendor = (char *) connSetup + sizeof (xConnSetup); + formats = (xPixmapFormat *) ((char *) vendor + + connSetup->nbytesVendor + + padlength[connSetup->nbytesVendor & 3]); + root = (xWindowRoot *) ((char *) formats + + sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); + while (screen != pScreen->myNum) + { + depth = (xDepth *) ((char *) root + + sizeof (xWindowRoot)); + for (d = 0; d < root->nDepths; d++) + { + visual = (xVisualType *) ((char *) depth + + sizeof (xDepth)); + depth = (xDepth *) ((char *) visual + + depth->nVisuals * sizeof (xVisualType)); + } + root = (xWindowRoot *) ((char *) depth); + screen++; + } + root->pixWidth = pScreen->width; + root->pixHeight = pScreen->height; + root->mmWidth = pScreen->mmWidth; + root->mmHeight = pScreen->mmHeight; +} + +static void +RRSendConfigNotify (ScreenPtr pScreen) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + xEvent event; + + event.u.u.type = ConfigureNotify; + event.u.configureNotify.window = pWin->drawable.id; + event.u.configureNotify.aboveSibling = None; + event.u.configureNotify.x = 0; + event.u.configureNotify.y = 0; + + /* XXX xinerama stuff ? */ + + event.u.configureNotify.width = pWin->drawable.width; + event.u.configureNotify.height = pWin->drawable.height; + event.u.configureNotify.borderWidth = wBorderWidth (pWin); + event.u.configureNotify.override = pWin->overrideRedirect; + DeliverEvents(pWin, &event, 1, NullWindow); +} + +void +RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + xRRScreenChangeNotifyEvent se; + RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL; + RROutputPtr output = pScrPriv->numOutputs ? pScrPriv->outputs[0] : NULL; + RRModePtr mode = crtc ? crtc->mode : NULL; + WindowPtr pRoot = WindowTable[pScreen->myNum]; + int i; + + se.type = RRScreenChangeNotify + RREventBase; + se.rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0); + se.timestamp = pScrPriv->lastSetTime.milliseconds; + se.sequenceNumber = client->sequence; + se.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + se.root = pRoot->drawable.id; + se.window = pWin->drawable.id; +#ifdef RENDER + se.subpixelOrder = PictureGetSubpixelOrder (pScreen); +#else + se.subpixelOrder = SubPixelUnknown; +#endif + + se.sequenceNumber = client->sequence; + if (mode) + { + se.sizeID = -1; + for (i = 0; i < output->numModes; i++) + if (mode == output->modes[i]) + { + se.sizeID = i; + break; + } + se.widthInPixels = mode->mode.width; + se.heightInPixels = mode->mode.height; + se.widthInMillimeters = mode->mode.mmWidth; + se.heightInMillimeters = mode->mode.mmHeight; + } + else + { + /* + * This "shouldn't happen", but a broken DDX can + * forget to set the current configuration on GetInfo + */ + se.sizeID = 0xffff; + se.widthInPixels = 0; + se.heightInPixels = 0; + se.widthInMillimeters = 0; + se.heightInMillimeters = 0; + } + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +/* + * 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 + */ +void +RRScreenSizeNotify (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + /* + * Deliver ConfigureNotify events when root changes + * pixel size + */ + if (pScrPriv->width == pScreen->width && + pScrPriv->height == pScreen->height) + return; + + pScrPriv->width = pScreen->width; + pScrPriv->height = pScreen->height; + pScrPriv->changed = TRUE; + + RRSendConfigNotify (pScreen); + RREditConnectionInfo (pScreen); + + /* + * Fix pointer bounds and location + */ + ScreenRestructured (pScreen); +} + +/* + * Request that the screen be resized + */ +Bool +RRScreenSizeSet (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + rrScrPriv(pScreen); + +#if RANDR_12_INTERFACE + if (pScrPriv->rrScreenSizeSet) + { + return (*pScrPriv->rrScreenSizeSet) (pScreen, + width, height, + mmWidth, mmHeight); + } +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) + { + return TRUE; /* can't set size separately */ + } +#endif + return FALSE; +} + -- cgit v1.2.3 From bf07893947cfca945598e194ed416fda6162b11c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 Sep 2006 23:03:23 -0700 Subject: Split out RandR dispatch code from randr.c to rr*dispatch.c. More disassembly to ease ongoing development. --- randr/Makefile.am | 4 +- randr/randr.c | 1100 ++------------------------------------------------- randr/randrstr.h | 69 +++- randr/rrcrtc.c | 15 +- randr/rrdispatch.c | 1034 ++++++++++++++++++++++++++++++++++++++++++++++++ randr/rrmode.c | 10 +- randr/rroutput.c | 148 ++++++- randr/rrsdispatch.c | 282 +++++++++++++ 8 files changed, 1575 insertions(+), 1087 deletions(-) create mode 100644 randr/rrdispatch.c create mode 100644 randr/rrsdispatch.c diff --git a/randr/Makefile.am b/randr/Makefile.am index 868786ecb..0a735574e 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -11,6 +11,8 @@ librandr_la_SOURCES = \ randr.c \ randrstr.h \ rrcrtc.c \ + rrdispatch.c \ rrmode.c \ rroutput.c \ - rrscreen.c + rrscreen.c \ + rrsdispatch.c diff --git a/randr/randr.c b/randr/randr.c index 2305b6094..63d471ce0 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -42,10 +42,8 @@ int RRGeneration; int RRNScreens; -static int ProcRRQueryVersion (ClientPtr pClient); static int ProcRRDispatch (ClientPtr pClient); static int SProcRRDispatch (ClientPtr pClient); -static int SProcRRQueryVersion (ClientPtr pClient); #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ @@ -56,57 +54,13 @@ static int SProcRRQueryVersion (ClientPtr pClient); real->mem = priv->mem; \ } -#if 0 -static CARD8 RRReqCode; -static int RRErrBase; -#endif int RREventBase; -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static int RRClientPrivateIndex; - -typedef struct _RRTimes { - TimeStamp setTime; - TimeStamp configTime; -} RRTimesRec, *RRTimesPtr; - -typedef struct _RRClient { - int major_version; - int minor_version; -/* RRTimesRec times[0]; */ -} RRClientRec, *RRClientPtr; - -/* - * 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; +int RRErrorBase; +RESTYPE RRClientType, RREventType; /* resource types for event masks */ +int RRClientPrivateIndex; int rrPrivIndex = -1; -#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) -#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) - -static Bool -RRClientKnowsRates (ClientPtr pClient) -{ - rrClientPriv(pClient); - - return (pRRClient->major_version > 1 || - (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); -} - static void RRClientCallback (CallbackListPtr *list, pointer closure, @@ -289,7 +243,7 @@ RRFreeClient (pointer data, XID id) pRREvent = (RREventPtr) data; pWin = pRREvent->window; - pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType); if (pHead) { pPrev = 0; for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next) @@ -315,7 +269,7 @@ RRFreeEvents (pointer data, XID id) pHead = (RREventPtr *) data; for (pCur = *pHead; pCur; pCur = pNext) { pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); + FreeResource (pCur->clientResource, RRClientType); xfree ((pointer) pCur); } xfree ((pointer) pHead); @@ -337,38 +291,26 @@ RRExtensionInit (void) if (!AddCallback (&ClientStateCallback, RRClientCallback, 0)) return; - ClientType = CreateNewResourceType(RRFreeClient); - if (!ClientType) + RRClientType = CreateNewResourceType(RRFreeClient); + if (!RRClientType) return; - EventType = CreateNewResourceType(RRFreeEvents); - if (!EventType) + RREventType = CreateNewResourceType(RRFreeEvents); + if (!RREventType) return; extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors, ProcRRDispatch, SProcRRDispatch, RRResetProc, StandardMinorOpcode); if (!extEntry) return; -#if 0 - RRReqCode = (CARD8) extEntry->base; - RRErrBase = extEntry->errorBase; -#endif + RRErrorBase = extEntry->errorBase; RREventBase = extEntry->eventBase; EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) - SRRScreenChangeNotifyEvent; + SRRScreenChangeNotifyEvent; EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) SRRNotifyEvent; return; } -static void -DeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) -{ -} - -static void -DeliverOutputEvent (ClientPtr client, WindowPtr pWin, RROutputPtr output) -{ -} static int TellChanged (WindowPtr pWin, pointer value) @@ -379,7 +321,7 @@ TellChanged (WindowPtr pWin, pointer value) rrScrPriv(pScreen); int i; - pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType); + pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType); if (!pHead) return WT_WALKCHILDREN; @@ -398,7 +340,7 @@ TellChanged (WindowPtr pWin, pointer value) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; if (crtc->changed) - DeliverCrtcEvent (client, pWin, crtc); + RRDeliverCrtcEvent (client, pWin, crtc); } } @@ -408,7 +350,7 @@ TellChanged (WindowPtr pWin, pointer value) { RROutputPtr output = pScrPriv->outputs[i]; if (output->changed) - DeliverOutputEvent (client, pWin, output); + RRDeliverOutputEvent (client, pWin, output); } } } @@ -438,7 +380,7 @@ RRTellChanged (ScreenPtr pScreen) * Return the first output which is connected to an active CRTC * Used in emulating 1.0 behaviour */ -static RROutputPtr +RROutputPtr RRFirstOutput (ScreenPtr pScreen) { rrScrPriv(pScreen); @@ -459,7 +401,6 @@ RRFirstOutput (ScreenPtr pScreen) } #ifdef RANDR_10_INTERFACE - static RRModePtr RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) { @@ -515,13 +456,31 @@ static void RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) { rrScrPriv(pScreen); - RROutputPtr output = RRFirstOutput (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); + } + + output = RRFirstOutput (pScreen); if (!output) return; crtc = output->crtc; @@ -601,7 +560,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) /* * Poll the driver for changed information */ -static Bool +Bool RRGetInfo (ScreenPtr pScreen) { rrScrPriv (pScreen); @@ -627,44 +586,6 @@ RRGetInfo (ScreenPtr pScreen) return TRUE; } -static int -ProcRRQueryVersion (ClientPtr client) -{ - xRRQueryVersionReply rep; - 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; - /* - * Report the current version; the current - * spec says they're all compatible after 1.0 - */ - rep.majorVersion = RANDR_MAJOR; - rep.minorVersion = RANDR_MINOR; - 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 (client->noClientException); -} - -typedef struct _RR10Data { - RRScreenSizePtr sizes; - int nsize; - int nrefresh; - int size; - CARD16 refresh; -} RR10DataRec, *RR10DataPtr; - CARD16 RRVerticalRefresh (xRRModeInfo *mode) { @@ -677,411 +598,6 @@ RRVerticalRefresh (xRRModeInfo *mode) return (CARD16) refresh; } -/* - * Convert 1.2 monitor data into 1.0 screen data - */ -static RR10DataPtr -RR10GetData (ScreenPtr pScreen, RROutputPtr output) -{ - RR10DataPtr data; - RRScreenSizePtr size; - int nmode = output->numModes; - int i, j, k; - RRScreenRatePtr refresh; - CARD16 vRefresh; - RRModePtr mode; - - /* Make sure there is plenty of space for any combination */ - data = malloc (sizeof (RR10DataRec) + - sizeof (RRScreenSize) * nmode + - sizeof (RRScreenRate) * nmode); - if (!data) - return NULL; - size = (RRScreenSizePtr) (data + 1); - refresh = (RRScreenRatePtr) (size + nmode); - data->sizes = size; - data->nsize = 0; - data->nrefresh = 0; - data->size = 0; - data->refresh = 0; - for (i = 0; i < output->numModes; i++) - { - mode = output->modes[i]; - for (j = 0; j < data->nsize; j++) - if (mode->mode.width == size[j].width && - mode->mode.height == size[j].height) - break; - if (j == data->nsize) - { - size[j].id = j; - size[j].width = mode->mode.width; - size[j].height = mode->mode.height; - size[j].mmWidth = mode->mode.mmWidth; - size[j].mmHeight = mode->mode.mmHeight; - size[j].nRates = 0; - size[j].pRates = &refresh[data->nrefresh]; - data->nsize++; - } - vRefresh = RRVerticalRefresh (&mode->mode); - for (k = 0; k < size[j].nRates; k++) - if (vRefresh == size[j].pRates[k].rate) - break; - if (k == size[j].nRates) - { - size[j].pRates[k].rate = vRefresh; - size[j].pRates[k].mode = mode; - size[j].nRates++; - data->nrefresh++; - } - if (mode == output->crtc->mode) - { - data->size = j; - data->refresh = vRefresh; - } - } - return data; -} - -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - RROutputPtr output; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - - if (pScrPriv) - RRGetInfo (pScreen); - - output = RRFirstOutput (pScreen); - - if (!pScrPriv || !output) - { - rep.type = X_Reply; - rep.setOfRotations = RR_Rotate_0;; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nSizes = 0; - rep.sizeID = 0; - rep.rotation = RR_Rotate_0; - rep.rate = 0; - rep.nrateEnts = 0; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - RR10DataPtr pData; - RRScreenSizePtr pSize; - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - rep.type = X_Reply; - rep.setOfRotations = output->crtc->rotations; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = output->crtc->rotation; - rep.nSizes = pData->nsize; - rep.nrateEnts = pData->nrefresh + pData->nsize; - rep.sizeID = pData->size; - rep.rate = pData->refresh; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - { - xfree (pData); - return BadAlloc; - } - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pData->nsize; i++) - { - pSize = &pData->sizes[i]; - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRates; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - *rates = pSize->pRates[j].rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - xfree (pData); - - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -#if 0 - return RRSetConfigSuccess; -} -#endif - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - int i; - Rotation rotation; - int rate; - Bool has_rate; - RROutputPtr output; - RRModePtr mode; - RR10DataPtr pData = NULL; - RRScreenSizePtr pSize; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - output = RRFirstOutput (pScreen); - if (!output) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - if (stuff->sizeID >= pData->nsize) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - xfree (pData); - return BadValue; - } - pSize = &pData->sizes[stuff->sizeID]; - - /* - * 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; - xfree (pData); - return BadValue; - } - - if ((~output->crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - xfree (pData); - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - if (pSize->pRates[i].rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - xfree (pData); - return BadValue; - } - mode = pSize->pRates[i].mode; - } - else - mode = pSize->pRates[0].mode; - - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, - 1, &output); - -sendReply: - - if (pData) - xfree (pData); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - #if 0 int RRSetScreenConfig (ScreenPtr pScreen, @@ -1159,478 +675,6 @@ RRSetScreenConfig (ScreenPtr pScreen, } #endif -static int -ProcRRSelectInput (ClientPtr client) -{ - REQUEST(xRRSelectInputReq); - rrClientPriv(client); - RRTimesPtr pTimes; - WindowPtr pWin; - RREventPtr pRREvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH(xRRSelectInputReq); - pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); - if (!pWin) - return BadWindow; - pHead = (RREventPtr *)SecurityLookupIDByType(client, - pWin->drawable.id, EventType, - SecurityWriteAccess); - - if (stuff->enable & (RRScreenChangeNotifyMask| - RRCrtcChangeNotifyMask| - RROutputChangeNotifyMask)) - { - 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) xalloc (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, ClientType, (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 *) xalloc (sizeof (RREventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, EventType, (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, ClientType); - if (pNewRREvent) - pNewRREvent->next = pRREvent->next; - else - *pHead = pRREvent->next; - xfree (pRREvent); - } - } - } - else - { - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - -/* - * Retrieve valid screen size range - */ -static int ProcRRGetScreenSizeRange (ClientPtr client) -{ - REQUEST(xRRGetScreenSizeRangeReq); - xRRGetScreenSizeRangeReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.length = 0; - - if (pScrPriv) - { - RRGetInfo (pScreen); - rep.minWidth = pScrPriv->minWidth; - rep.minHeight = pScrPriv->minHeight; - rep.maxWidth = pScrPriv->maxWidth; - rep.maxHeight = pScrPriv->maxHeight; - } - else - { - rep.maxWidth = rep.minWidth = pScreen->width; - rep.maxHeight = rep.minHeight = pScreen->height; - } - if (client->swapped) - { - int n; - - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.minWidth, n); - swaps(&rep.minHeight, n); - swaps(&rep.maxWidth, n); - swaps(&rep.maxHeight, n); - } - WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); - return (client->noClientException); -} - -static int ProcRRSetScreenSize (ClientPtr client) -{ - REQUEST(xRRSetScreenSizeReq); - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtcPtr crtc; - int i; - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) - { - client->errorValue = stuff->width; - return BadValue; - } - if (stuff->height < pScrPriv->minHeight || - pScrPriv->maxHeight < stuff->height) - { - client->errorValue = stuff->height; - return BadValue; - } - for (i = 0; i < pScrPriv->numCrtcs; i++) { - crtc = pScrPriv->crtcs[i]; - if (crtc->mode && - (crtc->x + crtc->mode->mode.width > stuff->width || - crtc->y + crtc->mode->mode.height > stuff->height)) - return BadMatch; - } - if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) - { - client->errorValue = 0; - return BadValue; - } - if (!RRScreenSizeSet (pScreen, - stuff->width, stuff->height, - stuff->widthInMillimeters, - stuff->heightInMillimeters)) - { - return BadMatch; - } - return Success; -} - -#if 0 -static int ProcRRGetMonitorInfo (ClientPtr client) -{ - REQUEST(xRRGetMonitorInfoReq); - xRRGetMonitorInfoReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRMonitorPtr pMonitor; - RRModePtr pMode; - int extraLen; - CARD8 *extra; - xRRMonitorInfo *monitor; - xRRMonitorMode *mode; - CARD8 *names; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.numMonitors = 0; - rep.numModes = 0; - rep.sizeNames = 0; - if (!pScrPriv) - { - extraLen = 0; - extra = NULL; - } - else - { - int i, m, b; - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - rep.numMonitors++; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - rep.numModes++; - rep.sizeNames += (1 + pMode->mode.nameLength); - } - } - extraLen = (rep.numMonitors * sizeof (xRRMonitorInfo) + - rep.numModes * sizeof (xRRMonitorMode) + - rep.sizeNames + 3) & ~3; - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - return BadAlloc; - monitor = (xRRMonitorInfo *) extra; - mode = (xRRMonitorMode *) (monitor + rep.numMonitors); - names = (CARD8 *) (mode + rep.numModes); - i = 0; - m = 0; - b = 0; - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - monitor[i].timestamp = pScrPriv->lastSetTime; - monitor[i].configTimestamp = pScrPriv->lastConfigTime; - monitor[i].x = pMonitor->x; - monitor[i].y = pMonitor->y; - monitor[i].rotation = pMonitor->rotation; - monitor[i].mode = pMonitor->pMode->id; - monitor[i].defaultMode = 0; /* XXX */ - monitor[i].rotations = pMonitor->rotations; - monitor[i].firstMode = m; - monitor[i].numModes = 0; - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - monitor[i].numModes++; - mode[m] = pMode->mode; - names[b] = pMode->mode.nameLength; - b++; - memcpy (names + b, (char *) (pMode + 1), - pMode->mode.nameLength); - b += pMode->mode.nameLength; - m++; - } - i++; - } - if ((char *) (names + ((b + 3) & ~3)) != (char *) extra + extraLen) - FatalError ("RRGetMonitorInfo length mismatch\n"); - } - rep.length = extraLen >> 2; - - WriteToClient(client, sizeof(xRRGetMonitorInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - - if (extra) - xfree (extra); - return (client->noClientException); -} - -static int ProcRRAddMonitorMode (ClientPtr client) -{ - return BadImplementation; -} - -static int ProcRRDeleteMonitorMode (ClientPtr client) -{ - return BadImplementation; -} - -static int ProcRRSetMonitorConfig (ClientPtr client) -{ - REQUEST(xRRSetMonitorConfigReq); - xRRSetMonitorConfigReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRMonitorPtr pMonitor; - RRModePtr pMode; - TimeStamp configTime; - TimeStamp time; - Rotation rotation; - - REQUEST_SIZE_MATCH(xRRSetScreenConfigReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - for (pMonitor = pScrPriv->pMonitors; pMonitor; pMonitor = pMonitor->next) - { - if (pMonitor->id == stuff->monitorIndex) - break; - } - if (!pMonitor) - { - client->errorValue = stuff->monitorIndex; - return BadValue; - } - - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - if (pMode->id == stuff->modeIndex) - break; - } - if (!pMode) - { - client->errorValue = stuff->modeIndex; - return BadValue; - } - - /* - * 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; - return BadValue; - } - - if ((~pMonitor->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - if (stuff->x + pMode->mode.width > pScreen->width) - { - client->errorValue = stufff - stuff->y + pMode->mode.height > pScreen - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRMonitorSetMode (pScreen, pMonitor, - pMode, stuff->x, stuff->y, rotation, time); - - return client->noClientException; -} -#endif - -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 */ -#if 0 - ProcRRGetScreenSizeRange, /* 6 */ - ProcRRSetScreenSize, /* 7 */ - ProcRRGetMonitorInfo, /* 8 */ - ProcRRAddMonitorMode, /* 9 */ - ProcRRDeleteMonitorMode, /* 10 */ - ProcRRSetMonitorConfig, /* 11 */ -#endif -}; - - static int ProcRRDispatch (ClientPtr client) { @@ -1640,82 +684,13 @@ ProcRRDispatch (ClientPtr client) return (*ProcRandrVector[stuff->data]) (client); } -static int -SProcRRQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRRQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return ProcRRQueryVersion(client); -} - -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(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 ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRSelectInput(client); -} - - static int SProcRRDispatch (ClientPtr client) { REQUEST(xReq); - switch (stuff->data) - { - case X_RRQueryVersion: - return SProcRRQueryVersion(client); - case X_RRSetScreenConfig: - return SProcRRSetScreenConfig(client); - case X_RRSelectInput: - return SProcRRSelectInput(client); - case X_RRGetScreenInfo: - return SProcRRGetScreenInfo(client); - default: + if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data]) return BadRequest; - } + return (*SProcRandrVector[stuff->data]) (client); } #if RANDR_12_INTERFACE @@ -1741,7 +716,6 @@ RRScreenSetSizeRange (ScreenPtr pScreen, #endif #ifdef RANDR_10_INTERFACE - static Bool RRScreenSizeMatches (RRScreenSizePtr a, RRScreenSizePtr b) diff --git a/randr/randrstr.h b/randr/randrstr.h index f323660d9..33461570f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -59,8 +59,11 @@ typedef XID RRMode; typedef XID RROutput; typedef XID RRCrtc; -extern int RREventBase; +extern int RREventBase, RRErrorBase; +extern int (*ProcRandrVector[RRNumberRequests])(ClientPtr); +extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); + /* * Modeline for a monitor. Name follows directly after this struct */ @@ -101,7 +104,7 @@ struct _rrOutput { int numCrtcs; RRCrtcPtr *crtcs; int numClones; - RROutputPtr *outputs; + RROutputPtr *clones; int numModes; RRModePtr *modes; Bool changed; @@ -210,6 +213,42 @@ extern int rrPrivIndex; #define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr) #define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (pointer) (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 RESTYPE RRClientType, RREventType; /* resource types for event masks */ +extern int RRClientPrivateIndex; +extern RESTYPE RRCrtcType, RRModeType, RROutputType; + +#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) +#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) + /* Initialize the extension */ void RRExtensionInit (void); @@ -278,8 +317,17 @@ miRRCrtcSet (ScreenPtr pScreen, void RRTellChanged (ScreenPtr pScreen); +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen); + Bool RRScreenInit(ScreenPtr pScreen); +RROutputPtr +RRFirstOutput (ScreenPtr pScreen); + Rotation RRGetRotation (ScreenPtr pScreen); @@ -338,13 +386,6 @@ RRCrtcPtr RRCrtcCreate (ScreenPtr pScreen, void *devPrivate); - -/* - * Use this value for any num parameter to indicate that - * the related data are unchanged - */ -#define RR_NUM_UNCHANGED -1 - /* * Notify the extension that the Crtc has been reconfigured, * the driver calls this whenever it has updated the mode @@ -358,6 +399,9 @@ RRCrtcNotify (RRCrtcPtr crtc, int numOutput, RROutputPtr *outputs); +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc); + /* * Request that the Crtc be reconfigured */ @@ -382,6 +426,10 @@ RRCrtcDestroy (RRCrtcPtr crtc); Bool RRCrtcInit (void); +/* rrdispatch.c */ +Bool +RRClientKnowsRates (ClientPtr pClient); + /* rrmode.c */ /* * Find, and if necessary, create a mode @@ -438,6 +486,9 @@ Bool RROutputSetConnection (RROutputPtr output, CARD8 connection); +void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); + void RROutputDestroy (RROutputPtr output); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index cc5b24d50..d343c3a57 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -22,7 +22,7 @@ #include "randrstr.h" -static RESTYPE CrtcType; +RESTYPE RRCrtcType; /* * Create a CRTC @@ -144,6 +144,12 @@ RRCrtcNotify (RRCrtcPtr crtc, return TRUE; } +void +RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc) +{ + +} + /* * Request that the Crtc be reconfigured */ @@ -216,6 +222,7 @@ RRCrtcDestroyResource (pointer value, XID pid) memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1, (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); --pScrPriv->numCrtcs; + break; } } free (value); @@ -228,11 +235,11 @@ RRCrtcDestroyResource (pointer value, XID pid) Bool RRCrtcInit (void) { - CrtcType = CreateNewResourceType (RRCrtcDestroyResource); - if (!CrtcType) + RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource); + if (!RRCrtcType) return FALSE; #ifdef XResExtension - RegisterResourceName (CrtcType, "CRTC"); + RegisterResourceName (RRCrtcType, "CRTC"); #endif return TRUE; } diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c new file mode 100644 index 000000000..acf629832 --- /dev/null +++ b/randr/rrdispatch.c @@ -0,0 +1,1034 @@ +/* + * 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" + +Bool +RRClientKnowsRates (ClientPtr pClient) +{ + rrClientPriv(pClient); + + return (pRRClient->major_version > 1 || + (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes; + int i, j, k; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + for (i = 0; i < output->numModes; i++) + { + mode = output->modes[i]; + for (j = 0; j < data->nsize; j++) + if (mode->mode.width == size[j].width && + mode->mode.height == size[j].height) + break; + if (j == data->nsize) + { + size[j].id = j; + size[j].width = mode->mode.width; + size[j].height = mode->mode.height; + size[j].mmWidth = mode->mode.mmWidth; + size[j].mmHeight = mode->mode.mmHeight; + size[j].nRates = 0; + size[j].pRates = &refresh[data->nrefresh]; + data->nsize++; + } + vRefresh = RRVerticalRefresh (&mode->mode); + for (k = 0; k < size[j].nRates; k++) + if (vRefresh == size[j].pRates[k].rate) + break; + if (k == size[j].nRates) + { + size[j].pRates[k].rate = vRefresh; + size[j].pRates[k].mode = mode; + size[j].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = j; + data->refresh = vRefresh; + } + } + return data; +} + +static int +ProcRRQueryVersion (ClientPtr client) +{ + xRRQueryVersionReply rep; + 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; + /* + * Report the current version; the current + * spec says they're all compatible after 1.0 + */ + rep.majorVersion = RANDR_MAJOR; + rep.minorVersion = RANDR_MINOR; + 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 (client->noClientException); +} + +static int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + output = RRFirstOutput (pScreen); + + if (!pScrPriv || !output) + { + rep.type = X_Reply; + rep.setOfRotations = RR_Rotate_0;; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nSizes = 0; + rep.sizeID = 0; + rep.rotation = RR_Rotate_0; + rep.rate = 0; + rep.nrateEnts = 0; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + rep.type = X_Reply; + rep.setOfRotations = output->crtc->rotations; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.rotation = output->crtc->rotation; + rep.nSizes = pData->nsize; + rep.nrateEnts = pData->nrefresh + pData->nsize; + rep.sizeID = pData->size; + rep.rate = pData->refresh; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +static int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp configTime; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, + SecurityWriteAccess); + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * 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; + xfree (pData); + return BadValue; + } + + if ((~output->crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + 1, &output); + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + +static int +ProcRRSelectInput (ClientPtr client) +{ + REQUEST(xRRSelectInputReq); + rrClientPriv(client); + RRTimesPtr pTimes; + WindowPtr pWin; + RREventPtr pRREvent, *pHead; + XID clientResource; + + REQUEST_SIZE_MATCH(xRRSelectInputReq); + pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess); + if (!pWin) + return BadWindow; + pHead = (RREventPtr *)SecurityLookupIDByType(client, + pWin->drawable.id, RREventType, + SecurityWriteAccess); + + if (stuff->enable & (RRScreenChangeNotifyMask| + RRCrtcChangeNotifyMask| + RROutputChangeNotifyMask)) + { + 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) xalloc (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 *) xalloc (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; + xfree (pRREvent); + } + } + } + else + { + client->errorValue = stuff->enable; + return BadValue; + } + return Success; +} + +/* + * Retrieve valid screen size range + */ +static int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.pad = 0; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + if (pScrPriv) + { + RRGetInfo (pScreen); + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +static int ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + int i; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) { + crtc = pScrPriv->crtcs[i]; + if (crtc->mode && + (crtc->x + crtc->mode->mode.width > stuff->width || + crtc->y + crtc->mode->mode.height > stuff->height)) + return BadMatch; + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +static int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq);; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRChangeOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + + REQUEST_SIZE_MATCH(xRRCreateModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + (void) stuff; + return BadImplementation; +} + +static 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 i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); + + crtc = LookupIDByType (stuff->crtc, RRCrtcType); + if (!crtc) + { + client->errorValue = stuff->crtc; + return RRErrorBase + BadCrtc; + } + if (stuff->mode == None) + { + mode = NULL; + if (numOutputs > 0) + return BadMatch; + } + else + { + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadMode; + } + if (numOutputs == 0) + return BadMatch; + } + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + return RRErrorBase + BadOutput; + } + /* validate crtc for this output */ + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) + break; + if (j == outputs[j]->numCrtcs) + return BadMatch; + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes; j++) + if (outputs[i]->modes[j] == mode) + break; + if (j == outputs[j]->numModes) + 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; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + 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; + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + return BadMatch; + } + + if (stuff->x + mode->mode.width > pScreen->width) + { + client->errorValue = stuff->x; + return BadValue; + } + + if (stuff->y + mode->mode.height > pScreen->height) + { + client->errorValue = stuff->y; + return BadValue; + } + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y, + rotation, numOutputs, outputs); + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.newTimestamp = pScrPriv->lastConfigTime.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 client->noClientException; +} + +static int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +static int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +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 */ + ProcRRChangeOutputProperty, /* 11 */ + ProcRRDeleteOutputProperty, /* 12 */ + ProcRRGetOutputProperty, /* 13 */ + ProcRRCreateMode, /* 14 */ + ProcRRDestroyMode, /* 15 */ + ProcRRAddOutputMode, /* 16 */ + ProcRRDeleteOutputMode, /* 17 */ + ProcRRGetCrtcInfo, /* 18 */ + ProcRRSetCrtcConfig, /* 19 */ + ProcRRGetCrtcGammaSize, /* 20 */ + ProcRRGetCrtcGamma, /* 21 */ + ProcRRSetCrtcGamma, /* 22 */ +}; + diff --git a/randr/rrmode.c b/randr/rrmode.c index 1eb53c388..3a9d55671 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -22,7 +22,7 @@ #include "randrstr.h" -static RESTYPE ModeType; +RESTYPE RRModeType; RRModePtr RRModeGet (ScreenPtr pScreen, @@ -50,7 +50,7 @@ RRModeGet (ScreenPtr pScreen, memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; mode->id = FakeClientID(0); - if (!AddResource (mode->id, ModeType, (pointer) mode)) + if (!AddResource (mode->id, RRModeType, (pointer) mode)) return NULL; ++mode->refcnt; pScrPriv->changed = TRUE; @@ -75,11 +75,11 @@ RRModeDestroyResource (pointer value, XID pid) Bool RRModeInit (void) { - ModeType = CreateNewResourceType (RRModeDestroyResource); - if (!ModeType) + RRModeType = CreateNewResourceType (RRModeDestroyResource); + if (!RRModeType) return FALSE; #ifdef XResExtension - RegisterResourceName (ModeType, "MODE"); + RegisterResourceName (RRModeType, "MODE"); #endif return TRUE; } diff --git a/randr/rroutput.c b/randr/rroutput.c index c7e7995fc..6b67f1997 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -22,7 +22,124 @@ #include "randrstr.h" -static RESTYPE OutputType; +RESTYPE RROutputType; + +/* + * Create an output + */ + +RROutputPtr +RROutputCreate (ScreenPtr pScreen, + char *name, + int nameLength, + void *devPrivate) +{ + rrScrPriv (pScreen); + RROutputPtr output; + RROutputPtr *outputs; + + output = xalloc (sizeof (RROutputRec) + nameLength + 1); + if (!output) + return NULL; + if (pScrPriv->numOutputs) + outputs = xrealloc (pScrPriv->outputs, + (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); + else + outputs = xalloc (sizeof (RROutputPtr)); + if (!outputs) + { + xfree (output); + return NULL; + } + output->id = FakeClientID (0); + output->pScreen = pScreen; + output->name = (char *) (output + 1); + output->nameLength = nameLength; + memcpy (output->name, name, nameLength); + output->connection = RR_UnknownConnection; + output->subpixelOrder = SubPixelUnknown; + output->crtc = NULL; + output->numCrtcs = 0; + output->crtcs = NULL; + output->numClones = 0; + output->clones = NULL; + output->numModes = 0; + output->modes = NULL; + output->changed = TRUE; + output->devPrivate = devPrivate; + pScrPriv->outputs[pScrPriv->numOutputs++] = output; + return output; +} + +/* + * Notify extension that output parameters have been changed + */ +Bool +RROutputSetClones (RROutputPtr output, + RROutputPtr *clones, + int numClones) +{ + RROutputPtr *newClones; + + newClones = xalloc (numClones * sizeof (RROutputPtr)); + if (!newClones) + return FALSE; + if (output->clones) + xfree (output->clones); + memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); + output->clones = newClones; + output->numClones = numClones; + return TRUE; +} + +Bool +RROutputSetModes (RROutputPtr output, + RRModePtr *modes, + int numModes) +{ + RRModePtr *newModes; + + newModes = xalloc (numModes * sizeof (RRModePtr)); + if (!newModes) + return FALSE; + if (output->modes) + xfree (output->modes); + memcpy (newModes, modes, numModes * sizeof (RRModePtr)); + output->modes = newModes; + output->numModes = numModes; + return TRUE; +} + +Bool +RROutputSetCrtcs (RROutputPtr output, + RRCrtcPtr *crtcs, + int numCrtcs) +{ + RRCrtcPtr *newCrtcs; + + newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); + if (!newCrtcs) + return FALSE; + if (output->crtcs) + xfree (output->crtcs); + memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); + output->crtcs = newCrtcs; + output->numCrtcs = numCrtcs; + return TRUE; +} + +Bool +RROutputSetConnection (RROutputPtr output, + CARD8 connection) +{ + output->connection = connection; + return TRUE; +} + +void +RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) +{ +} /* * Destroy a Output at shutdown @@ -36,7 +153,28 @@ RROutputDestroy (RROutputPtr crtc) static int RROutputDestroyResource (pointer value, XID pid) { - free (value); + RROutputPtr output = (RROutputPtr) value; + ScreenPtr pScreen = output->pScreen; + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + if (pScrPriv->outputs[i] == output) + { + memmove (pScrPriv->outputs, pScrPriv->outputs + 1, + (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); + --pScrPriv->numOutputs; + break; + } + } + if (output->modes) + xfree (output->modes); + if (output->crtcs) + xfree (output->crtcs); + if (output->clones) + xfree (output->clones); + xfree (output); return 1; } @@ -46,11 +184,11 @@ RROutputDestroyResource (pointer value, XID pid) Bool RROutputInit (void) { - OutputType = CreateNewResourceType (RROutputDestroyResource); - if (!OutputType) + RROutputType = CreateNewResourceType (RROutputDestroyResource); + if (!RROutputType) return FALSE; #ifdef XResExtension - RegisterResourceName (OutputType, "OUTPUT"); + RegisterResourceName (RROutputType, "OUTPUT"); #endif return TRUE; } diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c new file mode 100644 index 000000000..bf81f8bdb --- /dev/null +++ b/randr/rrsdispatch.c @@ -0,0 +1,282 @@ +/* + * 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); + return (*ProcRandrVector[stuff->randrReqType]) (client); +} + +static int +SProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + + REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq);; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRChangeOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + + REQUEST_SIZE_MATCH(xRRCreateModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcInfo (ClientPtr client) +{ + REQUEST(xRRGetCrtcInfoReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetCrtcConfig (ClientPtr client) +{ + REQUEST(xRRSetCrtcConfigReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcConfigReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); + (void) stuff; + return BadImplementation; +} + +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 */ + SProcRRChangeOutputProperty,/* 11 */ + SProcRRDeleteOutputProperty,/* 12 */ + SProcRRGetOutputProperty, /* 13 */ + SProcRRCreateMode, /* 14 */ + SProcRRDestroyMode, /* 15 */ + SProcRRAddOutputMode, /* 16 */ + SProcRRDeleteOutputMode, /* 17 */ + SProcRRGetCrtcInfo, /* 18 */ + SProcRRSetCrtcConfig, /* 19 */ + SProcRRGetCrtcGammaSize, /* 20 */ + SProcRRGetCrtcGamma, /* 21 */ + SProcRRSetCrtcGamma, /* 22 */ +}; + -- cgit v1.2.3 From 2be1ac15aee592782d7693b8de2c3815478a094e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Sep 2006 12:11:18 -0700 Subject: Remove smashing of CFLAGS from server build. CFLAGS is a user variable, extracted from the environment at configure time and settable by the user at build time. We must not override this variable. --- configure.ac | 6 ++---- hw/xfree86/common/Makefile.am | 2 +- hw/xfree86/ddc/Makefile.am | 2 +- hw/xfree86/dixmods/extmod/Makefile.am | 2 +- hw/xfree86/dri/Makefile.am | 2 +- hw/xfree86/dummylib/Makefile.am | 2 +- hw/xfree86/exa/Makefile.am | 2 +- hw/xfree86/fbdevhw/Makefile.am | 2 +- hw/xfree86/i2c/Makefile.am | 2 +- hw/xfree86/int10/Makefile.am | 6 +++--- hw/xfree86/loader/Makefile.am | 2 +- hw/xfree86/os-support/Makefile.am | 2 ++ hw/xfree86/parser/Makefile.am | 2 +- hw/xfree86/rac/Makefile.am | 2 +- hw/xfree86/ramdac/Makefile.am | 2 +- hw/xfree86/scanpci/Makefile.am | 2 +- hw/xfree86/shadowfb/Makefile.am | 2 +- hw/xfree86/vbe/Makefile.am | 2 +- hw/xfree86/vgahw/Makefile.am | 2 +- hw/xfree86/x86emu/Makefile.am | 2 +- hw/xfree86/xaa/Makefile.am | 2 +- hw/xfree86/xf4bpp/Makefile.am | 2 +- hw/xfree86/xf8_16bpp/Makefile.am | 2 +- hw/xfree86/xf8_32bpp/Makefile.am | 2 +- 24 files changed, 28 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 798c8f0da..d1afa784e 100644 --- a/configure.ac +++ b/configure.ac @@ -1605,13 +1605,11 @@ AM_CONDITIONAL(BUILD_KBD_MODE, [test x$BUILD_KBD_MODE = xyes]) AM_CONDITIONAL(BSD_KBD_MODE, [test x$KBD_MODE_TYPE = xbsd]) AM_CONDITIONAL(SUN_KBD_MODE, [test x$KBD_MODE_TYPE = xsun]) -CFLAGS="$XSERVER_CFLAGS $CFLAGS" -AC_SUBST([CFLAGS]) - BUILD_DATE="$(date +'%Y%m%d')" AC_SUBST([BUILD_DATE]) -DIX_CFLAGS="-DHAVE_DIX_CONFIG_H" +DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS" + AC_SUBST([DIX_CFLAGS]) AC_SUBST([libdir exec_prefix prefix]) diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index d983ee9cc..08a3a877d 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -103,4 +103,4 @@ if LNXACPI XORG_CFLAGS += -DHAVE_ACPI endif -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/ddc/Makefile.am b/hw/xfree86/ddc/Makefile.am index 7cfff4763..aff8cd3b7 100644 --- a/hw/xfree86/ddc/Makefile.am +++ b/hw/xfree86/ddc/Makefile.am @@ -8,6 +8,6 @@ libddc_la_SOURCES = xf86DDC.c edid.c interpret_edid.c print_edid.c \ INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) EXTRA_DIST = ddcPriv.h DDC.HOWTO diff --git a/hw/xfree86/dixmods/extmod/Makefile.am b/hw/xfree86/dixmods/extmod/Makefile.am index 229d4e592..9f6c4081b 100644 --- a/hw/xfree86/dixmods/extmod/Makefile.am +++ b/hw/xfree86/dixmods/extmod/Makefile.am @@ -11,7 +11,7 @@ if XV XV_SRCS = xvmod.c xvmodproc.h endif -AM_CFLAGS = @XORG_CFLAGS@ +AM_CFLAGS = @DIX_CFLAGS@ @XORG_CFLAGS@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/afb \ -I$(top_srcdir)/mfb \ diff --git a/hw/xfree86/dri/Makefile.am b/hw/xfree86/dri/Makefile.am index e711846b2..bc7124bc1 100644 --- a/hw/xfree86/dri/Makefile.am +++ b/hw/xfree86/dri/Makefile.am @@ -10,7 +10,7 @@ libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ \ \ \ - @DRIPROTO_CFLAGS@ \ + @DIX_CFLAGS@ @DRIPROTO_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @GL_CFLAGS@ libdri_la_LDFLAGS = -module -avoid-version diff --git a/hw/xfree86/dummylib/Makefile.am b/hw/xfree86/dummylib/Makefile.am index d89ee59a8..6299a1ff7 100644 --- a/hw/xfree86/dummylib/Makefile.am +++ b/hw/xfree86/dummylib/Makefile.am @@ -6,7 +6,7 @@ noinst_LIBRARIES = libdummy-nonserver.a INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) if NEED_STRLCAT STRL_SRCS = $(top_srcdir)/os/strlcat.c $(top_srcdir)/os/strlcpy.c diff --git a/hw/xfree86/exa/Makefile.am b/hw/xfree86/exa/Makefile.am index 31682c425..9eb2e1797 100644 --- a/hw/xfree86/exa/Makefile.am +++ b/hw/xfree86/exa/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = \ -I$(srcdir)/../../../exa \ -I$(srcdir)/../../../miext/cw -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) libexa_la_SOURCES = \ examodule.c diff --git a/hw/xfree86/fbdevhw/Makefile.am b/hw/xfree86/fbdevhw/Makefile.am index 10de50e83..6a4a6e4e6 100644 --- a/hw/xfree86/fbdevhw/Makefile.am +++ b/hw/xfree86/fbdevhw/Makefile.am @@ -11,7 +11,7 @@ endif INCLUDES = $(XORG_INCS) -I$(srcdir)/../i2c -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) sdk_HEADERS = fbdevhw.h diff --git a/hw/xfree86/i2c/Makefile.am b/hw/xfree86/i2c/Makefile.am index cbf4f6571..e73fcaeb8 100644 --- a/hw/xfree86/i2c/Makefile.am +++ b/hw/xfree86/i2c/Makefile.am @@ -15,7 +15,7 @@ libi2c_la_SOURCES = xf86i2c.c xf86i2cmodule.c INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) sdk_HEADERS = xf86i2c.h bt829.h fi1236.h msp3430.h tda8425.h tda9850.h tda9885.h uda1380.h i2c_def.h diff --git a/hw/xfree86/int10/Makefile.am b/hw/xfree86/int10/Makefile.am index c059070ec..868954fd4 100644 --- a/hw/xfree86/int10/Makefile.am +++ b/hw/xfree86/int10/Makefile.am @@ -14,7 +14,7 @@ COMMON_SOURCES = \ xf86int10module.c if INT10_VM86 -AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = -D_PC -D_VM86_LINUX $(DIX_CFLAGS) $(XORG_CFLAGS) $(EXTRA_CFLAGS) INCLUDES = $(XORG_INCS) libint10_la_SOURCES = \ $(COMMON_SOURCES) \ @@ -23,7 +23,7 @@ libint10_la_SOURCES = \ endif if INT10_X86EMU -AM_CFLAGS = -D_X86EMU -DNO_SYS_HEADERS -D_PC $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = -D_X86EMU -DNO_SYS_HEADERS -D_PC $(DIX_CFLAGS) $(XORG_CFLAGS) $(EXTRA_CFLAGS) INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu libint10_la_SOURCES = \ $(COMMON_SOURCES) \ @@ -33,7 +33,7 @@ libint10_la_SOURCES = \ endif if INT10_STUB -AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = -D_PC -D_VM86_LINUX $(DIX_CFLAGS) $(XORG_CFLAGS) $(EXTRA_CFLAGS) libint10_la_SOURCES = stub.c xf86int10module.c endif diff --git a/hw/xfree86/loader/Makefile.am b/hw/xfree86/loader/Makefile.am index 030672389..206600214 100644 --- a/hw/xfree86/loader/Makefile.am +++ b/hw/xfree86/loader/Makefile.am @@ -5,7 +5,7 @@ INCLUDES = $(XORG_INCS) -I$(srcdir)/../parser -I$(srcdir)/../dixmods/extmod \ -I$(srcdir)/../ddc -I$(srcdir)/../i2c #AM_LDFLAGS = -r -AM_CFLAGS = -DIN_LOADER $(XORG_CFLAGS) +AM_CFLAGS = -DIN_LOADER $(DIX_CFLAGS) $(XORG_CFLAGS) if XORG_LOADER_SPARC SPARC_SOURCES = SparcMulDiv.S diff --git a/hw/xfree86/os-support/Makefile.am b/hw/xfree86/os-support/Makefile.am index e64703a53..58b0e95c2 100644 --- a/hw/xfree86/os-support/Makefile.am +++ b/hw/xfree86/os-support/Makefile.am @@ -19,6 +19,8 @@ libxorgos_la_LIBADD = @XORG_OS_SUBDIR@/lib@XORG_OS_SUBDIR@.la \ bus/libbus.la \ misc/libmisc.la +AM_CFLAGS = $(DIX_CFLAGS) + xorgos.c: touch $@ diff --git a/hw/xfree86/parser/Makefile.am b/hw/xfree86/parser/Makefile.am index 46ef79060..a9491a18a 100644 --- a/hw/xfree86/parser/Makefile.am +++ b/hw/xfree86/parser/Makefile.am @@ -26,7 +26,7 @@ libxf86config_a_SOURCES = \ DRI.c \ Extensions.c -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) EXTRA_DIST = \ Configint.h \ diff --git a/hw/xfree86/rac/Makefile.am b/hw/xfree86/rac/Makefile.am index 2d8d87975..b25068271 100644 --- a/hw/xfree86/rac/Makefile.am +++ b/hw/xfree86/rac/Makefile.am @@ -5,4 +5,4 @@ sdk_HEADERS = xf86RAC.h INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/ramdac/Makefile.am b/hw/xfree86/ramdac/Makefile.am index c9afdad60..8d944455f 100644 --- a/hw/xfree86/ramdac/Makefile.am +++ b/hw/xfree86/ramdac/Makefile.am @@ -13,7 +13,7 @@ EXTRA_DIST = BTPriv.h IBMPriv.h TIPriv.h xf86CursorPriv.h xf86RamDacPriv.h \ CURSOR.NOTES AM_CFLAGS = -DXAAReverseBitOrder=xf86ReverseBitOrder -DRAMDAC_MODULE \ - $(XORG_CFLAGS) + $(DIX_CFLAGS) $(XORG_CFLAGS) INCLUDES = $(XORG_INCS) xf86BitOrder.c: diff --git a/hw/xfree86/scanpci/Makefile.am b/hw/xfree86/scanpci/Makefile.am index 7e5671aa1..d4d9da222 100644 --- a/hw/xfree86/scanpci/Makefile.am +++ b/hw/xfree86/scanpci/Makefile.am @@ -8,7 +8,7 @@ libscanpci_la_SOURCES = xf86ScanPci.c INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) BUILT_SOURCES = xf86PciIds.h diff --git a/hw/xfree86/shadowfb/Makefile.am b/hw/xfree86/shadowfb/Makefile.am index cb5ebb14a..02d2dd4ea 100644 --- a/hw/xfree86/shadowfb/Makefile.am +++ b/hw/xfree86/shadowfb/Makefile.am @@ -6,4 +6,4 @@ sdk_HEADERS = shadowfb.h INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/vbe/Makefile.am b/hw/xfree86/vbe/Makefile.am index 02fdb4837..85c6fd82a 100644 --- a/hw/xfree86/vbe/Makefile.am +++ b/hw/xfree86/vbe/Makefile.am @@ -4,7 +4,7 @@ libvbe_la_SOURCES = vbe.c vbeModes.c vbe_module.c sdk_HEADERS = vbe.h vbeModes.h -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c \ -I$(srcdir)/../int10 diff --git a/hw/xfree86/vgahw/Makefile.am b/hw/xfree86/vgahw/Makefile.am index 2aa27fa41..f48e46a11 100644 --- a/hw/xfree86/vgahw/Makefile.am +++ b/hw/xfree86/vgahw/Makefile.am @@ -2,7 +2,7 @@ module_LTLIBRARIES = libvgahw.la libvgahw_la_LDFLAGS = -avoid-version libvgahw_la_SOURCES = vgaHW.c vgaHWmodule.c INCLUDES = $(XORG_INCS) -I$(srcdir)/../ddc -I$(srcdir)/../i2c -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) sdk_HEADERS = vgaHW.h diff --git a/hw/xfree86/x86emu/Makefile.am b/hw/xfree86/x86emu/Makefile.am index 5959c867a..9f9c87f4f 100644 --- a/hw/xfree86/x86emu/Makefile.am +++ b/hw/xfree86/x86emu/Makefile.am @@ -11,7 +11,7 @@ libx86emu_a_SOURCES = debug.c \ INCLUDES = -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) EXTRA_DIST = validate.c \ x86emu/debug.h \ diff --git a/hw/xfree86/xaa/Makefile.am b/hw/xfree86/xaa/Makefile.am index 23b7e16b1..5d529b118 100644 --- a/hw/xfree86/xaa/Makefile.am +++ b/hw/xfree86/xaa/Makefile.am @@ -68,4 +68,4 @@ EXTRA_DIST = xaacexp.h xaawrap.h xaaLine.c xaaDashLine.c \ INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/xf4bpp/Makefile.am b/hw/xfree86/xf4bpp/Makefile.am index 7cb4ac235..9af336446 100644 --- a/hw/xfree86/xf4bpp/Makefile.am +++ b/hw/xfree86/xf4bpp/Makefile.am @@ -59,4 +59,4 @@ mfbseg.c: INCLUDES = $(XORG_INCS) -I$(srcdir)/../xf1bpp -I$(top_srcdir)/mfb -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/xf8_16bpp/Makefile.am b/hw/xfree86/xf8_16bpp/Makefile.am index 5b30f45ed..3c5b8c93d 100644 --- a/hw/xfree86/xf8_16bpp/Makefile.am +++ b/hw/xfree86/xf8_16bpp/Makefile.am @@ -4,7 +4,7 @@ sdk_HEADERS = cfb8_16.h INCLUDES = $(XORG_INCS) -I$(top_srcdir)/fb -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) libxf8_16bpp_la_LDFLAGS = -avoid-version diff --git a/hw/xfree86/xf8_32bpp/Makefile.am b/hw/xfree86/xf8_32bpp/Makefile.am index 3050b81d1..bbcd10f94 100644 --- a/hw/xfree86/xf8_32bpp/Makefile.am +++ b/hw/xfree86/xf8_32bpp/Makefile.am @@ -4,7 +4,7 @@ sdk_HEADERS = cfb8_32.h INCLUDES = $(XORG_INCS) -I$(top_srcdir)/mfb -I$(top_srcdir)/cfb -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) libxf8_32bpp_la_LDFLAGS = -avoid-version -- cgit v1.2.3 From afe5e9483b352ed06075ed68a6ffa50799194e2d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Sep 2006 12:18:22 -0700 Subject: RandR working with old clients and old API. --- randr/randr.c | 5 +++-- randr/randrstr.h | 3 +++ randr/rrcrtc.c | 16 ++++++++++++++++ randr/rrdispatch.c | 6 +++--- randr/rrmode.c | 19 +++++++++++++++++++ randr/rroutput.c | 18 ++++++++++++++++++ 6 files changed, 62 insertions(+), 5 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 63d471ce0..926e32f1c 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -477,6 +477,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) if (!output) return; RROutputSetCrtcs (output, &crtc, 1); + RROutputSetCrtc (output, crtc); RROutputSetConnection (output, RR_Connected); } @@ -552,8 +553,8 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) /* notice current mode */ if (newMode) - RRCrtcSet (output->crtc, newMode, 0, 0, pScrPriv->rotation, - 1, &output); + RRCrtcNotify (output->crtc, newMode, 0, 0, pScrPriv->rotation, + 1, &output); } #endif diff --git a/randr/randrstr.h b/randr/randrstr.h index 33461570f..a7f91b79a 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -482,6 +482,9 @@ RROutputSetCrtcs (RROutputPtr output, RRCrtcPtr *crtcs, int numCrtcs); +void +RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc); + Bool RROutputSetConnection (RROutputPtr output, CARD8 connection); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index d343c3a57..d1328e7ba 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -59,7 +59,13 @@ RRCrtcCreate (ScreenPtr pScreen, crtc->numOutputs = 0; crtc->changed = TRUE; crtc->devPrivate = devPrivate; + + if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) + return NULL; + + pScrPriv->crtcs = crtcs; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; + pScrPriv->changed = TRUE; return crtc; } @@ -165,6 +171,16 @@ RRCrtcSet (RRCrtcPtr crtc, ScreenPtr pScreen = crtc->pScreen; 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))) + { + return TRUE; + } #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index acf629832..279acfdee 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -824,7 +824,7 @@ ProcRRSetCrtcConfig (ClientPtr client) if (!crtc) { client->errorValue = stuff->crtc; - return RRErrorBase + BadCrtc; + return RRErrorBase + BadRRCrtc; } if (stuff->mode == None) { @@ -838,7 +838,7 @@ ProcRRSetCrtcConfig (ClientPtr client) if (!mode) { client->errorValue = stuff->mode; - return RRErrorBase + BadMode; + return RRErrorBase + BadRRMode; } if (numOutputs == 0) return BadMatch; @@ -854,7 +854,7 @@ ProcRRSetCrtcConfig (ClientPtr client) if (!outputs[i]) { client->errorValue = outputIds[i]; - return RRErrorBase + BadOutput; + return RRErrorBase + BadRROutput; } /* validate crtc for this output */ for (j = 0; j < outputs[i]->numCrtcs; j++) diff --git a/randr/rrmode.c b/randr/rrmode.c index 3a9d55671..52585d967 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -32,6 +32,7 @@ RRModeGet (ScreenPtr pScreen, rrScrPriv (pScreen); int i; RRModePtr mode; + RRModePtr *modes; for (i = 0; i < pScrPriv->numModes; i++) { @@ -43,16 +44,34 @@ RRModeGet (ScreenPtr pScreen, return mode; } } + mode = xalloc (sizeof (RRModeRec) + modeInfo->nameLength + 1); + if (!mode) + return NULL; mode->refcnt = 1; mode->mode = *modeInfo; mode->name = (char *) (mode + 1); memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; + + if (pScrPriv->numModes) + modes = xrealloc (pScrPriv->modes, + (pScrPriv->numModes + 1) * sizeof (RRModePtr)); + else + modes = xalloc (sizeof (RRModePtr)); + + if (!modes) + { + xfree (mode); + return NULL; + } + mode->id = FakeClientID(0); if (!AddResource (mode->id, RRModeType, (pointer) mode)) return NULL; ++mode->refcnt; + pScrPriv->modes = modes; + pScrPriv->modes[pScrPriv->numModes++] = mode; pScrPriv->changed = TRUE; return mode; } diff --git a/randr/rroutput.c b/randr/rroutput.c index 6b67f1997..ba5bcb451 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -56,6 +56,7 @@ RROutputCreate (ScreenPtr pScreen, output->name = (char *) (output + 1); output->nameLength = nameLength; memcpy (output->name, name, nameLength); + output->name[nameLength] = '\0'; output->connection = RR_UnknownConnection; output->subpixelOrder = SubPixelUnknown; output->crtc = NULL; @@ -67,7 +68,13 @@ RROutputCreate (ScreenPtr pScreen, output->modes = NULL; output->changed = TRUE; output->devPrivate = devPrivate; + + if (!AddResource (output->id, RROutputType, (pointer) output)) + return NULL; + + pScrPriv->outputs = outputs; pScrPriv->outputs[pScrPriv->numOutputs++] = output; + pScrPriv->changed = TRUE; return output; } @@ -89,6 +96,7 @@ RROutputSetClones (RROutputPtr output, memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); output->clones = newClones; output->numClones = numClones; + output->changed = TRUE; return TRUE; } @@ -107,6 +115,7 @@ RROutputSetModes (RROutputPtr output, memcpy (newModes, modes, numModes * sizeof (RRModePtr)); output->modes = newModes; output->numModes = numModes; + output->changed = TRUE; return TRUE; } @@ -125,14 +134,23 @@ RROutputSetCrtcs (RROutputPtr output, memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); output->crtcs = newCrtcs; output->numCrtcs = numCrtcs; + output->changed = TRUE; return TRUE; } +void +RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) +{ + output->crtc = crtc; + output->changed = TRUE; +} + Bool RROutputSetConnection (RROutputPtr output, CARD8 connection) { output->connection = connection; + output->changed = TRUE; return TRUE; } -- cgit v1.2.3 From 07112adb0802d28488de5a495aa61bb3cfc280b6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Sep 2006 00:46:27 -0700 Subject: RRGetScreenResources and RRGetOutputInfo are working now. Removed separate id field in RRModeRec. Pull screen subpixel order from Render extension. Implement RGetScreenResources and RRGetOutputInfo --- randr/randr.c | 5 +- randr/randrstr.h | 5 +- randr/rrdispatch.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++- randr/rrmode.c | 5 +- randr/rroutput.c | 9 +++ 5 files changed, 233 insertions(+), 8 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 926e32f1c..beddb50b0 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -442,7 +442,7 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) if (!modes) { RRModeDestroy (mode); - FreeResource (mode->id, 0); + FreeResource (mode->mode.id, 0); return NULL; } modes[output->numModes++] = mode; @@ -479,6 +479,9 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) RROutputSetCrtcs (output, &crtc, 1); RROutputSetCrtc (output, crtc); RROutputSetConnection (output, RR_Connected); +#ifdef RENDER + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); +#endif } output = RRFirstOutput (pScreen); diff --git a/randr/randrstr.h b/randr/randrstr.h index a7f91b79a..682ebbfed 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -74,7 +74,6 @@ typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; struct _rrMode { - RRMode id; int refcnt; xRRModeInfo mode; char *name; @@ -489,6 +488,10 @@ Bool RROutputSetConnection (RROutputPtr output, CARD8 connection); +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder); + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 279acfdee..aca0e542a 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -694,20 +694,229 @@ static int ProcRRGetScreenResources (ClientPtr client) { REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + int n; REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); - (void) stuff; - return BadImplementation; + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + if (!pScrPriv) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = 0; + rep.nOutputs = 0; + rep.nModes = 0; + rep.nbytesNames = 0; + extra = NULL; + extraLen = 0; + } + else + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = pScrPriv->numCrtcs; + rep.nOutputs = pScrPriv->numOutputs; + rep.nModes = pScrPriv->numModes;; + rep.nbytesNames = 0; + + for (i = 0; i < pScrPriv->numModes; i++) + rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength; + + rep.length = (pScrPriv->numCrtcs + + pScrPriv->numOutputs + + pScrPriv->numModes * 10 + + ((rep.nbytesNames + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + pScrPriv->numModes); + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + crtcs[i] = pScrPriv->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + outputs[i] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + + for (i = 0; i < pScrPriv->numModes; i++) + { + modeinfos[i] = pScrPriv->modes[i]->mode; + if (client->swapped) + { + swapl (&modeinfos[i].id, n); + swaps (&modeinfos[i].width, n); + swaps (&modeinfos[i].height, n); + swapl (&modeinfos[i].mmWidth, n); + swapl (&modeinfos[i].mmHeight, n); + swapl (&modeinfos[i].dotClock, n); + swaps (&modeinfos[i].hSyncStart, n); + swaps (&modeinfos[i].hSyncEnd, n); + swaps (&modeinfos[i].hTotal, n); + swaps (&modeinfos[i].hSkew, n); + swaps (&modeinfos[i].vSyncStart, n); + swaps (&modeinfos[i].vSyncEnd, n); + swaps (&modeinfos[i].vTotal, n); + swaps (&modeinfos[i].nameLength, n); + swapl (&modeinfos[i].modeFlags, n); + } + memcpy (names, pScrPriv->modes[i]->name, + pScrPriv->modes[i]->mode.nameLength); + names += pScrPriv->modes[i]->mode.nameLength; + } + assert ((names + 3 >> 3) == rep.length); + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.configTimestamp, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nOutputs, n); + swaps(&rep.nModes, n); + swaps(&rep.nbytesNames, n); + } + WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return client->noClientException; } static int ProcRRGetOutputInfo (ClientPtr client) { REQUEST(xRRGetOutputInfoReq);; + xRRGetOutputInfoReply rep; + RROutputPtr output; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtc *crtcs; + RRMode *modes; + RROutput *clones; + char *name; + int i, n; REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - (void) stuff; - return BadImplementation; + output = (RROutputPtr)SecurityLookupIDByType(client, stuff->output, + RROutputType, + SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + pScreen = output->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.crtc = output->crtc ? output->crtc->id : None; + rep.connection = output->connection; + rep.subpixelOrder = output->subpixelOrder; + rep.nCrtcs = output->numCrtcs; + rep.nModes = output->numModes; + rep.nClones = output->numClones; + rep.nameLength = output->nameLength; + + rep.length = (output->numCrtcs + + output->numModes + + output->numClones + + ((rep.nameLength + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + modes = (RRMode *) (crtcs + output->numCrtcs); + clones = (RROutput *) (modes + output->numModes); + name = (char *) (clones + output->numClones); + + for (i = 0; i < output->numCrtcs; i++) + { + crtcs[i] = output->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + for (i = 0; i < output->numModes; i++) + { + modes[i] = output->modes[i]->mode.id; + if (client->swapped) + swapl (&modes[i], n); + } + for (i = 0; i < output->numClones; i++) + { + clones[i] = output->clones[i]->id; + if (client->swapped) + swapl (&clones[i], n); + } + memcpy (name, output->name, output->nameLength); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.crtc, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nModes, n); + swaps(&rep.nClones, n); + swaps(&rep.nameLength, n); + } + WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; } static int diff --git a/randr/rrmode.c b/randr/rrmode.c index 52585d967..4e44e7d82 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -37,6 +37,7 @@ RRModeGet (ScreenPtr pScreen, for (i = 0; i < pScrPriv->numModes; i++) { mode = pScrPriv->modes[i]; + modeInfo->id = mode->mode.id; if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && !memcmp (name, mode->name, modeInfo->nameLength)) { @@ -66,8 +67,8 @@ RRModeGet (ScreenPtr pScreen, return NULL; } - mode->id = FakeClientID(0); - if (!AddResource (mode->id, RRModeType, (pointer) mode)) + mode->mode.id = FakeClientID(0); + if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) return NULL; ++mode->refcnt; pScrPriv->modes = modes; diff --git a/randr/rroutput.c b/randr/rroutput.c index ba5bcb451..478002300 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -154,6 +154,15 @@ RROutputSetConnection (RROutputPtr output, return TRUE; } +Bool +RROutputSetSubpixelOrder (RROutputPtr output, + int subpixelOrder) +{ + output->subpixelOrder = subpixelOrder; + output->changed = TRUE; + return TRUE; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { -- cgit v1.2.3 From ef1f3248cb5fff0a02c0059f865c4d931eba23a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Sep 2006 22:48:54 -0700 Subject: Split out 1.0-style info and new property routines to their own files. --- randr/Makefile.am | 2 + randr/mirandr.c | 12 +- randr/randr.c | 394 +------------------- randr/randrstr.h | 128 ++++++- randr/rrcrtc.c | 461 ++++++++++++++++++++++- randr/rrdispatch.c | 1035 ---------------------------------------------------- randr/rrmode.c | 41 +++ randr/rroutput.c | 96 ++++- randr/rrscreen.c | 651 +++++++++++++++++++++++++++++++++ 9 files changed, 1385 insertions(+), 1435 deletions(-) diff --git a/randr/Makefile.am b/randr/Makefile.am index 0a735574e..a28ead0eb 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -12,7 +12,9 @@ librandr_la_SOURCES = \ randrstr.h \ rrcrtc.c \ rrdispatch.c \ + rrinfo.c \ rrmode.c \ rroutput.c \ + rrproperty.c \ rrscreen.c \ rrsdispatch.c diff --git a/randr/mirandr.c b/randr/mirandr.c index a57a157ca..bcc8e0fcd 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -108,11 +108,13 @@ miRandRInit (ScreenPtr pScreen) output = RROutputCreate (pScreen, "screen", 6, NULL); if (!output) return FALSE; - if (!RROutputSet (output, - NULL, 0, /* clones */ - &mode, 1, /* modes */ - &crtc, 1, /* crtcs */ - RR_Connected)) + if (!RROutputSetClones (output, NULL, 0)) + return FALSE; + if (!RROutputSetModes (output, &mode, 1)) + return FALSE; + if (!RROutputSetCrtcs (output, &crtc, 1)) + return FALSE; + if (!RROutputSetConnection (output, RR_Connected)) return FALSE; RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); #endif diff --git a/randr/randr.c b/randr/randr.c index beddb50b0..5f6ef62e4 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -198,7 +198,9 @@ Bool RRScreenInit(ScreenPtr pScreen) pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; #if RANDR_12_INTERFACE - pScrPriv->rrCrtcSet = 0; + pScrPriv->rrScreenSizeSet = NULL; + pScrPriv->rrCrtcSet = NULL; + pScrPriv->rrCrtcSetGamma = NULL; #endif #if RANDR_10_INTERFACE pScrPriv->rrSetConfig = 0; @@ -400,196 +402,6 @@ RRFirstOutput (ScreenPtr pScreen) return NULL; } -#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.mmWidth = size->mmWidth; - modeInfo.mmHeight = size->mmHeight; - modeInfo.hTotal = size->width; - modeInfo.vTotal = size->height; - modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->width * - (CARD32) refresh); - modeInfo.nameLength = strlen (name); - mode = RRModeGet (pScreen, &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 = xrealloc (output->modes, - (output->numModes + 1) * sizeof (RRModePtr)); - else - modes = xalloc (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; - 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); - RROutputSetCrtc (output, crtc); - RROutputSetConnection (output, RR_Connected); -#ifdef RENDER - RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); -#endif - } - - output = RRFirstOutput (pScreen); - if (!output) - return; - crtc = output->crtc; - - /* 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; - } - } - xfree (size->pRates); - } - else - { - mode = RROldModeAdd (output, size, 0); - if (i == pScrPriv->size) - newMode = mode; - } - } - if (pScrPriv->nSizes) - xfree (pScrPriv->pSizes); - pScrPriv->pSizes = NULL; - pScrPriv->nSizes = 0; - - /* find size bounds */ - for (i = 0; i < output->numModes; i++) - { - RRModePtr mode = output->modes[i]; - 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; - } - - if (minWidth != pScrPriv->minWidth) { - pScrPriv->minWidth = minWidth; pScrPriv->changed = TRUE; - } - if (maxWidth != pScrPriv->maxWidth) { - pScrPriv->maxWidth = maxWidth; pScrPriv->changed = TRUE; - } - if (minHeight != pScrPriv->minHeight) { - pScrPriv->minHeight = minHeight; pScrPriv->changed = TRUE; - } - if (maxHeight != pScrPriv->maxHeight) { - pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE; - } - - /* notice current mode */ - if (newMode) - RRCrtcNotify (output->crtc, newMode, 0, 0, pScrPriv->rotation, - 1, &output); -} -#endif - -/* - * Poll the driver for changed information - */ -Bool -RRGetInfo (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - Rotation rotations; - int i; - - 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; - - if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) - return FALSE; - -#if RANDR_10_INTERFACE - if (pScrPriv->nSizes) - RRScanOldConfig (pScreen, rotations); -#endif - RRTellChanged (pScreen); - return TRUE; -} - CARD16 RRVerticalRefresh (xRRModeInfo *mode) { @@ -602,83 +414,6 @@ RRVerticalRefresh (xRRModeInfo *mode) return (CARD16) refresh; } -#if 0 -int -RRSetScreenConfig (ScreenPtr pScreen, - Rotation rotation, - int rate, - RRScreenSizePtr pSize) -{ - rrScrPrivPtr pScrPriv; - RRMonitorPtr pMonitor; - short oldWidth, oldHeight; - RRModePtr pMode; - int status; - - pScrPriv = rrGetScrPriv(pScreen); - - if (!pScrPriv) - return BadImplementation; - - pMonitor = pScrPriv->pMonitors; - if (!pMonitor) - return BadImplementation; - - oldWidth = pScreen->width; - oldHeight = pScreen->height; - - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * Validate requested 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 - */ - return BadValue; - } - - if ((~pScrPriv->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - return BadMatch; - } - - for (pMode = pMonitor->pModes; pMode; pMode = pMode->next) - { - if (pMode->mode.width == pSize->width && - pMode->mode.height == pSize->height && - pMode->mode.widthInMillimeters == pSize->mmWidth && - pMode->mode.heightInMillimeters == pSize->mmHeight && - (RRVerticalRefresh (&pMode->mode) == rate || rate == 0)) - { - break; - } - } - if (!pMode) - return BadValue; - - status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0, - rotation, currentTime); - - if (status != RRSetConfigSuccess) - return BadImplementation; - return Success; -} -#endif - static int ProcRRDispatch (ClientPtr client) { @@ -697,126 +432,3 @@ SProcRRDispatch (ClientPtr client) return (*SProcRandrVector[stuff->data]) (client); } -#if RANDR_12_INTERFACE -/* - * 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; - pScrPriv->minWidth = minWidth; - pScrPriv->minHeight = minHeight; - pScrPriv->maxWidth = maxWidth; - pScrPriv->maxHeight = maxHeight; -} -#endif - -#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 = xrealloc (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 = xrealloc (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/randr/randrstr.h b/randr/randrstr.h index 682ebbfed..26c180697 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -53,7 +53,7 @@ /* required for ABI compatibility for now */ #define RANDR_10_INTERFACE 1 -/* #define RANDR_12_INTERFACE 1 */ +#define RANDR_12_INTERFACE 1 typedef XID RRMode; typedef XID RROutput; @@ -89,6 +89,10 @@ struct _rrCrtc { Bool changed; int numOutputs; RROutputPtr *outputs; + int gammaSize; + CARD16 *gammaRed; + CARD16 *gammaBlue; + CARD16 *gammaGreen; void *devPrivate; }; @@ -107,11 +111,12 @@ struct _rrOutput { int numModes; RRModePtr *modes; Bool changed; + PropertyPtr properties; void *devPrivate; }; #if RANDR_12_INTERFACE -typedef Bool (*RRScreentSizeSetProcPtr) (ScreenPtr pScreen, +typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, CARD16 height, CARD32 mmWidth, @@ -125,6 +130,10 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, Rotation rotation, int numOutputs, RROutputPtr *outputs); + +typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, + RRCrtcPtr crtc); + #endif typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); @@ -167,6 +176,7 @@ typedef struct _rrScrPriv { #if RANDR_12_INTERFACE RRScreenSetSizeProcPtr rrScreenSizeSet; RRCrtcSetProcPtr rrCrtcSet; + RRCrtcSetGammaProcPtr rrCrtcSetGamma; #endif /* @@ -245,6 +255,16 @@ extern RESTYPE RRClientType, RREventType; /* resource types for event masks */ extern int RRClientPrivateIndex; extern RESTYPE RRCrtcType, RRModeType, RROutputType; +#define LookupOutput(client,id,a) ((RROutputPtr) \ + (SecurityLookupIDByType (client, id, \ + RROutputType, a))) +#define LookupCrtc(client,id,a) ((RRCrtcPtr) \ + (SecurityLookupIDByType (client, id, \ + RRCrtcType, a))) +#define LookupMode(client,id,a) ((RRModePtr) \ + (SecurityLookupIDByType (client, id, \ + RRModeType, a))) + #define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr) #define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient) @@ -283,6 +303,24 @@ RRScreenSizeSet (ScreenPtr pScreen, CARD32 mmWidth, CARD32 mmHeight); +/* + * screen dispatch + */ +int +ProcRRGetScreenSizeRange (ClientPtr client); + +int +ProcRRSetScreenSize (ClientPtr client); + +int +ProcRRGetScreenResources (ClientPtr client); + +int +ProcRRSetScreenConfig (ClientPtr client); + +int +ProcRRGetScreenInfo (ClientPtr client); + /* * Deliver a ScreenNotify event */ @@ -413,6 +451,33 @@ RRCrtcSet (RRCrtcPtr crtc, int numOutput, RROutputPtr *outputs); +/* + * Request that the Crtc gamma be changed + */ + +Bool +RRCrtcGammaSet (RRCrtcPtr crtc, + CARD16 *red, + CARD16 *green, + CARD16 *blue); + +/* + * 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); + +/* + * Set the size of the gamma table at server startup time + */ + +Bool +RRCrtcGammaSetSize (RRCrtcPtr crtc, + int size); + /* * Destroy a Crtc at shutdown */ @@ -425,6 +490,25 @@ RRCrtcDestroy (RRCrtcPtr crtc); Bool RRCrtcInit (void); +/* + * Crtc dispatch + */ + +int +ProcRRGetCrtcInfo (ClientPtr client); + +int +ProcRRSetCrtcConfig (ClientPtr client); + +int +ProcRRGetCrtcGammaSize (ClientPtr client); + +int +ProcRRGetCrtcGamma (ClientPtr client); + +int +ProcRRSetCrtcGamma (ClientPtr client); + /* rrdispatch.c */ Bool RRClientKnowsRates (ClientPtr pClient); @@ -452,6 +536,18 @@ RRModeDestroy (RRModePtr mode); Bool RRModeInit (void); +int +ProcRRCreateMode (ClientPtr client); + +int +ProcRRDestroyMode (ClientPtr client); + +int +ProcRRAddOutputMode (ClientPtr client); + +int +ProcRRDeleteOutputMode (ClientPtr client); + /* rroutput.c */ /* * Create an output @@ -498,10 +594,38 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); void RROutputDestroy (RROutputPtr output); +int +ProcRRGetOutputInfo (ClientPtr client); + /* * Initialize output type */ Bool RROutputInit (void); +/* rrproperty.c */ + +void +RRDeleteAllOutputProperties (RROutputPtr output); + +void +RRDeleteOutputProperty (RROutputPtr output, Atom property); + +int +RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, + int format, int mode, unsigned long len, + pointer value, Bool sendevent); + +int +ProcRRChangeOutputProperty (ClientPtr client); + +int +ProcRRGetOutputProperty (ClientPtr client); + +int +ProcRRListOutputProperties (ClientPtr client); + +int +ProcRRDeleteOutputProperty (ClientPtr client); + #endif /* _RANDRSTR_H_ */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index d1328e7ba..c55e08871 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -21,6 +21,7 @@ */ #include "randrstr.h" +#include "swaprep.h" RESTYPE RRCrtcType; @@ -57,6 +58,8 @@ RRCrtcCreate (ScreenPtr pScreen, crtc->rotations = RR_Rotate_0; crtc->outputs = NULL; crtc->numOutputs = 0; + crtc->gammaSize = 0; + crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; crtc->changed = TRUE; crtc->devPrivate = devPrivate; @@ -241,10 +244,74 @@ RRCrtcDestroyResource (pointer value, XID pid) break; } } - free (value); + if (crtc->gammaRed) + xfree (crtc->gammaRed); + xfree (value); 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; + rrScrPriv(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 (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (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 */ +} + +/* + * 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; + gamma = xalloc (size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + if (crtc->gammaRed) + xfree (crtc->gammaRed); + crtc->gammaRed = gamma; + crtc->gammaGreen = gamma + size; + crtc->gammaBlue = gamma + size*2; + crtc->gammaSize = size; + return TRUE; +} + /* * Initialize crtc type */ @@ -259,3 +326,395 @@ RRCrtcInit (void) #endif return TRUE; } + +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; + + REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); + crtc = LookupCrtc(client, stuff->crtc, SecurityReadAccess); + + if (!crtc) + return RRErrorBase + BadRRCrtc; + + 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; + rep.x = crtc->x; + rep.y = crtc->y; + rep.width = mode ? mode->mode.width : 0; + rep.height = mode ? mode->mode.height : 0; + rep.mode = mode->mode.id; + 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; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + 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); + xfree (extra); + } + + return client->noClientException; +} + +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 i, j; + + REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); + numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); + + crtc = LookupIDByType (stuff->crtc, RRCrtcType); + if (!crtc) + { + client->errorValue = stuff->crtc; + return RRErrorBase + BadRRCrtc; + } + if (stuff->mode == None) + { + mode = NULL; + if (numOutputs > 0) + return BadMatch; + } + else + { + mode = LookupIDByType (stuff->mode, RRModeType); + if (!mode) + { + client->errorValue = stuff->mode; + return RRErrorBase + BadRRMode; + } + if (numOutputs == 0) + return BadMatch; + } + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + + outputIds = (RROutput *) (stuff + 1); + for (i = 0; i < numOutputs; i++) + { + outputs[i] = LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) + { + client->errorValue = outputIds[i]; + if (outputs) + xfree (outputs); + return RRErrorBase + BadRROutput; + } + /* validate crtc for this output */ + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) + break; + if (j == outputs[j]->numCrtcs) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + /* validate mode for this output */ + for (j = 0; j < outputs[i]->numModes; j++) + if (outputs[i]->modes[j] == mode) + break; + if (j == outputs[i]->numModes) + { + if (outputs) + xfree (outputs); + return BadMatch; + } + } + + pScreen = crtc->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + if (!RRGetInfo (pScreen)) + { + if (outputs) + xfree (outputs); + return BadAlloc; + } + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + 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; + if (outputs) + xfree (outputs); + return BadValue; + } + + if ((~crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + if (outputs) + xfree (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 (pScrPriv->rrScreenSizeSet) + { + if (stuff->x + mode->mode.width > pScreen->width) + { + client->errorValue = stuff->x; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (stuff->y + mode->mode.height > pScreen->height) + { + client->errorValue = stuff->y; + if (outputs) + xfree (outputs); + return BadValue; + } + } +#endif + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y, + rotation, numOutputs, outputs); + +sendReply: + if (outputs) + xfree (outputs); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.newTimestamp = pScrPriv->lastConfigTime.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 client->noClientException; +} + +int +ProcRRGetCrtcGammaSize (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaSizeReq); + xRRGetCrtcGammaSizeReply reply; + RRCrtcPtr crtc; + int n; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); + crtc = LookupCrtc (client, stuff->crtc, SecurityReadAccess); + if (!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 client->noClientException; +} + +int +ProcRRGetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRGetCrtcGammaReq); + xRRGetCrtcGammaReply reply; + RRCrtcPtr crtc; + int n; + unsigned long len; + + REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, SecurityReadAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = crtc->gammaSize * 3 * 2; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = (len + 3) >> 2; + 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) + { + client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; + WriteSwappedDataToClient (client, len, (char *) crtc->gammaRed); + } + return client->noClientException; +} + +int +ProcRRSetCrtcGamma (ClientPtr client) +{ + REQUEST(xRRSetCrtcGammaReq); + RRCrtcPtr crtc; + unsigned long len; + CARD16 *red, *green, *blue; + + REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); + crtc = LookupCrtc (client, stuff->crtc, SecurityWriteAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + len = client->req_len - (sizeof (xRRSetCrtcGammaReq) >> 2); + 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; +} + diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index aca0e542a..49ba10bc0 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -31,79 +31,6 @@ RRClientKnowsRates (ClientPtr pClient) (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); } -typedef struct _RR10Data { - RRScreenSizePtr sizes; - int nsize; - int nrefresh; - int size; - CARD16 refresh; -} RR10DataRec, *RR10DataPtr; - -/* - * Convert 1.2 monitor data into 1.0 screen data - */ -static RR10DataPtr -RR10GetData (ScreenPtr pScreen, RROutputPtr output) -{ - RR10DataPtr data; - RRScreenSizePtr size; - int nmode = output->numModes; - int i, j, k; - RRScreenRatePtr refresh; - CARD16 vRefresh; - RRModePtr mode; - - /* Make sure there is plenty of space for any combination */ - data = malloc (sizeof (RR10DataRec) + - sizeof (RRScreenSize) * nmode + - sizeof (RRScreenRate) * nmode); - if (!data) - return NULL; - size = (RRScreenSizePtr) (data + 1); - refresh = (RRScreenRatePtr) (size + nmode); - data->sizes = size; - data->nsize = 0; - data->nrefresh = 0; - data->size = 0; - data->refresh = 0; - for (i = 0; i < output->numModes; i++) - { - mode = output->modes[i]; - for (j = 0; j < data->nsize; j++) - if (mode->mode.width == size[j].width && - mode->mode.height == size[j].height) - break; - if (j == data->nsize) - { - size[j].id = j; - size[j].width = mode->mode.width; - size[j].height = mode->mode.height; - size[j].mmWidth = mode->mode.mmWidth; - size[j].mmHeight = mode->mode.mmHeight; - size[j].nRates = 0; - size[j].pRates = &refresh[data->nrefresh]; - data->nsize++; - } - vRefresh = RRVerticalRefresh (&mode->mode); - for (k = 0; k < size[j].nRates; k++) - if (vRefresh == size[j].pRates[k].rate) - break; - if (k == size[j].nRates) - { - size[j].pRates[k].rate = vRefresh; - size[j].pRates[k].mode = mode; - size[j].nRates++; - data->nrefresh++; - } - if (mode == output->crtc->mode) - { - data->size = j; - data->refresh = vRefresh; - } - } - return data; -} - static int ProcRRQueryVersion (ClientPtr client) { @@ -134,341 +61,6 @@ ProcRRQueryVersion (ClientPtr client) return (client->noClientException); } -static int -ProcRRGetScreenInfo (ClientPtr client) -{ - REQUEST(xRRGetScreenInfoReq); - xRRGetScreenInfoReply rep; - WindowPtr pWin; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - RROutputPtr output; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - - if (pScrPriv) - RRGetInfo (pScreen); - - output = RRFirstOutput (pScreen); - - if (!pScrPriv || !output) - { - rep.type = X_Reply; - rep.setOfRotations = RR_Rotate_0;; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nSizes = 0; - rep.sizeID = 0; - rep.rotation = RR_Rotate_0; - rep.rate = 0; - rep.nrateEnts = 0; - extra = 0; - extraLen = 0; - } - else - { - int i, j; - xScreenSizes *size; - CARD16 *rates; - CARD8 *data8; - Bool has_rate = RRClientKnowsRates (client); - RR10DataPtr pData; - RRScreenSizePtr pSize; - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - rep.type = X_Reply; - rep.setOfRotations = output->crtc->rotations; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.rotation = output->crtc->rotation; - rep.nSizes = pData->nsize; - rep.nrateEnts = pData->nrefresh + pData->nsize; - rep.sizeID = pData->size; - rep.rate = pData->refresh; - - extraLen = (rep.nSizes * sizeof (xScreenSizes) + - rep.nrateEnts * sizeof (CARD16)); - - extra = (CARD8 *) xalloc (extraLen); - if (!extra) - { - xfree (pData); - return BadAlloc; - } - /* - * First comes the size information - */ - size = (xScreenSizes *) extra; - rates = (CARD16 *) (size + rep.nSizes); - for (i = 0; i < pData->nsize; i++) - { - pSize = &pData->sizes[i]; - size->widthInPixels = pSize->width; - size->heightInPixels = pSize->height; - size->widthInMillimeters = pSize->mmWidth; - size->heightInMillimeters = pSize->mmHeight; - if (client->swapped) - { - swaps (&size->widthInPixels, n); - swaps (&size->heightInPixels, n); - swaps (&size->widthInMillimeters, n); - swaps (&size->heightInMillimeters, n); - } - size++; - if (has_rate) - { - *rates = pSize->nRates; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - for (j = 0; j < pSize->nRates; j++) - { - *rates = pSize->pRates[j].rate; - if (client->swapped) - { - swaps (rates, n); - } - rates++; - } - } - } - xfree (pData); - - data8 = (CARD8 *) rates; - - if (data8 - (CARD8 *) extra != extraLen) - FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", - (unsigned long)(data8 - (CARD8 *) extra), extraLen); - rep.length = (extraLen + 3) >> 2; - } - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swaps(&rep.rotation, n); - swaps(&rep.nSizes, n); - swaps(&rep.sizeID, n); - swaps(&rep.rate, n); - swaps(&rep.nrateEnts, n); - } - WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return (client->noClientException); -} - -static int -ProcRRSetScreenConfig (ClientPtr client) -{ - REQUEST(xRRSetScreenConfigReq); - xRRSetScreenConfigReply rep; - DrawablePtr pDraw; - int n; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - TimeStamp configTime; - TimeStamp time; - int i; - Rotation rotation; - int rate; - Bool has_rate; - RROutputPtr output; - RRModePtr mode; - RR10DataPtr pData = NULL; - RRScreenSizePtr pSize; - - UpdateCurrentTime (); - - if (RRClientKnowsRates (client)) - { - REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); - has_rate = TRUE; - } - else - { - REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); - has_rate = FALSE; - } - - SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, - SecurityWriteAccess); - - pScreen = pDraw->pScreen; - - pScrPriv = rrGetScrPriv(pScreen); - - time = ClientTimeToServerTime(stuff->timestamp); - configTime = ClientTimeToServerTime(stuff->configTimestamp); - - if (!pScrPriv) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - output = RRFirstOutput (pScreen); - if (!output) - { - time = currentTime; - rep.status = RRSetConfigFailed; - goto sendReply; - } - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - goto sendReply; - } - - pData = RR10GetData (pScreen, output); - if (!pData) - return BadAlloc; - - if (stuff->sizeID >= pData->nsize) - { - /* - * Invalid size ID - */ - client->errorValue = stuff->sizeID; - xfree (pData); - return BadValue; - } - pSize = &pData->sizes[stuff->sizeID]; - - /* - * 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; - xfree (pData); - return BadValue; - } - - if ((~output->crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - xfree (pData); - return BadMatch; - } - - /* - * Validate requested refresh - */ - if (has_rate) - rate = (int) stuff->rate; - else - rate = 0; - - if (rate) - { - for (i = 0; i < pSize->nRates; i++) - { - if (pSize->pRates[i].rate == rate) - break; - } - if (i == pSize->nRates) - { - /* - * Invalid rate - */ - client->errorValue = rate; - xfree (pData); - return BadValue; - } - mode = pSize->pRates[i].mode; - } - else - mode = pSize->pRates[0].mode; - - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, - 1, &output); - -sendReply: - - if (pData) - xfree (pData); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; - rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; - rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.newTimestamp, n); - swapl(&rep.newConfigTimestamp, n); - swapl(&rep.root, n); - } - WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); - - return (client->noClientException); -} - static int ProcRRSelectInput (ClientPtr client) { @@ -584,633 +176,6 @@ ProcRRSelectInput (ClientPtr client) return Success; } -/* - * Retrieve valid screen size range - */ -static int -ProcRRGetScreenSizeRange (ClientPtr client) -{ - REQUEST(xRRGetScreenSizeRangeReq); - xRRGetScreenSizeRangeReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - - REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - rep.type = X_Reply; - rep.pad = 0; - rep.sequenceNumber = client->sequence; - rep.length = 0; - - if (pScrPriv) - { - RRGetInfo (pScreen); - rep.minWidth = pScrPriv->minWidth; - rep.minHeight = pScrPriv->minHeight; - rep.maxWidth = pScrPriv->maxWidth; - rep.maxHeight = pScrPriv->maxHeight; - } - else - { - rep.maxWidth = rep.minWidth = pScreen->width; - rep.maxHeight = rep.minHeight = pScreen->height; - } - if (client->swapped) - { - int n; - - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.minWidth, n); - swaps(&rep.minHeight, n); - swaps(&rep.maxWidth, n); - swaps(&rep.maxHeight, n); - } - WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); - return (client->noClientException); -} - -static int ProcRRSetScreenSize (ClientPtr client) -{ - REQUEST(xRRSetScreenSizeReq); - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtcPtr crtc; - int i; - - REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) - { - client->errorValue = stuff->width; - return BadValue; - } - if (stuff->height < pScrPriv->minHeight || - pScrPriv->maxHeight < stuff->height) - { - client->errorValue = stuff->height; - return BadValue; - } - for (i = 0; i < pScrPriv->numCrtcs; i++) { - crtc = pScrPriv->crtcs[i]; - if (crtc->mode && - (crtc->x + crtc->mode->mode.width > stuff->width || - crtc->y + crtc->mode->mode.height > stuff->height)) - return BadMatch; - } - if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) - { - client->errorValue = 0; - return BadValue; - } - if (!RRScreenSizeSet (pScreen, - stuff->width, stuff->height, - stuff->widthInMillimeters, - stuff->heightInMillimeters)) - { - return BadMatch; - } - return Success; -} - -static int -ProcRRGetScreenResources (ClientPtr client) -{ - REQUEST(xRRGetScreenResourcesReq); - xRRGetScreenResourcesReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - CARD8 *extra; - unsigned long extraLen; - int i; - RRCrtc *crtcs; - RROutput *outputs; - xRRModeInfo *modeinfos; - CARD8 *names; - int n; - - REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); - pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, - SecurityReadAccess); - - if (!pWin) - return BadWindow; - - pScreen = pWin->drawable.pScreen; - pScrPriv = rrGetScrPriv(pScreen); - rep.pad = 0; - - if (pScrPriv) - RRGetInfo (pScreen); - - if (!pScrPriv) - { - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nCrtcs = 0; - rep.nOutputs = 0; - rep.nModes = 0; - rep.nbytesNames = 0; - extra = NULL; - extraLen = 0; - } - else - { - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; - rep.nCrtcs = pScrPriv->numCrtcs; - rep.nOutputs = pScrPriv->numOutputs; - rep.nModes = pScrPriv->numModes;; - rep.nbytesNames = 0; - - for (i = 0; i < pScrPriv->numModes; i++) - rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength; - - rep.length = (pScrPriv->numCrtcs + - pScrPriv->numOutputs + - pScrPriv->numModes * 10 + - ((rep.nbytesNames + 3) >> 2)); - - extraLen = rep.length << 2; - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; - - crtcs = (RRCrtc *) extra; - outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); - modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); - names = (CARD8 *) (modeinfos + pScrPriv->numModes); - - for (i = 0; i < pScrPriv->numCrtcs; i++) - { - crtcs[i] = pScrPriv->crtcs[i]->id; - if (client->swapped) - swapl (&crtcs[i], n); - } - - for (i = 0; i < pScrPriv->numOutputs; i++) - { - outputs[i] = pScrPriv->outputs[i]->id; - if (client->swapped) - swapl (&outputs[i], n); - } - - for (i = 0; i < pScrPriv->numModes; i++) - { - modeinfos[i] = pScrPriv->modes[i]->mode; - if (client->swapped) - { - swapl (&modeinfos[i].id, n); - swaps (&modeinfos[i].width, n); - swaps (&modeinfos[i].height, n); - swapl (&modeinfos[i].mmWidth, n); - swapl (&modeinfos[i].mmHeight, n); - swapl (&modeinfos[i].dotClock, n); - swaps (&modeinfos[i].hSyncStart, n); - swaps (&modeinfos[i].hSyncEnd, n); - swaps (&modeinfos[i].hTotal, n); - swaps (&modeinfos[i].hSkew, n); - swaps (&modeinfos[i].vSyncStart, n); - swaps (&modeinfos[i].vSyncEnd, n); - swaps (&modeinfos[i].vTotal, n); - swaps (&modeinfos[i].nameLength, n); - swapl (&modeinfos[i].modeFlags, n); - } - memcpy (names, pScrPriv->modes[i]->name, - pScrPriv->modes[i]->mode.nameLength); - names += pScrPriv->modes[i]->mode.nameLength; - } - assert ((names + 3 >> 3) == rep.length); - } - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swapl(&rep.configTimestamp, n); - swaps(&rep.nCrtcs, n); - swaps(&rep.nOutputs, n); - swaps(&rep.nModes, n); - swaps(&rep.nbytesNames, n); - } - WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - return client->noClientException; -} - -static int -ProcRRGetOutputInfo (ClientPtr client) -{ - REQUEST(xRRGetOutputInfoReq);; - xRRGetOutputInfoReply rep; - RROutputPtr output; - CARD8 *extra; - unsigned long extraLen; - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; - RRCrtc *crtcs; - RRMode *modes; - RROutput *clones; - char *name; - int i, n; - - REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); - output = (RROutputPtr)SecurityLookupIDByType(client, stuff->output, - RROutputType, - SecurityReadAccess); - - if (!output) - return RRErrorBase + BadRROutput; - - pScreen = output->pScreen; - pScrPriv = rrGetScrPriv(pScreen); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.timestamp = pScrPriv->lastSetTime.milliseconds; - rep.crtc = output->crtc ? output->crtc->id : None; - rep.connection = output->connection; - rep.subpixelOrder = output->subpixelOrder; - rep.nCrtcs = output->numCrtcs; - rep.nModes = output->numModes; - rep.nClones = output->numClones; - rep.nameLength = output->nameLength; - - rep.length = (output->numCrtcs + - output->numModes + - output->numClones + - ((rep.nameLength + 3) >> 2)); - - extraLen = rep.length << 2; - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; - - crtcs = (RRCrtc *) extra; - modes = (RRMode *) (crtcs + output->numCrtcs); - clones = (RROutput *) (modes + output->numModes); - name = (char *) (clones + output->numClones); - - for (i = 0; i < output->numCrtcs; i++) - { - crtcs[i] = output->crtcs[i]->id; - if (client->swapped) - swapl (&crtcs[i], n); - } - for (i = 0; i < output->numModes; i++) - { - modes[i] = output->modes[i]->mode.id; - if (client->swapped) - swapl (&modes[i], n); - } - for (i = 0; i < output->numClones; i++) - { - clones[i] = output->clones[i]->id; - if (client->swapped) - swapl (&clones[i], n); - } - memcpy (name, output->name, output->nameLength); - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.timestamp, n); - swapl(&rep.crtc, n); - swaps(&rep.nCrtcs, n); - swaps(&rep.nModes, n); - swaps(&rep.nClones, n); - swaps(&rep.nameLength, n); - } - WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); - if (extraLen) - { - WriteToClient (client, extraLen, (char *) extra); - xfree (extra); - } - - return client->noClientException; -} - -static int -ProcRRListOutputProperties (ClientPtr client) -{ - REQUEST(xRRListOutputPropertiesReq); - - REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRChangeOutputProperty (ClientPtr client) -{ - REQUEST(xRRChangeOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRChangeOutputPropertyReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRDeleteOutputProperty (ClientPtr client) -{ - REQUEST(xRRDeleteOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRGetOutputProperty (ClientPtr client) -{ - REQUEST(xRRGetOutputPropertyReq); - - REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRCreateMode (ClientPtr client) -{ - REQUEST(xRRCreateModeReq); - - REQUEST_SIZE_MATCH(xRRCreateModeReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRDestroyMode (ClientPtr client) -{ - REQUEST(xRRDestroyModeReq); - - REQUEST_SIZE_MATCH(xRRDestroyModeReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRAddOutputMode (ClientPtr client) -{ - REQUEST(xRRAddOutputModeReq); - - REQUEST_SIZE_MATCH(xRRAddOutputModeReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRDeleteOutputMode (ClientPtr client) -{ - REQUEST(xRRDeleteOutputModeReq); - - REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRGetCrtcInfo (ClientPtr client) -{ - REQUEST(xRRGetCrtcInfoReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq); - (void) stuff; - return BadImplementation; -} - -static 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 i, j; - - REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); - - crtc = LookupIDByType (stuff->crtc, RRCrtcType); - if (!crtc) - { - client->errorValue = stuff->crtc; - return RRErrorBase + BadRRCrtc; - } - if (stuff->mode == None) - { - mode = NULL; - if (numOutputs > 0) - return BadMatch; - } - else - { - mode = LookupIDByType (stuff->mode, RRModeType); - if (!mode) - { - client->errorValue = stuff->mode; - return RRErrorBase + BadRRMode; - } - if (numOutputs == 0) - return BadMatch; - } - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); - if (!outputs) - return BadAlloc; - - outputIds = (RROutput *) (stuff + 1); - for (i = 0; i < numOutputs; i++) - { - outputs[i] = LookupIDByType (outputIds[i], RROutputType); - if (!outputs[i]) - { - client->errorValue = outputIds[i]; - return RRErrorBase + BadRROutput; - } - /* validate crtc for this output */ - for (j = 0; j < outputs[i]->numCrtcs; j++) - if (outputs[i]->crtcs[j] == crtc) - break; - if (j == outputs[j]->numCrtcs) - return BadMatch; - /* validate mode for this output */ - for (j = 0; j < outputs[i]->numModes; j++) - if (outputs[i]->modes[j] == mode) - break; - if (j == outputs[j]->numModes) - 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; - } - if (!RRGetInfo (pScreen)) - return BadAlloc; - - /* - * if the client's config timestamp is not the same as the last config - * timestamp, then the config information isn't up-to-date and - * can't even be validated - */ - if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) - { - rep.status = RRSetConfigInvalidConfigTime; - 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; - return BadValue; - } - - if ((~crtc->rotations) & rotation) - { - /* - * requested rotation or reflection not supported by screen - */ - client->errorValue = stuff->rotation; - return BadMatch; - } - - if (stuff->x + mode->mode.width > pScreen->width) - { - client->errorValue = stuff->x; - return BadValue; - } - - if (stuff->y + mode->mode.height > pScreen->height) - { - client->errorValue = stuff->y; - return BadValue; - } - - /* - * Make sure the requested set-time is not older than - * the last set-time - */ - if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) - { - rep.status = RRSetConfigInvalidTime; - goto sendReply; - } - - rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y, - rotation, numOutputs, outputs); - -sendReply: - if (outputs) - xfree (outputs); - - rep.type = X_Reply; - /* rep.status has already been filled in */ - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.newTimestamp = pScrPriv->lastConfigTime.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 client->noClientException; -} - -static int -ProcRRGetCrtcGammaSize (ClientPtr client) -{ - REQUEST(xRRGetCrtcGammaSizeReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRGetCrtcGamma (ClientPtr client) -{ - REQUEST(xRRGetCrtcGammaReq); - - REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq); - (void) stuff; - return BadImplementation; -} - -static int -ProcRRSetCrtcGamma (ClientPtr client) -{ - REQUEST(xRRSetCrtcGammaReq); - - REQUEST_SIZE_MATCH(xRRSetCrtcGammaReq); - (void) stuff; - return BadImplementation; -} - int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRQueryVersion, /* 0 */ /* we skip 1 to make old clients fail pretty immediately */ diff --git a/randr/rrmode.c b/randr/rrmode.c index 4e44e7d82..ab0ea18d9 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -103,3 +103,44 @@ RRModeInit (void) #endif return TRUE; } + +int +ProcRRCreateMode (ClientPtr client) +{ + REQUEST(xRRCreateModeReq); + + REQUEST_SIZE_MATCH(xRRCreateModeReq); + (void) stuff; + return BadImplementation; +} + +int +ProcRRDestroyMode (ClientPtr client) +{ + REQUEST(xRRDestroyModeReq); + + REQUEST_SIZE_MATCH(xRRDestroyModeReq); + (void) stuff; + return BadImplementation; +} + +int +ProcRRAddOutputMode (ClientPtr client) +{ + REQUEST(xRRAddOutputModeReq); + + REQUEST_SIZE_MATCH(xRRAddOutputModeReq); + (void) stuff; + return BadImplementation; +} + +int +ProcRRDeleteOutputMode (ClientPtr client) +{ + REQUEST(xRRDeleteOutputModeReq); + + REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq); + (void) stuff; + return BadImplementation; +} + diff --git a/randr/rroutput.c b/randr/rroutput.c index 478002300..07dabad2e 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -66,6 +66,7 @@ RROutputCreate (ScreenPtr pScreen, output->clones = NULL; output->numModes = 0; output->modes = NULL; + output->properties = NULL; output->changed = TRUE; output->devPrivate = devPrivate; @@ -201,12 +202,13 @@ RROutputDestroyResource (pointer value, XID pid) xfree (output->crtcs); if (output->clones) xfree (output->clones); + RRDeleteAllOutputProperties (output); xfree (output); return 1; } /* - * Initialize crtc type + * Initialize output type */ Bool RROutputInit (void) @@ -219,3 +221,95 @@ RROutputInit (void) #endif return TRUE; } + +int +ProcRRGetOutputInfo (ClientPtr client) +{ + REQUEST(xRRGetOutputInfoReq);; + xRRGetOutputInfoReply rep; + RROutputPtr output; + CARD8 *extra; + unsigned long extraLen; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtc *crtcs; + RRMode *modes; + RROutput *clones; + char *name; + int i, n; + + REQUEST_SIZE_MATCH(xRRGetOutputInfoReq); + output = LookupOutput(client, stuff->output, SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + pScreen = output->pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.crtc = output->crtc ? output->crtc->id : None; + rep.connection = output->connection; + rep.subpixelOrder = output->subpixelOrder; + rep.nCrtcs = output->numCrtcs; + rep.nModes = output->numModes; + rep.nClones = output->numClones; + rep.nameLength = output->nameLength; + + rep.length = (output->numCrtcs + + output->numModes + + output->numClones + + ((rep.nameLength + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + modes = (RRMode *) (crtcs + output->numCrtcs); + clones = (RROutput *) (modes + output->numModes); + name = (char *) (clones + output->numClones); + + for (i = 0; i < output->numCrtcs; i++) + { + crtcs[i] = output->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + for (i = 0; i < output->numModes; i++) + { + modes[i] = output->modes[i]->mode.id; + if (client->swapped) + swapl (&modes[i], n); + } + for (i = 0; i < output->numClones; i++) + { + clones[i] = output->clones[i]->id; + if (client->swapped) + swapl (&clones[i], n); + } + memcpy (name, output->name, output->nameLength); + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.crtc, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nModes, n); + swaps(&rep.nClones, n); + swaps(&rep.nameLength, n); + } + WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + + return client->noClientException; +} + diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 47ba12d39..58d5152d0 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -203,3 +203,654 @@ RRScreenSizeSet (ScreenPtr pScreen, return FALSE; } +/* + * Retrieve valid screen size range + */ +int +ProcRRGetScreenSizeRange (ClientPtr client) +{ + REQUEST(xRRGetScreenSizeRangeReq); + xRRGetScreenSizeRangeReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + + rep.type = X_Reply; + rep.pad = 0; + rep.sequenceNumber = client->sequence; + rep.length = 0; + + if (pScrPriv) + { + RRGetInfo (pScreen); + rep.minWidth = pScrPriv->minWidth; + rep.minHeight = pScrPriv->minHeight; + rep.maxWidth = pScrPriv->maxWidth; + rep.maxHeight = pScrPriv->maxHeight; + } + else + { + rep.maxWidth = rep.minWidth = pScreen->width; + rep.maxHeight = rep.minHeight = pScreen->height; + } + if (client->swapped) + { + int n; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.minWidth, n); + swaps(&rep.minHeight, n); + swaps(&rep.maxWidth, n); + swaps(&rep.maxHeight, n); + } + WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRSetScreenSize (ClientPtr client) +{ + REQUEST(xRRSetScreenSizeReq); + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + RRCrtcPtr crtc; + int i; + + REQUEST_SIZE_MATCH(xRRSetScreenSizeReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) + { + client->errorValue = stuff->width; + return BadValue; + } + if (stuff->height < pScrPriv->minHeight || + pScrPriv->maxHeight < stuff->height) + { + client->errorValue = stuff->height; + return BadValue; + } + for (i = 0; i < pScrPriv->numCrtcs; i++) { + crtc = pScrPriv->crtcs[i]; + if (crtc->mode && + (crtc->x + crtc->mode->mode.width > stuff->width || + crtc->y + crtc->mode->mode.height > stuff->height)) + return BadMatch; + } + if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) + { + client->errorValue = 0; + return BadValue; + } + if (!RRScreenSizeSet (pScreen, + stuff->width, stuff->height, + stuff->widthInMillimeters, + stuff->heightInMillimeters)) + { + return BadMatch; + } + return Success; +} + +int +ProcRRGetScreenResources (ClientPtr client) +{ + REQUEST(xRRGetScreenResourcesReq); + xRRGetScreenResourcesReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + int i; + RRCrtc *crtcs; + RROutput *outputs; + xRRModeInfo *modeinfos; + CARD8 *names; + int n; + + REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + if (!pScrPriv) + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = 0; + rep.nOutputs = 0; + rep.nModes = 0; + rep.nbytesNames = 0; + extra = NULL; + extraLen = 0; + } + else + { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nCrtcs = pScrPriv->numCrtcs; + rep.nOutputs = pScrPriv->numOutputs; + rep.nModes = pScrPriv->numModes;; + rep.nbytesNames = 0; + + for (i = 0; i < pScrPriv->numModes; i++) + rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength; + + rep.length = (pScrPriv->numCrtcs + + pScrPriv->numOutputs + + pScrPriv->numModes * 10 + + ((rep.nbytesNames + 3) >> 2)); + + extraLen = rep.length << 2; + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + + crtcs = (RRCrtc *) extra; + outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); + modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); + names = (CARD8 *) (modeinfos + pScrPriv->numModes); + + for (i = 0; i < pScrPriv->numCrtcs; i++) + { + crtcs[i] = pScrPriv->crtcs[i]->id; + if (client->swapped) + swapl (&crtcs[i], n); + } + + for (i = 0; i < pScrPriv->numOutputs; i++) + { + outputs[i] = pScrPriv->outputs[i]->id; + if (client->swapped) + swapl (&outputs[i], n); + } + + for (i = 0; i < pScrPriv->numModes; i++) + { + modeinfos[i] = pScrPriv->modes[i]->mode; + if (client->swapped) + { + swapl (&modeinfos[i].id, n); + swaps (&modeinfos[i].width, n); + swaps (&modeinfos[i].height, n); + swapl (&modeinfos[i].mmWidth, n); + swapl (&modeinfos[i].mmHeight, n); + swapl (&modeinfos[i].dotClock, n); + swaps (&modeinfos[i].hSyncStart, n); + swaps (&modeinfos[i].hSyncEnd, n); + swaps (&modeinfos[i].hTotal, n); + swaps (&modeinfos[i].hSkew, n); + swaps (&modeinfos[i].vSyncStart, n); + swaps (&modeinfos[i].vSyncEnd, n); + swaps (&modeinfos[i].vTotal, n); + swaps (&modeinfos[i].nameLength, n); + swapl (&modeinfos[i].modeFlags, n); + } + memcpy (names, pScrPriv->modes[i]->name, + pScrPriv->modes[i]->mode.nameLength); + names += pScrPriv->modes[i]->mode.nameLength; + } + assert ((names + 3 >> 3) == rep.length); + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swapl(&rep.configTimestamp, n); + swaps(&rep.nCrtcs, n); + swaps(&rep.nOutputs, n); + swaps(&rep.nModes, n); + swaps(&rep.nbytesNames, n); + } + WriteToClient(client, sizeof(xRRGetScreenResourcesReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return client->noClientException; +} + +typedef struct _RR10Data { + RRScreenSizePtr sizes; + int nsize; + int nrefresh; + int size; + CARD16 refresh; +} RR10DataRec, *RR10DataPtr; + +/* + * Convert 1.2 monitor data into 1.0 screen data + */ +static RR10DataPtr +RR10GetData (ScreenPtr pScreen, RROutputPtr output) +{ + RR10DataPtr data; + RRScreenSizePtr size; + int nmode = output->numModes; + int i, j, k; + RRScreenRatePtr refresh; + CARD16 vRefresh; + RRModePtr mode; + + /* Make sure there is plenty of space for any combination */ + data = malloc (sizeof (RR10DataRec) + + sizeof (RRScreenSize) * nmode + + sizeof (RRScreenRate) * nmode); + if (!data) + return NULL; + size = (RRScreenSizePtr) (data + 1); + refresh = (RRScreenRatePtr) (size + nmode); + data->sizes = size; + data->nsize = 0; + data->nrefresh = 0; + data->size = 0; + data->refresh = 0; + for (i = 0; i < output->numModes; i++) + { + mode = output->modes[i]; + for (j = 0; j < data->nsize; j++) + if (mode->mode.width == size[j].width && + mode->mode.height == size[j].height) + break; + if (j == data->nsize) + { + size[j].id = j; + size[j].width = mode->mode.width; + size[j].height = mode->mode.height; + size[j].mmWidth = mode->mode.mmWidth; + size[j].mmHeight = mode->mode.mmHeight; + size[j].nRates = 0; + size[j].pRates = &refresh[data->nrefresh]; + data->nsize++; + } + vRefresh = RRVerticalRefresh (&mode->mode); + for (k = 0; k < size[j].nRates; k++) + if (vRefresh == size[j].pRates[k].rate) + break; + if (k == size[j].nRates) + { + size[j].pRates[k].rate = vRefresh; + size[j].pRates[k].mode = mode; + size[j].nRates++; + data->nrefresh++; + } + if (mode == output->crtc->mode) + { + data->size = j; + data->refresh = vRefresh; + } + } + return data; +} + +int +ProcRRGetScreenInfo (ClientPtr client) +{ + REQUEST(xRRGetScreenInfoReq); + xRRGetScreenInfoReply rep; + WindowPtr pWin; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + CARD8 *extra; + unsigned long extraLen; + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client, + SecurityReadAccess); + + if (!pWin) + return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + rep.pad = 0; + + if (pScrPriv) + RRGetInfo (pScreen); + + output = RRFirstOutput (pScreen); + + if (!pScrPriv || !output) + { + rep.type = X_Reply; + rep.setOfRotations = RR_Rotate_0;; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = currentTime.milliseconds; + rep.configTimestamp = currentTime.milliseconds; + rep.nSizes = 0; + rep.sizeID = 0; + rep.rotation = RR_Rotate_0; + rep.rate = 0; + rep.nrateEnts = 0; + extra = 0; + extraLen = 0; + } + else + { + int i, j; + xScreenSizes *size; + CARD16 *rates; + CARD8 *data8; + Bool has_rate = RRClientKnowsRates (client); + RR10DataPtr pData; + RRScreenSizePtr pSize; + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + rep.type = X_Reply; + rep.setOfRotations = output->crtc->rotations; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.rotation = output->crtc->rotation; + rep.nSizes = pData->nsize; + rep.nrateEnts = pData->nrefresh + pData->nsize; + rep.sizeID = pData->size; + rep.rate = pData->refresh; + + extraLen = (rep.nSizes * sizeof (xScreenSizes) + + rep.nrateEnts * sizeof (CARD16)); + + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } + /* + * First comes the size information + */ + size = (xScreenSizes *) extra; + rates = (CARD16 *) (size + rep.nSizes); + for (i = 0; i < pData->nsize; i++) + { + pSize = &pData->sizes[i]; + size->widthInPixels = pSize->width; + size->heightInPixels = pSize->height; + size->widthInMillimeters = pSize->mmWidth; + size->heightInMillimeters = pSize->mmHeight; + if (client->swapped) + { + swaps (&size->widthInPixels, n); + swaps (&size->heightInPixels, n); + swaps (&size->widthInMillimeters, n); + swaps (&size->heightInMillimeters, n); + } + size++; + if (has_rate) + { + *rates = pSize->nRates; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + for (j = 0; j < pSize->nRates; j++) + { + *rates = pSize->pRates[j].rate; + if (client->swapped) + { + swaps (rates, n); + } + rates++; + } + } + } + xfree (pData); + + data8 = (CARD8 *) rates; + + if (data8 - (CARD8 *) extra != extraLen) + FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n", + (unsigned long)(data8 - (CARD8 *) extra), extraLen); + rep.length = (extraLen + 3) >> 2; + } + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.timestamp, n); + swaps(&rep.rotation, n); + swaps(&rep.nSizes, n); + swaps(&rep.sizeID, n); + swaps(&rep.rate, n); + swaps(&rep.nrateEnts, n); + } + WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep); + if (extraLen) + { + WriteToClient (client, extraLen, (char *) extra); + xfree (extra); + } + return (client->noClientException); +} + +int +ProcRRSetScreenConfig (ClientPtr client) +{ + REQUEST(xRRSetScreenConfigReq); + xRRSetScreenConfigReply rep; + DrawablePtr pDraw; + int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + TimeStamp configTime; + TimeStamp time; + int i; + Rotation rotation; + int rate; + Bool has_rate; + RROutputPtr output; + RRModePtr mode; + RR10DataPtr pData = NULL; + RRScreenSizePtr pSize; + + UpdateCurrentTime (); + + if (RRClientKnowsRates (client)) + { + REQUEST_SIZE_MATCH (xRRSetScreenConfigReq); + has_rate = TRUE; + } + else + { + REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq); + has_rate = FALSE; + } + + SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client, + SecurityWriteAccess); + + pScreen = pDraw->pScreen; + + pScrPriv = rrGetScrPriv(pScreen); + + time = ClientTimeToServerTime(stuff->timestamp); + configTime = ClientTimeToServerTime(stuff->configTimestamp); + + if (!pScrPriv) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + if (!RRGetInfo (pScreen)) + return BadAlloc; + + output = RRFirstOutput (pScreen); + if (!output) + { + time = currentTime; + rep.status = RRSetConfigFailed; + goto sendReply; + } + + /* + * if the client's config timestamp is not the same as the last config + * timestamp, then the config information isn't up-to-date and + * can't even be validated + */ + if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0) + { + rep.status = RRSetConfigInvalidConfigTime; + goto sendReply; + } + + pData = RR10GetData (pScreen, output); + if (!pData) + return BadAlloc; + + if (stuff->sizeID >= pData->nsize) + { + /* + * Invalid size ID + */ + client->errorValue = stuff->sizeID; + xfree (pData); + return BadValue; + } + pSize = &pData->sizes[stuff->sizeID]; + + /* + * 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; + xfree (pData); + return BadValue; + } + + if ((~output->crtc->rotations) & rotation) + { + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; + xfree (pData); + return BadMatch; + } + + /* + * Validate requested refresh + */ + if (has_rate) + rate = (int) stuff->rate; + else + rate = 0; + + if (rate) + { + for (i = 0; i < pSize->nRates; i++) + { + if (pSize->pRates[i].rate == rate) + break; + } + if (i == pSize->nRates) + { + /* + * Invalid rate + */ + client->errorValue = rate; + xfree (pData); + return BadValue; + } + mode = pSize->pRates[i].mode; + } + else + mode = pSize->pRates[0].mode; + + /* + * Make sure the requested set-time is not older than + * the last set-time + */ + if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0) + { + rep.status = RRSetConfigInvalidTime; + goto sendReply; + } + + rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + 1, &output); + +sendReply: + + if (pData) + xfree (pData); + + rep.type = X_Reply; + /* rep.status has already been filled in */ + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rep.newTimestamp = pScrPriv->lastSetTime.milliseconds; + rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds; + rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id; + + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.newTimestamp, n); + swapl(&rep.newConfigTimestamp, n); + swapl(&rep.root, n); + } + WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep); + + return (client->noClientException); +} + -- cgit v1.2.3 From d08718d8fd31477e90f13b9e122504c515b46ee0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 12:05:52 -0700 Subject: Avoid calling xalloc(0). Change rrScreenSizeSet to rrScreenSetSize. --- randr/randr.c | 2 +- randr/randrstr.h | 6 +++--- randr/rrcrtc.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------- randr/rrmode.c | 2 +- randr/rroutput.c | 46 +++++++++++++++++++++++++++++++++------------- randr/rrscreen.c | 29 ++++++++++++++++++++--------- 6 files changed, 98 insertions(+), 43 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 5f6ef62e4..5f54dea14 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -198,7 +198,7 @@ Bool RRScreenInit(ScreenPtr pScreen) pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height; #if RANDR_12_INTERFACE - pScrPriv->rrScreenSizeSet = NULL; + pScrPriv->rrScreenSetSize = NULL; pScrPriv->rrCrtcSet = NULL; pScrPriv->rrCrtcSetGamma = NULL; #endif diff --git a/randr/randrstr.h b/randr/randrstr.h index 26c180697..80272623c 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -174,7 +174,7 @@ typedef struct _rrScrPriv { #endif RRGetInfoProcPtr rrGetInfo; #if RANDR_12_INTERFACE - RRScreenSetSizeProcPtr rrScreenSizeSet; + RRScreenSetSizeProcPtr rrScreenSetSize; RRCrtcSetProcPtr rrCrtcSet; RRCrtcSetGammaProcPtr rrCrtcSetGamma; #endif @@ -521,7 +521,7 @@ RRClientKnowsRates (ClientPtr pClient); RRModePtr RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, - char *name); + const char *name); /* * Destroy a mode. @@ -555,7 +555,7 @@ ProcRRDeleteOutputMode (ClientPtr client); RROutputPtr RROutputCreate (ScreenPtr pScreen, - char *name, + const char *name, int nameLength, void *devPrivate); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index c55e08871..90d609ed0 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -94,13 +94,22 @@ RRCrtcNotify (RRCrtcPtr crtc, { RROutputPtr *outputs; - if (crtc->numOutputs) - outputs = xrealloc (crtc->outputs, - numOutputs * sizeof (RROutputPtr)); + if (numOutputs) + { + if (crtc->numOutputs) + outputs = xrealloc (crtc->outputs, + numOutputs * sizeof (RROutputPtr)); + else + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return FALSE; + } else - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); - if (!outputs) - return FALSE; + { + if (crtc->outputs) + xfree (crtc->outputs); + outputs = NULL; + } crtc->outputs = outputs; } for (i = 0; i < numOutputs; i++) @@ -300,9 +309,14 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc, if (size == crtc->gammaSize) return TRUE; - gamma = xalloc (size * 3 * sizeof (CARD16)); - if (!gamma) - return FALSE; + if (size) + { + gamma = xalloc (size * 3 * sizeof (CARD16)); + if (!gamma) + return FALSE; + } + else + gamma = NULL; if (crtc->gammaRed) xfree (crtc->gammaRed); crtc->gammaRed = gamma; @@ -376,9 +390,14 @@ ProcRRGetCrtcInfo (ClientPtr client) rep.length = rep.nOutput + rep.nPossibleOutput; extraLen = rep.length << 2; - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; outputs = (RROutput *) extra; possible = (RROutput *) (outputs + rep.nOutput); @@ -467,9 +486,14 @@ ProcRRSetCrtcConfig (ClientPtr client) if (numOutputs == 0) return BadMatch; } - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); - if (!outputs) - return BadAlloc; + if (numOutputs) + { + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!outputs) + return BadAlloc; + } + else + outputs = NULL; outputIds = (RROutput *) (stuff + 1); for (i = 0; i < numOutputs; i++) @@ -574,7 +598,7 @@ ProcRRSetCrtcConfig (ClientPtr client) * for setting screen size. Else, assume the CrtcSet sets * the size along with the mode */ - if (pScrPriv->rrScreenSizeSet) + if (pScrPriv->rrScreenSetSize) { if (stuff->x + mode->mode.width > pScreen->width) { diff --git a/randr/rrmode.c b/randr/rrmode.c index ab0ea18d9..23ac5305c 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -27,7 +27,7 @@ RESTYPE RRModeType; RRModePtr RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, - char *name) + const char *name) { rrScrPriv (pScreen); int i; diff --git a/randr/rroutput.c b/randr/rroutput.c index 07dabad2e..3d4c16342 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -30,7 +30,7 @@ RESTYPE RROutputType; RROutputPtr RROutputCreate (ScreenPtr pScreen, - char *name, + const char *name, int nameLength, void *devPrivate) { @@ -89,9 +89,14 @@ RROutputSetClones (RROutputPtr output, { RROutputPtr *newClones; - newClones = xalloc (numClones * sizeof (RROutputPtr)); - if (!newClones) - return FALSE; + if (numClones) + { + newClones = xalloc (numClones * sizeof (RROutputPtr)); + if (!newClones) + return FALSE; + } + else + newClones = NULL; if (output->clones) xfree (output->clones); memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); @@ -108,9 +113,14 @@ RROutputSetModes (RROutputPtr output, { RRModePtr *newModes; - newModes = xalloc (numModes * sizeof (RRModePtr)); - if (!newModes) - return FALSE; + if (numModes) + { + newModes = xalloc (numModes * sizeof (RRModePtr)); + if (!newModes) + return FALSE; + } + else + newModes = NULL; if (output->modes) xfree (output->modes); memcpy (newModes, modes, numModes * sizeof (RRModePtr)); @@ -127,9 +137,14 @@ RROutputSetCrtcs (RROutputPtr output, { RRCrtcPtr *newCrtcs; - newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); - if (!newCrtcs) - return FALSE; + if (numCrtcs) + { + newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); + if (!newCrtcs) + return FALSE; + } + else + newCrtcs = NULL; if (output->crtcs) xfree (output->crtcs); memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); @@ -265,9 +280,14 @@ ProcRRGetOutputInfo (ClientPtr client) ((rep.nameLength + 3) >> 2)); extraLen = rep.length << 2; - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; crtcs = (RRCrtc *) extra; modes = (RRMode *) (crtcs + output->numCrtcs); diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 58d5152d0..617ae4109 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -187,9 +187,9 @@ RRScreenSizeSet (ScreenPtr pScreen, rrScrPriv(pScreen); #if RANDR_12_INTERFACE - if (pScrPriv->rrScreenSizeSet) + if (pScrPriv->rrScreenSetSize) { - return (*pScrPriv->rrScreenSizeSet) (pScreen, + return (*pScrPriv->rrScreenSetSize) (pScreen, width, height, mmWidth, mmHeight); } @@ -376,9 +376,14 @@ ProcRRGetScreenResources (ClientPtr client) ((rep.nbytesNames + 3) >> 2)); extraLen = rep.length << 2; - extra = xalloc (extraLen); - if (!extra) - return BadAlloc; + if (extraLen) + { + extra = xalloc (extraLen); + if (!extra) + return BadAlloc; + } + else + extra = NULL; crtcs = (RRCrtc *) extra; outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); @@ -595,12 +600,18 @@ ProcRRGetScreenInfo (ClientPtr client) extraLen = (rep.nSizes * sizeof (xScreenSizes) + rep.nrateEnts * sizeof (CARD16)); - extra = (CARD8 *) xalloc (extraLen); - if (!extra) + if (extraLen) { - xfree (pData); - return BadAlloc; + extra = (CARD8 *) xalloc (extraLen); + if (!extra) + { + xfree (pData); + return BadAlloc; + } } + else + extra = NULL; + /* * First comes the size information */ -- cgit v1.2.3 From 9f870e0aa1ada238d6a0cd099996e8c47f6ba1d9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 13:14:53 -0700 Subject: When setting output state, leave output unchanged when setting to current. --- randr/randrstr.h | 1 + randr/rroutput.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/randr/randrstr.h b/randr/randrstr.h index 80272623c..e459452ff 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -77,6 +77,7 @@ struct _rrMode { int refcnt; xRRModeInfo mode; char *name; + void *devPrivate; }; struct _rrCrtc { diff --git a/randr/rroutput.c b/randr/rroutput.c index 3d4c16342..a4f5a66dd 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -88,7 +88,16 @@ RROutputSetClones (RROutputPtr output, int numClones) { RROutputPtr *newClones; + int i; + if (numClones == output->numClones) + { + for (i = 0; i < numClones; i++) + if (output->clones[i] != clones[i]) + break; + if (i == numClones) + return TRUE; + } if (numClones) { newClones = xalloc (numClones * sizeof (RROutputPtr)); @@ -112,6 +121,20 @@ RROutputSetModes (RROutputPtr output, int numModes) { RRModePtr *newModes; + int i; + + if (numModes == output->numModes) + { + for (i = 0; i < numModes; i++) + if (output->modes[i] != modes[i]) + break; + if (i == numModes) + { + for (i = 0; i < numModes; i++) + RRModeDestroy (modes[i]); + return TRUE; + } + } if (numModes) { @@ -122,7 +145,11 @@ RROutputSetModes (RROutputPtr output, else newModes = NULL; if (output->modes) + { + for (i = 0; i < output->numModes; i++) + RRModeDestroy (output->modes[i]); xfree (output->modes); + } memcpy (newModes, modes, numModes * sizeof (RRModePtr)); output->modes = newModes; output->numModes = numModes; @@ -136,7 +163,16 @@ RROutputSetCrtcs (RROutputPtr output, int numCrtcs) { RRCrtcPtr *newCrtcs; + int i; + if (numCrtcs == output->numCrtcs) + { + for (i = 0; i < numCrtcs; i++) + if (output->crtcs[i] != crtcs[i]) + break; + if (i == numCrtcs) + return TRUE; + } if (numCrtcs) { newCrtcs = xalloc (numCrtcs * sizeof (RRCrtcPtr)); @@ -157,6 +193,8 @@ RROutputSetCrtcs (RROutputPtr output, void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) { + if (output->crtc == crtc) + return TRUE; output->crtc = crtc; output->changed = TRUE; } @@ -165,6 +203,8 @@ Bool RROutputSetConnection (RROutputPtr output, CARD8 connection) { + if (output->connection == connection) + return TRUE; output->connection = connection; output->changed = TRUE; return TRUE; @@ -174,6 +214,9 @@ Bool RROutputSetSubpixelOrder (RROutputPtr output, int subpixelOrder) { + if (output->subpixelOrder == subpixelOrder) + return TRUE; + output->subpixelOrder = subpixelOrder; output->changed = TRUE; return TRUE; -- cgit v1.2.3 From 09f7499851bd2f2eba1e30460c61c7a82ed9e853 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 13:15:20 -0700 Subject: typo --- randr/rroutput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/randr/rroutput.c b/randr/rroutput.c index a4f5a66dd..90b2b9856 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -194,7 +194,7 @@ void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) { if (output->crtc == crtc) - return TRUE; + return; output->crtc = crtc; output->changed = TRUE; } -- cgit v1.2.3 From bde0a4c12cb393a6d7f1552b067624da1b0502ae Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 19:42:34 -0700 Subject: RRSetCrtcConfig status fix. RRGetScreenResources timestamp fix. RRSetCrtcConfig was returning the wrong status values. RRGetScreenResources was always returning currentTime. --- randr/rrcrtc.c | 9 +++++++-- randr/rrscreen.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 90d609ed0..dfa9ca6ee 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -628,8 +628,13 @@ ProcRRSetCrtcConfig (ClientPtr client) goto sendReply; } - rep.status = RRCrtcSet (crtc, mode, stuff->x, stuff->y, - rotation, numOutputs, outputs); + if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y, + rotation, numOutputs, outputs)) + { + rep.status = RRSetConfigFailed; + goto sendReply; + } + rep.status = RRSetConfigSuccess; sendReply: if (outputs) diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 617ae4109..e59947b36 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -360,8 +360,8 @@ ProcRRGetScreenResources (ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; - rep.timestamp = currentTime.milliseconds; - rep.configTimestamp = currentTime.milliseconds; + rep.timestamp = pScrPriv->lastSetTime.milliseconds; + rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; rep.nCrtcs = pScrPriv->numCrtcs; rep.nOutputs = pScrPriv->numOutputs; rep.nModes = pScrPriv->numModes;; -- cgit v1.2.3 From 219546fd76750f358ffb6738f17b9237c58c15a6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Sep 2006 22:43:05 -0700 Subject: Steal Xinerama code from SiS driver. Add missing files. Provide a Xinerama implementation when DIX version isn't enabled. This version exposes each crtc as a separate 'screen' and reports the size of that patch. The extension also sends ConfigureNotify events to the root window whenever crtcs change so that applications will re-fetch xinerama information. This actually works for metacity. --- randr/Makefile.am | 3 +- randr/randr.c | 2 +- randr/randrstr.h | 10 ++ randr/rrcrtc.c | 5 + randr/rrinfo.c | 337 +++++++++++++++++++++++++++++++++++++++++ randr/rrproperty.c | 430 +++++++++++++++++++++++++++++++++++++++++++++++++++++ randr/rrscreen.c | 2 +- randr/rrxinerama.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1210 insertions(+), 3 deletions(-) create mode 100644 randr/rrinfo.c create mode 100644 randr/rrproperty.c create mode 100644 randr/rrxinerama.c diff --git a/randr/Makefile.am b/randr/Makefile.am index a28ead0eb..91c4bc6dd 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -17,4 +17,5 @@ librandr_la_SOURCES = \ rroutput.c \ rrproperty.c \ rrscreen.c \ - rrsdispatch.c + rrsdispatch.c \ + rrxinerama.c diff --git a/randr/randr.c b/randr/randr.c index 5f54dea14..4ea72e505 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -311,7 +311,7 @@ RRExtensionInit (void) EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr) SRRNotifyEvent; - return; + RRXineramaExtensionInit(); } static int diff --git a/randr/randrstr.h b/randr/randrstr.h index e459452ff..0b8c61e1f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -304,6 +304,12 @@ RRScreenSizeSet (ScreenPtr pScreen, CARD32 mmWidth, CARD32 mmHeight); +/* + * Send ConfigureNotify event to root window when 'something' happens + */ +void +RRSendConfigNotify (ScreenPtr pScreen); + /* * screen dispatch */ @@ -629,4 +635,8 @@ ProcRRListOutputProperties (ClientPtr client); int ProcRRDeleteOutputProperty (ClientPtr client); +/* rrxinerama.c */ +void +RRXineramaExtensionInit(void); + #endif /* _RANDRSTR_H_ */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index dfa9ca6ee..ebb254068 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -111,6 +111,7 @@ RRCrtcNotify (RRCrtcPtr crtc, outputs = NULL; } crtc->outputs = outputs; + crtc->numOutputs = numOutputs; } for (i = 0; i < numOutputs; i++) { @@ -158,7 +159,11 @@ RRCrtcNotify (RRCrtcPtr crtc, crtc->changed = TRUE; } if (crtc->changed) + { + if (!pScrPriv->changed) + RRSendConfigNotify (pScreen); pScrPriv->changed = TRUE; + } return TRUE; } diff --git a/randr/rrinfo.c b/randr/rrinfo.c new file mode 100644 index 000000000..491ac218d --- /dev/null +++ b/randr/rrinfo.c @@ -0,0 +1,337 @@ +/* + * 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.mmWidth = size->mmWidth; + modeInfo.mmHeight = size->mmHeight; + modeInfo.hTotal = size->width; + modeInfo.vTotal = size->height; + modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * + (CARD32) refresh); + modeInfo.nameLength = strlen (name); + mode = RRModeGet (pScreen, &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 = xrealloc (output->modes, + (output->numModes + 1) * sizeof (RRModePtr)); + else + modes = xalloc (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; + 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); + RROutputSetCrtc (output, crtc); + RROutputSetConnection (output, RR_Connected); +#ifdef RENDER + RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); +#endif + } + + output = RRFirstOutput (pScreen); + if (!output) + return; + crtc = output->crtc; + + /* 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; + } + } + xfree (size->pRates); + } + else + { + mode = RROldModeAdd (output, size, 0); + if (i == pScrPriv->size) + newMode = mode; + } + } + if (pScrPriv->nSizes) + xfree (pScrPriv->pSizes); + pScrPriv->pSizes = NULL; + pScrPriv->nSizes = 0; + + /* find size bounds */ + for (i = 0; i < output->numModes; i++) + { + RRModePtr mode = output->modes[i]; + 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; + } + + if (minWidth != pScrPriv->minWidth) { + pScrPriv->minWidth = minWidth; pScrPriv->changed = TRUE; + } + if (maxWidth != pScrPriv->maxWidth) { + pScrPriv->maxWidth = maxWidth; pScrPriv->changed = TRUE; + } + if (minHeight != pScrPriv->minHeight) { + pScrPriv->minHeight = minHeight; pScrPriv->changed = TRUE; + } + if (maxHeight != pScrPriv->maxHeight) { + pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE; + } + + /* notice current mode */ + if (newMode) + RRCrtcNotify (output->crtc, newMode, 0, 0, pScrPriv->rotation, + 1, &output); +} +#endif + +/* + * Poll the driver for changed information + */ +Bool +RRGetInfo (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + Rotation rotations; + int i; + + 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; + + if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations)) + return FALSE; + +#if RANDR_10_INTERFACE + if (pScrPriv->nSizes) + RRScanOldConfig (pScreen, rotations); +#endif + RRTellChanged (pScreen); + return TRUE; +} + +#if RANDR_12_INTERFACE +/* + * 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; + pScrPriv->minWidth = minWidth; + pScrPriv->minHeight = minHeight; + pScrPriv->maxWidth = maxWidth; + pScrPriv->maxHeight = maxHeight; +} +#endif + +#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 = xrealloc (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 = xrealloc (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/randr/rrproperty.c b/randr/rrproperty.c new file mode 100644 index 000000000..cdafb5c9b --- /dev/null +++ b/randr/rrproperty.c @@ -0,0 +1,430 @@ +/* + * 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 "propertyst.h" +#include "swaprep.h" + +static void +RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask) +{ +} + +void +RRDeleteAllOutputProperties (RROutputPtr output) +{ + PropertyPtr prop, next; + xRROutputPropertyNotifyEvent event; + + for (prop = output->properties; prop; prop = next) + { + next = prop->next; + event.type = RREventBase + RRNotify; + event.subCode = RRNotify_OutputProperty; + event.output = output->id; + event.state = PropertyDelete; + event.atom = prop->propertyName; + event.timestamp = currentTime.milliseconds; + RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); + xfree(prop->data); + xfree(prop); + } +} + +void +RRDeleteOutputProperty (RROutputPtr output, Atom property) +{ + PropertyPtr prop, *prev; + xRROutputPropertyNotifyEvent event; + + for (prev = &output->properties; (prop = *prev); prev = &(prop->next)) + if (prop->propertyName == property) + break; + if (prop) + { + *prev = prop->next; + event.type = RREventBase + RRNotify; + event.subCode = RRNotify_OutputProperty; + event.output = output->id; + event.state = PropertyDelete; + event.atom = prop->propertyName; + event.timestamp = currentTime.milliseconds; + RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); + xfree(prop->data); + xfree(prop); + } +} + +int +RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type, + int format, int mode, unsigned long len, + pointer value, Bool sendevent) +{ + PropertyPtr prop; + xRROutputPropertyNotifyEvent event; + int sizeInBytes; + int totalSize; + pointer data; + + sizeInBytes = format >> 3; + totalSize = len * sizeInBytes; + + /* first see if property already exists */ + + for (prop = output->properties; prop; prop = prop->next) + if (prop->propertyName == property) + break; + + if (!prop) /* just add to list */ + { + prop = (PropertyPtr)xalloc(sizeof(PropertyRec)); + if (!prop) + return(BadAlloc); + data = (pointer)xalloc(totalSize); + if (!data && len) + { + xfree(prop); + return(BadAlloc); + } + prop->propertyName = property; + prop->type = type; + prop->format = format; + prop->data = data; + if (len) + memmove((char *)data, (char *)value, totalSize); + prop->size = len; + prop->next = output->properties; + output->properties = prop; + } + else + { + /* To append or prepend to a property the request format and type + must match those of the already defined property. The + existing format and type are irrelevant when using the mode + "PropModeReplace" since they will be written over. */ + + if ((format != prop->format) && (mode != PropModeReplace)) + return(BadMatch); + if ((prop->type != type) && (mode != PropModeReplace)) + return(BadMatch); + if (mode == PropModeReplace) + { + if (totalSize != prop->size * (prop->format >> 3)) + { + data = (pointer)xrealloc(prop->data, totalSize); + if (!data && len) + return(BadAlloc); + prop->data = data; + } + if (len) + memmove((char *)prop->data, (char *)value, totalSize); + prop->size = len; + prop->type = type; + prop->format = format; + } + else if (len == 0) + { + /* do nothing */ + } + else if (mode == PropModeAppend) + { + data = (pointer)xrealloc(prop->data, + sizeInBytes * (len + prop->size)); + if (!data) + return(BadAlloc); + prop->data = data; + memmove(&((char *)data)[prop->size * sizeInBytes], + (char *)value, + totalSize); + prop->size += len; + } + else if (mode == PropModePrepend) + { + data = (pointer)xalloc(sizeInBytes * (len + prop->size)); + if (!data) + return(BadAlloc); + memmove(&((char *)data)[totalSize], (char *)prop->data, + (int)(prop->size * sizeInBytes)); + memmove((char *)data, (char *)value, totalSize); + xfree(prop->data); + prop->data = data; + prop->size += len; + } + } + if (sendevent) + { + event.type = RREventBase + RRNotify; + event.subCode = RRNotify_OutputProperty; + event.output = output->id; + event.state = PropertyNewValue; + event.atom = prop->propertyName; + event.timestamp = currentTime.milliseconds; + RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); + } + return(Success); +} + +int +ProcRRListOutputProperties (ClientPtr client) +{ + REQUEST(xRRListOutputPropertiesReq); + Atom *pAtoms = NULL, *temppAtoms; + xRRListOutputPropertiesReply rep; + int numProps = 0; + RROutputPtr output; + PropertyPtr prop; + + REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq); + + output = LookupOutput (client, stuff->output, SecurityReadAccess); + + if (!output) + return RRErrorBase + BadRROutput; + + for (prop = output->properties; prop; prop = prop->next) + numProps++; + if (numProps) + if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom)))) + return(BadAlloc); + + rep.type = X_Reply; + rep.nProperties = numProps; + rep.length = (numProps * sizeof(Atom)) >> 2; + rep.sequenceNumber = client->sequence; + temppAtoms = pAtoms; + for (prop = output->properties; prop; prop = prop->next) + *temppAtoms++ = prop->propertyName; + + WriteReplyToClient(client, sizeof(xRRListOutputPropertiesReply), &rep); + if (numProps) + { + client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; + WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); + DEALLOCATE_LOCAL(pAtoms); + } + return(client->noClientException); +} + +int +ProcRRChangeOutputProperty (ClientPtr client) +{ + REQUEST(xRRChangeOutputPropertyReq); + RROutputPtr output; + char format, mode; + unsigned long len; + int sizeInBytes; + int totalSize; + int err; + + REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq); + UpdateCurrentTime(); + format = stuff->format; + mode = stuff->mode; + if ((mode != PropModeReplace) && (mode != PropModeAppend) && + (mode != PropModePrepend)) + { + client->errorValue = mode; + return BadValue; + } + if ((format != 8) && (format != 16) && (format != 32)) + { + client->errorValue = format; + return BadValue; + } + len = stuff->nUnits; + if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2)) + return BadLength; + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + REQUEST_FIXED_SIZE(xRRChangeOutputPropertyReq, totalSize); + + output = LookupOutput (client, stuff->output, SecurityWriteAccess); + if (!output) + return RRErrorBase + BadRROutput; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return(BadAtom); + } + if (!ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return(BadAtom); + } + + err = RRChangeOutputProperty(output, stuff->property, + stuff->type, (int)format, + (int)mode, len, (pointer)&stuff[1], TRUE); + if (err != Success) + return err; + else + return client->noClientException; +} + +int +ProcRRDeleteOutputProperty (ClientPtr client) +{ + REQUEST(xRRDeleteOutputPropertyReq); + RROutputPtr output; + + REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq); + UpdateCurrentTime(); + output = LookupOutput (client, stuff->output, SecurityWriteAccess); + if (!output) + return RRErrorBase + BadRROutput; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return (BadAtom); + } + + + RRDeleteOutputProperty(output, stuff->property); + return client->noClientException; +} + +int +ProcRRGetOutputProperty (ClientPtr client) +{ + REQUEST(xRRGetOutputPropertyReq); + PropertyPtr prop, *prev; + unsigned long n, len, ind; + RROutputPtr output; + xRRGetOutputPropertyReply reply; + + REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq); + if (stuff->delete) + UpdateCurrentTime(); + output = LookupOutput (client, stuff->output, + stuff->delete ? SecurityWriteAccess : + SecurityReadAccess); + if (!output) + return RRErrorBase + BadRROutput; + + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return(BadAtom); + } + if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) + { + client->errorValue = stuff->delete; + return(BadValue); + } + if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return(BadAtom); + } + + for (prev = &output->properties; (prop = *prev); prev = &prop->next) + if (prop->propertyName == stuff->property) + break; + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + if (!prop) + { + reply.nItems = 0; + reply.length = 0; + reply.bytesAfter = 0; + reply.propertyType = None; + reply.format = 0; + WriteReplyToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); + return(client->noClientException); + } + + /* If the request type and actual type don't match. Return the + property information, but not the data. */ + + if (((stuff->type != prop->type) && + (stuff->type != AnyPropertyType)) + ) + { + reply.bytesAfter = prop->size; + reply.format = prop->format; + reply.length = 0; + reply.nItems = 0; + reply.propertyType = prop->type; + WriteReplyToClient(client, sizeof(xRRGetOutputPropertyReply), &reply); + return(client->noClientException); + } + +/* + * Return type, format, value to client + */ + n = (prop->format/8) * prop->size; /* size (bytes) of prop */ + ind = stuff->longOffset << 2; + + /* If longOffset is invalid such that it causes "len" to + be negative, it's a value error. */ + + if (n < ind) + { + client->errorValue = stuff->longOffset; + return BadValue; + } + + len = min(n - ind, 4 * stuff->longLength); + + reply.bytesAfter = n - (ind + len); + reply.format = prop->format; + reply.length = (len + 3) >> 2; + reply.nItems = len / (prop->format / 8 ); + reply.propertyType = prop->type; + + if (stuff->delete && (reply.bytesAfter == 0)) + { + xRROutputPropertyNotifyEvent event; + + event.type = RREventBase + RRNotify; + event.subCode = RRNotify_OutputProperty; + event.output = output->id; + event.state = PropertyDelete; + event.atom = prop->propertyName; + event.timestamp = currentTime.milliseconds; + RRDeliverEvent (output->pScreen, (xEvent *) &event, RROutputPropertyNotifyMask); + } + + WriteReplyToClient(client, sizeof(xGenericReply), &reply); + if (len) + { + switch (reply.format) { + case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break; + case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break; + default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break; + } + WriteSwappedDataToClient(client, len, + (char *)prop->data + ind); + } + + if (stuff->delete && (reply.bytesAfter == 0)) + { /* delete the Property */ + *prev = prop->next; + xfree(prop->data); + xfree(prop); + } + return(client->noClientException); +} + diff --git a/randr/rrscreen.c b/randr/rrscreen.c index e59947b36..e382540b7 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -69,7 +69,7 @@ RREditConnectionInfo (ScreenPtr pScreen) root->mmHeight = pScreen->mmHeight; } -static void +void RRSendConfigNotify (ScreenPtr pScreen) { WindowPtr pWin = WindowTable[pScreen->myNum]; diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c new file mode 100644 index 000000000..31f60cca1 --- /dev/null +++ b/randr/rrxinerama.c @@ -0,0 +1,424 @@ +/* + * 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. + */ +/* + * This Xinerama implementation comes from the SiS driver which has + * the following notice: + */ +/* + * SiS driver main code + * + * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3) The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Thomas Winischhofer + * - driver entirely rewritten since 2001, only basic structure taken from + * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of + * sis_dga.c; these were mostly taken over; sis_dri.c was changed for + * new versions of the DRI layer) + * + * This notice covers the entire driver code unless indicated otherwise. + * + * Formerly based on code which was + * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. + * Written by: + * Alan Hourihane , + * Mike Chapman , + * Juanjo Santamarta , + * Mitani Hiroshi , + * David Thomas . + */ + +#include "randrstr.h" +#include "swaprep.h" +#include + +#define RR_XINERAMA_MAJOR_VERSION 1 +#define RR_XINERAMA_MINOR_VERSION 1 + +/* Xinerama is not multi-screen capable; just report about screen 0 */ +#define RR_XINERAMA_SCREEN 0 + +static int ProcRRXineramaQueryVersion(ClientPtr client); +static int ProcRRXineramaGetState(ClientPtr client); +static int ProcRRXineramaGetScreenCount(ClientPtr client); +static int ProcRRXineramaGetScreenSize(ClientPtr client); +static int ProcRRXineramaIsActive(ClientPtr client); +static int ProcRRXineramaQueryScreens(ClientPtr client); +static int SProcRRXineramaDispatch(ClientPtr client); + +/* Proc */ + +int +ProcRRXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = RR_XINERAMA_MAJOR_VERSION; + rep.minorVersion = RR_XINERAMA_MINOR_VERSION; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +ProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n; + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + Bool active = FALSE; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + pScreen = pWin->drawable.pScreen; + pScrPriv = rrGetScrPriv(pScreen); + if (pScrPriv) + { + /* XXX do we need more than this? */ + active = TRUE; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = active; + if(client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); + return client->noClientException; +} + +static Bool +RRXineramaScreenActive (ScreenPtr pScreen) +{ + return rrGetScrPriv(pScreen) != NULL; +} + +static Bool +RRXineramaCrtcActive (RRCrtcPtr crtc) +{ + return crtc->mode != NULL && crtc->numOutputs > 0; +} + +static int +RRXineramaScreenCount (ScreenPtr pScreen) +{ + int i, n; + + n = 0; + if (RRXineramaScreenActive (pScreen)) + { + rrScrPriv(pScreen); + for (i = 0; i < pScrPriv->numCrtcs; i++) + if (RRXineramaCrtcActive (pScrPriv->crtcs[i])) + n++; + } + return n; +} + +int +ProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = RRXineramaScreenCount (pWin->drawable.pScreen); + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.ScreenCount, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin, pRoot; + ScreenPtr pScreen; + xPanoramiXGetScreenSizeReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + pWin = LookupWindow (stuff->window, client); + if(!pWin) return BadWindow; + + pScreen = pWin->drawable.pScreen; + pRoot = WindowTable[pScreen->myNum]; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.width = pRoot->drawable.width; + rep.height = pRoot->drawable.height; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +ProcRRXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = RRXineramaScreenActive (screenInfo.screens[RR_XINERAMA_SCREEN]); + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.state, n); + } + WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); + return client->noClientException; +} + +int +ProcRRXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN]; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = RRXineramaScreenCount (pScreen); + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.number, n); + } + WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); + + if(rep.number) { + rrScrPriv(pScreen); + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + if (RRXineramaCrtcActive (crtc)) + { + scratch.x_org = crtc->x; + scratch.y_org = crtc->y; + scratch.width = crtc->mode->mode.width; + scratch.height = crtc->mode->mode.height; + if(client->swapped) { + register int n; + swaps(&scratch.x_org, n); + swaps(&scratch.y_org, n); + swaps(&scratch.width, n); + swaps(&scratch.height, n); + } + WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); + } + } + } + + return client->noClientException; +} + +static int +ProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return ProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return ProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return ProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return ProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +SProcRRXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcRRXineramaQueryVersion(client); +} + +static int +SProcRRXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return ProcRRXineramaGetState(client); +} + +static int +SProcRRXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return ProcRRXineramaGetScreenCount(client); +} + +static int +SProcRRXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return ProcRRXineramaGetScreenSize(client); +} + +static int +SProcRRXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcRRXineramaIsActive(client); +} + +static int +SProcRRXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcRRXineramaQueryScreens(client); +} + +int +SProcRRXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SProcRRXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SProcRRXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SProcRRXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcRRXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SProcRRXineramaIsActive(client); + case X_XineramaQueryScreens: + return SProcRRXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +RRXineramaResetProc(ExtensionEntry* extEntry) +{ +} + +void +RRXineramaExtensionInit(void) +{ +#ifdef PANORAMIX + if(!noPanoramiXExtension) + return; +#endif + + (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcRRXineramaDispatch, + SProcRRXineramaDispatch, + RRXineramaResetProc, + StandardMinorOpcode); +} -- cgit v1.2.3 From b36fde9257263fa502147df37e8331184c323e14 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 21 Sep 2006 09:52:04 -0700 Subject: When no mode is specified, don't validate mode-specific parameters. --- randr/rrcrtc.c | 95 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index ebb254068..77cba29fa 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -564,64 +564,67 @@ ProcRRSetCrtcConfig (ClientPtr client) 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; - if (outputs) - xfree (outputs); - return BadValue; - } - - if ((~crtc->rotations) & rotation) + if (mode) { /* - * requested rotation or reflection not supported by screen + * Validate requested rotation */ - client->errorValue = stuff->rotation; - if (outputs) - xfree (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 (pScrPriv->rrScreenSetSize) - { - if (stuff->x + mode->mode.width > pScreen->width) - { - client->errorValue = stuff->x; + 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; if (outputs) xfree (outputs); return BadValue; } - - if (stuff->y + mode->mode.height > pScreen->height) + + if ((~crtc->rotations) & rotation) { - client->errorValue = stuff->y; + /* + * requested rotation or reflection not supported by screen + */ + client->errorValue = stuff->rotation; if (outputs) xfree (outputs); - return BadValue; + 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 (pScrPriv->rrScreenSetSize) + { + if (stuff->x + mode->mode.width > pScreen->width) + { + client->errorValue = stuff->x; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (stuff->y + mode->mode.height > pScreen->height) + { + client->errorValue = stuff->y; + if (outputs) + xfree (outputs); + return BadValue; + } } - } #endif + } /* * Make sure the requested set-time is not older than -- cgit v1.2.3 From c4f30c63538e1451f15ed1991439869127d9b148 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 3 Oct 2006 21:06:11 -0700 Subject: Add mode origins and output options. Fix memmoves in resource free funcs. Output options and mode origins both affected driver ABI. memmove mistakes were causing 'Freeing resource which isn't there' messages. Prune unused non-user defined modes from available list now. --- randr/mirandr.c | 6 ++++- randr/randrstr.h | 28 +++++++++++++++++++---- randr/rrcrtc.c | 52 +++++++++++++++++++++++++------------------ randr/rrinfo.c | 1 + randr/rrmode.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- randr/rroutput.c | 43 +++++++++++++++++++++++++++++------ randr/rrscreen.c | 17 +++++++------- 7 files changed, 171 insertions(+), 44 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index bcc8e0fcd..7300cfebe 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -52,7 +52,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs) + RROutputConfigPtr outputs) { return TRUE; } @@ -114,6 +114,10 @@ miRandRInit (ScreenPtr pScreen) return FALSE; if (!RROutputSetCrtcs (output, &crtc, 1)) return FALSE; + if (!RROutputSetPossibleOptions (output, 0)) + return FALSE; + if (!RROutputSetCurrentOptions (output, 0)) + return FALSE; if (!RROutputSetConnection (output, RR_Connected)) return FALSE; RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); diff --git a/randr/randrstr.h b/randr/randrstr.h index 0b8c61e1f..a4e55890f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -72,12 +72,14 @@ extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); typedef struct _rrMode RRModeRec, *RRModePtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; +typedef struct _rrOutputConfig RROutputConfigRec, *RROutputConfigPtr; struct _rrMode { int refcnt; xRRModeInfo mode; char *name; void *devPrivate; + ScreenPtr screen; }; struct _rrCrtc { @@ -105,6 +107,8 @@ struct _rrOutput { CARD8 connection; CARD8 subpixelOrder; RRCrtcPtr crtc; + CARD32 currentOptions; + CARD32 possibleOptions; int numCrtcs; RRCrtcPtr *crtcs; int numClones; @@ -116,6 +120,11 @@ struct _rrOutput { void *devPrivate; }; +struct _rrOutputConfig { + RROutputPtr output; + CARD32 options; +}; + #if RANDR_12_INTERFACE typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, @@ -130,7 +139,7 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs); + RROutputConfigPtr outputs); typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); @@ -352,7 +361,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs); + RROutputConfigPtr outputs); /* randr.c */ /* @@ -440,7 +449,7 @@ RRCrtcNotify (RRCrtcPtr crtc, int x, int y, Rotation rotation, - int numOutput, + int numOutputs, RROutputPtr *outputs); void @@ -456,7 +465,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutput, - RROutputPtr *outputs); + RROutputConfigPtr outputs); /* * Request that the Crtc gamma be changed @@ -530,6 +539,9 @@ RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, const char *name); +void +RRModePruneUnused (ScreenPtr pScreen); + /* * Destroy a mode. */ @@ -584,6 +596,10 @@ RROutputSetCrtcs (RROutputPtr output, RRCrtcPtr *crtcs, int numCrtcs); +Bool +RROutputSetPossibleOptions (RROutputPtr output, + CARD32 possibleOptions); + void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc); @@ -595,6 +611,10 @@ Bool RROutputSetSubpixelOrder (RROutputPtr output, int subpixelOrder); +Bool +RROutputSetCurrentOptions (RROutputPtr output, + CARD32 currentOptions); + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 77cba29fa..3108f1452 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -92,25 +92,25 @@ RRCrtcNotify (RRCrtcPtr crtc, if (numOutputs != prevNumOutputs) { - RROutputPtr *outputs; + RROutputPtr *newoutputs; if (numOutputs) { if (crtc->numOutputs) - outputs = xrealloc (crtc->outputs, + newoutputs = xrealloc (crtc->outputs, numOutputs * sizeof (RROutputPtr)); else - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); - if (!outputs) + newoutputs = xalloc (numOutputs * sizeof (RROutputPtr)); + if (!newoutputs) return FALSE; } else { if (crtc->outputs) xfree (crtc->outputs); - outputs = NULL; + newoutputs = NULL; } - crtc->outputs = outputs; + crtc->outputs = newoutputs; crtc->numOutputs = numOutputs; } for (i = 0; i < numOutputs; i++) @@ -183,7 +183,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutputs, - RROutputPtr *outputs) + RROutputConfigPtr outputs) { ScreenPtr pScreen = crtc->pScreen; rrScrPriv(pScreen); @@ -252,7 +252,7 @@ RRCrtcDestroyResource (pointer value, XID pid) { if (pScrPriv->crtcs[i] == crtc) { - memmove (pScrPriv->crtcs, pScrPriv->crtcs + 1, + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); --pScrPriv->numCrtcs; break; @@ -458,15 +458,15 @@ ProcRRSetCrtcConfig (ClientPtr client) RRCrtcPtr crtc; RRModePtr mode; int numOutputs; - RROutputPtr *outputs = NULL; - RROutput *outputIds; + RROutputConfigPtr outputs = NULL; + xRROutputConfig *outputConfigs; TimeStamp configTime; TimeStamp time; Rotation rotation; int i, j; REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2); + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)) >> 1; crtc = LookupIDByType (stuff->crtc, RRCrtcType); if (!crtc) @@ -493,39 +493,47 @@ ProcRRSetCrtcConfig (ClientPtr client) } if (numOutputs) { - outputs = xalloc (numOutputs * sizeof (RROutputPtr)); + outputs = xalloc (numOutputs * sizeof (RROutputConfigRec)); if (!outputs) return BadAlloc; } else outputs = NULL; - outputIds = (RROutput *) (stuff + 1); + outputConfigs = (xRROutputConfig *) (stuff + 1); for (i = 0; i < numOutputs; i++) { - outputs[i] = LookupIDByType (outputIds[i], RROutputType); - if (!outputs[i]) + outputs[i].output = LookupIDByType (outputConfigs[i].output, RROutputType); + if (!outputs[i].output) { - client->errorValue = outputIds[i]; + client->errorValue = outputConfigs[i].output; if (outputs) xfree (outputs); return RRErrorBase + BadRROutput; } + outputs[i].options = outputConfigs[i].options; + if (outputs[i].options & ~outputs[i].output->possibleOptions) + { + client->errorValue = outputConfigs[i].options; + if (outputs) + xfree (outputs); + return BadMatch; + } /* validate crtc for this output */ - for (j = 0; j < outputs[i]->numCrtcs; j++) - if (outputs[i]->crtcs[j] == crtc) + for (j = 0; j < outputs[i].output->numCrtcs; j++) + if (outputs[i].output->crtcs[j] == crtc) break; - if (j == outputs[j]->numCrtcs) + if (j == outputs[j].output->numCrtcs) { if (outputs) xfree (outputs); return BadMatch; } /* validate mode for this output */ - for (j = 0; j < outputs[i]->numModes; j++) - if (outputs[i]->modes[j] == mode) + for (j = 0; j < outputs[i].output->numModes; j++) + if (outputs[i].output->modes[j] == mode) break; - if (j == outputs[i]->numModes) + if (j == outputs[i].output->numModes) { if (outputs) xfree (outputs); diff --git a/randr/rrinfo.c b/randr/rrinfo.c index 491ac218d..6fd4ee581 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -208,6 +208,7 @@ RRGetInfo (ScreenPtr pScreen) if (pScrPriv->nSizes) RRScanOldConfig (pScreen, rotations); #endif + RRModePruneUnused (pScreen); RRTellChanged (pScreen); return TRUE; } diff --git a/randr/rrmode.c b/randr/rrmode.c index 23ac5305c..3a6748691 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -24,6 +24,27 @@ RESTYPE RRModeType; +static Bool +RRModeEqual (xRRModeInfo *a, xRRModeInfo *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; + if (a->dotClock != b->dotClock) return FALSE; + if (a->hSyncStart != b->hSyncStart) return FALSE; + if (a->hSyncEnd != b->hSyncEnd) return FALSE; + if (a->hTotal != b->hTotal) return FALSE; + if (a->hSkew != b->hSkew) return FALSE; + if (a->vSyncStart != b->vSyncStart) return FALSE; + if (a->vSyncEnd != b->vSyncEnd) return FALSE; + if (a->vTotal != b->vTotal) return FALSE; + if (a->nameLength != b->nameLength) return FALSE; + if (a->modeFlags != b->modeFlags) return FALSE; + if (a->origin != b->origin) return FALSE; + return TRUE; +} + RRModePtr RRModeGet (ScreenPtr pScreen, xRRModeInfo *modeInfo, @@ -37,8 +58,7 @@ RRModeGet (ScreenPtr pScreen, for (i = 0; i < pScrPriv->numModes; i++) { mode = pScrPriv->modes[i]; - modeInfo->id = mode->mode.id; - if (!memcmp (modeInfo, &mode->mode, sizeof (xRRModeInfo)) && + if (RRModeEqual (&mode->mode, modeInfo) && !memcmp (name, mode->name, modeInfo->nameLength)) { ++mode->refcnt; @@ -54,6 +74,7 @@ RRModeGet (ScreenPtr pScreen, mode->name = (char *) (mode + 1); memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; + mode->screen = pScreen; if (pScrPriv->numModes) modes = xrealloc (pScrPriv->modes, @@ -80,8 +101,31 @@ RRModeGet (ScreenPtr pScreen, void RRModeDestroy (RRModePtr mode) { + ScreenPtr pScreen; + rrScrPrivPtr pScrPriv; + int m; + if (--mode->refcnt > 0) return; + pScreen = mode->screen; + pScrPriv = rrGetScrPriv (pScreen); + for (m = 0; m < pScrPriv->numModes; m++) + { + if (pScrPriv->modes[m] == mode) + { + memmove (pScrPriv->modes + m, pScrPriv->modes + m + 1, + (pScrPriv->numModes - m - 1) * sizeof (RRModePtr)); + pScrPriv->numModes--; + if (!pScrPriv->numModes) + { + xfree (pScrPriv->modes); + pScrPriv->modes = NULL; + } + pScrPriv->changed = TRUE; + break; + } + } + xfree (mode); } @@ -104,6 +148,26 @@ RRModeInit (void) return TRUE; } +void +RRModePruneUnused (ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + RRModePtr *unused, mode; + int m; + int num = pScrPriv->numModes; + + unused = xalloc (num * sizeof (RRModePtr)); + if (!unused) + return; + memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr)); + for (m = 0; m < num; m++) { + mode = unused[m]; + if (mode->refcnt == 1 && mode->mode.origin != RRModeOriginUser) + FreeResource (mode->mode.id, 0); + } + xfree (unused); +} + int ProcRRCreateMode (ClientPtr client) { diff --git a/randr/rroutput.c b/randr/rroutput.c index 90b2b9856..b252d7dec 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -60,6 +60,8 @@ RROutputCreate (ScreenPtr pScreen, output->connection = RR_UnknownConnection; output->subpixelOrder = SubPixelUnknown; output->crtc = NULL; + output->currentOptions = 0; + output->possibleOptions = 0; output->numCrtcs = 0; output->crtcs = NULL; output->numClones = 0; @@ -190,6 +192,17 @@ RROutputSetCrtcs (RROutputPtr output, return TRUE; } +Bool +RROutputSetPossibleOptions (RROutputPtr output, + CARD32 possibleOptions) +{ + if (output->possibleOptions == possibleOptions) + return TRUE; + output->possibleOptions = possibleOptions; + output->changed = TRUE; + return TRUE; +} + void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) { @@ -222,6 +235,17 @@ RROutputSetSubpixelOrder (RROutputPtr output, return TRUE; } +Bool +RROutputSetCurrentOptions (RROutputPtr output, + CARD32 currentOptions) +{ + if (output->currentOptions == currentOptions) + return TRUE; + output->currentOptions = currentOptions; + output->changed = TRUE; + return TRUE; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { @@ -248,7 +272,7 @@ RROutputDestroyResource (pointer value, XID pid) { if (pScrPriv->outputs[i] == output) { - memmove (pScrPriv->outputs, pScrPriv->outputs + 1, + memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); --pScrPriv->numOutputs; break; @@ -280,6 +304,8 @@ RROutputInit (void) return TRUE; } +#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32) + int ProcRRGetOutputInfo (ClientPtr client) { @@ -307,24 +333,27 @@ ProcRRGetOutputInfo (ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.length = 0; + rep.length = OutputInfoExtra >> 2; rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.crtc = output->crtc ? output->crtc->id : None; + rep.currentOptions = output->currentOptions; rep.connection = output->connection; rep.subpixelOrder = output->subpixelOrder; rep.nCrtcs = output->numCrtcs; rep.nModes = output->numModes; rep.nClones = output->numClones; rep.nameLength = output->nameLength; + rep.possibleOptions = output->possibleOptions; + rep.pad1 = 42; - rep.length = (output->numCrtcs + - output->numModes + - output->numClones + - ((rep.nameLength + 3) >> 2)); + extraLen = ((output->numCrtcs + + output->numModes + + output->numClones + + ((rep.nameLength + 3) >> 2)) << 2); - extraLen = rep.length << 2; if (extraLen) { + rep.length += extraLen >> 2; extra = xalloc (extraLen); if (!extra) return BadAlloc; diff --git a/randr/rrscreen.c b/randr/rrscreen.c index e382540b7..7b53f0468 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -372,7 +372,7 @@ ProcRRGetScreenResources (ClientPtr client) rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + - pScrPriv->numModes * 10 + + pScrPriv->numModes * (SIZEOF(xRRModeInfo) >> 2) + ((rep.nbytesNames + 3) >> 2)); extraLen = rep.length << 2; @@ -429,7 +429,7 @@ ProcRRGetScreenResources (ClientPtr client) pScrPriv->modes[i]->mode.nameLength); names += pScrPriv->modes[i]->mode.nameLength; } - assert ((names + 3 >> 3) == rep.length); + assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length); } if (client->swapped) { @@ -694,7 +694,7 @@ ProcRRSetScreenConfig (ClientPtr client) Rotation rotation; int rate; Bool has_rate; - RROutputPtr output; + RROutputConfigRec output; RRModePtr mode; RR10DataPtr pData = NULL; RRScreenSizePtr pSize; @@ -731,13 +731,14 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRGetInfo (pScreen)) return BadAlloc; - output = RRFirstOutput (pScreen); - if (!output) + output.output = RRFirstOutput (pScreen); + if (!output.output) { time = currentTime; rep.status = RRSetConfigFailed; goto sendReply; } + output.options = output.output->currentOptions; /* * if the client's config timestamp is not the same as the last config @@ -750,7 +751,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - pData = RR10GetData (pScreen, output); + pData = RR10GetData (pScreen, output.output); if (!pData) return BadAlloc; @@ -786,7 +787,7 @@ ProcRRSetScreenConfig (ClientPtr client) return BadValue; } - if ((~output->crtc->rotations) & rotation) + if ((~output.output->crtc->rotations) & rotation) { /* * requested rotation or reflection not supported by screen @@ -835,7 +836,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, + rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation, 1, &output); sendReply: -- cgit v1.2.3 From 1178796a4dff5ebf0bd9fb3cacb35be9709b41e5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 5 Oct 2006 22:31:35 -0700 Subject: Add preferred modes for each output. Round vrefresh. Deliver crtc events. --- randr/mirandr.c | 2 +- randr/randr.c | 5 +- randr/randrstr.h | 10 +++- randr/rrcrtc.c | 144 ++++++++++++++++++++++++++++++++++++------------------- randr/rrmode.c | 4 +- randr/rroutput.c | 9 ++-- 6 files changed, 117 insertions(+), 57 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index 7300cfebe..918e55da4 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -110,7 +110,7 @@ miRandRInit (ScreenPtr pScreen) return FALSE; if (!RROutputSetClones (output, NULL, 0)) return FALSE; - if (!RROutputSetModes (output, &mode, 1)) + if (!RROutputSetModes (output, &mode, 1, 0)) return FALSE; if (!RROutputSetCrtcs (output, &crtc, 1)) return FALSE; diff --git a/randr/randr.c b/randr/randr.c index 4ea72e505..35f9a4c80 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -406,9 +406,10 @@ CARD16 RRVerticalRefresh (xRRModeInfo *mode) { CARD32 refresh; - if (!mode->hTotal || !mode->vTotal) + CARD32 dots = mode->hTotal * mode->vTotal; + if (!dots) return 0; - refresh = mode->dotClock / (mode->hTotal * mode->vTotal); + refresh = (mode->dotClock + dots/2) / dots; if (refresh > 0xffff) refresh = 0xffff; return (CARD16) refresh; diff --git a/randr/randrstr.h b/randr/randrstr.h index a4e55890f..6690556b4 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -80,6 +80,7 @@ struct _rrMode { char *name; void *devPrivate; ScreenPtr screen; + Bool userDefined; }; struct _rrCrtc { @@ -114,6 +115,7 @@ struct _rrOutput { int numClones; RROutputPtr *clones; int numModes; + int numPreferred; RRModePtr *modes; Bool changed; PropertyPtr properties; @@ -144,6 +146,10 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); +typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property); + #endif typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); @@ -187,6 +193,7 @@ typedef struct _rrScrPriv { RRScreenSetSizeProcPtr rrScreenSetSize; RRCrtcSetProcPtr rrCrtcSet; RRCrtcSetGammaProcPtr rrCrtcSetGamma; + RROutputSetPropertyProcPtr rrOutputSetProperty; #endif /* @@ -589,7 +596,8 @@ RROutputSetClones (RROutputPtr output, Bool RROutputSetModes (RROutputPtr output, RRModePtr *modes, - int numModes); + int numModes, + int numPreferred); Bool RROutputSetCrtcs (RROutputPtr output, diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 3108f1452..baefd3a15 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -88,9 +88,41 @@ RRCrtcNotify (RRCrtcPtr crtc, ScreenPtr pScreen = crtc->pScreen; rrScrPriv(pScreen); int i, j; - int prevNumOutputs = crtc->numOutputs; - if (numOutputs != prevNumOutputs) + /* + * 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]->changed = TRUE; + crtc->changed = TRUE; + } + } + /* + * 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) + { + crtc->outputs[j]->changed = TRUE; + crtc->changed = TRUE; + } + } + /* + * Reallocate the crtc output array if necessary + */ + if (numOutputs != crtc->numOutputs) { RROutputPtr *newoutputs; @@ -113,28 +145,13 @@ RRCrtcNotify (RRCrtcPtr crtc, crtc->outputs = newoutputs; crtc->numOutputs = numOutputs; } - 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]->changed = TRUE; - crtc->changed = TRUE; - } - } - for (j = 0; j < crtc->numOutputs; j++) - { - for (i = 0; i < numOutputs; i++) - if (outputs[i] == crtc->outputs[j]) - break; - if (i != numOutputs) - { - crtc->outputs[j]->changed = TRUE; - crtc->changed = TRUE; - } - } + /* + * 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) @@ -158,6 +175,9 @@ RRCrtcNotify (RRCrtcPtr crtc, crtc->rotation = rotation; crtc->changed = TRUE; } + /* + * Send events if anything changed + */ if (crtc->changed) { if (!pScrPriv->changed) @@ -170,7 +190,35 @@ RRCrtcNotify (RRCrtcPtr crtc, 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.sequenceNumber = client->sequence; + 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); } /* @@ -381,7 +429,7 @@ ProcRRGetCrtcInfo (ClientPtr client) rep.y = crtc->y; rep.width = mode ? mode->mode.width : 0; rep.height = mode ? mode->mode.height : 0; - rep.mode = mode->mode.id; + rep.mode = mode ? mode->mode.id : 0; rep.rotation = crtc->rotation; rep.rotations = crtc->rotations; rep.nOutput = crtc->numOutputs; @@ -572,30 +620,30 @@ ProcRRSetCrtcConfig (ClientPtr client) goto sendReply; } - if (mode) - { + /* + * 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: /* - * Validate requested rotation + * Invalid 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; - if (outputs) - xfree (outputs); - return BadValue; - } - + client->errorValue = stuff->rotation; + if (outputs) + xfree (outputs); + return BadValue; + } + + if (mode) + { if ((~crtc->rotations) & rotation) { /* diff --git a/randr/rrmode.c b/randr/rrmode.c index 3a6748691..07cd0c14f 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -41,7 +41,6 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) if (a->vTotal != b->vTotal) return FALSE; if (a->nameLength != b->nameLength) return FALSE; if (a->modeFlags != b->modeFlags) return FALSE; - if (a->origin != b->origin) return FALSE; return TRUE; } @@ -75,6 +74,7 @@ RRModeGet (ScreenPtr pScreen, memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; mode->screen = pScreen; + mode->userDefined = FALSE; if (pScrPriv->numModes) modes = xrealloc (pScrPriv->modes, @@ -162,7 +162,7 @@ RRModePruneUnused (ScreenPtr pScreen) memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr)); for (m = 0; m < num; m++) { mode = unused[m]; - if (mode->refcnt == 1 && mode->mode.origin != RRModeOriginUser) + if (mode->refcnt == 1 && !mode->userDefined) FreeResource (mode->mode.id, 0); } xfree (unused); diff --git a/randr/rroutput.c b/randr/rroutput.c index b252d7dec..618ef1f80 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -67,6 +67,7 @@ RROutputCreate (ScreenPtr pScreen, output->numClones = 0; output->clones = NULL; output->numModes = 0; + output->numPreferred = 0; output->modes = NULL; output->properties = NULL; output->changed = TRUE; @@ -120,12 +121,13 @@ RROutputSetClones (RROutputPtr output, Bool RROutputSetModes (RROutputPtr output, RRModePtr *modes, - int numModes) + int numModes, + int numPreferred) { RRModePtr *newModes; int i; - if (numModes == output->numModes) + if (numModes == output->numModes && numPreferred == output->numPreferred) { for (i = 0; i < numModes; i++) if (output->modes[i] != modes[i]) @@ -155,6 +157,7 @@ RROutputSetModes (RROutputPtr output, memcpy (newModes, modes, numModes * sizeof (RRModePtr)); output->modes = newModes; output->numModes = numModes; + output->numPreferred = numPreferred; output->changed = TRUE; return TRUE; } @@ -341,10 +344,10 @@ ProcRRGetOutputInfo (ClientPtr client) rep.subpixelOrder = output->subpixelOrder; rep.nCrtcs = output->numCrtcs; rep.nModes = output->numModes; + rep.nPreferred = output->numPreferred; rep.nClones = output->numClones; rep.nameLength = output->nameLength; rep.possibleOptions = output->possibleOptions; - rep.pad1 = 42; extraLen = ((output->numCrtcs + output->numModes + -- cgit v1.2.3 From 054f8cd2675a80b14bc1ce266377fcfee2335cee Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 13 Oct 2006 17:34:53 -0700 Subject: Limit pointer to valid crtc areas. Add event swapping. Fix change tracking. Add function to keep pointer within valid crtc areas. Finish event delivery and swapping code. Separate configuration from layout changes to send correct events. --- randr/Makefile.am | 1 + randr/mirandr.c | 3 ++ randr/randr.c | 72 ++++++++++++++++++++++------ randr/randrstr.h | 104 +++++++++++++++++++++++++++++++++++++++- randr/rrcrtc.c | 53 ++++++++++++--------- randr/rroutput.c | 61 ++++++++++++++++++++---- randr/rrpointer.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++ randr/rrproperty.c | 1 + randr/rrscreen.c | 31 ++++++++++++ 9 files changed, 415 insertions(+), 48 deletions(-) create mode 100644 randr/rrpointer.c diff --git a/randr/Makefile.am b/randr/Makefile.am index 91c4bc6dd..9bf0e6531 100644 --- a/randr/Makefile.am +++ b/randr/Makefile.am @@ -15,6 +15,7 @@ librandr_la_SOURCES = \ rrinfo.c \ rrmode.c \ rroutput.c \ + rrpointer.c \ rrproperty.c \ rrscreen.c \ rrsdispatch.c \ diff --git a/randr/mirandr.c b/randr/mirandr.c index 918e55da4..fab0fd1bd 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -84,6 +84,9 @@ miRandRInit (ScreenPtr pScreen) pScrPriv->rrGetInfo = miRRGetInfo; #if RANDR_12_INTERFACE pScrPriv->rrCrtcSet = miRRCrtcSet; + pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma; + pScrPriv->rrOutputSetProperty = miRROutput + RRScreenSetSizeRange (pScreen, pScreen->width, pScreen->height, diff --git a/randr/randr.c b/randr/randr.c index 35f9a4c80..b422efe9d 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -130,38 +130,71 @@ SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from, cpswaps(from->subpixelOrder, to->subpixelOrder); } -#if 0 static void -SRRMonitorChangeNotifyEvent(xRRMonitorChangeNotifyEvent *from, - xRRMonitorChangeNotifyEvent *to) +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->configTimestamp, to->configTimestamp); - cpswapl(from->root, to->root); cpswapl(from->window, to->window); - cpswaps(from->monitor, to->monitor); - cpswaps(from->modeID, to->modeID); + cpswapl(from->crtc, to->crtc); + cpswapl(from->mode, to->mode); + cpswapl(from->window, to->window); cpswaps(from->rotation, to->rotation); - cpswaps(from->subpixelOrder, to->subpixelOrder); 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); +} + +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); } -#endif static void SRRNotifyEvent (xEvent *from, xEvent *to) { switch (from->u.u.detail) { -#if 0 - case RRNotify_MonitorChange: - SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from, - (xRRMonitorChangeNotifyEvent *) to); + 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; -#endif default: break; } @@ -359,6 +392,9 @@ TellChanged (WindowPtr pWin, pointer value) return WT_WALKCHILDREN; } +/* + * Something changed; send events and adjust pointer position + */ void RRTellChanged (ScreenPtr pScreen) { @@ -369,12 +405,18 @@ RRTellChanged (ScreenPtr pScreen) { UpdateCurrentTime (); pScrPriv->lastConfigTime = currentTime; - WalkTree (pScreen, TellChanged, (pointer) pScreen); 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); + } } } diff --git a/randr/randrstr.h b/randr/randrstr.h index 6690556b4..a8a995026 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -202,10 +202,11 @@ typedef struct _rrScrPriv { TimeStamp lastSetTime; /* last changed by client */ TimeStamp lastConfigTime; /* possible configs changed */ RRCloseScreenProcPtr CloseScreen; - Bool changed; + Bool changed; /* some config changed */ CARD16 minWidth, minHeight; CARD16 maxWidth, maxHeight; CARD16 width, height; /* last known screen size */ + Bool layoutChanged; /* screen layout changed */ /* modes, outputs and crtcs */ int numModes; @@ -217,6 +218,9 @@ typedef struct _rrScrPriv { int numCrtcs; RRCrtcPtr *crtcs; + /* Last known pointer position */ + RRCrtcPtr pointerCrtc; + #ifdef RANDR_10_INTERFACE /* * Configuration information @@ -439,6 +443,14 @@ RRSetScreenConfig (ScreenPtr pScreen, #endif /* rrcrtc.c */ + +/* + * Notify the CRTC of some change; layoutChanged indicates that + * some position or size element changed + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged); + /* * Create a CRTC */ @@ -575,6 +587,13 @@ int ProcRRDeleteOutputMode (ClientPtr client); /* rroutput.c */ + +/* + * Notify the output of some change + */ +void +RROutputChanged (RROutputPtr output); + /* * Create an output */ @@ -638,6 +657,13 @@ ProcRRGetOutputInfo (ClientPtr client); Bool RROutputInit (void); +/* rrpointer.c */ +void +RRPointerMoved (ScreenPtr pScreen, int x, int y); + +void +RRPointerScreenConfigured (ScreenPtr pScreen); + /* rrproperty.c */ void @@ -668,3 +694,79 @@ void RRXineramaExtensionInit(void); #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 + RROutputSetCrtc + RROutputSetPossibleOptions + RRSetCurrentOptions + 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 + RROutputSetCrtc + 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/randr/rrcrtc.c b/randr/rrcrtc.c index baefd3a15..c662899a4 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -25,6 +25,24 @@ RESTYPE RRCrtcType; +/* + * Notify the CRTC of some change + */ +void +RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) +{ + ScreenPtr pScreen = crtc->pScreen; + rrScrPriv(pScreen); + + crtc->changed = TRUE; + pScrPriv->changed = TRUE; + /* + * Send ConfigureNotify on any layout change + */ + if (layoutChanged) + pScrPriv->layoutChanged = TRUE; +} + /* * Create a CRTC */ @@ -60,7 +78,7 @@ RRCrtcCreate (ScreenPtr pScreen, crtc->numOutputs = 0; crtc->gammaSize = 0; crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; - crtc->changed = TRUE; + crtc->changed = FALSE; crtc->devPrivate = devPrivate; if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) @@ -68,7 +86,8 @@ RRCrtcCreate (ScreenPtr pScreen, pScrPriv->crtcs = crtcs; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; - pScrPriv->changed = TRUE; + + RRCrtcChanged (crtc, TRUE); return crtc; } @@ -85,8 +104,6 @@ RRCrtcNotify (RRCrtcPtr crtc, int numOutputs, RROutputPtr *outputs) { - ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(pScreen); int i, j; /* @@ -100,8 +117,8 @@ RRCrtcNotify (RRCrtcPtr crtc, break; if (j == crtc->numOutputs) { - outputs[i]->changed = TRUE; - crtc->changed = TRUE; + RROutputChanged (outputs[i]); + RRCrtcChanged (crtc, FALSE); } } /* @@ -115,8 +132,8 @@ RRCrtcNotify (RRCrtcPtr crtc, break; if (i == numOutputs) { - crtc->outputs[j]->changed = TRUE; - crtc->changed = TRUE; + RROutputChanged (crtc->outputs[j]); + RRCrtcChanged (crtc, FALSE); } } /* @@ -158,31 +175,22 @@ RRCrtcNotify (RRCrtcPtr crtc, RRModeDestroy (crtc->mode); crtc->mode = mode; mode->refcnt++; - crtc->changed = TRUE; + RRCrtcChanged (crtc, TRUE); } if (x != crtc->x) { crtc->x = x; - crtc->changed = TRUE; + RRCrtcChanged (crtc, TRUE); } if (y != crtc->y) { crtc->y = y; - crtc->changed = TRUE; + RRCrtcChanged (crtc, TRUE); } if (rotation != crtc->rotation) { crtc->rotation = rotation; - crtc->changed = TRUE; - } - /* - * Send events if anything changed - */ - if (crtc->changed) - { - if (!pScrPriv->changed) - RRSendConfigNotify (pScreen); - pScrPriv->changed = TRUE; + RRCrtcChanged (crtc, TRUE); } return TRUE; } @@ -272,10 +280,11 @@ RRCrtcSet (RRCrtcPtr crtc, * Old 1.0 interface tied screen size to mode size */ if (ret) - RRScreenSizeNotify (pScreen); + RRCrtcNotify (crtc, mode, x, y, rotation, return ret; } #endif + RRTellChanged (pScreen); return FALSE; } diff --git a/randr/rroutput.c b/randr/rroutput.c index 618ef1f80..fc84ec1e6 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -24,6 +24,19 @@ RESTYPE RROutputType; +/* + * Notify the output of some change + */ +void +RROutputChanged (RROutputPtr output) +{ + ScreenPtr pScreen = output->pScreen; + rrScrPriv (pScreen); + + output->changed = TRUE; + pScrPriv->changed = TRUE; +} + /* * Create an output */ @@ -70,7 +83,7 @@ RROutputCreate (ScreenPtr pScreen, output->numPreferred = 0; output->modes = NULL; output->properties = NULL; - output->changed = TRUE; + output->changed = FALSE; output->devPrivate = devPrivate; if (!AddResource (output->id, RROutputType, (pointer) output)) @@ -78,7 +91,7 @@ RROutputCreate (ScreenPtr pScreen, pScrPriv->outputs = outputs; pScrPriv->outputs[pScrPriv->numOutputs++] = output; - pScrPriv->changed = TRUE; + RROutputChanged (output); return output; } @@ -114,7 +127,7 @@ RROutputSetClones (RROutputPtr output, memcpy (newClones, clones, numClones * sizeof (RROutputPtr)); output->clones = newClones; output->numClones = numClones; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -158,7 +171,7 @@ RROutputSetModes (RROutputPtr output, output->modes = newModes; output->numModes = numModes; output->numPreferred = numPreferred; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -191,7 +204,7 @@ RROutputSetCrtcs (RROutputPtr output, memcpy (newCrtcs, crtcs, numCrtcs * sizeof (RRCrtcPtr)); output->crtcs = newCrtcs; output->numCrtcs = numCrtcs; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -202,7 +215,7 @@ RROutputSetPossibleOptions (RROutputPtr output, if (output->possibleOptions == possibleOptions) return TRUE; output->possibleOptions = possibleOptions; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -212,7 +225,7 @@ RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) if (output->crtc == crtc) return; output->crtc = crtc; - output->changed = TRUE; + RROutputChanged (output); } Bool @@ -222,7 +235,7 @@ RROutputSetConnection (RROutputPtr output, if (output->connection == connection) return TRUE; output->connection = connection; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -234,7 +247,7 @@ RROutputSetSubpixelOrder (RROutputPtr output, return TRUE; output->subpixelOrder = subpixelOrder; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } @@ -245,13 +258,41 @@ RROutputSetCurrentOptions (RROutputPtr output, if (output->currentOptions == currentOptions) return TRUE; output->currentOptions = currentOptions; - output->changed = TRUE; + RROutputChanged (output); return TRUE; } void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { + ScreenPtr pScreen = pWin->drawable.pScreen; + rrScrPriv (pScreen); + xRROutputChangeNotifyEvent oe; + RRCrtcPtr crtc = output->crtc; + RRModePtr mode = crtc ? crtc->mode : 0; + + oe.type = RRNotify + RREventBase; + oe.subCode = RRNotify_OutputChange; + oe.sequenceNumber = client->sequence; + oe.timestamp = pScrPriv->lastSetTime.milliseconds; + oe.configTimestamp = pScrPriv->lastConfigTime.milliseconds; + oe.window = pWin->drawable.id; + oe.output = output->id; + if (crtc) + { + oe.crtc = crtc->id; + oe.mode = mode ? mode->mode.id : None; + oe.rotation = crtc->rotation; + } + else + { + oe.crtc = None; + oe.mode = None; + oe.rotation = RR_Rotate_0; + } + oe.connection = output->connection; + oe.subpixelOrder = output->subpixelOrder; + WriteEventsToClient (client, 1, (xEvent *) &oe); } /* diff --git a/randr/rrpointer.c b/randr/rrpointer.c new file mode 100644 index 000000000..7ba0460f5 --- /dev/null +++ b/randr/rrpointer.c @@ -0,0 +1,137 @@ +/* + * 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" + +/* + * When the pointer moves, check to see if the specified position is outside + * any of theavailable CRTCs and move it to a 'sensible' place if so, where + * sensible is the closest monitor to the departing edge. + * + * Returns whether the position was adjusted + */ + +static Bool +RRCrtcContainsPosition (RRCrtcPtr crtc, int x, int y) +{ + RRModePtr mode = crtc->mode; + + if (!mode) + return FALSE; + if (crtc->x <= x && x < crtc->x + mode->mode.width && + crtc->y <= y && y < crtc->y + mode->mode.height) + return TRUE; + return FALSE; +} + +/* + * Find the CRTC nearest the specified position, ignoring 'skip' + */ +static void +RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) +{ + rrScrPriv (pScreen); + int c; + RRCrtcPtr nearest = NULL; + int best = 0; + int best_dx = 0, best_dy = 0; + + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + RRModePtr mode = crtc->mode; + int dx, dy; + int dist; + + if (!mode) + continue; + if (crtc == skip) + continue; + if (x < crtc->x) + dx = crtc->x - x; + else if (x > crtc->x + mode->mode.width) + dx = x - (crtc->x + mode->mode.width); + else + dx = 0; + if (y < crtc->y) + dy = crtc->y - x; + else if (y > crtc->y + mode->mode.height) + dy = y - (crtc->y + mode->mode.height); + else + dy = 0; + dist = dx + dy; + if (!nearest || dist < best) + { + nearest = crtc; + best_dx = dx; + best_dy = dy; + } + } + if (best_dx || best_dy) + (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); + pScrPriv->pointerCrtc = nearest; +} + +void +RRPointerMoved (ScreenPtr pScreen, int x, int y) +{ + rrScrPriv (pScreen); + RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;; + int c; + + /* Check last known CRTC */ + if (pointerCrtc && RRCrtcContainsPosition (pointerCrtc, x, y)) + return; + + /* Check all CRTCs */ + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + + if (RRCrtcContainsPosition (crtc, x, y)) + { + /* Remember containing CRTC */ + pScrPriv->pointerCrtc = crtc; + return; + } + } + + /* None contain pointer, find nearest */ + RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc); +} + +/* + * When the screen is reconfigured, move the pointer to the nearest + * CRTC + */ +void +RRPointerScreenConfigured (ScreenPtr pScreen) +{ + WindowPtr pRoot = GetCurrentRootWindow (); + ScreenPtr pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL; + int x, y; + + if (pScreen != pCurrentScreen) + return FALSE; + GetSpritePosition (&x, &y); + RRPointerToNearestCrtc (pScreen, x, y, NULL); +} diff --git a/randr/rrproperty.c b/randr/rrproperty.c index cdafb5c9b..44f1f0ace 100644 --- a/randr/rrproperty.c +++ b/randr/rrproperty.c @@ -27,6 +27,7 @@ static void RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask) { + } void diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 7b53f0468..6d38e96b5 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -164,10 +164,13 @@ RRScreenSizeNotify (ScreenPtr pScreen) pScrPriv->width = pScreen->width; pScrPriv->height = pScreen->height; pScrPriv->changed = TRUE; + pScrPriv->sizeChanged = TRUE; + RRTellChanged (pScreen); RRSendConfigNotify (pScreen); RREditConnectionInfo (pScreen); + RRPointerScreenConfigured (pScreen); /* * Fix pointer bounds and location */ @@ -836,9 +839,37 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } + /* + * If the screen size is changing, adjust all of the other outputs + * to fit the new size, mirroring as much as possible + */ + if (mode->mode.width != pScreen->width || + mode->mode.height != pScreen->height) + { + int c; + + for (c = 0; c < pScrPriv->numCrtcs; c++) + { + rep.status = RRCrtcSet (pScrPriv->->crtc, NULL, 0, 0, RR_Rotate_0, + 0, NULL); + if (rep.status != Success) + goto sendReply; + } + if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height, + pScreen->mmWidth, pScreen->mmHeight)) + { + rep.status RRSetConfigFailed; + goto sendReply; + } + } + rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation, 1, &output); + /* + * XXX Configure other crtcs to mirror as much as possible + */ + sendReply: if (pData) -- cgit v1.2.3 From e21604914dccece6bc64c69b55512d1f1a969235 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 25 Oct 2006 09:48:23 -0700 Subject: Merge master back in and clean up some unfinished code (closes 8745) --- randr/mirandr.c | 17 ++++++++++++++++- randr/randr.c | 54 +++-------------------------------------------------- randr/rrcrtc.c | 2 +- randr/rrscreen.c | 6 +++--- randr/rrsdispatch.c | 1 + randr/rrxinerama.c | 3 +++ 6 files changed, 27 insertions(+), 56 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index fab0fd1bd..8d79e8a11 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -57,6 +57,21 @@ miRRCrtcSet (ScreenPtr pScreen, return TRUE; } +static Bool +miRRCrtcSetGamma (ScreenPtr pScreen, + RRCrtcPtr crtc) +{ + return TRUE; +} + +static Bool +miRROutputSetProperty (ScreenPtr pScreen, + RROutputPtr output, + Atom property) +{ + return TRUE; +} + /* * This function assumes that only a single depth can be * displayed at a time, but that all visuals of that depth @@ -85,7 +100,7 @@ miRandRInit (ScreenPtr pScreen) #if RANDR_12_INTERFACE pScrPriv->rrCrtcSet = miRRCrtcSet; pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma; - pScrPriv->rrOutputSetProperty = miRROutput + pScrPriv->rrOutputSetProperty = miRROutputSetProperty; RRScreenSetSizeRange (pScreen, diff --git a/randr/randr.c b/randr/randr.c index 5494428fc..7b39e8045 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -42,9 +42,6 @@ int RRGeneration; int RRNScreens; -static int ProcRRDispatch (ClientPtr pClient); -static int SProcRRDispatch (ClientPtr pClient); - #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ real->mem = func; \ @@ -54,6 +51,9 @@ static int SProcRRDispatch (ClientPtr pClient); 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 */ @@ -466,54 +466,6 @@ ProcRRDispatch (ClientPtr client) return (*ProcRandrVector[stuff->data]) (client); } -static int -SProcRRGetScreenInfo (ClientPtr client) -{ - register int n; - REQUEST(xRRGetScreenInfoReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - return ProcRRGetScreenInfo(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 ProcRRSetScreenConfig(client); -} - -static int -SProcRRSelectInput (ClientPtr client) -{ - register int n; - REQUEST(xRRSelectInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swaps(&stuff->enable, n); - return ProcRRSelectInput(client); -} - - static int SProcRRDispatch (ClientPtr client) { diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index c662899a4..ee51cc23a 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -280,7 +280,7 @@ RRCrtcSet (RRCrtcPtr crtc, * Old 1.0 interface tied screen size to mode size */ if (ret) - RRCrtcNotify (crtc, mode, x, y, rotation, + RRCrtcNotify (crtc, mode, x, y, rotation, 1, &outputs[0].output); return ret; } #endif diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 6d38e96b5..b4d361846 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -164,7 +164,7 @@ RRScreenSizeNotify (ScreenPtr pScreen) pScrPriv->width = pScreen->width; pScrPriv->height = pScreen->height; pScrPriv->changed = TRUE; - pScrPriv->sizeChanged = TRUE; +/* pScrPriv->sizeChanged = TRUE; */ RRTellChanged (pScreen); RRSendConfigNotify (pScreen); @@ -850,7 +850,7 @@ ProcRRSetScreenConfig (ClientPtr client) for (c = 0; c < pScrPriv->numCrtcs; c++) { - rep.status = RRCrtcSet (pScrPriv->->crtc, NULL, 0, 0, RR_Rotate_0, + rep.status = RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0, 0, NULL); if (rep.status != Success) goto sendReply; @@ -858,7 +858,7 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRScreenSizeSet (pScreen, mode->mode.width, mode->mode.height, pScreen->mmWidth, pScreen->mmHeight)) { - rep.status RRSetConfigFailed; + rep.status = RRSetConfigFailed; goto sendReply; } } diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c index bf81f8bdb..67af75306 100644 --- a/randr/rrsdispatch.c +++ b/randr/rrsdispatch.c @@ -77,6 +77,7 @@ SProcRRSelectInput (ClientPtr client) swaps(&stuff->length, n); swapl(&stuff->window, n); + swaps(&stuff->enable, n); return (*ProcRandrVector[stuff->randrReqType]) (client); } diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index 31f60cca1..a8e4b390b 100644 --- a/randr/rrxinerama.c +++ b/randr/rrxinerama.c @@ -259,6 +259,9 @@ ProcRRXineramaQueryScreens(ClientPtr client) REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + if (RRXineramaScreenActive (pScreen)) + RRGetInfo (pScreen); + rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.number = RRXineramaScreenCount (pScreen); -- cgit v1.2.3 From 4056e6e79a4e37101d298ae29139c83d3816368b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 1 Nov 2006 00:29:46 -0800 Subject: Move physical size from mode to output. Modes can be shared across different sized monitors this way. Also caught some missing byteswapping and an incorrect return type. --- randr/mirandr.c | 2 -- randr/randrstr.h | 7 +++++++ randr/rrcrtc.c | 12 ++++++++++-- randr/rrinfo.c | 2 -- randr/rrmode.c | 2 -- randr/rroutput.c | 23 +++++++++++++++++++++++ randr/rrpointer.c | 2 +- randr/rrscreen.c | 15 +++++++++------ 8 files changed, 50 insertions(+), 15 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index 8d79e8a11..11c299133 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -111,8 +111,6 @@ miRandRInit (ScreenPtr pScreen) memset (&modeInfo, '\0', sizeof (modeInfo)); modeInfo.width = pScreen->width; modeInfo.height = pScreen->height; - modeInfo.mmWidth = pScreen->mmWidth; - modeInfo.mmHeight = pScreen->mmHeight; modeInfo.nameLength = strlen (name); mode = RRModeGet (pScreen, &modeInfo, name); diff --git a/randr/randrstr.h b/randr/randrstr.h index a8a995026..60877a3c1 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -107,6 +107,8 @@ struct _rrOutput { int nameLength; CARD8 connection; CARD8 subpixelOrder; + int mmWidth; + int mmHeight; RRCrtcPtr crtc; CARD32 currentOptions; CARD32 possibleOptions; @@ -642,6 +644,11 @@ Bool RROutputSetCurrentOptions (RROutputPtr output, CARD32 currentOptions); +Bool +RROutputSetPhysicalSize (RROutputPtr output, + int mmWidth, + int mmHeight); + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index ee51cc23a..c40dac129 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -270,8 +270,16 @@ RRCrtcSet (RRCrtcPtr crtc, size.width = mode->mode.width; size.height = mode->mode.height; - size.mmWidth = mode->mode.mmWidth; - size.mmHeight = mode->mode.mmHeight; + if (outputs[0].output->mmWidth && outputs[0].output->mmHeight) + { + size.mmWidth = outputs[0].output->mmWidth; + size.mmHeight = outputs[0].output->mmHeight; + } + else + { + size.mmWidth = pScreen->mmWidth; + size.mmHeight = pScreen->mmHeight; + } size.nRates = 1; rate.rate = RRVerticalRefresh (&mode->mode); size.pRates = &rate; diff --git a/randr/rrinfo.c b/randr/rrinfo.c index 6fd4ee581..e92caadfa 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -39,8 +39,6 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) modeInfo.width = size->width; modeInfo.height = size->height; - modeInfo.mmWidth = size->mmWidth; - modeInfo.mmHeight = size->mmHeight; modeInfo.hTotal = size->width; modeInfo.vTotal = size->height; modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * diff --git a/randr/rrmode.c b/randr/rrmode.c index 07cd0c14f..fb4b5eb1e 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -29,8 +29,6 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *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; if (a->dotClock != b->dotClock) return FALSE; if (a->hSyncStart != b->hSyncStart) return FALSE; if (a->hSyncEnd != b->hSyncEnd) return FALSE; diff --git a/randr/rroutput.c b/randr/rroutput.c index fc84ec1e6..1f6f33030 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -72,6 +72,8 @@ RROutputCreate (ScreenPtr pScreen, output->name[nameLength] = '\0'; output->connection = RR_UnknownConnection; output->subpixelOrder = SubPixelUnknown; + output->mmWidth = 0; + output->mmHeight = 0; output->crtc = NULL; output->currentOptions = 0; output->possibleOptions = 0; @@ -262,6 +264,20 @@ RROutputSetCurrentOptions (RROutputPtr output, return TRUE; } +Bool +RROutputSetPhysicalSize (RROutputPtr output, + int mmWidth, + int mmHeight) +{ + if (output->mmWidth == mmWidth && output->mmHeight == mmHeight) + return TRUE; + output->mmWidth = mmWidth; + output->mmHeight = mmHeight; + RROutputChanged (output); + return TRUE; +} + + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { @@ -381,6 +397,8 @@ ProcRRGetOutputInfo (ClientPtr client) rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.crtc = output->crtc ? output->crtc->id : None; rep.currentOptions = output->currentOptions; + rep.mmWidth = output->mmWidth; + rep.mmHeight = output->mmHeight; rep.connection = output->connection; rep.subpixelOrder = output->subpixelOrder; rep.nCrtcs = output->numCrtcs; @@ -434,10 +452,15 @@ ProcRRGetOutputInfo (ClientPtr client) swapl(&rep.length, n); swapl(&rep.timestamp, n); swapl(&rep.crtc, n); + swapl(&rep.currentOptions, n); + swapl(&rep.mmWidth, n); + swapl(&rep.mmHeight, n); swaps(&rep.nCrtcs, n); swaps(&rep.nModes, n); swaps(&rep.nClones, n); + swapl(&rep.possibleOptions, n); swaps(&rep.nameLength, n); + swapl(&rep.possibleOptions, n); } WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); if (extraLen) diff --git a/randr/rrpointer.c b/randr/rrpointer.c index 7ba0460f5..c092e494b 100644 --- a/randr/rrpointer.c +++ b/randr/rrpointer.c @@ -131,7 +131,7 @@ RRPointerScreenConfigured (ScreenPtr pScreen) int x, y; if (pScreen != pCurrentScreen) - return FALSE; + return; GetSpritePosition (&x, &y); RRPointerToNearestCrtc (pScreen, x, y, NULL); } diff --git a/randr/rrscreen.c b/randr/rrscreen.c index b4d361846..705e7d78c 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -126,8 +126,8 @@ RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen) } se.widthInPixels = mode->mode.width; se.heightInPixels = mode->mode.height; - se.widthInMillimeters = mode->mode.mmWidth; - se.heightInMillimeters = mode->mode.mmHeight; + se.widthInMillimeters = pScreen->mmWidth; + se.heightInMillimeters = pScreen->mmHeight; } else { @@ -415,8 +415,6 @@ ProcRRGetScreenResources (ClientPtr client) swapl (&modeinfos[i].id, n); swaps (&modeinfos[i].width, n); swaps (&modeinfos[i].height, n); - swapl (&modeinfos[i].mmWidth, n); - swapl (&modeinfos[i].mmHeight, n); swapl (&modeinfos[i].dotClock, n); swaps (&modeinfos[i].hSyncStart, n); swaps (&modeinfos[i].hSyncEnd, n); @@ -501,8 +499,13 @@ RR10GetData (ScreenPtr pScreen, RROutputPtr output) size[j].id = j; size[j].width = mode->mode.width; size[j].height = mode->mode.height; - size[j].mmWidth = mode->mode.mmWidth; - size[j].mmHeight = mode->mode.mmHeight; + if (output->mmWidth && output->mmHeight) { + size[j].mmWidth = output->mmWidth; + size[j].mmHeight = output->mmHeight; + } else { + size[j].mmWidth = pScreen->mmWidth; + size[j].mmHeight = pScreen->mmHeight; + } size[j].nRates = 0; size[j].pRates = &refresh[data->nrefresh]; data->nsize++; -- cgit v1.2.3 From cde8806c2930788ba8076e94651d391e45f3ccdb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 3 Nov 2006 16:36:34 -0800 Subject: Don't bump the refcnt if the new mode is NULL. --- randr/rrcrtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index c40dac129..76d0b6bf5 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -174,7 +174,8 @@ RRCrtcNotify (RRCrtcPtr crtc, if (crtc->mode) RRModeDestroy (crtc->mode); crtc->mode = mode; - mode->refcnt++; + if (mode != NULL) + mode->refcnt++; RRCrtcChanged (crtc, TRUE); } if (x != crtc->x) -- cgit v1.2.3 From 2db62bce0725ba2d88cbe40fc440b6bda45046f3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 4 Nov 2006 17:40:34 -0800 Subject: Define fbHasVisualTypes in fb.h as it is exported --- fb/fb.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fb/fb.h b/fb/fb.h index de0b3a8c2..e60507874 100644 --- a/fb/fb.h +++ b/fb/fb.h @@ -1341,6 +1341,9 @@ fbCreateDefColormap(ScreenPtr pScreen); void fbClearVisualTypes(void); +Bool +fbHasVisualTypes (int depth); + Bool fbSetVisualTypes (int depth, int visuals, int bitsPerRGB); -- cgit v1.2.3 From 7ffbe9d232e3a4621a204448d67e434736465cbe Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 4 Nov 2006 17:41:09 -0800 Subject: Add DIX_CFLAGS to hw/vfb/Makefile.am --- hw/vfb/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/vfb/Makefile.am b/hw/vfb/Makefile.am index baab5ca22..2a0151f57 100644 --- a/hw/vfb/Makefile.am +++ b/hw/vfb/Makefile.am @@ -21,8 +21,8 @@ Xvfb_LDFLAGS = AM_CFLAGS = -DHAVE_DIX_CONFIG_H \ -DNO_HW_ONLY_EXTS \ -DNO_MODULE_EXTS \ - \ - $(XVFBMODULES_CFLAGS) + $(XVFBMODULES_CFLAGS) \ + $(DIX_CFLAGS) # Man page include $(top_srcdir)/cpprules.in -- cgit v1.2.3 From 8b87ce19741753eafbd99e7093bc3dea8f26e838 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 4 Nov 2006 17:41:25 -0800 Subject: Allow X server to build against libdrm 2.1 --- configure.ac | 3 +++ hw/xfree86/os-support/drm/xf86drm.c | 2 ++ hw/xfree86/os-support/xf86drm.h | 2 ++ include/dix-config.h.in | 3 +++ 4 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index 195211cb9..cb194aee6 100644 --- a/configure.ac +++ b/configure.ac @@ -619,6 +619,9 @@ if test "x$DRI" = xyes; then PKG_CHECK_MODULES([DRIPROTO], [xf86driproto]) PKG_CHECK_MODULES([LIBDRM], [libdrm]) PKG_CHECK_MODULES([GL], [glproto >= 1.4.1]) + PKG_CHECK_EXISTS(libdrm >= 2.2.0, + [AC_DEFINE([HAVE_LIBDRM_2_2], 1, + [Has version 2.2 (or newer) of the drm library])]) AC_SUBST(DRIPROTO_CFLAGS) AC_SUBST(LIBDRM_CFLAGS) AC_SUBST(GL_CFLAGS) diff --git a/hw/xfree86/os-support/drm/xf86drm.c b/hw/xfree86/os-support/drm/xf86drm.c index e990e286b..8bcccee2a 100644 --- a/hw/xfree86/os-support/drm/xf86drm.c +++ b/hw/xfree86/os-support/drm/xf86drm.c @@ -2307,6 +2307,7 @@ int drmRemoveSIGIOHandler(int fd) return xf86RemoveSIGIOHandler(fd); } +#if HAVE_LIBDRM_2_2 /* * Valid flags are * DRM_FENCE_FLAG_EMIT @@ -3260,3 +3261,4 @@ int drmMMUnlock(int fd, unsigned memType) return ret; } +#endif /* HAVE_LIBDRM_2_2 */ diff --git a/hw/xfree86/os-support/xf86drm.h b/hw/xfree86/os-support/xf86drm.h index 18e4564d1..1d93f6f90 100644 --- a/hw/xfree86/os-support/xf86drm.h +++ b/hw/xfree86/os-support/xf86drm.h @@ -36,7 +36,9 @@ #define _XF86DRM_H_ #include +#if HAVE_LIBDRM_2_2 #include +#endif /* Defaults, if nothing set in xf86config */ #define DRM_DEV_UID 0 diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 35700e460..84d693f5c 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -127,6 +127,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have version 2.2 (or newer) of the drm library */ +#undef HAVE_LIBDRM_2_2 + /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM -- cgit v1.2.3 From 1dcda4f3c56214464c0b6123fea6daa69aae69fc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 Nov 2006 01:29:51 -0800 Subject: Avoid dereferencing sprite.screen when Xinerama is not running. (#8925) With Xinerama support built into the X server but not in use, sprite.screen is NULL and yet the SyntheticMotion macro would dereference it. Avoid that by just passing sprite.screen to PostSyntheticMotion which can then dereference it when Xinerama is enabled. Also, define PostSyntheticMotion in dixevents.h and include dixevents.h in getevents.c --- dix/events.c | 3 +-- dix/getevents.c | 8 +++++--- include/dixevents.h | 4 ++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dix/events.c b/dix/events.c index 3b1a0aaf4..ce053b347 100644 --- a/dix/events.c +++ b/dix/events.c @@ -327,11 +327,10 @@ static CARD8 criticalEvents[32] = #ifdef PANORAMIX static void ConfineToShape(RegionPtr shape, int *px, int *py); -extern void PostSyntheticMotion(int x, int y, int screenNum, int time); static void PostNewCursor(void); #define SyntheticMotion(x, y) \ - PostSyntheticMotion(x, y, sprite.screen->myNum, \ + PostSyntheticMotion(x, y, sprite.screen, \ syncEvents.playingEvents ? \ syncEvents.time.milliseconds : \ currentTime.milliseconds); diff --git a/dix/getevents.c b/dix/getevents.c index b19a73fa6..1d9502802 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -38,6 +38,7 @@ #include "dixstruct.h" #include "globals.h" +#include "dixevents.h" #include "mipointer.h" @@ -758,7 +759,7 @@ SwitchCorePointer(DeviceIntPtr pDev) * to shift the pointer to get it inside the new bounds. */ void -PostSyntheticMotion(int x, int y, int screenNum, unsigned long time) +PostSyntheticMotion(int x, int y, ScreenPtr pScreen, unsigned long time) { xEvent xE; @@ -767,8 +768,8 @@ PostSyntheticMotion(int x, int y, int screenNum, unsigned long time) will translate from sprite screen to screen 0 upon reentry to the DIX layer. */ if (!noPanoramiXExtension) { - x += panoramiXdataPtr[0].x - panoramiXdataPtr[screenNum].x; - y += panoramiXdataPtr[0].y - panoramiXdataPtr[screenNum].y; + x += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x; + y += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; } #endif @@ -776,6 +777,7 @@ PostSyntheticMotion(int x, int y, int screenNum, unsigned long time) xE.u.u.type = MotionNotify; xE.u.keyButtonPointer.rootX = x; xE.u.keyButtonPointer.rootY = y; + xE.u.keyButtonPointer.time = time; (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1); } diff --git a/include/dixevents.h b/include/dixevents.h index 2a9458f08..c78fb0e85 100644 --- a/include/dixevents.h +++ b/include/dixevents.h @@ -102,4 +102,8 @@ extern int ProcUngrabButton(ClientPtr /* client */); extern int ProcRecolorCursor(ClientPtr /* client */); +#ifdef PANORAMIX +extern void PostSyntheticMotion(int x, int y, ScreenPtr pScreen, unsigned long time); +#endif + #endif /* DIXEVENTS_H */ -- cgit v1.2.3 From 20e9144c0746943624ff77a61791b8596f3f8458 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 Nov 2006 12:49:28 -0800 Subject: Add $(DIX_CFLAGS) to remaining Makefile.am files --- hw/dmx/config/Makefile.am | 2 +- hw/dmx/glxProxy/Makefile.am | 2 +- hw/dmx/input/Makefile.am | 2 +- hw/xfree86/Makefile.am | 2 +- hw/xfree86/os-support/bsd/Makefile.am | 2 +- hw/xfree86/os-support/bus/Makefile.am | 2 +- hw/xfree86/os-support/hurd/Makefile.am | 2 +- hw/xfree86/os-support/linux/Makefile.am | 2 +- hw/xfree86/os-support/misc/Makefile.am | 2 +- hw/xfree86/os-support/solaris/Makefile.am | 2 +- hw/xgl/Makefile.am | 2 +- hw/xgl/egl/Makefile.am | 2 +- hw/xgl/egl/module/Makefile.am | 1 + hw/xgl/glx/Makefile.am | 2 +- hw/xgl/glx/module/Makefile.am | 2 +- hw/xgl/glxext/Makefile.am | 2 +- hw/xgl/glxext/module/Makefile.am | 2 +- hw/xwin/Makefile.am | 2 +- 18 files changed, 18 insertions(+), 17 deletions(-) diff --git a/hw/dmx/config/Makefile.am b/hw/dmx/config/Makefile.am index fbc7f35a1..c31e04942 100644 --- a/hw/dmx/config/Makefile.am +++ b/hw/dmx/config/Makefile.am @@ -27,7 +27,7 @@ endif AM_YFLAGS = -d AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -I$(top_srcdir)/hw/dmx \ $(GLX_INCS) \ -DHAVE_DMX_CONFIG_H \ diff --git a/hw/dmx/glxProxy/Makefile.am b/hw/dmx/glxProxy/Makefile.am index 2f4a3b708..1fbc8d764 100644 --- a/hw/dmx/glxProxy/Makefile.am +++ b/hw/dmx/glxProxy/Makefile.am @@ -32,7 +32,7 @@ libglxproxy_a_SOURCES = compsize.c \ unpack.h AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -I$(top_srcdir)/hw/dmx \ -I$(top_srcdir)/include \ -I$(top_srcdir)/GL/include \ diff --git a/hw/dmx/input/Makefile.am b/hw/dmx/input/Makefile.am index 326506e77..da8de0546 100644 --- a/hw/dmx/input/Makefile.am +++ b/hw/dmx/input/Makefile.am @@ -60,7 +60,7 @@ GLX_DEFS = @GL_CFLAGS@ GLX_INCS = -I@MESA_SOURCE@/include endif -AM_CFLAGS = \ +AM_CFLAGS = $(DIX_CFLAGS) \ -I$(top_srcdir)/hw/dmx \ -I$(top_srcdir)/hw/xfree86/common \ $(GLX_INCS) \ diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 72befea19..b373242e8 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -22,7 +22,7 @@ DIST_SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support \ bin_PROGRAMS = Xorg -AM_CFLAGS = @XORG_CFLAGS@ +AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ INCLUDES = @XORG_INCS@ Xorg_SOURCES = xorg.c diff --git a/hw/xfree86/os-support/bsd/Makefile.am b/hw/xfree86/os-support/bsd/Makefile.am index e456328df..099240467 100644 --- a/hw/xfree86/os-support/bsd/Makefile.am +++ b/hw/xfree86/os-support/bsd/Makefile.am @@ -50,7 +50,7 @@ ARCH_SOURCES = \ endif # FIXME: NetBSD Aperture defines (configure.ac) -AM_CFLAGS = -DUSESTDRES $(XORG_CFLAGS) +AM_CFLAGS = -DUSESTDRES $(XORG_CFLAGS) $(DIX_CFLAGS) INCLUDES = $(XORG_INCS) diff --git a/hw/xfree86/os-support/bus/Makefile.am b/hw/xfree86/os-support/bus/Makefile.am index c56f3d717..fba6e5421 100644 --- a/hw/xfree86/os-support/bus/Makefile.am +++ b/hw/xfree86/os-support/bus/Makefile.am @@ -53,6 +53,6 @@ libbus_la_SOURCES = Pci.c Pci.h $(PCI_SOURCES) $(PLATFORM_PCI_SOURCES) \ INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) EXTRA_DIST = $(sdk_HEADERS) diff --git a/hw/xfree86/os-support/hurd/Makefile.am b/hw/xfree86/os-support/hurd/Makefile.am index b80fdde99..731ff083d 100644 --- a/hw/xfree86/os-support/hurd/Makefile.am +++ b/hw/xfree86/os-support/hurd/Makefile.am @@ -12,6 +12,6 @@ libhurd_la_SOURCES = hurd_bell.c hurd_init.c hurd_mmap.c \ $(srcdir)/../shared/kmod_noop.c \ $(srcdir)/../shared/agp_noop.c -AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) +AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS) INCLUDES = $(XORG_INCS) diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am index caf600787..9c4fa4984 100644 --- a/hw/xfree86/os-support/linux/Makefile.am +++ b/hw/xfree86/os-support/linux/Makefile.am @@ -34,7 +34,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c lnx_mouse.c \ $(APM_SRCS) \ $(PLATFORM_PCI_SUPPORT) -AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(PLATFORM_DEFINES) +AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES) INCLUDES = $(XORG_INCS) $(PLATFORM_INCLUDES) -I/usr/include/drm # FIXME this last part is crack diff --git a/hw/xfree86/os-support/misc/Makefile.am b/hw/xfree86/os-support/misc/Makefile.am index 8bec35088..65fbe92b4 100644 --- a/hw/xfree86/os-support/misc/Makefile.am +++ b/hw/xfree86/os-support/misc/Makefile.am @@ -18,6 +18,6 @@ libmisc_la_SOURCES = xf86_Util.c Delay.c $(ARCH_SRCS) INCLUDES = $(XORG_INCS) -AM_CFLAGS = $(XORG_CFLAGS) +AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) EXTRA_DIST = $(I386_SRCS) $(PORTIO_SRCS) $(ILHACK_SRCS) diff --git a/hw/xfree86/os-support/solaris/Makefile.am b/hw/xfree86/os-support/solaris/Makefile.am index 291c329ea..57ec89e57 100644 --- a/hw/xfree86/os-support/solaris/Makefile.am +++ b/hw/xfree86/os-support/solaris/Makefile.am @@ -30,7 +30,7 @@ nodist_libsolaris_la_SOURCES = $(SOLARIS_INOUT_SRC) sdk_HEADERS = agpgart.h nodist_sdk_HEADERS = solaris-$(SOLARIS_INOUT_ARCH).il -AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) +AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS) INCLUDES = $(XORG_INCS) diff --git a/hw/xgl/Makefile.am b/hw/xgl/Makefile.am index 48a9825d2..965060cd7 100644 --- a/hw/xgl/Makefile.am +++ b/hw/xgl/Makefile.am @@ -19,7 +19,7 @@ SUBDIRS = \ $(XEGL_SUBDIRS) AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -DHAVE_XGL_CONFIG_H \ -DHAVE_DIX_CONFIG_H \ -I$(top_srcdir)/GL/glx \ diff --git a/hw/xgl/egl/Makefile.am b/hw/xgl/egl/Makefile.am index ded4a15e2..5136e58b1 100644 --- a/hw/xgl/egl/Makefile.am +++ b/hw/xgl/egl/Makefile.am @@ -9,7 +9,7 @@ SUBDIRS = \ $(XGL_MODULE_DIRS) AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -DHAVE_XGL_CONFIG_H \ -DHAVE_DIX_CONFIG_H \ $(XEGLMODULES_CFLAGS) diff --git a/hw/xgl/egl/module/Makefile.am b/hw/xgl/egl/module/Makefile.am index 7ed217322..c84f85c90 100644 --- a/hw/xgl/egl/module/Makefile.am +++ b/hw/xgl/egl/module/Makefile.am @@ -1,4 +1,5 @@ AM_CFLAGS = \ + $(DIX_CFLAGS) \ -I$(srcdir)/.. \ -I$(srcdir)/../.. \ $(XEGLMODULES_CFLAGS) diff --git a/hw/xgl/glx/Makefile.am b/hw/xgl/glx/Makefile.am index 10a831f94..314c02e96 100644 --- a/hw/xgl/glx/Makefile.am +++ b/hw/xgl/glx/Makefile.am @@ -15,7 +15,7 @@ AM_CFLAGS = \ -I$(top_srcdir)/GL/include \ -I@MESA_SOURCE@/include \ -I@MESA_SOURCE@/src/mesa/glapi \ - \ + $(DIX_CFLAGS) \ -DHAVE_XGL_CONFIG_H \ -DHAVE_DIX_CONFIG_H \ $(XGLXMODULES_CFLAGS) diff --git a/hw/xgl/glx/module/Makefile.am b/hw/xgl/glx/module/Makefile.am index 846942a43..bd1c4b08f 100644 --- a/hw/xgl/glx/module/Makefile.am +++ b/hw/xgl/glx/module/Makefile.am @@ -2,7 +2,7 @@ if GLX GLX_LIB = $(top_builddir)/hw/xgl/glxext/libxglglxext.la endif -AM_CFLAGS = \ +AM_CFLAGS = $(DIX_CFLAGS) \ -I$(srcdir)/.. \ -I$(srcdir)/../.. \ $(XGLXMODULES_CFLAGS) diff --git a/hw/xgl/glxext/Makefile.am b/hw/xgl/glxext/Makefile.am index c400f364a..98a9b13c4 100644 --- a/hw/xgl/glxext/Makefile.am +++ b/hw/xgl/glxext/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = module AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -DHAVE_XGL_CONFIG_H \ -DHAVE_DIX_CONFIG_H \ $(XGLMODULES_CFLAGS) \ diff --git a/hw/xgl/glxext/module/Makefile.am b/hw/xgl/glxext/module/Makefile.am index 82c4211d8..4633f7ffa 100644 --- a/hw/xgl/glxext/module/Makefile.am +++ b/hw/xgl/glxext/module/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = \ - \ + $(DIX_CFLAGS) \ -DHAVE_XGL_CONFIG_H \ -DHAVE_DIX_CONFIG_H \ $(XGLMODULES_CFLAGS) \ diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index dbbcb0545..57e20102e 100644 --- a/hw/xwin/Makefile.am +++ b/hw/xwin/Makefile.am @@ -161,7 +161,7 @@ CLEANFILES = $(BUILT_SOURCES) AM_YFLAGS = -d AM_LFLAGS = -i -AM_CFLAGS = -DHAVE_XWIN_CONFIG_H \ +AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ $(XWINMODULES_CFLAGS) dist_man1_MANS = XWin.man XWinrc.man -- cgit v1.2.3 From ec77a95a02329a2ee3a94d7de9d2a234aecb9ca0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 8 Nov 2006 21:36:35 -0800 Subject: Allow RandR objects to be created before the associated ScreenRec. xf86 drivers need to create RandR object in the PreInit stage, before the ScreenRec is allocated. Changing the RandR DIX code to permit this required the addition of functions that later associate the objects with the related screen. An additional change is that modes are now global, and no longer associated with a specific screen. This change actually makes mode management cleaner as there is no more per-screen list of modes to deal with. This changes the RandR 1.2 ABI/API for drivers. --- hw/xfree86/common/Makefile.am | 2 +- randr/mirandr.c | 13 +++- randr/randr.c | 4 - randr/randrstr.h | 36 ++++++--- randr/rrcrtc.c | 170 +++++++++++++++++++++++++----------------- randr/rrinfo.c | 14 +++- randr/rrmode.c | 108 +++++++++++++++------------ randr/rroutput.c | 44 ++++++----- randr/rrscreen.c | 32 +++++--- 9 files changed, 254 insertions(+), 169 deletions(-) diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 0e1582e69..35b22f007 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -51,7 +51,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \ xf86PciInfo.h xf86Priv.h xf86Privstr.h xf86Resources.h \ xf86cmap.h xf86fbman.h xf86str.h $(XISDKINCS) \ $(XVSDKINCS) atKeynames.h xf86Version.h xorgVersion.h \ - xf86sbusBus.h xf86xv.h xf86xvmc.h xf86xvpriv.h + xf86sbusBus.h xf86xv.h xf86xvmc.h xf86xvpriv.h xf86Keymap.h DISTCLEANFILES = xf86Build.h CLEANFILES = $(BUILT_SOURCES) diff --git a/randr/mirandr.c b/randr/mirandr.c index 11c299133..3f56fe42e 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -113,17 +113,24 @@ miRandRInit (ScreenPtr pScreen) modeInfo.height = pScreen->height; modeInfo.nameLength = strlen (name); - mode = RRModeGet (pScreen, &modeInfo, name); + mode = RRModeGet (&modeInfo, name); if (!mode) return FALSE; - crtc = RRCrtcCreate (pScreen, NULL); + crtc = RRCrtcCreate (NULL); if (!crtc) return FALSE; + if (!RRCrtcAttachScreen (crtc, pScreen)) + { + RRCrtcDestroy (crtc); + return FALSE; + } - output = RROutputCreate (pScreen, "screen", 6, NULL); + output = RROutputCreate ("screen", 6, NULL); if (!output) return FALSE; + if (!RROutputAttachScreen (output, pScreen)) + return FALSE; if (!RROutputSetClones (output, NULL, 0)) return FALSE; if (!RROutputSetModes (output, &mode, 1, 0)) diff --git a/randr/randr.c b/randr/randr.c index 7b39e8045..4426c4773 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -103,8 +103,6 @@ RRCloseScreen (int i, ScreenPtr pScreen) RRCrtcDestroy (pScrPriv->crtcs[j]); for (j = pScrPriv->numOutputs - 1; j >= 0; j--) RROutputDestroy (pScrPriv->outputs[j]); - for (j = pScrPriv->numModes - 1; j >= 0; j--) - RRModeDestroy (pScrPriv->modes[j]); xfree (pScrPriv); RRNScreens -= 1; /* ok, one fewer screen with RandR running */ @@ -257,8 +255,6 @@ Bool RRScreenInit(ScreenPtr pScreen) wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen); - pScrPriv->numModes = 0; - pScrPriv->modes = NULL; pScrPriv->numOutputs = 0; pScrPriv->outputs = NULL; pScrPriv->numCrtcs = 0; diff --git a/randr/randrstr.h b/randr/randrstr.h index 60877a3c1..345418b8f 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -79,7 +79,6 @@ struct _rrMode { xRRModeInfo mode; char *name; void *devPrivate; - ScreenPtr screen; Bool userDefined; }; @@ -210,10 +209,6 @@ typedef struct _rrScrPriv { CARD16 width, height; /* last known screen size */ Bool layoutChanged; /* screen layout changed */ - /* modes, outputs and crtcs */ - int numModes; - RRModePtr *modes; - int numOutputs; RROutputPtr *outputs; @@ -457,9 +452,16 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged); * Create a CRTC */ RRCrtcPtr -RRCrtcCreate (ScreenPtr pScreen, - void *devPrivate); +RRCrtcCreate (void *devPrivate); +/* + * Attach a CRTC to a screen. Once done, this cannot be + * undone without destroying the CRTC; it is separate from Create + * only to allow an xf86-based driver to create objects in preinit + */ +Bool +RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen); + /* * Notify the extension that the Crtc has been reconfigured, * the driver calls this whenever it has updated the mode @@ -556,8 +558,7 @@ RRClientKnowsRates (ClientPtr pClient); */ RRModePtr -RRModeGet (ScreenPtr pScreen, - xRRModeInfo *modeInfo, +RRModeGet (xRRModeInfo *modeInfo, const char *name); void @@ -570,6 +571,12 @@ RRModePruneUnused (ScreenPtr pScreen); void RRModeDestroy (RRModePtr mode); +/* + * Return a list of modes that are valid for some output in pScreen + */ +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret); + /* * Initialize mode type */ @@ -601,11 +608,18 @@ RROutputChanged (RROutputPtr output); */ RROutputPtr -RROutputCreate (ScreenPtr pScreen, - const char *name, +RROutputCreate (const char *name, int nameLength, void *devPrivate); +/* + * Attach an output to a screen, again split from creation so + * xf86 DDXen can create randr resources before the ScreenRec + * exists + */ +Bool +RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen); + /* * Notify extension that output parameters have been changed */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 76d0b6bf5..9f7177a34 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -32,43 +32,34 @@ void RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged) { ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(pScreen); crtc->changed = TRUE; - pScrPriv->changed = TRUE; - /* - * Send ConfigureNotify on any layout change - */ - if (layoutChanged) - pScrPriv->layoutChanged = 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) +RRCrtcCreate (void *devPrivate) { - rrScrPriv (pScreen); RRCrtcPtr crtc; - RRCrtcPtr *crtcs; crtc = xalloc (sizeof (RRCrtcRec)); if (!crtc) return NULL; - if (pScrPriv->numCrtcs) - crtcs = xrealloc (pScrPriv->crtcs, - (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); - else - crtcs = xalloc (sizeof (RRCrtcPtr)); - if (!crtcs) - { - xfree (crtc); - return NULL; - } crtc->id = FakeClientID (0); - crtc->pScreen = pScreen; + crtc->pScreen = NULL; crtc->mode = NULL; crtc->x = 0; crtc->y = 0; @@ -84,11 +75,37 @@ RRCrtcCreate (ScreenPtr pScreen, if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) return NULL; + return crtc; +} + +/* + * Attach a Crtc to a screen. This is done as a separate step + * so that an xf86-based driver can create CRTCs in PreInit + * before the Screen has been created + */ + +Bool +RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + RRCrtcPtr *crtcs; + + /* make space for the crtc pointer */ + if (pScrPriv->numCrtcs) + crtcs = xrealloc (pScrPriv->crtcs, + (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); + else + crtcs = xalloc (sizeof (RRCrtcPtr)); + if (!crtcs) + return FALSE; + + /* attach the screen and crtc together */ + crtc->pScreen = pScreen; pScrPriv->crtcs = crtcs; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; RRCrtcChanged (crtc, TRUE); - return crtc; + return TRUE; } /* @@ -243,7 +260,6 @@ RRCrtcSet (RRCrtcPtr crtc, RROutputConfigPtr outputs) { ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(pScreen); /* See if nothing changed */ if (crtc->mode == mode && @@ -255,45 +271,49 @@ RRCrtcSet (RRCrtcPtr crtc, { return TRUE; } -#if RANDR_12_INTERFACE - if (pScrPriv->rrCrtcSet) - { - return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, - rotation, numOutputs, outputs); - } -#endif -#if RANDR_10_INTERFACE - if (pScrPriv->rrSetConfig) + if (pScreen) { - RRScreenSize size; - RRScreenRate rate; - Bool ret; - - size.width = mode->mode.width; - size.height = mode->mode.height; - if (outputs[0].output->mmWidth && outputs[0].output->mmHeight) +#if RANDR_12_INTERFACE + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSet) { - size.mmWidth = outputs[0].output->mmWidth; - size.mmHeight = outputs[0].output->mmHeight; + return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, + rotation, numOutputs, outputs); } - else +#endif +#if RANDR_10_INTERFACE + if (pScrPriv->rrSetConfig) { - size.mmWidth = pScreen->mmWidth; - size.mmHeight = pScreen->mmHeight; + RRScreenSize size; + RRScreenRate rate; + Bool ret; + + size.width = mode->mode.width; + size.height = mode->mode.height; + if (outputs[0].output->mmWidth && outputs[0].output->mmHeight) + { + size.mmWidth = outputs[0].output->mmWidth; + size.mmHeight = outputs[0].output->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, 1, &outputs[0].output); + return ret; } - 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, 1, &outputs[0].output); - return ret; - } #endif - RRTellChanged (pScreen); + RRTellChanged (pScreen); + } return FALSE; } @@ -311,22 +331,26 @@ RRCrtcDestroyResource (pointer value, XID pid) { RRCrtcPtr crtc = (RRCrtcPtr) value; ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(pScreen); - int i; - for (i = 0; i < pScrPriv->numCrtcs; i++) + if (pScreen) { - if (pScrPriv->crtcs[i] == crtc) + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { - memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, - (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); - --pScrPriv->numCrtcs; - break; + if (pScrPriv->crtcs[i] == crtc) + { + memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1, + (pScrPriv->numCrtcs - (i - 1)) * sizeof (RRCrtcPtr)); + --pScrPriv->numCrtcs; + break; + } } } if (crtc->gammaRed) xfree (crtc->gammaRed); - xfree (value); + xfree (crtc); return 1; } @@ -343,15 +367,18 @@ RRCrtcGammaSet (RRCrtcPtr crtc, Bool ret = TRUE; #if RANDR_12_INTERFACE ScreenPtr pScreen = crtc->pScreen; - rrScrPriv(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 (pScrPriv->rrCrtcSetGamma) - ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc); + if (pScreen) + { + rrScrPriv(pScreen); + if (pScrPriv->rrCrtcSetGamma) + ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc); + } #endif return ret; } @@ -433,6 +460,9 @@ ProcRRGetCrtcInfo (ClientPtr client) if (!crtc) return RRErrorBase + BadRRCrtc; + /* All crtcs must be associated with screens before client + * requests are processed + */ pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); @@ -589,7 +619,7 @@ ProcRRSetCrtcConfig (ClientPtr client) for (j = 0; j < outputs[i].output->numCrtcs; j++) if (outputs[i].output->crtcs[j] == crtc) break; - if (j == outputs[j].output->numCrtcs) + if (j == outputs[i].output->numCrtcs) { if (outputs) xfree (outputs); diff --git a/randr/rrinfo.c b/randr/rrinfo.c index e92caadfa..244b089f3 100644 --- a/randr/rrinfo.c +++ b/randr/rrinfo.c @@ -44,7 +44,7 @@ RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh) modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height * (CARD32) refresh); modeInfo.nameLength = strlen (name); - mode = RRModeGet (pScreen, &modeInfo, name); + mode = RRModeGet (&modeInfo, name); if (!mode) return NULL; for (i = 0; i < output->numModes; i++) @@ -90,12 +90,19 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) if (pScrPriv->numOutputs == 0 && pScrPriv->numCrtcs == 0) { - crtc = RRCrtcCreate (pScreen, NULL); + crtc = RRCrtcCreate (NULL); if (!crtc) return; - output = RROutputCreate (pScreen, "default", 7, NULL); + if (!RRCrtcAttachScreen (crtc, pScreen)) + { + RRCrtcDestroy (crtc); + return; + } + output = RROutputCreate ("default", 7, NULL); if (!output) return; + if (!RROutputAttachScreen (output, pScreen)) + return; RROutputSetCrtcs (output, &crtc, 1); RROutputSetCrtc (output, crtc); RROutputSetConnection (output, RR_Connected); @@ -206,7 +213,6 @@ RRGetInfo (ScreenPtr pScreen) if (pScrPriv->nSizes) RRScanOldConfig (pScreen, rotations); #endif - RRModePruneUnused (pScreen); RRTellChanged (pScreen); return TRUE; } diff --git a/randr/rrmode.c b/randr/rrmode.c index fb4b5eb1e..3cd9ef273 100644 --- a/randr/rrmode.c +++ b/randr/rrmode.c @@ -42,19 +42,23 @@ RRModeEqual (xRRModeInfo *a, xRRModeInfo *b) return TRUE; } +/* + * Keep a list so it's easy to find modes in the resource database. + */ +static int num_modes; +static RRModePtr *modes; + RRModePtr -RRModeGet (ScreenPtr pScreen, - xRRModeInfo *modeInfo, +RRModeGet (xRRModeInfo *modeInfo, const char *name) { - rrScrPriv (pScreen); int i; RRModePtr mode; - RRModePtr *modes; + RRModePtr *newModes; - for (i = 0; i < pScrPriv->numModes; i++) + for (i = 0; i < num_modes; i++) { - mode = pScrPriv->modes[i]; + mode = modes[i]; if (RRModeEqual (&mode->mode, modeInfo) && !memcmp (name, mode->name, modeInfo->nameLength)) { @@ -71,16 +75,14 @@ RRModeGet (ScreenPtr pScreen, mode->name = (char *) (mode + 1); memcpy (mode->name, name, modeInfo->nameLength); mode->name[modeInfo->nameLength] = '\0'; - mode->screen = pScreen; mode->userDefined = FALSE; - if (pScrPriv->numModes) - modes = xrealloc (pScrPriv->modes, - (pScrPriv->numModes + 1) * sizeof (RRModePtr)); + if (num_modes) + newModes = xrealloc (modes, (num_modes + 1) * sizeof (RRModePtr)); else - modes = xalloc (sizeof (RRModePtr)); + newModes = xalloc (sizeof (RRModePtr)); - if (!modes) + if (!newModes) { xfree (mode); return NULL; @@ -89,37 +91,64 @@ RRModeGet (ScreenPtr pScreen, mode->mode.id = FakeClientID(0); if (!AddResource (mode->mode.id, RRModeType, (pointer) mode)) return NULL; + modes = newModes; + modes[num_modes++] = mode; + + /* + * give the caller a reference to this mode + */ ++mode->refcnt; - pScrPriv->modes = modes; - pScrPriv->modes[pScrPriv->numModes++] = mode; - pScrPriv->changed = TRUE; return mode; } +RRModePtr * +RRModesForScreen (ScreenPtr pScreen, int *num_ret) +{ + rrScrPriv(pScreen); + int o; + RRModePtr *screen_modes; + int num_screen_modes = 0; + + screen_modes = xalloc ((num_modes ? num_modes : 1) * sizeof (RRModePtr)); + + for (o = 0; o < pScrPriv->numOutputs; o++) + { + RROutputPtr output = pScrPriv->outputs[o]; + int m, n; + + for (m = 0; m < output->numModes; m++) + { + RRModePtr mode = output->modes[m]; + for (n = 0; n < num_screen_modes; n++) + if (screen_modes[n] == mode) + break; + if (n == num_screen_modes) + screen_modes[num_screen_modes++] = mode; + } + } + *num_ret = num_screen_modes; + return screen_modes; +} + void RRModeDestroy (RRModePtr mode) { - ScreenPtr pScreen; - rrScrPrivPtr pScrPriv; int m; if (--mode->refcnt > 0) return; - pScreen = mode->screen; - pScrPriv = rrGetScrPriv (pScreen); - for (m = 0; m < pScrPriv->numModes; m++) + for (m = 0; m < num_modes; m++) { - if (pScrPriv->modes[m] == mode) + if (modes[m] == mode) { - memmove (pScrPriv->modes + m, pScrPriv->modes + m + 1, - (pScrPriv->numModes - m - 1) * sizeof (RRModePtr)); - pScrPriv->numModes--; - if (!pScrPriv->numModes) + memmove (modes + m, modes + m + 1, + (num_modes - m - 1) * sizeof (RRModePtr)); + num_modes--; + if (!num_modes) { - xfree (pScrPriv->modes); - pScrPriv->modes = NULL; + xfree (modes); + modes = NULL; } - pScrPriv->changed = TRUE; break; } } @@ -137,6 +166,8 @@ RRModeDestroyResource (pointer value, XID pid) Bool RRModeInit (void) { + assert (num_modes == 0); + assert (modes == NULL); RRModeType = CreateNewResourceType (RRModeDestroyResource); if (!RRModeType) return FALSE; @@ -146,26 +177,6 @@ RRModeInit (void) return TRUE; } -void -RRModePruneUnused (ScreenPtr pScreen) -{ - rrScrPriv (pScreen); - RRModePtr *unused, mode; - int m; - int num = pScrPriv->numModes; - - unused = xalloc (num * sizeof (RRModePtr)); - if (!unused) - return; - memcpy (unused, pScrPriv->modes, num * sizeof (RRModePtr)); - for (m = 0; m < num; m++) { - mode = unused[m]; - if (mode->refcnt == 1 && !mode->userDefined) - FreeResource (mode->mode.id, 0); - } - xfree (unused); -} - int ProcRRCreateMode (ClientPtr client) { @@ -205,4 +216,3 @@ ProcRRDeleteOutputMode (ClientPtr client) (void) stuff; return BadImplementation; } - diff --git a/randr/rroutput.c b/randr/rroutput.c index 1f6f33030..1b0ecab93 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -42,30 +42,17 @@ RROutputChanged (RROutputPtr output) */ RROutputPtr -RROutputCreate (ScreenPtr pScreen, - const char *name, +RROutputCreate (const char *name, int nameLength, void *devPrivate) { - rrScrPriv (pScreen); RROutputPtr output; - RROutputPtr *outputs; output = xalloc (sizeof (RROutputRec) + nameLength + 1); if (!output) return NULL; - if (pScrPriv->numOutputs) - outputs = xrealloc (pScrPriv->outputs, - (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); - else - outputs = xalloc (sizeof (RROutputPtr)); - if (!outputs) - { - xfree (output); - return NULL; - } output->id = FakeClientID (0); - output->pScreen = pScreen; + output->pScreen = NULL; output->name = (char *) (output + 1); output->nameLength = nameLength; memcpy (output->name, name, nameLength); @@ -91,12 +78,35 @@ RROutputCreate (ScreenPtr pScreen, if (!AddResource (output->id, RROutputType, (pointer) output)) return NULL; + return output; +} + +/* + * Attach an Output to a screen. This is done as a separate step + * so that an xf86-based driver can create Outputs in PreInit + * before the Screen has been created + */ + +Bool +RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen) +{ + rrScrPriv (pScreen); + RROutputPtr *outputs; + + if (pScrPriv->numOutputs) + outputs = xrealloc (pScrPriv->outputs, + (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr)); + else + outputs = xalloc (sizeof (RROutputPtr)); + if (!outputs) + return FALSE; + output->pScreen = pScreen; pScrPriv->outputs = outputs; pScrPriv->outputs[pScrPriv->numOutputs++] = output; RROutputChanged (output); - return output; + return TRUE; } - + /* * Notify extension that output parameters have been changed */ diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 705e7d78c..d47e9d60a 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -360,6 +360,13 @@ ProcRRGetScreenResources (ClientPtr client) } else { + RRModePtr *modes; + int num_modes; + + modes = RRModesForScreen (pScreen, &num_modes); + if (!modes) + return BadAlloc; + rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; @@ -367,15 +374,15 @@ ProcRRGetScreenResources (ClientPtr client) rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds; rep.nCrtcs = pScrPriv->numCrtcs; rep.nOutputs = pScrPriv->numOutputs; - rep.nModes = pScrPriv->numModes;; + rep.nModes = num_modes; rep.nbytesNames = 0; - for (i = 0; i < pScrPriv->numModes; i++) - rep.nbytesNames += pScrPriv->modes[i]->mode.nameLength; + for (i = 0; i < num_modes; i++) + rep.nbytesNames += modes[i]->mode.nameLength; rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs + - pScrPriv->numModes * (SIZEOF(xRRModeInfo) >> 2) + + num_modes * (SIZEOF(xRRModeInfo) >> 2) + ((rep.nbytesNames + 3) >> 2)); extraLen = rep.length << 2; @@ -383,7 +390,10 @@ ProcRRGetScreenResources (ClientPtr client) { extra = xalloc (extraLen); if (!extra) + { + xfree (modes); return BadAlloc; + } } else extra = NULL; @@ -391,7 +401,7 @@ ProcRRGetScreenResources (ClientPtr client) crtcs = (RRCrtc *) extra; outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs); modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs); - names = (CARD8 *) (modeinfos + pScrPriv->numModes); + names = (CARD8 *) (modeinfos + num_modes); for (i = 0; i < pScrPriv->numCrtcs; i++) { @@ -407,9 +417,10 @@ ProcRRGetScreenResources (ClientPtr client) swapl (&outputs[i], n); } - for (i = 0; i < pScrPriv->numModes; i++) + for (i = 0; i < num_modes; i++) { - modeinfos[i] = pScrPriv->modes[i]->mode; + RRModePtr mode = modes[i]; + modeinfos[i] = mode->mode; if (client->swapped) { swapl (&modeinfos[i].id, n); @@ -426,10 +437,11 @@ ProcRRGetScreenResources (ClientPtr client) swaps (&modeinfos[i].nameLength, n); swapl (&modeinfos[i].modeFlags, n); } - memcpy (names, pScrPriv->modes[i]->name, - pScrPriv->modes[i]->mode.nameLength); - names += pScrPriv->modes[i]->mode.nameLength; + memcpy (names, mode->name, + mode->mode.nameLength); + names += mode->mode.nameLength; } + xfree (modes); assert (((((char *) names - (char *) extra) + 3) >> 2) == rep.length); } -- cgit v1.2.3 From 0dee48b8af3e054228aef0d15c1cb1c9e23790cc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 8 Nov 2006 23:17:55 -0800 Subject: Add RRInit function to create resource types for RR objects. To allow RandR objects to be created before the screen object exists, the resource types must be registered with the resource database. A driver wishing to create RandR objects must call RRInit before doing so. Also, fix a segfault when setting Output data before it is associated with a screen. --- randr/randr.c | 27 +++++++++++++++++++++------ randr/randrstr.h | 2 ++ randr/rroutput.c | 30 ++++++++++++++++++------------ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 4426c4773..147df8c2c 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -39,8 +39,7 @@ #endif #define RR_VALIDATE -int RRGeneration; -int RRNScreens; +static int RRNScreens; #define wrap(priv,real,mem,func) {\ priv->mem = real->mem; \ @@ -198,10 +197,10 @@ SRRNotifyEvent (xEvent *from, } } -Bool RRScreenInit(ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; +static int RRGeneration; +Bool RRInit (void) +{ if (RRGeneration != serverGeneration) { if (!RRModeInit ()) @@ -210,9 +209,25 @@ Bool RRScreenInit(ScreenPtr pScreen) return FALSE; if (!RROutputInit ()) return FALSE; + RRGeneration = serverGeneration; + } + return TRUE; +} + +static int RRScreenGeneration; + +Bool RRScreenInit(ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRInit ()) + return FALSE; + + if (RRScreenGeneration != serverGeneration) + { if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0) return FALSE; - RRGeneration = serverGeneration; + RRScreenGeneration = serverGeneration; } pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec)); diff --git a/randr/randrstr.h b/randr/randrstr.h index 345418b8f..2c3e0e71c 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -384,6 +384,8 @@ RRTellChanged (ScreenPtr pScreen); Bool RRGetInfo (ScreenPtr pScreen); +Bool RRInit (void); + Bool RRScreenInit(ScreenPtr pScreen); RROutputPtr diff --git a/randr/rroutput.c b/randr/rroutput.c index 1b0ecab93..102587b50 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -31,10 +31,13 @@ void RROutputChanged (RROutputPtr output) { ScreenPtr pScreen = output->pScreen; - rrScrPriv (pScreen); - + output->changed = TRUE; - pScrPriv->changed = TRUE; + if (pScreen) + { + rrScrPriv (pScreen); + pScrPriv->changed = TRUE; + } } /* @@ -335,17 +338,21 @@ RROutputDestroyResource (pointer value, XID pid) { RROutputPtr output = (RROutputPtr) value; ScreenPtr pScreen = output->pScreen; - rrScrPriv(pScreen); - int i; - for (i = 0; i < pScrPriv->numOutputs; i++) + if (pScreen) { - if (pScrPriv->outputs[i] == output) + rrScrPriv(pScreen); + int i; + + for (i = 0; i < pScrPriv->numOutputs; i++) { - memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, - (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); - --pScrPriv->numOutputs; - break; + if (pScrPriv->outputs[i] == output) + { + memmove (pScrPriv->outputs + i, pScrPriv->outputs + i + 1, + (pScrPriv->numOutputs - (i - 1)) * sizeof (RROutputPtr)); + --pScrPriv->numOutputs; + break; + } } } if (output->modes) @@ -481,4 +488,3 @@ ProcRRGetOutputInfo (ClientPtr client) return client->noClientException; } - -- cgit v1.2.3 From 6ff7f2ad6a5e2e769244590578e6809974b5235d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 7 Nov 2006 13:13:53 -0800 Subject: Fix build on FreeBSD after input-hotplug. (cherry picked from commit 4e6e4baead6c565363abbcd9e06cc685be121596) --- hw/xfree86/os-support/bsd/bsd_bell.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xfree86/os-support/bsd/bsd_bell.c b/hw/xfree86/os-support/bsd/bsd_bell.c index 60c2ffc8b..b7a0c486e 100644 --- a/hw/xfree86/os-support/bsd/bsd_bell.c +++ b/hw/xfree86/os-support/bsd/bsd_bell.c @@ -27,10 +27,15 @@ #include #endif +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) +#include +#endif + #include #include "xf86.h" #include "xf86Priv.h" +#include "xf86_OSlib.h" #ifdef WSCONS_SUPPORT #define KBD_FD(i) ((i).kbdFd != -1 ? (i).kbdFd : (i).consoleFd) -- cgit v1.2.3 From 07b26e690cd9a4fc626132feed0702515cbe5a88 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Nov 2006 09:48:33 -0800 Subject: Remove RandR output options. RandR output options are now expected to be handled by properties instead. (cherry picked from commit 8b2a7e94a1dc2776ab2cfaaebb309be02502602a) --- randr/mirandr.c | 6 +----- randr/randrstr.h | 24 +++--------------------- randr/rrcrtc.c | 46 +++++++++++++++++++--------------------------- randr/rroutput.c | 29 ----------------------------- randr/rrscreen.c | 13 ++++++------- 5 files changed, 29 insertions(+), 89 deletions(-) diff --git a/randr/mirandr.c b/randr/mirandr.c index 3f56fe42e..3a99bf9ed 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -52,7 +52,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputConfigPtr outputs) + RROutputPtr *outputs) { return TRUE; } @@ -137,10 +137,6 @@ miRandRInit (ScreenPtr pScreen) return FALSE; if (!RROutputSetCrtcs (output, &crtc, 1)) return FALSE; - if (!RROutputSetPossibleOptions (output, 0)) - return FALSE; - if (!RROutputSetCurrentOptions (output, 0)) - return FALSE; if (!RROutputSetConnection (output, RR_Connected)) return FALSE; RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output); diff --git a/randr/randrstr.h b/randr/randrstr.h index 2c3e0e71c..19af9b979 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -72,7 +72,6 @@ extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr); typedef struct _rrMode RRModeRec, *RRModePtr; typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr; typedef struct _rrOutput RROutputRec, *RROutputPtr; -typedef struct _rrOutputConfig RROutputConfigRec, *RROutputConfigPtr; struct _rrMode { int refcnt; @@ -109,8 +108,6 @@ struct _rrOutput { int mmWidth; int mmHeight; RRCrtcPtr crtc; - CARD32 currentOptions; - CARD32 possibleOptions; int numCrtcs; RRCrtcPtr *crtcs; int numClones; @@ -123,11 +120,6 @@ struct _rrOutput { void *devPrivate; }; -struct _rrOutputConfig { - RROutputPtr output; - CARD32 options; -}; - #if RANDR_12_INTERFACE typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen, CARD16 width, @@ -142,7 +134,7 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen, int y, Rotation rotation, int numOutputs, - RROutputConfigPtr outputs); + RROutputPtr *outputs); typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc); @@ -369,7 +361,7 @@ miRRCrtcSet (ScreenPtr pScreen, int y, Rotation rotation, int numOutput, - RROutputConfigPtr outputs); + RROutputPtr *outputs); /* randr.c */ /* @@ -490,7 +482,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutput, - RROutputConfigPtr outputs); + RROutputPtr *outputs); /* * Request that the Crtc gamma be changed @@ -641,10 +633,6 @@ RROutputSetCrtcs (RROutputPtr output, RRCrtcPtr *crtcs, int numCrtcs); -Bool -RROutputSetPossibleOptions (RROutputPtr output, - CARD32 possibleOptions); - void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc); @@ -656,10 +644,6 @@ Bool RROutputSetSubpixelOrder (RROutputPtr output, int subpixelOrder); -Bool -RROutputSetCurrentOptions (RROutputPtr output, - CARD32 currentOptions); - Bool RROutputSetPhysicalSize (RROutputPtr output, int mmWidth, @@ -739,8 +723,6 @@ Query state: RRScreenSetSizeRange RROutputSetCrtcs RROutputSetCrtc - RROutputSetPossibleOptions - RRSetCurrentOptions RRModeGet RROutputSetModes RROutputSetConnection diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 9f7177a34..c945468bf 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -257,7 +257,7 @@ RRCrtcSet (RRCrtcPtr crtc, int y, Rotation rotation, int numOutputs, - RROutputConfigPtr outputs) + RROutputPtr *outputs) { ScreenPtr pScreen = crtc->pScreen; @@ -290,10 +290,10 @@ RRCrtcSet (RRCrtcPtr crtc, size.width = mode->mode.width; size.height = mode->mode.height; - if (outputs[0].output->mmWidth && outputs[0].output->mmHeight) + if (outputs[0]->mmWidth && outputs[0]->mmHeight) { - size.mmWidth = outputs[0].output->mmWidth; - size.mmHeight = outputs[0].output->mmHeight; + size.mmWidth = outputs[0]->mmWidth; + size.mmHeight = outputs[0]->mmHeight; } else { @@ -308,7 +308,7 @@ RRCrtcSet (RRCrtcPtr crtc, * Old 1.0 interface tied screen size to mode size */ if (ret) - RRCrtcNotify (crtc, mode, x, y, rotation, 1, &outputs[0].output); + RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs); return ret; } #endif @@ -554,15 +554,15 @@ ProcRRSetCrtcConfig (ClientPtr client) RRCrtcPtr crtc; RRModePtr mode; int numOutputs; - RROutputConfigPtr outputs = NULL; - xRROutputConfig *outputConfigs; + RROutputPtr *outputs = NULL; + RROutput *outputIds; TimeStamp configTime; TimeStamp time; Rotation rotation; int i, j; REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq); - numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)) >> 1; + numOutputs = (stuff->length - (SIZEOF (xRRSetCrtcConfigReq) >> 2)); crtc = LookupIDByType (stuff->crtc, RRCrtcType); if (!crtc) @@ -589,47 +589,39 @@ ProcRRSetCrtcConfig (ClientPtr client) } if (numOutputs) { - outputs = xalloc (numOutputs * sizeof (RROutputConfigRec)); + outputs = xalloc (numOutputs * sizeof (RROutputPtr)); if (!outputs) return BadAlloc; } else outputs = NULL; - outputConfigs = (xRROutputConfig *) (stuff + 1); + outputIds = (RROutput *) (stuff + 1); for (i = 0; i < numOutputs; i++) { - outputs[i].output = LookupIDByType (outputConfigs[i].output, RROutputType); - if (!outputs[i].output) + outputs[i] = (RROutputPtr) LookupIDByType (outputIds[i], RROutputType); + if (!outputs[i]) { - client->errorValue = outputConfigs[i].output; + client->errorValue = outputIds[i]; if (outputs) xfree (outputs); return RRErrorBase + BadRROutput; } - outputs[i].options = outputConfigs[i].options; - if (outputs[i].options & ~outputs[i].output->possibleOptions) - { - client->errorValue = outputConfigs[i].options; - if (outputs) - xfree (outputs); - return BadMatch; - } /* validate crtc for this output */ - for (j = 0; j < outputs[i].output->numCrtcs; j++) - if (outputs[i].output->crtcs[j] == crtc) + for (j = 0; j < outputs[i]->numCrtcs; j++) + if (outputs[i]->crtcs[j] == crtc) break; - if (j == outputs[i].output->numCrtcs) + if (j == outputs[i]->numCrtcs) { if (outputs) xfree (outputs); return BadMatch; } /* validate mode for this output */ - for (j = 0; j < outputs[i].output->numModes; j++) - if (outputs[i].output->modes[j] == mode) + for (j = 0; j < outputs[i]->numModes; j++) + if (outputs[i]->modes[j] == mode) break; - if (j == outputs[i].output->numModes) + if (j == outputs[i]->numModes) { if (outputs) xfree (outputs); diff --git a/randr/rroutput.c b/randr/rroutput.c index 102587b50..8b760ec9a 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -65,8 +65,6 @@ RROutputCreate (const char *name, output->mmWidth = 0; output->mmHeight = 0; output->crtc = NULL; - output->currentOptions = 0; - output->possibleOptions = 0; output->numCrtcs = 0; output->crtcs = NULL; output->numClones = 0; @@ -223,17 +221,6 @@ RROutputSetCrtcs (RROutputPtr output, return TRUE; } -Bool -RROutputSetPossibleOptions (RROutputPtr output, - CARD32 possibleOptions) -{ - if (output->possibleOptions == possibleOptions) - return TRUE; - output->possibleOptions = possibleOptions; - RROutputChanged (output); - return TRUE; -} - void RROutputSetCrtc (RROutputPtr output, RRCrtcPtr crtc) { @@ -266,17 +253,6 @@ RROutputSetSubpixelOrder (RROutputPtr output, return TRUE; } -Bool -RROutputSetCurrentOptions (RROutputPtr output, - CARD32 currentOptions) -{ - if (output->currentOptions == currentOptions) - return TRUE; - output->currentOptions = currentOptions; - RROutputChanged (output); - return TRUE; -} - Bool RROutputSetPhysicalSize (RROutputPtr output, int mmWidth, @@ -413,7 +389,6 @@ ProcRRGetOutputInfo (ClientPtr client) rep.length = OutputInfoExtra >> 2; rep.timestamp = pScrPriv->lastSetTime.milliseconds; rep.crtc = output->crtc ? output->crtc->id : None; - rep.currentOptions = output->currentOptions; rep.mmWidth = output->mmWidth; rep.mmHeight = output->mmHeight; rep.connection = output->connection; @@ -423,7 +398,6 @@ ProcRRGetOutputInfo (ClientPtr client) rep.nPreferred = output->numPreferred; rep.nClones = output->numClones; rep.nameLength = output->nameLength; - rep.possibleOptions = output->possibleOptions; extraLen = ((output->numCrtcs + output->numModes + @@ -469,15 +443,12 @@ ProcRRGetOutputInfo (ClientPtr client) swapl(&rep.length, n); swapl(&rep.timestamp, n); swapl(&rep.crtc, n); - swapl(&rep.currentOptions, n); swapl(&rep.mmWidth, n); swapl(&rep.mmHeight, n); swaps(&rep.nCrtcs, n); swaps(&rep.nModes, n); swaps(&rep.nClones, n); - swapl(&rep.possibleOptions, n); swaps(&rep.nameLength, n); - swapl(&rep.possibleOptions, n); } WriteToClient(client, sizeof(xRRGetOutputInfoReply), (char *)&rep); if (extraLen) diff --git a/randr/rrscreen.c b/randr/rrscreen.c index d47e9d60a..76c16b010 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -712,7 +712,7 @@ ProcRRSetScreenConfig (ClientPtr client) Rotation rotation; int rate; Bool has_rate; - RROutputConfigRec output; + RROutputPtr output; RRModePtr mode; RR10DataPtr pData = NULL; RRScreenSizePtr pSize; @@ -749,14 +749,13 @@ ProcRRSetScreenConfig (ClientPtr client) if (!RRGetInfo (pScreen)) return BadAlloc; - output.output = RRFirstOutput (pScreen); - if (!output.output) + output = RRFirstOutput (pScreen); + if (!output) { time = currentTime; rep.status = RRSetConfigFailed; goto sendReply; } - output.options = output.output->currentOptions; /* * if the client's config timestamp is not the same as the last config @@ -769,7 +768,7 @@ ProcRRSetScreenConfig (ClientPtr client) goto sendReply; } - pData = RR10GetData (pScreen, output.output); + pData = RR10GetData (pScreen, output); if (!pData) return BadAlloc; @@ -805,7 +804,7 @@ ProcRRSetScreenConfig (ClientPtr client) return BadValue; } - if ((~output.output->crtc->rotations) & rotation) + if ((~output->crtc->rotations) & rotation) { /* * requested rotation or reflection not supported by screen @@ -878,7 +877,7 @@ ProcRRSetScreenConfig (ClientPtr client) } } - rep.status = RRCrtcSet (output.output->crtc, mode, 0, 0, stuff->rotation, + rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation, 1, &output); /* -- cgit v1.2.3 From ef47d9c3ba63e9a6243fe5c81ccc60c8246352b4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Nov 2006 13:50:48 -0800 Subject: Reduce calls to RRGetInfo. RRGetInfo can be expensive. Don't invoke it when quering Xinerama information or setting a new CRTC configuration. (cherry picked from commit b5aa9eb8e6eda36856a075f4b008c33f6c706bad) --- randr/rrcrtc.c | 7 ------- randr/rrxinerama.c | 6 +++++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index c945468bf..b81c390f1 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -632,13 +632,6 @@ ProcRRSetCrtcConfig (ClientPtr client) pScreen = crtc->pScreen; pScrPriv = rrGetScrPriv(pScreen); - if (!RRGetInfo (pScreen)) - { - if (outputs) - xfree (outputs); - return BadAlloc; - } - time = ClientTimeToServerTime(stuff->timestamp); configTime = ClientTimeToServerTime(stuff->configTimestamp); diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index a8e4b390b..771ed0976 100644 --- a/randr/rrxinerama.c +++ b/randr/rrxinerama.c @@ -260,7 +260,11 @@ ProcRRXineramaQueryScreens(ClientPtr client) REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); if (RRXineramaScreenActive (pScreen)) - RRGetInfo (pScreen); + { + rrScrPriv(pScreen); + if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0) + RRGetInfo (pScreen); + } rep.type = X_Reply; rep.sequenceNumber = client->sequence; -- cgit v1.2.3 From d6cd0313c7f23f32c9c7dda00ff739e772bf7db3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 27 Nov 2006 14:46:50 -0800 Subject: Add some mode helper functions from the intel driver. This also removes static from some other functions that had been copied out to at least the intel driver, but perhaps others that were doing mode list handling. --- hw/xfree86/common/xf86.h | 8 +++ hw/xfree86/common/xf86Mode.c | 129 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 119 insertions(+), 18 deletions(-) diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 458750007..57284c151 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -414,6 +414,14 @@ void xf86PruneDriverModes(ScrnInfoPtr scrp); void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags); void xf86PrintModes(ScrnInfoPtr scrp); void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges); +double xf86ModeHSync(DisplayModePtr mode); +double xf86ModeVRefresh(DisplayModePtr mode); +void xf86SetModeDefaultName(DisplayModePtr mode); +void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); +DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode); +DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList); +Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); +void xf86PrintModeline(int scrnIndex,DisplayModePtr mode); /* xf86Option.c */ diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index cd57e9916..6dccf2493 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -366,8 +366,9 @@ xf86HandleBuiltinMode(ScrnInfoPtr scrp, return MODE_OK; } -static double -ModeHSync(DisplayModePtr mode) +/** Calculates the horizontal sync rate of a mode */ +_X_EXPORT double +xf86ModeHSync(DisplayModePtr mode) { double hsync = 0.0; @@ -379,8 +380,9 @@ ModeHSync(DisplayModePtr mode) return hsync; } -static double -ModeVRefresh(DisplayModePtr mode) +/** Calculates the vertical refresh rate of a mode */ +_X_EXPORT double +xf86ModeVRefresh(DisplayModePtr mode) { double refresh = 0.0; @@ -398,6 +400,16 @@ ModeVRefresh(DisplayModePtr mode) return refresh; } +/** Sets a default mode name of x on a mode. */ +_X_EXPORT void +xf86SetModeDefaultName(DisplayModePtr mode) +{ + if (mode->name != NULL) + xfree(mode->name); + + mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay); +} + /* * xf86LookupMode * @@ -522,7 +534,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, ModePrivFlags = cp->PrivFlags; break; } - refresh = ModeVRefresh(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) refresh /= INTERLACE_REFRESH_WEIGHT; if (refresh > bestRefresh) { @@ -561,7 +573,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, found = TRUE; if (strategy == LOOKUP_BEST_REFRESH) { - refresh = ModeVRefresh(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) refresh /= INTERLACE_REFRESH_WEIGHT; if (refresh > bestRefresh) { @@ -662,7 +674,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, * Initialises the Crtc parameters for a mode. The initialisation includes * adjustments for interlaced and double scan modes. */ -static void +_X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) { if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) @@ -744,6 +756,87 @@ xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) } } +/** + * Allocates and returns a copy of pMode, including pointers within pMode. + */ +_X_EXPORT DisplayModePtr +xf86DuplicateMode(DisplayModePtr pMode) +{ + DisplayModePtr pNew; + + pNew = xnfalloc(sizeof(DisplayModeRec)); + *pNew = *pMode; + pNew->next = NULL; + pNew->prev = NULL; + if (pNew->name == NULL) { + xf86SetModeDefaultName(pMode); + } else { + pNew->name = xnfstrdup(pMode->name); + } + + return pNew; +} + +/** + * Duplicates every mode in the given list and returns a pointer to the first + * mode. + * + * \param modeList doubly-linked mode list + */ +_X_EXPORT DisplayModePtr +xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) +{ + DisplayModePtr first = NULL, last = NULL; + DisplayModePtr mode; + + for (mode = modeList; mode != NULL; mode = mode->next) { + DisplayModePtr new; + + new = xf86DuplicateMode(mode); + + /* Insert pNew into modeList */ + if (last) { + last->next = new; + new->prev = last; + } else { + first = new; + new->prev = NULL; + } + new->next = NULL; + last = new; + } + + return first; +} + +/** + * Returns true if the given modes should program to the same timings. + * + * This doesn't use Crtc values, as it might be used on ModeRecs without the + * Crtc values set. So, it's assumed that the other numbers are enough. + */ +_X_EXPORT Bool +xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) +{ + if (pMode1->Clock == pMode2->Clock && + pMode1->HDisplay == pMode2->HDisplay && + pMode1->HSyncStart == pMode2->HSyncStart && + pMode1->HSyncEnd == pMode2->HSyncEnd && + pMode1->HTotal == pMode2->HTotal && + pMode1->HSkew == pMode2->HSkew && + pMode1->VDisplay == pMode2->VDisplay && + pMode1->VSyncStart == pMode2->VSyncStart && + pMode1->VSyncEnd == pMode2->VSyncEnd && + pMode1->VTotal == pMode2->VTotal && + pMode1->VScan == pMode2->VScan && + pMode1->Flags == pMode2->Flags) + { + return TRUE; + } else { + return FALSE; + } +} + /* * xf86CheckModeForMonitor * @@ -802,7 +895,7 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) if (monitor->nHsync > 0) { /* Check hsync against the allowed ranges */ - float hsync = ModeHSync(mode); + float hsync = xf86ModeHSync(mode); for (i = 0; i < monitor->nHsync; i++) if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) && (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE))) @@ -815,7 +908,7 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) if (monitor->nVrefresh > 0) { /* Check vrefresh against the allowed ranges */ - float vrefrsh = ModeVRefresh(mode); + float vrefrsh = xf86ModeVRefresh(mode); for (i = 0; i < monitor->nVrefresh; i++) if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) && (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE))) @@ -1043,8 +1136,8 @@ xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, / (mode->CrtcHTotal * mode->CrtcVTotal); } - mode->HSync = ModeHSync(mode); - mode->VRefresh = ModeVRefresh(mode); + mode->HSync = xf86ModeHSync(mode); + mode->VRefresh = xf86ModeVRefresh(mode); /* Assume it is OK */ return MODE_OK; @@ -1683,7 +1776,7 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, "TargetRefresh", 0.0); if (targetRefresh > 0.0) { for (p = scrp->modePool; p != NULL; p = p->next) { - if (ModeVRefresh(p) > targetRefresh * (1.0 - SYNC_TOLERANCE)) + if (xf86ModeVRefresh(p) > targetRefresh * (1.0 - SYNC_TOLERANCE)) break; } if (!p) @@ -1772,7 +1865,7 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, * If there is a target refresh rate, skip modes that * don't match up. */ - if (ModeVRefresh(q) < + if (xf86ModeVRefresh(q) < (1.0 - SYNC_TOLERANCE) * targetRefresh) continue; @@ -2068,8 +2161,8 @@ add(char **p, char *new) strcat(*p, new); } -static void -PrintModeline(int scrnIndex,DisplayModePtr mode) +_X_EXPORT void +xf86PrintModeline(int scrnIndex,DisplayModePtr mode) { char tmp[256]; char *flags = xnfcalloc(1, 1); @@ -2124,8 +2217,8 @@ xf86PrintModes(ScrnInfoPtr scrp) do { desc = desc2 = ""; - hsync = ModeHSync(p); - refresh = ModeVRefresh(p); + hsync = xf86ModeHSync(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) { desc = " (I)"; } @@ -2166,7 +2259,7 @@ xf86PrintModes(ScrnInfoPtr scrp) p->SynthClock / 1000.0, hsync, refresh, desc, desc2); } if (hsync != 0 && refresh != 0) - PrintModeline(scrp->scrnIndex,p); + xf86PrintModeline(scrp->scrnIndex,p); p = p->next; } while (p != NULL && p != scrp->modes); } -- cgit v1.2.3