Support for downward scrolling and CSI operation L
This commit is contained in:
parent
d57bdb06e4
commit
f695f5c629
@ -146,6 +146,11 @@ struct ssh_guac_terminal {
|
|||||||
*/
|
*/
|
||||||
int cursor_col;
|
int cursor_col;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple cursor layer until scrollback, etc. is implemented.
|
||||||
|
*/
|
||||||
|
guac_layer* cursor_layer;
|
||||||
|
|
||||||
int foreground;
|
int foreground;
|
||||||
int background;
|
int background;
|
||||||
int reverse;
|
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_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,
|
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
||||||
char c, int foreground, int background);
|
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 ssh_guac_terminal_scroll_up(ssh_guac_terminal* term,
|
||||||
int start_row, int end_row, int amount);
|
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 ssh_guac_terminal_clear_range(ssh_guac_terminal* term,
|
||||||
int start_row, int start_col,
|
int start_row, int start_col,
|
||||||
int end_row, int end_col, int background_color);
|
int end_row, int end_col, int background_color);
|
||||||
|
@ -69,6 +69,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
|
|||||||
/* Add to password */
|
/* Add to password */
|
||||||
client_data->password[client_data->password_length++] = keysym;
|
client_data->password[client_data->password_length++] = keysym;
|
||||||
ssh_guac_terminal_write(client_data->term, "*", 1);
|
ssh_guac_terminal_write(client_data->term, "*", 1);
|
||||||
|
ssh_guac_terminal_redraw_cursor(client_data->term);
|
||||||
guac_flush(client->io);
|
guac_flush(client->io);
|
||||||
}
|
}
|
||||||
else if (keysym == 0xFF08) {
|
else if (keysym == 0xFF08) {
|
||||||
@ -78,6 +79,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
|
|||||||
|
|
||||||
/* Backspace */
|
/* Backspace */
|
||||||
ssh_guac_terminal_write(client_data->term, "\x08\x1B[K", 4);
|
ssh_guac_terminal_write(client_data->term, "\x08\x1B[K", 4);
|
||||||
|
ssh_guac_terminal_redraw_cursor(client_data->term);
|
||||||
guac_flush(client->io);
|
guac_flush(client->io);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +91,7 @@ int ssh_guac_client_password_key_handler(guac_client* client, int keysym, int pr
|
|||||||
|
|
||||||
/* Clear screen */
|
/* Clear screen */
|
||||||
ssh_guac_terminal_write(client_data->term, "\x1B[2J\x1B[1;1H", 10);
|
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);
|
guac_flush(client->io);
|
||||||
|
|
||||||
return ssh_guac_client_auth(client, client_data->password);
|
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;
|
client_data->password_length = 0;
|
||||||
ssh_guac_terminal_write(client_data->term, "Password: ", 10);
|
ssh_guac_terminal_write(client_data->term, "Password: ", 10);
|
||||||
|
ssh_guac_terminal_redraw_cursor(client_data->term);
|
||||||
guac_flush(client->io);
|
guac_flush(client->io);
|
||||||
|
|
||||||
client->key_handler = ssh_guac_client_password_key_handler;
|
client->key_handler = ssh_guac_client_password_key_handler;
|
||||||
|
@ -60,6 +60,8 @@ int ssh_guac_client_handle_messages(guac_client* client) {
|
|||||||
ssh_channel read_channels[2];
|
ssh_channel read_channels[2];
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
|
guac_log_info("ENTER HANDLE MESSAGES...");
|
||||||
|
|
||||||
/* Channels to read */
|
/* Channels to read */
|
||||||
read_channels[0] = client_data->term_channel;
|
read_channels[0] = client_data->term_channel;
|
||||||
read_channels[1] = NULL;
|
read_channels[1] = NULL;
|
||||||
@ -73,13 +75,17 @@ int ssh_guac_client_handle_messages(guac_client* client) {
|
|||||||
|
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
|
|
||||||
|
guac_log_info("DONE WAITING (%i)", GUAC_SYNC_FREQUENCY);
|
||||||
|
|
||||||
/* While data available, write to terminal */
|
/* While data available, write to terminal */
|
||||||
while (channel_is_open(client_data->term_channel)
|
while (channel_is_open(client_data->term_channel)
|
||||||
&& !channel_is_eof(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) {
|
&& (bytes_read = channel_read_nonblocking(client_data->term_channel, buffer, sizeof(buffer), 0)) > 0) {
|
||||||
|
|
||||||
ssh_guac_terminal_write(client_data->term, buffer, bytes_read);
|
if (ssh_guac_terminal_write(client_data->term, buffer, bytes_read)
|
||||||
guac_flush(io);
|
|| 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;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client) {
|
|||||||
|
|
||||||
term->cursor_row = 0;
|
term->cursor_row = 0;
|
||||||
term->cursor_col = 0;
|
term->cursor_col = 0;
|
||||||
|
term->cursor_layer = guac_client_alloc_layer(client, 1);
|
||||||
|
|
||||||
term->term_width = 80;
|
term->term_width = 80;
|
||||||
term->term_height = 24;
|
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,
|
int ssh_guac_terminal_set(ssh_guac_terminal* term, int row, int col,
|
||||||
char c, int foreground, int background) {
|
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 ssh_guac_terminal_clear_range(ssh_guac_terminal* term,
|
||||||
int start_row, int start_col,
|
int start_row, int start_col,
|
||||||
|
@ -407,6 +407,17 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
|
|||||||
|
|
||||||
break;
|
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 */
|
/* Warn of unhandled codes */
|
||||||
default:
|
default:
|
||||||
if (c != ';')
|
if (c != ';')
|
||||||
|
Loading…
Reference in New Issue
Block a user