summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-02 17:00:07 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-11-02 17:00:30 +1000
commitb7f2a59dd947e9d659aa1492cbcb962fa9eea785 (patch)
tree73253dab7a4f9e08a4b762ddc34e689c38c04f6a
parentb270b0be46c6577824325cdf6a35e8ea01129c4f (diff)
Use cairo for front and backbuffer surfaces
Much easier than xlib Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--multitouch.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/multitouch.c b/multitouch.c
index ec95eac..654719c 100644
--- a/multitouch.c
+++ b/multitouch.c
@@ -22,6 +22,8 @@ struct multitouch {
Screen* screen;
Window root;
Window win;
+ GC gc;
+ Visual *visual;
int xi_opcode;
Pixmap pixmap;
@@ -30,8 +32,13 @@ struct multitouch {
int height;
cairo_t *cr;
+ cairo_t *cr_win;
+ cairo_surface_t *surface;
+ cairo_surface_t *surface_win;
};
+static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2);
+
static int error(const char *fmt, ...)
{
va_list args;
@@ -98,6 +105,15 @@ static Pixmap init_pixmap(struct multitouch *mt)
return p;
}
+static GC init_gc(struct multitouch *mt)
+{
+ GC gc;
+
+ gc = XCreateGC(mt->dpy, mt->win, 0, NULL);
+
+ return gc;
+}
+
static int init_x11(struct multitouch *mt, int width, int height)
{
Display *dpy;
@@ -119,15 +135,18 @@ static int init_x11(struct multitouch *mt, int width, int height)
mt->screen_no = DefaultScreen(dpy);
mt->screen = DefaultScreenOfDisplay(dpy);
mt->root = DefaultRootWindow(dpy);
+ mt->visual = DefaultVisual(dpy, mt->screen_no);
mt->xi_opcode = xi_opcode;
mt->width = width;
mt->height = height;
mt->win = init_window(mt);
mt->pixmap = init_pixmap(mt);
+ mt->gc = init_gc(mt);
if (!mt->win)
return error("Failed to create window.\n");
+ XFlush(mt->dpy);
return EXIT_SUCCESS;
}
@@ -157,25 +176,54 @@ static int init_cairo(struct multitouch *mt)
cairo_surface_t *surface;
cairo_t *cr;
- surface = cairo_xlib_surface_create_for_bitmap(mt->dpy, mt->pixmap,
- mt->screen, mt->width, mt->height);
+ /* frontbuffer */
+ surface = cairo_xlib_surface_create(mt->dpy, mt->win,
+ mt->visual, mt->width, mt->height);
if (!surface)
return error("Failed to create cairo surface\n");
+ mt->surface_win = surface;
+
+ cr = cairo_create(surface);
+ if (!cr)
+ return error("Failed to create cairo context\n");
+
+ mt->cr_win = cr;
+
+ /* backbuffer */
+ surface = cairo_surface_create_similar(surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ mt->width, mt->height);
+ if (!surface)
+ return error("Failed to create cairo surface\n");
+
+ mt->surface = surface;
+
cr = cairo_create(surface);
if (!cr)
return error("Failed to create cairo context\n");
cairo_set_line_width(cr, 1);
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_rectangle(cr, 0, 0, 1, 1);
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_rectangle(cr, 0, 0, mt->width, mt->height);
cairo_fill(cr);
+ cairo_move_to(cr, 10, 10);
+ cairo_line_to(cr, 100, 100);
+ cairo_stroke(cr);
mt->cr = cr;
+ expose(mt, 0, 0, mt->width, mt->height);
+
return EXIT_SUCCESS;
}
+static void expose(struct multitouch *mt, int x1, int y1, int x2, int y2)
+{
+ cairo_set_source_surface(mt->cr_win, mt->surface, 0, 0);
+ cairo_paint(mt->cr_win);
+}
+
static int main_loop(struct multitouch *mt)
{
struct pollfd fd;
@@ -194,9 +242,14 @@ static int main_loop(struct multitouch *mt)
XGenericEventCookie *cookie = &ev.xcookie;
XNextEvent(mt->dpy, &ev);
- if (XGetEventData(mt->dpy, cookie) &&
- cookie->type == GenericEvent &&
- cookie->extension == mt->xi_opcode)
+ if (ev.type == Expose) {
+ expose(mt, ev.xexpose.x, ev.xexpose.y,
+ ev.xexpose.x + ev.xexpose.width,
+ ev.xexpose.y + ev.xexpose.height);
+ } else if (ev.type == GenericEvent &&
+ XGetEventData(mt->dpy, cookie) &&
+ cookie->type == GenericEvent &&
+ cookie->extension == mt->xi_opcode)
{
print_event(mt, cookie->data);
}