uint32_t key;
gboolean redraw_scheduled;
- gboolean redraw_pending;
- cairo_surface_t *surface;
gchar *filename;
};
struct rectangle rectangle;
GdkPixbuf *pb;
cairo_t *cr;
+ cairo_surface_t *wsurface, *surface;
- image->redraw_pending = 0;
+ image->redraw_scheduled = 0;
window_draw(image->window);
if (pb == NULL)
return;
- image->surface =
- window_create_surface(image->window, &rectangle);
+ wsurface = window_get_surface(image->window);
+ surface = cairo_surface_create_similar(wsurface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ rectangle.width,
+ rectangle.height);
- cr = cairo_create(image->surface);
+ cr = cairo_create(surface);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_paint(cr);
g_object_unref(pb);
- window_copy_surface(image->window,
- &rectangle,
- image->surface);
-
+ window_copy_surface(image->window, &rectangle, surface);
window_commit(image->window, image->key);
+ cairo_surface_destroy(surface);
}
static gboolean
if (!image->redraw_scheduled) {
image->redraw_scheduled = 1;
g_idle_add(image_idle_redraw, image);
- } else {
- image->redraw_pending = 1;
}
}
image_schedule_redraw(image);
}
-static void
-acknowledge_handler(struct window *window,
- uint32_t key, uint32_t frame, void *data)
-{
- struct image *image = data;
-
- if (image->key != key)
- return;
-
- cairo_surface_destroy(image->surface);
- image->redraw_scheduled = 0;
- if (image->redraw_pending) {
- image->redraw_pending = 0;
- image_schedule_redraw(image);
- }
-}
-
static struct image *
image_create(struct display *display, uint32_t key, const char *filename)
{
/* FIXME: Window uses key 1 for moves, need some kind of
* allocation scheme here. Or maybe just a real toolkit. */
image->key = key + 100;
- image->redraw_scheduled = 1;
window_set_resize_handler(image->window, resize_handler, image);
window_set_keyboard_focus_handler(image->window, keyboard_focus_handler, image);
- window_set_acknowledge_handler(image->window, acknowledge_handler, image);
image_draw(image);
struct terminal {
struct window *window;
struct display *display;
- int redraw_scheduled, redraw_pending;
+ int redraw_scheduled;
char *data;
int width, height, start, row, column;
int fd, master;
int fullscreen;
int focused;
struct color_scheme *color_scheme;
+ cairo_font_extents_t extents;
};
static char *
terminal_draw(struct terminal *terminal)
{
struct rectangle rectangle;
- cairo_surface_t *surface;
- cairo_font_extents_t extents;
- cairo_t *cr;
int32_t width, height;
window_get_child_rectangle(terminal->window, &rectangle);
- surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
- cr = cairo_create(surface);
- cairo_select_font_face (cr, "mono",
- CAIRO_FONT_SLANT_NORMAL,
- CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(cr, 14);
- cairo_font_extents(cr, &extents);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
-
- width = (rectangle.width - 2 * terminal->margin) / (int32_t) extents.max_x_advance;
- height = (rectangle.height - 2 * terminal->margin) / (int32_t) extents.height;
+ width = (rectangle.width - 2 * terminal->margin) /
+ (int32_t) terminal->extents.max_x_advance;
+ height = (rectangle.height - 2 * terminal->margin) /
+ (int32_t) terminal->extents.height;
terminal_resize(terminal, width, height);
if (!terminal->fullscreen) {
- rectangle.width = terminal->width * extents.max_x_advance + 2 * terminal->margin;
- rectangle.height = terminal->height * extents.height + 2 * terminal->margin;
+ rectangle.width = terminal->width *
+ terminal->extents.max_x_advance + 2 * terminal->margin;
+ rectangle.height = terminal->height *
+ terminal->extents.height + 2 * terminal->margin;
window_set_child_size(terminal->window, &rectangle);
}
struct terminal *terminal = data;
terminal_draw(terminal);
+ terminal->redraw_scheduled = 0;
return FALSE;
}
if (!terminal->redraw_scheduled) {
g_idle_add(idle_redraw, terminal);
terminal->redraw_scheduled = 1;
- } else {
- terminal->redraw_pending = 1;
}
}
terminal_schedule_redraw(terminal);
}
-static void
-acknowledge_handler(struct window *window,
- uint32_t key, uint32_t frame, void *data)
-{
- struct terminal *terminal = data;
-
- terminal->redraw_scheduled = 0;
- if (terminal->redraw_pending) {
- terminal->redraw_pending = 0;
- terminal_schedule_redraw(terminal);
- }
-}
-
static void
key_handler(struct window *window, uint32_t key, uint32_t unicode,
uint32_t state, uint32_t modifiers, void *data)
terminal_create(struct display *display, int fullscreen)
{
struct terminal *terminal;
+ cairo_surface_t *surface;
+ cairo_t *cr;
terminal = malloc(sizeof *terminal);
if (terminal == NULL)
terminal->window = window_create(display, "Wayland Terminal",
500, 100, 500, 400);
terminal->display = display;
- terminal->redraw_scheduled = 1;
terminal->margin = 5;
window_set_fullscreen(terminal->window, terminal->fullscreen);
window_set_resize_handler(terminal->window, resize_handler, terminal);
- window_set_acknowledge_handler(terminal->window, acknowledge_handler, terminal);
window_set_key_handler(terminal->window, key_handler, terminal);
window_set_keyboard_focus_handler(terminal->window,
keyboard_focus_handler, terminal);
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
+ cr = cairo_create(surface);
+ cairo_select_font_face (cr, "mono",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size(cr, 14);
+ cairo_font_extents(cr, &terminal->extents);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+
terminal_draw(terminal);
return terminal;
uint32_t key;
gboolean redraw_scheduled;
- gboolean redraw_pending;
- cairo_surface_t *surface;
gchar *filename;
PopplerDocument *document;
int page;
view_draw(struct view *view)
{
struct rectangle rectangle;
+ cairo_surface_t *surface;
cairo_t *cr;
PopplerPage *page;
double width, height, doc_aspect, window_aspect, scale;
- view->redraw_pending = 0;
+ view->redraw_scheduled = 0;
window_draw(view->window);
page = poppler_document_get_page(view->document, view->page);
- view->surface =
- window_create_surface(view->window, &rectangle);
+ surface = window_get_surface(view->window);
+
+ cr = cairo_create(surface);
+ cairo_rectangle(cr, rectangle.x, rectangle.y,
+ rectangle.width, rectangle.height);
+ cairo_clip(cr);
- cr = cairo_create(view->surface);
cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr);
scale = rectangle.height / height;
else
scale = rectangle.width / width;
+ cairo_translate(cr, rectangle.x, rectangle.y);
cairo_scale(cr, scale, scale);
cairo_translate(cr,
(rectangle.width - width * scale) / 2 / scale,
cairo_destroy(cr);
g_object_unref(G_OBJECT(page));
- window_copy_surface(view->window,
- &rectangle,
- view->surface);
-
window_commit(view->window, 0);
}
if (!view->redraw_scheduled) {
view->redraw_scheduled = 1;
g_idle_add(view_idle_redraw, view);
- } else {
- view->redraw_pending = 1;
}
}
view_schedule_redraw(view);
}
-static void
-acknowledge_handler(struct window *window,
- uint32_t key, uint32_t frame, void *data)
-{
- struct view *view = data;
-
- if (view->key != key)
- return;
-
- cairo_surface_destroy(view->surface);
- view->redraw_scheduled = 0;
- if (view->redraw_pending) {
- view->redraw_pending = 0;
- view_schedule_redraw(view);
- }
-}
-
static void
keyboard_focus_handler(struct window *window,
struct wl_input_device *device, void *data)
window_set_key_handler(view->window, key_handler, view);
window_set_keyboard_focus_handler(view->window,
keyboard_focus_handler, view);
- window_set_acknowledge_handler(view->window, acknowledge_handler, view);
view->document = poppler_document_new_from_file(view->filename,
NULL, &error);
struct display *display;
struct wl_surface *surface;
const char *title;
- struct rectangle allocation, saved_allocation;
+ struct rectangle allocation, saved_allocation, surface_allocation;
int minimum_width, minimum_height;
int margin;
int drag_x, drag_y;
EGLImageKHR *image;
cairo_surface_t *cairo_surface, *pending_surface;
- int new_surface;
window_resize_handler_t resize_handler;
window_key_handler_t key_handler;
if (window->pending_surface != NULL)
return;
- window->pending_surface =
- cairo_surface_reference(window->cairo_surface);
+ window->pending_surface = window->cairo_surface;
+ window->cairo_surface = NULL;
- data = cairo_surface_get_user_data (window->cairo_surface, &surface_data_key);
- eglExportDRMImageMESA(window->display->dpy, data->image, &name, NULL, &stride);
+ data = cairo_surface_get_user_data (window->pending_surface,
+ &surface_data_key);
+ eglExportDRMImageMESA(window->display->dpy,
+ data->image, &name, NULL, &stride);
visual = wl_display_get_premultiplied_argb_visual(window->display->display);
wl_surface_attach(window->surface,
name,
- window->allocation.width,
- window->allocation.height,
+ window->surface_allocation.width,
+ window->surface_allocation.height,
stride,
visual);
wl_surface_map(window->surface,
- window->allocation.x - window->margin,
- window->allocation.y - window->margin,
- window->allocation.width,
- window->allocation.height);
+ window->surface_allocation.x - window->margin,
+ window->surface_allocation.y - window->margin,
+ window->surface_allocation.width,
+ window->surface_allocation.height);
+
+ wl_compositor_commit(window->display->compositor, 0);
}
void
window_commit(struct window *window, uint32_t key)
{
- if (window->new_surface) {
+ if (window->cairo_surface) {
window_attach_surface(window);
- window->new_surface = 0;
+ } else {
+ wl_compositor_commit(window->display->compositor, key);
}
-
- wl_compositor_commit(window->display->compositor, key);
}
static void
window->cairo_surface =
window_create_surface(window, &window->allocation);
+ window->surface_allocation = window->allocation;
outline = cairo_pattern_create_rgb(0.1, 0.1, 0.1);
bright = cairo_pattern_create_rgb(0.8, 0.8, 0.8);
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_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);
{
window->cairo_surface =
window_create_surface(window, &window->allocation);
+ window->surface_allocation = window->allocation;
}
void
window_draw_fullscreen(window);
else
window_draw_decorations(window);
-
- window->new_surface = 1;
}
cairo_surface_t *
* window buffer if we resized and render the next frame into
* our back buffer.. */
wl_list_for_each(window, &d->window_list, link) {
- pending = window->pending_surface;
+ cairo_surface_destroy(window->pending_surface);
window->pending_surface = NULL;
- if (pending != window->cairo_surface)
+ if (window->cairo_surface)
window_attach_surface(window);
- cairo_surface_destroy(pending);
if (window->acknowledge_handler)
(*window->acknowledge_handler)(window, key, frame, window->user_data);
}