From b64aaa72ee263ee00a055eb1fc20598a6b8f82d5 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 26 Apr 2013 02:29:30 -0700 Subject: [PATCH] Partial restoration of display functionality. Modify get_row to expand row as necessary. --- protocols/ssh/include/buffer.h | 21 +++++++------ protocols/ssh/src/buffer.c | 57 +++++++++++++++++++++------------- protocols/ssh/src/display.c | 20 +++++++++--- protocols/ssh/src/terminal.c | 21 +++++++------ 4 files changed, 74 insertions(+), 45 deletions(-) diff --git a/protocols/ssh/include/buffer.h b/protocols/ssh/include/buffer.h index 83c05cce..eb9edb48 100644 --- a/protocols/ssh/include/buffer.h +++ b/protocols/ssh/include/buffer.h @@ -72,6 +72,11 @@ typedef struct guac_terminal_buffer_row { */ typedef struct guac_terminal_buffer { + /** + * The character to assign to newly-allocated cells. + */ + guac_terminal_char default_character; + /** * Array of buffer rows. This array functions as a ring buffer. * When a new row needs to be appended, the top reference is moved down @@ -98,9 +103,10 @@ typedef struct guac_terminal_buffer { } guac_terminal_buffer; /** - * Allocates a new buffer having the given maximum number of rows. + * Allocates a new buffer having the given maximum number of rows. New character cells will + * be initialized to the given character. */ -guac_terminal_buffer* guac_terminal_buffer_alloc(int rows); +guac_terminal_buffer* guac_terminal_buffer_alloc(int rows, guac_terminal_char* default_character); /** * Frees the given buffer. @@ -108,15 +114,10 @@ guac_terminal_buffer* guac_terminal_buffer_alloc(int rows); void guac_terminal_buffer_free(guac_terminal_buffer* buffer); /** - * Returns the row at the given location. + * Returns the row at the given location. The row returned is guaranteed to be at least the given + * width. */ -guac_terminal_buffer_row* guac_terminal_buffer_get_row(guac_terminal_buffer* buffer, int row); - -/** - * Ensures the given row has at least the given number of character spaces available. If new characters - * must be added, they are initialized with the given fill character. - */ -void guac_terminal_buffer_prepare_row(guac_terminal_buffer_row* row, int width, guac_terminal_char* fill); +guac_terminal_buffer_row* guac_terminal_buffer_get_row(guac_terminal_buffer* buffer, int row, int width); /** * Copies the given range of columns to a new location, offset from diff --git a/protocols/ssh/src/buffer.c b/protocols/ssh/src/buffer.c index bfc3951c..bf4d4246 100644 --- a/protocols/ssh/src/buffer.c +++ b/protocols/ssh/src/buffer.c @@ -39,7 +39,7 @@ #include "buffer.h" -guac_terminal_buffer* guac_terminal_buffer_alloc(int rows) { +guac_terminal_buffer* guac_terminal_buffer_alloc(int rows, guac_terminal_char* default_character) { /* Allocate scrollback */ guac_terminal_buffer* buffer = @@ -49,6 +49,7 @@ guac_terminal_buffer* guac_terminal_buffer_alloc(int rows) { guac_terminal_buffer_row* row; /* Init scrollback data */ + buffer->default_character = *default_character; buffer->available = rows; buffer->top = 0; buffer->length = 0; @@ -90,38 +91,39 @@ void guac_terminal_buffer_free(guac_terminal_buffer* buffer) { } -guac_terminal_buffer_row* guac_terminal_buffer_get_row(guac_terminal_buffer* buffer, int row) { +guac_terminal_buffer_row* guac_terminal_buffer_get_row(guac_terminal_buffer* buffer, int row, int width) { + + int i; + guac_terminal_char* first; + guac_terminal_buffer_row* buffer_row; /* Calculate scrollback row index */ int index = buffer->top + row; if (index < 0) index += buffer->available; - /* Return found row */ - return &(buffer->rows[index]); + /* Get row */ + buffer_row = &(buffer->rows[index]); -} + /* If resizing is needed */ + if (width >= buffer_row->length) { -void guac_terminal_buffer_prepare_row(guac_terminal_buffer_row* row, int width, guac_terminal_char* fill) { + /* Expand if necessary */ + if (width > buffer_row->available) { + buffer_row->available = width*2; + buffer_row->characters = realloc(buffer_row->characters, sizeof(guac_terminal_char) * buffer_row->available); + } - int i; - guac_terminal_char* first; + /* Initialize new part of row */ + first = &(buffer_row->characters[buffer_row->length]); + for (i=buffer_row->length; idefault_character; - /* If already wide enough, nothing to do. */ - if (width < row->length) - return; + buffer_row->length = width; - /* Expand if necessary */ - if (width > row->available) { - row->available = width*2; - row->characters = realloc(row->characters, sizeof(guac_terminal_char) * row->available); } - /* Initialize new part of row */ - first = &(row->characters[row->length]); - for (i=row->length; ilength = width; + /* Return found row */ + return buffer_row; } @@ -137,6 +139,17 @@ void guac_terminal_buffer_copy_rows(guac_terminal_buffer* buffer, void guac_terminal_buffer_set_columns(guac_terminal_buffer* buffer, int row, int start_column, int end_column, guac_terminal_char* character) { - /* STUB */ + + int i; + guac_terminal_char* current; + + /* Get and expand row */ + guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(buffer, row, end_column+1); + + /* Set values */ + current = &(buffer_row->characters[start_column]); + for (i=start_column; i<=end_column; i++) + *(current++) = *character; + } diff --git a/protocols/ssh/src/display.c b/protocols/ssh/src/display.c index 91561b90..e2028083 100644 --- a/protocols/ssh/src/display.c +++ b/protocols/ssh/src/display.c @@ -359,10 +359,22 @@ void guac_terminal_display_copy_rows(guac_terminal_display* display, void guac_terminal_display_set_columns(guac_terminal_display* display, int row, int start_column, int end_column, guac_terminal_char* character) { - /* STUB */ - guac_client_log_info(display->client, - "display_set_columns: row=%i, start=%i, end=%i, char='%c'", - row, start_column, end_column, character->value); + + int i; + guac_terminal_operation* current = + &(display->operations[row * display->width + start_column]); + + /* For each column in range */ + for (i=start_column; i<=end_column; i++) { + + /* Set operation */ + current->type = GUAC_CHAR_SET; + current->character = *character; + + /* Next column */ + current++; + } + } void guac_terminal_display_resize(guac_terminal_display* display, int rows, int cols) { diff --git a/protocols/ssh/src/terminal.c b/protocols/ssh/src/terminal.c index 0ce482ef..641b85a0 100644 --- a/protocols/ssh/src/terminal.c +++ b/protocols/ssh/src/terminal.c @@ -70,12 +70,12 @@ guac_terminal* guac_terminal_create(guac_client* client, term->client = client; /* Init buffer */ - term->buffer = guac_terminal_buffer_alloc(1000); + term->buffer = guac_terminal_buffer_alloc(1000, &default_char); term->scroll_offset = 0; /* Init display */ term->display = guac_terminal_display_alloc(client, - term->term_width, term->term_height, + 80, 24, /*term->term_width, term->term_height,*/ default_char.attributes.foreground, default_char.attributes.background); @@ -131,8 +131,7 @@ int guac_terminal_toggle_reverse(guac_terminal* term, int row, int col) { int scrolled_row = row + term->scroll_offset; /* Get character from buffer */ - guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(term->buffer, row); - guac_terminal_buffer_prepare_row(buffer_row, col+1, &term->default_char); + guac_terminal_buffer_row* buffer_row = guac_terminal_buffer_get_row(term->buffer, row, col+1); /* Toggle reverse */ guac_char = &(buffer_row->characters[col]); @@ -360,7 +359,7 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal, /* Get row from scrollback */ guac_terminal_buffer_row* buffer_row = - guac_terminal_buffer_get_row(terminal->buffer, row); + guac_terminal_buffer_get_row(terminal->buffer, row, 0); /* Draw row */ /* FIXME: Clear row first */ @@ -416,7 +415,7 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal, /* Get row from scrollback */ guac_terminal_buffer_row* buffer_row = - guac_terminal_buffer_get_row(terminal->buffer, row); + guac_terminal_buffer_get_row(terminal->buffer, row, 0); /* Draw row */ /* FIXME: Clear row first */ @@ -467,8 +466,12 @@ void guac_terminal_copy_rows(guac_terminal* terminal, void guac_terminal_set_columns(guac_terminal* terminal, int row, int start_column, int end_column, guac_terminal_char* character) { /* STUB */ - guac_client_log_info(terminal->client, - "terminal_set_columns: row=%i, start=%i, end=%i, char='%c'", - row, start_column, end_column, character->value); + + guac_terminal_display_set_columns(terminal->display, row, + start_column, end_column, character); + + guac_terminal_buffer_set_columns(terminal->buffer, row, + start_column, end_column, character); + }