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