[RFC] Use XCB to generate DPMS protocol headers and dispatch code

Tomas Carnecky tom at dbservice.com
Fri Aug 6 16:35:04 PDT 2010


Just one big patch for now (it's not that many changes anyway). I just don't
know how to split it up. There's one change that could easily be split up,
but other than that, it's a simple 'replace DPMS related sources in Xext/
with code from proto/ and ext/'. If you have an idea how to split this
up into multiple patches, please tell me.

proto/ houses the templates and script to generate the headers and dispatch
code. I chose to use templates instead of generating code with pure python
like xcb. It's much easier to edit. I added a custom rule to the makefile
in proto/ to automatically generate the files from the xcb xml files.
However, at this point the path to the xml files is hardcoded. Does
anyone know a good way to figure at configure time what the path to those
files is? Another question is whether to ship the generated files in the dist
tarball or depend on xcb to be present even when compiling from a tarball.
I'd prefer is someone more experienced with autotools could give me a hand
and write the correct automake instructions. There are also two supporting
files (common.[ch]), subject to change as I come across more functions which
are useful.

ext/ is the home for the actual implementation. DPMS doesn't have any, it
only depends on two functions which are provided by the DDX. That fact is
documented in the main header for DPMS (ext/dpms/dpms.h): it lists what
the extension is providing (functions, global variables etc) and what it
is using or expecting to be present in the DIX/DDX.

I had to edit/adjust include paths and bits and pieces of code in various
places, that's why the diffstat shows so many files. Currently only Xorg
compiles successfully, the other servers fail with unresolved symbols.
The difference between Xorg and the other servers is that Xorg first
puts all the objects into one big archive and then creates an executable
from that. By doing so it avoids the dependency hell between the different
archives that make up a server. The other servers link the individual
archives directly into the executable and fail. Though not very elegant,
doing what Xorg does in the other servers would save a lot trouble with
the dependencies. I already have a patch which modifies the Xvfb/Xnest/Xdmx
makefiles and it seems to work. Yay or nay to submit for review?

tom

---
 Makefile.am                         |    6 +
 Xext/Makefile.am                    |    7 -
 Xext/dpms.c                         |  379 -----------------------------------
 Xext/dpmsproc.h                     |   15 --
 Xext/dpmsstubs.c                    |    2 +-
 configure.ac                        |   12 +-
 dix/globals.c                       |   10 -
 dix/main.c                          |    5 +-
 ext/Makefile.am                     |    2 +
 ext/dpms/Makefile.am                |    5 +
 ext/dpms/dpms.c                     |   16 ++
 ext/dpms/dpms.h                     |   33 +++
 hw/dmx/dmxdpms.c                    |    4 +-
 hw/kdrive/src/kdrive.c              |    4 +-
 hw/vfb/InitOutput.c                 |    1 +
 hw/xfree86/common/xf86DPMS.c        |    9 +-
 hw/xfree86/common/xf86Events.c      |    9 +-
 hw/xfree86/common/xf86Init.c        |   10 +-
 hw/xfree86/common/xf86Xinput.c      |    5 -
 hw/xfree86/dixmods/extmod/modinit.c |    9 -
 hw/xfree86/dixmods/extmod/modinit.h |    5 -
 hw/xnest/Init.c                     |    4 +-
 hw/xwin/InitOutput.c                |    4 +-
 include/xext.h                      |    9 +
 mi/mieq.c                           |   12 +-
 mi/miinitext.c                      |    3 +
 os/WaitFor.c                        |    4 +-
 proto/Makefile.am                   |   16 ++
 proto/common.c                      |   12 +
 proto/common.h                      |   22 ++
 proto/dpms-glue.c                   |  103 ++++++++++
 proto/xcb-gen.py                    |   71 +++++++
 proto/xcb-gen/proto-defs.h.py       |   35 ++++
 proto/xcb-gen/proto-wire.h.py       |   39 ++++
 proto/xcb-gen/proto.c.py            |  103 ++++++++++
 35 files changed, 508 insertions(+), 477 deletions(-)
 delete mode 100644 Xext/dpms.c
 delete mode 100644 Xext/dpmsproc.h
 create mode 100644 ext/Makefile.am
 create mode 100644 ext/dpms/Makefile.am
 create mode 100644 ext/dpms/dpms.c
 create mode 100644 ext/dpms/dpms.h
 create mode 100644 include/xext.h
 create mode 100644 proto/Makefile.am
 create mode 100644 proto/common.c
 create mode 100644 proto/common.h
 create mode 100644 proto/dpms-glue.c
 create mode 100755 proto/xcb-gen.py
 create mode 100644 proto/xcb-gen/proto-defs.h.py
 create mode 100644 proto/xcb-gen/proto-wire.h.py
 create mode 100644 proto/xcb-gen/proto.c.py

diff --git a/Makefile.am b/Makefile.am
index 8b7a2c8..60ddc5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,8 @@
 AUTOMAKE_OPTIONS=nostdinc
 ACLOCAL_AMFLAGS = -I m4
 
+INCLUDES = -I$(srcdir)
+
 if COMPOSITE
 COMPOSITE_DIR=composite
 endif
@@ -20,6 +22,8 @@ endif
 SUBDIRS = \
 	doc \
 	include \
+	proto \
+	ext \
 	dix  \
 	fb \
 	mi \
@@ -72,6 +76,8 @@ DIST_SUBDIRS = \
 	doc \
 	include \
 	dix  \
+	proto \
+	ext \
 	fb \
 	mi \
 	Xext \
diff --git a/Xext/Makefile.am b/Xext/Makefile.am
index e444fd0..a3aabee 100644
--- a/Xext/Makefile.am
+++ b/Xext/Makefile.am
@@ -105,12 +105,6 @@ if XF86BIGFONT
 BUILTIN_SRCS += $(BIGFONT_SRCS)
 endif
 
-# DPMS extension
-DPMS_SRCS = dpms.c dpmsproc.h
-if DPMSExtension
-MODULE_SRCS += $(DPMS_SRCS)
-endif
-
 # Now take all of the above, mix well, bake for 10 minutes and get libXext*.la
 
 libXext_la_SOURCES =		$(BUILTIN_SRCS) $(MODULE_SRCS)
@@ -134,6 +128,5 @@ EXTRA_DIST = \
 	$(XCALIBRATE_SRCS) \
 	$(XINERAMA_SRCS) \
 	$(BIGFONT_SRCS) \
-	$(DPMS_SRCS) \
         $(GE_SRCS)
 
diff --git a/Xext/dpms.c b/Xext/dpms.c
deleted file mode 100644
index 33a6e26..0000000
--- a/Xext/dpms.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*****************************************************************
-
-Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation 
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital 
-Equipment Corporation.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "opaque.h"
-#include <X11/extensions/dpmsproto.h>
-#include "dpmsproc.h"
-#include "modinit.h"
-
-static int
-ProcDPMSGetVersion(ClientPtr client)
-{
-    /* REQUEST(xDPMSGetVersionReq); */
-    xDPMSGetVersionReply rep;
-    int n;
-
-    REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.majorVersion = DPMSMajorVersion;
-    rep.minorVersion = DPMSMinorVersion;
-    if (client->swapped) {
-    	swaps(&rep.sequenceNumber, n);
-	swaps(&rep.majorVersion, n);
-	swaps(&rep.minorVersion, n);
-    }
-    WriteToClient(client, sizeof(xDPMSGetVersionReply), (char *)&rep);
-    return Success;
-}
-
-static int
-ProcDPMSCapable(ClientPtr client)
-{
-    /* REQUEST(xDPMSCapableReq); */
-    xDPMSCapableReply rep;
-    int n;
-
-    REQUEST_SIZE_MATCH(xDPMSCapableReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.capable = DPMSCapableFlag;
-
-    if (client->swapped) {
-	swaps(&rep.sequenceNumber, n);
-    }
-    WriteToClient(client, sizeof(xDPMSCapableReply), (char *)&rep);
-    return Success;
-}
-
-static int
-ProcDPMSGetTimeouts(ClientPtr client)
-{
-    /* REQUEST(xDPMSGetTimeoutsReq); */
-    xDPMSGetTimeoutsReply rep;
-    int n;
-
-    REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.standby = DPMSStandbyTime / MILLI_PER_SECOND;
-    rep.suspend = DPMSSuspendTime / MILLI_PER_SECOND;
-    rep.off = DPMSOffTime / MILLI_PER_SECOND;
-
-    if (client->swapped) {
-    	swaps(&rep.sequenceNumber, n);
-	swaps(&rep.standby, n);
-	swaps(&rep.suspend, n);
-	swaps(&rep.off, n);
-    }
-    WriteToClient(client, sizeof(xDPMSGetTimeoutsReply), (char *)&rep);
-    return Success;
-}
-
-static int
-ProcDPMSSetTimeouts(ClientPtr client)
-{
-    REQUEST(xDPMSSetTimeoutsReq);
-
-    REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
-
-    if ((stuff->off != 0)&&(stuff->off < stuff->suspend)) 
-    {
-	client->errorValue = stuff->off;
-	return BadValue;
-    }
-    if ((stuff->suspend != 0)&&(stuff->suspend < stuff->standby))
-    {
-	client->errorValue = stuff->suspend;
-	return BadValue;
-    }  
-
-    DPMSStandbyTime = stuff->standby * MILLI_PER_SECOND;
-    DPMSSuspendTime = stuff->suspend * MILLI_PER_SECOND;
-    DPMSOffTime = stuff->off * MILLI_PER_SECOND;
-    SetScreenSaverTimer();
-
-    return Success;
-}
-
-static int
-ProcDPMSEnable(ClientPtr client)
-{
-    Bool was_enabled = DPMSEnabled;
-
-    REQUEST_SIZE_MATCH(xDPMSEnableReq);
-
-    if (DPMSCapableFlag) {
-	DPMSEnabled = TRUE;
-	if (!was_enabled)
-	    SetScreenSaverTimer();
-    }
-
-    return Success;
-}
-
-static int
-ProcDPMSDisable(ClientPtr client)
-{
-    /* REQUEST(xDPMSDisableReq); */
-
-    REQUEST_SIZE_MATCH(xDPMSDisableReq);
-
-    DPMSSet(client, DPMSModeOn);
-
-    DPMSEnabled = FALSE;
-
-    return Success;
-}
-
-static int
-ProcDPMSForceLevel(ClientPtr client)
-{
-    REQUEST(xDPMSForceLevelReq);
-
-    REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
-
-    if (!DPMSEnabled)
-	return BadMatch;
-
-    if (stuff->level != DPMSModeOn &&
-        stuff->level != DPMSModeStandby &&
-        stuff->level != DPMSModeSuspend &&
-        stuff->level != DPMSModeOff) {
-	client->errorValue = stuff->level;
-	return BadValue;
-    }
-
-    DPMSSet(client, stuff->level);
-
-    return Success;
-}
-
-static int
-ProcDPMSInfo(ClientPtr client)
-{
-    /* REQUEST(xDPMSInfoReq); */
-    xDPMSInfoReply rep;
-    int n;
-
-    REQUEST_SIZE_MATCH(xDPMSInfoReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.power_level = DPMSPowerLevel;
-    rep.state = DPMSEnabled;
-
-    if (client->swapped) {
-    	swaps(&rep.sequenceNumber, n);
-	swaps(&rep.power_level, n);
-    }
-    WriteToClient(client, sizeof(xDPMSInfoReply), (char *)&rep);
-    return Success;
-}
-
-static int
-ProcDPMSDispatch (ClientPtr client)
-{
-    REQUEST(xReq);
-
-    switch (stuff->data)
-    {
-    case X_DPMSGetVersion:
-	return ProcDPMSGetVersion(client);
-    case X_DPMSCapable:
-	return ProcDPMSCapable(client);
-    case X_DPMSGetTimeouts:
-	return ProcDPMSGetTimeouts(client);
-    case X_DPMSSetTimeouts:
-	return ProcDPMSSetTimeouts(client);
-    case X_DPMSEnable:
-	return ProcDPMSEnable(client);
-    case X_DPMSDisable:
-	return ProcDPMSDisable(client);
-    case X_DPMSForceLevel:
-	return ProcDPMSForceLevel(client);
-    case X_DPMSInfo:
-	return ProcDPMSInfo(client);
-    default:
-	return BadRequest;
-    }
-}
-
-static int
-SProcDPMSGetVersion(ClientPtr client)
-{
-    int n;
-    REQUEST(xDPMSGetVersionReq);
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
-    swaps(&stuff->majorVersion, n);
-    swaps(&stuff->minorVersion, n);
-    return ProcDPMSGetVersion(client);
-}
-
-static int
-SProcDPMSCapable(ClientPtr client)
-{
-    REQUEST(xDPMSCapableReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSCapableReq);
-
-    return ProcDPMSCapable(client);
-}
-
-static int
-SProcDPMSGetTimeouts(ClientPtr client)
-{
-    REQUEST(xDPMSGetTimeoutsReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
-
-    return ProcDPMSGetTimeouts(client);
-}
-
-static int
-SProcDPMSSetTimeouts(ClientPtr client)
-{
-    REQUEST(xDPMSSetTimeoutsReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
-
-    swaps(&stuff->standby, n);
-    swaps(&stuff->suspend, n);
-    swaps(&stuff->off, n);
-    return ProcDPMSSetTimeouts(client);
-}
-
-static int
-SProcDPMSEnable(ClientPtr client)
-{
-    REQUEST(xDPMSEnableReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSEnableReq);
-
-    return ProcDPMSEnable(client);
-}
-
-static int
-SProcDPMSDisable(ClientPtr client)
-{
-    REQUEST(xDPMSDisableReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSDisableReq);
-
-    return ProcDPMSDisable(client);
-}
-
-static int
-SProcDPMSForceLevel(ClientPtr client)
-{
-    REQUEST(xDPMSForceLevelReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
-
-    swaps(&stuff->level, n);
-
-    return ProcDPMSForceLevel(client);
-}
-
-static int
-SProcDPMSInfo(ClientPtr client)
-{
-    REQUEST(xDPMSInfoReq);
-    int n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xDPMSInfoReq);
-
-    return ProcDPMSInfo(client);
-}
-
-static int
-SProcDPMSDispatch (ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data)
-    {
-    case X_DPMSGetVersion:
-	return SProcDPMSGetVersion(client);
-    case X_DPMSCapable:
-	return SProcDPMSCapable(client);
-    case X_DPMSGetTimeouts:
-	return SProcDPMSGetTimeouts(client);
-    case X_DPMSSetTimeouts:
-	return SProcDPMSSetTimeouts(client);
-    case X_DPMSEnable:
-	return SProcDPMSEnable(client);
-    case X_DPMSDisable:
-	return SProcDPMSDisable(client);
-    case X_DPMSForceLevel:
-	return SProcDPMSForceLevel(client);
-    case X_DPMSInfo:
-	return SProcDPMSInfo(client);
-    default:
-	return BadRequest;
-    }
-}
-
-void
-DPMSExtensionInit(INITARGS)
-{
-    AddExtension(DPMSExtensionName, 0, 0,
-		 ProcDPMSDispatch, SProcDPMSDispatch,
-		 NULL, StandardMinorOpcode);
-}
diff --git a/Xext/dpmsproc.h b/Xext/dpmsproc.h
deleted file mode 100644
index c1df56f..0000000
--- a/Xext/dpmsproc.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Prototypes for functions that the DDX must provide */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _DPMSPROC_H_
-#define _DPMSPROC_H_
-
-#include "dixstruct.h"
-
-int  DPMSSet(ClientPtr client, int level);
-Bool DPMSSupported(void);
-
-#endif
diff --git a/Xext/dpmsstubs.c b/Xext/dpmsstubs.c
index f0f54d2..05be274 100644
--- a/Xext/dpmsstubs.c
+++ b/Xext/dpmsstubs.c
@@ -30,7 +30,7 @@ Equipment Corporation.
 #include <dix-config.h>
 #endif
 
-#include "dpmsproc.h"
+#include "ext/dpms/dpms.h"
 
 #define FALSE 0
 
diff --git a/configure.ac b/configure.ac
index 23a0f10..8fda58f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -80,6 +80,8 @@ AC_SYS_LARGEFILE
 XORG_PROG_RAWCPP
 AC_PROG_SED
 
+CFLAGS="${CFLAGS} -I\$(top_srcdir)"
+
 # Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow
 # easier overrides at build time.
 XSERVER_CFLAGS='$(CWARNFLAGS)'
@@ -771,6 +773,10 @@ esac
 dnl ---------------------------------------------------------------------------
 dnl Extension section
 dnl ---------------------------------------------------------------------------
+
+# Set of extensions required in all servers.
+EXTENSIONS='$(top_builddir)/proto/libproto.la'
+
 XEXT_INC='-I$(top_srcdir)/Xext'
 XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
@@ -1124,6 +1130,7 @@ fi
 AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes])
 if test "x$DPMSExtension" = xyes; then
 	AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
+	EXTENSIONS="$EXTENSIONS \$(top_builddir)/proto/libproto-dpms.la \$(top_builddir)/ext/dpms/libext-dpms.la"
 fi
 
 if test "x$XCALIBRATE" = xyes && test "$KDRIVE" = yes; then
@@ -1469,7 +1476,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
 # require.
 #
 XSERVER_CFLAGS="${XSERVER_CFLAGS} ${XSERVERCFLAGS_CFLAGS}"
-XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB"
+XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB $EXTENSIONS"
 XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
 AC_SUBST([XSERVER_LIBS])
 AC_SUBST([XSERVER_SYS_LIBS])
@@ -2266,5 +2273,8 @@ hw/kdrive/linux/Makefile
 hw/kdrive/src/Makefile
 test/Makefile
 test/xi2/Makefile
+proto/Makefile
+ext/Makefile
+ext/dpms/Makefile
 xorg-server.pc
 ])
