GUAC-608: Add inbound clipboard. Remove use of iconv().
This commit is contained in:
parent
c9b077af4c
commit
3c70e87aef
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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 */
|
int vnc_guac_client_blob_handler(guac_client* client, guac_stream* stream, void* data, int length) {
|
||||||
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 || _LIBICONV_VERSION >= 0x0105
|
return guac_vnc_clipboard_blob_handler(client, stream, data, length);
|
||||||
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. */
|
int vnc_guac_client_end_handler(guac_client* client, guac_stream* stream) {
|
||||||
if(iso_8559_1_data) {
|
return guac_vnc_clipboard_end_handler(client, stream);
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int vnc_guac_client_free_handler(guac_client* client) {
|
int vnc_guac_client_free_handler(guac_client* client) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user