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