rrdispatch.c revision 6747b715
105b261ecSmrg/* 205b261ecSmrg * Copyright © 2006 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that copyright 705b261ecSmrg * notice and this permission notice appear in supporting documentation, and 805b261ecSmrg * that the name of the copyright holders not be used in advertising or 905b261ecSmrg * publicity pertaining to distribution of the software without specific, 1005b261ecSmrg * written prior permission. The copyright holders make no representations 1105b261ecSmrg * about the suitability of this software for any purpose. It is provided "as 1205b261ecSmrg * is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2005b261ecSmrg * OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#include "randrstr.h" 246747b715Smrg#include "protocol-versions.h" 2505b261ecSmrg 2605b261ecSmrgBool 2705b261ecSmrgRRClientKnowsRates (ClientPtr pClient) 2805b261ecSmrg{ 2905b261ecSmrg rrClientPriv(pClient); 3005b261ecSmrg 3105b261ecSmrg return (pRRClient->major_version > 1 || 3205b261ecSmrg (pRRClient->major_version == 1 && pRRClient->minor_version >= 1)); 3305b261ecSmrg} 3405b261ecSmrg 3505b261ecSmrgstatic int 3605b261ecSmrgProcRRQueryVersion (ClientPtr client) 3705b261ecSmrg{ 3805b261ecSmrg xRRQueryVersionReply rep; 3905b261ecSmrg register int n; 4005b261ecSmrg REQUEST(xRRQueryVersionReq); 4105b261ecSmrg rrClientPriv(client); 4205b261ecSmrg 4305b261ecSmrg REQUEST_SIZE_MATCH(xRRQueryVersionReq); 4405b261ecSmrg pRRClient->major_version = stuff->majorVersion; 4505b261ecSmrg pRRClient->minor_version = stuff->minorVersion; 4605b261ecSmrg rep.type = X_Reply; 4705b261ecSmrg rep.length = 0; 4805b261ecSmrg rep.sequenceNumber = client->sequence; 496747b715Smrg 506747b715Smrg if ((stuff->majorVersion * 1000 + stuff->minorVersion) < 516747b715Smrg (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION)) 526747b715Smrg { 536747b715Smrg rep.majorVersion = stuff->majorVersion; 546747b715Smrg rep.minorVersion = stuff->minorVersion; 556747b715Smrg } else 566747b715Smrg { 576747b715Smrg rep.majorVersion = SERVER_RANDR_MAJOR_VERSION; 586747b715Smrg rep.minorVersion = SERVER_RANDR_MINOR_VERSION; 596747b715Smrg } 606747b715Smrg 6105b261ecSmrg if (client->swapped) { 6205b261ecSmrg swaps(&rep.sequenceNumber, n); 6305b261ecSmrg swapl(&rep.length, n); 6405b261ecSmrg swapl(&rep.majorVersion, n); 6505b261ecSmrg swapl(&rep.minorVersion, n); 6605b261ecSmrg } 6705b261ecSmrg WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep); 686747b715Smrg return Success; 6905b261ecSmrg} 7005b261ecSmrg 7105b261ecSmrgstatic int 7205b261ecSmrgProcRRSelectInput (ClientPtr client) 7305b261ecSmrg{ 7405b261ecSmrg REQUEST(xRRSelectInputReq); 7505b261ecSmrg rrClientPriv(client); 7605b261ecSmrg RRTimesPtr pTimes; 7705b261ecSmrg WindowPtr pWin; 7805b261ecSmrg RREventPtr pRREvent, *pHead; 7905b261ecSmrg XID clientResource; 8005b261ecSmrg int rc; 8105b261ecSmrg 8205b261ecSmrg REQUEST_SIZE_MATCH(xRRSelectInputReq); 834642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); 8405b261ecSmrg if (rc != Success) 8505b261ecSmrg return rc; 866747b715Smrg rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, 876747b715Smrg RREventType, client, DixWriteAccess); 886747b715Smrg if (rc != Success && rc != BadValue) 896747b715Smrg return rc; 9005b261ecSmrg 9105b261ecSmrg if (stuff->enable & (RRScreenChangeNotifyMask| 9205b261ecSmrg RRCrtcChangeNotifyMask| 934642e01fSmrg RROutputChangeNotifyMask| 944642e01fSmrg RROutputPropertyNotifyMask)) 9505b261ecSmrg { 9605b261ecSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 9705b261ecSmrg rrScrPriv (pScreen); 9805b261ecSmrg 9905b261ecSmrg pRREvent = NULL; 10005b261ecSmrg if (pHead) 10105b261ecSmrg { 10205b261ecSmrg /* check for existing entry. */ 10305b261ecSmrg for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) 10405b261ecSmrg if (pRREvent->client == client) 10505b261ecSmrg break; 10605b261ecSmrg } 10705b261ecSmrg 10805b261ecSmrg if (!pRREvent) 10905b261ecSmrg { 11005b261ecSmrg /* build the entry */ 1116747b715Smrg pRREvent = (RREventPtr) malloc(sizeof (RREventRec)); 11205b261ecSmrg if (!pRREvent) 11305b261ecSmrg return BadAlloc; 11405b261ecSmrg pRREvent->next = 0; 11505b261ecSmrg pRREvent->client = client; 11605b261ecSmrg pRREvent->window = pWin; 11705b261ecSmrg pRREvent->mask = stuff->enable; 11805b261ecSmrg /* 11905b261ecSmrg * add a resource that will be deleted when 12005b261ecSmrg * the client goes away 12105b261ecSmrg */ 12205b261ecSmrg clientResource = FakeClientID (client->index); 12305b261ecSmrg pRREvent->clientResource = clientResource; 12405b261ecSmrg if (!AddResource (clientResource, RRClientType, (pointer)pRREvent)) 12505b261ecSmrg return BadAlloc; 12605b261ecSmrg /* 12705b261ecSmrg * create a resource to contain a pointer to the list 12805b261ecSmrg * of clients selecting input. This must be indirect as 12905b261ecSmrg * the list may be arbitrarily rearranged which cannot be 13005b261ecSmrg * done through the resource database. 13105b261ecSmrg */ 13205b261ecSmrg if (!pHead) 13305b261ecSmrg { 1346747b715Smrg pHead = (RREventPtr *) malloc(sizeof (RREventPtr)); 13505b261ecSmrg if (!pHead || 13605b261ecSmrg !AddResource (pWin->drawable.id, RREventType, (pointer)pHead)) 13705b261ecSmrg { 13805b261ecSmrg FreeResource (clientResource, RT_NONE); 13905b261ecSmrg return BadAlloc; 14005b261ecSmrg } 14105b261ecSmrg *pHead = 0; 14205b261ecSmrg } 14305b261ecSmrg pRREvent->next = *pHead; 14405b261ecSmrg *pHead = pRREvent; 14505b261ecSmrg } 14605b261ecSmrg /* 14705b261ecSmrg * Now see if the client needs an event 14805b261ecSmrg */ 14905b261ecSmrg if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask)) 15005b261ecSmrg { 15105b261ecSmrg pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; 15205b261ecSmrg if (CompareTimeStamps (pTimes->setTime, 15305b261ecSmrg pScrPriv->lastSetTime) != 0 || 15405b261ecSmrg CompareTimeStamps (pTimes->configTime, 15505b261ecSmrg pScrPriv->lastConfigTime) != 0) 15605b261ecSmrg { 15705b261ecSmrg RRDeliverScreenEvent (client, pWin, pScreen); 15805b261ecSmrg } 15905b261ecSmrg } 16005b261ecSmrg } 16105b261ecSmrg else if (stuff->enable == 0) 16205b261ecSmrg { 16305b261ecSmrg /* delete the interest */ 16405b261ecSmrg if (pHead) { 16505b261ecSmrg RREventPtr pNewRREvent = 0; 16605b261ecSmrg for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { 16705b261ecSmrg if (pRREvent->client == client) 16805b261ecSmrg break; 16905b261ecSmrg pNewRREvent = pRREvent; 17005b261ecSmrg } 17105b261ecSmrg if (pRREvent) { 17205b261ecSmrg FreeResource (pRREvent->clientResource, RRClientType); 17305b261ecSmrg if (pNewRREvent) 17405b261ecSmrg pNewRREvent->next = pRREvent->next; 17505b261ecSmrg else 17605b261ecSmrg *pHead = pRREvent->next; 1776747b715Smrg free(pRREvent); 17805b261ecSmrg } 17905b261ecSmrg } 18005b261ecSmrg } 18105b261ecSmrg else 18205b261ecSmrg { 18305b261ecSmrg client->errorValue = stuff->enable; 18405b261ecSmrg return BadValue; 18505b261ecSmrg } 18605b261ecSmrg return Success; 18705b261ecSmrg} 18805b261ecSmrg 18905b261ecSmrgint (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { 19005b261ecSmrg ProcRRQueryVersion, /* 0 */ 19105b261ecSmrg/* we skip 1 to make old clients fail pretty immediately */ 19205b261ecSmrg NULL, /* 1 ProcRandrOldGetScreenInfo */ 19305b261ecSmrg/* V1.0 apps share the same set screen config request id */ 19405b261ecSmrg ProcRRSetScreenConfig, /* 2 */ 19505b261ecSmrg NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ 19605b261ecSmrg/* 3 used to be ScreenChangeSelectInput; deprecated */ 19705b261ecSmrg ProcRRSelectInput, /* 4 */ 19805b261ecSmrg ProcRRGetScreenInfo, /* 5 */ 19905b261ecSmrg/* V1.2 additions */ 20005b261ecSmrg ProcRRGetScreenSizeRange, /* 6 */ 20105b261ecSmrg ProcRRSetScreenSize, /* 7 */ 20205b261ecSmrg ProcRRGetScreenResources, /* 8 */ 20305b261ecSmrg ProcRRGetOutputInfo, /* 9 */ 20405b261ecSmrg ProcRRListOutputProperties, /* 10 */ 20505b261ecSmrg ProcRRQueryOutputProperty, /* 11 */ 20605b261ecSmrg ProcRRConfigureOutputProperty, /* 12 */ 20705b261ecSmrg ProcRRChangeOutputProperty, /* 13 */ 20805b261ecSmrg ProcRRDeleteOutputProperty, /* 14 */ 20905b261ecSmrg ProcRRGetOutputProperty, /* 15 */ 21005b261ecSmrg ProcRRCreateMode, /* 16 */ 21105b261ecSmrg ProcRRDestroyMode, /* 17 */ 21205b261ecSmrg ProcRRAddOutputMode, /* 18 */ 21305b261ecSmrg ProcRRDeleteOutputMode, /* 19 */ 21405b261ecSmrg ProcRRGetCrtcInfo, /* 20 */ 21505b261ecSmrg ProcRRSetCrtcConfig, /* 21 */ 21605b261ecSmrg ProcRRGetCrtcGammaSize, /* 22 */ 21705b261ecSmrg ProcRRGetCrtcGamma, /* 23 */ 21805b261ecSmrg ProcRRSetCrtcGamma, /* 24 */ 2194642e01fSmrg/* V1.3 additions */ 2204642e01fSmrg ProcRRGetScreenResourcesCurrent, /* 25 */ 2214642e01fSmrg ProcRRSetCrtcTransform, /* 26 */ 2224642e01fSmrg ProcRRGetCrtcTransform, /* 27 */ 2234642e01fSmrg ProcRRGetPanning, /* 28 */ 2244642e01fSmrg ProcRRSetPanning, /* 29 */ 2254642e01fSmrg ProcRRSetOutputPrimary, /* 30 */ 2264642e01fSmrg ProcRRGetOutputPrimary, /* 31 */ 22705b261ecSmrg}; 22805b261ecSmrg 229