diff --git a/protocols/ssh/include/ssh_terminal.h b/protocols/ssh/include/ssh_terminal.h index 7c9b7f4a..0c4f83cc 100644 --- a/protocols/ssh/include/ssh_terminal.h +++ b/protocols/ssh/include/ssh_terminal.h @@ -69,10 +69,24 @@ struct ssh_guac_terminal { int cursor_row; int cursor_col; + int foreground; + int background; + + int default_foreground; + int default_background; + ssh_guac_terminal_char_handler* char_handler; }; +typedef struct ssh_guac_terminal_color { + int red; + int green; + int blue; +} ssh_guac_terminal_color; + +extern const ssh_guac_terminal_color ssh_guac_terminal_palette[16]; + ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client); void ssh_guac_terminal_free(ssh_guac_terminal* term); @@ -82,15 +96,16 @@ int ssh_guac_terminal_send_glyph(ssh_guac_terminal* term, int row, int col, char int ssh_guac_terminal_copy(ssh_guac_terminal* term, int src_row, int src_col, int rows, int cols, int dst_row, int dst_col); + int ssh_guac_terminal_clear(ssh_guac_terminal* term, - int row, int col, int rows, int cols); + int row, int col, int rows, int cols, int background_color); int ssh_guac_terminal_scroll_up(ssh_guac_terminal* term, int start_row, int end_row, int amount); int ssh_guac_terminal_clear_range(ssh_guac_terminal* term, int start_row, int start_col, - int end_row, int end_col); + int end_row, int end_col, int background_color); #endif diff --git a/protocols/ssh/src/ssh_terminal.c b/protocols/ssh/src/ssh_terminal.c index 6ed440ec..0cb506fd 100644 --- a/protocols/ssh/src/ssh_terminal.c +++ b/protocols/ssh/src/ssh_terminal.c @@ -49,6 +49,30 @@ #include "ssh_terminal.h" #include "ssh_terminal_handlers.h" +const ssh_guac_terminal_color ssh_guac_terminal_palette[16] = { + + /* Normal colors */ + {0x00, 0x00, 0x00}, /* Black */ + {0x80, 0x00, 0x00}, /* Red */ + {0x00, 0x80, 0x00}, /* Green */ + {0x80, 0x80, 0x00}, /* Brown */ + {0x00, 0x00, 0x80}, /* Blue */ + {0x80, 0x00, 0x80}, /* Magenta */ + {0x00, 0x80, 0x80}, /* Cyan */ + {0x80, 0x80, 0x80}, /* White */ + + /* Intense colors */ + {0x40, 0x40, 0x40}, /* Black */ + {0xFF, 0x00, 0x00}, /* Red */ + {0x00, 0xFF, 0x00}, /* Green */ + {0xFF, 0xFF, 0x00}, /* Brown */ + {0x00, 0x00, 0xFF}, /* Blue */ + {0xFF, 0x00, 0xFF}, /* Magenta */ + {0x00, 0xFF, 0xFF}, /* Cyan */ + {0xFF, 0xFF, 0xFF}, /* White */ + +}; + ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) { PangoFontMap* font_map; @@ -59,6 +83,9 @@ ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) { ssh_guac_terminal* term = malloc(sizeof(ssh_guac_terminal)); term->client = client; + term->foreground = term->default_foreground = 7; /* White */ + term->background = term->default_background = 0; /* Black */ + term->cursor_row = 0; term->cursor_col = 0; @@ -94,6 +121,11 @@ ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) { (pango_font_metrics_get_descent(metrics) + pango_font_metrics_get_ascent(metrics)) / PANGO_SCALE; + /* Clear with background color */ + ssh_guac_terminal_clear(term, + 0, 0, term->term_width, term->term_height, + term->background); + return term; } @@ -106,6 +138,10 @@ guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) { GUACIO* io = term->client->io; guac_layer* glyph; + + /* Use default foreground color */ + const ssh_guac_terminal_color* color = + &ssh_guac_terminal_palette[term->default_foreground]; cairo_surface_t* surface; cairo_t* cairo; @@ -128,7 +164,12 @@ guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) { pango_layout_set_text(layout, &c, 1); /* Draw */ - cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0); + cairo_set_source_rgba(cairo, + color->red / 255.0, + color->green / 255.0, + color->blue / 255.0, + 1.0 /* alpha */ ); + cairo_move_to(cairo, 0.0, 0.0); pango_cairo_show_layout(cairo, layout); @@ -193,19 +234,20 @@ int ssh_guac_terminal_copy(ssh_guac_terminal* term, int ssh_guac_terminal_clear(ssh_guac_terminal* term, - int row, int col, int rows, int cols) { + int row, int col, int rows, int cols, int background_color) { GUACIO* io = term->client->io; + const ssh_guac_terminal_color* color = + &ssh_guac_terminal_palette[background_color]; - /* Fill with background */ + /* Fill with color */ return guac_send_rect(io, GUAC_COMP_SRC, GUAC_DEFAULT_LAYER, col * term->char_width, row * term->char_height, cols * term->char_width, rows * term->char_height, - /* Background */ - 0, 0, 0, 255); + color->red, color->green, color->blue, 255); } @@ -214,7 +256,7 @@ int ssh_guac_terminal_scroll_up(ssh_guac_terminal* term, /* Calculate height of scroll region */ int height = end_row - start_row + 1; - + return /* Move rows within scroll region up by the given amount */ @@ -225,21 +267,23 @@ int ssh_guac_terminal_scroll_up(ssh_guac_terminal* term, /* Fill new rows with background */ || ssh_guac_terminal_clear(term, - end_row - amount + 1, 0, amount, term->term_width); + end_row - amount + 1, 0, amount, term->term_width, + term->background); } int ssh_guac_terminal_clear_range(ssh_guac_terminal* term, int start_row, int start_col, - int end_row, int end_col) { + int end_row, int end_col, int background_color) { /* If not at far left, must clear sub-region to far right */ if (start_col > 0) { /* Clear from start_col to far right */ if (ssh_guac_terminal_clear(term, - start_row, start_col, 1, term->term_width - start_col)) + start_row, start_col, 1, term->term_width - start_col, + background_color)) return 1; /* One less row to clear */ @@ -251,7 +295,8 @@ int ssh_guac_terminal_clear_range(ssh_guac_terminal* term, /* Clear from far left to end_col */ if (ssh_guac_terminal_clear(term, - end_row, 0, 1, end_col + 1)) + end_row, 0, 1, end_col + 1, + background_color)) return 1; /* One less row to clear */ @@ -263,7 +308,8 @@ int ssh_guac_terminal_clear_range(ssh_guac_terminal* term, if (start_row <= end_row) { if (ssh_guac_terminal_clear(term, - start_row, 0, end_row - start_row + 1, term->term_width)) + start_row, 0, end_row - start_row + 1, term->term_width, + background_color)) return 1; } diff --git a/protocols/ssh/src/ssh_terminal_handlers.c b/protocols/ssh/src/ssh_terminal_handlers.c index 3a2735c8..7dcc0e43 100644 --- a/protocols/ssh/src/ssh_terminal_handlers.c +++ b/protocols/ssh/src/ssh_terminal_handlers.c @@ -186,18 +186,21 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) { if (argv[0] == 0) ssh_guac_terminal_clear_range(term, term->cursor_row, term->cursor_col, - term->term_height-1, term->term_width-1); + term->term_height-1, term->term_width-1, + term->background); /* Erase from start to cursor */ else if (argv[0] == 1) ssh_guac_terminal_clear_range(term, 0, 0, - term->cursor_row, term->cursor_col); + term->cursor_row, term->cursor_col, + term->background); /* Entire screen */ else if (argv[0] == 2) ssh_guac_terminal_clear(term, - 0, 0, term->term_height, term->term_width); + 0, 0, term->term_height, term->term_width, + term->background); break; @@ -208,19 +211,23 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) { if (argv[0] == 0) ssh_guac_terminal_clear(term, term->cursor_row, term->cursor_col, - 1, term->term_width - term->cursor_col); + 1, term->term_width - term->cursor_col, + term->background); + /* Erase from start to cursor */ else if (argv[0] == 1) ssh_guac_terminal_clear(term, term->cursor_row, 0, - 1, term->cursor_col + 1); + 1, term->cursor_col + 1, + term->background); /* Erase line */ else if (argv[0] == 2) ssh_guac_terminal_clear(term, term->cursor_row, 0, - 1, term->term_width); + 1, term->term_width, + term->background); break;