Oh GACK! src-clean doesn't quite work that easily since cleandist rebuilds the
[unix-history] / sys / i386 / isa / codrv / co_pc3.c
CommitLineData
15637ed4
RG
1/* Copyright 1992 by Holger Veit
2 * May be freely used with Bill Jolitz's port of
3 * 386bsd and may be included in a 386bsd collection
4 * as long as binary and source are available and reproduce the above
5 * copyright.
6 *
7 * You may freely modify this code and contribute improvements based
8 * on this code as long as you don't claim to be the original author.
9 * Commercial use of this source requires permittance of the copyright
10 * holder. A general license for 386bsd will override this restriction.
11 *
12 * Use at your own risk. The copyright holder or any person who makes
13 * this code available for the public (administrators of public archives
14 * for instance) are not responsible for any harm to hardware or software
15 * that might happen due to wrong application or program faults.
16 *
17 * @(#) $RCSfile: co_pc3.c,v $ $Revision: 1.6 $ (Contributed to 386bsd) $Date: 93/01/23 23:14:46 $
18 *
19 * History: see CO_HISTORY
20 */
21static char *rcsid = "$Header: /usr/src/sys.386bsd/i386/isa/codrv/RCS/co_pc3.c,v 1.6 93/01/23 23:14:46 root Exp Locker: root $";
22
23/* This file provides a plug-in interface for different terminal emulations.
24 * As a reference, the pc3/pc3x/pc3n/pc3nc interface is shown.
25 *
26 * Programmers are invited to provide different emulations, e.g.
27 * vt100/vt220/vt320, adm3a/adm31, hp262x, etc.
28 *
29 * The following conventions have to be met:
30 *
31 * The video subsystem provides a number of support functions to
32 * manipulate screen data, such as writing to a VTY screen, or moving the
33 * cursor, etc.
34 *
35 * All these routines are named "emul_*". See co_hdr.h for a list of available
36 * facilities. You will see that these are defines to either a set of
37 * "vga_*" or "gfx_*" routines (not yet available). To make a migration to
38 * the future graphics console as smooth as possible, avoid using other
39 * routines to access the screen, even if you know tricky code
40 * that runs 10 times as fast. There is time enough to do optimizations
41 * when the graphics subsystem is running.
42 *
43 ***************************************************************************
44 *
45 * This file contains one central routine, 'vtemul_exec', which is called
46 * by the console driver, with the following arguments:
47 *
48 * vp: Pointer to the actual vty
49 * ch: Character to be processed (note that this is not a "u_char"!)
50 *
51 ***************************************************************************
52 *
53 * A second call is used during coattach: 'vtemul_init', which
54 * can be used for local initialisation. vtemul_init also MUST fill an
55 * identifier into the field 'emul_name' of struct consinfo cons_capabilities.
56 *
57 ***************************************************************************
58 *
59 * Only use the PUBLIC fields in struct vty!
60 * Don't rely on the PRIVATE members of the structure, even if you
61 * can access them (PRIVATE and PUBLIC are #defines only).
62 * The reason is, that a future version may run in graphics mode, and
63 * will interpret these fields in a different way you may think they
64 * might be used. This holds in particular for Crtat and Crtat!!!!
65 *
66 * If you need more special variables, use a local structure
67 * use #include "vty.h" to find out the number of vtys available.
68 * But even in the local structure, don't think that there is
69 * direct accessible video memory, even if using this this speeds up
70 * everything extremely!
71 */
72
73/* example code follows: */
74
75/* check my optional symbol to avoid multiple inclusions */
76#ifdef PC3
77#ifndef MINITERM
78
79#include "co_hdr.h"
80#include "vty.h"
81
82#define ESC_NONE 0 /* No esc in progress */
83#define ESC_WBRAC 1 /* got esc, wait for '[' or 'c' */
84#define ESC_WPARAM 2 /* got esc [, wait for param, ';' or letter */
85
86/* !!! this may look like a Keycap_def, like in co_kbd.c, but isn't ! :-) */
87static struct Keycap2 {
88 short key;
89 u_short type; /* type of key */
90 XCHAR unshift[KBDDEFOVLKEYSIZE+1]; /* default codes */
91 XCHAR shift[KBDDEFOVLKEYSIZE+1];
92 XCHAR ctrl[KBDDEFOVLKEYSIZE+1];
93} pc3keys[] = {
9475, KBD_FUNC, XE3('[','L'), XE3('|','a'), XE3('|','b'), /* INS */
9576, KBD_FUNC, XC1('\177'), XE3('|','c'), XE3('|','d'), /* DEL */
9679, KBD_FUNC, XE3('[','D'), XE3('|','e'), XE3('|','f'), /* CU <- */
9780, KBD_FUNC, XE3('[','H'), XE3('|','g'), XE3('|','h'), /* HOME */
9881, KBD_FUNC, XE3('[','F'), XE3('|','i'), XE3('|','j'), /* END */
9983, KBD_FUNC, XE3('[','A'), XE3('|','k'), XE3('|','l'), /* CU ^ */
10084, KBD_FUNC, XE3('[','B'), XE3('|','m'), XE3('|','n'), /* CU v */
10185, KBD_FUNC, XE3('[','I'), XE3('|','o'), XE3('|','p'), /* PG UP */
10286, KBD_FUNC, XE3('[','G'), XE3('|','q'), XE3('|','r'), /* PG DN */
10389, KBD_FUNC, XE3('[','C'), XE3('|','s'), XE3('|','t'), /* CU -> */
10491, KBD_KP, XC1('7'), XE3('[','H'), XC1('7'),
10592, KBD_KP, XC1('4'), XE3('[','D'), XC1('4'),
10693, KBD_KP, XC1('1'), XE3('[','F'), XC1('1'),
10795, KBD_KP, XC1('/'), XC1('/'), XC1('/'),
10896, KBD_KP, XC1('8'), XE3('[','A'), XC1('8'),
10997, KBD_KP, XC1('5'), XE3('[','E'), XC1('5'),
11098, KBD_KP, XC1('2'), XE3('[','B'), XC1('2'),
11199, KBD_KP, XC1('0'), XE3('[','L'), XC1('0'),
112100, KBD_KP, XC1('*'), XC1('*'), XC1('*'),
113101, KBD_KP, XC1('9'), XE3('[','I'), XC1('9'),
114102, KBD_KP, XC1('6'), XE3('[','C'), XC1('6'),
115103, KBD_KP, XC1('3'), XE3('[','G'), XC1('3'),
116104, KBD_KP, XC1('.'), XC1('\177'), XC1('.'),
117105, KBD_KP, XC1('-'), XC1('-'), XC1('-'),
118106, KBD_KP, XC1('+'), XC1('+'), XC1('+'),
119112, KBD_FUNC, XE3('[','M'), XE3('[','Y'), XE3('[','k'), /* F1 */
120113, KBD_FUNC, XE3('[','N'), XE3('[','Z'), XE3('[','l'), /* F2 */
121114, KBD_FUNC, XE3('[','O'), XE3('[','a'), XE3('[','m'), /* F3 */
122115, KBD_FUNC, XE3('[','P'), XE3('[','b'), XE3('[','n'), /* F4 */
123116, KBD_FUNC, XE3('[','Q'), XE3('[','c'), XE3('[','o'), /* F5 */
124117, KBD_FUNC, XE3('[','R'), XE3('[','d'), XE3('[','p'), /* F6 */
125118, KBD_FUNC, XE3('[','S'), XE3('[','e'), XE3('[','q'), /* F7 */
126119, KBD_FUNC, XE3('[','T'), XE3('[','f'), XE3('[','r'), /* F8 */
127120, KBD_FUNC, XE3('[','U'), XE3('[','g'), XE3('[','s'), /* F9 */
128121, KBD_FUNC, XE3('[','V'), XE3('[','h'), XE3('[','t'), /* F10 */
129122, KBD_FUNC, XE3('[','W'), XE3('[','i'), XE3('[','u'), /* F11 */
130123, KBD_FUNC, XE3('[','X'), XE3('[','j'), XE3('[','v'), /* F12 */
131124, KBD_KP, XE3('[','w'), XE3('[','x'), XE3('[','y'),
1320, KBD_NONE, XC0, XC0, XC0
133};
134
135/*
136 * Do the local initialisations. Notice that many things are already done
137 * in vty_init
138 */
139void vtemul_init()
140{
141 char *c,*id = "pc3n";
142 XCHAR *xc;
143 Keycap_def *kp;
144 struct Keycap2 *k2;
145
146 /* fill the cons_capabilities structure
147 * Don't use strcpy here!
148 */
149 c = id;
150 xc = cons_capabilities.emul_name;
151 while (*xc++ = xc_char2xc(*c++)) ;
152
153#define copydef(src,dst)\
154 xc_bcopy(src,dst,KBDDEFOVLKEYSIZE)
155
156 /* set the function keys new */
157 for (k2 = pc3keys; k2->key; k2++) {
158 kp = &kbd_keytab[k2->key];
159 kp->type = k2->type;
160 kp->ovlptr = 0;
161 copydef(k2->unshift,kp->unshift);
162 copydef(k2->shift,kp->shift);
163 copydef(k2->ctrl,kp->ctrl);
164 }
165}
166
167/*
168 * this routine does all the ESC and character processing stuff
169 */
170void vtemul_exec(struct vty *vp, XCHAR ch)
171{
172 int inccol, par1, par2;
173 int sc = 1; /* do scroll check */
174 u_short at,sat;
175 struct outmode *sk = vp->op;
176
177 /* which attributes do we use? */
178 at = sk->fg_at|sk->bg_at;
179 sat= vp->so_at;
180
181 /* translate to proper font */
182 ch = vga_xlatiso646(vp,&at,&sat,ch);
183
184 switch(ch) {
185 case 016: /* SO, select font 2 */
186 emul_selectfont(vp,2);
187 break;
188 case 017: /* SI, select font 1 */
189 emul_selectfont(vp,1);
190 break;
191 case 0x1B:
192 if(sk->escstate != ESC_NONE)
193 emul_wrtchar(vp,ch,sat);
194 else
195 sk->escstate = ESC_WBRAC;
196 break;
197
198 case '\t':
199 inccol = (8 - vp->col % 8); /* non-destructive tab */
200 emul_cursorrelative(vp,inccol,0);
201 break;
202
203 case '\010':
204 emul_cursorleft(vp, 1);
205 break;
206
207 case '\r':
208 emul_cursorrelative(vp,-vp->col,0);
209 break;
210
211 case '\n':
212 emul_cursorrelative(vp,0,1);
213 break;
214
215 case 0x07:
216 /* different sounds for different vtys possible */
217 sysbeep (vp->pitch, vp->duration);
218 break;
219 default:
220 /* ESC Processing */
221 switch (sk->escstate) {
222
223 default:
224 case ESC_NONE:
225 /* NO ESC, normal processing */
226 emul_wrtchar(vp,ch,vp->so ? sat : at);
227 if (vp->col >= vp->ncol) vp->col = 0;
228 break;
229
230 case ESC_WBRAC:
231 /* has seen ESC, wait for [ or 'c' */
232 if (ch=='[') {
233 sk->escstate = ESC_WPARAM;
234 sk->parcnt = 0;
235 sk->param[0] = 0;
236 sk->param[1] = 0;
237 }
238 else if (ch == 'c') {
239 /* Clear screen & home */
240 emul_clearcursor(vp, 2);
241 emul_cursormove(vp, 0, 0);
242 sk->escstate = ESC_NONE;
243 }
244 else {
245 /* error */
246 sk->escstate = ESC_NONE;
247 emul_wrtchar(vp, ch, sat);
248 }
249 break;
250
251 case ESC_WPARAM: /* has seen ESC [ wait for digit, ';' or letter */
252 if (ch>='0' && ch<='9') {
253 sk->param[sk->parcnt] *= 10;
254 sk->param[sk->parcnt] += ch-'0';
255 }
256 else if (ch==';') {
257 if (sk->parcnt>=2) {
258 sk->escstate = ESC_NONE; /* error */
259 emul_wrtchar(vp,ch,sat);
260 }
261 else {
262 sk->parcnt++;
263 sk->param[sk->parcnt] = 0;
264 }
265 }
266 else if (ch>=' ' && ch<='~') {
267 par1 = sk->param[0];
268 par2 = sk->param[1];
269 sk->parcnt++;
270 sk->param[sk->parcnt] = 0;
271 switch (ch) {
272 case 'A': /* back cx rows */
273 emul_cursorup(vp, par1);
274 sc = 0;
275 break;
276 case 'B': /* down cx rows */
277 emul_cursordown(vp, par1);
278 sc = 0;
279 break;
280 case 'C': /* right cursor */
281 emul_cursorright(vp, par1, 1);
282 sc = 0;
283 break;
284 case 'D': /* left cursor */
285 emul_cursorleft(vp, par1);
286 sc = 0;
287 break;
288 case 'f': /* in system V consoles */
289 case 'H': /* Cursor move */
290 emul_cursormove(vp, par1, par2);
291 break;
292 case 'J': /* Clear ... */
293 emul_clearcursor(vp, par1);
294 break;
295 case 'K': /* Clear line ... */
296 emul_clearline(vp, par1);
297 break;
298 case 'L': /* Insert Line */
299 emul_insertline(vp, par1);
300 break;
301 case 'M': /* Delete Line */
302 emul_deleteline(vp, par1);
303 break;
304 case 'P': /* delete spaces */
305 emul_deletechars(vp, par1);
306 break;
307 case 'S': /* scroll up cx lines */
308 emul_scrollup(vp, par1, 0);
309 break;
310 case 'T': /* scroll down cx lines */
311 emul_scrolldown(vp, par1);
312 break;
313 case 'm': /* standout mode */
314 if (par1) vp->so = 1;
315 else vp->so = 0;
316 break;
317 case 'r':
318 vp->so_at = (par1 & 0x0f) | ((par2 & 0x0f) << 4);
319 break;
320 case 'x': /* set attributes */
321 emul_setattributes(vp, par1, par2);
322 break;
323 case '@': /* insert spaces */
324 emul_insertchars(vp, par1);
325 break;
326 case '!': /* set beep pitch and duration */
327 kbd_cvtsound(par1, &vp->pitch,
328 par2, &vp->duration);
329 break;
330 default:
331 emul_wrtchar(vp,ch,sat);
332 }
333 sk->escstate = ESC_NONE;
334 }
335 break;
336 }
337 }
338
339 if (sc && emul_checkcursor(vp) > 0) {
340 if (consoftc.cs_flags&CO_OPEN)
341 do
342 (void)kbd_sgetc(1);
343 while (vp->scroll);
344
345 emul_scrollup(vp, 1, 1);
346 }
347}
348
349#endif /* !MINITERM */
350#endif /* PC3 */