Using C99, POSIX, and BSD. Added guac_layer and layer/buffer alloc/free.
This commit is contained in:
parent
208ff61edd
commit
6341346cb7
@ -40,8 +40,15 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
AC_PROG_CC_C99
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
# POSIX
|
||||||
|
AC_DEFINE(_POSIX_C_SOURCE, 199309L)
|
||||||
|
|
||||||
|
# BSD
|
||||||
|
AC_DEFINE(_BSD_SOURCE)
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
AC_CHECK_LIB([dl], [dlopen],, AC_MSG_ERROR("libdl is required for loading client plugins"))
|
AC_CHECK_LIB([dl], [dlopen],, AC_MSG_ERROR("libdl is required for loading client plugins"))
|
||||||
AC_CHECK_LIB([cairo], [cairo_create],, AC_MSG_ERROR("cairo is required for drawing instructions"))
|
AC_CHECK_LIB([cairo], [cairo_create],, AC_MSG_ERROR("cairo is required for drawing instructions"))
|
||||||
|
@ -147,6 +147,29 @@ struct guac_client {
|
|||||||
*/
|
*/
|
||||||
guac_client_state state;
|
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.
|
||||||
|
*/
|
||||||
|
int next_buffer_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The head pointer of the list of all available (allocated but not used)
|
||||||
|
* buffers.
|
||||||
|
*/
|
||||||
|
guac_layer* available_buffers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The head pointer of the list of all allocated layers, regardless of use
|
||||||
|
* status.
|
||||||
|
*/
|
||||||
|
guac_layer* all_layers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time (in milliseconds) of receipt of the last sync message from
|
* The time (in milliseconds) of receipt of the last sync message from
|
||||||
* the client.
|
* the client.
|
||||||
@ -328,4 +351,43 @@ int guac_client_handle_instruction(guac_client* client, guac_instruction* instru
|
|||||||
*/
|
*/
|
||||||
void guac_client_stop(guac_client* client);
|
void guac_client_stop(guac_client* client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a new buffer (invisible layer). An arbitrary index is
|
||||||
|
* automatically assigned if no existing buffer is available for use.
|
||||||
|
*
|
||||||
|
* @param client The proxy client to allocate the buffer for.
|
||||||
|
* @return The next available buffer, or a newly allocated buffer.
|
||||||
|
*/
|
||||||
|
guac_layer* guac_client_alloc_buffer(guac_client* client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a new layer. The layer will be given the specified index,
|
||||||
|
* even if the layer returned was a previously used (and free'd) layer.
|
||||||
|
*
|
||||||
|
* @param client The proxy client to allocate the layer buffer for.
|
||||||
|
* @param index The index of the layer to allocate.
|
||||||
|
* @return The next available layer, or a newly allocated layer.
|
||||||
|
*/
|
||||||
|
guac_layer* guac_client_alloc_layer(guac_client* client, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the given buffer to the pool of available buffers, such that it
|
||||||
|
* can be reused by any subsequent call to guac_client_allow_buffer().
|
||||||
|
*
|
||||||
|
* @param client The proxy client to return the buffer to.
|
||||||
|
* @param layer The buffer to return to the pool of available buffers.
|
||||||
|
*/
|
||||||
|
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
|
#endif
|
||||||
|
@ -102,6 +102,30 @@ typedef enum guac_composite_mode_t {
|
|||||||
|
|
||||||
} guac_composite_mode_t;
|
} guac_composite_mode_t;
|
||||||
|
|
||||||
|
typedef struct guac_layer guac_layer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single layer within the Guacamole protocol.
|
||||||
|
*/
|
||||||
|
struct guac_layer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of this layer.
|
||||||
|
*/
|
||||||
|
int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next allocated layer in the list of all layers.
|
||||||
|
*/
|
||||||
|
guac_layer* next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next available (unused) layer in the list of
|
||||||
|
* allocated but free'd layers.
|
||||||
|
*/
|
||||||
|
guac_layer* next_available;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a single instruction within the Guacamole protocol.
|
* Represents a single instruction within the Guacamole protocol.
|
||||||
@ -230,13 +254,13 @@ int guac_send_size(GUACIO* io, int w, int h);
|
|||||||
* Sends a copy instruction over the given GUACIO connection.
|
* Sends a copy instruction over the given GUACIO connection.
|
||||||
*
|
*
|
||||||
* @param io The GUACIO connection to use.
|
* @param io The GUACIO connection to use.
|
||||||
* @param srcl The index of the source layer.
|
* @param srcl The source layer.
|
||||||
* @param srcx The X coordinate of the source rectangle.
|
* @param srcx The X coordinate of the source rectangle.
|
||||||
* @param srcy The Y coordinate of the source rectangle.
|
* @param srcy The Y coordinate of the source rectangle.
|
||||||
* @param w The width of the source rectangle.
|
* @param w The width of the source rectangle.
|
||||||
* @param h The height of the source rectangle.
|
* @param h The height of the source rectangle.
|
||||||
* @param mode The composite mode to use.
|
* @param mode The composite mode to use.
|
||||||
* @param dstl The index of the destination layer.
|
* @param dstl The destination layer.
|
||||||
* @param dstx The X coordinate of the destination, where the source rectangle
|
* @param dstx The X coordinate of the destination, where the source rectangle
|
||||||
* should be copied.
|
* should be copied.
|
||||||
* @param dsty The Y coordinate of the destination, where the source rectangle
|
* @param dsty The Y coordinate of the destination, where the source rectangle
|
||||||
@ -244,8 +268,8 @@ int guac_send_size(GUACIO* io, int w, int h);
|
|||||||
* @return Zero on success, non-zero on error.
|
* @return Zero on success, non-zero on error.
|
||||||
*/
|
*/
|
||||||
int guac_send_copy(GUACIO* io,
|
int guac_send_copy(GUACIO* io,
|
||||||
int srcl, int srcx, int srcy, int w, int h,
|
const guac_layer* srcl, int srcx, int srcy, int w, int h,
|
||||||
guac_composite_mode_t mode, int dstl, int dstx, int dsty);
|
guac_composite_mode_t mode, const guac_layer* dstl, int dstx, int dsty);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a png instruction over the given GUACIO connection. The PNG image data
|
* Sends a png instruction over the given GUACIO connection. The PNG image data
|
||||||
@ -253,14 +277,14 @@ int guac_send_copy(GUACIO* io,
|
|||||||
*
|
*
|
||||||
* @param io The GUACIO connection to use.
|
* @param io The GUACIO connection to use.
|
||||||
* @param mode The composite mode to use.
|
* @param mode The composite mode to use.
|
||||||
* @param layer The index of the destination layer.
|
* @param layer The destination layer.
|
||||||
* @param x The destination X coordinate.
|
* @param x The destination X coordinate.
|
||||||
* @param y The destination Y coordinate.
|
* @param y The destination Y coordinate.
|
||||||
* @param surface A cairo surface containing the image data to send.
|
* @param surface A cairo surface containing the image data to send.
|
||||||
* @return Zero on success, non-zero on error.
|
* @return Zero on success, non-zero on error.
|
||||||
*/
|
*/
|
||||||
int guac_send_png(GUACIO* io, guac_composite_mode_t mode,
|
int guac_send_png(GUACIO* io, guac_composite_mode_t mode,
|
||||||
int layer, int x, int y, cairo_surface_t* surface);
|
const guac_layer* layer, int x, int y, cairo_surface_t* surface);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a cursor instruction over the given GUACIO connection. The PNG image
|
* Sends a cursor instruction over the given GUACIO connection. The PNG image
|
||||||
|
@ -47,6 +47,15 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "client-handlers.h"
|
#include "client-handlers.h"
|
||||||
|
|
||||||
|
guac_layer __GUAC_DEFAULT_LAYER = {
|
||||||
|
.index = 0,
|
||||||
|
.next = NULL,
|
||||||
|
.next_available = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const guac_layer* GUAC_DEFAULT_LAYER = &__GUAC_DEFAULT_LAYER;
|
||||||
|
|
||||||
|
|
||||||
guac_client* __guac_alloc_client(GUACIO* io) {
|
guac_client* __guac_alloc_client(GUACIO* io) {
|
||||||
|
|
||||||
/* Allocate new client (not handoff) */
|
/* Allocate new client (not handoff) */
|
||||||
@ -58,9 +67,80 @@ guac_client* __guac_alloc_client(GUACIO* io) {
|
|||||||
client->last_received_timestamp = client->last_sent_timestamp = guac_current_timestamp();
|
client->last_received_timestamp = client->last_sent_timestamp = guac_current_timestamp();
|
||||||
client->state = RUNNING;
|
client->state = RUNNING;
|
||||||
|
|
||||||
|
client->all_layers = NULL;
|
||||||
|
client->available_layers = NULL;
|
||||||
|
client->available_buffers = NULL;
|
||||||
|
|
||||||
|
client->next_buffer_index = -1;
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
allocd_layer->index = index;
|
||||||
|
return allocd_layer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_client_free_layer(guac_client* client, guac_layer* layer) {
|
||||||
|
layer->next = client->available_layers;
|
||||||
|
client->available_layers = layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
guac_layer* guac_client_alloc_buffer(guac_client* client) {
|
||||||
|
|
||||||
|
guac_layer* allocd_layer;
|
||||||
|
|
||||||
|
/* If available layers, pop off first available buffer */
|
||||||
|
if (client->available_buffers != NULL) {
|
||||||
|
allocd_layer = client->available_buffers;
|
||||||
|
client->available_buffers = client->available_buffers->next_available;
|
||||||
|
allocd_layer->next_available = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no available buffer, allocate new buffer, add to all_layers list */
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* Init new layer */
|
||||||
|
allocd_layer = malloc(sizeof(guac_layer));
|
||||||
|
allocd_layer->index = client->next_buffer_index--;
|
||||||
|
|
||||||
|
/* Add to all_layers list */
|
||||||
|
allocd_layer->next = client->all_layers;
|
||||||
|
client->all_layers = allocd_layer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocd_layer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_client_free_buffer(guac_client* client, guac_layer* layer) {
|
||||||
|
layer->next = client->available_buffers;
|
||||||
|
client->available_buffers = layer;
|
||||||
|
}
|
||||||
|
|
||||||
guac_client* guac_get_client(int client_fd) {
|
guac_client* guac_get_client(int client_fd) {
|
||||||
|
|
||||||
@ -254,6 +334,13 @@ void guac_free_client(guac_client* client) {
|
|||||||
guac_log_error("Could not close client plugin while unloading client: %s", dlerror());
|
guac_log_error("Could not close client plugin while unloading client: %s", dlerror());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free all layers */
|
||||||
|
while (client->all_layers != NULL) {
|
||||||
|
guac_layer* layer = client->all_layers;
|
||||||
|
client->all_layers = layer->next;
|
||||||
|
free(layer);
|
||||||
|
}
|
||||||
|
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,12 +273,12 @@ int guac_send_sync(GUACIO* io, guac_timestamp_t timestamp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int guac_send_copy(GUACIO* io,
|
int guac_send_copy(GUACIO* io,
|
||||||
int srcl, int srcx, int srcy, int w, int h,
|
const guac_layer* srcl, int srcx, int srcy, int w, int h,
|
||||||
guac_composite_mode_t mode, int dstl, int dstx, int dsty) {
|
guac_composite_mode_t mode, const guac_layer* dstl, int dstx, int dsty) {
|
||||||
|
|
||||||
return
|
return
|
||||||
guac_write_string(io, "copy:")
|
guac_write_string(io, "copy:")
|
||||||
|| guac_write_int(io, srcl)
|
|| guac_write_int(io, srcl->index)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, srcx)
|
|| guac_write_int(io, srcx)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
@ -290,7 +290,7 @@ int guac_send_copy(GUACIO* io,
|
|||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, mode)
|
|| guac_write_int(io, mode)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, dstl)
|
|| guac_write_int(io, dstl->index)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, dstx)
|
|| guac_write_int(io, dstx)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
@ -311,7 +311,7 @@ cairo_status_t __guac_write_png(void* closure, const unsigned char* data, unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
int guac_send_png(GUACIO* io, guac_composite_mode_t mode,
|
int guac_send_png(GUACIO* io, guac_composite_mode_t mode,
|
||||||
int layer, int x, int y, cairo_surface_t* surface) {
|
const guac_layer* layer, int x, int y, cairo_surface_t* surface) {
|
||||||
|
|
||||||
/* Write instruction and args */
|
/* Write instruction and args */
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ int guac_send_png(GUACIO* io, guac_composite_mode_t mode,
|
|||||||
guac_write_string(io, "png:")
|
guac_write_string(io, "png:")
|
||||||
|| guac_write_int(io, mode)
|
|| guac_write_int(io, mode)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, layer)
|
|| guac_write_int(io, layer->index)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|| guac_write_int(io, x)
|
|| guac_write_int(io, x)
|
||||||
|| guac_write_string(io, ",")
|
|| guac_write_string(io, ",")
|
||||||
|
Loading…
Reference in New Issue
Block a user