GUACAMOLE-377: Remove all old surface, display, cursor, and rect code from src/common/.
This commit is contained in:
parent
c48409c352
commit
de30928a4d
@ -31,36 +31,20 @@ SUBDIRS = . tests
|
||||
|
||||
noinst_HEADERS = \
|
||||
common/io.h \
|
||||
common/blank_cursor.h \
|
||||
common/clipboard.h \
|
||||
common/cursor.h \
|
||||
common/defaults.h \
|
||||
common/display.h \
|
||||
common/dot_cursor.h \
|
||||
common/ibar_cursor.h \
|
||||
common/iconv.h \
|
||||
common/json.h \
|
||||
common/list.h \
|
||||
common/pointer_cursor.h \
|
||||
common/rect.h \
|
||||
common/string.h \
|
||||
common/surface.h
|
||||
common/string.h
|
||||
|
||||
libguac_common_la_SOURCES = \
|
||||
io.c \
|
||||
blank_cursor.c \
|
||||
clipboard.c \
|
||||
cursor.c \
|
||||
display.c \
|
||||
dot_cursor.c \
|
||||
ibar_cursor.c \
|
||||
iconv.c \
|
||||
json.c \
|
||||
list.c \
|
||||
pointer_cursor.c \
|
||||
rect.c \
|
||||
string.c \
|
||||
surface.c
|
||||
string.c
|
||||
|
||||
libguac_common_la_CFLAGS = \
|
||||
-Werror -Wall -pedantic \
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/layer.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/* Dimensions */
|
||||
const int guac_common_blank_cursor_width = 1;
|
||||
const int guac_common_blank_cursor_height = 1;
|
||||
|
||||
/* Format */
|
||||
const cairo_format_t guac_common_blank_cursor_format = CAIRO_FORMAT_ARGB32;
|
||||
const int guac_common_blank_cursor_stride = 4;
|
||||
|
||||
/* Embedded blank cursor graphic */
|
||||
unsigned char guac_common_blank_cursor[] = {
|
||||
|
||||
0x00,0x00,0x00,0x00
|
||||
|
||||
};
|
||||
|
||||
void guac_common_set_blank_cursor(guac_user* user) {
|
||||
|
||||
guac_client* client = user->client;
|
||||
guac_socket* socket = user->socket;
|
||||
|
||||
/* Draw to buffer */
|
||||
guac_layer* cursor = guac_client_alloc_buffer(client);
|
||||
|
||||
cairo_surface_t* graphic = cairo_image_surface_create_for_data(
|
||||
guac_common_blank_cursor,
|
||||
guac_common_blank_cursor_format,
|
||||
guac_common_blank_cursor_width,
|
||||
guac_common_blank_cursor_height,
|
||||
guac_common_blank_cursor_stride);
|
||||
|
||||
guac_user_stream_png(user, socket, GUAC_COMP_SRC, cursor,
|
||||
0, 0, graphic);
|
||||
cairo_surface_destroy(graphic);
|
||||
|
||||
/* Set cursor */
|
||||
guac_protocol_send_cursor(socket, 0, 0, cursor, 0, 0,
|
||||
guac_common_blank_cursor_width,
|
||||
guac_common_blank_cursor_height);
|
||||
|
||||
/* Free buffer */
|
||||
guac_client_free_buffer(client, cursor);
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Client cursor image set to generic transparent (blank) cursor.");
|
||||
|
||||
}
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_COMMON_BLANK_CURSOR_H
|
||||
#define GUAC_COMMON_BLANK_CURSOR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* Width of the embedded transparent (blank) mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_blank_cursor_width;
|
||||
|
||||
/**
|
||||
* Height of the embedded transparent (blank) mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_blank_cursor_height;
|
||||
|
||||
/**
|
||||
* Number of bytes in each row of the embedded transparent (blank) mouse cursor
|
||||
* graphic.
|
||||
*/
|
||||
extern const int guac_common_blank_cursor_stride;
|
||||
|
||||
/**
|
||||
* The Cairo grapic format of the transparent (blank) mouse cursor graphic.
|
||||
*/
|
||||
extern const cairo_format_t guac_common_blank_cursor_format;
|
||||
|
||||
/**
|
||||
* Embedded transparent (blank) mouse cursor graphic.
|
||||
*/
|
||||
extern unsigned char guac_common_blank_cursor[];
|
||||
|
||||
/**
|
||||
* Sets the cursor of the remote display to the embedded transparent (blank)
|
||||
* cursor graphic.
|
||||
*
|
||||
* @param user
|
||||
* The guac_user to send the cursor to.
|
||||
*/
|
||||
void guac_common_set_blank_cursor(guac_user* user);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,307 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_COMMON_CURSOR_H
|
||||
#define GUAC_COMMON_CURSOR_H
|
||||
|
||||
#include "surface.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* The default size of the cursor image buffer.
|
||||
*/
|
||||
#define GUAC_COMMON_CURSOR_DEFAULT_SIZE 64*64*4
|
||||
|
||||
/**
|
||||
* Cursor object which maintains and synchronizes the current mouse cursor
|
||||
* state across all users of a specific client.
|
||||
*/
|
||||
typedef struct guac_common_cursor {
|
||||
|
||||
/**
|
||||
* The client to maintain the mouse cursor for.
|
||||
*/
|
||||
guac_client* client;
|
||||
|
||||
/**
|
||||
* The buffer containing the current cursor image.
|
||||
*/
|
||||
guac_layer* buffer;
|
||||
|
||||
/**
|
||||
* The width of the cursor image, in pixels.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* The height of the cursor image, in pixels.
|
||||
*/
|
||||
int height;
|
||||
|
||||
/**
|
||||
* Arbitrary image data buffer, backing the Cairo surface used to store
|
||||
* the cursor image.
|
||||
*/
|
||||
unsigned char* image_buffer;
|
||||
|
||||
/**
|
||||
* The size of the image data buffer, in bytes.
|
||||
*/
|
||||
size_t image_buffer_size;
|
||||
|
||||
/**
|
||||
* The current cursor image, if any. If the mouse cursor has not yet been
|
||||
* set, this will be NULL.
|
||||
*/
|
||||
cairo_surface_t* surface;
|
||||
|
||||
/**
|
||||
* The X coordinate of the hotspot of the mouse cursor.
|
||||
*/
|
||||
int hotspot_x;
|
||||
|
||||
/**
|
||||
* The Y coordinate of the hotspot of the mouse cursor.
|
||||
*/
|
||||
int hotspot_y;
|
||||
|
||||
/**
|
||||
* The last user to move the mouse, or NULL if no user has moved the
|
||||
* mouse yet.
|
||||
*/
|
||||
guac_user* user;
|
||||
|
||||
/**
|
||||
* The X coordinate of the current mouse cursor location.
|
||||
*/
|
||||
int x;
|
||||
|
||||
/**
|
||||
* The Y coordinate of the current mouse cursor location.
|
||||
*/
|
||||
int y;
|
||||
|
||||
/**
|
||||
* An integer value representing the current state of each button, where
|
||||
* the Nth bit within the integer is set to 1 if and only if the Nth mouse
|
||||
* button is currently pressed. The lowest-order bit is the left mouse
|
||||
* button, followed by the middle button, right button, and finally the up
|
||||
* and down buttons of the scroll wheel.
|
||||
*
|
||||
* @see GUAC_CLIENT_MOUSE_LEFT
|
||||
* @see GUAC_CLIENT_MOUSE_MIDDLE
|
||||
* @see GUAC_CLIENT_MOUSE_RIGHT
|
||||
* @see GUAC_CLIENT_MOUSE_SCROLL_UP
|
||||
* @see GUAC_CLIENT_MOUSE_SCROLL_DOWN
|
||||
*/
|
||||
int button_mask;
|
||||
|
||||
/**
|
||||
* The server timestamp representing the point in time when the mouse
|
||||
* location was last updated.
|
||||
*/
|
||||
guac_timestamp timestamp;
|
||||
|
||||
/**
|
||||
* Lock which restricts simultaneous access to the cursor, guaranteeing
|
||||
* ordered modifications to the cursor and that incompatible operations
|
||||
* do not occur simultaneously. This lock is for internal use within the
|
||||
* cursor only.
|
||||
*/
|
||||
pthread_mutex_t _lock;
|
||||
|
||||
} guac_common_cursor;
|
||||
|
||||
/**
|
||||
* Allocates a new cursor object which maintains and synchronizes the current
|
||||
* mouse cursor state across all users of the given client.
|
||||
*
|
||||
* @param client
|
||||
* The client for which this object shall maintain the mouse cursor.
|
||||
*
|
||||
* @return
|
||||
* The newly-allocated mouse cursor.
|
||||
*/
|
||||
guac_common_cursor* guac_common_cursor_alloc(guac_client* client);
|
||||
|
||||
/**
|
||||
* Frees the given cursor.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to free.
|
||||
*/
|
||||
void guac_common_cursor_free(guac_common_cursor* cursor);
|
||||
|
||||
/**
|
||||
* Sends the current state of this cursor across the given socket, including
|
||||
* the current cursor image. The resulting cursor on the remote display will
|
||||
* be visible.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to send.
|
||||
*
|
||||
* @param client
|
||||
* The user receiving the updated cursor.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which the updated cursor should be sent.
|
||||
*/
|
||||
void guac_common_cursor_dup(
|
||||
guac_common_cursor* cursor, guac_client* client, guac_socket* socket);
|
||||
|
||||
/**
|
||||
* Updates the current position and button state of the mouse cursor, marking
|
||||
* the given user as the most recent user of the mouse. The remote mouse cursor
|
||||
* will be hidden for this user and shown for all others.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor being updated.
|
||||
*
|
||||
* @param user
|
||||
* The user that moved the cursor.
|
||||
*
|
||||
* @param x
|
||||
* The new X coordinate of the cursor.
|
||||
*
|
||||
* @param y
|
||||
* The new Y coordinate of the cursor.
|
||||
*
|
||||
* @param button_mask
|
||||
* An integer value representing the current state of each button, where
|
||||
* the Nth bit within the integer is set to 1 if and only if the Nth mouse
|
||||
* button is currently pressed. The lowest-order bit is the left mouse
|
||||
* button, followed by the middle button, right button, and finally the up
|
||||
* and down buttons of the scroll wheel.
|
||||
*
|
||||
* @see GUAC_CLIENT_MOUSE_LEFT
|
||||
* @see GUAC_CLIENT_MOUSE_MIDDLE
|
||||
* @see GUAC_CLIENT_MOUSE_RIGHT
|
||||
* @see GUAC_CLIENT_MOUSE_SCROLL_UP
|
||||
* @see GUAC_CLIENT_MOUSE_SCROLL_DOWN
|
||||
*/
|
||||
void guac_common_cursor_update(guac_common_cursor* cursor, guac_user* user,
|
||||
int x, int y, int button_mask);
|
||||
|
||||
/**
|
||||
* Sets the cursor image to the given raw image data. This raw image data must
|
||||
* be in 32-bit ARGB format, having 8 bits per color component, where the
|
||||
* alpha component is stored in the high-order 8 bits, and blue is stored
|
||||
* in the low-order 8 bits.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*
|
||||
* @param hx
|
||||
* The X coordinate of the hotspot of the new cursor image.
|
||||
*
|
||||
* @param hy
|
||||
* The Y coordinate of the hotspot of the new cursor image.
|
||||
*
|
||||
* @param data
|
||||
* A pointer to raw 32-bit ARGB image data.
|
||||
*
|
||||
* @param width
|
||||
* The width of the given image data, in pixels.
|
||||
*
|
||||
* @param height
|
||||
* The height of the given image data, in pixels.
|
||||
*
|
||||
* @param stride
|
||||
* The number of bytes in a single row of image data.
|
||||
*/
|
||||
void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
|
||||
unsigned const char* data, int width, int height, int stride);
|
||||
|
||||
/**
|
||||
* Sets the cursor image to the contents of the given surface. The entire
|
||||
* contents of the surface are used, and the dimensions of the resulting
|
||||
* cursor will be the dimensions of the given surface.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*
|
||||
* @param hx
|
||||
* The X coordinate of the hotspot of the new cursor image.
|
||||
*
|
||||
* @param hy
|
||||
* The Y coordinate of the hotspot of the new cursor image.
|
||||
*
|
||||
* @param surface
|
||||
* The surface containing the cursor image.
|
||||
*/
|
||||
void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,
|
||||
guac_common_surface* surface);
|
||||
|
||||
/**
|
||||
* Set the cursor of the remote display to the embedded "pointer" graphic. The
|
||||
* pointer graphic is a black arrow with white border.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*/
|
||||
void guac_common_cursor_set_pointer(guac_common_cursor* cursor);
|
||||
|
||||
/**
|
||||
* Set the cursor of the remote display to the embedded "dot" graphic. The dot
|
||||
* graphic is a small black square with white border.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*/
|
||||
void guac_common_cursor_set_dot(guac_common_cursor* cursor);
|
||||
|
||||
/**
|
||||
* Sets the cursor of the remote display to the embedded "I-bar" graphic. The
|
||||
* I-bar graphic is a small black "I" shape with white border, used to indicate
|
||||
* the presence of selectable or editable text.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*/
|
||||
void guac_common_cursor_set_ibar(guac_common_cursor* cursor);
|
||||
|
||||
/**
|
||||
* Sets the cursor of the remote display to the embedded transparent (blank)
|
||||
* graphic, effectively hiding the mouse cursor.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to set the image of.
|
||||
*/
|
||||
void guac_common_cursor_set_blank(guac_common_cursor* cursor);
|
||||
|
||||
/**
|
||||
* Removes the given user, such that future synchronization will not occur.
|
||||
* This is necessary when a user leaves the connection. If a user leaves the
|
||||
* connection and this is not called, the mouse cursor state may not update
|
||||
* correctly in response to mouse events.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor to remove the user from.
|
||||
*
|
||||
* @param user
|
||||
* The user to remove.
|
||||
*/
|
||||
void guac_common_cursor_remove_user(guac_common_cursor* cursor,
|
||||
guac_user* user);
|
||||
|
||||
#endif
|
||||
@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_COMMON_DISPLAY_H
|
||||
#define GUAC_COMMON_DISPLAY_H
|
||||
|
||||
#include "cursor.h"
|
||||
#include "surface.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* The minimum display size (height or width) in pixels.
|
||||
*/
|
||||
#define GUAC_COMMON_DISPLAY_MIN_SIZE 200
|
||||
|
||||
/**
|
||||
* The maximum display size (height or width) in pixels.
|
||||
*/
|
||||
#define GUAC_COMMON_DISPLAY_MAX_SIZE 8192
|
||||
|
||||
/**
|
||||
* The minimum amount of time that must elapse between display size updates,
|
||||
* in milliseconds.
|
||||
*/
|
||||
#define GUAC_COMMON_DISPLAY_UPDATE_INTERVAL 500
|
||||
|
||||
/**
|
||||
* A list element representing a pairing of a Guacamole layer with a
|
||||
* corresponding guac_common_surface which wraps that layer. Adjacent layers
|
||||
* within the same list are pointed to with traditional prev/next pointers. The
|
||||
* order of layers in lists need not correspond in any way to the natural
|
||||
* ordering of those layers' indexes nor their stacking order (Z-order) within
|
||||
* the display.
|
||||
*/
|
||||
typedef struct guac_common_display_layer guac_common_display_layer;
|
||||
|
||||
struct guac_common_display_layer {
|
||||
|
||||
/**
|
||||
* A Guacamole layer.
|
||||
*/
|
||||
guac_layer* layer;
|
||||
|
||||
/**
|
||||
* The surface which wraps the associated layer.
|
||||
*/
|
||||
guac_common_surface* surface;
|
||||
|
||||
/**
|
||||
* The layer immediately prior to this layer within the list containing
|
||||
* this layer, or NULL if this is the first layer/buffer in the list.
|
||||
*/
|
||||
guac_common_display_layer* prev;
|
||||
|
||||
/**
|
||||
* The layer immediately following this layer within the list containing
|
||||
* this layer, or NULL if this is the last layer/buffer in the list.
|
||||
*/
|
||||
guac_common_display_layer* next;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstracts a remote Guacamole display, having an associated client,
|
||||
* default surface, mouse cursor, and various allocated buffers and layers.
|
||||
*/
|
||||
typedef struct guac_common_display {
|
||||
|
||||
/**
|
||||
* The client associate with this display.
|
||||
*/
|
||||
guac_client* client;
|
||||
|
||||
/**
|
||||
* The default surface of the client display.
|
||||
*/
|
||||
guac_common_surface* default_surface;
|
||||
|
||||
/**
|
||||
* Client-wide cursor, synchronized across all users.
|
||||
*/
|
||||
guac_common_cursor* cursor;
|
||||
|
||||
/**
|
||||
* The first element within a linked list of all currently-allocated
|
||||
* layers, or NULL if no layers are currently allocated. The default layer,
|
||||
* layer #0, is stored within default_surface and will not have a
|
||||
* corresponding element within this list.
|
||||
*/
|
||||
guac_common_display_layer* layers;
|
||||
|
||||
/**
|
||||
* The first element within a linked list of all currently-allocated
|
||||
* buffers, or NULL if no buffers are currently allocated.
|
||||
*/
|
||||
guac_common_display_layer* buffers;
|
||||
|
||||
/**
|
||||
* Non-zero if all graphical updates for this display should use lossless
|
||||
* compression, 0 otherwise. By default, newly-created displays will use
|
||||
* lossy compression when heuristics determine it is appropriate.
|
||||
*/
|
||||
int lossless;
|
||||
|
||||
/**
|
||||
* Mutex which is locked internally when access to the display must be
|
||||
* synchronized. All public functions of guac_common_display should be
|
||||
* considered threadsafe.
|
||||
*/
|
||||
pthread_mutex_t _lock;
|
||||
|
||||
} guac_common_display;
|
||||
|
||||
/**
|
||||
* Allocates a new display, abstracting the cursor and buffer/layer allocation
|
||||
* operations of the given guac_client such that client state can be easily
|
||||
* synchronized to joining users.
|
||||
*
|
||||
* @param client
|
||||
* The guac_client to associate with this display.
|
||||
*
|
||||
* @param width
|
||||
* The initial width of the display, in pixels.
|
||||
*
|
||||
* @param height
|
||||
* The initial height of the display, in pixels.
|
||||
*
|
||||
* @return
|
||||
* The newly-allocated display.
|
||||
*/
|
||||
guac_common_display* guac_common_display_alloc(guac_client* client,
|
||||
int width, int height);
|
||||
|
||||
/**
|
||||
* Fits a given dimension within the allowed bounds for display sizing,
|
||||
* adjusting the other dimension such that aspect ratio is maintained.
|
||||
*
|
||||
* @param a
|
||||
* The dimension to fit within allowed bounds.
|
||||
*
|
||||
* @param b
|
||||
* The other dimension to adjust if and only if necessary to preserve
|
||||
* aspect ratio.
|
||||
*/
|
||||
void guac_common_display_fit(int* a, int* b);
|
||||
|
||||
/**
|
||||
* Frees the given display, and any associated resources, including any
|
||||
* allocated buffers/layers.
|
||||
*
|
||||
* @param display
|
||||
* The display to free.
|
||||
*/
|
||||
void guac_common_display_free(guac_common_display* display);
|
||||
|
||||
/**
|
||||
* Duplicates the state of the given display to the given socket. Any pending
|
||||
* changes to buffers, layers, or the default layer are not flushed.
|
||||
*
|
||||
* @param display
|
||||
* The display whose state should be sent along the given socket.
|
||||
*
|
||||
* @param client
|
||||
* The client associated with the users receiving the display state.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which the display state should be sent.
|
||||
*/
|
||||
void guac_common_display_dup(
|
||||
guac_common_display* display, guac_client* client,
|
||||
guac_socket* socket);
|
||||
|
||||
/**
|
||||
* Flushes pending changes to the given display. All pending operations will
|
||||
* become visible to any connected users.
|
||||
*
|
||||
* @param display
|
||||
* The display to flush.
|
||||
*/
|
||||
void guac_common_display_flush(guac_common_display* display);
|
||||
|
||||
/**
|
||||
* Allocates a new layer, returning a new wrapped layer and corresponding
|
||||
* surface. The layer may be reused from a previous allocation, if that layer
|
||||
* has since been freed.
|
||||
*
|
||||
* @param display
|
||||
* The display to allocate a new layer from.
|
||||
*
|
||||
* @param width
|
||||
* The width of the layer to allocate, in pixels.
|
||||
*
|
||||
* @param height
|
||||
* The height of the layer to allocate, in pixels.
|
||||
*
|
||||
* @return
|
||||
* A newly-allocated layer.
|
||||
*/
|
||||
guac_common_display_layer* guac_common_display_alloc_layer(
|
||||
guac_common_display* display, int width, int height);
|
||||
|
||||
/**
|
||||
* Allocates a new buffer, returning a new wrapped buffer and corresponding
|
||||
* surface. The buffer may be reused from a previous allocation, if that buffer
|
||||
* has since been freed.
|
||||
*
|
||||
* @param display
|
||||
* The display to allocate a new buffer from.
|
||||
*
|
||||
* @param width
|
||||
* The width of the buffer to allocate, in pixels.
|
||||
*
|
||||
* @param height
|
||||
* The height of the buffer to allocate, in pixels.
|
||||
*
|
||||
* @return
|
||||
* A newly-allocated buffer.
|
||||
*/
|
||||
guac_common_display_layer* guac_common_display_alloc_buffer(
|
||||
guac_common_display* display, int width, int height);
|
||||
|
||||
/**
|
||||
* Frees the given surface and associated layer, returning the layer to the
|
||||
* given display for future use.
|
||||
*
|
||||
* @param display
|
||||
* The display originally allocating the layer.
|
||||
*
|
||||
* @param display_layer
|
||||
* The layer to free.
|
||||
*/
|
||||
void guac_common_display_free_layer(guac_common_display* display,
|
||||
guac_common_display_layer* display_layer);
|
||||
|
||||
/**
|
||||
* Frees the given surface and associated buffer, returning the buffer to the
|
||||
* given display for future use.
|
||||
*
|
||||
* @param display
|
||||
* The display originally allocating the buffer.
|
||||
*
|
||||
* @param display_buffer
|
||||
* The buffer to free.
|
||||
*/
|
||||
void guac_common_display_free_buffer(guac_common_display* display,
|
||||
guac_common_display_layer* display_buffer);
|
||||
|
||||
/**
|
||||
* Sets the overall lossless compression policy of the given display to the
|
||||
* given value, affecting all current and future layers/buffers maintained by
|
||||
* the display. By default, newly-created displays will use lossy compression
|
||||
* for graphical updates when heuristics determine that doing so is
|
||||
* appropriate. Specifying a non-zero value here will force all graphical
|
||||
* updates to always use lossless compression, whereas specifying zero will
|
||||
* restore the default policy.
|
||||
*
|
||||
* Note that this can also be adjusted on a per-layer / per-buffer basis with
|
||||
* guac_common_surface_set_lossless().
|
||||
*
|
||||
* @param display
|
||||
* The display to modify.
|
||||
*
|
||||
* @param lossless
|
||||
* Non-zero if all graphical updates for this display should use lossless
|
||||
* compression, 0 otherwise.
|
||||
*/
|
||||
void guac_common_display_set_lossless(guac_common_display* display,
|
||||
int lossless);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _GUAC_COMMON_DOT_CURSOR_H
|
||||
#define _GUAC_COMMON_DOT_CURSOR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* Width of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_dot_cursor_width;
|
||||
|
||||
/**
|
||||
* Height of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_dot_cursor_height;
|
||||
|
||||
/**
|
||||
* Number of bytes in each row of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_dot_cursor_stride;
|
||||
|
||||
/**
|
||||
* The Cairo graphic format of the mouse cursor graphic.
|
||||
*/
|
||||
extern const cairo_format_t guac_common_dot_cursor_format;
|
||||
|
||||
/**
|
||||
* Embedded mouse cursor graphic.
|
||||
*/
|
||||
extern unsigned char guac_common_dot_cursor[];
|
||||
|
||||
/**
|
||||
* Set the cursor of the remote display to the embedded cursor graphic.
|
||||
*
|
||||
* @param user The guac_user to send the cursor to.
|
||||
*/
|
||||
void guac_common_set_dot_cursor(guac_user* user);
|
||||
|
||||
#endif
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_COMMON_IBAR_CURSOR_H
|
||||
#define GUAC_COMMON_IBAR_CURSOR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* Width of the embedded I-bar mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_ibar_cursor_width;
|
||||
|
||||
/**
|
||||
* Height of the embedded I-bar mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_ibar_cursor_height;
|
||||
|
||||
/**
|
||||
* Number of bytes in each row of the embedded I-bar mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_ibar_cursor_stride;
|
||||
|
||||
/**
|
||||
* The Cairo grapic format of the I-bar mouse cursor graphic.
|
||||
*/
|
||||
extern const cairo_format_t guac_common_ibar_cursor_format;
|
||||
|
||||
/**
|
||||
* Embedded I-bar mouse cursor graphic.
|
||||
*/
|
||||
extern unsigned char guac_common_ibar_cursor[];
|
||||
|
||||
/**
|
||||
* Sets the cursor of the remote display to the embedded I-bar cursor graphic.
|
||||
*
|
||||
* @param user
|
||||
* The guac_user to send the cursor to.
|
||||
*/
|
||||
void guac_common_set_ibar_cursor(guac_user* user);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef _GUAC_COMMON_POINTER_CURSOR_H
|
||||
#define _GUAC_COMMON_POINTER_CURSOR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/**
|
||||
* Width of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_pointer_cursor_width;
|
||||
|
||||
/**
|
||||
* Height of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_pointer_cursor_height;
|
||||
|
||||
/**
|
||||
* Number of bytes in each row of the embedded mouse cursor graphic.
|
||||
*/
|
||||
extern const int guac_common_pointer_cursor_stride;
|
||||
|
||||
/**
|
||||
* The Cairo grapic format of the mouse cursor graphic.
|
||||
*/
|
||||
extern const cairo_format_t guac_common_pointer_cursor_format;
|
||||
|
||||
/**
|
||||
* Embedded mouse cursor graphic.
|
||||
*/
|
||||
extern unsigned char guac_common_pointer_cursor[];
|
||||
|
||||
/**
|
||||
* Set the cursor of the remote display to the embedded cursor graphic.
|
||||
*
|
||||
* @param user The guac_user to send the cursor to.
|
||||
*/
|
||||
void guac_common_set_pointer_cursor(guac_user* user);
|
||||
|
||||
#endif
|
||||
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __GUAC_COMMON_RECT_H
|
||||
#define __GUAC_COMMON_RECT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* Simple representation of a rectangle, having a defined corner and dimensions.
|
||||
*/
|
||||
typedef struct guac_common_rect {
|
||||
|
||||
/**
|
||||
* The X coordinate of the upper-left corner of this rectangle.
|
||||
*/
|
||||
int x;
|
||||
|
||||
/**
|
||||
* The Y coordinate of the upper-left corner of this rectangle.
|
||||
*/
|
||||
int y;
|
||||
|
||||
/**
|
||||
* The width of this rectangle.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* The height of this rectangle.
|
||||
*/
|
||||
int height;
|
||||
|
||||
} guac_common_rect;
|
||||
|
||||
/**
|
||||
* Initialize the given rect with the given coordinates and dimensions.
|
||||
*
|
||||
* @param rect The rect to initialize.
|
||||
* @param x The X coordinate of the upper-left corner of the rect.
|
||||
* @param y The Y coordinate of the upper-left corner of the rect.
|
||||
* @param width The width of the rect.
|
||||
* @param height The height of the rect.
|
||||
*/
|
||||
void guac_common_rect_init(guac_common_rect* rect, int x, int y, int width, int height);
|
||||
|
||||
/**
|
||||
* Expand the rectangle to fit an NxN grid.
|
||||
*
|
||||
* The rectangle will be shifted to the left and up, expanded and adjusted to
|
||||
* fit within the max bounding rect.
|
||||
*
|
||||
* @param cell_size
|
||||
* The (NxN) grid cell size.
|
||||
*
|
||||
* @param rect
|
||||
* The rectangle to adjust.
|
||||
*
|
||||
* @param max_rect
|
||||
* The bounding area in which the given rect can exist.
|
||||
*
|
||||
* @return
|
||||
* Zero on success, non-zero on error.
|
||||
*/
|
||||
int guac_common_rect_expand_to_grid(int cell_size, guac_common_rect* rect,
|
||||
const guac_common_rect* max_rect);
|
||||
|
||||
/**
|
||||
* Extend the given rect such that it contains at least the specified minimum
|
||||
* rect.
|
||||
*
|
||||
* @param rect The rect to extend.
|
||||
* @param min The minimum area which must be contained within the given rect.
|
||||
*/
|
||||
void guac_common_rect_extend(guac_common_rect* rect, const guac_common_rect* min);
|
||||
|
||||
/**
|
||||
* Collapse the given rect such that it exists only within the given maximum
|
||||
* rect.
|
||||
*
|
||||
* @param rect The rect to extend.
|
||||
* @param max The maximum area in which the given rect can exist.
|
||||
*/
|
||||
void guac_common_rect_constrain(guac_common_rect* rect, const guac_common_rect* max);
|
||||
|
||||
/**
|
||||
* Check whether a rectangle intersects another.
|
||||
*
|
||||
* @param rect
|
||||
* Rectangle to check for intersection.
|
||||
*
|
||||
* @param other
|
||||
* The other rectangle.
|
||||
*
|
||||
* @return
|
||||
* Zero if no intersection, 1 if partial intersection,
|
||||
* 2 if first rect is completely inside the other.
|
||||
*/
|
||||
int guac_common_rect_intersects(const guac_common_rect* rect,
|
||||
const guac_common_rect* other);
|
||||
|
||||
/**
|
||||
* Clip and split a rectangle into rectangles which are not covered by the
|
||||
* hole rectangle.
|
||||
*
|
||||
* This function will clip and split single edges when executed and must be
|
||||
* invoked until it returns zero. The edges are handled counter-clockwise
|
||||
* starting at the top edge.
|
||||
*
|
||||
* @param rect
|
||||
* The rectangle to be split. This rectangle will be clipped by the
|
||||
* split_rect.
|
||||
*
|
||||
* @param hole
|
||||
* The rectangle which represents the hole.
|
||||
*
|
||||
* @param split_rect
|
||||
* Resulting split rectangle.
|
||||
*
|
||||
* @return
|
||||
* Zero when no splits were done, non-zero when the rectangle was split.
|
||||
*/
|
||||
int guac_common_rect_clip_and_split(guac_common_rect* rect,
|
||||
const guac_common_rect* hole, guac_common_rect* split_rect);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,539 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __GUAC_COMMON_SURFACE_H
|
||||
#define __GUAC_COMMON_SURFACE_H
|
||||
|
||||
#include "config.h"
|
||||
#include "rect.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/layer.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* The maximum number of updates to allow within the bitmap queue.
|
||||
*/
|
||||
#define GUAC_COMMON_SURFACE_QUEUE_SIZE 256
|
||||
|
||||
/**
|
||||
* Heat map cell size in pixels. Each side of each heat map cell will consist
|
||||
* of this many pixels.
|
||||
*/
|
||||
#define GUAC_COMMON_SURFACE_HEAT_CELL_SIZE 64
|
||||
|
||||
/**
|
||||
* The width or height of the heat map (in cells) given the width or height of
|
||||
* the image (in pixels).
|
||||
*/
|
||||
#define GUAC_COMMON_SURFACE_HEAT_DIMENSION(x) ( \
|
||||
(x + GUAC_COMMON_SURFACE_HEAT_CELL_SIZE - 1) \
|
||||
/ GUAC_COMMON_SURFACE_HEAT_CELL_SIZE \
|
||||
)
|
||||
|
||||
/**
|
||||
* The number of entries to collect within each heat map cell. Collected
|
||||
* history entries are used to determine the framerate of the region associated
|
||||
* with that cell.
|
||||
*/
|
||||
#define GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE 5
|
||||
|
||||
/**
|
||||
* Representation of a cell in the refresh heat map. This cell is used to keep
|
||||
* track of how often an area on a surface is refreshed.
|
||||
*/
|
||||
typedef struct guac_common_surface_heat_cell {
|
||||
|
||||
/**
|
||||
* Timestamps of each of the last N updates covering the location
|
||||
* associated with this heat map cell. This is used to calculate the
|
||||
* framerate. This array is structured as a ring buffer containing history
|
||||
* entries in chronologically-ascending order, starting at the entry
|
||||
* pointed to by oldest_entry and proceeding through all other entries,
|
||||
* wrapping around if the end of the array is reached.
|
||||
*/
|
||||
guac_timestamp history[GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE];
|
||||
|
||||
/**
|
||||
* Index of the oldest entry within the history.
|
||||
*/
|
||||
int oldest_entry;
|
||||
|
||||
} guac_common_surface_heat_cell;
|
||||
|
||||
/**
|
||||
* Representation of a bitmap update, having a rectangle of image data (stored
|
||||
* elsewhere) and a flushed/not-flushed state.
|
||||
*/
|
||||
typedef struct guac_common_surface_bitmap_rect {
|
||||
|
||||
/**
|
||||
* Whether this rectangle has been flushed.
|
||||
*/
|
||||
int flushed;
|
||||
|
||||
/**
|
||||
* The rectangle containing the bitmap update.
|
||||
*/
|
||||
guac_common_rect rect;
|
||||
|
||||
} guac_common_surface_bitmap_rect;
|
||||
|
||||
/**
|
||||
* Surface which backs a Guacamole buffer or layer, automatically
|
||||
* combining updates when possible.
|
||||
*/
|
||||
typedef struct guac_common_surface {
|
||||
|
||||
/**
|
||||
* The layer this surface will draw to.
|
||||
*/
|
||||
const guac_layer* layer;
|
||||
|
||||
/**
|
||||
* The client associated with this surface.
|
||||
*/
|
||||
guac_client* client;
|
||||
|
||||
/**
|
||||
* The socket to send instructions on when flushing.
|
||||
*/
|
||||
guac_socket* socket;
|
||||
|
||||
/**
|
||||
* The number of simultaneous touches that this surface can accept, where 0
|
||||
* indicates that the surface does not support touch events at all.
|
||||
*/
|
||||
int touches;
|
||||
|
||||
/**
|
||||
* Non-zero if all graphical updates for this surface should use lossless
|
||||
* compression, 0 otherwise. By default, newly-created surfaces will use
|
||||
* lossy compression when heuristics determine it is appropriate.
|
||||
*/
|
||||
int lossless;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
int width;
|
||||
|
||||
/**
|
||||
* The height of this layer, in pixels.
|
||||
*/
|
||||
int height;
|
||||
|
||||
/**
|
||||
* The size of each image row, in bytes.
|
||||
*/
|
||||
int stride;
|
||||
|
||||
/**
|
||||
* The underlying buffer of the Cairo 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.
|
||||
*/
|
||||
int dirty;
|
||||
|
||||
/**
|
||||
* The dirty rectangle.
|
||||
*/
|
||||
guac_common_rect dirty_rect;
|
||||
|
||||
/**
|
||||
* Whether the surface actually exists on the client.
|
||||
*/
|
||||
int realized;
|
||||
|
||||
/**
|
||||
* Whether drawing operations are currently clipped by the clipping
|
||||
* rectangle.
|
||||
*/
|
||||
int clipped;
|
||||
|
||||
/**
|
||||
* The clipping rectangle.
|
||||
*/
|
||||
guac_common_rect clip_rect;
|
||||
|
||||
/**
|
||||
* The number of updates in the bitmap queue.
|
||||
*/
|
||||
int bitmap_queue_length;
|
||||
|
||||
/**
|
||||
* All queued bitmap updates.
|
||||
*/
|
||||
guac_common_surface_bitmap_rect bitmap_queue[GUAC_COMMON_SURFACE_QUEUE_SIZE];
|
||||
|
||||
/**
|
||||
* A heat map keeping track of the refresh frequency of
|
||||
* the areas of the screen.
|
||||
*/
|
||||
guac_common_surface_heat_cell* heat_map;
|
||||
|
||||
/**
|
||||
* Mutex which is locked internally when access to the surface must be
|
||||
* synchronized. All public functions of guac_common_surface should be
|
||||
* considered threadsafe.
|
||||
*/
|
||||
pthread_mutex_t _lock;
|
||||
|
||||
} guac_common_surface;
|
||||
|
||||
/**
|
||||
* Allocates a new guac_common_surface, assigning it to the given layer.
|
||||
*
|
||||
* @param client
|
||||
* The client associated with the given layer.
|
||||
*
|
||||
* @param socket
|
||||
* The socket to send instructions on when flushing.
|
||||
*
|
||||
* @param layer
|
||||
* The layer to associate with the new surface.
|
||||
*
|
||||
* @param w
|
||||
* The width of the surface.
|
||||
*
|
||||
* @param h
|
||||
* The height of the surface.
|
||||
*
|
||||
* @return
|
||||
* A newly-allocated guac_common_surface.
|
||||
*/
|
||||
guac_common_surface* guac_common_surface_alloc(guac_client* client,
|
||||
guac_socket* socket, const guac_layer* layer, int w, int h);
|
||||
|
||||
/**
|
||||
* Frees the given guac_common_surface. Beware that this will NOT free any
|
||||
* associated layers, which must be freed manually.
|
||||
*
|
||||
* @param surface The surface to free.
|
||||
*/
|
||||
void guac_common_surface_free(guac_common_surface* surface);
|
||||
|
||||
/**
|
||||
* Resizes the given surface to the given size.
|
||||
*
|
||||
* @param surface The surface to resize.
|
||||
* @param w The width of the surface.
|
||||
* @param h The height of the surface.
|
||||
*/
|
||||
void guac_common_surface_resize(guac_common_surface* surface, int w, int h);
|
||||
|
||||
/**
|
||||
* Draws the given data to the given guac_common_surface. If the source surface
|
||||
* is ARGB, the draw operation will be performed using the Porter-Duff "over"
|
||||
* composite operator. If the source surface is RGB (no alpha channel), no
|
||||
* compositing is performed and destination pixels are ignored.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to draw to.
|
||||
*
|
||||
* @param x
|
||||
* The X coordinate of the draw location.
|
||||
*
|
||||
* @param y
|
||||
* The Y coordinate of the draw location.
|
||||
*
|
||||
* @param src
|
||||
* The Cairo surface to retrieve data from.
|
||||
*/
|
||||
void guac_common_surface_draw(guac_common_surface* surface, int x, int y,
|
||||
cairo_surface_t* src);
|
||||
|
||||
/**
|
||||
* Paints to the given guac_common_surface using the given data as a stencil,
|
||||
* filling opaque regions with the specified color, and leaving transparent
|
||||
* regions untouched.
|
||||
*
|
||||
* @param surface The surface to draw to.
|
||||
* @param x The X coordinate of the draw location.
|
||||
* @param y The Y coordinate of the draw location.
|
||||
* @param src The Cairo surface to retrieve data from.
|
||||
* @param red The red component of the fill color.
|
||||
* @param green The green component of the fill color.
|
||||
* @param blue The blue component of the fill color.
|
||||
*/
|
||||
void guac_common_surface_paint(guac_common_surface* surface, int x, int y, cairo_surface_t* src,
|
||||
int red, int green, int blue);
|
||||
|
||||
/**
|
||||
* Copies a rectangle of data between two surfaces.
|
||||
*
|
||||
* @param src The source surface.
|
||||
* @param sx The X coordinate of the upper-left corner of the source rect.
|
||||
* @param sy The Y coordinate of the upper-left corner of the source rect.
|
||||
* @param w The width of the source rect.
|
||||
* @param h The height of the source rect.
|
||||
* @param dst The destination surface.
|
||||
* @param dx The X coordinate of the upper-left corner of the destination rect.
|
||||
* @param dy The Y coordinate of the upper-left corner of the destination rect.
|
||||
*/
|
||||
void guac_common_surface_copy(guac_common_surface* src, int sx, int sy, int w, int h,
|
||||
guac_common_surface* dst, int dx, int dy);
|
||||
|
||||
/**
|
||||
* Transfers a rectangle of data between two surfaces.
|
||||
*
|
||||
* @param src The source surface.
|
||||
* @param sx The X coordinate of the upper-left corner of the source rect.
|
||||
* @param sy The Y coordinate of the upper-left corner of the source rect.
|
||||
* @param w The width of the source rect.
|
||||
* @param h The height of the source rect.
|
||||
* @param op The transfer function.
|
||||
* @param dst The destination surface.
|
||||
* @param dx The X coordinate of the upper-left corner of the destination rect.
|
||||
* @param dy The Y coordinate of the upper-left corner of the destination rect.
|
||||
*/
|
||||
void guac_common_surface_transfer(guac_common_surface* src, int sx, int sy, int w, int h,
|
||||
guac_transfer_function op, guac_common_surface* dst, int dx, int dy);
|
||||
|
||||
/**
|
||||
* Assigns the given value to all pixels within a rectangle of the given
|
||||
* surface. The color of all pixels within the rectangle, including the alpha
|
||||
* component, is entirely replaced.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to draw upon.
|
||||
*
|
||||
* @param x
|
||||
* The X coordinate of the upper-left corner of the rectangle.
|
||||
*
|
||||
* @param y
|
||||
* The Y coordinate of the upper-left corner of the rectangle.
|
||||
*
|
||||
* @param w
|
||||
* The width of the rectangle.
|
||||
*
|
||||
* @param h
|
||||
* The height of the rectangle.
|
||||
*
|
||||
* @param red
|
||||
* The red component of the color value to assign to all pixels within the
|
||||
* rectangle.
|
||||
*
|
||||
* @param green
|
||||
* The green component of the color value to assign to all pixels within
|
||||
* the rectangle.
|
||||
*
|
||||
* @param blue
|
||||
* The blue component of the color value to assign to all pixels within the
|
||||
* rectangle.
|
||||
*
|
||||
* @param alpha
|
||||
* The alpha component of the color value to assign to all pixels within
|
||||
* the rectangle.
|
||||
*/
|
||||
void guac_common_surface_set(guac_common_surface* surface, int x, int y,
|
||||
int w, int h, int red, int green, int blue, int alpha);
|
||||
|
||||
/**
|
||||
* Given the coordinates and dimensions of a rectangle, clips all future
|
||||
* operations within that rectangle.
|
||||
*
|
||||
* @param surface The surface whose clipping rectangle should be changed.
|
||||
* @param x The X coordinate of the upper-left corner of the bounding rectangle.
|
||||
* @param y The Y coordinate of the upper-left corner of the bounding rectangle.
|
||||
* @param w The width of the bounding rectangle.
|
||||
* @param h The height of the bounding rectangle.
|
||||
*/
|
||||
void guac_common_surface_clip(guac_common_surface* surface, int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Resets the clipping rectangle, allowing drawing operations throughout the
|
||||
* entire surface.
|
||||
*
|
||||
* @param surface The surface whose clipping rectangle should be reset.
|
||||
*/
|
||||
void guac_common_surface_reset_clip(guac_common_surface* surface);
|
||||
|
||||
/**
|
||||
* 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 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 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);
|
||||
|
||||
/**
|
||||
* Duplicates the contents of the current surface to the given socket. Pending
|
||||
* changes are not flushed.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to duplicate.
|
||||
*
|
||||
* @param client
|
||||
* The client whose users are receiving the surface.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which the surface contents should be sent.
|
||||
*/
|
||||
void guac_common_surface_dup(guac_common_surface* surface,
|
||||
guac_client* client, guac_socket* socket);
|
||||
|
||||
/**
|
||||
* Declares that the given surface should receive touch events. By default,
|
||||
* surfaces are assumed to not expect touch events. This value is advisory, and
|
||||
* the client is not required to honor the declared level of touch support.
|
||||
* Implementations are expected to safely handle or ignore any received touch
|
||||
* events, regardless of the level of touch support declared. regardless of
|
||||
* the level of touch support declared.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to modify.
|
||||
*
|
||||
* @param touches
|
||||
* The number of simultaneous touches that this surface can accept, where 0
|
||||
* indicates that the surface does not support touch events at all.
|
||||
*/
|
||||
void guac_common_surface_set_multitouch(guac_common_surface* surface,
|
||||
int touches);
|
||||
|
||||
/**
|
||||
* Sets the lossless compression policy of the given surface to the given
|
||||
* value. By default, newly-created surfaces will use lossy compression for
|
||||
* graphical updates when heuristics determine that doing so is appropriate.
|
||||
* Specifying a non-zero value here will force all graphical updates to always
|
||||
* use lossless compression, whereas specifying zero will restore the default
|
||||
* policy.
|
||||
*
|
||||
* @param surface
|
||||
* The surface to modify.
|
||||
*
|
||||
* @param lossless
|
||||
* Non-zero if all graphical updates for this surface should use lossless
|
||||
* compression, 0 otherwise.
|
||||
*/
|
||||
void guac_common_surface_set_lossless(guac_common_surface* surface,
|
||||
int lossless);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,327 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/blank_cursor.h"
|
||||
#include "common/dot_cursor.h"
|
||||
#include "common/cursor.h"
|
||||
#include "common/ibar_cursor.h"
|
||||
#include "common/pointer_cursor.h"
|
||||
#include "common/surface.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/mem.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/timestamp.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Allocates a cursor as well as an image buffer where the cursor is rendered.
|
||||
*
|
||||
* @param client
|
||||
* The client owning the cursor.
|
||||
*
|
||||
* @return
|
||||
* The newly-allocated cursor or NULL if cursor cannot be allocated.
|
||||
*/
|
||||
guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
|
||||
|
||||
guac_common_cursor* cursor = guac_mem_alloc(sizeof(guac_common_cursor));
|
||||
if (cursor == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Associate cursor with client and allocate cursor buffer */
|
||||
cursor->client = client;
|
||||
cursor->buffer = guac_client_alloc_buffer(client);
|
||||
|
||||
/* Allocate initial image buffer */
|
||||
cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE;
|
||||
cursor->image_buffer = guac_mem_alloc(cursor->image_buffer_size);
|
||||
|
||||
/* No cursor image yet */
|
||||
cursor->width = 0;
|
||||
cursor->height = 0;
|
||||
cursor->surface = NULL;
|
||||
cursor->hotspot_x = 0;
|
||||
cursor->hotspot_y = 0;
|
||||
|
||||
/* No user has moved the mouse yet */
|
||||
cursor->user = NULL;
|
||||
cursor->timestamp = guac_timestamp_current();
|
||||
|
||||
/* Start cursor in upper-left */
|
||||
cursor->x = 0;
|
||||
cursor->y = 0;
|
||||
|
||||
pthread_mutex_init(&(cursor->_lock), NULL);
|
||||
|
||||
return cursor;
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_free(guac_common_cursor* cursor) {
|
||||
|
||||
pthread_mutex_destroy(&(cursor->_lock));
|
||||
|
||||
guac_client* client = cursor->client;
|
||||
guac_layer* buffer = cursor->buffer;
|
||||
cairo_surface_t* surface = cursor->surface;
|
||||
|
||||
/* Free image buffer and surface */
|
||||
guac_mem_free(cursor->image_buffer);
|
||||
if (surface != NULL)
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
/* Destroy buffer within remotely-connected client */
|
||||
guac_protocol_send_dispose(client->socket, buffer);
|
||||
|
||||
/* Return buffer to pool */
|
||||
guac_client_free_buffer(client, buffer);
|
||||
|
||||
guac_mem_free(cursor);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_dup(
|
||||
guac_common_cursor* cursor, guac_client* client, guac_socket* socket) {
|
||||
|
||||
pthread_mutex_lock(&(cursor->_lock));
|
||||
|
||||
/* Synchronize location */
|
||||
guac_protocol_send_mouse(socket, cursor->x, cursor->y, cursor->button_mask,
|
||||
cursor->timestamp);
|
||||
|
||||
/* Synchronize cursor image */
|
||||
if (cursor->surface != NULL) {
|
||||
guac_protocol_send_size(socket, cursor->buffer,
|
||||
cursor->width, cursor->height);
|
||||
|
||||
guac_client_stream_png(client, socket, GUAC_COMP_SRC,
|
||||
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);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(cursor->_lock));
|
||||
|
||||
guac_socket_flush(socket);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for guac_client_foreach_user() which sends the current cursor
|
||||
* position and button state to any given user except the user that moved the
|
||||
* cursor last.
|
||||
*
|
||||
* @param data
|
||||
* A pointer to the guac_common_cursor whose state should be broadcast to
|
||||
* all users except the user that moved the cursor last.
|
||||
*
|
||||
* @return
|
||||
* Always NULL.
|
||||
*/
|
||||
static void* guac_common_cursor_broadcast_state(guac_user* user,
|
||||
void* data) {
|
||||
|
||||
guac_common_cursor* cursor = (guac_common_cursor*) data;
|
||||
|
||||
/* Send cursor state only if the user is not moving the cursor */
|
||||
if (user != cursor->user) {
|
||||
guac_protocol_send_mouse(user->socket, cursor->x, cursor->y,
|
||||
cursor->button_mask, cursor->timestamp);
|
||||
guac_socket_flush(user->socket);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_update(guac_common_cursor* cursor, guac_user* user,
|
||||
int x, int y, int button_mask) {
|
||||
|
||||
pthread_mutex_lock(&(cursor->_lock));
|
||||
|
||||
/* Update current user of cursor */
|
||||
cursor->user = user;
|
||||
|
||||
/* Update cursor state */
|
||||
cursor->x = x;
|
||||
cursor->y = y;
|
||||
cursor->button_mask = button_mask;
|
||||
|
||||
/* Store time at which cursor was updated */
|
||||
cursor->timestamp = guac_timestamp_current();
|
||||
|
||||
/* Notify all other users of change in cursor state */
|
||||
guac_client_foreach_user(cursor->client,
|
||||
guac_common_cursor_broadcast_state, cursor);
|
||||
|
||||
pthread_mutex_unlock(&(cursor->_lock));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the cursor image buffer has enough room to fit an image with the
|
||||
* given characteristics. Existing image buffer data may be destroyed.
|
||||
*
|
||||
* @param cursor
|
||||
* The cursor whose buffer size should be checked. If this cursor lacks
|
||||
* sufficient space to contain a cursor image of the specified width,
|
||||
* height, and stride, the current contents of this cursor will be
|
||||
* destroyed and replaced with an new buffer having sufficient space.
|
||||
*
|
||||
* @param width
|
||||
* The required cursor width, in pixels.
|
||||
*
|
||||
* @param height
|
||||
* The required cursor height, in pixels.
|
||||
*
|
||||
* @param stride
|
||||
* The number of bytes in each row of image data.
|
||||
*/
|
||||
static void guac_common_cursor_resize(guac_common_cursor* cursor,
|
||||
int width, int height, int stride) {
|
||||
|
||||
size_t minimum_size = guac_mem_ckd_mul_or_die(height, stride);
|
||||
|
||||
/* Grow image buffer if necessary */
|
||||
if (cursor->image_buffer_size < minimum_size) {
|
||||
|
||||
/* Calculate new size */
|
||||
cursor->image_buffer_size = guac_mem_ckd_mul_or_die(minimum_size, 2);
|
||||
|
||||
/* Destructively reallocate image buffer */
|
||||
guac_mem_free(cursor->image_buffer);
|
||||
cursor->image_buffer = guac_mem_alloc(cursor->image_buffer_size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
|
||||
unsigned const char* data, int width, int height, int stride) {
|
||||
|
||||
pthread_mutex_lock(&(cursor->_lock));
|
||||
|
||||
/* Copy image data */
|
||||
guac_common_cursor_resize(cursor, width, height, stride);
|
||||
memcpy(cursor->image_buffer, data, height * stride);
|
||||
|
||||
if (cursor->surface != NULL)
|
||||
cairo_surface_destroy(cursor->surface);
|
||||
|
||||
cursor->surface = cairo_image_surface_create_for_data(cursor->image_buffer,
|
||||
CAIRO_FORMAT_ARGB32, width, height, stride);
|
||||
|
||||
/* Set new cursor parameters */
|
||||
cursor->width = width;
|
||||
cursor->height = height;
|
||||
cursor->hotspot_x = hx;
|
||||
cursor->hotspot_y = hy;
|
||||
|
||||
/* Broadcast new cursor image to all users */
|
||||
guac_protocol_send_size(cursor->client->socket, cursor->buffer,
|
||||
width, height);
|
||||
|
||||
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);
|
||||
|
||||
pthread_mutex_unlock(&(cursor->_lock));
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,
|
||||
guac_common_surface* surface) {
|
||||
|
||||
/* Set cursor to surface contents */
|
||||
guac_common_cursor_set_argb(cursor, hx, hy, surface->buffer,
|
||||
surface->width, surface->height, surface->stride);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_pointer(guac_common_cursor* cursor) {
|
||||
|
||||
guac_common_cursor_set_argb(cursor, 0, 0,
|
||||
guac_common_pointer_cursor,
|
||||
guac_common_pointer_cursor_width,
|
||||
guac_common_pointer_cursor_height,
|
||||
guac_common_pointer_cursor_stride);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_dot(guac_common_cursor* cursor) {
|
||||
|
||||
guac_common_cursor_set_argb(cursor, 2, 2,
|
||||
guac_common_dot_cursor,
|
||||
guac_common_dot_cursor_width,
|
||||
guac_common_dot_cursor_height,
|
||||
guac_common_dot_cursor_stride);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_ibar(guac_common_cursor* cursor) {
|
||||
|
||||
guac_common_cursor_set_argb(cursor,
|
||||
guac_common_ibar_cursor_width / 2,
|
||||
guac_common_ibar_cursor_height / 2,
|
||||
guac_common_ibar_cursor,
|
||||
guac_common_ibar_cursor_width,
|
||||
guac_common_ibar_cursor_height,
|
||||
guac_common_ibar_cursor_stride);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_set_blank(guac_common_cursor* cursor) {
|
||||
|
||||
guac_common_cursor_set_argb(cursor, 0, 0,
|
||||
guac_common_blank_cursor,
|
||||
guac_common_blank_cursor_width,
|
||||
guac_common_blank_cursor_height,
|
||||
guac_common_blank_cursor_stride);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_cursor_remove_user(guac_common_cursor* cursor,
|
||||
guac_user* user) {
|
||||
|
||||
pthread_mutex_lock(&(cursor->_lock));
|
||||
|
||||
/* Disassociate from given user */
|
||||
if (cursor->user == user)
|
||||
cursor->user = NULL;
|
||||
|
||||
pthread_mutex_unlock(&(cursor->_lock));
|
||||
|
||||
}
|
||||
|
||||
@ -1,422 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/cursor.h"
|
||||
#include "common/display.h"
|
||||
#include "common/surface.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/mem.h>
|
||||
#include <guacamole/socket.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Synchronizes all surfaces within the given linked list to the given socket.
|
||||
* If the provided pointer to the linked list is NULL, this function has no
|
||||
* effect.
|
||||
*
|
||||
* @param layers
|
||||
* The head element of the linked list of layers to synchronize, which may
|
||||
* be NULL if the list is currently empty.
|
||||
*
|
||||
* @param client
|
||||
* The client associated with the users receiving the layers.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which each layer should be sent.
|
||||
*/
|
||||
static void guac_common_display_dup_layers(guac_common_display_layer* layers,
|
||||
guac_client* client, guac_socket* socket) {
|
||||
|
||||
guac_common_display_layer* current = layers;
|
||||
|
||||
/* Synchronize all surfaces in given list */
|
||||
while (current != NULL) {
|
||||
guac_common_surface_dup(current->surface, client, socket);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all layers and associated surfaces within the given list, as well as
|
||||
* their corresponding list elements. If the provided pointer to the linked
|
||||
* list is NULL, this function has no effect.
|
||||
*
|
||||
* @param layers
|
||||
* The head element of the linked list of layers to free, which may be NULL
|
||||
* if the list is currently empty.
|
||||
*
|
||||
* @param client
|
||||
* The client owning the layers wrapped by each of the layers in the list.
|
||||
*/
|
||||
static void guac_common_display_free_layers(guac_common_display_layer* layers,
|
||||
guac_client* client) {
|
||||
|
||||
guac_common_display_layer* current = layers;
|
||||
|
||||
/* Free each surface in given list */
|
||||
while (current != NULL) {
|
||||
|
||||
guac_common_display_layer* next = current->next;
|
||||
guac_layer* layer = current->layer;
|
||||
|
||||
/* Free surface */
|
||||
guac_common_surface_free(current->surface);
|
||||
|
||||
/* Destroy layer within remotely-connected client */
|
||||
guac_protocol_send_dispose(client->socket, layer);
|
||||
|
||||
/* Free layer or buffer depending on index */
|
||||
if (layer->index < 0)
|
||||
guac_client_free_buffer(client, layer);
|
||||
else if (layer->index > 0)
|
||||
guac_client_free_layer(client, layer);
|
||||
|
||||
/* Free current element and advance to next */
|
||||
guac_mem_free(current);
|
||||
current = next;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a display and a cursor which are used to represent the remote
|
||||
* display and cursor.
|
||||
*
|
||||
* @param client
|
||||
* The client owning the cursor.
|
||||
*
|
||||
* @param width
|
||||
* The desired width of the display.
|
||||
*
|
||||
* @param height
|
||||
* The desired height of the display.
|
||||
*
|
||||
* @return
|
||||
* The newly-allocated display or NULL if display cannot be allocated.
|
||||
*/
|
||||
guac_common_display* guac_common_display_alloc(guac_client* client,
|
||||
int width, int height) {
|
||||
|
||||
/* Allocate display */
|
||||
guac_common_display* display = guac_mem_alloc(sizeof(guac_common_display));
|
||||
if (display == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Allocate shared cursor */
|
||||
display->cursor = guac_common_cursor_alloc(client);
|
||||
if (display->cursor == NULL) {
|
||||
guac_mem_free(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&display->_lock, NULL);
|
||||
|
||||
/* Associate display with given client */
|
||||
display->client = client;
|
||||
|
||||
display->default_surface = guac_common_surface_alloc(client,
|
||||
client->socket, GUAC_DEFAULT_LAYER, width, height);
|
||||
|
||||
/* No initial layers or buffers */
|
||||
display->layers = NULL;
|
||||
display->buffers = NULL;
|
||||
|
||||
return display;
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_free(guac_common_display* display) {
|
||||
|
||||
/* Free shared cursor */
|
||||
guac_common_cursor_free(display->cursor);
|
||||
|
||||
/* Free default surface */
|
||||
guac_common_surface_free(display->default_surface);
|
||||
|
||||
/* Free all layers and buffers */
|
||||
guac_common_display_free_layers(display->buffers, display->client);
|
||||
guac_common_display_free_layers(display->layers, display->client);
|
||||
|
||||
pthread_mutex_destroy(&display->_lock);
|
||||
guac_mem_free(display);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_dup(
|
||||
guac_common_display* display, guac_client* client,
|
||||
guac_socket* socket) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Synchronize shared cursor */
|
||||
guac_common_cursor_dup(display->cursor, client, socket);
|
||||
|
||||
/* Synchronize default surface */
|
||||
guac_common_surface_dup(display->default_surface, client, socket);
|
||||
|
||||
/* Synchronize all layers and buffers */
|
||||
guac_common_display_dup_layers(display->layers, client, socket);
|
||||
guac_common_display_dup_layers(display->buffers, client, socket);
|
||||
|
||||
/* Sends a sync instruction to mark the boundary of the first frame */
|
||||
guac_protocol_send_sync(socket, client->last_sent_timestamp, 1);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_fit(int* a, int* b) {
|
||||
|
||||
int a_value = *a;
|
||||
int b_value = *b;
|
||||
|
||||
/* Ensure first dimension is within allowed range */
|
||||
if (a_value < GUAC_COMMON_DISPLAY_MIN_SIZE) {
|
||||
|
||||
/* Adjust other dimension to maintain aspect ratio */
|
||||
int adjusted_b = b_value * GUAC_COMMON_DISPLAY_MIN_SIZE / a_value;
|
||||
if (adjusted_b > GUAC_COMMON_DISPLAY_MAX_SIZE)
|
||||
adjusted_b = GUAC_COMMON_DISPLAY_MAX_SIZE;
|
||||
|
||||
*a = GUAC_COMMON_DISPLAY_MIN_SIZE;
|
||||
*b = adjusted_b;
|
||||
|
||||
}
|
||||
else if (a_value > GUAC_COMMON_DISPLAY_MAX_SIZE) {
|
||||
|
||||
/* Adjust other dimension to maintain aspect ratio */
|
||||
int adjusted_b = b_value * GUAC_COMMON_DISPLAY_MAX_SIZE / a_value;
|
||||
if (adjusted_b < GUAC_COMMON_DISPLAY_MIN_SIZE)
|
||||
adjusted_b = GUAC_COMMON_DISPLAY_MIN_SIZE;
|
||||
|
||||
*a = GUAC_COMMON_DISPLAY_MAX_SIZE;
|
||||
*b = adjusted_b;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_set_lossless(guac_common_display* display,
|
||||
int lossless) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Update lossless setting to be applied to all newly-allocated
|
||||
* layers/buffers */
|
||||
display->lossless = lossless;
|
||||
|
||||
/* Update losslessness of all allocated layers/buffers */
|
||||
guac_common_display_layer* current = display->layers;
|
||||
while (current != NULL) {
|
||||
guac_common_surface_set_lossless(current->surface, lossless);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
/* Update losslessness of default display layer (not included within layers
|
||||
* list) */
|
||||
guac_common_surface_set_lossless(display->default_surface, lossless);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_flush(guac_common_display* display) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
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);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and inserts a new element into the given linked list of display
|
||||
* layers, associating it with the given layer and surface.
|
||||
*
|
||||
* @param head
|
||||
* A pointer to the head pointer of the list of layers. The head pointer
|
||||
* will be updated by this function to point to the newly-allocated
|
||||
* display layer.
|
||||
*
|
||||
* @param layer
|
||||
* The Guacamole layer to associated with the new display layer.
|
||||
*
|
||||
* @param surface
|
||||
* The surface associated with the given Guacamole layer and which should
|
||||
* be associated with the new display layer.
|
||||
*
|
||||
* @return
|
||||
* The newly-allocated display layer, which has been associated with the
|
||||
* provided layer and surface.
|
||||
*/
|
||||
static guac_common_display_layer* guac_common_display_add_layer(
|
||||
guac_common_display_layer** head, guac_layer* layer,
|
||||
guac_common_surface* surface) {
|
||||
|
||||
guac_common_display_layer* old_head = *head;
|
||||
|
||||
guac_common_display_layer* display_layer =
|
||||
guac_mem_alloc(sizeof(guac_common_display_layer));
|
||||
|
||||
/* Init layer/surface pair */
|
||||
display_layer->layer = layer;
|
||||
display_layer->surface = surface;
|
||||
|
||||
/* Insert list element as the new head */
|
||||
display_layer->prev = NULL;
|
||||
display_layer->next = old_head;
|
||||
*head = display_layer;
|
||||
|
||||
/* Update old head to point to new element, if it existed */
|
||||
if (old_head != NULL)
|
||||
old_head->prev = display_layer;
|
||||
|
||||
return display_layer;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given display layer from the linked list whose head pointer is
|
||||
* provided.
|
||||
*
|
||||
* @param head
|
||||
* A pointer to the head pointer of the list of layers. The head pointer
|
||||
* will be updated by this function if necessary, and will be set to NULL
|
||||
* if the display layer being removed is the only layer in the list.
|
||||
*
|
||||
* @param display_layer
|
||||
* The display layer to remove from the given list.
|
||||
*/
|
||||
static void guac_common_display_remove_layer(guac_common_display_layer** head,
|
||||
guac_common_display_layer* display_layer) {
|
||||
|
||||
/* Update previous element, if it exists */
|
||||
if (display_layer->prev != NULL)
|
||||
display_layer->prev->next = display_layer->next;
|
||||
|
||||
/* If there is no previous element, update the list head */
|
||||
else
|
||||
*head = display_layer->next;
|
||||
|
||||
/* Update next element, if it exists */
|
||||
if (display_layer->next != NULL)
|
||||
display_layer->next->prev = display_layer->prev;
|
||||
|
||||
}
|
||||
|
||||
guac_common_display_layer* guac_common_display_alloc_layer(
|
||||
guac_common_display* display, int width, int height) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Allocate Guacamole layer */
|
||||
guac_layer* layer = guac_client_alloc_layer(display->client);
|
||||
|
||||
/* Allocate corresponding surface */
|
||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||
display->client->socket, layer, width, height);
|
||||
|
||||
/* Apply current display losslessness */
|
||||
guac_common_surface_set_lossless(surface, display->lossless);
|
||||
|
||||
/* Add layer and surface to list */
|
||||
guac_common_display_layer* display_layer =
|
||||
guac_common_display_add_layer(&display->layers, layer, surface);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
return display_layer;
|
||||
|
||||
}
|
||||
|
||||
guac_common_display_layer* guac_common_display_alloc_buffer(
|
||||
guac_common_display* display, int width, int height) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Allocate Guacamole buffer */
|
||||
guac_layer* buffer = guac_client_alloc_buffer(display->client);
|
||||
|
||||
/* Allocate corresponding surface */
|
||||
guac_common_surface* surface = guac_common_surface_alloc(display->client,
|
||||
display->client->socket, buffer, width, height);
|
||||
|
||||
/* Apply current display losslessness */
|
||||
guac_common_surface_set_lossless(surface, display->lossless);
|
||||
|
||||
/* Add buffer and surface to list */
|
||||
guac_common_display_layer* display_layer =
|
||||
guac_common_display_add_layer(&display->buffers, buffer, surface);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
return display_layer;
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_free_layer(guac_common_display* display,
|
||||
guac_common_display_layer* display_layer) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Remove list element from list */
|
||||
guac_common_display_remove_layer(&display->layers, display_layer);
|
||||
|
||||
/* Free associated layer and surface */
|
||||
guac_common_surface_free(display_layer->surface);
|
||||
guac_client_free_layer(display->client, display_layer->layer);
|
||||
|
||||
/* Free list element */
|
||||
guac_mem_free(display_layer);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_display_free_buffer(guac_common_display* display,
|
||||
guac_common_display_layer* display_buffer) {
|
||||
|
||||
pthread_mutex_lock(&display->_lock);
|
||||
|
||||
/* Remove list element from list */
|
||||
guac_common_display_remove_layer(&display->buffers, display_buffer);
|
||||
|
||||
/* Free associated layer and surface */
|
||||
guac_common_surface_free(display_buffer->surface);
|
||||
guac_client_free_buffer(display->client, display_buffer->layer);
|
||||
|
||||
/* Free list element */
|
||||
guac_mem_free(display_buffer);
|
||||
|
||||
pthread_mutex_unlock(&display->_lock);
|
||||
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/layer.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/* Macros for prettying up the embedded image. */
|
||||
#define X 0x00,0x00,0x00,0xFF
|
||||
#define O 0xFF,0xFF,0xFF,0xFF
|
||||
#define _ 0x00,0x00,0x00,0x00
|
||||
|
||||
/* Dimensions */
|
||||
const int guac_common_dot_cursor_width = 5;
|
||||
const int guac_common_dot_cursor_height = 5;
|
||||
|
||||
/* Format */
|
||||
const cairo_format_t guac_common_dot_cursor_format = CAIRO_FORMAT_ARGB32;
|
||||
const int guac_common_dot_cursor_stride = 20;
|
||||
|
||||
/* Embedded pointer graphic */
|
||||
unsigned char guac_common_dot_cursor[] = {
|
||||
|
||||
_,O,O,O,_,
|
||||
O,X,X,X,O,
|
||||
O,X,X,X,O,
|
||||
O,X,X,X,O,
|
||||
_,O,O,O,_
|
||||
|
||||
};
|
||||
|
||||
void guac_common_set_dot_cursor(guac_user* user) {
|
||||
|
||||
guac_client* client = user->client;
|
||||
guac_socket* socket = user->socket;
|
||||
|
||||
/* Draw to buffer */
|
||||
guac_layer* cursor = guac_client_alloc_buffer(client);
|
||||
|
||||
cairo_surface_t* graphic = cairo_image_surface_create_for_data(
|
||||
guac_common_dot_cursor,
|
||||
guac_common_dot_cursor_format,
|
||||
guac_common_dot_cursor_width,
|
||||
guac_common_dot_cursor_height,
|
||||
guac_common_dot_cursor_stride);
|
||||
|
||||
guac_user_stream_png(user, socket, GUAC_COMP_SRC, cursor,
|
||||
0, 0, graphic);
|
||||
cairo_surface_destroy(graphic);
|
||||
|
||||
/* Set cursor */
|
||||
guac_protocol_send_cursor(socket, 2, 2, cursor,
|
||||
0, 0,
|
||||
guac_common_dot_cursor_width,
|
||||
guac_common_dot_cursor_height);
|
||||
|
||||
/* Free buffer */
|
||||
guac_client_free_buffer(client, cursor);
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Client cursor image set to generic built-in dot.");
|
||||
|
||||
}
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/layer.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/* Macros for prettying up the embedded image. */
|
||||
#define X 0x00,0x00,0x00,0xFF
|
||||
#define U 0x80,0x80,0x80,0xFF
|
||||
#define O 0xFF,0xFF,0xFF,0xFF
|
||||
#define _ 0x00,0x00,0x00,0x00
|
||||
|
||||
/* Dimensions */
|
||||
const int guac_common_ibar_cursor_width = 7;
|
||||
const int guac_common_ibar_cursor_height = 16;
|
||||
|
||||
/* Format */
|
||||
const cairo_format_t guac_common_ibar_cursor_format = CAIRO_FORMAT_ARGB32;
|
||||
const int guac_common_ibar_cursor_stride = 28;
|
||||
|
||||
/* Embedded I-bar graphic */
|
||||
unsigned char guac_common_ibar_cursor[] = {
|
||||
|
||||
X,X,X,X,X,X,X,
|
||||
X,O,O,U,O,O,X,
|
||||
X,X,X,O,X,X,X,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
_,_,X,O,X,_,_,
|
||||
X,X,X,O,X,X,X,
|
||||
X,O,O,U,O,O,X,
|
||||
X,X,X,X,X,X,X
|
||||
|
||||
};
|
||||
|
||||
void guac_common_set_ibar_cursor(guac_user* user) {
|
||||
|
||||
guac_client* client = user->client;
|
||||
guac_socket* socket = user->socket;
|
||||
|
||||
/* Draw to buffer */
|
||||
guac_layer* cursor = guac_client_alloc_buffer(client);
|
||||
|
||||
cairo_surface_t* graphic = cairo_image_surface_create_for_data(
|
||||
guac_common_ibar_cursor,
|
||||
guac_common_ibar_cursor_format,
|
||||
guac_common_ibar_cursor_width,
|
||||
guac_common_ibar_cursor_height,
|
||||
guac_common_ibar_cursor_stride);
|
||||
|
||||
guac_user_stream_png(user, socket, GUAC_COMP_SRC, cursor,
|
||||
0, 0, graphic);
|
||||
cairo_surface_destroy(graphic);
|
||||
|
||||
/* Set cursor */
|
||||
guac_protocol_send_cursor(socket, 0, 0, cursor,
|
||||
guac_common_ibar_cursor_width / 2,
|
||||
guac_common_ibar_cursor_height / 2,
|
||||
guac_common_ibar_cursor_width,
|
||||
guac_common_ibar_cursor_height);
|
||||
|
||||
/* Free buffer */
|
||||
guac_client_free_buffer(client, cursor);
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Client cursor image set to generic built-in I-bar.");
|
||||
|
||||
}
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/layer.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
/* Macros for prettying up the embedded image. */
|
||||
#define X 0x00,0x00,0x00,0xFF
|
||||
#define O 0xFF,0xFF,0xFF,0xFF
|
||||
#define _ 0x00,0x00,0x00,0x00
|
||||
|
||||
/* Dimensions */
|
||||
const int guac_common_pointer_cursor_width = 11;
|
||||
const int guac_common_pointer_cursor_height = 16;
|
||||
|
||||
/* Format */
|
||||
const cairo_format_t guac_common_pointer_cursor_format = CAIRO_FORMAT_ARGB32;
|
||||
const int guac_common_pointer_cursor_stride = 44;
|
||||
|
||||
/* Embedded pointer graphic */
|
||||
unsigned char guac_common_pointer_cursor[] = {
|
||||
|
||||
O,_,_,_,_,_,_,_,_,_,_,
|
||||
O,O,_,_,_,_,_,_,_,_,_,
|
||||
O,X,O,_,_,_,_,_,_,_,_,
|
||||
O,X,X,O,_,_,_,_,_,_,_,
|
||||
O,X,X,X,O,_,_,_,_,_,_,
|
||||
O,X,X,X,X,O,_,_,_,_,_,
|
||||
O,X,X,X,X,X,O,_,_,_,_,
|
||||
O,X,X,X,X,X,X,O,_,_,_,
|
||||
O,X,X,X,X,X,X,X,O,_,_,
|
||||
O,X,X,X,X,X,X,X,X,O,_,
|
||||
O,X,X,X,X,X,O,O,O,O,O,
|
||||
O,X,X,O,X,X,O,_,_,_,_,
|
||||
O,X,O,_,O,X,X,O,_,_,_,
|
||||
O,O,_,_,O,X,X,O,_,_,_,
|
||||
O,_,_,_,_,O,X,X,O,_,_,
|
||||
_,_,_,_,_,O,O,O,O,_,_
|
||||
|
||||
};
|
||||
|
||||
void guac_common_set_pointer_cursor(guac_user* user) {
|
||||
|
||||
guac_client* client = user->client;
|
||||
guac_socket* socket = user->socket;
|
||||
|
||||
/* Draw to buffer */
|
||||
guac_layer* cursor = guac_client_alloc_buffer(client);
|
||||
|
||||
cairo_surface_t* graphic = cairo_image_surface_create_for_data(
|
||||
guac_common_pointer_cursor,
|
||||
guac_common_pointer_cursor_format,
|
||||
guac_common_pointer_cursor_width,
|
||||
guac_common_pointer_cursor_height,
|
||||
guac_common_pointer_cursor_stride);
|
||||
|
||||
guac_user_stream_png(user, socket, GUAC_COMP_SRC, cursor,
|
||||
0, 0, graphic);
|
||||
cairo_surface_destroy(graphic);
|
||||
|
||||
/* Set cursor */
|
||||
guac_protocol_send_cursor(socket, 0, 0, cursor,
|
||||
0, 0,
|
||||
guac_common_pointer_cursor_width,
|
||||
guac_common_pointer_cursor_height);
|
||||
|
||||
/* Free buffer */
|
||||
guac_client_free_buffer(client, cursor);
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Client cursor image set to generic built-in pointer.");
|
||||
|
||||
}
|
||||
|
||||
@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
void guac_common_rect_init(guac_common_rect* rect, int x, int y, int width, int height) {
|
||||
rect->x = x;
|
||||
rect->y = y;
|
||||
rect->width = width;
|
||||
rect->height = height;
|
||||
}
|
||||
|
||||
void guac_common_rect_extend(guac_common_rect* rect, const guac_common_rect* min) {
|
||||
|
||||
/* Calculate extents of existing dirty rect */
|
||||
int left = rect->x;
|
||||
int top = rect->y;
|
||||
int right = left + rect->width;
|
||||
int bottom = top + rect->height;
|
||||
|
||||
/* Calculate missing extents of given new rect */
|
||||
int min_left = min->x;
|
||||
int min_top = min->y;
|
||||
int min_right = min_left + min->width;
|
||||
int min_bottom = min_top + min->height;
|
||||
|
||||
/* Update minimums */
|
||||
if (min_left < left) left = min_left;
|
||||
if (min_top < top) top = min_top;
|
||||
if (min_right > right) right = min_right;
|
||||
if (min_bottom > bottom) bottom = min_bottom;
|
||||
|
||||
/* Commit rect */
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
}
|
||||
|
||||
void guac_common_rect_constrain(guac_common_rect* rect, const guac_common_rect* max) {
|
||||
|
||||
/* Calculate extents of existing dirty rect */
|
||||
int left = rect->x;
|
||||
int top = rect->y;
|
||||
int right = left + rect->width;
|
||||
int bottom = top + rect->height;
|
||||
|
||||
/* Calculate missing extents of given new rect */
|
||||
int max_left = max->x;
|
||||
int max_top = max->y;
|
||||
int max_right = max_left + max->width;
|
||||
int max_bottom = max_top + max->height;
|
||||
|
||||
/* Update maximums */
|
||||
if (max_left > left) left = max_left;
|
||||
if (max_top > top) top = max_top;
|
||||
if (max_right < right) right = max_right;
|
||||
if (max_bottom < bottom) bottom = max_bottom;
|
||||
|
||||
/* Commit rect */
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
}
|
||||
|
||||
int guac_common_rect_expand_to_grid(int cell_size, guac_common_rect* rect,
|
||||
const guac_common_rect* max_rect) {
|
||||
|
||||
/* Invalid cell_size received */
|
||||
if (cell_size <= 0)
|
||||
return -1;
|
||||
|
||||
/* Nothing to do */
|
||||
if (cell_size == 1)
|
||||
return 0;
|
||||
|
||||
/* Calculate how much the rectangle must be adjusted to fit within the
|
||||
* given cell size. */
|
||||
int dw = cell_size - rect->width % cell_size;
|
||||
int dh = cell_size - rect->height % cell_size;
|
||||
|
||||
int dx = dw / 2;
|
||||
int dy = dh / 2;
|
||||
|
||||
/* Set initial extents of adjusted rectangle. */
|
||||
int top = rect->y - dy;
|
||||
int left = rect->x - dx;
|
||||
int bottom = top + rect->height + dh;
|
||||
int right = left + rect->width + dw;
|
||||
|
||||
/* The max rectangle */
|
||||
int max_left = max_rect->x;
|
||||
int max_top = max_rect->y;
|
||||
int max_right = max_left + max_rect->width;
|
||||
int max_bottom = max_top + max_rect->height;
|
||||
|
||||
/* If the adjusted rectangle has sides beyond the max rectangle, or is larger
|
||||
* in any direction; shift or adjust the rectangle while trying to fit in
|
||||
* the grid */
|
||||
|
||||
/* Adjust left/right */
|
||||
if (right > max_right) {
|
||||
|
||||
/* shift to left */
|
||||
dw = right - max_right;
|
||||
right -= dw;
|
||||
left -= dw;
|
||||
|
||||
/* clamp left if too far */
|
||||
if (left < max_left) {
|
||||
left = max_left;
|
||||
}
|
||||
}
|
||||
else if (left < max_left) {
|
||||
|
||||
/* shift to right */
|
||||
dw = max_left - left;
|
||||
left += dw;
|
||||
right += dw;
|
||||
|
||||
/* clamp right if too far */
|
||||
if (right > max_right) {
|
||||
right = max_right;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust top/bottom */
|
||||
if (bottom > max_bottom) {
|
||||
|
||||
/* shift up */
|
||||
dh = bottom - max_bottom;
|
||||
bottom -= dh;
|
||||
top -= dh;
|
||||
|
||||
/* clamp top if too far */
|
||||
if (top < max_top) {
|
||||
top = max_top;
|
||||
}
|
||||
}
|
||||
else if (top < max_top) {
|
||||
|
||||
/* shift down */
|
||||
dh = max_top - top;
|
||||
top += dh;
|
||||
bottom += dh;
|
||||
|
||||
/* clamp bottom if too far */
|
||||
if (bottom > max_bottom) {
|
||||
bottom = max_bottom;
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit rect */
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int guac_common_rect_intersects(const guac_common_rect* rect,
|
||||
const guac_common_rect* other) {
|
||||
|
||||
/* Empty (no intersection) */
|
||||
if (other->x + other->width < rect->x || rect->x + rect->width < other->x ||
|
||||
other->y + other->height < rect->y || rect->y + rect->height < other->y) {
|
||||
return 0;
|
||||
}
|
||||
/* Complete */
|
||||
else if (other->x <= rect->x && (other->x + other->width) >= (rect->x + rect->width) &&
|
||||
other->y <= rect->y && (other->y + other->height) >= (rect->y + rect->height)) {
|
||||
return 2;
|
||||
}
|
||||
/* Partial intersection */
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int guac_common_rect_clip_and_split(guac_common_rect* rect,
|
||||
const guac_common_rect* hole, guac_common_rect* split_rect) {
|
||||
|
||||
/* Only continue if the rectangles intersects */
|
||||
if (!guac_common_rect_intersects(rect, hole))
|
||||
return 0;
|
||||
|
||||
int top, left, bottom, right;
|
||||
|
||||
/* Clip and split top */
|
||||
if (rect->y < hole->y) {
|
||||
top = rect->y;
|
||||
left = rect->x;
|
||||
bottom = hole->y;
|
||||
right = rect->x + rect->width;
|
||||
guac_common_rect_init(split_rect, left, top, right - left, bottom - top);
|
||||
|
||||
/* Re-initialize original rect */
|
||||
top = hole->y;
|
||||
bottom = rect->y + rect->height;
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Clip and split left */
|
||||
else if (rect->x < hole->x) {
|
||||
top = rect->y;
|
||||
left = rect->x;
|
||||
bottom = rect->y + rect->height;
|
||||
right = hole->x;
|
||||
guac_common_rect_init(split_rect, left, top, right - left, bottom - top);
|
||||
|
||||
/* Re-initialize original rect */
|
||||
left = hole->x;
|
||||
right = rect->x + rect->width;
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Clip and split bottom */
|
||||
else if (rect->y + rect->height > hole->y + hole->height) {
|
||||
top = hole->y + hole->height;
|
||||
left = rect->x;
|
||||
bottom = rect->y + rect->height;
|
||||
right = rect->x + rect->width;
|
||||
guac_common_rect_init(split_rect, left, top, right - left, bottom - top);
|
||||
|
||||
/* Re-initialize original rect */
|
||||
top = rect->y;
|
||||
bottom = hole->y + hole->height;
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Clip and split right */
|
||||
else if (rect->x + rect->width > hole->x + hole->width) {
|
||||
top = rect->y;
|
||||
left = hole->x + hole->width;
|
||||
bottom = rect->y + rect->height;
|
||||
right = rect->x + rect->width;
|
||||
guac_common_rect_init(split_rect, left, top, right - left, bottom - top);
|
||||
|
||||
/* Re-initialize original rect */
|
||||
left = rect->x;
|
||||
right = hole->x + hole->width;
|
||||
guac_common_rect_init(rect, left, top, right - left, bottom - top);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
2041
src/common/surface.c
2041
src/common/surface.c
File diff suppressed because it is too large
Load Diff
@ -39,12 +39,6 @@ noinst_HEADERS = \
|
||||
test_common_SOURCES = \
|
||||
iconv/convert.c \
|
||||
iconv/convert-test-data.c \
|
||||
rect/clip_and_split.c \
|
||||
rect/constrain.c \
|
||||
rect/expand_to_grid.c \
|
||||
rect/extend.c \
|
||||
rect/init.c \
|
||||
rect/intersects.c \
|
||||
string/count_occurrences.c \
|
||||
string/split.c
|
||||
|
||||
|
||||
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies that guac_common_rect_clip_and_split() divides a
|
||||
* rectangle into subrectangles after removing a "hole" rectangle.
|
||||
*/
|
||||
void test_rect__clip_and_split() {
|
||||
|
||||
int res;
|
||||
|
||||
guac_common_rect cut;
|
||||
guac_common_rect min;
|
||||
guac_common_rect rect;
|
||||
|
||||
guac_common_rect_init(&min, 10, 10, 10, 10);
|
||||
|
||||
/* Clip top */
|
||||
guac_common_rect_init(&rect, 10, 5, 10, 10);
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(10, cut.x);
|
||||
CU_ASSERT_EQUAL(5, cut.y);
|
||||
CU_ASSERT_EQUAL(10, cut.width);
|
||||
CU_ASSERT_EQUAL(5, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(10, rect.width);
|
||||
CU_ASSERT_EQUAL(5, rect.height);
|
||||
|
||||
/* Clip bottom */
|
||||
guac_common_rect_init(&rect, 10, 15, 10, 10);
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(10, cut.x);
|
||||
CU_ASSERT_EQUAL(20, cut.y);
|
||||
CU_ASSERT_EQUAL(10, cut.width);
|
||||
CU_ASSERT_EQUAL(5, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(15, rect.y);
|
||||
CU_ASSERT_EQUAL(10, rect.width);
|
||||
CU_ASSERT_EQUAL(5, rect.height);
|
||||
|
||||
/* Clip left */
|
||||
guac_common_rect_init(&rect, 5, 10, 10, 10);
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(5, cut.x);
|
||||
CU_ASSERT_EQUAL(10, cut.y);
|
||||
CU_ASSERT_EQUAL(5, cut.width);
|
||||
CU_ASSERT_EQUAL(10, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(5, rect.width);
|
||||
CU_ASSERT_EQUAL(10, rect.height);
|
||||
|
||||
/* Clip right */
|
||||
guac_common_rect_init(&rect, 15, 10, 10, 10);
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(20, cut.x);
|
||||
CU_ASSERT_EQUAL(10, cut.y);
|
||||
CU_ASSERT_EQUAL(5, cut.width);
|
||||
CU_ASSERT_EQUAL(10, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(15, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(5, rect.width);
|
||||
CU_ASSERT_EQUAL(10, rect.height);
|
||||
|
||||
/*
|
||||
* Test a rectangle which completely covers the hole.
|
||||
* Clip and split until done.
|
||||
*/
|
||||
guac_common_rect_init(&rect, 5, 5, 20, 20);
|
||||
|
||||
/* Clip top */
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(5, cut.x);
|
||||
CU_ASSERT_EQUAL(5, cut.y);
|
||||
CU_ASSERT_EQUAL(20, cut.width);
|
||||
CU_ASSERT_EQUAL(5, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(5, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(20, rect.width);
|
||||
CU_ASSERT_EQUAL(15, rect.height);
|
||||
|
||||
/* Clip left */
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(5, cut.x);
|
||||
CU_ASSERT_EQUAL(10, cut.y);
|
||||
CU_ASSERT_EQUAL(5, cut.width);
|
||||
CU_ASSERT_EQUAL(15, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(15, rect.width);
|
||||
CU_ASSERT_EQUAL(15, rect.height);
|
||||
|
||||
/* Clip bottom */
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
CU_ASSERT_EQUAL(10, cut.x);
|
||||
CU_ASSERT_EQUAL(20, cut.y);
|
||||
CU_ASSERT_EQUAL(15, cut.width);
|
||||
CU_ASSERT_EQUAL(5, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(15, rect.width);
|
||||
CU_ASSERT_EQUAL(10, rect.height);
|
||||
|
||||
/* Clip right */
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(20, cut.x);
|
||||
CU_ASSERT_EQUAL(10, cut.y);
|
||||
CU_ASSERT_EQUAL(5, cut.width);
|
||||
CU_ASSERT_EQUAL(10, cut.height);
|
||||
|
||||
CU_ASSERT_EQUAL(10, rect.x);
|
||||
CU_ASSERT_EQUAL(10, rect.y);
|
||||
CU_ASSERT_EQUAL(10, rect.width);
|
||||
CU_ASSERT_EQUAL(10, rect.height);
|
||||
|
||||
/* Make sure nothing is left to do */
|
||||
res = guac_common_rect_clip_and_split(&rect, &min, &cut);
|
||||
CU_ASSERT_EQUAL(0, res);
|
||||
|
||||
}
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies that guac_common_rect_constrain() restricts a given
|
||||
* rectangle to arbitrary bounds.
|
||||
*/
|
||||
void test_rect__constrain() {
|
||||
|
||||
guac_common_rect max;
|
||||
guac_common_rect rect;
|
||||
|
||||
guac_common_rect_init(&rect, -10, -10, 110, 110);
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
guac_common_rect_constrain(&rect, &max);
|
||||
|
||||
CU_ASSERT_EQUAL(0, rect.x);
|
||||
CU_ASSERT_EQUAL(0, rect.y);
|
||||
CU_ASSERT_EQUAL(100, rect.width);
|
||||
CU_ASSERT_EQUAL(100, rect.height);
|
||||
|
||||
}
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies guac_common_rect_expand_to_grid() properly shifts and
|
||||
* resizes rectangles to fit an NxN grid.
|
||||
*/
|
||||
void test_rect__expand_to_grid() {
|
||||
|
||||
int cell_size = 16;
|
||||
|
||||
guac_common_rect max;
|
||||
guac_common_rect rect;
|
||||
|
||||
/* Simple adjustment */
|
||||
guac_common_rect_init(&rect, 0, 0, 25, 25);
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
guac_common_rect_expand_to_grid(cell_size, &rect, &max);
|
||||
CU_ASSERT_EQUAL(0, rect.x);
|
||||
CU_ASSERT_EQUAL(0, rect.y);
|
||||
CU_ASSERT_EQUAL(32, rect.width);
|
||||
CU_ASSERT_EQUAL(32, rect.height);
|
||||
|
||||
/* Adjustment with moving of rect */
|
||||
guac_common_rect_init(&rect, 75, 75, 25, 25);
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
guac_common_rect_expand_to_grid(cell_size, &rect, &max);
|
||||
CU_ASSERT_EQUAL(max.width - 32, rect.x);
|
||||
CU_ASSERT_EQUAL(max.height - 32, rect.y);
|
||||
CU_ASSERT_EQUAL(32, rect.width);
|
||||
CU_ASSERT_EQUAL(32, rect.height);
|
||||
|
||||
guac_common_rect_init(&rect, -5, -5, 25, 25);
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
guac_common_rect_expand_to_grid(cell_size, &rect, &max);
|
||||
CU_ASSERT_EQUAL(0, rect.x);
|
||||
CU_ASSERT_EQUAL(0, rect.y);
|
||||
CU_ASSERT_EQUAL(32, rect.width);
|
||||
CU_ASSERT_EQUAL(32, rect.height);
|
||||
|
||||
/* Adjustment with moving and clamping of rect */
|
||||
guac_common_rect_init(&rect, 0, 0, 25, 15);
|
||||
guac_common_rect_init(&max, 0, 5, 32, 15);
|
||||
guac_common_rect_expand_to_grid(cell_size, &rect, &max);
|
||||
CU_ASSERT_EQUAL(max.x, rect.x);
|
||||
CU_ASSERT_EQUAL(max.y, rect.y);
|
||||
CU_ASSERT_EQUAL(max.width, rect.width);
|
||||
CU_ASSERT_EQUAL(max.height, rect.height);
|
||||
|
||||
}
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies that guac_common_rect_extend() expands the given
|
||||
* rectangle as necessary to contain at least the given bounds.
|
||||
*/
|
||||
void test_rect__extend() {
|
||||
|
||||
guac_common_rect max;
|
||||
guac_common_rect rect;
|
||||
|
||||
guac_common_rect_init(&rect, 10, 10, 90, 90);
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
guac_common_rect_extend(&rect, &max);
|
||||
CU_ASSERT_EQUAL(0, rect.x);
|
||||
CU_ASSERT_EQUAL(0, rect.y);
|
||||
CU_ASSERT_EQUAL(100, rect.width);
|
||||
CU_ASSERT_EQUAL(100, rect.height);
|
||||
|
||||
}
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies rectangle initialization via guac_common_rect_init().
|
||||
*/
|
||||
void test_rect__init() {
|
||||
|
||||
guac_common_rect max;
|
||||
|
||||
guac_common_rect_init(&max, 0, 0, 100, 100);
|
||||
|
||||
CU_ASSERT_EQUAL(0, max.x);
|
||||
CU_ASSERT_EQUAL(0, max.y);
|
||||
CU_ASSERT_EQUAL(100, max.width);
|
||||
CU_ASSERT_EQUAL(100, max.height);
|
||||
|
||||
}
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
/**
|
||||
* Test which verifies intersection testing via guac_common_rect_intersects().
|
||||
*/
|
||||
void test_rect__intersects() {
|
||||
|
||||
int res;
|
||||
|
||||
guac_common_rect min;
|
||||
guac_common_rect rect;
|
||||
|
||||
guac_common_rect_init(&min, 10, 10, 10, 10);
|
||||
|
||||
/* Rectangle intersection - empty
|
||||
* rectangle is outside */
|
||||
guac_common_rect_init(&rect, 25, 25, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(0, res);
|
||||
|
||||
/* Rectangle intersection - complete
|
||||
* rectangle is completely inside */
|
||||
guac_common_rect_init(&rect, 11, 11, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(2, res);
|
||||
|
||||
/* Rectangle intersection - partial
|
||||
* rectangle intersects UL */
|
||||
guac_common_rect_init(&rect, 8, 8, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
|
||||
/* Rectangle intersection - partial
|
||||
* rectangle intersects LR */
|
||||
guac_common_rect_init(&rect, 18, 18, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
|
||||
/* Rectangle intersection - complete
|
||||
* rect intersects along UL but inside */
|
||||
guac_common_rect_init(&rect, 10, 10, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(2, res);
|
||||
|
||||
/* Rectangle intersection - partial
|
||||
* rectangle intersects along L but outside */
|
||||
guac_common_rect_init(&rect, 5, 10, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
|
||||
/* Rectangle intersection - complete
|
||||
* rectangle intersects along LR but rest is inside */
|
||||
guac_common_rect_init(&rect, 15, 15, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(2, res);
|
||||
|
||||
/* Rectangle intersection - partial
|
||||
* rectangle intersects along R but rest is outside */
|
||||
guac_common_rect_init(&rect, 20, 10, 5, 5);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
|
||||
/* Rectangle intersection - partial
|
||||
* rectangle encloses min; which is a partial intersection */
|
||||
guac_common_rect_init(&rect, 5, 5, 20, 20);
|
||||
res = guac_common_rect_intersects(&rect, &min);
|
||||
CU_ASSERT_EQUAL(1, res);
|
||||
|
||||
}
|
||||
|
||||
@ -21,8 +21,6 @@
|
||||
|
||||
#include "clipboard.h"
|
||||
#include "input.h"
|
||||
#include "common/dot_cursor.h"
|
||||
#include "common/pointer_cursor.h"
|
||||
#include "user.h"
|
||||
#include "sftp.h"
|
||||
#include "vnc.h"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user