Add terminal character buffer, update buffer with each operation.

This commit is contained in:
Michael Jumper 2013-03-29 01:56:27 -07:00
parent 38794ed94b
commit 95923b2752
2 changed files with 158 additions and 0 deletions

View File

@ -207,6 +207,28 @@ typedef struct guac_terminal_delta {
} 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 * Represents a terminal emulator which uses a given Guacamole client to
* render itself. * render itself.
@ -329,6 +351,13 @@ struct guac_terminal {
*/ */
guac_terminal_delta* delta; 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); 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 #endif

View File

@ -168,6 +168,10 @@ guac_terminal* guac_terminal_create(guac_client* client,
term->delta = guac_terminal_delta_alloc(term->term_width, term->delta = guac_terminal_delta_alloc(term->term_width,
term->term_height); term->term_height);
/* Init buffer */
term->buffer = guac_terminal_buffer_alloc(term->term_width,
term->term_height);
/* Clear with background color */ /* Clear with background color */
guac_terminal_clear(term, guac_terminal_clear(term,
0, 0, term->term_height, term->term_width, 0, 0, term->term_height, term->term_width,
@ -188,6 +192,9 @@ void guac_terminal_free(guac_terminal* term) {
/* Free delta */ /* Free delta */
guac_terminal_delta_free(term->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 */ /* Set delta */
guac_terminal_delta_set(term->delta, row, col, &guac_char); guac_terminal_delta_set(term->delta, row, col, &guac_char);
/* Set buffer */
guac_terminal_buffer_set(term->buffer, row, col, &guac_char);
return 0; return 0;
} }
@ -405,6 +416,12 @@ int guac_terminal_copy(guac_terminal* term,
src_row, src_col, src_row, src_col,
cols, rows); cols, rows);
/* Update buffer */
guac_terminal_buffer_copy(term->buffer,
dst_row, dst_col,
src_row, src_col,
cols, rows);
return 0; return 0;
} }
@ -423,6 +440,9 @@ int guac_terminal_clear(guac_terminal* term,
guac_terminal_delta_set_rect(term->delta, guac_terminal_delta_set_rect(term->delta,
row, col, cols, rows, &character); row, col, cols, rows, &character);
guac_terminal_buffer_set_rect(term->buffer,
row, col, cols, rows, &character);
return 0; return 0;
} }
@ -981,3 +1001,73 @@ int guac_terminal_redraw_cursor(guac_terminal* term) {
1); 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; row<h; row++) {
/* Copy character throughout row */
guac_terminal_char* current = current_row;
for (column=0; column<w; column++)
*(current++) = *character;
/* Next row */
current_row += buffer->width;
}
}