mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
Converting to double-I/O switching and new transfer instruction
This commit is contained in:
@@ -273,7 +273,7 @@ function VNCClient(display) {
|
|||||||
|
|
||||||
// Start next request as soon as possible
|
// Start next request as soon as possible
|
||||||
if (xmlhttprequest.readyState >= 2 && nextRequest == null && uuid)
|
if (xmlhttprequest.readyState >= 2 && nextRequest == null && uuid)
|
||||||
nextRequest = makeRequest("resume:" + uuid + ";yield;");
|
nextRequest = makeRequest("transfer:out," + uuid + ";");
|
||||||
|
|
||||||
// Parse stream when data is received and when complete.
|
// Parse stream when data is received and when complete.
|
||||||
if (xmlhttprequest.readyState == 3 ||
|
if (xmlhttprequest.readyState == 3 ||
|
||||||
|
@@ -62,7 +62,8 @@ struct guac_client {
|
|||||||
* their own mechanism of I/O for their protocol. The GUACIO structure is
|
* their own mechanism of I/O for their protocol. The GUACIO structure is
|
||||||
* used only to communicate conveniently with the Guacamole web-client.
|
* used only to communicate conveniently with the Guacamole web-client.
|
||||||
*/
|
*/
|
||||||
GUACIO* io;
|
GUACIO* io_in;
|
||||||
|
GUACIO* io_out;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Semaphore which will be locked while I/O is owned.
|
* Semaphore which will be locked while I/O is owned.
|
||||||
|
@@ -56,12 +56,16 @@ void guac_free_png_buffer(png_byte** png_buffer, int h) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __guac_set_client_io(guac_client* client, GUACIO* io) {
|
void __guac_set_client_io_out(guac_client* client, GUACIO* io) {
|
||||||
sem_wait(&(client->io_lock)); /* Acquire I/O */
|
client->io_out = io;
|
||||||
client->io = io;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __guac_release_client_io(guac_client* client) {
|
void __guac_set_client_io_in(guac_client* client, GUACIO* io) {
|
||||||
|
sem_wait(&(client->io_lock)); /* Acquire I/O */
|
||||||
|
client->io_in = io;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __guac_release_client_io_in(guac_client* client) {
|
||||||
sem_post(&(client->io_lock));
|
sem_post(&(client->io_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +76,7 @@ guac_client* __guac_alloc_client(GUACIO* io) {
|
|||||||
memset(client, 0, sizeof(guac_client));
|
memset(client, 0, sizeof(guac_client));
|
||||||
|
|
||||||
/* Init new client */
|
/* Init new client */
|
||||||
client->io = io;
|
client->io_in = client->io_out = io;
|
||||||
uuid_generate(client->uuid);
|
uuid_generate(client->uuid);
|
||||||
sem_init(&(client->io_lock), 0, 0); /* I/O starts locked */
|
sem_init(&(client->io_lock), 0, 0); /* I/O starts locked */
|
||||||
|
|
||||||
@@ -114,7 +118,7 @@ guac_client* guac_get_client(int client_fd, guac_client_registry* registry, guac
|
|||||||
|
|
||||||
/* Send UUID to web-client */
|
/* Send UUID to web-client */
|
||||||
guac_send_uuid(io, client->uuid);
|
guac_send_uuid(io, client->uuid);
|
||||||
guac_flush(client->io);
|
guac_flush(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_init(client, argc, scratch_argv) != 0)
|
if (client_init(client, argc, scratch_argv) != 0)
|
||||||
@@ -124,17 +128,28 @@ guac_client* guac_get_client(int client_fd, guac_client_registry* registry, guac
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* resume -> resume existing connection (when that connection pauses) */
|
/* resume -> resume existing connection (when that connection pauses) */
|
||||||
if (strcmp(instruction.opcode, "resume") == 0) {
|
if (strcmp(instruction.opcode, "transfer") == 0) {
|
||||||
|
|
||||||
if (registry) {
|
if (registry) {
|
||||||
|
|
||||||
client = guac_find_client(
|
client = guac_find_client(
|
||||||
registry,
|
registry,
|
||||||
(unsigned char*) guac_decode_base64_inplace(instruction.argv[0])
|
(unsigned char*) guac_decode_base64_inplace(instruction.argv[1])
|
||||||
);
|
);
|
||||||
|
|
||||||
if (client) {
|
if (client) {
|
||||||
__guac_set_client_io(client, io);
|
|
||||||
|
if (strcmp(instruction.argv[0], "in") == 0)
|
||||||
|
__guac_set_client_io_in(client, io);
|
||||||
|
|
||||||
|
else if (strcmp(instruction.argv[0], "out") == 0)
|
||||||
|
__guac_set_client_io_out(client, io);
|
||||||
|
|
||||||
|
else if (strcmp(instruction.argv[0], "both") == 0) {
|
||||||
|
__guac_set_client_io_in(client, io);
|
||||||
|
__guac_set_client_io_out(client, io);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL; /* Returning NULL, so old client loop is used */
|
return NULL; /* Returning NULL, so old client loop is used */
|
||||||
/* FIXME: Fix semantics of returning NULL vs ptr. This function needs redocumentation, and callers
|
/* FIXME: Fix semantics of returning NULL vs ptr. This function needs redocumentation, and callers
|
||||||
* need to lose their "error" handling. */
|
* need to lose their "error" handling. */
|
||||||
@@ -173,7 +188,9 @@ void guac_free_client(guac_client* client, guac_client_registry* registry) {
|
|||||||
syslog(LOG_ERR, "Error calling client free handler");
|
syslog(LOG_ERR, "Error calling client free handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
guac_close(client->io);
|
if (client->io_in != client->io_out)
|
||||||
|
guac_close(client->io_in);
|
||||||
|
guac_close(client->io_out);
|
||||||
|
|
||||||
guac_remove_client(registry, client->uuid);
|
guac_remove_client(registry, client->uuid);
|
||||||
|
|
||||||
@@ -196,9 +213,20 @@ void guac_start_client(guac_client* client) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
/* Accept changes to client I/O only before handling messages */
|
/* Accept changes to client I/O only before handling messages */
|
||||||
if (client_copy.io != client->io) {
|
if (client_copy.io_in != client->io_in) {
|
||||||
guac_close_final(client_copy.io); /* Close old I/O and fd */
|
/* Close and free previous I/O if unused */
|
||||||
client_copy.io = client->io;
|
if (client_copy.io_in != client_copy.io_out
|
||||||
|
&& client_copy.io_in != client->io_out)
|
||||||
|
guac_close_final(client_copy.io_in);
|
||||||
|
client_copy.io_in = client->io_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_copy.io_out != client->io_out) {
|
||||||
|
/* Close and free previous I/O if unused */
|
||||||
|
if (client_copy.io_out != client_copy.io_in
|
||||||
|
&& client_copy.io_out != client->io_in)
|
||||||
|
guac_close_final(client_copy.io_out);
|
||||||
|
client_copy.io_out = client->io_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle server messages */
|
/* Handle server messages */
|
||||||
@@ -210,14 +238,14 @@ void guac_start_client(guac_client* client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
guac_flush(client_copy.io);
|
guac_flush(client_copy.io_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_result = guac_instructions_waiting(client_copy.io);
|
wait_result = guac_instructions_waiting(client_copy.io_in);
|
||||||
if (wait_result > 0) {
|
if (wait_result > 0) {
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
retval = guac_read_instruction(client_copy.io, &instruction); /* 0 if no instructions finished yet, <0 if error or EOF */
|
retval = guac_read_instruction(client_copy.io_in, &instruction); /* 0 if no instructions finished yet, <0 if error or EOF */
|
||||||
|
|
||||||
if (retval > 0) {
|
if (retval > 0) {
|
||||||
|
|
||||||
@@ -274,7 +302,7 @@ void guac_start_client(guac_client* client) {
|
|||||||
else if (strcmp(instruction.opcode, "yield") == 0) {
|
else if (strcmp(instruction.opcode, "yield") == 0) {
|
||||||
|
|
||||||
/* Allow other connection to take over I/O */
|
/* Allow other connection to take over I/O */
|
||||||
__guac_release_client_io(client);
|
__guac_release_client_io_in(client);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +311,7 @@ void guac_start_client(guac_client* client) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while ((retval = guac_read_instruction(client_copy.io, &instruction)) > 0);
|
} while ((retval = guac_read_instruction(client_copy.io_in, &instruction)) > 0);
|
||||||
|
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
syslog(LOG_ERR, "Error reading instruction from stream");
|
syslog(LOG_ERR, "Error reading instruction from stream");
|
||||||
|
@@ -49,7 +49,7 @@ void guac_vnc_cursor(rfbClient* client, int x, int y, int w, int h, int bpp) {
|
|||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
|
||||||
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
||||||
GUACIO* io = gc->io;
|
GUACIO* io = gc->io_out;
|
||||||
png_byte** png_buffer = ((vnc_guac_client_data*) gc->data)->png_buffer_alpha;
|
png_byte** png_buffer = ((vnc_guac_client_data*) gc->data)->png_buffer_alpha;
|
||||||
png_byte* row;
|
png_byte* row;
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ void guac_vnc_update(rfbClient* client, int x, int y, int w, int h) {
|
|||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
|
||||||
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
||||||
GUACIO* io = gc->io;
|
GUACIO* io = gc->io_out;
|
||||||
png_byte** png_buffer = ((vnc_guac_client_data*) gc->data)->png_buffer;
|
png_byte** png_buffer = ((vnc_guac_client_data*) gc->data)->png_buffer;
|
||||||
png_byte* row;
|
png_byte* row;
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ void guac_vnc_update(rfbClient* client, int x, int y, int w, int h) {
|
|||||||
void guac_vnc_copyrect(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
|
void guac_vnc_copyrect(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
|
||||||
|
|
||||||
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
||||||
GUACIO* io = gc->io;
|
GUACIO* io = gc->io_out;
|
||||||
|
|
||||||
guac_send_copy(io, src_x, src_y, w, h, dest_x, dest_y);
|
guac_send_copy(io, src_x, src_y, w, h, dest_x, dest_y);
|
||||||
((vnc_guac_client_data*) gc->data)->copy_rect_used = 1;
|
((vnc_guac_client_data*) gc->data)->copy_rect_used = 1;
|
||||||
@@ -187,7 +187,7 @@ char* guac_vnc_get_password(rfbClient* client) {
|
|||||||
void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) {
|
void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) {
|
||||||
|
|
||||||
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
guac_client* gc = rfbClientGetClientData(client, __GUAC_CLIENT);
|
||||||
GUACIO* io = gc->io;
|
GUACIO* io = gc->io_out;
|
||||||
|
|
||||||
guac_send_clipboard(io, text);
|
guac_send_clipboard(io, text);
|
||||||
|
|
||||||
@@ -335,10 +335,10 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
client->clipboard_handler = vnc_guac_client_clipboard_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_out, rfb_client->desktopName);
|
||||||
|
|
||||||
/* Send size */
|
/* Send size */
|
||||||
guac_send_size(client->io, rfb_client->width, rfb_client->height);
|
guac_send_size(client->io_out, rfb_client->width, rfb_client->height);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user