static int blink_is_real; /* Actually blink blinking text */
static int term_echoing; /* Does terminal want local echo? */
static int term_editing; /* Does terminal want local edit? */
+static int sco_acs, save_sco_acs; /* CSI 10,11,12m -> OEM charset */
static int vt52_bold; /* Force bold on non-bold colours */
static int utf_state; /* Is there a pending UTF-8 character */
static int utf_char; /* and what is it so far. */
/*
* Saved settings on the alternate screen.
*/
-static int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset;
+static int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins, alt_cset, alt_sco_acs;
static int alt_t, alt_b;
static int alt_which;
static void logtraffic(unsigned char c, int logmode);
/*
+ * Resize a line to make it `cols' columns wide.
+ */
+unsigned long *resizeline(unsigned long *line, int cols)
+{
+ int i, oldlen;
+ unsigned long lineattrs;
+
+ if (line[0] != (unsigned long)cols) {
+ /*
+ * This line is the wrong length, which probably means it
+ * hasn't been accessed since a resize. Resize it now.
+ */
+ oldlen = line[0];
+ lineattrs = line[oldlen + 1];
+ line = srealloc(line, TSIZE * (2 + cols));
+ line[0] = cols;
+ for (i = oldlen; i < cols; i++)
+ line[i + 1] = ERASE_CHAR;
+ line[cols + 1] = lineattrs & LATTR_MODE;
+ }
+
+ return line;
+}
+
+/*
* Retrieve a line of the screen or of the scrollback, according to
* whether the y coordinate is non-negative or negative
* (respectively).
*/
unsigned long *lineptr(int y, int lineno)
{
- unsigned long *line, lineattrs;
+ unsigned long *line, *newline;
tree234 *whichtree;
- int i, treeindex, oldlen;
+ int treeindex;
if (y >= 0) {
whichtree = screen;
/* We assume that we don't screw up and retrieve something out of range. */
assert(line != NULL);
- if (line[0] != cols) {
- /*
- * This line is the wrong length, which probably means it
- * hasn't been accessed since a resize. Resize it now.
- */
- oldlen = line[0];
- lineattrs = line[oldlen + 1];
+ newline = resizeline(line, cols);
+ if (newline != line) {
delpos234(whichtree, treeindex);
- line = srealloc(line, TSIZE * (2 + cols));
- line[0] = cols;
- for (i = oldlen; i < cols; i++)
- line[i + 1] = ERASE_CHAR;
- line[cols + 1] = lineattrs & LATTR_MODE;
- addpos234(whichtree, line, treeindex);
+ addpos234(whichtree, newline, treeindex);
}
return line + 1;
alt_wnext = wrapnext = alt_ins = insert = FALSE;
alt_wrap = wrap = cfg.wrap_mode;
alt_cset = cset = 0;
+ alt_sco_acs = sco_acs = 0;
cset_attr[0] = cset_attr[1] = ATTR_ASCII;
rvideo = 0;
in_vbell = FALSE;
Context ctx;
ctx = get_ctx();
if (ctx) {
+ if (seen_disp_event)
+ update_sbar();
if ((seen_key_event && (cfg.scroll_on_key)) ||
(seen_disp_event && (cfg.scroll_on_disp))) {
disptop = 0; /* return to main screen */
seen_disp_event = seen_key_event = 0;
- update_sbar();
}
do_paint(ctx, TRUE);
sys_cursor(curs.x, curs.y - disptop);
t = cset;
cset = alt_cset;
alt_cset = t;
+ t = sco_acs;
+ sco_acs = alt_sco_acs;
+ alt_sco_acs = t;
fix_cpos;
}
if (lines < 0) {
while (lines < 0) {
line = delpos234(screen, botline);
+ line = resizeline(line, cols);
for (i = 0; i < cols; i++)
line[i + 1] = erase_char;
line[cols + 1] = 0;
addpos234(scrollback, line, sblen);
line = line2;
}
+ line = resizeline(line, cols);
for (i = 0; i < cols; i++)
line[i + 1] = erase_char;
line[cols + 1] = 0;
save_attr = curr_attr;
save_cset = cset;
save_csattr = cset_attr[cset];
+ save_sco_acs = sco_acs;
} else {
curs = savecurs;
/* Make sure the window hasn't shrunk since the save */
curr_attr = save_attr;
cset = save_cset;
cset_attr[cset] = save_csattr;
+ sco_acs = save_sco_acs;
fix_cpos;
if (use_bce)
erase_char = (' ' | (curr_attr & (ATTR_FGMASK | ATTR_BGMASK)));
}
if (!to_end) {
end = curs;
+ incpos(end);
}
check_selection(start, end);
ldata = lineptr(start.y);
while (poslt(start, end)) {
- if (start.y == cols && !erase_lattr)
+ if (start.x == cols && !erase_lattr)
ldata[start.x] &= ~LATTR_WRAPPED;
else
ldata[start.x] = erase_char;
if (c >= 0x10000)
c = 0xFFFD;
break;
+ }
+ /* Are we in the nasty ACS mode? Note: no sco in utf mode. */
+ else if(sco_acs &&
+ (c!='\033' && c!='\n' && c!='\r' && c!='\b'))
+ {
+ if (sco_acs == 2) c ^= 0x80;
+ c |= ATTR_SCOACS;
} else {
evil_jump:;
switch (cset_attr[cset]) {
else
c = ((unsigned char) c) | ATTR_ASCII;
break;
+ case ATTR_SCOACS:
+ if (c>=' ') c = ((unsigned char)c) | ATTR_SCOACS;
+ break;
}
}
}
compatibility(VT100);
cset_attr[0] = ATTR_LINEDRW;
break;
+ case ANSI('U', '('):
+ compatibility(OTHER);
+ cset_attr[0] = ATTR_SCOACS;
+ break;
case ANSI('A', ')'):
compatibility(VT100);
compatibility(VT100);
cset_attr[1] = ATTR_LINEDRW;
break;
+ case ANSI('U', ')'):
+ compatibility(OTHER);
+ cset_attr[1] = ATTR_SCOACS;
+ break;
case ANSI('8', '%'): /* Old Linux code */
case ANSI('G', '%'):
break;
case 'e': /* move down N lines */
compatibility(ANSI);
+ /* FALLTHROUGH */
case 'B':
move(curs.x, curs.y + def(esc_args[0], 1), 1);
seen_disp_event = TRUE;
break;
- case 'a': /* move right N cols */
- compatibility(ANSI);
case ANSI('c', '>'): /* report xterm version */
compatibility(OTHER);
/* this reports xterm version 136 so that VIM can
use the drag messages from the mouse reporting */
ldisc_send("\033[>0;136;0c", 11);
break;
+ case 'a': /* move right N cols */
+ compatibility(ANSI);
+ /* FALLTHROUGH */
case 'C':
move(curs.x + def(esc_args[0], 1), curs.y, 1);
seen_disp_event = TRUE;
case 7: /* enable reverse video */
curr_attr |= ATTR_REVERSE;
break;
+ case 10: /* SCO acs off */
+ compatibility(SCOANSI);
+ sco_acs = 0; break;
+ case 11: /* SCO acs on */
+ compatibility(SCOANSI);
+ sco_acs = 1; break;
+ case 12: /* SCO acs on flipped */
+ compatibility(SCOANSI);
+ sco_acs = 2; break;
case 22: /* disable bold */
compatibility2(OTHER, VT220);
curr_attr &= ~ATTR_BOLD;
case ATTR_LINEDRW:
tchar = unitab_xterm[tchar & 0xFF];
break;
+ case ATTR_SCOACS:
+ tchar = unitab_scoacs[tchar&0xFF];
+ break;
}
tattr |= (tchar & CSET_MASK);
tchar &= CHAR_MASK;
case ATTR_ASCII:
uc = unitab_line[uc & 0xFF];
break;
+ case ATTR_SCOACS:
+ uc = unitab_scoacs[uc&0xFF];
+ break;
}
switch (uc & CSET_MASK) {
case ATTR_ACP:
case ATTR_ASCII:
uc = unitab_line[uc & 0xFF];
break;
+ case ATTR_SCOACS:
+ uc = unitab_scoacs[uc&0xFF];
+ break;
}
switch (uc & CSET_MASK) {
case ATTR_ACP:
incpos(selend);
}
+void term_do_paste(void)
+{
+ wchar_t *data;
+ int len;
+
+ get_clip(&data, &len);
+ if (data) {
+ wchar_t *p, *q;
+
+ if (paste_buffer)
+ sfree(paste_buffer);
+ paste_pos = paste_hold = paste_len = 0;
+ paste_buffer = smalloc(len * sizeof(wchar_t));
+
+ p = q = data;
+ while (p < data + len) {
+ while (p < data + len &&
+ !(p <= data + len - sel_nl_sz &&
+ !memcmp(p, sel_nl, sizeof(sel_nl))))
+ p++;
+
+ {
+ int i;
+ for (i = 0; i < p - q; i++) {
+ paste_buffer[paste_len++] = q[i];
+ }
+ }
+
+ if (p <= data + len - sel_nl_sz &&
+ !memcmp(p, sel_nl, sizeof(sel_nl))) {
+ paste_buffer[paste_len++] = '\r';
+ p += sel_nl_sz;
+ }
+ q = p;
+ }
+
+ /* Assume a small paste will be OK in one go. */
+ if (paste_len < 256) {
+ luni_send(paste_buffer, paste_len);
+ if (paste_buffer)
+ sfree(paste_buffer);
+ paste_buffer = 0;
+ paste_pos = paste_hold = paste_len = 0;
+ }
+ }
+ get_clip(NULL, NULL);
+}
+
void term_mouse(Mouse_Button b, Mouse_Action a, int x, int y,
int shift, int ctrl)
{
selstate = NO_SELECTION;
} else if (b == MBT_PASTE
&& (a == MA_CLICK || a == MA_2CLK || a == MA_3CLK)) {
- wchar_t *data;
- int len;
-
- get_clip(&data, &len);
- if (data) {
- wchar_t *p, *q;
-
- if (paste_buffer)
- sfree(paste_buffer);
- paste_pos = paste_hold = paste_len = 0;
- paste_buffer = smalloc(len * sizeof(wchar_t));
-
- p = q = data;
- while (p < data + len) {
- while (p < data + len &&
- !(p <= data + len - sel_nl_sz &&
- !memcmp(p, sel_nl, sizeof(sel_nl))))
- p++;
-
- {
- int i;
- for (i = 0; i < p - q; i++) {
- paste_buffer[paste_len++] = q[i];
- }
- }
-
- if (p <= data + len - sel_nl_sz &&
- !memcmp(p, sel_nl, sizeof(sel_nl))) {
- paste_buffer[paste_len++] = '\r';
- p += sel_nl_sz;
- }
- q = p;
- }
-
- /* Assume a small paste will be OK in one go. */
- if (paste_len < 256) {
- luni_send(paste_buffer, paste_len);
- if (paste_buffer)
- sfree(paste_buffer);
- paste_buffer = 0;
- paste_pos = paste_hold = paste_len = 0;
- }
- }
- get_clip(NULL, NULL);
+ term_do_paste();
}
term_update();