GUACAMOLE-176: Support layer location and opacity for guac_common_surface.
This commit is contained in:
parent
a1886f51bd
commit
6bd19b6ac6
@ -118,6 +118,40 @@ typedef struct guac_common_surface {
|
||||
*/
|
||||
guac_socket* socket;
|
||||
|
||||
/**
|
||||
* The X coordinate of the upper-left corner of this layer, in pixels,
|
||||
* relative to its parent layer. This is only applicable to visible
|
||||
* (non-buffer) layers which are not the default layer.
|
||||
*/
|
||||
int x;
|
||||
|
||||
/**
|
||||
* The Y coordinate of the upper-left corner of this layer, in pixels,
|
||||
* relative to its parent layer. This is only applicable to visible
|
||||
* (non-buffer) layers which are not the default layer.
|
||||
*/
|
||||
int y;
|
||||
|
||||
/**
|
||||
* The Z-order of this layer, relative to sibling layers. This is only
|
||||
* applicable to visible (non-buffer) layers which are not the default
|
||||
* layer.
|
||||
*/
|
||||
int z;
|
||||
|
||||
/**
|
||||
* The level of opacity applied to this layer. Fully opaque is 255, while
|
||||
* fully transparent is 0. This is only applicable to visible (non-buffer)
|
||||
* layers which are not the default layer.
|
||||
*/
|
||||
int opacity;
|
||||
|
||||
/**
|
||||
* The layer which contains this layer. This is only applicable to visible
|
||||
* (non-buffer) layers which are not the default layer.
|
||||
*/
|
||||
const guac_layer* parent;
|
||||
|
||||
/**
|
||||
* The width of this layer, in pixels.
|
||||
*/
|
||||
@ -138,6 +172,18 @@ typedef struct guac_common_surface {
|
||||
*/
|
||||
unsigned char* buffer;
|
||||
|
||||
/**
|
||||
* Non-zero if the location or parent layer of this surface has been
|
||||
* changed and needs to be flushed, 0 otherwise.
|
||||
*/
|
||||
int location_dirty;
|
||||
|
||||
/**
|
||||
* Non-zero if the opacity of this surface has been changed and needs to be
|
||||
* flushed, 0 otherwise.
|
||||
*/
|
||||
int opacity_dirty;
|
||||
|
||||
/**
|
||||
* Non-zero if this surface is dirty and needs to be flushed, 0 otherwise.
|
||||
*/
|
||||
@ -317,10 +363,77 @@ void guac_common_surface_clip(guac_common_surface* surface, int x, int y, int w,
|
||||
void guac_common_surface_reset_clip(guac_common_surface* surface);
|
||||
|
||||
/**
|
||||
* Flushes the given surface, drawing any pending operations on the remote
|
||||
* display.
|
||||
* Changes the location of the surface relative to its parent layer. If the
|
||||
* surface does not represent a non-default visible layer, then this function
|
||||
* has no effect.
|
||||
*
|
||||
* @param surface The surface to flush.
|
||||
* @param surface
|
||||
* The surface to move relative to its parent layer.
|
||||
*
|
||||
* @param x
|
||||
* The new X coordinate for the upper-left corner of the layer, in pixels.
|
||||
*
|
||||
* @param y
|
||||
* The new Y coordinate for the upper-left corner of the layer, in pixels.
|
||||
*/
|
||||
void guac_common_surface_move(guac_common_surface* surface, int x, int y);
|
||||
|
||||
/**
|
||||
* Changes the stacking order of the surface relative to other surfaces within
|
||||
* the same parent layer. If the surface does not represent a non-default
|
||||
* visible layer, then this function has no effect.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to reorder relative to sibling layers.
|
||||
*
|
||||
* @param z
|
||||
* The new Z-order for this layer, relative to sibling layers.
|
||||
*/
|
||||
void guac_common_surface_stack(guac_common_surface* surface, int z);
|
||||
|
||||
/**
|
||||
* Changes the parent layer of ths given surface. By default, layers will be
|
||||
* children of the default layer. If the surface does not represent a
|
||||
* non-default visible layer, then this function has no effect.
|
||||
*
|
||||
* @param surface
|
||||
* The surface whose parent layer should be changed.
|
||||
*
|
||||
* @param parent
|
||||
* The layer which should be set as the new parent of the given surface.
|
||||
*/
|
||||
void guac_common_surface_set_parent(guac_common_surface* surface,
|
||||
const guac_layer* parent);
|
||||
|
||||
/**
|
||||
* Sets the opacity of the surface. If the surface does not represent a
|
||||
* non-default visible layer, then this function has no effect.
|
||||
*
|
||||
* @param surface
|
||||
* The surface whose opacity should be changed.
|
||||
*
|
||||
* @param opacity
|
||||
* The level of opacity applied to this surface, where fully opaque is 255,
|
||||
* and fully transparent is 0.
|
||||
*/
|
||||
void guac_common_surface_set_opacity(guac_common_surface* surface, int opacity);
|
||||
|
||||
/**
|
||||
* Flushes only the properties of the given surface, such as layer location or
|
||||
* opacity. Image state is not flushed. If the surface represents a buffer or
|
||||
* the default layer, this function has no effect.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to flush.
|
||||
*/
|
||||
void guac_common_surface_flush_properties(guac_common_surface* surface);
|
||||
|
||||
/**
|
||||
* Flushes the given surface, including any applicable properties, drawing any
|
||||
* pending operations on the remote display.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to flush.
|
||||
*/
|
||||
void guac_common_surface_flush(guac_common_surface* surface);
|
||||
|
||||
|
@ -155,7 +155,17 @@ void guac_common_display_dup(guac_common_display* display, guac_user* user,
|
||||
}
|
||||
|
||||
void guac_common_display_flush(guac_common_display* display) {
|
||||
|
||||
guac_common_display_layer* current = display->layers;
|
||||
|
||||
/* Flush all surfaces */
|
||||
while (current != NULL) {
|
||||
guac_common_surface_flush(current->surface);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
guac_common_surface_flush(display->default_surface);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,6 +116,29 @@
|
||||
*/
|
||||
#define GUAC_SURFACE_WEBP_BLOCK_SIZE 8
|
||||
|
||||
void guac_common_surface_move(guac_common_surface* surface, int x, int y) {
|
||||
surface->x = x;
|
||||
surface->y = y;
|
||||
surface->location_dirty = 1;
|
||||
}
|
||||
|
||||
void guac_common_surface_stack(guac_common_surface* surface, int z) {
|
||||
surface->z = z;
|
||||
surface->location_dirty = 1;
|
||||
}
|
||||
|
||||
void guac_common_surface_set_parent(guac_common_surface* surface,
|
||||
const guac_layer* parent) {
|
||||
surface->parent = parent;
|
||||
surface->location_dirty = 1;
|
||||
}
|
||||
|
||||
void guac_common_surface_set_opacity(guac_common_surface* surface,
|
||||
int opacity) {
|
||||
surface->opacity = opacity;
|
||||
surface->opacity_dirty = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the coordinates of the given rectangle to be within the bounds of
|
||||
* the given surface.
|
||||
@ -990,6 +1013,7 @@ guac_common_surface* guac_common_surface_alloc(guac_client* client,
|
||||
surface->client = client;
|
||||
surface->socket = socket;
|
||||
surface->layer = layer;
|
||||
surface->parent = GUAC_DEFAULT_LAYER;
|
||||
surface->width = w;
|
||||
surface->height = h;
|
||||
|
||||
@ -1443,6 +1467,29 @@ static int __guac_common_surface_bitmap_rect_compare(const void* a, const void*
|
||||
|
||||
}
|
||||
|
||||
void guac_common_surface_flush_properties(guac_common_surface* surface) {
|
||||
|
||||
guac_socket* socket = surface->socket;
|
||||
|
||||
/* Only applicable to non-default visible layers */
|
||||
if (surface->layer->index <= 0)
|
||||
return;
|
||||
|
||||
/* Flush opacity */
|
||||
if (surface->opacity_dirty) {
|
||||
guac_protocol_send_shade(socket, surface->layer, surface->opacity);
|
||||
surface->opacity_dirty = 0;
|
||||
}
|
||||
|
||||
/* Flush location and hierarchy */
|
||||
if (surface->location_dirty) {
|
||||
guac_protocol_send_move(socket, surface->layer,
|
||||
surface->parent, surface->x, surface->y, surface->z);
|
||||
surface->location_dirty = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void guac_common_surface_flush(guac_common_surface* surface) {
|
||||
|
||||
/* Flush final dirty rectangle to queue. */
|
||||
@ -1523,6 +1570,9 @@ void guac_common_surface_flush(guac_common_surface* surface) {
|
||||
|
||||
}
|
||||
|
||||
/* Flush any applicable layer properties */
|
||||
guac_common_surface_flush_properties(surface);
|
||||
|
||||
/* Flush complete */
|
||||
surface->bitmap_queue_length = 0;
|
||||
|
||||
@ -1535,8 +1585,21 @@ void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
|
||||
if (!surface->realized)
|
||||
return;
|
||||
|
||||
/* Synchronize layer-specific properties if applicable */
|
||||
if (surface->layer->index > 0) {
|
||||
|
||||
/* Synchronize opacity */
|
||||
guac_protocol_send_shade(socket, surface->layer, surface->opacity);
|
||||
|
||||
/* Synchronize location and hierarchy */
|
||||
guac_protocol_send_move(socket, surface->layer,
|
||||
surface->parent, surface->x, surface->y, surface->z);
|
||||
|
||||
}
|
||||
|
||||
/* Sync size to new socket */
|
||||
guac_protocol_send_size(socket, surface->layer, surface->width, surface->height);
|
||||
guac_protocol_send_size(socket, surface->layer,
|
||||
surface->width, surface->height);
|
||||
|
||||
/* Get entire surface */
|
||||
cairo_surface_t* rect = cairo_image_surface_create_for_data(
|
||||
|
Loading…
Reference in New Issue
Block a user