}
free(dst);
+ cairo_surface_mark_dirty(surface);
+}
+
+void
+tile_mask(cairo_t *cr, cairo_surface_t *surface,
+ int x, int y, int width, int height, int margin)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t matrix;
+ int i, fx, fy;
+
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ pattern = cairo_pattern_create_for_surface (surface);
+
+ for (i = 0; i < 4; i++) {
+ fx = i & 1;
+ fy = i >> 1;
+
+ cairo_matrix_init_translate(&matrix,
+ -x + fx * (128 - width),
+ -y + fy * (128 - height));
+ cairo_pattern_set_matrix(pattern, &matrix);
+
+ cairo_reset_clip(cr);
+ cairo_rectangle(cr,
+ x + fx * (width - margin),
+ y + fy * (height - margin),
+ margin, margin);
+ cairo_clip (cr);
+ cairo_mask(cr, pattern);
+ }
+
+ /* Top strecth */
+ cairo_matrix_init_translate(&matrix, 64, 0);
+ cairo_matrix_scale(&matrix, 64.0 / (width - 2 * margin), 1);
+ cairo_matrix_translate(&matrix, -x - width / 2, -y);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x + margin, y, width - 2 * margin, margin);
+
+ cairo_reset_clip(cr);
+ cairo_rectangle(cr,
+ x + margin,
+ y,
+ width - 2 * margin, margin);
+ cairo_clip (cr);
+ cairo_mask(cr, pattern);
+
+ /* Bottom strecth */
+ cairo_matrix_translate(&matrix, 0, -height + 128);
+ cairo_pattern_set_matrix(pattern, &matrix);
+
+ cairo_reset_clip(cr);
+ cairo_rectangle(cr, x + margin, y + height - margin,
+ width - 2 * margin, margin);
+ cairo_clip (cr);
+ cairo_mask(cr, pattern);
+
+ /* Left strecth */
+ cairo_matrix_init_translate(&matrix, 0, 64);
+ cairo_matrix_scale(&matrix, 1, 64.0 / (height - 2 * margin));
+ cairo_matrix_translate(&matrix, -x, -y - height / 2);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_reset_clip(cr);
+ cairo_rectangle(cr, x, y + margin, margin, height - 2 * margin);
+ cairo_clip (cr);
+ cairo_mask(cr, pattern);
+
+ /* Right strecth */
+ cairo_matrix_translate(&matrix, -width + 128, 0);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x + width - margin, y + margin,
+ margin, height - 2 * margin);
+ cairo_reset_clip(cr);
+ cairo_clip (cr);
+ cairo_mask(cr, pattern);
+
+ cairo_pattern_destroy(pattern);
+ cairo_reset_clip(cr);
+}
+
+void
+tile_source(cairo_t *cr, cairo_surface_t *surface,
+ int x, int y, int width, int height, int margin)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t matrix;
+ int i, fx, fy;
+
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_set_source(cr, pattern);
+ cairo_pattern_destroy(pattern);
+
+ for (i = 0; i < 4; i++) {
+ fx = i & 1;
+ fy = i >> 1;
+
+ cairo_matrix_init_translate(&matrix,
+ -x + fx * (128 - width),
+ -y + fy * (128 - height));
+ cairo_pattern_set_matrix(pattern, &matrix);
+
+ cairo_rectangle(cr,
+ x + fx * (width - margin),
+ y + fy * (height - margin),
+ margin, margin);
+ cairo_fill(cr);
+ }
+
+ /* Top strecth */
+ cairo_matrix_init_translate(&matrix, 64, 0);
+ cairo_matrix_scale(&matrix, 64.0 / (width - 2 * margin), 1);
+ cairo_matrix_translate(&matrix, -x - width / 2, -y);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x + margin, y, width - 2 * margin, margin);
+ cairo_fill(cr);
+
+ /* Bottom strecth */
+ cairo_matrix_translate(&matrix, 0, -height + 128);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x + margin, y + height - margin,
+ width - 2 * margin, margin);
+ cairo_fill(cr);
+
+ /* Left strecth */
+ cairo_matrix_init_translate(&matrix, 0, 64);
+ cairo_matrix_scale(&matrix, 1, 64.0 / (height - 2 * margin));
+ cairo_matrix_translate(&matrix, -x, -y - height / 2);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x, y + margin, margin, height - 2 * margin);
+ cairo_fill(cr);
+
+ /* Right strecth */
+ cairo_matrix_translate(&matrix, -width + 128, 0);
+ cairo_pattern_set_matrix(pattern, &matrix);
+ cairo_rectangle(cr, x + width - margin, y + margin,
+ margin, height - 2 * margin);
+ cairo_fill(cr);
}
GSource *source;
struct wl_list window_list;
char *device_name;
+ cairo_surface_t *active_frame, *inactive_frame, *shadow;
};
struct window {
}
cairo_surface_t *
-window_create_surface(struct window *window,
- struct rectangle *rectangle)
+display_create_surface(struct display *display,
+ struct rectangle *rectangle)
{
struct surface_data *data;
- EGLDisplay dpy = window->display->dpy;
+ EGLDisplay dpy = display->dpy;
cairo_surface_t *surface;
EGLint image_attribs[] = {
glBindTexture(GL_TEXTURE_2D, data->texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, data->image);
- surface = cairo_gl_surface_create_for_texture(window->display->device,
+ surface = cairo_gl_surface_create_for_texture(display->device,
CAIRO_CONTENT_COLOR_ALPHA,
data->texture,
rectangle->width,
cairo_t *cr;
int border = 2, radius = 5;
cairo_text_extents_t extents;
- cairo_pattern_t *gradient, *outline, *bright, *dim;
+ cairo_pattern_t *pattern, *gradient, *outline, *bright, *dim;
int width, height;
int shadow_dx = 4, shadow_dy = 4;
+ cairo_matrix_t matrix;
window->cairo_surface =
- window_create_surface(window, &window->allocation);
+ display_create_surface(window->display, &window->allocation);
window->surface_allocation = window->allocation;
+ width = window->allocation.width;
+ height = 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);
cr = cairo_create(window->cairo_surface);
- width = window->allocation.width - window->margin * 2;
- height = window->allocation.height - window->margin * 2;
-
- cairo_set_source_rgba(cr, 0, 0, 0, 0);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 0, 0, 0, 0);
cairo_paint(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_translate(cr, window->margin + shadow_dx,
- window->margin + shadow_dy);
- cairo_set_line_width (cr, border);
- cairo_set_source_rgba(cr, 0, 0, 0, 0.7);
- rounded_rect(cr, -1, -1, width + 1, height + 1, radius);
- cairo_fill(cr);
-
-#define SLOW_BUT_PWETTY_not_right_now
-#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, 32);
- cairo_drm_surface_unmap(window->cairo_surface, map);
- }
-#endif
-
- cairo_translate(cr, -shadow_dx, -shadow_dy);
- if (window->keyboard_device) {
- rounded_rect(cr, 0, 0, width, height, radius);
- gradient = cairo_pattern_create_linear (0, 0, 0, 100);
- cairo_pattern_add_color_stop_rgb(gradient, 0, 0.6, 0.6, 0.6);
- cairo_pattern_add_color_stop_rgb(gradient, 1, 0.8, 0.8, 0.8);
- cairo_set_source(cr, gradient);
- cairo_fill(cr);
- cairo_pattern_destroy(gradient);
- } else {
- rounded_rect(cr, 0, 0, width, height, radius);
- cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
- cairo_fill(cr);
- }
-
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_move_to(cr, 10, 50);
- cairo_line_to(cr, width - 10, 50);
- cairo_line_to(cr, width - 10, height - 10);
- cairo_line_to(cr, 10, height - 10);
- cairo_close_path(cr);
- cairo_set_source(cr, dim);
- cairo_stroke(cr);
+ cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
+ tile_mask(cr, window->display->shadow, 3, 3, width, height, 32);
- cairo_move_to(cr, 11, 51);
- cairo_line_to(cr, width - 10, 51);
- cairo_line_to(cr, width - 10, height - 10);
- cairo_line_to(cr, 11, height - 10);
- cairo_close_path(cr);
- cairo_set_source(cr, bright);
- cairo_stroke(cr);
+ if (window->keyboard_device)
+ tile_source(cr, window->display->active_frame,
+ 0, 0, width, height, 96);
+ else
+ tile_source(cr, window->display->inactive_frame,
+ 0, 0, width, height, 96);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_font_size(cr, 14);
cairo_text_extents(cr, window->title, &extents);
- cairo_move_to(cr, (width - extents.width) / 2, 10 - extents.y_bearing);
+ cairo_move_to(cr, (width - extents.width) / 2, 32 - extents.y_bearing);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_width (cr, 4);
- cairo_text_path(cr, window->title);
- if (window->keyboard_device) {
- cairo_set_source_rgb(cr, 0.56, 0.56, 0.56);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
- } else {
+ if (window->keyboard_device)
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ else
cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);
- cairo_fill(cr);
- }
+ cairo_show_text(cr, window->title);
+
cairo_destroy(cr);
}
window_draw_fullscreen(struct window *window)
{
window->cairo_surface =
- window_create_surface(window, &window->allocation);
+ display_create_surface(window->display, &window->allocation);
window->surface_allocation = window->allocation;
}
static const char socket_name[] = "\0wayland";
+static void
+display_render_frame(struct display *d)
+{
+ struct rectangle r = { 0, 0, 128, 128 };
+ int radius = 8;
+ cairo_t *cr;
+
+ d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
+ cr = cairo_create(d->shadow);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba(cr, 0, 0, 0, 1);
+ rounded_rect(cr, 16, 16, 112, 112, radius);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+ blur_surface(d->shadow, 64);
+
+ d->active_frame =
+ cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
+ cr = cairo_create(d->active_frame);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba(cr, 0.8, 0.8, 0.4, 1);
+ rounded_rect(cr, 16, 16, 112, 112, radius);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+
+ d->inactive_frame =
+ cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
+ cr = cairo_create(d->inactive_frame);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
+ rounded_rect(cr, 16, 16, 112, 112, radius);
+ cairo_fill(cr);
+ cairo_destroy(cr);
+}
+
struct display *
display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
{
return NULL;
}
+ display_render_frame(d);
+
d->loop = g_main_loop_new(NULL, FALSE);
d->source = wl_glib_source_new(d->display);
g_source_attach(d->source, NULL);