[PATCH xserver] dpms: Add support for DPMSInfoNotify event
From: Alexander Volkov It was introduced in DPMS 1.2 (xorgproto). This allows applications to respond to changes of power level of a monitor, e.g. an application may stop rendering and related calculations when the monitor is off. Related bug: https://bugs.freedesktop.org/57120 Signed-off-by: Alexander Volkov --- Xext/dpms.c | 212 ++-- 1 file changed, 207 insertions(+), 5 deletions(-) diff --git a/Xext/dpms.c b/Xext/dpms.c index e43a37974..3ac8b5795 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -50,6 +50,173 @@ CARD32 DPMSSuspendTime = -1; CARD32 DPMSOffTime = -1; Bool DPMSEnabled; +static int DPMSEventBase = 0; +static RESTYPE ClientType, DPMSEventType; /* resource types for event masks */ +static XID eventResource; + +typedef struct _DPMSEvent *DPMSEventPtr; +typedef struct _DPMSEvent { +DPMSEventPtr next; +ClientPtr client; +XID clientResource; +unsigned int mask; +} DPMSEventRec; + + /*ARGSUSED*/ static int +DPMSFreeClient(void *data, XID id) +{ +DPMSEventPtr pEvent; +DPMSEventPtr *pHead, pCur, pPrev; + +pEvent = (DPMSEventPtr) data; +dixLookupResourceByType((void *) &pHead, eventResource, DPMSEventType, +NullClient, DixUnknownAccess); +if (pHead) { +pPrev = 0; +for (pCur = *pHead; pCur && pCur != pEvent; pCur = pCur->next) +pPrev = pCur; +if (pCur) { +if (pPrev) +pPrev->next = pEvent->next; +else +*pHead = pEvent->next; +} +} +free((void *) pEvent); +return 1; +} + + /*ARGSUSED*/ static int +DPMSFreeEvents(void *data, XID id) +{ +DPMSEventPtr *pHead, pCur, pNext; + +pHead = (DPMSEventPtr *) data; +for (pCur = *pHead; pCur; pCur = pNext) { +pNext = pCur->next; +FreeResource(pCur->clientResource, ClientType); +free((void *) pCur); +} +free((void *) pHead); +return 1; +} + +static void +SDPMSInfoNotifyEvent(xDPMSInfoNotifyEvent * from, + xDPMSInfoNotifyEvent * to) +{ +to->type = from->type; +cpswaps(from->sequenceNumber, to->sequenceNumber); +cpswapl(from->timestamp, to->timestamp); +cpswaps(from->power_level, to->power_level); +to->state = from->state; +} + +static int +ProcDPMSSelectInput(register ClientPtr client) +{ +REQUEST(xDPMSSelectInputReq); +DPMSEventPtr pEvent, pNewEvent, *pHead; +XID clientResource; +int i; + +REQUEST_SIZE_MATCH(xDPMSSelectInputReq); +i = dixLookupResourceByType((void **)&pHead, eventResource, DPMSEventType, +client, +DixWriteAccess); +if (stuff->eventMask != 0) { +if (i == Success && pHead) { +/* check for existing entry. */ +for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { +if (pEvent->client == client) { +pEvent->mask = stuff->eventMask; +return Success; +} +} +} + +/* build the entry */ +pNewEvent = (DPMSEventPtr)malloc(sizeof(DPMSEventRec)); +if (!pNewEvent) +return BadAlloc; +pNewEvent->next = 0; +pNewEvent->client = client; +pNewEvent->mask = stuff->eventMask; +/* + * add a resource that will be deleted when + * the client goes away + */ +clientResource = FakeClientID(client->index); +pNewEvent->clientResource = clientResource; +if (!AddResource(clientResource, ClientType, (void *)pNewEvent)) +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 (i != Success || !pHead) { +pHead = (DPMSEventPtr *)malloc(sizeof(DPMSEventPtr)); +if (!pHead || +!AddResource(eventResource, DPMSEventType, (void *)pHead)) { +FreeResource(clientResource, RT_NONE); +return BadAlloc; +} +*pHead = 0; +} +pNewEvent->next = *pHead; +*pHead = pNewEvent; +} +else if (stuff->eventMask == 0) { +/* delete the interest */ +if (i == Success && pHead) { +pNewEvent = 0; +for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { +if (pEvent->client == client) +break; +pNewEvent = pEvent; +} +if (pEvent) { +FreeResource(pEvent->clientResource, ClientType); +if (pNewEvent) +pNewEvent->next = pEvent->next; +else +*pHead = pEvent->next; +free(pEvent); +}
[PATCH xserver] dpms: Add support for DPMSInfoNotify event
From: Alexander Volkov It was introduced in DPMS 1.2 (xorgproto). This allows applications to respond to changes of power level of a monitor, e.g. an application may stop rendering and related calculations when the monitor is off. Related bug: https://bugs.freedesktop.org/57120 Signed-off-by: Alexander Volkov --- Xext/dpms.c | 212 ++-- 1 file changed, 207 insertions(+), 5 deletions(-) diff --git a/Xext/dpms.c b/Xext/dpms.c index e43a37974..3ac8b5795 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -50,6 +50,173 @@ CARD32 DPMSSuspendTime = -1; CARD32 DPMSOffTime = -1; Bool DPMSEnabled; +static int DPMSEventBase = 0; +static RESTYPE ClientType, DPMSEventType; /* resource types for event masks */ +static XID eventResource; + +typedef struct _DPMSEvent *DPMSEventPtr; +typedef struct _DPMSEvent { +DPMSEventPtr next; +ClientPtr client; +XID clientResource; +unsigned int mask; +} DPMSEventRec; + + /*ARGSUSED*/ static int +DPMSFreeClient(void *data, XID id) +{ +DPMSEventPtr pEvent; +DPMSEventPtr *pHead, pCur, pPrev; + +pEvent = (DPMSEventPtr) data; +dixLookupResourceByType((void *) &pHead, eventResource, DPMSEventType, +NullClient, DixUnknownAccess); +if (pHead) { +pPrev = 0; +for (pCur = *pHead; pCur && pCur != pEvent; pCur = pCur->next) +pPrev = pCur; +if (pCur) { +if (pPrev) +pPrev->next = pEvent->next; +else +*pHead = pEvent->next; +} +} +free((void *) pEvent); +return 1; +} + + /*ARGSUSED*/ static int +DPMSFreeEvents(void *data, XID id) +{ +DPMSEventPtr *pHead, pCur, pNext; + +pHead = (DPMSEventPtr *) data; +for (pCur = *pHead; pCur; pCur = pNext) { +pNext = pCur->next; +FreeResource(pCur->clientResource, ClientType); +free((void *) pCur); +} +free((void *) pHead); +return 1; +} + +static void +SDPMSInfoNotifyEvent(xDPMSInfoNotifyEvent * from, + xDPMSInfoNotifyEvent * to) +{ +to->type = from->type; +cpswaps(from->sequenceNumber, to->sequenceNumber); +cpswapl(from->timestamp, to->timestamp); +cpswaps(from->power_level, to->power_level); +to->state = from->state; +} + +static int +ProcDPMSSelectInput(register ClientPtr client) +{ +REQUEST(xDPMSSelectInputReq); +DPMSEventPtr pEvent, pNewEvent, *pHead; +XID clientResource; +int i; + +REQUEST_SIZE_MATCH(xDPMSSelectInputReq); +i = dixLookupResourceByType((void **)&pHead, eventResource, DPMSEventType, +client, +DixWriteAccess); +if (stuff->eventMask != 0) { +if (i == Success && pHead) { +/* check for existing entry. */ +for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { +if (pEvent->client == client) { +pEvent->mask = stuff->eventMask; +return Success; +} +} +} + +/* build the entry */ +pNewEvent = (DPMSEventPtr)malloc(sizeof(DPMSEventRec)); +if (!pNewEvent) +return BadAlloc; +pNewEvent->next = 0; +pNewEvent->client = client; +pNewEvent->mask = stuff->eventMask; +/* + * add a resource that will be deleted when + * the client goes away + */ +clientResource = FakeClientID(client->index); +pNewEvent->clientResource = clientResource; +if (!AddResource(clientResource, ClientType, (void *)pNewEvent)) +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 (i != Success || !pHead) { +pHead = (DPMSEventPtr *)malloc(sizeof(DPMSEventPtr)); +if (!pHead || +!AddResource(eventResource, DPMSEventType, (void *)pHead)) { +FreeResource(clientResource, RT_NONE); +return BadAlloc; +} +*pHead = 0; +} +pNewEvent->next = *pHead; +*pHead = pNewEvent; +} +else if (stuff->eventMask == 0) { +/* delete the interest */ +if (i == Success && pHead) { +pNewEvent = 0; +for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { +if (pEvent->client == client) +break; +pNewEvent = pEvent; +} +if (pEvent) { +FreeResource(pEvent->clientResource, ClientType); +if (pNewEvent) +pNewEvent->next = pEvent->next; +else +*pHead = pEvent->next; +free(pEvent); +}