diff options
author | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-06 11:26:15 +0800 |
---|---|---|
committer | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-06 11:26:15 +0800 |
commit | 21f3daebe3c049cca2753fae9b56d28958647543 (patch) | |
tree | 1a80729ddea4de7d0a132f48cc9b689d03f36f39 /sub | |
parent | d1d6a9978ebc8b7ac4e6d3c34fb151681efc37ac (diff) |
sub: Initial commit of subwindow transformation test
Diffstat (limited to 'sub')
-rw-r--r-- | sub/Makefile | 15 | ||||
-rw-r--r-- | sub/sub.c | 266 |
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; + } + } +} |