Re: [PATCH xserver v2] dpms: Add support for DPMSInfoNotify event

2018-10-02 Thread Александр Волков

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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Peter Harris
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

2018-10-02 Thread Alexander Volkov

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

2018-10-02 Thread Julien Cristau
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

2018-10-02 Thread Alexander Volkov

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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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

2018-10-02 Thread Alexander Volkov
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);
+}
+}