static int TellChanged (WindowPtr pWin, pointer value) { RREventPtr *pHead, pRREvent; ClientPtr client; ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); int i; dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, RREventType, serverClient, DixReadAccess); if (!pHead) return WT_WALKCHILDREN; for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) { client = pRREvent->client; if (client == serverClient || client->clientGone) continue; if (pRREvent->mask & RRScreenChangeNotifyMask) RRDeliverScreenEvent (client, pWin, pScreen); if (pRREvent->mask & RRCrtcChangeNotifyMask) { for (i = 0; i < pScrPriv->numCrtcs; i++) { RRCrtcPtr crtc = pScrPriv->crtcs[i]; if (crtc->changed) RRDeliverCrtcEvent (client, pWin, crtc); } } if (pRREvent->mask & RROutputChangeNotifyMask) { for (i = 0; i < pScrPriv->numOutputs; i++) { RROutputPtr output = pScrPriv->outputs[i]; if (output->changed) RRDeliverOutputEvent (client, pWin, output); } } } return WT_WALKCHILDREN; }
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; rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id, RREventType, client, DixWriteAccess); if (rc != Success && rc != BadValue) return rc; if (stuff->enable & (RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask | RRProviderPropertyNotifyMask)) { ScreenPtr pScreen = pWin->drawable.pScreen; rrScrPriv(pScreen); pRREvent = NULL; if (pHead) { /* check for existing entry. */ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) if (pRREvent->client == client) break; } if (!pRREvent) { /* build the entry */ pRREvent = (RREventPtr) malloc(sizeof(RREventRec)); if (!pRREvent) return BadAlloc; 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, RRClientType, (void *) 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 *) malloc(sizeof(RREventPtr)); if (!pHead || !AddResource(pWin->drawable.id, RREventType, (void *) pHead)) { FreeResource(clientResource, RT_NONE); return BadAlloc; } *pHead = 0; } pRREvent->next = *pHead; *pHead = pRREvent; } /* * Now see if the client needs an event */ if (pScrPriv) { pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum]; if (CompareTimeStamps(pTimes->setTime, pScrPriv->lastSetTime) != 0 || CompareTimeStamps(pTimes->configTime, pScrPriv->lastConfigTime) != 0) { if (pRREvent->mask & RRScreenChangeNotifyMask) { RRDeliverScreenEvent(client, pWin, pScreen); } if (pRREvent->mask & RRCrtcChangeNotifyMask) { int i; for (i = 0; i < pScrPriv->numCrtcs; i++) { RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]); } } if (pRREvent->mask & RROutputChangeNotifyMask) { int i; for (i = 0; i < pScrPriv->numOutputs; i++) { RRDeliverOutputEvent(client, pWin, pScrPriv->outputs[i]); } } /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't * say if there ought to be notifications of changes to output properties * if those changes occurred before the time RRSelectInput is called. */ } } } else if (stuff->enable == 0) { /* delete the interest */ 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; free(pRREvent); } } } else { client->errorValue = stuff->enable; return BadValue; } return Success; }