Support for downward scrolling and CSI operation L

This commit is contained in:
Michael Jumper 2011-08-09 18:32:54 -07:00
parent d57bdb06e4
commit f695f5c629
5 changed files with 82 additions and 2 deletions

View File

@ -146,6 +146,11 @@ struct ssh_guac_terminal {
*/
int cursor_col;
/**
* Simple cursor layer until scrollback, etc. is implemented.
*/
guac_layer* cursor_layer;
int foreground;
int background;
int reverse;
@ -172,6 +177,8 @@ void ssh_guac_terminal_free(ssh_guac_terminal* term);
int ssh_guac_terminal_write(ssh_guac_terminal* term, const char* c, int size);
int ssh_guac_terminal_redraw_cursor(ssh_guac_terminal* term);
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
char c, int foreground, int background);
@ -185,6 +192,9 @@ int ssh_guac_terminal_clear(ssh_guac_terminal* term,
int ssh_guac_terminal_scroll_up(ssh_guac_terminal* term,
int start_row, int end_row, int amount);
int ssh_guac_terminal_scroll_down(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 background_color);

View File

@ -69,6 +69,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Add to password */
client_data->password[client_data->password_length++] = keysym;
ssh_guac_terminal_write(client_data->term, "*", 1);
ssh_guac_terminal_redraw_cursor(client_data->term);
guac_flush(client->io);
}
else if (keysym == 0xFF08) {
@ -78,6 +79,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Backspace */
ssh_guac_terminal_write(client_data->term, "\x08\x1B[K", 4);
ssh_guac_terminal_redraw_cursor(client_data->term);
guac_flush(client->io);
}
@ -89,6 +91,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
/* Clear screen */
ssh_guac_terminal_write(client_data->term, "\x1B[2J\x1B[1;1H", 10);
ssh_guac_terminal_redraw_cursor(client_data->term);
guac_flush(client->io);
return ssh_guac_client_auth(client, client_data->password);
@ -148,6 +151,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
client_data->password_length = 0;
ssh_guac_terminal_write(client_data->term, "Password: ", 10);
ssh_guac_terminal_redraw_cursor(client_data->term);
guac_flush(client->io);
client->key_handler = ssh_guac_client_password_key_handler;

View File

@ -60,6 +60,8 @@ int ssh_guac_client_handle_messages(guac_client* client) {
ssh_channel read_channels[2];
struct timeval timeout;
guac_log_info("ENTER HANDLE MESSAGES...");
/* Channels to read */
read_channels[0] = client_data->term_channel;
read_channels[1] = NULL;
@ -73,13 +75,17 @@ int ssh_guac_client_handle_messages(guac_client* client) {
int bytes_read = 0;
guac_log_info("DONE WAITING (%i)", GUAC_SYNC_FREQUENCY);
/* While data available, write to terminal */
while (channel_is_open(client_data->term_channel)
&& !channel_is_eof(client_data->term_channel)
&& (bytes_read = channel_read_nonblocking(client_data->term_channel, buffer, sizeof(buffer), 0)) > 0) {
ssh_guac_terminal_write(client_data->term, buffer, bytes_read);
guac_flush(io);
if (ssh_guac_terminal_write(client_data->term, buffer, bytes_read)
|| ssh_guac_terminal_redraw_cursor(client_data->term)
|| guac_flush(io))
return 1;
}
@ -91,6 +97,7 @@ int ssh_guac_client_handle_messages(guac_client* client) {
}
}
guac_log_info("LEAVE HANDLE MESSAGES");
return 0;
}

View File

@ -93,6 +93,7 @@ ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) {
term->cursor_row = 0;
term->cursor_col = 0;
term->cursor_layer = guac_client_alloc_layer(client, 1);
term->term_width = 80;
term->term_height = 24;
@ -220,6 +221,33 @@ guac_layer* __ssh_guac_terminal_get_glyph(ssh_guac_terminal* term, char c) {
}
int ssh_guac_terminal_redraw_cursor(ssh_guac_terminal* term) {
GUACIO* io = term->client->io;
/* Erase old cursor */
return
guac_send_rect(io,
GUAC_COMP_SRC, term->cursor_layer,
0, 0,
term->char_width * term->term_width,
term->char_height * term->term_height,
0, 0, 0, 0)
|| guac_send_rect(io,
GUAC_COMP_SRC, term->cursor_layer,
term->char_width * term->cursor_col,
term->char_height * term->cursor_row,
term->char_width, term->char_height,
0x40, 0xFF, 0x80,
0x80);
}
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
char c, int foreground, int background) {
@ -342,6 +370,26 @@ int ssh_guac_terminal_scroll_up(ssh_guac_terminal* term,
}
int ssh_guac_terminal_scroll_down(ssh_guac_terminal* term,
int start_row, int end_row, int amount) {
/* Calculate height of scroll region */
int height = end_row - start_row + 1;
return
/* Move rows within scroll region down by the given amount */
ssh_guac_terminal_copy(term,
start_row, 0,
height - amount, term->term_width,
start_row + amount, 0)
/* Fill new rows with background */
|| ssh_guac_terminal_clear(term,
start_row, 0, amount, term->term_width,
term->background);
}
int ssh_guac_terminal_clear_range(ssh_guac_terminal* term,
int start_row, int start_col,

View File

@ -407,6 +407,17 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
break;
/* L: Insert blank lines (scroll down) */
case 'L':
amount = argv[0];
if (amount == 0) amount = 1;
ssh_guac_terminal_scroll_down(term,
term->cursor_row, term->scroll_end, amount);
break;
/* Warn of unhandled codes */
default:
if (c != ';')