Remove xcl and CVSROOT.
authorJosh Triplett <josh@freedesktop.org>
Sun, 19 Feb 2006 00:49:41 +0000 (16:49 -0800)
committerJosh Triplett <josh@josh-mobile.localdomain>
Sun, 19 Feb 2006 00:49:41 +0000 (16:49 -0800)
22 files changed:
.cvsignore [new file with mode: 0644]
COPYING [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
dpms.c [new file with mode: 0644]
hypnomoire.c [new file with mode: 0644]
main.c [new file with mode: 0644]
rendertest.c [new file with mode: 0644]
reply_formats.c [new file with mode: 0644]
reply_formats.h [new file with mode: 0644]
tests/.cvsignore [new file with mode: 0644]
tests/Makefile.am [new file with mode: 0644]
tests/flames.c [new file with mode: 0644]
tests/julia.c [new file with mode: 0644]
tests/julia.h [new file with mode: 0644]
tests/lissajoux.c [new file with mode: 0644]
tests/lissajoux.h [new file with mode: 0644]
xcbrandr.c [new file with mode: 0644]
xcbxvinfo.c [new file with mode: 0644]
xdpyinfo.c [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..aab0e68
--- /dev/null
@@ -0,0 +1,26 @@
+.deps
+.libs
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+missing
+mkinstalldirs
+stamp-h1
+hypnomoire
+dpms
+xcb-test
+rendertest
+xdpyinfo
+xcbrandr
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..1df05e4
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,156 @@
+Copyright (C) 2001-2002 Bart Massey and Jamey Sharp. All Rights Reserved.
+
+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, and to
+permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+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 THE AUTHORS
+BE LIABLE FOR ANY CLAIM, 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 names of the authors
+or their institutions shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this
+Software without prior written authorization from the
+authors.
+
+
+Portions of this software are subject to the following notice:
+
+Copyright 1985, 1986, 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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 THE OPEN GROUP BE LIABLE FOR ANY CLAIM, 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 The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Portions of this software are subject to the following notice:
+
+Copyright 1986, 1998  The Open Group
+Copyright (c) 2000  The XFree86 Project, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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 THE
+X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, 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 the X Consortium or of the
+XFree86 Project shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from the X Consortium and the XFree86 Project.
+
+
+Portions of this software are subject to the following notice:
+
+Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard,
+Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Portions of this software are subject to the following notice:
+
+Copyright 1988 by Wyse Technology, Inc., San Jose, Ca.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name Wyse not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+WYSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Portions of this software are subject to the following notice:
+
+Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..6ba5c56
--- /dev/null
@@ -0,0 +1,27 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+SUBDIRS = tests
+
+EXTRA_DIST = autogen.sh README
+
+INCLUDES = $(XCB_CFLAGS)
+LDADD = $(XCB_LIBS)
+
+bin_PROGRAMS = hypnomoire xdpyinfo xcb-test dpms rendertest xcbrandr
+
+hypnomoire_LDADD = $(LDADD) $(XCBAUX_LIBS) -lm -lpthread
+hypnomoire_SOURCES = hypnomoire.c reply_formats.c
+
+xdpyinfo_SOURCES = xdpyinfo.c
+
+xcb_test_LDADD = $(LDADD) $(XCBAUX_LIBS) -lpthread
+xcb_test_SOURCES = main.c reply_formats.c
+
+dpms_SOURCES = dpms.c
+
+rendertest_LDADD = $(XCBAUX_LIBS)
+rendertest_SOURCES = rendertest.c
+
+xcbrandr_LDADD = $(XCBAUX_LIBS)
+xcbrandr_SOURCES = xcbrandr.c
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..f36e16b
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+xcb-demo: A collection of demo programs that use the XCB library.
+
+dpms........: test of the dpms extension.
+hypnomoire..: 
+rendertest..: test of the render extension.
+xcb-test....: test of the events on a window.
+xcbrandr....: test of the randr extension.
+xdpyinfo....: XCB port of the standard xdpyinfo.
+
+In tests/ :
+
+julia.......: example of XCBImage use, with a colormap.
+lissajoux...: simple example of XCBImage use.
\ No newline at end of file
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..d68a142
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+autoreconf -v --install || exit 1
+./configure "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..8b512ea
--- /dev/null
@@ -0,0 +1,18 @@
+AC_PREREQ(2.57)
+AC_INIT([xcb-demo],0.8,[jamey@minilop.net])
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+dnl AC_PROG_INSTALL
+dnl AC_PROG_LN_S
+dnl AM_PROG_LIBTOOL
+dnl AC_PROG_MAKE_SET
+
+PKG_CHECK_MODULES(XCB, xcb)
+PKG_CHECK_MODULES(XCBAUX, xcb-aux)
+PKG_CHECK_MODULES(XCBIMAGE, xcb-image)
+PKG_CHECK_MODULES(XCBICCCM, xcb-icccm)
+
+AC_OUTPUT([Makefile tests/Makefile])
diff --git a/dpms.c b/dpms.c
new file mode 100644 (file)
index 0000000..a739f97
--- /dev/null
+++ b/dpms.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2001-2005 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.  See the file COPYING in this directory
+ * for licensing information.
+ */
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/dpms.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+       XCBConnection *c = XCBConnect(0, 0);
+       XCBDPMSGetVersionCookie vc;
+       XCBDPMSGetVersionRep *ver;
+       XCBDPMSCapableCookie cc;
+       XCBDPMSCapableRep *cap;
+       XCBDPMSGetTimeoutsCookie tc;
+       XCBDPMSGetTimeoutsRep *time;
+
+       XCBPrefetchExtensionData(c, &XCBDPMSId);
+
+       vc = XCBDPMSGetVersion(c, 1, 1);
+       cc = XCBDPMSCapable(c);
+       tc = XCBDPMSGetTimeouts(c);
+
+       ver = XCBDPMSGetVersionReply(c, vc, 0);
+       cap = XCBDPMSCapableReply(c, cc, 0);
+       time = XCBDPMSGetTimeoutsReply(c, tc, 0);
+
+       assert(ver);
+       assert(ver->server_major_version == 1);
+       assert(ver->server_minor_version == 1);
+       free(ver);
+
+       assert(cap);
+       assert(cap->capable);
+       free(cap);
+
+       assert(time);
+       printf("Standby: %d\n" "Suspend: %d\n" "Off: %d\n",
+               time->standby_timeout, time->suspend_timeout, time->off_timeout);
+       free(time);
+
+       XCBDisconnect(c);
+
+       exit(0);
+       /*NOTREACHED*/
+}
diff --git a/hypnomoire.c b/hypnomoire.c
new file mode 100644 (file)
index 0000000..0b47d83
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.  See the file COPYING in this directory
+ * for licensing information.
+ */
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/xcb_aux.h>
+#include "reply_formats.h"
+#include <math.h>
+#include <stdlib.h> /* for free(3) */
+#include <unistd.h> /* for usleep(3) */
+#include <stdio.h>
+#include <pthread.h>
+
+#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 10.0 /* frames per second */
+
+#define PI 3.14159265
+
+static XCBConnection *c;
+static XCBSCREEN *root;
+static XCBGCONTEXT white, black;
+static int depth;
+
+#define WINS 8
+static struct {
+       XCBDRAWABLE w;
+       XCBDRAWABLE p;
+       CARD16 width;
+       CARD16 height;
+       float angv;
+} windows[WINS];
+
+void *run(void *param);
+void *event_thread(void *param);
+
+static void get_depth()
+{
+       XCBDRAWABLE drawable = { root->root };
+       XCBGetGeometryRep *geom;
+       geom = XCBGetGeometryReply(c, XCBGetGeometry(c, drawable), 0);
+       if(!geom)
+       {
+               perror("GetGeometry(root) failed");
+               abort();
+       }
+
+       depth = geom->depth;
+       fprintf(stderr, "Root 0x%lx: %dx%dx%d\n",
+                root->root.xid, geom->width, geom->height, geom->depth);
+       free(geom);
+}
+
+int main()
+{
+       pthread_t thr;
+       int i;
+
+       CARD32 mask = GCForeground | GCGraphicsExposures;
+       CARD32 values[2];
+       XCBDRAWABLE rootwin;
+       int screen_num;
+
+       c = XCBConnect(0, &screen_num);
+       root = XCBAuxGetScreen(c, screen_num);
+       get_depth();
+
+       rootwin.window = root->root;
+       white = XCBGCONTEXTNew(c);
+       black = XCBGCONTEXTNew(c);
+
+       pthread_create(&thr, 0, event_thread, 0);
+
+       values[1] = 0; /* no graphics exposures */
+
+       values[0] = root->white_pixel;
+       XCBCreateGC(c, white, rootwin, mask, values);
+
+       values[0] = root->black_pixel;
+       XCBCreateGC(c, black, rootwin, 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)
+{
+       XCBCopyArea(c, windows[idx].p, windows[idx].w, white, 0, 0, 0, 0,
+               windows[idx].width, windows[idx].height);
+       if(!XCBSync(c, 0))
+       {
+               perror("XCBSync failed");
+               abort();
+       }
+}
+
+void *run(void *param)
+{
+       int idx = (int)param;
+
+       int xo, yo;
+       double r, theta = 0;
+
+       XCBPOINT line[2];
+
+       windows[idx].w.window = XCBWINDOWNew(c);
+       windows[idx].p.pixmap = XCBPIXMAPNew(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;
+       windows[idx].angv = 0.05;
+
+       {
+               int ws = windows[idx].width * windows[idx].width;
+               int hs = windows[idx].height * windows[idx].height;
+               r = sqrt(ws + hs) + 1.0;
+       }
+
+       {
+               CARD32 mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+               CARD32 values[3];
+               XCBRECTANGLE rect = { 0, 0, windows[idx].width, windows[idx].height };
+               values[0] = root->white_pixel;
+               values[1] = ButtonReleaseMask | ExposureMask;
+               values[2] = ButtonPressMask;
+
+               XCBCreateWindow(c, depth, windows[idx].w.window, root->root,
+                       /* x */ 0, /* y */ 0,
+                       windows[idx].width, windows[idx].height,
+                       /* border */ 0, InputOutput,
+                       /* visual */ root->root_visual,
+                       mask, values);
+
+               XCBMapWindow(c, windows[idx].w.window);
+
+               XCBCreatePixmap(c, depth,
+                       windows[idx].p.pixmap, windows[idx].w,
+                       windows[idx].width, windows[idx].height);
+
+               XCBPolyFillRectangle(c, windows[idx].p, white, 1, &rect);
+       }
+
+       XCBSync(c, 0);
+
+       while(1)
+       {
+               line[1].x = xo + r * cos(theta);
+               line[1].y = yo + r * sin(theta);
+               XCBPolyLine(c, CoordModeOrigin, windows[idx].p, black,
+                       2, line);
+
+               line[1].x = xo + r * cos(theta + LAG);
+               line[1].y = yo + r * sin(theta + LAG);
+               XCBPolyLine(c, CoordModeOrigin, windows[idx].p, white,
+                       2, line);
+
+               paint(idx);
+               theta += windows[idx].angv;
+               while(theta > 2 * PI)
+                       theta -= 2 * PI;
+               while(theta < 0)
+                       theta += 2 * PI;
+
+               usleep(1000000 / FRAME_RATE);
+       }
+}
+
+int lookup_window(XCBWINDOW w)
+{
+       int i;
+       for(i = 0; i < WINS; ++i)
+               if(windows[i].w.window.xid == w.xid)
+                       return i;
+       return -1;
+}
+
+void *event_thread(void *param)
+{
+       XCBGenericEvent *e;
+       int idx;
+
+       while(1)
+       {
+               e = XCBWaitForEvent(c);
+               if(!formatEvent(e))
+                       return 0;
+               if(e->response_type == XCBExpose)
+               {
+                       XCBExposeEvent *ee = (XCBExposeEvent *) e;
+                       idx = lookup_window(ee->window);
+                       if(idx == -1)
+                               fprintf(stderr, "Expose on unknown window!\n");
+                       else
+                       {
+                               XCBCopyArea(c, windows[idx].p, windows[idx].w,
+                                       white, ee->x, ee->y, ee->x, ee->y,
+                                       ee->width, ee->height);
+                               if(ee->count == 0)
+                                       XCBFlush(c);
+                       }
+               }
+               else if(e->response_type == XCBButtonRelease)
+               {
+                       XCBButtonReleaseEvent *bre = (XCBButtonReleaseEvent *) e;
+                       idx = lookup_window(bre->event);
+                       if(idx == -1)
+                               fprintf(stderr, "ButtonRelease on unknown window!\n");
+                       else
+                       {
+                               if(bre->detail.id == Button1)
+                                       windows[idx].angv = -windows[idx].angv;
+                               else if(bre->detail.id == Button4)
+                                       windows[idx].angv += 0.001;
+                               else if(bre->detail.id == Button5)
+                                       windows[idx].angv -= 0.001;
+                       }
+               }
+               free(e);
+       }
+}
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..0a81a57
--- /dev/null
+++ b/main.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.  See the file COPYING in this directory
+ * for licensing information.
+ */
+
+#define TEST_GET_WINDOW_ATTRIBUTES
+#define TEST_GET_GEOMETRY
+#define TEST_QUERY_TREE
+#undef TEST_THREADS
+#define VERBOSE
+#undef SUPERVERBOSE
+#define TEST_ICCCM
+
+#ifdef TEST_THREADS
+#include <pthread.h>
+#endif
+
+#ifdef TEST_ICCCM
+#include <string.h>
+#endif
+
+#include <stdlib.h>
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/xcb_aux.h>
+#include "reply_formats.h"
+
+#ifdef VERBOSE
+#include <stdio.h>
+#endif
+
+void try_events(XCBConnection *c);
+void wait_events(XCBConnection *c);
+
+static XCBConnection *c;
+static XCBWINDOW window;
+
+int main(int argc, char **argv)
+{
+    CARD32 mask = 0;
+    CARD32 values[6];
+    XCBDRAWABLE d;
+    XCBSCREEN *root;
+#ifdef TEST_GET_GEOMETRY
+    XCBGetGeometryCookie geom[3];
+    XCBGetGeometryRep *geomrep[3];
+#endif
+#ifdef TEST_QUERY_TREE
+    XCBQueryTreeCookie tree[3];
+    XCBQueryTreeRep *treerep[3];
+#endif
+#ifdef TEST_GET_WINDOW_ATTRIBUTES
+    XCBGetWindowAttributesCookie attr[1];
+    XCBGetWindowAttributesRep *attrrep[1];
+#endif
+#ifdef TEST_ICCCM
+    XCBInternAtomCookie atom[2];
+    XCBInternAtomRep *atomrep[2];
+#endif
+#ifdef TEST_THREADS
+    pthread_t event_thread;
+#endif
+    int screen_num;
+
+    c = XCBConnect(0, &screen_num);
+    root = XCBAuxGetScreen(c, screen_num);
+
+#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 = XCBWINDOWNew(c);
+#else
+    window = 0; /* should be an invalid ID */
+#endif
+
+    mask |= XCBCWBackPixel;
+    values[0] = root->white_pixel;
+
+    mask |= XCBCWBorderPixel;
+    values[1] = root->black_pixel;
+
+    mask |= XCBCWBackingStore;
+    values[2] = Always;
+
+    mask |= XCBCWOverrideRedirect;
+    values[3] = 0;
+
+    mask |= XCBCWEventMask;
+    values[4] = ButtonReleaseMask | ExposureMask | StructureNotifyMask
+        | EnterWindowMask | LeaveWindowMask;
+
+    mask |= XCBCWDontPropagate;
+    values[5] = ButtonPressMask;
+
+    XCBCreateWindow(c, /* depth */ 0,
+        window, root->root,
+        /* x */ 20, /* y */ 200, /* width */ 150, /* height */ 150,
+        /* border_width */ 10, /* class */ InputOutput,
+        /* visual */ root->root_visual, mask, values);
+#ifdef TEST_ICCCM
+    atom[0] = XCBInternAtom(c, 0, sizeof("WM_PROTOCOLS")-1, "WM_PROTOCOLS");
+    atom[1] = XCBInternAtom(c, 0, sizeof("WM_DELETE_WINDOW")-1, "WM_DELETE_WINDOW");
+    atomrep[1] = XCBInternAtomReply(c, atom[1], 0);
+    atomrep[0] = XCBInternAtomReply(c, atom[0], 0);
+    {
+        XCBATOM XA_WM_NAME = { 39 };
+        XCBATOM XA_STRING = { 31 };
+        XCBChangeProperty(c, PropModeReplace, window, XA_WM_NAME, XA_STRING, 8, strlen(argv[0]), argv[0]);
+    }
+    if(atomrep[0] && atomrep[1])
+    {
+        XCBATOM WM_PROTOCOLS = atomrep[0]->atom;
+        XCBATOM WM_DELETE_WINDOW = atomrep[1]->atom;
+        XCBATOM XA_ATOM = { 4 };
+        XCBChangeProperty(c, PropModeReplace, window, WM_PROTOCOLS, XA_ATOM, 32, 1, &WM_DELETE_WINDOW);
+    }
+    free(atomrep[0]);
+    free(atomrep[1]);
+#endif
+    try_events(c);
+
+    XCBMapWindow(c, window);
+    XCBFlush(c);
+
+    /* Send off a collection of requests */
+#ifdef TEST_GET_WINDOW_ATTRIBUTES
+    attr[0] = XCBGetWindowAttributes(c, window);
+#endif
+#ifdef TEST_GET_GEOMETRY
+    d.window = root->root;
+    geom[0] = XCBGetGeometry(c, d);
+    d.window = window;
+    geom[1] = XCBGetGeometry(c, d);
+#endif
+#ifdef TEST_QUERY_TREE
+# ifdef SUPERVERBOSE /* this produces a lot of output :) */
+    tree[0] = XCBQueryTree(c, root->root);
+# endif
+    tree[1] = XCBQueryTree(c, window);
+#endif
+
+    /* Start reading replies and possibly events */
+#ifdef TEST_GET_GEOMETRY
+    geomrep[0] = XCBGetGeometryReply(c, geom[0], 0);
+    formatGetGeometryReply(root->root, geomrep[0]);
+    free(geomrep[0]);
+#endif
+
+#ifdef TEST_QUERY_TREE
+# ifdef SUPERVERBOSE /* this produces a lot of output :) */
+    treerep[0] = XCBQueryTreeReply(c, tree[0], 0);
+    formatQueryTreeReply(root->root, treerep[0]);
+    free(treerep[0]);
+# endif
+#endif
+
+#ifdef TEST_GET_GEOMETRY
+    geomrep[1] = XCBGetGeometryReply(c, geom[1], 0);
+    formatGetGeometryReply(window, geomrep[1]);
+    free(geomrep[1]);
+#endif
+
+    try_events(c);
+
+    /* Mix in some more requests */
+#ifdef TEST_QUERY_TREE
+    treerep[1] = XCBQueryTreeReply(c, tree[1], 0);
+    formatQueryTreeReply(window, treerep[1]);
+
+    if(treerep[1] && treerep[1]->parent.xid && treerep[1]->parent.xid != root->root.xid)
+    {
+        tree[2] = XCBQueryTree(c, treerep[1]->parent);
+
+# ifdef TEST_GET_GEOMETRY
+        d.window = treerep[1]->parent;
+        geom[2] = XCBGetGeometry(c, d);
+        geomrep[2] = XCBGetGeometryReply(c, geom[2], 0);
+        formatGetGeometryReply(treerep[1]->parent, geomrep[2]);
+        free(geomrep[2]);
+# endif
+
+        treerep[2] = XCBQueryTreeReply(c, tree[2], 0);
+        formatQueryTreeReply(treerep[1]->parent, treerep[2]);
+        free(treerep[2]);
+    }
+
+    free(treerep[1]);
+#endif
+
+    try_events(c);
+
+    /* 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] = XCBGetWindowAttributesReply(c, attr[0], 0);
+    formatGetWindowAttributesReply(window, attrrep[0]);
+    free(attrrep[0]);
+#endif
+#endif
+
+#ifdef TEST_THREADS
+    pthread_join(event_thread, 0);
+#else
+    wait_events(c);
+#endif
+
+    exit(0);
+    /*NOTREACHED*/
+}
+
+int show_event(XCBGenericEvent *e)
+{
+    int ret = 1;
+    if(!formatEvent(e))
+        return 0;
+
+    if(e->response_type == XCBButtonRelease)
+        ret = 0; /* They clicked, therefore, we're done. */
+    free(e);
+    return ret;
+}
+
+void try_events(XCBConnection *c)
+{
+    XCBGenericEvent *e;
+    while((e = XCBPollForEvent(c, 0)) && show_event(e))
+        /* empty statement */ ;
+}
+
+void wait_events(XCBConnection *c)
+{
+    XCBGenericEvent *e;
+#ifdef TEST_THREADS
+# ifdef VERBOSE
+    printf("wait_events() thread ID: %ld\n", pthread_self());
+# endif
+#endif
+    while((e = XCBWaitForEvent(c)) && show_event(e))
+        /* empty statement */ ;
+}
diff --git a/rendertest.c b/rendertest.c
new file mode 100644 (file)
index 0000000..9a2840d
--- /dev/null
@@ -0,0 +1,561 @@
+
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/xcb_aux.h>
+#include <X11/XCB/render.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * FUNCTION PROTOTYPES
+ */
+void print_version_info(XCBRenderQueryVersionRep *reply);
+int print_formats_info(XCBRenderQueryPictFormatsRep *reply);
+int draw_window(XCBConnection *conn, XCBRenderQueryPictFormatsRep *reply);
+XCBRenderPICTFORMAT get_pictformat_from_visual(XCBRenderQueryPictFormatsRep *reply, XCBVISUALID visual);
+XCBRenderPICTFORMINFO *get_pictforminfo(XCBRenderQueryPictFormatsRep *reply, XCBRenderPICTFORMINFO *query);
+
+XCBConnection   *c;
+XCBRenderPICTFORMAT pf;
+
+XCBRenderFIXED make_fixed(INT16 i, INT16 f)
+{
+    return (i << 16) | (f & 0xffff);
+}
+
+void print_version_info(XCBRenderQueryVersionRep *reply)
+{
+    
+    fprintf(stdout, "Render Version: %ld.%ld\n", reply->major_version, 
+            reply->minor_version);
+}
+
+int print_formats_info(XCBRenderQueryPictFormatsRep *reply)
+{
+    XCBRenderPICTFORMINFO *first_forminfo;
+    int num_formats;
+    int num_screens;
+    int num_depths;
+    int num_visuals;
+    XCBRenderPICTFORMINFOIter forminfo_iter;
+    XCBRenderPICTSCREENIter     screen_iter;
+    
+    forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
+    screen_iter =  XCBRenderQueryPictFormatsScreensIter(reply);
+
+    fprintf(stdout, "Number of PictFormInfo iterations: %d\n", forminfo_iter.rem);
+
+    num_formats = reply->num_formats;
+    first_forminfo = forminfo_iter.data;
+    pf = first_forminfo->id;
+    while(forminfo_iter.rem)
+    {
+        XCBRenderPICTFORMINFO *forminfo = (XCBRenderPICTFORMINFO *)forminfo_iter.data;
+
+        fprintf(stdout, "PICTFORMINFO #%d\n", 1 + num_formats - forminfo_iter.rem);
+        fprintf(stdout, "    PICTFORMAT ID:          %ld\n", forminfo->id.xid);
+        fprintf(stdout, "    PICTFORMAT Type:        %d\n", forminfo->type);
+        fprintf(stdout, "    PICTFORMAT Depth:       %d\n", forminfo->depth);
+        fprintf(stdout, "        Direct RedShift:    %d\n", forminfo->direct.red_shift);
+        fprintf(stdout, "        Direct RedMask:     %d\n", forminfo->direct.red_mask);
+        fprintf(stdout, "        Direct BlueShift:   %d\n", forminfo->direct.blue_shift);
+        fprintf(stdout, "        Direct BlueMask:    %d\n", forminfo->direct.blue_mask);
+        fprintf(stdout, "        Direct GreenShift:  %d\n", forminfo->direct.green_shift);
+        fprintf(stdout, "        Direct GreenMask:   %d\n", forminfo->direct.green_mask);
+        fprintf(stdout, "        Direct AlphaShift:  %d\n", forminfo->direct.alpha_shift);
+        fprintf(stdout, "        Direct AlphaMask:   %d\n", forminfo->direct.alpha_mask);
+        fprintf(stdout, "\n");
+        XCBRenderPICTFORMINFONext(&forminfo_iter);
+    }
+
+    num_screens = reply->num_screens;
+    while(screen_iter.rem)
+    {
+        XCBRenderPICTDEPTHIter depth_iter;
+        XCBRenderPICTSCREEN *cscreen = screen_iter.data;
+        
+        fprintf(stdout, "Screen #%d\n", 1 + num_screens - screen_iter.rem);
+        fprintf(stdout, "    Depths for this screen:    %ld\n", cscreen->num_depths);
+        fprintf(stdout, "    Fallback PICTFORMAT:       %ld\n", cscreen->fallback.xid);
+        depth_iter = XCBRenderPICTSCREENDepthsIter(cscreen);
+
+        num_depths = cscreen->num_depths;
+        while(depth_iter.rem)
+        {
+            XCBRenderPICTVISUALIter    visual_iter;
+            XCBRenderPICTDEPTH *cdepth = depth_iter.data;
+
+            fprintf(stdout, "    Depth #%d\n", 1 + num_depths - depth_iter.rem);
+            fprintf(stdout, "        Visuals for this depth:    %d\n", cdepth->num_visuals);
+            fprintf(stdout, "        Depth:                     %d\n", cdepth->depth);
+            visual_iter = XCBRenderPICTDEPTHVisualsIter(cdepth);
+
+            num_visuals = cdepth->num_visuals;
+            while(visual_iter.rem)
+            {
+                XCBRenderPICTVISUAL *cvisual = visual_iter.data;
+                
+                fprintf(stdout, "        Visual #%d\n", 1 + num_visuals - visual_iter.rem);
+                fprintf(stdout, "            VISUALID:      %ld\n", cvisual->visual.id);
+                fprintf(stdout, "            PICTFORMAT:    %ld\n", cvisual->format.xid);
+                XCBRenderPICTVISUALNext(&visual_iter);
+            }
+            XCBRenderPICTDEPTHNext(&depth_iter);
+        }
+        XCBRenderPICTSCREENNext(&screen_iter);
+    }
+    return 0;
+}
+
+int draw_window(XCBConnection *conn, XCBRenderQueryPictFormatsRep *reply)
+{
+    XCBWINDOW          window;
+    XCBDRAWABLE        window_drawable, tmp, root_drawable;
+    XCBPIXMAP          surfaces[4], alpha_surface;
+    XCBRenderPICTFORMAT      alpha_mask_format, window_format, surface_format, no_format = {0};
+    XCBRenderPICTURE         window_pict, pict_surfaces[4], alpha_pict, 
+                        no_picture = {0}, root_picture;
+    XCBRenderPICTFORMINFO    *forminfo_ptr, *alpha_forminfo_ptr, query;
+    CARD32          value_mask, value_list[4];
+    XCBRECTANGLE       pict_rect[1], window_rect;
+    XCBRenderCOLOR           pict_color[4], back_color, alpha_color;
+    XCBSCREEN          *root;
+    XCBRenderTRAP            traps[4];
+    XCBRenderTRIANGLE        triangles[4];
+    XCBRenderPOINTFIX        tristrips[9];
+    XCBRenderPOINTFIX        trifans[9];
+    int index;
+
+    root = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c)).data;
+    root_drawable.window = root->root;
+   
+    /* Setting query so that it will search for an 8 bit alpha surface. */
+    query.id.xid = 0;
+    query.type = XCBRenderPictTypeDirect;
+    query.depth = 8;
+    query.direct.red_mask = 0;
+    query.direct.green_mask = 0;
+    query.direct.blue_mask = 0;
+    query.direct.alpha_mask = 255;
+
+    /* Get the XCBRenderPICTFORMAT associated with the window. */
+    window_format = get_pictformat_from_visual(reply, root->root_visual);
+
+    /* Get the XCBRenderPICTFORMAT we will use for the alpha mask */
+    alpha_forminfo_ptr = get_pictforminfo(reply, &query);
+    alpha_mask_format.xid = alpha_forminfo_ptr->id.xid;
+    
+    /* resetting certain parts of query to search for the surface format */
+    query.depth = 32;
+    query.direct.alpha_mask = 0;
+  
+    /* Get the surface forminfo and XCBRenderPICTFORMAT */
+    forminfo_ptr = get_pictforminfo(reply, &query);
+    surface_format.xid = forminfo_ptr->id.xid;
+    
+    /* assign XIDs to all of the drawables and pictures */
+    for(index = 0; index < 4; index++)
+    {
+        surfaces[index] = XCBPIXMAPNew(conn);
+        pict_surfaces[index] = XCBRenderPICTURENew(conn);
+    }
+    alpha_surface = XCBPIXMAPNew(conn);
+    alpha_pict = XCBRenderPICTURENew(conn);
+    window = XCBWINDOWNew(conn);
+    window_pict = XCBRenderPICTURENew(conn);
+    window_drawable.window = window;
+    root_picture = XCBRenderPICTURENew(conn);
+    
+    /* Here we will create the pixmaps that we will use */
+    for(index = 0; index < 4; index++)
+    {
+        surfaces[index] = XCBPIXMAPNew(conn);
+        XCBCreatePixmap(conn, 32, surfaces[index], root_drawable, 600, 600);
+    }
+    alpha_surface = XCBPIXMAPNew(conn);
+    XCBCreatePixmap(conn, 8, alpha_surface, root_drawable, 600, 600);
+    
+    /* initialize the value list */
+    value_mask = XCBCWEventMask;
+    value_list[0] = XCBExpose;
+    
+    /* Create the window */
+    XCBCreateWindow(conn, /* XCBConnection */
+            0,  /* depth, 0 means it will copy it from the parent */
+            window, root_drawable.window, /* window and parent */
+            0, 0,   /* x and y */
+            600, 600,   /* width and height */
+            0,  /* border width */
+            InputOutput,    /* class */
+            root->root_visual,   /* XCBVISUALID */
+            value_mask, value_list); /* LISTofVALUES */
+    
+    /* 
+     * Create the pictures 
+     */
+    value_mask = 1<<0; /* repeat (still needs to be added to xcb_render.m4) */
+    value_list[0] = 1;
+
+    XCBRenderCreatePicture(conn, root_picture, root_drawable, window_format,
+            value_mask, value_list);
+    XCBRenderCreatePicture(conn, window_pict, window_drawable, window_format,
+            value_mask, value_list);
+    tmp.pixmap = alpha_surface;
+    XCBRenderCreatePicture(conn, alpha_pict, tmp, alpha_mask_format,
+            value_mask, value_list);
+    for(index = 0; index < 4; index++)
+    {
+        tmp.pixmap = surfaces[index];
+        XCBRenderCreatePicture(conn, pict_surfaces[index], tmp, surface_format,
+                value_mask, value_list);
+    }
+
+    /* 
+     * initialize the rectangles
+     */
+    window_rect.x = 0;
+    window_rect.y = 0;
+    window_rect.width = 600;
+    window_rect.height = 600;
+
+    pict_rect[0].x = 0;
+    pict_rect[0].y = 0;
+    pict_rect[0].width = 600;
+    pict_rect[0].height = 600;
+   
+    /* 
+     * initialize the colors
+     */
+    back_color.red = 0xffff;
+    back_color.green = 0xffff;
+    back_color.blue = 0xffff;
+    back_color.alpha = 0xffff;
+   
+    pict_color[0].red = 0x5fff;
+    pict_color[0].green = 0x0000;
+    pict_color[0].blue = 0x0000;
+    pict_color[0].alpha = 0x5fff;
+    
+    pict_color[1].red = 0x0000;
+    pict_color[1].green = 0x5fff;
+    pict_color[1].blue = 0x0000;
+    pict_color[1].alpha = 0x5fff;
+
+    pict_color[2].red = 0x0000;
+    pict_color[2].green = 0x0000;
+    pict_color[2].blue = 0x5fff;
+    pict_color[2].alpha = 0x5fff;
+
+    pict_color[3].red = 0x0000;
+    pict_color[3].green = 0x0000;
+    pict_color[3].blue = 0x5fff;
+    pict_color[3].alpha = 0x5fff;
+
+    alpha_color.red = 0x0000;
+    alpha_color.green = 0x0000;
+    alpha_color.blue = 0x0000;
+    alpha_color.alpha = 0xffff;
+
+    /* Create the trapeziod dimensions */
+    traps[0].top = make_fixed(300, 32000);
+    traps[0].bottom = make_fixed(416, 0);
+    traps[0].left.p1.y = make_fixed(250, 0);
+    traps[0].left.p1.x = make_fixed(300, 0);
+    traps[0].left.p2.y = make_fixed(500, 0);
+    traps[0].left.p2.x = make_fixed(100, 0);
+    traps[0].right.p1.y = make_fixed(250, 0);
+    traps[0].right.p1.x = make_fixed(300, 0);
+    traps[0].right.p2.y = make_fixed(505, 6000);
+    traps[0].right.p2.x = make_fixed(456, 512);
+
+    /* Create the triangle dimensions */
+    triangles[0].p1.x = make_fixed(100, 40000);
+    triangles[0].p1.y = make_fixed(100, 0);
+    triangles[0].p2.x = make_fixed(400, 0);
+    triangles[0].p2.y = make_fixed(150, 30000);
+    triangles[0].p3.x = make_fixed(30, 0);
+    triangles[0].p3.y = make_fixed(456, 0);
+
+    /* Create the tristrip dimensions */
+    tristrips[0].x = make_fixed(400, 0);
+    tristrips[0].y = make_fixed(50, 0);
+    tristrips[1].x = make_fixed(436, 0);
+    tristrips[1].y = make_fixed(50, 0);
+    tristrips[2].x = make_fixed(398, 0);
+    tristrips[2].y = make_fixed(127, 0);
+    tristrips[3].x = make_fixed(450, 0);
+    tristrips[3].y = make_fixed(120, 0);
+    tristrips[4].x = make_fixed(450, 0);
+    tristrips[4].y = make_fixed(180, 0);
+    tristrips[5].x = make_fixed(503, 0);
+    tristrips[5].y = make_fixed(124, 0);
+    tristrips[6].x = make_fixed(500, 0);
+    tristrips[6].y = make_fixed(217, 0);
+    tristrips[7].x = make_fixed(542, 0);
+    tristrips[7].y = make_fixed(237, 0);
+    tristrips[8].x = make_fixed(501, 0);
+    tristrips[8].y = make_fixed(250, 0);
+
+    /* Create the trifan dimensions */
+    trifans[0].x = make_fixed(424, 0);
+    trifans[0].y = make_fixed(415, 0);
+    trifans[1].x = make_fixed(375, 0);
+    trifans[1].y = make_fixed(355, 0);
+    trifans[2].x = make_fixed(403, 0);
+    trifans[2].y = make_fixed(350, 0);
+    trifans[3].x = make_fixed(430, 0);
+    trifans[3].y = make_fixed(380, 0);
+    trifans[4].x = make_fixed(481, 0);
+    trifans[4].y = make_fixed(400, 0);
+    trifans[5].x = make_fixed(475, 0);
+    trifans[5].y = make_fixed(437, 0);
+    trifans[6].x = make_fixed(430, 0);
+    trifans[6].y = make_fixed(444, 0);
+    trifans[7].x = make_fixed(400, 0);
+    trifans[7].y = make_fixed(430, 0);
+
+    /* 
+     * Map the window
+     */
+    XCBMapWindow(conn, window);
+    
+    /*
+     * Play around with Render
+     */
+
+    XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, alpha_pict, alpha_color, 1, pict_rect);
+    XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[0], pict_color[0], 1, pict_rect);
+    XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[1], pict_color[1], 1, pict_rect);
+    XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[2], pict_color[2], 1, pict_rect);
+    XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[3], pict_color[3], 1, pict_rect);
+
+    XCBFlush(conn);
+    sleep(1);
+
+    XCBRenderFillRectangles(conn, XCBRenderPictOpOver, window_pict, back_color, 1, &window_rect);
+
+    XCBFlush(conn);
+    sleep(1);
+
+
+    /* Composite the first pict_surface onto the window picture */
+    XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[0], no_picture /* alpha_pict */, window_pict,
+            0, 0, 0, 0, 200, 200,
+            400, 400);
+    XCBFlush(conn);
+    sleep(1);
+/*
+    XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[0], alpha_pict, window_pict,
+            0, 0, 0, 0, 0, 0,
+            200, 200);
+    XCBFlush(conn);
+    sleep(1);
+*/
+    XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[1], no_picture /* alpha_pict */, window_pict,
+            0, 0, 0, 0, 0, 0,
+            400, 400);
+    XCBFlush(conn);
+    sleep(1);
+    
+    XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[2], no_picture /* alpha_pict */, window_pict,
+            0, 0, 0, 0, 200, 0,
+            400, 400);
+    XCBFlush(conn);
+    sleep(1);
+    
+    XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[3],  no_picture /* alpha_pict */, window_pict,
+            0, 0, 0, 0, 0, 200,
+            400, 400);
+    XCBFlush(conn);
+    sleep(1);
+
+    XCBRenderTrapezoids(conn, XCBRenderPictOpOver, pict_surfaces[0], window_pict, alpha_mask_format, 0, 0, 1, &traps[0]);
+    XCBFlush(conn);
+    sleep(1);
+
+    XCBRenderTriangles(conn, XCBRenderPictOpOver, pict_surfaces[1], window_pict, no_format, 0, 0, 1, &triangles[0]);
+    XCBFlush(conn);
+    sleep(1);
+    
+    XCBRenderTriStrip(conn, XCBRenderPictOpOver, pict_surfaces[2], window_pict, no_format, 0, 0, 9, &tristrips[0]);
+    XCBFlush(conn);
+    sleep(1);
+    
+    XCBRenderTriFan(conn, XCBRenderPictOpOver, pict_surfaces[3], window_pict, no_format, 0, 0, 8, &trifans[0]);
+    XCBFlush(conn);
+    sleep(2);
+    
+    
+    /* Free up all of the resources we used */
+    for(index = 0; index < 4; index++)
+    {
+        XCBFreePixmap(conn, surfaces[index]);
+        XCBRenderFreePicture(conn, pict_surfaces[index]);
+    }
+    XCBFreePixmap(conn, alpha_surface);
+    XCBRenderFreePicture(conn, alpha_pict);
+    XCBRenderFreePicture(conn, window_pict);
+    XCBRenderFreePicture(conn, root_picture);
+   
+    /* sync up and leave the function */
+    XCBSync(conn, 0);
+    return 0;
+}
+
+
+/**********************************************************
+ * This function searches through the reply for a 
+ * PictVisual who's XCBVISUALID is the same as the one
+ * specified in query. The function will then return the
+ * XCBRenderPICTFORMAT from that PictVIsual structure. 
+ * This is useful for getting the XCBRenderPICTFORMAT that is
+ * the same visual type as the root window.
+ **********************************************************/
+XCBRenderPICTFORMAT get_pictformat_from_visual(XCBRenderQueryPictFormatsRep *reply, XCBVISUALID query)
+{
+    XCBRenderPICTSCREENIter screen_iter;
+    XCBRenderPICTSCREEN    *cscreen;
+    XCBRenderPICTDEPTHIter  depth_iter;
+    XCBRenderPICTDEPTH     *cdepth;
+    XCBRenderPICTVISUALIter visual_iter; 
+    XCBRenderPICTVISUAL    *cvisual;
+    XCBRenderPICTFORMAT  return_value;
+    
+    screen_iter = XCBRenderQueryPictFormatsScreensIter(reply);
+
+    while(screen_iter.rem)
+    {
+        cscreen = screen_iter.data;
+        
+        depth_iter = XCBRenderPICTSCREENDepthsIter(cscreen);
+        while(depth_iter.rem)
+        {
+            cdepth = depth_iter.data;
+
+            visual_iter = XCBRenderPICTDEPTHVisualsIter(cdepth);
+            while(visual_iter.rem)
+            {
+                cvisual = visual_iter.data;
+
+                if(cvisual->visual.id == query.id)
+                {
+                    return cvisual->format;
+                }
+                XCBRenderPICTVISUALNext(&visual_iter);
+            }
+            XCBRenderPICTDEPTHNext(&depth_iter);
+        }
+        XCBRenderPICTSCREENNext(&screen_iter);
+    }
+    return_value.xid = 0;
+    return return_value;
+}
+
+XCBRenderPICTFORMINFO *get_pictforminfo(XCBRenderQueryPictFormatsRep *reply, XCBRenderPICTFORMINFO *query)
+{
+    XCBRenderPICTFORMINFOIter forminfo_iter;
+    
+    forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
+
+    while(forminfo_iter.rem)
+    {
+        XCBRenderPICTFORMINFO *cformat;
+        cformat  = forminfo_iter.data;
+        XCBRenderPICTFORMINFONext(&forminfo_iter);
+
+        if( (query->id.xid != 0) && (query->id.xid != cformat->id.xid) )
+        {
+            continue;
+        }
+
+        if(query->type != cformat->type)
+        {
+            continue;
+        }
+        
+        if( (query->depth != 0) && (query->depth != cformat->depth) )
+        {
+            continue;
+        }
+        
+        if( (query->direct.red_mask  != 0)&& (query->direct.red_mask != cformat->direct.red_mask))
+        {
+            continue;
+        }
+        
+        if( (query->direct.green_mask != 0) && (query->direct.green_mask != cformat->direct.green_mask))
+        {
+            continue;
+        }
+        
+        if( (query->direct.blue_mask != 0) && (query->direct.blue_mask != cformat->direct.blue_mask))
+        {
+            continue;
+        }
+        
+        if( (query->direct.alpha_mask != 0) && (query->direct.alpha_mask != cformat->direct.alpha_mask))
+        {
+            continue;
+        }
+        
+        /* This point will only be reached if the pict format   *
+         * matches what the user specified                      */
+        return cformat; 
+    }
+    
+    return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+    XCBRenderQueryVersionCookie version_cookie;
+    XCBRenderQueryVersionRep    *version_reply;
+    XCBRenderQueryPictFormatsCookie formats_cookie;
+    XCBRenderQueryPictFormatsRep *formats_reply;
+    XCBRenderPICTFORMAT  rootformat;
+    XCBSCREEN *root;
+    int screen_num;
+    
+    XCBRenderPICTFORMINFO  forminfo_query, *forminfo_result;
+    
+    c = XCBConnect(0, &screen_num);
+    root = XCBAuxGetScreen(c, screen_num);
+    
+    version_cookie = XCBRenderQueryVersion(c, (CARD32)0, (CARD32)3);
+    version_reply = XCBRenderQueryVersionReply(c, version_cookie, 0);
+
+    print_version_info(version_reply);
+    
+    formats_cookie = XCBRenderQueryPictFormats(c);
+    formats_reply = XCBRenderQueryPictFormatsReply(c, formats_cookie, 0);
+
+    draw_window(c, formats_reply);
+    
+    print_formats_info(formats_reply);
+   
+    forminfo_query.id.xid = 0;
+    forminfo_query.type = XCBRenderPictTypeDirect;
+    forminfo_query.depth = 8;
+    forminfo_query.direct.red_mask = 0;
+    forminfo_query.direct.green_mask = 0;
+    forminfo_query.direct.blue_mask = 0;
+    forminfo_query.direct.alpha_mask = 255;
+    
+    forminfo_result = get_pictforminfo(formats_reply, &forminfo_query);
+    fprintf(stdout, "\n***** found PICTFORMAT:  %ld *****\n",
+            forminfo_result->id.xid);
+    rootformat = get_pictformat_from_visual(formats_reply, root->root_visual);
+    fprintf(stdout, "\n***** found root PICTFORMAT:   %ld *****\n", rootformat.xid);
+   
+#if 0
+    draw_window(c, formats_reply);
+#endif
+    
+    /* It's very important to free the replys. We don't want memory leaks. */
+    free(version_reply);
+    free(formats_reply);
+
+    XCBDisconnect(c);
+
+    exit(0);
+}
diff --git a/reply_formats.c b/reply_formats.c
new file mode 100644 (file)
index 0000000..7920f3f
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.  See the file COPYING in this directory
+ * for licensing information.
+ */
+
+#include <stdio.h>
+#include "reply_formats.h"
+
+#define WINFMT "0x%08x"
+
+int formatGetWindowAttributesReply(XCBWINDOW wid, XCBGetWindowAttributesRep *reply)
+{
+    if(!reply)
+    {
+        fprintf(stderr, "Failed to get attributes for window " WINFMT ".\n",
+            (unsigned int) wid.xid);
+        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.xid,
+        reply->backing_store,
+        (unsigned int) reply->visual.id,
+        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.xid,
+        (unsigned int) reply->all_event_masks,
+        (unsigned int) reply->your_event_mask,
+        reply->do_not_propagate_mask);
+
+    fflush(stdout);
+    return 1;
+}
+
+int formatGetGeometryReply(XCBWINDOW wid, XCBGetGeometryRep *reply)
+{
+    if(!reply)
+    {
+        fprintf(stderr, "Failed to get geometry for window " WINFMT ".\n",
+            (unsigned int) wid.xid);
+        return 0;
+    }
+
+    printf("Geometry for window " WINFMT ": %dx%d%+d%+d\n",
+        (unsigned int) wid.xid,
+        reply->width,
+        reply->height,
+        reply->x,
+        reply->y);
+
+    fflush(stdout);
+    return 1;
+}
+
+int formatQueryTreeReply(XCBWINDOW wid, XCBQueryTreeRep *reply)
+{
+    int i;
+
+    if(!reply)
+    {
+        fprintf(stderr, "Failed to query tree for window " WINFMT ".\n",
+            (unsigned int) wid.xid);
+        return 0;
+    }
+
+    printf("Window " WINFMT " has parent " WINFMT ", root " WINFMT ", and %d children%c\n",
+        (unsigned int) wid.xid,
+        (unsigned int) reply->parent.xid,
+        (unsigned int) reply->root.xid,
+        (unsigned int) reply->children_len,
+        reply->children_len ? ':' : '.');
+
+    for(i = 0; i < reply->children_len; ++i)
+        printf("    window " WINFMT "\n",
+            (unsigned int) XCBQueryTreeChildren(reply)[i].xid);
+
+    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(XCBGenericEvent *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 XCBKeymapNotify:
+        printf("Event %s%s.\n",
+            labelEvent[e->response_type],
+            labelSendEvent[sendEvent]);
+        break;
+    }
+
+    fflush(stdout);
+    return 1;
+}
diff --git a/reply_formats.h b/reply_formats.h
new file mode 100644 (file)
index 0000000..431eca1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.  See the file COPYING in this directory
+ * for licensing information.
+ */
+
+#ifndef REPLY_FORMATS_H
+#define REPLY_FORMATS_H
+
+#include <X11/XCB/xcb.h>
+
+int formatGetWindowAttributesReply(XCBWINDOW wid, XCBGetWindowAttributesRep *reply);
+int formatGetGeometryReply(XCBWINDOW wid, XCBGetGeometryRep *reply);
+int formatQueryTreeReply(XCBWINDOW wid, XCBQueryTreeRep *reply);
+int formatEvent(XCBGenericEvent *e);
+
+#endif /* REPLY_FORMATS_H */
diff --git a/tests/.cvsignore b/tests/.cvsignore
new file mode 100644 (file)
index 0000000..4d30c20
--- /dev/null
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+.deps
+lissajoux
+julia
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..435eb98
--- /dev/null
@@ -0,0 +1,16 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = $(XCBAUX_CFLAGS) $(XCBIMAGE_CFLAGS)
+
+bin_PROGRAMS = julia lissajoux flames
+
+julia_LDADD = $(XCBAUX_LIBS) $(XCBIMAGE_LIBS)
+julia_SOURCES = julia.c
+
+lissajoux_LDADD = $(XCBAUX_LIBS) $(XCBIMAGE_LIBS) -lm
+lissajoux_SOURCES =lissajoux.c
+
+flames_CFLAGS = -O3
+flames_LDADD = $(XCBAUX_LIBS) $(XCBIMAGE_LIBS) $(XCBICCCM_LIBS)
+flames_SOURCES = flames.c
diff --git a/tests/flames.c b/tests/flames.c
new file mode 100644 (file)
index 0000000..fb1cf2e
--- /dev/null
@@ -0,0 +1,482 @@
+/*****************************************************************************/
+/*                                  XCB Flame                                */
+/*****************************************************************************/
+/* Originally By:                                                            */
+/*     The Rasterman (Carsten Haitzler)                                      */
+/*      Copyright (C) 1996                                                   */
+/*****************************************************************************/
+/* XcB port:                                                                 */
+/*     d'Oursse (Vincent TORRI), 2006                                        */
+/*****************************************************************************/
+/* This code is Freeware. You may copy it, modify it or do with it as you    */
+/* please, but you may not claim copyright on any code wholly or partly      */
+/* based on this code. I accept no responisbility for any consequences of    */
+/* using this code, be they proper or otherwise.                             */
+/*****************************************************************************/
+/* Okay, now all the legal mumbo-jumbo is out of the way, I will just say    */
+/* this: enjoy this program, do with it as you please and watch out for more */
+/* code releases from The Rasterman running under X... the only way to code. */
+/*****************************************************************************/
+
+/* standard library */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <assert.h>
+#include <string.h>
+
+#include <X11/X.h>
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+#include <X11/XCB/xcb_aux.h>
+#include <X11/XCB/xcb_image.h>
+#include <X11/XCB/xcb_icccm.h>
+
+/* some defines for the flame */
+#define HSPREAD 26
+#define VSPREAD 78
+#define VARIANCE 5
+#define VARTREND 2
+#define RESIDUAL 68
+
+/* default width and height of the window */
+#define BG_W 256
+#define BG_H 256
+
+#define IMAX 300
+
+typedef struct
+{
+  struct
+  {
+    XCBConnection *c;
+    XCBDRAWABLE    draw;
+    XCBDRAWABLE    pixmap;
+    XCBCOLORMAP    cmap;
+    CARD8          depth;
+    XCBGCONTEXT    gc;
+  }xcb;
+  
+  /* the palette */
+  unsigned int  pal[IMAX];
+  unsigned int *im;
+  int           ims;
+  
+  /* the flame arrays */
+  int           ws;
+  unsigned int *flame;
+  unsigned int *flame2;
+  
+}flame;
+
+static void title_set (flame *f, const char *title);
+static int  ilog2 (unsigned int n);
+static void flame_set_palette (flame *f);
+static void flame_set_flame_zero (flame *f);
+static void flame_set_random_flame_base (flame *f);
+static void flame_modify_flame_base (flame *f);
+static void flame_process_flame (flame *f);
+static void flame_draw_flame (flame *f);
+
+flame *
+flame_init ()
+{
+  flame       *f;
+  XCBSCREEN   *screen;
+  XCBGCONTEXT  gc = { 0 };
+  int          screen_nbr;
+  CARD32       mask;
+  CARD32       values[2];
+  int          size;
+  int          flame_width;
+  int          flame_height;
+  XCBRECTANGLE rect_coord = { 0, 0, BG_W, BG_H};
+
+  f = (flame *)malloc (sizeof (flame));
+  if (!f)
+    return NULL;
+
+  f->xcb.c = XCBConnect (NULL, &screen_nbr);
+  if (!f->xcb.c)
+    {
+      free (f);
+      return NULL;
+    }
+  screen = XCBAuxGetScreen (f->xcb.c, screen_nbr);
+
+  f->xcb.draw.window = screen->root;
+  f->xcb.gc = XCBGCONTEXTNew (f->xcb.c);
+  mask = GCForeground | GCGraphicsExposures;
+  values[0] = screen->black_pixel;
+  values[1] = 0; /* no graphics exposures */
+  XCBCreateGC (f->xcb.c, f->xcb.gc, f->xcb.draw, mask, values);
+
+  gc = XCBGCONTEXTNew (f->xcb.c);
+  mask = GCForeground | GCGraphicsExposures;
+  values[0] = screen->white_pixel;
+  values[1] = 0; /* no graphics exposures */
+  XCBCreateGC (f->xcb.c, gc, f->xcb.draw, mask, values);
+
+  f->xcb.depth = XCBAuxGetDepth (f->xcb.c, screen);
+  mask = XCBCWBackPixel | XCBCWEventMask;
+  values[0] = screen->white_pixel;
+  values[1] = ExposureMask | ButtonPressMask;
+  f->xcb.draw.window = XCBWINDOWNew (f->xcb.c);
+  XCBCreateWindow (f->xcb.c, f->xcb.depth,
+                  f->xcb.draw.window,
+                  screen->root,
+                  0, 0, BG_W, BG_H,
+                  0,
+                  InputOutput,
+                  screen->root_visual,
+                  mask, values);
+  title_set (f, "XCB Flames");
+  
+  f->xcb.pixmap.pixmap = XCBPIXMAPNew (f->xcb.c);
+  XCBCreatePixmap (f->xcb.c, f->xcb.depth,
+                  f->xcb.pixmap.pixmap, f->xcb.draw,
+                  BG_W, BG_H);
+  XCBPolyFillRectangle(f->xcb.c, f->xcb.pixmap, gc, 1, &rect_coord);
+
+  XCBMapWindow (f->xcb.c, f->xcb.draw.window);
+  XCBSync (f->xcb.c, 0);
+
+  f->xcb.cmap = XCBCOLORMAPNew (f->xcb.c);
+  XCBCreateColormap (f->xcb.c,
+                    AllocNone,
+                    f->xcb.cmap,
+                    f->xcb.draw.window,
+                    screen->root_visual);
+
+  /* Allocation of the flame arrays */
+  flame_width  = BG_W >> 1;
+  flame_height = BG_H >> 1;
+  f->ws = ilog2 (flame_width);
+  size = (1 << f->ws) * flame_height * sizeof (unsigned int);
+  f->flame = (unsigned int *)malloc (size);
+  if (! f->flame)
+    {
+      XCBDisconnect (f->xcb.c);
+      free (f);
+      return NULL;
+    }
+  f->flame2 = (unsigned int *)malloc (size);
+  if (! f->flame2)
+    {
+      free (f->flame);
+      XCBDisconnect (f->xcb.c);
+      free (f);
+      return NULL;
+    }
+
+  /* allocation of the image */
+  f->ims = ilog2 (BG_W);
+
+  /* initialization of the palette */
+  flame_set_palette (f);
+
+  return f;
+}
+
+void
+flame_shutdown (flame *f)
+{
+  if (!f)
+    return;
+
+  free (f->flame2);
+  free (f->flame);
+  XCBDisconnect (f->xcb.c);
+  free (f);
+}
+
+int
+main ()
+{
+  flame *f;
+  XCBGenericEvent *e;
+  XCBGCONTEXT gc = { 0 };
+
+  f = flame_init ();
+  if (!f)
+    {
+      printf ("Can't initialize global data\nExiting...\n");
+      return -1;
+    }
+
+  flame_set_flame_zero (f);
+  flame_set_random_flame_base (f);
+
+  while (1)
+    {
+      if ((e = XCBPollForEvent (f->xcb.c, NULL)))
+       {
+         switch (e->response_type)
+           {
+           case XCBExpose:
+             XCBCopyArea(f->xcb.c, f->xcb.pixmap, f->xcb.draw, gc,
+                         0, 0, 0, 0, BG_W, BG_H);
+             XCBSync (f->xcb.c, 0);
+             break;
+            case XCBButtonPress:
+              printf ("Exiting...\n");
+              free (e);
+              goto sortie;
+           }
+         free (e);
+        }
+      flame_draw_flame (f);
+      XCBSync (f->xcb.c, 0);
+    }
+
+ sortie:
+  flame_shutdown (f);
+
+  return 0;
+}
+
+static void title_set (flame *f, const char *title)
+{
+  XCBInternAtomRep *rep;
+  XCBATOM           encoding;
+  char             *atom_name;
+
+  /* encoding */
+  atom_name = "UTF8_STRING";
+  rep = XCBInternAtomReply (f->xcb.c,
+                            XCBInternAtom (f->xcb.c,
+                                           0,
+                                           strlen (atom_name),
+                                           atom_name),
+                            NULL);
+  encoding = rep->atom;
+  free (rep);
+
+  /* ICCCM */
+/*   SetWMName (f->xcb.c, f->xcb.draw.window, encoding, strlen (title), title); */
+
+  /* NETWM */
+  atom_name = "_NET_WM_NAME";
+  rep = XCBInternAtomReply (f->xcb.c,
+                            XCBInternAtom (f->xcb.c,
+                                           0,
+                                           strlen (atom_name),
+                                           atom_name),
+                            NULL);
+  XCBChangeProperty(f->xcb.c, PropModeReplace,
+                    f->xcb.draw.window,
+                    rep->atom, encoding, 8, strlen (title), title);
+  free (rep);
+}
+
+static void
+flame_draw_flame (flame *f)
+{
+  XCBImage     *image;
+  unsigned int *ptr;
+  int           x;
+  int           y;
+  int           xx;
+  int           yy;
+  int           cl;
+  int           cl1;
+  int           cl2;
+  int           cl3;
+  int           cl4;
+
+  /* modify the base of the flame */
+  flame_modify_flame_base (f);
+  /* process the flame array, propagating the flames up the array */
+  flame_process_flame (f);
+
+  image = XCBImageGet (f->xcb.c, f->xcb.draw,
+                      0, 0, BG_W, BG_H,
+                      ((unsigned long)~0L), ZPixmap);
+  f->im = (unsigned int *)image->data;
+
+  for (y = 0 ; y < ((BG_H >> 1) - 1) ; y++)
+    {
+      for (x = 0 ; x < ((BG_W >> 1) - 1) ; x++)
+       {
+         xx = x << 1;
+         yy = y << 1;
+
+         ptr = f->flame2 + (y << f->ws) + x;
+         cl1 = cl = (int)*ptr;
+         ptr = f->flame2 + (y << f->ws) + x + 1;
+         cl2 = (int)*ptr;
+         ptr = f->flame2 + ((y + 1) << f->ws) + x + 1;
+         cl3 = (int)*ptr;
+         ptr = f->flame2 + ((y + 1) << f->ws) + x;
+         cl4 = (int)*ptr;
+
+          
+          XCBImagePutPixel (image,
+                            xx, yy,
+                            f->pal[cl]);
+          XCBImagePutPixel (image,
+                            xx + 1, yy,
+                            f->pal[((cl1+cl2) >> 1)]);
+          XCBImagePutPixel (image,
+                            xx, yy + 1,
+                            f->pal[((cl1 + cl3) >> 1)]);
+          XCBImagePutPixel (image,
+                            xx + 1, yy + 1,
+                            f->pal[((cl1 + cl4) >> 1)]);
+       }
+    }
+  XCBImagePut (f->xcb.c, f->xcb.draw, f->xcb.gc, image,
+              0, 0, 0, 0, BG_W, BG_H);
+  XCBImageDestroy (image);
+}
+
+/* set the flame palette */
+static void
+flame_set_palette (flame *f)
+{
+  XCBAllocColorCookie cookies[IMAX];
+  XCBAllocColorRep *rep;
+  int               i;
+  int               r;
+  int               g;
+  int               b;
+
+  for (i = 0 ; i < IMAX ; i++)
+    {
+      r = i * 3;
+      g = (i - 80) * 3;
+      b = (i - 160) * 3;
+
+      if (r < 0)   r = 0;
+      if (r > 255) r = 255;
+      if (g < 0)   g = 0;
+      if (g > 255) g = 255;
+      if (b < 0)   b = 0;
+      if (b > 255) b = 255;
+
+      cookies[i] = XCBAllocColor (f->xcb.c, f->xcb.cmap,
+                                  r << 8, g << 8, b << 8);
+    }
+
+  for (i = 0 ; i < IMAX ; i++)
+    {
+      rep = XCBAllocColorReply (f->xcb.c, cookies[i], NULL);
+      f->pal[i] = rep->pixel;
+      free (rep);
+    }
+}
+
+/* set the flame array to zero */
+static void
+flame_set_flame_zero (flame *f)
+{
+  int           x;
+  int           y;
+  unsigned int *ptr;
+
+  for (y = 0 ; y < (BG_H >> 1) ; y++)
+    {
+      for (x = 0 ; x < (BG_W >> 1) ; x++)
+       {
+         ptr = f->flame + (y << f->ws) + x;
+         *ptr = 0;
+       }
+    }
+}
+
+static void
+flame_set_random_flame_base (flame *f)
+{
+  int           x;
+  int           y;
+  unsigned int *ptr;
+  
+  /* initialize a random number seed from the time, so we get random */
+  /* numbers each time */
+  srand (time(NULL));
+  y = (BG_H >> 1) - 1;
+  for (x = 0 ; x < (BG_W >> 1) ; x++)
+    {
+      ptr = f->flame + (y << f->ws) + x;
+      *ptr = rand ()%IMAX;
+    }
+}
+
+/* modify the base of the flame with random values */
+static void
+flame_modify_flame_base (flame *f)
+{
+  int           x;
+  int           y;
+  unsigned int *ptr;
+  int           val;
+  
+  y = (BG_H >> 1) - 1;
+  for (x = 0 ; x < (BG_W >> 1) ; x++)
+    {
+      ptr = f->flame + (y << f->ws) + x;
+      *ptr += ((rand ()%VARIANCE) - VARTREND);
+      val = *ptr;
+      if (val > IMAX) *ptr = 0;
+      if (val < 0)    *ptr = 0;
+    }
+}
+
+/* process entire flame array */
+static void
+flame_process_flame (flame *f)
+{
+  int           x;
+  int           y;
+  unsigned int *ptr;
+  unsigned int *p;
+  unsigned int  val;
+  unsigned int  tmp;
+  
+  for (y = ((BG_H >> 1) - 1) ; y >= 2 ; y--)
+    {
+      for (x = 1 ; x < ((BG_W >> 1) - 1) ; x++)
+       {
+         ptr = f->flame + (y << f->ws) + x;
+         val = (unsigned int)*ptr;
+         if (val > IMAX)
+           *ptr = (unsigned int)IMAX;
+         val = (unsigned int)*ptr;
+         if (val > 0)
+           {
+             tmp = (val * VSPREAD) >> 8;
+             p   = ptr - (2 << f->ws);
+             *p  = *p + (tmp >> 1);
+             p   = ptr - (1 << f->ws);
+             *p  = *p + tmp;
+             tmp = (val * HSPREAD) >> 8;
+             p   = ptr - (1 << f->ws) - 1;
+             *p  = *p + tmp;
+             p   = ptr - (1 << f->ws) + 1;
+             *p  = *p + tmp;
+             p   = ptr - 1;
+             *p  = *p + (tmp >>1 );
+             p   = ptr + 1;
+             *p  = *p + (tmp >> 1);
+             p   = f->flame2 + (y << f->ws) + x;
+             *p  = val;
+             if (y < ((BG_H >> 1) - 1))
+               *ptr = (val * RESIDUAL) >> 8;
+           }
+       }
+    }
+}
+
+static int
+ilog2 (unsigned int n)
+{
+  int p = -1;
+
+  assert(n > 0);
+  while (n > 0) {
+    p++;
+    n >>= 1;
+  }
+
+  return p;
+}
diff --git a/tests/julia.c b/tests/julia.c
new file mode 100644 (file)
index 0000000..e5f1870
--- /dev/null
@@ -0,0 +1,212 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+#include <X11/XCB/xcb_aux.h>
+#include <X11/XCB/xcb_image.h>
+
+#include "julia.h"
+
+#define W_W 640
+#define W_H 480
+
+/* Parameters of the fractal */
+
+/* double cr = -0.7927; */
+/* double ci = 0.1609; */
+
+/* double cr = 0.32; */
+/* double ci = 0.043; */
+
+/* double cr = -1.1380; */
+/* double ci = -0.2403; */
+
+/* double cr = -0.0986; */
+/* double ci = -0.65186; */
+
+/* double cr = -0.1225; */
+/* double ci = 0.7449; */
+
+double cr = -0.3380;
+double ci = -0.6230;
+double origin_x = -1.8;
+double origin_y = -1.2;
+double width = 3.6;
+double height = 2.4;
+
+/* Numbers of colors in the palette */
+int cmax = 316;
+
+void
+palette_julia (Data *datap)
+{
+  XCBAllocColorRep *rep;
+  int               i;
+
+  datap->palette = (CARD32 *)malloc (sizeof (CARD32) * cmax);
+  
+  for (i = 0 ; i < cmax ; i++)
+    {
+      if (i < 128)
+       rep = XCBAllocColorReply (datap->conn,
+                                 XCBAllocColor (datap->conn,
+                                                datap->cmap,
+                                                i<<9, 0, 0),
+                                 0);
+      else if (i < 255)
+       rep = XCBAllocColorReply (datap->conn,
+                                 XCBAllocColor (datap->conn,
+                                                datap->cmap,
+                                                65535, (i-127)<<9, 0),
+                                 0);
+      else
+       rep = XCBAllocColorReply (datap->conn,
+                                 XCBAllocColor (datap->conn,
+                                                datap->cmap,
+                                                65535, 65535, (i-255)<<10),
+                                 0);
+      
+      if (!rep)
+       datap->palette[i] = 0;
+      else
+       datap->palette[i] = rep->pixel;
+      free (rep);
+    }
+  
+}
+
+void
+draw_julia (Data *datap)
+{
+  double    zr, zi, t;
+  int       c;
+  int       i, j;
+  
+  datap->image = XCBImageGet (datap->conn, datap->draw,
+                      0, 0, W_W, W_H,
+                      AllPlanes, datap->format);
+  
+  for (i = 0 ; i < datap->image->width ; i++)
+    for (j = 0 ; j < datap->image->height ; j++)
+      {
+       zr = origin_x + width * (double)i / (double)datap->image->width;
+       zi = origin_y + height * (double)j / (double)datap->image->height;
+       c = 0;
+       while ((zr*zr + zi*zi < 4.0) &&
+              (c < cmax-1))
+         {
+           t = zr;
+           zr = zr*zr - zi*zi + cr;
+           zi = 2.0*t*zi + ci;
+           c++;
+         }
+       XCBImagePutPixel (datap->image,
+                         i,j,
+                         datap->palette[c]);
+      }
+
+  XCBImagePut (datap->conn, datap->draw, datap->gc, datap->image,
+              0, 0, 0, 0, W_W, W_H);
+}
+
+int
+main (int argc, char *argv[])
+{
+  Data             data;
+  XCBSCREEN       *screen;
+  XCBDRAWABLE      win;
+  XCBDRAWABLE      rect;
+  XCBGCONTEXT      bgcolor;
+  CARD32           mask;
+  CARD32           valgc[2];
+  CARD32           valwin[3];
+  XCBRECTANGLE     rect_coord = { 0, 0, W_W, W_H};
+  XCBGenericEvent *e;
+  int              screen_num;
+  
+  data.conn = XCBConnect (0, &screen_num);
+  screen = XCBAuxGetScreen (data.conn, screen_num);
+  data.depth = XCBAuxGetDepth (data.conn, screen);
+
+  win.window = screen->root;
+
+  data.gc = XCBGCONTEXTNew (data.conn);
+  mask = GCForeground | GCGraphicsExposures;
+  valgc[0] = screen->black_pixel;
+  valgc[1] = 0; /* no graphics exposures */
+  XCBCreateGC (data.conn, data.gc, win, mask, valgc);
+
+  bgcolor = XCBGCONTEXTNew (data.conn);
+  mask = GCForeground | GCGraphicsExposures;
+  valgc[0] = screen->white_pixel;
+  valgc[1] = 0; /* no graphics exposures */
+  XCBCreateGC (data.conn, bgcolor, win, mask, valgc);
+
+  data.draw.window = XCBWINDOWNew (data.conn);
+  mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+  valwin[0] = screen->white_pixel;
+  valwin[1] = KeyReleaseMask | ButtonReleaseMask | ExposureMask;
+  valwin[2] = ButtonPressMask;
+  XCBCreateWindow (data.conn, 0,
+                  data.draw.window,
+                  screen->root,
+                  0, 0, W_W, W_H,
+                  10,
+                  InputOutput,
+                  screen->root_visual,
+                  mask, valwin);
+  XCBMapWindow (data.conn, data.draw.window);
+
+  rect.pixmap = XCBPIXMAPNew (data.conn);
+  XCBCreatePixmap (data.conn, data.depth,
+                  rect.pixmap, data.draw,
+                  W_W, W_H);
+  XCBPolyFillRectangle(data.conn, rect, bgcolor, 1, &rect_coord);
+
+  XCBMapWindow (data.conn, data.draw.window);
+
+  data.format = ZPixmap;
+
+  data.cmap = XCBCOLORMAPNew (data.conn);
+  XCBCreateColormap (data.conn,
+                    AllocNone,
+                    data.cmap,
+                    data.draw.window,
+                    screen->root_visual);
+
+  palette_julia (&data);
+
+  XCBSync (data.conn, 0); 
+
+  while ((e = XCBWaitForEvent(data.conn)))
+    {
+      switch (e->response_type)
+       {
+       case XCBExpose:
+         {
+           XCBCopyArea(data.conn, rect, data.draw, bgcolor,
+                       0, 0, 0, 0, W_W, W_H);
+           draw_julia (&data);
+           XCBSync (data.conn, 0);
+           break;
+         }
+       case XCBKeyRelease:
+       case XCBButtonRelease:
+         {
+            if (data.palette)
+              free (data.palette);
+            if (data.image)
+              XCBImageDestroy (data.image);
+            free (e);
+            XCBDisconnect (data.conn);
+            exit (0);
+           break;
+         }
+       }
+      free (e);
+    }
+
+  return 1;
+}
diff --git a/tests/julia.h b/tests/julia.h
new file mode 100644 (file)
index 0000000..f0b2321
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __TEST_H__
+#define __TEST_H__
+
+typedef struct Data_ Data;
+
+struct Data_
+{
+  XCBConnection *conn;
+  CARD8          depth;
+  XCBDRAWABLE    draw;
+  XCBGCONTEXT    gc;
+  XCBCOLORMAP    cmap;
+  CARD8          format;
+
+  XCBImage      *image;
+  CARD32        *palette;
+};
+
+#endif /* __TEST_H__ */
diff --git a/tests/lissajoux.c b/tests/lissajoux.c
new file mode 100644 (file)
index 0000000..9ba2996
--- /dev/null
@@ -0,0 +1,275 @@
+#include <assert.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <sys/time.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <X11/Xlib.h>
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/shm.h>
+#include <X11/XCB/xcb_aux.h>
+#include <X11/XCB/xcb_image.h>
+
+#include "lissajoux.h"
+
+#define W_W 100
+#define W_H 100
+
+double time_start;
+int    loop_count;
+double t_previous;
+double t;
+int    do_shm = 0;
+
+XCBShmSegmentInfo shminfo;
+
+double
+get_time(void)
+{
+  struct timeval timev;
+  
+  gettimeofday(&timev, NULL);
+
+  return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
+}
+
+void
+draw_lissajoux (Data *datap)
+{
+  int       i, nbr;
+  double    a1, a2, p1, p2;
+  double    pi, period;
+  double    x, y;
+  
+  if (do_shm)
+    { 
+      i = XCBImageSHMGet (datap->conn, datap->draw,
+                         datap->image, shminfo,
+                         0, 0,
+                         AllPlanes);
+      assert(i);
+    }
+  else
+    {
+      datap->image = XCBImageGet (datap->conn, datap->draw,
+                                  0, 0, W_W, W_H,
+                                  AllPlanes, datap->format);
+      assert(datap->image);
+    }
+  
+  pi = 3.1415926535897;
+  period = 2.0 * pi;
+  a1 = 2.0;
+  a2 = 3.0;
+  p1 = 4.0*t_previous*pi*0.05;
+  p2 = 0.0;
+
+  nbr = 1000;
+  for (i = 0 ; i < nbr ; i++)
+      {
+       x = cos (a1*i*period/nbr + p1);
+       y = sin (a2*i*period/nbr + p2);
+       XCBImagePutPixel (datap->image,
+                         (int)((double)(W_W-5)*(x+1)/2.0),
+                         (int)((double)(W_H-5)*(y+1)/2.0), 65535);
+      }
+
+  p1 = 4.0*t*pi*0.05;
+  p2 = 0.0;
+
+  for (i = 0 ; i < nbr ; i++)
+      {
+       x = cos (a1*i*period/nbr + p1);
+       y = sin (a2*i*period/nbr + p2);
+       XCBImagePutPixel (datap->image,
+                         (int)((double)(W_W-5)*(x+1)/2.0),
+                         (int)((double)(W_H-5)*(y+1)/2.0), 0);
+      }
+
+  if (do_shm)
+    XCBImageSHMPut (datap->conn, datap->draw, datap->gc,
+                   datap->image, shminfo,
+                   0, 0, 0, 0, W_W, W_H, 0);
+  else
+    {
+      XCBImagePut (datap->conn, datap->draw, datap->gc, datap->image,
+                   0, 0, 0, 0, W_W, W_H);
+      XCBImageDestroy (datap->image);
+    }
+}
+
+void
+step (Data *datap)
+{
+  loop_count++;
+  t = get_time () - time_start;
+
+  if (t <= 20.0)
+    {
+      draw_lissajoux (datap);
+    }
+  else
+    {
+      printf("FRAME COUNT..: %i frames\n", loop_count);
+      printf("TIME.........: %3.3f seconds\n", t);
+      printf("AVERAGE FPS..: %3.3f fps\n", (double)loop_count / t);
+      XCBDisconnect (datap->conn);
+      exit(0);
+    }
+}
+
+/* Return 0 if shm is not availaible, 1 otherwise */
+void
+shm_test (Data *datap)
+{
+  XCBShmQueryVersionRep *rep;
+
+  rep = XCBShmQueryVersionReply (datap->conn,
+                                XCBShmQueryVersion (datap->conn),
+                                NULL);
+  if (rep)
+    {
+      CARD8 format;
+      int shmctl_status;
+      
+      if (rep->shared_pixmaps && 
+         (rep->major_version > 1 || rep->minor_version > 0))
+       format = rep->pixmap_format;
+      else
+       format = 0;
+      datap->image = XCBImageSHMCreate (datap->conn, datap->depth,
+                                     format, NULL, W_W, W_H);
+      assert(datap->image);
+
+      shminfo.shmid = shmget (IPC_PRIVATE,
+                             datap->image->bytes_per_line*datap->image->height,
+                             IPC_CREAT | 0777);
+      assert(shminfo.shmid != -1);
+      shminfo.shmaddr = shmat (shminfo.shmid, 0, 0);
+      assert(shminfo.shmaddr);
+      datap->image->data = shminfo.shmaddr;
+
+      shminfo.shmseg = XCBShmSEGNew (datap->conn);
+      XCBShmAttach (datap->conn, shminfo.shmseg,
+                   shminfo.shmid, 0);
+      shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0);
+      assert(shmctl_status != -1);
+    }
+
+  if (datap->image)
+    {
+      printf ("Use of shm.\n");
+      do_shm = 1;
+    }
+  else
+    {
+      printf ("Can't use shm. Use standard functions.\n");
+      shmdt (shminfo.shmaddr);                
+      shmctl (shminfo.shmid, IPC_RMID, 0);
+      datap->image = NULL;
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  Data             data;
+  XCBSCREEN       *screen;
+  XCBDRAWABLE      win;
+  XCBDRAWABLE      rect;
+  XCBGCONTEXT      bgcolor;
+  CARD32           mask;
+  CARD32           valgc[2];
+  CARD32           valwin[3];
+  XCBRECTANGLE     rect_coord = { 0, 0, W_W, W_H};
+  XCBGenericEvent *e;
+  int              try_shm;
+  int              screen_num;
+  
+  try_shm = 0;
+
+  /* Arguments test */
+  if (argc < 2)
+    {
+      printf ("Usage: lissajoux try_shm\n");
+      printf ("         try_shm == 0: shm not used\n");
+      printf ("         try_shm != 0: shm is used (if availaible)\n");
+      exit (0);
+    }
+  if (argc >= 2)
+    try_shm = atoi (argv[1]);
+  if (try_shm != 0)
+    try_shm = 1;
+
+  data.conn = XCBConnect (0, &screen_num);
+  screen = XCBAuxGetScreen(data.conn, screen_num);
+  data.depth = XCBAuxGetDepth (data.conn, screen);
+
+  win.window = screen->root;
+
+  data.gc = XCBGCONTEXTNew (data.conn);
+  mask = GCForeground | GCGraphicsExposures;
+  valgc[0] = screen->black_pixel;
+  valgc[1] = 0; /* no graphics exposures */
+  XCBCreateGC (data.conn, data.gc, win, mask, valgc);
+
+  bgcolor = XCBGCONTEXTNew (data.conn);
+  mask = GCForeground | GCGraphicsExposures;
+  valgc[0] = screen->white_pixel;
+  valgc[1] = 0; /* no graphics exposures */
+  XCBCreateGC (data.conn, bgcolor, win, mask, valgc);
+
+  data.draw.window = XCBWINDOWNew (data.conn);
+  mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
+  valwin[0] = screen->white_pixel;
+  valwin[1] = KeyPressMask | ButtonReleaseMask | ExposureMask;
+  valwin[2] = ButtonPressMask;
+  XCBCreateWindow (data.conn, 0,
+                  data.draw.window,
+                  screen->root,
+                  0, 0, W_W, W_H,
+                  10,
+                  InputOutput,
+                  screen->root_visual,
+                  mask, valwin);
+  XCBMapWindow (data.conn, data.draw.window);
+
+  rect.pixmap = XCBPIXMAPNew (data.conn);
+  XCBCreatePixmap (data.conn, data.depth,
+                  rect.pixmap, data.draw,
+                  W_W, W_H);
+  XCBPolyFillRectangle(data.conn, rect, bgcolor, 1, &rect_coord);
+
+  data.format = ZPixmap;
+  XCBSync (data.conn, 0); 
+
+  if (try_shm)
+    shm_test (&data);
+
+  time_start = get_time ();
+  t_previous = 0.0;
+  while (1)
+    {
+      e = XCBPollForEvent(data.conn, NULL);
+      if (e)
+       {
+         switch (e->response_type)
+           {
+           case XCBExpose:
+             XCBCopyArea(data.conn, rect, data.draw, bgcolor,
+                         0, 0, 0, 0, W_W, W_H);
+             XCBSync (data.conn, 0);
+             break;
+           }
+         free (e);
+        }
+      step (&data);
+      XCBFlush (data.conn);
+      t_previous = t;
+    }
+  /*NOTREACHED*/
+}
diff --git a/tests/lissajoux.h b/tests/lissajoux.h
new file mode 100644 (file)
index 0000000..922b576
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __TEST_H__
+#define __TEST_H__
+
+typedef struct Data_ Data;
+
+struct Data_
+{
+  XCBConnection *conn;
+  CARD8          depth;
+  XCBDRAWABLE    draw;
+  XCBGCONTEXT    gc;
+  CARD8          format;
+  XCBImage      *image;
+};
+
+#endif /* __TEST_H__ */
diff --git a/xcbrandr.c b/xcbrandr.c
new file mode 100644 (file)
index 0000000..44b3f3e
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * $XFree86: xc/programs/xrandr/xrandr.c,v 1.11 2002/10/14 18:01:43 keithp Exp $
+ *
+ * Copyright Â© 2001 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright Â© 2002 Hewlett Pacard Company, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard or HP not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard and HP makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD and HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Blame Jim Gettys for any bugs; he wrote most of the client side code,
+ * and part of the server code for randr.
+ *
+ * Ported to XCB by Jeremy Kolb 2/8/2005
+ */
+
+#include <stdio.h>
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/xcb_aux.h>
+#include <X11/XCB/randr.h>
+#include <X11/XCB/render.h>    /* we share subpixel information */
+#include <string.h>
+#include <stdlib.h>
+
+#define CurrentTime 0L /* special time apparently*/
+
+static char *program_name;
+
+static char *direction[5] = {
+  "normal", 
+  "left", 
+  "inverted", 
+  "right",
+  "\n"};
+
+/* subpixel order */
+static char *order[6] = {
+  "unknown",
+  "horizontal rgb",
+  "horizontal bgr",
+  "vertical rgb",
+  "vertical bgr",
+  "no subpixels"};
+
+
+static void
+usage(void)
+{
+  fprintf(stderr, "usage: %s [options]\n", program_name);
+  fprintf(stderr, "  where options are:\n");
+  fprintf(stderr, "  -display <display> or -d <display>\n");
+  fprintf(stderr, "  -help\n");
+  fprintf(stderr, "  -o <normal,inverted,left,right,0,1,2,3>\n");
+  fprintf(stderr, "            or --orientation <normal,inverted,left,right,0,1,2,3>\n");
+  fprintf(stderr, "  -q        or --query\n");
+  fprintf(stderr, "  -s <size>/<width>x<height> or --size <size>/<width>x<height>\n");
+  fprintf(stderr, "  -r <rate> or --rate <rate>\n");
+  fprintf(stderr, "  -v        or --version\n");
+  fprintf(stderr, "  -x        (reflect in x)\n");
+  fprintf(stderr, "  -y        (reflect in y)\n");
+  fprintf(stderr, "  --screen <screen>\n");
+  fprintf(stderr, "  --verbose\n");
+  
+  exit(1);
+  /*NOTREACHED*/
+}
+
+/*
+ * Same idea as xc/lib/Xrandr.c (XRRConfigRates).
+ * Returns the rates for a given screen.
+ * Would be nice to put in another library or something.
+ */
+short*
+ConfigRates(XCBRandRGetScreenInfoRep *config, int sizeID, int *nrates)
+{
+    int i = 0;
+    short *ents;
+    XCBRandRRefreshRatesIter ri = XCBRandRGetScreenInfoRatesIter(config);
+    
+    while (i++ < sizeID) {
+       XCBRandRRefreshRatesNext(&ri);
+    }
+    
+    ents = (short *)XCBRandRRefreshRatesRates(ri.data);
+    *nrates = XCBRandRRefreshRatesRatesLength(ri.data);
+    
+    if (!nrates) {
+       *nrates = 0;
+       return 0;
+    }
+    
+    return ents;
+}
+
+int
+main (int argc, char **argv)
+{
+  XCBConnection  *c;
+  XCBRandRScreenSize *sizes;
+  XCBRandRGetScreenInfoRep *sc;
+  int          nsize;
+  int          nrate;
+  short                *rates;
+  XCBSCREEN    *root;
+  int          status = XCBRandRSetConfigFailed;
+  int          rot = -1;
+  int          verbose = 0, query = 0;
+  short                rotation, current_rotation, rotations;
+  XCBGenericEvent *event;
+  XCBRandRScreenChangeNotifyEvent *sce;
+  char          *display_name = NULL;
+  int          i, j;
+  int          current_size;
+  short                current_rate;
+  short                rate = -1;
+  short                size = -1;
+  int          dirind = 0;
+  static int   setit = 0;
+  int          screen = -1;
+  int          version = 0;
+  int          event_base, error_base;
+  short                reflection = 0;
+  int          width = 0, height = 0;
+  int          have_pixel_size = 0;
+  XCBGenericError *err;
+  CARD16 mask = (CARD16) StructureNotifyMask;
+  CARD32 values[1];
+  XCBRandRGetScreenInfoCookie scookie;
+  int major_version, minor_version;
+  XCBRandRQueryVersionRep *rr_version;
+
+  program_name = argv[0];
+  if (argc == 1) query = 1;
+  for (i = 1; i < argc; i++) {
+    if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
+      if (++i>=argc) usage ();
+      display_name = argv[i];
+      continue;
+    }
+    if (!strcmp("-help", argv[i])) {
+      usage();
+      continue;
+    }
+    if (!strcmp ("--verbose", argv[i])) {
+      verbose = 1;
+      continue;
+    }
+
+    if (!strcmp ("-s", argv[i]) || !strcmp ("--size", argv[i])) {
+      if (++i>=argc) usage ();
+      if (sscanf (argv[i], "%dx%d", &width, &height) == 2)
+       have_pixel_size = 1;
+      else {
+       size = atoi (argv[i]);
+       if (size < 0) usage();
+      }
+      setit = 1;
+      continue;
+    }
+
+    if (!strcmp ("-r", argv[i]) || !strcmp ("--rate", argv[i])) {
+      if (++i>=argc) usage ();
+      rate = atoi (argv[i]);
+      if (rate < 0) usage();
+      setit = 1;
+      continue;
+    }
+
+    if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) {
+      version = 1;
+      continue;
+    }
+
+    if (!strcmp ("-x", argv[i])) {
+      reflection |= XCBRandRRotationReflect_X;
+      setit = 1;
+      continue;
+    }
+    if (!strcmp ("-y", argv[i])) {
+      reflection |= XCBRandRRotationReflect_Y;
+      setit = 1;
+      continue;
+    }
+    if (!strcmp ("--screen", argv[i])) {
+      if (++i>=argc) usage ();
+      screen = atoi (argv[i]);
+      if (screen < 0) usage();
+      continue;
+    }
+    if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) {
+      query = 1;
+      continue;
+    }
+    if (!strcmp ("-o", argv[i]) || !strcmp ("--orientation", argv[i])) {
+      char *endptr;
+      if (++i>=argc) usage ();
+      dirind = strtol(argv[i], &endptr, 0);
+      if (*endptr != '\0') {
+       for (dirind = 0; dirind < 4; dirind++) {
+         if (strcmp (direction[dirind], argv[i]) == 0) break;
+       }
+       if ((dirind < 0) || (dirind > 3))  usage();
+      }
+      rot = dirind;
+      setit = 1;
+      continue;
+    }
+    
+    usage();
+  }
+  if (verbose) query = 1;
+
+  if (!display_name)
+      display_name = getenv("DISPLAY");
+  if (!display_name) {
+      fprintf (stderr, "No display available\n");
+      exit (1);
+  }
+  c = XCBConnect(display_name, &screen);
+  if (!c) {
+      fprintf (stderr, "Can't open display %s\n", display_name);
+      exit (1);
+  }
+  root = XCBAuxGetScreen(c, screen);
+  rr_version = XCBRandRQueryVersionReply(c, XCBRandRQueryVersion(c, 1, 1), 0);
+  if (!rr_version) {
+      fprintf(stderr, "Can't get VersionReply.\n");
+      exit (1);
+  }
+  major_version = rr_version->major_version;
+  minor_version = rr_version->minor_version;
+
+  scookie = XCBRandRGetScreenInfo(c, root->root);
+  sc = XCBRandRGetScreenInfoReply(c, scookie, 0);
+  if (!sc) {
+       fprintf(stderr, "Can't get ScreenInfo.\n");
+       exit (1);
+  }
+
+  current_rotation = sc->rotation;
+  current_size = sc->sizeID;
+  
+  nsize = sc->nSizes;
+  sizes = XCBRandRGetScreenInfoSizes(sc);
+
+  if (have_pixel_size) {
+    for (size = 0; size < nsize; size++)
+    {
+      if (sizes[size].width == width && sizes[size].height == height)
+       break;
+    }
+  }
+  else if (size < 0)
+    size = current_size;
+
+  if (size >= nsize) usage();
+
+  if (rot < 0)
+  {
+    for (rot = 0; rot < 4; rot++)
+       if (1 << rot == (current_rotation & 0xf))
+           break;
+  }
+
+  current_rate = sc->rate;
+  
+  if (rate < 0)
+  {
+    if (size == current_size)
+       rate = current_rate;
+    else
+       rate = 0;
+  }
+
+  if (version) {
+    printf("Server reports RandR version %d.%d\n", 
+          major_version, minor_version);
+  }
+  
+  if (query) {
+    printf(" SZ:    Pixels          Physical       Refresh\n");
+    for (i = 0; i < nsize; i++) {
+      printf ("%c%-2d %5d x %-5d  (%4dmm x%4dmm )",
+          i == current_size ? '*' : ' ',
+          i, sizes[i].width, sizes[i].height,
+          sizes[i].mwidth, sizes[i].mheight);
+      rates = ConfigRates (sc, i, &nrate);
+
+      if (nrate) printf ("  ");
+      for (j = 0; j < nrate; j++)
+       printf ("%c%-4d",
+               i == current_size && rates[j] == current_rate ? '*' : ' ',
+               rates[j]);
+      printf ("\n");
+    }
+  }
+
+#if 0
+  rotations = XRRConfigRotations(sc, &current_rotation);
+#else
+  rotations = sc->rotation;
+#endif
+
+  rotation = 1 << rot ;
+  if (query) {
+    for (i = 0; i < 4; i ++) {
+      if ((current_rotation >> i) & 1) 
+       printf("Current rotation - %s\n", direction[i]);
+    }
+
+    printf("Current reflection - ");
+    if (current_rotation & (XCBRandRRotationReflect_X|XCBRandRRotationReflect_Y))
+    {
+       if (current_rotation & XCBRandRRotationReflect_X) printf ("X Axis ");
+       if (current_rotation & XCBRandRRotationReflect_Y) printf ("Y Axis");
+    }
+    else
+       printf ("none");
+    printf ("\n");
+    
+
+    printf ("Rotations possible - ");
+    for (i = 0; i < 4; i ++) {
+      if ((rotations >> i) & 1)  printf("%s ", direction[i]);
+    }
+    printf ("\n");
+
+    printf ("Reflections possible - ");
+    if (rotations & (XCBRandRRotationReflect_X|XCBRandRRotationReflect_Y))
+    {
+        if (rotations & XCBRandRRotationReflect_X) printf ("X Axis ");
+       if (rotations & XCBRandRRotationReflect_Y) printf ("Y Axis");
+    }
+    else
+       printf ("none");
+    printf ("\n");
+  }
+
+  if (verbose) { 
+    printf("Setting size to %d, rotation to %s\n",  size, direction[rot]);
+
+    printf ("Setting reflection on ");
+    if (reflection)
+    {
+       if (reflection & XCBRandRRotationReflect_X) printf ("X Axis ");
+       if (reflection & XCBRandRRotationReflect_Y) printf ("Y Axis");
+    }
+    else
+       printf ("neither axis");
+    printf ("\n");
+
+    if (reflection & XCBRandRRotationReflect_X) printf("Setting reflection on X axis\n");
+
+    if (reflection & XCBRandRRotationReflect_Y) printf("Setting reflection on Y axis\n");
+  }
+
+  /* we should test configureNotify on the root window */
+  values[0] = 1;
+  XCBConfigureWindow(c, root->root, mask, values);
+
+  if (setit) XCBRandRSelectInput (c, root->root, XCBRandRSMScreenChangeNotify);
+
+  if (setit) {
+    XCBRandRSetScreenConfigCookie sscc;
+    XCBRandRSetScreenConfigRep *config;
+    sscc = XCBRandRSetScreenConfig(c, root->root, CurrentTime, sc->config_timestamp, size,
+           (short) (rotation | reflection), rate);
+    config = XCBRandRSetScreenConfigReply(c, sscc, &err);
+    if (!config) {
+       fprintf(stderr, "Can't set the screen. Error Code: %i Status:%i\n",
+               err->error_code, status);
+       exit(1);
+    }
+    status = config->status;
+  }
+    
+  const XCBQueryExtensionRep *qrre_rep = XCBRandRInit(c);
+  event_base = qrre_rep->first_event;
+  error_base = qrre_rep->first_error;
+  
+  if (verbose && setit) {
+    if (status == XCBRandRSetConfigSuccess)
+      {
+       while (1) {
+       int spo;
+       event = XCBWaitForEvent(c);
+       
+       printf ("Event received, type = %d\n", event->response_type);
+#if 0
+       /*
+        * update Xlib's knowledge of the event
+        * Not sure what the equiv of this is or if we need it.
+        */
+       XRRUpdateConfiguration (&event);
+#endif
+       
+       if (event->response_type == ConfigureNotify)
+         printf("Received ConfigureNotify Event!\n");
+       
+       switch (event->response_type - event_base) {
+       case XCBRandRScreenChangeNotify:
+         sce = (XCBRandRScreenChangeNotifyEvent *) event;
+
+         printf("Got a screen change notify event!\n");
+         printf(" window = %d\n root = %d\n size_index = %d\n rotation %d\n", 
+              (int) sce->request_window.xid, (int) sce->root.xid, 
+              sce->sizeID,  sce->rotation);
+         printf(" timestamp = %ld, config_timestamp = %ld\n",
+              sce->timestamp, sce->config_timestamp);
+         printf(" Rotation = %x\n", sce->rotation);
+         printf(" %d X %d pixels, %d X %d mm\n",
+                sce->width, sce->height, sce->mwidth, sce->mheight);
+         
+         printf("Display width   %d, height   %d\n",
+                root->width_in_pixels, root->height_in_pixels);
+         printf("Display widthmm %d, heightmm %d\n", 
+                root->width_in_millimeters, root->height_in_millimeters);
+         
+         spo = sce->subpixel_order;
+         if ((spo < 0) || (spo > 5))
+           printf ("Unknown subpixel order, value = %d\n", spo);
+         else printf ("new Subpixel rendering model is %s\n", order[spo]);
+         break;
+       default:
+         if (event->response_type != ConfigureNotify) 
+           printf("unknown event received, type = %d!\n", event->response_type);
+       }
+       }
+      }
+  }
+#if 0
+  XRRFreeScreenConfigInfo(sc);
+#endif
+  free(sc);
+  free(c);
+  return(0);
+}
diff --git a/xcbxvinfo.c b/xcbxvinfo.c
new file mode 100644 (file)
index 0000000..495af78
--- /dev/null
@@ -0,0 +1,347 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <X11/XCB/xcb.h>
+#include <X11/XCB/xv.h>
+
+static void PrintUsage()
+{
+    fprintf(stderr, "Usage:  xvinfo [-display host:dpy]\n");
+    exit(0);
+}
+
+XCBSCREEN *ScreenOfDisplay (XCBConnection *c, int screen)
+{
+    XCBSCREENIter iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
+    for (; iter.rem; --screen, XCBSCREENNext (&iter))
+        if (screen == 0)
+            return iter.data;
+    return NULL;
+}
+
+static int nstrcmp(char *b, int n, char *s) {
+    while (n > 0) {
+        if (*s == '\0')
+            return 1;
+        if (*b - *s != 0)
+            return *b - *s;
+        b++, s++, --n;
+    }
+    return -(*s != '\0');
+}
+
+/* 
+ * Copies a string s of size n and returns it with a NULL appended.
+ * String returned is allocated with malloc and should be freed later.
+ */
+static char *ExtractString(char *s, int n) {
+    char *str;
+    str = (char *)malloc(sizeof(char) * (n+1));
+    strncpy(str, s, n); 
+    str[n] = '\0';
+    return str;
+}
+
+int main(int argc, char *argv[])
+{
+    XCBConnection *c;
+    int scrn;
+    char *display_name = NULL;
+    char *name = NULL;
+    XCBWINDOW root_window = {0};
+    XCBSCREEN *screen;
+    XCBXvQueryExtensionRep *query_ext;
+    XCBXvQueryAdaptorsRep *adaptors_rep;
+    XCBXvAdaptorInfoIter adaptors_iter;
+    XCBXvAdaptorInfo *ainfo;
+    XCBXvFormat *format;
+    XCBXvQueryPortAttributesRep *attr_rep;
+    XCBXvAttributeInfoIter attr_iter;
+    XCBXvAttributeInfo *attribute;
+
+    int nscreens, nattr, i, j, k;
+
+    if ((argc != 1) && (argc != 3))
+        PrintUsage();
+
+    if (argc != 1) {
+        if (strcmp(argv[1], "-display"))
+            PrintUsage();
+        display_name = argv[2];
+    }
+
+    if (!display_name) display_name = getenv("DISPLAY");
+    if (!(c = XCBConnect(display_name, &scrn)))
+    {
+        fprintf(stderr, "xcbxvinfo: Unable to open display %s\n", display_name);
+        exit(1);
+    }
+
+    if (!(query_ext = XCBXvQueryExtensionReply(c, XCBXvQueryExtension(c), NULL)))
+    {
+        fprintf(stderr, "xvinfo: No X-Video extension on %s\n", display_name);
+        exit(0);
+    }
+    else
+    {
+        fprintf(stdout, "X-Video Extension version %i.%i\n", query_ext->major, query_ext->minor);
+    }
+
+    free(query_ext);
+
+    nscreens = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c)).rem;
+
+    for (i = 0; i < nscreens; i++)
+    {
+        fprintf(stdout, "screen #%i\n", i);
+
+        screen = ScreenOfDisplay(c, scrn);
+        if (screen) root_window = screen->root;
+
+        adaptors_rep = XCBXvQueryAdaptorsReply(c, XCBXvQueryAdaptors(c, root_window), NULL);
+        if (!adaptors_rep->num_adaptors) {
+            fprintf(stdout, " no adaptors present.\n");
+            continue;
+        }
+
+        adaptors_iter = XCBXvQueryAdaptorsInfoIter(adaptors_rep);
+
+        for (j = 0; j < adaptors_rep->num_adaptors; j++)
+        {
+            ainfo = adaptors_iter.data;
+            name = ExtractString(XCBXvAdaptorInfoName(ainfo), XCBXvAdaptorInfoNameLength(ainfo));
+            fprintf(stdout, "  Adaptor #%i: \"%s\"\n", j, name);
+            fprintf(stdout, "    number of ports: %i\n", ainfo->num_ports);
+            fprintf(stdout, "    port base: %li\n", ainfo->base_id.xid);
+            fprintf(stdout, "    operations supported: ");
+            free(name);
+
+            switch(ainfo->type & (XCBXvTypeInputMask | XCBXvTypeOutputMask)) {
+                case XCBXvTypeInputMask:
+                    if (ainfo->type & XCBXvTypeVideoMask)
+                        fprintf(stdout, "PutVideo ");
+                    if (ainfo->type & XCBXvTypeStillMask)
+                        fprintf(stdout, "PutStill ");
+                    if (ainfo->type & XCBXvTypeImageMask)
+                        fprintf(stdout, "PutImage ");
+                    break;
+                case XCBXvTypeOutputMask:
+                    if (ainfo->type & XCBXvTypeVideoMask)
+                        fprintf(stdout, "GetVideo ");
+                    if (ainfo->type & XCBXvTypeStillMask)
+                        fprintf(stdout, "GetStill ");
+                    break;
+                default:
+                    fprintf(stdout, "none ");
+                    break;
+            }
+            fprintf(stdout, "\n");
+
+            format = XCBXvAdaptorInfoFormats(ainfo);
+
+            fprintf(stdout, "    supported visuals:\n");
+            for (k=0; k < ainfo->num_formats; k++, format++)
+                fprintf(stdout, "      depth %i, visualID 0x%2lx\n",
+                        format->depth, format->visual.id);
+
+            attr_rep = XCBXvQueryPortAttributesReply(c,
+                    XCBXvQueryPortAttributes(c, ainfo->base_id), NULL);
+            nattr = attr_rep->num_attributes;
+            attr_iter = XCBXvQueryPortAttributesAttributesIter(attr_rep);
+
+            if (nattr) {            
+                fprintf(stdout, "    number of attributes: %i\n", nattr);
+
+                for (k = 0; k < nattr; k++) {
+                    attribute = attr_iter.data;
+                    fprintf(stdout, "      \"%s\" (range %li to %li)\n",
+                            XCBXvAttributeInfoName(attribute),
+                            attribute->min,
+                            attribute->max);
+
+                    if (attribute->flags & XCBXvAttributeFlagSettable)
+                        fprintf(stdout, "              client settable attribute\n");
+
+                    if (attribute->flags & XCBXvAttributeFlagGettable) {
+                        XCBATOM the_atom;
+                        XCBInternAtomRep *atom_rep;
+
+                        fprintf(stdout, "              client gettable attribute");
+
+                        atom_rep = XCBInternAtomReply(c,
+                                XCBInternAtom(c,
+                                    1, 
+                                    /*XCBXvAttributeInfoNameLength(attribute),*/
+                                    strlen(XCBXvAttributeInfoName(attribute)),
+                                    XCBXvAttributeInfoName(attribute)),
+                                NULL);
+                        the_atom = atom_rep->atom;
+
+                        if (the_atom.xid != 0) {
+                            XCBXvGetPortAttributeRep *pattr_rep =
+                                XCBXvGetPortAttributeReply(c,
+                                        XCBXvGetPortAttribute(c, ainfo->base_id, the_atom),
+                                        NULL);
+                            if (pattr_rep) fprintf(stdout, " (current value is %li)", pattr_rep->value);
+                            free(pattr_rep);
+                        }
+                        fprintf(stdout, "\n");
+                        free(atom_rep);
+                    }
+                    XCBXvAttributeInfoNext(&attr_iter);
+                }
+            }
+            else {
+                fprintf(stdout, "    no port attributes defined\n");
+            }
+
+            XCBXvQueryEncodingsRep *qencodings_rep;
+            qencodings_rep = XCBXvQueryEncodingsReply(c, XCBXvQueryEncodings(c, ainfo->base_id), NULL);
+            int nencode = qencodings_rep->num_encodings;
+            XCBXvEncodingInfoIter encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
+            XCBXvEncodingInfo *encoding;
+
+            int ImageEncodings = 0;
+            if (nencode) {
+                int n;
+                for (n = 0; n < nencode; n++) {
+                    encoding = encoding_iter.data;
+                    name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
+                    if (!nstrcmp(name, strlen(name), "XV_IMAGE"))
+                        ImageEncodings++;
+                    XCBXvEncodingInfoNext(&encoding_iter);
+                    free(name);
+                }
+
+                if(nencode - ImageEncodings) {
+                    fprintf(stdout, "    number of encodings: %i\n", nencode - ImageEncodings);
+
+                    /* Reset the iter. */
+                    encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
+                    for(n = 0; n < nencode; n++) {
+                        encoding = encoding_iter.data;
+                        name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
+                        if(nstrcmp(name, strlen(name), "XV_IMAGE")) {
+                            fprintf(stdout,
+                                    "      encoding ID #%li: \"%*s\"\n",
+                                    encoding->encoding.xid,
+                                    strlen(name),
+                                    name);
+                            fprintf(stdout, "        size: %i x %i\n",
+                                    encoding->width,
+                                    encoding->height);
+                            fprintf(stdout, "        rate: %f\n",
+                                    (float)encoding->rate.numerator/
+                                    (float)encoding->rate.denominator);
+                            free(name);
+                        }
+                        XCBXvEncodingInfoNext(&encoding_iter);
+                    }
+                }
+
+                if(ImageEncodings && (ainfo->type & XCBXvTypeImageMask)) {
+                    char imageName[5] = {0, 0, 0, 0, 0};
+                    encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
+                    for(n = 0; n < nencode; n++) {
+                        encoding = encoding_iter.data;
+                        name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
+                        if(!nstrcmp(name, strlen(name), "XV_IMAGE")) {
+                            fprintf(stdout, 
+                                    "    maximum XvImage size: %i x %i\n",     
+                                    encoding->width, encoding->height);
+                            break;
+                        }
+                        free(name);
+                    }
+                    XCBXvListImageFormatsRep *formats_rep;
+                    formats_rep = XCBXvListImageFormatsReply(c,
+                            XCBXvListImageFormats(c, ainfo->base_id),
+                            NULL);
+
+                    int numImages = formats_rep->num_formats;
+                    XCBXvImageFormatInfo *format;
+                    XCBXvImageFormatInfoIter formats_iter = XCBXvListImageFormatsFormatIter(formats_rep);
+                    fprintf(stdout, "    Number of image formats: %i\n",
+                            numImages);
+
+                    for(n = 0; n < numImages; n++) {
+                        format = formats_iter.data;
+                        memcpy(imageName, &(format->id), 4);
+                        fprintf(stdout, "      id: 0x%lx", format->id);
+                        if(isprint(imageName[0]) && isprint(imageName[1]) &&
+                                isprint(imageName[2]) && isprint(imageName[3])) 
+                        {
+                            fprintf(stdout, " (%s)\n", imageName);
+                        } else {
+                            fprintf(stdout, "\n");
+                        }
+                        fprintf(stdout, "        guid: ");
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[0]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[1]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[2]);
+                        fprintf(stdout, "%02x-", (unsigned char) 
+                                format->guid[3]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[4]);
+                        fprintf(stdout, "%02x-", (unsigned char) 
+                                format->guid[5]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[6]);
+                        fprintf(stdout, "%02x-", (unsigned char) 
+                                format->guid[7]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[8]);
+                        fprintf(stdout, "%02x-", (unsigned char) 
+                                format->guid[9]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[10]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[11]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[12]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[13]);
+                        fprintf(stdout, "%02x", (unsigned char) 
+                                format->guid[14]);
+                        fprintf(stdout, "%02x\n", (unsigned char) 
+                                format->guid[15]);
+
+                        fprintf(stdout, "        bits per pixel: %i\n",
+                                format->bpp);
+                        fprintf(stdout, "        number of planes: %i\n",
+                                format->num_planes);
+                        fprintf(stdout, "        type: %s (%s)\n", 
+                                (format->type == XCBXvImageFormatInfoTypeRGB) ? "RGB" : "YUV",
+                                (format->format == XCBXvImageFormatInfoFormatPacked) ? "packed" : "planar");
+
+                        if(format->type == XCBXvImageFormatInfoTypeRGB) {
+                            fprintf(stdout, "        depth: %i\n", 
+                                    format->depth);
+
+                            fprintf(stdout, "        red, green, blue masks: " 
+                                    "0x%lx, 0x%lx, 0x%lx\n", 
+                                    format->red_mask,
+                                    format->green_mask,
+                                    format->blue_mask);
+                        } else {
+
+                        }
+                        XCBXvImageFormatInfoNext(&formats_iter);
+                    }
+                    free(formats_rep);
+                }
+            }
+            free(qencodings_rep);
+            XCBXvAdaptorInfoNext(&adaptors_iter);
+        }
+    }
+
+    free(adaptors_rep);
+    adaptors_rep = NULL;
+
+    return 1;
+}
diff --git a/xdpyinfo.c b/xdpyinfo.c
new file mode 100644 (file)
index 0000000..3b3717d
--- /dev/null
@@ -0,0 +1,151 @@
+#include <X11/XCB/xcb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+XCBConnection *c;
+
+void print_setup();
+void print_formats();
+void list_extensions(void (*)(int, char *));
+void print_extension(int, char *);
+void query_extension(int, char *);
+void list_screens();
+void print_screen(XCBSCREEN *s);
+
+int main(int argc, char **argv)
+{
+    void (*ext_printer)(int, char *) = print_extension;
+    int screen;
+
+    c = XCBConnect(0, &screen);
+    if(!c)
+    {
+       fputs("Connect failed.\n", stderr);
+       exit(1);
+    }
+
+    for(--argc; argc; --argc)
+       if(!strcmp(argv[argc], "-queryExtensions"))
+           ext_printer = query_extension;
+
+    /* "name of display:    %s" "\n" */
+    print_setup(c);
+    /* "\n" "focus:  window 0x%x, revert to %s" (e.g. PointerRoot) */
+    list_extensions(ext_printer);
+    printf("\n" "default screen number:    %d", screen);
+    list_screens();
+    fputs("\n", stdout);
+
+    XCBDisconnect(c);
+
+    exit(0);
+}
+
+void print_setup()
+{
+    printf("version number:    %d.%d", XCBGetSetup(c)->protocol_major_version, XCBGetSetup(c)->protocol_minor_version);
+    fputs("\n" "vendor string:    ", stdout);
+    fwrite(XCBConnSetupSuccessRepVendor(XCBGetSetup(c)), 1, XCBConnSetupSuccessRepVendorLength(XCBGetSetup(c)), stdout);
+    printf("\n" "vendor release number:    %d", (int) XCBGetSetup(c)->release_number);
+    /* "\n" "XFree86 version: %d.%d.%d.%d" */
+    printf("\n" "maximum request size:  %d bytes", XCBGetSetup(c)->maximum_request_length * 4);
+    printf("\n" "motion buffer size:  %d", (int)XCBGetSetup(c)->motion_buffer_size);
+    printf("\n" "bitmap unit, bit order, padding:    %d, %s, %d", XCBGetSetup(c)->bitmap_format_scanline_unit, (XCBGetSetup(c)->bitmap_format_bit_order == LSBFirst) ? "LSBFirst" : "MSBFirst", XCBGetSetup(c)->bitmap_format_scanline_pad);
+    printf("\n" "image byte order:    %s", (XCBGetSetup(c)->image_byte_order == LSBFirst) ? "LSBFirst" : "MSBFirst");
+
+    print_formats();
+
+    printf("\n" "keycode range:    minimum %d, maximum %d", XCBGetSetup(c)->min_keycode.id, XCBGetSetup(c)->max_keycode.id);
+}
+
+void print_formats()
+{
+    int i = XCBConnSetupSuccessRepPixmapFormatsLength(XCBGetSetup(c));
+    XCBFORMAT *p = XCBConnSetupSuccessRepPixmapFormats(XCBGetSetup(c));
+    printf("\n" "number of supported pixmap formats:    %d", i);
+    fputs("\n" "supported pixmap formats:", stdout);
+    for(--i; i >= 0; --i, ++p)
+       printf("\n" "    depth %d, bits_per_pixel %d, scanline_pad %d", p->depth, p->bits_per_pixel, p->scanline_pad);
+}
+
+void list_extensions(void (*ext_printer)(int, char *))
+{
+    XCBListExtensionsRep *r;
+    XCBSTRIter i;
+
+    r = XCBListExtensionsReply(c, XCBListExtensions(c), 0);
+    if(!r)
+    {
+       fputs("ListExtensions failed.\n", stderr);
+       return;
+    }
+
+    i = XCBListExtensionsNamesIter(r);
+    printf("\n" "number of extensions:    %d", i.rem);
+    for(; i.rem; XCBSTRNext(&i))
+    {
+       fputs("\n" "    ", stdout);
+       ext_printer(XCBSTRNameLength(i.data), XCBSTRName(i.data));
+    }
+    free(r);
+}
+
+void print_extension(int len, char *name)
+{
+    fwrite(name, 1, len, stdout);
+}
+
+void query_extension(int len, char *name)
+{
+    XCBQueryExtensionRep *r;
+    int comma = 0;
+
+    r = XCBQueryExtensionReply(c, XCBQueryExtension(c, len, name), 0);
+    if(!r)
+    {
+       fputs("QueryExtension failed.\n", stderr);
+       return;
+    }
+
+    print_extension(len, name);
+    fputs("  (", stdout);
+    if(r->major_opcode)
+    {
+       printf("opcode: %d", r->major_opcode);
+       comma = 1;
+    }
+    if(r->first_event)
+    {
+       if(comma)
+           fputs(", ", stdout);
+       printf("base event: %d", r->first_event);
+       comma = 1;
+    }
+    if(r->first_error)
+    {
+       if(comma)
+           fputs(", ", stdout);
+       printf("base error: %d", r->first_error);
+    }
+    fputs(")", stdout);
+}
+
+void list_screens()
+{
+    XCBSCREENIter i;
+    int cur;
+
+    i = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c));
+    printf("\n" "number of screens:    %d" "\n", i.rem);
+    for(cur = 1; i.rem; XCBSCREENNext(&i), ++cur)
+    {
+       printf("\n" "screen #%d:", cur);
+       print_screen(i.data);
+    }
+}
+
+void print_screen(XCBSCREEN *s)
+{
+    printf("\n" "  dimensions:    %dx%d pixels (%dx%d millimeters)", s->width_in_pixels, s->height_in_pixels, s->width_in_millimeters, s->height_in_millimeters);
+}