chiark / gitweb /
8a7dc56ebae2ca4abeda216007afb5af0e58ca58
[sympathy.git] / src / vt102.c
1 /*
2  * vt102.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.3  2008/02/04 02:05:06  james
14  * *** empty log message ***
15  *
16  * Revision 1.2  2008/02/04 01:32:39  james
17  * *** empty log message ***
18  *
19  * Revision 1.1  2008/02/03 23:36:41  james
20  * *** empty log message ***
21  *
22  */
23
24
25 /* Termcap he say:
26
27 vt102|dec vt102:\
28         :mi:\
29         :al=\E[L:dc=\E[P:dl=\E[M:ei=\E[4l:im=\E[4h:tc=vt100:
30
31 vt100|vt100-am|dec vt100 (w/advanced video):\
32         :am:bs:ms:xn:xo:\
33         :co#80:it#8:li#24:vt#3:\
34         :DO=\E[%dB:LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:\
35         :UP=\E[%dA:\
36         :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\
37         :ae=^O:as=^N:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\
38         :cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:ct=\E[3g:do=^J:\
39         :eA=\E(B\E)0:ho=\E[H:kb=^H:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\
40         :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:mb=\E[5m:md=\E[1m:\
41         :me=\E[m\017:mr=\E[7m:nd=\E[C:rc=\E8:\
42         :rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:sc=\E7:se=\E[m:\
43         :sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:ue=\E[m:up=\E[A:\
44         :us=\E[4m:tc=vt100+fnkeys:
45
46 vt100+fnkeys|dec vt100 numeric keypad:\
47         :k0=\EOy:k5=\EOt:k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:\
48         :tc=vt100+pfkeys:
49
50 vt100+pfkeys|dec vt100 numeric keypad:\
51         :@8=\EOM:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:tc=vt100+keypad:
52
53 vt100+keypad|dec vt100 numeric keypad no fkeys:\
54         :K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:
55
56 */
57
58 /*
59 so the parser needs to be able to at least do
60 CTRL-G
61 CTRL-H
62 CTRL-I
63 CTRL-J
64 CTRL-M
65 CTRL-N
66 CTRL-O
67
68 ESC7
69 ESC8
70 ESCH
71 ESCM
72 ESC> 
73
74 ESC[%dA
75 ESC[%dB
76 ESC[%dC
77 ESC[%dD
78 ESC[H
79 ESC[%d;%dH
80 ESC[J
81 ESC[K
82 ESC[1K
83 ESC[L
84 ESC[M
85 ESC[P
86
87 ESC[3g
88 ESC[4h
89 ESC[4l
90 ESC[m 
91 ESC[1m
92 ESC[4m
93 ESC[5m
94 ESC[7m
95 ESC[%d;%dr
96
97 ESC(B
98 ESC)0
99
100 ESC[?3l 
101 ESC[?4l 
102 ESC[?5l
103 ESC[?7h
104 ESC[?7h
105 ESC[?7l
106 ESC[?8h
107
108 */
109
110 #include "project.h"
111
112
113 static inline int
114 csi_ender (int c)
115 {
116   if ((c >= 'a') && (c <= 'z'))
117     return 1;
118   if ((c >= 'A') && (c <= 'Z'))
119     return 1;
120   return 0;
121 }
122
123 static inline int
124 csi_starter (int c)
125 {
126   switch (c)
127     {
128     case '[':
129     case '(':
130     case ')':
131       return 1;
132     }
133   return 0;
134 }
135
136 void
137 vt102_cursor_normalize (VT102 * v, int wrap, int scroll)
138 {
139   if (v->pos.x < -1)            /*don't wrap backwards */
140     v->pos.x = 0;
141
142   if (v->pos.x >= CRT_COLS)
143     {
144       if (wrap)
145         {
146           v->pos.x = 0;
147           v->pos.y++;
148         }
149       else
150         {
151           v->pos.x = CRT_COLS - 1;
152         }
153     }
154
155   if (v->pos.y < 0)
156     v->pos.y = 0;
157
158   if (v->pos.y >= CRT_ROWS)
159     {
160       if (scroll)
161         vt102_scroll (v, 0, CRT_ROWS - 1);
162       v->pos.y = CRT_ROWS - 1;
163     }
164 }
165
166
167 void
168 vt102_cursor_motion (VT102 * v, int x, int y, int wrap, int scroll)
169 {
170   while (x > 0)
171     {
172       x--;
173       v->pos.x++;
174       vt102_cursor_normalize (v, wrap, scroll);
175     }
176
177   while (x < 0)
178     {
179       x++;
180       v->pos.x--;
181       vt102_cursor_normalize (v, wrap, scroll);
182     }
183
184   while (y > 0)
185     {
186       y--;
187       v->pos.y++;
188       vt102_cursor_normalize (v, wrap, scroll);
189     }
190
191   while (y < 0)
192     {
193       y++;
194       v->pos.y--;
195       vt102_cursor_normalize (v, wrap, scroll);
196     }
197 }
198
199
200 void
201 vt102_parse_char (VT102 * v, int c)
202 {
203   VT102_parser *p = &v->parser;
204
205
206   if (p->in_csi)
207     {
208       p->csi_buf[p->csi_ptr++] = c;
209       if (csi_ender (c) || (p->csi_ptr == VT102_CSI_LEN))
210         {
211           vt102_parse_csi (v, p->csi_buf, p->csi_ptr);
212           p->in_csi = 0;
213         }
214     }
215   else if (p->in_escape)
216     {
217       if (csi_starter (c))
218         {
219           p->csi_ptr = 0;
220           p->csi_buf[p->csi_ptr++] = c;
221           p->in_csi++;
222           p->in_escape = 0;
223         }
224       else
225         {
226           p->in_escape = 0;
227           vt102_parse_esc (v, c);
228         }
229     }
230   else
231     {
232
233       switch (c)
234         {
235          /*NUL*/ case 0:
236          /*SOH*/ case 1:
237          /*STX*/ case 2:
238          /*ETX*/ case 3:
239          /*EOT*/ case 4:
240          /*ENQ*/ case 5:
241          /*ACK*/ case 6:
242          /*BEL*/ case 7:
243          /*BS*/ case 8:
244           vt102_cursor_motion (v, -1, 0, 0, 0);
245           break;
246          /*HT*/ case 9:
247           break;
248          /*LF*/ case 10:
249           vt102_cursor_motion (v, 0, 1, 0, 1);
250           break;
251          /*VT*/ case 11:
252           break;
253          /*FF*/ case 12:
254           break;
255          /*CR*/ case 13:
256           v->pos.x = 0;
257           break;
258          /*SO*/ case 14:
259          /*SI*/ case 15:
260          /*DLE*/ case 16:
261         /*DC1 */ case 17:
262         /*DC2 */ case 18:
263         /*DC3 */ case 19:
264         /*DC4 */ case 20:
265          /*NAK*/ case 21:
266          /*SYN*/ case 22:
267          /*ETB*/ case 23:
268          /*CAN*/ case 24:
269          /*EM*/ case 25:
270          /*SUB*/ case 26:
271           break;
272          /*ESC*/ case 27:
273           p->in_escape++;
274           return;
275          /*FS*/ case 28:
276          /*GS*/ case 29:
277          /*RS*/ case 30:
278          /*US*/ case 31:
279          /*DEL*/ case 127:
280           break;
281         /*regular character */ default:
282           v->crt.screen[CRT_ADDR_POS (&v->pos)].chr = c;
283           v->crt.screen[CRT_ADDR_POS (&v->pos)].attr = v->attr;
284           vt102_cursor_motion (v, 1, 0, 1, 1);
285         }
286     }
287 }