aboutsummaryrefslogtreecommitdiff
path: root/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'input.c')
-rw-r--r--input.c180
1 files changed, 115 insertions, 65 deletions
diff --git a/input.c b/input.c
index ce103bd2..de11f629 100644
--- a/input.c
+++ b/input.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -52,9 +52,11 @@ int input_split(struct input_ctx *);
int input_get(struct input_ctx *, u_int, int, int);
void input_reply(struct input_ctx *, const char *, ...);
void input_set_state(struct window_pane *, const struct input_transition *);
+void input_reset_cell(struct input_ctx *);
/* Transition entry/exit handlers. */
void input_clear(struct input_ctx *);
+void input_ground(struct input_ctx *);
void input_enter_osc(struct input_ctx *);
void input_exit_osc(struct input_ctx *);
void input_enter_apc(struct input_ctx *);
@@ -103,19 +105,23 @@ enum input_esc_type {
INPUT_ESC_NEL,
INPUT_ESC_RI,
INPUT_ESC_RIS,
- INPUT_ESC_SCSOFF_G0,
- INPUT_ESC_SCSON_G0,
+ INPUT_ESC_SCSG0_OFF,
+ INPUT_ESC_SCSG0_ON,
+ INPUT_ESC_SCSG1_OFF,
+ INPUT_ESC_SCSG1_ON,
};
/* Escape command table. */
const struct input_table_entry input_esc_table[] = {
- { '0', "(", INPUT_ESC_SCSOFF_G0 },
+ { '0', "(", INPUT_ESC_SCSG0_ON },
+ { '0', ")", INPUT_ESC_SCSG1_ON },
{ '7', "", INPUT_ESC_DECSC },
{ '8', "", INPUT_ESC_DECRC },
{ '8', "#", INPUT_ESC_DECALN },
{ '=', "", INPUT_ESC_DECKPAM },
{ '>', "", INPUT_ESC_DECKPNM },
- { 'B', "(", INPUT_ESC_SCSON_G0 },
+ { 'B', "(", INPUT_ESC_SCSG0_OFF },
+ { 'B', ")", INPUT_ESC_SCSG1_OFF },
{ 'D', "", INPUT_ESC_IND },
{ 'E', "", INPUT_ESC_NEL },
{ 'H', "", INPUT_ESC_HTS },
@@ -242,7 +248,7 @@ const struct input_transition input_state_utf8_one_table[];
/* ground state definition. */
const struct input_state input_state_ground = {
"ground",
- NULL, NULL,
+ input_ground, NULL,
input_state_ground_table
};
@@ -683,17 +689,26 @@ input_table_compare(const void *key, const void *value)
return (strcmp(ictx->interm_buf, entry->interm));
}
+/* Reset cell state to default. */
+void
+input_reset_cell(struct input_ctx *ictx)
+{
+ memcpy(&ictx->cell.cell, &grid_default_cell, sizeof ictx->cell.cell);
+ ictx->cell.set = 0;
+ ictx->cell.g0set = ictx->cell.g1set = 0;
+
+ memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
+ ictx->old_cx = 0;
+ ictx->old_cy = 0;
+}
+
/* Initialise input parser. */
void
input_init(struct window_pane *wp)
{
struct input_ctx *ictx = &wp->ictx;
- memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
-
- memcpy(&ictx->old_cell, &grid_default_cell, sizeof ictx->old_cell);
- ictx->old_cx = 0;
- ictx->old_cy = 0;
+ input_reset_cell(ictx);
*ictx->interm_buf = '\0';
ictx->interm_len = 0;
@@ -701,6 +716,12 @@ input_init(struct window_pane *wp)
*ictx->param_buf = '\0';
ictx->param_len = 0;
+ ictx->input_space = INPUT_BUF_START;
+ ictx->input_buf = xmalloc(INPUT_BUF_START);
+
+ *ictx->input_buf = '\0';
+ ictx->input_len = 0;
+
ictx->state = &input_state_ground;
ictx->flags = 0;
@@ -711,8 +732,11 @@ input_init(struct window_pane *wp)
void
input_free(struct window_pane *wp)
{
- if (wp != NULL)
- evbuffer_free(wp->ictx.since_ground);
+ if (wp == NULL)
+ return;
+
+ free(wp->ictx.input_buf);
+ evbuffer_free(wp->ictx.since_ground);
}
/* Change input state. */
@@ -720,14 +744,9 @@ void
input_set_state(struct window_pane *wp, const struct input_transition *itr)
{
struct input_ctx *ictx = &wp->ictx;
- struct evbuffer *ground_evb = ictx->since_ground;
if (ictx->state->exit != NULL)
ictx->state->exit(ictx);
-
- if (itr->state == &input_state_ground)
- evbuffer_drain(ground_evb, EVBUFFER_LENGTH(ground_evb));
-
ictx->state = itr->state;
if (ictx->state->enter != NULL)
ictx->state->enter(ictx);
@@ -882,12 +901,34 @@ input_clear(struct input_ctx *ictx)
ictx->flags &= ~INPUT_DISCARD;
}
+/* Reset for ground state. */
+void
+input_ground(struct input_ctx *ictx)
+{
+ evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
+
+ if (ictx->input_space > INPUT_BUF_START) {
+ ictx->input_space = INPUT_BUF_START;
+ ictx->input_buf = xrealloc(ictx->input_buf, INPUT_BUF_START);
+ }
+}
+
/* Output this character to the screen. */
int
input_print(struct input_ctx *ictx)
{
- grid_cell_one(&ictx->cell, ictx->ch);
- screen_write_cell(&ictx->ctx, &ictx->cell);
+ int set;
+
+ set = ictx->cell.set == 0 ? ictx->cell.g0set : ictx->cell.g1set;
+ if (set == 1)
+ ictx->cell.cell.attr |= GRID_ATTR_CHARSET;
+ else
+ ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
+
+ grid_cell_one(&ictx->cell.cell, ictx->ch);
+ screen_write_cell(&ictx->ctx, &ictx->cell.cell);
+
+ ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
return (0);
}
@@ -924,12 +965,20 @@ input_parameter(struct input_ctx *ictx)
int
input_input(struct input_ctx *ictx)
{
- if (ictx->input_len == (sizeof ictx->input_buf) - 1)
- ictx->flags |= INPUT_DISCARD;
- else {
- ictx->input_buf[ictx->input_len++] = ictx->ch;
- ictx->input_buf[ictx->input_len] = '\0';
+ size_t available;
+
+ available = ictx->input_space;
+ while (ictx->input_len + 1 >= available) {
+ available *= 2;
+ if (available > INPUT_BUF_LIMIT) {
+ ictx->flags |= INPUT_DISCARD;
+ return (0);
+ }
+ ictx->input_buf = xrealloc(ictx->input_buf, available);
+ ictx->input_space = available;
}
+ ictx->input_buf[ictx->input_len++] = ictx->ch;
+ ictx->input_buf[ictx->input_len] = '\0';
return (0);
}
@@ -975,10 +1024,10 @@ input_c0_dispatch(struct input_ctx *ictx)
screen_write_carriagereturn(sctx);
goto count_c0;
case '\016': /* SO */
- ictx->cell.attr |= GRID_ATTR_CHARSET;
+ ictx->cell.set = 1;
break;
case '\017': /* SI */
- ictx->cell.attr &= ~GRID_ATTR_CHARSET;
+ ictx->cell.set = 0;
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
@@ -989,7 +1038,7 @@ input_c0_dispatch(struct input_ctx *ictx)
count_c0:
trigger = options_get_number(&wp->window->options, "c0-change-trigger");
- if (++wp->changes == trigger) {
+ if (trigger != 0 && ++wp->changes >= trigger) {
wp->flags |= PANE_DROP;
window_pane_timer_start(wp);
}
@@ -1018,11 +1067,7 @@ input_esc_dispatch(struct input_ctx *ictx)
switch (entry->type) {
case INPUT_ESC_RIS:
- memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
- memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
- ictx->old_cx = 0;
- ictx->old_cy = 0;
-
+ input_reset_cell(ictx);
screen_write_reset(sctx);
break;
case INPUT_ESC_IND:
@@ -1057,16 +1102,17 @@ input_esc_dispatch(struct input_ctx *ictx)
case INPUT_ESC_DECALN:
screen_write_alignmenttest(sctx);
break;
- case INPUT_ESC_SCSON_G0:
- /*
- * Not really supported, but fake it up enough for those that
- * use it to switch character sets (by redefining G0 to
- * graphics set, rather than switching to G1).
- */
- ictx->cell.attr &= ~GRID_ATTR_CHARSET;
+ case INPUT_ESC_SCSG0_ON:
+ ictx->cell.g0set = 1;
break;
- case INPUT_ESC_SCSOFF_G0:
- ictx->cell.attr |= GRID_ATTR_CHARSET;
+ case INPUT_ESC_SCSG0_OFF:
+ ictx->cell.g0set = 0;
+ break;
+ case INPUT_ESC_SCSG1_ON:
+ ictx->cell.g1set = 1;
+ break;
+ case INPUT_ESC_SCSG1_OFF:
+ ictx->cell.g1set = 0;
break;
}
@@ -1147,7 +1193,7 @@ input_csi_dispatch(struct input_ctx *ictx)
case INPUT_CSI_DA_TWO:
switch (input_get(ictx, 0, 0, 0)) {
case 0:
- input_reply(ictx, "\033[>0;95;0c");
+ input_reply(ictx, "\033[>84;0;0c");
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
@@ -1296,6 +1342,9 @@ input_csi_dispatch_rm(struct input_ctx *ictx)
case 4: /* IRM */
screen_write_mode_clear(&ictx->ctx, MODE_INSERT);
break;
+ case 34:
+ screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
+ break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;
@@ -1307,7 +1356,8 @@ input_csi_dispatch_rm(struct input_ctx *ictx)
void
input_csi_dispatch_rm_private(struct input_ctx *ictx)
{
- u_int i;
+ struct window_pane *wp = ictx->wp;
+ u_int i;
for (i = 0; i < ictx->param_list_len; i++) {
switch (input_get(ictx, i, 0, -1)) {
@@ -1321,13 +1371,15 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
case 7: /* DECAWM */
screen_write_mode_clear(&ictx->ctx, MODE_WRAP);
break;
+ case 12:
+ screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
+ break;
case 25: /* TCEM */
screen_write_mode_clear(&ictx->ctx, MODE_CURSOR);
break;
case 1000:
case 1001:
case 1002:
- case 1003:
screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
break;
case 1004:
@@ -1341,10 +1393,10 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
break;
case 47:
case 1047:
- window_pane_alternate_off(ictx->wp, &ictx->cell, 0);
+ window_pane_alternate_off(wp, &ictx->cell.cell, 0);
break;
case 1049:
- window_pane_alternate_off(ictx->wp, &ictx->cell, 1);
+ window_pane_alternate_off(wp, &ictx->cell.cell, 1);
break;
case 2004:
screen_write_mode_clear(&ictx->ctx, MODE_BRACKETPASTE);
@@ -1367,6 +1419,9 @@ input_csi_dispatch_sm(struct input_ctx *ictx)
case 4: /* IRM */
screen_write_mode_set(&ictx->ctx, MODE_INSERT);
break;
+ case 34:
+ screen_write_mode_clear(&ictx->ctx, MODE_BLINKING);
+ break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;
@@ -1378,7 +1433,8 @@ input_csi_dispatch_sm(struct input_ctx *ictx)
void
input_csi_dispatch_sm_private(struct input_ctx *ictx)
{
- u_int i;
+ struct window_pane *wp = ictx->wp;
+ u_int i;
for (i = 0; i < ictx->param_list_len; i++) {
switch (input_get(ictx, i, 0, -1)) {
@@ -1392,6 +1448,9 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
case 7: /* DECAWM */
screen_write_mode_set(&ictx->ctx, MODE_WRAP);
break;
+ case 12:
+ screen_write_mode_set(&ictx->ctx, MODE_BLINKING);
+ break;
case 25: /* TCEM */
screen_write_mode_set(&ictx->ctx, MODE_CURSOR);
break;
@@ -1403,15 +1462,11 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
screen_write_mode_set(&ictx->ctx, MODE_MOUSE_BUTTON);
break;
- case 1003:
- screen_write_mode_clear(&ictx->ctx, ALL_MOUSE_MODES);
- screen_write_mode_set(&ictx->ctx, MODE_MOUSE_ANY);
- break;
case 1004:
if (ictx->ctx.s->mode & MODE_FOCUSON)
break;
screen_write_mode_set(&ictx->ctx, MODE_FOCUSON);
- ictx->wp->flags |= PANE_FOCUSPUSH; /* force update */
+ wp->flags |= PANE_FOCUSPUSH; /* force update */
break;
case 1005:
screen_write_mode_set(&ictx->ctx, MODE_MOUSE_UTF8);
@@ -1421,10 +1476,10 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
break;
case 47:
case 1047:
- window_pane_alternate_on(ictx->wp, &ictx->cell, 0);
+ window_pane_alternate_on(wp, &ictx->cell.cell, 0);
break;
case 1049:
- window_pane_alternate_on(ictx->wp, &ictx->cell, 1);
+ window_pane_alternate_on(wp, &ictx->cell.cell, 1);
break;
case 2004:
screen_write_mode_set(&ictx->ctx, MODE_BRACKETPASTE);
@@ -1489,15 +1544,12 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
void
input_csi_dispatch_sgr(struct input_ctx *ictx)
{
- struct grid_cell *gc = &ictx->cell;
+ struct grid_cell *gc = &ictx->cell.cell;
u_int i;
int n, m;
- u_char attr;
if (ictx->param_list_len == 0) {
- attr = gc->attr;
memcpy(gc, &grid_default_cell, sizeof *gc);
- gc->attr |= (attr & GRID_ATTR_CHARSET);
return;
}
@@ -1535,9 +1587,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
switch (n) {
case 0:
case 10:
- attr = gc->attr;
memcpy(gc, &grid_default_cell, sizeof *gc);
- gc->attr |= (attr & GRID_ATTR_CHARSET);
break;
case 1:
gc->attr |= GRID_ATTR_BRIGHT;
@@ -1666,8 +1716,8 @@ input_enter_osc(struct input_ctx *ictx)
void
input_exit_osc(struct input_ctx *ictx)
{
- u_char *p = ictx->input_buf;
- int option;
+ u_char *p = ictx->input_buf;
+ int option;
if (ictx->flags & INPUT_DISCARD)
return;
@@ -1781,8 +1831,8 @@ input_utf8_close(struct input_ctx *ictx)
utf8_append(&ictx->utf8data, ictx->ch);
- grid_cell_set(&ictx->cell, &ictx->utf8data);
- screen_write_cell(&ictx->ctx, &ictx->cell);
+ grid_cell_set(&ictx->cell.cell, &ictx->utf8data);
+ screen_write_cell(&ictx->ctx, &ictx->cell.cell);
return (0);
}