#include "randrstr.h"
#define SERVER_RANDR_MAJOR 1
#define SERVER_RANDR_MINOR 3
Bool
RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
}
static int
ProcRRQueryVersion (ClientPtr client)
{
xRRQueryVersionReply rep;
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;
rep.majorVersion = SERVER_RANDR_MAJOR;
rep.minorVersion = SERVER_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
ProcRRSelectInput (ClientPtr client)
{
REQUEST(xRRSelectInputReq);
rrClientPriv(client);
RRTimesPtr pTimes;
WindowPtr pWin;
RREventPtr pRREvent, *pHead;
XID clientResource;
int rc;
REQUEST_SIZE_MATCH(xRRSelectInputReq);
rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
if (rc != Success)
return rc;
pHead = (RREventPtr *)SecurityLookupIDByType(client,
pWin->drawable.id, RREventType,
DixWriteAccess);
if (stuff->enable & (RRScreenChangeNotifyMask|
RRCrtcChangeNotifyMask|
RROutputChangeNotifyMask|
RROutputPropertyNotifyMask))
{
ScreenPtr pScreen = pWin->drawable.pScreen;
rrScrPriv (pScreen);
pRREvent = NULL;
if (pHead)
{
for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
if (pRREvent->client == client)
break;
}
if (!pRREvent)
{
pRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
if (!pRREvent)
return BadAlloc;
pRREvent->next = 0;
pRREvent->client = client;
pRREvent->window = pWin;
pRREvent->mask = stuff->enable;
clientResource = FakeClientID (client->index);
pRREvent->clientResource = clientResource;
if (!AddResource (clientResource, RRClientType, (pointer)pRREvent))
return BadAlloc;
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;
}
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)
{
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;
}
int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
ProcRRQueryVersion,
NULL,
ProcRRSetScreenConfig,
NULL,
ProcRRSelectInput,
ProcRRGetScreenInfo,
ProcRRGetScreenSizeRange,
ProcRRSetScreenSize,
ProcRRGetScreenResources,
ProcRRGetOutputInfo,
ProcRRListOutputProperties,
ProcRRQueryOutputProperty,
ProcRRConfigureOutputProperty,
ProcRRChangeOutputProperty,
ProcRRDeleteOutputProperty,
ProcRRGetOutputProperty,
ProcRRCreateMode,
ProcRRDestroyMode,
ProcRRAddOutputMode,
ProcRRDeleteOutputMode,
ProcRRGetCrtcInfo,
ProcRRSetCrtcConfig,
ProcRRGetCrtcGammaSize,
ProcRRGetCrtcGamma,
ProcRRSetCrtcGamma,
ProcRRGetScreenResourcesCurrent,
ProcRRSetCrtcTransform,
ProcRRGetCrtcTransform,
ProcRRGetPanning,
ProcRRSetPanning,
ProcRRSetOutputPrimary,
ProcRRGetOutputPrimary,
};