summaryrefslogtreecommitdiff
path: root/sub
diff options
context:
space:
mode:
authorJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-06 11:26:15 +0800
committerJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-06 11:26:15 +0800
commit21f3daebe3c049cca2753fae9b56d28958647543 (patch)
tree1a80729ddea4de7d0a132f48cc9b689d03f36f39 /sub
parentd1d6a9978ebc8b7ac4e6d3c34fb151681efc37ac (diff)
sub: Initial commit of subwindow transformation test
Diffstat (limited to 'sub')
-rw-r--r--sub/Makefile15
-rw-r--r--sub/sub.c266
2 files changed, 281 insertions, 0 deletions
diff --git a/sub/Makefile b/sub/Makefile
new file mode 100644
index 0000000..97bb71c
--- /dev/null
+++ b/sub/Makefile
@@ -0,0 +1,15 @@
+PROJECT = sub
+OBJ = sub.o
+
+C99 = gcc --std=gnu99
+CFLAGS = -Wall -g `pkg-config --cflags --libs x11 xcomposite cairo-xlib`
+
+$(PROJECT) : $(OBJ)
+ $(C99) $(CFLAGS) -o $(PROJECT) $(OBJ)
+
+%.o : %.c
+ $(C99) $(CFLAGS) -c $< -o $@
+
+clean :
+ rm -f $(OBJ)
+
diff --git a/sub/sub.c b/sub/sub.c
new file mode 100644
index 0000000..6a2425c
--- /dev/null
+++ b/sub/sub.c
@@ -0,0 +1,266 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+#include <cairo-xlib.h>
+#include <limits.h>
+
+#define N_SUB 5
+#define IntToxFixed(x) ((x)<<16);
+#define CSIZE 128
+
+typedef struct
+{
+ Window id;
+ Pixmap p;
+ int width, height;
+ XTriangle *mesh;
+ int nNormTri;
+ int nTotal;
+ bool drawing;
+ int x, y;
+ cairo_surface_t *s;
+ cairo_t *cr;
+} SubWindow;
+
+Display *d;
+Window w;
+SubWindow sub[N_SUB];
+Visual *v;
+
+static void
+meshSquare (XTriangle t[4], int px1, int py1, int px2, int py2,
+ int cx1, int cy1, int cx2, int cy2)
+{
+ t[0].p1.x = IntToxFixed (px1);
+ t[0].p1.y = IntToxFixed (py1);
+ t[0].p2.x = IntToxFixed (px2);
+ t[0].p2.y = IntToxFixed (py1);
+ t[0].p3.x = IntToxFixed (px2);
+ t[0].p3.y = IntToxFixed (py2);
+
+ t[1].p1.x = IntToxFixed (cx1);
+ t[1].p1.y = IntToxFixed (cy1);
+ t[1].p2.x = IntToxFixed (cx2);
+ t[1].p2.y = IntToxFixed (cy1);
+ t[1].p3.x = IntToxFixed (cx2);
+ t[1].p3.y = IntToxFixed (cy2);
+
+ t[2].p1.x = IntToxFixed (px1);
+ t[2].p1.y = IntToxFixed (py1);
+ t[2].p2.x = IntToxFixed (px2);
+ t[2].p2.y = IntToxFixed (py2);
+ t[2].p3.x = IntToxFixed (px1);
+ t[2].p3.y = IntToxFixed (py2);
+
+ t[3].p1.x = IntToxFixed (cx1);
+ t[3].p1.y = IntToxFixed (cy1);
+ t[3].p2.x = IntToxFixed (cx2);
+ t[3].p2.y = IntToxFixed (cy2);
+ t[3].p3.x = IntToxFixed (cx1);
+ t[3].p3.y = IntToxFixed (cy2);
+}
+
+static void
+meshWindow (XTriangle *t, int px1, int py1, int px2, int py2,
+ int cx1, int cy1, int cx2, int cy2)
+{
+ meshSquare (&t[0], px1, py1, px2, py2, cx1, cy1, cx2, cy2);
+ /* Top Row */
+ meshSquare (&t[4], SHRT_MIN, SHRT_MIN, px1, py1, SHRT_MIN, SHRT_MIN, cx1, cy1);
+ meshSquare (&t[8], px1, SHRT_MIN, px2, py1, cx1, SHRT_MIN, cx2, cy1);
+ meshSquare (&t[12], px2, SHRT_MIN, SHRT_MAX, py1, cx2, SHRT_MIN, SHRT_MAX, cy1);
+ /* Middle Row */
+ meshSquare (&t[16], SHRT_MIN, py1, px1, py2, SHRT_MIN, cy1, cx1, cy2);
+ meshSquare (&t[20], px2, py1, SHRT_MAX, py2, cx2, cy1, SHRT_MAX, cy2);
+ /* Bottom Row */
+ meshSquare (&t[24], SHRT_MIN, py2, px1, SHRT_MAX, SHRT_MIN, cy2, cx1, SHRT_MAX);
+ meshSquare (&t[28], px1, py2, px2, SHRT_MAX, cx1, cy2, cx2, SHRT_MAX);
+ meshSquare (&t[32], px2, py2, SHRT_MAX, SHRT_MAX, cx2, cy2, SHRT_MAX, SHRT_MAX);
+}
+
+static SubWindow
+*findSubwindow (Window id)
+{
+ for (int i = 0; i < N_SUB; i++)
+ if (sub[i].id == id)
+ return &sub[i];
+ return NULL;
+}
+
+static void
+paintTri (cairo_t *cr, cairo_surface_t *s, XTriangle p, XTriangle c)
+{
+
+}
+
+static void
+drawSubWindow (cairo_t *cr, SubWindow *s)
+{
+ /* The next two lines are just temporary, until I write proper code to draw
+ * arbitrary triangles in the mesh - which will allow for more exotic
+ * meshes to be used, and really neat effects to be done
+ */
+ cairo_set_source_surface (cr, s->s, s->mesh[0].p1.x>>16, s->mesh[0].p1.y>>16);
+ cairo_paint (cr);
+ for (int i = 0; i+1 < s->nNormTri; i+=2)
+ paintTri (cr, s->s, s->mesh[i], s->mesh[i+1]);
+}
+
+static void
+drawWindow (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_restore (cr);
+ for (int i = 0; i < N_SUB; i++)
+ drawSubWindow (cr, &sub[i]);
+}
+
+static Visual
+*findArgbVisual ()
+{
+ int screen = DefaultScreen (d);
+ XVisualInfo *xvi;
+ XVisualInfo temp;
+ int nvi;
+ int i;
+ XRenderPictFormat *format;
+ Visual *visual;
+
+ temp.screen = screen;
+ temp.depth = 32;
+ temp.class = TrueColor;
+
+ xvi = XGetVisualInfo (d,
+ VisualScreenMask |
+ VisualDepthMask |
+ VisualClassMask,
+ &temp,
+ &nvi);
+ if (!xvi)
+ return 0;
+
+ visual = 0;
+ for (i = 0; i < nvi; i++)
+ {
+ format = XRenderFindVisualFormat (d, xvi[i].visual);
+ if (format->type == PictTypeDirect && format->direct.alphaMask)
+ {
+ visual = xvi[i].visual;
+ break;
+ }
+ }
+
+ XFree (xvi);
+
+ return visual;
+}
+
+int
+main (int argc, char **argv)
+{
+ d = XOpenDisplay(NULL);
+ if(!d) return 1;
+
+ v = findArgbVisual ();
+ if(!v) abort ();
+ XSetWindowAttributes attr = {};
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap (d, RootWindow(d, 0),
+ v, AllocNone);
+
+ w = XCreateWindow(d, RootWindow(d, 0), 0, 0, 1024, 768, 0,
+ 32, InputOutput, v, CWBackPixel | CWBorderPixel | CWColormap, &attr);
+ XSelectInput (d, w, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
+ XCompositeRedirectSubwindows (d, w, CompositeRedirectManual);
+
+ for (int i = 0; i < N_SUB; i++)
+ {
+ sub[i].width = sub[i].height = CSIZE;
+ sub[i].id = XCreateSimpleWindow(d, w, 0, 0, sub[i].width, sub[i].height,
+ 0, 0, 0);
+ XSelectInput (d, sub[i].id, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
+ XMapWindow (d, sub[i].id);
+ }
+
+ XMapWindow (d, w);
+ XFlush (d);
+ XSync (d, w);
+
+ for (int i = 0; i < N_SUB; i++)
+ {
+ sub[i].nTotal = 36;
+ sub[i].mesh = malloc (sizeof(XTriangle) * sub[i].nTotal);
+ sub[i].nNormTri = 4;
+ meshWindow (&sub[i].mesh[0], CSIZE*i, CSIZE*i, CSIZE*(i+1), CSIZE*(i+1), 0, 0, CSIZE, CSIZE);
+ XCompositeSetTriangularCoordinateMesh (d, sub[i].id, sub[i].mesh, sub[i].nNormTri, sub[i].nTotal - sub[i].nNormTri);
+ sub[i].p = XCompositeNameWindowPixmap (d, sub[i].id);
+
+ sub[i].s = cairo_xlib_surface_create (d, sub[i].id, v, CSIZE, CSIZE);
+ sub[i].cr = cairo_create (sub[i].s);
+
+ cairo_set_source_rgba (sub[i].cr, 0.0, 1.0, 0.0, 0.75);
+ cairo_set_operator (sub[i].cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (sub[i].cr);
+ }
+
+ cairo_surface_t *surface = cairo_xlib_surface_create (d, w, v, 1024, 768);
+ cairo_t *cr = cairo_create (surface);
+
+ while(1)
+ {
+ drawWindow (cr);
+ XEvent ev;
+ XNextEvent(d, &ev);
+
+ switch (ev.type) {
+ case ButtonPress:
+ {
+ if ( ev.xany.window == w ) continue;
+ SubWindow *s = findSubwindow (ev.xany.window);
+ s->drawing = true;
+ s->x = ev.xbutton.x;
+ s->y = ev.xbutton.y;
+ }
+ break;
+ case MotionNotify:
+ if ( ev.xany.window == w ) continue;
+ SubWindow *s = findSubwindow (ev.xany.window);
+ if(s->drawing)
+ {
+ cairo_move_to (s->cr, s->x, s->y);
+ cairo_line_to (s->cr, ev.xbutton.x, ev.xbutton.y);
+ cairo_set_source_rgb (s->cr, 0.0, 0.0, 1.0);
+ cairo_set_line_width (s->cr, 5.0);
+ cairo_stroke (s->cr);
+ drawWindow (cr);
+fprintf(stderr,"ev - w:0x%x\t(%d %d)\t(%d %d)\n",(unsigned)ev.xany.window,ev.xbutton.x_root, ev.xbutton.y_root,ev.xbutton.x, ev.xbutton.y);
+int x, y, rx, ry;
+Window child, root;
+unsigned mask;
+XTranslateCoordinates (d, RootWindow(d, 0), s->id, ev.xbutton.x_root, ev.xbutton.y_root, &x, &y, &child);
+XTranslateCoordinates (d, s->id, RootWindow(d, 0), ev.xbutton.x, ev.xbutton.y, &rx, &ry, &child);
+fprintf(stderr,"tr - w:0x%x\t(%d %d)\t(%d %d)\n",(unsigned)ev.xany.window,rx,ry,x,y);
+XQueryPointer (d, s->id, &root, &child, &rx, &ry, &x, &y, &mask);
+fprintf(stderr,"qu - w:0x%x\t(%d %d)\t(%d %d)\n\n",(unsigned)ev.xany.window,rx,ry,x,y);
+ }
+ s->x = ev.xbutton.x;
+ s->y = ev.xbutton.y;
+ break;
+ case ButtonRelease:
+ {
+ if ( ev.xany.window == w ) continue;
+ SubWindow *s = findSubwindow (ev.xany.window);
+ s->drawing = false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}