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