X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fansi.c;h=42f6a4c650476b752907670e96b36dbfcbc55c1d;hb=76292c6be7fcbabad9ab8687eb01f3af51568a9b;hp=7f44957cbb0516b708b7202e16e0b690de73d202;hpb=c06c4c87aef651f32419c6a63d8291b15bad5cf4;p=sympathy.git diff --git a/src/ansi.c b/src/ansi.c index 7f44957..42f6a4c 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -10,6 +10,48 @@ static char rcsid[] = "$Id$"; /* * $Log$ + * Revision 1.33 2008/02/27 09:42:21 james + * *** empty log message *** + * + * Revision 1.32 2008/02/26 23:56:12 james + * *** empty log message *** + * + * Revision 1.31 2008/02/26 23:23:17 james + * *** empty log message *** + * + * Revision 1.30 2008/02/24 00:42:53 james + * *** empty log message *** + * + * Revision 1.29 2008/02/23 11:48:37 james + * *** empty log message *** + * + * Revision 1.28 2008/02/22 17:07:00 james + * *** empty log message *** + * + * Revision 1.27 2008/02/20 22:54:22 staffcvs + * *** empty log message *** + * + * Revision 1.26 2008/02/20 20:16:07 james + * *** empty log message *** + * + * Revision 1.25 2008/02/20 19:44:37 james + * @@ + * + * Revision 1.24 2008/02/20 19:36:06 james + * @@ + * + * Revision 1.23 2008/02/20 19:25:09 james + * *** empty log message *** + * + * Revision 1.22 2008/02/15 03:32:07 james + * *** empty log message *** + * + * Revision 1.21 2008/02/14 02:46:44 james + * *** empty log message *** + * + * Revision 1.20 2008/02/14 01:55:57 james + * *** empty log message *** + * * Revision 1.19 2008/02/13 16:57:29 james * *** empty log message *** * @@ -71,7 +113,7 @@ static char rcsid[] = "$Id$"; #include "project.h" -void +static void ansi_move (ANSI * a, CRT_Pos p) { char buf[16]; @@ -161,7 +203,7 @@ ansi_move (ANSI * a, CRT_Pos p) } -void +static void ansi_showhide_cursor (ANSI * a, int hide) { if (a->hide_cursor == hide) @@ -180,7 +222,7 @@ ansi_showhide_cursor (ANSI * a, int hide) } -void +static void ansi_force_attr_normal (ANSI * a) { a->terminal->xmit (a->terminal, "\033[0m", 4); @@ -188,7 +230,7 @@ ansi_force_attr_normal (ANSI * a) a->color = ANSI_INVAL; } -void +static void ansi_set_color (ANSI * a, int color) { int dif; @@ -229,7 +271,7 @@ ansi_set_color (ANSI * a, int color) } } -void +static void ansi_set_attr (ANSI * a, int attr) { int dif; @@ -286,21 +328,66 @@ ansi_set_attr (ANSI * a, int attr) } +static void +ascii_emit (TTY * t, uint32_t ch) +{ + int i; -void +/*Some quick obvious subsititons for quotation marks*/ + switch (ch) + { + case 0x2018: + ch = '`'; + break; + case 0x2019: + ch = '\''; + break; + case 0x201c: + case 0x201d: + ch = '"'; + break; + } + +/*Short cut the easy stuff*/ + if (ch < 0x7f) + { + uint8_t c = ch; + t->xmit (t, &c, 1); + return; + } + + for (i = 0; i < VT102_CHARSET_SIZE; ++i) + { + if (vt102_charset_gl[i] == ch) + { + uint8_t c[3] = { 016, i, 017 }; + t->xmit (t, &c, 3); + return; + } + } + + t->xmit (t, "?", 1); + +} + +static void ansi_render (ANSI * a, CRT_CA ca) { int dif; - if (ca.chr < 32) - ca.chr = ' '; - if (ca.chr > 126) + if ((ca.chr < VT102_CHARSET_SIZE) && (vt102_charset_c0[ca.chr])) + ca.chr = vt102_charset_c0[ca.chr]; + + if ((ca.chr >= 0x80) && (ca.chr < 0xa0)) ca.chr = ' '; ansi_set_attr (a, ca.attr); ansi_set_color (a, ca.color); - a->terminal->xmit (a->terminal, &ca.chr, 1); + if (a->utf8) + utf8_emit (a->terminal, ca.chr); + else + ascii_emit (a->terminal, ca.chr); a->pos.x++; @@ -312,7 +399,7 @@ ansi_render (ANSI * a, CRT_CA ca) } -void +static void ansi_cls (ANSI * a) { CRT_Pos p = { 0 }; @@ -359,7 +446,7 @@ ansi_scroll_up (ANSI * a, CRT_Pos s, CRT_Pos e) } -void +static void ansi_spot_scroll_up (ANSI * a, CRT * c) { int l, n, p; @@ -394,7 +481,7 @@ ansi_spot_scroll_up (ANSI * a, CRT * c) } -void +static void ansi_spot_scroll (ANSI * a, CRT * c) { @@ -412,13 +499,13 @@ ansi_spot_scroll (ANSI * a, CRT * c) #endif -void +static void ansi_draw_line (ANSI * a, CRT_CA * cap, int y) { CRT_Pos p = { 0, y }; CRT_CA *acap = &a->crt.screen[CRT_ADDR_POS (&p)]; - for (p.x = 0; p.x < CRT_COLS; ++p.x) + for (p.x = 0; p.x < a->crt.size.x; ++p.x) { if (p.x >= a->size.x) continue; @@ -437,53 +524,73 @@ ansi_draw_line (ANSI * a, CRT_CA * cap, int y) } } -void -ansi_resize_check (ANSI * a) +static void +ansi_resize_check (ANSI * a, CRT_Pos *size) { - if (!crt_pos_cmp (a->terminal->size, a->size)) - return; + if ((size && crt_pos_cmp(a->crt.size,*size)) + || crt_pos_cmp (a->terminal->size, a->size)) + { - terminal_getsize (a->terminal); + terminal_getsize (a->terminal); - a->size = a->terminal->size; + a->size = a->terminal->size; - a->pos.x = ANSI_INVAL; - a->hide_cursor = ANSI_INVAL; + a->pos.x = ANSI_INVAL; + a->hide_cursor = ANSI_INVAL; - crt_reset (&a->crt); + crt_reset (&a->crt); + + if (size) + a->crt.size =*size; // FIXME: -- echos back crap? // a->terminal->xmit (a->terminal, "\033[c", 3); - ansi_cls (a); - a->terminal->xmit (a->terminal, "\033=", 2); - a->terminal->xmit (a->terminal, "\033[?6l", 5); - a->terminal->xmit (a->terminal, "\033[r", 3); +// maybe - issue 132 column command if we're 132? + + ansi_cls (a); + a->terminal->xmit (a->terminal, "\033=", 2); + a->terminal->xmit (a->terminal, "\033[?6l", 5); + a->terminal->xmit (a->terminal, "\033[r", 3); + if (a->utf8) + { + a->terminal->xmit (a->terminal, "\033%G", 3); + } + else + { + a->terminal->xmit (a->terminal, "\033(B", 3); + a->terminal->xmit (a->terminal, "\033)0", 3); + a->terminal->xmit (a->terminal, "\017", 1); + } + } } -#define HISTORY_GUESS_SCROLL 24 /*guess all 24 lines usually scroll */ /*if they haven't then ansi_draw will patch it up*/ -void +static void ansi_history (ANSI * a, History * h) { char buf[32]; int i; + int guess_scroll; /*Do we need to catch up on history?*/ if (a->history_ptr == h->wptr) return; - ansi_resize_check (a); + ansi_resize_check (a, NULL); - if ((a->size.x < CRT_COLS) || (a->size.y < CRT_ROWS)) + if ((a->size.x < a->crt.size.x) || (a->size.y < a->crt.size.y)) return; + guess_scroll=a->crt.size.y-1; /*Bototm line should be a status line*/ + + ansi_force_attr_normal (a); ansi_set_color (a, CRT_COLOR_NORMAL); - i = sprintf (buf, "\033[%d;%dr", 1, HISTORY_GUESS_SCROLL); + i = sprintf (buf, "\033[%d;%dr", 1, guess_scroll); a->terminal->xmit (a->terminal, buf, i); @@ -501,11 +608,14 @@ ansi_history (ANSI * a, History * h) ansi_draw_line (a, e->line, 0); - /*Roll HISTORY_GUESS_SCROLL lines up putting the top line into the xterm's history */ + /*Roll guess_scroll lines up putting the top line into the xterm's history */ + + /*Make extra lines a predictable colour */ + ansi_set_color (a, CRT_COLOR_NORMAL); ansi_showhide_cursor (a, 1); - i = sprintf (buf, "\033[%d;%dH", HISTORY_GUESS_SCROLL, 1); + i = sprintf (buf, "\033[%d;%dH", guess_scroll, 1); a->terminal->xmit (a->terminal, buf, i); a->terminal->xmit (a->terminal, "\033D", 2); a->pos.x = ANSI_INVAL; @@ -519,17 +629,17 @@ ansi_history (ANSI * a, History * h) 0}; /*scroll lines up */ - for (s.y++; s.y < HISTORY_GUESS_SCROLL; s.y++, e.y++) + for (s.y++; s.y < guess_scroll; s.y++, e.y++) { memcpy (&a->crt.screen[CRT_ADDR_POS (&e)], &a->crt.screen[CRT_ADDR_POS (&s)], - sizeof (CRT_CA) * CRT_COLS); + sizeof (CRT_CA) * a->crt.size.x); } /* erase new line */ s.y = e.y; e.x = CRT_COLS - 1; - crt_erase (&a->crt, s, e, 1); + crt_erase (&a->crt, s, e, 1, CRT_COLOR_NORMAL); } } @@ -542,18 +652,17 @@ ansi_history (ANSI * a, History * h) -void +static void ansi_draw (ANSI * a, CRT * c) { CRT_Pos p; int o; int hidden_cursor = 0; - ansi_resize_check (a); - + ansi_resize_check (a, &c->size); - for (p.y = 0; p.y < CRT_ROWS; ++p.y) + for (p.y = 0; p.y < a->crt.size.y; ++p.y) { if (p.y >= a->size.y) continue; @@ -563,7 +672,7 @@ ansi_draw (ANSI * a, CRT * c) } - if ((CRT_COLS > a->size.x) || (CRT_ROWS > a->size.y)) + if ((c->size.x > a->size.x) || (c->size.y > a->size.y)) { char msg[1024]; // = "Window is too small"; int i; @@ -572,7 +681,7 @@ ansi_draw (ANSI * a, CRT * c) i = sprintf (msg, "Window too small (%dx%d need %dx%d)", a->size.x, - a->size.y, CRT_COLS, CRT_ROWS); + a->size.y, c->size.x, c->size.y); ansi_showhide_cursor (a, 1); ansi_set_attr (a, CRT_ATTR_REVERSE); @@ -597,23 +706,23 @@ ansi_draw (ANSI * a, CRT * c) ansi_showhide_cursor (a, a->crt.hide_cursor); } -void +static void ansi_reset (ANSI * a, CRT * c) { a->size.x = -1; ansi_draw (a, c ? c : &a->crt); } -void +static void ansi_terminal_reset (ANSI * a) { - CRT_Pos p = { 0, CRT_ROWS }; + CRT_Pos p = { 0, a->crt.size.y}; ansi_force_attr_normal (a); ansi_move (a, p); } -void +static void ansi_flush_escape (ANSI * a, Context * c) { ANSI_Parser *p = &a->parser; @@ -621,14 +730,14 @@ ansi_flush_escape (ANSI * a, Context * c) for (i = 0; i < p->escape_ptr; ++i) { - vt102_send (c, p->escape_buf[i]); + keydis_key (c->k, c, p->escape_buf[i]); } p->escape_ptr = 0; p->in_escape = 0; } -void +static void ansi_parse_deckey (ANSI * a, Context * c) { ANSI_Parser *p = &a->parser; @@ -640,11 +749,11 @@ ansi_parse_deckey (ANSI * a, Context * c) if ((p->escape_buf[2] >= 'A') || (p->escape_buf[2] <= 'Z')) { - vt102_send (c, KEY_UP + (p->escape_buf[2] - 'A')); + keydis_key (c->k, c, KEY_UP + (p->escape_buf[2] - 'A')); } else if ((p->escape_buf[2] >= 'a') || (p->escape_buf[2] <= 'z')) { - vt102_send (c, KEY_154 + (p->escape_buf[2] - 'a')); + keydis_key (c->k, c, KEY_154 + (p->escape_buf[2] - 'a')); } else { @@ -655,7 +764,7 @@ ansi_parse_deckey (ANSI * a, Context * c) p->escape_ptr = 0; } -void +static void ansi_parse_ansikey (ANSI * a, Context * c) { ANSI_Parser *p = &a->parser; @@ -667,7 +776,7 @@ ansi_parse_ansikey (ANSI * a, Context * c) } if ((p->escape_buf[2] >= '0') || (p->escape_buf[2] <= '9')) { - vt102_send (c, KEY_180 + (p->escape_buf[2] - '0')); + keydis_key (c->k, c, KEY_180 + (p->escape_buf[2] - '0')); } else { @@ -681,7 +790,7 @@ ansi_parse_ansikey (ANSI * a, Context * c) -void +static void ansi_parse_escape (ANSI * a, Context * c) { ANSI_Parser *p = &a->parser; @@ -730,7 +839,7 @@ ansi_parse_escape (ANSI * a, Context * c) } -void +static void ansi_check_escape (ANSI * a, Context * c) { ANSI_Parser *p = &a->parser; @@ -754,7 +863,7 @@ ansi_check_escape (ANSI * a, Context * c) } -void +static void ansi_parse_char (ANSI * a, Context * c, int ch) { ANSI_Parser *p = &a->parser; @@ -780,12 +889,12 @@ ansi_parse_char (ANSI * a, Context * c, int ch) } else { - vt102_send (c, ch); + keydis_key (c->k, c, ch); } } -void +static void ansi_parse (ANSI * a, Context * c, char *buf, int len) { while (len--) @@ -802,7 +911,7 @@ ansi_dispatch (ANSI * a, Context * c) if (!a->terminal) - return; + return 0; red = a->terminal->recv (a->terminal, buf, sizeof (buf)); if (red <= 0) @@ -813,17 +922,14 @@ ansi_dispatch (ANSI * a, Context * c) return -1; #endif -#if 1 - if (*buf == 1) - { - ansi_reset (a, NULL); - return 0; - } +#if 0 if (*buf == 2) { +#if 0 a->history_ptr = c->h->wptr; HISTORY_INC (c->h, a->history_ptr); - return 0; +#endif + return -1; } #endif @@ -834,9 +940,40 @@ ansi_dispatch (ANSI * a, Context * c) } -void +static void ansi_update (ANSI * a, Context * c) { ansi_history (a, c->h); ansi_draw (a, &c->v->crt); } + +static void +ansi_free (ANSI * a) +{ + a->terminal_reset (a); + if (a->terminal) + a->terminal->close (a->terminal); + + free (a); + +} + +ANSI * +ansi_new_from_terminal (TTY * t, int utf8) +{ + ANSI *ret; + + ret = malloc (sizeof (ANSI)); + memset (ret, 0, sizeof (ANSI)); + + ret->terminal = t; + + ret->utf8 = utf8; + ret->update = ansi_update; + ret->reset = ansi_reset; + ret->terminal_reset = ansi_terminal_reset; + ret->close = ansi_free; + ret->dispatch = ansi_dispatch; + + return ret; +}