From ae7e8d3890e6d08271f87551c4d501f8ff605bb3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 10 Mar 2017 12:28:00 -0800 Subject: [PATCH] GUACAMOLE-231: Report mouse position using new "mouse" instruction. Rely on client-side cursor layer implementation. --- src/common/common/cursor.h | 5 +- src/common/cursor.c | 168 ++++++------------------------------- 2 files changed, 27 insertions(+), 146 deletions(-) diff --git a/src/common/common/cursor.h b/src/common/common/cursor.h index 86a7f14a..00bc48e7 100644 --- a/src/common/common/cursor.h +++ b/src/common/common/cursor.h @@ -45,10 +45,9 @@ typedef struct guac_common_cursor { guac_client* client; /** - * The cursor layer. This layer will be available to all connected users, - * but will be visible only to those users who are not moving the mouse. + * The buffer containing the current cursor image. */ - guac_layer* layer; + guac_layer* buffer; /** * The width of the cursor image, in pixels. diff --git a/src/common/cursor.c b/src/common/cursor.c index e63ada10..0384ea36 100644 --- a/src/common/cursor.c +++ b/src/common/cursor.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -41,9 +40,9 @@ guac_common_cursor* guac_common_cursor_alloc(guac_client* client) { if (cursor == NULL) return NULL; - /* Associate cursor with client and allocate cursor layer */ + /* Associate cursor with client and allocate cursor buffer */ cursor->client = client; - cursor->layer= guac_client_alloc_layer(client); + cursor->buffer = guac_client_alloc_buffer(client); /* Allocate initial image buffer */ cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE; @@ -70,7 +69,7 @@ guac_common_cursor* guac_common_cursor_alloc(guac_client* client) { void guac_common_cursor_free(guac_common_cursor* cursor) { guac_client* client = cursor->client; - guac_layer* layer = cursor->layer; + guac_layer* buffer = cursor->buffer; cairo_surface_t* surface = cursor->surface; /* Free image buffer and surface */ @@ -78,11 +77,11 @@ void guac_common_cursor_free(guac_common_cursor* cursor) { if (surface != NULL) cairo_surface_destroy(surface); - /* Destroy layer within remotely-connected client */ - guac_protocol_send_dispose(client->socket, layer); + /* Destroy buffer within remotely-connected client */ + guac_protocol_send_dispose(client->socket, buffer); - /* Return layer to pool */ - guac_client_free_layer(client, layer); + /* Return buffer to pool */ + guac_client_free_buffer(client, buffer); free(cursor); @@ -92,89 +91,37 @@ void guac_common_cursor_dup(guac_common_cursor* cursor, guac_user* user, guac_socket* socket) { /* Synchronize location */ - guac_protocol_send_move(socket, cursor->layer, GUAC_DEFAULT_LAYER, - cursor->x - cursor->hotspot_x, - cursor->y - cursor->hotspot_y, - INT_MAX); + guac_protocol_send_mouse(socket, cursor->x, cursor->y); /* Synchronize cursor image */ if (cursor->surface != NULL) { - guac_protocol_send_size(socket, cursor->layer, + guac_protocol_send_size(socket, cursor->buffer, cursor->width, cursor->height); guac_user_stream_png(user, socket, GUAC_COMP_SRC, - cursor->layer, 0, 0, cursor->surface); + cursor->buffer, 0, 0, cursor->surface); + + guac_protocol_send_cursor(socket, + cursor->hotspot_x, cursor->hotspot_y, + cursor->buffer, 0, 0, cursor->width, cursor->height); } guac_socket_flush(socket); } -/** - * Callback for guac_client_for_user() which shows the cursor layer for the - * given user (if they exist). The cursor layer is normally hidden when a user - * is moving the mouse, and will only be shown if a DIFFERENT user is moving - * the mouse. - * - * @param user - * The user to show the cursor to, or NULL if that user does not exist. - * - * @param data - * A pointer to the guac_common_cursor structure describing the cursor to - * be shown. - * - * @return - * Always NULL. - */ -static void* guac_common_cursor_show(guac_user* user, void* data) { - - guac_common_cursor* cursor = (guac_common_cursor*) data; - - /* Make cursor layer visible to given user */ - if (user != NULL) { - guac_protocol_send_shade(user->socket, cursor->layer, 255); - guac_socket_flush(user->socket); - } - - return NULL; - -} - void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user, int x, int y) { - guac_user* last_user = cursor->user; - /* Update current user of cursor */ - if (last_user != user) { - - cursor->user = user; - - /* Make cursor layer visible to previous user */ - guac_client_for_user(cursor->client, last_user, - guac_common_cursor_show, cursor); - - /* Show hardware cursor */ - guac_protocol_send_cursor(user->socket, - cursor->hotspot_x, cursor->hotspot_y, - cursor->layer, 0, 0, cursor->width, cursor->height); - - /* Hide cursor layer from new user */ - guac_protocol_send_shade(user->socket, cursor->layer, 0); - guac_socket_flush(user->socket); - - } + cursor->user = user; /* Update cursor position */ cursor->x = x; cursor->y = y; - guac_protocol_send_move(cursor->client->socket, cursor->layer, - GUAC_DEFAULT_LAYER, - x - cursor->hotspot_x, - y - cursor->hotspot_y, - INT_MAX); - + /* Notify of change in cursor position */ + guac_protocol_send_mouse(cursor->client->socket, x, y); guac_socket_flush(cursor->client->socket); } @@ -217,65 +164,6 @@ static void guac_common_cursor_resize(guac_common_cursor* cursor, } -/** - * Callback for guac_client_foreach_user() which sends the current cursor image - * as PNG data to each connected client. - * - * @param user - * The user to send the cursor image to. - * - * @param data - * A pointer to the guac_common_cursor structure containing the cursor - * image that should be sent to the given user. - * - * @return - * Always NULL. - */ -static void* __send_user_cursor_image(guac_user* user, void* data) { - - guac_common_cursor* cursor = (guac_common_cursor*) data; - - guac_user_stream_png(user, user->socket, GUAC_COMP_SRC, - cursor->layer, 0, 0, cursor->surface); - - return NULL; - -} - -/** - * Callback for guac_client_for_user() which updates the hardware cursor and - * hotspot for the given user (if they exist). The hardware cursor image is - * normally hidden when a user is not moving the mouse, and will only be shown - * if that user begins moving the mouse. - * - * @param user - * The user whose hardware cursor should be updated, or NULL if that user - * does not exist. - * - * @param data - * A pointer to the guac_common_cursor structure describing the cursor to - * be sent as the hardware cursor. - * - * @return - * Always NULL. - */ -static void* guac_common_cursor_update(guac_user* user, void* data) { - - guac_common_cursor* cursor = (guac_common_cursor*) data; - - /* Update hardware cursor of current user */ - if (user != NULL) { - guac_protocol_send_cursor(user->socket, - cursor->hotspot_x, cursor->hotspot_y, - cursor->layer, 0, 0, cursor->width, cursor->height); - - guac_socket_flush(user->socket); - } - - return NULL; - -} - void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy, unsigned const char* data, int width, int height, int stride) { @@ -295,26 +183,20 @@ void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy, cursor->hotspot_x = hx; cursor->hotspot_y = hy; - /* Update location based on new hotspot */ - guac_protocol_send_move(cursor->client->socket, cursor->layer, - GUAC_DEFAULT_LAYER, - cursor->x - hx, - cursor->y - hy, - INT_MAX); - /* Broadcast new cursor image to all users */ - guac_protocol_send_size(cursor->client->socket, cursor->layer, + guac_protocol_send_size(cursor->client->socket, cursor->buffer, width, height); - guac_client_foreach_user(cursor->client, __send_user_cursor_image, cursor); + guac_client_stream_png(cursor->client, cursor->client->socket, + GUAC_COMP_SRC, cursor->buffer, 0, 0, cursor->surface); + + /* Update cursor image */ + guac_protocol_send_cursor(cursor->client->socket, + cursor->hotspot_x, cursor->hotspot_y, + cursor->buffer, 0, 0, cursor->width, cursor->height); guac_socket_flush(cursor->client->socket); - /* Update hardware cursor of current user (if they are indeed valid) */ - if (cursor->user != NULL) - guac_client_for_user(cursor->client, cursor->user, - guac_common_cursor_update, cursor); - } void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,