diff --git a/dix/globals.c b/dix/globals.c
index b128569..dcb033c 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -92,16 +92,6 @@ CARD32 ScreenSaverInterval;
 int ScreenSaverBlanking;
 int  ScreenSaverAllowExposures;
 
-#ifdef DPMSExtension
-CARD16 DPMSPowerLevel = 0;
-Bool DPMSDisabledSwitch = FALSE;
-Bool DPMSCapableFlag = FALSE;
-CARD32 DPMSStandbyTime;
-CARD32 DPMSSuspendTime;
-CARD32 DPMSOffTime;
-Bool DPMSEnabled;
-#endif
-
 CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME;
 CARD32 defaultScreenSaverInterval = DEFAULT_SCREEN_SAVER_INTERVAL;
 int  defaultScreenSaverBlanking = DEFAULT_SCREEN_SAVER_BLANKING;
diff --git a/dix/main.c b/dix/main.c
index 47a932f..7555ad8 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -111,10 +111,7 @@ Equipment Corporation.
 #include "dispatch.h"		/* InitProcVectors() */
 #endif
 
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 
 extern void Dispatch(void);
 
diff --git a/ext/Makefile.am b/ext/Makefile.am
new file mode 100644
index 0000000..bfa8a29
--- /dev/null
+++ b/ext/Makefile.am
@@ -0,0 +1,2 @@
+
+SUBDIRS = dpms
diff --git a/ext/dpms/Makefile.am b/ext/dpms/Makefile.am
new file mode 100644
index 0000000..9fe333d
--- /dev/null
+++ b/ext/dpms/Makefile.am
@@ -0,0 +1,5 @@
+
+AM_CFLAGS = $(DIX_CFLAGS)
+
+noinst_LTLIBRARIES = libext-dpms.la
+libext_dpms_la_SOURCES = dpms.c dpms.h
diff --git a/ext/dpms/dpms.c b/ext/dpms/dpms.c
new file mode 100644
index 0000000..b0eef6e
--- /dev/null
+++ b/ext/dpms/dpms.c
@@ -0,0 +1,16 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "ext/dpms/dpms.h"
+
+CARD16 DPMSPowerLevel = DPMS_DPMSMode_On;
+
+CARD32 DPMSStandbyTime;
+CARD32 DPMSSuspendTime;
+CARD32 DPMSOffTime;
+
+Bool DPMSEnabled = FALSE;
+Bool DPMSDisabledSwitch = FALSE;
+Bool DPMSCapableFlag = FALSE;
diff --git a/ext/dpms/dpms.h b/ext/dpms/dpms.h
new file mode 100644
index 0000000..c31b4ca
--- /dev/null
+++ b/ext/dpms/dpms.h
@@ -0,0 +1,33 @@
+
+#ifndef _XEXT_DPMS_H_
+#define _XEXT_DPMS_H_
+
+#include "proto/dpms-defs.h"
+
+#include "dixstruct.h"
+
+
+/*
+ * Exported symbols (What this extension provides)
+ */
+
+extern _X_EXPORT CARD16 DPMSPowerLevel;
+
+extern _X_EXPORT CARD32 DPMSStandbyTime;
+extern _X_EXPORT CARD32 DPMSSuspendTime;
+extern _X_EXPORT CARD32 DPMSOffTime;
+
+extern _X_EXPORT Bool DPMSEnabled;
+extern _X_EXPORT Bool DPMSDisabledSwitch;
+extern _X_EXPORT Bool DPMSCapableFlag;
+
+
+/*
+ * Imported symbols (What this extension uses)
+ */
+
+int  DPMSSet(ClientPtr client, int level);
+Bool DPMSSupported(void);
+
+
+#endif /* _XEXT_DPMS_H_ */
diff --git a/hw/dmx/dmxdpms.c b/hw/dmx/dmxdpms.c
index 2af1605..50fe1c1 100644
--- a/hw/dmx/dmxdpms.c
+++ b/hw/dmx/dmxdpms.c
@@ -47,9 +47,7 @@
 #include "dmxdpms.h"
 #include "dmxlog.h"
 #include "dmxsync.h"
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 #include "windowstr.h"          /* For screenIsSaved */
 #include <X11/extensions/dpms.h>
 
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 06c3661..66c930b 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -35,9 +35,7 @@
 #include "kxv.h"
 #endif
 
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 
 #ifdef HAVE_EXECINFO_H
 #include <execinfo.h>
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index e109734..c062e80 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -66,6 +66,7 @@ from The Open Group.
 #endif /* HAS_SHM */
 #include "dix.h"
 #include "miline.h"
