mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Added clipboard support.
This commit is contained in:
@@ -113,7 +113,13 @@ public class GuacamoleClient extends Client {
|
||||
}
|
||||
|
||||
public void setClipboard(String clipboard) throws GuacamoleException {
|
||||
// STUB
|
||||
try {
|
||||
output.write("clipboard:" + Instruction.escape(clipboard) + ";");
|
||||
output.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() throws GuacamoleException {
|
||||
|
@@ -29,7 +29,7 @@ public abstract class Instruction {
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
public String escape(String str) {
|
||||
public static String escape(String str) {
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
|
@@ -120,6 +120,14 @@ void guac_start_client(guac_client* client) {
|
||||
);
|
||||
}
|
||||
|
||||
else if (strcmp(instruction.opcode, "clipboard") == 0) {
|
||||
if (client->clipboard_handler)
|
||||
client->clipboard_handler(
|
||||
client,
|
||||
guac_unescape_string_inplace(instruction.argv[0]) /* data */
|
||||
);
|
||||
}
|
||||
|
||||
} while ((retval = guac_read_instruction(io, &instruction)) > 0);
|
||||
|
||||
if (retval < 0)
|
||||
|
@@ -32,6 +32,7 @@ typedef struct guac_client {
|
||||
void (*handle_messages)(struct guac_client* client);
|
||||
void (*mouse_handler)(struct guac_client* client, int x, int y, int button_mask);
|
||||
void (*key_handler)(struct guac_client* client, int keysym, int pressed);
|
||||
void (*clipboard_handler)(struct guac_client* client, char* copied);
|
||||
void (*free_handler)(void* client);
|
||||
|
||||
} guac_client;
|
||||
|
@@ -81,16 +81,65 @@ char* guac_escape_string(const char* str) {
|
||||
|
||||
}
|
||||
|
||||
*current = '\0';
|
||||
|
||||
return escaped;
|
||||
|
||||
}
|
||||
|
||||
char* guac_unescape_string_inplace(char* str) {
|
||||
|
||||
char* from;
|
||||
char* to;
|
||||
|
||||
from = to = str;
|
||||
for (;;) {
|
||||
|
||||
char c = *(from++);
|
||||
|
||||
if (c == '\\') {
|
||||
|
||||
c = *(from++);
|
||||
if (c == 's')
|
||||
*(to++) = ';';
|
||||
|
||||
else if (c == 'c')
|
||||
*(to++) = ',';
|
||||
|
||||
else if (c == '\\')
|
||||
*(to++) = '\\';
|
||||
|
||||
else if (c == '\0') {
|
||||
*(to++) = '\\';
|
||||
break;
|
||||
}
|
||||
|
||||
else {
|
||||
*(to++) = '\\';
|
||||
*(to++) = c;
|
||||
}
|
||||
}
|
||||
|
||||
else if (c == '\0')
|
||||
break;
|
||||
|
||||
else
|
||||
*(to++) = c;
|
||||
|
||||
}
|
||||
|
||||
*to = '\0';
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
|
||||
void guac_send_name(GUACIO* io, const char* name) {
|
||||
|
||||
char* escaped = guac_escape_string(name);
|
||||
|
||||
guac_write_string(io, "name:");
|
||||
guac_write_string(io, name);
|
||||
guac_write_string(io, escaped);
|
||||
guac_write_string(io, ";");
|
||||
|
||||
free(escaped);
|
||||
@@ -105,6 +154,30 @@ void guac_send_size(GUACIO* io, int w, int h) {
|
||||
guac_write_string(io, ";");
|
||||
}
|
||||
|
||||
void guac_send_clipboard(GUACIO* io, const char* data) {
|
||||
|
||||
char* escaped = guac_escape_string(data);
|
||||
|
||||
guac_write_string(io, "clipboard:");
|
||||
guac_write_string(io, escaped);
|
||||
guac_write_string(io, ";");
|
||||
|
||||
free(escaped);
|
||||
|
||||
}
|
||||
|
||||
void guac_send_error(GUACIO* io, const char* error) {
|
||||
|
||||
char* escaped = guac_escape_string(error);
|
||||
|
||||
guac_write_string(io, "error:");
|
||||
guac_write_string(io, escaped);
|
||||
guac_write_string(io, ";");
|
||||
|
||||
free(escaped);
|
||||
|
||||
}
|
||||
|
||||
void guac_send_copy(GUACIO* io, int srcx, int srcy, int w, int h, int dstx, int dsty) {
|
||||
guac_write_string(io, "copy:");
|
||||
guac_write_int(io, srcx);
|
||||
|
@@ -36,7 +36,10 @@ typedef struct guac_instruction {
|
||||
|
||||
void guac_free_instruction(guac_instruction* instruction);
|
||||
char* guac_escape_string(const char* str);
|
||||
char* guac_unescape_string_inplace(char* str);
|
||||
void guac_send_name(GUACIO* io, const char* name);
|
||||
void guac_send_error(GUACIO* io, const char* error);
|
||||
void guac_send_clipboard(GUACIO* io, const char* data);
|
||||
void guac_send_size(GUACIO* io, int w, int h);
|
||||
void guac_send_copy(GUACIO* io, int srcx, int srcy, int w, int h, int dstx, int dsty);
|
||||
void guac_send_png(GUACIO* io, int x, int y, png_byte** png_rows, int w, int h);
|
||||
|
@@ -34,10 +34,12 @@ char __guac_password[] = "potato";
|
||||
static char* __GUAC_CLIENT = "GUAC_CLIENT";
|
||||
|
||||
typedef struct vnc_guac_client_data {
|
||||
|
||||
rfbClient* rfb_client;
|
||||
png_byte** png_buffer;
|
||||
png_byte** png_buffer_alpha;
|
||||
int copy_rect_used;
|
||||
|
||||
} vnc_guac_client_data;
|
||||
|
||||
void guac_vnc_cursor(rfbClient* client, int x, int y, int w, int h, int bpp) {
|
||||
@@ -178,6 +180,16 @@ char* guac_vnc_get_password(rfbClient* client) {
|
||||
}
|
||||
|
||||
|
||||
void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) {
|
||||
|
||||
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
||||
GUACIO* io = gc->io;
|
||||
|
||||
guac_send_clipboard(io, text);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void vnc_guac_client_handle_messages(guac_client* client) {
|
||||
|
||||
int wait_result;
|
||||
@@ -228,6 +240,14 @@ void vnc_guac_client_key_handler(guac_client* client, int keysym, int pressed) {
|
||||
|
||||
}
|
||||
|
||||
void vnc_guac_client_clipboard_handler(guac_client* client, char* data) {
|
||||
|
||||
rfbClient* rfb_client = ((vnc_guac_client_data*) client->data)->rfb_client;
|
||||
|
||||
SendClientCutText(rfb_client, data, strlen(data));
|
||||
|
||||
}
|
||||
|
||||
void vnc_guac_client_free_handler(guac_client* client) {
|
||||
|
||||
rfbClient* rfb_client = ((vnc_guac_client_data*) client->data)->rfb_client;
|
||||
@@ -266,6 +286,9 @@ void vnc_guac_client_init(guac_client* client, const char* hostname, int port) {
|
||||
rfb_client->GotCursorShape = guac_vnc_cursor;
|
||||
rfb_client->appData.useRemoteCursor = TRUE;
|
||||
|
||||
/* Clipboard */
|
||||
rfb_client->GotXCutText = guac_vnc_cut_text;
|
||||
|
||||
/* Password */
|
||||
rfb_client->GetPassword = guac_vnc_get_password;
|
||||
|
||||
@@ -297,6 +320,7 @@ void vnc_guac_client_init(guac_client* client, const char* hostname, int port) {
|
||||
client->handle_messages = vnc_guac_client_handle_messages;
|
||||
client->mouse_handler = vnc_guac_client_mouse_handler;
|
||||
client->key_handler = vnc_guac_client_key_handler;
|
||||
client->clipboard_handler = vnc_guac_client_clipboard_handler;
|
||||
|
||||
/* Send name */
|
||||
guac_send_name(client->io, rfb_client->desktopName);
|
||||
|
Reference in New Issue
Block a user