GUAC-608: Add inbound clipboard. Remove use of iconv().

This commit is contained in:
Michael Jumper 2014-04-08 17:08:29 -07:00
parent c9b077af4c
commit 3c70e87aef
7 changed files with 41 additions and 168 deletions

View File

@ -32,14 +32,12 @@ lib_LTLIBRARIES = libguac-client-vnc.la
libguac_client_vnc_la_SOURCES = \ libguac_client_vnc_la_SOURCES = \
client.c \ client.c \
clipboard.c \ clipboard.c \
convert.c \
guac_handlers.c \ guac_handlers.c \
vnc_handlers.c vnc_handlers.c
noinst_HEADERS = \ noinst_HEADERS = \
client.h \ client.h \
clipboard.h \ clipboard.h \
convert.h \
guac_handlers.h \ guac_handlers.h \
vnc_handlers.h vnc_handlers.h

View File

@ -351,6 +351,8 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
client->mouse_handler = vnc_guac_client_mouse_handler; client->mouse_handler = vnc_guac_client_mouse_handler;
client->key_handler = vnc_guac_client_key_handler; client->key_handler = vnc_guac_client_key_handler;
client->clipboard_handler = vnc_guac_client_clipboard_handler; client->clipboard_handler = vnc_guac_client_clipboard_handler;
client->blob_handler = vnc_guac_client_blob_handler;
client->end_handler = vnc_guac_client_end_handler;
/* If not read-only but cursor is remote, set a dot cursor */ /* If not read-only but cursor is remote, set a dot cursor */
if (guac_client_data->remote_cursor) if (guac_client_data->remote_cursor)

View File

@ -21,22 +21,48 @@
*/ */
#include "config.h" #include "config.h"
#include "client.h"
#include "clipboard.h" #include "clipboard.h"
#include "guac_clipboard.h"
#include "guac_iconv.h"
int guac_vnc_clipboard_handler(guac_client* client, guac_stream* stream, int guac_vnc_clipboard_handler(guac_client* client, guac_stream* stream,
char* mimetype) { char* mimetype) {
/* STUB */
/* Clear clipboard and prepare for new data */
vnc_guac_client_data* client_data = (vnc_guac_client_data*) client->data;
guac_common_clipboard_reset(client_data->clipboard, mimetype);
return 0; return 0;
} }
int guac_vnc_clipboard_blob_handler(guac_client* client, guac_stream* stream, int guac_vnc_clipboard_blob_handler(guac_client* client, guac_stream* stream,
void* data, int length) { void* data, int length) {
/* STUB */
/* Append new data */
vnc_guac_client_data* client_data = (vnc_guac_client_data*) client->data;
guac_common_clipboard_append(client_data->clipboard, (char*) data, length);
return 0; return 0;
} }
int guac_vnc_clipboard_end_handler(guac_client* client, guac_stream* stream) { int guac_vnc_clipboard_end_handler(guac_client* client, guac_stream* stream) {
/* STUB */
vnc_guac_client_data* client_data = (vnc_guac_client_data*) client->data;
rfbClient* rfb_client = client_data->rfb_client;
char output_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH];
const char* input = client_data->clipboard->buffer;
char* output = output_data;
/* Convert clipboard to ISO 8859-1 */
guac_iconv(GUAC_READ_UTF8, &input, client_data->clipboard->length,
GUAC_WRITE_ISO8859_1, &output, sizeof(output_data));
/* Send via VNC */
SendClientCutText(rfb_client, output_data, output - output_data);
return 0; return 0;
} }

View File

