+/*
+ * Terminal emulator.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define has_compat(x) ( ((CL_##x)&term->compatibility_level) != 0 )
+char *EMPTY_WINDOW_TITLE = "";
+
const char sco2ansicolour[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
#define sel_nl_sz (sizeof(sel_nl)/sizeof(wchar_t))
{
term->alt_x = term->alt_y = 0;
term->savecurs.x = term->savecurs.y = 0;
+ term->alt_savecurs.x = term->alt_savecurs.y = 0;
term->alt_t = term->marg_t = 0;
if (term->rows != -1)
term->alt_b = term->marg_b = term->rows - 1;
}
term->alt_om = term->dec_om = term->cfg.dec_om;
term->alt_ins = term->insert = FALSE;
- term->alt_wnext = term->wrapnext = term->save_wnext = FALSE;
+ term->alt_wnext = term->wrapnext =
+ term->save_wnext = term->alt_save_wnext = FALSE;
term->alt_wrap = term->wrap = term->cfg.wrap_mode;
- term->alt_cset = term->cset = term->save_cset = 0;
- term->alt_utf = term->utf = term->save_utf = 0;
+ term->alt_cset = term->cset = term->save_cset = term->alt_save_cset = 0;
+ term->alt_utf = term->utf = term->save_utf = term->alt_save_utf = 0;
term->utf_state = 0;
- term->alt_sco_acs = term->sco_acs = term->save_sco_acs = 0;
- term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = CSET_ASCII;
+ term->alt_sco_acs = term->sco_acs =
+ term->save_sco_acs = term->alt_save_sco_acs = 0;
+ term->cset_attr[0] = term->cset_attr[1] =
+ term->save_csattr = term->alt_save_csattr = CSET_ASCII;
term->rvideo = 0;
term->in_vbell = FALSE;
term->cursor_on = 1;
term->big_cursor = 0;
- term->default_attr = term->save_attr = term->curr_attr = ATTR_DEFAULT;
+ term->default_attr = term->save_attr =
+ term->alt_save_attr = term->curr_attr = ATTR_DEFAULT;
term->term_editing = term->term_echoing = FALSE;
term->app_cursor_keys = term->cfg.app_cursor;
term->app_keypad_keys = term->cfg.app_keypad;
{
term->resize_fn = resize_fn;
term->resize_ctx = resize_ctx;
- if (term->cols > 0 && term->rows > 0)
+ if (resize_fn && term->cols > 0 && term->rows > 0)
resize_fn(resize_ctx, term->cols, term->rows);
}
static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos)
{
int t;
+ pos tp;
tree234 *ttr;
if (!which)
t = term->sco_acs;
if (!reset) term->sco_acs = term->alt_sco_acs;
term->alt_sco_acs = t;
+
+ tp = term->savecurs;
+ if (!reset && !keep_cur_pos)
+ term->savecurs = term->alt_savecurs;
+ term->alt_savecurs = tp;
+ t = term->save_cset;
+ if (!reset && !keep_cur_pos)
+ term->save_cset = term->alt_save_cset;
+ term->alt_save_cset = t;
+ t = term->save_csattr;
+ if (!reset && !keep_cur_pos)
+ term->save_csattr = term->alt_save_csattr;
+ term->alt_save_csattr = t;
+ t = term->save_attr;
+ if (!reset && !keep_cur_pos)
+ term->save_attr = term->alt_save_attr;
+ term->alt_save_attr = t;
+ t = term->save_utf;
+ if (!reset && !keep_cur_pos)
+ term->save_utf = term->alt_save_utf;
+ term->alt_save_utf = t;
+ t = term->save_wnext;
+ if (!reset && !keep_cur_pos)
+ term->save_wnext = term->alt_save_wnext;
+ term->alt_save_wnext = t;
+ t = term->save_sco_acs;
+ if (!reset && !keep_cur_pos)
+ term->save_sco_acs = term->alt_save_sco_acs;
+ term->alt_save_sco_acs = t;
}
if (reset && term->screen) {
term->wrapnext = FALSE;
seen_disp_event(term);
term->paste_hold = 0;
+
+ if (term->cfg.crhaslf) {
+ if (term->curs.y == term->marg_b)
+ scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+ else if (term->curs.y < term->rows - 1)
+ term->curs.y++;
+ }
if (term->logctx)
logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
break;
break;
case 'J': /* ED: erase screen or parts of it */
{
- unsigned int i = def(term->esc_args[0], 0) + 1;
- if (i > 3)
- i = 0;
- erase_lots(term, FALSE, !!(i & 2), !!(i & 1));
+ unsigned int i = def(term->esc_args[0], 0);
+ if (i == 3) {
+ /* Erase Saved Lines (xterm)
+ * This follows Thomas Dickey's xterm. */
+ term_clrsb(term);
+ } else {
+ i++;
+ if (i > 3)
+ i = 0;
+ erase_lots(term, FALSE, !!(i & 2), !!(i & 1));
+ }
}
term->disptop = 0;
seen_disp_event(term);
break;
case 20:
if (term->ldisc &&
- !term->cfg.no_remote_qtitle) {
- p = get_window_title(term->frontend, TRUE);
+ term->cfg.remote_qtitle_action != TITLE_NONE) {
+ if(term->cfg.remote_qtitle_action == TITLE_REAL)
+ p = get_window_title(term->frontend, TRUE);
+ else
+ p = EMPTY_WINDOW_TITLE;
len = strlen(p);
ldisc_send(term->ldisc, "\033]L", 3, 0);
ldisc_send(term->ldisc, p, len, 0);
break;
case 21:
if (term->ldisc &&
- !term->cfg.no_remote_qtitle) {
- p = get_window_title(term->frontend,FALSE);
+ term->cfg.remote_qtitle_action != TITLE_NONE) {
+ if(term->cfg.remote_qtitle_action == TITLE_REAL)
+ p = get_window_title(term->frontend, FALSE);
+ else
+ p = EMPTY_WINDOW_TITLE;
len = strlen(p);
ldisc_send(term->ldisc, "\033]l", 3, 0);
ldisc_send(term->ldisc, p, len, 0);
break;
case SEEN_OSC_P:
{
- int max = (term->osc_strlen == 0 ? 21 : 16);
+ int max = (term->osc_strlen == 0 ? 21 : 15);
int val;
if ((int)c >= '0' && (int)c <= '9')
val = c - '0';
!= newline[j].attr) {
int k;
- for (k = laststart; k < j; k++)
- term->disptext[i]->chars[k].attr |= ATTR_INVALID;
+ if (!dirtyrect) {
+ for (k = laststart; k < j; k++)
+ term->disptext[i]->chars[k].attr |= ATTR_INVALID;
- dirtyrect = TRUE;
+ dirtyrect = TRUE;
+ }
}
if (dirtyrect)
selpoint.x = x;
unlineptr(ldata);
- if (raw_mouse) {
+ /*
+ * If we're in the middle of a selection operation, we ignore raw
+ * mouse mode until it's done (we must have been not in raw mouse
+ * mode when it started).
+ * This makes use of Shift for selection reliable, and avoids the
+ * host seeing mouse releases for which they never saw corresponding
+ * presses.
+ */
+ if (raw_mouse &&
+ (term->selstate != ABOUT_TO) && (term->selstate != DRAGGING)) {
int encstate = 0, r, c;
char abuf[16];
*/
{
int i;
- for (i = 0; i < p->n_prompts; i++)
+ for (i = 0; i < (int)p->n_prompts; i++)
memset(p->prompts[i]->result, 0, p->prompts[i]->result_len);
}
}