GUAC-653: Implement render_frame function.

This commit is contained in:
Michael Jumper 2014-05-06 16:12:29 -07:00
parent 81229d9fe4
commit 470dc67c34
3 changed files with 107 additions and 69 deletions

View File

@ -23,10 +23,8 @@
#include "config.h" #include "config.h"
#include "client.h" #include "client.h"
#include "clipboard.h"
#include "common.h"
#include "cursor.h"
#include "guac_handlers.h" #include "guac_handlers.h"
#include "terminal.h"
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
@ -44,56 +42,7 @@
int ssh_guac_client_handle_messages(guac_client* client) { int ssh_guac_client_handle_messages(guac_client* client) {
ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data;
char buffer[8192]; return guac_terminal_render_frame(client_data->term);
int ret_val;
int fd = client_data->term->stdout_pipe_fd[0];
struct timeval timeout;
fd_set fds;
/* Build fd_set */
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Time to wait */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* Wait for data to be available */
ret_val = select(fd+1, &fds, NULL, NULL, &timeout);
if (ret_val > 0) {
int bytes_read = 0;
guac_terminal_lock(client_data->term);
/* Read data, write to terminal */
if ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) {
if (guac_terminal_write(client_data->term, buffer, bytes_read)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error writing data");
return 1;
}
}
/* Notify on error */
if (bytes_read < 0) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error reading data");
return 1;
}
/* Flush terminal */
guac_terminal_flush(client_data->term);
guac_terminal_unlock(client_data->term);
}
else if (ret_val < 0) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error waiting for data");
return 1;
}
return 0;
} }
@ -103,10 +52,7 @@ int ssh_guac_client_mouse_handler(guac_client* client, int x, int y, int mask) {
guac_terminal* term = client_data->term; guac_terminal* term = client_data->term;
/* Send mouse event */ /* Send mouse event */
guac_terminal_lock(term);
guac_terminal_send_mouse(term, x, y, mask); guac_terminal_send_mouse(term, x, y, mask);
guac_terminal_unlock(term);
return 0; return 0;
} }
@ -117,10 +63,7 @@ int ssh_guac_client_key_handler(guac_client* client, int keysym, int pressed) {
guac_terminal* term = client_data->term; guac_terminal* term = client_data->term;
/* Send key */ /* Send key */
guac_terminal_lock(term);
guac_terminal_send_key(term, keysym, pressed); guac_terminal_send_key(term, keysym, pressed);
guac_terminal_unlock(term);
return 0; return 0;
} }
@ -132,9 +75,7 @@ int ssh_guac_client_size_handler(guac_client* client, int width, int height) {
guac_terminal* terminal = guac_client_data->term; guac_terminal* terminal = guac_client_data->term;
/* Resize terminal */ /* Resize terminal */
guac_terminal_lock(terminal);
guac_terminal_resize(terminal, width, height); guac_terminal_resize(terminal, width, height);
guac_terminal_unlock(terminal);
/* Update SSH pty size if connected */ /* Update SSH pty size if connected */
if (guac_client_data->term_channel != NULL) if (guac_client_data->term_channel != NULL)

View File

@ -37,6 +37,8 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/select.h>
#include <unistd.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <guacamole/client.h> #include <guacamole/client.h>
@ -193,6 +195,66 @@ void guac_terminal_free(guac_terminal* term) {
} }
int guac_terminal_render_frame(guac_terminal* terminal) {
guac_client* client = terminal->client;
char buffer[8192];
int ret_val;
int fd = terminal->stdout_pipe_fd[0];
struct timeval timeout;
fd_set fds;
/* Build fd_set */
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Time to wait */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* Wait for data to be available */
ret_val = select(fd+1, &fds, NULL, NULL, &timeout);
if (ret_val > 0) {
int bytes_read = 0;
guac_terminal_lock(terminal);
/* Read data, write to terminal */
if ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) {
if (guac_terminal_write(terminal, buffer, bytes_read)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error writing data");
return 1;
}
}
/* Notify on error */
if (bytes_read < 0) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error reading data");
return 1;
}
/* Flush terminal */
guac_terminal_flush(terminal);
guac_terminal_unlock(terminal);
}
else if (ret_val < 0) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Error waiting for data");
return 1;
}
return 0;
}
int guac_terminal_read_input(guac_terminal* terminal, char* c, int size) {
return 0;
}
int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint) { int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint) {
/* Build character with current attributes */ /* Build character with current attributes */
@ -838,7 +900,7 @@ int guac_terminal_send_string(guac_terminal* term, const char* data) {
return guac_terminal_write_all(term->stdin_pipe_fd[1], data, strlen(data)); return guac_terminal_write_all(term->stdin_pipe_fd[1], data, strlen(data));
} }
int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) { static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) {
/* Hide mouse cursor if not already hidden */ /* Hide mouse cursor if not already hidden */
if (term->current_cursor != term->blank_cursor) { if (term->current_cursor != term->blank_cursor) {
@ -970,10 +1032,21 @@ int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) {
return 0; return 0;
}
int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) {
int result;
guac_terminal_lock(term);
result = __guac_terminal_send_key(term, keysym, pressed);
guac_terminal_unlock(term);
return result;
} }
int guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) { static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) {
/* Determine which buttons were just released and pressed */ /* Determine which buttons were just released and pressed */
int released_mask = term->mouse_mask & ~mask; int released_mask = term->mouse_mask & ~mask;
@ -1043,7 +1116,17 @@ int guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) {
return 0; return 0;
}
int guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) {
int result;
guac_terminal_lock(term);
result = __guac_terminal_send_mouse(term, x, y, mask);
guac_terminal_unlock(term);
return result;
} }

View File

@ -304,16 +304,18 @@ guac_terminal* guac_terminal_create(guac_client* client,
void guac_terminal_free(guac_terminal* term); void guac_terminal_free(guac_terminal* term);
/** /**
* Acquires exclusive access to the terminal. Note that enforcing this * Renders a single frame of terminal data. If data is not yet available,
* exclusive access requires that ALL users of the terminal call this * this function will block until data is written.
* function before making further calls to the terminal.
*/ */
void guac_terminal_lock(guac_terminal* terminal); int guac_terminal_render_frame(guac_terminal* terminal);
/** /**
* Releases exclusive access to the terminal. * Reads from this terminal's STDIN. Input comes from key and mouse events
* supplied by calls to guac_terminal_send_key() and
* guac_terminal_send_mouse(). If input is not yet available, this function
* will block.
*/ */
void guac_terminal_unlock(guac_terminal* terminal); int guac_terminal_read_input(guac_terminal* terminal, char* c, int size);
/** /**
* Handles the given key event, sending data, scrolling, pasting clipboard * Handles the given key event, sending data, scrolling, pasting clipboard
@ -342,6 +344,18 @@ void guac_terminal_clipboard_append(guac_terminal* term, const void* data, int l
/* INTERNAL FUNCTIONS */ /* INTERNAL FUNCTIONS */
/**
* Acquires exclusive access to the terminal. Note that enforcing this
* exclusive access requires that ALL users of the terminal call this
* function before making further calls to the terminal.
*/
void guac_terminal_lock(guac_terminal* terminal);
/**
* Releases exclusive access to the terminal.
*/
void guac_terminal_unlock(guac_terminal* terminal);
/** /**
* Resets the state of the given terminal, as if it were just allocated. * Resets the state of the given terminal, as if it were just allocated.
*/ */