source: trunk/third/x3270/ansi.c @ 9081

Revision 9081, 32.4 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9080, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright 1993, 1994, 1995, 1996 by Paul Mattes.
3 *  Permission to use, copy, modify, and distribute this software and its
4 *  documentation for any purpose and without fee is hereby granted,
5 *  provided that the above copyright notice appear in all copies and that
6 *  both that copyright notice and this permission notice appear in
7 *  supporting documentation.
8 */
9
10/*
11 *      ansi.c
12 *              ANSI terminal emulation.
13 */
14
15#include "globals.h"
16#include <X11/Shell.h>
17#include "appres.h"
18#include "ctlr.h"
19
20#include "ansic.h"
21#include "ctlrc.h"
22#include "screenc.h"
23#include "scrollc.h"
24#include "tablesc.h"
25#include "telnetc.h"
26#include "trace_dsc.h"
27
28#define SC      1       /* save cursor position */
29#define RC      2       /* restore cursor position */
30#define NL      3       /* new line */
31#define UP      4       /* cursor up */
32#define E2      5       /* second level of ESC processing */
33#define RS      6       /* reset */
34#define IC      7       /* insert chars */
35#define DN      8       /* cursor down */
36#define RT      9       /* cursor right */
37#define LT      10      /* cursor left */
38#define CM      11      /* cursor motion */
39#define ED      12      /* erase in display */
40#define EL      13      /* erase in line */
41#define IL      14      /* insert lines */
42#define DL      15      /* delete lines */
43#define DC      16      /* delete characters */
44#define SG      17      /* set graphic rendition */
45#define BL      18      /* ring bell */
46#define NP      19      /* new page */
47#define BS      20      /* backspace */
48#define CR      21      /* carriage return */
49#define LF      22      /* line feed */
50#define HT      23      /* horizontal tab */
51#define E1      24      /* first level of ESC processing */
52#define Xx      25      /* undefined control character (nop) */
53#define Pc      26      /* printing character */
54#define Sc      27      /* semicolon (after ESC [) */
55#define Dg      28      /* digit (after ESC [ or ESC [ ?) */
56#define RI      29      /* reverse index */
57#define DA      30      /* send device attributes */
58#define SM      31      /* set mode */
59#define RM      32      /* reset mode */
60#define DO      33      /* return terminal ID (obsolete) */
61#define SR      34      /* device status report */
62#define CS      35      /* character set designate */
63#define E3      36      /* third level of ESC processing */
64#define DS      37      /* DEC private set */
65#define DR      38      /* DEC private reset */
66#define DV      39      /* DEC private save */
67#define DT      40      /* DEC private restore */
68#define SS      41      /* set scrolling region */
69#define TM      42      /* text mode (ESC ]) */
70#define T2      43      /* semicolon (after ESC ]) */
71#define TX      44      /* text parameter (after ESC ] n ;) */
72#define TB      45      /* text parameter done (ESC ] n ; xxx BEL) */
73#define TS      46      /* tab set */
74#define TC      47      /* tab clear */
75#define C2      48      /* character set designate (finish) */
76#define G0      49      /* select G0 character set */
77#define G1      50      /* select G1 character set */
78#define G2      51      /* select G2 character set */
79#define G3      52      /* select G3 character set */
80#define S2      53      /* select G2 for next character */
81#define S3      54      /* select G3 for next character */
82
83static enum state {
84    DATA = 0, ESC = 1, CSDES = 2,
85    N1 = 3, DECP = 4, TEXT = 5, TEXT2 = 6
86} state = DATA;
87
88static enum state ansi_data_mode();
89static enum state dec_save_cursor();
90static enum state dec_restore_cursor();
91static enum state ansi_newline();
92static enum state ansi_cursor_up();
93static enum state ansi_esc2();
94static enum state ansi_reset();
95static enum state ansi_insert_chars();
96static enum state ansi_cursor_down();
97static enum state ansi_cursor_right();
98static enum state ansi_cursor_left();
99static enum state ansi_cursor_motion();
100static enum state ansi_erase_in_display();
101static enum state ansi_erase_in_line();
102static enum state ansi_insert_lines();
103static enum state ansi_delete_lines();
104static enum state ansi_delete_chars();
105static enum state ansi_sgr();
106static enum state ansi_bell();
107static enum state ansi_newpage();
108static enum state ansi_backspace();
109static enum state ansi_cr();
110static enum state ansi_lf();
111static enum state ansi_htab();
112static enum state ansi_escape();
113static enum state ansi_nop();
114static enum state ansi_printing();
115static enum state ansi_semicolon();
116static enum state ansi_digit();
117static enum state ansi_reverse_index();
118static enum state ansi_send_attributes();
119static enum state ansi_set_mode();
120static enum state ansi_reset_mode();
121static enum state dec_return_terminal_id();
122static enum state ansi_status_report();
123static enum state ansi_cs_designate();
124static enum state ansi_esc3();
125static enum state dec_set();
126static enum state dec_reset();
127static enum state dec_save();
128static enum state dec_restore();
129static enum state dec_scrolling_region();
130static enum state xterm_text_mode();
131static enum state xterm_text_semicolon();
132static enum state xterm_text();
133static enum state xterm_text_do();
134static enum state ansi_htab_set();
135static enum state ansi_htab_clear();
136static enum state ansi_cs_designate2();
137static enum state ansi_select_g0();
138static enum state ansi_select_g1();
139static enum state ansi_select_g2();
140static enum state ansi_select_g3();
141static enum state ansi_one_g2();
142static enum state ansi_one_g3();
143
144static enum state (*ansi_fn[])() = {
145/* 0 */         ansi_data_mode,
146/* 1 */         dec_save_cursor,
147/* 2 */         dec_restore_cursor,
148/* 3 */         ansi_newline,
149/* 4 */         ansi_cursor_up,
150/* 5 */         ansi_esc2,
151/* 6 */         ansi_reset,
152/* 7 */         ansi_insert_chars,
153/* 8 */         ansi_cursor_down,
154/* 9 */         ansi_cursor_right,
155/* 10 */        ansi_cursor_left,
156/* 11 */        ansi_cursor_motion,
157/* 12 */        ansi_erase_in_display,
158/* 13 */        ansi_erase_in_line,
159/* 14 */        ansi_insert_lines,
160/* 15 */        ansi_delete_lines,
161/* 16 */        ansi_delete_chars,
162/* 17 */        ansi_sgr,
163/* 18 */        ansi_bell,
164/* 19 */        ansi_newpage,
165/* 20 */        ansi_backspace,
166/* 21 */        ansi_cr,
167/* 22 */        ansi_lf,
168/* 23 */        ansi_htab,
169/* 24 */        ansi_escape,
170/* 25 */        ansi_nop,
171/* 26 */        ansi_printing,
172/* 27 */        ansi_semicolon,
173/* 28 */        ansi_digit,
174/* 29 */        ansi_reverse_index,
175/* 30 */        ansi_send_attributes,
176/* 31 */        ansi_set_mode,
177/* 32 */        ansi_reset_mode,
178/* 33 */        dec_return_terminal_id,
179/* 34 */        ansi_status_report,
180/* 35 */        ansi_cs_designate,
181/* 36 */        ansi_esc3,
182/* 37 */        dec_set,
183/* 38 */        dec_reset,
184/* 39 */        dec_save,
185/* 40 */        dec_restore,
186/* 41 */        dec_scrolling_region,
187/* 42 */        xterm_text_mode,
188/* 43 */        xterm_text_semicolon,
189/* 44 */        xterm_text,
190/* 45 */        xterm_text_do,
191/* 46 */        ansi_htab_set,
192/* 47 */        ansi_htab_clear,
193/* 48 */        ansi_cs_designate2,
194/* 49 */        ansi_select_g0,
195/* 50 */        ansi_select_g1,
196/* 51 */        ansi_select_g2,
197/* 52 */        ansi_select_g3,
198/* 53 */        ansi_one_g2,
199/* 54 */        ansi_one_g3,
200};
201
202static unsigned char st[7][256] = {
203/*
204 * State table for base processing (state == DATA)
205 */
206{
207             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
208/* 00 */       Xx,Xx,Xx,Xx,Xx,Xx,Xx,BL,BS,HT,LF,LF,NP,CR,G1,G0,
209/* 10 */       Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,E1,Xx,Xx,Xx,Xx,
210/* 20 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
211/* 30 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
212/* 40 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
213/* 50 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
214/* 60 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
215/* 70 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Xx,
216/* 80 */       Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,
217/* 90 */       Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,Xx,
218/* a0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
219/* b0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
220/* c0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
221/* d0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
222/* e0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,
223/* f0 */       Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc,Pc
224},
225
226/*
227 * State table for ESC processing (state == ESC)
228 */
229{
230             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
231/* 00 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233/* 20 */        0, 0, 0, 0, 0, 0, 0, 0,CS,CS,CS,CS, 0, 0, 0, 0,
234/* 30 */        0, 0, 0, 0, 0, 0, 0,SC,RC, 0, 0, 0, 0, 0, 0, 0,
235/* 40 */        0, 0, 0, 0, 0,NL, 0, 0,TS, 0, 0, 0, 0,RI,S2,S3,
236/* 50 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,E2, 0,TM, 0, 0,
237/* 60 */        0, 0, 0,RS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,G2,G3,
238/* 70 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239/* 80 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240/* 90 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241/* a0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242/* b0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243/* c0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244/* d0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245/* e0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246/* f0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
247},
248
249/*
250 * State table for ESC ()*+ C processing (state == CSDES)
251 */
252{
253             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
254/* 00 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256/* 20 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257/* 30 */       C2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258/* 40 */        0,C2,C2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259/* 50 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260/* 60 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261/* 70 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262/* 80 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263/* 90 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264/* a0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265/* b0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266/* c0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
267/* d0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
268/* e0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269/* f0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
270},
271
272/*
273 * State table for ESC [ processing (state == N1)
274 */
275{
276             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
277/* 00 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279/* 20 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280/* 30 */       Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg, 0,Sc, 0, 0, 0,E3,
281/* 40 */       IC,UP,DN,RT,LT, 0, 0, 0,CM, 0,ED,EL,IL,DL, 0, 0,
282/* 50 */       DC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283/* 60 */        0, 0, 0,DA, 0, 0,CM,TC,SM, 0, 0, 0,RM,SG,SR, 0,
284/* 70 */        0, 0,SS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285/* 80 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286/* 90 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287/* a0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
288/* b0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289/* c0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290/* d0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291/* e0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292/* f0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
293},
294
295/*
296 * State table for ESC [ ? processing (state == DECP)
297 */
298{
299             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
300/* 00 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302/* 20 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303/* 30 */       Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg, 0, 0, 0, 0, 0, 0,
304/* 40 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305/* 50 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306/* 60 */        0, 0, 0, 0, 0, 0, 0, 0,DS, 0, 0, 0,DR, 0, 0, 0,
307/* 70 */        0, 0,DT,DV, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308/* 80 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309/* 90 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310/* a0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311/* b0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312/* c0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313/* d0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314/* e0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315/* f0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
316},
317
318/*
319 * State table for ESC ] processing (state == TEXT)
320 */
321{
322             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
323/* 00 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
324/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
325/* 20 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
326/* 30 */       Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg,Dg, 0,T2, 0, 0, 0, 0,
327/* 40 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328/* 50 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329/* 60 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330/* 70 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331/* 80 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332/* 90 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333/* a0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334/* b0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335/* c0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336/* d0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337/* e0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338/* f0 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
339},
340
341/*
342 * State table for ESC ] n ; processing (state == TEXT2)
343 */
344{
345             /* 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  */
346/* 00 */        0, 0, 0, 0, 0, 0, 0,TB, 0, 0, 0, 0, 0, 0, 0, 0,
347/* 10 */        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
348/* 20 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
349/* 30 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
350/* 40 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
351/* 50 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
352/* 60 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
353/* 70 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,Xx,
354/* 80 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
355/* 90 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
356/* a0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
357/* b0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
358/* c0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
359/* d0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
360/* e0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,
361/* f0 */       TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX,TX
362},
363};
364
365/* Character sets. */
366#define CS_G0           0
367#define CS_G1           1
368#define CS_G2           2
369#define CS_G3           3
370
371/* Character set designations. */
372#define CSD_LD          0
373#define CSD_UK          1
374#define CSD_US          2
375
376static int      saved_cursor = 0;
377#define NN      20
378static int      n[NN], nx = 0;
379#define NT      256
380static char     text[NT + 1];
381static int      tx = 0;
382static int      ansi_ch;
383static unsigned char gr = 0;
384static unsigned char saved_gr = 0;
385static unsigned char fg = 0;
386static unsigned char saved_fg = 0;
387static unsigned char bg = 0;
388static unsigned char saved_bg = 0;
389static int      cset = CS_G0;
390static int      saved_cset = CS_G0;
391static int      csd[4] = { CSD_US, CSD_US, CSD_US, CSD_US };
392static int      saved_csd[4] = { CSD_US, CSD_US, CSD_US, CSD_US };
393static int      once_cset = -1;
394static int      insert_mode = 0;
395static int      auto_newline_mode = 0;
396static int      appl_cursor = 0;
397static int      saved_appl_cursor = 0;
398static int      wraparound_mode = 1;
399static int      saved_wraparound_mode = 1;
400static int      rev_wraparound_mode = 0;
401static int      saved_rev_wraparound_mode = 0;
402static Boolean  saved_altbuffer = False;
403static int      scroll_top = -1;
404static int      scroll_bottom = -1;
405static unsigned char *tabs = (unsigned char *) NULL;
406static char     gnnames[] = "()*+";
407static char     csnames[] = "0AB";
408static int      cs_to_change;
409
410static Boolean  held_wrap = False;
411
412static void     ansi_scroll();
413
414static enum state
415ansi_data_mode()
416{
417        return DATA;
418}
419
420static enum state
421dec_save_cursor()
422{
423        int i;
424
425        saved_cursor = cursor_addr;
426        saved_cset = cset;
427        for (i = 0; i < 4; i++)
428                saved_csd[i] = csd[i];
429        saved_fg = fg;
430        saved_bg = bg;
431        saved_gr = gr;
432        return DATA;
433}
434
435static enum state
436dec_restore_cursor()
437{
438        int i;
439
440        cset = saved_cset;
441        for (i = 0; i < 4; i++)
442                csd[i] = saved_csd[i];
443        fg = saved_fg;
444        bg = saved_bg;
445        gr = saved_gr;
446        cursor_move(saved_cursor);
447        held_wrap = False;
448        return DATA;
449}
450
451static enum state
452ansi_newline()
453{
454        int nc;
455
456        cursor_move(cursor_addr - (cursor_addr % COLS));
457        nc = cursor_addr + COLS;
458        if (nc < scroll_bottom * COLS)
459                cursor_move(nc);
460        else
461                ansi_scroll();
462        held_wrap = False;
463        return DATA;
464}
465
466static enum state
467ansi_cursor_up(nn)
468int nn;
469{
470        int rr;
471
472        if (nn < 1)
473                nn = 1;
474        rr = cursor_addr / COLS;
475        if (rr - nn < 0)
476                cursor_move(cursor_addr % COLS);
477        else
478                cursor_move(cursor_addr - (nn * COLS));
479        held_wrap = False;
480        return DATA;
481}
482
483static enum state
484ansi_esc2()
485{
486        register int    i;
487
488        for (i = 0; i < NN; i++)
489                n[i] = 0;
490        nx = 0;
491        return N1;
492}
493
494static enum state
495ansi_reset()
496{
497        int i;
498        static Boolean first = True;
499
500        gr = 0;
501        saved_gr = 0;
502        fg = 0;
503        saved_fg = 0;
504        bg = 0;
505        saved_bg = 0;
506        cset = CS_G0;
507        saved_cset = CS_G0;
508        csd[0] = csd[1] = csd[2] = csd[3] = CSD_US;
509        saved_csd[0] = saved_csd[1] = saved_csd[2] = saved_csd[3] = CSD_US;
510        once_cset = -1;
511        saved_cursor = 0;
512        insert_mode = 0;
513        auto_newline_mode = 0;
514        appl_cursor = 0;
515        saved_appl_cursor = 0;
516        wraparound_mode = 1;
517        saved_wraparound_mode = 1;
518        rev_wraparound_mode = 0;
519        saved_rev_wraparound_mode = 0;
520        saved_altbuffer = False;
521        scroll_top = 1;
522        scroll_bottom = ROWS;
523        if (tabs == (unsigned char *)NULL)
524                XtFree((char *)tabs);
525        tabs = (unsigned char *)XtMalloc((COLS+7)/8);
526        for (i = 0; i < (COLS+7)/8; i++)
527                tabs[i] = 0x01;
528        held_wrap = False;
529        if (!first) {
530                ctlr_altbuffer(True);
531                ctlr_aclear(0, ROWS * COLS, 1);
532                ctlr_altbuffer(False);
533                ctlr_clear(False);
534        }
535        first = False;
536        return DATA;
537}
538
539static enum state
540ansi_insert_chars(nn)
541int nn;
542{
543        int cc = cursor_addr % COLS;    /* current col */
544        int mc = COLS - cc;             /* max chars that can be inserted */
545        int ns;                         /* chars that are shifting */
546
547        if (nn < 1)
548                nn = 1;
549        if (nn > mc)
550                nn = mc;
551
552        /* Move the surviving chars right */
553        ns = mc - nn;
554        if (ns)
555                ctlr_bcopy(cursor_addr, cursor_addr + nn, ns, 1);
556
557        /* Clear the middle of the line */
558        ctlr_aclear(cursor_addr, nn, 1);
559        return DATA;
560}
561
562static enum state
563ansi_cursor_down(nn)
564int nn;
565{
566        int rr;
567
568        if (nn < 1)
569                nn = 1;
570        rr = cursor_addr / COLS;
571        if (rr + nn >= ROWS)
572                cursor_move((ROWS-1)*COLS + (cursor_addr%COLS));
573        else
574                cursor_move(cursor_addr + (nn * COLS));
575        held_wrap = False;
576        return DATA;
577}
578
579static enum state
580ansi_cursor_right(nn)
581int nn;
582{
583        int cc;
584
585        if (nn < 1)
586                nn = 1;
587        cc = cursor_addr % COLS;
588        if (cc == COLS-1)
589                return DATA;
590        if (cc + nn >= COLS)
591                nn = COLS - 1 - cc;
592        cursor_move(cursor_addr + nn);
593        held_wrap = False;
594        return DATA;
595}
596
597static enum state
598ansi_cursor_left(nn)
599int nn;
600{
601        int cc;
602
603        if (held_wrap) {
604                held_wrap = False;
605                return DATA;
606        }
607        if (nn < 1)
608                nn = 1;
609        cc = cursor_addr % COLS;
610        if (!cc)
611                return DATA;
612        if (nn > cc)
613                nn = cc;
614        cursor_move(cursor_addr - nn);
615        return DATA;
616}
617
618static enum state
619ansi_cursor_motion(n1, n2)
620int n1, n2;
621{
622        if (n1 < 1) n1 = 1;
623        if (n1 > ROWS) n1 = ROWS;
624        if (n2 < 1) n2 = 1;
625        if (n2 > COLS) n2 = COLS;
626        cursor_move((n1 - 1) * COLS + (n2 - 1));
627        held_wrap = False;
628        return DATA;
629}
630
631static enum state
632ansi_erase_in_display(nn)
633int nn;
634{
635        switch (nn) {
636            case 0:     /* below */
637                ctlr_aclear(cursor_addr, (ROWS * COLS) - cursor_addr, 1);
638                break;
639            case 1:     /* above */
640                ctlr_aclear(0, cursor_addr + 1, 1);
641                break;
642            case 2:     /* all (without moving cursor) */
643                if (cursor_addr == 0 && !is_altbuffer)
644                        scroll_save(ROWS, True);
645                ctlr_aclear(0, ROWS * COLS, 1);
646                break;
647        }
648        return DATA;
649}
650
651static enum state
652ansi_erase_in_line(nn)
653int nn;
654{
655        int nc = cursor_addr % COLS;
656
657        switch (nn) {
658            case 0:     /* to right */
659                ctlr_aclear(cursor_addr, COLS - nc, 1);
660                break;
661            case 1:     /* to left */
662                ctlr_aclear(cursor_addr - nc, nc+1, 1);
663                break;
664            case 2:     /* all */
665                ctlr_aclear(cursor_addr - nc, COLS, 1);
666                break;
667        }
668        return DATA;
669}
670
671static enum state
672ansi_insert_lines(nn)
673int nn;
674{
675        int rr = cursor_addr / COLS;    /* current row */
676        int mr = scroll_bottom - rr;    /* rows left at and below this one */
677        int ns;                         /* rows that are shifting */
678
679        /* If outside of the scrolling region, do nothing */
680        if (rr < scroll_top - 1 || rr >= scroll_bottom)
681                return DATA;
682
683        if (nn < 1)
684                nn = 1;
685        if (nn > mr)
686                nn = mr;
687       
688        /* Move the victims down */
689        ns = mr - nn;
690        if (ns)
691                ctlr_bcopy(rr * COLS, (rr + nn) * COLS, ns * COLS, 1);
692
693        /* Clear the middle of the screen */
694        ctlr_aclear(rr * COLS, nn * COLS, 1);
695        return DATA;
696}
697
698static enum state
699ansi_delete_lines(nn)
700int nn;
701{
702        int rr = cursor_addr / COLS;    /* current row */
703        int mr = scroll_bottom - rr;    /* max rows that can be deleted */
704        int ns;                         /* rows that are shifting */
705
706        /* If outside of the scrolling region, do nothing */
707        if (rr < scroll_top - 1 || rr >= scroll_bottom)
708                return DATA;
709
710        if (nn < 1)
711                nn = 1;
712        if (nn > mr)
713                nn = mr;
714
715        /* Move the surviving rows up */
716        ns = mr - nn;
717        if (ns)
718                ctlr_bcopy((rr + nn) * COLS, rr * COLS, ns * COLS, 1);
719
720        /* Clear the rest of the screen */
721        ctlr_aclear((rr + ns) * COLS, nn * COLS, 1);
722        return DATA;
723}
724
725static enum state
726ansi_delete_chars(nn)
727int nn;
728{
729        int cc = cursor_addr % COLS;    /* current col */
730        int mc = COLS - cc;             /* max chars that can be deleted */
731        int ns;                         /* chars that are shifting */
732
733        if (nn < 1)
734                nn = 1;
735        if (nn > mc)
736                nn = mc;
737
738        /* Move the surviving chars left */
739        ns = mc - nn;
740        if (ns)
741                ctlr_bcopy(cursor_addr + nn, cursor_addr, ns, 1);
742
743        /* Clear the end of the line */
744        ctlr_aclear(cursor_addr + ns, nn, 1);
745        return DATA;
746}
747
748static enum state
749ansi_sgr()
750{
751        int i;
752
753        for (i = 0; i <= nx && i < NN; i++)
754            switch (n[i]) {
755                case 0:
756                    gr = 0;
757                    fg = 0;
758                    bg = 0;
759                    break;
760                case 1:
761                    gr |= GR_INTENSIFY;
762                    break;
763                case 4:
764                    gr |= GR_UNDERLINE;
765                    break;
766                case 5:
767                    gr |= GR_BLINK;
768                    break;
769                case 7:
770                    gr |= GR_REVERSE;
771                    break;
772                case 30:
773                    fg = 0xf0;  /* black */
774                    break;
775                case 31:
776                    fg = 0xf2;  /* red */
777                    break;
778                case 32:
779                    fg = 0xf4;  /* green */
780                    break;
781                case 33:
782                    fg = 0xf6;  /* yellow */
783                    break;
784                case 34:
785                    fg = 0xf1;  /* blue */
786                    break;
787                case 35:
788                    fg = 0xf3;  /* megenta */
789                    break;
790                case 36:
791                    fg = 0xfd;  /* cyan */
792                    break;
793                case 37:
794                    fg = 0xff;  /* white */
795                    break;
796                case 39:
797                    fg = 0;     /* default */
798                    break;
799                case 40:
800                    bg = 0xf0;  /* black */
801                    break;
802                case 41:
803                    bg = 0xf2;  /* red */
804                    break;
805                case 42:
806                    bg = 0xf4;  /* green */
807                    break;
808                case 43:
809                    bg = 0xf6;  /* yellow */
810                    break;
811                case 44:
812                    bg = 0xf1;  /* blue */
813                    break;
814                case 45:
815                    bg = 0xf3;  /* megenta */
816                    break;
817                case 46:
818                    bg = 0xfd;  /* cyan */
819                    break;
820                case 47:
821                    bg = 0xff;  /* white */
822                    break;
823                case 49:
824                    bg = 0;     /* default */
825                    break;
826            }
827
828        return DATA;
829}
830
831static enum state
832ansi_bell()
833{
834        ring_bell();
835        return DATA;
836}
837
838static enum state
839ansi_newpage()
840{
841        ctlr_clear(False);
842        return DATA;
843}
844
845static enum state
846ansi_backspace()
847{
848        if (held_wrap) {
849                held_wrap = False;
850                return DATA;
851        }
852        if (rev_wraparound_mode) {
853                if (cursor_addr > (scroll_top - 1) * COLS)
854                        cursor_move(cursor_addr - 1);
855        } else {
856                if (cursor_addr % COLS)
857                        cursor_move(cursor_addr - 1);
858        }
859        return DATA;
860}
861
862static enum state
863ansi_cr()
864{
865        if (cursor_addr % COLS)
866                cursor_move(cursor_addr - (cursor_addr % COLS));
867        if (auto_newline_mode)
868                (void) ansi_lf();
869        held_wrap = False;
870        return DATA;
871}
872
873static enum state
874ansi_lf()
875{
876        int nc = cursor_addr + COLS;
877
878        held_wrap = False;
879
880        /* If we're below the scrolling region, don't scroll. */
881        if ((cursor_addr / COLS) >= scroll_bottom) {
882                if (nc < ROWS * COLS)
883                        cursor_move(nc);
884                return DATA;
885        }
886
887        if (nc < scroll_bottom * COLS)
888                cursor_move(nc);
889        else
890                ansi_scroll();
891        return DATA;
892}
893
894static enum state
895ansi_htab()
896{
897        int col = cursor_addr % COLS;
898        int i;
899
900        held_wrap = False;
901        if (col == COLS-1)
902                return DATA;
903        for (i = col+1; i < COLS-1; i++)
904                if (tabs[i/8] & 1<<(i%8))
905                        break;
906        cursor_move(cursor_addr - col + i);
907        return DATA;
908}
909
910static enum state
911ansi_escape()
912{
913        return ESC;
914}
915
916static enum state
917ansi_nop()
918{
919        return DATA;
920}
921
922#define PWRAP { \
923    nc = cursor_addr + 1; \
924    if (nc < scroll_bottom * COLS) \
925            cursor_move(nc); \
926    else { \
927            if (cursor_addr / COLS >= scroll_bottom) \
928                    cursor_move(cursor_addr / COLS * COLS); \
929            else { \
930                    ansi_scroll(); \
931                    cursor_move(nc - COLS); \
932            } \
933    } \
934}
935
936static enum state
937ansi_printing()
938{
939        int nc;
940
941        if (held_wrap) {
942                PWRAP;
943                held_wrap = False;
944        }
945
946        if (insert_mode)
947                (void) ansi_insert_chars(1);
948        switch (csd[(once_cset != -1) ? once_cset : cset]) {
949            case CSD_LD:        /* line drawing "0" */
950                if (ansi_ch >= 0x5f && ansi_ch <= 0x7e)
951                        ctlr_add(cursor_addr, (unsigned char)(ansi_ch - 0x5f),
952                            2);
953                else
954                        ctlr_add(cursor_addr, asc2cg[ansi_ch], 0);
955                break;
956            case CSD_UK:        /* UK "A" */
957                if (ansi_ch == '#')
958                        ctlr_add(cursor_addr, 0x1e, 2);
959                else
960                        ctlr_add(cursor_addr, asc2cg[ansi_ch], 0);
961                break;
962            case CSD_US:        /* US "B" */
963                ctlr_add(cursor_addr, asc2cg[ansi_ch], 0);
964                break;
965        }
966        once_cset = -1;
967        ctlr_add_gr(cursor_addr, gr);
968        ctlr_add_fg(cursor_addr, fg);
969        ctlr_add_bg(cursor_addr, bg);
970        if (wraparound_mode) {
971                /*
972                 * There is a fascinating behavior of xterm which we will
973                 * attempt to emulate here.  When a character is printed in the
974                 * last column, the cursor sticks there, rather than wrapping
975                 * to the next line.  Another printing character will put the
976                 * cursor in column 2 of the next line.  One cursor-left
977                 * sequence won't budge it; two will.  Saving and restoring
978                 * the cursor won't move the cursor, but will cancel all of
979                 * the above behaviors...
980                 *
981                 * In my opinion, very strange, but among other things, 'vi'
982                 * depends on it!
983                 */
984                if (!((cursor_addr + 1) % COLS)) {
985                        held_wrap = True;
986                } else {
987                        PWRAP;
988                }
989        } else {
990                if ((cursor_addr % COLS) != (COLS - 1))
991                        cursor_move(cursor_addr + 1);
992        }
993        return DATA;
994}
995
996static enum state
997ansi_semicolon()
998{
999        if (nx >= NN)
1000                return DATA;
1001        nx++;
1002        return state;
1003}
1004
1005static enum state
1006ansi_digit()
1007{
1008        n[nx] = (n[nx] * 10) + (ansi_ch - '0');
1009        return state;
1010}
1011
1012static enum state
1013ansi_reverse_index()
1014{
1015        int rr = cursor_addr / COLS;    /* current row */
1016        int np = (scroll_top - 1) - rr; /* number of rows in the scrolling
1017                                           region, above this line */
1018        int ns;                         /* number of rows to scroll */
1019        int nn = 1;                     /* number of rows to index */
1020
1021        held_wrap = False;
1022
1023        /* If the cursor is above the scrolling region, do a simple margined
1024           cursor up.  */
1025        if (np < 0) {
1026                (void) ansi_cursor_up(nn);
1027                return DATA;
1028        }
1029
1030        /* Split the number of lines to scroll into ns */
1031        if (nn > np) {
1032                ns = nn - np;
1033                nn = np;
1034        } else
1035                ns = 0;
1036
1037        /* Move the cursor up without scrolling */
1038        if (nn)
1039                (void) ansi_cursor_up(nn);
1040
1041        /* Insert lines at the top for backward scroll */
1042        if (ns)
1043                (void) ansi_insert_lines(ns);
1044
1045        return DATA;
1046}
1047
1048static enum state
1049ansi_send_attributes(nn)
1050int nn;
1051{
1052        if (!nn)
1053                net_sends("\033[?1;2c");
1054        return DATA;
1055}
1056
1057static enum state
1058dec_return_terminal_id()
1059{
1060        return ansi_send_attributes(0);
1061}
1062
1063static enum state
1064ansi_set_mode(nn)
1065int nn;
1066{
1067        switch (nn) {
1068            case 4:
1069                insert_mode = 1;
1070                break;
1071            case 20:
1072                auto_newline_mode = 1;
1073                break;
1074        }
1075        return DATA;
1076}
1077
1078static enum state
1079ansi_reset_mode(nn)
1080int nn;
1081{
1082        switch (nn) {
1083            case 4:
1084                insert_mode = 0;
1085                break;
1086            case 20:
1087                auto_newline_mode = 0;
1088                break;
1089        }
1090        return DATA;
1091}
1092
1093static enum state
1094ansi_status_report(nn)
1095int nn;
1096{
1097        static char cpr[11];
1098
1099        switch (nn) {
1100            case 5:
1101                net_sends("\033[0n");
1102                break;
1103            case 6:
1104                (void) sprintf(cpr, "\033[%d;%dR",
1105                    (cursor_addr/COLS) + 1, (cursor_addr%COLS) + 1);
1106                net_sends(cpr);
1107                break;
1108        }
1109        return DATA;
1110}
1111
1112static enum state
1113ansi_cs_designate()
1114{
1115        cs_to_change = strchr(gnnames, ansi_ch) - gnnames;
1116        return CSDES;
1117}
1118
1119static enum state
1120ansi_cs_designate2()
1121{
1122        csd[cs_to_change] = strchr(csnames, ansi_ch) - csnames;
1123        return DATA;
1124}
1125
1126static enum state
1127ansi_select_g0()
1128{
1129        cset = CS_G0;
1130        return DATA;
1131}
1132
1133static enum state
1134ansi_select_g1()
1135{
1136        cset = CS_G1;
1137        return DATA;
1138}
1139
1140static enum state
1141ansi_select_g2()
1142{
1143        cset = CS_G2;
1144        return DATA;
1145}
1146
1147static enum state
1148ansi_select_g3()
1149{
1150        cset = CS_G3;
1151        return DATA;
1152}
1153
1154static enum state
1155ansi_one_g2()
1156{
1157        once_cset = CS_G2;
1158        return DATA;
1159}
1160
1161static enum state
1162ansi_one_g3()
1163{
1164        once_cset = CS_G3;
1165        return DATA;
1166}
1167
1168static enum state
1169ansi_esc3()
1170{
1171        return DECP;
1172}
1173
1174static enum state
1175dec_set()
1176{
1177        int i;
1178
1179        for (i = 0; i <= nx && i < NN; i++)
1180                switch (n[i]) {
1181                    case 1:     /* application cursor keys */
1182                        appl_cursor = 1;
1183                        break;
1184                    case 2:     /* set G0-G3 */
1185                        csd[0] = csd[1] = csd[2] = csd[3] = CSD_US;
1186                        break;
1187                    case 7:     /* wraparound mode */
1188                        wraparound_mode = 1;
1189                        break;
1190                    case 45:    /* reverse-wraparound mode */
1191                        rev_wraparound_mode = 1;
1192                        break;
1193                    case 47:    /* alt buffer */
1194                        ctlr_altbuffer(True);
1195                        break;
1196                }
1197        return DATA;
1198}
1199
1200static enum state
1201dec_reset()
1202{
1203        int i;
1204
1205        for (i = 0; i <= nx && i < NN; i++)
1206                switch (n[i]) {
1207                    case 1:     /* normal cursor keys */
1208                        appl_cursor = 0;
1209                        break;
1210                    case 7:     /* no wraparound mode */
1211                        wraparound_mode = 0;
1212                        break;
1213                    case 45:    /* no reverse-wraparound mode */
1214                        rev_wraparound_mode = 0;
1215                        break;
1216                    case 47:    /* alt buffer */
1217                        ctlr_altbuffer(False);
1218                        break;
1219                }
1220        return DATA;
1221}
1222
1223static enum state
1224dec_save()
1225{
1226        int i;
1227
1228        for (i = 0; i <= nx && i < NN; i++)
1229                switch (n[i]) {
1230                    case 1:     /* application cursor keys */
1231                        saved_appl_cursor = appl_cursor;
1232                        break;
1233                    case 7:     /* wraparound mode */
1234                        saved_wraparound_mode = wraparound_mode;
1235                        break;
1236                    case 45:    /* reverse-wraparound mode */
1237                        saved_rev_wraparound_mode = rev_wraparound_mode;
1238                        break;
1239                    case 47:    /* alt buffer */
1240                        saved_altbuffer = is_altbuffer;
1241                        break;
1242                }
1243        return DATA;
1244}
1245
1246static enum state
1247dec_restore()
1248{
1249        int i;
1250
1251        for (i = 0; i <= nx && i < NN; i++)
1252                switch (n[i]) {
1253                    case 1:     /* application cursor keys */
1254                        appl_cursor = saved_appl_cursor;
1255                        break;
1256                    case 7:     /* wraparound mode */
1257                        wraparound_mode = saved_wraparound_mode;
1258                        break;
1259                    case 45:    /* reverse-wraparound mode */
1260                        rev_wraparound_mode = saved_rev_wraparound_mode;
1261                        break;
1262                    case 47:    /* alt buffer */
1263                        ctlr_altbuffer(saved_altbuffer);
1264                        break;
1265                }
1266        return DATA;
1267}
1268
1269static enum state
1270dec_scrolling_region(top, bottom)
1271int top, bottom;
1272{
1273        if (top < 1)
1274                top = 1;
1275        if (bottom > ROWS)
1276                bottom = ROWS;
1277        if (top <= bottom && (top > 1 || bottom < ROWS)) {
1278                scroll_top = top;
1279                scroll_bottom = bottom;
1280                cursor_move(0);
1281        } else {
1282                scroll_top = 1;
1283                scroll_bottom = ROWS;
1284        }
1285        return DATA;
1286}
1287
1288static enum state
1289xterm_text_mode()
1290{
1291        nx = 0;
1292        n[0] = 0;
1293        return TEXT;
1294}
1295
1296static enum state
1297xterm_text_semicolon()
1298{
1299        tx = 0;
1300        return TEXT2;
1301}
1302
1303static enum state
1304xterm_text()
1305{
1306        if (tx < NT)
1307                text[tx++] = ansi_ch;
1308        return state;
1309}
1310
1311static enum state
1312xterm_text_do()
1313{
1314        text[tx] = '\0';
1315
1316        switch (n[0]) {
1317            case 0:     /* icon name and window title */
1318                XtVaSetValues(toplevel, XtNiconName, text, NULL);
1319                XtVaSetValues(toplevel, XtNtitle, text, NULL);
1320                break;
1321            case 1:     /* icon name */
1322                XtVaSetValues(toplevel, XtNiconName, text, NULL);
1323                break;
1324            case 2:     /* window_title */
1325                XtVaSetValues(toplevel, XtNtitle, text, NULL);
1326                break;
1327            case 50:    /* font */
1328                screen_newfont(text, False);
1329                break;
1330        }
1331        return DATA;
1332}
1333
1334static enum state
1335ansi_htab_set()
1336{
1337        register int col = cursor_addr % COLS;
1338
1339        tabs[col/8] |= 1<<(col%8);
1340        return DATA;
1341}
1342
1343static enum state
1344ansi_htab_clear(nn)
1345int nn;
1346{
1347        register int col, i;
1348
1349        switch (nn) {
1350            case 0:
1351                col = cursor_addr % COLS;
1352                tabs[col/8] &= ~(1<<(col%8));
1353                break;
1354            case 3:
1355                for (i = 0; i < (COLS+7)/8; i++)
1356                        tabs[i] = 0;
1357                break;
1358        }
1359        return DATA;
1360}
1361
1362/*
1363 * Scroll the screen or the scrolling region.
1364 */
1365static void
1366ansi_scroll()
1367{
1368        held_wrap = False;
1369
1370        /* Save the top line */
1371        if (scroll_top == 1 && scroll_bottom == ROWS) {
1372                if (!is_altbuffer)
1373                        scroll_save(1, False);
1374                ctlr_scroll();
1375                return;
1376        }
1377
1378        /* Scroll all but the last line up */
1379        if (scroll_bottom > scroll_top)
1380                ctlr_bcopy(scroll_top * COLS,
1381                    (scroll_top - 1) * COLS,
1382                    (scroll_bottom - scroll_top) * COLS,
1383                    1);
1384
1385        /* Clear the last line */
1386        ctlr_aclear((scroll_bottom - 1) * COLS, COLS, 1);
1387}
1388
1389
1390/*
1391 * External entry points
1392 */
1393
1394void
1395ansi_init()
1396{
1397        (void) ansi_reset();
1398}
1399
1400void
1401ansi_process(c)
1402unsigned int c;
1403{
1404        c &= 0xff;
1405        ansi_ch = c;
1406
1407        scroll_to_bottom();
1408
1409        if (toggled(SCREEN_TRACE))
1410                trace_char((char)c);
1411
1412        state = (*ansi_fn[st[(int)state][c]])(n[0], n[1]);
1413}
1414
1415void
1416ansi_send_up()
1417{
1418        if (appl_cursor)
1419                net_sends("\033OA");
1420        else
1421                net_sends("\033[A");
1422}
1423
1424void
1425ansi_send_down()
1426{
1427        if (appl_cursor)
1428                net_sends("\033OB");
1429        else
1430                net_sends("\033[B");
1431}
1432
1433void
1434ansi_send_right()
1435{
1436        if (appl_cursor)
1437                net_sends("\033OC");
1438        else
1439                net_sends("\033[C");
1440}
1441
1442void
1443ansi_send_left()
1444{
1445        if (appl_cursor)
1446                net_sends("\033OD");
1447        else
1448                net_sends("\033[D");
1449}
1450
1451void
1452ansi_send_home()
1453{
1454        net_sends("\033[H");
1455}
1456
1457void
1458ansi_send_clear()
1459{
1460        net_sends("\033[2K");
1461}
1462
1463void
1464ansi_send_pf(nn)
1465int nn;
1466{
1467        static char fn_buf[6];
1468        static int code[20] = {
1469                11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 23, 24,
1470                25, 26, 28, 29, 31, 32, 33, 34
1471        };
1472
1473        if (nn < 1 || nn > 20)
1474                return;
1475        (void) sprintf(fn_buf, "\033[%d~", code[nn-1]);
1476        net_sends(fn_buf);
1477}
1478
1479void
1480ansi_send_pa(nn)
1481int nn;
1482{
1483        static char fn_buf[4];
1484        static char code[4] = { 'P', 'Q', 'R', 'S' };
1485
1486        if (nn < 1 || nn > 4)
1487                return;
1488        (void) sprintf(fn_buf, "\033O%c", code[nn-1]);
1489        net_sends(fn_buf);
1490}
1491
1492void
1493toggle_lineWrap()
1494{
1495        if (toggled(LINE_WRAP))
1496                wraparound_mode = 1;
1497        else
1498                wraparound_mode = 0;
1499}
Note: See TracBrowser for help on using the repository browser.