rrdispatch.c revision 9ace9065
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{ 389ace9065Smrg xRRQueryVersionReply rep = {0}; 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 */ 1499ace9065Smrg if (pScrPriv) 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 { 1579ace9065Smrg if (pRREvent->mask & RRScreenChangeNotifyMask) 1589ace9065Smrg { 1599ace9065Smrg RRDeliverScreenEvent (client, pWin, pScreen); 1609ace9065Smrg } 1619ace9065Smrg 1629ace9065Smrg if (pRREvent->mask & RRCrtcChangeNotifyMask) 1639ace9065Smrg { 1649ace9065Smrg int i; 1659ace9065Smrg 1669ace9065Smrg for (i = 0; i < pScrPriv->numCrtcs; i++) 1679ace9065Smrg { 1689ace9065Smrg RRDeliverCrtcEvent (client, pWin, pScrPriv->crtcs[i]); 1699ace9065Smrg } 1709ace9065Smrg } 1719ace9065Smrg 1729ace9065Smrg if (pRREvent->mask & RROutputChangeNotifyMask) 1739ace9065Smrg { 1749ace9065Smrg int i; 1759ace9065Smrg 1769ace9065Smrg for (i = 0; i < pScrPriv->numOutputs; i++) 1779ace9065Smrg { 1789ace9065Smrg RRDeliverOutputEvent (client, pWin, pScrPriv->outputs[i]); 1799ace9065Smrg } 1809ace9065Smrg } 1819ace9065Smrg 1829ace9065Smrg /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't 1839ace9065Smrg * say if there ought to be notifications of changes to output properties 1849ace9065Smrg * if those changes occurred before the time RRSelectInput is called. 1859ace9065Smrg */ 18605b261ecSmrg } 18705b261ecSmrg } 18805b261ecSmrg } 18905b261ecSmrg else if (stuff->enable == 0) 19005b261ecSmrg { 19105b261ecSmrg /* delete the interest */ 19205b261ecSmrg if (pHead) { 19305b261ecSmrg RREventPtr pNewRREvent = 0; 19405b261ecSmrg for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { 19505b261ecSmrg if (pRREvent->client == client) 19605b261ecSmrg break; 19705b261ecSmrg pNewRREvent = pRREvent; 19805b261ecSmrg } 19905b261ecSmrg if (pRREvent) { 20005b261ecSmrg FreeResource (pRREvent->clientResource, RRClientType); 20105b261ecSmrg if (pNewRREvent) 20205b261ecSmrg pNewRREvent->next = pRREvent->next; 20305b261ecSmrg else 20405b261ecSmrg *pHead = pRREvent->next; 2056747b715Smrg free(pRREvent); 20605b261ecSmrg } 20705b261ecSmrg } 20805b261ecSmrg } 20905b261ecSmrg else 21005b261ecSmrg { 21105b261ecSmrg client->errorValue = stuff->enable; 21205b261ecSmrg return BadValue; 21305b261ecSmrg } 21405b261ecSmrg return Success; 21505b261ecSmrg} 21605b261ecSmrg 21705b261ecSmrgint (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { 21805b261ecSmrg ProcRRQueryVersion, /* 0 */ 21905b261ecSmrg/* we skip 1 to make old clients fail pretty immediately */ 22005b261ecSmrg NULL, /* 1 ProcRandrOldGetScreenInfo */ 22105b261ecSmrg/* V1.0 apps share the same set screen config request id */ 22205b261ecSmrg ProcRRSetScreenConfig, /* 2 */ 22305b261ecSmrg NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ 22405b261ecSmrg/* 3 used to be ScreenChangeSelectInput; deprecated */ 22505b261ecSmrg ProcRRSelectInput, /* 4 */ 22605b261ecSmrg ProcRRGetScreenInfo, /* 5 */ 22705b261ecSmrg/* V1.2 additions */ 22805b261ecSmrg ProcRRGetScreenSizeRange, /* 6 */ 22905b261ecSmrg ProcRRSetScreenSize, /* 7 */ 23005b261ecSmrg ProcRRGetScreenResources, /* 8 */ 23105b261ecSmrg ProcRRGetOutputInfo, /* 9 */ 23205b261ecSmrg ProcRRListOutputProperties, /* 10 */ 23305b261ecSmrg ProcRRQueryOutputProperty, /* 11 */ 23405b261ecSmrg ProcRRConfigureOutputProperty, /* 12 */ 23505b261ecSmrg ProcRRChangeOutputProperty, /* 13 */ 23605b261ecSmrg ProcRRDeleteOutputProperty, /* 14 */ 23705b261ecSmrg ProcRRGetOutputProperty, /* 15 */ 23805b261ecSmrg ProcRRCreateMode, /* 16 */ 23905b261ecSmrg ProcRRDestroyMode, /* 17 */ 24005b261ecSmrg ProcRRAddOutputMode, /* 18 */ 24105b261ecSmrg ProcRRDeleteOutputMode, /* 19 */ 24205b261ecSmrg ProcRRGetCrtcInfo, /* 20 */ 24305b261ecSmrg ProcRRSetCrtcConfig, /* 21 */ 24405b261ecSmrg ProcRRGetCrtcGammaSize, /* 22 */ 24505b261ecSmrg ProcRRGetCrtcGamma, /* 23 */ 24605b261ecSmrg ProcRRSetCrtcGamma, /* 24 */ 2474642e01fSmrg/* V1.3 additions */ 2484642e01fSmrg ProcRRGetScreenResourcesCurrent, /* 25 */ 2494642e01fSmrg ProcRRSetCrtcTransform, /* 26 */ 2504642e01fSmrg ProcRRGetCrtcTransform, /* 27 */ 2514642e01fSmrg ProcRRGetPanning, /* 28 */ 2524642e01fSmrg ProcRRSetPanning, /* 29 */ 2534642e01fSmrg ProcRRSetOutputPrimary, /* 30 */ 2544642e01fSmrg ProcRRGetOutputPrimary, /* 31 */ 25505b261ecSmrg}; 25605b261ecSmrg 257