GUAC-656: Implement flush. Implement draw.

This commit is contained in:
Michael Jumper 2014-04-30 16:45:09 -07:00
parent db96b5f691
commit 98a041336a
2 changed files with 48 additions and 17 deletions

View File

@ -133,6 +133,11 @@ guac_common_surface* guac_common_surface_alloc(guac_socket* socket, const guac_l
surface->buffer = malloc(surface->stride * h); surface->buffer = malloc(surface->stride * h);
surface->surface = cairo_image_surface_create_for_data(surface->buffer, CAIRO_FORMAT_RGB24, surface->surface = cairo_image_surface_create_for_data(surface->buffer, CAIRO_FORMAT_RGB24,
w, h, surface->stride); w, h, surface->stride);
surface->cairo = cairo_create(surface->surface);
/* Init with black */
cairo_set_source_rgb(surface->cairo, 0, 0, 0);
cairo_paint(surface->cairo);
guac_protocol_send_size(socket, layer, w, h); guac_protocol_send_size(socket, layer, w, h);
return surface; return surface;
@ -141,6 +146,7 @@ guac_common_surface* guac_common_surface_alloc(guac_socket* socket, const guac_l
void guac_common_surface_free(guac_common_surface* surface) { void guac_common_surface_free(guac_common_surface* surface) {
guac_protocol_send_dispose(surface->socket, surface->layer); guac_protocol_send_dispose(surface->socket, surface->layer);
cairo_surface_destroy(surface->surface); cairo_surface_destroy(surface->surface);
cairo_destroy(surface->cairo);
free(surface->buffer); free(surface->buffer);
free(surface); free(surface);
} }
@ -148,7 +154,6 @@ void guac_common_surface_free(guac_common_surface* surface) {
void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src) { void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src) {
guac_socket* socket = surface->socket; guac_socket* socket = surface->socket;
const guac_layer* layer = surface->layer;
int w = cairo_image_surface_get_width(src); int w = cairo_image_surface_get_width(src);
int h = cairo_image_surface_get_height(src); int h = cairo_image_surface_get_height(src);
@ -159,11 +164,14 @@ void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_
guac_common_surface_flush(surface); guac_common_surface_flush(surface);
} }
/* STUB */ /* Draw with given surface */
__guac_common_mark_dirty(surface, x, y, cairo_save(surface->cairo);
cairo_image_surface_get_width(src), cairo_set_source_surface(surface->cairo, src, x, y);
cairo_image_surface_get_height(src)); cairo_rectangle(surface->cairo, x, y, w, h);
guac_protocol_send_png(socket, GUAC_COMP_OVER, layer, x, y, src); cairo_fill(surface->cairo);
cairo_restore(surface->cairo);
__guac_common_mark_dirty(surface, x, y, w, h);
} }
@ -181,13 +189,15 @@ void guac_common_surface_copy(guac_common_surface* src, int sx, int sy, int w, i
} }
if (dst->dirty) { if (dst->dirty) {
/* STUB */
guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending copy"); guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending copy");
__guac_common_mark_dirty(dst, dx, dy, w, h); __guac_common_mark_dirty(dst, dx, dy, w, h);
} }
/* STUB */ else {
guac_common_surface_flush(src); guac_common_surface_flush(src);
guac_protocol_send_copy(socket, src_layer, sx, sy, w, h, GUAC_COMP_OVER, dst_layer, dx, dy); guac_protocol_send_copy(socket, src_layer, sx, sy, w, h, GUAC_COMP_OVER, dst_layer, dx, dy);
}
} }
@ -205,13 +215,15 @@ void guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int
} }
if (dst->dirty) { if (dst->dirty) {
/* STUB */
guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending transfer"); guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending transfer");
__guac_common_mark_dirty(dst, dx, dy, w, h); __guac_common_mark_dirty(dst, dx, dy, w, h);
} }
/* STUB */ else {
guac_common_surface_flush(src); guac_common_surface_flush(src);
guac_protocol_send_transfer(socket, src_layer, sx, sy, w, h, op, dst_layer, dx, dy); guac_protocol_send_transfer(socket, src_layer, sx, sy, w, h, op, dst_layer, dx, dy);
}
} }
@ -229,26 +241,40 @@ void guac_common_surface_rect(guac_common_surface* surface,
} }
if (surface->dirty) { if (surface->dirty) {
/* STUB */
guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending rect+cfill"); guac_protocol_send_log(socket, "NOTE - would rewrite as PNG instead of sending rect+cfill");
__guac_common_mark_dirty(surface, x, y, w, h); __guac_common_mark_dirty(surface, x, y, w, h);
} }
/* STUB */ else {
guac_protocol_send_rect(socket, layer, x, y, w, h); guac_protocol_send_rect(socket, layer, x, y, w, h);
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, 0xFF); guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, 0xFF);
}
} }
void guac_common_surface_flush(guac_common_surface* surface) { void guac_common_surface_flush(guac_common_surface* surface) {
/* STUB */
if (surface->dirty) { if (surface->dirty) {
guac_socket* socket = surface->socket; guac_socket* socket = surface->socket;
const guac_layer* layer = surface->layer;
cairo_surface_t* rect;
guac_protocol_send_log(socket, "Flushing surface %i: (%i, %i) %ix%i", guac_protocol_send_log(socket, "Flushing surface %i: (%i, %i) %ix%i",
surface->layer->index, surface->layer->index,
surface->dirty_x, surface->dirty_y, surface->dirty_x, surface->dirty_y,
surface->dirty_width, surface->dirty_height); surface->dirty_width, surface->dirty_height);
/* Send PNG for dirty rect */
rect = cairo_surface_create_for_rectangle(surface->surface,
surface->dirty_x, surface->dirty_y,
surface->dirty_width, surface->dirty_height);
guac_protocol_send_png(socket, GUAC_COMP_OVER, layer, surface->dirty_x, surface->dirty_y, rect);
cairo_surface_destroy(rect);
surface->dirty = 0; surface->dirty = 0;
} }
} }

View File

@ -67,11 +67,16 @@ typedef struct guac_common_surface {
unsigned char* buffer; unsigned char* buffer;
/** /**
* The Cairo surface containins this Guacamole surface's current * The Cairo surface containing this Guacamole surface's current
* graphical state. * graphical state.
*/ */
cairo_surface_t* surface; cairo_surface_t* surface;
/**
* Cairo object for the underlying surface.
*/
cairo_t* cairo;
/** /**
* Non-zero if this surface is dirty and needs to be flushed, 0 otherwise. * Non-zero if this surface is dirty and needs to be flushed, 0 otherwise.
*/ */