Merge 0.9.12-incubating changes back to master.
This commit is contained in:
commit
2c2824fc5b
@ -45,10 +45,9 @@ typedef struct guac_common_cursor {
|
|||||||
guac_client* client;
|
guac_client* client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cursor layer. This layer will be available to all connected users,
|
* The buffer containing the current cursor image.
|
||||||
* but will be visible only to those users who are not moving the mouse.
|
|
||||||
*/
|
*/
|
||||||
guac_layer* layer;
|
guac_layer* buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the cursor image, in pixels.
|
* The width of the cursor image, in pixels.
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/layer.h>
|
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
#include <guacamole/user.h>
|
#include <guacamole/user.h>
|
||||||
@ -41,9 +40,9 @@ guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
|
|||||||
if (cursor == NULL)
|
if (cursor == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Associate cursor with client and allocate cursor layer */
|
/* Associate cursor with client and allocate cursor buffer */
|
||||||
cursor->client = client;
|
cursor->client = client;
|
||||||
cursor->layer= guac_client_alloc_layer(client);
|
cursor->buffer = guac_client_alloc_buffer(client);
|
||||||
|
|
||||||
/* Allocate initial image buffer */
|
/* Allocate initial image buffer */
|
||||||
cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE;
|
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) {
|
void guac_common_cursor_free(guac_common_cursor* cursor) {
|
||||||
|
|
||||||
guac_client* client = cursor->client;
|
guac_client* client = cursor->client;
|
||||||
guac_layer* layer = cursor->layer;
|
guac_layer* buffer = cursor->buffer;
|
||||||
cairo_surface_t* surface = cursor->surface;
|
cairo_surface_t* surface = cursor->surface;
|
||||||
|
|
||||||
/* Free image buffer and surface */
|
/* Free image buffer and surface */
|
||||||
@ -78,11 +77,11 @@ void guac_common_cursor_free(guac_common_cursor* cursor) {
|
|||||||
if (surface != NULL)
|
if (surface != NULL)
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
/* Destroy layer within remotely-connected client */
|
/* Destroy buffer within remotely-connected client */
|
||||||
guac_protocol_send_dispose(client->socket, layer);
|
guac_protocol_send_dispose(client->socket, buffer);
|
||||||
|
|
||||||
/* Return layer to pool */
|
/* Return buffer to pool */
|
||||||
guac_client_free_layer(client, layer);
|
guac_client_free_buffer(client, buffer);
|
||||||
|
|
||||||
free(cursor);
|
free(cursor);
|
||||||
|
|
||||||
@ -92,18 +91,19 @@ void guac_common_cursor_dup(guac_common_cursor* cursor, guac_user* user,
|
|||||||
guac_socket* socket) {
|
guac_socket* socket) {
|
||||||
|
|
||||||
/* Synchronize location */
|
/* Synchronize location */
|
||||||
guac_protocol_send_move(socket, cursor->layer, GUAC_DEFAULT_LAYER,
|
guac_protocol_send_mouse(socket, cursor->x, cursor->y);
|
||||||
cursor->x - cursor->hotspot_x,
|
|
||||||
cursor->y - cursor->hotspot_y,
|
|
||||||
INT_MAX);
|
|
||||||
|
|
||||||
/* Synchronize cursor image */
|
/* Synchronize cursor image */
|
||||||
if (cursor->surface != NULL) {
|
if (cursor->surface != NULL) {
|
||||||
guac_protocol_send_size(socket, cursor->layer,
|
guac_protocol_send_size(socket, cursor->buffer,
|
||||||
cursor->width, cursor->height);
|
cursor->width, cursor->height);
|
||||||
|
|
||||||
guac_user_stream_png(user, socket, GUAC_COMP_SRC,
|
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);
|
guac_socket_flush(socket);
|
||||||
@ -111,28 +111,24 @@ void guac_common_cursor_dup(guac_common_cursor* cursor, guac_user* user,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for guac_client_for_user() which shows the cursor layer for the
|
* Callback for guac_client_foreach_user() which sends the current cursor
|
||||||
* given user (if they exist). The cursor layer is normally hidden when a user
|
* position to any given user except the user that moved the cursor last.
|
||||||
* 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
|
* @param data
|
||||||
* A pointer to the guac_common_cursor structure describing the cursor to
|
* A pointer to the guac_common_cursor whose position should be broadcast
|
||||||
* be shown.
|
* to all users except the user that moved the cursor last.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Always NULL.
|
* Always NULL.
|
||||||
*/
|
*/
|
||||||
static void* guac_common_cursor_show(guac_user* user, void* data) {
|
static void* guac_common_cursor_broadcast_position(guac_user* user,
|
||||||
|
void* data) {
|
||||||
|
|
||||||
guac_common_cursor* cursor = (guac_common_cursor*) data;
|
guac_common_cursor* cursor = (guac_common_cursor*) data;
|
||||||
|
|
||||||
/* Make cursor layer visible to given user */
|
/* Send cursor position only if the user is not moving the cursor */
|
||||||
if (user != NULL) {
|
if (user != cursor->user) {
|
||||||
guac_protocol_send_shade(user->socket, cursor->layer, 255);
|
guac_protocol_send_mouse(user->socket, cursor->x, cursor->y);
|
||||||
guac_socket_flush(user->socket);
|
guac_socket_flush(user->socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,39 +139,16 @@ static void* guac_common_cursor_show(guac_user* user, void* data) {
|
|||||||
void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
|
void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
|
||||||
int x, int y) {
|
int x, int y) {
|
||||||
|
|
||||||
guac_user* last_user = cursor->user;
|
|
||||||
|
|
||||||
/* Update current user of cursor */
|
/* Update current user of cursor */
|
||||||
if (last_user != user) {
|
cursor->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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update cursor position */
|
/* Update cursor position */
|
||||||
cursor->x = x;
|
cursor->x = x;
|
||||||
cursor->y = y;
|
cursor->y = y;
|
||||||
|
|
||||||
guac_protocol_send_move(cursor->client->socket, cursor->layer,
|
/* Notify all other users of change in cursor position */
|
||||||
GUAC_DEFAULT_LAYER,
|
guac_client_foreach_user(cursor->client,
|
||||||
x - cursor->hotspot_x,
|
guac_common_cursor_broadcast_position, cursor);
|
||||||
y - cursor->hotspot_y,
|
|
||||||
INT_MAX);
|
|
||||||
|
|
||||||
guac_socket_flush(cursor->client->socket);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,65 +190,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,
|
void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
|
||||||
unsigned const char* data, int width, int height, int stride) {
|
unsigned const char* data, int width, int height, int stride) {
|
||||||
|
|
||||||
@ -295,26 +209,20 @@ void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
|
|||||||
cursor->hotspot_x = hx;
|
cursor->hotspot_x = hx;
|
||||||
cursor->hotspot_y = hy;
|
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 */
|
/* 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);
|
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);
|
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,
|
void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,
|
||||||
|
@ -144,6 +144,26 @@ int guac_protocol_send_log(guac_socket* socket, const char* format, ...);
|
|||||||
int vguac_protocol_send_log(guac_socket* socket, const char* format,
|
int vguac_protocol_send_log(guac_socket* socket, const char* format,
|
||||||
va_list args);
|
va_list args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a mouse instruction over the given guac_socket connection.
|
||||||
|
*
|
||||||
|
* If an error occurs sending the instruction, a non-zero value is
|
||||||
|
* returned, and guac_error is set appropriately.
|
||||||
|
*
|
||||||
|
* @param socket
|
||||||
|
* The guac_socket connection to use.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* The X coordinate of the current mouse position.
|
||||||
|
*
|
||||||
|
* @param y
|
||||||
|
* The Y coordinate of the current mouse position.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int guac_protocol_send_mouse(guac_socket* socket, int x, int y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a nest instruction over the given guac_socket connection.
|
* Sends a nest instruction over the given guac_socket connection.
|
||||||
*
|
*
|
||||||
|
@ -684,6 +684,23 @@ int guac_protocol_send_lstroke(guac_socket* socket,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guac_protocol_send_mouse(guac_socket* socket, int x, int y) {
|
||||||
|
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
guac_socket_instruction_begin(socket);
|
||||||
|
ret_val =
|
||||||
|
guac_socket_write_string(socket, "5.mouse,")
|
||||||
|
|| __guac_socket_write_length_int(socket, x)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_int(socket, y)
|
||||||
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
|
guac_socket_instruction_end(socket);
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int guac_protocol_send_move(guac_socket* socket, const guac_layer* layer,
|
int guac_protocol_send_move(guac_socket* socket, const guac_layer* layer,
|
||||||
const guac_layer* parent, int x, int y, int z) {
|
const guac_layer* parent, int x, int y, int z) {
|
||||||
|
|
||||||
|
@ -1746,7 +1746,6 @@ int guac_terminal_send_mouse(guac_terminal* term, guac_user* user,
|
|||||||
result = __guac_terminal_send_mouse(term, user, x, y, mask);
|
result = __guac_terminal_send_mouse(term, user, x, y, mask);
|
||||||
guac_terminal_unlock(term);
|
guac_terminal_unlock(term);
|
||||||
|
|
||||||
guac_terminal_notify(term);
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user