ite.c revision 1.1 1 1.1 mw /*
2 1.1 mw * Copyright (c) 1988 University of Utah.
3 1.1 mw * Copyright (c) 1990 The Regents of the University of California.
4 1.1 mw * All rights reserved.
5 1.1 mw *
6 1.1 mw * This code is derived from software contributed to Berkeley by
7 1.1 mw * the Systems Programming Group of the University of Utah Computer
8 1.1 mw * Science Department.
9 1.1 mw *
10 1.1 mw * Redistribution and use in source and binary forms, with or without
11 1.1 mw * modification, are permitted provided that the following conditions
12 1.1 mw * are met:
13 1.1 mw * 1. Redistributions of source code must retain the above copyright
14 1.1 mw * notice, this list of conditions and the following disclaimer.
15 1.1 mw * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 mw * notice, this list of conditions and the following disclaimer in the
17 1.1 mw * documentation and/or other materials provided with the distribution.
18 1.1 mw * 3. All advertising materials mentioning features or use of this software
19 1.1 mw * must display the following acknowledgement:
20 1.1 mw * This product includes software developed by the University of
21 1.1 mw * California, Berkeley and its contributors.
22 1.1 mw * 4. Neither the name of the University nor the names of its contributors
23 1.1 mw * may be used to endorse or promote products derived from this software
24 1.1 mw * without specific prior written permission.
25 1.1 mw *
26 1.1 mw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 1.1 mw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 1.1 mw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1 mw * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 1.1 mw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 1.1 mw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 1.1 mw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 1.1 mw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 1.1 mw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 1.1 mw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 1.1 mw * SUCH DAMAGE.
37 1.1 mw *
38 1.1 mw * from: Utah $Hdr: ite.c 1.1 90/07/09$
39 1.1 mw *
40 1.1 mw * from: @(#)ite.c 7.6 (Berkeley) 5/16/91
41 1.1 mw * $Id: ite.c,v 1.1 1993/07/05 19:19:43 mw Exp $
42 1.1 mw */
43 1.1 mw
44 1.1 mw /*
45 1.1 mw * Bit-mapped display terminal emulator machine independent code.
46 1.1 mw * This is a very rudimentary. Much more can be abstracted out of
47 1.1 mw * the hardware dependent routines.
48 1.1 mw */
49 1.1 mw #include "ite.h"
50 1.1 mw #if NITE > 0
51 1.1 mw
52 1.1 mw #include "grf.h"
53 1.1 mw
54 1.1 mw #undef NITE
55 1.1 mw #define NITE NGRF
56 1.1 mw
57 1.1 mw #include "param.h"
58 1.1 mw #include "conf.h"
59 1.1 mw #include "proc.h"
60 1.1 mw #include "ioctl.h"
61 1.1 mw #include "tty.h"
62 1.1 mw #include "systm.h"
63 1.1 mw #include "malloc.h"
64 1.1 mw
65 1.1 mw #include "itevar.h"
66 1.1 mw #include "iteioctl.h"
67 1.1 mw #include "kbdmap.h"
68 1.1 mw
69 1.1 mw #include "machine/cpu.h"
70 1.1 mw
71 1.1 mw #ifdef __STDC__
72 1.1 mw /* automatically generated, as you might guess:-) */
73 1.1 mw
74 1.1 mw struct consdev;
75 1.1 mw struct itesw;
76 1.1 mw
77 1.1 mw extern int iteon (dev_t dev, int flag);
78 1.1 mw extern int iteinit (dev_t dev);
79 1.1 mw extern int iteoff (dev_t dev, int flag);
80 1.1 mw extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p);
81 1.1 mw extern int iteclose (dev_t dev, int flag, int mode, struct proc *p);
82 1.1 mw extern int iteread (dev_t dev, struct uio *uio, int flag);
83 1.1 mw extern int itewrite (dev_t dev, struct uio *uio, int flag);
84 1.1 mw extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag);
85 1.1 mw extern int itestart (register struct tty *tp);
86 1.1 mw extern int itefilter (register u_char c, enum caller caller);
87 1.1 mw extern int iteputchar (register int c, dev_t dev);
88 1.1 mw extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
89 1.1 mw extern int itecnprobe (struct consdev *cp);
90 1.1 mw extern int itecninit (struct consdev *cp);
91 1.1 mw extern int itecngetc (dev_t dev);
92 1.1 mw extern int itecnputc (dev_t dev, int c);
93 1.1 mw static void repeat_handler (int a0, int a1);
94 1.1 mw static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n);
95 1.1 mw static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n);
96 1.1 mw static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp, int y, int x);
97 1.1 mw static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp, int y, int x);
98 1.1 mw static void ite_clrline (struct ite_softc *ip, struct itesw *sp, int y, int x);
99 1.1 mw static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp);
100 1.1 mw static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp);
101 1.1 mw static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp);
102 1.1 mw static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n);
103 1.1 mw static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n);
104 1.1 mw static void ite_lf (struct ite_softc *ip, struct itesw *sp);
105 1.1 mw static void ite_crlf (struct ite_softc *ip, struct itesw *sp);
106 1.1 mw static void ite_cr (struct ite_softc *ip, struct itesw *sp);
107 1.1 mw static void ite_rlf (struct ite_softc *ip, struct itesw *sp);
108 1.1 mw static int atoi (const char *cp);
109 1.1 mw static char *index (const char *cp, char ch);
110 1.1 mw static int ite_argnum (struct ite_softc *ip);
111 1.1 mw static int ite_zargnum (struct ite_softc *ip);
112 1.1 mw static void ite_sendstr (struct ite_softc *ip, char *str);
113 1.1 mw static int strncmp (const char *a, const char *b, int l);
114 1.1 mw #endif
115 1.1 mw
116 1.1 mw
117 1.1 mw #define set_attr(ip, attr) ((ip)->attribute |= (attr))
118 1.1 mw #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr))
119 1.1 mw
120 1.1 mw extern int nodev();
121 1.1 mw
122 1.1 mw int customc_scroll(), customc_init(), customc_deinit();
123 1.1 mw int customc_clear(), customc_putc(), customc_cursor();
124 1.1 mw
125 1.1 mw int tiga_scroll(), tiga_init(), tiga_deinit();
126 1.1 mw int tiga_clear(), tiga_putc(), tiga_cursor();
127 1.1 mw
128 1.1 mw
129 1.1 mw struct itesw itesw[] =
130 1.1 mw {
131 1.1 mw customc_init, customc_deinit, customc_clear,
132 1.1 mw customc_putc, customc_cursor, customc_scroll,
133 1.1 mw
134 1.1 mw tiga_init, tiga_deinit, tiga_clear,
135 1.1 mw tiga_putc, tiga_cursor, tiga_scroll,
136 1.1 mw };
137 1.1 mw
138 1.1 mw /*
139 1.1 mw * # of chars are output in a single itestart() call.
140 1.1 mw * If this is too big, user processes will be blocked out for
141 1.1 mw * long periods of time while we are emptying the queue in itestart().
142 1.1 mw * If it is too small, console output will be very ragged.
143 1.1 mw */
144 1.1 mw int iteburst = 64;
145 1.1 mw
146 1.1 mw int nite = NITE;
147 1.1 mw struct tty *kbd_tty = NULL;
148 1.1 mw struct tty ite_cons;
149 1.1 mw struct tty *ite_tty[NITE] = { &ite_cons };
150 1.1 mw struct ite_softc ite_softc[NITE];
151 1.1 mw
152 1.1 mw int itestart();
153 1.1 mw extern int ttrstrt();
154 1.1 mw extern struct tty *constty;
155 1.1 mw
156 1.1 mw /* These are (later..) settable via an ioctl */
157 1.1 mw int start_repeat_timo = 30; /* /100: initial timeout till pressed key repeats */
158 1.1 mw int next_repeat_timo = 5; /* /100: timeout when repeating for next char */
159 1.1 mw
160 1.1 mw /*
161 1.1 mw * Primary attribute buffer to be used by the first bitmapped console
162 1.1 mw * found. Secondary displays alloc the attribute buffer as needed.
163 1.1 mw * Size is based on a 68x128 display, which is currently our largest.
164 1.1 mw */
165 1.1 mw u_char console_attributes[0x2200];
166 1.1 mw
167 1.1 mw /*
168 1.1 mw * Perform functions necessary to setup device as a terminal emulator.
169 1.1 mw */
170 1.1 mw iteon(dev, flag)
171 1.1 mw dev_t dev;
172 1.1 mw {
173 1.1 mw int unit = UNIT(dev);
174 1.1 mw struct tty *tp = ite_tty[unit];
175 1.1 mw struct ite_softc *ip = &ite_softc[unit];
176 1.1 mw
177 1.1 mw if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
178 1.1 mw return(ENXIO);
179 1.1 mw /* force ite active, overriding graphics mode */
180 1.1 mw if (flag & 1) {
181 1.1 mw ip->flags |= ITE_ACTIVE;
182 1.1 mw ip->flags &= ~(ITE_INGRF|ITE_INITED);
183 1.1 mw }
184 1.1 mw /* leave graphics mode */
185 1.1 mw if (flag & 2) {
186 1.1 mw ip->flags &= ~ITE_INGRF;
187 1.1 mw if ((ip->flags & ITE_ACTIVE) == 0)
188 1.1 mw return(0);
189 1.1 mw }
190 1.1 mw ip->flags |= ITE_ACTIVE;
191 1.1 mw if (ip->flags & ITE_INGRF)
192 1.1 mw return(0);
193 1.1 mw if (kbd_tty == NULL || kbd_tty == tp) {
194 1.1 mw kbd_tty = tp;
195 1.1 mw kbdenable();
196 1.1 mw }
197 1.1 mw iteinit(dev);
198 1.1 mw return(0);
199 1.1 mw }
200 1.1 mw
201 1.1 mw /* used by the grf layer to reinitialize ite after changing fb parameters */
202 1.1 mw itereinit(dev)
203 1.1 mw dev_t dev;
204 1.1 mw {
205 1.1 mw int unit = UNIT(dev);
206 1.1 mw struct ite_softc *ip = &ite_softc[unit];
207 1.1 mw
208 1.1 mw ip->flags &= ~ITE_INITED;
209 1.1 mw iteinit (dev);
210 1.1 mw }
211 1.1 mw
212 1.1 mw iteinit(dev)
213 1.1 mw dev_t dev;
214 1.1 mw {
215 1.1 mw int unit = UNIT(dev);
216 1.1 mw struct ite_softc *ip = &ite_softc[unit];
217 1.1 mw
218 1.1 mw if (ip->flags & ITE_INITED)
219 1.1 mw return;
220 1.1 mw
221 1.1 mw ip->curx = 0;
222 1.1 mw ip->cury = 0;
223 1.1 mw ip->cursorx = 0;
224 1.1 mw ip->cursory = 0;
225 1.1 mw ip->save_curx = 0;
226 1.1 mw ip->save_cury = 0;
227 1.1 mw ip->ap = ip->argbuf;
228 1.1 mw ip->emul_level = EMUL_VT300_7;
229 1.1 mw ip->eightbit_C1 = 0;
230 1.1 mw ip->inside_margins = 0;
231 1.1 mw ip->linefeed_newline = 0;
232 1.1 mw
233 1.1 mw (*itesw[ip->type].ite_init)(ip);
234 1.1 mw (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
235 1.1 mw
236 1.1 mw /* ip->rows initialized by ite_init above */
237 1.1 mw ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
238 1.1 mw
239 1.1 mw ip->attribute = 0;
240 1.1 mw if (ip->attrbuf == NULL)
241 1.1 mw ip->attrbuf = (u_char *)
242 1.1 mw malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
243 1.1 mw bzero(ip->attrbuf, (ip->rows * ip->cols));
244 1.1 mw
245 1.1 mw ip->imode = 0;
246 1.1 mw ip->flags |= ITE_INITED;
247 1.1 mw }
248 1.1 mw
249 1.1 mw /*
250 1.1 mw * "Shut down" device as terminal emulator.
251 1.1 mw * Note that we do not deinit the console device unless forced.
252 1.1 mw * Deinit'ing the console every time leads to a very active
253 1.1 mw * screen when processing /etc/rc.
254 1.1 mw */
255 1.1 mw iteoff(dev, flag)
256 1.1 mw dev_t dev;
257 1.1 mw {
258 1.1 mw register struct ite_softc *ip = &ite_softc[UNIT(dev)];
259 1.1 mw
260 1.1 mw if (flag & 2)
261 1.1 mw ip->flags |= ITE_INGRF;
262 1.1 mw if ((ip->flags & ITE_ACTIVE) == 0)
263 1.1 mw return;
264 1.1 mw if ((flag & 1) ||
265 1.1 mw (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
266 1.1 mw (*itesw[ip->type].ite_deinit)(ip);
267 1.1 mw if ((flag & 2) == 0)
268 1.1 mw ip->flags &= ~ITE_ACTIVE;
269 1.1 mw }
270 1.1 mw
271 1.1 mw /* ARGSUSED */
272 1.1 mw #ifdef __STDC__
273 1.1 mw iteopen(dev_t dev, int mode, int devtype, struct proc *p)
274 1.1 mw #else
275 1.1 mw iteopen(dev, mode, devtype, p)
276 1.1 mw dev_t dev;
277 1.1 mw int mode, devtype;
278 1.1 mw struct proc *p;
279 1.1 mw #endif
280 1.1 mw {
281 1.1 mw int unit = UNIT(dev);
282 1.1 mw register struct tty *tp;
283 1.1 mw register struct ite_softc *ip = &ite_softc[unit];
284 1.1 mw register int error;
285 1.1 mw int first = 0;
286 1.1 mw
287 1.1 mw if(!ite_tty[unit]) {
288 1.1 mw MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
289 1.1 mw bzero(tp, sizeof(struct tty));
290 1.1 mw ite_tty[unit] = tp;
291 1.1 mw } else
292 1.1 mw tp = ite_tty[unit];
293 1.1 mw
294 1.1 mw if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
295 1.1 mw && p->p_ucred->cr_uid != 0)
296 1.1 mw return (EBUSY);
297 1.1 mw if ((ip->flags & ITE_ACTIVE) == 0) {
298 1.1 mw error = iteon(dev, 0);
299 1.1 mw if (error)
300 1.1 mw return (error);
301 1.1 mw first = 1;
302 1.1 mw }
303 1.1 mw tp->t_oproc = itestart;
304 1.1 mw tp->t_param = NULL;
305 1.1 mw tp->t_dev = dev;
306 1.1 mw if ((tp->t_state&TS_ISOPEN) == 0) {
307 1.1 mw ttychars(tp);
308 1.1 mw tp->t_iflag = TTYDEF_IFLAG;
309 1.1 mw tp->t_oflag = TTYDEF_OFLAG;
310 1.1 mw tp->t_cflag = CS8|CREAD;
311 1.1 mw tp->t_lflag = TTYDEF_LFLAG;
312 1.1 mw tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
313 1.1 mw /* don't set TS_ISOPEN here, or the tty queues won't
314 1.1 mw be initialized in ttyopen()! */
315 1.1 mw tp->t_state = TS_CARR_ON;
316 1.1 mw ttsetwater(tp);
317 1.1 mw }
318 1.1 mw error = (*linesw[tp->t_line].l_open)(dev, tp);
319 1.1 mw if (error == 0) {
320 1.1 mw tp->t_winsize.ws_row = ip->rows;
321 1.1 mw tp->t_winsize.ws_col = ip->cols;
322 1.1 mw } else if (first)
323 1.1 mw iteoff(dev, 0);
324 1.1 mw return (error);
325 1.1 mw }
326 1.1 mw
327 1.1 mw /*ARGSUSED*/
328 1.1 mw iteclose(dev, flag, mode, p)
329 1.1 mw dev_t dev;
330 1.1 mw int flag, mode;
331 1.1 mw struct proc *p;
332 1.1 mw {
333 1.1 mw register struct tty *tp = ite_tty[UNIT(dev)];
334 1.1 mw
335 1.1 mw (*linesw[tp->t_line].l_close)(tp, flag);
336 1.1 mw ttyclose(tp);
337 1.1 mw iteoff(dev, 0);
338 1.1 mw if (tp != &ite_cons)
339 1.1 mw {
340 1.1 mw FREE(tp, M_TTYS);
341 1.1 mw ite_tty[UNIT(dev)] = (struct tty *)NULL;
342 1.1 mw }
343 1.1 mw return(0);
344 1.1 mw }
345 1.1 mw
346 1.1 mw iteread(dev, uio, flag)
347 1.1 mw dev_t dev;
348 1.1 mw struct uio *uio;
349 1.1 mw {
350 1.1 mw register struct tty *tp = ite_tty[UNIT(dev)];
351 1.1 mw int rc;
352 1.1 mw
353 1.1 mw rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag));
354 1.1 mw return rc;
355 1.1 mw }
356 1.1 mw
357 1.1 mw itewrite(dev, uio, flag)
358 1.1 mw dev_t dev;
359 1.1 mw struct uio *uio;
360 1.1 mw {
361 1.1 mw int unit = UNIT(dev);
362 1.1 mw register struct tty *tp = ite_tty[unit];
363 1.1 mw
364 1.1 mw if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
365 1.1 mw (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
366 1.1 mw tp = constty;
367 1.1 mw return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
368 1.1 mw }
369 1.1 mw
370 1.1 mw iteioctl(dev, cmd, addr, flag)
371 1.1 mw dev_t dev;
372 1.1 mw caddr_t addr;
373 1.1 mw {
374 1.1 mw register struct tty *tp = ite_tty[UNIT(dev)];
375 1.1 mw int error;
376 1.1 mw
377 1.1 mw error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
378 1.1 mw if (error >= 0)
379 1.1 mw return (error);
380 1.1 mw error = ttioctl(tp, cmd, addr, flag);
381 1.1 mw if (error >= 0)
382 1.1 mw return (error);
383 1.1 mw return (ENOTTY);
384 1.1 mw }
385 1.1 mw
386 1.1 mw itestart(tp)
387 1.1 mw register struct tty *tp;
388 1.1 mw {
389 1.1 mw register int cc, s;
390 1.1 mw int hiwat = 0;
391 1.1 mw
392 1.1 mw s = spltty();
393 1.1 mw if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
394 1.1 mw splx(s);
395 1.1 mw return;
396 1.1 mw }
397 1.1 mw tp->t_state |= TS_BUSY;
398 1.1 mw cc = RB_LEN (&tp->t_out);
399 1.1 mw if (cc <= tp->t_lowat) {
400 1.1 mw if (tp->t_state & TS_ASLEEP) {
401 1.1 mw tp->t_state &= ~TS_ASLEEP;
402 1.1 mw wakeup(&tp->t_out);
403 1.1 mw }
404 1.1 mw selwakeup(&tp->t_wsel);
405 1.1 mw }
406 1.1 mw /*
407 1.1 mw * Limit the amount of output we do in one burst
408 1.1 mw * to prevent hogging the CPU.
409 1.1 mw */
410 1.1 mw if (cc > iteburst) {
411 1.1 mw hiwat++;
412 1.1 mw cc = iteburst;
413 1.1 mw }
414 1.1 mw while (--cc >= 0) {
415 1.1 mw register int c;
416 1.1 mw
417 1.1 mw c = rbgetc(&tp->t_out);
418 1.1 mw /*
419 1.1 mw * iteputchar() may take a long time and we don't want to
420 1.1 mw * block all interrupts for long periods of time. Since
421 1.1 mw * there is no need to stay at high priority while outputing
422 1.1 mw * the character (since we don't have to worry about
423 1.1 mw * interrupts), we don't. We just need to make sure that
424 1.1 mw * we don't reenter iteputchar, which is guarenteed by the
425 1.1 mw * earlier setting of TS_BUSY.
426 1.1 mw */
427 1.1 mw splx(s);
428 1.1 mw iteputchar(c, tp->t_dev);
429 1.1 mw spltty();
430 1.1 mw }
431 1.1 mw if (hiwat) {
432 1.1 mw tp->t_state |= TS_TIMEOUT;
433 1.1 mw timeout(ttrstrt, tp, 1);
434 1.1 mw }
435 1.1 mw tp->t_state &= ~TS_BUSY;
436 1.1 mw splx(s);
437 1.1 mw }
438 1.1 mw
439 1.1 mw /* these are used to implement repeating keys.. */
440 1.1 mw static u_char last_char = 0;
441 1.1 mw static u_char tout_pending = 0;
442 1.1 mw
443 1.1 mw static void
444 1.1 mw repeat_handler (a0, a1)
445 1.1 mw int a0, a1;
446 1.1 mw {
447 1.1 mw tout_pending = 0;
448 1.1 mw /* leave it up to itefilter() to possible install a new callout entry
449 1.1 mw to reinvoke repeat_handler() */
450 1.1 mw itefilter (last_char, ITEFILT_REPEATER);
451 1.1 mw }
452 1.1 mw
453 1.1 mw
454 1.1 mw int
455 1.1 mw itefilter(c, caller)
456 1.1 mw register u_char c;
457 1.1 mw enum caller caller;
458 1.1 mw {
459 1.1 mw static u_char mod = 0;
460 1.1 mw static u_char last_dead = 0;
461 1.1 mw register char code, *str;
462 1.1 mw u_char up, mask, i;
463 1.1 mw struct key key;
464 1.1 mw
465 1.1 mw if (caller != ITEFILT_CONSOLE && kbd_tty == NULL)
466 1.1 mw return;
467 1.1 mw
468 1.1 mw up = c & 0x80 ? 1 : 0;
469 1.1 mw c &= 0x7f;
470 1.1 mw code = 0;
471 1.1 mw
472 1.1 mw mask = 0;
473 1.1 mw if (c >= KBD_LEFT_SHIFT)
474 1.1 mw {
475 1.1 mw switch (c)
476 1.1 mw {
477 1.1 mw case KBD_LEFT_SHIFT:
478 1.1 mw mask = KBD_MOD_LSHIFT;
479 1.1 mw break;
480 1.1 mw
481 1.1 mw case KBD_RIGHT_SHIFT:
482 1.1 mw mask = KBD_MOD_RSHIFT;
483 1.1 mw break;
484 1.1 mw
485 1.1 mw case KBD_LEFT_ALT:
486 1.1 mw mask = KBD_MOD_LALT;
487 1.1 mw break;
488 1.1 mw
489 1.1 mw case KBD_RIGHT_ALT:
490 1.1 mw mask = KBD_MOD_RALT;
491 1.1 mw break;
492 1.1 mw
493 1.1 mw case KBD_LEFT_META:
494 1.1 mw mask = KBD_MOD_LMETA;
495 1.1 mw break;
496 1.1 mw
497 1.1 mw case KBD_RIGHT_META:
498 1.1 mw mask = KBD_MOD_RMETA;
499 1.1 mw break;
500 1.1 mw
501 1.1 mw case KBD_CAPS_LOCK:
502 1.1 mw /* capslock already behaves `right', don't need to keep track of the
503 1.1 mw state in here. */
504 1.1 mw mask = KBD_MOD_CAPS;
505 1.1 mw break;
506 1.1 mw
507 1.1 mw case KBD_CTRL:
508 1.1 mw mask = KBD_MOD_CTRL;
509 1.1 mw break;
510 1.1 mw }
511 1.1 mw
512 1.1 mw if (mask)
513 1.1 mw {
514 1.1 mw if (up)
515 1.1 mw mod &= ~mask;
516 1.1 mw else
517 1.1 mw mod |= mask;
518 1.1 mw }
519 1.1 mw
520 1.1 mw /* these keys should not repeat, so it's the Right Thing dealing with
521 1.1 mw repeaters only after this block. */
522 1.1 mw
523 1.1 mw /* return even if it wasn't a modifier key, the other codes up here
524 1.1 mw are either special (like reset warning), or not yet defined */
525 1.1 mw return -1;
526 1.1 mw }
527 1.1 mw
528 1.1 mw /* no matter which character we're repeating, stop it if we get a key-up
529 1.1 mw event. I think this is the same thing amigados does. */
530 1.1 mw if (up)
531 1.1 mw {
532 1.1 mw if (tout_pending)
533 1.1 mw {
534 1.1 mw untimeout (repeat_handler, 0);
535 1.1 mw tout_pending = 0;
536 1.1 mw }
537 1.1 mw return -1;
538 1.1 mw }
539 1.1 mw
540 1.1 mw
541 1.1 mw switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT))
542 1.1 mw {
543 1.1 mw case 0:
544 1.1 mw key = kbdmap.keys[c];
545 1.1 mw if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
546 1.1 mw break;
547 1.1 mw /* FALL INTO */
548 1.1 mw
549 1.1 mw case KBD_MOD_LSHIFT:
550 1.1 mw case KBD_MOD_RSHIFT:
551 1.1 mw case KBD_MOD_SHIFT:
552 1.1 mw key = kbdmap.shift_keys[c];
553 1.1 mw break;
554 1.1 mw
555 1.1 mw case KBD_MOD_LALT:
556 1.1 mw case KBD_MOD_RALT:
557 1.1 mw case KBD_MOD_ALT:
558 1.1 mw key = kbdmap.alt_keys[c];
559 1.1 mw if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
560 1.1 mw break;
561 1.1 mw /* FALL INTO */
562 1.1 mw
563 1.1 mw case KBD_MOD_LALT|KBD_MOD_LSHIFT:
564 1.1 mw case KBD_MOD_LALT|KBD_MOD_RSHIFT:
565 1.1 mw case KBD_MOD_LALT|KBD_MOD_SHIFT:
566 1.1 mw case KBD_MOD_RALT|KBD_MOD_RSHIFT:
567 1.1 mw case KBD_MOD_RALT|KBD_MOD_SHIFT:
568 1.1 mw case KBD_MOD_ALT|KBD_MOD_RSHIFT:
569 1.1 mw key = kbdmap.alt_shift_keys[c];
570 1.1 mw break;
571 1.1 mw }
572 1.1 mw
573 1.1 mw code = key.code;
574 1.1 mw
575 1.1 mw /* arrange to repeat the keystroke. By doing this at the level of scan-codes,
576 1.1 mw we can have function keys, and keys that send strings, repeat too. This
577 1.1 mw also entitles an additional overhead, since we have to do the conversion
578 1.1 mw each time, but I guess that's ok. */
579 1.1 mw if (!tout_pending && caller == ITEFILT_TTY)
580 1.1 mw {
581 1.1 mw tout_pending = 1;
582 1.1 mw last_char = c;
583 1.1 mw timeout (repeat_handler, 0, start_repeat_timo);
584 1.1 mw }
585 1.1 mw else if (!tout_pending && caller == ITEFILT_REPEATER)
586 1.1 mw {
587 1.1 mw tout_pending = 1;
588 1.1 mw last_char = c;
589 1.1 mw timeout (repeat_handler, 0, next_repeat_timo);
590 1.1 mw }
591 1.1 mw
592 1.1 mw /* handle dead keys */
593 1.1 mw if (key.mode & KBD_MODE_DEAD)
594 1.1 mw {
595 1.1 mw /* if entered twice, send accent itself */
596 1.1 mw if (last_dead == key.mode & KBD_MODE_ACCMASK)
597 1.1 mw last_dead = 0;
598 1.1 mw else
599 1.1 mw {
600 1.1 mw last_dead = key.mode & KBD_MODE_ACCMASK;
601 1.1 mw return -1;
602 1.1 mw }
603 1.1 mw }
604 1.1 mw if (last_dead)
605 1.1 mw {
606 1.1 mw /* can't apply dead flag to string-keys */
607 1.1 mw if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f)
608 1.1 mw code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@'];
609 1.1 mw
610 1.1 mw last_dead = 0;
611 1.1 mw }
612 1.1 mw
613 1.1 mw /* if not string, apply META and CTRL modifiers */
614 1.1 mw if (! (key.mode & KBD_MODE_STRING))
615 1.1 mw {
616 1.1 mw if (mod & KBD_MOD_CTRL)
617 1.1 mw code &= 0x1f;
618 1.1 mw
619 1.1 mw if (mod & KBD_MOD_META)
620 1.1 mw code |= 0x80;
621 1.1 mw }
622 1.1 mw else
623 1.1 mw {
624 1.1 mw /* strings are only supported in normal tty mode, not in console mode */
625 1.1 mw if (caller != ITEFILT_CONSOLE)
626 1.1 mw {
627 1.1 mw str = kbdmap.strings + code;
628 1.1 mw /* using a length-byte instead of 0-termination allows to embed \0 into
629 1.1 mw strings, although this is not used in the default keymap */
630 1.1 mw for (i = *str++; i; i--)
631 1.1 mw (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
632 1.1 mw }
633 1.1 mw return -1;
634 1.1 mw }
635 1.1 mw
636 1.1 mw if (caller == ITEFILT_CONSOLE)
637 1.1 mw return code;
638 1.1 mw else
639 1.1 mw (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
640 1.1 mw
641 1.1 mw return -1;
642 1.1 mw }
643 1.1 mw
644 1.1 mw
645 1.1 mw /* helper functions, makes the code below more readable */
646 1.1 mw static void inline
647 1.1 mw ite_dnchar(ip, sp, n)
648 1.1 mw struct ite_softc *ip;
649 1.1 mw struct itesw *sp;
650 1.1 mw int n;
651 1.1 mw {
652 1.1 mw (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
653 1.1 mw attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
654 1.1 mw 1, ip->cols - ip->curx - n);
655 1.1 mw attrclr(ip, ip->cury, ip->cols - n, 1, n);
656 1.1 mw while (n--)
657 1.1 mw (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
658 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
659 1.1 mw }
660 1.1 mw
661 1.1 mw static void inline
662 1.1 mw ite_inchar(ip, sp, n)
663 1.1 mw struct ite_softc *ip;
664 1.1 mw struct itesw *sp;
665 1.1 mw int n;
666 1.1 mw {
667 1.1 mw (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
668 1.1 mw attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
669 1.1 mw 1, ip->cols - ip->curx - n);
670 1.1 mw attrclr(ip, ip->cury, ip->curx, 1, n);
671 1.1 mw while (n--)
672 1.1 mw (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
673 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
674 1.1 mw }
675 1.1 mw
676 1.1 mw static void inline
677 1.1 mw ite_clrtoeol(ip, sp, y, x)
678 1.1 mw struct ite_softc *ip;
679 1.1 mw struct itesw *sp;
680 1.1 mw int y, x;
681 1.1 mw {
682 1.1 mw (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
683 1.1 mw attrclr(ip, y, x, 1, ip->cols - x);
684 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
685 1.1 mw }
686 1.1 mw
687 1.1 mw static void inline
688 1.1 mw ite_clrtobol(ip, sp, y, x)
689 1.1 mw struct ite_softc *ip;
690 1.1 mw struct itesw *sp;
691 1.1 mw int y, x;
692 1.1 mw {
693 1.1 mw (*sp->ite_clear)(ip, y, 0, 1, x);
694 1.1 mw attrclr(ip, y, 0, 1, x);
695 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
696 1.1 mw }
697 1.1 mw
698 1.1 mw static void inline
699 1.1 mw ite_clrline(ip, sp, y, x)
700 1.1 mw struct ite_softc *ip;
701 1.1 mw struct itesw *sp;
702 1.1 mw int y, x;
703 1.1 mw {
704 1.1 mw (*sp->ite_clear)(ip, y, 0, 1, ip->cols);
705 1.1 mw attrclr(ip, y, 0, 1, ip->cols);
706 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
707 1.1 mw }
708 1.1 mw
709 1.1 mw
710 1.1 mw
711 1.1 mw static void inline
712 1.1 mw ite_clrtoeos(ip, sp)
713 1.1 mw struct ite_softc *ip;
714 1.1 mw struct itesw *sp;
715 1.1 mw {
716 1.1 mw (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
717 1.1 mw attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
718 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
719 1.1 mw }
720 1.1 mw
721 1.1 mw static void inline
722 1.1 mw ite_clrtobos(ip, sp)
723 1.1 mw struct ite_softc *ip;
724 1.1 mw struct itesw *sp;
725 1.1 mw {
726 1.1 mw (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols);
727 1.1 mw attrclr(ip, 0, 0, ip->cury, ip->cols);
728 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
729 1.1 mw }
730 1.1 mw
731 1.1 mw static void inline
732 1.1 mw ite_clrscreen(ip, sp)
733 1.1 mw struct ite_softc *ip;
734 1.1 mw struct itesw *sp;
735 1.1 mw {
736 1.1 mw (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols);
737 1.1 mw attrclr(ip, 0, 0, ip->rows, ip->cols);
738 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
739 1.1 mw }
740 1.1 mw
741 1.1 mw
742 1.1 mw
743 1.1 mw static void inline
744 1.1 mw ite_dnline(ip, sp, n)
745 1.1 mw struct ite_softc *ip;
746 1.1 mw struct itesw *sp;
747 1.1 mw int n;
748 1.1 mw {
749 1.1 mw (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP);
750 1.1 mw attrmov(ip, ip->cury + n, 0, ip->cury, 0,
751 1.1 mw ip->bottom_margin + 1 - ip->cury - n, ip->cols);
752 1.1 mw (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
753 1.1 mw attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
754 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
755 1.1 mw }
756 1.1 mw
757 1.1 mw static void inline
758 1.1 mw ite_inline(ip, sp, n)
759 1.1 mw struct ite_softc *ip;
760 1.1 mw struct itesw *sp;
761 1.1 mw int n;
762 1.1 mw {
763 1.1 mw (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN);
764 1.1 mw attrmov(ip, ip->cury, 0, ip->cury + n, 0,
765 1.1 mw ip->bottom_margin + 1 - ip->cury - n, ip->cols);
766 1.1 mw (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols);
767 1.1 mw attrclr(ip, ip->cury, 0, n, ip->cols);
768 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
769 1.1 mw }
770 1.1 mw
771 1.1 mw static void inline
772 1.1 mw ite_lf (ip, sp)
773 1.1 mw struct ite_softc *ip;
774 1.1 mw struct itesw *sp;
775 1.1 mw {
776 1.1 mw #if 0
777 1.1 mw if (ip->inside_margins)
778 1.1 mw {
779 1.1 mw #endif
780 1.1 mw if (++ip->cury >= ip->bottom_margin + 1)
781 1.1 mw {
782 1.1 mw ip->cury = ip->bottom_margin;
783 1.1 mw (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
784 1.1 mw ite_clrtoeol(ip, sp, ip->cury, 0);
785 1.1 mw }
786 1.1 mw else
787 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
788 1.1 mw #if 0
789 1.1 mw }
790 1.1 mw else
791 1.1 mw {
792 1.1 mw if (++ip->cury == ip->rows)
793 1.1 mw {
794 1.1 mw --ip->cury;
795 1.1 mw (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
796 1.1 mw ite_clrtoeol(ip, sp, ip->cury, 0);
797 1.1 mw }
798 1.1 mw else
799 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
800 1.1 mw }
801 1.1 mw #endif
802 1.1 mw clr_attr(ip, ATTR_INV);
803 1.1 mw }
804 1.1 mw
805 1.1 mw static void inline
806 1.1 mw ite_crlf (ip, sp)
807 1.1 mw struct ite_softc *ip;
808 1.1 mw struct itesw *sp;
809 1.1 mw {
810 1.1 mw ip->curx = 0;
811 1.1 mw ite_lf (ip, sp);
812 1.1 mw }
813 1.1 mw
814 1.1 mw static void inline
815 1.1 mw ite_cr (ip, sp)
816 1.1 mw struct ite_softc *ip;
817 1.1 mw struct itesw *sp;
818 1.1 mw {
819 1.1 mw if (ip->curx)
820 1.1 mw {
821 1.1 mw ip->curx = 0;
822 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
823 1.1 mw }
824 1.1 mw }
825 1.1 mw
826 1.1 mw static void inline
827 1.1 mw ite_rlf (ip, sp)
828 1.1 mw struct ite_softc *ip;
829 1.1 mw struct itesw *sp;
830 1.1 mw {
831 1.1 mw if (ip->cury > 0)
832 1.1 mw {
833 1.1 mw ip->cury--;
834 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
835 1.1 mw }
836 1.1 mw else
837 1.1 mw ite_inline (ip, sp, 1);
838 1.1 mw clr_attr(ip, ATTR_INV);
839 1.1 mw }
840 1.1 mw
841 1.1 mw static int inline
842 1.1 mw atoi (cp)
843 1.1 mw const char *cp;
844 1.1 mw {
845 1.1 mw int n;
846 1.1 mw
847 1.1 mw for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
848 1.1 mw n = n * 10 + *cp - '0';
849 1.1 mw
850 1.1 mw return n;
851 1.1 mw }
852 1.1 mw
853 1.1 mw static char *
854 1.1 mw index (cp, ch)
855 1.1 mw const char *cp;
856 1.1 mw char ch;
857 1.1 mw {
858 1.1 mw while (*cp && *cp != ch) cp++;
859 1.1 mw return *cp ? cp : 0;
860 1.1 mw }
861 1.1 mw
862 1.1 mw
863 1.1 mw
864 1.1 mw static int inline
865 1.1 mw ite_argnum (ip)
866 1.1 mw struct ite_softc *ip;
867 1.1 mw {
868 1.1 mw char ch;
869 1.1 mw int n;
870 1.1 mw
871 1.1 mw /* convert argument string into number */
872 1.1 mw if (ip->ap == ip->argbuf)
873 1.1 mw return 1;
874 1.1 mw ch = *ip->ap;
875 1.1 mw *ip->ap = 0;
876 1.1 mw n = atoi (ip->argbuf);
877 1.1 mw *ip->ap = ch;
878 1.1 mw
879 1.1 mw return n;
880 1.1 mw }
881 1.1 mw
882 1.1 mw static int inline
883 1.1 mw ite_zargnum (ip)
884 1.1 mw struct ite_softc *ip;
885 1.1 mw {
886 1.1 mw char ch, *cp;
887 1.1 mw int n;
888 1.1 mw
889 1.1 mw /* convert argument string into number */
890 1.1 mw if (ip->ap == ip->argbuf)
891 1.1 mw return 0;
892 1.1 mw ch = *ip->ap;
893 1.1 mw *ip->ap = 0;
894 1.1 mw n = atoi (ip->argbuf);
895 1.1 mw *ip->ap = ch;
896 1.1 mw
897 1.1 mw return n;
898 1.1 mw }
899 1.1 mw
900 1.1 mw static void inline
901 1.1 mw ite_sendstr (ip, str)
902 1.1 mw struct ite_softc *ip;
903 1.1 mw char *str;
904 1.1 mw {
905 1.1 mw while (*str)
906 1.1 mw (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
907 1.1 mw }
908 1.1 mw
909 1.1 mw static int inline
910 1.1 mw strncmp (a, b, l)
911 1.1 mw const char *a, *b;
912 1.1 mw int l;
913 1.1 mw {
914 1.1 mw for (;l--; a++, b++)
915 1.1 mw if (*a != *b)
916 1.1 mw return *a - *b;
917 1.1 mw return 0;
918 1.1 mw }
919 1.1 mw
920 1.1 mw static void inline
921 1.1 mw ite_reinit(ip)
922 1.1 mw struct ite_softc *ip;
923 1.1 mw {
924 1.1 mw ip->curx = 0;
925 1.1 mw ip->cury = 0;
926 1.1 mw ip->cursorx = 0;
927 1.1 mw ip->cursory = 0;
928 1.1 mw ip->save_curx = 0;
929 1.1 mw ip->save_cury = 0;
930 1.1 mw ip->ap = ip->argbuf;
931 1.1 mw ip->emul_level = EMUL_VT300_7;
932 1.1 mw ip->eightbit_C1 = 0;
933 1.1 mw ip->top_margin = 0; ip->bottom_margin = 23;
934 1.1 mw ip->inside_margins = 0;
935 1.1 mw ip->linefeed_newline = 0;
936 1.1 mw
937 1.1 mw (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
938 1.1 mw
939 1.1 mw ip->attribute = 0;
940 1.1 mw bzero(ip->attrbuf, (ip->rows * ip->cols));
941 1.1 mw
942 1.1 mw ip->imode = 0;
943 1.1 mw }
944 1.1 mw
945 1.1 mw
946 1.1 mw
947 1.1 mw iteputchar(c, dev)
948 1.1 mw register int c;
949 1.1 mw dev_t dev;
950 1.1 mw {
951 1.1 mw int unit = UNIT(dev);
952 1.1 mw register struct ite_softc *ip = &ite_softc[unit];
953 1.1 mw register struct itesw *sp = &itesw[ip->type];
954 1.1 mw register int n;
955 1.1 mw int x, y;
956 1.1 mw char *cp;
957 1.1 mw
958 1.1 mw if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
959 1.1 mw return;
960 1.1 mw
961 1.1 mw if ((ite_tty[unit]->t_cflag & CSIZE) == CS7
962 1.1 mw || (ite_tty[unit]->t_cflag & PARENB))
963 1.1 mw c &= 0x7f;
964 1.1 mw
965 1.1 mw if (ip->escape)
966 1.1 mw {
967 1.1 mw doesc:
968 1.1 mw switch (ip->escape)
969 1.1 mw {
970 1.1 mw case ESC:
971 1.1 mw switch (c)
972 1.1 mw {
973 1.1 mw /* first 7bit equivalents for the 8bit control characters */
974 1.1 mw
975 1.1 mw case 'D':
976 1.1 mw c = IND;
977 1.1 mw ip->escape = 0;
978 1.1 mw break;
979 1.1 mw
980 1.1 mw case 'E':
981 1.1 mw c = NEL;
982 1.1 mw ip->escape = 0;
983 1.1 mw break;
984 1.1 mw
985 1.1 mw case 'H':
986 1.1 mw c = HTS;
987 1.1 mw ip->escape = 0;
988 1.1 mw break;
989 1.1 mw
990 1.1 mw case 'M':
991 1.1 mw c = RI;
992 1.1 mw ip->escape = 0;
993 1.1 mw break;
994 1.1 mw
995 1.1 mw case 'N':
996 1.1 mw c = SS2;
997 1.1 mw ip->escape = 0;
998 1.1 mw break;
999 1.1 mw
1000 1.1 mw case 'O':
1001 1.1 mw c = SS3;
1002 1.1 mw ip->escape = 0;
1003 1.1 mw break;
1004 1.1 mw
1005 1.1 mw case 'P':
1006 1.1 mw c = DCS;
1007 1.1 mw ip->escape = 0;
1008 1.1 mw break;
1009 1.1 mw
1010 1.1 mw case '[':
1011 1.1 mw c = CSI;
1012 1.1 mw ip->escape = 0;
1013 1.1 mw break;
1014 1.1 mw
1015 1.1 mw case '\\':
1016 1.1 mw c = ST;
1017 1.1 mw ip->escape = 0;
1018 1.1 mw break;
1019 1.1 mw
1020 1.1 mw case ']':
1021 1.1 mw c = OSC;
1022 1.1 mw ip->escape = 0;
1023 1.1 mw break;
1024 1.1 mw
1025 1.1 mw case '^':
1026 1.1 mw c = PM;
1027 1.1 mw ip->escape = 0;
1028 1.1 mw break;
1029 1.1 mw
1030 1.1 mw case '_':
1031 1.1 mw c = APC;
1032 1.1 mw ip->escape = 0;
1033 1.1 mw break;
1034 1.1 mw
1035 1.1 mw
1036 1.1 mw /* introduces 7/8bit control */
1037 1.1 mw case ' ':
1038 1.1 mw /* can be followed by either F or G */
1039 1.1 mw ip->escape = ' ';
1040 1.1 mw break;
1041 1.1 mw
1042 1.1 mw
1043 1.1 mw /* a lot of character set selections, not yet used...
1044 1.1 mw 94-character sets: */
1045 1.1 mw case '(': /* G0 */
1046 1.1 mw case ')': /* G1 */
1047 1.1 mw case '*': /* G2 */
1048 1.1 mw case '+': /* G3 */
1049 1.1 mw case 'B': /* ASCII */
1050 1.1 mw case 'A': /* ISO latin 1 */
1051 1.1 mw case '<': /* user preferred suplemental */
1052 1.1 mw case '0': /* dec special graphics */
1053 1.1 mw
1054 1.1 mw /* 96-character sets: */
1055 1.1 mw case '-': /* G1 */
1056 1.1 mw case '.': /* G2 */
1057 1.1 mw case '/': /* G3 */
1058 1.1 mw
1059 1.1 mw /* national character sets: */
1060 1.1 mw case '4': /* dutch */
1061 1.1 mw case '5':
1062 1.1 mw case 'C': /* finnish */
1063 1.1 mw case 'R': /* french */
1064 1.1 mw case 'Q': /* french canadian */
1065 1.1 mw case 'K': /* german */
1066 1.1 mw case 'Y': /* italian */
1067 1.1 mw case '6': /* norwegian/danish */
1068 1.1 mw case 'Z': /* spanish */
1069 1.1 mw case '=': /* swiss */
1070 1.1 mw /* note: %5 and %6 are not supported (two chars..) */
1071 1.1 mw
1072 1.1 mw ip->escape = 0;
1073 1.1 mw /* just ignore for now */
1074 1.1 mw return -1;
1075 1.1 mw
1076 1.1 mw
1077 1.1 mw /* locking shift modes (as you might guess, not yet supported..) */
1078 1.1 mw case '`':
1079 1.1 mw ip->GR = ip->G1;
1080 1.1 mw ip->escape = 0;
1081 1.1 mw return -1;
1082 1.1 mw
1083 1.1 mw case 'n':
1084 1.1 mw ip->GL = ip->G2;
1085 1.1 mw ip->escape = 0;
1086 1.1 mw return -1;
1087 1.1 mw
1088 1.1 mw case '}':
1089 1.1 mw ip->GR = ip->G2;
1090 1.1 mw ip->escape = 0;
1091 1.1 mw return -1;
1092 1.1 mw
1093 1.1 mw case 'o':
1094 1.1 mw ip->GL = ip->G3;
1095 1.1 mw ip->escape = 0;
1096 1.1 mw return -1;
1097 1.1 mw
1098 1.1 mw case '|':
1099 1.1 mw ip->GR = ip->G3;
1100 1.1 mw ip->escape = 0;
1101 1.1 mw return -1;
1102 1.1 mw
1103 1.1 mw
1104 1.1 mw /* font width/height control */
1105 1.1 mw case '#':
1106 1.1 mw ip->escape = '#';
1107 1.1 mw return -1;
1108 1.1 mw
1109 1.1 mw
1110 1.1 mw /* hard terminal reset .. */
1111 1.1 mw case 'c':
1112 1.1 mw ite_reinit (ip);
1113 1.1 mw ip->escape = 0;
1114 1.1 mw return -1;
1115 1.1 mw
1116 1.1 mw
1117 1.1 mw case '7':
1118 1.1 mw ip->save_curx = ip->curx;
1119 1.1 mw ip->save_cury = ip->cury;
1120 1.1 mw ip->escape = 0;
1121 1.1 mw return -1;
1122 1.1 mw
1123 1.1 mw case '8':
1124 1.1 mw ip->curx = ip->save_curx;
1125 1.1 mw ip->cury = ip->save_cury;
1126 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1127 1.1 mw ip->escape = 0;
1128 1.1 mw return -1;
1129 1.1 mw
1130 1.1 mw
1131 1.1 mw /* default catch all for not recognized ESC sequences */
1132 1.1 mw default:
1133 1.1 mw ip->escape = 0;
1134 1.1 mw return -1;
1135 1.1 mw }
1136 1.1 mw break;
1137 1.1 mw
1138 1.1 mw
1139 1.1 mw case ' ':
1140 1.1 mw switch (c)
1141 1.1 mw {
1142 1.1 mw case 'F':
1143 1.1 mw ip->eightbit_C1 = 0;
1144 1.1 mw ip->escape = 0;
1145 1.1 mw return -1;
1146 1.1 mw
1147 1.1 mw case 'G':
1148 1.1 mw ip->eightbit_C1 = 1;
1149 1.1 mw ip->escape = 0;
1150 1.1 mw return -1;
1151 1.1 mw
1152 1.1 mw default:
1153 1.1 mw /* not supported */
1154 1.1 mw ip->escape = 0;
1155 1.1 mw return -1;
1156 1.1 mw }
1157 1.1 mw break;
1158 1.1 mw
1159 1.1 mw
1160 1.1 mw case '#':
1161 1.1 mw switch (c)
1162 1.1 mw {
1163 1.1 mw case '5':
1164 1.1 mw /* single height, single width */
1165 1.1 mw ip->escape = 0;
1166 1.1 mw return -1;
1167 1.1 mw
1168 1.1 mw case '6':
1169 1.1 mw /* double width, single height */
1170 1.1 mw ip->escape = 0;
1171 1.1 mw return -1;
1172 1.1 mw
1173 1.1 mw case '3':
1174 1.1 mw /* top half */
1175 1.1 mw ip->escape = 0;
1176 1.1 mw return -1;
1177 1.1 mw
1178 1.1 mw case '4':
1179 1.1 mw /* bottom half */
1180 1.1 mw ip->escape = 0;
1181 1.1 mw return -1;
1182 1.1 mw
1183 1.1 mw case '8':
1184 1.1 mw /* screen alignment pattern... */
1185 1.1 mw ip->escape = 0;
1186 1.1 mw return -1;
1187 1.1 mw
1188 1.1 mw default:
1189 1.1 mw ip->escape = 0;
1190 1.1 mw return -1;
1191 1.1 mw }
1192 1.1 mw break;
1193 1.1 mw
1194 1.1 mw
1195 1.1 mw
1196 1.1 mw #if 0
1197 1.1 mw case DCS:
1198 1.1 mw case PM:
1199 1.1 mw case APC:
1200 1.1 mw case OSC:
1201 1.1 mw switch (c)
1202 1.1 mw {
1203 1.1 mw case ST:
1204 1.1 mw ip->escape = 0;
1205 1.1 mw return -1;
1206 1.1 mw
1207 1.1 mw default:
1208 1.1 mw return -1;
1209 1.1 mw }
1210 1.1 mw break;
1211 1.1 mw #endif
1212 1.1 mw
1213 1.1 mw
1214 1.1 mw case CSI:
1215 1.1 mw /* the biggie... */
1216 1.1 mw switch (c)
1217 1.1 mw {
1218 1.1 mw case '0': case '1': case '2': case '3': case '4':
1219 1.1 mw case '5': case '6': case '7': case '8': case '9':
1220 1.1 mw case ';': case '\"': case '$': case '>':
1221 1.1 mw if (ip->ap < ip->argbuf + ARGBUF_SIZE)
1222 1.1 mw *ip->ap++ = c;
1223 1.1 mw return -1;
1224 1.1 mw
1225 1.1 mw case CAN:
1226 1.1 mw ip->escape = 0;
1227 1.1 mw return -1;
1228 1.1 mw
1229 1.1 mw
1230 1.1 mw case 'p':
1231 1.1 mw *ip->ap = 0;
1232 1.1 mw if (! strncmp (ip->argbuf, "61\"", 3))
1233 1.1 mw ip->emul_level = EMUL_VT100;
1234 1.1 mw else if (! strncmp (ip->argbuf, "63;1\"", 5)
1235 1.1 mw || ! strncmp (ip->argbuf, "62;1\"", 5))
1236 1.1 mw ip->emul_level = EMUL_VT300_7;
1237 1.1 mw else
1238 1.1 mw ip->emul_level = EMUL_VT300_8;
1239 1.1 mw ip->escape = 0;
1240 1.1 mw return -1;
1241 1.1 mw
1242 1.1 mw
1243 1.1 mw case '?':
1244 1.1 mw *ip->ap = 0;
1245 1.1 mw ip->escape = '?';
1246 1.1 mw ip->ap = ip->argbuf;
1247 1.1 mw return -1;
1248 1.1 mw
1249 1.1 mw
1250 1.1 mw case 'c':
1251 1.1 mw *ip->ap = 0;
1252 1.1 mw if (ip->ap == ip->argbuf
1253 1.1 mw || (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '0'))
1254 1.1 mw {
1255 1.1 mw /* primary DA request, send primary DA response */
1256 1.1 mw if (ip->emul_level == EMUL_VT100)
1257 1.1 mw ite_sendstr (ip, "\033[61;0c");
1258 1.1 mw else
1259 1.1 mw ite_sendstr (ip, "\033[63;0c");
1260 1.1 mw }
1261 1.1 mw
1262 1.1 mw else if ((ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '>')
1263 1.1 mw || (ip->ap == &ip->argbuf[2]
1264 1.1 mw && !strncmp (ip->argbuf, ">0", 2)))
1265 1.1 mw {
1266 1.1 mw ite_sendstr (ip, "\033[>24;0;0;0c");
1267 1.1 mw }
1268 1.1 mw
1269 1.1 mw ip->escape = 0;
1270 1.1 mw return -1;
1271 1.1 mw
1272 1.1 mw
1273 1.1 mw case 'n':
1274 1.1 mw *ip->ap = 0;
1275 1.1 mw if (ip->ap == &ip->argbuf[1])
1276 1.1 mw {
1277 1.1 mw if (ip->argbuf[0] == '5')
1278 1.1 mw ite_sendstr (ip, "\033[0n"); /* no malfunction */
1279 1.1 mw
1280 1.1 mw else if (ip->argbuf[0] == '6')
1281 1.1 mw {
1282 1.1 mw sprintf (ip->argbuf, "\033[%d;%dR",
1283 1.1 mw ip->cury + 1, ip->curx + 1);
1284 1.1 mw /* cursor position report */
1285 1.1 mw ite_sendstr (ip, ip->argbuf);
1286 1.1 mw }
1287 1.1 mw
1288 1.1 mw }
1289 1.1 mw ip->escape = 0;
1290 1.1 mw return -1;
1291 1.1 mw
1292 1.1 mw
1293 1.1 mw case 'h': case 'l':
1294 1.1 mw *ip->ap = 0;
1295 1.1 mw if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4')
1296 1.1 mw ip->imode = (c == 'h'); /* insert/replace mode */
1297 1.1 mw
1298 1.1 mw else if (ip->ap == &ip->argbuf[2]
1299 1.1 mw && !strncmp (ip->argbuf, "20", 2))
1300 1.1 mw ip->linefeed_newline = (c == 'h');
1301 1.1 mw
1302 1.1 mw
1303 1.1 mw /* various not supported commands */
1304 1.1 mw ip->escape = 0;
1305 1.1 mw return -1;
1306 1.1 mw
1307 1.1 mw
1308 1.1 mw case 'M':
1309 1.1 mw *ip->ap = 0;
1310 1.1 mw ite_dnline (ip, sp, ite_argnum (ip));
1311 1.1 mw ip->escape = 0;
1312 1.1 mw return -1;
1313 1.1 mw
1314 1.1 mw
1315 1.1 mw case 'L':
1316 1.1 mw *ip->ap = 0;
1317 1.1 mw ite_inline (ip, sp, ite_argnum (ip));
1318 1.1 mw ip->escape = 0;
1319 1.1 mw return -1;
1320 1.1 mw
1321 1.1 mw
1322 1.1 mw case 'P':
1323 1.1 mw *ip->ap = 0;
1324 1.1 mw ite_dnchar (ip, sp, ite_argnum (ip));
1325 1.1 mw ip->escape = 0;
1326 1.1 mw return -1;
1327 1.1 mw
1328 1.1 mw
1329 1.1 mw case '@':
1330 1.1 mw *ip->ap = 0;
1331 1.1 mw ite_inchar (ip, sp, ite_argnum (ip));
1332 1.1 mw ip->escape = 0;
1333 1.1 mw return -1;
1334 1.1 mw
1335 1.1 mw
1336 1.1 mw case 'H':
1337 1.1 mw case 'f':
1338 1.1 mw *ip->ap = 0;
1339 1.1 mw y = atoi (ip->argbuf);
1340 1.1 mw x = 0;
1341 1.1 mw cp = index (ip->argbuf, ';');
1342 1.1 mw if (cp)
1343 1.1 mw x = atoi (cp + 1);
1344 1.1 mw if (x) x--;
1345 1.1 mw if (y) y--;
1346 1.1 mw if (ip->inside_margins)
1347 1.1 mw {
1348 1.1 mw y += ip->top_margin;
1349 1.1 mw ip->cury = MIN(y, ip->bottom_margin);
1350 1.1 mw }
1351 1.1 mw else
1352 1.1 mw {
1353 1.1 mw ip->cury = MIN(y, ip->rows - 1);
1354 1.1 mw }
1355 1.1 mw ip->curx = MIN(x, ip->cols - 1);
1356 1.1 mw ip->escape = 0;
1357 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1358 1.1 mw clr_attr (ip, ATTR_INV);
1359 1.1 mw return -1;
1360 1.1 mw
1361 1.1 mw case 'A':
1362 1.1 mw *ip->ap = 0;
1363 1.1 mw n = ip->cury - ite_argnum (ip);
1364 1.1 mw ip->cury = n >= 0 ? n : 0;
1365 1.1 mw ip->escape = 0;
1366 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1367 1.1 mw clr_attr (ip, ATTR_INV);
1368 1.1 mw return -1;
1369 1.1 mw
1370 1.1 mw case 'B':
1371 1.1 mw *ip->ap = 0;
1372 1.1 mw n = ite_argnum (ip) + ip->cury;
1373 1.1 mw ip->cury = MIN(n, ip->rows - 1);
1374 1.1 mw ip->escape = 0;
1375 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1376 1.1 mw clr_attr (ip, ATTR_INV);
1377 1.1 mw return -1;
1378 1.1 mw
1379 1.1 mw case 'C':
1380 1.1 mw *ip->ap = 0;
1381 1.1 mw n = ite_argnum (ip) + ip->curx;
1382 1.1 mw ip->curx = MIN(n, ip->cols - 1);
1383 1.1 mw ip->escape = 0;
1384 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1385 1.1 mw clr_attr (ip, ATTR_INV);
1386 1.1 mw return -1;
1387 1.1 mw
1388 1.1 mw case 'D':
1389 1.1 mw *ip->ap = 0;
1390 1.1 mw n = ip->curx - ite_argnum (ip);
1391 1.1 mw ip->curx = n >= 0 ? n : 0;
1392 1.1 mw ip->escape = 0;
1393 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1394 1.1 mw clr_attr (ip, ATTR_INV);
1395 1.1 mw return -1;
1396 1.1 mw
1397 1.1 mw
1398 1.1 mw
1399 1.1 mw
1400 1.1 mw case 'J':
1401 1.1 mw *ip->ap = 0;
1402 1.1 mw n = ite_zargnum (ip);
1403 1.1 mw if (n == 0)
1404 1.1 mw ite_clrtoeos(ip, sp);
1405 1.1 mw else if (n == 1)
1406 1.1 mw ite_clrtobos(ip, sp);
1407 1.1 mw else if (n == 2)
1408 1.1 mw ite_clrscreen(ip, sp);
1409 1.1 mw ip->escape = 0;
1410 1.1 mw return -1;
1411 1.1 mw
1412 1.1 mw
1413 1.1 mw case 'K':
1414 1.1 mw *ip->ap = 0;
1415 1.1 mw n = ite_zargnum (ip);
1416 1.1 mw if (n == 0)
1417 1.1 mw ite_clrtoeol(ip, sp, ip->cury, ip->curx);
1418 1.1 mw else if (n == 1)
1419 1.1 mw ite_clrtobol(ip, sp, ip->cury, ip->curx);
1420 1.1 mw else if (n == 2)
1421 1.1 mw ite_clrline(ip, sp, ip->cury, ip->curx);
1422 1.1 mw ip->escape = 0;
1423 1.1 mw return -1;
1424 1.1 mw
1425 1.1 mw
1426 1.1 mw case 'X':
1427 1.1 mw *ip->ap = 0;
1428 1.1 mw for (n = ite_argnum (ip); n > 0; n--)
1429 1.1 mw {
1430 1.1 mw attrclr(ip, ip->cury, ip->curx + n - 1, 1, 1);
1431 1.1 mw (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n - 1, ATTR_NOR);
1432 1.1 mw }
1433 1.1 mw ip->escape = 0;
1434 1.1 mw return -1;
1435 1.1 mw
1436 1.1 mw
1437 1.1 mw case '}': case '`':
1438 1.1 mw /* status line control */
1439 1.1 mw ip->escape = 0;
1440 1.1 mw return -1;
1441 1.1 mw
1442 1.1 mw
1443 1.1 mw case 'r':
1444 1.1 mw *ip->ap = 0;
1445 1.1 mw x = atoi (ip->argbuf);
1446 1.1 mw y = 0;
1447 1.1 mw cp = index (ip->argbuf, ';');
1448 1.1 mw if (cp)
1449 1.1 mw y = atoi (cp + 1);
1450 1.1 mw if (x) x--;
1451 1.1 mw if (y) y--;
1452 1.1 mw ip->top_margin = MIN(x, ip->rows - 1);
1453 1.1 mw ip->bottom_margin = MIN(y, ip->rows - 1);
1454 1.1 mw ip->escape = 0;
1455 1.1 mw return -1;
1456 1.1 mw
1457 1.1 mw
1458 1.1 mw case 'm':
1459 1.1 mw /* big attribute setter/resetter */
1460 1.1 mw {
1461 1.1 mw char *cp;
1462 1.1 mw *ip->ap = 0;
1463 1.1 mw for (cp = ip->argbuf; cp < ip->ap; )
1464 1.1 mw {
1465 1.1 mw switch (*cp)
1466 1.1 mw {
1467 1.1 mw case '0':
1468 1.1 mw clr_attr (ip, ATTR_ALL);
1469 1.1 mw cp++;
1470 1.1 mw break;
1471 1.1 mw
1472 1.1 mw case '1':
1473 1.1 mw set_attr (ip, ATTR_BOLD);
1474 1.1 mw cp++;
1475 1.1 mw break;
1476 1.1 mw
1477 1.1 mw case '2':
1478 1.1 mw switch (cp[1])
1479 1.1 mw {
1480 1.1 mw case '2':
1481 1.1 mw clr_attr (ip, ATTR_BOLD);
1482 1.1 mw cp += 2;
1483 1.1 mw break;
1484 1.1 mw
1485 1.1 mw case '4':
1486 1.1 mw clr_attr (ip, ATTR_UL);
1487 1.1 mw cp += 2;
1488 1.1 mw break;
1489 1.1 mw
1490 1.1 mw case '5':
1491 1.1 mw clr_attr (ip, ATTR_BLINK);
1492 1.1 mw cp += 2;
1493 1.1 mw break;
1494 1.1 mw
1495 1.1 mw case '7':
1496 1.1 mw clr_attr (ip, ATTR_INV);
1497 1.1 mw cp += 2;
1498 1.1 mw break;
1499 1.1 mw
1500 1.1 mw default:
1501 1.1 mw cp++;
1502 1.1 mw break;
1503 1.1 mw }
1504 1.1 mw break;
1505 1.1 mw
1506 1.1 mw case '4':
1507 1.1 mw set_attr (ip, ATTR_UL);
1508 1.1 mw cp++;
1509 1.1 mw break;
1510 1.1 mw
1511 1.1 mw case '5':
1512 1.1 mw set_attr (ip, ATTR_BLINK);
1513 1.1 mw cp++;
1514 1.1 mw break;
1515 1.1 mw
1516 1.1 mw case '7':
1517 1.1 mw set_attr (ip, ATTR_INV);
1518 1.1 mw cp++;
1519 1.1 mw break;
1520 1.1 mw
1521 1.1 mw default:
1522 1.1 mw cp++;
1523 1.1 mw break;
1524 1.1 mw }
1525 1.1 mw }
1526 1.1 mw
1527 1.1 mw }
1528 1.1 mw ip->escape = 0;
1529 1.1 mw return -1;
1530 1.1 mw
1531 1.1 mw
1532 1.1 mw case 'u':
1533 1.1 mw /* DECRQTSR */
1534 1.1 mw ite_sendstr (ip, "\033P\033\\");
1535 1.1 mw ip->escape = 0;
1536 1.1 mw return -1;
1537 1.1 mw
1538 1.1 mw
1539 1.1 mw
1540 1.1 mw default:
1541 1.1 mw ip->escape = 0;
1542 1.1 mw return -1;
1543 1.1 mw }
1544 1.1 mw break;
1545 1.1 mw
1546 1.1 mw
1547 1.1 mw
1548 1.1 mw case '?': /* CSI ? */
1549 1.1 mw switch (c)
1550 1.1 mw {
1551 1.1 mw case '0': case '1': case '2': case '3': case '4':
1552 1.1 mw case '5': case '6': case '7': case '8': case '9':
1553 1.1 mw case ';': case '\"': case '$':
1554 1.1 mw if (ip->ap < ip->argbuf + ARGBUF_SIZE)
1555 1.1 mw *ip->ap++ = c;
1556 1.1 mw return -1;
1557 1.1 mw
1558 1.1 mw
1559 1.1 mw case CAN:
1560 1.1 mw ip->escape = 0;
1561 1.1 mw return -1;
1562 1.1 mw
1563 1.1 mw
1564 1.1 mw case 'n':
1565 1.1 mw *ip->ap = 0;
1566 1.1 mw if (ip->ap == &ip->argbuf[2])
1567 1.1 mw {
1568 1.1 mw if (! strncmp (ip->argbuf, "15", 2))
1569 1.1 mw /* printer status: no printer */
1570 1.1 mw ite_sendstr (ip, "\033[13n");
1571 1.1 mw
1572 1.1 mw else if (! strncmp (ip->argbuf, "25", 2))
1573 1.1 mw /* udk status */
1574 1.1 mw ite_sendstr (ip, "\033[20n");
1575 1.1 mw
1576 1.1 mw else if (! strncmp (ip->argbuf, "26", 2))
1577 1.1 mw /* keyboard dialect: US */
1578 1.1 mw ite_sendstr (ip, "\033[27;1n");
1579 1.1 mw }
1580 1.1 mw ip->escape = 0;
1581 1.1 mw return -1;
1582 1.1 mw
1583 1.1 mw
1584 1.1 mw case 'h': case 'l':
1585 1.1 mw *ip->ap = 0;
1586 1.1 mw if (ip->ap[0] == '6')
1587 1.1 mw ip->inside_margins = (c == 'h');
1588 1.1 mw
1589 1.1 mw else if (! strncmp (ip->ap, "25", 2))
1590 1.1 mw (*itesw[ip->type].ite_cursor)(ip,
1591 1.1 mw (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR);
1592 1.1 mw
1593 1.1 mw /* others.. */
1594 1.1 mw
1595 1.1 mw default:
1596 1.1 mw ip->escape = 0;
1597 1.1 mw return -1;
1598 1.1 mw }
1599 1.1 mw break;
1600 1.1 mw
1601 1.1 mw
1602 1.1 mw default:
1603 1.1 mw ip->escape = 0;
1604 1.1 mw return -1;
1605 1.1 mw }
1606 1.1 mw }
1607 1.1 mw
1608 1.1 mw
1609 1.1 mw switch (c) {
1610 1.1 mw
1611 1.1 mw case VT: /* VT is treated like LF */
1612 1.1 mw case FF: /* so is FF */
1613 1.1 mw case LF:
1614 1.1 mw if (ip->linefeed_newline)
1615 1.1 mw ite_crlf (ip, sp);
1616 1.1 mw else
1617 1.1 mw ite_lf (ip, sp);
1618 1.1 mw break;
1619 1.1 mw
1620 1.1 mw case CR:
1621 1.1 mw ite_cr (ip, sp);
1622 1.1 mw break;
1623 1.1 mw
1624 1.1 mw case BS:
1625 1.1 mw if (--ip->curx < 0)
1626 1.1 mw ip->curx = 0;
1627 1.1 mw else
1628 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1629 1.1 mw break;
1630 1.1 mw
1631 1.1 mw case HT:
1632 1.1 mw if (ip->curx < TABEND(unit)) {
1633 1.1 mw n = TABSIZE - (ip->curx & (TABSIZE - 1));
1634 1.1 mw ip->curx += n;
1635 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1636 1.1 mw } else
1637 1.1 mw itecheckwrap(ip, sp);
1638 1.1 mw break;
1639 1.1 mw
1640 1.1 mw case BEL:
1641 1.1 mw if (ite_tty[unit] == kbd_tty)
1642 1.1 mw kbdbell();
1643 1.1 mw break;
1644 1.1 mw
1645 1.1 mw case SO:
1646 1.1 mw ip->GL = ip->G1;
1647 1.1 mw break;
1648 1.1 mw
1649 1.1 mw case SI:
1650 1.1 mw ip->GL = ip->G0;
1651 1.1 mw break;
1652 1.1 mw
1653 1.1 mw case ENQ:
1654 1.1 mw /* send answer-back message !! */
1655 1.1 mw break;
1656 1.1 mw
1657 1.1 mw case CAN:
1658 1.1 mw ip->escape = 0; /* cancel any escape sequence in progress */
1659 1.1 mw break;
1660 1.1 mw
1661 1.1 mw case SUB:
1662 1.1 mw ip->escape = 0; /* dito, but see below */
1663 1.1 mw /* should also display a reverse question mark!! */
1664 1.1 mw break;
1665 1.1 mw
1666 1.1 mw case ESC:
1667 1.1 mw ip->escape = ESC;
1668 1.1 mw break;
1669 1.1 mw
1670 1.1 mw
1671 1.1 mw /* now it gets weird.. 8bit control sequences.. */
1672 1.1 mw case IND: /* index: move cursor down, scroll */
1673 1.1 mw ite_lf (ip, sp);
1674 1.1 mw break;
1675 1.1 mw
1676 1.1 mw case NEL: /* next line. next line, first pos. */
1677 1.1 mw ite_crlf (ip, sp);
1678 1.1 mw break;
1679 1.1 mw
1680 1.1 mw case HTS: /* set horizontal tab */
1681 1.1 mw /* not yet supported */
1682 1.1 mw break;
1683 1.1 mw
1684 1.1 mw case RI: /* reverse index */
1685 1.1 mw ite_rlf (ip, sp);
1686 1.1 mw break;
1687 1.1 mw
1688 1.1 mw case SS2: /* go into G2 for one character */
1689 1.1 mw /* not yet supported */
1690 1.1 mw break;
1691 1.1 mw
1692 1.1 mw case SS3: /* go into G3 for one character */
1693 1.1 mw break;
1694 1.1 mw
1695 1.1 mw case DCS: /* device control string introducer */
1696 1.1 mw ip->escape = DCS;
1697 1.1 mw ip->ap = ip->argbuf;
1698 1.1 mw break;
1699 1.1 mw
1700 1.1 mw case CSI: /* control sequence introducer */
1701 1.1 mw ip->escape = CSI;
1702 1.1 mw ip->ap = ip->argbuf;
1703 1.1 mw break;
1704 1.1 mw
1705 1.1 mw case ST: /* string terminator */
1706 1.1 mw /* ignore, if not used as terminator */
1707 1.1 mw break;
1708 1.1 mw
1709 1.1 mw case OSC: /* introduces OS command. Ignore everything upto ST */
1710 1.1 mw ip->escape = OSC;
1711 1.1 mw break;
1712 1.1 mw
1713 1.1 mw case PM: /* privacy message, ignore everything upto ST */
1714 1.1 mw ip->escape = PM;
1715 1.1 mw break;
1716 1.1 mw
1717 1.1 mw case APC: /* application program command, ignore everything upto ST */
1718 1.1 mw ip->escape = APC;
1719 1.1 mw break;
1720 1.1 mw
1721 1.1 mw default:
1722 1.1 mw if (c < ' ' || c == DEL)
1723 1.1 mw break;
1724 1.1 mw if (ip->imode)
1725 1.1 mw ite_inchar(ip, sp, 1);
1726 1.1 mw if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
1727 1.1 mw attrset(ip, ATTR_INV);
1728 1.1 mw (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
1729 1.1 mw }
1730 1.1 mw else
1731 1.1 mw (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
1732 1.1 mw (*sp->ite_cursor)(ip, DRAW_CURSOR);
1733 1.1 mw itecheckwrap(ip, sp);
1734 1.1 mw break;
1735 1.1 mw }
1736 1.1 mw }
1737 1.1 mw
1738 1.1 mw itecheckwrap(ip, sp)
1739 1.1 mw register struct ite_softc *ip;
1740 1.1 mw register struct itesw *sp;
1741 1.1 mw {
1742 1.1 mw if (++ip->curx == ip->cols) {
1743 1.1 mw ip->curx = 0;
1744 1.1 mw clr_attr(ip, ATTR_INV);
1745 1.1 mw if (++ip->cury >= ip->bottom_margin + 1) {
1746 1.1 mw ip->cury = ip->bottom_margin;
1747 1.1 mw (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1748 1.1 mw ite_clrtoeol(ip, sp, ip->cury, 0);
1749 1.1 mw return;
1750 1.1 mw }
1751 1.1 mw }
1752 1.1 mw (*sp->ite_cursor)(ip, MOVE_CURSOR);
1753 1.1 mw }
1754 1.1 mw
1755 1.1 mw /*
1756 1.1 mw * Console functions
1757 1.1 mw */
1758 1.1 mw #include "../amiga/cons.h"
1759 1.1 mw #include "grfioctl.h"
1760 1.1 mw #include "grfvar.h"
1761 1.1 mw
1762 1.1 mw #ifdef DEBUG
1763 1.1 mw /*
1764 1.1 mw * Minimum ITE number at which to start looking for a console.
1765 1.1 mw * Setting to 0 will do normal search, 1 will skip first ITE device,
1766 1.1 mw * NITE will skip ITEs and use serial port.
1767 1.1 mw */
1768 1.1 mw int whichconsole = 0;
1769 1.1 mw #endif
1770 1.1 mw
1771 1.1 mw itecnprobe(cp)
1772 1.1 mw struct consdev *cp;
1773 1.1 mw {
1774 1.1 mw register struct ite_softc *ip;
1775 1.1 mw int i, maj, unit, pri;
1776 1.1 mw
1777 1.1 mw /* locate the major number */
1778 1.1 mw for (maj = 0; maj < nchrdev; maj++)
1779 1.1 mw if (cdevsw[maj].d_open == iteopen)
1780 1.1 mw break;
1781 1.1 mw
1782 1.1 mw /* urk! */
1783 1.1 mw grfconfig();
1784 1.1 mw
1785 1.1 mw /* check all the individual displays and find the best */
1786 1.1 mw unit = -1;
1787 1.1 mw pri = CN_DEAD;
1788 1.1 mw for (i = 0; i < NITE; i++) {
1789 1.1 mw struct grf_softc *gp = &grf_softc[i];
1790 1.1 mw
1791 1.1 mw ip = &ite_softc[i];
1792 1.1 mw if ((gp->g_flags & GF_ALIVE) == 0)
1793 1.1 mw continue;
1794 1.1 mw ip->flags = (ITE_ALIVE|ITE_CONSOLE);
1795 1.1 mw
1796 1.1 mw /* XXX - we need to do something about mapping these */
1797 1.1 mw switch (gp->g_type) {
1798 1.1 mw case GT_CUSTOMCHIPS:
1799 1.1 mw ip->type = ITE_CUSTOMCHIPS;
1800 1.1 mw break;
1801 1.1 mw
1802 1.1 mw case GT_TIGA_A2410:
1803 1.1 mw ip->type = ITE_TIGA_A2410;
1804 1.1 mw break;
1805 1.1 mw }
1806 1.1 mw #ifdef DEBUG
1807 1.1 mw if (i < whichconsole)
1808 1.1 mw continue;
1809 1.1 mw #endif
1810 1.1 mw if ((int)gp->g_type == GT_CUSTOMCHIPS) {
1811 1.1 mw pri = CN_INTERNAL;
1812 1.1 mw unit = i;
1813 1.1 mw } else if (unit < 0) {
1814 1.1 mw pri = CN_NORMAL;
1815 1.1 mw unit = i;
1816 1.1 mw }
1817 1.1 mw }
1818 1.1 mw
1819 1.1 mw /* initialize required fields */
1820 1.1 mw cp->cn_dev = makedev(maj, unit);
1821 1.1 mw cp->cn_tp = ite_tty[unit];
1822 1.1 mw cp->cn_pri = pri;
1823 1.1 mw }
1824 1.1 mw
1825 1.1 mw itecninit(cp)
1826 1.1 mw struct consdev *cp;
1827 1.1 mw {
1828 1.1 mw int unit = UNIT(cp->cn_dev);
1829 1.1 mw struct ite_softc *ip = &ite_softc[unit];
1830 1.1 mw ip->attrbuf = console_attributes;
1831 1.1 mw iteinit(cp->cn_dev);
1832 1.1 mw ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
1833 1.1 mw kbd_tty = ite_tty[unit];
1834 1.1 mw kbdenable();
1835 1.1 mw }
1836 1.1 mw
1837 1.1 mw /*ARGSUSED*/
1838 1.1 mw itecngetc(dev)
1839 1.1 mw dev_t dev;
1840 1.1 mw {
1841 1.1 mw register int c;
1842 1.1 mw
1843 1.1 mw do
1844 1.1 mw {
1845 1.1 mw c = kbdgetcn ();
1846 1.1 mw c = itefilter (c, ITEFILT_CONSOLE);
1847 1.1 mw }
1848 1.1 mw while (c == -1);
1849 1.1 mw
1850 1.1 mw return(c);
1851 1.1 mw }
1852 1.1 mw
1853 1.1 mw itecnputc(dev, c)
1854 1.1 mw dev_t dev;
1855 1.1 mw int c;
1856 1.1 mw {
1857 1.1 mw static int paniced = 0;
1858 1.1 mw struct ite_softc *ip = &ite_softc[UNIT(dev)];
1859 1.1 mw extern char *panicstr;
1860 1.1 mw
1861 1.1 mw if (panicstr && !paniced &&
1862 1.1 mw (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
1863 1.1 mw (void) iteon(dev, 3);
1864 1.1 mw paniced = 1;
1865 1.1 mw }
1866 1.1 mw iteputchar(c, dev);
1867 1.1 mw }
1868 1.1 mw #endif
1869