From 7da95aa6cf6bb1051371d24dcbf930cfb36773a7 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 23 Oct 2011 15:35:23 -0700 Subject: [PATCH] Removed guac_client_free_layer (doesn't make sense), added free() for update queue, added update queue structures. --- libguac/include/client.h | 15 ------ libguac/include/protocol.h | 98 ++++++++++++++++++++++++++++++++++++++ libguac/src/client.c | 62 +++++++++++++++--------- libguac/src/protocol.c | 21 ++++++++ 4 files changed, 158 insertions(+), 38 deletions(-) diff --git a/libguac/include/client.h b/libguac/include/client.h index 9703733c..ae7e2362 100644 --- a/libguac/include/client.h +++ b/libguac/include/client.h @@ -147,12 +147,6 @@ struct guac_client { */ guac_client_state state; - /** - * The head pointer of the list of all available (allocated but not used) - * layers. - */ - guac_layer* available_layers; - /** * The index of the next available buffer. */ @@ -379,15 +373,6 @@ guac_layer* guac_client_alloc_layer(guac_client* client, int index); */ void guac_client_free_buffer(guac_client* client, guac_layer* layer); -/** - * Returns the given layer to the pool of available layers, such that it - * can be reused by any subsequent call to guac_client_allow_layer(). - * - * @param client The proxy client to return the layer to. - * @param layer The layer to return to the pool of available layers. - */ -void guac_client_free_layer(guac_client* client, guac_layer* layer); - extern const guac_layer* GUAC_DEFAULT_LAYER; #endif diff --git a/libguac/include/protocol.h b/libguac/include/protocol.h index b680fa5e..3ca809f4 100644 --- a/libguac/include/protocol.h +++ b/libguac/include/protocol.h @@ -104,8 +104,101 @@ typedef enum guac_composite_mode_t { } guac_composite_mode_t; +typedef struct guac_layer_update guac_layer_update; typedef struct guac_layer guac_layer; + +/** + * The type of a layer update (png, copy, or rect, for + * example). + */ +typedef enum guac_layer_update_type_t { + + GUAC_LAYER_UPDATE_PNG, + GUAC_LAYER_UPDATE_COPY, + GUAC_LAYER_UPDATE_CLIP, + GUAC_LAYER_UPDATE_RECT + +} guac_layer_update_type_t; + +/** + * Represents an abstract graphical update or state change + * of a layer, including dirty rectangle information. + */ +struct guac_layer_update { + + /** + * The type of this update. Update type corresponds + * directly to the instruction that would be sent + * if the queue is flushed. + */ + guac_layer_update_type_t type; + + /** + * The composite mode to use in this update. + */ + guac_composite_mode_t mode; + + /** + * The layer to retrieve image data from. + */ + guac_layer* src_layer; + + /** + * The surface to retrieve image data from. + */ + cairo_surface_t* src_image; + + /** + * The X coordinage of the upper-left corner of the + * source rectangle. + */ + int src_x; + + /** + * The Y coordinage of the upper-left corner of the + * source rectangle. + */ + int src_y; + + /** + * The layer this update should affect. + */ + guac_layer* dst_layer; + + /** + * The X coordinate of the upper-left corner of the + * destination rectangle. + */ + int dst_x; + + /** + * The Y coordinate of the upper-left corner of the + * destination rectangle. + */ + int dst_y; + + /** + * The width of the destination or source rectangle. + * The dimensions of the destination and source + * rectangles are always identical. + */ + int width; + + /** + * The height of the destination or source rectangle. + * The dimensions of the destination and source + * rectangles are always identical. + */ + int height; + + /** + * The next update in the update queue, if any. + */ + guac_layer_update* next; + +}; + /** * Represents a single layer within the Guacamole protocol. */ @@ -127,6 +220,11 @@ struct guac_layer { */ guac_layer* next_available; + /** + * The first element in this layer's update queue. + */ + guac_layer_update* update_queue_head; + }; /** diff --git a/libguac/src/client.c b/libguac/src/client.c index d04a267d..1208fc90 100644 --- a/libguac/src/client.c +++ b/libguac/src/client.c @@ -68,7 +68,6 @@ guac_client* __guac_alloc_client(GUACIO* io) { client->state = RUNNING; client->all_layers = NULL; - client->available_layers = NULL; client->available_buffers = NULL; client->next_buffer_index = -1; @@ -80,35 +79,19 @@ guac_layer* guac_client_alloc_layer(guac_client* client, int index) { guac_layer* allocd_layer; - /* If available layers, pop off first available layer */ - if (client->available_layers != NULL) { - allocd_layer = client->available_layers; - client->available_layers = client->available_layers->next_available; - allocd_layer->next_available = NULL; - } + /* Init new layer */ + allocd_layer = malloc(sizeof(guac_layer)); + allocd_layer->update_queue_head = NULL; - /* If no available layers, allocate new layer, add to all_layers list */ - else { - - /* Init new layer */ - allocd_layer = malloc(sizeof(guac_layer)); - - /* Add to all_layers list */ - allocd_layer->next = client->all_layers; - client->all_layers = allocd_layer; - - } + /* Add to all_layers list */ + allocd_layer->next = client->all_layers; + client->all_layers = allocd_layer; allocd_layer->index = index; return allocd_layer; } -void guac_client_free_layer(guac_client* client, guac_layer* layer) { - layer->next_available = client->available_layers; - client->available_layers = layer; -} - guac_layer* guac_client_alloc_buffer(guac_client* client) { guac_layer* allocd_layer; @@ -126,6 +109,7 @@ guac_layer* guac_client_alloc_buffer(guac_client* client) { /* Init new layer */ allocd_layer = malloc(sizeof(guac_layer)); allocd_layer->index = client->next_buffer_index--; + allocd_layer->update_queue_head = NULL; /* Add to all_layers list */ allocd_layer->next = client->all_layers; @@ -138,8 +122,23 @@ guac_layer* guac_client_alloc_buffer(guac_client* client) { } void guac_client_free_buffer(guac_client* client, guac_layer* layer) { + + /* Add layer to pool of available buffers */ layer->next_available = client->available_buffers; client->available_buffers = layer; + + /* Free all queued updates */ + while (layer->update_queue_head != NULL) { + + /* Get unflushed update, update queue head */ + guac_layer_update* unflushed_update = layer->update_queue_head; + layer->update_queue_head = unflushed_update->next; + + /* Free update */ + free(unflushed_update); + + } + } guac_client* guac_get_client(int client_fd) { @@ -336,9 +335,26 @@ void guac_free_client(guac_client* client) { /* Free all layers */ while (client->all_layers != NULL) { + + /* Get layer, update layer pool head */ guac_layer* layer = client->all_layers; client->all_layers = layer->next; + + /* Free all queued updates */ + while (layer->update_queue_head != NULL) { + + /* Get unflushed update, update queue head */ + guac_layer_update* unflushed_update = layer->update_queue_head; + layer->update_queue_head = unflushed_update->next; + + /* Free update */ + free(unflushed_update); + + } + + /* Free layer */ free(layer); + } free(client); diff --git a/libguac/src/protocol.c b/libguac/src/protocol.c index 9dfe74f7..efd1fb32 100644 --- a/libguac/src/protocol.c +++ b/libguac/src/protocol.c @@ -518,3 +518,24 @@ void guac_sleep(int millis) { } +void guac_layer_png(guac_layer* layer, guac_composite_mode_t mode, + int x, int y, cairo_surface_t* surface) { + /* STUB */ +} + +void guac_layer_copy(guac_layer* layer, guac_composite_mode_t mode, + const guac_layer* srcl, int srcx, int srcy, int w, int h, + int dstx, int dsty) { + /* STUB */ +} + +void guac_layer_clip(guac_layer* layer, + int x, int y, int width, int height) { + /* STUB */ +} + +int guac_layer_flush(guac_layer* layer, GUACIO* io) { + /* STUB */ + return 0; +} +