diff options
author | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-13 10:18:09 +0800 |
---|---|---|
committer | Joel Bosveld <Joel.Bosveld@gmail.com> | 2009-07-13 11:07:03 +0800 |
commit | ed430bdf5d36e69e2869776328e0e2e65df9d6ba (patch) | |
tree | 4c87061ba947089f3655194b766fc223650437ae | |
parent | 0e58db56833035717f5b664cf050ee06d7c576c1 (diff) |
red: use an input mesh as well
This allows testing of redirection and mesh together, which was actually
broken at one stage...
-rw-r--r-- | red/red.c | 107 |
1 files changed, 92 insertions, 15 deletions
@@ -5,6 +5,9 @@ #include <X11/extensions/Xcomposite.h> #include <X11/extensions/Xdamage.h> #include <cairo-xlib.h> +#include <limits.h> + +#define IntToxFixed(x) ((x)<<16); typedef struct { @@ -12,8 +15,9 @@ typedef struct Window red; int width, height; cairo_surface_t *s; - int x,y; Damage d; + Visual *v; + XTriangle t[36]; } SubWindow; Display *d; @@ -23,10 +27,71 @@ int 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 void drawSubWindow (cairo_t *cr, SubWindow *s) { - cairo_set_source_surface (cr, s->s, s->x, s->y); + cairo_matrix_t m; + m.xx = s->width/256.0; + m.yy = s->height/256.0; + m.xy = m.yx = 0; + m.x0 = (-s->t[0].p1.x >> 16)*s->width/256.0; + m.y0 = (-s->t[0].p1.y >> 16)*s->height/256.0; + cairo_pattern_t *p = cairo_pattern_create_for_surface (s->s); + cairo_pattern_set_matrix (p, &m); + cairo_set_source (cr, p); cairo_paint (cr); + cairo_pattern_destroy (p); } static void @@ -91,13 +156,22 @@ static SubWindow } static void -setupWindow (Window win, cairo_t **cr, cairo_surface_t **s, int width, int height) +setupSubwindow (SubWindow *s) +{ + int i = s - sub; + meshWindow (s->t, 256*i+32*(i+1), 32, 256*(i+1)+32*(i+1), 256+32, 0, 0, s->width, s->height); + XCompositeSetTriangularCoordinateMesh (d, s->id, s->t, 4, 32); + if (s->s) cairo_surface_destroy (s->s); + s->s = cairo_xlib_surface_create (d, s->red, s->v, s->width, s->height); +} + +static void +setupWindow (cairo_t **cr, cairo_surface_t **s, int width, int height) { - if (cr) - if (*cr) cairo_destroy (*cr); + if (*cr) cairo_destroy (*cr); if (*s) cairo_surface_destroy (*s); - *s = cairo_xlib_surface_create (d, win, v, width, height); - if (cr) *cr = cairo_create (*s); + *s = cairo_xlib_surface_create (d, w, v, width, height); + *cr = cairo_create (*s); } int @@ -131,7 +205,7 @@ main (int argc, char **argv) w = XCreateWindow(d, RootWindow(d, 0), 0, 0, 1024, 768, 0, 32, InputOutput, v, CWBackPixel | CWBorderPixel | CWColormap, &attr); - XSelectInput (d, w, ButtonPressMask | StructureNotifyMask); + XSelectInput (d, w, StructureNotifyMask); for (int i = 0; i < N_SUB; i++) { @@ -140,25 +214,26 @@ main (int argc, char **argv) XGetWindowAttributes(d, sub[i].red, &wa); sub[i].width = wa.width; sub[i].height = wa.height; - sub[i].x = sub[i].y = 64 * i; - sub[i].id = XCreateWindow(d, w, sub[i].x, sub[i].y, sub[i].width, sub[i].height, + sub[i].id = XCreateWindow(d, w, 0, 0, sub[i].width, sub[i].height, 0, 0, InputOnly, 0, 0, 0); XMapWindow (d, sub[i].id); XSelectInput (d, sub[i].red, StructureNotifyMask); XCompositeRedirectWindowInput (d, sub[i].id, sub[i].red); sub[i].d = XDamageCreate (d, sub[i].red, XDamageReportRawRectangles); + sub[i].v = wa.visual; + sub[i].s = NULL; } XMapWindow (d, w); for (int i = 0; i < N_SUB; i++) - sub[i].s = cairo_xlib_surface_create (d, sub[i].red, v, 64, 64); + setupSubwindow (&sub[i]); cairo_surface_t *surface = NULL; cairo_t *cr = NULL; - setupWindow (w, &cr, &surface, 1024, 768); + setupWindow (&cr, &surface, 1024, 768); while(1) { @@ -170,12 +245,14 @@ main (int argc, char **argv) case ConfigureNotify: { if ( ev.xany.window == w ) - setupWindow (w, &cr, &surface, ev.xconfigure.width, ev.xconfigure.height); + setupWindow (&cr, &surface, ev.xconfigure.width, ev.xconfigure.height); else { SubWindow *s = findSubWindow ( ev.xany.window ); - setupWindow (s->red, NULL, &s->s, ev.xconfigure.width, ev.xconfigure.height); - XResizeWindow (d, s->id, ev.xconfigure.width, ev.xconfigure.height); + s->width = ev.xconfigure.width; + s->height = ev.xconfigure.height; + setupSubwindow (s); + XResizeWindow (d, s->id, s->width, s->height); } } default: |