Re: [PATCH xserver v2] dpms: Add support for DPMSInfoNotify event
Patch for xcb-proto and a test program are applied. The test program can be compiled by gcc -o dpmsnotify dpmsnotify.c -lxcb -lxcb-dpms >From 00f7947121181fc98cb09e4b86e14bd4738958d0 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 1 Oct 2018 19:41:18 +0300 Subject: [PATCH] dpms: Add DPMSInfoNotify event See the description in xorgproto repository. Signed-off-by: Alexander Volkov --- src/dpms.xml | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/dpms.xml b/src/dpms.xml index 5581284..814a14e 100644 --- a/src/dpms.xml +++ b/src/dpms.xml @@ -26,7 +26,8 @@ sale, use or other dealings in this Software without prior written authorization from the authors. --> +major-version="1" minor-version="2"> + xproto @@ -84,4 +85,20 @@ authorization from the authors. + + + 0 + + + + + + + + + + + + + -- 2.17.0 #include #include #include #include int main() { xcb_connection_t*c; xcb_generic_event_t *e; /* Open the connection to the X server */ c = xcb_connect (NULL, NULL); const struct xcb_query_extension_reply_t *dpms = xcb_get_extension_data(c, _dpms_id); fprintf(stdout, "dpms present %d\n", dpms->present); xcb_dpms_get_version_cookie_t version_cookie = xcb_dpms_get_version(c, XCB_DPMS_MAJOR_VERSION, XCB_DPMS_MINOR_VERSION); xcb_dpms_get_version_reply_t *version_reply = xcb_dpms_get_version_reply(c, version_cookie, NULL); fprintf(stdout, "dpms version %d.%d\n", version_reply->server_major_version, version_reply->server_minor_version); free(version_reply); xcb_dpms_select_input(c, XCB_DPMS_EVENT_MASK_INFO_NOTIFY); xcb_flush (c); while ((e = xcb_wait_for_event (c))) { uint8_t response_type = e->response_type & ~0x80; if (response_type == XCB_GE_GENERIC) { xcb_dpms_info_notify_event_t *info = (xcb_dpms_info_notify_event_t *)e; if (info->extension == dpms->major_opcode && info->event_type == XCB_DPMS_INFO_NOTIFY) fprintf(stdout, "dpms state %d, power level %d\n", info->state, info->power_level); } free (e); } return 0; } ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver v2] 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 v2: send as generic event Signed-off-by: Alexander Volkov --- Xext/dpms.c | 219 ++-- 1 file changed, 214 insertions(+), 5 deletions(-) diff --git a/Xext/dpms.c b/Xext/dpms.c index e43a37974..2a39b3d5d 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -50,6 +50,180 @@ CARD32 DPMSSuspendTime = -1; CARD32 DPMSOffTime = -1; Bool DPMSEnabled; +static int DPMSReqCode = 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 *) , 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(xGenericEvent * from, + xGenericEvent * to) +{ +*to = *from; +swaps(>sequenceNumber); +swapl(>length); +swaps(>evtype); +if (from->evtype == DPMSInfoNotify) { +xDPMSInfoNotifyEvent *c = (xDPMSInfoNotifyEvent *) to; +swapl(>timestamp); +swaps(>power_level); +} +} + +static int +ProcDPMSSelectInput(register ClientPtr client) +{ +REQUEST(xDPMSSelectInputReq); +DPMSEventPtr pEvent, pNewEvent, *pHead; +XID clientResource; +int i; + +REQUEST_SIZE_MATCH(xDPMSSelectInputReq); +i = dixLookupResourceByType((void **), 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 =
[PATCH xorgproto v2] Add DPMSInfoNotify event
From: Alexander Volkov 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. Bump DPMS version to 1.2. v2: add it as generic event Signed-off-by: Alexander Volkov --- include/X11/extensions/dpmsconst.h | 5 - include/X11/extensions/dpmsproto.h | 26 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/X11/extensions/dpmsconst.h b/include/X11/extensions/dpmsconst.h index 75f0586..f46d2d9 100644 --- a/include/X11/extensions/dpmsconst.h +++ b/include/X11/extensions/dpmsconst.h @@ -30,7 +30,7 @@ Equipment Corporation. #define _DPMSCONST_H 1 #define DPMSMajorVersion 1 -#define DPMSMinorVersion 1 +#define DPMSMinorVersion 2 #define DPMSExtensionName "DPMS" @@ -39,5 +39,8 @@ Equipment Corporation. #define DPMSModeSuspend2 #define DPMSModeOff3 +#define DPMSInfoNotifyMask (1L << 0) +#define DPMSInfoNotify 0 + #endif /* !_DPMSCONST_H */ diff --git a/include/X11/extensions/dpmsproto.h b/include/X11/extensions/dpmsproto.h index 63fd3fc..5d1aeec 100644 --- a/include/X11/extensions/dpmsproto.h +++ b/include/X11/extensions/dpmsproto.h @@ -39,6 +39,7 @@ Equipment Corporation. #define X_DPMSDisable 5 #define X_DPMSForceLevel 6 #define X_DPMSInfo 7 +#define X_DPMSSelectInput 8 #define DPMSNumberEvents 0 @@ -172,4 +173,29 @@ typedef struct { } xDPMSInfoReply; #define sz_xDPMSInfoReply 32 +typedef struct { +CARD8 reqType;/* always DPMSCode */ +CARD8 dpmsReqType;/* always X_DPMSSelectInput */ +CARD16 length B16; +CARD32 eventMask B32; +} xDPMSSelectInputReq; +#define sz_xDPMSSelectInputReq 8 + +typedef struct { +CARD8 type; +CARD8 extension; +CARD16 sequenceNumber B16; +CARD32 length; +CARD16 evtype B16; +CARD16 pad0 B16; +Time timestamp B32; +CARD16 power_level B16; +BOOL state; +CARD8 pad1; +CARD32 pad2 B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +} xDPMSInfoNotifyEvent; +#define sz_xDPMSInfoNotifyEvent 32 + #endif /* _DPMSPROTO_H_ */ -- 2.17.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
RE: [EXTERNAL] - [PATCH xorgproto] Add DPMSInfoNotify event
On 2018-10-02 Alexander Volkov wrote: > > -#define DPMSNumberEvents 0 > +#define DPMSNumberEvents 1 I don't have a strong opinion, so feel free to ignore me, but in general we don't add core events any more (the limited event space is already full in some configurations). The "modern" way to add events to extensions is called "generic events". Xcb has . I'm not sure how Xlib works. See the Present extension for a recent example that uses generic events. Peter Harris ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xorgproto] Add DPMSInfoNotify event
02.10.2018 17:33, Julien Cristau пишет: We shouldn't be adding new extension events that don't come through the Generic Event Extension, as the extension event space is basically full, IIRC (see https://lists.x.org/pipermail/xorg-devel/2010-March/006716.html). Ok, thanks. This also seems like it might belong in RANDR rather than DPMS, as DPMS doesn't actually tie things to a monitor? DPMS turns off/on all monitors. It's more convenient to process a single event than to detect available area from monitor's state. Besides it seems much harder to implemet DPMS for RANDR. ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xorgproto] Add DPMSInfoNotify event
On 10/02/2018 03:10 PM, Alexander Volkov wrote: > From: Alexander Volkov > > 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. > > Bump DPMS version to 1.2. > > Signed-off-by: Alexander Volkov > --- > include/X11/extensions/dpmsconst.h | 5 - > include/X11/extensions/dpmsproto.h | 27 ++- > 2 files changed, 30 insertions(+), 2 deletions(-) > We shouldn't be adding new extension events that don't come through the Generic Event Extension, as the extension event space is basically full, IIRC (see https://lists.x.org/pipermail/xorg-devel/2010-March/006716.html). This also seems like it might belong in RANDR rather than DPMS, as DPMS doesn't actually tie things to a monitor? Cheers, Julien ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xcb] dpms: Add DPMSInfoNotify event
Oh, sorry for sending it twice. See the test program in the attachment. It can be compiled by gcc -o dpmsnotify dpmsnotify.c -lxcb -lxcb-dpms #include #include #include #include int main() { xcb_connection_t*c; xcb_generic_event_t *e; /* Open the connection to the X server */ c = xcb_connect (NULL, NULL); const struct xcb_query_extension_reply_t *dpms = xcb_get_extension_data(c, _dpms_id); fprintf(stdout, "dpms present %d\n", dpms->present); xcb_dpms_get_version_cookie_t version_cookie = xcb_dpms_get_version(c, XCB_DPMS_MAJOR_VERSION, XCB_DPMS_MINOR_VERSION); xcb_dpms_get_version_reply_t *version_reply = xcb_dpms_get_version_reply(c, version_cookie, NULL); fprintf(stdout, "dpms version %d.%d\n", version_reply->server_major_version, version_reply->server_minor_version); free(version_reply); xcb_dpms_select_input(c, XCB_DPMS_EVENT_MASK_INFO_NOTIFY); xcb_flush (c); while ((e = xcb_wait_for_event (c))) { uint8_t response_type = e->response_type & ~0x80; if (response_type == dpms->first_event + XCB_DPMS_INFO_NOTIFY) { xcb_dpms_info_notify_event_t *info = (xcb_dpms_info_notify_event_t *)e; fprintf(stdout, "dpms state %d, power level %d\n", info->state, info->power_level); } free (e); } return 0; } ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[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 *) , 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 **), 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 xcb] dpms: Add DPMSInfoNotify event
From: Alexander Volkov See the description in xorgproto repository. Signed-off-by: Alexander Volkov --- src/dpms.xml | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/dpms.xml b/src/dpms.xml index 5581284..51decb7 100644 --- a/src/dpms.xml +++ b/src/dpms.xml @@ -26,7 +26,8 @@ sale, use or other dealings in this Software without prior written authorization from the authors. --> +major-version="1" minor-version="2"> + xproto @@ -84,4 +85,20 @@ authorization from the authors. + + + 0 + + + + + + + + + + + + + -- 2.17.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xorgproto] Add DPMSInfoNotify event
From: Alexander Volkov 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. Bump DPMS version to 1.2. Signed-off-by: Alexander Volkov --- include/X11/extensions/dpmsconst.h | 5 - include/X11/extensions/dpmsproto.h | 27 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/X11/extensions/dpmsconst.h b/include/X11/extensions/dpmsconst.h index 75f0586..f46d2d9 100644 --- a/include/X11/extensions/dpmsconst.h +++ b/include/X11/extensions/dpmsconst.h @@ -30,7 +30,7 @@ Equipment Corporation. #define _DPMSCONST_H 1 #define DPMSMajorVersion 1 -#define DPMSMinorVersion 1 +#define DPMSMinorVersion 2 #define DPMSExtensionName "DPMS" @@ -39,5 +39,8 @@ Equipment Corporation. #define DPMSModeSuspend2 #define DPMSModeOff3 +#define DPMSInfoNotifyMask (1L << 0) +#define DPMSInfoNotify 0 + #endif /* !_DPMSCONST_H */ diff --git a/include/X11/extensions/dpmsproto.h b/include/X11/extensions/dpmsproto.h index 63fd3fc..9c26054 100644 --- a/include/X11/extensions/dpmsproto.h +++ b/include/X11/extensions/dpmsproto.h @@ -39,8 +39,9 @@ Equipment Corporation. #define X_DPMSDisable 5 #define X_DPMSForceLevel 6 #define X_DPMSInfo 7 +#define X_DPMSSelectInput 8 -#define DPMSNumberEvents 0 +#define DPMSNumberEvents 1 #define DPMSNumberErrors 0 @@ -172,4 +173,28 @@ typedef struct { } xDPMSInfoReply; #define sz_xDPMSInfoReply 32 +typedef struct { +CARD8 reqType;/* always DPMSCode */ +CARD8 dpmsReqType;/* always X_DPMSSelectInput */ +CARD16 length B16; +CARD32 eventMask B32; +} xDPMSSelectInputReq; +#define sz_xDPMSSelectInputReq 8 + +typedef struct { +CARD8 type; /* always eventBase + DPMSInfoNotify */ +CARD8 pad0; +CARD16 sequenceNumber B16; +Time timestamp B32; +CARD16 power_level B16; +BOOL state; +CARD8 pad1; +CARD32 pad2 B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +CARD32 pad5 B32; +CARD32 pad6 B32; +} xDPMSInfoNotifyEvent; +#define sz_xDPMSInfoNotifyEvent 32 + #endif /* _DPMSPROTO_H_ */ -- 2.17.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xcb] dpms: Add DPMSInfoNotify event
From: Alexander Volkov See the description in xorgproto repository. Signed-off-by: Alexander Volkov --- src/dpms.xml | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/dpms.xml b/src/dpms.xml index 5581284..51decb7 100644 --- a/src/dpms.xml +++ b/src/dpms.xml @@ -26,7 +26,8 @@ sale, use or other dealings in this Software without prior written authorization from the authors. --> +major-version="1" minor-version="2"> + xproto @@ -84,4 +85,20 @@ authorization from the authors. + + + 0 + + + + + + + + + + + + + -- 2.17.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xorgproto] Add DPMSInfoNotify event
From: Alexander Volkov 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. Bump DPMS version to 1.2. Signed-off-by: Alexander Volkov --- include/X11/extensions/dpmsconst.h | 5 - include/X11/extensions/dpmsproto.h | 27 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/X11/extensions/dpmsconst.h b/include/X11/extensions/dpmsconst.h index 75f0586..f46d2d9 100644 --- a/include/X11/extensions/dpmsconst.h +++ b/include/X11/extensions/dpmsconst.h @@ -30,7 +30,7 @@ Equipment Corporation. #define _DPMSCONST_H 1 #define DPMSMajorVersion 1 -#define DPMSMinorVersion 1 +#define DPMSMinorVersion 2 #define DPMSExtensionName "DPMS" @@ -39,5 +39,8 @@ Equipment Corporation. #define DPMSModeSuspend2 #define DPMSModeOff3 +#define DPMSInfoNotifyMask (1L << 0) +#define DPMSInfoNotify 0 + #endif /* !_DPMSCONST_H */ diff --git a/include/X11/extensions/dpmsproto.h b/include/X11/extensions/dpmsproto.h index 63fd3fc..9c26054 100644 --- a/include/X11/extensions/dpmsproto.h +++ b/include/X11/extensions/dpmsproto.h @@ -39,8 +39,9 @@ Equipment Corporation. #define X_DPMSDisable 5 #define X_DPMSForceLevel 6 #define X_DPMSInfo 7 +#define X_DPMSSelectInput 8 -#define DPMSNumberEvents 0 +#define DPMSNumberEvents 1 #define DPMSNumberErrors 0 @@ -172,4 +173,28 @@ typedef struct { } xDPMSInfoReply; #define sz_xDPMSInfoReply 32 +typedef struct { +CARD8 reqType;/* always DPMSCode */ +CARD8 dpmsReqType;/* always X_DPMSSelectInput */ +CARD16 length B16; +CARD32 eventMask B32; +} xDPMSSelectInputReq; +#define sz_xDPMSSelectInputReq 8 + +typedef struct { +CARD8 type; /* always eventBase + DPMSInfoNotify */ +CARD8 pad0; +CARD16 sequenceNumber B16; +Time timestamp B32; +CARD16 power_level B16; +BOOL state; +CARD8 pad1; +CARD32 pad2 B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +CARD32 pad5 B32; +CARD32 pad6 B32; +} xDPMSInfoNotifyEvent; +#define sz_xDPMSInfoNotifyEvent 32 + #endif /* _DPMSPROTO_H_ */ -- 2.17.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[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 *) , 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 **), 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); +} +}