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 {
|
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 {
|
public void disconnect() throws GuacamoleException {
|
||||||
|
@@ -29,7 +29,7 @@ public abstract class Instruction {
|
|||||||
@Override
|
@Override
|
||||||
public abstract String toString();
|
public abstract String toString();
|
||||||
|
|
||||||
public String escape(String str) {
|
public static String escape(String str) {
|
||||||
|
|
||||||
StringBuffer sb = new StringBuffer();
|
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);
|
} while ((retval = guac_read_instruction(io, &instruction)) > 0);
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
|
@@ -32,6 +32,7 @@ typedef struct guac_client {
|
|||||||
void (*handle_messages)(struct guac_client* client);
|
void (*handle_messages)(struct guac_client* client);
|
||||||
void (*mouse_handler)(struct guac_client* client, int x, int y, int button_mask);
|
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 (*key_handler)(struct guac_client* client, int keysym, int pressed);
|
||||||
|
void (*clipboard_handler)(struct guac_client* client, char* copied);
|
||||||
void (*free_handler)(void* client);
|
void (*free_handler)(void* client);
|
||||||
|
|
||||||
} guac_client;
|
} guac_client;
|
||||||
|
@@ -81,16 +81,65 @@ char* guac_escape_string(const char* str) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*current = '\0';
|
||||||
|
|
||||||
return escaped;
|
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) {
|
void guac_send_name(GUACIO* io, const char* name) {
|
||||||
|
|
||||||
char* escaped = guac_escape_string(name);
|
char* escaped = guac_escape_string(name);
|
||||||
|
|
||||||
guac_write_string(io, "name:");
|
guac_write_string(io, "name:");
|
||||||
guac_write_string(io, name);
|
guac_write_string(io, escaped);
|
||||||
guac_write_string(io, ";");
|
guac_write_string(io, ";");
|
||||||
|
|
||||||
free(escaped);
|
free(escaped);
|
||||||
@@ -105,6 +154,30 @@ void guac_send_size(GUACIO* io, int w, int h) {
|
|||||||
guac_write_string(io, ";");
|
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) {
|
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_string(io, "copy:");
|
||||||
guac_write_int(io, srcx);
|
guac_write_int(io, srcx);
|
||||||
|
@@ -36,7 +36,10 @@ typedef struct guac_instruction {
|
|||||||
|
|
||||||
void guac_free_instruction(guac_instruction* instruction);
|
void guac_free_instruction(guac_instruction* instruction);
|
||||||
char* guac_escape_string(const char* str);
|
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_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_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_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);
|
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";
|
static char* __GUAC_CLIENT = "GUAC_CLIENT";
|
||||||
|
|
||||||
typedef struct vnc_guac_client_data {
|
typedef struct vnc_guac_client_data {
|
||||||
|
|
||||||
rfbClient* rfb_client;
|
rfbClient* rfb_client;
|
||||||
png_byte** png_buffer;
|
png_byte** png_buffer;
|
||||||
png_byte** png_buffer_alpha;
|
png_byte** png_buffer_alpha;
|
||||||
int copy_rect_used;
|
int copy_rect_used;
|
||||||
|
|
||||||
} vnc_guac_client_data;
|
} vnc_guac_client_data;
|
||||||
|
|
||||||
void guac_vnc_cursor(rfbClient* client, int x, int y, int w, int h, int bpp) {
|
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) {
|
void vnc_guac_client_handle_messages(guac_client* client) {
|
||||||
|
|
||||||
int wait_result;
|
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) {
|
void vnc_guac_client_free_handler(guac_client* client) {
|
||||||
|
|
||||||
rfbClient* rfb_client = ((vnc_guac_client_data*) client->data)->rfb_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->GotCursorShape = guac_vnc_cursor;
|
||||||
rfb_client->appData.useRemoteCursor = TRUE;
|
rfb_client->appData.useRemoteCursor = TRUE;
|
||||||
|
|
||||||
|
/* Clipboard */
|
||||||
|
rfb_client->GotXCutText = guac_vnc_cut_text;
|
||||||
|
|
||||||
/* Password */
|
/* Password */
|
||||||
rfb_client->GetPassword = guac_vnc_get_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->handle_messages = vnc_guac_client_handle_messages;
|
||||||
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;
|
||||||
|
|
||||||
/* Send name */
|
/* Send name */
|
||||||
guac_send_name(client->io, rfb_client->desktopName);
|
guac_send_name(client->io, rfb_client->desktopName);
|
||||||
|
Reference in New Issue
Block a user