From 855e32c7a56e1602e9e646fbfddee244f5aade5c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 8 Apr 2014 14:54:43 -0700 Subject: [PATCH] GUAC-608: Add common clipboard code. --- src/common/Makefile.am | 2 + src/common/guac_clipboard.c | 102 ++++++++++++++++++++++++++++++++++ src/common/guac_clipboard.h | 106 ++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 src/common/guac_clipboard.c create mode 100644 src/common/guac_clipboard.h diff --git a/src/common/Makefile.am b/src/common/Makefile.am index db0c6885..bb6789c3 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -28,6 +28,7 @@ noinst_LTLIBRARIES = libguac_common.la noinst_HEADERS = \ guac_io.h \ + guac_clipboard.h \ guac_dot_cursor.h \ guac_iconv.h \ guac_list.h \ @@ -36,6 +37,7 @@ noinst_HEADERS = \ libguac_common_la_SOURCES = \ guac_io.c \ + guac_clipboard.c \ guac_dot_cursor.c \ guac_iconv.c \ guac_list.c \ diff --git a/src/common/guac_clipboard.c b/src/common/guac_clipboard.c new file mode 100644 index 00000000..9501e252 --- /dev/null +++ b/src/common/guac_clipboard.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "config.h" +#include "guac_clipboard.h" + +#include +#include +#include +#include +#include + +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); +} + +void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client) { + + char* current = clipboard->buffer; + int remaining = clipboard->length; + + /* Begin stream */ + guac_stream* stream = guac_client_alloc_stream(client); + guac_protocol_send_clipboard(client->socket, stream, 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(client->socket, stream, current, block_size); + + /* Next block */ + remaining -= block_size; + current += block_size; + + } + + /* End stream */ + guac_protocol_send_end(client->socket, stream); + guac_client_free_stream(client, stream); + +} + +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; + +} + diff --git a/src/common/guac_clipboard.h b/src/common/guac_clipboard.h new file mode 100644 index 00000000..0b9433f4 --- /dev/null +++ b/src/common/guac_clipboard.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __GUAC_CLIPBOARD_H +#define __GUAC_CLIPBOARD_H + +#include "config.h" + +#include + +/** + * 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. + * + * @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 +