From: Josh Triplett Date: Sun, 19 Feb 2006 00:49:41 +0000 (-0800) Subject: Remove xcl and CVSROOT. X-Git-Tag: 0.1~31 X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a49d7099e26ff026dfec35067908b18dc05d2e88;p=free-sw%2Fxcb%2Fdemo Remove xcl and CVSROOT. --- a49d7099e26ff026dfec35067908b18dc05d2e88 diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..aab0e68 --- /dev/null +++ b/.cvsignore @@ -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 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 index 0000000..6ba5c56 --- /dev/null +++ b/Makefile.am @@ -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 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 index 0000000..d68a142 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,3 @@ +#! /bin/sh +autoreconf -v --install || exit 1 +./configure "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..8b512ea --- /dev/null +++ b/configure.ac @@ -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 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 +#include +#include +#include +#include + +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 index 0000000..0b47d83 --- /dev/null +++ b/hypnomoire.c @@ -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 +#include +#include "reply_formats.h" +#include +#include /* for free(3) */ +#include /* for usleep(3) */ +#include +#include + +#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 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 +#endif + +#ifdef TEST_ICCCM +#include +#endif + +#include + +#include +#include +#include "reply_formats.h" + +#ifdef VERBOSE +#include +#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 index 0000000..9a2840d --- /dev/null +++ b/rendertest.c @@ -0,0 +1,561 @@ + +#include +#include +#include +#include +#include +#include + +/* + * 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 index 0000000..7920f3f --- /dev/null +++ b/reply_formats.c @@ -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 +#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 index 0000000..431eca1 --- /dev/null +++ b/reply_formats.h @@ -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 + +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 index 0000000..4d30c20 --- /dev/null +++ b/tests/.cvsignore @@ -0,0 +1,5 @@ +Makefile.in +Makefile +.deps +lissajoux +julia diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..435eb98 --- /dev/null +++ b/tests/Makefile.am @@ -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 index 0000000..fb1cf2e --- /dev/null +++ b/tests/flames.c @@ -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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* 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 index 0000000..e5f1870 --- /dev/null +++ b/tests/julia.c @@ -0,0 +1,212 @@ +#include +#include + +#include +#include +#include +#include +#include + +#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 index 0000000..f0b2321 --- /dev/null +++ b/tests/julia.h @@ -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 index 0000000..9ba2996 --- /dev/null +++ b/tests/lissajoux.c @@ -0,0 +1,275 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#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 index 0000000..922b576 --- /dev/null +++ b/tests/lissajoux.h @@ -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 index 0000000..44b3f3e --- /dev/null +++ b/xcbrandr.c @@ -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 +#include +#include +#include +#include /* we share subpixel information */ +#include +#include + +#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 or -d \n"); + fprintf(stderr, " -help\n"); + fprintf(stderr, " -o \n"); + fprintf(stderr, " or --orientation \n"); + fprintf(stderr, " -q or --query\n"); + fprintf(stderr, " -s /x or --size /x\n"); + fprintf(stderr, " -r or --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 \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, ¤t_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 index 0000000..495af78 --- /dev/null +++ b/xcbxvinfo.c @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include + +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 index 0000000..3b3717d --- /dev/null +++ b/xdpyinfo.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +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); +}