Switch to cairo-drm, drop struct buffer hacks.
diff --git a/window.c b/window.c
index ce7823a..1c318e8 100644
--- a/window.c
+++ b/window.c
@@ -30,13 +30,12 @@
#include <time.h>
#include <cairo.h>
#include <glib.h>
+#include <cairo-drm.h>
#include <linux/input.h>
#include "wayland-client.h"
#include "wayland-glib.h"
-#include "cairo-util.h"
-
#include "window.h"
struct window {
@@ -52,9 +51,9 @@
int fullscreen;
struct wl_input_device *grab_device;
uint32_t name;
- int fd;
+ cairo_drm_context_t *ctx;
- struct buffer *buffer;
+ cairo_surface_t *cairo_surface;
window_resize_handler_t resize_handler;
window_key_handler_t key_handler;
@@ -78,7 +77,6 @@
static void
window_draw_decorations(struct window *window)
{
- cairo_surface_t *surface;
cairo_t *cr;
int border = 2, radius = 5;
cairo_text_extents_t extents;
@@ -86,15 +84,17 @@
struct wl_visual *visual;
int width, height;
- surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
- window->allocation.width,
- window->allocation.height);
+ window->cairo_surface =
+ cairo_drm_surface_create(window->ctx,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ window->allocation.width,
+ window->allocation.height);
outline = cairo_pattern_create_rgb(0.1, 0.1, 0.1);
bright = cairo_pattern_create_rgb(0.8, 0.8, 0.8);
dim = cairo_pattern_create_rgb(0.4, 0.4, 0.4);
- cr = cairo_create(surface);
+ cr = cairo_create(window->cairo_surface);
width = window->allocation.width - window->margin * 2;
height = window->allocation.height - window->margin * 2;
@@ -104,7 +104,20 @@
cairo_set_source_rgba(cr, 0, 0, 0, 0.7);
rounded_rect(cr, 0, 0, width, height, radius);
cairo_fill(cr);
- blur_surface(surface, 24 + radius);
+
+#ifdef SLOW_BUT_PWETTY
+ /* FIXME: Aw, pretty drop shadows now have to fallback to sw.
+ * Ideally we should have convolution filters in cairo, but we
+ * can also fallback to compositing the shadow image a bunch
+ * of times according to the blur kernel. */
+ {
+ cairo_surface_t *map;
+
+ map = cairo_drm_surface_map(window->cairo_surface);
+ blur_surface(map);
+ cairo_drm_surface_unmap(window->cairo_surface, map);
+ }
+#endif
cairo_translate(cr, -7, -5);
cairo_set_line_width (cr, border);
@@ -157,15 +170,12 @@
cairo_fill(cr);
cairo_destroy(cr);
- window->buffer = buffer_create_from_cairo_surface(window->fd, surface);
- cairo_surface_destroy(surface);
-
visual = wl_display_get_premultiplied_argb_visual(window->display);
wl_surface_attach(window->surface,
- window->buffer->name,
- window->buffer->width,
- window->buffer->height,
- window->buffer->stride,
+ cairo_drm_surface_get_name(window->cairo_surface),
+ window->allocation.width,
+ window->allocation.height,
+ cairo_drm_surface_get_stride(window->cairo_surface),
visual);
wl_surface_map(window->surface,
@@ -179,19 +189,19 @@
window_draw_fullscreen(struct window *window)
{
struct wl_visual *visual;
- int stride = window->allocation.width * 4;
- window->buffer = buffer_create(window->fd,
- window->allocation.width,
- window->allocation.height,
- stride);
+ window->cairo_surface =
+ cairo_drm_surface_create(window->ctx,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ window->allocation.width,
+ window->allocation.height);
visual = wl_display_get_premultiplied_argb_visual(window->display);
wl_surface_attach(window->surface,
- window->buffer->name,
- window->buffer->width,
- window->buffer->height,
- window->buffer->stride,
+ cairo_drm_surface_get_name(window->cairo_surface),
+ window->allocation.width,
+ window->allocation.height,
+ cairo_drm_surface_get_stride(window->cairo_surface),
visual);
wl_surface_map(window->surface,
@@ -222,9 +232,9 @@
* safely free the old window buffer if we resized and
* render the next frame into our back buffer.. */
- if (key == 0 && window->buffer != NULL) {
- buffer_destroy(window->buffer, window->fd);
- window->buffer = NULL;
+ if (key == 0 && window->cairo_surface != NULL) {
+ cairo_surface_destroy(window->cairo_surface);
+ window->cairo_surface = NULL;
}
}
@@ -382,6 +392,16 @@
}
}
+cairo_surface_t *
+window_create_surface(struct window *window,
+ struct rectangle *rectangle)
+{
+ return cairo_drm_surface_create(window->ctx,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ rectangle->width,
+ rectangle->height);
+}
+
void
window_copy(struct window *window,
struct rectangle *rectangle,
@@ -397,6 +417,21 @@
}
void
+window_copy_surface(struct window *window,
+ struct rectangle *rectangle,
+ cairo_surface_t *surface)
+{
+ wl_surface_copy(window->surface,
+ rectangle->x,
+ rectangle->y,
+ cairo_drm_surface_get_name(surface),
+ cairo_drm_surface_get_stride(surface),
+ 0, 0,
+ rectangle->width,
+ rectangle->height);
+}
+
+void
window_set_fullscreen(struct window *window, int fullscreen)
{
window->fullscreen = fullscreen;
@@ -488,7 +523,11 @@
window->saved_allocation = window->allocation;
window->margin = 16;
window->state = WINDOW_STABLE;
- window->fd = fd;
+ window->ctx = cairo_drm_context_get_for_fd(fd);
+ if (window->ctx == NULL) {
+ fprintf(stderr, "failed to get cairo drm context\n");
+ return NULL;
+ }
wl_display_add_global_listener(display,
window_handle_global, window);