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