From 95923b2752d9b1f453aaf5b1e1cc34d64acf422a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 29 Mar 2013 01:56:27 -0700 Subject: [PATCH] Add terminal character buffer, update buffer with each operation. --- protocols/ssh/include/terminal.h | 68 ++++++++++++++++++++++++ protocols/ssh/src/terminal.c | 90 ++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/protocols/ssh/include/terminal.h b/protocols/ssh/include/terminal.h index 3b33507c..e7542383 100644 --- a/protocols/ssh/include/terminal.h +++ b/protocols/ssh/include/terminal.h @@ -207,6 +207,28 @@ typedef struct guac_terminal_delta { } guac_terminal_delta; +/** + * Dynamically-resizable character buffer. + */ +typedef struct guac_terminal_buffer { + + /** + * Array of characters. + */ + guac_terminal_char* characters; + + /** + * The width of this buffer in characters. + */ + int width; + + /** + * The height of this buffer in characters. + */ + int height; + +} guac_terminal_buffer; + /** * Represents a terminal emulator which uses a given Guacamole client to * render itself. @@ -329,6 +351,13 @@ struct guac_terminal { */ guac_terminal_delta* delta; + /** + * Current terminal display state. All characters present on the screen + * are within this buffer. This has nothing to do with the delta, which + * facilitates transfer of a set of changes to the remote display. + */ + guac_terminal_buffer* buffer; + }; /** @@ -438,5 +467,44 @@ void guac_terminal_delta_flush(guac_terminal_delta* delta, */ int guac_terminal_redraw_cursor(guac_terminal* term); +/** + * Allocates a new character buffer having the given dimensions. + */ +guac_terminal_buffer* guac_terminal_buffer_alloc(int width, int height); + +/** + * Resizes the given character buffer to the given dimensions. + */ +void guac_terminal_buffer_resize(guac_terminal_buffer* buffer, + int width, int height); + +/** + * Sets the character at the given location within the buffer to the given + * value. + */ +void guac_terminal_buffer_set(guac_terminal_buffer* buffer, int r, int c, + guac_terminal_char* character); + +/** + * Copies a rectangle of character data within the buffer. The source and + * destination may overlap. + */ +void guac_terminal_buffer_copy(guac_terminal_buffer* buffer, + int dst_row, int dst_column, + int src_row, int src_column, + int w, int h); + +/** + * Sets a rectangle of character data to the given character value. + */ +void guac_terminal_buffer_set_rect(guac_terminal_buffer* buffer, + int row, int column, int w, int h, + guac_terminal_char* character); + +/** + * Frees the given character buffer. + */ +void guac_terminal_buffer_free(guac_terminal_buffer* buffer); + #endif diff --git a/protocols/ssh/src/terminal.c b/protocols/ssh/src/terminal.c index 91fe2353..bbcd683d 100644 --- a/protocols/ssh/src/terminal.c +++ b/protocols/ssh/src/terminal.c @@ -168,6 +168,10 @@ guac_terminal* guac_terminal_create(guac_client* client, term->delta = guac_terminal_delta_alloc(term->term_width, term->term_height); + /* Init buffer */ + term->buffer = guac_terminal_buffer_alloc(term->term_width, + term->term_height); + /* Clear with background color */ guac_terminal_clear(term, 0, 0, term->term_height, term->term_width, @@ -188,6 +192,9 @@ void guac_terminal_free(guac_terminal* term) { /* Free delta */ guac_terminal_delta_free(term->delta); + /* Free buffer */ + guac_terminal_buffer_free(term->buffer); + } /** @@ -380,6 +387,10 @@ int guac_terminal_set(guac_terminal* term, int row, int col, char c) { /* Set delta */ guac_terminal_delta_set(term->delta, row, col, &guac_char); + + /* Set buffer */ + guac_terminal_buffer_set(term->buffer, row, col, &guac_char); + return 0; } @@ -405,6 +416,12 @@ int guac_terminal_copy(guac_terminal* term, src_row, src_col, cols, rows); + /* Update buffer */ + guac_terminal_buffer_copy(term->buffer, + dst_row, dst_col, + src_row, src_col, + cols, rows); + return 0; } @@ -423,6 +440,9 @@ int guac_terminal_clear(guac_terminal* term, guac_terminal_delta_set_rect(term->delta, row, col, cols, rows, &character); + guac_terminal_buffer_set_rect(term->buffer, + row, col, cols, rows, &character); + return 0; } @@ -981,3 +1001,73 @@ int guac_terminal_redraw_cursor(guac_terminal* term) { 1); } + +guac_terminal_buffer* guac_terminal_buffer_alloc(int width, int height) { + + /* Allocate buffer */ + guac_terminal_buffer* buffer = malloc(sizeof(guac_terminal_buffer)); + + /* Set width and height */ + buffer->width = width; + buffer->height = height; + + /* Alloc characters */ + buffer->characters = malloc(width * height * + sizeof(guac_terminal_char)); + + return buffer; + +} + +void guac_terminal_buffer_resize(guac_terminal_buffer* buffer, + int width, int height) { + /* STUB */ +} + +void guac_terminal_buffer_free(guac_terminal_buffer* buffer) { + + /* Free characters */ + free(buffer->characters); + + /* Free buffer*/ + free(buffer); + +} + +void guac_terminal_buffer_set(guac_terminal_buffer* buffer, int r, int c, + guac_terminal_char* character) { + + /* Store character */ + buffer->characters[r * buffer->width + c] = *character; + +} + +void guac_terminal_buffer_copy(guac_terminal_buffer* buffer, + int dst_row, int dst_column, + int src_row, int src_column, + int w, int h) { + /* STUB */ +} + +void guac_terminal_buffer_set_rect(guac_terminal_buffer* buffer, + int row, int column, int w, int h, + guac_terminal_char* character) { + + guac_terminal_char* current_row = + &(buffer->characters[row*buffer->width + column]); + + /* Set rectangle contents to given character */ + for (row=0; rowwidth; + + } + +} +