ite.c revision 1.70 1 1.70 tsutsui /* $NetBSD: ite.c,v 1.70 2022/06/25 05:01:31 tsutsui Exp $ */
2 1.1 oki
3 1.1 oki /*
4 1.58 rmind * Copyright (c) 1988 University of Utah.
5 1.1 oki * Copyright (c) 1990 The Regents of the University of California.
6 1.1 oki * All rights reserved.
7 1.1 oki *
8 1.1 oki * This code is derived from software contributed to Berkeley by
9 1.1 oki * the Systems Programming Group of the University of Utah Computer
10 1.1 oki * Science Department.
11 1.1 oki *
12 1.1 oki * Redistribution and use in source and binary forms, with or without
13 1.1 oki * modification, are permitted provided that the following conditions
14 1.1 oki * are met:
15 1.1 oki * 1. Redistributions of source code must retain the above copyright
16 1.1 oki * notice, this list of conditions and the following disclaimer.
17 1.1 oki * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 oki * notice, this list of conditions and the following disclaimer in the
19 1.1 oki * documentation and/or other materials provided with the distribution.
20 1.35 agc * 3. Neither the name of the University nor the names of its contributors
21 1.35 agc * may be used to endorse or promote products derived from this software
22 1.35 agc * without specific prior written permission.
23 1.35 agc *
24 1.35 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 1.35 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 1.35 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 1.35 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 1.35 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 1.35 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 1.35 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.35 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.35 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.35 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.35 agc * SUCH DAMAGE.
35 1.35 agc *
36 1.35 agc * from: Utah $Hdr: ite.c 1.1 90/07/09$
37 1.35 agc *
38 1.35 agc * @(#)ite.c 7.6 (Berkeley) 5/16/91
39 1.35 agc */
40 1.1 oki
41 1.1 oki /*
42 1.1 oki * ite - bitmaped terminal.
43 1.1 oki * Supports VT200, a few terminal features will be unavailable until
44 1.1 oki * the system actually probes the device (i.e. not after consinit())
45 1.1 oki */
46 1.34 lukem
47 1.34 lukem #include <sys/cdefs.h>
48 1.70 tsutsui __KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.70 2022/06/25 05:01:31 tsutsui Exp $");
49 1.1 oki
50 1.1 oki #include "ite.h"
51 1.1 oki #if NITE > 0
52 1.1 oki
53 1.1 oki #include "bell.h"
54 1.14 minoura #include "kbd.h"
55 1.17 minoura
56 1.17 minoura #include "opt_ite.h"
57 1.1 oki
58 1.1 oki #include <sys/param.h>
59 1.1 oki #include <sys/conf.h>
60 1.1 oki #include <sys/proc.h>
61 1.1 oki #include <sys/ioctl.h>
62 1.1 oki #include <sys/tty.h>
63 1.1 oki #include <sys/systm.h>
64 1.1 oki #include <sys/device.h>
65 1.1 oki #include <sys/malloc.h>
66 1.45 elad #include <sys/kauth.h>
67 1.65 riastrad #include <sys/device_impl.h> /* XXX autoconf abuse */
68 1.14 minoura
69 1.16 minoura #include <machine/cpu.h>
70 1.1 oki #include <machine/kbio.h>
71 1.14 minoura #include <machine/bus.h>
72 1.56 isaki #include <machine/autoconf.h>
73 1.14 minoura #include <machine/grfioctl.h>
74 1.13 minoura #include <machine/iteioctl.h>
75 1.1 oki
76 1.14 minoura #include <arch/x68k/dev/grfvar.h>
77 1.14 minoura #include <arch/x68k/dev/itevar.h>
78 1.14 minoura #include <arch/x68k/dev/kbdmap.h>
79 1.14 minoura #include <arch/x68k/dev/mfp.h>
80 1.66 tsutsui
81 1.66 tsutsui #include "ioconf.h"
82 1.66 tsutsui
83 1.16 minoura #if NBELL > 0
84 1.38 chs void opm_bell(void);
85 1.16 minoura #endif
86 1.1 oki
87 1.1 oki #define SUBR_INIT(ip) ip->isw->ite_init(ip)
88 1.1 oki #define SUBR_DEINIT(ip) ip->isw->ite_deinit(ip)
89 1.1 oki #define SUBR_PUTC(ip,c,dy,dx,m) ip->isw->ite_putc(ip,c,dy,dx,m)
90 1.1 oki #define SUBR_CURSOR(ip,flg) ip->isw->ite_cursor(ip,flg)
91 1.1 oki #define SUBR_CLEAR(ip,sy,sx,h,w) ip->isw->ite_clear(ip,sy,sx,h,w)
92 1.1 oki #define SUBR_SCROLL(ip,sy,sx,count,dir) \
93 1.1 oki ip->isw->ite_scroll(ip,sy,sx,count,dir)
94 1.1 oki
95 1.1 oki struct consdev;
96 1.1 oki
97 1.69 tsutsui static inline void itesendch(int);
98 1.69 tsutsui static inline void alignment_display(struct ite_softc *);
99 1.69 tsutsui static inline void snap_cury(struct ite_softc *);
100 1.69 tsutsui static inline void ite_dnchar(struct ite_softc *, int);
101 1.38 chs static void ite_inchar(struct ite_softc *, int);
102 1.69 tsutsui static inline void ite_clrtoeol(struct ite_softc *);
103 1.69 tsutsui static inline void ite_clrtobol(struct ite_softc *);
104 1.69 tsutsui static inline void ite_clrline(struct ite_softc *);
105 1.69 tsutsui static inline void ite_clrtoeos(struct ite_softc *);
106 1.69 tsutsui static inline void ite_clrtobos(struct ite_softc *);
107 1.69 tsutsui static inline void ite_clrscreen(struct ite_softc *);
108 1.69 tsutsui static inline void ite_dnline(struct ite_softc *, int);
109 1.69 tsutsui static inline void ite_inline(struct ite_softc *, int);
110 1.69 tsutsui static inline void ite_index(struct ite_softc *);
111 1.69 tsutsui static inline void ite_lf(struct ite_softc *);
112 1.69 tsutsui static inline void ite_crlf(struct ite_softc *);
113 1.69 tsutsui static inline void ite_cr(struct ite_softc *);
114 1.69 tsutsui static inline void ite_rlf(struct ite_softc *);
115 1.38 chs static void iteprecheckwrap(struct ite_softc *);
116 1.38 chs static void itecheckwrap(struct ite_softc *);
117 1.38 chs static int ite_argnum(struct ite_softc *);
118 1.38 chs static int ite_zargnum(struct ite_softc *);
119 1.40 he static void ite_sendstr(struct ite_softc *, const char *);
120 1.69 tsutsui static inline int atoi(const char *);
121 1.69 tsutsui static struct ite_softc *getitesp(dev_t);
122 1.1 oki
123 1.69 tsutsui static struct itesw itesw[] = {
124 1.16 minoura {0, tv_init, tv_deinit, 0,
125 1.16 minoura 0, 0, 0}
126 1.1 oki };
127 1.1 oki
128 1.1 oki /*
129 1.1 oki * # of chars are output in a single itestart() call.
130 1.1 oki * If this is too big, user processes will be blocked out for
131 1.1 oki * long periods of time while we are emptying the queue in itestart().
132 1.1 oki * If it is too small, console output will be very ragged.
133 1.1 oki */
134 1.1 oki #define ITEBURST 64
135 1.1 oki
136 1.1 oki struct tty *ite_tty[NITE];
137 1.1 oki
138 1.69 tsutsui static struct ite_softc *kbd_ite = NULL;
139 1.69 tsutsui static struct ite_softc con_itesoftc;
140 1.69 tsutsui static struct device con_itedev;
141 1.1 oki
142 1.69 tsutsui static struct tty *kbd_tty = NULL;
143 1.1 oki
144 1.69 tsutsui static int start_repeat_timeo = 20; /* /100: initial timeout till pressed
145 1.69 tsutsui key repeats */
146 1.69 tsutsui static int next_repeat_timeo = 3; /* /100: timeout when repeating for
147 1.69 tsutsui next char */
148 1.1 oki
149 1.69 tsutsui static u_char cons_tabs[MAX_TABS];
150 1.1 oki
151 1.69 tsutsui static void itestart(struct tty *);
152 1.1 oki
153 1.69 tsutsui static void iteputchar(int, struct ite_softc *);
154 1.69 tsutsui static void ite_putstr(const u_char *, int, dev_t);
155 1.69 tsutsui
156 1.69 tsutsui static int itematch(device_t, cfdata_t, void *);
157 1.69 tsutsui static void iteattach(device_t, device_t, void *);
158 1.1 oki
159 1.57 isaki CFATTACH_DECL_NEW(ite, sizeof(struct ite_softc),
160 1.32 thorpej itematch, iteattach, NULL, NULL);
161 1.1 oki
162 1.69 tsutsui static dev_type_open(iteopen);
163 1.69 tsutsui static dev_type_close(iteclose);
164 1.69 tsutsui static dev_type_read(iteread);
165 1.69 tsutsui static dev_type_write(itewrite);
166 1.69 tsutsui static dev_type_ioctl(iteioctl);
167 1.69 tsutsui static dev_type_tty(itetty);
168 1.69 tsutsui static dev_type_poll(itepoll);
169 1.29 gehenna
170 1.29 gehenna const struct cdevsw ite_cdevsw = {
171 1.61 dholland .d_open = iteopen,
172 1.61 dholland .d_close = iteclose,
173 1.61 dholland .d_read = iteread,
174 1.61 dholland .d_write = itewrite,
175 1.61 dholland .d_ioctl = iteioctl,
176 1.61 dholland .d_stop = nostop,
177 1.61 dholland .d_tty = itetty,
178 1.61 dholland .d_poll = itepoll,
179 1.61 dholland .d_mmap = nommap,
180 1.61 dholland .d_kqfilter = ttykqfilter,
181 1.63 dholland .d_discard = nodiscard,
182 1.61 dholland .d_flag = D_TTY
183 1.29 gehenna };
184 1.29 gehenna
185 1.69 tsutsui static int
186 1.60 tsutsui itematch(device_t parent, cfdata_t cf, void *aux)
187 1.1 oki {
188 1.1 oki struct grf_softc *gp;
189 1.1 oki
190 1.60 tsutsui gp = aux;
191 1.60 tsutsui if (cf->cf_loc[GRFCF_GRFADDR] != gp->g_cfaddr)
192 1.39 chs return 0;
193 1.1 oki
194 1.39 chs return 1;
195 1.1 oki }
196 1.1 oki
197 1.50 isaki /*
198 1.1 oki * iteinit() is the standard entry point for initialization of
199 1.1 oki * an ite device, it is also called from ite_cninit().
200 1.1 oki */
201 1.69 tsutsui static void
202 1.60 tsutsui iteattach(device_t parent, device_t self, void *aux)
203 1.1 oki {
204 1.1 oki struct ite_softc *ip;
205 1.1 oki struct grf_softc *gp;
206 1.1 oki
207 1.60 tsutsui gp = aux;
208 1.60 tsutsui ip = device_private(self);
209 1.60 tsutsui ip->device = self;
210 1.56 isaki if(con_itesoftc.grf != NULL
211 1.56 isaki /*&& con_itesoftc.grf->g_unit == gp->g_unit*/) {
212 1.56 isaki /*
213 1.56 isaki * console reinit copy params over.
214 1.56 isaki * and console always gets keyboard
215 1.56 isaki */
216 1.56 isaki memcpy(&ip->grf, &con_itesoftc.grf,
217 1.56 isaki (char *)&ip[1] - (char *)&ip->grf);
218 1.56 isaki con_itesoftc.grf = NULL;
219 1.56 isaki kbd_ite = ip;
220 1.56 isaki }
221 1.56 isaki ip->grf = gp;
222 1.60 tsutsui iteinit(device_unit(self)); /* XXX */
223 1.57 isaki aprint_normal(": rows %d cols %d", ip->rows, ip->cols);
224 1.56 isaki if (kbd_ite == NULL)
225 1.56 isaki kbd_ite = ip;
226 1.57 isaki aprint_normal("\n");
227 1.1 oki }
228 1.1 oki
229 1.69 tsutsui static struct ite_softc *
230 1.38 chs getitesp(dev_t dev)
231 1.1 oki {
232 1.1 oki
233 1.1 oki if (x68k_realconfig && con_itesoftc.grf == NULL)
234 1.55 cegger return device_lookup_private(&ite_cd, UNIT(dev));
235 1.1 oki
236 1.1 oki if (con_itesoftc.grf == NULL)
237 1.1 oki panic("no ite_softc for console");
238 1.69 tsutsui return &con_itesoftc;
239 1.1 oki }
240 1.1 oki
241 1.49 isaki void
242 1.38 chs iteinit(dev_t dev)
243 1.1 oki {
244 1.1 oki struct ite_softc *ip;
245 1.1 oki
246 1.1 oki ip = getitesp(dev);
247 1.1 oki
248 1.1 oki if (ip->flags & ITE_INITED)
249 1.1 oki return;
250 1.27 wiz memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap));
251 1.1 oki
252 1.1 oki ip->curx = 0;
253 1.1 oki ip->cury = 0;
254 1.1 oki ip->cursorx = 0;
255 1.1 oki ip->cursory = 0;
256 1.1 oki
257 1.60 tsutsui ip->isw = &itesw[device_unit(ip->device)]; /* XXX */
258 1.1 oki SUBR_INIT(ip);
259 1.1 oki SUBR_CURSOR(ip, DRAW_CURSOR);
260 1.69 tsutsui if (ip->tabs == NULL)
261 1.69 tsutsui ip->tabs = malloc(MAX_TABS * sizeof(u_char),
262 1.69 tsutsui M_DEVBUF, M_WAITOK);
263 1.1 oki ite_reset(ip);
264 1.1 oki ip->flags |= ITE_INITED;
265 1.1 oki }
266 1.1 oki
267 1.56 isaki void
268 1.56 isaki ite_config_console(void)
269 1.56 isaki {
270 1.56 isaki struct grf_softc *gp = &congrf;
271 1.56 isaki
272 1.56 isaki if (con_itesoftc.grf != NULL)
273 1.56 isaki return;
274 1.56 isaki con_itesoftc.grf = gp;
275 1.56 isaki con_itesoftc.tabs = cons_tabs;
276 1.60 tsutsui con_itesoftc.device = &con_itedev;
277 1.56 isaki }
278 1.56 isaki
279 1.1 oki /*
280 1.1 oki * Perform functions necessary to setup device as a terminal emulator.
281 1.1 oki */
282 1.49 isaki int
283 1.38 chs iteon(dev_t dev, int flag)
284 1.1 oki {
285 1.1 oki int unit = UNIT(dev);
286 1.12 minoura struct ite_softc *ip;
287 1.1 oki
288 1.12 minoura if (unit < 0 || unit >= ite_cd.cd_ndevs ||
289 1.69 tsutsui (ip = getitesp(dev)) == NULL || (ip->flags & ITE_ALIVE) == 0)
290 1.69 tsutsui return ENXIO;
291 1.1 oki /* force ite active, overriding graphics mode */
292 1.69 tsutsui if ((flag & 1) != 0) {
293 1.1 oki ip->flags |= ITE_ACTIVE;
294 1.1 oki ip->flags &= ~(ITE_INGRF|ITE_INITED);
295 1.1 oki }
296 1.1 oki /* leave graphics mode */
297 1.69 tsutsui if ((flag & 2) != 0) {
298 1.1 oki ip->flags &= ~ITE_INGRF;
299 1.1 oki if ((ip->flags & ITE_ACTIVE) == 0)
300 1.69 tsutsui return 0;
301 1.1 oki }
302 1.1 oki ip->flags |= ITE_ACTIVE;
303 1.69 tsutsui if ((ip->flags & ITE_INGRF) != 0)
304 1.69 tsutsui return 0;
305 1.1 oki iteinit(dev);
306 1.69 tsutsui if ((flag & 2) != 0)
307 1.20 minoura ite_reset(ip);
308 1.14 minoura #if NKBD > 0
309 1.49 isaki mfp_send_usart(0x49); /* XXX */
310 1.14 minoura #endif
311 1.69 tsutsui return 0;
312 1.1 oki }
313 1.1 oki
314 1.1 oki /*
315 1.1 oki * "Shut down" device as terminal emulator.
316 1.1 oki * Note that we do not deinit the console device unless forced.
317 1.1 oki * Deinit'ing the console every time leads to a very active
318 1.1 oki * screen when processing /etc/rc.
319 1.1 oki */
320 1.49 isaki void
321 1.38 chs iteoff(dev_t dev, int flag)
322 1.1 oki {
323 1.4 oki int unit = UNIT(dev);
324 1.38 chs struct ite_softc *ip;
325 1.1 oki
326 1.4 oki /* XXX check whether when call from grf.c */
327 1.12 minoura if (unit < 0 || unit >= ite_cd.cd_ndevs ||
328 1.69 tsutsui (ip = getitesp(dev)) == NULL || (ip->flags & ITE_ALIVE) == 0)
329 1.4 oki return;
330 1.69 tsutsui if ((flag & 2) != 0)
331 1.1 oki ip->flags |= ITE_INGRF;
332 1.1 oki
333 1.1 oki if ((ip->flags & ITE_ACTIVE) == 0)
334 1.1 oki return;
335 1.69 tsutsui if ((flag & 1) != 0 ||
336 1.69 tsutsui (ip->flags & (ITE_INGRF | ITE_ISCONS | ITE_INITED)) == ITE_INITED)
337 1.1 oki SUBR_DEINIT(ip);
338 1.1 oki
339 1.1 oki /*
340 1.1 oki * XXX When the system is rebooted with "reboot", init(8)
341 1.1 oki * kills the last process to have the console open.
342 1.37 simonb * If we don't revent the ITE_ACTIVE bit from being
343 1.1 oki * cleared, we will never see messages printed during
344 1.1 oki * the process of rebooting.
345 1.1 oki */
346 1.14 minoura if ((flag & 2) == 0 && (ip->flags & ITE_ISCONS) == 0) {
347 1.1 oki ip->flags &= ~ITE_ACTIVE;
348 1.14 minoura #if NKBD > 0
349 1.49 isaki mfp_send_usart(0x48); /* XXX */
350 1.14 minoura #endif
351 1.14 minoura }
352 1.1 oki }
353 1.1 oki
354 1.1 oki /*
355 1.1 oki * standard entry points to the device.
356 1.1 oki */
357 1.1 oki
358 1.1 oki /* ARGSUSED */
359 1.69 tsutsui static int
360 1.42 christos iteopen(dev_t dev, int mode, int devtype, struct lwp *l)
361 1.1 oki {
362 1.1 oki int unit = UNIT(dev);
363 1.38 chs struct tty *tp;
364 1.38 chs struct ite_softc *ip;
365 1.38 chs int error;
366 1.1 oki int first = 0;
367 1.1 oki
368 1.15 minoura if (unit >= ite_cd.cd_ndevs || (ip = getitesp(dev)) == NULL)
369 1.69 tsutsui return ENXIO;
370 1.69 tsutsui if (ite_tty[unit] == NULL) {
371 1.59 rmind tp = ite_tty[unit] = tty_alloc();
372 1.3 oki tty_attach(tp);
373 1.3 oki } else
374 1.1 oki tp = ite_tty[unit];
375 1.47 elad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
376 1.69 tsutsui return EBUSY;
377 1.1 oki if ((ip->flags & ITE_ACTIVE) == 0) {
378 1.1 oki error = iteon(dev, 0);
379 1.1 oki if (error)
380 1.69 tsutsui return error;
381 1.1 oki first = 1;
382 1.1 oki }
383 1.1 oki tp->t_oproc = itestart;
384 1.1 oki tp->t_param = NULL;
385 1.1 oki tp->t_dev = dev;
386 1.1 oki if ((tp->t_state&TS_ISOPEN) == 0) {
387 1.1 oki ttychars(tp);
388 1.1 oki tp->t_iflag = TTYDEF_IFLAG;
389 1.1 oki tp->t_oflag = TTYDEF_OFLAG;
390 1.1 oki tp->t_cflag = TTYDEF_CFLAG;
391 1.1 oki tp->t_lflag = TTYDEF_LFLAG;
392 1.1 oki tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
393 1.1 oki tp->t_state = TS_ISOPEN|TS_CARR_ON;
394 1.1 oki ttsetwater(tp);
395 1.1 oki }
396 1.23 eeh error = (*tp->t_linesw->l_open)(dev, tp);
397 1.1 oki if (error == 0) {
398 1.1 oki tp->t_winsize.ws_row = ip->rows;
399 1.1 oki tp->t_winsize.ws_col = ip->cols;
400 1.1 oki } else if (first)
401 1.1 oki iteoff(dev, 0);
402 1.69 tsutsui return error;
403 1.1 oki }
404 1.1 oki
405 1.1 oki /*ARGSUSED*/
406 1.69 tsutsui static int
407 1.42 christos iteclose(dev_t dev, int flag, int mode, struct lwp *l)
408 1.1 oki {
409 1.38 chs struct tty *tp = ite_tty[UNIT(dev)];
410 1.1 oki
411 1.23 eeh (*tp->t_linesw->l_close)(tp, flag);
412 1.1 oki ttyclose(tp);
413 1.1 oki iteoff(dev, 0);
414 1.1 oki #if 0
415 1.59 rmind tty_free(tp);
416 1.69 tsutsui ite_tty[UNIT(dev)] = NULL;
417 1.1 oki #endif
418 1.69 tsutsui return 0;
419 1.1 oki }
420 1.1 oki
421 1.69 tsutsui static int
422 1.38 chs iteread(dev_t dev, struct uio *uio, int flag)
423 1.1 oki {
424 1.38 chs struct tty *tp = ite_tty[UNIT(dev)];
425 1.1 oki
426 1.69 tsutsui return (*tp->t_linesw->l_read)(tp, uio, flag);
427 1.1 oki }
428 1.1 oki
429 1.69 tsutsui static int
430 1.38 chs itewrite(dev_t dev, struct uio *uio, int flag)
431 1.1 oki {
432 1.38 chs struct tty *tp = ite_tty[UNIT(dev)];
433 1.1 oki
434 1.69 tsutsui return (*tp->t_linesw->l_write)(tp, uio, flag);
435 1.25 scw }
436 1.25 scw
437 1.69 tsutsui static int
438 1.42 christos itepoll(dev_t dev, int events, struct lwp *l)
439 1.25 scw {
440 1.38 chs struct tty *tp = ite_tty[UNIT(dev)];
441 1.50 isaki
442 1.69 tsutsui return (*tp->t_linesw->l_poll)(tp, events, l);
443 1.1 oki }
444 1.1 oki
445 1.69 tsutsui static struct tty *
446 1.38 chs itetty(dev_t dev)
447 1.1 oki {
448 1.1 oki
449 1.69 tsutsui return ite_tty[UNIT(dev)];
450 1.1 oki }
451 1.1 oki
452 1.69 tsutsui static int
453 1.48 christos iteioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
454 1.1 oki {
455 1.1 oki struct iterepeat *irp;
456 1.38 chs struct tty *tp = ite_tty[UNIT(dev)];
457 1.1 oki int error;
458 1.1 oki
459 1.42 christos error = (*tp->t_linesw->l_ioctl)(tp, cmd, addr, flag, l);
460 1.28 atatat if (error != EPASSTHROUGH)
461 1.69 tsutsui return error;
462 1.28 atatat
463 1.42 christos error = ttioctl(tp, cmd, addr, flag, l);
464 1.28 atatat if (error != EPASSTHROUGH)
465 1.69 tsutsui return error;
466 1.1 oki
467 1.1 oki switch (cmd) {
468 1.1 oki case ITEIOCSKMAP:
469 1.69 tsutsui if (addr == NULL)
470 1.69 tsutsui return EFAULT;
471 1.27 wiz memcpy(&kbdmap, addr, sizeof(struct kbdmap));
472 1.69 tsutsui return 0;
473 1.1 oki
474 1.1 oki case ITEIOCGKMAP:
475 1.1 oki if (addr == NULL)
476 1.69 tsutsui return EFAULT;
477 1.27 wiz memcpy(addr, &kbdmap, sizeof(struct kbdmap));
478 1.69 tsutsui return 0;
479 1.1 oki
480 1.1 oki case ITEIOCGREPT:
481 1.1 oki irp = (struct iterepeat *)addr;
482 1.1 oki irp->start = start_repeat_timeo;
483 1.1 oki irp->next = next_repeat_timeo;
484 1.1 oki
485 1.1 oki case ITEIOCSREPT:
486 1.1 oki irp = (struct iterepeat *)addr;
487 1.1 oki if (irp->start < ITEMINREPEAT && irp->next < ITEMINREPEAT)
488 1.1 oki return(EINVAL);
489 1.1 oki start_repeat_timeo = irp->start;
490 1.1 oki next_repeat_timeo = irp->next;
491 1.1 oki #if x68k
492 1.1 oki case ITELOADFONT:
493 1.69 tsutsui if (addr != NULL) {
494 1.49 isaki memcpy(kern_font, addr, 4096 /*sizeof(kernel_font)*/);
495 1.26 isaki ite_set_glyph();
496 1.1 oki return 0;
497 1.1 oki } else
498 1.1 oki return EFAULT;
499 1.1 oki
500 1.1 oki case ITETVCTRL:
501 1.69 tsutsui if (addr != NULL && *(uint8_t *)addr < 0x40) {
502 1.69 tsutsui return mfp_send_usart(*(uint8_t *)addr);
503 1.14 minoura } else {
504 1.1 oki return EFAULT;
505 1.14 minoura }
506 1.1 oki #endif
507 1.1 oki }
508 1.69 tsutsui return EPASSTHROUGH;
509 1.1 oki }
510 1.1 oki
511 1.69 tsutsui static void
512 1.38 chs itestart(struct tty *tp)
513 1.1 oki {
514 1.1 oki struct clist *rbp;
515 1.69 tsutsui uint8_t buf[ITEBURST];
516 1.16 minoura int s, len;
517 1.1 oki
518 1.62 christos getitesp(tp->t_dev);
519 1.1 oki /*
520 1.1 oki * (Potentially) lower priority. We only need to protect ourselves
521 1.1 oki * from keyboard interrupts since that is all that can affect the
522 1.6 christos * state of our tty (kernel printf doesn't go through this routine).
523 1.1 oki */
524 1.1 oki s = spltty();
525 1.69 tsutsui if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) != 0)
526 1.1 oki goto out;
527 1.1 oki tp->t_state |= TS_BUSY;
528 1.1 oki rbp = &tp->t_outq;
529 1.1 oki len = q_to_b(rbp, buf, ITEBURST);
530 1.1 oki /*splx(s);*/
531 1.1 oki
532 1.1 oki /* Here is a really good place to implement pre/jumpscroll() */
533 1.1 oki ite_putstr(buf, len, tp->t_dev);
534 1.1 oki
535 1.1 oki /*s = spltty();*/
536 1.1 oki tp->t_state &= ~TS_BUSY;
537 1.1 oki /* we have characters remaining. */
538 1.53 ad if (ttypull(tp)) {
539 1.1 oki tp->t_state |= TS_TIMEOUT;
540 1.52 joerg callout_schedule(&tp->t_rstrt_ch, 1);
541 1.1 oki }
542 1.69 tsutsui out:
543 1.1 oki splx(s);
544 1.1 oki }
545 1.1 oki
546 1.1 oki /* XXX called after changes made in underlying grf layer. */
547 1.1 oki /* I want to nuke this */
548 1.49 isaki void
549 1.38 chs ite_reinit(dev_t dev)
550 1.1 oki {
551 1.1 oki struct ite_softc *ip;
552 1.4 oki int unit = UNIT(dev);
553 1.4 oki
554 1.4 oki /* XXX check whether when call from grf.c */
555 1.12 minoura if (unit < 0 || unit >= ite_cd.cd_ndevs ||
556 1.60 tsutsui (ip = getitesp(dev)) == NULL)
557 1.4 oki return;
558 1.1 oki
559 1.1 oki ip->flags &= ~ITE_INITED;
560 1.1 oki iteinit(dev);
561 1.1 oki }
562 1.1 oki
563 1.49 isaki void
564 1.38 chs ite_reset(struct ite_softc *ip)
565 1.1 oki {
566 1.1 oki int i;
567 1.1 oki
568 1.1 oki ip->curx = 0;
569 1.1 oki ip->cury = 0;
570 1.1 oki ip->attribute = 0;
571 1.1 oki ip->save_curx = 0;
572 1.1 oki ip->save_cury = 0;
573 1.1 oki ip->save_attribute = 0;
574 1.1 oki ip->ap = ip->argbuf;
575 1.1 oki ip->emul_level = EMUL_VT300_8;
576 1.1 oki ip->eightbit_C1 = 0;
577 1.1 oki ip->top_margin = 0;
578 1.1 oki ip->bottom_margin = ip->rows - 1;
579 1.1 oki ip->inside_margins = 0; /* origin mode == absolute */
580 1.1 oki ip->linefeed_newline = 0;
581 1.1 oki ip->auto_wrap = 1;
582 1.1 oki ip->cursor_appmode = 0;
583 1.1 oki ip->keypad_appmode = 0;
584 1.1 oki ip->imode = 0;
585 1.1 oki ip->key_repeat = 1;
586 1.1 oki ip->G0 = CSET_ASCII;
587 1.1 oki ip->G1 = CSET_JIS1983;
588 1.1 oki ip->G2 = CSET_JISKANA;
589 1.1 oki ip->G3 = CSET_JIS1990;
590 1.1 oki ip->GL = &ip->G0;
591 1.1 oki ip->GR = &ip->G1;
592 1.1 oki ip->save_GL = 0;
593 1.1 oki ip->save_char = 0;
594 1.1 oki ip->fgcolor = 7;
595 1.1 oki ip->bgcolor = 0;
596 1.1 oki for (i = 0; i < ip->cols; i++)
597 1.1 oki ip->tabs[i] = ((i & 7) == 0);
598 1.1 oki /* XXX clear screen */
599 1.1 oki SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
600 1.1 oki attrclr(ip, 0, 0, ip->rows, ip->cols);
601 1.1 oki }
602 1.1 oki
603 1.1 oki /* Used in console at startup only */
604 1.1 oki int
605 1.49 isaki ite_cnfilter(u_char c)
606 1.1 oki {
607 1.1 oki static u_char mod = 0;
608 1.1 oki struct key key;
609 1.69 tsutsui uint8_t code, up, mask;
610 1.16 minoura int s;
611 1.1 oki
612 1.1 oki up = c & 0x80 ? 1 : 0;
613 1.1 oki c &= 0x7f;
614 1.1 oki code = 0;
615 1.1 oki
616 1.1 oki s = spltty();
617 1.1 oki
618 1.1 oki mask = 0;
619 1.69 tsutsui if (c >= KBD_LEFT_ALT &&
620 1.69 tsutsui !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
621 1.1 oki switch (c) {
622 1.1 oki case KBD_LEFT_SHIFT:
623 1.1 oki mask = KBD_MOD_SHIFT;
624 1.1 oki break;
625 1.1 oki
626 1.1 oki case KBD_LEFT_ALT:
627 1.1 oki mask = KBD_MOD_LALT;
628 1.1 oki break;
629 1.1 oki
630 1.1 oki case KBD_RIGHT_ALT:
631 1.1 oki mask = KBD_MOD_RALT;
632 1.1 oki break;
633 1.1 oki
634 1.1 oki case KBD_LEFT_META:
635 1.1 oki mask = KBD_MOD_LMETA;
636 1.1 oki break;
637 1.1 oki
638 1.1 oki case KBD_RIGHT_META:
639 1.1 oki mask = KBD_MOD_RMETA;
640 1.1 oki break;
641 1.1 oki
642 1.49 isaki case KBD_CAPS_LOCK:
643 1.1 oki /*
644 1.1 oki * capslock already behaves `right', don't need to
645 1.1 oki * keep track of the state in here.
646 1.1 oki */
647 1.1 oki mask = KBD_MOD_CAPS;
648 1.1 oki break;
649 1.1 oki
650 1.1 oki case KBD_CTRL:
651 1.1 oki mask = KBD_MOD_CTRL;
652 1.1 oki break;
653 1.1 oki
654 1.1 oki case KBD_RECONNECT:
655 1.1 oki /* ite got 0xff */
656 1.1 oki if (up)
657 1.1 oki kbd_setLED();
658 1.1 oki break;
659 1.1 oki }
660 1.1 oki if (mask & KBD_MOD_CAPS) {
661 1.1 oki if (!up) {
662 1.1 oki mod ^= KBD_MOD_CAPS;
663 1.1 oki kbdled ^= LED_CAPS_LOCK;
664 1.1 oki kbd_setLED();
665 1.1 oki }
666 1.1 oki } else if (up)
667 1.1 oki mod &= ~mask;
668 1.69 tsutsui else
669 1.69 tsutsui mod |= mask;
670 1.49 isaki splx(s);
671 1.1 oki return -1;
672 1.1 oki }
673 1.1 oki
674 1.1 oki if (up) {
675 1.1 oki splx(s);
676 1.1 oki return -1;
677 1.1 oki }
678 1.1 oki
679 1.1 oki /* translate modifiers */
680 1.69 tsutsui if ((mod & KBD_MOD_SHIFT) != 0) {
681 1.69 tsutsui if ((mod & KBD_MOD_ALT) != 0)
682 1.1 oki key = kbdmap.alt_shift_keys[c];
683 1.50 isaki else
684 1.1 oki key = kbdmap.shift_keys[c];
685 1.69 tsutsui } else if ((mod & KBD_MOD_ALT) != 0)
686 1.1 oki key = kbdmap.alt_keys[c];
687 1.1 oki else {
688 1.1 oki key = kbdmap.keys[c];
689 1.1 oki /* if CAPS and key is CAPable (no pun intended) */
690 1.69 tsutsui if ((mod & KBD_MOD_CAPS) != 0 &&
691 1.69 tsutsui (key.mode & KBD_MODE_CAPS) != 0)
692 1.1 oki key = kbdmap.shift_keys[c];
693 1.1 oki }
694 1.1 oki code = key.code;
695 1.1 oki
696 1.1 oki /* if string return */
697 1.69 tsutsui if ((key.mode & (KBD_MODE_STRING | KBD_MODE_KPAD)) != 0) {
698 1.1 oki splx(s);
699 1.1 oki return -1;
700 1.1 oki }
701 1.1 oki /* handle dead keys */
702 1.69 tsutsui if ((key.mode & KBD_MODE_DEAD) != 0) {
703 1.1 oki splx(s);
704 1.1 oki return -1;
705 1.1 oki }
706 1.69 tsutsui if ((mod & KBD_MOD_CTRL) != 0)
707 1.1 oki code &= 0x1f;
708 1.69 tsutsui if ((mod & KBD_MOD_META) != 0)
709 1.1 oki code |= 0x80;
710 1.1 oki
711 1.1 oki /* do console mapping. */
712 1.1 oki code = code == '\r' ? '\n' : code;
713 1.1 oki
714 1.1 oki splx(s);
715 1.69 tsutsui return code;
716 1.1 oki }
717 1.1 oki
718 1.1 oki /* And now the old stuff. */
719 1.69 tsutsui static inline void
720 1.38 chs itesendch(int ch)
721 1.1 oki {
722 1.69 tsutsui
723 1.24 minoura (*kbd_tty->t_linesw->l_rint)(ch, kbd_tty);
724 1.1 oki }
725 1.1 oki
726 1.1 oki void
727 1.49 isaki ite_filter(u_char c)
728 1.1 oki {
729 1.69 tsutsui static uint16_t mod = 0;
730 1.69 tsutsui uint8_t code, *str;
731 1.69 tsutsui uint16_t up, mask;
732 1.1 oki struct key key;
733 1.1 oki int s, i;
734 1.1 oki
735 1.69 tsutsui if (kbd_ite == NULL ||
736 1.69 tsutsui (kbd_tty = ite_tty[device_unit(kbd_ite->device)]) == NULL)
737 1.1 oki return;
738 1.1 oki
739 1.1 oki /* have to make sure we're at spltty in here */
740 1.49 isaki s = spltty();
741 1.1 oki
742 1.1 oki up = c & 0x80 ? 1 : 0;
743 1.1 oki c &= 0x7f;
744 1.1 oki code = 0;
745 1.50 isaki
746 1.1 oki mask = 0;
747 1.1 oki if (c >= KBD_LEFT_ALT &&
748 1.1 oki !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
749 1.1 oki switch (c) {
750 1.1 oki case KBD_LEFT_SHIFT:
751 1.1 oki mask = KBD_MOD_SHIFT;
752 1.1 oki break;
753 1.1 oki
754 1.1 oki case KBD_LEFT_ALT:
755 1.1 oki mask = KBD_MOD_LALT;
756 1.1 oki break;
757 1.49 isaki
758 1.1 oki case KBD_RIGHT_ALT:
759 1.1 oki mask = KBD_MOD_RALT;
760 1.1 oki break;
761 1.49 isaki
762 1.1 oki case KBD_LEFT_META:
763 1.1 oki mask = KBD_MOD_LMETA;
764 1.1 oki break;
765 1.1 oki
766 1.1 oki case KBD_RIGHT_META:
767 1.1 oki mask = KBD_MOD_RMETA;
768 1.1 oki break;
769 1.1 oki
770 1.1 oki case KBD_CAPS_LOCK:
771 1.1 oki /*
772 1.1 oki * capslock already behaves `right', don't need to keep
773 1.1 oki * track of the state in here.
774 1.1 oki */
775 1.1 oki mask = KBD_MOD_CAPS;
776 1.1 oki break;
777 1.1 oki
778 1.1 oki case KBD_CTRL:
779 1.1 oki mask = KBD_MOD_CTRL;
780 1.1 oki break;
781 1.1 oki
782 1.1 oki case KBD_OPT1:
783 1.1 oki mask = KBD_MOD_OPT1;
784 1.1 oki break;
785 1.1 oki
786 1.1 oki case KBD_OPT2:
787 1.1 oki mask = KBD_MOD_OPT2;
788 1.1 oki break;
789 1.1 oki
790 1.1 oki case KBD_RECONNECT:
791 1.1 oki if (up) { /* ite got 0xff */
792 1.1 oki kbd_setLED();
793 1.1 oki }
794 1.1 oki break;
795 1.1 oki }
796 1.1 oki
797 1.69 tsutsui if ((mask & KBD_MOD_CAPS) != 0) {
798 1.1 oki if (!up) {
799 1.1 oki mod ^= KBD_MOD_CAPS;
800 1.1 oki kbdled ^= LED_CAPS_LOCK;
801 1.1 oki kbd_setLED();
802 1.1 oki }
803 1.1 oki } else if (up) {
804 1.1 oki mod &= ~mask;
805 1.69 tsutsui } else
806 1.69 tsutsui mod |= mask;
807 1.1 oki
808 1.1 oki /*
809 1.1 oki * return even if it wasn't a modifier key, the other
810 1.1 oki * codes up here are either special (like reset warning),
811 1.1 oki * or not yet defined
812 1.1 oki */
813 1.49 isaki splx(s);
814 1.1 oki return;
815 1.1 oki }
816 1.1 oki
817 1.1 oki if (up) {
818 1.49 isaki splx(s);
819 1.1 oki return;
820 1.1 oki }
821 1.1 oki
822 1.1 oki /*
823 1.1 oki * intercept LAlt-LMeta-F1 here to switch back to original ascii-keymap.
824 1.1 oki * this should probably be configurable..
825 1.1 oki */
826 1.16 minoura if (mod == (KBD_MOD_LALT|KBD_MOD_LMETA) && c == 0x63) {
827 1.27 wiz memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap));
828 1.49 isaki splx(s);
829 1.1 oki return;
830 1.1 oki }
831 1.1 oki
832 1.1 oki /* translate modifiers */
833 1.69 tsutsui if ((mod & KBD_MOD_SHIFT) != 0) {
834 1.69 tsutsui if ((mod & KBD_MOD_ALT) != 0)
835 1.1 oki key = kbdmap.alt_shift_keys[c];
836 1.50 isaki else
837 1.1 oki key = kbdmap.shift_keys[c];
838 1.69 tsutsui } else if ((mod & KBD_MOD_ALT) != 0)
839 1.1 oki key = kbdmap.alt_keys[c];
840 1.1 oki else {
841 1.1 oki key = kbdmap.keys[c];
842 1.1 oki /* if CAPS and key is CAPable (no pun intended) */
843 1.69 tsutsui if ((mod & KBD_MOD_CAPS) != 0 &&
844 1.69 tsutsui (key.mode & KBD_MODE_CAPS) != 0)
845 1.1 oki key = kbdmap.shift_keys[c];
846 1.69 tsutsui else if ((mod & KBD_MOD_OPT2) != 0 &&
847 1.69 tsutsui (key.mode & KBD_MODE_KPAD) != 0)
848 1.1 oki key = kbdmap.shift_keys[c];
849 1.1 oki }
850 1.1 oki code = key.code;
851 1.50 isaki
852 1.1 oki /* handle dead keys */
853 1.69 tsutsui if ((key.mode & KBD_MODE_DEAD) != 0) {
854 1.49 isaki splx(s);
855 1.1 oki return;
856 1.1 oki }
857 1.50 isaki /* if not string, apply META and CTRL modifiers */
858 1.69 tsutsui if ((key.mode & KBD_MODE_STRING) == 0 &&
859 1.69 tsutsui ((key.mode & KBD_MODE_KPAD) == 0 ||
860 1.69 tsutsui (kbd_ite != NULL && kbd_ite->keypad_appmode == 0))) {
861 1.69 tsutsui if ((mod & KBD_MOD_CTRL) != 0 &&
862 1.1 oki (code == ' ' || (code >= '@' && code <= 'z')))
863 1.1 oki code &= 0x1f;
864 1.69 tsutsui if ((mod & KBD_MOD_META) != 0)
865 1.1 oki code |= 0x80;
866 1.69 tsutsui } else if ((key.mode & KBD_MODE_KPAD) != 0 &&
867 1.69 tsutsui (kbd_ite != NULL && kbd_ite->keypad_appmode != 0)) {
868 1.36 jdolecek static const char * const in = "0123456789-+.\r()/*";
869 1.36 jdolecek static const char * const out = "pqrstuvwxymlnMPQRS";
870 1.36 jdolecek char *cp = strchr(in, code);
871 1.1 oki
872 1.50 isaki /*
873 1.1 oki * keypad-appmode sends SS3 followed by the above
874 1.1 oki * translated character
875 1.1 oki */
876 1.49 isaki (*kbd_tty->t_linesw->l_rint)(27, kbd_tty);
877 1.49 isaki (*kbd_tty->t_linesw->l_rint)('O', kbd_tty);
878 1.49 isaki (*kbd_tty->t_linesw->l_rint)(out[cp - in], kbd_tty);
879 1.1 oki splx(s);
880 1.1 oki return;
881 1.1 oki } else {
882 1.1 oki /* *NO* I don't like this.... */
883 1.69 tsutsui static u_char app_cursor[] = {
884 1.1 oki 3, 27, 'O', 'A',
885 1.1 oki 3, 27, 'O', 'B',
886 1.1 oki 3, 27, 'O', 'C',
887 1.69 tsutsui 3, 27, 'O', 'D'
888 1.69 tsutsui };
889 1.1 oki
890 1.1 oki str = kbdmap.strings + code;
891 1.50 isaki /*
892 1.1 oki * if this is a cursor key, AND it has the default
893 1.1 oki * keymap setting, AND we're in app-cursor mode, switch
894 1.1 oki * to the above table. This is *nasty* !
895 1.1 oki */
896 1.69 tsutsui if (c >= 0x3b && c <= 0x3e && kbd_ite->cursor_appmode != 0 &&
897 1.69 tsutsui memcmp(str, "\x03\x1b[", 3) == 0 &&
898 1.69 tsutsui strchr("ABCD", str[3]) != 0)
899 1.1 oki str = app_cursor + 4 * (str[3] - 'A');
900 1.1 oki
901 1.50 isaki /*
902 1.1 oki * using a length-byte instead of 0-termination allows
903 1.1 oki * to embed \0 into strings, although this is not used
904 1.1 oki * in the default keymap
905 1.1 oki */
906 1.1 oki for (i = *str++; i; i--)
907 1.49 isaki (*kbd_tty->t_linesw->l_rint)(*str++, kbd_tty);
908 1.1 oki splx(s);
909 1.1 oki return;
910 1.1 oki }
911 1.24 minoura (*kbd_tty->t_linesw->l_rint)(code, kbd_tty);
912 1.1 oki
913 1.1 oki splx(s);
914 1.1 oki return;
915 1.1 oki }
916 1.1 oki
917 1.1 oki /* helper functions, makes the code below more readable */
918 1.69 tsutsui static inline void
919 1.40 he ite_sendstr(struct ite_softc *ip, const char *str)
920 1.1 oki {
921 1.69 tsutsui
922 1.69 tsutsui while (*str != 0)
923 1.49 isaki itesendch(*str++);
924 1.1 oki }
925 1.1 oki
926 1.69 tsutsui static inline void
927 1.38 chs alignment_display(struct ite_softc *ip)
928 1.1 oki {
929 1.1 oki int i, j;
930 1.1 oki
931 1.1 oki for (j = 0; j < ip->rows; j++)
932 1.1 oki for (i = 0; i < ip->cols; i++)
933 1.1 oki SUBR_PUTC(ip, 'E', j, i, ATTR_NOR);
934 1.1 oki attrclr(ip, 0, 0, ip->rows, ip->cols);
935 1.1 oki }
936 1.1 oki
937 1.69 tsutsui static inline void
938 1.38 chs snap_cury(struct ite_softc *ip)
939 1.1 oki {
940 1.69 tsutsui
941 1.69 tsutsui if (ip->inside_margins != 0) {
942 1.1 oki if (ip->cury < ip->top_margin)
943 1.1 oki ip->cury = ip->top_margin;
944 1.1 oki if (ip->cury > ip->bottom_margin)
945 1.1 oki ip->cury = ip->bottom_margin;
946 1.1 oki }
947 1.1 oki }
948 1.1 oki
949 1.69 tsutsui static inline void
950 1.38 chs ite_dnchar(struct ite_softc *ip, int n)
951 1.1 oki {
952 1.69 tsutsui
953 1.64 riastrad n = uimin(n, ip->cols - ip->curx);
954 1.1 oki if (n < ip->cols - ip->curx) {
955 1.1 oki SUBR_SCROLL(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
956 1.1 oki attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
957 1.69 tsutsui 1, ip->cols - ip->curx - n);
958 1.1 oki attrclr(ip, ip->cury, ip->cols - n, 1, n);
959 1.1 oki }
960 1.1 oki while (n-- > 0)
961 1.1 oki SUBR_PUTC(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
962 1.1 oki }
963 1.1 oki
964 1.49 isaki static void
965 1.38 chs ite_inchar(struct ite_softc *ip, int n)
966 1.1 oki {
967 1.1 oki int c = ip->save_char;
968 1.69 tsutsui
969 1.1 oki ip->save_char = 0;
970 1.64 riastrad n = uimin(n, ip->cols - ip->curx);
971 1.1 oki if (n < ip->cols - ip->curx) {
972 1.1 oki SUBR_SCROLL(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
973 1.1 oki attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
974 1.69 tsutsui 1, ip->cols - ip->curx - n);
975 1.1 oki attrclr(ip, ip->cury, ip->curx, 1, n);
976 1.1 oki }
977 1.69 tsutsui while (n-- != 0)
978 1.1 oki SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
979 1.1 oki ip->save_char = c;
980 1.1 oki }
981 1.1 oki
982 1.69 tsutsui static inline void
983 1.38 chs ite_clrtoeol(struct ite_softc *ip)
984 1.1 oki {
985 1.1 oki int y = ip->cury, x = ip->curx;
986 1.69 tsutsui
987 1.1 oki if (ip->cols - x > 0) {
988 1.1 oki SUBR_CLEAR(ip, y, x, 1, ip->cols - x);
989 1.1 oki attrclr(ip, y, x, 1, ip->cols - x);
990 1.1 oki }
991 1.1 oki }
992 1.1 oki
993 1.69 tsutsui static inline void
994 1.38 chs ite_clrtobol(struct ite_softc *ip)
995 1.1 oki {
996 1.64 riastrad int y = ip->cury, x = uimin(ip->curx + 1, ip->cols);
997 1.69 tsutsui
998 1.1 oki SUBR_CLEAR(ip, y, 0, 1, x);
999 1.1 oki attrclr(ip, y, 0, 1, x);
1000 1.1 oki }
1001 1.1 oki
1002 1.69 tsutsui static inline void
1003 1.38 chs ite_clrline(struct ite_softc *ip)
1004 1.1 oki {
1005 1.1 oki int y = ip->cury;
1006 1.69 tsutsui
1007 1.1 oki SUBR_CLEAR(ip, y, 0, 1, ip->cols);
1008 1.1 oki attrclr(ip, y, 0, 1, ip->cols);
1009 1.1 oki }
1010 1.1 oki
1011 1.69 tsutsui static inline void
1012 1.38 chs ite_clrtoeos(struct ite_softc *ip)
1013 1.1 oki {
1014 1.69 tsutsui
1015 1.1 oki ite_clrtoeol(ip);
1016 1.1 oki if (ip->cury < ip->rows - 1) {
1017 1.69 tsutsui SUBR_CLEAR(ip, ip->cury + 1, 0,
1018 1.69 tsutsui ip->rows - 1 - ip->cury, ip->cols);
1019 1.1 oki attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
1020 1.1 oki }
1021 1.1 oki }
1022 1.1 oki
1023 1.69 tsutsui static inline void
1024 1.38 chs ite_clrtobos(struct ite_softc *ip)
1025 1.1 oki {
1026 1.69 tsutsui
1027 1.1 oki ite_clrtobol(ip);
1028 1.1 oki if (ip->cury > 0) {
1029 1.1 oki SUBR_CLEAR(ip, 0, 0, ip->cury, ip->cols);
1030 1.1 oki attrclr(ip, 0, 0, ip->cury, ip->cols);
1031 1.1 oki }
1032 1.1 oki }
1033 1.1 oki
1034 1.69 tsutsui static inline void
1035 1.38 chs ite_clrscreen(struct ite_softc *ip)
1036 1.1 oki {
1037 1.69 tsutsui
1038 1.1 oki SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
1039 1.1 oki attrclr(ip, 0, 0, ip->rows, ip->cols);
1040 1.1 oki }
1041 1.1 oki
1042 1.69 tsutsui static inline void
1043 1.38 chs ite_dnline(struct ite_softc *ip, int n)
1044 1.1 oki {
1045 1.69 tsutsui
1046 1.1 oki /*
1047 1.1 oki * interesting.. if the cursor is outside the scrolling
1048 1.1 oki * region, this command is simply ignored..
1049 1.1 oki */
1050 1.1 oki if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
1051 1.1 oki return;
1052 1.1 oki
1053 1.64 riastrad n = uimin(n, ip->bottom_margin + 1 - ip->cury);
1054 1.1 oki if (n <= ip->bottom_margin - ip->cury) {
1055 1.1 oki SUBR_SCROLL(ip, ip->cury + n, 0, n, SCROLL_UP);
1056 1.1 oki attrmov(ip, ip->cury + n, 0, ip->cury, 0,
1057 1.69 tsutsui ip->bottom_margin + 1 - ip->cury - n, ip->cols);
1058 1.1 oki }
1059 1.1 oki SUBR_CLEAR(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
1060 1.1 oki attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
1061 1.1 oki }
1062 1.1 oki
1063 1.69 tsutsui static inline void
1064 1.38 chs ite_inline(struct ite_softc *ip, int n)
1065 1.1 oki {
1066 1.69 tsutsui
1067 1.1 oki /*
1068 1.1 oki * interesting.. if the cursor is outside the scrolling
1069 1.1 oki * region, this command is simply ignored..
1070 1.1 oki */
1071 1.1 oki if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
1072 1.1 oki return;
1073 1.1 oki
1074 1.1 oki if (n <= 0)
1075 1.1 oki n = 1;
1076 1.69 tsutsui else
1077 1.69 tsutsui n = uimin(n, ip->bottom_margin + 1 - ip->cury);
1078 1.1 oki if (n <= ip->bottom_margin - ip->cury) {
1079 1.1 oki SUBR_SCROLL(ip, ip->cury, 0, n, SCROLL_DOWN);
1080 1.1 oki attrmov(ip, ip->cury, 0, ip->cury + n, 0,
1081 1.69 tsutsui ip->bottom_margin + 1 - ip->cury - n, ip->cols);
1082 1.1 oki }
1083 1.1 oki SUBR_CLEAR(ip, ip->cury, 0, n, ip->cols);
1084 1.1 oki attrclr(ip, ip->cury, 0, n, ip->cols);
1085 1.1 oki ip->curx = 0;
1086 1.1 oki }
1087 1.1 oki
1088 1.69 tsutsui static inline void
1089 1.38 chs ite_index(struct ite_softc *ip)
1090 1.1 oki {
1091 1.69 tsutsui
1092 1.1 oki ++ip->cury;
1093 1.1 oki if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows)) {
1094 1.1 oki ip->cury--;
1095 1.1 oki SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1096 1.1 oki ite_clrline(ip);
1097 1.1 oki }
1098 1.1 oki /*clr_attr(ip, ATTR_INV);*/
1099 1.1 oki }
1100 1.1 oki
1101 1.69 tsutsui static inline void
1102 1.38 chs ite_lf(struct ite_softc *ip)
1103 1.1 oki {
1104 1.69 tsutsui
1105 1.1 oki ++ip->cury;
1106 1.1 oki if (ip->cury > ip->bottom_margin) {
1107 1.1 oki ip->cury--;
1108 1.1 oki SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1109 1.1 oki ite_clrline(ip);
1110 1.1 oki }
1111 1.69 tsutsui /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
1112 1.1 oki /*clr_attr(ip, ATTR_INV);*/
1113 1.1 oki /* reset character set ... thanks for mohta. */
1114 1.1 oki ip->G0 = CSET_ASCII;
1115 1.1 oki ip->G1 = CSET_JIS1983;
1116 1.1 oki ip->G2 = CSET_JISKANA;
1117 1.1 oki ip->G3 = CSET_JIS1990;
1118 1.1 oki ip->GL = &ip->G0;
1119 1.1 oki ip->GR = &ip->G1;
1120 1.1 oki ip->save_GL = 0;
1121 1.1 oki ip->save_char = 0;
1122 1.1 oki }
1123 1.1 oki
1124 1.69 tsutsui static inline void
1125 1.38 chs ite_crlf(struct ite_softc *ip)
1126 1.1 oki {
1127 1.69 tsutsui
1128 1.1 oki ip->curx = 0;
1129 1.69 tsutsui ite_lf(ip);
1130 1.1 oki }
1131 1.1 oki
1132 1.69 tsutsui static inline void
1133 1.38 chs ite_cr(struct ite_softc *ip)
1134 1.1 oki {
1135 1.69 tsutsui
1136 1.69 tsutsui if (ip->curx != 0) {
1137 1.1 oki ip->curx = 0;
1138 1.1 oki }
1139 1.1 oki }
1140 1.1 oki
1141 1.69 tsutsui static inline void
1142 1.38 chs ite_rlf(struct ite_softc *ip)
1143 1.1 oki {
1144 1.69 tsutsui
1145 1.1 oki ip->cury--;
1146 1.1 oki if ((ip->cury < 0) || (ip->cury == ip->top_margin - 1)) {
1147 1.1 oki ip->cury++;
1148 1.1 oki SUBR_SCROLL(ip, ip->top_margin, 0, 1, SCROLL_DOWN);
1149 1.1 oki ite_clrline(ip);
1150 1.1 oki }
1151 1.1 oki clr_attr(ip, ATTR_INV);
1152 1.1 oki }
1153 1.1 oki
1154 1.69 tsutsui static inline int
1155 1.38 chs atoi(const char *cp)
1156 1.1 oki {
1157 1.1 oki int n;
1158 1.1 oki
1159 1.1 oki for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
1160 1.1 oki n = n * 10 + *cp - '0';
1161 1.1 oki return n;
1162 1.1 oki }
1163 1.1 oki
1164 1.69 tsutsui static inline int
1165 1.38 chs ite_argnum(struct ite_softc *ip)
1166 1.1 oki {
1167 1.1 oki char ch;
1168 1.1 oki int n;
1169 1.1 oki
1170 1.1 oki /* convert argument string into number */
1171 1.1 oki if (ip->ap == ip->argbuf)
1172 1.1 oki return 1;
1173 1.1 oki ch = *ip->ap;
1174 1.1 oki *ip->ap = 0;
1175 1.49 isaki n = atoi(ip->argbuf);
1176 1.1 oki *ip->ap = ch;
1177 1.1 oki
1178 1.1 oki return n;
1179 1.1 oki }
1180 1.1 oki
1181 1.69 tsutsui static inline int
1182 1.38 chs ite_zargnum(struct ite_softc *ip)
1183 1.1 oki {
1184 1.1 oki char ch;
1185 1.1 oki int n;
1186 1.1 oki
1187 1.1 oki /* convert argument string into number */
1188 1.1 oki if (ip->ap == ip->argbuf)
1189 1.1 oki return 0;
1190 1.1 oki ch = *ip->ap;
1191 1.1 oki *ip->ap = 0; /* terminate string */
1192 1.49 isaki n = atoi(ip->argbuf);
1193 1.1 oki *ip->ap = ch;
1194 1.50 isaki
1195 1.1 oki return n; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
1196 1.1 oki }
1197 1.1 oki
1198 1.69 tsutsui static void
1199 1.49 isaki ite_putstr(const u_char *s, int len, dev_t dev)
1200 1.1 oki {
1201 1.1 oki struct ite_softc *ip;
1202 1.1 oki int i;
1203 1.1 oki
1204 1.1 oki ip = getitesp(dev);
1205 1.1 oki
1206 1.1 oki /* XXX avoid problems */
1207 1.1 oki if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
1208 1.1 oki return;
1209 1.1 oki
1210 1.1 oki SUBR_CURSOR(ip, START_CURSOROPT);
1211 1.1 oki for (i = 0; i < len; i++)
1212 1.69 tsutsui if (s[i] != 0)
1213 1.1 oki iteputchar(s[i], ip);
1214 1.1 oki SUBR_CURSOR(ip, END_CURSOROPT);
1215 1.1 oki }
1216 1.1 oki
1217 1.69 tsutsui static void
1218 1.38 chs iteputchar(int c, struct ite_softc *ip)
1219 1.1 oki {
1220 1.1 oki int n, x, y;
1221 1.1 oki char *cp;
1222 1.1 oki
1223 1.69 tsutsui if (c >= 0x20 && ip->escape != 0) {
1224 1.1 oki switch (ip->escape) {
1225 1.1 oki
1226 1.1 oki case ESC:
1227 1.1 oki switch (c) {
1228 1.69 tsutsui /*
1229 1.69 tsutsui * first 7bit equivalents for the 8bit control
1230 1.69 tsutsui * characters
1231 1.69 tsutsui */
1232 1.50 isaki
1233 1.1 oki case 'D':
1234 1.1 oki c = IND;
1235 1.1 oki ip->escape = 0;
1236 1.69 tsutsui break;
1237 1.69 tsutsui /*
1238 1.69 tsutsui * and fall into the next switch below
1239 1.69 tsutsui * (same for all `break')
1240 1.69 tsutsui */
1241 1.1 oki
1242 1.1 oki case 'E':
1243 1.1 oki /* next line */
1244 1.1 oki c = NEL;
1245 1.1 oki ip->escape = 0;
1246 1.1 oki break;
1247 1.1 oki
1248 1.1 oki case 'H':
1249 1.1 oki /* set TAB at current col */
1250 1.1 oki c = HTS;
1251 1.1 oki ip->escape = 0;
1252 1.1 oki break;
1253 1.1 oki
1254 1.1 oki case 'M':
1255 1.1 oki /* reverse index */
1256 1.1 oki c = RI;
1257 1.1 oki ip->escape = 0;
1258 1.1 oki break;
1259 1.1 oki
1260 1.1 oki case 'N':
1261 1.1 oki /* single shift G2 */
1262 1.1 oki c = SS2;
1263 1.1 oki ip->escape = 0;
1264 1.1 oki break;
1265 1.1 oki
1266 1.1 oki case 'O':
1267 1.1 oki /* single shift G3 */
1268 1.1 oki c = SS3;
1269 1.1 oki ip->escape = 0;
1270 1.1 oki break;
1271 1.1 oki
1272 1.1 oki case 'P':
1273 1.1 oki /* DCS detected */
1274 1.1 oki c = DCS;
1275 1.1 oki ip->escape = 0;
1276 1.1 oki break;
1277 1.1 oki
1278 1.1 oki case '[':
1279 1.1 oki c = CSI;
1280 1.1 oki ip->escape = 0;
1281 1.1 oki break;
1282 1.1 oki
1283 1.1 oki case '\\':
1284 1.1 oki /* String Terminator */
1285 1.1 oki c = ST;
1286 1.1 oki ip->escape = 0;
1287 1.1 oki break;
1288 1.1 oki
1289 1.1 oki case ']':
1290 1.1 oki c = OSC;
1291 1.1 oki ip->escape = 0;
1292 1.1 oki break;
1293 1.1 oki
1294 1.1 oki case '^':
1295 1.1 oki c = PM;
1296 1.1 oki ip->escape = 0;
1297 1.1 oki break;
1298 1.1 oki
1299 1.1 oki case '_':
1300 1.1 oki c = APC;
1301 1.1 oki ip->escape = 0;
1302 1.1 oki break;
1303 1.1 oki
1304 1.1 oki /* introduces 7/8bit control */
1305 1.1 oki case ' ':
1306 1.1 oki /* can be followed by either F or G */
1307 1.1 oki ip->escape = ' ';
1308 1.1 oki break;
1309 1.1 oki
1310 1.69 tsutsui /* a lot of character set selections, not yet used... */
1311 1.69 tsutsui /* 94-character sets: */
1312 1.1 oki case '(': /* G0 */
1313 1.1 oki case ')': /* G1 */
1314 1.1 oki ip->escape = c;
1315 1.1 oki return;
1316 1.1 oki
1317 1.1 oki case '*': /* G2 */
1318 1.1 oki case '+': /* G3 */
1319 1.1 oki case 'B': /* ASCII */
1320 1.1 oki case 'A': /* ISO latin 1 */
1321 1.1 oki case '<': /* user preferred suplemental */
1322 1.70 tsutsui case '0': /* DEC special graphics */
1323 1.1 oki
1324 1.1 oki /* 96-character sets: */
1325 1.1 oki case '-': /* G1 */
1326 1.1 oki case '.': /* G2 */
1327 1.1 oki case '/': /* G3 */
1328 1.1 oki
1329 1.1 oki /* national character sets: */
1330 1.1 oki case '4': /* dutch */
1331 1.1 oki case '5':
1332 1.1 oki case 'C': /* finnish */
1333 1.1 oki case 'R': /* french */
1334 1.1 oki case 'Q': /* french canadian */
1335 1.1 oki case 'K': /* german */
1336 1.1 oki case 'Y': /* italian */
1337 1.1 oki case '6': /* norwegian/danish */
1338 1.1 oki /* note: %5 and %6 are not supported (two chars..) */
1339 1.1 oki
1340 1.1 oki ip->escape = 0;
1341 1.1 oki /* just ignore for now */
1342 1.1 oki return;
1343 1.1 oki
1344 1.1 oki /* 94-multibyte character sets designate */
1345 1.1 oki case '$':
1346 1.1 oki ip->escape = '$';
1347 1.1 oki return;
1348 1.1 oki
1349 1.1 oki /* locking shift modes */
1350 1.1 oki case '`':
1351 1.1 oki ip->GR = &ip->G1;
1352 1.1 oki ip->escape = 0;
1353 1.1 oki return;
1354 1.1 oki
1355 1.1 oki case 'n':
1356 1.1 oki ip->GL = &ip->G2;
1357 1.1 oki ip->escape = 0;
1358 1.1 oki return;
1359 1.1 oki
1360 1.1 oki case '}':
1361 1.1 oki ip->GR = &ip->G2;
1362 1.1 oki ip->escape = 0;
1363 1.1 oki return;
1364 1.1 oki
1365 1.1 oki case 'o':
1366 1.1 oki ip->GL = &ip->G3;
1367 1.1 oki ip->escape = 0;
1368 1.1 oki return;
1369 1.1 oki
1370 1.1 oki case '|':
1371 1.1 oki ip->GR = &ip->G3;
1372 1.1 oki ip->escape = 0;
1373 1.1 oki return;
1374 1.1 oki
1375 1.1 oki case '~':
1376 1.1 oki ip->GR = &ip->G1;
1377 1.1 oki ip->escape = 0;
1378 1.1 oki return;
1379 1.1 oki
1380 1.1 oki /* font width/height control */
1381 1.1 oki case '#':
1382 1.1 oki ip->escape = '#';
1383 1.1 oki return;
1384 1.1 oki
1385 1.1 oki case 'c':
1386 1.1 oki /* hard terminal reset .. */
1387 1.49 isaki ite_reset(ip);
1388 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1389 1.1 oki ip->escape = 0;
1390 1.1 oki return;
1391 1.1 oki
1392 1.1 oki case '7':
1393 1.1 oki /* save cursor */
1394 1.1 oki ip->save_curx = ip->curx;
1395 1.1 oki ip->save_cury = ip->cury;
1396 1.1 oki ip->save_attribute = ip->attribute;
1397 1.1 oki ip->sc_om = ip->inside_margins;
1398 1.1 oki ip->sc_G0 = ip->G0;
1399 1.1 oki ip->sc_G1 = ip->G1;
1400 1.1 oki ip->sc_G2 = ip->G2;
1401 1.1 oki ip->sc_G3 = ip->G3;
1402 1.1 oki ip->sc_GL = ip->GL;
1403 1.1 oki ip->sc_GR = ip->GR;
1404 1.1 oki ip->escape = 0;
1405 1.1 oki return;
1406 1.1 oki
1407 1.1 oki case '8':
1408 1.1 oki /* restore cursor */
1409 1.1 oki ip->curx = ip->save_curx;
1410 1.1 oki ip->cury = ip->save_cury;
1411 1.1 oki ip->attribute = ip->save_attribute;
1412 1.1 oki ip->inside_margins = ip->sc_om;
1413 1.1 oki ip->G0 = ip->sc_G0;
1414 1.1 oki ip->G1 = ip->sc_G1;
1415 1.1 oki ip->G2 = ip->sc_G2;
1416 1.1 oki ip->G3 = ip->sc_G3;
1417 1.1 oki ip->GL = ip->sc_GL;
1418 1.1 oki ip->GR = ip->sc_GR;
1419 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1420 1.1 oki ip->escape = 0;
1421 1.1 oki return;
1422 1.1 oki
1423 1.1 oki case '=':
1424 1.1 oki /* keypad application mode */
1425 1.1 oki ip->keypad_appmode = 1;
1426 1.1 oki ip->escape = 0;
1427 1.1 oki return;
1428 1.1 oki
1429 1.1 oki case '>':
1430 1.1 oki /* keypad numeric mode */
1431 1.1 oki ip->keypad_appmode = 0;
1432 1.1 oki ip->escape = 0;
1433 1.1 oki return;
1434 1.1 oki
1435 1.1 oki case 'Z': /* request ID */
1436 1.69 tsutsui if (ip->emul_level == EMUL_VT100) {
1437 1.69 tsutsui /* XXX not clean */
1438 1.69 tsutsui ite_sendstr(ip, "\033[61;0c");
1439 1.69 tsutsui } else {
1440 1.69 tsutsui /* XXX not clean */
1441 1.69 tsutsui ite_sendstr(ip, "\033[63;0c");
1442 1.69 tsutsui }
1443 1.1 oki ip->escape = 0;
1444 1.1 oki return;
1445 1.1 oki
1446 1.1 oki /* default catch all for not recognized ESC sequences */
1447 1.1 oki default:
1448 1.1 oki ip->escape = 0;
1449 1.1 oki return;
1450 1.1 oki }
1451 1.1 oki break;
1452 1.1 oki
1453 1.1 oki case '(': /* designate G0 */
1454 1.1 oki switch (c) {
1455 1.1 oki case 'B': /* USASCII */
1456 1.1 oki ip->G0 = CSET_ASCII;
1457 1.1 oki ip->escape = 0;
1458 1.1 oki return;
1459 1.1 oki case 'I':
1460 1.1 oki ip->G0 = CSET_JISKANA;
1461 1.1 oki ip->escape = 0;
1462 1.1 oki return;
1463 1.1 oki case 'J':
1464 1.1 oki ip->G0 = CSET_JISROMA;
1465 1.1 oki ip->escape = 0;
1466 1.1 oki return;
1467 1.70 tsutsui case '0': /* DEC special graphics */
1468 1.69 tsutsui ip->G0 = CSET_DECGRAPH;
1469 1.69 tsutsui ip->escape = 0;
1470 1.69 tsutsui return;
1471 1.1 oki case 'A': /* British or ISO-Latin-1 */
1472 1.1 oki case 'H': /* Swedish */
1473 1.1 oki case 'K': /* German */
1474 1.1 oki case 'R': /* French */
1475 1.1 oki case 'Y': /* Italian */
1476 1.1 oki case 'Z': /* Spanish */
1477 1.1 oki default:
1478 1.1 oki /* not supported */
1479 1.1 oki ip->escape = 0;
1480 1.1 oki return;
1481 1.1 oki }
1482 1.1 oki
1483 1.1 oki case ')': /* designate G1 */
1484 1.70 tsutsui ip->escape = 0;
1485 1.1 oki return;
1486 1.1 oki
1487 1.1 oki case '$': /* 94-multibyte character set */
1488 1.1 oki switch (c) {
1489 1.1 oki case '@':
1490 1.1 oki ip->G0 = CSET_JIS1978;
1491 1.1 oki ip->escape = 0;
1492 1.1 oki return;
1493 1.1 oki case 'B':
1494 1.1 oki ip->G0 = CSET_JIS1983;
1495 1.1 oki ip->escape = 0;
1496 1.1 oki return;
1497 1.1 oki case 'D':
1498 1.1 oki ip->G0 = CSET_JIS1990;
1499 1.1 oki ip->escape = 0;
1500 1.1 oki return;
1501 1.1 oki default:
1502 1.1 oki /* not supported */
1503 1.1 oki ip->escape = 0;
1504 1.1 oki return;
1505 1.1 oki }
1506 1.1 oki
1507 1.1 oki case ' ':
1508 1.1 oki switch (c) {
1509 1.1 oki case 'F':
1510 1.1 oki ip->eightbit_C1 = 0;
1511 1.1 oki ip->escape = 0;
1512 1.1 oki return;
1513 1.1 oki
1514 1.1 oki case 'G':
1515 1.1 oki ip->eightbit_C1 = 1;
1516 1.1 oki ip->escape = 0;
1517 1.1 oki return;
1518 1.1 oki
1519 1.1 oki default:
1520 1.1 oki /* not supported */
1521 1.1 oki ip->escape = 0;
1522 1.1 oki return;
1523 1.1 oki }
1524 1.1 oki break;
1525 1.1 oki
1526 1.1 oki case '#':
1527 1.1 oki switch (c) {
1528 1.1 oki case '5':
1529 1.1 oki /* single height, single width */
1530 1.1 oki ip->escape = 0;
1531 1.1 oki return;
1532 1.1 oki
1533 1.1 oki case '6':
1534 1.1 oki /* double width, single height */
1535 1.1 oki ip->escape = 0;
1536 1.1 oki return;
1537 1.1 oki
1538 1.1 oki case '3':
1539 1.1 oki /* top half */
1540 1.1 oki ip->escape = 0;
1541 1.1 oki return;
1542 1.1 oki
1543 1.1 oki case '4':
1544 1.1 oki /* bottom half */
1545 1.1 oki ip->escape = 0;
1546 1.1 oki return;
1547 1.1 oki
1548 1.1 oki case '8':
1549 1.1 oki /* screen alignment pattern... */
1550 1.49 isaki alignment_display(ip);
1551 1.1 oki ip->escape = 0;
1552 1.1 oki return;
1553 1.1 oki
1554 1.1 oki default:
1555 1.1 oki ip->escape = 0;
1556 1.1 oki return;
1557 1.1 oki }
1558 1.1 oki break;
1559 1.1 oki
1560 1.1 oki case CSI:
1561 1.1 oki /* the biggie... */
1562 1.1 oki switch (c) {
1563 1.69 tsutsui case '0':
1564 1.69 tsutsui case '1':
1565 1.69 tsutsui case '2':
1566 1.69 tsutsui case '3':
1567 1.69 tsutsui case '4':
1568 1.69 tsutsui case '5':
1569 1.69 tsutsui case '6':
1570 1.69 tsutsui case '7':
1571 1.69 tsutsui case '8':
1572 1.69 tsutsui case '9':
1573 1.69 tsutsui case ';':
1574 1.69 tsutsui case '\"':
1575 1.69 tsutsui case '$':
1576 1.69 tsutsui case '>':
1577 1.1 oki if (ip->ap < ip->argbuf + MAX_ARGSIZE)
1578 1.1 oki *ip->ap++ = c;
1579 1.1 oki return;
1580 1.1 oki
1581 1.1 oki case 'p':
1582 1.1 oki *ip->ap = 0;
1583 1.1 oki if (!strncmp(ip->argbuf, "61\"", 3))
1584 1.1 oki ip->emul_level = EMUL_VT100;
1585 1.69 tsutsui else if (!strncmp(ip->argbuf, "63;1\"", 5) ||
1586 1.69 tsutsui !strncmp(ip->argbuf, "62;1\"", 5))
1587 1.1 oki ip->emul_level = EMUL_VT300_7;
1588 1.1 oki else
1589 1.1 oki ip->emul_level = EMUL_VT300_8;
1590 1.1 oki ip->escape = 0;
1591 1.1 oki return;
1592 1.1 oki
1593 1.1 oki case '?':
1594 1.1 oki *ip->ap = 0;
1595 1.1 oki ip->escape = '?';
1596 1.1 oki ip->ap = ip->argbuf;
1597 1.1 oki return;
1598 1.1 oki
1599 1.1 oki case 'c':
1600 1.1 oki /* device attributes */
1601 1.1 oki *ip->ap = 0;
1602 1.1 oki if (ip->argbuf[0] == '>') {
1603 1.49 isaki ite_sendstr(ip, "\033[>24;0;0;0c");
1604 1.69 tsutsui } else {
1605 1.1 oki switch (ite_zargnum(ip)) {
1606 1.1 oki case 0:
1607 1.69 tsutsui /*
1608 1.69 tsutsui * primary DA request, send
1609 1.69 tsutsui * primary DA response
1610 1.69 tsutsui */
1611 1.69 tsutsui if (ip->emul_level ==
1612 1.69 tsutsui EMUL_VT100)
1613 1.69 tsutsui ite_sendstr(ip,
1614 1.69 tsutsui "\033[?1;1c");
1615 1.1 oki else
1616 1.69 tsutsui ite_sendstr(ip,
1617 1.69 tsutsui "\033[63;0c");
1618 1.1 oki break;
1619 1.1 oki }
1620 1.69 tsutsui }
1621 1.1 oki ip->escape = 0;
1622 1.1 oki return;
1623 1.1 oki
1624 1.1 oki case 'n':
1625 1.1 oki switch (ite_zargnum(ip)) {
1626 1.1 oki case 5:
1627 1.69 tsutsui /* no malfunction */
1628 1.69 tsutsui ite_sendstr(ip, "\033[0n");
1629 1.1 oki break;
1630 1.1 oki case 6:
1631 1.1 oki /* cursor position report */
1632 1.62 christos snprintf(ip->argbuf, sizeof(ip->argbuf),
1633 1.62 christos "\033[%d;%dR",
1634 1.62 christos ip->cury + 1, ip->curx + 1);
1635 1.49 isaki ite_sendstr(ip, ip->argbuf);
1636 1.1 oki break;
1637 1.1 oki }
1638 1.1 oki ip->escape = 0;
1639 1.1 oki return;
1640 1.1 oki
1641 1.1 oki case 'x':
1642 1.1 oki switch (ite_zargnum(ip)) {
1643 1.1 oki case 0:
1644 1.1 oki /* Fake some terminal parameters. */
1645 1.69 tsutsui ite_sendstr(ip,
1646 1.69 tsutsui "\033[2;1;1;112;112;1;0x");
1647 1.1 oki break;
1648 1.1 oki case 1:
1649 1.69 tsutsui ite_sendstr(ip,
1650 1.69 tsutsui "\033[3;1;1;112;112;1;0x");
1651 1.1 oki break;
1652 1.1 oki }
1653 1.1 oki ip->escape = 0;
1654 1.1 oki return;
1655 1.1 oki
1656 1.1 oki case 'g':
1657 1.1 oki /* clear tabs */
1658 1.1 oki switch (ite_zargnum(ip)) {
1659 1.1 oki case 0:
1660 1.1 oki if (ip->curx < ip->cols)
1661 1.1 oki ip->tabs[ip->curx] = 0;
1662 1.1 oki break;
1663 1.1 oki case 3:
1664 1.1 oki for (n = 0; n < ip->cols; n++)
1665 1.1 oki ip->tabs[n] = 0;
1666 1.1 oki break;
1667 1.1 oki
1668 1.1 oki default:
1669 1.1 oki /* ignore */
1670 1.1 oki break;
1671 1.1 oki }
1672 1.1 oki ip->escape = 0;
1673 1.1 oki return;
1674 1.1 oki
1675 1.1 oki case 'h': /* set mode */
1676 1.1 oki case 'l': /* reset mode */
1677 1.49 isaki n = ite_zargnum(ip);
1678 1.1 oki switch (n) {
1679 1.1 oki case 4:
1680 1.69 tsutsui /* insert/replace mode */
1681 1.69 tsutsui ip->imode = (c == 'h');
1682 1.1 oki break;
1683 1.1 oki case 20:
1684 1.1 oki ip->linefeed_newline = (c == 'h');
1685 1.1 oki break;
1686 1.1 oki }
1687 1.1 oki ip->escape = 0;
1688 1.1 oki return;
1689 1.1 oki
1690 1.1 oki case 'M':
1691 1.1 oki /* delete line */
1692 1.49 isaki ite_dnline(ip, ite_argnum(ip));
1693 1.1 oki ip->escape = 0;
1694 1.1 oki return;
1695 1.1 oki
1696 1.1 oki case 'L':
1697 1.1 oki /* insert line */
1698 1.49 isaki ite_inline(ip, ite_argnum(ip));
1699 1.1 oki ip->escape = 0;
1700 1.1 oki return;
1701 1.1 oki
1702 1.1 oki case 'P':
1703 1.1 oki /* delete char */
1704 1.49 isaki ite_dnchar(ip, ite_argnum(ip));
1705 1.1 oki ip->escape = 0;
1706 1.1 oki return;
1707 1.1 oki
1708 1.1 oki case '@':
1709 1.1 oki /* insert char(s) */
1710 1.49 isaki ite_inchar(ip, ite_argnum(ip));
1711 1.1 oki ip->escape = 0;
1712 1.1 oki return;
1713 1.1 oki
1714 1.1 oki case '!':
1715 1.1 oki /* soft terminal reset */
1716 1.1 oki ip->escape = 0; /* XXX */
1717 1.1 oki return;
1718 1.1 oki
1719 1.1 oki case 'G':
1720 1.69 tsutsui /*
1721 1.69 tsutsui * this one was *not* in my vt320 manual but
1722 1.69 tsutsui * in a vt320 termcap entry.. who is right?
1723 1.69 tsutsui * It's supposed to set the horizontal cursor
1724 1.69 tsutsui * position.
1725 1.69 tsutsui */
1726 1.1 oki *ip->ap = 0;
1727 1.49 isaki x = atoi(ip->argbuf);
1728 1.69 tsutsui if (x != 0)
1729 1.49 isaki x--;
1730 1.64 riastrad ip->curx = uimin(x, ip->cols - 1);
1731 1.1 oki ip->escape = 0;
1732 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1733 1.49 isaki clr_attr(ip, ATTR_INV);
1734 1.1 oki return;
1735 1.1 oki
1736 1.1 oki case 'd':
1737 1.69 tsutsui /*
1738 1.69 tsutsui * same thing here, this one's for setting
1739 1.69 tsutsui * the absolute vertical cursor position.
1740 1.69 tsutsui * Not documented...
1741 1.69 tsutsui */
1742 1.1 oki *ip->ap = 0;
1743 1.49 isaki y = atoi(ip->argbuf);
1744 1.49 isaki if (y)
1745 1.49 isaki y--;
1746 1.1 oki if (ip->inside_margins)
1747 1.1 oki y += ip->top_margin;
1748 1.64 riastrad ip->cury = uimin(y, ip->rows - 1);
1749 1.1 oki ip->escape = 0;
1750 1.1 oki snap_cury(ip);
1751 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1752 1.49 isaki clr_attr(ip, ATTR_INV);
1753 1.1 oki return;
1754 1.1 oki
1755 1.1 oki case 'H':
1756 1.1 oki case 'f':
1757 1.1 oki *ip->ap = 0;
1758 1.49 isaki y = atoi(ip->argbuf);
1759 1.1 oki x = 0;
1760 1.36 jdolecek cp = strchr(ip->argbuf, ';');
1761 1.69 tsutsui if (cp != NULL)
1762 1.49 isaki x = atoi(cp + 1);
1763 1.69 tsutsui if (x != 0)
1764 1.49 isaki x--;
1765 1.69 tsutsui if (y != 0)
1766 1.49 isaki y--;
1767 1.69 tsutsui if (ip->inside_margins != 0)
1768 1.1 oki y += ip->top_margin;
1769 1.64 riastrad ip->cury = uimin(y, ip->rows - 1);
1770 1.64 riastrad ip->curx = uimin(x, ip->cols - 1);
1771 1.1 oki ip->escape = 0;
1772 1.1 oki snap_cury(ip);
1773 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1774 1.49 isaki /*clr_attr(ip, ATTR_INV);*/
1775 1.1 oki return;
1776 1.1 oki
1777 1.1 oki case 'A':
1778 1.1 oki /* cursor up */
1779 1.49 isaki n = ite_argnum(ip);
1780 1.1 oki n = ip->cury - (n ? n : 1);
1781 1.49 isaki if (n < 0)
1782 1.49 isaki n = 0;
1783 1.1 oki if (ip->inside_margins)
1784 1.64 riastrad n = uimax(ip->top_margin, n);
1785 1.1 oki else if (n == ip->top_margin - 1)
1786 1.69 tsutsui /*
1787 1.69 tsutsui * allow scrolling outside region,
1788 1.69 tsutsui * but don't scroll out of active
1789 1.69 tsutsui * region without explicit CUP
1790 1.69 tsutsui */
1791 1.1 oki n = ip->top_margin;
1792 1.1 oki ip->cury = n;
1793 1.1 oki ip->escape = 0;
1794 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1795 1.49 isaki clr_attr(ip, ATTR_INV);
1796 1.1 oki return;
1797 1.1 oki
1798 1.1 oki case 'B':
1799 1.1 oki /* cursor down */
1800 1.49 isaki n = ite_argnum(ip);
1801 1.1 oki n = ip->cury + (n ? n : 1);
1802 1.64 riastrad n = uimin(ip->rows - 1, n);
1803 1.1 oki #if 0
1804 1.1 oki if (ip->inside_margins)
1805 1.1 oki #endif
1806 1.64 riastrad n = uimin(ip->bottom_margin, n);
1807 1.1 oki #if 0
1808 1.1 oki else if (n == ip->bottom_margin + 1)
1809 1.69 tsutsui /*
1810 1.69 tsutsui * allow scrolling outside region,
1811 1.69 tsutsui * but don't scroll out of active
1812 1.69 tsutsui * region without explicit CUP
1813 1.69 tsutsui */
1814 1.1 oki n = ip->bottom_margin;
1815 1.1 oki #endif
1816 1.1 oki ip->cury = n;
1817 1.1 oki ip->escape = 0;
1818 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1819 1.49 isaki clr_attr(ip, ATTR_INV);
1820 1.1 oki return;
1821 1.1 oki
1822 1.1 oki case 'C':
1823 1.1 oki /* cursor forward */
1824 1.49 isaki n = ite_argnum(ip);
1825 1.1 oki n = n ? n : 1;
1826 1.64 riastrad ip->curx = uimin(ip->curx + n, ip->cols - 1);
1827 1.1 oki ip->escape = 0;
1828 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1829 1.49 isaki clr_attr(ip, ATTR_INV);
1830 1.1 oki return;
1831 1.1 oki
1832 1.1 oki case 'D':
1833 1.1 oki /* cursor backward */
1834 1.49 isaki n = ite_argnum(ip);
1835 1.1 oki n = n ? n : 1;
1836 1.1 oki n = ip->curx - n;
1837 1.1 oki ip->curx = n >= 0 ? n : 0;
1838 1.1 oki ip->escape = 0;
1839 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
1840 1.49 isaki clr_attr(ip, ATTR_INV);
1841 1.1 oki return;
1842 1.1 oki
1843 1.1 oki case 'J':
1844 1.1 oki /* erase screen */
1845 1.1 oki *ip->ap = 0;
1846 1.49 isaki n = ite_zargnum(ip);
1847 1.1 oki if (n == 0)
1848 1.1 oki ite_clrtoeos(ip);
1849 1.1 oki else if (n == 1)
1850 1.1 oki ite_clrtobos(ip);
1851 1.1 oki else if (n == 2)
1852 1.1 oki ite_clrscreen(ip);
1853 1.1 oki ip->escape = 0;
1854 1.1 oki return;
1855 1.1 oki
1856 1.1 oki case 'K':
1857 1.1 oki /* erase line */
1858 1.49 isaki n = ite_zargnum(ip);
1859 1.1 oki if (n == 0)
1860 1.1 oki ite_clrtoeol(ip);
1861 1.1 oki else if (n == 1)
1862 1.1 oki ite_clrtobol(ip);
1863 1.1 oki else if (n == 2)
1864 1.1 oki ite_clrline(ip);
1865 1.1 oki ip->escape = 0;
1866 1.1 oki return;
1867 1.1 oki
1868 1.1 oki case 'S':
1869 1.1 oki /* scroll up */
1870 1.49 isaki n = ite_zargnum(ip);
1871 1.1 oki if (n <= 0)
1872 1.1 oki n = 1;
1873 1.1 oki else if (n > ip->rows-1)
1874 1.1 oki n = ip->rows-1;
1875 1.1 oki SUBR_SCROLL(ip, ip->rows-1, 0, n, SCROLL_UP);
1876 1.1 oki ip->escape = 0;
1877 1.1 oki return;
1878 1.1 oki
1879 1.1 oki case 'T':
1880 1.1 oki /* scroll down */
1881 1.49 isaki n = ite_zargnum(ip);
1882 1.1 oki if (n <= 0)
1883 1.1 oki n = 1;
1884 1.1 oki else if (n > ip->rows-1)
1885 1.1 oki n = ip->rows-1;
1886 1.1 oki SUBR_SCROLL(ip, 0, 0, n, SCROLL_DOWN);
1887 1.1 oki ip->escape = 0;
1888 1.1 oki return;
1889 1.1 oki
1890 1.1 oki case 'X':
1891 1.1 oki /* erase character */
1892 1.1 oki n = ite_argnum(ip) - 1;
1893 1.64 riastrad n = uimin(n, ip->cols - 1 - ip->curx);
1894 1.1 oki for (; n >= 0; n--) {
1895 1.69 tsutsui attrclr(ip, ip->cury, ip->curx + n,
1896 1.69 tsutsui 1, 1);
1897 1.69 tsutsui SUBR_PUTC(ip, ' ',
1898 1.69 tsutsui ip->cury, ip->curx + n, ATTR_NOR);
1899 1.1 oki }
1900 1.1 oki ip->escape = 0;
1901 1.1 oki return;
1902 1.1 oki
1903 1.1 oki case '}': case '`':
1904 1.1 oki /* status line control */
1905 1.1 oki ip->escape = 0;
1906 1.1 oki return;
1907 1.1 oki
1908 1.1 oki case 'r':
1909 1.1 oki /* set scrolling region */
1910 1.1 oki ip->escape = 0;
1911 1.1 oki *ip->ap = 0;
1912 1.49 isaki x = atoi(ip->argbuf);
1913 1.1 oki x = x ? x : 1;
1914 1.1 oki y = ip->rows;
1915 1.36 jdolecek cp = strchr(ip->argbuf, ';');
1916 1.1 oki if (cp) {
1917 1.49 isaki y = atoi(cp + 1);
1918 1.1 oki y = y ? y : ip->rows;
1919 1.1 oki }
1920 1.1 oki if (y <= x)
1921 1.1 oki return;
1922 1.1 oki x--;
1923 1.1 oki y--;
1924 1.64 riastrad ip->top_margin = uimin(x, ip->rows - 2);
1925 1.64 riastrad ip->bottom_margin = uimin(y, ip->rows - 1);
1926 1.1 oki if (ip->inside_margins) {
1927 1.1 oki ip->cury = ip->top_margin;
1928 1.1 oki } else
1929 1.1 oki ip->cury = 0;
1930 1.1 oki ip->curx = 0;
1931 1.1 oki return;
1932 1.1 oki
1933 1.1 oki case 'm':
1934 1.1 oki /* big attribute setter/resetter */
1935 1.1 oki {
1936 1.40 he char *c_p;
1937 1.69 tsutsui
1938 1.1 oki *ip->ap = 0;
1939 1.1 oki /* kludge to make CSIm work (== CSI0m) */
1940 1.1 oki if (ip->ap == ip->argbuf)
1941 1.1 oki ip->ap++;
1942 1.40 he for (c_p = ip->argbuf; c_p < ip->ap; ) {
1943 1.40 he switch (*c_p) {
1944 1.1 oki case 0:
1945 1.1 oki case '0':
1946 1.49 isaki clr_attr(ip, ATTR_ALL);
1947 1.1 oki ip->fgcolor = 7;
1948 1.1 oki ip->bgcolor = 0;
1949 1.40 he c_p++;
1950 1.1 oki break;
1951 1.1 oki
1952 1.1 oki case '1':
1953 1.49 isaki set_attr(ip, ATTR_BOLD);
1954 1.40 he c_p++;
1955 1.1 oki break;
1956 1.1 oki
1957 1.1 oki case '2':
1958 1.40 he switch (c_p[1]) {
1959 1.1 oki case '2':
1960 1.49 isaki clr_attr(ip, ATTR_BOLD);
1961 1.40 he c_p += 2;
1962 1.1 oki break;
1963 1.1 oki
1964 1.1 oki case '4':
1965 1.49 isaki clr_attr(ip, ATTR_UL);
1966 1.40 he c_p += 2;
1967 1.1 oki break;
1968 1.1 oki
1969 1.1 oki case '5':
1970 1.69 tsutsui clr_attr(ip,
1971 1.69 tsutsui ATTR_BLINK);
1972 1.40 he c_p += 2;
1973 1.1 oki break;
1974 1.1 oki
1975 1.1 oki case '7':
1976 1.49 isaki clr_attr(ip, ATTR_INV);
1977 1.40 he c_p += 2;
1978 1.1 oki break;
1979 1.1 oki
1980 1.1 oki default:
1981 1.40 he c_p++;
1982 1.1 oki break;
1983 1.1 oki }
1984 1.1 oki break;
1985 1.1 oki
1986 1.1 oki case '3':
1987 1.40 he switch (c_p[1]) {
1988 1.69 tsutsui case '0':
1989 1.69 tsutsui case '1':
1990 1.69 tsutsui case '2':
1991 1.69 tsutsui case '3':
1992 1.69 tsutsui case '4':
1993 1.69 tsutsui case '5':
1994 1.69 tsutsui case '6':
1995 1.69 tsutsui case '7':
1996 1.1 oki /* foreground colors */
1997 1.69 tsutsui ip->fgcolor =
1998 1.69 tsutsui c_p[1] - '0';
1999 1.40 he c_p += 2;
2000 1.1 oki break;
2001 1.1 oki default:
2002 1.40 he c_p++;
2003 1.1 oki break;
2004 1.1 oki }
2005 1.1 oki break;
2006 1.1 oki
2007 1.1 oki case '4':
2008 1.40 he switch (c_p[1]) {
2009 1.69 tsutsui case '0':
2010 1.69 tsutsui case '1':
2011 1.69 tsutsui case '2':
2012 1.69 tsutsui case '3':
2013 1.69 tsutsui case '4':
2014 1.69 tsutsui case '5':
2015 1.69 tsutsui case '6':
2016 1.69 tsutsui case '7':
2017 1.1 oki /* background colors */
2018 1.69 tsutsui ip->bgcolor =
2019 1.69 tsutsui c_p[1] - '0';
2020 1.40 he c_p += 2;
2021 1.1 oki break;
2022 1.1 oki default:
2023 1.49 isaki set_attr(ip, ATTR_UL);
2024 1.40 he c_p++;
2025 1.1 oki break;
2026 1.1 oki }
2027 1.1 oki break;
2028 1.1 oki
2029 1.1 oki case '5':
2030 1.49 isaki set_attr(ip, ATTR_BLINK);
2031 1.40 he c_p++;
2032 1.1 oki break;
2033 1.1 oki
2034 1.1 oki case '7':
2035 1.49 isaki set_attr(ip, ATTR_INV);
2036 1.40 he c_p++;
2037 1.1 oki break;
2038 1.1 oki
2039 1.1 oki default:
2040 1.40 he c_p++;
2041 1.1 oki break;
2042 1.1 oki }
2043 1.1 oki }
2044 1.1 oki
2045 1.1 oki }
2046 1.1 oki ip->escape = 0;
2047 1.1 oki return;
2048 1.1 oki
2049 1.1 oki case 'u':
2050 1.1 oki /* DECRQTSR */
2051 1.49 isaki ite_sendstr(ip, "\033P\033\\");
2052 1.1 oki ip->escape = 0;
2053 1.1 oki return;
2054 1.1 oki
2055 1.1 oki default:
2056 1.1 oki ip->escape = 0;
2057 1.1 oki return;
2058 1.1 oki }
2059 1.1 oki break;
2060 1.1 oki
2061 1.1 oki case '?': /* CSI ? */
2062 1.1 oki switch (c) {
2063 1.69 tsutsui case '0':
2064 1.69 tsutsui case '1':
2065 1.69 tsutsui case '2':
2066 1.69 tsutsui case '3':
2067 1.69 tsutsui case '4':
2068 1.69 tsutsui case '5':
2069 1.69 tsutsui case '6':
2070 1.69 tsutsui case '7':
2071 1.69 tsutsui case '8':
2072 1.69 tsutsui case '9':
2073 1.69 tsutsui case ';':
2074 1.69 tsutsui case '\"':
2075 1.69 tsutsui case '$':
2076 1.69 tsutsui /*
2077 1.69 tsutsui * Don't fill the last character; it's needed.
2078 1.69 tsutsui */
2079 1.1 oki /* XXX yeah, where ?? */
2080 1.1 oki if (ip->ap < ip->argbuf + MAX_ARGSIZE - 1)
2081 1.1 oki *ip->ap++ = c;
2082 1.1 oki return;
2083 1.1 oki
2084 1.1 oki case 'n':
2085 1.1 oki /* Terminal Reports */
2086 1.1 oki *ip->ap = 0;
2087 1.1 oki if (ip->ap == &ip->argbuf[2]) {
2088 1.1 oki if (!strncmp(ip->argbuf, "15", 2))
2089 1.1 oki /* printer status: no printer */
2090 1.49 isaki ite_sendstr(ip, "\033[13n");
2091 1.1 oki else if (!strncmp(ip->argbuf, "25", 2))
2092 1.1 oki /* udk status */
2093 1.49 isaki ite_sendstr(ip, "\033[20n");
2094 1.1 oki else if (!strncmp(ip->argbuf, "26", 2))
2095 1.1 oki /* keyboard dialect: US */
2096 1.49 isaki ite_sendstr(ip, "\033[27;1n");
2097 1.1 oki }
2098 1.1 oki ip->escape = 0;
2099 1.1 oki return;
2100 1.1 oki
2101 1.1 oki case 'h': /* set dec private modes */
2102 1.1 oki case 'l': /* reset dec private modes */
2103 1.49 isaki n = ite_zargnum(ip);
2104 1.1 oki switch (n) {
2105 1.1 oki case 1:
2106 1.1 oki /* CKM - cursor key mode */
2107 1.1 oki ip->cursor_appmode = (c == 'h');
2108 1.1 oki break;
2109 1.1 oki
2110 1.1 oki case 3:
2111 1.1 oki /* 132/80 columns (132 == 'h') */
2112 1.1 oki break;
2113 1.1 oki
2114 1.1 oki case 4: /* smooth scroll */
2115 1.1 oki break;
2116 1.1 oki
2117 1.1 oki case 5:
2118 1.69 tsutsui /*
2119 1.69 tsutsui * light background (=='h') /
2120 1.69 tsutsui * dark background (=='l')
2121 1.69 tsutsui */
2122 1.1 oki break;
2123 1.1 oki
2124 1.1 oki case 6: /* origin mode */
2125 1.1 oki ip->inside_margins = (c == 'h');
2126 1.1 oki #if 0
2127 1.1 oki ip->curx = 0;
2128 1.69 tsutsui ip->cury = ip->inside_margins ?
2129 1.69 tsutsui ip->top_margin : 0;
2130 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
2131 1.1 oki #endif
2132 1.1 oki break;
2133 1.1 oki
2134 1.1 oki case 7: /* auto wraparound */
2135 1.1 oki ip->auto_wrap = (c == 'h');
2136 1.1 oki break;
2137 1.1 oki
2138 1.1 oki case 8: /* keyboard repeat */
2139 1.1 oki ip->key_repeat = (c == 'h');
2140 1.1 oki break;
2141 1.1 oki
2142 1.1 oki case 20: /* newline mode */
2143 1.1 oki ip->linefeed_newline = (c == 'h');
2144 1.1 oki break;
2145 1.1 oki
2146 1.1 oki case 25: /* cursor on/off */
2147 1.69 tsutsui SUBR_CURSOR(ip, (c == 'h') ?
2148 1.69 tsutsui DRAW_CURSOR : ERASE_CURSOR);
2149 1.1 oki break;
2150 1.1 oki }
2151 1.1 oki ip->escape = 0;
2152 1.1 oki return;
2153 1.1 oki
2154 1.1 oki case 'K':
2155 1.1 oki /* selective erase in line */
2156 1.1 oki case 'J':
2157 1.1 oki /* selective erase in display */
2158 1.1 oki
2159 1.1 oki default:
2160 1.1 oki ip->escape = 0;
2161 1.1 oki return;
2162 1.1 oki }
2163 1.1 oki break;
2164 1.1 oki
2165 1.1 oki default:
2166 1.1 oki ip->escape = 0;
2167 1.1 oki return;
2168 1.1 oki }
2169 1.1 oki }
2170 1.1 oki
2171 1.1 oki switch (c) {
2172 1.1 oki case 0x00: /* NUL */
2173 1.1 oki case 0x01: /* SOH */
2174 1.1 oki case 0x02: /* STX */
2175 1.1 oki case 0x03: /* ETX */
2176 1.1 oki case 0x04: /* EOT */
2177 1.1 oki case 0x05: /* ENQ */
2178 1.1 oki case 0x06: /* ACK */
2179 1.1 oki break;
2180 1.1 oki
2181 1.1 oki case BEL:
2182 1.1 oki #if NBELL > 0
2183 1.60 tsutsui if (kbd_ite && ite_tty[device_unit(kbd_ite->device)])
2184 1.1 oki opm_bell();
2185 1.1 oki #endif
2186 1.1 oki break;
2187 1.1 oki
2188 1.1 oki case BS:
2189 1.1 oki if (--ip->curx < 0)
2190 1.1 oki ip->curx = 0;
2191 1.1 oki else
2192 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
2193 1.1 oki break;
2194 1.1 oki
2195 1.1 oki case HT:
2196 1.1 oki for (n = ip->curx + 1; n < ip->cols; n++) {
2197 1.1 oki if (ip->tabs[n]) {
2198 1.1 oki ip->curx = n;
2199 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
2200 1.1 oki break;
2201 1.1 oki }
2202 1.1 oki }
2203 1.1 oki break;
2204 1.1 oki
2205 1.1 oki case VT: /* VT is treated like LF */
2206 1.1 oki case FF: /* so is FF */
2207 1.1 oki case LF:
2208 1.69 tsutsui /*
2209 1.69 tsutsui * cr->crlf distinction is done here, on output,
2210 1.69 tsutsui * not on input!
2211 1.69 tsutsui */
2212 1.1 oki if (ip->linefeed_newline)
2213 1.49 isaki ite_crlf(ip);
2214 1.1 oki else
2215 1.49 isaki ite_lf(ip);
2216 1.1 oki break;
2217 1.1 oki
2218 1.1 oki case CR:
2219 1.49 isaki ite_cr(ip);
2220 1.1 oki break;
2221 1.1 oki
2222 1.1 oki case SO:
2223 1.1 oki ip->GL = &ip->G1;
2224 1.1 oki break;
2225 1.1 oki
2226 1.1 oki case SI:
2227 1.1 oki ip->GL = &ip->G0;
2228 1.1 oki break;
2229 1.1 oki
2230 1.1 oki case 0x10: /* DLE */
2231 1.1 oki case 0x11: /* DC1/XON */
2232 1.1 oki case 0x12: /* DC2 */
2233 1.1 oki case 0x13: /* DC3/XOFF */
2234 1.1 oki case 0x14: /* DC4 */
2235 1.1 oki case 0x15: /* NAK */
2236 1.1 oki case 0x16: /* SYN */
2237 1.1 oki case 0x17: /* ETB */
2238 1.1 oki break;
2239 1.1 oki
2240 1.1 oki case CAN:
2241 1.1 oki ip->escape = 0; /* cancel any escape sequence in progress */
2242 1.1 oki break;
2243 1.1 oki
2244 1.1 oki case 0x19: /* EM */
2245 1.1 oki break;
2246 1.1 oki
2247 1.1 oki case SUB:
2248 1.1 oki ip->escape = 0; /* dito, but see below */
2249 1.1 oki /* should also display a reverse question mark!! */
2250 1.1 oki break;
2251 1.1 oki
2252 1.1 oki case ESC:
2253 1.1 oki ip->escape = ESC;
2254 1.1 oki break;
2255 1.1 oki
2256 1.1 oki case 0x1c: /* FS */
2257 1.1 oki case 0x1d: /* GS */
2258 1.1 oki case 0x1e: /* RS */
2259 1.1 oki case 0x1f: /* US */
2260 1.1 oki break;
2261 1.1 oki
2262 1.1 oki /* now it gets weird.. 8bit control sequences.. */
2263 1.1 oki case IND: /* index: move cursor down, scroll */
2264 1.49 isaki ite_index(ip);
2265 1.1 oki break;
2266 1.1 oki
2267 1.1 oki case NEL: /* next line. next line, first pos. */
2268 1.49 isaki ite_crlf(ip);
2269 1.1 oki break;
2270 1.1 oki
2271 1.1 oki case HTS: /* set horizontal tab */
2272 1.1 oki if (ip->curx < ip->cols)
2273 1.1 oki ip->tabs[ip->curx] = 1;
2274 1.1 oki break;
2275 1.1 oki
2276 1.1 oki case RI: /* reverse index */
2277 1.49 isaki ite_rlf(ip);
2278 1.1 oki break;
2279 1.1 oki
2280 1.1 oki case SS2: /* go into G2 for one character */
2281 1.1 oki ip->save_GL = ip->GR; /* GL XXX EUC */
2282 1.1 oki ip->GR = &ip->G2; /* GL XXX */
2283 1.1 oki break;
2284 1.1 oki
2285 1.1 oki case SS3: /* go into G3 for one character */
2286 1.1 oki ip->save_GL = ip->GR; /* GL XXX EUC */
2287 1.1 oki ip->GR = &ip->G3; /* GL XXX */
2288 1.1 oki break;
2289 1.1 oki
2290 1.1 oki case DCS: /* device control string introducer */
2291 1.1 oki ip->escape = DCS;
2292 1.1 oki ip->ap = ip->argbuf;
2293 1.1 oki break;
2294 1.1 oki
2295 1.1 oki case CSI: /* control sequence introducer */
2296 1.1 oki ip->escape = CSI;
2297 1.1 oki ip->ap = ip->argbuf;
2298 1.1 oki break;
2299 1.1 oki
2300 1.1 oki case ST: /* string terminator */
2301 1.1 oki /* ignore, if not used as terminator */
2302 1.1 oki break;
2303 1.1 oki
2304 1.69 tsutsui case OSC: /* introduces OS command. */
2305 1.69 tsutsui /* Ignore everything upto ST */
2306 1.1 oki ip->escape = OSC;
2307 1.1 oki break;
2308 1.1 oki
2309 1.69 tsutsui case PM: /* privacy message */
2310 1.69 tsutsui /* ignore everything upto ST */
2311 1.1 oki ip->escape = PM;
2312 1.1 oki break;
2313 1.1 oki
2314 1.69 tsutsui case APC: /* application program command */
2315 1.69 tsutsui /* ignore everything upto ST */
2316 1.1 oki ip->escape = APC;
2317 1.1 oki break;
2318 1.1 oki
2319 1.1 oki case DEL:
2320 1.1 oki break;
2321 1.1 oki
2322 1.1 oki default:
2323 1.69 tsutsui if (ip->save_char == 0 &&
2324 1.69 tsutsui (*((c & 0x80) ? ip->GR : ip->GL) & CSET_MULTI) != 0) {
2325 1.1 oki ip->save_char = c;
2326 1.1 oki break;
2327 1.1 oki }
2328 1.69 tsutsui if (ip->imode != 0)
2329 1.1 oki ite_inchar(ip, ip->save_char ? 2 : 1);
2330 1.1 oki iteprecheckwrap(ip);
2331 1.1 oki #ifdef DO_WEIRD_ATTRIBUTES
2332 1.1 oki if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
2333 1.1 oki attrset(ip, ATTR_INV);
2334 1.1 oki SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_INV);
2335 1.1 oki }
2336 1.1 oki else
2337 1.1 oki SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_NOR);
2338 1.1 oki #else
2339 1.1 oki SUBR_PUTC(ip, c, ip->cury, ip->curx, ip->attribute);
2340 1.1 oki #endif
2341 1.69 tsutsui /*SUBR_CURSOR(ip, DRAW_CURSOR);*/
2342 1.1 oki itecheckwrap(ip);
2343 1.1 oki if (ip->save_char) {
2344 1.1 oki itecheckwrap(ip);
2345 1.1 oki ip->save_char = 0;
2346 1.1 oki }
2347 1.1 oki if (ip->save_GL) {
2348 1.1 oki /*
2349 1.1 oki * reset single shift
2350 1.1 oki */
2351 1.1 oki ip->GR = ip->save_GL;
2352 1.1 oki ip->save_GL = 0;
2353 1.1 oki }
2354 1.1 oki break;
2355 1.1 oki }
2356 1.1 oki }
2357 1.1 oki
2358 1.49 isaki static void
2359 1.38 chs iteprecheckwrap(struct ite_softc *ip)
2360 1.1 oki {
2361 1.69 tsutsui
2362 1.1 oki if (ip->auto_wrap && ip->curx + (ip->save_char ? 1 : 0) == ip->cols) {
2363 1.1 oki ip->curx = 0;
2364 1.1 oki clr_attr(ip, ATTR_INV);
2365 1.1 oki if (++ip->cury >= ip->bottom_margin + 1) {
2366 1.1 oki ip->cury = ip->bottom_margin;
2367 1.1 oki /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2368 1.1 oki SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
2369 1.1 oki ite_clrtoeol(ip);
2370 1.1 oki } /*else
2371 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);*/
2372 1.1 oki }
2373 1.1 oki }
2374 1.1 oki
2375 1.49 isaki static void
2376 1.38 chs itecheckwrap(struct ite_softc *ip)
2377 1.1 oki {
2378 1.69 tsutsui
2379 1.1 oki #if 0
2380 1.1 oki if (++ip->curx == ip->cols) {
2381 1.1 oki if (ip->auto_wrap) {
2382 1.1 oki ip->curx = 0;
2383 1.1 oki clr_attr(ip, ATTR_INV);
2384 1.1 oki if (++ip->cury >= ip->bottom_margin + 1) {
2385 1.1 oki ip->cury = ip->bottom_margin;
2386 1.1 oki SUBR_CURSOR(ip, MOVE_CURSOR);
2387 1.69 tsutsui SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1,
2388 1.69 tsutsui SCROLL_UP);
2389 1.1 oki ite_clrtoeol(ip);
2390 1.1 oki return;
2391 1.1 oki }
2392 1.1 oki } else
2393 1.1 oki /* stay there if no autowrap.. */
2394 1.1 oki ip->curx--;
2395 1.1 oki }
2396 1.1 oki #else
2397 1.1 oki if (ip->curx < ip->cols) {
2398 1.1 oki ip->curx++;
2399 1.1 oki /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2400 1.1 oki }
2401 1.1 oki #endif
2402 1.1 oki }
2403 1.1 oki
2404 1.69 tsutsui /*
2405 1.69 tsutsui * A convertion table from DEC special graphics characters to ASCII characters.
2406 1.69 tsutsui * Mostly for box drawing on sysinst(8).
2407 1.69 tsutsui */
2408 1.69 tsutsui const uint8_t ite_decgraph2ascii[128] = {
2409 1.69 tsutsui /* same as ASCII from 0x00 to 0x5e */
2410 1.69 tsutsui 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2411 1.69 tsutsui 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
2412 1.69 tsutsui 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2413 1.69 tsutsui 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
2414 1.69 tsutsui 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
2415 1.69 tsutsui 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
2416 1.69 tsutsui 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
2417 1.69 tsutsui 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
2418 1.69 tsutsui 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
2419 1.69 tsutsui 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
2420 1.69 tsutsui 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
2421 1.69 tsutsui 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
2422 1.69 tsutsui
2423 1.69 tsutsui /* special graphics characters from 0x5f to 0x7e */
2424 1.69 tsutsui ' ', /* 0x5f NBSP */
2425 1.69 tsutsui '*', /* 0x60 diamond */
2426 1.69 tsutsui ' ', /* 0x61 medium shade */
2427 1.69 tsutsui ' ', /* 0x62 HT */
2428 1.69 tsutsui ' ', /* 0x63 FF */
2429 1.69 tsutsui ' ', /* 0x64 CR */
2430 1.69 tsutsui ' ', /* 0x65 LF */
2431 1.69 tsutsui ' ', /* 0x66 degree symbol */
2432 1.69 tsutsui ' ', /* 0x67 plus-minus sign */
2433 1.69 tsutsui ' ', /* 0x68 NL */
2434 1.69 tsutsui ' ', /* 0x69 VT */
2435 1.69 tsutsui '+', /* 0x6a box drawings up left */
2436 1.69 tsutsui '+', /* 0x6b box drawings down left */
2437 1.69 tsutsui '+', /* 0x6c box drawings down right */
2438 1.69 tsutsui '+', /* 0x6d box drawings up right */
2439 1.69 tsutsui '+', /* 0x6e box drawings vertical horizontal */
2440 1.69 tsutsui '~', /* 0x6f scan line 1 */
2441 1.69 tsutsui '-', /* 0x70 scan line 3 */
2442 1.69 tsutsui '-', /* 0x71 scan line 5 */
2443 1.69 tsutsui '-', /* 0x72 scan line 7 */
2444 1.69 tsutsui '_', /* 0x73 scan line 9 */
2445 1.69 tsutsui '+', /* 0x74 box drawings vertical right */
2446 1.69 tsutsui '+', /* 0x75 box drawings vertical left */
2447 1.69 tsutsui '+', /* 0x76 box drawings horizontal up */
2448 1.69 tsutsui '+', /* 0x77 box drawings horizontal down */
2449 1.69 tsutsui '|', /* 0x78 box drawings vertical */
2450 1.69 tsutsui '<', /* 0x79 less than or equal to */
2451 1.69 tsutsui '>', /* 0x7a greater than or equal to */
2452 1.69 tsutsui ' ', /* 0x7b pi */
2453 1.69 tsutsui ' ', /* 0x7c not equal */
2454 1.69 tsutsui ' ', /* 0x7d pound sign */
2455 1.69 tsutsui '.', /* 0x7e middle dot */
2456 1.69 tsutsui /* end of special graphics characters */
2457 1.69 tsutsui 0x7f
2458 1.69 tsutsui };
2459 1.69 tsutsui
2460 1.1 oki #endif
2461 1.1 oki
2462 1.14 minoura #if NITE > 0 && NKBD > 0
2463 1.14 minoura
2464 1.1 oki /*
2465 1.1 oki * Console functions
2466 1.1 oki */
2467 1.1 oki #include <dev/cons.h>
2468 1.38 chs extern void kbdenable(int);
2469 1.38 chs extern int kbdcngetc(void);
2470 1.1 oki
2471 1.1 oki /*
2472 1.1 oki * Return a priority in consdev->cn_pri field highest wins. This function
2473 1.1 oki * is called before any devices have been probed.
2474 1.1 oki */
2475 1.49 isaki void
2476 1.38 chs itecnprobe(struct consdev *cd)
2477 1.1 oki {
2478 1.2 oki int maj;
2479 1.1 oki
2480 1.1 oki /* locate the major number */
2481 1.29 gehenna maj = cdevsw_lookup_major(&ite_cdevsw);
2482 1.1 oki
2483 1.50 isaki /*
2484 1.1 oki * return priority of the best ite (already picked from attach)
2485 1.1 oki * or CN_DEAD.
2486 1.1 oki */
2487 1.1 oki if (con_itesoftc.grf == NULL)
2488 1.1 oki cd->cn_pri = CN_DEAD;
2489 1.1 oki else {
2490 1.1 oki con_itesoftc.flags = (ITE_ALIVE|ITE_CONSOLE);
2491 1.14 minoura /*
2492 1.14 minoura * hardcode the minor number.
2493 1.14 minoura * currently we support only one ITE, it is enough for now.
2494 1.14 minoura */
2495 1.14 minoura con_itesoftc.isw = &itesw[0];
2496 1.1 oki cd->cn_pri = CN_INTERNAL;
2497 1.14 minoura cd->cn_dev = makedev(maj, 0);
2498 1.1 oki }
2499 1.1 oki }
2500 1.1 oki
2501 1.49 isaki void
2502 1.38 chs itecninit(struct consdev *cd)
2503 1.1 oki {
2504 1.1 oki struct ite_softc *ip;
2505 1.1 oki
2506 1.1 oki ip = getitesp(cd->cn_dev);
2507 1.1 oki iteinit(cd->cn_dev); /* init console unit */
2508 1.1 oki ip->flags |= ITE_ACTIVE | ITE_ISCONS;
2509 1.14 minoura kbdenable(0);
2510 1.14 minoura mfp_send_usart(0x49);
2511 1.1 oki }
2512 1.1 oki
2513 1.1 oki /*
2514 1.1 oki * itecnfinish() is called in ite_init() when the device is
2515 1.68 andvar * being probed in the normal fashion, thus we can finish setting
2516 1.1 oki * up this ite now that the system is more functional.
2517 1.1 oki */
2518 1.49 isaki void
2519 1.38 chs itecnfinish(struct ite_softc *ip)
2520 1.1 oki {
2521 1.1 oki static int done;
2522 1.1 oki
2523 1.1 oki if (done)
2524 1.1 oki return;
2525 1.1 oki done = 1;
2526 1.1 oki }
2527 1.1 oki
2528 1.1 oki /*ARGSUSED*/
2529 1.49 isaki int
2530 1.38 chs itecngetc(dev_t dev)
2531 1.1 oki {
2532 1.38 chs int c;
2533 1.1 oki
2534 1.1 oki do {
2535 1.14 minoura c = kbdcngetc();
2536 1.16 minoura c = ite_cnfilter(c);
2537 1.1 oki } while (c == -1);
2538 1.1 oki return (c);
2539 1.1 oki }
2540 1.1 oki
2541 1.49 isaki void
2542 1.38 chs itecnputc(dev_t dev, int c)
2543 1.1 oki {
2544 1.1 oki static int paniced = 0;
2545 1.1 oki struct ite_softc *ip = getitesp(dev);
2546 1.1 oki char ch = c;
2547 1.14 minoura #ifdef ITE_KERNEL_ATTR
2548 1.14 minoura short save_attribute;
2549 1.14 minoura #endif
2550 1.1 oki
2551 1.1 oki if (panicstr && !paniced &&
2552 1.1 oki (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
2553 1.1 oki (void) iteon(dev, 3);
2554 1.1 oki paniced = 1;
2555 1.1 oki }
2556 1.14 minoura #ifdef ITE_KERNEL_ATTR
2557 1.14 minoura save_attribute = ip->attribute;
2558 1.14 minoura ip->attribute = ITE_KERNEL_ATTR;
2559 1.14 minoura #endif
2560 1.1 oki ite_putstr(&ch, 1, dev);
2561 1.14 minoura #ifdef ITE_KERNEL_ATTR
2562 1.14 minoura ip->attribute = save_attribute;
2563 1.14 minoura #endif
2564 1.1 oki }
2565 1.14 minoura #endif
2566