Switching to per-state static variables rather than per-terminal instance variables (states need not be thread safe)

This commit is contained in:
Michael Jumper 2011-08-04 19:36:04 -07:00
parent e3d1a3f023
commit f2732acc5a
2 changed files with 35 additions and 34 deletions

View File

@ -55,9 +55,9 @@ typedef int ssh_guac_terminal_char_handler(ssh_guac_terminal* term, char c);
struct ssh_guac_terminal { struct ssh_guac_terminal {
PangoFontDescription* font_desc;
guac_client* client; guac_client* client;
PangoFontDescription* font_desc;
guac_layer* glyphs[256]; guac_layer* glyphs[256];
int char_width; int char_width;
@ -65,16 +65,12 @@ struct ssh_guac_terminal {
int term_width; int term_width;
int term_height; int term_height;
ssh_guac_terminal_char_handler* char_handler;
int term_seq_argc;
int term_seq_argv[16];
char term_seq_argv_buffer[16];
int term_seq_argv_buffer_current;
int cursor_row; int cursor_row;
int cursor_col; int cursor_col;
ssh_guac_terminal_char_handler* char_handler;
}; };
ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client); ssh_guac_terminal* ssh_guac_terminal_create(guac_client* client);

View File

@ -132,14 +132,10 @@ int ssh_guac_terminal_escape(ssh_guac_terminal* term, char c) {
case ']': case ']':
term->char_handler = ssh_guac_terminal_osc; term->char_handler = ssh_guac_terminal_osc;
term->term_seq_argc = 0;
term->term_seq_argv_buffer_current = 0;
break; break;
case '[': case '[':
term->char_handler = ssh_guac_terminal_csi; term->char_handler = ssh_guac_terminal_csi;
term->term_seq_argc = 0;
term->term_seq_argv_buffer_current = 0;
break; break;
default: default:
@ -161,6 +157,14 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
GUACIO* io = term->client->io; GUACIO* io = term->client->io;
/* CSI function arguments */
static int argc = 0;
static int argv[16];
/* Argument building counter and buffer */
static int argv_length = 0;
static char argv_buffer[256];
/* FIXME: "The sequence of parameters may be preceded by a single question mark. */ /* FIXME: "The sequence of parameters may be preceded by a single question mark. */
if (c == '?') if (c == '?')
return 0; return 0;
@ -169,13 +173,8 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
/* Concatenate digit if there is space in buffer */ /* Concatenate digit if there is space in buffer */
if (term->term_seq_argv_buffer_current < if (argv_length < sizeof(argv_buffer)-1)
sizeof(term->term_seq_argv_buffer)) { argv_buffer[argv_length++] = c;
term->term_seq_argv_buffer[
term->term_seq_argv_buffer_current++
] = c;
}
} }
@ -183,14 +182,15 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
else { else {
/* At most 16 parameters */ /* At most 16 parameters */
if (term->term_seq_argc < 16) { if (argc < 16) {
/* Finish parameter */ /* Finish parameter */
term->term_seq_argv_buffer[term->term_seq_argv_buffer_current] = 0; argv_buffer[argv_length] = 0;
term->term_seq_argv[term->term_seq_argc++] = argv[argc++] = atoi(argv_buffer);
atoi(term->term_seq_argv_buffer);
/* Prepare for next parameter */ /* Prepare for next parameter */
term->term_seq_argv_buffer_current = 0; argv_length = 0;
} }
/* Handle CSI functions */ /* Handle CSI functions */
@ -198,15 +198,15 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
/* H: Move cursor */ /* H: Move cursor */
case 'H': case 'H':
term->cursor_row = term->term_seq_argv[0] - 1; term->cursor_row = argv[0] - 1;
term->cursor_col = term->term_seq_argv[1] - 1; term->cursor_col = argv[1] - 1;
break; break;
/* J: Erase display */ /* J: Erase display */
case 'J': case 'J':
/* Erase from cursor to end of display */ /* Erase from cursor to end of display */
if (term->term_seq_argv[0] == 0) { if (argv[0] == 0) {
/* Until end of line */ /* Until end of line */
guac_send_rect(io, guac_send_rect(io,
@ -231,7 +231,7 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
} }
/* Erase from start to cursor */ /* Erase from start to cursor */
else if (term->term_seq_argv[0] == 1) { else if (argv[0] == 1) {
/* Until start of line */ /* Until start of line */
guac_send_rect(io, guac_send_rect(io,
@ -256,7 +256,7 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
} }
/* Entire screen */ /* Entire screen */
else if (term->term_seq_argv[0] == 2) { else if (argv[0] == 2) {
guac_send_rect(io, guac_send_rect(io,
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER, GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
0, 0,
@ -272,7 +272,7 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
case 'K': case 'K':
/* Erase from cursor to end of line */ /* Erase from cursor to end of line */
if (term->term_seq_argv[0] == 0) { if (argv[0] == 0) {
guac_send_rect(io, guac_send_rect(io,
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER, GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
term->cursor_col * term->char_width, term->cursor_col * term->char_width,
@ -283,7 +283,7 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
} }
/* Erase from start to cursor */ /* Erase from start to cursor */
else if (term->term_seq_argv[0] == 1) { else if (argv[0] == 1) {
guac_send_rect(io, guac_send_rect(io,
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER, GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
0, 0,
@ -294,7 +294,7 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
} }
/* Erase line */ /* Erase line */
else if (term->term_seq_argv[0] == 2) { else if (argv[0] == 2) {
guac_send_rect(io, guac_send_rect(io,
GUAC_COMP_SRC, GUAC_DEFAULT_LAYER, GUAC_COMP_SRC, GUAC_DEFAULT_LAYER,
0, 0,
@ -314,8 +314,13 @@ int ssh_guac_terminal_csi(ssh_guac_terminal* term, char c) {
} }
/* If not a semicolon, end of CSI sequence */ /* If not a semicolon, end of CSI sequence */
if (c != ';') if (c != ';') {
term->char_handler = ssh_guac_terminal_echo; term->char_handler = ssh_guac_terminal_echo;
/* Reset argument counters */
argc = 0;
argv_length = 0;
}
} }