@ -1,103 +0,0 @@
/*
* Copyright (C) 2013 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 <errno.h>
#include <iconv.h>
#include <stdlib.h>
#include <string.h>
char* convert(const char* from_charset, const char* to_charset, const char* input) {
size_t input_remaining;
size_t output_remaining;
size_t bytes_converted = 0;
char* output;
char* output_buffer;
char* new_buffer;
char* input_buffer;
size_t output_length;
iconv_t cd;
cd = iconv_open(to_charset, from_charset);
if(cd == (iconv_t) -1)
/* Cannot convert due to invalid character set */
return NULL;
input_remaining = strlen(input);
input_buffer = (char*) input;
/* Start the output buffer the same size as the input buffer */
output_length = input_remaining;
/* Leave some space at the end for NULL terminator */
if (!(output = (char*) malloc(output_length + 4))) {
/* Cannot convert due to memory allocation error */
iconv_close(cd);
return NULL;
}
do {
output_buffer = output + bytes_converted;
output_remaining = output_length - bytes_converted;
bytes_converted = iconv(cd, &input_buffer,
&input_remaining, &output_buffer, &output_remaining);
if(bytes_converted == -1) {
if(errno == E2BIG) {
/* The output buffer is too small, so allocate more space */
bytes_converted = output_buffer - output;
output_length += input_remaining * 2 + 8;
if (!(new_buffer = (char*) realloc(output, output_length + 4))) {
/* Cannot convert due to memory allocation error */
iconv_close(cd);
free(output);
return NULL;
}
output = new_buffer;
output_buffer = output + bytes_converted;
}
else if (errno == EILSEQ) {
/* Invalid sequence detected, return what's been converted so far */
break;
}
else if (errno == EINVAL) {
/* Incomplete sequence detected, can be ignored */
break;
}
}
} while (input_remaining);
/* Flush the iconv conversion */
iconv(cd, NULL, NULL, &output_buffer, &output_remaining);
iconv_close(cd);
/* Add the NULL terminator */
memset(output_buffer, 0, 4);
return output;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 2013 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_VNC_VNC_CONVERT_H
#define __GUAC_VNC_VNC_CONVERT_H
#include "config.h"
#include <iconv.h>
/**
* Converts a string from one charset to another. Returns a newly allocated string.
* @param from_charset The string representing the character set to convert from.
* @param to_charset The string representing the character set to convert to.
* @return A newly allocated string that is the result of the conversion, or NULL
* if an error has occured.
*/
char* convert (const char* from_charset, const char* to_charset, const char* input);
#endif

View File

@ -23,7 +23,7 @@
#include "config.h" #include "config.h"
#include "client.h" #include "client.h"
#include "convert.h" #include "clipboard.h"
#include "guac_clipboard.h" #include "guac_clipboard.h"
#include <stdlib.h> #include <stdlib.h>
@ -98,26 +98,15 @@ int vnc_guac_client_key_handler(guac_client* client, int keysym, int pressed) {
} }
int vnc_guac_client_clipboard_handler(guac_client* client, guac_stream* stream, char* mimetype) { int vnc_guac_client_clipboard_handler(guac_client* client, guac_stream* stream, char* mimetype) {
#if 0 return guac_vnc_clipboard_handler(client, stream, mimetype);
rfbClient* rfb_client = ((vnc_guac_client_data*) client->data)->rfb_client;
/* Convert UTF-8 character data to ISO_8859-1 */
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105
char* iso_8559_1_data = convert("UTF-8", "ISO_8859-1//TRANSLIT", data);
#else
char* iso_8559_1_data = convert("UTF-8", "ISO_8859-1", data);
#endif
/* If the conversion was successful, send the converted character data. */
if(iso_8559_1_data) {
SendClientCutText(rfb_client, iso_8559_1_data, strlen(iso_8559_1_data));
free(iso_8559_1_data);
/* Otherwise, just send an empty string. */
} }
else
SendClientCutText(rfb_client, "", 0); int vnc_guac_client_blob_handler(guac_client* client, guac_stream* stream, void* data, int length) {
#endif return guac_vnc_clipboard_blob_handler(client, stream, data, length);
return 0; }
int vnc_guac_client_end_handler(guac_client* client, guac_stream* stream) {
return guac_vnc_clipboard_end_handler(client, stream);
} }
int vnc_guac_client_free_handler(guac_client* client) { int vnc_guac_client_free_handler(guac_client* client) {

View File

@ -32,6 +32,8 @@ int vnc_guac_client_handle_messages(guac_client* client);
int vnc_guac_client_mouse_handler(guac_client* client, int x, int y, int mask); int vnc_guac_client_mouse_handler(guac_client* client, int x, int y, int mask);
int vnc_guac_client_key_handler(guac_client* client, int keysym, int pressed); int vnc_guac_client_key_handler(guac_client* client, int keysym, int pressed);
int vnc_guac_client_clipboard_handler(guac_client* client, guac_stream* stream, char* mimetype); int vnc_guac_client_clipboard_handler(guac_client* client, guac_stream* stream, char* mimetype);
int vnc_guac_client_blob_handler(guac_client* client, guac_stream* stream, void* data, int length);
int vnc_guac_client_end_handler(guac_client* client, guac_stream* stream);
int vnc_guac_client_free_handler(guac_client* client); int vnc_guac_client_free_handler(guac_client* client);
#endif #endif