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