You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by jm...@apache.org on 2017/01/24 19:43:22 UTC
[1/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use
proper namespace for internal common headers.
Repository: incubator-guacamole-server
Updated Branches:
refs/heads/master 0ef87c443 -> 52ccd276d
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/recording.c
----------------------------------------------------------------------
diff --git a/src/common/recording.c b/src/common/recording.c
new file mode 100644
index 0000000..2c953b5
--- /dev/null
+++ b/src/common/recording.c
@@ -0,0 +1,160 @@
+/*
+ * 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/recording.h"
+
+#include <guacamole/client.h>
+#include <guacamole/socket.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/**
+ * Attempts to open a new recording within the given path and having the given
+ * name. If such a file already exists, sequential numeric suffixes (.1, .2,
+ * .3, etc.) are appended until a filename is found which does not exist (or
+ * until the maximum number of numeric suffixes has been tried). If the file
+ * absolutely cannot be opened due to an error, -1 is returned and errno is set
+ * appropriately.
+ *
+ * @param path
+ * The full path to the directory in which the data file should be created.
+ *
+ * @param name
+ * The name of the data file which should be crated within the given path.
+ *
+ * @param basename
+ * A buffer in which the path, a path separator, the filename, any
+ * necessary suffix, and a NULL terminator will be stored. If insufficient
+ * space is available, -1 will be returned, and errno will be set to
+ * ENAMETOOLONG.
+ *
+ * @param basename_size
+ * The number of bytes available within the provided basename buffer.
+ *
+ * @return
+ * The file descriptor of the open data file if open succeeded, or -1 on
+ * failure.
+ */
+static int guac_common_recording_open(const char* path,
+ const char* name, char* basename, int basename_size) {
+
+ int i;
+
+ /* Concatenate path and name (separated by a single slash) */
+ int basename_length = snprintf(basename,
+ basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH,
+ "%s/%s", path, name);
+
+ /* Abort if maximum length reached */
+ if (basename_length ==
+ basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ /* Attempt to open recording */
+ int fd = open(basename,
+ O_CREAT | O_EXCL | O_WRONLY,
+ S_IRUSR | S_IWUSR);
+
+ /* Continuously retry with alternate names on failure */
+ if (fd == -1) {
+
+ /* Prepare basename for additional suffix */
+ basename[basename_length] = '.';
+ char* suffix = &(basename[basename_length + 1]);
+
+ /* Continue retrying alternative suffixes if file already exists */
+ for (i = 1; fd == -1 && errno == EEXIST
+ && i <= GUAC_COMMON_RECORDING_MAX_SUFFIX; i++) {
+
+ /* Append new suffix */
+ sprintf(suffix, "%i", i);
+
+ /* Retry with newly-suffixed filename */
+ fd = open(basename,
+ O_CREAT | O_EXCL | O_WRONLY,
+ S_IRUSR | S_IWUSR);
+
+ }
+
+ /* Abort if we've run out of filenames */
+ if (fd == -1)
+ return -1;
+
+ } /* end if open succeeded */
+
+ /* Lock entire output file for writing by the current process */
+ struct flock file_lock = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0,
+ .l_pid = getpid()
+ };
+
+ /* Abort if file cannot be locked for reading */
+ if (fcntl(fd, F_SETLK, &file_lock) == -1) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+
+}
+
+int guac_common_recording_create(guac_client* client, const char* path,
+ const char* name, int create_path) {
+
+ char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];
+
+ /* Create path if it does not exist, fail if impossible */
+ if (create_path && mkdir(path, S_IRWXU) && errno != EEXIST) {
+ guac_client_log(client, GUAC_LOG_ERROR,
+ "Creation of recording failed: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Attempt to open recording file */
+ int fd = guac_common_recording_open(path, name, filename, sizeof(filename));
+ if (fd == -1) {
+ guac_client_log(client, GUAC_LOG_ERROR,
+ "Creation of recording failed: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Replace client socket with wrapped socket */
+ client->socket = guac_socket_tee(client->socket, guac_socket_open(fd));
+
+ /* Recording creation succeeded */
+ guac_client_log(client, GUAC_LOG_INFO,
+ "Recording of session will be saved to \"%s\".",
+ filename);
+
+ return 0;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/rect.c
----------------------------------------------------------------------
diff --git a/src/common/rect.c b/src/common/rect.c
new file mode 100644
index 0000000..a7ca7da
--- /dev/null
+++ b/src/common/rect.c
@@ -0,0 +1,266 @@
+/*
+ * 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;
+}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/string.c
----------------------------------------------------------------------
diff --git a/src/common/string.c b/src/common/string.c
new file mode 100644
index 0000000..b247999
--- /dev/null
+++ b/src/common/string.c
@@ -0,0 +1,90 @@
+/*
+ * 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/string.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+int guac_count_occurrences(const char* string, char c) {
+
+ int count = 0;
+
+ while (*string != 0) {
+
+ /* Count each occurrence */
+ if (*string == c)
+ count++;
+
+ /* Next character */
+ string++;
+
+ }
+
+ return count;
+
+}
+
+char** guac_split(const char* string, char delim) {
+
+ int i = 0;
+
+ int token_count = guac_count_occurrences(string, delim) + 1;
+ const char* token_start = string;
+
+ /* Allocate space for tokens */
+ char** tokens = malloc(sizeof(char*) * (token_count+1));
+
+ do {
+
+ int length;
+ char* token;
+
+ /* Find end of token */
+ while (*string != 0 && *string != delim)
+ string++;
+
+ /* Calculate token length */
+ length = string - token_start;
+
+ /* Allocate space for token and NULL terminator */
+ tokens[i++] = token = malloc(length + 1);
+
+ /* Copy token, store null */
+ memcpy(token, token_start, length);
+ token[length] = 0;
+
+ /* Stop at end of string */
+ if (*string == 0)
+ break;
+
+ /* Next token */
+ token_start = ++string;
+
+ } while (i < token_count);
+
+ /* NULL terminator */
+ tokens[i] = NULL;
+
+ return tokens;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/surface.c
----------------------------------------------------------------------
diff --git a/src/common/surface.c b/src/common/surface.c
new file mode 100644
index 0000000..5a68093
--- /dev/null
+++ b/src/common/surface.c
@@ -0,0 +1,1552 @@
+/*
+ * 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"
+#include "common/surface.h"
+
+#include <cairo/cairo.h>
+#include <guacamole/client.h>
+#include <guacamole/layer.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/timestamp.h>
+#include <guacamole/user.h>
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+/**
+ * The width of an update which should be considered negible and thus
+ * trivial overhead compared ot the cost of two updates.
+ */
+#define GUAC_SURFACE_NEGLIGIBLE_WIDTH 64
+
+/**
+ * The height of an update which should be considered negible and thus
+ * trivial overhead compared ot the cost of two updates.
+ */
+#define GUAC_SURFACE_NEGLIGIBLE_HEIGHT 64
+
+/**
+ * The proportional increase in cost contributed by transfer and processing of
+ * image data, compared to processing an equivalent amount of client-side
+ * data.
+ */
+#define GUAC_SURFACE_DATA_FACTOR 16
+
+/**
+ * The base cost of every update. Each update should be considered to have
+ * this starting cost, plus any additional cost estimated from its
+ * content.
+ */
+#define GUAC_SURFACE_BASE_COST 4096
+
+/**
+ * An increase in cost is negligible if it is less than
+ * 1/GUAC_SURFACE_NEGLIGIBLE_INCREASE of the old cost.
+ */
+#define GUAC_SURFACE_NEGLIGIBLE_INCREASE 4
+
+/**
+ * If combining an update because it appears to be follow a fill pattern,
+ * the combined cost must not exceed
+ * GUAC_SURFACE_FILL_PATTERN_FACTOR * (total uncombined cost).
+ */
+#define GUAC_SURFACE_FILL_PATTERN_FACTOR 3
+
+/* Define cairo_format_stride_for_width() if missing */
+#ifndef HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH
+#define cairo_format_stride_for_width(format, width) (width*4)
+#endif
+
+/**
+ * The JPEG image quality ('quantization') setting to use. Range 0-100 where
+ * 100 is the highest quality/largest file size, and 0 is the lowest
+ * quality/smallest file size.
+ */
+#define GUAC_SURFACE_JPEG_IMAGE_QUALITY 90
+
+/**
+ * The framerate which, if exceeded, indicates that JPEG is preferred.
+ */
+#define GUAC_COMMON_SURFACE_JPEG_FRAMERATE 3
+
+/**
+ * Minimum JPEG bitmap size (area). If the bitmap is smaller than this threshold,
+ * it should be compressed as a PNG image to avoid the JPEG compression tax.
+ */
+#define GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE 4096
+
+/**
+ * The WebP image quality ('quantization') setting to use. Range 0-100 where
+ * 100 is the highest quality/largest file size, and 0 is the lowest
+ * quality/smallest file size.
+ */
+#define GUAC_SURFACE_WEBP_IMAGE_QUALITY 90
+
+/**
+ * The JPEG compression min block size. This defines the optimal rectangle block
+ * size factor for JPEG compression. Usually 8x8 would suffice, but use 16 to
+ * reduce the occurrence of ringing artifacts further.
+ */
+#define GUAC_SURFACE_JPEG_BLOCK_SIZE 16
+
+/**
+ * The WebP compression min block size. This defines the optimal rectangle block
+ * size factor for WebP compression. WebP does utilize variable block size, but
+ * ensuring a block size factor reduces any noise on the image edges.
+ */
+#define GUAC_SURFACE_WEBP_BLOCK_SIZE 8
+
+/**
+ * Updates the coordinates of the given rectangle to be within the bounds of
+ * the given surface.
+ *
+ * @param surface The surface to use for clipping.
+ * @param rect The rectangle to clip.
+ * @param sx The X coordinate of the source rectangle, if any.
+ * @param sy The Y coordinate of the source rectangle, if any.
+ */
+static void __guac_common_bound_rect(guac_common_surface* surface,
+ guac_common_rect* rect, int* sx, int* sy) {
+
+ guac_common_rect bounds_rect = {
+ .x = 0,
+ .y = 0,
+ .width = surface->width,
+ .height = surface->height
+ };
+
+ int orig_x = rect->x;
+ int orig_y = rect->y;
+
+ guac_common_rect_constrain(rect, &bounds_rect);
+
+ /* Update source X/Y if given */
+ if (sx != NULL) *sx += rect->x - orig_x;
+ if (sy != NULL) *sy += rect->y - orig_y;
+
+}
+
+/**
+ * Updates the coordinates of the given rectangle to be within the clipping
+ * rectangle of the given surface, which must always be within the bounding
+ * rectangle of the given surface.
+ *
+ * @param surface The surface to use for clipping.
+ * @param rect The rectangle to clip.
+ * @param sx The X coordinate of the source rectangle, if any.
+ * @param sy The Y coordinate of the source rectangle, if any.
+ */
+static void __guac_common_clip_rect(guac_common_surface* surface,
+ guac_common_rect* rect, int* sx, int* sy) {
+
+ int orig_x = rect->x;
+ int orig_y = rect->y;
+
+ /* Just bound within surface if no clipping rectangle applied */
+ if (!surface->clipped) {
+ __guac_common_bound_rect(surface, rect, sx, sy);
+ return;
+ }
+
+ guac_common_rect_constrain(rect, &surface->clip_rect);
+
+ /* Update source X/Y if given */
+ if (sx != NULL) *sx += rect->x - orig_x;
+ if (sy != NULL) *sy += rect->y - orig_y;
+
+}
+
+/**
+ * Returns whether the given rectangle should be combined into the existing
+ * dirty rectangle, to be eventually flushed as a "png" instruction.
+ *
+ * @param surface The surface to be queried.
+ * @param rect The update rectangle.
+ * @param rect_only Non-zero if this update, by its nature, contains only
+ * metainformation about the update's rectangle, zero if
+ * the update also contains image data.
+ * @return Non-zero if the update should be combined with any existing update,
+ * zero otherwise.
+ */
+static int __guac_common_should_combine(guac_common_surface* surface, const guac_common_rect* rect, int rect_only) {
+
+ if (surface->dirty) {
+
+ int combined_cost, dirty_cost, update_cost;
+
+ /* Simulate combination */
+ guac_common_rect combined = surface->dirty_rect;
+ guac_common_rect_extend(&combined, rect);
+
+ /* Combine if result is still small */
+ if (combined.width <= GUAC_SURFACE_NEGLIGIBLE_WIDTH && combined.height <= GUAC_SURFACE_NEGLIGIBLE_HEIGHT)
+ return 1;
+
+ /* Estimate costs of the existing update, new update, and both combined */
+ combined_cost = GUAC_SURFACE_BASE_COST + combined.width * combined.height;
+ dirty_cost = GUAC_SURFACE_BASE_COST + surface->dirty_rect.width * surface->dirty_rect.height;
+ update_cost = GUAC_SURFACE_BASE_COST + rect->width * rect->height;
+
+ /* Reduce cost if no image data */
+ if (rect_only)
+ update_cost /= GUAC_SURFACE_DATA_FACTOR;
+
+ /* Combine if cost estimate shows benefit */
+ if (combined_cost <= update_cost + dirty_cost)
+ return 1;
+
+ /* Combine if increase in cost is negligible */
+ if (combined_cost - dirty_cost <= dirty_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
+ return 1;
+
+ if (combined_cost - update_cost <= update_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
+ return 1;
+
+ /* Combine if we anticipate further updates, as this update follows a common fill pattern */
+ if (rect->x == surface->dirty_rect.x && rect->y == surface->dirty_rect.y + surface->dirty_rect.height) {
+ if (combined_cost <= (dirty_cost + update_cost) * GUAC_SURFACE_FILL_PATTERN_FACTOR)
+ return 1;
+ }
+
+ }
+
+ /* Otherwise, do not combine */
+ return 0;
+
+}
+
+/**
+ * Expands the dirty rect of the given surface to contain the rect described by the given
+ * coordinates.
+ *
+ * @param surface The surface to mark as dirty.
+ * @param rect The rectangle of the update which is dirtying the surface.
+ */
+static void __guac_common_mark_dirty(guac_common_surface* surface, const guac_common_rect* rect) {
+
+ /* Ignore empty rects */
+ if (rect->width <= 0 || rect->height <= 0)
+ return;
+
+ /* If already dirty, update existing rect */
+ if (surface->dirty)
+ guac_common_rect_extend(&surface->dirty_rect, rect);
+
+ /* Otherwise init dirty rect */
+ else {
+ surface->dirty_rect = *rect;
+ surface->dirty = 1;
+ }
+
+}
+
+/**
+ * Calculate the current average framerate for a given area on the surface.
+ *
+ * @param surface
+ * The surface on which the framerate will be calculated.
+ *
+ * @param rect
+ * The rect containing the area for which the average framerate will be
+ * calculated.
+ *
+ * @return
+ * The average framerate of the given area, in frames per second.
+ */
+static unsigned int __guac_common_surface_calculate_framerate(
+ guac_common_surface* surface, const guac_common_rect* rect) {
+
+ int x, y;
+
+ /* Calculate heat map dimensions */
+ int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
+
+ /* Calculate minimum X/Y coordinates intersecting given rect */
+ int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+ int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+
+ /* Calculate maximum X/Y coordinates intersecting given rect */
+ int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+ int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+
+ unsigned int sum_framerate = 0;
+ unsigned int count = 0;
+
+ /* Get start of buffer at given coordinates */
+ const guac_common_surface_heat_cell* heat_row =
+ surface->heat_map + min_y * heat_width + min_x;
+
+ /* Iterate over all the heat map cells for the area
+ * and calculate the average framerate */
+ for (y = min_y; y < max_y; y++) {
+
+ /* Get current row of heat map */
+ const guac_common_surface_heat_cell* heat_cell = heat_row;
+
+ /* For each cell in subset of row */
+ for (x = min_x; x < max_x; x++) {
+
+ /* Calculate indicies for latest and oldest history entries */
+ int oldest_entry = heat_cell->oldest_entry;
+ int latest_entry = oldest_entry - 1;
+ if (latest_entry < 0)
+ latest_entry = GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE - 1;
+
+ /* Calculate elapsed time covering entire history for this cell */
+ int elapsed_time = heat_cell->history[latest_entry]
+ - heat_cell->history[oldest_entry];
+
+ /* Calculate and add framerate */
+ if (elapsed_time)
+ sum_framerate += GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE
+ * 1000 / elapsed_time;
+
+ /* Next heat map cell */
+ heat_cell++;
+ count++;
+
+ }
+
+ /* Next heat map row */
+ heat_row += heat_width;
+
+ }
+
+ /* Calculate the average framerate over entire rect */
+ if (count)
+ return sum_framerate / count;
+
+ return 0;
+
+}
+
+ /**
+ * Guesses whether a rectangle within a particular surface would be better
+ * compressed as PNG or using a lossy format like JPEG. Positive values
+ * indicate PNG is likely to be superior, while negative values indicate the
+ * opposite.
+ *
+ * @param surface
+ * The surface containing the image data to check.
+ *
+ * @param rect
+ * The rect to check within the given surface.
+ *
+ * @return
+ * Positive values if PNG compression is likely to perform better than
+ * lossy alternatives, or negative values if PNG is likely to perform
+ * worse.
+ */
+static int __guac_common_surface_png_optimality(guac_common_surface* surface,
+ const guac_common_rect* rect) {
+
+ int x, y;
+
+ int num_same = 0;
+ int num_different = 1;
+
+ /* Get image/buffer metrics */
+ int width = rect->width;
+ int height = rect->height;
+ int stride = surface->stride;
+
+ /* Get buffer from surface */
+ unsigned char* buffer = surface->buffer + rect->y * stride + rect->x * 4;
+
+ /* Image must be at least 1x1 */
+ if (width < 1 || height < 1)
+ return 0;
+
+ /* For each row */
+ for (y = 0; y < height; y++) {
+
+ uint32_t* row = (uint32_t*) buffer;
+ uint32_t last_pixel = *(row++) | 0xFF000000;
+
+ /* For each pixel in current row */
+ for (x = 1; x < width; x++) {
+
+ /* Get next pixel */
+ uint32_t current_pixel = *(row++) | 0xFF000000;
+
+ /* Update same/different counts according to pixel value */
+ if (current_pixel == last_pixel)
+ num_same++;
+ else
+ num_different++;
+
+ last_pixel = current_pixel;
+
+ }
+
+ /* Advance to next row */
+ buffer += stride;
+
+ }
+
+ /* Return rough approximation of optimality for PNG compression */
+ return 0x100 * num_same / num_different - 0x400;
+
+}
+
+/**
+ * Returns whether the given rectangle would be optimally encoded as JPEG
+ * rather than PNG.
+ *
+ * @param surface
+ * The surface to be queried.
+ *
+ * @param rect
+ * The rectangle to check.
+ *
+ * @return
+ * Non-zero if the rectangle would be optimally encoded as JPEG, zero
+ * otherwise.
+ */
+static int __guac_common_surface_should_use_jpeg(guac_common_surface* surface,
+ const guac_common_rect* rect) {
+
+ /* Calculate the average framerate for the given rect */
+ int framerate = __guac_common_surface_calculate_framerate(surface, rect);
+
+ int rect_size = rect->width * rect->height;
+
+ /* JPEG is preferred if:
+ * - frame rate is high enough
+ * - image size is large enough
+ * - PNG is not more optimal based on image contents */
+ return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
+ && rect_size > GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE
+ && __guac_common_surface_png_optimality(surface, rect) < 0;
+
+}
+
+/**
+ * Returns whether the given rectangle would be optimally encoded as WebP
+ * rather than PNG.
+ *
+ * @param surface
+ * The surface to be queried.
+ *
+ * @param rect
+ * The rectangle to check.
+ *
+ * @return
+ * Non-zero if the rectangle would be optimally encoded as WebP, zero
+ * otherwise.
+ */
+static int __guac_common_surface_should_use_webp(guac_common_surface* surface,
+ const guac_common_rect* rect) {
+
+ /* Do not use WebP if not supported */
+ if (!guac_client_supports_webp(surface->client))
+ return 0;
+
+ /* Calculate the average framerate for the given rect */
+ int framerate = __guac_common_surface_calculate_framerate(surface, rect);
+
+ /* WebP is preferred if:
+ * - frame rate is high enough
+ * - PNG is not more optimal based on image contents */
+ return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
+ && __guac_common_surface_png_optimality(surface, rect) < 0;
+
+}
+
+/**
+ * Updates the heat map cells which intersect the given rectangle using the
+ * given timestamp. This timestamp, along with timestamps from past updates,
+ * is used to calculate the framerate of each heat cell.
+ *
+ * @param surface
+ * The surface containing the heat map cells to be updated.
+ *
+ * @param rect
+ * The rectangle containing the heat map cells to be updated.
+ *
+ * @param time
+ * The timestamp to use when updating the heat map cells which intersect
+ * the given rectangle.
+ */
+static void __guac_common_surface_touch_rect(guac_common_surface* surface,
+ guac_common_rect* rect, guac_timestamp time) {
+
+ int x, y;
+
+ /* Calculate heat map dimensions */
+ int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
+
+ /* Calculate minimum X/Y coordinates intersecting given rect */
+ int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+ int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+
+ /* Calculate maximum X/Y coordinates intersecting given rect */
+ int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+ int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
+
+ /* Get start of buffer at given coordinates */
+ guac_common_surface_heat_cell* heat_row =
+ surface->heat_map + min_y * heat_width + min_x;
+
+ /* Update all heat map cells which intersect with rectangle */
+ for (y = min_y; y <= max_y; y++) {
+
+ /* Get current row of heat map */
+ guac_common_surface_heat_cell* heat_cell = heat_row;
+
+ /* For each cell in subset of row */
+ for (x = min_x; x <= max_x; x++) {
+
+ /* Replace oldest entry with new timestamp */
+ heat_cell->history[heat_cell->oldest_entry] = time;
+
+ /* Update to next oldest entry */
+ heat_cell->oldest_entry++;
+ if (heat_cell->oldest_entry >=
+ GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE)
+ heat_cell->oldest_entry = 0;
+
+ /* Advance to next heat map cell */
+ heat_cell++;
+
+ }
+
+ /* Next heat map row */
+ heat_row += heat_width;
+
+ }
+
+}
+
+/**
+ * Flushes the bitmap update currently described by the dirty rectangle within the
+ * given surface to that surface's bitmap queue. There MUST be space within the
+ * queue.
+ *
+ * @param surface The surface to flush.
+ */
+static void __guac_common_surface_flush_to_queue(guac_common_surface* surface) {
+
+ guac_common_surface_bitmap_rect* rect;
+
+ /* Do not flush if not dirty */
+ if (!surface->dirty)
+ return;
+
+ /* Add new rect to queue */
+ rect = &(surface->bitmap_queue[surface->bitmap_queue_length++]);
+ rect->rect = surface->dirty_rect;
+ rect->flushed = 0;
+
+ /* Surface now flushed */
+ surface->dirty = 0;
+
+}
+
+void guac_common_surface_flush_deferred(guac_common_surface* surface) {
+
+ /* Do not flush if not dirty */
+ if (!surface->dirty)
+ return;
+
+ /* Flush if queue size has reached maximum (space is reserved for the final dirty rect,
+ * as guac_common_surface_flush() MAY add an additional rect to the queue */
+ if (surface->bitmap_queue_length == GUAC_COMMON_SURFACE_QUEUE_SIZE-1)
+ guac_common_surface_flush(surface);
+
+ /* Append dirty rect to queue */
+ __guac_common_surface_flush_to_queue(surface);
+
+}
+
+/**
+ * Transfers a single uint32_t using the given transfer function.
+ *
+ * @param op The transfer function to use.
+ * @param src The source of the uint32_t value.
+ * @param dst THe destination which will hold the result of the transfer.
+ * @return Non-zero if the destination value was changed, zero otherwise.
+ */
+static int __guac_common_surface_transfer_int(guac_transfer_function op, uint32_t* src, uint32_t* dst) {
+
+ uint32_t orig = *dst;
+
+ switch (op) {
+
+ case GUAC_TRANSFER_BINARY_BLACK:
+ *dst = 0xFF000000;
+ break;
+
+ case GUAC_TRANSFER_BINARY_WHITE:
+ *dst = 0xFFFFFFFF;
+ break;
+
+ case GUAC_TRANSFER_BINARY_SRC:
+ *dst = *src;
+ break;
+
+ case GUAC_TRANSFER_BINARY_DEST:
+ /* NOP */
+ break;
+
+ case GUAC_TRANSFER_BINARY_NSRC:
+ *dst = ~(*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_NDEST:
+ *dst = ~(*dst);
+ break;
+
+ case GUAC_TRANSFER_BINARY_AND:
+ *dst = (*dst) & (*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_NAND:
+ *dst = ~((*dst) & (*src));
+ break;
+
+ case GUAC_TRANSFER_BINARY_OR:
+ *dst = (*dst) | (*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_NOR:
+ *dst = ~((*dst) | (*src));
+ break;
+
+ case GUAC_TRANSFER_BINARY_XOR:
+ *dst = (*dst) ^ (*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_XNOR:
+ *dst = ~((*dst) ^ (*src));
+ break;
+
+ case GUAC_TRANSFER_BINARY_NSRC_AND:
+ *dst = (*dst) & ~(*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_NSRC_NAND:
+ *dst = ~((*dst) & ~(*src));
+ break;
+
+ case GUAC_TRANSFER_BINARY_NSRC_OR:
+ *dst = (*dst) | ~(*src);
+ break;
+
+ case GUAC_TRANSFER_BINARY_NSRC_NOR:
+ *dst = ~((*dst) | ~(*src));
+ break;
+
+ }
+
+ return *dst != orig;
+
+}
+
+/**
+ * Draws a rectangle of solid color within the backing surface of the
+ * given destination surface.
+ *
+ * @param dst The destination surface.
+ * @param rect The rectangle to draw.
+ * @param red The red component of the color of the rectangle.
+ * @param green The green component of the color of the rectangle.
+ * @param blue The blue component of the color of the rectangle.
+ */
+static void __guac_common_surface_rect(guac_common_surface* dst, guac_common_rect* rect,
+ int red, int green, int blue) {
+
+ int x, y;
+
+ int dst_stride;
+ unsigned char* dst_buffer;
+
+ uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
+
+ int min_x = rect->width - 1;
+ int min_y = rect->height - 1;
+ int max_x = 0;
+ int max_y = 0;
+
+ dst_stride = dst->stride;
+ dst_buffer = dst->buffer + (dst_stride * rect->y) + (4 * rect->x);
+
+ /* For each row */
+ for (y=0; y < rect->height; y++) {
+
+ uint32_t* dst_current = (uint32_t*) dst_buffer;
+
+ /* Set row */
+ for (x=0; x < rect->width; x++) {
+
+ uint32_t old_color = *dst_current;
+
+ if (old_color != color) {
+ if (x < min_x) min_x = x;
+ if (y < min_y) min_y = y;
+ if (x > max_x) max_x = x;
+ if (y > max_y) max_y = y;
+ *dst_current = color;
+ }
+
+ dst_current++;
+ }
+
+ /* Next row */
+ dst_buffer += dst_stride;
+
+ }
+
+ /* Restrict destination rect to only updated pixels */
+ if (max_x >= min_x && max_y >= min_y) {
+ rect->x += min_x;
+ rect->y += min_y;
+ rect->width = max_x - min_x + 1;
+ rect->height = max_y - min_y + 1;
+ }
+ else {
+ rect->width = 0;
+ rect->height = 0;
+ }
+
+}
+
+/**
+ * Copies data from the given buffer to the surface at the given coordinates.
+ * The dimensions and location of the destination rectangle will be altered
+ * to remove as many unchanged pixels as possible.
+ *
+ * @param src_buffer The buffer to copy.
+ * @param src_stride The number of bytes in each row of the source buffer.
+ * @param sx The X coordinate of the source rectangle.
+ * @param sy The Y coordinate of the source rectangle.
+ * @param dst The destination surface.
+ * @param rect The destination rectangle.
+ * @param opaque Non-zero if the source surface is opaque (its alpha channel
+ * should be ignored), zero otherwise.
+ */
+static void __guac_common_surface_put(unsigned char* src_buffer, int src_stride,
+ int* sx, int* sy,
+ guac_common_surface* dst, guac_common_rect* rect,
+ int opaque) {
+
+ unsigned char* dst_buffer = dst->buffer;
+ int dst_stride = dst->stride;
+
+ int x, y;
+
+ int min_x = rect->width;
+ int min_y = rect->height;
+ int max_x = 0;
+ int max_y = 0;
+
+ int orig_x = rect->x;
+ int orig_y = rect->y;
+
+ src_buffer += src_stride * (*sy) + 4 * (*sx);
+ dst_buffer += (dst_stride * rect->y) + (4 * rect->x);
+
+ /* For each row */
+ for (y=0; y < rect->height; y++) {
+
+ uint32_t* src_current = (uint32_t*) src_buffer;
+ uint32_t* dst_current = (uint32_t*) dst_buffer;
+
+ /* Copy row */
+ for (x=0; x < rect->width; x++) {
+
+ if (opaque || (*src_current & 0xFF000000)) {
+
+ uint32_t new_color = *src_current | 0xFF000000;
+ uint32_t old_color = *dst_current;
+
+ if (old_color != new_color) {
+ if (x < min_x) min_x = x;
+ if (y < min_y) min_y = y;
+ if (x > max_x) max_x = x;
+ if (y > max_y) max_y = y;
+ *dst_current = new_color;
+ }
+ }
+
+ src_current++;
+ dst_current++;
+ }
+
+ /* Next row */
+ src_buffer += src_stride;
+ dst_buffer += dst_stride;
+
+ }
+
+ /* Restrict destination rect to only updated pixels */
+ if (max_x >= min_x && max_y >= min_y) {
+ rect->x += min_x;
+ rect->y += min_y;
+ rect->width = max_x - min_x + 1;
+ rect->height = max_y - min_y + 1;
+ }
+ else {
+ rect->width = 0;
+ rect->height = 0;
+ }
+
+ /* Update source X/Y */
+ *sx += rect->x - orig_x;
+ *sy += rect->y - orig_y;
+
+}
+
+/**
+ * Fills the given surface with color, using the given buffer as a mask. Color
+ * will be added to the given surface iff the corresponding pixel within the
+ * buffer is opaque.
+ *
+ * @param src_buffer The buffer to use as a mask.
+ * @param src_stride The number of bytes in each row of the source buffer.
+ * @param sx The X coordinate of the source rectangle.
+ * @param sy The Y coordinate of the source rectangle.
+ * @param dst The destination surface.
+ * @param rect The destination rectangle.
+ * @param red The red component of the color of the fill.
+ * @param green The green component of the color of the fill.
+ * @param blue The blue component of the color of the fill.
+ */
+static void __guac_common_surface_fill_mask(unsigned char* src_buffer, int src_stride,
+ int sx, int sy,
+ guac_common_surface* dst, guac_common_rect* rect,
+ int red, int green, int blue) {
+
+ unsigned char* dst_buffer = dst->buffer;
+ int dst_stride = dst->stride;
+
+ uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
+ int x, y;
+
+ src_buffer += src_stride*sy + 4*sx;
+ dst_buffer += (dst_stride * rect->y) + (4 * rect->x);
+
+ /* For each row */
+ for (y=0; y < rect->height; y++) {
+
+ uint32_t* src_current = (uint32_t*) src_buffer;
+ uint32_t* dst_current = (uint32_t*) dst_buffer;
+
+ /* Stencil row */
+ for (x=0; x < rect->width; x++) {
+
+ /* Fill with color if opaque */
+ if (*src_current & 0xFF000000)
+ *dst_current = color;
+
+ src_current++;
+ dst_current++;
+ }
+
+ /* Next row */
+ src_buffer += src_stride;
+ dst_buffer += dst_stride;
+
+ }
+
+}
+
+/**
+ * Copies data from the given surface to the given destination surface using
+ * the specified transfer function.
+ *
+ * @param src_buffer The buffer to copy.
+ * @param src_stride The number of bytes in each row of the source buffer.
+ * @param sx The X coordinate of the source rectangle.
+ * @param sy The Y coordinate of the source rectangle.
+ * @param op The transfer function to use.
+ * @param dst The destination surface.
+ * @param rect The destination rectangle.
+ */
+static void __guac_common_surface_transfer(guac_common_surface* src, int* sx, int* sy,
+ guac_transfer_function op,
+ guac_common_surface* dst, guac_common_rect* rect) {
+
+ unsigned char* src_buffer = src->buffer;
+ unsigned char* dst_buffer = dst->buffer;
+
+ int x, y;
+ int src_stride, dst_stride;
+ int step = 1;
+
+ int min_x = rect->width - 1;
+ int min_y = rect->height - 1;
+ int max_x = 0;
+ int max_y = 0;
+
+ int orig_x = rect->x;
+ int orig_y = rect->y;
+
+ /* Copy forwards only if destination is in a different surface or is before source */
+ if (src != dst || rect->y < *sy || (rect->y == *sy && rect->x < *sx)) {
+ src_buffer += src->stride * (*sy) + 4 * (*sx);
+ dst_buffer += (dst->stride * rect->y) + (4 * rect->x);
+ src_stride = src->stride;
+ dst_stride = dst->stride;
+ step = 1;
+ }
+
+ /* Otherwise, copy backwards */
+ else {
+ src_buffer += src->stride * (*sy + rect->height - 1) + 4 * (*sx + rect->width - 1);
+ dst_buffer += dst->stride * (rect->y + rect->height - 1) + 4 * (rect->x + rect->width - 1);
+ src_stride = -src->stride;
+ dst_stride = -dst->stride;
+ step = -1;
+ }
+
+ /* For each row */
+ for (y=0; y < rect->height; y++) {
+
+ uint32_t* src_current = (uint32_t*) src_buffer;
+ uint32_t* dst_current = (uint32_t*) dst_buffer;
+
+ /* Transfer each pixel in row */
+ for (x=0; x < rect->width; x++) {
+
+ if (__guac_common_surface_transfer_int(op, src_current, dst_current)) {
+ if (x < min_x) min_x = x;
+ if (y < min_y) min_y = y;
+ if (x > max_x) max_x = x;
+ if (y > max_y) max_y = y;
+ }
+
+ src_current += step;
+ dst_current += step;
+ }
+
+ /* Next row */
+ src_buffer += src_stride;
+ dst_buffer += dst_stride;
+
+ }
+
+ /* Translate X coordinate space of moving backwards */
+ if (step < 0) {
+ int old_max_x = max_x;
+ max_x = rect->width - 1 - min_x;
+ min_x = rect->width - 1 - old_max_x;
+ }
+
+ /* Translate Y coordinate space of moving backwards */
+ if (dst_stride < 0) {
+ int old_max_y = max_y;
+ max_y = rect->height - 1 - min_y;
+ min_y = rect->height - 1 - old_max_y;
+ }
+
+ /* Restrict destination rect to only updated pixels */
+ if (max_x >= min_x && max_y >= min_y) {
+ rect->x += min_x;
+ rect->y += min_y;
+ rect->width = max_x - min_x + 1;
+ rect->height = max_y - min_y + 1;
+ }
+ else {
+ rect->width = 0;
+ rect->height = 0;
+ }
+
+ /* Update source X/Y */
+ *sx += rect->x - orig_x;
+ *sy += rect->y - orig_y;
+
+}
+
+guac_common_surface* guac_common_surface_alloc(guac_client* client,
+ guac_socket* socket, const guac_layer* layer, int w, int h) {
+
+ /* Calculate heat map dimensions */
+ int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
+ int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
+
+ /* Init surface */
+ guac_common_surface* surface = calloc(1, sizeof(guac_common_surface));
+ surface->client = client;
+ surface->socket = socket;
+ surface->layer = layer;
+ surface->width = w;
+ surface->height = h;
+
+ /* Create corresponding Cairo surface */
+ surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
+ surface->buffer = calloc(h, surface->stride);
+
+ /* Create corresponding heat map */
+ surface->heat_map = calloc(heat_width * heat_height,
+ sizeof(guac_common_surface_heat_cell));
+
+ /* Reset clipping rect */
+ guac_common_surface_reset_clip(surface);
+
+ /* Layers must initially exist */
+ if (layer->index >= 0) {
+ guac_protocol_send_size(socket, layer, w, h);
+ surface->realized = 1;
+ }
+
+ /* Defer creation of buffers */
+ else
+ surface->realized = 0;
+
+ return surface;
+}
+
+void guac_common_surface_free(guac_common_surface* surface) {
+
+ /* Only dispose of surface if it exists */
+ if (surface->realized)
+ guac_protocol_send_dispose(surface->socket, surface->layer);
+
+ free(surface->heat_map);
+ free(surface->buffer);
+ free(surface);
+
+}
+
+void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
+
+ guac_socket* socket = surface->socket;
+ const guac_layer* layer = surface->layer;
+
+ unsigned char* old_buffer;
+ int old_stride;
+ guac_common_rect old_rect;
+
+ int sx = 0;
+ int sy = 0;
+
+ /* Calculate heat map dimensions */
+ int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
+ int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
+
+ /* Copy old surface data */
+ old_buffer = surface->buffer;
+ old_stride = surface->stride;
+ guac_common_rect_init(&old_rect, 0, 0, surface->width, surface->height);
+
+ /* Re-initialize at new size */
+ surface->width = w;
+ surface->height = h;
+ surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
+ surface->buffer = calloc(h, surface->stride);
+ __guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);
+
+ /* Copy relevant old data */
+ __guac_common_bound_rect(surface, &old_rect, NULL, NULL);
+ __guac_common_surface_put(old_buffer, old_stride, &sx, &sy, surface, &old_rect, 1);
+
+ /* Free old data */
+ free(old_buffer);
+
+ /* Allocate completely new heat map (can safely discard old stats) */
+ free(surface->heat_map);
+ surface->heat_map = calloc(heat_width * heat_height,
+ sizeof(guac_common_surface_heat_cell));
+
+ /* Resize dirty rect to fit new surface dimensions */
+ if (surface->dirty) {
+ __guac_common_bound_rect(surface, &surface->dirty_rect, NULL, NULL);
+ if (surface->dirty_rect.width <= 0 || surface->dirty_rect.height <= 0)
+ surface->dirty = 0;
+ }
+
+ /* Update Guacamole layer */
+ if (surface->realized)
+ guac_protocol_send_size(socket, layer, w, h);
+
+}
+
+void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src) {
+
+ unsigned char* buffer = cairo_image_surface_get_data(src);
+ cairo_format_t format = cairo_image_surface_get_format(src);
+ int stride = cairo_image_surface_get_stride(src);
+ int w = cairo_image_surface_get_width(src);
+ int h = cairo_image_surface_get_height(src);
+
+ int sx = 0;
+ int sy = 0;
+
+ guac_common_rect rect;
+ guac_common_rect_init(&rect, x, y, w, h);
+
+ /* Clip operation */
+ __guac_common_clip_rect(surface, &rect, &sx, &sy);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update backing surface */
+ __guac_common_surface_put(buffer, stride, &sx, &sy, surface, &rect, format != CAIRO_FORMAT_ARGB32);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update the heat map for the update rectangle. */
+ guac_timestamp time = guac_timestamp_current();
+ __guac_common_surface_touch_rect(surface, &rect, time);
+
+ /* Flush if not combining */
+ if (!__guac_common_should_combine(surface, &rect, 0))
+ guac_common_surface_flush_deferred(surface);
+
+ /* Always defer draws */
+ __guac_common_mark_dirty(surface, &rect);
+
+}
+
+void guac_common_surface_paint(guac_common_surface* surface, int x, int y, cairo_surface_t* src,
+ int red, int green, int blue) {
+
+ unsigned char* buffer = cairo_image_surface_get_data(src);
+ int stride = cairo_image_surface_get_stride(src);
+ int w = cairo_image_surface_get_width(src);
+ int h = cairo_image_surface_get_height(src);
+
+ int sx = 0;
+ int sy = 0;
+
+ guac_common_rect rect;
+ guac_common_rect_init(&rect, x, y, w, h);
+
+ /* Clip operation */
+ __guac_common_clip_rect(surface, &rect, &sx, &sy);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update backing surface */
+ __guac_common_surface_fill_mask(buffer, stride, sx, sy, surface, &rect, red, green, blue);
+
+ /* Flush if not combining */
+ if (!__guac_common_should_combine(surface, &rect, 0))
+ guac_common_surface_flush_deferred(surface);
+
+ /* Always defer draws */
+ __guac_common_mark_dirty(surface, &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) {
+
+ guac_socket* socket = dst->socket;
+ const guac_layer* src_layer = src->layer;
+ const guac_layer* dst_layer = dst->layer;
+
+ guac_common_rect rect;
+ guac_common_rect_init(&rect, dx, dy, w, h);
+
+ /* Clip operation */
+ __guac_common_clip_rect(dst, &rect, &sx, &sy);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update backing surface first only if destination rect cannot intersect source rect */
+ if (src != dst) {
+ __guac_common_surface_transfer(src, &sx, &sy, GUAC_TRANSFER_BINARY_SRC, dst, &rect);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+ }
+
+ /* Defer if combining */
+ if (__guac_common_should_combine(dst, &rect, 1))
+ __guac_common_mark_dirty(dst, &rect);
+
+ /* Otherwise, flush and draw immediately */
+ else {
+ guac_common_surface_flush(dst);
+ guac_common_surface_flush(src);
+ guac_protocol_send_copy(socket, src_layer, sx, sy, rect.width, rect.height,
+ GUAC_COMP_OVER, dst_layer, rect.x, rect.y);
+ dst->realized = 1;
+ }
+
+ /* Update backing surface last if destination rect can intersect source rect */
+ if (src == dst)
+ __guac_common_surface_transfer(src, &sx, &sy, GUAC_TRANSFER_BINARY_SRC, dst, &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) {
+
+ guac_socket* socket = dst->socket;
+ const guac_layer* src_layer = src->layer;
+ const guac_layer* dst_layer = dst->layer;
+
+ guac_common_rect rect;
+ guac_common_rect_init(&rect, dx, dy, w, h);
+
+ /* Clip operation */
+ __guac_common_clip_rect(dst, &rect, &sx, &sy);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update backing surface first only if destination rect cannot intersect source rect */
+ if (src != dst) {
+ __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+ }
+
+ /* Defer if combining */
+ if (__guac_common_should_combine(dst, &rect, 1))
+ __guac_common_mark_dirty(dst, &rect);
+
+ /* Otherwise, flush and draw immediately */
+ else {
+ guac_common_surface_flush(dst);
+ guac_common_surface_flush(src);
+ guac_protocol_send_transfer(socket, src_layer, sx, sy, rect.width, rect.height, op, dst_layer, rect.x, rect.y);
+ dst->realized = 1;
+ }
+
+ /* Update backing surface last if destination rect can intersect source rect */
+ if (src == dst)
+ __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
+
+}
+
+void guac_common_surface_rect(guac_common_surface* surface,
+ int x, int y, int w, int h,
+ int red, int green, int blue) {
+
+ guac_socket* socket = surface->socket;
+ const guac_layer* layer = surface->layer;
+
+ guac_common_rect rect;
+ guac_common_rect_init(&rect, x, y, w, h);
+
+ /* Clip operation */
+ __guac_common_clip_rect(surface, &rect, NULL, NULL);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Update backing surface */
+ __guac_common_surface_rect(surface, &rect, red, green, blue);
+ if (rect.width <= 0 || rect.height <= 0)
+ return;
+
+ /* Defer if combining */
+ if (__guac_common_should_combine(surface, &rect, 1))
+ __guac_common_mark_dirty(surface, &rect);
+
+ /* Otherwise, flush and draw immediately */
+ else {
+ guac_common_surface_flush(surface);
+ guac_protocol_send_rect(socket, layer, rect.x, rect.y, rect.width, rect.height);
+ guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, 0xFF);
+ surface->realized = 1;
+ }
+
+}
+
+void guac_common_surface_clip(guac_common_surface* surface, int x, int y, int w, int h) {
+
+ guac_common_rect clip;
+
+ /* Init clipping rectangle if clipping not already applied */
+ if (!surface->clipped) {
+ guac_common_rect_init(&surface->clip_rect, 0, 0, surface->width, surface->height);
+ surface->clipped = 1;
+ }
+
+ guac_common_rect_init(&clip, x, y, w, h);
+ guac_common_rect_constrain(&surface->clip_rect, &clip);
+
+}
+
+void guac_common_surface_reset_clip(guac_common_surface* surface) {
+ surface->clipped = 0;
+}
+
+/**
+ * Flushes the bitmap update currently described by the dirty rectangle within
+ * the given surface directly via an "img" instruction as PNG data. The
+ * resulting instructions will be sent over the socket associated with the
+ * given surface.
+ *
+ * @param surface
+ * The surface to flush.
+ */
+static void __guac_common_surface_flush_to_png(guac_common_surface* surface) {
+
+ if (surface->dirty) {
+
+ guac_socket* socket = surface->socket;
+ const guac_layer* layer = surface->layer;
+
+ /* Get Cairo surface for specified rect */
+ unsigned char* buffer = surface->buffer
+ + surface->dirty_rect.y * surface->stride
+ + surface->dirty_rect.x * 4;
+
+ cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
+ CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
+ surface->dirty_rect.height, surface->stride);
+
+ /* Send PNG for rect */
+ guac_client_stream_png(surface->client, socket, GUAC_COMP_OVER,
+ layer, surface->dirty_rect.x, surface->dirty_rect.y, rect);
+
+ cairo_surface_destroy(rect);
+ surface->realized = 1;
+
+ /* Surface is no longer dirty */
+ surface->dirty = 0;
+
+ }
+
+}
+
+/**
+ * Flushes the bitmap update currently described by the dirty rectangle within
+ * the given surface directly via an "img" instruction as JPEG data. The
+ * resulting instructions will be sent over the socket associated with the
+ * given surface.
+ *
+ * @param surface
+ * The surface to flush.
+ */
+static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {
+
+ if (surface->dirty) {
+
+ guac_socket* socket = surface->socket;
+ const guac_layer* layer = surface->layer;
+
+ guac_common_rect max;
+ guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
+
+ /* Expand the dirty rect size to fit in a grid with cells equal to the
+ * minimum JPEG block size */
+ guac_common_rect_expand_to_grid(GUAC_SURFACE_JPEG_BLOCK_SIZE,
+ &surface->dirty_rect, &max);
+
+ /* Get Cairo surface for specified rect */
+ unsigned char* buffer = surface->buffer
+ + surface->dirty_rect.y * surface->stride
+ + surface->dirty_rect.x * 4;
+
+ cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
+ CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
+ surface->dirty_rect.height, surface->stride);
+
+ /* Send JPEG for rect */
+ guac_client_stream_jpeg(surface->client, socket, GUAC_COMP_OVER, layer,
+ surface->dirty_rect.x, surface->dirty_rect.y, rect,
+ GUAC_SURFACE_JPEG_IMAGE_QUALITY);
+
+ cairo_surface_destroy(rect);
+ surface->realized = 1;
+
+ /* Surface is no longer dirty */
+ surface->dirty = 0;
+
+ }
+
+}
+
+/**
+ * Flushes the bitmap update currently described by the dirty rectangle within
+ * the given surface directly via an "img" instruction as WebP data. The
+ * resulting instructions will be sent over the socket associated with the
+ * given surface.
+ *
+ * @param surface
+ * The surface to flush.
+ */
+static void __guac_common_surface_flush_to_webp(guac_common_surface* surface) {
+
+ if (surface->dirty) {
+
+ guac_socket* socket = surface->socket;
+ const guac_layer* layer = surface->layer;
+
+ guac_common_rect max;
+ guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
+
+ /* Expand the dirty rect size to fit in a grid with cells equal to the
+ * minimum WebP block size */
+ guac_common_rect_expand_to_grid(GUAC_SURFACE_WEBP_BLOCK_SIZE,
+ &surface->dirty_rect, &max);
+
+ /* Get Cairo surface for specified rect */
+ unsigned char* buffer = surface->buffer
+ + surface->dirty_rect.y * surface->stride
+ + surface->dirty_rect.x * 4;
+
+ cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
+ CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
+ surface->dirty_rect.height, surface->stride);
+
+ /* Send WebP for rect */
+ guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
+ surface->dirty_rect.x, surface->dirty_rect.y, rect,
+ GUAC_SURFACE_WEBP_IMAGE_QUALITY, 0);
+
+ cairo_surface_destroy(rect);
+ surface->realized = 1;
+
+ /* Surface is no longer dirty */
+ surface->dirty = 0;
+
+ }
+
+}
+
+
+/**
+ * Comparator for instances of guac_common_surface_bitmap_rect, the elements
+ * which make up a surface's bitmap buffer.
+ *
+ * @see qsort
+ */
+static int __guac_common_surface_bitmap_rect_compare(const void* a, const void* b) {
+
+ guac_common_surface_bitmap_rect* ra = (guac_common_surface_bitmap_rect*) a;
+ guac_common_surface_bitmap_rect* rb = (guac_common_surface_bitmap_rect*) b;
+
+ /* Order roughly top to bottom, left to right */
+ if (ra->rect.y != rb->rect.y) return ra->rect.y - rb->rect.y;
+ if (ra->rect.x != rb->rect.x) return ra->rect.x - rb->rect.x;
+
+ /* Wider updates should come first (more likely to intersect later) */
+ if (ra->rect.width != rb->rect.width) return rb->rect.width - ra->rect.width;
+
+ /* Shorter updates should come first (less likely to increase cost) */
+ return ra->rect.height - rb->rect.height;
+
+}
+
+void guac_common_surface_flush(guac_common_surface* surface) {
+
+ /* Flush final dirty rectangle to queue. */
+ __guac_common_surface_flush_to_queue(surface);
+
+ guac_common_surface_bitmap_rect* current = surface->bitmap_queue;
+ int i, j;
+ int original_queue_length;
+ int flushed = 0;
+
+ original_queue_length = surface->bitmap_queue_length;
+
+ /* Sort updates to make combination less costly */
+ qsort(surface->bitmap_queue, surface->bitmap_queue_length, sizeof(guac_common_surface_bitmap_rect),
+ __guac_common_surface_bitmap_rect_compare);
+
+ /* Flush all rects in queue */
+ for (i=0; i < surface->bitmap_queue_length; i++) {
+
+ /* Get next unflushed candidate */
+ guac_common_surface_bitmap_rect* candidate = current;
+ if (!candidate->flushed) {
+
+ int combined = 0;
+
+ /* Build up rect as much as possible */
+ for (j=i; j < surface->bitmap_queue_length; j++) {
+
+ if (!candidate->flushed) {
+
+ /* Clip candidate within current bounds */
+ __guac_common_bound_rect(surface, &candidate->rect, NULL, NULL);
+ if (candidate->rect.width <= 0 || candidate->rect.height <= 0)
+ candidate->flushed = 1;
+
+ /* Combine if reasonable */
+ else if (__guac_common_should_combine(surface, &candidate->rect, 0) || !surface->dirty) {
+ __guac_common_mark_dirty(surface, &candidate->rect);
+ candidate->flushed = 1;
+ combined++;
+ }
+
+ }
+
+ candidate++;
+
+ }
+
+ /* Re-add to queue if there's room and this update was modified or we expect others might be */
+ if ((combined > 1 || i < original_queue_length)
+ && surface->bitmap_queue_length < GUAC_COMMON_SURFACE_QUEUE_SIZE)
+ __guac_common_surface_flush_to_queue(surface);
+
+ /* Flush as bitmap otherwise */
+ else if (surface->dirty) {
+
+ flushed++;
+
+ /* Prefer WebP when reasonable */
+ if (__guac_common_surface_should_use_webp(surface,
+ &surface->dirty_rect))
+ __guac_common_surface_flush_to_webp(surface);
+
+ /* If not WebP, JPEG is the next best (lossy) choice */
+ else if (__guac_common_surface_should_use_jpeg(surface,
+ &surface->dirty_rect))
+ __guac_common_surface_flush_to_jpeg(surface);
+
+ /* Use PNG if no lossy formats are appropriate */
+ else
+ __guac_common_surface_flush_to_png(surface);
+
+ }
+
+ }
+
+ current++;
+
+ }
+
+ /* Flush complete */
+ surface->bitmap_queue_length = 0;
+
+}
+
+void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
+ guac_socket* socket) {
+
+ /* Do nothing if not realized */
+ if (!surface->realized)
+ return;
+
+ /* Sync size to new socket */
+ guac_protocol_send_size(socket, surface->layer, surface->width, surface->height);
+
+ /* Get entire surface */
+ cairo_surface_t* rect = cairo_image_surface_create_for_data(
+ surface->buffer, CAIRO_FORMAT_RGB24,
+ surface->width, surface->height, surface->stride);
+
+ /* Send PNG for rect */
+ guac_user_stream_png(user, socket, GUAC_COMP_OVER, surface->layer,
+ 0, 0, rect);
+ cairo_surface_destroy(rect);
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/guacd/proc-map.c
----------------------------------------------------------------------
diff --git a/src/guacd/proc-map.c b/src/guacd/proc-map.c
index 410ac45..c09c06a 100644
--- a/src/guacd/proc-map.c
+++ b/src/guacd/proc-map.c
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "guac_list.h"
+#include "common/list.h"
#include "proc.h"
#include "proc-map.h"
#include "user.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/guacd/proc-map.h
----------------------------------------------------------------------
diff --git a/src/guacd/proc-map.h b/src/guacd/proc-map.h
index 2078f5a..123449d 100644
--- a/src/guacd/proc-map.h
+++ b/src/guacd/proc-map.h
@@ -22,7 +22,7 @@
#define _GUACD_PROC_MAP_H
#include "config.h"
-#include "guac_list.h"
+#include "common/list.h"
#include "proc.h"
#include "user.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/dvc.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/dvc.c b/src/protocols/rdp/dvc.c
index 10c65d7..34406c9 100644
--- a/src/protocols/rdp/dvc.c
+++ b/src/protocols/rdp/dvc.c
@@ -18,8 +18,8 @@
*/
#include "config.h"
+#include "common/list.h"
#include "dvc.h"
-#include "guac_list.h"
#include "rdp.h"
#include <freerdp/channels/channels.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/dvc.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/dvc.h b/src/protocols/rdp/dvc.h
index 02ca643..63694f5 100644
--- a/src/protocols/rdp/dvc.h
+++ b/src/protocols/rdp/dvc.h
@@ -21,7 +21,7 @@
#define GUAC_RDP_DVC_H
#include "config.h"
-#include "guac_list.h"
+#include "common/list.h"
#include <freerdp/freerdp.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index e759888..893fde5 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -21,10 +21,10 @@
#include "audio_input.h"
#include "client.h"
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
#include "dvc.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
-#include "guac_recording.h"
#include "keyboard.h"
#include "rdp.h"
#include "rdp_bitmap.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp.h b/src/protocols/rdp/rdp.h
index 247ec13..af26408 100644
--- a/src/protocols/rdp/rdp.h
+++ b/src/protocols/rdp/rdp.h
@@ -23,10 +23,10 @@
#include "config.h"
#include "audio_input.h"
-#include "guac_clipboard.h"
-#include "guac_display.h"
-#include "guac_surface.h"
-#include "guac_list.h"
+#include "common/clipboard.h"
+#include "common/display.h"
+#include "common/list.h"
+#include "common/surface.h"
#include "keyboard.h"
#include "rdp_disp.h"
#include "rdp_fs.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_bitmap.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_bitmap.c b/src/protocols/rdp/rdp_bitmap.c
index 351d5a3..f77bbae 100644
--- a/src/protocols/rdp/rdp_bitmap.c
+++ b/src/protocols/rdp/rdp_bitmap.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "client.h"
-#include "guac_display.h"
-#include "guac_surface.h"
+#include "common/display.h"
+#include "common/surface.h"
#include "rdp.h"
#include "rdp_bitmap.h"
#include "rdp_settings.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_bitmap.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_bitmap.h b/src/protocols/rdp/rdp_bitmap.h
index dbf452a..dda3f76 100644
--- a/src/protocols/rdp/rdp_bitmap.h
+++ b/src/protocols/rdp/rdp_bitmap.h
@@ -22,7 +22,7 @@
#define _GUAC_RDP_RDP_BITMAP_H
#include "config.h"
-#include "guac_display.h"
+#include "common/display.h"
#include <freerdp/freerdp.h>
#include <guacamole/layer.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_cliprdr.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_cliprdr.c b/src/protocols/rdp/rdp_cliprdr.c
index 6f45387..647ddda 100644
--- a/src/protocols/rdp/rdp_cliprdr.c
+++ b/src/protocols/rdp/rdp_cliprdr.c
@@ -20,10 +20,10 @@
#include "config.h"
#include "client.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
#include "rdp.h"
#include "rdp_cliprdr.h"
-#include "guac_clipboard.h"
-#include "guac_iconv.h"
#include <freerdp/channels/channels.h>
#include <freerdp/freerdp.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_gdi.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_gdi.c b/src/protocols/rdp/rdp_gdi.c
index 7bf495b..1805319 100644
--- a/src/protocols/rdp/rdp_gdi.c
+++ b/src/protocols/rdp/rdp_gdi.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "client.h"
-#include "guac_surface.h"
+#include "common/surface.h"
#include "rdp.h"
#include "rdp_bitmap.h"
#include "rdp_color.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_glyph.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_glyph.c b/src/protocols/rdp/rdp_glyph.c
index ddbf2d0..68ce7a2 100644
--- a/src/protocols/rdp/rdp_glyph.c
+++ b/src/protocols/rdp/rdp_glyph.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "client.h"
-#include "guac_surface.h"
+#include "common/surface.h"
#include "rdp.h"
#include "rdp_color.h"
#include "rdp_glyph.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_pointer.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_pointer.c b/src/protocols/rdp/rdp_pointer.c
index 1f497a3..f510b57 100644
--- a/src/protocols/rdp/rdp_pointer.c
+++ b/src/protocols/rdp/rdp_pointer.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "client.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
+#include "common/cursor.h"
+#include "common/display.h"
#include "rdp.h"
#include "rdp_pointer.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_pointer.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_pointer.h b/src/protocols/rdp/rdp_pointer.h
index 8818f52..995c8d6 100644
--- a/src/protocols/rdp/rdp_pointer.h
+++ b/src/protocols/rdp/rdp_pointer.h
@@ -22,7 +22,7 @@
#define _GUAC_RDP_RDP_POINTER_H
#include "config.h"
-#include "guac_display.h"
+#include "common/display.h"
#include <freerdp/freerdp.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c
index fd77e92..e8161b1 100644
--- a/src/protocols/rdp/rdp_settings.c
+++ b/src/protocols/rdp/rdp_settings.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "client.h"
-#include "guac_string.h"
+#include "common/string.h"
#include "rdp.h"
#include "rdp_settings.h"
#include "resolution.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_stream.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_stream.c b/src/protocols/rdp/rdp_stream.c
index eb5b9f3..5dae366 100644
--- a/src/protocols/rdp/rdp_stream.c
+++ b/src/protocols/rdp/rdp_stream.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "client.h"
-#include "guac_clipboard.h"
+#include "common/clipboard.h"
#include "rdp.h"
#include "rdp_fs.h"
#include "rdp_svc.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_stream.h
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_stream.h b/src/protocols/rdp/rdp_stream.h
index 1bd490e..c9c3838 100644
--- a/src/protocols/rdp/rdp_stream.h
+++ b/src/protocols/rdp/rdp_stream.h
@@ -22,7 +22,7 @@
#define _GUAC_RDP_STREAM_H
#include "config.h"
-#include "guac_json.h"
+#include "common/json.h"
#include "rdp_svc.h"
#include <guacamole/user.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/rdp_svc.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/rdp_svc.c b/src/protocols/rdp/rdp_svc.c
index 0d20746..83537a8 100644
--- a/src/protocols/rdp/rdp_svc.c
+++ b/src/protocols/rdp/rdp_svc.c
@@ -19,7 +19,7 @@
#include "config.h"
#include "client.h"
-#include "guac_list.h"
+#include "common/list.h"
#include "rdp.h"
#include "rdp_svc.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/rdp/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/rdp/user.c b/src/protocols/rdp/user.c
index ae02a10..6aa71ae 100644
--- a/src/protocols/rdp/user.c
+++ b/src/protocols/rdp/user.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "audio_input.h"
+#include "common/display.h"
#include "input.h"
-#include "guac_display.h"
#include "user.h"
#include "rdp.h"
#include "rdp_settings.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/ssh/input.c
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/input.c b/src/protocols/ssh/input.c
index 240f729..e0267e2 100644
--- a/src/protocols/ssh/input.c
+++ b/src/protocols/ssh/input.c
@@ -19,8 +19,8 @@
#include "config.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
+#include "common/cursor.h"
+#include "common/display.h"
#include "ssh.h"
#include "terminal.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/ssh/ssh.c
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c
index 4bdf76f..53835c8 100644
--- a/src/protocols/ssh/ssh.c
+++ b/src/protocols/ssh/ssh.c
@@ -19,7 +19,7 @@
#include "config.h"
-#include "guac_recording.h"
+#include "common/recording.h"
#include "guac_sftp.h"
#include "guac_ssh.h"
#include "settings.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/ssh/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/ssh/user.c b/src/protocols/ssh/user.c
index 4ebbab2..24d0fbb 100644
--- a/src/protocols/ssh/user.c
+++ b/src/protocols/ssh/user.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "clipboard.h"
+#include "common/display.h"
#include "input.h"
-#include "guac_display.h"
#include "user.h"
#include "sftp.h"
#include "ssh.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/telnet/telnet.c
----------------------------------------------------------------------
diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c
index 531819f..b80c959 100644
--- a/src/protocols/telnet/telnet.c
+++ b/src/protocols/telnet/telnet.c
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "guac_recording.h"
+#include "common/recording.h"
#include "telnet.h"
#include "terminal.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/clipboard.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/clipboard.c b/src/protocols/vnc/clipboard.c
index eab708d..8a80223 100644
--- a/src/protocols/vnc/clipboard.c
+++ b/src/protocols/vnc/clipboard.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "client.h"
#include "clipboard.h"
-#include "guac_clipboard.h"
-#include "guac_iconv.h"
+#include "common/clipboard.h"
+#include "common/iconv.h"
#include "user.h"
#include "vnc.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/cursor.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/cursor.c b/src/protocols/vnc/cursor.c
index fd075bc..22d45eb 100644
--- a/src/protocols/vnc/cursor.c
+++ b/src/protocols/vnc/cursor.c
@@ -20,9 +20,9 @@
#include "config.h"
#include "client.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
-#include "guac_surface.h"
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/surface.h"
#include "vnc.h"
#include <cairo/cairo.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/display.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/display.c b/src/protocols/vnc/display.c
index 99edb77..22de084 100644
--- a/src/protocols/vnc/display.c
+++ b/src/protocols/vnc/display.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "client.h"
-#include "guac_iconv.h"
-#include "guac_surface.h"
+#include "common/iconv.h"
+#include "common/surface.h"
#include "vnc.h"
#include <cairo/cairo.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/input.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/input.c b/src/protocols/vnc/input.c
index 08f3ec3..d8fcda5 100644
--- a/src/protocols/vnc/input.c
+++ b/src/protocols/vnc/input.c
@@ -19,8 +19,8 @@
#include "config.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
+#include "common/cursor.h"
+#include "common/display.h"
#include "vnc.h"
#include <guacamole/user.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/log.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/log.c b/src/protocols/vnc/log.c
index 84e28ad..ba593e8 100644
--- a/src/protocols/vnc/log.c
+++ b/src/protocols/vnc/log.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "client.h"
-#include "guac_iconv.h"
-#include "guac_surface.h"
+#include "common/iconv.h"
+#include "common/surface.h"
#include <cairo/cairo.h>
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/log.h
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/log.h b/src/protocols/vnc/log.h
index 829d60f..65f3dc2 100644
--- a/src/protocols/vnc/log.h
+++ b/src/protocols/vnc/log.h
@@ -23,8 +23,8 @@
#include "config.h"
#include "client.h"
-#include "guac_iconv.h"
-#include "guac_surface.h"
+#include "common/iconv.h"
+#include "common/surface.h"
#include <cairo/cairo.h>
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/user.c b/src/protocols/vnc/user.c
index e01ee75..aecf4e9 100644
--- a/src/protocols/vnc/user.c
+++ b/src/protocols/vnc/user.c
@@ -21,9 +21,9 @@
#include "clipboard.h"
#include "input.h"
-#include "guac_display.h"
-#include "guac_dot_cursor.h"
-#include "guac_pointer_cursor.h"
+#include "common/display.h"
+#include "common/dot_cursor.h"
+#include "common/pointer_cursor.h"
#include "user.h"
#include "sftp.h"
#include "vnc.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/vnc.c
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c
index f9ab687..9238ef1 100644
--- a/src/protocols/vnc/vnc.c
+++ b/src/protocols/vnc/vnc.c
@@ -22,12 +22,12 @@
#include "auth.h"
#include "client.h"
#include "clipboard.h"
+#include "common/clipboard.h"
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
#include "cursor.h"
#include "display.h"
-#include "guac_clipboard.h"
-#include "guac_cursor.h"
-#include "guac_display.h"
-#include "guac_recording.h"
#include "log.h"
#include "settings.h"
#include "vnc.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/protocols/vnc/vnc.h
----------------------------------------------------------------------
diff --git a/src/protocols/vnc/vnc.h b/src/protocols/vnc/vnc.h
index cf9895b..7938d84 100644
--- a/src/protocols/vnc/vnc.h
+++ b/src/protocols/vnc/vnc.h
@@ -22,10 +22,10 @@
#include "config.h"
-#include "guac_clipboard.h"
-#include "guac_display.h"
-#include "guac_iconv.h"
-#include "guac_surface.h"
+#include "common/clipboard.h"
+#include "common/display.h"
+#include "common/iconv.h"
+#include "common/surface.h"
#include "settings.h"
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/terminal/display.c
----------------------------------------------------------------------
diff --git a/src/terminal/display.c b/src/terminal/display.c
index fdb1943..da1a8d9 100644
--- a/src/terminal/display.c
+++ b/src/terminal/display.c
@@ -20,8 +20,8 @@
#include "config.h"
#include "common.h"
+#include "common/surface.h"
#include "display.h"
-#include "guac_surface.h"
#include "types.h"
#include <math.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/terminal/display.h
----------------------------------------------------------------------
diff --git a/src/terminal/display.h b/src/terminal/display.h
index 440d809..655d1aa 100644
--- a/src/terminal/display.h
+++ b/src/terminal/display.h
@@ -23,7 +23,7 @@
#include "config.h"
-#include "guac_surface.h"
+#include "common/surface.h"
#include "types.h"
#include <guacamole/client.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/terminal/terminal.c
----------------------------------------------------------------------
diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c
index 7488a31..5057123 100644
--- a/src/terminal/terminal.c
+++ b/src/terminal/terminal.c
@@ -21,10 +21,9 @@
#include "buffer.h"
#include "common.h"
+#include "common/clipboard.h"
+#include "common/cursor.h"
#include "display.h"
-#include "guac_clipboard.h"
-#include "guac_cursor.h"
-#include "scrollbar.h"
#include "terminal.h"
#include "terminal_handlers.h"
#include "types.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/terminal/terminal.h
----------------------------------------------------------------------
diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h
index 62312b0..965d7ea 100644
--- a/src/terminal/terminal.h
+++ b/src/terminal/terminal.h
@@ -24,9 +24,9 @@
#include "config.h"
#include "buffer.h"
+#include "common/clipboard.h"
+#include "common/cursor.h"
#include "display.h"
-#include "guac_clipboard.h"
-#include "guac_cursor.h"
#include "scrollbar.h"
#include "types.h"
#include "typescript.h"
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/terminal/typescript.c
----------------------------------------------------------------------
diff --git a/src/terminal/typescript.c b/src/terminal/typescript.c
index 0cf5edf..aa922f0 100644
--- a/src/terminal/typescript.c
+++ b/src/terminal/typescript.c
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "guac_io.h"
+#include "common/io.h"
#include "typescript.h"
#include <guacamole/timestamp.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/tests/common/guac_iconv.c
----------------------------------------------------------------------
diff --git a/tests/common/guac_iconv.c b/tests/common/guac_iconv.c
index 6f7726a..6af706f 100644
--- a/tests/common/guac_iconv.c
+++ b/tests/common/guac_iconv.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "common_suite.h"
-#include "guac_iconv.h"
+#include "common/iconv.h"
#include <stdlib.h>
#include <CUnit/Basic.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/tests/common/guac_rect.c
----------------------------------------------------------------------
diff --git a/tests/common/guac_rect.c b/tests/common/guac_rect.c
index 97a7196..a45ee38 100644
--- a/tests/common/guac_rect.c
+++ b/tests/common/guac_rect.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "common_suite.h"
-#include "guac_rect.h"
+#include "common/rect.h"
#include <stdlib.h>
#include <stdio.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/tests/common/guac_string.c
----------------------------------------------------------------------
diff --git a/tests/common/guac_string.c b/tests/common/guac_string.c
index 2ba7f04..543a41b 100644
--- a/tests/common/guac_string.c
+++ b/tests/common/guac_string.c
@@ -20,7 +20,7 @@
#include "config.h"
#include "common_suite.h"
-#include "guac_string.h"
+#include "common/string.h"
#include <stdlib.h>
#include <CUnit/Basic.h>
[5/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use
proper namespace for internal common headers.
Posted by jm...@apache.org.
GUACAMOLE-169: Use proper namespace for internal common headers.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/eee92854
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/eee92854
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/eee92854
Branch: refs/heads/master
Commit: eee928548d6859cc4bbc4f632084e6b4ea841e9c
Parents: 0ef87c4
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 11 17:28:50 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Jan 23 23:26:26 2017 -0800
----------------------------------------------------------------------
src/common-ssh/guac_sftp.h | 2 +-
src/common/Makefile.am | 62 +-
src/common/blank_cursor.c | 75 ++
src/common/clipboard.c | 135 +++
src/common/common/blank_cursor.h | 64 ++
src/common/common/clipboard.h | 104 +++
src/common/common/cursor.h | 267 ++++++
src/common/common/display.h | 223 +++++
src/common/common/dot_cursor.h | 61 ++
src/common/common/ibar_cursor.h | 62 ++
src/common/common/iconv.h | 100 ++
src/common/common/io.h | 50 +
src/common/common/json.h | 196 ++++
src/common/common/list.h | 122 +++
src/common/common/pointer_cursor.h | 61 ++
src/common/common/recording.h | 78 ++
src/common/common/rect.h | 143 +++
src/common/common/string.h | 47 +
src/common/common/surface.h | 354 +++++++
src/common/cursor.c | 378 ++++++++
src/common/display.c | 301 ++++++
src/common/dot_cursor.c | 85 ++
src/common/guac_blank_cursor.c | 75 --
src/common/guac_blank_cursor.h | 64 --
src/common/guac_clipboard.c | 135 ---
src/common/guac_clipboard.h | 104 ---
src/common/guac_cursor.c | 378 --------
src/common/guac_cursor.h | 267 ------
src/common/guac_display.c | 301 ------
src/common/guac_display.h | 223 -----
src/common/guac_dot_cursor.c | 85 --
src/common/guac_dot_cursor.h | 61 --
src/common/guac_ibar_cursor.c | 98 --
src/common/guac_ibar_cursor.h | 62 --
src/common/guac_iconv.c | 192 ----
src/common/guac_iconv.h | 100 --
src/common/guac_io.c | 68 --
src/common/guac_io.h | 50 -
src/common/guac_json.c | 180 ----
src/common/guac_json.h | 196 ----
src/common/guac_list.c | 81 --
src/common/guac_list.h | 122 ---
src/common/guac_pointer_cursor.c | 96 --
src/common/guac_pointer_cursor.h | 61 --
src/common/guac_recording.c | 160 ----
src/common/guac_recording.h | 78 --
src/common/guac_rect.c | 266 ------
src/common/guac_rect.h | 143 ---
src/common/guac_string.c | 90 --
src/common/guac_string.h | 47 -
src/common/guac_surface.c | 1552 -------------------------------
src/common/guac_surface.h | 354 -------
src/common/ibar_cursor.c | 98 ++
src/common/iconv.c | 192 ++++
src/common/io.c | 68 ++
src/common/json.c | 180 ++++
src/common/list.c | 81 ++
src/common/pointer_cursor.c | 96 ++
src/common/recording.c | 160 ++++
src/common/rect.c | 266 ++++++
src/common/string.c | 90 ++
src/common/surface.c | 1552 +++++++++++++++++++++++++++++++
src/guacd/proc-map.c | 2 +-
src/guacd/proc-map.h | 2 +-
src/protocols/rdp/dvc.c | 2 +-
src/protocols/rdp/dvc.h | 2 +-
src/protocols/rdp/rdp.c | 6 +-
src/protocols/rdp/rdp.h | 8 +-
src/protocols/rdp/rdp_bitmap.c | 4 +-
src/protocols/rdp/rdp_bitmap.h | 2 +-
src/protocols/rdp/rdp_cliprdr.c | 4 +-
src/protocols/rdp/rdp_gdi.c | 2 +-
src/protocols/rdp/rdp_glyph.c | 2 +-
src/protocols/rdp/rdp_pointer.c | 4 +-
src/protocols/rdp/rdp_pointer.h | 2 +-
src/protocols/rdp/rdp_settings.c | 2 +-
src/protocols/rdp/rdp_stream.c | 2 +-
src/protocols/rdp/rdp_stream.h | 2 +-
src/protocols/rdp/rdp_svc.c | 2 +-
src/protocols/rdp/user.c | 2 +-
src/protocols/ssh/input.c | 4 +-
src/protocols/ssh/ssh.c | 2 +-
src/protocols/ssh/user.c | 2 +-
src/protocols/telnet/telnet.c | 2 +-
src/protocols/vnc/clipboard.c | 4 +-
src/protocols/vnc/cursor.c | 6 +-
src/protocols/vnc/display.c | 4 +-
src/protocols/vnc/input.c | 4 +-
src/protocols/vnc/log.c | 4 +-
src/protocols/vnc/log.h | 4 +-
src/protocols/vnc/user.c | 6 +-
src/protocols/vnc/vnc.c | 8 +-
src/protocols/vnc/vnc.h | 8 +-
src/terminal/display.c | 2 +-
src/terminal/display.h | 2 +-
src/terminal/terminal.c | 5 +-
src/terminal/terminal.h | 4 +-
src/terminal/typescript.c | 2 +-
tests/common/guac_iconv.c | 2 +-
tests/common/guac_rect.c | 2 +-
tests/common/guac_string.c | 2 +-
101 files changed, 5786 insertions(+), 5787 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common-ssh/guac_sftp.h
----------------------------------------------------------------------
diff --git a/src/common-ssh/guac_sftp.h b/src/common-ssh/guac_sftp.h
index c43c00c..fdc1e72 100644
--- a/src/common-ssh/guac_sftp.h
+++ b/src/common-ssh/guac_sftp.h
@@ -20,7 +20,7 @@
#ifndef GUAC_COMMON_SSH_SFTP_H
#define GUAC_COMMON_SSH_SFTP_H
-#include "guac_json.h"
+#include "common/json.h"
#include "guac_ssh.h"
#include <guacamole/object.h>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/Makefile.am
----------------------------------------------------------------------
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index f36d903..32d1283 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -22,39 +22,39 @@ ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libguac_common.la
-noinst_HEADERS = \
- guac_io.h \
- guac_blank_cursor.h \
- guac_clipboard.h \
- guac_cursor.h \
- guac_display.h \
- guac_dot_cursor.h \
- guac_ibar_cursor.h \
- guac_iconv.h \
- guac_json.h \
- guac_list.h \
- guac_pointer_cursor.h \
- guac_recording.h \
- guac_rect.h \
- guac_string.h \
- guac_surface.h
+noinst_HEADERS = \
+ common/io.h \
+ common/blank_cursor.h \
+ common/clipboard.h \
+ common/cursor.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/recording.h \
+ common/rect.h \
+ common/string.h \
+ common/surface.h
libguac_common_la_SOURCES = \
- guac_io.c \
- guac_blank_cursor.c \
- guac_clipboard.c \
- guac_cursor.c \
- guac_display.c \
- guac_dot_cursor.c \
- guac_ibar_cursor.c \
- guac_iconv.c \
- guac_json.c \
- guac_list.c \
- guac_pointer_cursor.c \
- guac_recording.c \
- guac_rect.c \
- guac_string.c \
- guac_surface.c
+ 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 \
+ recording.c \
+ rect.c \
+ string.c \
+ surface.c
libguac_common_la_CFLAGS = \
-Werror -Wall -pedantic \
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/blank_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/blank_cursor.c b/src/common/blank_cursor.c
new file mode 100644
index 0000000..c65db0c
--- /dev/null
+++ b/src/common/blank_cursor.c
@@ -0,0 +1,75 @@
+/*
+ * 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.");
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/clipboard.c
----------------------------------------------------------------------
diff --git a/src/common/clipboard.c b/src/common/clipboard.c
new file mode 100644
index 0000000..4452bee
--- /dev/null
+++ b/src/common/clipboard.c
@@ -0,0 +1,135 @@
+/*
+ * 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/clipboard.h"
+
+#include <guacamole/client.h>
+#include <guacamole/protocol.h>
+#include <guacamole/stream.h>
+#include <guacamole/user.h>
+#include <string.h>
+#include <stdlib.h>
+
+guac_common_clipboard* guac_common_clipboard_alloc(int size) {
+
+ guac_common_clipboard* clipboard = malloc(sizeof(guac_common_clipboard));
+
+ /* Init clipboard */
+ clipboard->mimetype[0] = '\0';
+ clipboard->buffer = malloc(size);
+ clipboard->length = 0;
+ clipboard->available = size;
+
+ return clipboard;
+
+}
+
+void guac_common_clipboard_free(guac_common_clipboard* clipboard) {
+ free(clipboard->buffer);
+ free(clipboard);
+}
+
+/**
+ * Callback for guac_client_foreach_user() which sends clipboard data to each
+ * connected client.
+ *
+ * @param user
+ * The user to send the clipboard data to.
+ *
+ * @param
+ * A pointer to the guac_common_clipboard structure containing the
+ * clipboard data that should be sent to the given user.
+ *
+ * @return
+ * Always NULL.
+ */
+static void* __send_user_clipboard(guac_user* user, void* data) {
+
+ guac_common_clipboard* clipboard = (guac_common_clipboard*) data;
+
+ char* current = clipboard->buffer;
+ int remaining = clipboard->length;
+
+ /* Begin stream */
+ guac_stream* stream = guac_user_alloc_stream(user);
+ guac_protocol_send_clipboard(user->socket, stream, clipboard->mimetype);
+
+ guac_user_log(user, GUAC_LOG_DEBUG,
+ "Created stream %i for %s clipboard data.",
+ stream->index, clipboard->mimetype);
+
+ /* Split clipboard into chunks */
+ while (remaining > 0) {
+
+ /* Calculate size of next block */
+ int block_size = GUAC_COMMON_CLIPBOARD_BLOCK_SIZE;
+ if (remaining < block_size)
+ block_size = remaining;
+
+ /* Send block */
+ guac_protocol_send_blob(user->socket, stream, current, block_size);
+ guac_user_log(user, GUAC_LOG_DEBUG,
+ "Sent %i bytes of clipboard data on stream %i.",
+ block_size, stream->index);
+
+ /* Next block */
+ remaining -= block_size;
+ current += block_size;
+
+ }
+
+ guac_user_log(user, GUAC_LOG_DEBUG,
+ "Clipboard stream %i complete.",
+ stream->index);
+
+ /* End stream */
+ guac_protocol_send_end(user->socket, stream);
+ guac_user_free_stream(user, stream);
+
+ return NULL;
+
+}
+
+void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client) {
+ guac_client_log(client, GUAC_LOG_DEBUG, "Broadcasting clipboard to all connected users.");
+ guac_client_foreach_user(client, __send_user_clipboard, clipboard);
+ guac_client_log(client, GUAC_LOG_DEBUG, "Broadcast of clipboard complete.");
+}
+
+void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype) {
+ clipboard->length = 0;
+ strncpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype)-1);
+}
+
+void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length) {
+
+ /* Truncate data to available length */
+ int remaining = clipboard->available - clipboard->length;
+ if (remaining < length)
+ length = remaining;
+
+ /* Append to buffer */
+ memcpy(clipboard->buffer + clipboard->length, data, length);
+
+ /* Update length */
+ clipboard->length += length;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/blank_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/common/blank_cursor.h b/src/common/common/blank_cursor.h
new file mode 100644
index 0000000..86a4a9f
--- /dev/null
+++ b/src/common/common/blank_cursor.h
@@ -0,0 +1,64 @@
+/*
+ * 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
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/clipboard.h
----------------------------------------------------------------------
diff --git a/src/common/common/clipboard.h b/src/common/common/clipboard.h
new file mode 100644
index 0000000..5ebb261
--- /dev/null
+++ b/src/common/common/clipboard.h
@@ -0,0 +1,104 @@
+/*
+ * 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_CLIPBOARD_H
+#define __GUAC_CLIPBOARD_H
+
+#include "config.h"
+
+#include <guacamole/client.h>
+
+/**
+ * The maximum number of bytes to send in an individual blob when
+ * transmitting the clipboard contents to a connected client.
+ */
+#define GUAC_COMMON_CLIPBOARD_BLOCK_SIZE 4096
+
+/**
+ * Generic clipboard structure.
+ */
+typedef struct guac_common_clipboard {
+
+ /**
+ * The mimetype of the contained clipboard data.
+ */
+ char mimetype[256];
+
+ /**
+ * Arbitrary clipboard data.
+ */
+ char* buffer;
+
+ /**
+ * The number of bytes currently stored in the clipboard buffer.
+ */
+ int length;
+
+ /**
+ * The total number of bytes available in the clipboard buffer.
+ */
+ int available;
+
+} guac_common_clipboard;
+
+/**
+ * Creates a new clipboard having the given initial size.
+ *
+ * @param size The maximum number of bytes to allow within the clipboard.
+ * @return A newly-allocated clipboard.
+ */
+guac_common_clipboard* guac_common_clipboard_alloc(int size);
+
+/**
+ * Frees the given clipboard.
+ *
+ * @param clipboard The clipboard to free.
+ */
+void guac_common_clipboard_free(guac_common_clipboard* clipboard);
+
+/**
+ * Sends the contents of the clipboard along the given client, splitting
+ * the contents as necessary.
+ *
+ * @param clipboard The clipboard whose contents should be sent.
+ * @param client The client to send the clipboard contents on.
+ */
+void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client);
+
+/**
+ * Clears the clipboard contents and assigns a new mimetype for future data.
+ *
+ * @param clipboard The clipboard to reset.
+ * @param mimetype The mimetype of future data.
+ */
+void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype);
+
+/**
+ * Appends the given data to the current clipboard contents. The data must
+ * match the mimetype chosen for the clipboard data by
+ * guac_common_clipboard_reset().
+ *
+ * @param clipboard The clipboard to append data to.
+ * @param data The data to append.
+ * @param length The number of bytes to append from the data given.
+ */
+void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/cursor.h
----------------------------------------------------------------------
diff --git a/src/common/common/cursor.h b/src/common/common/cursor.h
new file mode 100644
index 0000000..86a7f14
--- /dev/null
+++ b/src/common/common/cursor.h
@@ -0,0 +1,267 @@
+/*
+ * 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 cursor layer. This layer will be available to all connected users,
+ * but will be visible only to those users who are not moving the mouse.
+ */
+ guac_layer* layer;
+
+ /**
+ * 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.
+ */
+ int 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;
+
+} 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 user
+ * 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_user* user,
+ guac_socket* socket);
+
+/**
+ * Moves 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 moved.
+ *
+ * @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.
+ */
+void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
+ int x, int y);
+
+/**
+ * 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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/display.h
----------------------------------------------------------------------
diff --git a/src/common/common/display.h b/src/common/common/display.h
new file mode 100644
index 0000000..0b54338
--- /dev/null
+++ b/src/common/common/display.h
@@ -0,0 +1,223 @@
+/*
+ * 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>
+
+/**
+ * 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;
+
+} 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);
+
+/**
+ * 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 user
+ * The user 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_user* user,
+ 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);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/dot_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/common/dot_cursor.h b/src/common/common/dot_cursor.h
new file mode 100644
index 0000000..034d044
--- /dev/null
+++ b/src/common/common/dot_cursor.h
@@ -0,0 +1,61 @@
+/*
+ * 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 grapic 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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/ibar_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/common/ibar_cursor.h b/src/common/common/ibar_cursor.h
new file mode 100644
index 0000000..ae11fff
--- /dev/null
+++ b/src/common/common/ibar_cursor.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/iconv.h
----------------------------------------------------------------------
diff --git a/src/common/common/iconv.h b/src/common/common/iconv.h
new file mode 100644
index 0000000..6381b0a
--- /dev/null
+++ b/src/common/common/iconv.h
@@ -0,0 +1,100 @@
+/*
+ * 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_ICONV_H
+#define __GUAC_COMMON_ICONV_H
+
+#include "config.h"
+
+/**
+ * Function which reads a character from the given string data, returning
+ * the Unicode codepoint read, updating the string pointer to point to the
+ * byte immediately after the character read.
+ */
+typedef int guac_iconv_read(const char** input, int remaining);
+
+/**
+ * Function writes the character having the given Unicode codepoint value to
+ * the given string data, updating the string pointer to point to the byte
+ * immediately after the character written.
+ */
+typedef void guac_iconv_write(char** output, int remaining, int value);
+
+/**
+ * Converts characters within a given string from one encoding to another,
+ * as defined by the reader/writer functions specified. The input and output
+ * string pointers will be updated based on the number of bytes read or
+ * written.
+ *
+ * @param reader The reader function to use when reading the input string.
+ * @param input Pointer to the beginning of the input string.
+ * @param in_remaining The number of bytes remaining after the pointer to the
+ * input string.
+ * @param writer The writer function to use when writing the output string.
+ * @param output Pointer to the beginning of the output string.
+ * @param out_remaining The number of bytes remaining after the pointer to the
+ * output string.
+ * @return Non-zero if the NULL terminator of the input string was read and
+ * copied into the destination string, zero otherwise.
+ */
+int guac_iconv(guac_iconv_read* reader, const char** input, int in_remaining,
+ guac_iconv_write* writer, char** output, int out_remaining);
+
+/**
+ * Read function for UTF8.
+ */
+guac_iconv_read GUAC_READ_UTF8;
+
+/**
+ * Read function for UTF16.
+ */
+guac_iconv_read GUAC_READ_UTF16;
+
+/**
+ * Read function for CP-1252.
+ */
+guac_iconv_read GUAC_READ_CP1252;
+
+/**
+ * Read function for ISO-8859-1
+ */
+guac_iconv_read GUAC_READ_ISO8859_1;
+
+/**
+ * Write function for UTF8.
+ */
+guac_iconv_write GUAC_WRITE_UTF8;
+
+/**
+ * Write function for UTF16.
+ */
+guac_iconv_write GUAC_WRITE_UTF16;
+
+/**
+ * Write function for CP-1252.
+ */
+guac_iconv_write GUAC_WRITE_CP1252;
+
+/**
+ * Write function for ISO-8859-1
+ */
+guac_iconv_write GUAC_WRITE_ISO8859_1;
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/io.h
----------------------------------------------------------------------
diff --git a/src/common/common/io.h b/src/common/common/io.h
new file mode 100644
index 0000000..832fc2b
--- /dev/null
+++ b/src/common/common/io.h
@@ -0,0 +1,50 @@
+/*
+ * 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_IO_H
+#define __GUAC_COMMON_IO_H
+
+#include "config.h"
+
+/**
+ * Writes absolutely all bytes from within the given buffer, returning an error
+ * only if the required writes fail.
+ *
+ * @param fd The file descriptor to write to.
+ * @param buffer The buffer containing the data to write.
+ * @param length The number of bytes to write.
+ * @return The number of bytes written, or a value less than zero if an error
+ * occurs.
+ */
+int guac_common_write(int fd, void* buffer, int length);
+
+/**
+ * Reads enough bytes to fill the given buffer, returning an error only if the
+ * required reads fail.
+ *
+ * @param fd The file descriptor to read from.
+ * @param buffer The buffer to read data into.
+ * @param length The number of bytes to read.
+ * @return The number of bytes read, or a value less than zero if an error
+ * occurs.
+ */
+int guac_common_read(int fd, void* buffer, int length);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/json.h
----------------------------------------------------------------------
diff --git a/src/common/common/json.h b/src/common/common/json.h
new file mode 100644
index 0000000..edb233c
--- /dev/null
+++ b/src/common/common/json.h
@@ -0,0 +1,196 @@
+/*
+ * 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_JSON_H
+#define GUAC_COMMON_JSON_H
+
+#include "config.h"
+
+#include <guacamole/stream.h>
+#include <guacamole/user.h>
+
+/**
+ * The current streaming state of an arbitrary JSON object, consisting of
+ * any number of property name/value pairs.
+ */
+typedef struct guac_common_json_state {
+
+ /**
+ * Buffer of partial JSON data. The individual blobs which make up the JSON
+ * body of the object being sent over the Guacamole protocol will be
+ * built here.
+ */
+ char buffer[4096];
+
+ /**
+ * The number of bytes currently used within the JSON buffer.
+ */
+ int size;
+
+ /**
+ * The number of property name/value pairs written to the JSON object thus
+ * far.
+ */
+ int properties_written;
+
+} guac_common_json_state;
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object, flushes the contents of the JSON buffer to a blob
+ * instruction. Note that this will flush the JSON buffer only, and will not
+ * necessarily flush the underlying guac_socket of the user.
+ *
+ * @param user
+ * The user to which the data will be flushed.
+ *
+ * @param stream
+ * The stream through which the flushed data should be sent as a blob.
+ *
+ * @param json_state
+ * The state object whose buffer should be flushed.
+ */
+void guac_common_json_flush(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state);
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object, writes the contents of the given buffer to the JSON buffer
+ * of the stream state, flushing as necessary.
+ *
+ * @param user
+ * The user to which the data will be flushed as necessary.
+ *
+ * @param stream
+ * The stream through which the flushed data should be sent as a blob, if
+ * data must be flushed at all.
+ *
+ * @param json_state
+ * The state object containing the JSON buffer to which the given buffer
+ * should be written.
+ *
+ * @param buffer
+ * The buffer to write.
+ *
+ * @param length
+ * The number of bytes in the buffer.
+ *
+ * @return
+ * Non-zero if at least one blob was written, zero otherwise.
+ */
+int guac_common_json_write(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state, const char* buffer, int length);
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object state, writes the given string as a proper JSON string,
+ * including starting and ending quotes. The contents of the string will be
+ * escaped as necessary.
+ *
+ * @param user
+ * The user to which the data will be flushed as necessary.
+ *
+ * @param stream
+ * The stream through which the flushed data should be sent as a blob, if
+ * data must be flushed at all.
+ *
+ * @param json_state
+ * The state object containing the JSON buffer to which the given string
+ * should be written as a JSON name/value pair.
+ *
+ * @param str
+ * The string to write.
+ *
+ * @return
+ * Non-zero if at least one blob was written, zero otherwise.
+ */
+int guac_common_json_write_string(guac_user* user,
+ guac_stream* stream, guac_common_json_state* json_state,
+ const char* str);
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object, writes the given JSON property name/value pair. The
+ * name and value will be written as proper JSON strings separated by a colon.
+ *
+ * @param user
+ * The user to which the data will be flushed as necessary.
+ *
+ * @param stream
+ * The stream through which the flushed data should be sent as a blob, if
+ * data must be flushed at all.
+ *
+ * @param json_state
+ * The state object containing the JSON buffer to which the given strings
+ * should be written as a JSON name/value pair.
+ *
+ * @param name
+ * The name of the property to write.
+ *
+ * @param value
+ * The value of the property to write.
+ *
+ * @return
+ * Non-zero if at least one blob was written, zero otherwise.
+ */
+int guac_common_json_write_property(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state, const char* name,
+ const char* value);
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object, initializes the state for writing a new JSON object. Note
+ * that although the user and stream must be provided, no instruction or
+ * blobs will be written due to any call to this function.
+ *
+ * @param user
+ * The user associated with the given stream.
+ *
+ * @param stream
+ * The stream associated with the JSON object being written.
+ *
+ * @param json_state
+ * The state object to initialize.
+ */
+void guac_common_json_begin_object(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state);
+
+/**
+ * Given a stream, the user to which it belongs, and the current stream state
+ * of a JSON object, completes writing that JSON object by writing the final
+ * terminating brace. This function must only be called following a
+ * corresponding call to guac_common_json_begin_object().
+ *
+ * @param user
+ * The user associated with the given stream.
+ *
+ * @param stream
+ * The stream associated with the JSON object being written.
+ *
+ * @param json_state
+ * The state object whose in-progress JSON object should be terminated.
+ *
+ * @return
+ * Non-zero if at least one blob was written, zero otherwise.
+ */
+int guac_common_json_end_object(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/list.h
----------------------------------------------------------------------
diff --git a/src/common/common/list.h b/src/common/common/list.h
new file mode 100644
index 0000000..5f6be1b
--- /dev/null
+++ b/src/common/common/list.h
@@ -0,0 +1,122 @@
+/*
+ * 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_LIST_H
+#define __GUAC_LIST_H
+
+#include "config.h"
+
+#include <pthread.h>
+
+/**
+ * Generic linked list element.
+ */
+typedef struct guac_common_list_element guac_common_list_element;
+
+struct guac_common_list_element {
+
+ /**
+ * The next element in the list, or NULL if none.
+ */
+ guac_common_list_element* next;
+
+ /**
+ * Generic data.
+ */
+ void* data;
+
+ /**
+ * The pointer which points to this element, whether another element's
+ * next pointer, or the entire list's head pointer.
+ */
+ guac_common_list_element** _ptr;
+
+};
+
+/**
+ * Generic linked list.
+ */
+typedef struct guac_common_list {
+
+ /**
+ * The first element in the list.
+ */
+ guac_common_list_element* head;
+
+ /**
+ * Mutex which is locked when exclusive access to the list is required.
+ * Possession of the lock is not enforced outside the
+ * guac_common_list_lock() function.
+ */
+ pthread_mutex_t _lock;
+
+} guac_common_list;
+
+/**
+ * Creates a new list.
+ *
+ * @return A newly-allocated list.
+ */
+guac_common_list* guac_common_list_alloc();
+
+/**
+ * Frees the given list.
+ *
+ * @param list The list to free.
+ */
+void guac_common_list_free(guac_common_list* list);
+
+/**
+ * Adds the given data to the list as a new element, returning the created
+ * element.
+ *
+ * @param list The list to add an element to.
+ * @param data The data to associate with the newly-created element.
+ * @param The newly-created element.
+ */
+guac_common_list_element* guac_common_list_add(guac_common_list* list,
+ void* data);
+
+/**
+ * Removes the given element from the list.
+ *
+ * @param list The list to remove the element from.
+ * @param element The element to remove.
+ */
+void guac_common_list_remove(guac_common_list* list,
+ guac_common_list_element* element);
+
+/**
+ * Acquires exclusive access to the list. No list functions implicitly lock or
+ * unlock the list, so any list access which must be threadsafe must use
+ * guac_common_list_lock() and guac_common_list_unlock() manually.
+ *
+ * @param list The list to acquire exclusive access to.
+ */
+void guac_common_list_lock(guac_common_list* list);
+
+/**
+ * Releases exclusive access to the list.
+ *
+ * @param list The list to release from exclusive access.
+ */
+void guac_common_list_unlock(guac_common_list* list);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/pointer_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/common/pointer_cursor.h b/src/common/common/pointer_cursor.h
new file mode 100644
index 0000000..3289576
--- /dev/null
+++ b/src/common/common/pointer_cursor.h
@@ -0,0 +1,61 @@
+/*
+ * 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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/recording.h
----------------------------------------------------------------------
diff --git a/src/common/common/recording.h b/src/common/common/recording.h
new file mode 100644
index 0000000..71d8fbc
--- /dev/null
+++ b/src/common/common/recording.h
@@ -0,0 +1,78 @@
+/*
+ * 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_RECORDING_H
+#define GUAC_COMMON_RECORDING_H
+
+#include <guacamole/client.h>
+
+/**
+ * The maximum numeric value allowed for the .1, .2, .3, etc. suffix appended
+ * to the end of the session recording filename if a recording having the
+ * requested name already exists.
+ */
+#define GUAC_COMMON_RECORDING_MAX_SUFFIX 255
+
+/**
+ * The maximum length of the string containing a sequential numeric suffix
+ * between 1 and GUAC_COMMON_RECORDING_MAX_SUFFIX inclusive, in bytes,
+ * including NULL terminator.
+ */
+#define GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH 4
+
+/**
+ * The maximum overall length of the full path to the session recording file,
+ * including any additional suffix and NULL terminator, in bytes.
+ */
+#define GUAC_COMMON_RECORDING_MAX_NAME_LENGTH 2048
+
+/**
+ * Replaces the socket of the given client such that all further Guacamole
+ * protocol output will be copied into a file within the given path and having
+ * the given name. If the create_path flag is non-zero, the given path will be
+ * created if it does not yet exist. If creation of the recording file or path
+ * fails, error messages will automatically be logged, and no recording will be
+ * written. The recording will automatically be closed once the client is
+ * freed.
+ *
+ * @param client
+ * The client whose output should be copied to a recording file.
+ *
+ * @param path
+ * The full absolute path to a directory in which the recording file should
+ * be created.
+ *
+ * @param name
+ * The base name to use for the recording file created within the specified
+ * path.
+ *
+ * @param create_path
+ * Zero if the specified path MUST exist for the recording file to be
+ * written, or non-zero if the path should be created if it does not yet
+ * exist.
+ *
+ * @return
+ * Zero if the recording file has been successfully created and a recording
+ * will be written, non-zero otherwise.
+ */
+int guac_common_recording_create(guac_client* client, const char* path,
+ const char* name, int create_path);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/rect.h
----------------------------------------------------------------------
diff --git a/src/common/common/rect.h b/src/common/common/rect.h
new file mode 100644
index 0000000..6b31048
--- /dev/null
+++ b/src/common/common/rect.h
@@ -0,0 +1,143 @@
+/*
+ * 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
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/string.h
----------------------------------------------------------------------
diff --git a/src/common/common/string.h b/src/common/common/string.h
new file mode 100644
index 0000000..442d7f4
--- /dev/null
+++ b/src/common/common/string.h
@@ -0,0 +1,47 @@
+/*
+ * 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_STRING_H
+#define __GUAC_COMMON_STRING_H
+
+#include "config.h"
+
+/**
+ * Counts the number of occurrences of a given character in a string.
+ *
+ * @param string The string to count occurrences within.
+ * @param c The character to count occurrences of.
+ * @return The number of occurrences.
+ */
+int guac_count_occurrences(const char* string, char c);
+
+/**
+ * Splits a string into a newly-allocated array of strings. The array itself
+ * and each string within the array will eventually need to be freed. The array
+ * is NULL-terminated.
+ *
+ * @param string The string to split.
+ * @param delim The character which separates individual substrings within the
+ * given string.
+ * @return A newly-allocated, NULL-terminated array of strings.
+ */
+char** guac_split(const char* string, char delim);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/common/surface.h
----------------------------------------------------------------------
diff --git a/src/common/common/surface.h b/src/common/common/surface.h
new file mode 100644
index 0000000..3da3f17
--- /dev/null
+++ b/src/common/common/surface.h
@@ -0,0 +1,354 @@
+/*
+ * 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>
+
+/**
+ * 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 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 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;
+
+} 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.
+ *
+ * @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);
+
+/**
+ * Draws a solid color rectangle at the given coordinates on the given surface.
+ *
+ * @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 of the rectangle.
+ * @param green The green component of the color of the rectangle.
+ * @param blue The blue component of the color of the rectangle.
+ */
+void guac_common_surface_rect(guac_common_surface* surface,
+ int x, int y, int w, int h,
+ int red, int green, int blue);
+
+/**
+ * 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);
+
+/**
+ * Flushes the given surface, drawing any pending operations on the remote
+ * display.
+ *
+ * @param surface The surface to flush.
+ */
+void guac_common_surface_flush(guac_common_surface* surface);
+
+/**
+ * Schedules a deferred flush of the given surface. This will not immediately
+ * flush the surface to the client. Instead, the result of the flush is
+ * added to a queue which is reinspected and combined (if possible) with other
+ * deferred flushes during the call to guac_common_surface_flush().
+ *
+ * @param surface The surface to flush.
+ */
+void guac_common_surface_flush_deferred(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 user
+ * The user 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_user* user,
+ guac_socket* socket);
+
+#endif
+
[4/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use
proper namespace for internal common headers.
Posted by jm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/cursor.c
----------------------------------------------------------------------
diff --git a/src/common/cursor.c b/src/common/cursor.c
new file mode 100644
index 0000000..6dd000f
--- /dev/null
+++ b/src/common/cursor.c
@@ -0,0 +1,378 @@
+/*
+ * 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/layer.h>
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
+
+ guac_common_cursor* cursor = malloc(sizeof(guac_common_cursor));
+ if (cursor == NULL)
+ return NULL;
+
+ /* Associate cursor with client and allocate cursor layer */
+ cursor->client = client;
+ cursor->layer= guac_client_alloc_layer(client);
+
+ /* Allocate initial image buffer */
+ cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE;
+ cursor->image_buffer = malloc(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;
+
+ /* Start cursor in upper-left */
+ cursor->x = 0;
+ cursor->y = 0;
+
+ return cursor;
+
+}
+
+void guac_common_cursor_free(guac_common_cursor* cursor) {
+
+ guac_client* client = cursor->client;
+ guac_layer* layer = cursor->layer;
+ cairo_surface_t* surface = cursor->surface;
+
+ /* Free image buffer and surface */
+ free(cursor->image_buffer);
+ if (surface != NULL)
+ cairo_surface_destroy(surface);
+
+ /* Destroy layer within remotely-connected client */
+ guac_protocol_send_dispose(client->socket, layer);
+
+ /* Return layer to pool */
+ guac_client_free_layer(client, layer);
+
+ free(cursor);
+
+}
+
+void guac_common_cursor_dup(guac_common_cursor* cursor, guac_user* user,
+ guac_socket* socket) {
+
+ /* Synchronize location */
+ guac_protocol_send_move(socket, cursor->layer, GUAC_DEFAULT_LAYER,
+ cursor->x - cursor->hotspot_x,
+ cursor->y - cursor->hotspot_y,
+ 0);
+
+ /* Synchronize cursor image */
+ if (cursor->surface != NULL) {
+ guac_protocol_send_size(socket, cursor->layer,
+ cursor->width, cursor->height);
+
+ guac_user_stream_png(user, socket, GUAC_COMP_SRC,
+ cursor->layer, 0, 0, cursor->surface);
+ }
+
+ guac_socket_flush(socket);
+
+}
+
+/**
+ * Callback for guac_client_for_user() which shows the cursor layer for the
+ * given user (if they exist). The cursor layer is normally hidden when a user
+ * is moving the mouse, and will only be shown if a DIFFERENT user is moving
+ * the mouse.
+ *
+ * @param user
+ * The user to show the cursor to, or NULL if that user does not exist.
+ *
+ * @param data
+ * A pointer to the guac_common_cursor structure describing the cursor to
+ * be shown.
+ *
+ * @return
+ * Always NULL.
+ */
+static void* guac_common_cursor_show(guac_user* user, void* data) {
+
+ guac_common_cursor* cursor = (guac_common_cursor*) data;
+
+ /* Make cursor layer visible to given user */
+ if (user != NULL) {
+ guac_protocol_send_shade(user->socket, cursor->layer, 255);
+ guac_socket_flush(user->socket);
+ }
+
+ return NULL;
+
+}
+
+void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
+ int x, int y) {
+
+ guac_user* last_user = cursor->user;
+
+ /* Update current user of cursor */
+ if (last_user != user) {
+
+ cursor->user = user;
+
+ /* Make cursor layer visible to previous user */
+ guac_client_for_user(cursor->client, last_user,
+ guac_common_cursor_show, cursor);
+
+ /* Show hardware cursor */
+ guac_protocol_send_cursor(user->socket,
+ cursor->hotspot_x, cursor->hotspot_y,
+ cursor->layer, 0, 0, cursor->width, cursor->height);
+
+ /* Hide cursor layer from new user */
+ guac_protocol_send_shade(user->socket, cursor->layer, 0);
+ guac_socket_flush(user->socket);
+
+ }
+
+ /* Update cursor position */
+ cursor->x = x;
+ cursor->y = y;
+
+ guac_protocol_send_move(cursor->client->socket, cursor->layer,
+ GUAC_DEFAULT_LAYER,
+ x - cursor->hotspot_x,
+ y - cursor->hotspot_y,
+ 0);
+
+ guac_socket_flush(cursor->client->socket);
+
+}
+
+/**
+ * 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) {
+
+ int minimum_size = height * stride;
+
+ /* Grow image buffer if necessary */
+ if (cursor->image_buffer_size < minimum_size) {
+
+ /* Calculate new size */
+ cursor->image_buffer_size = minimum_size*2;
+
+ /* Destructively reallocate image buffer */
+ free(cursor->image_buffer);
+ cursor->image_buffer = malloc(cursor->image_buffer_size);
+
+ }
+
+}
+
+/**
+ * Callback for guac_client_foreach_user() which sends the current cursor image
+ * as PNG data to each connected client.
+ *
+ * @param user
+ * The user to send the cursor image to.
+ *
+ * @param data
+ * A pointer to the guac_common_cursor structure containing the cursor
+ * image that should be sent to the given user.
+ *
+ * @return
+ * Always NULL.
+ */
+static void* __send_user_cursor_image(guac_user* user, void* data) {
+
+ guac_common_cursor* cursor = (guac_common_cursor*) data;
+
+ guac_user_stream_png(user, user->socket, GUAC_COMP_SRC,
+ cursor->layer, 0, 0, cursor->surface);
+
+ return NULL;
+
+}
+
+/**
+ * Callback for guac_client_for_user() which updates the hardware cursor and
+ * hotspot for the given user (if they exist). The hardware cursor image is
+ * normally hidden when a user is not moving the mouse, and will only be shown
+ * if that user begins moving the mouse.
+ *
+ * @param user
+ * The user whose hardware cursor should be updated, or NULL if that user
+ * does not exist.
+ *
+ * @param data
+ * A pointer to the guac_common_cursor structure describing the cursor to
+ * be sent as the hardware cursor.
+ *
+ * @return
+ * Always NULL.
+ */
+static void* guac_common_cursor_update(guac_user* user, void* data) {
+
+ guac_common_cursor* cursor = (guac_common_cursor*) data;
+
+ /* Update hardware cursor of current user */
+ if (user != NULL) {
+ guac_protocol_send_cursor(user->socket,
+ cursor->hotspot_x, cursor->hotspot_y,
+ cursor->layer, 0, 0, cursor->width, cursor->height);
+
+ guac_socket_flush(user->socket);
+ }
+
+ return NULL;
+
+}
+
+void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
+ unsigned const char* data, int width, int height, int stride) {
+
+ /* 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;
+
+ /* Update location based on new hotspot */
+ guac_protocol_send_move(cursor->client->socket, cursor->layer,
+ GUAC_DEFAULT_LAYER,
+ cursor->x - hx,
+ cursor->y - hy,
+ 0);
+
+ /* Broadcast new cursor image to all users */
+ guac_protocol_send_size(cursor->client->socket, cursor->layer,
+ width, height);
+
+ guac_client_foreach_user(cursor->client, __send_user_cursor_image, cursor);
+
+ guac_socket_flush(cursor->client->socket);
+
+ /* Update hardware cursor of current user (if they are indeed valid) */
+ if (cursor->user != NULL)
+ guac_client_for_user(cursor->client, cursor->user,
+ guac_common_cursor_update, cursor);
+
+}
+
+void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,
+ 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) {
+
+ /* Disassociate from given user */
+ if (cursor->user == user)
+ cursor->user = NULL;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/display.c
----------------------------------------------------------------------
diff --git a/src/common/display.c b/src/common/display.c
new file mode 100644
index 0000000..38a2ad4
--- /dev/null
+++ b/src/common/display.c
@@ -0,0 +1,301 @@
+/*
+ * 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/socket.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 user
+ * The user 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_user* user, guac_socket* socket) {
+
+ guac_common_display_layer* current = layers;
+
+ /* Synchronize all surfaces in given list */
+ while (current != NULL) {
+ guac_common_surface_dup(current->surface, user, 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 */
+ free(current);
+ current = next;
+
+ }
+
+}
+
+guac_common_display* guac_common_display_alloc(guac_client* client,
+ int width, int height) {
+
+ /* Allocate display */
+ guac_common_display* display = malloc(sizeof(guac_common_display));
+ if (display == NULL)
+ return NULL;
+
+ /* Associate display with given client */
+ display->client = client;
+
+ /* Allocate shared cursor */
+ display->cursor = guac_common_cursor_alloc(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);
+
+ free(display);
+
+}
+
+void guac_common_display_dup(guac_common_display* display, guac_user* user,
+ guac_socket* socket) {
+
+ /* Sunchronize shared cursor */
+ guac_common_cursor_dup(display->cursor, user, socket);
+
+ /* Synchronize default surface */
+ guac_common_surface_dup(display->default_surface, user, socket);
+
+ /* Synchronize all layers and buffers */
+ guac_common_display_dup_layers(display->layers, user, socket);
+ guac_common_display_dup_layers(display->buffers, user, socket);
+
+}
+
+void guac_common_display_flush(guac_common_display* display) {
+ guac_common_surface_flush(display->default_surface);
+}
+
+/**
+ * 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 =
+ malloc(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) {
+
+ guac_layer* layer;
+ guac_common_surface* surface;
+
+ /* Allocate Guacamole layer */
+ layer = guac_client_alloc_layer(display->client);
+
+ /* Allocate corresponding surface */
+ surface = guac_common_surface_alloc(display->client,
+ display->client->socket, layer, width, height);
+
+ /* Add layer and surface to list */
+ return guac_common_display_add_layer(&display->layers, layer, surface);
+
+}
+
+guac_common_display_layer* guac_common_display_alloc_buffer(
+ guac_common_display* display, int width, int height) {
+
+ guac_layer* buffer;
+ guac_common_surface* surface;
+
+ /* Allocate Guacamole buffer */
+ buffer = guac_client_alloc_buffer(display->client);
+
+ /* Allocate corresponding surface */
+ surface = guac_common_surface_alloc(display->client,
+ display->client->socket, buffer, width, height);
+
+ /* Add buffer and surface to list */
+ return guac_common_display_add_layer(&display->buffers, buffer, surface);
+
+}
+
+void guac_common_display_free_layer(guac_common_display* display,
+ guac_common_display_layer* display_layer) {
+
+ /* 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 */
+ free(display_layer);
+
+}
+
+void guac_common_display_free_buffer(guac_common_display* display,
+ guac_common_display_layer* display_buffer) {
+
+ /* 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 */
+ free(display_buffer);
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/dot_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/dot_cursor.c b/src/common/dot_cursor.c
new file mode 100644
index 0000000..fde79b0
--- /dev/null
+++ b/src/common/dot_cursor.c
@@ -0,0 +1,85 @@
+/*
+ * 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.");
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_blank_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/guac_blank_cursor.c b/src/common/guac_blank_cursor.c
deleted file mode 100644
index c65db0c..0000000
--- a/src/common/guac_blank_cursor.c
+++ /dev/null
@@ -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.");
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_blank_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/guac_blank_cursor.h b/src/common/guac_blank_cursor.h
deleted file mode 100644
index 86a4a9f..0000000
--- a/src/common/guac_blank_cursor.h
+++ /dev/null
@@ -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
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_clipboard.c
----------------------------------------------------------------------
diff --git a/src/common/guac_clipboard.c b/src/common/guac_clipboard.c
deleted file mode 100644
index 15cdd84..0000000
--- a/src/common/guac_clipboard.c
+++ /dev/null
@@ -1,135 +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 "guac_clipboard.h"
-
-#include <guacamole/client.h>
-#include <guacamole/protocol.h>
-#include <guacamole/stream.h>
-#include <guacamole/user.h>
-#include <string.h>
-#include <stdlib.h>
-
-guac_common_clipboard* guac_common_clipboard_alloc(int size) {
-
- guac_common_clipboard* clipboard = malloc(sizeof(guac_common_clipboard));
-
- /* Init clipboard */
- clipboard->mimetype[0] = '\0';
- clipboard->buffer = malloc(size);
- clipboard->length = 0;
- clipboard->available = size;
-
- return clipboard;
-
-}
-
-void guac_common_clipboard_free(guac_common_clipboard* clipboard) {
- free(clipboard->buffer);
- free(clipboard);
-}
-
-/**
- * Callback for guac_client_foreach_user() which sends clipboard data to each
- * connected client.
- *
- * @param user
- * The user to send the clipboard data to.
- *
- * @param
- * A pointer to the guac_common_clipboard structure containing the
- * clipboard data that should be sent to the given user.
- *
- * @return
- * Always NULL.
- */
-static void* __send_user_clipboard(guac_user* user, void* data) {
-
- guac_common_clipboard* clipboard = (guac_common_clipboard*) data;
-
- char* current = clipboard->buffer;
- int remaining = clipboard->length;
-
- /* Begin stream */
- guac_stream* stream = guac_user_alloc_stream(user);
- guac_protocol_send_clipboard(user->socket, stream, clipboard->mimetype);
-
- guac_user_log(user, GUAC_LOG_DEBUG,
- "Created stream %i for %s clipboard data.",
- stream->index, clipboard->mimetype);
-
- /* Split clipboard into chunks */
- while (remaining > 0) {
-
- /* Calculate size of next block */
- int block_size = GUAC_COMMON_CLIPBOARD_BLOCK_SIZE;
- if (remaining < block_size)
- block_size = remaining;
-
- /* Send block */
- guac_protocol_send_blob(user->socket, stream, current, block_size);
- guac_user_log(user, GUAC_LOG_DEBUG,
- "Sent %i bytes of clipboard data on stream %i.",
- block_size, stream->index);
-
- /* Next block */
- remaining -= block_size;
- current += block_size;
-
- }
-
- guac_user_log(user, GUAC_LOG_DEBUG,
- "Clipboard stream %i complete.",
- stream->index);
-
- /* End stream */
- guac_protocol_send_end(user->socket, stream);
- guac_user_free_stream(user, stream);
-
- return NULL;
-
-}
-
-void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client) {
- guac_client_log(client, GUAC_LOG_DEBUG, "Broadcasting clipboard to all connected users.");
- guac_client_foreach_user(client, __send_user_clipboard, clipboard);
- guac_client_log(client, GUAC_LOG_DEBUG, "Broadcast of clipboard complete.");
-}
-
-void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype) {
- clipboard->length = 0;
- strncpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype)-1);
-}
-
-void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length) {
-
- /* Truncate data to available length */
- int remaining = clipboard->available - clipboard->length;
- if (remaining < length)
- length = remaining;
-
- /* Append to buffer */
- memcpy(clipboard->buffer + clipboard->length, data, length);
-
- /* Update length */
- clipboard->length += length;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_clipboard.h
----------------------------------------------------------------------
diff --git a/src/common/guac_clipboard.h b/src/common/guac_clipboard.h
deleted file mode 100644
index 5ebb261..0000000
--- a/src/common/guac_clipboard.h
+++ /dev/null
@@ -1,104 +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_CLIPBOARD_H
-#define __GUAC_CLIPBOARD_H
-
-#include "config.h"
-
-#include <guacamole/client.h>
-
-/**
- * The maximum number of bytes to send in an individual blob when
- * transmitting the clipboard contents to a connected client.
- */
-#define GUAC_COMMON_CLIPBOARD_BLOCK_SIZE 4096
-
-/**
- * Generic clipboard structure.
- */
-typedef struct guac_common_clipboard {
-
- /**
- * The mimetype of the contained clipboard data.
- */
- char mimetype[256];
-
- /**
- * Arbitrary clipboard data.
- */
- char* buffer;
-
- /**
- * The number of bytes currently stored in the clipboard buffer.
- */
- int length;
-
- /**
- * The total number of bytes available in the clipboard buffer.
- */
- int available;
-
-} guac_common_clipboard;
-
-/**
- * Creates a new clipboard having the given initial size.
- *
- * @param size The maximum number of bytes to allow within the clipboard.
- * @return A newly-allocated clipboard.
- */
-guac_common_clipboard* guac_common_clipboard_alloc(int size);
-
-/**
- * Frees the given clipboard.
- *
- * @param clipboard The clipboard to free.
- */
-void guac_common_clipboard_free(guac_common_clipboard* clipboard);
-
-/**
- * Sends the contents of the clipboard along the given client, splitting
- * the contents as necessary.
- *
- * @param clipboard The clipboard whose contents should be sent.
- * @param client The client to send the clipboard contents on.
- */
-void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client);
-
-/**
- * Clears the clipboard contents and assigns a new mimetype for future data.
- *
- * @param clipboard The clipboard to reset.
- * @param mimetype The mimetype of future data.
- */
-void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype);
-
-/**
- * Appends the given data to the current clipboard contents. The data must
- * match the mimetype chosen for the clipboard data by
- * guac_common_clipboard_reset().
- *
- * @param clipboard The clipboard to append data to.
- * @param data The data to append.
- * @param length The number of bytes to append from the data given.
- */
-void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/guac_cursor.c b/src/common/guac_cursor.c
deleted file mode 100644
index 4ed66b1..0000000
--- a/src/common/guac_cursor.c
+++ /dev/null
@@ -1,378 +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 "guac_blank_cursor.h"
-#include "guac_dot_cursor.h"
-#include "guac_cursor.h"
-#include "guac_ibar_cursor.h"
-#include "guac_pointer_cursor.h"
-#include "guac_surface.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>
-
-#include <stdlib.h>
-#include <string.h>
-
-guac_common_cursor* guac_common_cursor_alloc(guac_client* client) {
-
- guac_common_cursor* cursor = malloc(sizeof(guac_common_cursor));
- if (cursor == NULL)
- return NULL;
-
- /* Associate cursor with client and allocate cursor layer */
- cursor->client = client;
- cursor->layer= guac_client_alloc_layer(client);
-
- /* Allocate initial image buffer */
- cursor->image_buffer_size = GUAC_COMMON_CURSOR_DEFAULT_SIZE;
- cursor->image_buffer = malloc(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;
-
- /* Start cursor in upper-left */
- cursor->x = 0;
- cursor->y = 0;
-
- return cursor;
-
-}
-
-void guac_common_cursor_free(guac_common_cursor* cursor) {
-
- guac_client* client = cursor->client;
- guac_layer* layer = cursor->layer;
- cairo_surface_t* surface = cursor->surface;
-
- /* Free image buffer and surface */
- free(cursor->image_buffer);
- if (surface != NULL)
- cairo_surface_destroy(surface);
-
- /* Destroy layer within remotely-connected client */
- guac_protocol_send_dispose(client->socket, layer);
-
- /* Return layer to pool */
- guac_client_free_layer(client, layer);
-
- free(cursor);
-
-}
-
-void guac_common_cursor_dup(guac_common_cursor* cursor, guac_user* user,
- guac_socket* socket) {
-
- /* Synchronize location */
- guac_protocol_send_move(socket, cursor->layer, GUAC_DEFAULT_LAYER,
- cursor->x - cursor->hotspot_x,
- cursor->y - cursor->hotspot_y,
- 0);
-
- /* Synchronize cursor image */
- if (cursor->surface != NULL) {
- guac_protocol_send_size(socket, cursor->layer,
- cursor->width, cursor->height);
-
- guac_user_stream_png(user, socket, GUAC_COMP_SRC,
- cursor->layer, 0, 0, cursor->surface);
- }
-
- guac_socket_flush(socket);
-
-}
-
-/**
- * Callback for guac_client_for_user() which shows the cursor layer for the
- * given user (if they exist). The cursor layer is normally hidden when a user
- * is moving the mouse, and will only be shown if a DIFFERENT user is moving
- * the mouse.
- *
- * @param user
- * The user to show the cursor to, or NULL if that user does not exist.
- *
- * @param data
- * A pointer to the guac_common_cursor structure describing the cursor to
- * be shown.
- *
- * @return
- * Always NULL.
- */
-static void* guac_common_cursor_show(guac_user* user, void* data) {
-
- guac_common_cursor* cursor = (guac_common_cursor*) data;
-
- /* Make cursor layer visible to given user */
- if (user != NULL) {
- guac_protocol_send_shade(user->socket, cursor->layer, 255);
- guac_socket_flush(user->socket);
- }
-
- return NULL;
-
-}
-
-void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
- int x, int y) {
-
- guac_user* last_user = cursor->user;
-
- /* Update current user of cursor */
- if (last_user != user) {
-
- cursor->user = user;
-
- /* Make cursor layer visible to previous user */
- guac_client_for_user(cursor->client, last_user,
- guac_common_cursor_show, cursor);
-
- /* Show hardware cursor */
- guac_protocol_send_cursor(user->socket,
- cursor->hotspot_x, cursor->hotspot_y,
- cursor->layer, 0, 0, cursor->width, cursor->height);
-
- /* Hide cursor layer from new user */
- guac_protocol_send_shade(user->socket, cursor->layer, 0);
- guac_socket_flush(user->socket);
-
- }
-
- /* Update cursor position */
- cursor->x = x;
- cursor->y = y;
-
- guac_protocol_send_move(cursor->client->socket, cursor->layer,
- GUAC_DEFAULT_LAYER,
- x - cursor->hotspot_x,
- y - cursor->hotspot_y,
- 0);
-
- guac_socket_flush(cursor->client->socket);
-
-}
-
-/**
- * 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) {
-
- int minimum_size = height * stride;
-
- /* Grow image buffer if necessary */
- if (cursor->image_buffer_size < minimum_size) {
-
- /* Calculate new size */
- cursor->image_buffer_size = minimum_size*2;
-
- /* Destructively reallocate image buffer */
- free(cursor->image_buffer);
- cursor->image_buffer = malloc(cursor->image_buffer_size);
-
- }
-
-}
-
-/**
- * Callback for guac_client_foreach_user() which sends the current cursor image
- * as PNG data to each connected client.
- *
- * @param user
- * The user to send the cursor image to.
- *
- * @param data
- * A pointer to the guac_common_cursor structure containing the cursor
- * image that should be sent to the given user.
- *
- * @return
- * Always NULL.
- */
-static void* __send_user_cursor_image(guac_user* user, void* data) {
-
- guac_common_cursor* cursor = (guac_common_cursor*) data;
-
- guac_user_stream_png(user, user->socket, GUAC_COMP_SRC,
- cursor->layer, 0, 0, cursor->surface);
-
- return NULL;
-
-}
-
-/**
- * Callback for guac_client_for_user() which updates the hardware cursor and
- * hotspot for the given user (if they exist). The hardware cursor image is
- * normally hidden when a user is not moving the mouse, and will only be shown
- * if that user begins moving the mouse.
- *
- * @param user
- * The user whose hardware cursor should be updated, or NULL if that user
- * does not exist.
- *
- * @param data
- * A pointer to the guac_common_cursor structure describing the cursor to
- * be sent as the hardware cursor.
- *
- * @return
- * Always NULL.
- */
-static void* guac_common_cursor_update(guac_user* user, void* data) {
-
- guac_common_cursor* cursor = (guac_common_cursor*) data;
-
- /* Update hardware cursor of current user */
- if (user != NULL) {
- guac_protocol_send_cursor(user->socket,
- cursor->hotspot_x, cursor->hotspot_y,
- cursor->layer, 0, 0, cursor->width, cursor->height);
-
- guac_socket_flush(user->socket);
- }
-
- return NULL;
-
-}
-
-void guac_common_cursor_set_argb(guac_common_cursor* cursor, int hx, int hy,
- unsigned const char* data, int width, int height, int stride) {
-
- /* 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;
-
- /* Update location based on new hotspot */
- guac_protocol_send_move(cursor->client->socket, cursor->layer,
- GUAC_DEFAULT_LAYER,
- cursor->x - hx,
- cursor->y - hy,
- 0);
-
- /* Broadcast new cursor image to all users */
- guac_protocol_send_size(cursor->client->socket, cursor->layer,
- width, height);
-
- guac_client_foreach_user(cursor->client, __send_user_cursor_image, cursor);
-
- guac_socket_flush(cursor->client->socket);
-
- /* Update hardware cursor of current user (if they are indeed valid) */
- if (cursor->user != NULL)
- guac_client_for_user(cursor->client, cursor->user,
- guac_common_cursor_update, cursor);
-
-}
-
-void guac_common_cursor_set_surface(guac_common_cursor* cursor, int hx, int hy,
- 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) {
-
- /* Disassociate from given user */
- if (cursor->user == user)
- cursor->user = NULL;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/guac_cursor.h b/src/common/guac_cursor.h
deleted file mode 100644
index a6d9681..0000000
--- a/src/common/guac_cursor.h
+++ /dev/null
@@ -1,267 +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 "guac_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 cursor layer. This layer will be available to all connected users,
- * but will be visible only to those users who are not moving the mouse.
- */
- guac_layer* layer;
-
- /**
- * 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.
- */
- int 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;
-
-} 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 user
- * 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_user* user,
- guac_socket* socket);
-
-/**
- * Moves 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 moved.
- *
- * @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.
- */
-void guac_common_cursor_move(guac_common_cursor* cursor, guac_user* user,
- int x, int y);
-
-/**
- * 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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_display.c
----------------------------------------------------------------------
diff --git a/src/common/guac_display.c b/src/common/guac_display.c
deleted file mode 100644
index a81ff24..0000000
--- a/src/common/guac_display.c
+++ /dev/null
@@ -1,301 +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 "guac_cursor.h"
-#include "guac_display.h"
-#include "guac_surface.h"
-
-#include <guacamole/client.h>
-#include <guacamole/socket.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 user
- * The user 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_user* user, guac_socket* socket) {
-
- guac_common_display_layer* current = layers;
-
- /* Synchronize all surfaces in given list */
- while (current != NULL) {
- guac_common_surface_dup(current->surface, user, 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 */
- free(current);
- current = next;
-
- }
-
-}
-
-guac_common_display* guac_common_display_alloc(guac_client* client,
- int width, int height) {
-
- /* Allocate display */
- guac_common_display* display = malloc(sizeof(guac_common_display));
- if (display == NULL)
- return NULL;
-
- /* Associate display with given client */
- display->client = client;
-
- /* Allocate shared cursor */
- display->cursor = guac_common_cursor_alloc(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);
-
- free(display);
-
-}
-
-void guac_common_display_dup(guac_common_display* display, guac_user* user,
- guac_socket* socket) {
-
- /* Sunchronize shared cursor */
- guac_common_cursor_dup(display->cursor, user, socket);
-
- /* Synchronize default surface */
- guac_common_surface_dup(display->default_surface, user, socket);
-
- /* Synchronize all layers and buffers */
- guac_common_display_dup_layers(display->layers, user, socket);
- guac_common_display_dup_layers(display->buffers, user, socket);
-
-}
-
-void guac_common_display_flush(guac_common_display* display) {
- guac_common_surface_flush(display->default_surface);
-}
-
-/**
- * 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 =
- malloc(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) {
-
- guac_layer* layer;
- guac_common_surface* surface;
-
- /* Allocate Guacamole layer */
- layer = guac_client_alloc_layer(display->client);
-
- /* Allocate corresponding surface */
- surface = guac_common_surface_alloc(display->client,
- display->client->socket, layer, width, height);
-
- /* Add layer and surface to list */
- return guac_common_display_add_layer(&display->layers, layer, surface);
-
-}
-
-guac_common_display_layer* guac_common_display_alloc_buffer(
- guac_common_display* display, int width, int height) {
-
- guac_layer* buffer;
- guac_common_surface* surface;
-
- /* Allocate Guacamole buffer */
- buffer = guac_client_alloc_buffer(display->client);
-
- /* Allocate corresponding surface */
- surface = guac_common_surface_alloc(display->client,
- display->client->socket, buffer, width, height);
-
- /* Add buffer and surface to list */
- return guac_common_display_add_layer(&display->buffers, buffer, surface);
-
-}
-
-void guac_common_display_free_layer(guac_common_display* display,
- guac_common_display_layer* display_layer) {
-
- /* 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 */
- free(display_layer);
-
-}
-
-void guac_common_display_free_buffer(guac_common_display* display,
- guac_common_display_layer* display_buffer) {
-
- /* 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 */
- free(display_buffer);
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_display.h
----------------------------------------------------------------------
diff --git a/src/common/guac_display.h b/src/common/guac_display.h
deleted file mode 100644
index 4bac8ea..0000000
--- a/src/common/guac_display.h
+++ /dev/null
@@ -1,223 +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 "guac_cursor.h"
-#include "guac_surface.h"
-
-#include <guacamole/client.h>
-#include <guacamole/socket.h>
-
-/**
- * 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;
-
-} 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);
-
-/**
- * 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 user
- * The user 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_user* user,
- 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);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_dot_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/guac_dot_cursor.c b/src/common/guac_dot_cursor.c
deleted file mode 100644
index fde79b0..0000000
--- a/src/common/guac_dot_cursor.c
+++ /dev/null
@@ -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.");
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_dot_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/guac_dot_cursor.h b/src/common/guac_dot_cursor.h
deleted file mode 100644
index 034d044..0000000
--- a/src/common/guac_dot_cursor.h
+++ /dev/null
@@ -1,61 +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 grapic 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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_ibar_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/guac_ibar_cursor.c b/src/common/guac_ibar_cursor.c
deleted file mode 100644
index 6494591..0000000
--- a/src/common/guac_ibar_cursor.c
+++ /dev/null
@@ -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.");
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_ibar_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/guac_ibar_cursor.h b/src/common/guac_ibar_cursor.h
deleted file mode 100644
index ae11fff..0000000
--- a/src/common/guac_ibar_cursor.h
+++ /dev/null
@@ -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
-
[3/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use
proper namespace for internal common headers.
Posted by jm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_iconv.c
----------------------------------------------------------------------
diff --git a/src/common/guac_iconv.c b/src/common/guac_iconv.c
deleted file mode 100644
index f918226..0000000
--- a/src/common/guac_iconv.c
+++ /dev/null
@@ -1,192 +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 "guac_iconv.h"
-
-#include <guacamole/unicode.h>
-#include <stdint.h>
-
-/**
- * Lookup table for Unicode code points, indexed by CP-1252 codepoint.
- */
-const static int __GUAC_RDP_CP1252_CODEPOINT[32] = {
- 0x20AC, /* 0x80 */
- 0xFFFD, /* 0x81 */
- 0x201A, /* 0x82 */
- 0x0192, /* 0x83 */
- 0x201E, /* 0x84 */
- 0x2026, /* 0x85 */
- 0x2020, /* 0x86 */
- 0x2021, /* 0x87 */
- 0x02C6, /* 0x88 */
- 0x2030, /* 0x89 */
- 0x0160, /* 0x8A */
- 0x2039, /* 0x8B */
- 0x0152, /* 0x8C */
- 0xFFFD, /* 0x8D */
- 0x017D, /* 0x8E */
- 0xFFFD, /* 0x8F */
- 0xFFFD, /* 0x90 */
- 0x2018, /* 0x91 */
- 0x2019, /* 0x92 */
- 0x201C, /* 0x93 */
- 0x201D, /* 0x94 */
- 0x2022, /* 0x95 */
- 0x2013, /* 0x96 */
- 0x2014, /* 0x97 */
- 0x02DC, /* 0x98 */
- 0x2122, /* 0x99 */
- 0x0161, /* 0x9A */
- 0x203A, /* 0x9B */
- 0x0153, /* 0x9C */
- 0xFFFD, /* 0x9D */
- 0x017E, /* 0x9E */
- 0x0178, /* 0x9F */
-};
-
-int guac_iconv(guac_iconv_read* reader, const char** input, int in_remaining,
- guac_iconv_write* writer, char** output, int out_remaining) {
-
- while (in_remaining > 0 && out_remaining > 0) {
-
- int value;
- const char* read_start;
- char* write_start;
-
- /* Read character */
- read_start = *input;
- value = reader(input, in_remaining);
- in_remaining -= *input - read_start;
-
- /* Write character */
- write_start = *output;
- writer(output, out_remaining, value);
- out_remaining -= *output - write_start;
-
- /* Stop if null terminator reached */
- if (value == 0)
- return 1;
-
- }
-
- /* Null terminator not reached */
- return 0;
-
-}
-
-int GUAC_READ_UTF8(const char** input, int remaining) {
-
- int value;
-
- *input += guac_utf8_read(*input, remaining, &value);
- return value;
-
-}
-
-int GUAC_READ_UTF16(const char** input, int remaining) {
-
- int value;
-
- /* Bail if not enough data */
- if (remaining < 2)
- return 0;
-
- /* Read two bytes as integer */
- value = *((uint16_t*) *input);
- *input += 2;
-
- return value;
-
-}
-
-int GUAC_READ_CP1252(const char** input, int remaining) {
-
- int value = *((unsigned char*) *input);
-
- /* Replace value with exception if not identical to ISO-8859-1 */
- if (value >= 0x80 && value <= 0x9F)
- value = __GUAC_RDP_CP1252_CODEPOINT[value - 0x80];
-
- (*input)++;
- return value;
-
-}
-
-int GUAC_READ_ISO8859_1(const char** input, int remaining) {
-
- int value = *((unsigned char*) *input);
-
- (*input)++;
- return value;
-
-}
-
-void GUAC_WRITE_UTF8(char** output, int remaining, int value) {
- *output += guac_utf8_write(value, *output, remaining);
-}
-
-void GUAC_WRITE_UTF16(char** output, int remaining, int value) {
-
- /* Bail if not enough data */
- if (remaining < 2)
- return;
-
- /* Write two bytes as integer */
- *((uint16_t*) *output) = value;
- *output += 2;
-
-}
-
-void GUAC_WRITE_CP1252(char** output, int remaining, int value) {
-
- /* If not in ISO-8859-1 part of CP1252, check lookup table */
- if ((value >= 0x80 && value <= 0x9F) || value > 0xFF) {
-
- int i;
- int replacement_value = '?';
- const int* codepoint = __GUAC_RDP_CP1252_CODEPOINT;
-
- /* Search lookup table for value */
- for (i=0x80; i<=0x9F; i++, codepoint++) {
- if (*codepoint == value) {
- replacement_value = i;
- break;
- }
- }
-
- /* Replace value with discovered value (or question mark) */
- value = replacement_value;
-
- }
-
- *((unsigned char*) *output) = (unsigned char) value;
- (*output)++;
-}
-
-void GUAC_WRITE_ISO8859_1(char** output, int remaining, int value) {
-
- /* Translate to question mark if out of range */
- if (value > 0xFF)
- value = '?';
-
- *((unsigned char*) *output) = (unsigned char) value;
- (*output)++;
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_iconv.h
----------------------------------------------------------------------
diff --git a/src/common/guac_iconv.h b/src/common/guac_iconv.h
deleted file mode 100644
index 6381b0a..0000000
--- a/src/common/guac_iconv.h
+++ /dev/null
@@ -1,100 +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_ICONV_H
-#define __GUAC_COMMON_ICONV_H
-
-#include "config.h"
-
-/**
- * Function which reads a character from the given string data, returning
- * the Unicode codepoint read, updating the string pointer to point to the
- * byte immediately after the character read.
- */
-typedef int guac_iconv_read(const char** input, int remaining);
-
-/**
- * Function writes the character having the given Unicode codepoint value to
- * the given string data, updating the string pointer to point to the byte
- * immediately after the character written.
- */
-typedef void guac_iconv_write(char** output, int remaining, int value);
-
-/**
- * Converts characters within a given string from one encoding to another,
- * as defined by the reader/writer functions specified. The input and output
- * string pointers will be updated based on the number of bytes read or
- * written.
- *
- * @param reader The reader function to use when reading the input string.
- * @param input Pointer to the beginning of the input string.
- * @param in_remaining The number of bytes remaining after the pointer to the
- * input string.
- * @param writer The writer function to use when writing the output string.
- * @param output Pointer to the beginning of the output string.
- * @param out_remaining The number of bytes remaining after the pointer to the
- * output string.
- * @return Non-zero if the NULL terminator of the input string was read and
- * copied into the destination string, zero otherwise.
- */
-int guac_iconv(guac_iconv_read* reader, const char** input, int in_remaining,
- guac_iconv_write* writer, char** output, int out_remaining);
-
-/**
- * Read function for UTF8.
- */
-guac_iconv_read GUAC_READ_UTF8;
-
-/**
- * Read function for UTF16.
- */
-guac_iconv_read GUAC_READ_UTF16;
-
-/**
- * Read function for CP-1252.
- */
-guac_iconv_read GUAC_READ_CP1252;
-
-/**
- * Read function for ISO-8859-1
- */
-guac_iconv_read GUAC_READ_ISO8859_1;
-
-/**
- * Write function for UTF8.
- */
-guac_iconv_write GUAC_WRITE_UTF8;
-
-/**
- * Write function for UTF16.
- */
-guac_iconv_write GUAC_WRITE_UTF16;
-
-/**
- * Write function for CP-1252.
- */
-guac_iconv_write GUAC_WRITE_CP1252;
-
-/**
- * Write function for ISO-8859-1
- */
-guac_iconv_write GUAC_WRITE_ISO8859_1;
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_io.c
----------------------------------------------------------------------
diff --git a/src/common/guac_io.c b/src/common/guac_io.c
deleted file mode 100644
index 0cefd7a..0000000
--- a/src/common/guac_io.c
+++ /dev/null
@@ -1,68 +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 "guac_io.h"
-
-#include <unistd.h>
-
-int guac_common_write(int fd, void* buffer, int length) {
-
- unsigned char* bytes = (unsigned char*) buffer;
-
- while (length > 0) {
-
- /* Attempt write */
- int bytes_written = write(fd, bytes, length);
- if (bytes_written < 0)
- return bytes_written;
-
- /* Update buffer */
- length -= bytes_written;
- bytes += bytes_written;
-
- }
-
- /* Success */
- return length;
-
-}
-
-int guac_common_read(int fd, void* buffer, int length) {
-
- unsigned char* bytes = (unsigned char*) buffer;
-
- while (length > 0) {
-
- /* Attempt read */
- int bytes_read = read(fd, bytes, length);
- if (bytes_read < 0)
- return bytes_read;
-
- /* Update buffer */
- length -= bytes_read;
- bytes += bytes_read;
-
- }
-
- /* Success */
- return length;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_io.h
----------------------------------------------------------------------
diff --git a/src/common/guac_io.h b/src/common/guac_io.h
deleted file mode 100644
index 832fc2b..0000000
--- a/src/common/guac_io.h
+++ /dev/null
@@ -1,50 +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_IO_H
-#define __GUAC_COMMON_IO_H
-
-#include "config.h"
-
-/**
- * Writes absolutely all bytes from within the given buffer, returning an error
- * only if the required writes fail.
- *
- * @param fd The file descriptor to write to.
- * @param buffer The buffer containing the data to write.
- * @param length The number of bytes to write.
- * @return The number of bytes written, or a value less than zero if an error
- * occurs.
- */
-int guac_common_write(int fd, void* buffer, int length);
-
-/**
- * Reads enough bytes to fill the given buffer, returning an error only if the
- * required reads fail.
- *
- * @param fd The file descriptor to read from.
- * @param buffer The buffer to read data into.
- * @param length The number of bytes to read.
- * @return The number of bytes read, or a value less than zero if an error
- * occurs.
- */
-int guac_common_read(int fd, void* buffer, int length);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_json.c
----------------------------------------------------------------------
diff --git a/src/common/guac_json.c b/src/common/guac_json.c
deleted file mode 100644
index 4bd1140..0000000
--- a/src/common/guac_json.c
+++ /dev/null
@@ -1,180 +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 "guac_json.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <guacamole/protocol.h>
-#include <guacamole/socket.h>
-#include <guacamole/stream.h>
-#include <guacamole/user.h>
-
-void guac_common_json_flush(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state) {
-
- /* If JSON buffer is non-empty, write contents to blob and reset */
- if (json_state->size > 0) {
- guac_protocol_send_blob(user->socket, stream,
- json_state->buffer, json_state->size);
-
- /* Reset JSON buffer size */
- json_state->size = 0;
-
- }
-
-}
-
-int guac_common_json_write(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state, const char* buffer, int length) {
-
- int blob_written = 0;
-
- /*
- * Append to and flush the JSON buffer as necessary to write the given
- * data
- */
- while (length > 0) {
-
- /* Ensure provided data does not exceed size of buffer */
- int blob_length = length;
- if (blob_length > sizeof(json_state->buffer))
- blob_length = sizeof(json_state->buffer);
-
- /* Flush if more room is needed */
- if (json_state->size + blob_length > sizeof(json_state->buffer)) {
- guac_common_json_flush(user, stream, json_state);
- blob_written = 1;
- }
-
- /* Append data to JSON buffer */
- memcpy(json_state->buffer + json_state->size,
- buffer, blob_length);
-
- json_state->size += blob_length;
-
- /* Advance to next blob of data */
- buffer += blob_length;
- length -= blob_length;
-
- }
-
- return blob_written;
-
-}
-
-int guac_common_json_write_string(guac_user* user,
- guac_stream* stream, guac_common_json_state* json_state,
- const char* str) {
-
- int blob_written = 0;
-
- /* Write starting quote */
- blob_written |= guac_common_json_write(user, stream,
- json_state, "\"", 1);
-
- /* Write given string, escaping as necessary */
- const char* current = str;
- for (; *current != '\0'; current++) {
-
- /* Escape all quotes */
- if (*current == '"') {
-
- /* Write any string content up to current character */
- if (current != str)
- blob_written |= guac_common_json_write(user, stream,
- json_state, str, current - str);
-
- /* Escape the quote that was just read */
- blob_written |= guac_common_json_write(user, stream,
- json_state, "\\", 1);
-
- /* Reset string */
- str = current;
-
- }
-
- }
-
- /* Write any remaining string content */
- if (current != str)
- blob_written |= guac_common_json_write(user, stream,
- json_state, str, current - str);
-
- /* Write ending quote */
- blob_written |= guac_common_json_write(user, stream,
- json_state, "\"", 1);
-
- return blob_written;
-
-}
-
-int guac_common_json_write_property(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state, const char* name,
- const char* value) {
-
- int blob_written = 0;
-
- /* Write leading comma if not first property */
- if (json_state->properties_written != 0)
- blob_written |= guac_common_json_write(user, stream,
- json_state, ",", 1);
-
- /* Write property name */
- blob_written |= guac_common_json_write_string(user, stream,
- json_state, name);
-
- /* Separate name from value with colon */
- blob_written |= guac_common_json_write(user, stream,
- json_state, ":", 1);
-
- /* Write property value */
- blob_written |= guac_common_json_write_string(user, stream,
- json_state, value);
-
- json_state->properties_written++;
-
- return blob_written;
-
-}
-
-void guac_common_json_begin_object(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state) {
-
- /* Init JSON state */
- json_state->size = 0;
- json_state->properties_written = 0;
-
- /* Write leading brace - no blob can possibly be written by this */
- assert(!guac_common_json_write(user, stream, json_state, "{", 1));
-
-}
-
-int guac_common_json_end_object(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state) {
-
- /* Write final brace of JSON object */
- return guac_common_json_write(user, stream, json_state, "}", 1);
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_json.h
----------------------------------------------------------------------
diff --git a/src/common/guac_json.h b/src/common/guac_json.h
deleted file mode 100644
index edb233c..0000000
--- a/src/common/guac_json.h
+++ /dev/null
@@ -1,196 +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_JSON_H
-#define GUAC_COMMON_JSON_H
-
-#include "config.h"
-
-#include <guacamole/stream.h>
-#include <guacamole/user.h>
-
-/**
- * The current streaming state of an arbitrary JSON object, consisting of
- * any number of property name/value pairs.
- */
-typedef struct guac_common_json_state {
-
- /**
- * Buffer of partial JSON data. The individual blobs which make up the JSON
- * body of the object being sent over the Guacamole protocol will be
- * built here.
- */
- char buffer[4096];
-
- /**
- * The number of bytes currently used within the JSON buffer.
- */
- int size;
-
- /**
- * The number of property name/value pairs written to the JSON object thus
- * far.
- */
- int properties_written;
-
-} guac_common_json_state;
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object, flushes the contents of the JSON buffer to a blob
- * instruction. Note that this will flush the JSON buffer only, and will not
- * necessarily flush the underlying guac_socket of the user.
- *
- * @param user
- * The user to which the data will be flushed.
- *
- * @param stream
- * The stream through which the flushed data should be sent as a blob.
- *
- * @param json_state
- * The state object whose buffer should be flushed.
- */
-void guac_common_json_flush(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state);
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object, writes the contents of the given buffer to the JSON buffer
- * of the stream state, flushing as necessary.
- *
- * @param user
- * The user to which the data will be flushed as necessary.
- *
- * @param stream
- * The stream through which the flushed data should be sent as a blob, if
- * data must be flushed at all.
- *
- * @param json_state
- * The state object containing the JSON buffer to which the given buffer
- * should be written.
- *
- * @param buffer
- * The buffer to write.
- *
- * @param length
- * The number of bytes in the buffer.
- *
- * @return
- * Non-zero if at least one blob was written, zero otherwise.
- */
-int guac_common_json_write(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state, const char* buffer, int length);
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object state, writes the given string as a proper JSON string,
- * including starting and ending quotes. The contents of the string will be
- * escaped as necessary.
- *
- * @param user
- * The user to which the data will be flushed as necessary.
- *
- * @param stream
- * The stream through which the flushed data should be sent as a blob, if
- * data must be flushed at all.
- *
- * @param json_state
- * The state object containing the JSON buffer to which the given string
- * should be written as a JSON name/value pair.
- *
- * @param str
- * The string to write.
- *
- * @return
- * Non-zero if at least one blob was written, zero otherwise.
- */
-int guac_common_json_write_string(guac_user* user,
- guac_stream* stream, guac_common_json_state* json_state,
- const char* str);
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object, writes the given JSON property name/value pair. The
- * name and value will be written as proper JSON strings separated by a colon.
- *
- * @param user
- * The user to which the data will be flushed as necessary.
- *
- * @param stream
- * The stream through which the flushed data should be sent as a blob, if
- * data must be flushed at all.
- *
- * @param json_state
- * The state object containing the JSON buffer to which the given strings
- * should be written as a JSON name/value pair.
- *
- * @param name
- * The name of the property to write.
- *
- * @param value
- * The value of the property to write.
- *
- * @return
- * Non-zero if at least one blob was written, zero otherwise.
- */
-int guac_common_json_write_property(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state, const char* name,
- const char* value);
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object, initializes the state for writing a new JSON object. Note
- * that although the user and stream must be provided, no instruction or
- * blobs will be written due to any call to this function.
- *
- * @param user
- * The user associated with the given stream.
- *
- * @param stream
- * The stream associated with the JSON object being written.
- *
- * @param json_state
- * The state object to initialize.
- */
-void guac_common_json_begin_object(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state);
-
-/**
- * Given a stream, the user to which it belongs, and the current stream state
- * of a JSON object, completes writing that JSON object by writing the final
- * terminating brace. This function must only be called following a
- * corresponding call to guac_common_json_begin_object().
- *
- * @param user
- * The user associated with the given stream.
- *
- * @param stream
- * The stream associated with the JSON object being written.
- *
- * @param json_state
- * The state object whose in-progress JSON object should be terminated.
- *
- * @return
- * Non-zero if at least one blob was written, zero otherwise.
- */
-int guac_common_json_end_object(guac_user* user, guac_stream* stream,
- guac_common_json_state* json_state);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_list.c
----------------------------------------------------------------------
diff --git a/src/common/guac_list.c b/src/common/guac_list.c
deleted file mode 100644
index 869d59c..0000000
--- a/src/common/guac_list.c
+++ /dev/null
@@ -1,81 +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 "guac_list.h"
-
-#include <stdlib.h>
-#include <pthread.h>
-
-guac_common_list* guac_common_list_alloc() {
-
- guac_common_list* list = malloc(sizeof(guac_common_list));
-
- pthread_mutex_init(&list->_lock, NULL);
- list->head = NULL;
-
- return list;
-
-}
-
-void guac_common_list_free(guac_common_list* list) {
- free(list);
-}
-
-guac_common_list_element* guac_common_list_add(guac_common_list* list,
- void* data) {
-
- /* Allocate element, initialize as new head */
- guac_common_list_element* element =
- malloc(sizeof(guac_common_list_element));
- element->data = data;
- element->next = list->head;
- element->_ptr = &(list->head);
-
- /* If head already existed, point it at this element */
- if (list->head != NULL)
- list->head->_ptr = &(element->next);
-
- /* Set as new head */
- list->head = element;
- return element;
-
-}
-
-void guac_common_list_remove(guac_common_list* list,
- guac_common_list_element* element) {
-
- /* Point previous (or head) to next */
- *(element->_ptr) = element->next;
-
- if (element->next != NULL)
- element->next->_ptr = element->_ptr;
-
- free(element);
-
-}
-
-void guac_common_list_lock(guac_common_list* list) {
- pthread_mutex_lock(&list->_lock);
-}
-
-void guac_common_list_unlock(guac_common_list* list) {
- pthread_mutex_unlock(&list->_lock);
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_list.h
----------------------------------------------------------------------
diff --git a/src/common/guac_list.h b/src/common/guac_list.h
deleted file mode 100644
index 5f6be1b..0000000
--- a/src/common/guac_list.h
+++ /dev/null
@@ -1,122 +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_LIST_H
-#define __GUAC_LIST_H
-
-#include "config.h"
-
-#include <pthread.h>
-
-/**
- * Generic linked list element.
- */
-typedef struct guac_common_list_element guac_common_list_element;
-
-struct guac_common_list_element {
-
- /**
- * The next element in the list, or NULL if none.
- */
- guac_common_list_element* next;
-
- /**
- * Generic data.
- */
- void* data;
-
- /**
- * The pointer which points to this element, whether another element's
- * next pointer, or the entire list's head pointer.
- */
- guac_common_list_element** _ptr;
-
-};
-
-/**
- * Generic linked list.
- */
-typedef struct guac_common_list {
-
- /**
- * The first element in the list.
- */
- guac_common_list_element* head;
-
- /**
- * Mutex which is locked when exclusive access to the list is required.
- * Possession of the lock is not enforced outside the
- * guac_common_list_lock() function.
- */
- pthread_mutex_t _lock;
-
-} guac_common_list;
-
-/**
- * Creates a new list.
- *
- * @return A newly-allocated list.
- */
-guac_common_list* guac_common_list_alloc();
-
-/**
- * Frees the given list.
- *
- * @param list The list to free.
- */
-void guac_common_list_free(guac_common_list* list);
-
-/**
- * Adds the given data to the list as a new element, returning the created
- * element.
- *
- * @param list The list to add an element to.
- * @param data The data to associate with the newly-created element.
- * @param The newly-created element.
- */
-guac_common_list_element* guac_common_list_add(guac_common_list* list,
- void* data);
-
-/**
- * Removes the given element from the list.
- *
- * @param list The list to remove the element from.
- * @param element The element to remove.
- */
-void guac_common_list_remove(guac_common_list* list,
- guac_common_list_element* element);
-
-/**
- * Acquires exclusive access to the list. No list functions implicitly lock or
- * unlock the list, so any list access which must be threadsafe must use
- * guac_common_list_lock() and guac_common_list_unlock() manually.
- *
- * @param list The list to acquire exclusive access to.
- */
-void guac_common_list_lock(guac_common_list* list);
-
-/**
- * Releases exclusive access to the list.
- *
- * @param list The list to release from exclusive access.
- */
-void guac_common_list_unlock(guac_common_list* list);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_pointer_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/guac_pointer_cursor.c b/src/common/guac_pointer_cursor.c
deleted file mode 100644
index fbcb602..0000000
--- a/src/common/guac_pointer_cursor.c
+++ /dev/null
@@ -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.");
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_pointer_cursor.h
----------------------------------------------------------------------
diff --git a/src/common/guac_pointer_cursor.h b/src/common/guac_pointer_cursor.h
deleted file mode 100644
index 3289576..0000000
--- a/src/common/guac_pointer_cursor.h
+++ /dev/null
@@ -1,61 +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
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_recording.c
----------------------------------------------------------------------
diff --git a/src/common/guac_recording.c b/src/common/guac_recording.c
deleted file mode 100644
index 5d30fa9..0000000
--- a/src/common/guac_recording.c
+++ /dev/null
@@ -1,160 +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 "guac_recording.h"
-
-#include <guacamole/client.h>
-#include <guacamole/socket.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/**
- * Attempts to open a new recording within the given path and having the given
- * name. If such a file already exists, sequential numeric suffixes (.1, .2,
- * .3, etc.) are appended until a filename is found which does not exist (or
- * until the maximum number of numeric suffixes has been tried). If the file
- * absolutely cannot be opened due to an error, -1 is returned and errno is set
- * appropriately.
- *
- * @param path
- * The full path to the directory in which the data file should be created.
- *
- * @param name
- * The name of the data file which should be crated within the given path.
- *
- * @param basename
- * A buffer in which the path, a path separator, the filename, any
- * necessary suffix, and a NULL terminator will be stored. If insufficient
- * space is available, -1 will be returned, and errno will be set to
- * ENAMETOOLONG.
- *
- * @param basename_size
- * The number of bytes available within the provided basename buffer.
- *
- * @return
- * The file descriptor of the open data file if open succeeded, or -1 on
- * failure.
- */
-static int guac_common_recording_open(const char* path,
- const char* name, char* basename, int basename_size) {
-
- int i;
-
- /* Concatenate path and name (separated by a single slash) */
- int basename_length = snprintf(basename,
- basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH,
- "%s/%s", path, name);
-
- /* Abort if maximum length reached */
- if (basename_length ==
- basename_size - GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- /* Attempt to open recording */
- int fd = open(basename,
- O_CREAT | O_EXCL | O_WRONLY,
- S_IRUSR | S_IWUSR);
-
- /* Continuously retry with alternate names on failure */
- if (fd == -1) {
-
- /* Prepare basename for additional suffix */
- basename[basename_length] = '.';
- char* suffix = &(basename[basename_length + 1]);
-
- /* Continue retrying alternative suffixes if file already exists */
- for (i = 1; fd == -1 && errno == EEXIST
- && i <= GUAC_COMMON_RECORDING_MAX_SUFFIX; i++) {
-
- /* Append new suffix */
- sprintf(suffix, "%i", i);
-
- /* Retry with newly-suffixed filename */
- fd = open(basename,
- O_CREAT | O_EXCL | O_WRONLY,
- S_IRUSR | S_IWUSR);
-
- }
-
- /* Abort if we've run out of filenames */
- if (fd == -1)
- return -1;
-
- } /* end if open succeeded */
-
- /* Lock entire output file for writing by the current process */
- struct flock file_lock = {
- .l_type = F_WRLCK,
- .l_whence = SEEK_SET,
- .l_start = 0,
- .l_len = 0,
- .l_pid = getpid()
- };
-
- /* Abort if file cannot be locked for reading */
- if (fcntl(fd, F_SETLK, &file_lock) == -1) {
- close(fd);
- return -1;
- }
-
- return fd;
-
-}
-
-int guac_common_recording_create(guac_client* client, const char* path,
- const char* name, int create_path) {
-
- char filename[GUAC_COMMON_RECORDING_MAX_NAME_LENGTH];
-
- /* Create path if it does not exist, fail if impossible */
- if (create_path && mkdir(path, S_IRWXU) && errno != EEXIST) {
- guac_client_log(client, GUAC_LOG_ERROR,
- "Creation of recording failed: %s", strerror(errno));
- return 1;
- }
-
- /* Attempt to open recording file */
- int fd = guac_common_recording_open(path, name, filename, sizeof(filename));
- if (fd == -1) {
- guac_client_log(client, GUAC_LOG_ERROR,
- "Creation of recording failed: %s", strerror(errno));
- return 1;
- }
-
- /* Replace client socket with wrapped socket */
- client->socket = guac_socket_tee(client->socket, guac_socket_open(fd));
-
- /* Recording creation succeeded */
- guac_client_log(client, GUAC_LOG_INFO,
- "Recording of session will be saved to \"%s\".",
- filename);
-
- return 0;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_recording.h
----------------------------------------------------------------------
diff --git a/src/common/guac_recording.h b/src/common/guac_recording.h
deleted file mode 100644
index 71d8fbc..0000000
--- a/src/common/guac_recording.h
+++ /dev/null
@@ -1,78 +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_RECORDING_H
-#define GUAC_COMMON_RECORDING_H
-
-#include <guacamole/client.h>
-
-/**
- * The maximum numeric value allowed for the .1, .2, .3, etc. suffix appended
- * to the end of the session recording filename if a recording having the
- * requested name already exists.
- */
-#define GUAC_COMMON_RECORDING_MAX_SUFFIX 255
-
-/**
- * The maximum length of the string containing a sequential numeric suffix
- * between 1 and GUAC_COMMON_RECORDING_MAX_SUFFIX inclusive, in bytes,
- * including NULL terminator.
- */
-#define GUAC_COMMON_RECORDING_MAX_SUFFIX_LENGTH 4
-
-/**
- * The maximum overall length of the full path to the session recording file,
- * including any additional suffix and NULL terminator, in bytes.
- */
-#define GUAC_COMMON_RECORDING_MAX_NAME_LENGTH 2048
-
-/**
- * Replaces the socket of the given client such that all further Guacamole
- * protocol output will be copied into a file within the given path and having
- * the given name. If the create_path flag is non-zero, the given path will be
- * created if it does not yet exist. If creation of the recording file or path
- * fails, error messages will automatically be logged, and no recording will be
- * written. The recording will automatically be closed once the client is
- * freed.
- *
- * @param client
- * The client whose output should be copied to a recording file.
- *
- * @param path
- * The full absolute path to a directory in which the recording file should
- * be created.
- *
- * @param name
- * The base name to use for the recording file created within the specified
- * path.
- *
- * @param create_path
- * Zero if the specified path MUST exist for the recording file to be
- * written, or non-zero if the path should be created if it does not yet
- * exist.
- *
- * @return
- * Zero if the recording file has been successfully created and a recording
- * will be written, non-zero otherwise.
- */
-int guac_common_recording_create(guac_client* client, const char* path,
- const char* name, int create_path);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_rect.c
----------------------------------------------------------------------
diff --git a/src/common/guac_rect.c b/src/common/guac_rect.c
deleted file mode 100644
index 2d7fca6..0000000
--- a/src/common/guac_rect.c
+++ /dev/null
@@ -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 "guac_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;
-}
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_rect.h
----------------------------------------------------------------------
diff --git a/src/common/guac_rect.h b/src/common/guac_rect.h
deleted file mode 100644
index 6b31048..0000000
--- a/src/common/guac_rect.h
+++ /dev/null
@@ -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
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_string.c
----------------------------------------------------------------------
diff --git a/src/common/guac_string.c b/src/common/guac_string.c
deleted file mode 100644
index 437cd77..0000000
--- a/src/common/guac_string.c
+++ /dev/null
@@ -1,90 +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 "guac_string.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-int guac_count_occurrences(const char* string, char c) {
-
- int count = 0;
-
- while (*string != 0) {
-
- /* Count each occurrence */
- if (*string == c)
- count++;
-
- /* Next character */
- string++;
-
- }
-
- return count;
-
-}
-
-char** guac_split(const char* string, char delim) {
-
- int i = 0;
-
- int token_count = guac_count_occurrences(string, delim) + 1;
- const char* token_start = string;
-
- /* Allocate space for tokens */
- char** tokens = malloc(sizeof(char*) * (token_count+1));
-
- do {
-
- int length;
- char* token;
-
- /* Find end of token */
- while (*string != 0 && *string != delim)
- string++;
-
- /* Calculate token length */
- length = string - token_start;
-
- /* Allocate space for token and NULL terminator */
- tokens[i++] = token = malloc(length + 1);
-
- /* Copy token, store null */
- memcpy(token, token_start, length);
- token[length] = 0;
-
- /* Stop at end of string */
- if (*string == 0)
- break;
-
- /* Next token */
- token_start = ++string;
-
- } while (i < token_count);
-
- /* NULL terminator */
- tokens[i] = NULL;
-
- return tokens;
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_string.h
----------------------------------------------------------------------
diff --git a/src/common/guac_string.h b/src/common/guac_string.h
deleted file mode 100644
index 442d7f4..0000000
--- a/src/common/guac_string.h
+++ /dev/null
@@ -1,47 +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_STRING_H
-#define __GUAC_COMMON_STRING_H
-
-#include "config.h"
-
-/**
- * Counts the number of occurrences of a given character in a string.
- *
- * @param string The string to count occurrences within.
- * @param c The character to count occurrences of.
- * @return The number of occurrences.
- */
-int guac_count_occurrences(const char* string, char c);
-
-/**
- * Splits a string into a newly-allocated array of strings. The array itself
- * and each string within the array will eventually need to be freed. The array
- * is NULL-terminated.
- *
- * @param string The string to split.
- * @param delim The character which separates individual substrings within the
- * given string.
- * @return A newly-allocated, NULL-terminated array of strings.
- */
-char** guac_split(const char* string, char delim);
-
-#endif
-
[2/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use
proper namespace for internal common headers.
Posted by jm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_surface.c
----------------------------------------------------------------------
diff --git a/src/common/guac_surface.c b/src/common/guac_surface.c
deleted file mode 100644
index 64726a9..0000000
--- a/src/common/guac_surface.c
+++ /dev/null
@@ -1,1552 +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 "guac_rect.h"
-#include "guac_surface.h"
-
-#include <cairo/cairo.h>
-#include <guacamole/client.h>
-#include <guacamole/layer.h>
-#include <guacamole/protocol.h>
-#include <guacamole/socket.h>
-#include <guacamole/timestamp.h>
-#include <guacamole/user.h>
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-/**
- * The width of an update which should be considered negible and thus
- * trivial overhead compared ot the cost of two updates.
- */
-#define GUAC_SURFACE_NEGLIGIBLE_WIDTH 64
-
-/**
- * The height of an update which should be considered negible and thus
- * trivial overhead compared ot the cost of two updates.
- */
-#define GUAC_SURFACE_NEGLIGIBLE_HEIGHT 64
-
-/**
- * The proportional increase in cost contributed by transfer and processing of
- * image data, compared to processing an equivalent amount of client-side
- * data.
- */
-#define GUAC_SURFACE_DATA_FACTOR 16
-
-/**
- * The base cost of every update. Each update should be considered to have
- * this starting cost, plus any additional cost estimated from its
- * content.
- */
-#define GUAC_SURFACE_BASE_COST 4096
-
-/**
- * An increase in cost is negligible if it is less than
- * 1/GUAC_SURFACE_NEGLIGIBLE_INCREASE of the old cost.
- */
-#define GUAC_SURFACE_NEGLIGIBLE_INCREASE 4
-
-/**
- * If combining an update because it appears to be follow a fill pattern,
- * the combined cost must not exceed
- * GUAC_SURFACE_FILL_PATTERN_FACTOR * (total uncombined cost).
- */
-#define GUAC_SURFACE_FILL_PATTERN_FACTOR 3
-
-/* Define cairo_format_stride_for_width() if missing */
-#ifndef HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH
-#define cairo_format_stride_for_width(format, width) (width*4)
-#endif
-
-/**
- * The JPEG image quality ('quantization') setting to use. Range 0-100 where
- * 100 is the highest quality/largest file size, and 0 is the lowest
- * quality/smallest file size.
- */
-#define GUAC_SURFACE_JPEG_IMAGE_QUALITY 90
-
-/**
- * The framerate which, if exceeded, indicates that JPEG is preferred.
- */
-#define GUAC_COMMON_SURFACE_JPEG_FRAMERATE 3
-
-/**
- * Minimum JPEG bitmap size (area). If the bitmap is smaller than this threshold,
- * it should be compressed as a PNG image to avoid the JPEG compression tax.
- */
-#define GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE 4096
-
-/**
- * The WebP image quality ('quantization') setting to use. Range 0-100 where
- * 100 is the highest quality/largest file size, and 0 is the lowest
- * quality/smallest file size.
- */
-#define GUAC_SURFACE_WEBP_IMAGE_QUALITY 90
-
-/**
- * The JPEG compression min block size. This defines the optimal rectangle block
- * size factor for JPEG compression. Usually 8x8 would suffice, but use 16 to
- * reduce the occurrence of ringing artifacts further.
- */
-#define GUAC_SURFACE_JPEG_BLOCK_SIZE 16
-
-/**
- * The WebP compression min block size. This defines the optimal rectangle block
- * size factor for WebP compression. WebP does utilize variable block size, but
- * ensuring a block size factor reduces any noise on the image edges.
- */
-#define GUAC_SURFACE_WEBP_BLOCK_SIZE 8
-
-/**
- * Updates the coordinates of the given rectangle to be within the bounds of
- * the given surface.
- *
- * @param surface The surface to use for clipping.
- * @param rect The rectangle to clip.
- * @param sx The X coordinate of the source rectangle, if any.
- * @param sy The Y coordinate of the source rectangle, if any.
- */
-static void __guac_common_bound_rect(guac_common_surface* surface,
- guac_common_rect* rect, int* sx, int* sy) {
-
- guac_common_rect bounds_rect = {
- .x = 0,
- .y = 0,
- .width = surface->width,
- .height = surface->height
- };
-
- int orig_x = rect->x;
- int orig_y = rect->y;
-
- guac_common_rect_constrain(rect, &bounds_rect);
-
- /* Update source X/Y if given */
- if (sx != NULL) *sx += rect->x - orig_x;
- if (sy != NULL) *sy += rect->y - orig_y;
-
-}
-
-/**
- * Updates the coordinates of the given rectangle to be within the clipping
- * rectangle of the given surface, which must always be within the bounding
- * rectangle of the given surface.
- *
- * @param surface The surface to use for clipping.
- * @param rect The rectangle to clip.
- * @param sx The X coordinate of the source rectangle, if any.
- * @param sy The Y coordinate of the source rectangle, if any.
- */
-static void __guac_common_clip_rect(guac_common_surface* surface,
- guac_common_rect* rect, int* sx, int* sy) {
-
- int orig_x = rect->x;
- int orig_y = rect->y;
-
- /* Just bound within surface if no clipping rectangle applied */
- if (!surface->clipped) {
- __guac_common_bound_rect(surface, rect, sx, sy);
- return;
- }
-
- guac_common_rect_constrain(rect, &surface->clip_rect);
-
- /* Update source X/Y if given */
- if (sx != NULL) *sx += rect->x - orig_x;
- if (sy != NULL) *sy += rect->y - orig_y;
-
-}
-
-/**
- * Returns whether the given rectangle should be combined into the existing
- * dirty rectangle, to be eventually flushed as a "png" instruction.
- *
- * @param surface The surface to be queried.
- * @param rect The update rectangle.
- * @param rect_only Non-zero if this update, by its nature, contains only
- * metainformation about the update's rectangle, zero if
- * the update also contains image data.
- * @return Non-zero if the update should be combined with any existing update,
- * zero otherwise.
- */
-static int __guac_common_should_combine(guac_common_surface* surface, const guac_common_rect* rect, int rect_only) {
-
- if (surface->dirty) {
-
- int combined_cost, dirty_cost, update_cost;
-
- /* Simulate combination */
- guac_common_rect combined = surface->dirty_rect;
- guac_common_rect_extend(&combined, rect);
-
- /* Combine if result is still small */
- if (combined.width <= GUAC_SURFACE_NEGLIGIBLE_WIDTH && combined.height <= GUAC_SURFACE_NEGLIGIBLE_HEIGHT)
- return 1;
-
- /* Estimate costs of the existing update, new update, and both combined */
- combined_cost = GUAC_SURFACE_BASE_COST + combined.width * combined.height;
- dirty_cost = GUAC_SURFACE_BASE_COST + surface->dirty_rect.width * surface->dirty_rect.height;
- update_cost = GUAC_SURFACE_BASE_COST + rect->width * rect->height;
-
- /* Reduce cost if no image data */
- if (rect_only)
- update_cost /= GUAC_SURFACE_DATA_FACTOR;
-
- /* Combine if cost estimate shows benefit */
- if (combined_cost <= update_cost + dirty_cost)
- return 1;
-
- /* Combine if increase in cost is negligible */
- if (combined_cost - dirty_cost <= dirty_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
- return 1;
-
- if (combined_cost - update_cost <= update_cost / GUAC_SURFACE_NEGLIGIBLE_INCREASE)
- return 1;
-
- /* Combine if we anticipate further updates, as this update follows a common fill pattern */
- if (rect->x == surface->dirty_rect.x && rect->y == surface->dirty_rect.y + surface->dirty_rect.height) {
- if (combined_cost <= (dirty_cost + update_cost) * GUAC_SURFACE_FILL_PATTERN_FACTOR)
- return 1;
- }
-
- }
-
- /* Otherwise, do not combine */
- return 0;
-
-}
-
-/**
- * Expands the dirty rect of the given surface to contain the rect described by the given
- * coordinates.
- *
- * @param surface The surface to mark as dirty.
- * @param rect The rectangle of the update which is dirtying the surface.
- */
-static void __guac_common_mark_dirty(guac_common_surface* surface, const guac_common_rect* rect) {
-
- /* Ignore empty rects */
- if (rect->width <= 0 || rect->height <= 0)
- return;
-
- /* If already dirty, update existing rect */
- if (surface->dirty)
- guac_common_rect_extend(&surface->dirty_rect, rect);
-
- /* Otherwise init dirty rect */
- else {
- surface->dirty_rect = *rect;
- surface->dirty = 1;
- }
-
-}
-
-/**
- * Calculate the current average framerate for a given area on the surface.
- *
- * @param surface
- * The surface on which the framerate will be calculated.
- *
- * @param rect
- * The rect containing the area for which the average framerate will be
- * calculated.
- *
- * @return
- * The average framerate of the given area, in frames per second.
- */
-static unsigned int __guac_common_surface_calculate_framerate(
- guac_common_surface* surface, const guac_common_rect* rect) {
-
- int x, y;
-
- /* Calculate heat map dimensions */
- int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
-
- /* Calculate minimum X/Y coordinates intersecting given rect */
- int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
- int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
-
- /* Calculate maximum X/Y coordinates intersecting given rect */
- int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
- int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
-
- unsigned int sum_framerate = 0;
- unsigned int count = 0;
-
- /* Get start of buffer at given coordinates */
- const guac_common_surface_heat_cell* heat_row =
- surface->heat_map + min_y * heat_width + min_x;
-
- /* Iterate over all the heat map cells for the area
- * and calculate the average framerate */
- for (y = min_y; y < max_y; y++) {
-
- /* Get current row of heat map */
- const guac_common_surface_heat_cell* heat_cell = heat_row;
-
- /* For each cell in subset of row */
- for (x = min_x; x < max_x; x++) {
-
- /* Calculate indicies for latest and oldest history entries */
- int oldest_entry = heat_cell->oldest_entry;
- int latest_entry = oldest_entry - 1;
- if (latest_entry < 0)
- latest_entry = GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE - 1;
-
- /* Calculate elapsed time covering entire history for this cell */
- int elapsed_time = heat_cell->history[latest_entry]
- - heat_cell->history[oldest_entry];
-
- /* Calculate and add framerate */
- if (elapsed_time)
- sum_framerate += GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE
- * 1000 / elapsed_time;
-
- /* Next heat map cell */
- heat_cell++;
- count++;
-
- }
-
- /* Next heat map row */
- heat_row += heat_width;
-
- }
-
- /* Calculate the average framerate over entire rect */
- if (count)
- return sum_framerate / count;
-
- return 0;
-
-}
-
- /**
- * Guesses whether a rectangle within a particular surface would be better
- * compressed as PNG or using a lossy format like JPEG. Positive values
- * indicate PNG is likely to be superior, while negative values indicate the
- * opposite.
- *
- * @param surface
- * The surface containing the image data to check.
- *
- * @param rect
- * The rect to check within the given surface.
- *
- * @return
- * Positive values if PNG compression is likely to perform better than
- * lossy alternatives, or negative values if PNG is likely to perform
- * worse.
- */
-static int __guac_common_surface_png_optimality(guac_common_surface* surface,
- const guac_common_rect* rect) {
-
- int x, y;
-
- int num_same = 0;
- int num_different = 1;
-
- /* Get image/buffer metrics */
- int width = rect->width;
- int height = rect->height;
- int stride = surface->stride;
-
- /* Get buffer from surface */
- unsigned char* buffer = surface->buffer + rect->y * stride + rect->x * 4;
-
- /* Image must be at least 1x1 */
- if (width < 1 || height < 1)
- return 0;
-
- /* For each row */
- for (y = 0; y < height; y++) {
-
- uint32_t* row = (uint32_t*) buffer;
- uint32_t last_pixel = *(row++) | 0xFF000000;
-
- /* For each pixel in current row */
- for (x = 1; x < width; x++) {
-
- /* Get next pixel */
- uint32_t current_pixel = *(row++) | 0xFF000000;
-
- /* Update same/different counts according to pixel value */
- if (current_pixel == last_pixel)
- num_same++;
- else
- num_different++;
-
- last_pixel = current_pixel;
-
- }
-
- /* Advance to next row */
- buffer += stride;
-
- }
-
- /* Return rough approximation of optimality for PNG compression */
- return 0x100 * num_same / num_different - 0x400;
-
-}
-
-/**
- * Returns whether the given rectangle would be optimally encoded as JPEG
- * rather than PNG.
- *
- * @param surface
- * The surface to be queried.
- *
- * @param rect
- * The rectangle to check.
- *
- * @return
- * Non-zero if the rectangle would be optimally encoded as JPEG, zero
- * otherwise.
- */
-static int __guac_common_surface_should_use_jpeg(guac_common_surface* surface,
- const guac_common_rect* rect) {
-
- /* Calculate the average framerate for the given rect */
- int framerate = __guac_common_surface_calculate_framerate(surface, rect);
-
- int rect_size = rect->width * rect->height;
-
- /* JPEG is preferred if:
- * - frame rate is high enough
- * - image size is large enough
- * - PNG is not more optimal based on image contents */
- return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
- && rect_size > GUAC_SURFACE_JPEG_MIN_BITMAP_SIZE
- && __guac_common_surface_png_optimality(surface, rect) < 0;
-
-}
-
-/**
- * Returns whether the given rectangle would be optimally encoded as WebP
- * rather than PNG.
- *
- * @param surface
- * The surface to be queried.
- *
- * @param rect
- * The rectangle to check.
- *
- * @return
- * Non-zero if the rectangle would be optimally encoded as WebP, zero
- * otherwise.
- */
-static int __guac_common_surface_should_use_webp(guac_common_surface* surface,
- const guac_common_rect* rect) {
-
- /* Do not use WebP if not supported */
- if (!guac_client_supports_webp(surface->client))
- return 0;
-
- /* Calculate the average framerate for the given rect */
- int framerate = __guac_common_surface_calculate_framerate(surface, rect);
-
- /* WebP is preferred if:
- * - frame rate is high enough
- * - PNG is not more optimal based on image contents */
- return framerate >= GUAC_COMMON_SURFACE_JPEG_FRAMERATE
- && __guac_common_surface_png_optimality(surface, rect) < 0;
-
-}
-
-/**
- * Updates the heat map cells which intersect the given rectangle using the
- * given timestamp. This timestamp, along with timestamps from past updates,
- * is used to calculate the framerate of each heat cell.
- *
- * @param surface
- * The surface containing the heat map cells to be updated.
- *
- * @param rect
- * The rectangle containing the heat map cells to be updated.
- *
- * @param time
- * The timestamp to use when updating the heat map cells which intersect
- * the given rectangle.
- */
-static void __guac_common_surface_touch_rect(guac_common_surface* surface,
- guac_common_rect* rect, guac_timestamp time) {
-
- int x, y;
-
- /* Calculate heat map dimensions */
- int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(surface->width);
-
- /* Calculate minimum X/Y coordinates intersecting given rect */
- int min_x = rect->x / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
- int min_y = rect->y / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
-
- /* Calculate maximum X/Y coordinates intersecting given rect */
- int max_x = min_x + (rect->width - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
- int max_y = min_y + (rect->height - 1) / GUAC_COMMON_SURFACE_HEAT_CELL_SIZE;
-
- /* Get start of buffer at given coordinates */
- guac_common_surface_heat_cell* heat_row =
- surface->heat_map + min_y * heat_width + min_x;
-
- /* Update all heat map cells which intersect with rectangle */
- for (y = min_y; y <= max_y; y++) {
-
- /* Get current row of heat map */
- guac_common_surface_heat_cell* heat_cell = heat_row;
-
- /* For each cell in subset of row */
- for (x = min_x; x <= max_x; x++) {
-
- /* Replace oldest entry with new timestamp */
- heat_cell->history[heat_cell->oldest_entry] = time;
-
- /* Update to next oldest entry */
- heat_cell->oldest_entry++;
- if (heat_cell->oldest_entry >=
- GUAC_COMMON_SURFACE_HEAT_CELL_HISTORY_SIZE)
- heat_cell->oldest_entry = 0;
-
- /* Advance to next heat map cell */
- heat_cell++;
-
- }
-
- /* Next heat map row */
- heat_row += heat_width;
-
- }
-
-}
-
-/**
- * Flushes the bitmap update currently described by the dirty rectangle within the
- * given surface to that surface's bitmap queue. There MUST be space within the
- * queue.
- *
- * @param surface The surface to flush.
- */
-static void __guac_common_surface_flush_to_queue(guac_common_surface* surface) {
-
- guac_common_surface_bitmap_rect* rect;
-
- /* Do not flush if not dirty */
- if (!surface->dirty)
- return;
-
- /* Add new rect to queue */
- rect = &(surface->bitmap_queue[surface->bitmap_queue_length++]);
- rect->rect = surface->dirty_rect;
- rect->flushed = 0;
-
- /* Surface now flushed */
- surface->dirty = 0;
-
-}
-
-void guac_common_surface_flush_deferred(guac_common_surface* surface) {
-
- /* Do not flush if not dirty */
- if (!surface->dirty)
- return;
-
- /* Flush if queue size has reached maximum (space is reserved for the final dirty rect,
- * as guac_common_surface_flush() MAY add an additional rect to the queue */
- if (surface->bitmap_queue_length == GUAC_COMMON_SURFACE_QUEUE_SIZE-1)
- guac_common_surface_flush(surface);
-
- /* Append dirty rect to queue */
- __guac_common_surface_flush_to_queue(surface);
-
-}
-
-/**
- * Transfers a single uint32_t using the given transfer function.
- *
- * @param op The transfer function to use.
- * @param src The source of the uint32_t value.
- * @param dst THe destination which will hold the result of the transfer.
- * @return Non-zero if the destination value was changed, zero otherwise.
- */
-static int __guac_common_surface_transfer_int(guac_transfer_function op, uint32_t* src, uint32_t* dst) {
-
- uint32_t orig = *dst;
-
- switch (op) {
-
- case GUAC_TRANSFER_BINARY_BLACK:
- *dst = 0xFF000000;
- break;
-
- case GUAC_TRANSFER_BINARY_WHITE:
- *dst = 0xFFFFFFFF;
- break;
-
- case GUAC_TRANSFER_BINARY_SRC:
- *dst = *src;
- break;
-
- case GUAC_TRANSFER_BINARY_DEST:
- /* NOP */
- break;
-
- case GUAC_TRANSFER_BINARY_NSRC:
- *dst = ~(*src);
- break;
-
- case GUAC_TRANSFER_BINARY_NDEST:
- *dst = ~(*dst);
- break;
-
- case GUAC_TRANSFER_BINARY_AND:
- *dst = (*dst) & (*src);
- break;
-
- case GUAC_TRANSFER_BINARY_NAND:
- *dst = ~((*dst) & (*src));
- break;
-
- case GUAC_TRANSFER_BINARY_OR:
- *dst = (*dst) | (*src);
- break;
-
- case GUAC_TRANSFER_BINARY_NOR:
- *dst = ~((*dst) | (*src));
- break;
-
- case GUAC_TRANSFER_BINARY_XOR:
- *dst = (*dst) ^ (*src);
- break;
-
- case GUAC_TRANSFER_BINARY_XNOR:
- *dst = ~((*dst) ^ (*src));
- break;
-
- case GUAC_TRANSFER_BINARY_NSRC_AND:
- *dst = (*dst) & ~(*src);
- break;
-
- case GUAC_TRANSFER_BINARY_NSRC_NAND:
- *dst = ~((*dst) & ~(*src));
- break;
-
- case GUAC_TRANSFER_BINARY_NSRC_OR:
- *dst = (*dst) | ~(*src);
- break;
-
- case GUAC_TRANSFER_BINARY_NSRC_NOR:
- *dst = ~((*dst) | ~(*src));
- break;
-
- }
-
- return *dst != orig;
-
-}
-
-/**
- * Draws a rectangle of solid color within the backing surface of the
- * given destination surface.
- *
- * @param dst The destination surface.
- * @param rect The rectangle to draw.
- * @param red The red component of the color of the rectangle.
- * @param green The green component of the color of the rectangle.
- * @param blue The blue component of the color of the rectangle.
- */
-static void __guac_common_surface_rect(guac_common_surface* dst, guac_common_rect* rect,
- int red, int green, int blue) {
-
- int x, y;
-
- int dst_stride;
- unsigned char* dst_buffer;
-
- uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
-
- int min_x = rect->width - 1;
- int min_y = rect->height - 1;
- int max_x = 0;
- int max_y = 0;
-
- dst_stride = dst->stride;
- dst_buffer = dst->buffer + (dst_stride * rect->y) + (4 * rect->x);
-
- /* For each row */
- for (y=0; y < rect->height; y++) {
-
- uint32_t* dst_current = (uint32_t*) dst_buffer;
-
- /* Set row */
- for (x=0; x < rect->width; x++) {
-
- uint32_t old_color = *dst_current;
-
- if (old_color != color) {
- if (x < min_x) min_x = x;
- if (y < min_y) min_y = y;
- if (x > max_x) max_x = x;
- if (y > max_y) max_y = y;
- *dst_current = color;
- }
-
- dst_current++;
- }
-
- /* Next row */
- dst_buffer += dst_stride;
-
- }
-
- /* Restrict destination rect to only updated pixels */
- if (max_x >= min_x && max_y >= min_y) {
- rect->x += min_x;
- rect->y += min_y;
- rect->width = max_x - min_x + 1;
- rect->height = max_y - min_y + 1;
- }
- else {
- rect->width = 0;
- rect->height = 0;
- }
-
-}
-
-/**
- * Copies data from the given buffer to the surface at the given coordinates.
- * The dimensions and location of the destination rectangle will be altered
- * to remove as many unchanged pixels as possible.
- *
- * @param src_buffer The buffer to copy.
- * @param src_stride The number of bytes in each row of the source buffer.
- * @param sx The X coordinate of the source rectangle.
- * @param sy The Y coordinate of the source rectangle.
- * @param dst The destination surface.
- * @param rect The destination rectangle.
- * @param opaque Non-zero if the source surface is opaque (its alpha channel
- * should be ignored), zero otherwise.
- */
-static void __guac_common_surface_put(unsigned char* src_buffer, int src_stride,
- int* sx, int* sy,
- guac_common_surface* dst, guac_common_rect* rect,
- int opaque) {
-
- unsigned char* dst_buffer = dst->buffer;
- int dst_stride = dst->stride;
-
- int x, y;
-
- int min_x = rect->width;
- int min_y = rect->height;
- int max_x = 0;
- int max_y = 0;
-
- int orig_x = rect->x;
- int orig_y = rect->y;
-
- src_buffer += src_stride * (*sy) + 4 * (*sx);
- dst_buffer += (dst_stride * rect->y) + (4 * rect->x);
-
- /* For each row */
- for (y=0; y < rect->height; y++) {
-
- uint32_t* src_current = (uint32_t*) src_buffer;
- uint32_t* dst_current = (uint32_t*) dst_buffer;
-
- /* Copy row */
- for (x=0; x < rect->width; x++) {
-
- if (opaque || (*src_current & 0xFF000000)) {
-
- uint32_t new_color = *src_current | 0xFF000000;
- uint32_t old_color = *dst_current;
-
- if (old_color != new_color) {
- if (x < min_x) min_x = x;
- if (y < min_y) min_y = y;
- if (x > max_x) max_x = x;
- if (y > max_y) max_y = y;
- *dst_current = new_color;
- }
- }
-
- src_current++;
- dst_current++;
- }
-
- /* Next row */
- src_buffer += src_stride;
- dst_buffer += dst_stride;
-
- }
-
- /* Restrict destination rect to only updated pixels */
- if (max_x >= min_x && max_y >= min_y) {
- rect->x += min_x;
- rect->y += min_y;
- rect->width = max_x - min_x + 1;
- rect->height = max_y - min_y + 1;
- }
- else {
- rect->width = 0;
- rect->height = 0;
- }
-
- /* Update source X/Y */
- *sx += rect->x - orig_x;
- *sy += rect->y - orig_y;
-
-}
-
-/**
- * Fills the given surface with color, using the given buffer as a mask. Color
- * will be added to the given surface iff the corresponding pixel within the
- * buffer is opaque.
- *
- * @param src_buffer The buffer to use as a mask.
- * @param src_stride The number of bytes in each row of the source buffer.
- * @param sx The X coordinate of the source rectangle.
- * @param sy The Y coordinate of the source rectangle.
- * @param dst The destination surface.
- * @param rect The destination rectangle.
- * @param red The red component of the color of the fill.
- * @param green The green component of the color of the fill.
- * @param blue The blue component of the color of the fill.
- */
-static void __guac_common_surface_fill_mask(unsigned char* src_buffer, int src_stride,
- int sx, int sy,
- guac_common_surface* dst, guac_common_rect* rect,
- int red, int green, int blue) {
-
- unsigned char* dst_buffer = dst->buffer;
- int dst_stride = dst->stride;
-
- uint32_t color = 0xFF000000 | (red << 16) | (green << 8) | blue;
- int x, y;
-
- src_buffer += src_stride*sy + 4*sx;
- dst_buffer += (dst_stride * rect->y) + (4 * rect->x);
-
- /* For each row */
- for (y=0; y < rect->height; y++) {
-
- uint32_t* src_current = (uint32_t*) src_buffer;
- uint32_t* dst_current = (uint32_t*) dst_buffer;
-
- /* Stencil row */
- for (x=0; x < rect->width; x++) {
-
- /* Fill with color if opaque */
- if (*src_current & 0xFF000000)
- *dst_current = color;
-
- src_current++;
- dst_current++;
- }
-
- /* Next row */
- src_buffer += src_stride;
- dst_buffer += dst_stride;
-
- }
-
-}
-
-/**
- * Copies data from the given surface to the given destination surface using
- * the specified transfer function.
- *
- * @param src_buffer The buffer to copy.
- * @param src_stride The number of bytes in each row of the source buffer.
- * @param sx The X coordinate of the source rectangle.
- * @param sy The Y coordinate of the source rectangle.
- * @param op The transfer function to use.
- * @param dst The destination surface.
- * @param rect The destination rectangle.
- */
-static void __guac_common_surface_transfer(guac_common_surface* src, int* sx, int* sy,
- guac_transfer_function op,
- guac_common_surface* dst, guac_common_rect* rect) {
-
- unsigned char* src_buffer = src->buffer;
- unsigned char* dst_buffer = dst->buffer;
-
- int x, y;
- int src_stride, dst_stride;
- int step = 1;
-
- int min_x = rect->width - 1;
- int min_y = rect->height - 1;
- int max_x = 0;
- int max_y = 0;
-
- int orig_x = rect->x;
- int orig_y = rect->y;
-
- /* Copy forwards only if destination is in a different surface or is before source */
- if (src != dst || rect->y < *sy || (rect->y == *sy && rect->x < *sx)) {
- src_buffer += src->stride * (*sy) + 4 * (*sx);
- dst_buffer += (dst->stride * rect->y) + (4 * rect->x);
- src_stride = src->stride;
- dst_stride = dst->stride;
- step = 1;
- }
-
- /* Otherwise, copy backwards */
- else {
- src_buffer += src->stride * (*sy + rect->height - 1) + 4 * (*sx + rect->width - 1);
- dst_buffer += dst->stride * (rect->y + rect->height - 1) + 4 * (rect->x + rect->width - 1);
- src_stride = -src->stride;
- dst_stride = -dst->stride;
- step = -1;
- }
-
- /* For each row */
- for (y=0; y < rect->height; y++) {
-
- uint32_t* src_current = (uint32_t*) src_buffer;
- uint32_t* dst_current = (uint32_t*) dst_buffer;
-
- /* Transfer each pixel in row */
- for (x=0; x < rect->width; x++) {
-
- if (__guac_common_surface_transfer_int(op, src_current, dst_current)) {
- if (x < min_x) min_x = x;
- if (y < min_y) min_y = y;
- if (x > max_x) max_x = x;
- if (y > max_y) max_y = y;
- }
-
- src_current += step;
- dst_current += step;
- }
-
- /* Next row */
- src_buffer += src_stride;
- dst_buffer += dst_stride;
-
- }
-
- /* Translate X coordinate space of moving backwards */
- if (step < 0) {
- int old_max_x = max_x;
- max_x = rect->width - 1 - min_x;
- min_x = rect->width - 1 - old_max_x;
- }
-
- /* Translate Y coordinate space of moving backwards */
- if (dst_stride < 0) {
- int old_max_y = max_y;
- max_y = rect->height - 1 - min_y;
- min_y = rect->height - 1 - old_max_y;
- }
-
- /* Restrict destination rect to only updated pixels */
- if (max_x >= min_x && max_y >= min_y) {
- rect->x += min_x;
- rect->y += min_y;
- rect->width = max_x - min_x + 1;
- rect->height = max_y - min_y + 1;
- }
- else {
- rect->width = 0;
- rect->height = 0;
- }
-
- /* Update source X/Y */
- *sx += rect->x - orig_x;
- *sy += rect->y - orig_y;
-
-}
-
-guac_common_surface* guac_common_surface_alloc(guac_client* client,
- guac_socket* socket, const guac_layer* layer, int w, int h) {
-
- /* Calculate heat map dimensions */
- int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
- int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
-
- /* Init surface */
- guac_common_surface* surface = calloc(1, sizeof(guac_common_surface));
- surface->client = client;
- surface->socket = socket;
- surface->layer = layer;
- surface->width = w;
- surface->height = h;
-
- /* Create corresponding Cairo surface */
- surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
- surface->buffer = calloc(h, surface->stride);
-
- /* Create corresponding heat map */
- surface->heat_map = calloc(heat_width * heat_height,
- sizeof(guac_common_surface_heat_cell));
-
- /* Reset clipping rect */
- guac_common_surface_reset_clip(surface);
-
- /* Layers must initially exist */
- if (layer->index >= 0) {
- guac_protocol_send_size(socket, layer, w, h);
- surface->realized = 1;
- }
-
- /* Defer creation of buffers */
- else
- surface->realized = 0;
-
- return surface;
-}
-
-void guac_common_surface_free(guac_common_surface* surface) {
-
- /* Only dispose of surface if it exists */
- if (surface->realized)
- guac_protocol_send_dispose(surface->socket, surface->layer);
-
- free(surface->heat_map);
- free(surface->buffer);
- free(surface);
-
-}
-
-void guac_common_surface_resize(guac_common_surface* surface, int w, int h) {
-
- guac_socket* socket = surface->socket;
- const guac_layer* layer = surface->layer;
-
- unsigned char* old_buffer;
- int old_stride;
- guac_common_rect old_rect;
-
- int sx = 0;
- int sy = 0;
-
- /* Calculate heat map dimensions */
- int heat_width = GUAC_COMMON_SURFACE_HEAT_DIMENSION(w);
- int heat_height = GUAC_COMMON_SURFACE_HEAT_DIMENSION(h);
-
- /* Copy old surface data */
- old_buffer = surface->buffer;
- old_stride = surface->stride;
- guac_common_rect_init(&old_rect, 0, 0, surface->width, surface->height);
-
- /* Re-initialize at new size */
- surface->width = w;
- surface->height = h;
- surface->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, w);
- surface->buffer = calloc(h, surface->stride);
- __guac_common_bound_rect(surface, &surface->clip_rect, NULL, NULL);
-
- /* Copy relevant old data */
- __guac_common_bound_rect(surface, &old_rect, NULL, NULL);
- __guac_common_surface_put(old_buffer, old_stride, &sx, &sy, surface, &old_rect, 1);
-
- /* Free old data */
- free(old_buffer);
-
- /* Allocate completely new heat map (can safely discard old stats) */
- free(surface->heat_map);
- surface->heat_map = calloc(heat_width * heat_height,
- sizeof(guac_common_surface_heat_cell));
-
- /* Resize dirty rect to fit new surface dimensions */
- if (surface->dirty) {
- __guac_common_bound_rect(surface, &surface->dirty_rect, NULL, NULL);
- if (surface->dirty_rect.width <= 0 || surface->dirty_rect.height <= 0)
- surface->dirty = 0;
- }
-
- /* Update Guacamole layer */
- if (surface->realized)
- guac_protocol_send_size(socket, layer, w, h);
-
-}
-
-void guac_common_surface_draw(guac_common_surface* surface, int x, int y, cairo_surface_t* src) {
-
- unsigned char* buffer = cairo_image_surface_get_data(src);
- cairo_format_t format = cairo_image_surface_get_format(src);
- int stride = cairo_image_surface_get_stride(src);
- int w = cairo_image_surface_get_width(src);
- int h = cairo_image_surface_get_height(src);
-
- int sx = 0;
- int sy = 0;
-
- guac_common_rect rect;
- guac_common_rect_init(&rect, x, y, w, h);
-
- /* Clip operation */
- __guac_common_clip_rect(surface, &rect, &sx, &sy);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update backing surface */
- __guac_common_surface_put(buffer, stride, &sx, &sy, surface, &rect, format != CAIRO_FORMAT_ARGB32);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update the heat map for the update rectangle. */
- guac_timestamp time = guac_timestamp_current();
- __guac_common_surface_touch_rect(surface, &rect, time);
-
- /* Flush if not combining */
- if (!__guac_common_should_combine(surface, &rect, 0))
- guac_common_surface_flush_deferred(surface);
-
- /* Always defer draws */
- __guac_common_mark_dirty(surface, &rect);
-
-}
-
-void guac_common_surface_paint(guac_common_surface* surface, int x, int y, cairo_surface_t* src,
- int red, int green, int blue) {
-
- unsigned char* buffer = cairo_image_surface_get_data(src);
- int stride = cairo_image_surface_get_stride(src);
- int w = cairo_image_surface_get_width(src);
- int h = cairo_image_surface_get_height(src);
-
- int sx = 0;
- int sy = 0;
-
- guac_common_rect rect;
- guac_common_rect_init(&rect, x, y, w, h);
-
- /* Clip operation */
- __guac_common_clip_rect(surface, &rect, &sx, &sy);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update backing surface */
- __guac_common_surface_fill_mask(buffer, stride, sx, sy, surface, &rect, red, green, blue);
-
- /* Flush if not combining */
- if (!__guac_common_should_combine(surface, &rect, 0))
- guac_common_surface_flush_deferred(surface);
-
- /* Always defer draws */
- __guac_common_mark_dirty(surface, &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) {
-
- guac_socket* socket = dst->socket;
- const guac_layer* src_layer = src->layer;
- const guac_layer* dst_layer = dst->layer;
-
- guac_common_rect rect;
- guac_common_rect_init(&rect, dx, dy, w, h);
-
- /* Clip operation */
- __guac_common_clip_rect(dst, &rect, &sx, &sy);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update backing surface first only if destination rect cannot intersect source rect */
- if (src != dst) {
- __guac_common_surface_transfer(src, &sx, &sy, GUAC_TRANSFER_BINARY_SRC, dst, &rect);
- if (rect.width <= 0 || rect.height <= 0)
- return;
- }
-
- /* Defer if combining */
- if (__guac_common_should_combine(dst, &rect, 1))
- __guac_common_mark_dirty(dst, &rect);
-
- /* Otherwise, flush and draw immediately */
- else {
- guac_common_surface_flush(dst);
- guac_common_surface_flush(src);
- guac_protocol_send_copy(socket, src_layer, sx, sy, rect.width, rect.height,
- GUAC_COMP_OVER, dst_layer, rect.x, rect.y);
- dst->realized = 1;
- }
-
- /* Update backing surface last if destination rect can intersect source rect */
- if (src == dst)
- __guac_common_surface_transfer(src, &sx, &sy, GUAC_TRANSFER_BINARY_SRC, dst, &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) {
-
- guac_socket* socket = dst->socket;
- const guac_layer* src_layer = src->layer;
- const guac_layer* dst_layer = dst->layer;
-
- guac_common_rect rect;
- guac_common_rect_init(&rect, dx, dy, w, h);
-
- /* Clip operation */
- __guac_common_clip_rect(dst, &rect, &sx, &sy);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update backing surface first only if destination rect cannot intersect source rect */
- if (src != dst) {
- __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
- if (rect.width <= 0 || rect.height <= 0)
- return;
- }
-
- /* Defer if combining */
- if (__guac_common_should_combine(dst, &rect, 1))
- __guac_common_mark_dirty(dst, &rect);
-
- /* Otherwise, flush and draw immediately */
- else {
- guac_common_surface_flush(dst);
- guac_common_surface_flush(src);
- guac_protocol_send_transfer(socket, src_layer, sx, sy, rect.width, rect.height, op, dst_layer, rect.x, rect.y);
- dst->realized = 1;
- }
-
- /* Update backing surface last if destination rect can intersect source rect */
- if (src == dst)
- __guac_common_surface_transfer(src, &sx, &sy, op, dst, &rect);
-
-}
-
-void guac_common_surface_rect(guac_common_surface* surface,
- int x, int y, int w, int h,
- int red, int green, int blue) {
-
- guac_socket* socket = surface->socket;
- const guac_layer* layer = surface->layer;
-
- guac_common_rect rect;
- guac_common_rect_init(&rect, x, y, w, h);
-
- /* Clip operation */
- __guac_common_clip_rect(surface, &rect, NULL, NULL);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Update backing surface */
- __guac_common_surface_rect(surface, &rect, red, green, blue);
- if (rect.width <= 0 || rect.height <= 0)
- return;
-
- /* Defer if combining */
- if (__guac_common_should_combine(surface, &rect, 1))
- __guac_common_mark_dirty(surface, &rect);
-
- /* Otherwise, flush and draw immediately */
- else {
- guac_common_surface_flush(surface);
- guac_protocol_send_rect(socket, layer, rect.x, rect.y, rect.width, rect.height);
- guac_protocol_send_cfill(socket, GUAC_COMP_OVER, layer, red, green, blue, 0xFF);
- surface->realized = 1;
- }
-
-}
-
-void guac_common_surface_clip(guac_common_surface* surface, int x, int y, int w, int h) {
-
- guac_common_rect clip;
-
- /* Init clipping rectangle if clipping not already applied */
- if (!surface->clipped) {
- guac_common_rect_init(&surface->clip_rect, 0, 0, surface->width, surface->height);
- surface->clipped = 1;
- }
-
- guac_common_rect_init(&clip, x, y, w, h);
- guac_common_rect_constrain(&surface->clip_rect, &clip);
-
-}
-
-void guac_common_surface_reset_clip(guac_common_surface* surface) {
- surface->clipped = 0;
-}
-
-/**
- * Flushes the bitmap update currently described by the dirty rectangle within
- * the given surface directly via an "img" instruction as PNG data. The
- * resulting instructions will be sent over the socket associated with the
- * given surface.
- *
- * @param surface
- * The surface to flush.
- */
-static void __guac_common_surface_flush_to_png(guac_common_surface* surface) {
-
- if (surface->dirty) {
-
- guac_socket* socket = surface->socket;
- const guac_layer* layer = surface->layer;
-
- /* Get Cairo surface for specified rect */
- unsigned char* buffer = surface->buffer
- + surface->dirty_rect.y * surface->stride
- + surface->dirty_rect.x * 4;
-
- cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
- CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
- surface->dirty_rect.height, surface->stride);
-
- /* Send PNG for rect */
- guac_client_stream_png(surface->client, socket, GUAC_COMP_OVER,
- layer, surface->dirty_rect.x, surface->dirty_rect.y, rect);
-
- cairo_surface_destroy(rect);
- surface->realized = 1;
-
- /* Surface is no longer dirty */
- surface->dirty = 0;
-
- }
-
-}
-
-/**
- * Flushes the bitmap update currently described by the dirty rectangle within
- * the given surface directly via an "img" instruction as JPEG data. The
- * resulting instructions will be sent over the socket associated with the
- * given surface.
- *
- * @param surface
- * The surface to flush.
- */
-static void __guac_common_surface_flush_to_jpeg(guac_common_surface* surface) {
-
- if (surface->dirty) {
-
- guac_socket* socket = surface->socket;
- const guac_layer* layer = surface->layer;
-
- guac_common_rect max;
- guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
-
- /* Expand the dirty rect size to fit in a grid with cells equal to the
- * minimum JPEG block size */
- guac_common_rect_expand_to_grid(GUAC_SURFACE_JPEG_BLOCK_SIZE,
- &surface->dirty_rect, &max);
-
- /* Get Cairo surface for specified rect */
- unsigned char* buffer = surface->buffer
- + surface->dirty_rect.y * surface->stride
- + surface->dirty_rect.x * 4;
-
- cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
- CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
- surface->dirty_rect.height, surface->stride);
-
- /* Send JPEG for rect */
- guac_client_stream_jpeg(surface->client, socket, GUAC_COMP_OVER, layer,
- surface->dirty_rect.x, surface->dirty_rect.y, rect,
- GUAC_SURFACE_JPEG_IMAGE_QUALITY);
-
- cairo_surface_destroy(rect);
- surface->realized = 1;
-
- /* Surface is no longer dirty */
- surface->dirty = 0;
-
- }
-
-}
-
-/**
- * Flushes the bitmap update currently described by the dirty rectangle within
- * the given surface directly via an "img" instruction as WebP data. The
- * resulting instructions will be sent over the socket associated with the
- * given surface.
- *
- * @param surface
- * The surface to flush.
- */
-static void __guac_common_surface_flush_to_webp(guac_common_surface* surface) {
-
- if (surface->dirty) {
-
- guac_socket* socket = surface->socket;
- const guac_layer* layer = surface->layer;
-
- guac_common_rect max;
- guac_common_rect_init(&max, 0, 0, surface->width, surface->height);
-
- /* Expand the dirty rect size to fit in a grid with cells equal to the
- * minimum WebP block size */
- guac_common_rect_expand_to_grid(GUAC_SURFACE_WEBP_BLOCK_SIZE,
- &surface->dirty_rect, &max);
-
- /* Get Cairo surface for specified rect */
- unsigned char* buffer = surface->buffer
- + surface->dirty_rect.y * surface->stride
- + surface->dirty_rect.x * 4;
-
- cairo_surface_t* rect = cairo_image_surface_create_for_data(buffer,
- CAIRO_FORMAT_RGB24, surface->dirty_rect.width,
- surface->dirty_rect.height, surface->stride);
-
- /* Send WebP for rect */
- guac_client_stream_webp(surface->client, socket, GUAC_COMP_OVER, layer,
- surface->dirty_rect.x, surface->dirty_rect.y, rect,
- GUAC_SURFACE_WEBP_IMAGE_QUALITY, 0);
-
- cairo_surface_destroy(rect);
- surface->realized = 1;
-
- /* Surface is no longer dirty */
- surface->dirty = 0;
-
- }
-
-}
-
-
-/**
- * Comparator for instances of guac_common_surface_bitmap_rect, the elements
- * which make up a surface's bitmap buffer.
- *
- * @see qsort
- */
-static int __guac_common_surface_bitmap_rect_compare(const void* a, const void* b) {
-
- guac_common_surface_bitmap_rect* ra = (guac_common_surface_bitmap_rect*) a;
- guac_common_surface_bitmap_rect* rb = (guac_common_surface_bitmap_rect*) b;
-
- /* Order roughly top to bottom, left to right */
- if (ra->rect.y != rb->rect.y) return ra->rect.y - rb->rect.y;
- if (ra->rect.x != rb->rect.x) return ra->rect.x - rb->rect.x;
-
- /* Wider updates should come first (more likely to intersect later) */
- if (ra->rect.width != rb->rect.width) return rb->rect.width - ra->rect.width;
-
- /* Shorter updates should come first (less likely to increase cost) */
- return ra->rect.height - rb->rect.height;
-
-}
-
-void guac_common_surface_flush(guac_common_surface* surface) {
-
- /* Flush final dirty rectangle to queue. */
- __guac_common_surface_flush_to_queue(surface);
-
- guac_common_surface_bitmap_rect* current = surface->bitmap_queue;
- int i, j;
- int original_queue_length;
- int flushed = 0;
-
- original_queue_length = surface->bitmap_queue_length;
-
- /* Sort updates to make combination less costly */
- qsort(surface->bitmap_queue, surface->bitmap_queue_length, sizeof(guac_common_surface_bitmap_rect),
- __guac_common_surface_bitmap_rect_compare);
-
- /* Flush all rects in queue */
- for (i=0; i < surface->bitmap_queue_length; i++) {
-
- /* Get next unflushed candidate */
- guac_common_surface_bitmap_rect* candidate = current;
- if (!candidate->flushed) {
-
- int combined = 0;
-
- /* Build up rect as much as possible */
- for (j=i; j < surface->bitmap_queue_length; j++) {
-
- if (!candidate->flushed) {
-
- /* Clip candidate within current bounds */
- __guac_common_bound_rect(surface, &candidate->rect, NULL, NULL);
- if (candidate->rect.width <= 0 || candidate->rect.height <= 0)
- candidate->flushed = 1;
-
- /* Combine if reasonable */
- else if (__guac_common_should_combine(surface, &candidate->rect, 0) || !surface->dirty) {
- __guac_common_mark_dirty(surface, &candidate->rect);
- candidate->flushed = 1;
- combined++;
- }
-
- }
-
- candidate++;
-
- }
-
- /* Re-add to queue if there's room and this update was modified or we expect others might be */
- if ((combined > 1 || i < original_queue_length)
- && surface->bitmap_queue_length < GUAC_COMMON_SURFACE_QUEUE_SIZE)
- __guac_common_surface_flush_to_queue(surface);
-
- /* Flush as bitmap otherwise */
- else if (surface->dirty) {
-
- flushed++;
-
- /* Prefer WebP when reasonable */
- if (__guac_common_surface_should_use_webp(surface,
- &surface->dirty_rect))
- __guac_common_surface_flush_to_webp(surface);
-
- /* If not WebP, JPEG is the next best (lossy) choice */
- else if (__guac_common_surface_should_use_jpeg(surface,
- &surface->dirty_rect))
- __guac_common_surface_flush_to_jpeg(surface);
-
- /* Use PNG if no lossy formats are appropriate */
- else
- __guac_common_surface_flush_to_png(surface);
-
- }
-
- }
-
- current++;
-
- }
-
- /* Flush complete */
- surface->bitmap_queue_length = 0;
-
-}
-
-void guac_common_surface_dup(guac_common_surface* surface, guac_user* user,
- guac_socket* socket) {
-
- /* Do nothing if not realized */
- if (!surface->realized)
- return;
-
- /* Sync size to new socket */
- guac_protocol_send_size(socket, surface->layer, surface->width, surface->height);
-
- /* Get entire surface */
- cairo_surface_t* rect = cairo_image_surface_create_for_data(
- surface->buffer, CAIRO_FORMAT_RGB24,
- surface->width, surface->height, surface->stride);
-
- /* Send PNG for rect */
- guac_user_stream_png(user, socket, GUAC_COMP_OVER, surface->layer,
- 0, 0, rect);
- cairo_surface_destroy(rect);
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/guac_surface.h
----------------------------------------------------------------------
diff --git a/src/common/guac_surface.h b/src/common/guac_surface.h
deleted file mode 100644
index 144d45a..0000000
--- a/src/common/guac_surface.h
+++ /dev/null
@@ -1,354 +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 "guac_rect.h"
-
-#include <cairo/cairo.h>
-#include <guacamole/client.h>
-#include <guacamole/layer.h>
-#include <guacamole/protocol.h>
-#include <guacamole/socket.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 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 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;
-
-} 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.
- *
- * @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);
-
-/**
- * Draws a solid color rectangle at the given coordinates on the given surface.
- *
- * @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 of the rectangle.
- * @param green The green component of the color of the rectangle.
- * @param blue The blue component of the color of the rectangle.
- */
-void guac_common_surface_rect(guac_common_surface* surface,
- int x, int y, int w, int h,
- int red, int green, int blue);
-
-/**
- * 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);
-
-/**
- * Flushes the given surface, drawing any pending operations on the remote
- * display.
- *
- * @param surface The surface to flush.
- */
-void guac_common_surface_flush(guac_common_surface* surface);
-
-/**
- * Schedules a deferred flush of the given surface. This will not immediately
- * flush the surface to the client. Instead, the result of the flush is
- * added to a queue which is reinspected and combined (if possible) with other
- * deferred flushes during the call to guac_common_surface_flush().
- *
- * @param surface The surface to flush.
- */
-void guac_common_surface_flush_deferred(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 user
- * The user 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_user* user,
- guac_socket* socket);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/ibar_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/ibar_cursor.c b/src/common/ibar_cursor.c
new file mode 100644
index 0000000..6494591
--- /dev/null
+++ b/src/common/ibar_cursor.c
@@ -0,0 +1,98 @@
+/*
+ * 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.");
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/iconv.c
----------------------------------------------------------------------
diff --git a/src/common/iconv.c b/src/common/iconv.c
new file mode 100644
index 0000000..f4cc6c5
--- /dev/null
+++ b/src/common/iconv.c
@@ -0,0 +1,192 @@
+/*
+ * 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/iconv.h"
+
+#include <guacamole/unicode.h>
+#include <stdint.h>
+
+/**
+ * Lookup table for Unicode code points, indexed by CP-1252 codepoint.
+ */
+const static int __GUAC_RDP_CP1252_CODEPOINT[32] = {
+ 0x20AC, /* 0x80 */
+ 0xFFFD, /* 0x81 */
+ 0x201A, /* 0x82 */
+ 0x0192, /* 0x83 */
+ 0x201E, /* 0x84 */
+ 0x2026, /* 0x85 */
+ 0x2020, /* 0x86 */
+ 0x2021, /* 0x87 */
+ 0x02C6, /* 0x88 */
+ 0x2030, /* 0x89 */
+ 0x0160, /* 0x8A */
+ 0x2039, /* 0x8B */
+ 0x0152, /* 0x8C */
+ 0xFFFD, /* 0x8D */
+ 0x017D, /* 0x8E */
+ 0xFFFD, /* 0x8F */
+ 0xFFFD, /* 0x90 */
+ 0x2018, /* 0x91 */
+ 0x2019, /* 0x92 */
+ 0x201C, /* 0x93 */
+ 0x201D, /* 0x94 */
+ 0x2022, /* 0x95 */
+ 0x2013, /* 0x96 */
+ 0x2014, /* 0x97 */
+ 0x02DC, /* 0x98 */
+ 0x2122, /* 0x99 */
+ 0x0161, /* 0x9A */
+ 0x203A, /* 0x9B */
+ 0x0153, /* 0x9C */
+ 0xFFFD, /* 0x9D */
+ 0x017E, /* 0x9E */
+ 0x0178, /* 0x9F */
+};
+
+int guac_iconv(guac_iconv_read* reader, const char** input, int in_remaining,
+ guac_iconv_write* writer, char** output, int out_remaining) {
+
+ while (in_remaining > 0 && out_remaining > 0) {
+
+ int value;
+ const char* read_start;
+ char* write_start;
+
+ /* Read character */
+ read_start = *input;
+ value = reader(input, in_remaining);
+ in_remaining -= *input - read_start;
+
+ /* Write character */
+ write_start = *output;
+ writer(output, out_remaining, value);
+ out_remaining -= *output - write_start;
+
+ /* Stop if null terminator reached */
+ if (value == 0)
+ return 1;
+
+ }
+
+ /* Null terminator not reached */
+ return 0;
+
+}
+
+int GUAC_READ_UTF8(const char** input, int remaining) {
+
+ int value;
+
+ *input += guac_utf8_read(*input, remaining, &value);
+ return value;
+
+}
+
+int GUAC_READ_UTF16(const char** input, int remaining) {
+
+ int value;
+
+ /* Bail if not enough data */
+ if (remaining < 2)
+ return 0;
+
+ /* Read two bytes as integer */
+ value = *((uint16_t*) *input);
+ *input += 2;
+
+ return value;
+
+}
+
+int GUAC_READ_CP1252(const char** input, int remaining) {
+
+ int value = *((unsigned char*) *input);
+
+ /* Replace value with exception if not identical to ISO-8859-1 */
+ if (value >= 0x80 && value <= 0x9F)
+ value = __GUAC_RDP_CP1252_CODEPOINT[value - 0x80];
+
+ (*input)++;
+ return value;
+
+}
+
+int GUAC_READ_ISO8859_1(const char** input, int remaining) {
+
+ int value = *((unsigned char*) *input);
+
+ (*input)++;
+ return value;
+
+}
+
+void GUAC_WRITE_UTF8(char** output, int remaining, int value) {
+ *output += guac_utf8_write(value, *output, remaining);
+}
+
+void GUAC_WRITE_UTF16(char** output, int remaining, int value) {
+
+ /* Bail if not enough data */
+ if (remaining < 2)
+ return;
+
+ /* Write two bytes as integer */
+ *((uint16_t*) *output) = value;
+ *output += 2;
+
+}
+
+void GUAC_WRITE_CP1252(char** output, int remaining, int value) {
+
+ /* If not in ISO-8859-1 part of CP1252, check lookup table */
+ if ((value >= 0x80 && value <= 0x9F) || value > 0xFF) {
+
+ int i;
+ int replacement_value = '?';
+ const int* codepoint = __GUAC_RDP_CP1252_CODEPOINT;
+
+ /* Search lookup table for value */
+ for (i=0x80; i<=0x9F; i++, codepoint++) {
+ if (*codepoint == value) {
+ replacement_value = i;
+ break;
+ }
+ }
+
+ /* Replace value with discovered value (or question mark) */
+ value = replacement_value;
+
+ }
+
+ *((unsigned char*) *output) = (unsigned char) value;
+ (*output)++;
+}
+
+void GUAC_WRITE_ISO8859_1(char** output, int remaining, int value) {
+
+ /* Translate to question mark if out of range */
+ if (value > 0xFF)
+ value = '?';
+
+ *((unsigned char*) *output) = (unsigned char) value;
+ (*output)++;
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/io.c
----------------------------------------------------------------------
diff --git a/src/common/io.c b/src/common/io.c
new file mode 100644
index 0000000..2e2a5ad
--- /dev/null
+++ b/src/common/io.c
@@ -0,0 +1,68 @@
+/*
+ * 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/io.h"
+
+#include <unistd.h>
+
+int guac_common_write(int fd, void* buffer, int length) {
+
+ unsigned char* bytes = (unsigned char*) buffer;
+
+ while (length > 0) {
+
+ /* Attempt write */
+ int bytes_written = write(fd, bytes, length);
+ if (bytes_written < 0)
+ return bytes_written;
+
+ /* Update buffer */
+ length -= bytes_written;
+ bytes += bytes_written;
+
+ }
+
+ /* Success */
+ return length;
+
+}
+
+int guac_common_read(int fd, void* buffer, int length) {
+
+ unsigned char* bytes = (unsigned char*) buffer;
+
+ while (length > 0) {
+
+ /* Attempt read */
+ int bytes_read = read(fd, bytes, length);
+ if (bytes_read < 0)
+ return bytes_read;
+
+ /* Update buffer */
+ length -= bytes_read;
+ bytes += bytes_read;
+
+ }
+
+ /* Success */
+ return length;
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/json.c
----------------------------------------------------------------------
diff --git a/src/common/json.c b/src/common/json.c
new file mode 100644
index 0000000..6dad60b
--- /dev/null
+++ b/src/common/json.c
@@ -0,0 +1,180 @@
+/*
+ * 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/json.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/stream.h>
+#include <guacamole/user.h>
+
+void guac_common_json_flush(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state) {
+
+ /* If JSON buffer is non-empty, write contents to blob and reset */
+ if (json_state->size > 0) {
+ guac_protocol_send_blob(user->socket, stream,
+ json_state->buffer, json_state->size);
+
+ /* Reset JSON buffer size */
+ json_state->size = 0;
+
+ }
+
+}
+
+int guac_common_json_write(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state, const char* buffer, int length) {
+
+ int blob_written = 0;
+
+ /*
+ * Append to and flush the JSON buffer as necessary to write the given
+ * data
+ */
+ while (length > 0) {
+
+ /* Ensure provided data does not exceed size of buffer */
+ int blob_length = length;
+ if (blob_length > sizeof(json_state->buffer))
+ blob_length = sizeof(json_state->buffer);
+
+ /* Flush if more room is needed */
+ if (json_state->size + blob_length > sizeof(json_state->buffer)) {
+ guac_common_json_flush(user, stream, json_state);
+ blob_written = 1;
+ }
+
+ /* Append data to JSON buffer */
+ memcpy(json_state->buffer + json_state->size,
+ buffer, blob_length);
+
+ json_state->size += blob_length;
+
+ /* Advance to next blob of data */
+ buffer += blob_length;
+ length -= blob_length;
+
+ }
+
+ return blob_written;
+
+}
+
+int guac_common_json_write_string(guac_user* user,
+ guac_stream* stream, guac_common_json_state* json_state,
+ const char* str) {
+
+ int blob_written = 0;
+
+ /* Write starting quote */
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, "\"", 1);
+
+ /* Write given string, escaping as necessary */
+ const char* current = str;
+ for (; *current != '\0'; current++) {
+
+ /* Escape all quotes */
+ if (*current == '"') {
+
+ /* Write any string content up to current character */
+ if (current != str)
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, str, current - str);
+
+ /* Escape the quote that was just read */
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, "\\", 1);
+
+ /* Reset string */
+ str = current;
+
+ }
+
+ }
+
+ /* Write any remaining string content */
+ if (current != str)
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, str, current - str);
+
+ /* Write ending quote */
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, "\"", 1);
+
+ return blob_written;
+
+}
+
+int guac_common_json_write_property(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state, const char* name,
+ const char* value) {
+
+ int blob_written = 0;
+
+ /* Write leading comma if not first property */
+ if (json_state->properties_written != 0)
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, ",", 1);
+
+ /* Write property name */
+ blob_written |= guac_common_json_write_string(user, stream,
+ json_state, name);
+
+ /* Separate name from value with colon */
+ blob_written |= guac_common_json_write(user, stream,
+ json_state, ":", 1);
+
+ /* Write property value */
+ blob_written |= guac_common_json_write_string(user, stream,
+ json_state, value);
+
+ json_state->properties_written++;
+
+ return blob_written;
+
+}
+
+void guac_common_json_begin_object(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state) {
+
+ /* Init JSON state */
+ json_state->size = 0;
+ json_state->properties_written = 0;
+
+ /* Write leading brace - no blob can possibly be written by this */
+ assert(!guac_common_json_write(user, stream, json_state, "{", 1));
+
+}
+
+int guac_common_json_end_object(guac_user* user, guac_stream* stream,
+ guac_common_json_state* json_state) {
+
+ /* Write final brace of JSON object */
+ return guac_common_json_write(user, stream, json_state, "}", 1);
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/list.c
----------------------------------------------------------------------
diff --git a/src/common/list.c b/src/common/list.c
new file mode 100644
index 0000000..072ef89
--- /dev/null
+++ b/src/common/list.c
@@ -0,0 +1,81 @@
+/*
+ * 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/list.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+
+guac_common_list* guac_common_list_alloc() {
+
+ guac_common_list* list = malloc(sizeof(guac_common_list));
+
+ pthread_mutex_init(&list->_lock, NULL);
+ list->head = NULL;
+
+ return list;
+
+}
+
+void guac_common_list_free(guac_common_list* list) {
+ free(list);
+}
+
+guac_common_list_element* guac_common_list_add(guac_common_list* list,
+ void* data) {
+
+ /* Allocate element, initialize as new head */
+ guac_common_list_element* element =
+ malloc(sizeof(guac_common_list_element));
+ element->data = data;
+ element->next = list->head;
+ element->_ptr = &(list->head);
+
+ /* If head already existed, point it at this element */
+ if (list->head != NULL)
+ list->head->_ptr = &(element->next);
+
+ /* Set as new head */
+ list->head = element;
+ return element;
+
+}
+
+void guac_common_list_remove(guac_common_list* list,
+ guac_common_list_element* element) {
+
+ /* Point previous (or head) to next */
+ *(element->_ptr) = element->next;
+
+ if (element->next != NULL)
+ element->next->_ptr = element->_ptr;
+
+ free(element);
+
+}
+
+void guac_common_list_lock(guac_common_list* list) {
+ pthread_mutex_lock(&list->_lock);
+}
+
+void guac_common_list_unlock(guac_common_list* list) {
+ pthread_mutex_unlock(&list->_lock);
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/eee92854/src/common/pointer_cursor.c
----------------------------------------------------------------------
diff --git a/src/common/pointer_cursor.c b/src/common/pointer_cursor.c
new file mode 100644
index 0000000..fbcb602
--- /dev/null
+++ b/src/common/pointer_cursor.c
@@ -0,0 +1,96 @@
+/*
+ * 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.");
+
+}
+
[6/6] incubator-guacamole-server git commit: GUACAMOLE-169: Merge
common namespace normalization.
Posted by jm...@apache.org.
GUACAMOLE-169: Merge common namespace normalization.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/52ccd276
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/52ccd276
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/52ccd276
Branch: refs/heads/master
Commit: 52ccd276da4988ea25bd8d0a9bc9d675fac1aeb9
Parents: 6d4b7a9 eee9285
Author: James Muehlner <ja...@guac-dev.org>
Authored: Tue Jan 24 11:42:31 2017 -0800
Committer: James Muehlner <ja...@guac-dev.org>
Committed: Tue Jan 24 11:42:31 2017 -0800
----------------------------------------------------------------------
src/common-ssh/guac_sftp.h | 2 +-
src/common-ssh/guac_ssh.c | 8 +-
src/common/Makefile.am | 62 +-
src/common/blank_cursor.c | 75 ++
src/common/clipboard.c | 135 +++
src/common/common/blank_cursor.h | 64 ++
src/common/common/clipboard.h | 104 +++
src/common/common/cursor.h | 267 ++++++
src/common/common/display.h | 223 +++++
src/common/common/dot_cursor.h | 61 ++
src/common/common/ibar_cursor.h | 62 ++
src/common/common/iconv.h | 100 ++
src/common/common/io.h | 50 +
src/common/common/json.h | 196 ++++
src/common/common/list.h | 122 +++
src/common/common/pointer_cursor.h | 61 ++
src/common/common/recording.h | 78 ++
src/common/common/rect.h | 143 +++
src/common/common/string.h | 47 +
src/common/common/surface.h | 354 +++++++
src/common/cursor.c | 378 ++++++++
src/common/display.c | 301 ++++++
src/common/dot_cursor.c | 85 ++
src/common/guac_blank_cursor.c | 75 --
src/common/guac_blank_cursor.h | 64 --
src/common/guac_clipboard.c | 135 ---
src/common/guac_clipboard.h | 104 ---
src/common/guac_cursor.c | 378 --------
src/common/guac_cursor.h | 267 ------
src/common/guac_display.c | 301 ------
src/common/guac_display.h | 223 -----
src/common/guac_dot_cursor.c | 85 --
src/common/guac_dot_cursor.h | 61 --
src/common/guac_ibar_cursor.c | 98 --
src/common/guac_ibar_cursor.h | 62 --
src/common/guac_iconv.c | 192 ----
src/common/guac_iconv.h | 100 --
src/common/guac_io.c | 68 --
src/common/guac_io.h | 50 -
src/common/guac_json.c | 180 ----
src/common/guac_json.h | 196 ----
src/common/guac_list.c | 81 --
src/common/guac_list.h | 122 ---
src/common/guac_pointer_cursor.c | 96 --
src/common/guac_pointer_cursor.h | 61 --
src/common/guac_recording.c | 160 ----
src/common/guac_recording.h | 78 --
src/common/guac_rect.c | 266 ------
src/common/guac_rect.h | 143 ---
src/common/guac_string.c | 90 --
src/common/guac_string.h | 47 -
src/common/guac_surface.c | 1552 -------------------------------
src/common/guac_surface.h | 354 -------
src/common/ibar_cursor.c | 98 ++
src/common/iconv.c | 192 ++++
src/common/io.c | 68 ++
src/common/json.c | 180 ++++
src/common/list.c | 81 ++
src/common/pointer_cursor.c | 96 ++
src/common/recording.c | 160 ++++
src/common/rect.c | 266 ++++++
src/common/string.c | 90 ++
src/common/surface.c | 1552 +++++++++++++++++++++++++++++++
src/guacd/proc-map.c | 2 +-
src/guacd/proc-map.h | 2 +-
src/protocols/rdp/dvc.c | 2 +-
src/protocols/rdp/dvc.h | 2 +-
src/protocols/rdp/rdp.c | 6 +-
src/protocols/rdp/rdp.h | 8 +-
src/protocols/rdp/rdp_bitmap.c | 4 +-
src/protocols/rdp/rdp_bitmap.h | 2 +-
src/protocols/rdp/rdp_cliprdr.c | 4 +-
src/protocols/rdp/rdp_gdi.c | 2 +-
src/protocols/rdp/rdp_glyph.c | 2 +-
src/protocols/rdp/rdp_pointer.c | 4 +-
src/protocols/rdp/rdp_pointer.h | 2 +-
src/protocols/rdp/rdp_settings.c | 2 +-
src/protocols/rdp/rdp_stream.c | 2 +-
src/protocols/rdp/rdp_stream.h | 2 +-
src/protocols/rdp/rdp_svc.c | 2 +-
src/protocols/rdp/user.c | 2 +-
src/protocols/ssh/input.c | 4 +-
src/protocols/ssh/ssh.c | 4 +-
src/protocols/ssh/user.c | 2 +-
src/protocols/telnet/telnet.c | 6 +-
src/protocols/vnc/clipboard.c | 4 +-
src/protocols/vnc/cursor.c | 6 +-
src/protocols/vnc/display.c | 4 +-
src/protocols/vnc/input.c | 4 +-
src/protocols/vnc/log.c | 4 +-
src/protocols/vnc/log.h | 4 +-
src/protocols/vnc/user.c | 6 +-
src/protocols/vnc/vnc.c | 8 +-
src/protocols/vnc/vnc.h | 8 +-
src/terminal/Makefile.am | 2 -
src/terminal/common.c | 20 -
src/terminal/common.h | 21 -
src/terminal/display.c | 2 +-
src/terminal/display.h | 2 +-
src/terminal/packet.c | 64 --
src/terminal/packet.h | 89 --
src/terminal/terminal.c | 192 ++--
src/terminal/terminal.h | 39 +-
src/terminal/typescript.c | 2 +-
tests/common/guac_iconv.c | 2 +-
tests/common/guac_rect.c | 2 +-
tests/common/guac_string.c | 2 +-
107 files changed, 5909 insertions(+), 6096 deletions(-)
----------------------------------------------------------------------