+#include "xext.h"
 
 #define VFB_DEFAULT_WIDTH      1280
 #define VFB_DEFAULT_HEIGHT     1024
diff --git a/hw/xfree86/common/xf86DPMS.c b/hw/xfree86/common/xf86DPMS.c
index cd025dc..8e3e627 100644
--- a/hw/xfree86/common/xf86DPMS.c
+++ b/hw/xfree86/common/xf86DPMS.c
@@ -38,10 +38,7 @@
 #include "globals.h"
 #include "xf86.h"
 #include "xf86Priv.h"
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 #include "xf86VGAarbiter.h"
 
 
@@ -123,7 +120,7 @@ DPMSClose(int i, ScreenPtr pScreen)
      * to deal with this internally.
      */
     if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
- 	xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
+ 	xf86Screens[i]->DPMSSet(xf86Screens[i],DPMS_DPMSMode_On,0);
     }
     
     if (--DPMSCount == 0)
@@ -149,7 +146,7 @@ DPMSSet(ClientPtr client, int level)
     if (DPMSKey == NULL)
 	return Success;
 
-    if (level != DPMSModeOn) {
+    if (level != DPMS_DPMSMode_On) {
 	rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
 	if (rc != Success)
 	    return rc;
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 2e82848..eb4952f 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -79,10 +79,7 @@
 #include "xkbsrv.h"
 #include "xkbstr.h"
 
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 
 /*
  * This is a toggling variable:
@@ -434,8 +431,8 @@ xf86VTSwitch(void)
     DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
 	   BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
 #ifdef DPMSExtension
-    if (DPMSPowerLevel != DPMSModeOn)
-	DPMSSet(serverClient, DPMSModeOn);
+    if (DPMSPowerLevel != DPMS_DPMSMode_On)
+	DPMSSet(serverClient, DPMS_DPMSMode_On);
 #endif
     for (i = 0; i < xf86NumScreens; i++) {
       if (!(dispatchException & DE_TERMINATE))
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index ca532ee..c9d63dd 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -81,10 +81,8 @@
 #include "xf86VGAarbiter.h"
 #include "globals.h"
 
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
+
 #include <hotplug.h>
 
 
@@ -958,8 +956,8 @@ AbortDDX(void)
    * try to restore the original video state
    */
 #ifdef DPMSExtension /* Turn screens back on */
-  if (DPMSPowerLevel != DPMSModeOn)
-      DPMSSet(serverClient, DPMSModeOn);
+  if (DPMSPowerLevel != DPMS_DPMSMode_On)
+      DPMSSet(serverClient, DPMS_DPMSMode_On);
 #endif
   if (xf86Screens) {
       if (xf86Screens[0]->vtSema)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 76d2d00..0cfcf3b 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -67,11 +67,6 @@
 #include "compiler.h"
 #include "extinit.h"
 
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
 #include "exevents.h"	/* AddInputDevice */
 #include "exglobals.h"
 #include "eventstr.h"
diff --git a/hw/xfree86/dixmods/extmod/modinit.c b/hw/xfree86/dixmods/extmod/modinit.c
index f4e922c..f908048 100644
--- a/hw/xfree86/dixmods/extmod/modinit.c
+++ b/hw/xfree86/dixmods/extmod/modinit.c
@@ -74,15 +74,6 @@ static ExtensionModule extensionModules[] = {
 	NULL
     },
 #endif
-#ifdef DPMSExtension
-    {
-	DPMSExtensionInit,
-	DPMSExtensionName,
-	&noDPMSExtension,
-	NULL,
-	NULL
-    },
-#endif
 #ifdef XV
     {
 	XvExtensionInit,
diff --git a/hw/xfree86/dixmods/extmod/modinit.h b/hw/xfree86/dixmods/extmod/modinit.h
index 1154e46..26f17f8 100644
--- a/hw/xfree86/dixmods/extmod/modinit.h
+++ b/hw/xfree86/dixmods/extmod/modinit.h
@@ -34,11 +34,6 @@ extern void XFree86DGARegister(INITARGS);
 #include <X11/extensions/xf86dgaproto.h>
 #endif
 
-#ifdef DPMSExtension
-extern void DPMSExtensionInit(INITARGS);
-#include <X11/extensions/dpmsconst.h>
-#endif
-
 #ifdef XV
 extern void XvExtensionInit(INITARGS);
 extern void XvMCExtensionInit(INITARGS);
diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c
index 8a90cc6..ff2e010 100644
--- a/hw/xnest/Init.c
+++ b/hw/xnest/Init.c
@@ -39,9 +39,7 @@ is" without express or implied warranty.
 #include "Drawable.h"
 #include "XNGC.h"
 #include "XNFont.h"
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 
 Bool xnestDoFullGeneration = True;
 
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 73cc263..be37947 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -38,9 +38,7 @@ from The Open Group.
 #ifdef XWIN_CLIPBOARD
 #include "X11/Xlocale.h"
 #endif
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 #ifdef __CYGWIN__
 #include <mntent.h>
 #endif
diff --git a/include/xext.h b/include/xext.h
new file mode 100644
index 0000000..d06f720
--- /dev/null
+++ b/include/xext.h
@@ -0,0 +1,9 @@
+
+#ifndef _XEXT_H_
+#define _XEXT_H_
+
+#ifdef DPMSExtension
+#include "ext/dpms/dpms.h"
+#endif
+
+#endif /* _XEXT_H_ */
diff --git a/mi/mieq.c b/mi/mieq.c
index fa60b40..d3cad84 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -52,11 +52,7 @@ in this Software without prior written authorization from The Open Group.
 # include   "extinit.h"
 # include   "exglobals.h"
 # include   "eventstr.h"
-
-#ifdef DPMSExtension
-# include "dpmsproc.h"
-# include <X11/extensions/dpmsconst.h>
-#endif
+# include   "xext.h"
 
 #define QUEUE_SIZE  512
 
@@ -461,11 +457,11 @@ mieqProcessInputEvents(void)
         if (screenIsSaved == SCREEN_SAVER_ON)
             dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
 #ifdef DPMSExtension
-        else if (DPMSPowerLevel != DPMSModeOn)
+        else if (DPMSPowerLevel != DPMS_DPMSMode_On)
             SetScreenSaverTimer();
 
-        if (DPMSPowerLevel != DPMSModeOn)
-            DPMSSet(serverClient, DPMSModeOn);
+        if (DPMSPowerLevel != DPMS_DPMSMode_On)
+            DPMSSet(serverClient, DPMS_DPMSMode_On);
 #endif
 
         mieqProcessDeviceEvent(dev, event, screen);
diff --git a/mi/miinitext.c b/mi/miinitext.c
index a7441c9..fe5007a 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -513,6 +513,9 @@ static ExtensionModule staticExtensions[] = {
 #ifdef DAMAGE
     { DamageExtensionInit, "DAMAGE", &noDamageExtension, NULL },
 #endif
+#ifdef DPMSExtension
+    { DPMSExtensionInit, "DPMS", &noDPMSExtension, NULL },
+#endif
     { NULL, NULL, NULL, NULL, NULL }
 };
     
diff --git a/os/WaitFor.c b/os/WaitFor.c
index e663004..1c613df 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -71,9 +71,7 @@ SOFTWARE.
 #include <X11/Xpoll.h>
 #include "dixstruct.h"
 #include "opaque.h"
-#ifdef DPMSExtension
-#include "dpmsproc.h"
-#endif
+#include "xext.h"
 
 #ifdef WIN32
 /* Error codes from windows sockets differ from fileio error codes  */
diff --git a/proto/Makefile.am b/proto/Makefile.am
new file mode 100644
index 0000000..7c1377f
--- /dev/null
+++ b/proto/Makefile.am
@@ -0,0 +1,16 @@
+
+AM_CFLAGS = $(DIX_CFLAGS)
+
+noinst_LTLIBRARIES = libproto.la
+libproto_la_SOURCES = common.c common.h
+
+%.c: /opt/xorg/share/xcb/%.xml
+	$(AM_V_GEN) ./xcb-gen.py $<
+
+CLEANFILES =
+
+if DPMSExtension
+noinst_LTLIBRARIES += libproto-dpms.la
+libproto_dpms_la_SOURCES = dpms.c dpms-defs.h dpms-wire.h dpms-glue.c
+CLEANFILES += dpms.c dpms-defs.h dpms-wire.h
+endif
diff --git a/proto/common.c b/proto/common.c
new file mode 100644
index 0000000..1f95bb7
--- /dev/null
+++ b/proto/common.c
@@ -0,0 +1,12 @@
+
+#include <proto/common.h>
+
+void
+xcb_write(ClientPtr client, const void *buf, int count)
+{
+	static uint8_t padding[32];
+
+	WriteToClient(client, count, buf);
+	if (count < 32)
+		WriteToClient(client, 32 - count, padding);
+}
diff --git a/proto/common.h b/proto/common.h
new file mode 100644
index 0000000..7891250
--- /dev/null
+++ b/proto/common.h
@@ -0,0 +1,22 @@
+
+#ifndef __PROTO_COMMON_H__
+#define __PROTO_COMMON_H__
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <arpa/inet.h>
+
+#define swap16(ptr) *ptr = htons(*ptr)
+#define swap32(ptr) *ptr = htonl(*ptr)
+
+#include <include/os.h> 
+#include <include/extnsionst.h>
+#include <include/dixstruct.h>
+
+
+void
+xcb_write(ClientPtr client, const void *buf, int count);
+
+#endif /* __PROTO_COMMON_H__ */
diff --git a/proto/dpms-glue.c b/proto/dpms-glue.c
new file mode 100644
index 0000000..b089834
--- /dev/null
+++ b/proto/dpms-glue.c
@@ -0,0 +1,103 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+/* Only include the extension header to ensure everything we use from
+ * here is properly recorded in that header. */
+#include <ext/dpms/dpms.h>
+
+/* The wire structures are obviously not exported to code using this
+ * extension, so we have to include that header separately. */
+#include <proto/dpms-wire.h>
+
+
+int
+impl_DPMS_GetVersion(ClientPtr client, struct req_DPMS_GetVersion *req, struct rep_DPMS_GetVersion *rep)
+{
+    rep->server_major_version = xcb_DPMS_Major;
+    rep->server_minor_version = xcb_DPMS_Minor;
+
+    return 0;
+}
+
+int
+impl_DPMS_Capable(ClientPtr client, struct req_DPMS_Capable *req, struct rep_DPMS_Capable *rep)
+{
+    rep->capable = DPMSCapableFlag;
+
+    return 0;
+}
+
+int
+impl_DPMS_GetTimeouts(ClientPtr client, struct req_DPMS_GetTimeouts *req, struct rep_DPMS_GetTimeouts *rep)
+{
+    rep->standby_timeout = DPMSStandbyTime / MILLI_PER_SECOND;
+    rep->suspend_timeout = DPMSSuspendTime / MILLI_PER_SECOND;
+    rep->off_timeout = DPMSOffTime / MILLI_PER_SECOND;
+
+    return 0;
+}
+
+int
+impl_DPMS_SetTimeouts(ClientPtr client, struct req_DPMS_SetTimeouts *req)
+{
+    DPMSStandbyTime = req->standby_timeout * MILLI_PER_SECOND;
+    DPMSSuspendTime = req->suspend_timeout * MILLI_PER_SECOND;
+    DPMSOffTime = req->off_timeout * MILLI_PER_SECOND;
+
+    SetScreenSaverTimer();
+
+    return 0;
+}
+
+int
+impl_DPMS_Enable(ClientPtr client, struct req_DPMS_Enable *req)
+{
+    Bool was_enabled = DPMSEnabled;
+    if (DPMSCapableFlag) {
+        DPMSEnabled = TRUE;
+	if (!was_enabled)
+            SetScreenSaverTimer();
+    }
+
+    return 0;
+}
+
+int
+impl_DPMS_Disable(ClientPtr client, struct req_DPMS_Disable *req)
+{
+    DPMSSet(client, DPMS_DPMSMode_On);
+    DPMSEnabled = FALSE;
+
+    return 0;
+}
+
+int
+impl_DPMS_ForceLevel(ClientPtr client, struct req_DPMS_ForceLevel *req)
+{
+    if (!DPMSEnabled)
+        return BadMatch;
+
+    /* TODO: generate this validation from the xcb protocol description */
+    if (req->power_level != DPMS_DPMSMode_On &&
+        req->power_level != DPMS_DPMSMode_Standby &&
+        req->power_level != DPMS_DPMSMode_Suspend &&
+	req->power_level != DPMS_DPMSMode_Off) {
+        client->errorValue = req->power_level;
+	return BadValue;
+    }
+
+    DPMSSet(client, req->power_level);
+
+    return 0;
+}
+
+int
+impl_DPMS_Info(ClientPtr client, struct req_DPMS_Info *req, struct rep_DPMS_Info *rep)
+{
+    rep->power_level = DPMSPowerLevel;
+    rep->state = DPMSEnabled;
+    
+    return 0;
+}
diff --git a/proto/xcb-gen.py b/proto/xcb-gen.py
new file mode 100755
index 0000000..2020ade
--- /dev/null
+++ b/proto/xcb-gen.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+
+from xml.etree.cElementTree import *
+from os.path import basename
+
+import getopt
+import getopt
+import sys
+import re
+
+args = sys.argv[1:]
+
+from mako.template import Template
+
+data = { 'version':'0.1', 'simple':[], 'enum':[], 'struct':[],
+         'union':[], 'request':[], 'event':[], 'error':[] }
+
+def gen(format):
+    source = 'xcb-gen/%s.py' % (format % 'proto')
+    template = Template(filename=source)
+    f = open('%s' % (format % module.namespace.header), 'w')
+    f.write(template.render(**data))
+
+def c_open(self):
+    pass
+
+def c_close(self):
+    gen('%s-defs.h')
+    gen('%s-wire.h')
+    gen('%s.c')
+
+def c_simple(self, name):
+    data['simple'].append((self, name))
+
+def c_enum(self, name):
+    data['enum'].append((self, name))
+
+def c_struct(self, name):
+    data['struct'].append(self)
+
+def c_union(self, name):
+    data['union'].append(self)
+
+def c_request(self, name):
+    data['request'].append(self)
+
+def c_event(self, name):
+    data['event'].append(self)
+
+def c_error(self, name):
+    data['error'].append(self)
+
+
+output = {'open'    : c_open,
+          'close'   : c_close,
+          'simple'  : c_simple,
+          'enum'    : c_enum,
+          'struct'  : c_struct,
+          'union'   : c_union,
+          'request' : c_request,
+          'event'   : c_event,
+          'error'   : c_error
+          }
+from xcbgen.state import Module
+
+module = Module(args[0], output)
+data['module'] = module
+
+module.register()
+module.resolve()
+module.generate()
diff --git a/proto/xcb-gen/proto-defs.h.py b/proto/xcb-gen/proto-defs.h.py
new file mode 100644
index 0000000..fd4d3e2
--- /dev/null
+++ b/proto/xcb-gen/proto-defs.h.py
@@ -0,0 +1,35 @@
+/* template: v0.1, bindings: v${version} */
+
+<% define = '__PROTO_%s__' % ('_').join(module.namespace.prefix[1:]).upper() %>
+
+#ifndef ${define}
+#define ${define}
+
+#include <stdint.h>
+#include <include/dix.h>
+
+% for value in module.imports:
+#include <proto/${value[1]}.h>
+% endfor
+
+#define ${('_').join(module.namespace.prefix)}_Major ${module.namespace.major_version}
+#define ${('_').join(module.namespace.prefix)}_Minor ${module.namespace.minor_version}
+
+% for (type, name) in simple:
+typedef ${('_').join(type.name).lower()} ${('_').join(name).lower()}_t; 
+% endfor
+
+% for (type, name) in enum:
+enum ${('_').join(name)} {
+% for val in type.values:
+% if val[1]:
+    ${('_').join(name[1:])}_${val[0]} = ${val[1]},
+% else:
+    ${('_').join(name[1:])}_${val[0]},
+% endif
+% endfor
+    __${('_').join(name[1:])}_Last
+};
+% endfor
+
+#endif /* ${define} */
diff --git a/proto/xcb-gen/proto-wire.h.py b/proto/xcb-gen/proto-wire.h.py
new file mode 100644
index 0000000..1e7efca
--- /dev/null
+++ b/proto/xcb-gen/proto-wire.h.py
@@ -0,0 +1,39 @@
+/* template: v0.1, bindings: v${version} */
+
+<% define = '__PROTO_%s_WIRE__' % ('_').join(module.namespace.prefix[1:]).upper() %>
+
+#ifndef ${define}
+#define ${define}
+
+#include <stdint.h>
+
+% for req in request:
+<% name = ('_').join(req.name[1:]) %>
+/************************************************************
+ * Request ${(':').join(req.name[1:])}, opcode: ${req.opcode}
+ */
+
+struct req_${name} {
+% for field in req.fields:
+    ${('_').join(field.type.name)} ${field.field_name};
+% endfor
+};
+
+% if req.reply:
+struct rep_${name} {
+% for field in req.reply.fields:
+    ${('_').join(field.type.name)} ${field.field_name};
+% endfor
+};
+
+int
+impl_${name}(ClientPtr client, struct req_${name} *req, struct rep_${name} *rep);
+% else:
+int
+impl_${name}(ClientPtr client, struct req_${name} *req);
+% endif
+
+
+% endfor
+
+#endif /* ${define} */
diff --git a/proto/xcb-gen/proto.c.py b/proto/xcb-gen/proto.c.py
new file mode 100644
index 0000000..e01ff93
--- /dev/null
+++ b/proto/xcb-gen/proto.c.py
@@ -0,0 +1,103 @@
+/* template: v0.1, bindings: v${version} */
+
+#include <proto/common.h>
+
+#include <proto/${module.namespace.header}-defs.h>
+#include <proto/${module.namespace.header}-wire.h>
+
+% for req in request:
+<% name = ('_').join(req.name[1:]) %>
+/************************************************************
+ * Request ${(':').join(req.name[1:])}, opcode: ${req.opcode}
+ */
+
+static void
+swap_req_${name}(struct req_${name} *req, unsigned long length)
+{
+% for field in [field for field in req.fields if field.wire]:
+% if field.type.is_simple and field.type.size > 1:
+    swap${field.type.size * 8}(&req->${field.field_name});
+% endif
+% endfor
+}
+
+% if req.reply:
+static void
+swap_rep_${name}(struct rep_${name} *rep)
+{
+% for field in [field for field in req.reply.fields if field.wire]:
+% if field.type.is_simple and field.type.size > 1:
+    swap${field.type.size * 8}(&rep->${field.field_name});
+% endif
+% endfor
+}
+% endif
+
+static void
+wire_${name}(ClientPtr client)
+{
+% if req.fixed_size():
+    if ((sizeof(struct req_${name}) + 3) >> 2 != client->req_len)
+        return;
+% else:
+    if ((sizeof(struct req_${name}) + 3) >> 2 > client->req_len)
+        return;
+% endif
+
+    struct req_${name} *req = client->requestBuffer;
+    if (client->swapped)
+        swap_req_${name}(req, client->req_len);
+
+% if not req.reply:
+    impl_${name}(client, req);
+% else:
+    struct rep_${name} rep = { .response_type = 1,
+        .length = 0, .sequence = client->sequence
+    };
+
+    int err = impl_${name}(client, req, &rep);
+    if (err)
+        return;
+
+    if (client->swapped)
+        swap_rep_${name}(&rep);
+
+    xcb_write(client, &rep, sizeof(rep));
+% endif
+}
+
+% endfor
+
+
+
+/************************************************************
+ * Request dispatch code
+ */
+
+typedef void (*xcb_handler_t)(ClientPtr client);
+static xcb_handler_t handler[] = {
+% for req in request:
+    [${req.opcode}] = &wire_${('_').join(req.name[1:])},
+% endfor
+    [${len(request)}] = NULL
+};
+
+static int
+dispatch(ClientPtr client)
+{
+    unsigned short minor = StandardMinorOpcode(client);
+    if (!handler[minor])
+        return BadRequest;
+
+    (*handler[minor])(client);
+
+    return 0;
+}
+
+void
+${module.namespace.prefix[1]}ExtensionInit(void)
+{
+    ErrorF("Initializing ${module.namespace.prefix[1]}\n");
+    AddExtension("${module.namespace.ext_xname}", 0, 0,
+        &dispatch, &dispatch, NULL, &StandardMinorOpcode);
+}
-- 
1.7.2.1.g43c6fa



More information about the xorg-devel mailing list