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:26 UTC

[5/6] incubator-guacamole-server git commit: GUACAMOLE-169: Use proper namespace for internal common headers.

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
+