示例#1
0
文件: randr.c 项目: hush-z/VMGL
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;
}
示例#2
0
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;
}