rrdispatch.c revision 1b5d61b8
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 2735c4bbdfSmrgRRClientKnowsRates(ClientPtr pClient) 2805b261ecSmrg{ 2905b261ecSmrg rrClientPriv(pClient); 3005b261ecSmrg 3135c4bbdfSmrg return version_compare(pRRClient->major_version, pRRClient->minor_version, 3235c4bbdfSmrg 1, 1) >= 0; 3305b261ecSmrg} 3405b261ecSmrg 3505b261ecSmrgstatic int 3635c4bbdfSmrgProcRRQueryVersion(ClientPtr client) 3705b261ecSmrg{ 3835c4bbdfSmrg xRRQueryVersionReply rep = { 3935c4bbdfSmrg .type = X_Reply, 4035c4bbdfSmrg .sequenceNumber = client->sequence, 4135c4bbdfSmrg .length = 0 4235c4bbdfSmrg }; 4305b261ecSmrg REQUEST(xRRQueryVersionReq); 4405b261ecSmrg rrClientPriv(client); 4505b261ecSmrg 4605b261ecSmrg REQUEST_SIZE_MATCH(xRRQueryVersionReq); 4705b261ecSmrg pRRClient->major_version = stuff->majorVersion; 4805b261ecSmrg pRRClient->minor_version = stuff->minorVersion; 496747b715Smrg 5035c4bbdfSmrg if (version_compare(stuff->majorVersion, stuff->minorVersion, 5135c4bbdfSmrg SERVER_RANDR_MAJOR_VERSION, 5235c4bbdfSmrg SERVER_RANDR_MINOR_VERSION) < 0) { 5335c4bbdfSmrg rep.majorVersion = stuff->majorVersion; 5435c4bbdfSmrg rep.minorVersion = stuff->minorVersion; 5535c4bbdfSmrg } 5635c4bbdfSmrg else { 576747b715Smrg rep.majorVersion = SERVER_RANDR_MAJOR_VERSION; 586747b715Smrg rep.minorVersion = SERVER_RANDR_MINOR_VERSION; 596747b715Smrg } 606747b715Smrg 6105b261ecSmrg if (client->swapped) { 6235c4bbdfSmrg swaps(&rep.sequenceNumber); 6335c4bbdfSmrg swapl(&rep.length); 6435c4bbdfSmrg swapl(&rep.majorVersion); 6535c4bbdfSmrg swapl(&rep.minorVersion); 6605b261ecSmrg } 6735c4bbdfSmrg WriteToClient(client, sizeof(xRRQueryVersionReply), &rep); 686747b715Smrg return Success; 6905b261ecSmrg} 7005b261ecSmrg 7105b261ecSmrgstatic int 7235c4bbdfSmrgProcRRSelectInput(ClientPtr client) 7305b261ecSmrg{ 7405b261ecSmrg REQUEST(xRRSelectInputReq); 7505b261ecSmrg rrClientPriv(client); 7635c4bbdfSmrg RRTimesPtr pTimes; 7735c4bbdfSmrg WindowPtr pWin; 7835c4bbdfSmrg RREventPtr pRREvent, *pHead; 7935c4bbdfSmrg XID clientResource; 8035c4bbdfSmrg int rc; 8105b261ecSmrg 8205b261ecSmrg REQUEST_SIZE_MATCH(xRRSelectInputReq); 834642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); 8405b261ecSmrg if (rc != Success) 8535c4bbdfSmrg return rc; 8635c4bbdfSmrg rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id, 8735c4bbdfSmrg RREventType, client, DixWriteAccess); 886747b715Smrg if (rc != Success && rc != BadValue) 8935c4bbdfSmrg return rc; 9035c4bbdfSmrg 9135c4bbdfSmrg if (stuff->enable & (RRScreenChangeNotifyMask | 9235c4bbdfSmrg RRCrtcChangeNotifyMask | 9335c4bbdfSmrg RROutputChangeNotifyMask | 9435c4bbdfSmrg RROutputPropertyNotifyMask | 9535c4bbdfSmrg RRProviderChangeNotifyMask | 9635c4bbdfSmrg RRProviderPropertyNotifyMask | 9735c4bbdfSmrg RRResourceChangeNotifyMask)) { 9835c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 9905b261ecSmrg 10035c4bbdfSmrg rrScrPriv(pScreen); 10105b261ecSmrg 10235c4bbdfSmrg pRREvent = NULL; 10335c4bbdfSmrg if (pHead) { 10435c4bbdfSmrg /* check for existing entry. */ 10535c4bbdfSmrg for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) 10635c4bbdfSmrg if (pRREvent->client == client) 10735c4bbdfSmrg break; 10835c4bbdfSmrg } 10905b261ecSmrg 11035c4bbdfSmrg if (!pRREvent) { 11135c4bbdfSmrg /* build the entry */ 11235c4bbdfSmrg pRREvent = (RREventPtr) malloc(sizeof(RREventRec)); 11335c4bbdfSmrg if (!pRREvent) 11435c4bbdfSmrg return BadAlloc; 11535c4bbdfSmrg pRREvent->next = 0; 11635c4bbdfSmrg pRREvent->client = client; 11735c4bbdfSmrg pRREvent->window = pWin; 11835c4bbdfSmrg pRREvent->mask = stuff->enable; 11935c4bbdfSmrg /* 12035c4bbdfSmrg * add a resource that will be deleted when 12135c4bbdfSmrg * the client goes away 12235c4bbdfSmrg */ 12335c4bbdfSmrg clientResource = FakeClientID(client->index); 12435c4bbdfSmrg pRREvent->clientResource = clientResource; 12535c4bbdfSmrg if (!AddResource(clientResource, RRClientType, (void *) pRREvent)) 12635c4bbdfSmrg return BadAlloc; 12735c4bbdfSmrg /* 12835c4bbdfSmrg * create a resource to contain a pointer to the list 12935c4bbdfSmrg * of clients selecting input. This must be indirect as 13035c4bbdfSmrg * the list may be arbitrarily rearranged which cannot be 13135c4bbdfSmrg * done through the resource database. 13235c4bbdfSmrg */ 13335c4bbdfSmrg if (!pHead) { 13435c4bbdfSmrg pHead = (RREventPtr *) malloc(sizeof(RREventPtr)); 13535c4bbdfSmrg if (!pHead || 13635c4bbdfSmrg !AddResource(pWin->drawable.id, RREventType, 13735c4bbdfSmrg (void *) pHead)) { 13835c4bbdfSmrg FreeResource(clientResource, RT_NONE); 13935c4bbdfSmrg return BadAlloc; 14035c4bbdfSmrg } 14135c4bbdfSmrg *pHead = 0; 14235c4bbdfSmrg } 14335c4bbdfSmrg pRREvent->next = *pHead; 14435c4bbdfSmrg *pHead = pRREvent; 14535c4bbdfSmrg } 14635c4bbdfSmrg /* 14735c4bbdfSmrg * Now see if the client needs an event 14835c4bbdfSmrg */ 14935c4bbdfSmrg if (pScrPriv) { 15035c4bbdfSmrg pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; 15135c4bbdfSmrg if (CompareTimeStamps(pTimes->setTime, 15235c4bbdfSmrg pScrPriv->lastSetTime) != 0 || 15335c4bbdfSmrg CompareTimeStamps(pTimes->configTime, 15435c4bbdfSmrg pScrPriv->lastConfigTime) != 0) { 15535c4bbdfSmrg if (pRREvent->mask & RRScreenChangeNotifyMask) { 15635c4bbdfSmrg RRDeliverScreenEvent(client, pWin, pScreen); 15735c4bbdfSmrg } 1589ace9065Smrg 15935c4bbdfSmrg if (pRREvent->mask & RRCrtcChangeNotifyMask) { 16035c4bbdfSmrg int i; 1619ace9065Smrg 16235c4bbdfSmrg for (i = 0; i < pScrPriv->numCrtcs; i++) { 16335c4bbdfSmrg RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]); 16435c4bbdfSmrg } 16535c4bbdfSmrg } 1669ace9065Smrg 16735c4bbdfSmrg if (pRREvent->mask & RROutputChangeNotifyMask) { 16835c4bbdfSmrg int i; 1699ace9065Smrg 17035c4bbdfSmrg for (i = 0; i < pScrPriv->numOutputs; i++) { 17135c4bbdfSmrg RRDeliverOutputEvent(client, pWin, 17235c4bbdfSmrg pScrPriv->outputs[i]); 17335c4bbdfSmrg } 17435c4bbdfSmrg } 1759ace9065Smrg 17635c4bbdfSmrg /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't 17735c4bbdfSmrg * say if there ought to be notifications of changes to output properties 17835c4bbdfSmrg * if those changes occurred before the time RRSelectInput is called. 17935c4bbdfSmrg */ 18035c4bbdfSmrg } 18135c4bbdfSmrg } 18205b261ecSmrg } 18335c4bbdfSmrg else if (stuff->enable == 0) { 18435c4bbdfSmrg /* delete the interest */ 18535c4bbdfSmrg if (pHead) { 18635c4bbdfSmrg RREventPtr pNewRREvent = 0; 18735c4bbdfSmrg 18835c4bbdfSmrg for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { 18935c4bbdfSmrg if (pRREvent->client == client) 19035c4bbdfSmrg break; 19135c4bbdfSmrg pNewRREvent = pRREvent; 19235c4bbdfSmrg } 19335c4bbdfSmrg if (pRREvent) { 19435c4bbdfSmrg FreeResource(pRREvent->clientResource, RRClientType); 19535c4bbdfSmrg if (pNewRREvent) 19635c4bbdfSmrg pNewRREvent->next = pRREvent->next; 19735c4bbdfSmrg else 19835c4bbdfSmrg *pHead = pRREvent->next; 19935c4bbdfSmrg free(pRREvent); 20035c4bbdfSmrg } 20135c4bbdfSmrg } 20205b261ecSmrg } 20335c4bbdfSmrg else { 20435c4bbdfSmrg client->errorValue = stuff->enable; 20535c4bbdfSmrg return BadValue; 20605b261ecSmrg } 20705b261ecSmrg return Success; 20805b261ecSmrg} 20905b261ecSmrg 21035c4bbdfSmrgint (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = { 21135c4bbdfSmrg ProcRRQueryVersion, /* 0 */ 21205b261ecSmrg/* we skip 1 to make old clients fail pretty immediately */ 21335c4bbdfSmrg NULL, /* 1 ProcRandrOldGetScreenInfo */ 21405b261ecSmrg/* V1.0 apps share the same set screen config request id */ 21535c4bbdfSmrg ProcRRSetScreenConfig, /* 2 */ 21635c4bbdfSmrg NULL, /* 3 ProcRandrOldScreenChangeSelectInput */ 21705b261ecSmrg/* 3 used to be ScreenChangeSelectInput; deprecated */ 21835c4bbdfSmrg ProcRRSelectInput, /* 4 */ 21935c4bbdfSmrg ProcRRGetScreenInfo, /* 5 */ 22005b261ecSmrg/* V1.2 additions */ 22135c4bbdfSmrg ProcRRGetScreenSizeRange, /* 6 */ 22235c4bbdfSmrg ProcRRSetScreenSize, /* 7 */ 22335c4bbdfSmrg ProcRRGetScreenResources, /* 8 */ 22435c4bbdfSmrg ProcRRGetOutputInfo, /* 9 */ 22535c4bbdfSmrg ProcRRListOutputProperties, /* 10 */ 22635c4bbdfSmrg ProcRRQueryOutputProperty, /* 11 */ 22735c4bbdfSmrg ProcRRConfigureOutputProperty, /* 12 */ 22835c4bbdfSmrg ProcRRChangeOutputProperty, /* 13 */ 22935c4bbdfSmrg ProcRRDeleteOutputProperty, /* 14 */ 23035c4bbdfSmrg ProcRRGetOutputProperty, /* 15 */ 23135c4bbdfSmrg ProcRRCreateMode, /* 16 */ 23235c4bbdfSmrg ProcRRDestroyMode, /* 17 */ 23335c4bbdfSmrg ProcRRAddOutputMode, /* 18 */ 23435c4bbdfSmrg ProcRRDeleteOutputMode, /* 19 */ 23535c4bbdfSmrg ProcRRGetCrtcInfo, /* 20 */ 23635c4bbdfSmrg ProcRRSetCrtcConfig, /* 21 */ 23735c4bbdfSmrg ProcRRGetCrtcGammaSize, /* 22 */ 23835c4bbdfSmrg ProcRRGetCrtcGamma, /* 23 */ 23935c4bbdfSmrg ProcRRSetCrtcGamma, /* 24 */ 2404642e01fSmrg/* V1.3 additions */ 24135c4bbdfSmrg ProcRRGetScreenResourcesCurrent, /* 25 */ 24235c4bbdfSmrg ProcRRSetCrtcTransform, /* 26 */ 24335c4bbdfSmrg ProcRRGetCrtcTransform, /* 27 */ 24435c4bbdfSmrg ProcRRGetPanning, /* 28 */ 24535c4bbdfSmrg ProcRRSetPanning, /* 29 */ 24635c4bbdfSmrg ProcRRSetOutputPrimary, /* 30 */ 24735c4bbdfSmrg ProcRRGetOutputPrimary, /* 31 */ 24835c4bbdfSmrg/* V1.4 additions */ 24935c4bbdfSmrg ProcRRGetProviders, /* 32 */ 25035c4bbdfSmrg ProcRRGetProviderInfo, /* 33 */ 25135c4bbdfSmrg ProcRRSetProviderOffloadSink, /* 34 */ 25235c4bbdfSmrg ProcRRSetProviderOutputSource, /* 35 */ 25335c4bbdfSmrg ProcRRListProviderProperties, /* 36 */ 25435c4bbdfSmrg ProcRRQueryProviderProperty, /* 37 */ 25535c4bbdfSmrg ProcRRConfigureProviderProperty, /* 38 */ 25635c4bbdfSmrg ProcRRChangeProviderProperty, /* 39 */ 25735c4bbdfSmrg ProcRRDeleteProviderProperty, /* 40 */ 25835c4bbdfSmrg ProcRRGetProviderProperty, /* 41 */ 2591b5d61b8Smrg/* V1.5 additions */ 26035c4bbdfSmrg ProcRRGetMonitors, /* 42 */ 26135c4bbdfSmrg ProcRRSetMonitor, /* 43 */ 26235c4bbdfSmrg ProcRRDeleteMonitor, /* 44 */ 2631b5d61b8Smrg/* V1.6 additions */ 2641b5d61b8Smrg ProcRRCreateLease, /* 45 */ 2651b5d61b8Smrg ProcRRFreeLease, /* 46 */ 26605b261ecSmrg}; 267