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(-)
----------------------------------------------------------------------