summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamey Sharp <jamey@minilop.net>2002-01-03 06:48:11 +0000
committerJamey Sharp <jamey@minilop.net>2002-01-03 06:48:11 +0000
commit97d87ecc32efb3be741d2ea214b5a970dc2e5551 (patch)
treeb7744a5e036e577d8c895223a52af6cc310ab908
parente7da4a94299e23a8638b4a2da64d5b08edb838cc (diff)
Organized things a bit. Added xcb_shape.m4 finally (oops).
-rw-r--r--Makefile.am50
-rw-r--r--configure.ac4
-rw-r--r--doc/specs/XCB/xcb_proto_macros.tex (renamed from xcb_proto_macros.tex)0
-rw-r--r--programs/hypnomoire/hypnomoire.c (renamed from hypnomoire.c)2
-rw-r--r--programs/xcbtests/dpms.c (renamed from dpms.c)2
-rw-r--r--programs/xcbtests/main.c (renamed from main.c)2
-rw-r--r--programs/xcbtests/reply_formats.c (renamed from reply_formats.c)0
-rw-r--r--programs/xcbtests/reply_formats.h (renamed from reply_formats.h)2
-rw-r--r--xcb-demo/dpms.c50
-rw-r--r--xcb-demo/hypnomoire.c140
-rw-r--r--xcb-demo/main.c202
-rw-r--r--xcb-demo/reply_formats.c331
-rw-r--r--xcb-demo/reply_formats.h11
-rw-r--r--xcb_conn.m422
-rw-r--r--xcb_dpms.m45
-rw-r--r--xcb_shape.m4117
-rw-r--r--xcbgen.m4435
-rw-r--r--xp_core.m412
18 files changed, 869 insertions, 518 deletions
diff --git a/Makefile.am b/Makefile.am
index 98a0b15..48e95e8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,50 +1,6 @@
AUTOMAKE_OPTIONS = foreign
+SUBDIRS = client test
-SUFFIXES = .m4 .c .h
-
-.m4.h:
- $(M4) -D"_H" xcbgen.m4 $*.m4 > $*.h
-
-.m4.c:
- $(M4) -D"_C" xcbgen.m4 $*.m4 > $*.c
-
-lib_LTLIBRARIES = libxcb.la libxcb_dpms.la libxcb_shape.la
-
-libxcb_la_SOURCES = xcb_conn.c xp_core.c xcb_conn.h xp_core.h
-libxcb_la_DEPENDENCIES = xcb_conn.m4 xp_core.m4 xcbgen.m4
-
-libxcb_dpms_la_SOURCES = xcb_dpms.c xcb_dpms.h
-libxcb_dpms_la_DEPENDENCIES = xcb_dpms.m4
-
-libxcb_shape_la_SOURCES = xcb_shape.c xcb_shape.h
-libxcb_shape_la_DEPENDENCIES = xcb_shape.m4
-
-GENSOURCES = $(libxcb_la_SOURCES) $(libxcb_dpms_la_SOURCES) \
- $(libxcb_shape_la_SOURCES)
-$(GENSOURCES): xcbgen.m4
-
-xcb_conn.lo: xcb_conn.h
-xp_core.lo: xp_core.h xcb_conn.h
-xcb_dpms.lo: xcb_dpms.h xp_core.h xcb_conn.h
-xcb_shape.lo: xcb_shape.h xp_core.h xcb_conn.h
-
-clean-local:
- -rm -f $(GENSOURCES)
-
-sources: $(GENSOURCES)
-
-bin_PROGRAMS = main hypnomoire dpms
-
-main_SOURCES = main.c reply_formats.c reply_formats.h
-main_LDADD = libxcb.la
-main_LDFLAGS = -lpthread
-
-hypnomoire_SOURCES = hypnomoire.c reply_formats.c reply_formats.h
-hypnomoire_LDADD = libxcb.la
-hypnomoire_LDFLAGS = -lm -lpthread
-
-dpms_SOURCES = dpms.c
-dpms_LDADD = libxcb.la libxcb_dpms.la
-
-main.o reply_formats.o hypnomoire.o dpms.o: xcb_conn.h xp_core.h
+sources:
+ $(MAKE) -C client sources
diff --git a/configure.ac b/configure.ac
index cb26346..83e1134 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(xcbgen.m4)
+AC_INIT(xcb_conn.m4)
AM_INIT_AUTOMAKE([xcb], [0.1])
AM_PROG_LIBTOOL
@@ -7,4 +7,4 @@ AC_CHECK_PROGS(M4, m4)
AC_CHECK_HEADERS(X11/X.h X11/Xproto.h pthread.h)
AC_CHECK_FUNCS(pthread_mutex_lock)
-AC_OUTPUT(Makefile)
+AC_OUTPUT([Makefile client/Makefile test/Makefile])
diff --git a/xcb_proto_macros.tex b/doc/specs/XCB/xcb_proto_macros.tex
index 78b296f..78b296f 100644
--- a/xcb_proto_macros.tex
+++ b/doc/specs/XCB/xcb_proto_macros.tex
diff --git a/hypnomoire.c b/programs/hypnomoire/hypnomoire.c
index 09f506d..79b774c 100644
--- a/hypnomoire.c
+++ b/programs/hypnomoire/hypnomoire.c
@@ -1,4 +1,4 @@
-#include "xp_core.h"
+#include <client/xp_core.h>
#include "reply_formats.h"
#include <math.h>
#include <stdlib.h> /* for free(3) */
diff --git a/dpms.c b/programs/xcbtests/dpms.c
index 049db7c..58ca369 100644
--- a/dpms.c
+++ b/programs/xcbtests/dpms.c
@@ -1,4 +1,4 @@
-#include "xcb_dpms.h"
+#include <client/xcb_dpms.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/main.c b/programs/xcbtests/main.c
index 6951445..79f426d 100644
--- a/main.c
+++ b/programs/xcbtests/main.c
@@ -15,7 +15,7 @@
#include <stdlib.h>
-#include "xp_core.h"
+#include <client/xp_core.h>
#include "reply_formats.h"
void try_events(XCB_Connection *c);
diff --git a/reply_formats.c b/programs/xcbtests/reply_formats.c
index f297906..f297906 100644
--- a/reply_formats.c
+++ b/programs/xcbtests/reply_formats.c
diff --git a/reply_formats.h b/programs/xcbtests/reply_formats.h
index 7742deb..2afccfe 100644
--- a/reply_formats.h
+++ b/programs/xcbtests/reply_formats.h
@@ -1,7 +1,7 @@
#ifndef REPLY_FORMATS_H
#define REPLY_FORMATS_H
-#include "xp_core.h"
+#include <client/xp_core.h>
int formatGetWindowAttributesReply(Window wid, XCB_GetWindowAttributes_Rep *reply);
int formatGetGeometryReply(Window wid, XCB_GetGeometry_Rep *reply);
diff --git a/xcb-demo/dpms.c b/xcb-demo/dpms.c
new file mode 100644
index 0000000..58ca369
--- /dev/null
+++ b/xcb-demo/dpms.c
@@ -0,0 +1,50 @@
+#include <client/xcb_dpms.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void check_dpms_version(XCB_Connection *);
+void check_dpms_capable(XCB_Connection *);
+void print_dpms_timeouts(XCB_Connection *);
+
+int main(int argc, char **argv)
+{
+ XCB_Connection *c = XCB_Connect_Basic();
+ /*XCB_DPMS_Init(c);*/
+ check_dpms_version(c);
+ check_dpms_capable(c);
+
+ print_dpms_timeouts(c);
+
+ exit(0);
+ /*NOTREACHED*/
+}
+
+void check_dpms_version(XCB_Connection *c)
+{
+ XCB_DPMSGetVersion_cookie cookie = XCB_DPMSGetVersion(c, 1, 1);
+ XCB_DPMSGetVersion_Rep *ver = XCB_DPMSGetVersion_Reply(c, cookie, 0);
+ assert(ver);
+ assert(ver->server_major_version == 1);
+ assert(ver->server_minor_version == 1);
+ free(ver);
+}
+
+void check_dpms_capable(XCB_Connection *c)
+{
+ XCB_DPMSCapable_cookie cookie = XCB_DPMSCapable(c);
+ XCB_DPMSCapable_Rep *cap = XCB_DPMSCapable_Reply(c, cookie, 0);
+ assert(cap);
+ assert(cap->capable);
+ free(cap);
+}
+
+void print_dpms_timeouts(XCB_Connection *c)
+{
+ XCB_DPMSGetTimeouts_cookie cookie = XCB_DPMSGetTimeouts(c);
+ XCB_DPMSGetTimeouts_Rep *time = XCB_DPMSGetTimeouts_Reply(c, cookie, 0);
+ assert(time);
+ printf("Standby: %d\n" "Suspend: %d\n" "Off: %d\n",
+ time->standby_timeout, time->suspend_timeout, time->off_timeout);
+ free(time);
+}
diff --git a/xcb-demo/hypnomoire.c b/xcb-demo/hypnomoire.c
new file mode 100644
index 0000000..79b774c
--- /dev/null
+++ b/xcb-demo/hypnomoire.c
@@ -0,0 +1,140 @@
+#include <client/xp_core.h>
+#include "reply_formats.h"
+#include <math.h>
+#include <stdlib.h> /* for free(3) */
+#include <unistd.h> /* for usleep(3) */
+#include <pthread.h>
+
+#define JUMP 0.05 /* angle increment */
+#define LAG 0.3 /* lag angle for the follow line */
+
+/* If I've done my math right, Linux maxes out at 100 fps on Intel (1000 fps
+ * on Alpha) due to the granularity of the kernel timer. */
+#define FRAME_RATE 100.0 /* frames per second */
+
+#define PI 3.14159265
+
+static XCB_Connection *c;
+static GContext white, black;
+
+#define WINS 8
+static struct { Window w; Pixmap p; CARD16 width; CARD16 height; } windows[WINS];
+
+void *run(void *param);
+void *event_thread(void *param);
+
+int main()
+{
+ pthread_t thr;
+ int i;
+
+ CARD32 mask = GCForeground | GCGraphicsExposures;
+ CARD32 values[2];
+
+ c = XCB_Connect_Basic();
+ white = XCB_Generate_ID(c);
+ black = XCB_Generate_ID(c);
+
+ pthread_create(&thr, 0, event_thread, 0);
+
+ values[1] = 0; /* no graphics exposures */
+
+ values[0] = c->roots[0].data->whitePixel;
+ XCB_CreateGC(c, white, c->roots[0].data->windowId, mask, values);
+
+ values[0] = c->roots[0].data->blackPixel;
+ XCB_CreateGC(c, black, c->roots[0].data->windowId, mask, values);
+
+ for(i = 1; i < WINS; ++i)
+ pthread_create(&thr, 0, run, (void*)i);
+ run((void*)0);
+
+ exit(0);
+ /*NOTREACHED*/
+}
+
+void paint(int idx)
+{
+ XCB_CopyArea(c, windows[idx].p, windows[idx].w, white, 0, 0, 0, 0,
+ windows[idx].width, windows[idx].height);
+ XCB_Sync(c, 0);
+}
+
+void *run(void *param)
+{
+ int idx = (int)param;
+ CARD32 mask = 0;
+ CARD32 values[1];
+
+ int xo, yo;
+ double r, theta = 0;
+
+ xPoint line[2];
+
+ windows[idx].w = XCB_Generate_ID(c);
+ windows[idx].p = XCB_Generate_ID(c);
+ windows[idx].width = 300;
+ line[0].x = xo = windows[idx].width / 2;
+ windows[idx].height = 300;
+ line[0].y = yo = windows[idx].height / 2;
+
+ {
+ int ws = windows[idx].width * windows[idx].width;
+ int hs = windows[idx].height * windows[idx].height;
+ r = sqrt(ws + hs) + 1.0;
+ }
+
+ mask |= CWBackPixel;
+ values[0] = c->roots[0].data->whitePixel;
+
+ XCB_CreateWindow(c, c->roots[0].depths[0].data->depth,
+ windows[idx].w, c->roots[0].data->windowId,
+ /* x */ 0, /* y */ 0, windows[idx].width, windows[idx].height,
+ /* border */ 0, InputOutput,
+ /* visual */ c->roots[0].data->rootVisualID, mask, values);
+ XCB_MapWindow(c, windows[idx].w);
+
+ XCB_CreatePixmap(c, c->roots[0].depths[0].data->depth,
+ windows[idx].p, windows[idx].w,
+ windows[idx].width, windows[idx].height);
+
+ XCB_Sync(c, 0);
+
+ {
+ xRectangle rects[1] = { { 0, 0, windows[idx].width, windows[idx].height } };
+ XCB_PolyFillRectangle(c, windows[idx].p, white, 1, rects);
+ }
+
+ while(1)
+ {
+ usleep(1000000 / FRAME_RATE);
+
+ line[1].x = xo + r * cos(theta);
+ line[1].y = yo + r * sin(theta);
+ XCB_PolyLine(c, CoordModeOrigin, windows[idx].p, black,
+ 2, line);
+
+ line[1].x = xo + r * cos(theta + LAG);
+ line[1].y = yo + r * sin(theta + LAG);
+ XCB_PolyLine(c, CoordModeOrigin, windows[idx].p, white,
+ 2, line);
+
+ paint(idx);
+ theta += JUMP;
+ while(theta > 2 * PI)
+ theta -= 2 * PI;
+ }
+}
+
+void *event_thread(void *param)
+{
+ XCB_Event *e;
+
+ while(1)
+ {
+ e = XCB_Wait_Event(c);
+ if(!formatEvent(e))
+ return 0;
+ free(e);
+ }
+}
diff --git a/xcb-demo/main.c b/xcb-demo/main.c
new file mode 100644
index 0000000..79f426d
--- /dev/null
+++ b/xcb-demo/main.c
@@ -0,0 +1,202 @@
+#define TEST_GET_WINDOW_ATTRIBUTES
+#define TEST_GET_GEOMETRY
+#define TEST_QUERY_TREE
+#undef TEST_THREADS
+#define VERBOSE
+#undef SUPERVERBOSE
+
+#ifdef TEST_THREADS
+#include <pthread.h>
+#endif
+
+#ifdef VERBOSE
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+
+#include <client/xp_core.h>
+#include "reply_formats.h"
+
+void try_events(XCB_Connection *c);
+void wait_events(XCB_Connection *c);
+
+static XCB_Connection *c;
+static Window window;
+
+int main(int argc, char **argv)
+{
+ CARD32 mask = 0;
+ CARD32 values[6];
+#ifdef TEST_GET_GEOMETRY
+ XCB_GetGeometry_cookie geom[3];
+ XCB_GetGeometry_Rep *geomrep[3];
+#endif
+#ifdef TEST_QUERY_TREE
+ XCB_QueryTree_cookie tree[3];
+ XCB_QueryTree_Rep *treerep[3];
+#endif
+#ifdef TEST_GET_WINDOW_ATTRIBUTES
+ XCB_GetWindowAttributes_cookie attr[1];
+ XCB_GetWindowAttributes_Rep *attrrep[1];
+#endif
+#ifdef TEST_THREADS
+ pthread_t event_thread;
+#endif
+
+ c = XCB_Connect_Basic();
+
+#ifdef TEST_THREADS
+# ifdef VERBOSE
+ printf("main() thread ID: %ld\n", pthread_self());
+# endif
+ /* don't do this cast. */
+ pthread_create(&event_thread, 0, (void *(*)(void *))wait_events, c);
+#endif
+
+#if 1
+ window = XCB_Generate_ID(c);
+#else
+ window = 0; /* should be an invalid ID */
+#endif
+
+ mask |= CWBackPixel;
+ values[0] = c->roots[0].data->whitePixel;
+
+ mask |= CWBorderPixel;
+ values[1] = c->roots[0].data->blackPixel;
+
+ mask |= CWBackingStore;
+ values[2] = Always;
+
+ mask |= CWOverrideRedirect;
+ values[3] = xFalse;
+
+ mask |= CWEventMask;
+ values[4] = ButtonReleaseMask | ExposureMask | StructureNotifyMask
+ | EnterWindowMask | LeaveWindowMask;
+
+ mask |= CWDontPropagate;
+ values[5] = ButtonPressMask;
+
+ XCB_CreateWindow(c, c->roots[0].depths[0].data->depth,
+ window, c->roots[0].data->windowId,
+ /* x */ 20, /* y */ 200, /* width */ 150, /* height */ 150,
+ /* border_width */ 10, /* class */ InputOutput,
+ /* visual */ c->roots[0].data->rootVisualID, mask, values);
+ XCB_MapWindow(c, window);
+
+ /* Send off a collection of requests */
+#ifdef TEST_GET_WINDOW_ATTRIBUTES
+ attr[0] = XCB_GetWindowAttributes(c, window);
+#endif
+#ifdef TEST_GET_GEOMETRY
+ geom[0] = XCB_GetGeometry(c, c->roots[0].data->windowId);
+ geom[1] = XCB_GetGeometry(c, window);
+#endif
+#ifdef TEST_QUERY_TREE
+# ifdef SUPERVERBOSE /* this produces a lot of output :) */
+ tree[0] = XCB_QueryTree(c, c->roots[0].data->windowId);
+# endif
+ tree[1] = XCB_QueryTree(c, window);
+#endif
+
+ /* Start reading replies and possibly events */
+#ifdef TEST_GET_GEOMETRY
+ geomrep[0] = XCB_GetGeometry_Reply(c, geom[0], 0);
+ formatGetGeometryReply(c->roots[0].data->windowId, geomrep[0]);
+ free(geomrep[0]);
+#endif
+
+#ifdef TEST_QUERY_TREE
+# ifdef SUPERVERBOSE /* this produces a lot of output :) */
+ treerep[0] = XCB_QueryTree_Reply(c, tree[0], 0);
+ formatQueryTreeReply(c->roots[0].data->windowId, treerep[0]);
+ free(treerep[0]);
+# endif
+#endif
+
+#ifdef TEST_GET_GEOMETRY
+ geomrep[1] = XCB_GetGeometry_Reply(c, geom[1], 0);
+ formatGetGeometryReply(window, geomrep[1]);
+ free(geomrep[1]);
+#endif
+
+ /* Mix in some more requests */
+#ifdef TEST_QUERY_TREE
+ treerep[1] = XCB_QueryTree_Reply(c, tree[1], 0);
+ formatQueryTreeReply(window, treerep[1]);
+
+ if(treerep[1] && treerep[1]->parent && treerep[1]->parent != c->roots[0].data->windowId)
+ {
+ tree[2] = XCB_QueryTree(c, treerep[1]->parent);
+
+# ifdef TEST_GET_GEOMETRY
+ geom[2] = XCB_GetGeometry(c, treerep[1]->parent);
+ geomrep[2] = XCB_GetGeometry_Reply(c, geom[2], 0);
+ formatGetGeometryReply(treerep[1]->parent, geomrep[2]);
+ free(geomrep[2]);
+# endif
+
+ treerep[2] = XCB_QueryTree_Reply(c, tree[2], 0);
+ formatQueryTreeReply(treerep[1]->parent, treerep[2]);
+ free(treerep[2]);
+ }
+
+ free(treerep[1]);
+#endif
+
+ /* Get the last reply of the first batch */
+#if 1 /* if 0, leaves a reply in the reply queue */
+#ifdef TEST_GET_WINDOW_ATTRIBUTES
+ attrrep[0] = XCB_GetWindowAttributes_Reply(c, attr[0], 0);
+ formatGetWindowAttributesReply(window, attrrep[0]);
+ free(attrrep[0]);
+#endif
+#endif
+
+#ifdef VERBOSE
+ if(!XCB_List_is_empty(&c->reply_data))
+ printf("Unexpected additional replies waiting, dunno why...\n");
+#endif
+
+#ifdef TEST_THREADS
+ pthread_join(event_thread, 0);
+#else
+ wait_events(c);
+#endif
+
+ exit(0);
+ /*NOTREACHED*/
+}
+
+int wait_event(XCB_Connection *c)
+{
+ int ret = 1;
+ XCB_Event *e = XCB_Wait_Event(c);
+
+ if(!formatEvent(e))
+ return 0;
+
+ if(e->response_type == ButtonRelease)
+ ret = 0; /* They clicked, therefore, we're done. */
+ free(e);
+ return ret;
+}
+
+void try_events(XCB_Connection *c)
+{
+ while(!XCB_EventQueueIsEmpty(c) && wait_event(c))
+ /* empty statement */ ;
+}
+
+void wait_events(XCB_Connection *c)
+{
+#ifdef TEST_THREADS
+# ifdef VERBOSE
+ printf("wait_events() thread ID: %ld\n", pthread_self());
+# endif
+#endif
+ while(wait_event(c))
+ /* empty statement */ ;
+}
diff --git a/xcb-demo/reply_formats.c b/xcb-demo/reply_formats.c
new file mode 100644
index 0000000..f297906
--- /dev/null
+++ b/xcb-demo/reply_formats.c
@@ -0,0 +1,331 @@
+#include <stdio.h>
+#include "reply_formats.h"
+
+#define WINFMT "0x%08x"
+
+int formatGetWindowAttributesReply(Window wid, XCB_GetWindowAttributes_Rep *reply)
+{
+ if(!reply)
+ {
+ fprintf(stderr, "Failed to get attributes for window 0x%x.\n",
+ (unsigned int) wid);
+ return 0;
+ }
+
+ printf("Window " WINFMT " has attributes:\n"
+ " backingStore = %d\n"
+ " visualID = %#x\n"
+ " class = %d\n"
+ " bitGravity = %d\n"
+ " winGravity = %d\n"
+ " backingBitPlanes = 0x%08lx\n"
+ " backingPixel = %ld\n"
+ " saveUnder = %d\n"
+ " mapInstalled = %d\n"
+ " mapState = %d\n"
+ " override = %d\n"
+ " colormap = 0x%08x\n"
+ " allEventMasks = 0x%08x\n"
+ " yourEventMask = 0x%08x\n"
+ " doNotPropagateMask = 0x%08x\n",
+ (unsigned int) wid,
+ reply->backing_store,
+ (unsigned int) reply->visual,
+ reply->_class,
+ reply->bit_gravity,
+ reply->win_gravity,
+ reply->backing_planes,
+ reply->backing_pixel,
+ reply->save_under,
+ reply->map_is_installed,
+ reply->map_state,
+ reply->override_redirect,
+ (unsigned int) reply->colormap,
+ (unsigned int) reply->all_event_masks,
+ (unsigned int) reply->your_event_mask,
+ reply->do_not_propagate_mask);
+
+ fflush(stdout);
+ return 1;
+}
+
+int formatGetGeometryReply(Window wid, XCB_GetGeometry_Rep *reply)
+{
+ if(!reply)
+ {
+ fprintf(stderr, "Failed to get geometry for window " WINFMT ".\n",
+ (unsigned int) wid);
+ return 0;
+ }
+
+ printf("Geometry for window " WINFMT ": %dx%d%+d%+d\n",
+ (unsigned int) wid,
+ reply->width,
+ reply->height,
+ reply->x,
+ reply->y);
+
+ fflush(stdout);
+ return 1;
+}
+
+int formatQueryTreeReply(Window wid, XCB_QueryTree_Rep *reply)
+{
+ int i;
+
+ if(!reply)
+ {
+ fprintf(stderr, "Failed to query tree for window " WINFMT ".\n",
+ (unsigned int) wid);
+ return 0;
+ }
+
+ printf("Window " WINFMT " has parent " WINFMT ", root " WINFMT ", and %d children%c\n",
+ (unsigned int) wid,
+ (unsigned int) reply->parent,
+ (unsigned int) reply->root,
+ (unsigned int) reply->children_len,
+ reply->children_len ? ':' : '.');
+
+ for(i = 0; i < reply->children_len; ++i)
+ printf(" window " WINFMT "\n",
+ (unsigned int) XCB_QUERYTREE_CHILDREN(reply)[i]);
+
+ fflush(stdout);
+ return 1;
+}
+
+static const char *labelError[] = {
+ "Success",
+ "BadRequest",
+ "BadValue",
+ "BadWindow",
+ "BadPixmap",
+ "BadAtom",
+ "BadCursor",
+ "BadFont",
+ "BadMatch",
+ "BadDrawable",
+ "BadAccess",
+ "BadAlloc",
+ "BadColor",
+ "BadGC",
+ "BadIDChoice",
+ "BadName",
+ "BadLength",
+ "BadImplementation",
+};
+
+static const char *labelRequest[] = {
+ "no request",
+ "CreateWindow",
+ "ChangeWindowAttributes",
+ "GetWindowAttributes",
+ "DestroyWindow",
+ "DestroySubwindows",
+ "ChangeSaveSet",
+ "ReparentWindow",
+ "MapWindow",
+ "MapSubwindows",
+ "UnmapWindow",
+ "UnmapSubwindows",
+ "ConfigureWindow",
+ "CirculateWindow",
+ "GetGeometry",
+ "QueryTree",
+ "InternAtom",
+ "GetAtomName",
+ "ChangeProperty",
+ "DeleteProperty",
+ "GetProperty",
+ "ListProperties",
+ "SetSelectionOwner",
+ "GetSelectionOwner",
+ "ConvertSelection",
+ "SendEvent",
+ "GrabPointer",
+ "UngrabPointer",
+ "GrabButton",
+ "UngrabButton",
+ "ChangeActivePointerGrab",
+ "GrabKeyboard",
+ "UngrabKeyboard",
+ "GrabKey",
+ "UngrabKey",
+ "AllowEvents",
+ "GrabServer",
+ "UngrabServer",
+ "QueryPointer",
+ "GetMotionEvents",
+ "TranslateCoords",
+ "WarpPointer",
+ "SetInputFocus",
+ "GetInputFocus",
+ "QueryKeymap",
+ "OpenFont",
+ "CloseFont",
+ "QueryFont",
+ "QueryTextExtents",
+ "ListFonts",
+ "ListFontsWithInfo",
+ "SetFontPath",
+ "GetFontPath",
+ "CreatePixmap",
+ "FreePixmap",
+ "CreateGC",
+ "ChangeGC",
+ "CopyGC",
+ "SetDashes",
+ "SetClipRectangles",
+ "FreeGC",
+ "ClearArea",
+ "CopyArea",
+ "CopyPlane",
+ "PolyPoint",
+ "PolyLine",
+ "PolySegment",
+ "PolyRectangle",
+ "PolyArc",
+ "FillPoly",
+ "PolyFillRectangle",
+ "PolyFillArc",
+ "PutImage",
+ "GetImage",
+ "PolyText",
+ "PolyText",
+ "ImageText",
+ "ImageText",
+ "CreateColormap",
+ "FreeColormap",
+ "CopyColormapAndFree",
+ "InstallColormap",
+ "UninstallColormap",
+ "ListInstalledColormaps",
+ "AllocColor",
+ "AllocNamedColor",
+ "AllocColorCells",
+ "AllocColorPlanes",
+ "FreeColors",
+ "StoreColors",
+ "StoreNamedColor",
+ "QueryColors",
+ "LookupColor",
+ "CreateCursor",
+ "CreateGlyphCursor",
+ "FreeCursor",
+ "RecolorCursor",
+ "QueryBestSize",
+ "QueryExtension",
+ "ListExtensions",
+ "ChangeKeyboardMapping",
+ "GetKeyboardMapping",
+ "ChangeKeyboardControl",
+ "GetKeyboardControl",
+ "Bell",
+ "ChangePointerControl",
+ "GetPointerControl",
+ "SetScreenSaver",
+ "GetScreenSaver",
+ "ChangeHosts",
+ "ListHosts",
+ "SetAccessControl",
+ "SetCloseDownMode",
+ "KillClient",
+ "RotateProperties",
+ "ForceScreenSaver",
+ "SetPointerMapping",
+ "GetPointerMapping",
+ "SetModifierMapping",
+ "GetModifierMapping",
+ "major 120",
+ "major 121",
+ "major 122",
+ "major 123",
+ "major 124",
+ "major 125",
+ "major 126",
+ "NoOperation",
+};
+
+static const char *labelEvent[] = {
+ "error",
+ "reply",
+ "KeyPress",
+ "KeyRelease",
+ "ButtonPress",
+ "ButtonRelease",
+ "MotionNotify",
+ "EnterNotify",
+ "LeaveNotify",
+ "FocusIn",
+ "FocusOut",
+ "KeymapNotify",
+ "Expose",
+ "GraphicsExpose",
+ "NoExpose",
+ "VisibilityNotify",
+ "CreateNotify",
+ "DestroyNotify",
+ "UnmapNotify",
+ "MapNotify",
+ "MapRequest",
+ "ReparentNotify",
+ "ConfigureNotify",
+ "ConfigureRequest",
+ "GravityNotify",
+ "ResizeRequest",
+ "CirculateNotify",
+ "CirculateRequest",
+ "PropertyNotify",
+ "SelectionClear",
+ "SelectionRequest",
+ "SelectionNotify",
+ "ColormapNotify",
+ "ClientMessage",
+ "MappingNotify",
+};
+
+static const char *labelSendEvent[] = {
+ "",
+ " (from SendEvent)",
+};
+
+int formatEvent(XCB_Event *e)
+{
+ BYTE sendEvent;
+ CARD16 seqnum;
+
+ if(!e)
+ {
+ fprintf(stderr, "Error reading event from server.\n");
+ return 0;
+ }
+
+ sendEvent = (e->response_type & 0x80) ? 1 : 0;
+ e->response_type &= ~0x80;
+ seqnum = *((CARD16 *) e + 1);
+
+ switch(e->response_type)
+ {
+ case 0:
+ printf("Error %s on seqnum %d (%s).\n",
+ labelError[*((BYTE *) e + 1)],
+ seqnum,
+ labelRequest[*((CARD8 *) e + 10)]);
+ break;
+ default:
+ printf("Event %s following seqnum %d%s.\n",
+ labelEvent[e->response_type],
+ seqnum,
+ labelSendEvent[sendEvent]);
+ break;
+ case KeymapNotify:
+ printf("Event %s%s.\n",
+ labelEvent[e->response_type],
+ labelSendEvent[sendEvent]);
+ break;
+ }
+
+ fflush(stdout);
+ return 1;
+}
diff --git a/xcb-demo/reply_formats.h b/xcb-demo/reply_formats.h
new file mode 100644
index 0000000..2afccfe
--- /dev/null
+++ b/xcb-demo/reply_formats.h
@@ -0,0 +1,11 @@
+#ifndef REPLY_FORMATS_H
+#define REPLY_FORMATS_H
+
+#include <client/xp_core.h>
+
+int formatGetWindowAttributesReply(Window wid, XCB_GetWindowAttributes_Rep *reply);
+int formatGetGeometryReply(Window wid, XCB_GetGeometry_Rep *reply);
+int formatQueryTreeReply(Window wid, XCB_QueryTree_Rep *reply);
+int formatEvent(XCB_Event *e);
+
+#endif /* REPLY_FORMATS_H */
diff --git a/xcb_conn.m4 b/xcb_conn.m4
index eba4ddf..8a5d66a 100644
--- a/xcb_conn.m4
+++ b/xcb_conn.m4
@@ -3,29 +3,15 @@
*/
XCBGEN(XCB_CONN)
-SOURCEONLY(`dnl
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/fcntl.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <assert.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-
+SOURCEONLY(`
+INCHEADERS(INCHERE(xcb_conn.h), sys/types.h, sys/socket.h, sys/fcntl.h,
+ sys/un.h, netinet/in.h, netdb.h, stdio.h, unistd.h, stdlib.h, errno.h)
#undef USENONBLOCKING
')HEADERONLY(`dnl
-#include <sys/uio.h>
-#include <pthread.h>
-
#define NEED_EVENTS
#define NEED_REPLIES
#define ANSICPP
-#include <X11/X.h>
-#include <X11/Xproto.h>
+INCHEADERS(X11/X.h, X11/Xproto.h, sys/uio.h, pthread.h)
#define XCB_PAD(E) ((4-((E)%4))%4)
#define X_TCP_PORT 6000 /* add display number */
diff --git a/xcb_dpms.m4 b/xcb_dpms.m4
index 62ad330..fed7120 100644
--- a/xcb_dpms.m4
+++ b/xcb_dpms.m4
@@ -1,6 +1,6 @@
XCBGEN(XCB_DPMS)
-_C`'#include <assert.h>
-_H`'#include "xp_core.h"
+_H`'INCHEADERS(INCHERE(xp_core.h))
+_C`'INCHEADERS(INCHERE(xcb_dpms.h))
BEGINEXTENSION(DPMS, DPMS)
@@ -57,6 +57,5 @@ REQUEST(DPMSInfo, `
REPLY(CARD16, `power_level')
REPLY(BOOL, `state')
')
-_H
ENDEXTENSION
ENDXCBGEN
diff --git a/xcb_shape.m4 b/xcb_shape.m4
new file mode 100644
index 0000000..6327921
--- /dev/null
+++ b/xcb_shape.m4
@@ -0,0 +1,117 @@
+XCBGEN(XCB_SHAPE)
+_H`'INCHEADERS(INCHERE(xp_core.h))
+_C`'INCHEADERS(INCHERE(xcb_shape.h))
+
+BEGINEXTENSION(SHAPE, Shape)
+HEADERONLY(`
+typedef CARD8 SHAPE_OP;
+typedef CARD8 SHAPE_KIND;
+
+EVENT(ShapeNotify, 0, `
+ REPLY(SHAPE_KIND, `shape_kind')
+ REPLY(Window, `affected_window')
+ REPLY(INT16, `extents_x')
+ REPLY(INT16, `extents_y')
+ REPLY(CARD16, `extents_width')
+ REPLY(CARD16, `extents_height')
+ REPLY(Time, `server_time')
+ REPLY(BOOL, `shaped')
+')
+')
+REQUEST(ShapeQueryVersion, `
+ OPCODE(0)
+', `
+ PAD(1)
+ REPLY(CARD16, `major_version')
+ REPLY(CARD16, `minor_version')
+')
+
+VOIDREQUEST(ShapeRectangles, `
+ OPCODE(1)
+ PARAM(SHAPE_OP, `operation')
+ PARAM(SHAPE_KIND, `destination_kind')
+ PARAM(BYTE, `ordering')
+ PAD(1)
+ PARAM(Window, `destination_window')
+ PARAM(INT16, `x_offset')
+ PARAM(INT16, `y_offset')
+ LOCALPARAM(CARD32, `rectangles_len')
+ LISTPARAM(xRectangle, `rectangles', `rectangles_len')
+')
+
+VOIDREQUEST(ShapeMask, `
+ OPCODE(2)
+ PARAM(SHAPE_OP, `operation')
+ PARAM(SHAPE_KIND, `destination_kind')
+ PAD(2)
+ PARAM(Window, `destination_window')
+ PARAM(INT16, `x_offset')
+ PARAM(INT16, `y_offset')
+ PARAM(Pixmap, `source_bitmap')
+')
+
+VOIDREQUEST(ShapeCombine, `
+ OPCODE(3)
+ PARAM(SHAPE_OP, `operation')
+ PARAM(SHAPE_KIND, `destination_kind')
+ PARAM(SHAPE_KIND, `source_kind')
+ PAD(1)
+ PARAM(Window, `destination_window')
+ PARAM(INT16, `x_offset')
+ PARAM(INT16, `y_offset')
+ PARAM(Window, `source_window')
+')
+
+VOIDREQUEST(ShapeOffset, `
+ OPCODE(4)
+ PARAM(SHAPE_KIND, `destination_kind')
+ PAD(3)
+ PARAM(Window, `destination_window')
+ PARAM(INT16, `x_offset')
+ PARAM(INT16, `y_offset')
+')
+
+REQUEST(ShapeQueryExtents, `
+ OPCODE(5)
+ PARAM(Window, `destination_window')
+', `
+ PAD(1)
+ REPLY(BOOL, `bounding_shaped')
+ REPLY(BOOL, `clip_shaped')
+ PAD(2)
+ REPLY(INT16, `bounding_shape_extents_x')
+ REPLY(INT16, `bounding_shape_extents_y')
+ REPLY(CARD16, `bounding_shape_extents_width')
+ REPLY(CARD16, `bounding_shape_extents_height')
+ REPLY(INT16, `clip_shape_extents_x')
+ REPLY(INT16, `clip_shape_extents_y')
+ REPLY(CARD16, `clip_shape_extents_width')
+ REPLY(CARD16, `clip_shape_extents_height')
+')
+
+VOIDREQUEST(ShapeSelectInput, `
+ OPCODE(6)
+ PARAM(Window, `destination_window')
+ PARAM(BOOL, `enable')
+')
+
+REQUEST(ShapeInputSelected, `
+ OPCODE(6)
+ PARAM(Window, `destination_window')
+', `
+ REPLY(BOOL, `enabled')
+')
+
+REQUEST(ShapeGetRectangles, `
+ OPCODE(7)
+ PARAM(Window, `window')
+ PARAM(SHAPE_KIND, `source_kind')
+', `
+ REPLY(BYTE, `ordering')
+ PAD(1)
+ REPLY(CARD32, `rectangles_len')
+ ARRAYREPLY(xRectangle, `rectangles', `rectangles_len')
+')
+
+ENDEXTENSION
+ENDXCBGEN
diff --git a/xcbgen.m4 b/xcbgen.m4
deleted file mode 100644
index 8cd2c60..0000000
--- a/xcbgen.m4
+++ /dev/null
@@ -1,435 +0,0 @@
-dnl
-dnl generate XCB C code
-dnl Bart & Jamey 9/2001
-dnl
-dnl
-dnl Don't insert this text in the source file.
-dnl This makes succeeding dnl commands unnecessary but harmless.
-dnl
-divert(-1)
-
-
-dnl -- General definitions
-
-
-dnl GNU m4 m4wrap() executes argument at end of input.
-dnl In this case the argument discards unprocessed diversions.
-m4wrap(`divert(-1)undivert')
-
-dnl Use C-style comments.
-changecom(`/*', `*/')
-
-
-dnl Push diversion on the diversion stack
-dnl PUSHDIV(diversion)
-define(`PUSHDIV', `pushdef(`DIVNUM',divnum)divert($1)')
-
-dnl Pop diversion off the diversion stack and discards it
-dnl POPDIV()
-define(`POPDIV', `divert(DIVNUM)popdef(`DIVNUM')')
-
-
-dnl Indent current line appropriately by inserting spaces.
-dnl TAB()
-define(`TAB', `')
-
-dnl Move line indentation to the right 4 spaces.
-dnl INDENT()
-define(`INDENT', `pushdef(`TAB', ` 'TAB)')
-
-dnl Move line indentation to the left 4 spaces.
-dnl UNINDENT()
-define(`UNINDENT', `popdef(`TAB')')
-
-
-dnl Transliterates lowercase characters to uppercase.
-dnl TOUPPER(string)
-define(`TOUPPER', `translit($1, `a-z', `A-Z')')
-
-
-dnl Exactly one of _H and _C should be set on the command line.
-dnl When _H is set, _C lines will be thrown away.
-dnl Similarly, when _C is set, _H lines will be thrown away.
-dnl Stuff that belongs in header files only should be
-dnl prefixed with _H, stuff that belongs in .c files only should
-dnl be prefixed with _C.
-dnl Note that the define()s are in the else part of the ifdef.
-dnl Do not make the obvious change without careful thought.
-define(`HEADERONLY', `PUSHDIV(-1) $1
-POPDIV()')
-ifdef(`_H', `define(`HEADERONLY', `$1')', `define(`_H', `dnl')')
-define(`SOURCEONLY', `PUSHDIV(-1) $1
-POPDIV()')
-ifdef(`_C', `define(`SOURCEONLY', `$1')', `define(`_C', `dnl')')
-
-
-dnl Declare a C function.
-dnl Note that this macro also sticks a declaration
-dnl in the header file.
-dnl FUNCTION(return type and function name, params, body)
-define(`FUNCTION', `dnl
-$1($2)HEADERONLY(;)SOURCEONLY(`
-{INDENT()dnl
-$3}UNINDENT()')')
-
-dnl Declare a C function local to the .c file.
-dnl The header file is not affected.
-dnl STATICFUNCTION(return type and function name, params, body)
-define(`STATICFUNCTION', `SOURCEONLY(
-`static $1($2)
-{INDENT()dnl
-$3}UNINDENT()')')
-
-dnl Declare a C function which should be compiled inline if possible.
-dnl TODO: fallback to a regular function if inline is not supported by
-dnl the compiler.
-dnl INLINEFUNCTION(return type and function name, params, body)
-define(`INLINEFUNCTION', `HEADERONLY(
-`static inline $1($2)
-{INDENT()dnl
-$3}UNINDENT()')')
-
-
-dnl Allocate a block or array of storage with a given name.
-dnl There is no FREE() macro: just call free().
-dnl ALLOC(type, result name, count)
-define(`ALLOC', `dnl
-TAB()$2 = ($1 *) malloc(($3) * sizeof($1));
-TAB()assert($2);')
-
-dnl REALLOC(type, result name, count)
-define(`REALLOC', `dnl
-TAB()$2 = ($1 *) realloc($2, ($3) * sizeof($1));
-TAB()assert($2);')
-
-
-dnl -- Names used internally
-
-dnl Diversions holding various portions of the generated code.
-define(`PARMDIV', 1) dnl List of parameters in a REQUEST
-define(`OUTDIV', 2) dnl Structure assignment code for
- dnl binding out->* in REQUEST
-define(`VARDIV', 3) dnl Variable declarations for REQUEST bodies
-define(`STRUCTDIV', 4) dnl Body of structure declared
- dnl with STRUCT or UNION macros
-
-dnl
-define(`FIELDQTY', 0) dnl Count of fields in a struct (or request)
-define(`PADQTY', 0) dnl Count of padding fields in a request or reply
-define(`PARTQTY', 0) dnl Count of variable length elements in request
-define(`PARAMQTY', 0) dnl Count of parameters to request (currently tests
- dnl only for zero/nonzero)
-
-
-dnl -- Request/Response macros
-
-dnl The *PARAM and *FIELD macros must only appear inside a REQUEST or
-dnl VOIDREQUEST macro call, and must be quoted. All fields must appear
-dnl in the order the X server expects to recieve them in. Parameters to
-dnl the generated request functions will appear in the same order as the
-dnl PARAM/FIELD macros they're related to.
-
-
-dnl The X protocol specification says that the X name of the extension
-dnl "should use the ISO Latin-1 encoding, and uppercase and lowercase matter."
-dnl The C name should be a valid C identifier which can be guessed easily
-dnl from the X name, as it will appear in programmer-visible names.
-dnl BEGINEXTENSION(X name, C name)
-define(`BEGINEXTENSION', `define(`EXTENSION', `XCB_`'$2`'_id')dnl
-_H`'extern const char EXTENSION[];
-_C`'const char EXTENSION[] = "`$1'";
-FUNCTION(`const XCB_QueryExtension_Rep *XCB_`'$2`'_Init', `XCB_Connection *c', `
- return XCB_QueryExtension_Cached(c, EXTENSION, 0);
-')')
-
-dnl ENDEXTENSION()
-define(`ENDEXTENSION', `undefine(`EXTENSION')dnl')
-
-
-
-dnl Defines a BITMASK/LISTofVALUE parameter pair. The bitmask type should
-dnl probably be either CARD16 or CARD32, depending on the specified width
-dnl of the bitmask. The value array must be given to the generated
-dnl function in the order the X server expects.
-dnl VALUEPARAM(bitmask type, bitmask name, value array name)
-define(`VALUEPARAM', `FIELD(`$1', `$2')
-PUSHDIV(OUTDIV)
-TAB()out->`$2' = `$2';
-TAB()out->length += XCB_Ones(`$2');
-TAB()parts[PARTQTY].iov_base = `$3';
-TAB()parts[PARTQTY].iov_len = XCB_Ones(`$2') * 4;
-define(`PARTQTY', eval(1+PARTQTY))dnl
-divert(PARMDIV), $1 `$2', CARD32 *`$3'dnl
-POPDIV()ifelse(FIELDQTY, 2, `LENGTHFIELD()')')
-
-dnl Defines a LISTofFOO parameter. The length of the list may be given as
-dnl any C expression and may reference any of the other fields of this
-dnl request.
-dnl LISTPARAM(element type, list name, length expression)
-define(`LISTPARAM', `PUSHDIV(PARMDIV), const `$1' *`$2'dnl
-divert(OUTDIV)
-TAB()out->length += (`$3') * sizeof(`$1') / 4;
-TAB()parts[PARTQTY].iov_base = (`$1' *) `$2';
-TAB()parts[PARTQTY].iov_len = (`$3') * sizeof(`$1');
-POPDIV()define(`PARTQTY', eval(1+PARTQTY))')
-
-dnl Defines a field which should be filled in with the given expression.
-dnl The field name is available for use in the expression of a LISTPARAM
-dnl or a following EXPRFIELD.
-dnl EXPRFIELD(field type, field name, expression)
-define(`EXPRFIELD', `FIELD(`$1', `$2')
-PUSHDIV(VARDIV)dnl
-TAB()$1 `$2' = `$3';
-divert(OUTDIV)dnl
-TAB()out->`$2' = `$2';
-POPDIV()ifelse(FIELDQTY, 2, `LENGTHFIELD()')')
-
-dnl Defines a parameter with no associated field. The name can be used in
-dnl expressions.
-dnl LOCALPARAM(type, name)
-define(`LOCALPARAM', `PUSHDIV(PARMDIV), $1 `$2'POPDIV()')
-
-dnl Defines a parameter with a field of the same type.
-dnl PARAM(type, name)
-define(`PARAM', `FIELD($1, `$2')
-PUSHDIV(PARMDIV), $1 `$2'`'dnl
-divert(OUTDIV)dnl
-TAB()out->`$2' = `$2';
-POPDIV()define(`PARAMQTY', eval(1+PARAMQTY))
-ifelse(FIELDQTY, 2, `LENGTHFIELD()')')
-
-dnl Sets the major number for all instances of this request to the given code.
-dnl OPCODE(number)
-define(`OPCODE', `ifdef(`EXTENSION', `
- FIELD(CARD8, `major_opcode')
- FIELD(CARD8, `minor_opcode')
-PUSHDIV(VARDIV)dnl
-TAB()const XCB_QueryExtension_Rep *extension = XCB_QueryExtension_Cached(c, EXTENSION, 0);
-divert(OUTDIV)dnl
-dnl TODO: better error handling here, please!
-TAB()assert(extension && extension->present);
-
-TAB()out->major_opcode = extension->major_opcode;
-TAB()out->minor_opcode = `$1';
-POPDIV()
- ifelse(FIELDQTY, 2, `LENGTHFIELD()')
-', `
- FIELD(CARD8, `major_opcode')
-PUSHDIV(OUTDIV)dnl
-TAB()out->major_opcode = `$1';
-POPDIV()
-')')
-
-dnl PAD(bytes)
-define(`PAD', `ARRAYFIELD(`CARD8', `pad'PADQTY, `$1')
-define(`PADQTY', eval(1+PADQTY))
-ifelse(FIELDQTY, 2, `LENGTHFIELD()')')
-
-dnl REPLY(type, name)
-define(`REPLY', `FIELD(`$1', `$2')
-ifelse(FIELDQTY, 2, `LENGTHFIELD()')')
-
-dnl Generates a C pre-processor macro providing access to a variable-length
-dnl portion of a reply. If another reply field follows, the length name
-dnl must be provided. The length name is the name of a field in the
-dnl fixed-length portion of the response which contains the number of
-dnl elements in this section.
-dnl ARRAYREPLY(field type, field name, opt length name)
-define(`ARRAYREPLY', `PUSHDIV(OUTDIV)HEADERONLY(
-#define `XCB_'REQ`_'TOUPPER($2)`(reply) (($1 *) ('ifdef(`LASTFIELD', `XCB_'REQ`_'LASTFIELD`(reply) + reply->'LASTLEN, `reply + 1')`))'
-)POPDIV()
-define(`LASTFIELD', TOUPPER($2))ifelse($#, 3, `define(`LASTLEN', $3)')')
-
-dnl Generates an iterator for the variable-length portion of a reply.
-dnl TODO: um, write this.
-dnl LISTREPLY(???)
-define(`LISTREPLY', `')
-
-
-
-dnl Creates a function named XCB_<name> returning XCB_void_cookie and
-dnl accepting whatever parameters are necessary to deliver the given PARAMs
-dnl and FIELDs to the X server.
-dnl VOIDREQUEST(name, 0 or more PARAMs/FIELDs)
-define(`VOIDREQUEST', `REQUESTFUNCTION(`void', `$1', `$2')')
-
-dnl Creates a function named XCB_<name> returning XCB_<name>_cookie and
-dnl accepting whatever parameters are necessary to deliver the given PARAMs
-dnl and FIELDs to the X server. Declares the struct XCB_<name>_cookie.
-dnl Creates a function named XCB_<name>_Reply returning a pointer to
-dnl XCB_<name>_Rep which forces a cookie returned from XCB_<name>, waiting
-dnl for the response from the server if necessary. Declares the struct
-dnl XCB_<name>_Rep. The three parameters must be quoted.
-dnl REQUEST(name, 0 or more PARAMs, 0 or more REPLYs)
-define(`REQUEST',`REQUESTFUNCTION(`$1', `$1', `$2')
-_H
-PACKETSTRUCT(`$1', `Rep', `$3')
-undivert(OUTDIV)`'dnl
-INLINEFUNCTION(`XCB_'$1`_Rep *XCB_'$1`_Reply',
-`XCB_Connection *c, XCB_'$1`_cookie cookie, XCB_Event **e', `
- return (XCB_'$1`_Rep *) XCB_Wait_Seqnum(c, cookie.seqnum, e);
-')undefine(`LASTFIELD')undefine(`LASTLEN')')
-
-
-dnl Internal function shared by REQUEST and VOIDREQUEST, implementing the
-dnl common portions of those macros.
-dnl REQUESTFUNCTION(return type, request name, parameters)
-define(`REQUESTFUNCTION',`dnl
-ifelse($1, void, `dnl', `COOKIETYPE($1)
-_H')
-PACKETSTRUCT(`$2', `Req', `$3')
-FUNCTION(`XCB_'$1`_cookie XCB_'$2, `XCB_Connection *c`'undivert(PARMDIV)', `
- XCB_`$1'_cookie ret;
- XCB_`$2'_Req *out;
-undivert(VARDIV)`'dnl
-ifelse(PARTQTY, 0, `dnl', ` struct iovec parts[PARTQTY];')
-
- pthread_mutex_lock(&c->locked);
- out = (XCB_`$2'_Req *) XCB_Alloc_Out(c, (sizeof(*out) + XCB_PAD(sizeof(*out))));
-
-undivert(OUTDIV)`'dnl
-ifelse(PARAMQTY, 0, `dnl')
- ret.seqnum = ++c->seqnum;
-ifelse(PARTQTY, 0, `dnl', ` XCB_Write(c, parts, PARTQTY);')
-ifelse($1, void, `dnl', ` XCB_Add_Reply_Data(c, ret.seqnum);')
- pthread_mutex_unlock(&c->locked);
-
- return ret;
-define(`PARTQTY', 0)define(`PARAMQTY', 0)')')
-
-
-dnl -- Type macros
-
-dnl FIELD, ARRAYFIELD, and POINTERFIELD can be used in either STRUCT or
-dnl UNION definitions.
-
-dnl Declares a field of the given type with the given name.
-dnl FIELD(type, name)
-define(`FIELD', `PUSHDIV(STRUCTDIV)dnl
- `$1' `$2';
-POPDIV()define(`FIELDQTY', eval(1+FIELDQTY))')
-
-dnl Declares an array field with the given quantity of elements of the
-dnl given type.
-dnl ARRAYFIELD(type, name, quantity)
-define(`ARRAYFIELD', `PUSHDIV(STRUCTDIV)dnl
- `$1' `$2'[`$3'];
-POPDIV()define(`FIELDQTY', eval(1+FIELDQTY))')
-
-dnl Declares a field with the given name which is a pointer to the given type.
-dnl POINTERFIELD(type, name)
-define(`POINTERFIELD', `PUSHDIV(STRUCTDIV)dnl
- `$1' *`$2';
-POPDIV()define(`FIELDQTY', eval(1+FIELDQTY))')
-
-dnl STRUCT(name, 1 or more FIELDs)
-define(`STRUCT', `PUSHDIV(-1)
-$2
-define(`FIELDQTY',0)
-POPDIV()HEADERONLY(`typedef struct `$1' {
-undivert(STRUCTDIV)dnl
-} `$1';')')
-
-dnl STATICSTRUCT(name, 1 or more FIELDs)
-define(`STATICSTRUCT', `PUSHDIV(-1)
-$2
-define(`FIELDQTY',0)
-POPDIV()SOURCEONLY(`typedef struct `$1' {
-undivert(STRUCTDIV)dnl
-} `$1';')')
-
-dnl UNION(name, 1 or more FIELDs)
-define(`UNION', `PUSHDIV(-1)
-$2
-define(`FIELDQTY',0)
-POPDIV()HEADERONLY(`typedef union `$1' {
-undivert(STRUCTDIV)dnl
-} `$1';')')
-
-
-dnl Declares a struct named XCB_<name>_cookie with a single "int seqnum"
-dnl field.
-dnl COOKIETYPE(name)
-define(`COOKIETYPE', `STRUCT(XCB_$1_cookie, `FIELD(int, `seqnum')')')
-
-
-dnl EVENT(name, number, 1 or more FIELDs)
-define(`EVENT', `dnl
-_H`'#define XCB_`$1' `$2'
-PACKETSTRUCT(`$1', `Event', `$3')')
-
-dnl EVENTCOPY(new name, new number, old name)
-define(`EVENTCOPY', `HEADERONLY(
-#define XCB_`$1' `$2'
-typedef XCB_`$3'_Event XCB_`$1'_Event;
-)')
-
-dnl ERROR(name, number, 1 or more FIELDs)
-define(`ERROR', `dnl
-_H`'#define XCB_`$1' `$2'
-PACKETSTRUCT(`$1', `Error', `$3')')
-
-dnl ERRORCOPY(new name, new number, old name)
-define(`ERRORCOPY', `HEADERONLY(
-#define XCB_`$1' `$2'
-typedef XCB_`$3'_Error XCB_`$1'_Error;
-)')
-
-
-dnl EVENTMIDDLE()
-define(`EVENTMIDDLE', `FIELD(CARD16, `seqnum')')
-
-dnl ERRORMIDDLE()
-define(`ERRORMIDDLE', `FIELD(CARD16, `seqnum')')
-
-dnl REPMIDDLE()
-define(`REPMIDDLE', `
- FIELD(CARD16, `seqnum')
- FIELD(CARD32, `length')
-')
-
-dnl REQMIDDLE()
-define(`REQMIDDLE', `FIELD(CARD16, `length')
-PUSHDIV(OUTDIV)dnl
-TAB()out->length = (sizeof(*out) + XCB_PAD(sizeof(*out))) / 4;
-POPDIV()')
-
-dnl for kind in (Event, Error, Rep, Req)
-dnl PACKETSTRUCT(name, kind, 1 or more FIELDs)
-define(`PACKETSTRUCT', `dnl
-pushdef(`REQ', `TOUPPER($1)')dnl
-pushdef(`LENGTHFIELD', `TOUPPER($2)MIDDLE')dnl
-INDENT()dnl
-STRUCT(XCB_`$1'_`$2', `
-dnl Everything except requests has a response type.
-ifelse(`$2', `Req', , `REPLY(BYTE, `response_type')')
-dnl Only errors have an error code.
-ifelse(`$2', `Error', `REPLY(BYTE, `error_code')')
-$3
-dnl Requests and replies always have length fields.
-ifelse(FIELDQTY, 1,
- `ifelse(`$2', `Req', `PAD(1)',
- `ifelse(`$2', `Rep', `PAD(1)')')')
-')_H
-UNINDENT()dnl
-define(`PADQTY', 0)dnl
-popdef(`LENGTHFIELD')popdef(`REQ')_H')
-
-
-dnl -- Other macros
-
-dnl XCBGEN(header name)
-define(`XCBGEN', `dnl
-`/*'
- * This file generated automatically from __file__ by xcbgen.m4 using m4.
- * Edit at your peril.
-` */'
-
-_H`'#ifndef __$1_H
-_H`'#define __$1_H
-_C`'#include "patsubst(__file__, `\.m4$', `.h')"')
-
-dnl ENDXCBGEN()
-define(`ENDXCBGEN', `_H`'#endif')
-
-divert(0)`'dnl
diff --git a/xp_core.m4 b/xp_core.m4
index f02f4a7..dafc50b 100644
--- a/xp_core.m4
+++ b/xp_core.m4
@@ -1,13 +1,7 @@
XCBGEN(XP_CORE)
-SOURCEONLY(`dnl
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h> /* for perror */
-#include <string.h>
-dnl')
-HEADERONLY(`dnl
-#include "xcb_conn.h"
-
+_C`'INCHEADERS(INCHERE(xp_core.h), stdlib.h, stdio.h, string.h)
+HEADERONLY(`
+INCHEADERS(INCHERE(xcb_conn.h))
typedef char CHAR2B[2];