summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-13 10:18:09 +0800
committerJoel Bosveld <Joel.Bosveld@gmail.com>2009-07-13 11:07:03 +0800
commited430bdf5d36e69e2869776328e0e2e65df9d6ba (patch)
tree4c87061ba947089f3655194b766fc223650437ae
parent0e58db56833035717f5b664cf050ee06d7c576c1 (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.c107
1 files changed, 92 insertions, 15 deletions
diff --git a/red/red.c b/red/red.c
index 8cb0911..7de1795 100644
--- a/red/red.c
+++ b/red/red.c
@@ -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: