2003-11-14 17:48:57 +01:00
|
|
|
/*
|
2006-07-02 04:46:38 +02:00
|
|
|
* Copyright © 2000 Compaq Computer Corporation
|
|
|
|
* Copyright © 2002 Hewlett-Packard Company
|
|
|
|
* Copyright © 2006 Intel Corporation
|
2003-11-14 17:48:57 +01:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
2006-07-02 04:46:38 +02:00
|
|
|
* 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.
|
2003-11-14 17:48:57 +01:00
|
|
|
*
|
2006-07-02 04:46:38 +02:00
|
|
|
* 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.
|
2003-11-14 17:48:57 +01:00
|
|
|
*
|
2006-07-02 04:46:38 +02:00
|
|
|
* Author: Jim Gettys, Hewlett-Packard Company, Inc.
|
|
|
|
* Keith Packard, Intel Corporation
|
2003-11-14 17:48:57 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define NEED_REPLIES
|
|
|
|
#define NEED_EVENTS
|
2005-07-03 09:02:09 +02:00
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include <dix-config.h>
|
|
|
|
#endif
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#include "randrstr.h"
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
/* From render.h */
|
|
|
|
#ifndef SubPixelUnknown
|
|
|
|
#define SubPixelUnknown 0
|
|
|
|
#endif
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
#define RR_VALIDATE
|
|
|
|
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; \
|
|
|
|
real->mem = func; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define unwrap(priv,real,mem) {\
|
|
|
|
real->mem = priv->mem; \
|
|
|
|
}
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
#if 0
|
2003-11-14 17:48:57 +01:00
|
|
|
static CARD8 RRReqCode;
|
|
|
|
static int RRErrBase;
|
2003-11-25 20:29:01 +01:00
|
|
|
#endif
|
2006-09-17 08:21:37 +02:00
|
|
|
int RREventBase;
|
2003-11-14 17:48:57 +01:00
|
|
|
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 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,
|
|
|
|
pointer data)
|
|
|
|
{
|
|
|
|
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
|
|
|
ClientPtr pClient = clientinfo->client;
|
|
|
|
rrClientPriv(pClient);
|
|
|
|
RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pRRClient->major_version = 0;
|
|
|
|
pRRClient->minor_version = 0;
|
|
|
|
for (i = 0; i < screenInfo.numScreens; i++)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = screenInfo.screens[i];
|
|
|
|
rrScrPriv(pScreen);
|
|
|
|
|
|
|
|
if (pScrPriv)
|
|
|
|
{
|
|
|
|
pTimes[i].setTime = pScrPriv->lastSetTime;
|
|
|
|
pTimes[i].configTime = pScrPriv->lastConfigTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
RRResetProc (ExtensionEntry *extEntry)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
RRCloseScreen (int i, ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
rrScrPriv(pScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
int j;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
unwrap (pScrPriv, pScreen, CloseScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
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]);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
xfree (pScrPriv);
|
|
|
|
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
|
|
|
|
return (*pScreen->CloseScreen) (i, pScreen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
|
|
|
|
xRRScreenChangeNotifyEvent *to)
|
|
|
|
{
|
|
|
|
to->type = from->type;
|
|
|
|
to->rotation = from->rotation;
|
|
|
|
cpswaps(from->sequenceNumber, to->sequenceNumber);
|
|
|
|
cpswapl(from->timestamp, to->timestamp);
|
|
|
|
cpswapl(from->configTimestamp, to->configTimestamp);
|
|
|
|
cpswapl(from->root, to->root);
|
|
|
|
cpswapl(from->window, to->window);
|
|
|
|
cpswaps(from->sizeID, to->sizeID);
|
|
|
|
cpswaps(from->widthInPixels, to->widthInPixels);
|
|
|
|
cpswaps(from->heightInPixels, to->heightInPixels);
|
|
|
|
cpswaps(from->widthInMillimeters, to->widthInMillimeters);
|
|
|
|
cpswaps(from->heightInMillimeters, to->heightInMillimeters);
|
|
|
|
cpswaps(from->subpixelOrder, to->subpixelOrder);
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
2006-07-02 04:46:38 +02:00
|
|
|
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);
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
2006-07-02 04:46:38 +02:00
|
|
|
|
2006-07-17 07:21:11 +02:00
|
|
|
static void
|
|
|
|
SRRNotifyEvent (xEvent *from,
|
|
|
|
xEvent *to)
|
|
|
|
{
|
|
|
|
switch (from->u.u.detail) {
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
2006-07-17 07:21:11 +02:00
|
|
|
case RRNotify_MonitorChange:
|
|
|
|
SRRMonitorChangeNotifyEvent ((xRRMonitorChangeNotifyEvent *) from,
|
|
|
|
(xRRMonitorChangeNotifyEvent *) to);
|
|
|
|
break;
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
2006-07-17 07:21:11 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
Bool RRScreenInit(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
rrScrPrivPtr pScrPriv;
|
|
|
|
|
|
|
|
if (RRGeneration != serverGeneration)
|
|
|
|
{
|
2006-09-17 08:21:37 +02:00
|
|
|
if (!RRModeInit ())
|
2006-09-17 06:44:42 +02:00
|
|
|
return FALSE;
|
2006-09-17 08:21:37 +02:00
|
|
|
if (!RRCrtcInit ())
|
2006-09-17 06:44:42 +02:00
|
|
|
return FALSE;
|
2006-09-17 08:21:37 +02:00
|
|
|
if (!RROutputInit ())
|
2006-09-17 06:44:42 +02:00
|
|
|
return FALSE;
|
2003-11-14 17:48:57 +01:00
|
|
|
if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
|
|
|
|
return FALSE;
|
|
|
|
RRGeneration = serverGeneration;
|
|
|
|
}
|
|
|
|
|
|
|
|
pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
|
|
|
|
if (!pScrPriv)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
SetRRScreen(pScreen, pScrPriv);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calling function best set these function vectors
|
|
|
|
*/
|
|
|
|
pScrPriv->rrGetInfo = 0;
|
2006-09-17 06:44:42 +02:00
|
|
|
pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
|
|
|
|
pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
|
2006-09-17 08:21:37 +02:00
|
|
|
|
|
|
|
#if RANDR_12_INTERFACE
|
|
|
|
pScrPriv->rrCrtcSet = 0;
|
|
|
|
#endif
|
|
|
|
#if RANDR_10_INTERFACE
|
2006-07-02 04:46:38 +02:00
|
|
|
pScrPriv->rrSetConfig = 0;
|
2006-09-17 08:21:37 +02:00
|
|
|
pScrPriv->rotations = RR_Rotate_0;
|
2006-09-17 06:44:42 +02:00
|
|
|
pScrPriv->reqWidth = pScreen->width;
|
|
|
|
pScrPriv->reqHeight = pScreen->height;
|
2006-09-17 08:21:37 +02:00
|
|
|
pScrPriv->nSizes = 0;
|
|
|
|
pScrPriv->pSizes = NULL;
|
|
|
|
pScrPriv->rotation = RR_Rotate_0;
|
|
|
|
pScrPriv->rate = 0;
|
|
|
|
pScrPriv->size = 0;
|
2006-07-02 04:46:38 +02:00
|
|
|
#endif
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/*
|
|
|
|
* This value doesn't really matter -- any client must call
|
|
|
|
* GetScreenInfo before reading it which will automatically update
|
|
|
|
* the time
|
|
|
|
*/
|
|
|
|
pScrPriv->lastSetTime = currentTime;
|
|
|
|
pScrPriv->lastConfigTime = currentTime;
|
|
|
|
|
|
|
|
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
pScrPriv->numModes = 0;
|
|
|
|
pScrPriv->modes = NULL;
|
|
|
|
pScrPriv->numOutputs = 0;
|
|
|
|
pScrPriv->outputs = NULL;
|
|
|
|
pScrPriv->numCrtcs = 0;
|
|
|
|
pScrPriv->crtcs = NULL;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
RRNScreens += 1; /* keep count of screens that implement randr */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
|
|
|
RRFreeClient (pointer data, XID id)
|
|
|
|
{
|
|
|
|
RREventPtr pRREvent;
|
|
|
|
WindowPtr pWin;
|
|
|
|
RREventPtr *pHead, pCur, pPrev;
|
|
|
|
|
|
|
|
pRREvent = (RREventPtr) data;
|
|
|
|
pWin = pRREvent->window;
|
|
|
|
pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
|
|
|
|
if (pHead) {
|
|
|
|
pPrev = 0;
|
|
|
|
for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
|
|
|
|
pPrev = pCur;
|
|
|
|
if (pCur)
|
|
|
|
{
|
|
|
|
if (pPrev)
|
|
|
|
pPrev->next = pRREvent->next;
|
|
|
|
else
|
|
|
|
*pHead = pRREvent->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xfree ((pointer) pRREvent);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
|
|
|
RRFreeEvents (pointer data, XID id)
|
|
|
|
{
|
|
|
|
RREventPtr *pHead, pCur, pNext;
|
|
|
|
|
|
|
|
pHead = (RREventPtr *) data;
|
|
|
|
for (pCur = *pHead; pCur; pCur = pNext) {
|
|
|
|
pNext = pCur->next;
|
|
|
|
FreeResource (pCur->clientResource, ClientType);
|
|
|
|
xfree ((pointer) pCur);
|
|
|
|
}
|
|
|
|
xfree ((pointer) pHead);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RRExtensionInit (void)
|
|
|
|
{
|
|
|
|
ExtensionEntry *extEntry;
|
|
|
|
|
|
|
|
if (RRNScreens == 0) return;
|
|
|
|
|
|
|
|
RRClientPrivateIndex = AllocateClientPrivateIndex ();
|
|
|
|
if (!AllocateClientPrivate (RRClientPrivateIndex,
|
|
|
|
sizeof (RRClientRec) +
|
|
|
|
screenInfo.numScreens * sizeof (RRTimesRec)))
|
|
|
|
return;
|
|
|
|
if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ClientType = CreateNewResourceType(RRFreeClient);
|
|
|
|
if (!ClientType)
|
|
|
|
return;
|
|
|
|
EventType = CreateNewResourceType(RRFreeEvents);
|
|
|
|
if (!EventType)
|
|
|
|
return;
|
|
|
|
extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
|
|
|
|
ProcRRDispatch, SProcRRDispatch,
|
|
|
|
RRResetProc, StandardMinorOpcode);
|
|
|
|
if (!extEntry)
|
|
|
|
return;
|
2003-11-25 20:29:01 +01:00
|
|
|
#if 0
|
2003-11-14 17:48:57 +01:00
|
|
|
RRReqCode = (CARD8) extEntry->base;
|
|
|
|
RRErrBase = extEntry->errorBase;
|
2003-11-25 20:29:01 +01:00
|
|
|
#endif
|
2003-11-14 17:48:57 +01:00
|
|
|
RREventBase = extEntry->eventBase;
|
|
|
|
EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
|
|
|
|
SRRScreenChangeNotifyEvent;
|
2006-07-17 07:21:11 +02:00
|
|
|
EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
|
|
|
|
SRRNotifyEvent;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
static void
|
|
|
|
DeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
DeliverOutputEvent (ClientPtr client, WindowPtr pWin, RROutputPtr output)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
static int
|
|
|
|
TellChanged (WindowPtr pWin, pointer value)
|
|
|
|
{
|
|
|
|
RREventPtr *pHead, pRREvent;
|
|
|
|
ClientPtr client;
|
|
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
|
rrScrPriv(pScreen);
|
2006-07-02 04:46:38 +02:00
|
|
|
int i;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
|
|
|
|
if (!pHead)
|
|
|
|
return WT_WALKCHILDREN;
|
|
|
|
|
|
|
|
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
|
|
|
|
{
|
|
|
|
client = pRREvent->client;
|
|
|
|
if (client == serverClient || client->clientGone)
|
|
|
|
continue;
|
2006-07-02 04:46:38 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (pRREvent->mask & RRScreenChangeNotifyMask)
|
2006-09-17 08:21:37 +02:00
|
|
|
RRDeliverScreenEvent (client, pWin, pScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
|
|
|
|
if (pRREvent->mask & RRCrtcChangeNotifyMask)
|
2006-07-02 04:46:38 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < pScrPriv->numCrtcs; i++)
|
2006-07-02 04:46:38 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
RRCrtcPtr crtc = pScrPriv->crtcs[i];
|
|
|
|
if (crtc->changed)
|
|
|
|
DeliverCrtcEvent (client, pWin, crtc);
|
2006-07-02 04:46:38 +02:00
|
|
|
}
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
|
|
|
|
if (pRREvent->mask & RROutputChangeNotifyMask)
|
2006-07-02 04:46:38 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < pScrPriv->numOutputs; i++)
|
2006-07-02 04:46:38 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
RROutputPtr output = pScrPriv->outputs[i];
|
|
|
|
if (output->changed)
|
|
|
|
DeliverOutputEvent (client, pWin, output);
|
2006-07-02 04:46:38 +02:00
|
|
|
}
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
return WT_WALKCHILDREN;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
void
|
|
|
|
RRTellChanged (ScreenPtr pScreen)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
/*
|
|
|
|
* Return the first output which is connected to an active CRTC
|
|
|
|
* Used in emulating 1.0 behaviour
|
|
|
|
*/
|
|
|
|
static RROutputPtr
|
|
|
|
RRFirstOutput (ScreenPtr pScreen)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
rrScrPriv(pScreen);
|
|
|
|
RROutputPtr output;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < pScrPriv->numCrtcs; i++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
RRCrtcPtr crtc = pScrPriv->crtcs[i];
|
|
|
|
for (j = 0; j < pScrPriv->numOutputs; j++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
output = pScrPriv->outputs[j];
|
|
|
|
if (output->crtc == crtc)
|
|
|
|
return output;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
#ifdef RANDR_10_INTERFACE
|
2006-09-17 06:44:42 +02:00
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
static RRModePtr
|
2006-09-17 06:44:42 +02:00
|
|
|
RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
|
|
|
|
{
|
2006-09-17 08:21:37 +02:00
|
|
|
ScreenPtr pScreen = output->pScreen;
|
|
|
|
rrScrPriv(pScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
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);
|
2006-09-17 08:21:37 +02:00
|
|
|
mode = RRModeGet (pScreen, &modeInfo, name);
|
2006-09-17 06:44:42 +02:00
|
|
|
if (!mode)
|
2006-09-17 08:21:37 +02:00
|
|
|
return NULL;
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < output->numModes; i++)
|
|
|
|
if (output->modes[i] == mode)
|
2006-09-17 08:21:37 +02:00
|
|
|
{
|
|
|
|
RRModeDestroy (mode);
|
|
|
|
return mode;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
|
|
|
|
if (output->numModes)
|
|
|
|
modes = xrealloc (output->modes,
|
|
|
|
(output->numModes + 1) * sizeof (RRModePtr));
|
|
|
|
else
|
|
|
|
modes = xalloc (sizeof (RRModePtr));
|
|
|
|
if (!modes)
|
2006-09-17 08:21:37 +02:00
|
|
|
{
|
|
|
|
RRModeDestroy (mode);
|
|
|
|
FreeResource (mode->id, 0);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
modes[output->numModes++] = mode;
|
|
|
|
output->modes = modes;
|
|
|
|
output->changed = TRUE;
|
2006-09-17 08:21:37 +02:00
|
|
|
pScrPriv->changed = TRUE;
|
|
|
|
return mode;
|
2006-09-17 06:44:42 +02:00
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static void
|
|
|
|
RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
|
|
|
|
{
|
|
|
|
rrScrPriv(pScreen);
|
|
|
|
RROutputPtr output = RRFirstOutput (pScreen);
|
|
|
|
RRCrtcPtr crtc;
|
2006-09-17 08:21:37 +02:00
|
|
|
RRModePtr mode, newMode = NULL;
|
2006-09-17 06:44:42 +02:00
|
|
|
int i;
|
|
|
|
CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT;
|
|
|
|
CARD16 maxWidth = 0, maxHeight = 0;
|
2006-07-02 04:46:38 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (!output)
|
|
|
|
return;
|
|
|
|
crtc = output->crtc;
|
|
|
|
|
|
|
|
/* check rotations */
|
|
|
|
if (rotations != crtc->rotations)
|
|
|
|
{
|
|
|
|
crtc->rotations = rotations;
|
|
|
|
crtc->changed = TRUE;
|
|
|
|
pScrPriv->changed = TRUE;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-07-02 04:46:38 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
/* regenerate mode list */
|
|
|
|
for (i = 0; i < pScrPriv->nSizes; i++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
RRScreenSizePtr size = &pScrPriv->pSizes[i];
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if (size->nRates)
|
2006-09-17 08:21:37 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
for (r = 0; r < size->nRates; r++)
|
2006-09-17 08:21:37 +02:00
|
|
|
{
|
|
|
|
mode = RROldModeAdd (output, size, size->pRates[r].rate);
|
|
|
|
if (i == pScrPriv->size &&
|
|
|
|
size->pRates[r].rate == pScrPriv->rate)
|
|
|
|
{
|
|
|
|
newMode = mode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xfree (size->pRates);
|
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
else
|
2006-09-17 08:21:37 +02:00
|
|
|
{
|
|
|
|
mode = RROldModeAdd (output, size, 0);
|
|
|
|
if (i == pScrPriv->size)
|
|
|
|
newMode = mode;
|
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-09-17 08:21:37 +02:00
|
|
|
if (pScrPriv->nSizes)
|
|
|
|
xfree (pScrPriv->pSizes);
|
|
|
|
pScrPriv->pSizes = NULL;
|
|
|
|
pScrPriv->nSizes = 0;
|
2006-09-17 06:44:42 +02:00
|
|
|
|
|
|
|
/* find size bounds */
|
|
|
|
for (i = 0; i < output->numModes; i++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
if (maxHeight != pScrPriv->maxHeight) {
|
|
|
|
pScrPriv->maxHeight = maxHeight; pScrPriv->changed = TRUE;
|
|
|
|
}
|
2006-09-17 08:21:37 +02:00
|
|
|
|
|
|
|
/* notice current mode */
|
|
|
|
if (newMode)
|
|
|
|
RRCrtcSet (output->crtc, newMode, 0, 0, pScrPriv->rotation,
|
|
|
|
1, &output);
|
2006-09-17 06:44:42 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
/*
|
|
|
|
* Poll the driver for changed information
|
|
|
|
*/
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
#if RANDR_10_INTERFACE
|
2006-09-17 06:44:42 +02:00
|
|
|
if (pScrPriv->nSizes)
|
|
|
|
RRScanOldConfig (pScreen, rotations);
|
|
|
|
#endif
|
|
|
|
RRTellChanged (pScreen);
|
2003-11-14 17:48:57 +01:00
|
|
|
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;
|
2006-07-17 07:21:11 +02:00
|
|
|
/*
|
|
|
|
* Report the current version; the current
|
|
|
|
* spec says they're all compatible after 1.0
|
|
|
|
*/
|
2003-11-14 17:48:57 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2006-07-17 07:21:11 +02:00
|
|
|
typedef struct _RR10Data {
|
|
|
|
RRScreenSizePtr sizes;
|
|
|
|
int nsize;
|
|
|
|
int nrefresh;
|
|
|
|
int size;
|
|
|
|
CARD16 refresh;
|
|
|
|
} RR10DataRec, *RR10DataPtr;
|
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
CARD16
|
2006-09-17 06:44:42 +02:00
|
|
|
RRVerticalRefresh (xRRModeInfo *mode)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
|
|
|
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
|
2006-09-17 06:44:42 +02:00
|
|
|
RR10GetData (ScreenPtr pScreen, RROutputPtr output)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
|
|
|
RR10DataPtr data;
|
|
|
|
RRScreenSizePtr size;
|
2006-09-17 06:44:42 +02:00
|
|
|
int nmode = output->numModes;
|
|
|
|
int i, j, k;
|
|
|
|
RRScreenRatePtr refresh;
|
2006-07-17 07:21:11 +02:00
|
|
|
CARD16 vRefresh;
|
2006-09-17 06:44:42 +02:00
|
|
|
RRModePtr mode;
|
2006-07-17 07:21:11 +02:00
|
|
|
|
|
|
|
/* Make sure there is plenty of space for any combination */
|
|
|
|
data = malloc (sizeof (RR10DataRec) +
|
2006-09-17 06:44:42 +02:00
|
|
|
sizeof (RRScreenSize) * nmode +
|
|
|
|
sizeof (RRScreenRate) * nmode);
|
2006-07-17 07:21:11 +02:00
|
|
|
if (!data)
|
|
|
|
return NULL;
|
|
|
|
size = (RRScreenSizePtr) (data + 1);
|
2006-09-17 06:44:42 +02:00
|
|
|
refresh = (RRScreenRatePtr) (size + nmode);
|
2006-07-17 20:43:07 +02:00
|
|
|
data->sizes = size;
|
2006-07-17 07:21:11 +02:00
|
|
|
data->nsize = 0;
|
|
|
|
data->nrefresh = 0;
|
|
|
|
data->size = 0;
|
|
|
|
data->refresh = 0;
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < output->numModes; i++)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
mode = output->modes[i];
|
|
|
|
for (j = 0; j < data->nsize; j++)
|
|
|
|
if (mode->mode.width == size[j].width &&
|
|
|
|
mode->mode.height == size[j].height)
|
2006-07-17 07:21:11 +02:00
|
|
|
break;
|
2006-09-17 06:44:42 +02:00
|
|
|
if (j == data->nsize)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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];
|
2006-07-17 07:21:11 +02:00
|
|
|
data->nsize++;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
vRefresh = RRVerticalRefresh (&mode->mode);
|
|
|
|
for (k = 0; k < size[j].nRates; k++)
|
|
|
|
if (vRefresh == size[j].pRates[k].rate)
|
2006-07-17 07:21:11 +02:00
|
|
|
break;
|
2006-09-17 06:44:42 +02:00
|
|
|
if (k == size[j].nRates)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
size[j].pRates[k].rate = vRefresh;
|
|
|
|
size[j].pRates[k].mode = mode;
|
|
|
|
size[j].nRates++;
|
2006-07-17 07:21:11 +02:00
|
|
|
data->nrefresh++;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
if (mode == output->crtc->mode)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
data->size = j;
|
2006-07-17 07:21:11 +02:00
|
|
|
data->refresh = vRefresh;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
static int
|
|
|
|
ProcRRGetScreenInfo (ClientPtr client)
|
|
|
|
{
|
|
|
|
REQUEST(xRRGetScreenInfoReq);
|
|
|
|
xRRGetScreenInfoReply rep;
|
|
|
|
WindowPtr pWin;
|
|
|
|
int n;
|
|
|
|
ScreenPtr pScreen;
|
|
|
|
rrScrPrivPtr pScrPriv;
|
|
|
|
CARD8 *extra;
|
2003-11-25 20:29:01 +01:00
|
|
|
unsigned long extraLen;
|
2006-09-17 06:44:42 +02:00
|
|
|
RROutputPtr output;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
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;
|
2006-07-17 07:21:11 +02:00
|
|
|
|
|
|
|
if (pScrPriv)
|
|
|
|
RRGetInfo (pScreen);
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
output = RRFirstOutput (pScreen);
|
|
|
|
|
|
|
|
if (!pScrPriv || !output)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
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);
|
2006-07-17 07:21:11 +02:00
|
|
|
RR10DataPtr pData;
|
|
|
|
RRScreenSizePtr pSize;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
pData = RR10GetData (pScreen, output);
|
2006-07-17 07:21:11 +02:00
|
|
|
if (!pData)
|
|
|
|
return BadAlloc;
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
rep.type = X_Reply;
|
2006-09-17 06:44:42 +02:00
|
|
|
rep.setOfRotations = output->crtc->rotations;
|
2003-11-14 17:48:57 +01:00
|
|
|
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;
|
2006-09-17 06:44:42 +02:00
|
|
|
rep.rotation = output->crtc->rotation;
|
2006-07-17 07:21:11 +02:00
|
|
|
rep.nSizes = pData->nsize;
|
2006-07-17 20:43:07 +02:00
|
|
|
rep.nrateEnts = pData->nrefresh + pData->nsize;
|
2006-07-17 07:21:11 +02:00
|
|
|
rep.sizeID = pData->size;
|
|
|
|
rep.rate = pData->refresh;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
extraLen = (rep.nSizes * sizeof (xScreenSizes) +
|
|
|
|
rep.nrateEnts * sizeof (CARD16));
|
|
|
|
|
|
|
|
extra = (CARD8 *) xalloc (extraLen);
|
|
|
|
if (!extra)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
|
|
|
xfree (pData);
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadAlloc;
|
2006-07-17 07:21:11 +02:00
|
|
|
}
|
2003-11-14 17:48:57 +01:00
|
|
|
/*
|
|
|
|
* First comes the size information
|
|
|
|
*/
|
|
|
|
size = (xScreenSizes *) extra;
|
|
|
|
rates = (CARD16 *) (size + rep.nSizes);
|
2006-07-17 07:21:11 +02:00
|
|
|
for (i = 0; i < pData->nsize; i++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-07-17 07:21:11 +02:00
|
|
|
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)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
*rates = pSize->nRates;
|
2003-11-14 17:48:57 +01:00
|
|
|
if (client->swapped)
|
|
|
|
{
|
2006-07-17 07:21:11 +02:00
|
|
|
swaps (rates, n);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
rates++;
|
2006-09-17 06:44:42 +02:00
|
|
|
for (j = 0; j < pSize->nRates; j++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
*rates = pSize->pRates[j].rate;
|
2003-11-14 17:48:57 +01:00
|
|
|
if (client->swapped)
|
|
|
|
{
|
|
|
|
swaps (rates, n);
|
|
|
|
}
|
|
|
|
rates++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
xfree (pData);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
data8 = (CARD8 *) rates;
|
|
|
|
|
|
|
|
if (data8 - (CARD8 *) extra != extraLen)
|
2003-11-25 20:29:01 +01:00
|
|
|
FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
|
|
|
|
(unsigned long)(data8 - (CARD8 *) extra), extraLen);
|
2003-11-14 17:48:57 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
2006-07-17 20:43:07 +02:00
|
|
|
return RRSetConfigSuccess;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
2006-07-17 20:43:07 +02:00
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
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;
|
2006-09-17 06:44:42 +02:00
|
|
|
RROutputPtr output;
|
|
|
|
RRModePtr mode;
|
2006-07-17 07:21:11 +02:00
|
|
|
RR10DataPtr pData = NULL;
|
|
|
|
RRScreenSizePtr pSize;
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
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;
|
|
|
|
|
2004-06-25 10:56:04 +02:00
|
|
|
pScrPriv = rrGetScrPriv(pScreen);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
time = ClientTimeToServerTime(stuff->timestamp);
|
|
|
|
configTime = ClientTimeToServerTime(stuff->configTimestamp);
|
|
|
|
|
|
|
|
if (!pScrPriv)
|
|
|
|
{
|
|
|
|
time = currentTime;
|
|
|
|
rep.status = RRSetConfigFailed;
|
|
|
|
goto sendReply;
|
|
|
|
}
|
|
|
|
if (!RRGetInfo (pScreen))
|
|
|
|
return BadAlloc;
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
output = RRFirstOutput (pScreen);
|
|
|
|
if (!output)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
|
|
|
time = currentTime;
|
|
|
|
rep.status = RRSetConfigFailed;
|
|
|
|
goto sendReply;
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
pData = RR10GetData (pScreen, output);
|
2006-07-17 07:21:11 +02:00
|
|
|
if (!pData)
|
|
|
|
return BadAlloc;
|
|
|
|
|
|
|
|
if (stuff->sizeID >= pData->nsize)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Invalid size ID
|
|
|
|
*/
|
|
|
|
client->errorValue = stuff->sizeID;
|
2006-07-17 07:21:11 +02:00
|
|
|
xfree (pData);
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadValue;
|
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
pSize = &pData->sizes[stuff->sizeID];
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
2006-07-17 07:21:11 +02:00
|
|
|
xfree (pData);
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadValue;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if ((~output->crtc->rotations) & rotation)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* requested rotation or reflection not supported by screen
|
|
|
|
*/
|
|
|
|
client->errorValue = stuff->rotation;
|
2006-07-17 07:21:11 +02:00
|
|
|
xfree (pData);
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadMatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate requested refresh
|
|
|
|
*/
|
|
|
|
if (has_rate)
|
|
|
|
rate = (int) stuff->rate;
|
|
|
|
else
|
|
|
|
rate = 0;
|
|
|
|
|
|
|
|
if (rate)
|
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < pSize->nRates; i++)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
if (pSize->pRates[i].rate == rate)
|
2003-11-14 17:48:57 +01:00
|
|
|
break;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
if (i == pSize->nRates)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Invalid rate
|
|
|
|
*/
|
|
|
|
client->errorValue = rate;
|
2006-07-17 07:21:11 +02:00
|
|
|
xfree (pData);
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadValue;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
mode = pSize->pRates[i].mode;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
else
|
2006-09-17 06:44:42 +02:00
|
|
|
mode = pSize->pRates[0].mode;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
rep.status = RRCrtcSet (output->crtc, mode, 0, 0, stuff->rotation,
|
|
|
|
1, &output);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
sendReply:
|
|
|
|
|
2006-07-17 07:21:11 +02:00
|
|
|
if (pData)
|
|
|
|
xfree (pData);
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
2004-06-25 10:56:04 +02:00
|
|
|
int
|
|
|
|
RRSetScreenConfig (ScreenPtr pScreen,
|
|
|
|
Rotation rotation,
|
|
|
|
int rate,
|
|
|
|
RRScreenSizePtr pSize)
|
|
|
|
{
|
|
|
|
rrScrPrivPtr pScrPriv;
|
2006-07-17 20:43:07 +02:00
|
|
|
RRMonitorPtr pMonitor;
|
2004-06-25 10:56:04 +02:00
|
|
|
short oldWidth, oldHeight;
|
2006-07-17 20:43:07 +02:00
|
|
|
RRModePtr pMode;
|
|
|
|
int status;
|
2004-06-25 10:56:04 +02:00
|
|
|
|
|
|
|
pScrPriv = rrGetScrPriv(pScreen);
|
|
|
|
|
2006-07-17 20:43:07 +02:00
|
|
|
if (!pScrPriv)
|
|
|
|
return BadImplementation;
|
|
|
|
|
|
|
|
pMonitor = pScrPriv->pMonitors;
|
|
|
|
if (!pMonitor)
|
|
|
|
return BadImplementation;
|
|
|
|
|
2004-06-25 10:56:04 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2006-07-17 20:43:07 +02:00
|
|
|
for (pMode = pMonitor->pModes; pMode; pMode = pMode->next)
|
2004-06-25 10:56:04 +02:00
|
|
|
{
|
2006-07-17 20:43:07 +02:00
|
|
|
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))
|
2004-06-25 10:56:04 +02:00
|
|
|
{
|
2006-07-17 20:43:07 +02:00
|
|
|
break;
|
2004-06-25 10:56:04 +02:00
|
|
|
}
|
|
|
|
}
|
2006-07-17 20:43:07 +02:00
|
|
|
if (!pMode)
|
|
|
|
return BadValue;
|
2004-06-25 10:56:04 +02:00
|
|
|
|
2006-07-17 20:43:07 +02:00
|
|
|
status = RRMonitorSetMode (pScreen, pMonitor, pMode, 0, 0,
|
|
|
|
rotation, currentTime);
|
2006-09-17 06:44:42 +02:00
|
|
|
|
2006-07-17 20:43:07 +02:00
|
|
|
if (status != RRSetConfigSuccess)
|
|
|
|
return BadImplementation;
|
2004-06-25 10:56:04 +02:00
|
|
|
return Success;
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
static int
|
|
|
|
ProcRRSelectInput (ClientPtr client)
|
|
|
|
{
|
|
|
|
REQUEST(xRRSelectInputReq);
|
|
|
|
rrClientPriv(client);
|
|
|
|
RRTimesPtr pTimes;
|
|
|
|
WindowPtr pWin;
|
2006-09-17 06:44:42 +02:00
|
|
|
RREventPtr pRREvent, *pHead;
|
2003-11-14 17:48:57 +01:00
|
|
|
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);
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (stuff->enable & (RRScreenChangeNotifyMask|
|
|
|
|
RRCrtcChangeNotifyMask|
|
|
|
|
RROutputChangeNotifyMask))
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
|
rrScrPriv (pScreen);
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
pRREvent = NULL;
|
2003-11-14 17:48:57 +01:00
|
|
|
if (pHead)
|
|
|
|
{
|
|
|
|
/* check for existing entry. */
|
|
|
|
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
|
|
|
|
if (pRREvent->client == client)
|
2006-09-17 06:44:42 +02:00
|
|
|
break;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (!pRREvent)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
/* build the entry */
|
|
|
|
pRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
|
|
|
|
if (!pRREvent)
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadAlloc;
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
pRREvent->next = *pHead;
|
|
|
|
*pHead = pRREvent;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Now see if the client needs an event
|
|
|
|
*/
|
2006-09-17 06:44:42 +02:00
|
|
|
if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask))
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
|
|
|
|
if (CompareTimeStamps (pTimes->setTime,
|
|
|
|
pScrPriv->lastSetTime) != 0 ||
|
|
|
|
CompareTimeStamps (pTimes->configTime,
|
|
|
|
pScrPriv->lastConfigTime) != 0)
|
|
|
|
{
|
2006-09-17 08:21:37 +02:00
|
|
|
RRDeliverScreenEvent (client, pWin, pScreen);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
else if (stuff->enable == 0)
|
2003-11-14 17:48:57 +01:00
|
|
|
{
|
|
|
|
/* delete the interest */
|
|
|
|
if (pHead) {
|
2006-09-17 06:44:42 +02:00
|
|
|
RREventPtr pNewRREvent = 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
/*
|
|
|
|
* Retrieve valid screen size range
|
|
|
|
*/
|
|
|
|
static int ProcRRGetScreenSizeRange (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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);
|
2006-07-17 20:43:07 +02:00
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static int ProcRRSetScreenSize (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
|
|
|
}
|
2006-09-17 08:21:37 +02:00
|
|
|
if (!RRScreenSizeSet (pScreen,
|
2006-09-17 06:44:42 +02:00
|
|
|
stuff->width, stuff->height,
|
|
|
|
stuff->widthInMillimeters,
|
|
|
|
stuff->heightInMillimeters))
|
|
|
|
{
|
|
|
|
return BadMatch;
|
|
|
|
}
|
|
|
|
return Success;
|
2006-07-17 20:43:07 +02:00
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
|
|
|
static int ProcRRGetMonitorInfo (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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);
|
2006-07-17 20:43:07 +02:00
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static int ProcRRAddMonitorMode (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
|
|
|
return BadImplementation;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static int ProcRRDeleteMonitorMode (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
|
|
|
return BadImplementation;
|
|
|
|
}
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static int ProcRRSetMonitorConfig (ClientPtr client)
|
2006-07-17 20:43:07 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
2006-07-17 20:43:07 +02:00
|
|
|
}
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
2006-07-17 20:43:07 +02:00
|
|
|
|
|
|
|
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 */
|
2006-09-17 06:44:42 +02:00
|
|
|
#if 0
|
2006-07-17 20:43:07 +02:00
|
|
|
ProcRRGetScreenSizeRange, /* 6 */
|
|
|
|
ProcRRSetScreenSize, /* 7 */
|
|
|
|
ProcRRGetMonitorInfo, /* 8 */
|
|
|
|
ProcRRAddMonitorMode, /* 9 */
|
|
|
|
ProcRRDeleteMonitorMode, /* 10 */
|
|
|
|
ProcRRSetMonitorConfig, /* 11 */
|
2006-09-17 06:44:42 +02:00
|
|
|
#endif
|
2006-07-17 20:43:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
static int
|
|
|
|
ProcRRDispatch (ClientPtr client)
|
|
|
|
{
|
|
|
|
REQUEST(xReq);
|
2006-07-17 20:43:07 +02:00
|
|
|
if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
|
2003-11-14 17:48:57 +01:00
|
|
|
return BadRequest;
|
2006-07-17 20:43:07 +02:00
|
|
|
return (*ProcRandrVector[stuff->data]) (client);
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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:
|
|
|
|
return BadRequest;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
#if RANDR_12_INTERFACE
|
2006-07-17 07:21:11 +02:00
|
|
|
/*
|
2006-09-17 06:44:42 +02:00
|
|
|
* Register the range of sizes for the screen
|
2006-07-17 07:21:11 +02:00
|
|
|
*/
|
2006-09-17 06:44:42 +02:00
|
|
|
void
|
|
|
|
RRScreenSetSizeRange (ScreenPtr pScreen,
|
|
|
|
CARD16 minWidth,
|
|
|
|
CARD16 minHeight,
|
|
|
|
CARD16 maxWidth,
|
|
|
|
CARD16 maxHeight)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
|
|
|
rrScrPriv (pScreen);
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (!pScrPriv)
|
|
|
|
return;
|
|
|
|
pScrPriv->minWidth = minWidth;
|
|
|
|
pScrPriv->minHeight = minHeight;
|
|
|
|
pScrPriv->maxWidth = maxWidth;
|
|
|
|
pScrPriv->maxHeight = maxHeight;
|
2006-07-17 07:21:11 +02:00
|
|
|
}
|
2006-09-17 08:21:37 +02:00
|
|
|
#endif
|
2006-07-17 07:21:11 +02:00
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
#ifdef RANDR_10_INTERFACE
|
2006-07-17 07:21:11 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
static Bool
|
|
|
|
RRScreenSizeMatches (RRScreenSizePtr a,
|
|
|
|
RRScreenSizePtr b)
|
2006-07-17 07:21:11 +02:00
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
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;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
RRScreenSizePtr
|
|
|
|
RRRegisterSize (ScreenPtr pScreen,
|
|
|
|
short width,
|
|
|
|
short height,
|
|
|
|
short mmWidth,
|
|
|
|
short mmHeight)
|
|
|
|
{
|
|
|
|
rrScrPriv (pScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
int i;
|
|
|
|
RRScreenSize tmp;
|
|
|
|
RRScreenSizePtr pNew;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (!pScrPriv)
|
2006-09-17 06:44:42 +02:00
|
|
|
return 0;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
2006-09-17 08:21:37 +02:00
|
|
|
tmp.id = 0;
|
2006-07-17 07:21:11 +02:00
|
|
|
tmp.width = width;
|
|
|
|
tmp.height= height;
|
2006-09-17 06:44:42 +02:00
|
|
|
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];
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Bool RRRegisterRate (ScreenPtr pScreen,
|
|
|
|
RRScreenSizePtr pSize,
|
|
|
|
int rate)
|
|
|
|
{
|
|
|
|
rrScrPriv(pScreen);
|
2006-09-17 06:44:42 +02:00
|
|
|
int i;
|
|
|
|
RRScreenRatePtr pNew, pRate;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
if (!pScrPriv)
|
|
|
|
return FALSE;
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
for (i = 0; i < pSize->nRates; i++)
|
|
|
|
if (pSize->pRates[i].rate == rate)
|
|
|
|
return TRUE;
|
2006-07-17 07:21:11 +02:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
pNew = xrealloc (pSize->pRates,
|
|
|
|
(pSize->nRates + 1) * sizeof (RRScreenRate));
|
|
|
|
if (!pNew)
|
2003-11-14 17:48:57 +01:00
|
|
|
return FALSE;
|
2006-09-17 06:44:42 +02:00
|
|
|
pRate = &pNew[pSize->nRates++];
|
|
|
|
pRate->rate = rate;
|
|
|
|
pSize->pRates = pNew;
|
2003-11-14 17:48:57 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-02-01 23:20:05 +01:00
|
|
|
Rotation
|
|
|
|
RRGetRotation(ScreenPtr pScreen)
|
|
|
|
{
|
2006-09-17 06:44:42 +02:00
|
|
|
RROutputPtr output = RRFirstOutput (pScreen);
|
2006-02-01 23:20:05 +01:00
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
if (!output)
|
2006-02-01 23:20:05 +01:00
|
|
|
return RR_Rotate_0;
|
|
|
|
|
2006-09-17 06:44:42 +02:00
|
|
|
return output->crtc->rotation;
|
2006-02-01 23:20:05 +01:00
|
|
|
}
|
|
|
|
|
2003-11-14 17:48:57 +01:00
|
|
|
void
|
|
|
|
RRSetCurrentConfig (ScreenPtr pScreen,
|
|
|
|
Rotation rotation,
|
|
|
|
int rate,
|
|
|
|
RRScreenSizePtr pSize)
|
|
|
|
{
|
|
|
|
rrScrPriv (pScreen);
|
|
|
|
|
|
|
|
if (!pScrPriv)
|
|
|
|
return;
|
2006-09-17 06:44:42 +02:00
|
|
|
pScrPriv->size = pSize - pScrPriv->pSizes;
|
|
|
|
pScrPriv->rotation = rotation;
|
|
|
|
pScrPriv->rate = rate;
|
2003-11-14 17:48:57 +01:00
|
|
|
}
|
2006-07-17 07:21:11 +02:00
|
|
|
#endif
|