scterm-sck.c revision 64021
156337Skato/*- 256337Skato * Copyright (c) 1999 FreeBSD(98) Porting Team. 356337Skato * All rights reserved. 456337Skato * 556337Skato * Redistribution and use in source and binary forms, with or without 656337Skato * modification, are permitted provided that the following conditions 756337Skato * are met: 856337Skato * 1. Redistributions of source code must retain the above copyright 956337Skato * notice, this list of conditions and the following disclaimer as 1056337Skato * the first lines of this file unmodified. 1156337Skato * 2. Redistributions in binary form must reproduce the above copyright 1256337Skato * notice, this list of conditions and the following disclaimer in the 1356337Skato * documentation and/or other materials provided with the distribution. 1456337Skato * 1556337Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1656337Skato * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1756337Skato * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1856337Skato * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1956337Skato * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2056337Skato * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2156337Skato * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2256337Skato * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2356337Skato * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2456337Skato * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2556337Skato * 2656337Skato * $FreeBSD: head/sys/pc98/cbus/scterm-sck.c 64021 2000-07-30 08:12:08Z nyan $ 2756337Skato */ 2856337Skato 2956337Skato#include "opt_syscons.h" 3056337Skato 3156337Skato#include <sys/param.h> 3256337Skato#include <sys/systm.h> 3356337Skato#include <sys/kernel.h> 3456337Skato#include <sys/consio.h> 3556337Skato 3656337Skato#include <machine/pc/display.h> 3756337Skato 3856337Skato#include <dev/syscons/syscons.h> 3956337Skato#include <dev/syscons/sctermvar.h> 4056337Skato 4156337Skato#ifndef SC_DUMB_TERMINAL 4256337Skato 4356337Skato#define MAX_ESC_PAR 5 4456337Skato 4556337Skato#ifdef KANJI 4656337Skato#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) 4756337Skato#define IS_KTYPE_KANA(A) ((A) & 0x11) 4856337Skato#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) 4956337Skato#endif /* KANJI */ 5056337Skato 5156337Skato/* attribute flags */ 5256337Skatotypedef struct { 5356337Skato u_short fg; /* foreground color */ 5456337Skato u_short bg; /* background color */ 5556337Skato} color_t; 5656337Skato 5756337Skatotypedef struct { 5856337Skato int flags; 5956337Skato#define SCTERM_BUSY (1 << 0) 6056337Skato int esc; 6156337Skato int num_param; 6256337Skato int last_param; 6356337Skato int param[MAX_ESC_PAR]; 6456337Skato int saved_xpos; 6556337Skato int saved_ypos; 6656337Skato 6756337Skato#ifdef KANJI 6856337Skato u_char kanji_1st_char; 6956337Skato u_char kanji_type; 7056337Skato#define KTYPE_ASCII 0 /* ASCII */ 7156337Skato#define KTYPE_KANA 1 /* HANKAKU */ 7256337Skato#define KTYPE_JKANA 0x10 /* JIS HANKAKU */ 7356337Skato#define KTYPE_7JIS 0x20 /* JIS */ 7456337Skato#define KTYPE_SJIS 2 /* Shift JIS */ 7556337Skato#define KTYPE_UJIS 4 /* UJIS */ 7656337Skato#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */ 7756337Skato#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */ 7856337Skato#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */ 7956337Skato#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */ 8056337Skato#endif /* KANJI */ 8156337Skato 8256337Skato int attr_mask; /* current logical attr mask */ 8356337Skato#define NORMAL_ATTR 0x00 8456337Skato#define BLINK_ATTR 0x01 8556337Skato#define BOLD_ATTR 0x02 8656337Skato#define UNDERLINE_ATTR 0x04 8756337Skato#define REVERSE_ATTR 0x08 8856337Skato#define FG_CHANGED 0x10 8956337Skato#define BG_CHANGED 0x20 9056337Skato int cur_attr; /* current hardware attr word */ 9156337Skato color_t cur_color; /* current hardware color */ 9256337Skato color_t std_color; /* normal hardware color */ 9356337Skato color_t rev_color; /* reverse hardware color */ 9456337Skato color_t dflt_std_color; /* default normal color */ 9556337Skato color_t dflt_rev_color; /* default reverse color */ 9656337Skato} term_stat; 9756337Skato 9856337Skatostatic sc_term_init_t scterm_init; 9956337Skatostatic sc_term_term_t scterm_term; 10056337Skatostatic sc_term_puts_t scterm_puts; 10156337Skatostatic sc_term_ioctl_t scterm_ioctl; 10256337Skatostatic sc_term_reset_t scterm_reset; 10356337Skatostatic sc_term_default_attr_t scterm_default_attr; 10456337Skatostatic sc_term_clear_t scterm_clear; 10556337Skatostatic sc_term_notify_t scterm_notify; 10656337Skatostatic sc_term_input_t scterm_input; 10756337Skato 10856337Skatostatic sc_term_sw_t sc_term_sc = { 10956337Skato { NULL, NULL }, 11058381Snyan "sck", /* emulator name */ 11158381Snyan "syscons kanji terminal", /* description */ 11258381Snyan "*", /* matching renderer, any :-) */ 11358381Snyan sizeof(term_stat), /* softc size */ 11456337Skato 0, 11556337Skato scterm_init, 11656337Skato scterm_term, 11756337Skato scterm_puts, 11856337Skato scterm_ioctl, 11956337Skato scterm_reset, 12056337Skato scterm_default_attr, 12156337Skato scterm_clear, 12256337Skato scterm_notify, 12356337Skato scterm_input, 12456337Skato}; 12556337Skato 12656337SkatoSCTERM_MODULE(sc, sc_term_sc); 12756337Skato 12856337Skatostatic term_stat reserved_term_stat; 12956337Skatostatic int default_kanji = UJIS; 13056337Skatostatic void scterm_scan_esc(scr_stat *scp, term_stat *tcp, 13156337Skato u_char c); 13256337Skatostatic int mask2attr(term_stat *tcp); 13356337Skatostatic u_char iskanji1(u_char mode, u_char c); 13456337Skatostatic u_char iskanji2(u_char mode, u_char c); 13556337Skatostatic u_short kanji_convert(u_char mode, u_char h, u_char l); 13656337Skato 13756337Skatostatic int 13856337Skatoscterm_init(scr_stat *scp, void **softc, int code) 13956337Skato{ 14056337Skato term_stat *tcp; 14156337Skato 14256337Skato if (*softc == NULL) { 14356337Skato if (reserved_term_stat.flags & SCTERM_BUSY) 14456337Skato return EINVAL; 14556337Skato *softc = &reserved_term_stat; 14656337Skato } 14756337Skato tcp = *softc; 14856337Skato 14956337Skato switch (code) { 15056337Skato case SC_TE_COLD_INIT: 15156337Skato bzero(tcp, sizeof(*tcp)); 15256337Skato tcp->flags = SCTERM_BUSY; 15356337Skato tcp->esc = 0; 15456337Skato tcp->saved_xpos = -1; 15556337Skato tcp->saved_ypos = -1; 15656337Skato 15756337Skato#ifdef KANJI 15856337Skato tcp->kanji_1st_char = 0; 15956337Skato tcp->kanji_type = KTYPE_ASCII; 16056337Skato#endif 16156337Skato 16256337Skato tcp->attr_mask = NORMAL_ATTR; 16356337Skato /* XXX */ 16456337Skato tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f; 16556337Skato tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f; 16656337Skato tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f; 16756337Skato tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f; 16856337Skato tcp->std_color = tcp->dflt_std_color; 16956337Skato tcp->rev_color = tcp->dflt_rev_color; 17056337Skato tcp->cur_color = tcp->std_color; 17156337Skato tcp->cur_attr = mask2attr(tcp); 17256337Skato ++sc_term_sc.te_refcount; 17356337Skato break; 17456337Skato 17556337Skato case SC_TE_WARM_INIT: 17656337Skato tcp->esc = 0; 17756337Skato tcp->saved_xpos = -1; 17856337Skato tcp->saved_ypos = -1; 17957136Skato#if 0 18056337Skato tcp->std_color = tcp->dflt_std_color; 18156337Skato tcp->rev_color = tcp->dflt_rev_color; 18257136Skato#endif 18356337Skato tcp->cur_color = tcp->std_color; 18456337Skato tcp->cur_attr = mask2attr(tcp); 18556337Skato break; 18656337Skato } 18756337Skato 18856337Skato return 0; 18956337Skato} 19056337Skato 19156337Skatostatic int 19256337Skatoscterm_term(scr_stat *scp, void **softc) 19356337Skato{ 19456337Skato if (*softc == &reserved_term_stat) { 19556337Skato *softc = NULL; 19656337Skato bzero(&reserved_term_stat, sizeof(reserved_term_stat)); 19756337Skato } 19856337Skato --sc_term_sc.te_refcount; 19956337Skato return 0; 20056337Skato} 20156337Skato 20256337Skatostatic void 20356337Skatoscterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) 20456337Skato{ 20556337Skato static u_char ansi_col[16] = { 20656337Skato FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, 20756337Skato FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, 20856337Skato FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, 20956337Skato FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE 21058381Snyan }; 21156337Skato sc_softc_t *sc; 21256337Skato int i, n; 21356337Skato 21458381Snyan i = n = 0; 21558381Snyan sc = scp->sc; 21658381Snyan if (tcp->esc == 1) { /* seen ESC */ 21759778Snyan#ifdef KANJI 21859778Snyan switch (tcp->kanji_type) { 21959778Snyan case KTYPE_KANIN: /* Kanji Invoke sequence */ 22059778Snyan switch (c) { 22159778Snyan case 'B': 22259778Snyan case '@': 22359778Snyan tcp->kanji_type = KTYPE_7JIS; 22459778Snyan tcp->esc = 0; 22559778Snyan tcp->kanji_1st_char = 0; 22659778Snyan return; 22759778Snyan default: 22859778Snyan tcp->kanji_type = KTYPE_ASCII; 22959778Snyan tcp->esc = 0; 23059778Snyan break; 23159778Snyan } 23259778Snyan break; 23359778Snyan case KTYPE_ASCIN: /* Ascii Invoke sequence */ 23459778Snyan switch (c) { 23559778Snyan case 'J': 23659778Snyan case 'B': 23759778Snyan case 'H': 23859778Snyan tcp->kanji_type = KTYPE_ASCII; 23959778Snyan tcp->esc = 0; 24059778Snyan tcp->kanji_1st_char = 0; 24159778Snyan return; 24259778Snyan case 'I': 24359778Snyan tcp->kanji_type = KTYPE_JKANA; 24459778Snyan tcp->esc = 0; 24559778Snyan tcp->kanji_1st_char = 0; 24659778Snyan return; 24759778Snyan default: 24859778Snyan tcp->kanji_type = KTYPE_ASCII; 24959778Snyan tcp->esc = 0; 25059778Snyan break; 25159778Snyan } 25259778Snyan break; 25359778Snyan default: 25459778Snyan break; 25559778Snyan } 25659778Snyan#endif 25758381Snyan switch (c) { 25856337Skato 25958381Snyan case '7': /* Save cursor position */ 26058381Snyan tcp->saved_xpos = scp->xpos; 26158381Snyan tcp->saved_ypos = scp->ypos; 26258381Snyan break; 26356337Skato 26458381Snyan case '8': /* Restore saved cursor position */ 26558381Snyan if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 26658381Snyan sc_move_cursor(scp, tcp->saved_xpos, 26758381Snyan tcp->saved_ypos); 26858381Snyan break; 26956337Skato 27058381Snyan case '[': /* Start ESC [ sequence */ 27158381Snyan tcp->esc = 2; 27258381Snyan tcp->last_param = -1; 27358381Snyan for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 27458381Snyan tcp->param[i] = 1; 27558381Snyan tcp->num_param = 0; 27658381Snyan return; 27756337Skato 27856337Skato#ifdef KANJI 27958381Snyan case '$': /* Kanji Invoke sequence */ 28058381Snyan tcp->kanji_type = KTYPE_KANIN; 28158381Snyan return; 28256337Skato#endif 28356337Skato 28458381Snyan case 'M': /* Move cursor up 1 line, scroll if at top */ 28558381Snyan sc_term_up_scroll(scp, 1, sc->scr_map[0x20], 28658381Snyan tcp->cur_attr, 0, 0); 28758381Snyan break; 28856337Skato#if notyet 28958381Snyan case 'Q': 29058381Snyan tcp->esc = 4; 29158381Snyan return; 29256337Skato#endif 29364021Snyan case 'c': /* reset */ 29464021Snyan tcp->attr_mask = NORMAL_ATTR; 29564021Snyan tcp->cur_color = tcp->std_color 29664021Snyan = tcp->dflt_std_color; 29764021Snyan tcp->rev_color = tcp->dflt_rev_color; 29864021Snyan tcp->cur_attr = mask2attr(tcp); 29958381Snyan sc_clear_screen(scp); 30058381Snyan break; 30156337Skato 30258381Snyan case '(': /* iso-2022: designate 94 character set to G0 */ 30356337Skato#ifdef KANJI 30458381Snyan tcp->kanji_type = KTYPE_ASCIN; 30556337Skato#else 30658381Snyan tcp->esc = 5; 30756337Skato#endif 30858381Snyan return; 30956337Skato } 31058381Snyan } else if (tcp->esc == 2) { /* seen ESC [ */ 31158381Snyan if (c >= '0' && c <= '9') { 31258381Snyan if (tcp->num_param < MAX_ESC_PAR) { 31358381Snyan if (tcp->last_param != tcp->num_param) { 31458381Snyan tcp->last_param = tcp->num_param; 31558381Snyan tcp->param[tcp->num_param] = 0; 31658381Snyan } else { 31758381Snyan tcp->param[tcp->num_param] *= 10; 31858381Snyan } 31958381Snyan tcp->param[tcp->num_param] += c - '0'; 32058381Snyan return; 32158381Snyan } 32258381Snyan } 32358381Snyan tcp->num_param = tcp->last_param + 1; 32458381Snyan switch (c) { 32556337Skato 32658381Snyan case ';': 32758381Snyan if (tcp->num_param < MAX_ESC_PAR) 32858381Snyan return; 32958381Snyan break; 33056337Skato 33158381Snyan case '=': 33258381Snyan tcp->esc = 3; 33358381Snyan tcp->last_param = -1; 33458381Snyan for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 33558381Snyan tcp->param[i] = 1; 33658381Snyan tcp->num_param = 0; 33758381Snyan return; 33856337Skato 33958381Snyan case 'A': /* up n rows */ 34058381Snyan sc_term_up(scp, tcp->param[0], 0); 34158381Snyan break; 34256337Skato 34358381Snyan case 'B': /* down n rows */ 34458381Snyan sc_term_down(scp, tcp->param[0], 0); 34558381Snyan break; 34656337Skato 34758381Snyan case 'C': /* right n columns */ 34858381Snyan sc_term_right(scp, tcp->param[0]); 34958381Snyan break; 35056337Skato 35158381Snyan case 'D': /* left n columns */ 35258381Snyan sc_term_left(scp, tcp->param[0]); 35358381Snyan break; 35456337Skato 35558381Snyan case 'E': /* cursor to start of line n lines down */ 35658381Snyan n = tcp->param[0]; 35758381Snyan if (n < 1) 35858381Snyan n = 1; 35958381Snyan sc_move_cursor(scp, 0, scp->ypos + n); 36058381Snyan break; 36156337Skato 36258381Snyan case 'F': /* cursor to start of line n lines up */ 36358381Snyan n = tcp->param[0]; 36458381Snyan if (n < 1) 36558381Snyan n = 1; 36658381Snyan sc_move_cursor(scp, 0, scp->ypos - n); 36758381Snyan break; 36856337Skato 36958381Snyan case 'f': /* Cursor move */ 37058381Snyan case 'H': 37158381Snyan if (tcp->num_param == 0) 37258381Snyan sc_move_cursor(scp, 0, 0); 37358381Snyan else if (tcp->num_param == 2) 37458381Snyan sc_move_cursor(scp, tcp->param[1] - 1, 37558381Snyan tcp->param[0] - 1); 37658381Snyan break; 37756337Skato 37858381Snyan case 'J': /* Clear all or part of display */ 37958381Snyan if (tcp->num_param == 0) 38058381Snyan n = 0; 38158381Snyan else 38258381Snyan n = tcp->param[0]; 38358381Snyan sc_term_clr_eos(scp, n, sc->scr_map[0x20], 38458381Snyan tcp->cur_attr); 38558381Snyan break; 38656337Skato 38758381Snyan case 'K': /* Clear all or part of line */ 38858381Snyan if (tcp->num_param == 0) 38958381Snyan n = 0; 39058381Snyan else 39158381Snyan n = tcp->param[0]; 39258381Snyan sc_term_clr_eol(scp, n, sc->scr_map[0x20], 39358381Snyan tcp->cur_attr); 39458381Snyan break; 39556337Skato 39658381Snyan case 'L': /* Insert n lines */ 39758381Snyan sc_term_ins_line(scp, scp->ypos, tcp->param[0], 39858381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 39958381Snyan break; 40056337Skato 40158381Snyan case 'M': /* Delete n lines */ 40258381Snyan sc_term_del_line(scp, scp->ypos, tcp->param[0], 40358381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 40458381Snyan break; 40556337Skato 40658381Snyan case 'P': /* Delete n chars */ 40758381Snyan sc_term_del_char(scp, tcp->param[0], 40858381Snyan sc->scr_map[0x20], tcp->cur_attr); 40958381Snyan break; 41056337Skato 41158381Snyan case '@': /* Insert n chars */ 41258381Snyan sc_term_ins_char(scp, tcp->param[0], 41358381Snyan sc->scr_map[0x20], tcp->cur_attr); 41458381Snyan break; 41556337Skato 41658381Snyan case 'S': /* scroll up n lines */ 41758381Snyan sc_term_del_line(scp, 0, tcp->param[0], 41858381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 41958381Snyan break; 42056337Skato 42158381Snyan case 'T': /* scroll down n lines */ 42258381Snyan sc_term_ins_line(scp, 0, tcp->param[0], 42358381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 42458381Snyan break; 42556337Skato 42658381Snyan case 'X': /* erase n characters in line */ 42758381Snyan n = tcp->param[0]; 42858381Snyan if (n < 1) 42958381Snyan n = 1; 43058381Snyan if (n > scp->xsize - scp->xpos) 43158381Snyan n = scp->xsize - scp->xpos; 43258381Snyan sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, 43358381Snyan sc->scr_map[0x20], tcp->cur_attr); 43458381Snyan mark_for_update(scp, scp->cursor_pos); 43558381Snyan mark_for_update(scp, scp->cursor_pos + n - 1); 43658381Snyan break; 43756337Skato 43858381Snyan case 'Z': /* move n tabs backwards */ 43958381Snyan sc_term_backtab(scp, tcp->param[0]); 44058381Snyan break; 44156337Skato 44258381Snyan case '`': /* move cursor to column n */ 44358381Snyan sc_term_col(scp, tcp->param[0]); 44458381Snyan break; 44556337Skato 44658381Snyan case 'a': /* move cursor n columns to the right */ 44758381Snyan sc_term_right(scp, tcp->param[0]); 44858381Snyan break; 44956337Skato 45058381Snyan case 'd': /* move cursor to row n */ 45158381Snyan sc_term_row(scp, tcp->param[0]); 45258381Snyan break; 45356337Skato 45458381Snyan case 'e': /* move cursor n rows down */ 45558381Snyan sc_term_down(scp, tcp->param[0], 0); 45658381Snyan break; 45756337Skato 45858381Snyan case 'm': /* change attribute */ 45958381Snyan if (tcp->num_param == 0) { 46058381Snyan tcp->attr_mask = NORMAL_ATTR; 46158381Snyan tcp->cur_color = tcp->std_color; 46258381Snyan tcp->cur_attr = mask2attr(tcp); 46358381Snyan break; 46458381Snyan } 46558381Snyan for (i = 0; i < tcp->num_param; i++) { 46658381Snyan switch (n = tcp->param[i]) { 46758381Snyan case 0: /* back to normal */ 46858381Snyan tcp->attr_mask = NORMAL_ATTR; 46958381Snyan tcp->cur_color = tcp->std_color; 47058381Snyan tcp->cur_attr = mask2attr(tcp); 47158381Snyan break; 47258381Snyan case 1: /* bold */ 47358381Snyan tcp->attr_mask |= BOLD_ATTR; 47458381Snyan tcp->cur_attr = mask2attr(tcp); 47558381Snyan break; 47658381Snyan case 4: /* underline */ 47758381Snyan tcp->attr_mask |= UNDERLINE_ATTR; 47858381Snyan tcp->cur_attr = mask2attr(tcp); 47958381Snyan break; 48058381Snyan case 5: /* blink */ 48158381Snyan tcp->attr_mask |= BLINK_ATTR; 48258381Snyan tcp->cur_attr = mask2attr(tcp); 48358381Snyan break; 48464021Snyan case 7: /* reverse */ 48558381Snyan tcp->attr_mask |= REVERSE_ATTR; 48658381Snyan tcp->cur_attr = mask2attr(tcp); 48758381Snyan break; 48864021Snyan case 22: /* remove bold (or dim) */ 48964021Snyan tcp->attr_mask &= ~BOLD_ATTR; 49064021Snyan tcp->cur_attr = mask2attr(tcp); 49164021Snyan break; 49264021Snyan case 24: /* remove underline */ 49364021Snyan tcp->attr_mask &= ~UNDERLINE_ATTR; 49464021Snyan tcp->cur_attr = mask2attr(tcp); 49564021Snyan break; 49664021Snyan case 25: /* remove blink */ 49764021Snyan tcp->attr_mask &= ~BLINK_ATTR; 49864021Snyan tcp->cur_attr = mask2attr(tcp); 49964021Snyan break; 50064021Snyan case 27: /* remove reverse */ 50164021Snyan tcp->attr_mask &= ~REVERSE_ATTR; 50264021Snyan tcp->cur_attr = mask2attr(tcp); 50364021Snyan break; 50464021Snyan case 30: case 31: /* set ansi fg color */ 50558381Snyan case 32: case 33: case 34: 50658381Snyan case 35: case 36: case 37: 50758381Snyan tcp->attr_mask |= FG_CHANGED; 50858381Snyan tcp->cur_color.fg = ansi_col[n - 30]; 50958381Snyan tcp->cur_attr = mask2attr(tcp); 51058381Snyan break; 51164021Snyan case 39: /* restore fg color back to normal */ 51264021Snyan tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR); 51361950Snyan tcp->cur_color.fg = tcp->std_color.fg; 51461950Snyan tcp->cur_attr = mask2attr(tcp); 51561950Snyan break; 51664021Snyan case 40: case 41: /* set ansi bg color */ 51758381Snyan case 42: case 43: case 44: 51858381Snyan case 45: case 46: case 47: 51958381Snyan tcp->attr_mask |= BG_CHANGED; 52058381Snyan tcp->cur_color.bg = ansi_col[n - 40]; 52158381Snyan tcp->cur_attr = mask2attr(tcp); 52258381Snyan break; 52364021Snyan case 49: /* restore bg color back to normal */ 52461950Snyan tcp->attr_mask &= ~BG_CHANGED; 52561950Snyan tcp->cur_color.bg = tcp->std_color.bg; 52661950Snyan tcp->cur_attr = mask2attr(tcp); 52761950Snyan break; 52858381Snyan } 52958381Snyan } 53058381Snyan break; 53156337Skato 53258381Snyan case 's': /* Save cursor position */ 53358381Snyan tcp->saved_xpos = scp->xpos; 53458381Snyan tcp->saved_ypos = scp->ypos; 53558381Snyan break; 53656337Skato 53758381Snyan case 'u': /* Restore saved cursor position */ 53858381Snyan if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 53958381Snyan sc_move_cursor(scp, tcp->saved_xpos, 54058381Snyan tcp->saved_ypos); 54158381Snyan break; 54256337Skato 54358381Snyan case 'x': 54458381Snyan if (tcp->num_param == 0) 54558381Snyan n = 0; 54658381Snyan else 54758381Snyan n = tcp->param[0]; 54858381Snyan switch (n) { 54964021Snyan case 0: /* reset colors and attributes back to normal */ 55058381Snyan tcp->attr_mask = NORMAL_ATTR; 55158381Snyan tcp->cur_color = tcp->std_color = 55258381Snyan tcp->dflt_std_color; 55358381Snyan tcp->rev_color = tcp->dflt_rev_color; 55458381Snyan tcp->cur_attr = mask2attr(tcp); 55558381Snyan break; 55658381Snyan case 1: /* set ansi background */ 55758381Snyan tcp->attr_mask &= ~BG_CHANGED; 55858381Snyan tcp->cur_color.bg = tcp->std_color.bg = 55958381Snyan ansi_col[tcp->param[1] & 0x0f]; 56058381Snyan tcp->cur_attr = mask2attr(tcp); 56158381Snyan break; 56258381Snyan case 2: /* set ansi foreground */ 56358381Snyan tcp->attr_mask &= ~FG_CHANGED; 56458381Snyan tcp->cur_color.fg = tcp->std_color.fg = 56558381Snyan ansi_col[tcp->param[1] & 0x0f]; 56658381Snyan tcp->cur_attr = mask2attr(tcp); 56758381Snyan break; 56864021Snyan case 3: /* set adapter attribute directly */ 56958381Snyan tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); 57058381Snyan tcp->cur_color.fg = tcp->std_color.fg = 57158381Snyan tcp->param[1] & 0x0f; 57258381Snyan tcp->cur_color.bg = tcp->std_color.bg = 57358381Snyan (tcp->param[1] >> 4) & 0x0f; 57458381Snyan tcp->cur_attr = mask2attr(tcp); 57558381Snyan break; 57664021Snyan case 5: /* set ansi reverse background */ 57758381Snyan tcp->rev_color.bg = 57858381Snyan ansi_col[tcp->param[1] & 0x0f]; 57958381Snyan tcp->cur_attr = mask2attr(tcp); 58058381Snyan break; 58164021Snyan case 6: /* set ansi reverse foreground */ 58258381Snyan tcp->rev_color.fg = 58358381Snyan ansi_col[tcp->param[1] & 0x0f]; 58458381Snyan tcp->cur_attr = mask2attr(tcp); 58558381Snyan break; 58664021Snyan case 7: /* set adapter reverse attribute directly */ 58758381Snyan tcp->rev_color.fg = tcp->param[1] & 0x0f; 58858381Snyan tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; 58958381Snyan tcp->cur_attr = mask2attr(tcp); 59058381Snyan break; 59158381Snyan } 59258381Snyan break; 59356337Skato 59458381Snyan case 'z': /* switch to (virtual) console n */ 59558381Snyan if (tcp->num_param == 1) 59658381Snyan sc_switch_scr(sc, tcp->param[0]); 59758381Snyan break; 59856337Skato } 59958381Snyan } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ 60058381Snyan if (c >= '0' && c <= '9') { 60158381Snyan if (tcp->num_param < MAX_ESC_PAR) { 60258381Snyan if (tcp->last_param != tcp->num_param) { 60358381Snyan tcp->last_param = tcp->num_param; 60458381Snyan tcp->param[tcp->num_param] = 0; 60558381Snyan } else { 60658381Snyan tcp->param[tcp->num_param] *= 10; 60758381Snyan } 60858381Snyan tcp->param[tcp->num_param] += c - '0'; 60958381Snyan return; 61058381Snyan } 61158381Snyan } 61258381Snyan tcp->num_param = tcp->last_param + 1; 61358381Snyan switch (c) { 61456337Skato 61558381Snyan case ';': 61658381Snyan if (tcp->num_param < MAX_ESC_PAR) 61758381Snyan return; 61858381Snyan break; 61956337Skato 62058381Snyan case 'A': /* set display border color */ 62158381Snyan if (tcp->num_param == 1) { 62258381Snyan scp->border=tcp->param[0] & 0xff; 62358381Snyan if (scp == sc->cur_scp) 62458381Snyan sc_set_border(scp, scp->border); 62558381Snyan } 62658381Snyan break; 62756337Skato 62858381Snyan case 'B': /* set bell pitch and duration */ 62958381Snyan if (tcp->num_param == 2) { 63058381Snyan scp->bell_pitch = tcp->param[0]; 63158381Snyan scp->bell_duration = tcp->param[1]; 63258381Snyan } 63358381Snyan break; 63456337Skato 63558381Snyan case 'C': /* set cursor type & shape */ 63658381Snyan i = spltty(); 63758381Snyan if (!ISGRAPHSC(sc->cur_scp)) 63858381Snyan sc_remove_cursor_image(sc->cur_scp); 63958381Snyan if (tcp->num_param == 1) { 64058381Snyan if (tcp->param[0] & 0x01) 64158381Snyan sc->flags |= SC_BLINK_CURSOR; 64258381Snyan else 64358381Snyan sc->flags &= ~SC_BLINK_CURSOR; 64458381Snyan if (tcp->param[0] & 0x02) 64558381Snyan sc->flags |= SC_CHAR_CURSOR; 64658381Snyan else 64758381Snyan sc->flags &= ~SC_CHAR_CURSOR; 64858381Snyan } else if (tcp->num_param == 2) { 64958381Snyan sc->cursor_base = scp->font_size 65058381Snyan - (tcp->param[1] & 0x1F) - 1; 65158381Snyan sc->cursor_height = (tcp->param[1] & 0x1F) 65258381Snyan - (tcp->param[0] & 0x1F) + 1; 65358381Snyan } 65458381Snyan /* 65558381Snyan * The cursor shape is global property; 65658381Snyan * all virtual consoles are affected. 65758381Snyan * Update the cursor in the current console... 65858381Snyan */ 65958381Snyan if (!ISGRAPHSC(sc->cur_scp)) { 66058381Snyan sc_set_cursor_image(sc->cur_scp); 66158381Snyan sc_draw_cursor_image(sc->cur_scp); 66258381Snyan } 66358381Snyan splx(i); 66458381Snyan break; 66556337Skato 66664021Snyan case 'F': /* set adapter foreground */ 66758381Snyan if (tcp->num_param == 1) { 66858381Snyan tcp->attr_mask &= ~FG_CHANGED; 66958381Snyan tcp->cur_color.fg = tcp->std_color.fg = 67058381Snyan tcp->param[0] & 0x0f; 67158381Snyan tcp->cur_attr = mask2attr(tcp); 67258381Snyan } 67358381Snyan break; 67456337Skato 67564021Snyan case 'G': /* set adapter background */ 67658381Snyan if (tcp->num_param == 1) { 67758381Snyan tcp->attr_mask &= ~BG_CHANGED; 67858381Snyan tcp->cur_color.bg = tcp->std_color.bg = 67958381Snyan tcp->param[0] & 0x0f; 68058381Snyan tcp->cur_attr = mask2attr(tcp); 68158381Snyan } 68258381Snyan break; 68356337Skato 68464021Snyan case 'H': /* set adapter reverse foreground */ 68558381Snyan if (tcp->num_param == 1) { 68658381Snyan tcp->rev_color.fg = tcp->param[0] & 0x0f; 68758381Snyan tcp->cur_attr = mask2attr(tcp); 68858381Snyan } 68958381Snyan break; 69056337Skato 69164021Snyan case 'I': /* set adapter reverse background */ 69258381Snyan if (tcp->num_param == 1) { 69358381Snyan tcp->rev_color.bg = tcp->param[0] & 0x0f; 69458381Snyan tcp->cur_attr = mask2attr(tcp); 69558381Snyan } 69658381Snyan break; 69758381Snyan } 69856337Skato#if notyet 69958381Snyan } else if (tcp->esc == 4) { /* seen ESC Q */ 70058381Snyan /* to be filled */ 70156337Skato#endif 70258381Snyan } else if (tcp->esc == 5) { /* seen ESC ( */ 70358381Snyan switch (c) { 70458381Snyan case 'B': /* iso-2022: desginate ASCII into G0 */ 70558381Snyan break; 70658381Snyan /* other items to be filled */ 70758381Snyan default: 70858381Snyan break; 70958381Snyan } 71056337Skato } 71158381Snyan tcp->esc = 0; 71256337Skato} 71356337Skato 71456337Skatostatic void 71556337Skatoscterm_puts(scr_stat *scp, u_char *buf, int len) 71656337Skato{ 71756337Skato term_stat *tcp = scp->ts; 71856337Skato u_char *ptr = buf; 71956337Skato#ifdef KANJI 72056337Skato u_short kanji_code; 72156337Skato#endif 72256337Skato 72356337Skatooutloop: 72458381Snyan scp->sc->write_in_progress++; 72556337Skato 72658381Snyan if (tcp->esc) { 72758381Snyan scterm_scan_esc(scp, tcp, *ptr++); 72858381Snyan len--; 72958381Snyan } else if (PRINTABLE(*ptr)) { /* Print only printables */ 73058381Snyan vm_offset_t p; 73158381Snyan u_char *map; 73258381Snyan int attr; 73358381Snyan int i; 73456337Skato#ifdef KANJI 73558381Snyan u_char c; 73656337Skato#else 73758381Snyan int cnt; 73856337Skato#endif 73956337Skato 74058381Snyan p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); 74158381Snyan map = scp->sc->scr_map; 74258381Snyan attr = tcp->cur_attr; 74356337Skato 74456337Skato#ifdef KANJI 74558381Snyan c = *ptr; 74658381Snyan if (tcp->kanji_1st_char == 0) { 74758381Snyan tcp->kanji_type = iskanji1(tcp->kanji_type, c); 74858381Snyan if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { 74958381Snyan /* not Ascii & not HANKAKU */ 75058381Snyan tcp->kanji_1st_char = c; 75158381Snyan goto kanji_end; 75258381Snyan } else { 75358381Snyan tcp->kanji_1st_char = 0; 75456337Skato } 75558381Snyan } else { 75658381Snyan if ((tcp->kanji_type = 75758381Snyan iskanji2(tcp->kanji_type, c)) & 0xee) { 75858381Snyan /* print kanji on TEXT VRAM */ 75958381Snyan kanji_code = kanji_convert(tcp->kanji_type, c, 76058381Snyan tcp->kanji_1st_char); 76158381Snyan mark_for_update(scp, scp->cursor_pos); 76258381Snyan for (i = 0; i < 2; i++) { 76358381Snyan /* *cursor_pos = (kanji_code | (i*0x80)); */ 76458381Snyan p = sc_vtb_putchar(&scp->vtb, p, 76558381Snyan kanji_code | ((i == 0) ? 0x00 : 0x80), attr); 76658381Snyan ++scp->cursor_pos; 76758381Snyan if (++scp->xpos >= scp->xsize) { 76858381Snyan scp->xpos = 0; 76958381Snyan scp->ypos++; 77058381Snyan } 77158381Snyan } 77258381Snyan mark_for_update(scp, scp->cursor_pos - 1); 77358381Snyan KTYPE_MASK_CTRL(tcp->kanji_type); 77458381Snyan tcp->kanji_1st_char = 0; 77558381Snyan goto kanji_end; 77658381Snyan } else { 77758381Snyan tcp->kanji_1st_char = 0; 77858381Snyan } 77958381Snyan } 78058381Snyan if (IS_KTYPE_KANA(tcp->kanji_type)) 78158381Snyan c |= 0x80; 78256337Skato KTYPE_MASK_CTRL(tcp->kanji_type); 78358381Snyan sc_vtb_putchar(&scp->vtb, p, map[c], attr); 78458381Snyan mark_for_update(scp, scp->cursor_pos); 78558381Snyan mark_for_update(scp, scp->cursor_pos); 78658381Snyan ++scp->cursor_pos; 78758381Snyan ++scp->xpos; 78856337Skatokanji_end: 78958381Snyan ++ptr; 79058381Snyan --len; 79156337Skato#else /* !KANJI */ 79258381Snyan cnt = imin(len, scp->xsize - scp->xpos); 79358381Snyan i = cnt; 79458381Snyan do { 79558381Snyan /* 79658381Snyan * gcc-2.6.3 generates poor (un)sign extension code. 79758381Snyan * Casting the pointers in the following to volatile should 79858381Snyan * have no effect, but in fact speeds up this inner loop 79958381Snyan * from 26 to 18 cycles (+ cache misses) on i486's. 80058381Snyan */ 80156337Skato#define UCVP(ucp) ((u_char volatile *)(ucp)) 80258381Snyan p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], 80358381Snyan attr); 80458381Snyan ++ptr; 80558381Snyan --i; 80658381Snyan } while (i > 0 && PRINTABLE(*ptr)); 80756337Skato 80858381Snyan len -= cnt - i; 80958381Snyan mark_for_update(scp, scp->cursor_pos); 81058381Snyan scp->cursor_pos += cnt - i; 81158381Snyan mark_for_update(scp, scp->cursor_pos - 1); 81258381Snyan scp->xpos += cnt - i; 81356337Skato#endif /* !KANJI */ 81456337Skato 81558381Snyan if (scp->xpos >= scp->xsize) { 81658381Snyan scp->xpos = 0; 81758381Snyan scp->ypos++; 81856337Skato } 81958381Snyan } else { 82058381Snyan switch (*ptr) { 82158381Snyan case 0x07: 82258381Snyan sc_bell(scp, scp->bell_pitch, scp->bell_duration); 82358381Snyan break; 82456337Skato 82558381Snyan case 0x08: /* non-destructive backspace */ 82658381Snyan if (scp->cursor_pos > 0) { 82758381Snyan mark_for_update(scp, scp->cursor_pos); 82858381Snyan scp->cursor_pos--; 82958381Snyan mark_for_update(scp, scp->cursor_pos); 83058381Snyan if (scp->xpos > 0) 83158381Snyan scp->xpos--; 83258381Snyan else { 83358381Snyan scp->xpos += scp->xsize - 1; 83458381Snyan scp->ypos--; 83558381Snyan } 83658381Snyan } 83758381Snyan break; 83856337Skato 83958381Snyan case 0x09: /* non-destructive tab */ 84058381Snyan mark_for_update(scp, scp->cursor_pos); 84158381Snyan scp->cursor_pos += (8 - scp->xpos % 8u); 84258381Snyan scp->xpos += (8 - scp->xpos % 8u); 84358381Snyan if (scp->xpos >= scp->xsize) { 84458381Snyan scp->xpos = 0; 84558381Snyan scp->ypos++; 84658381Snyan scp->cursor_pos = scp->xsize * scp->ypos; 84758381Snyan } 84858381Snyan mark_for_update(scp, scp->cursor_pos); 84958381Snyan break; 85056337Skato 85158381Snyan case 0x0a: /* newline, same pos */ 85258381Snyan mark_for_update(scp, scp->cursor_pos); 85358381Snyan scp->cursor_pos += scp->xsize; 85458381Snyan mark_for_update(scp, scp->cursor_pos); 85558381Snyan scp->ypos++; 85658381Snyan break; 85756337Skato 85858381Snyan case 0x0c: /* form feed, clears screen */ 85958381Snyan sc_clear_screen(scp); 86058381Snyan break; 86156337Skato 86258381Snyan case 0x0d: /* return, return to pos 0 */ 86358381Snyan mark_for_update(scp, scp->cursor_pos); 86458381Snyan scp->cursor_pos -= scp->xpos; 86558381Snyan mark_for_update(scp, scp->cursor_pos); 86658381Snyan scp->xpos = 0; 86758381Snyan break; 86858381Snyan 86956337Skato#ifdef PC98 87058381Snyan case 0x0e: /* ^N */ 87158381Snyan tcp->kanji_type = KTYPE_JKANA; 87258381Snyan tcp->esc = 0; 87358381Snyan tcp->kanji_1st_char = 0; 87458381Snyan break; 87556337Skato 87658381Snyan case 0x0f: /* ^O */ 87758381Snyan tcp->kanji_type = KTYPE_ASCII; 87858381Snyan tcp->esc = 0; 87958381Snyan tcp->kanji_1st_char = 0; 88058381Snyan break; 88156337Skato#endif /* PC98 */ 88256337Skato 88358381Snyan case 0x1b: /* start escape sequence */ 88458381Snyan tcp->esc = 1; 88558381Snyan tcp->num_param = 0; 88658381Snyan break; 88758381Snyan } 88858381Snyan ptr++; 88958381Snyan len--; 89056337Skato } 89156337Skato 89258381Snyan sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); 89356337Skato 89458381Snyan scp->sc->write_in_progress--; 89558381Snyan if (len) 89658381Snyan goto outloop; 89756337Skato} 89856337Skato 89956337Skatostatic int 90056337Skatoscterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 90156337Skato int flag, struct proc *p) 90256337Skato{ 90356337Skato term_stat *tcp = scp->ts; 90456337Skato vid_info_t *vi; 90556337Skato 90656337Skato switch (cmd) { 90756337Skato case GIO_ATTR: /* get current attributes */ 90856337Skato /* FIXME: */ 90956337Skato *(int*)data = (tcp->cur_attr >> 8) & 0xff; 91056337Skato return 0; 91156337Skato case CONS_GETINFO: /* get current (virtual) console info */ 91256337Skato vi = (vid_info_t *)data; 91356337Skato if (vi->size != sizeof(struct vid_info)) 91456337Skato return EINVAL; 91556337Skato vi->mv_norm.fore = tcp->std_color.fg; 91656337Skato vi->mv_norm.back = tcp->std_color.bg; 91756337Skato vi->mv_rev.fore = tcp->rev_color.fg; 91856337Skato vi->mv_rev.back = tcp->rev_color.bg; 91956337Skato /* 92056337Skato * The other fields are filled by the upper routine. XXX 92156337Skato */ 92256337Skato return ENOIOCTL; 92356337Skato } 92456337Skato return ENOIOCTL; 92556337Skato} 92656337Skato 92756337Skatostatic int 92856337Skatoscterm_reset(scr_stat *scp, int code) 92956337Skato{ 93056337Skato /* FIXME */ 93156337Skato return 0; 93256337Skato} 93356337Skato 93456337Skatostatic void 93556337Skatoscterm_default_attr(scr_stat *scp, int color, int rev_color) 93656337Skato{ 93756337Skato term_stat *tcp = scp->ts; 93856337Skato 93956337Skato tcp->dflt_std_color.fg = color & 0x0f; 94056337Skato tcp->dflt_std_color.bg = (color >> 4) & 0x0f; 94156337Skato tcp->dflt_rev_color.fg = rev_color & 0x0f; 94256337Skato tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; 94356337Skato tcp->std_color = tcp->dflt_std_color; 94456337Skato tcp->rev_color = tcp->dflt_rev_color; 94556337Skato tcp->cur_color = tcp->std_color; 94656337Skato tcp->cur_attr = mask2attr(tcp); 94756337Skato} 94856337Skato 94956337Skatostatic void 95056337Skatoscterm_clear(scr_stat *scp) 95156337Skato{ 95256337Skato term_stat *tcp = scp->ts; 95356337Skato 95456337Skato sc_move_cursor(scp, 0, 0); 95556337Skato sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); 95656337Skato mark_all(scp); 95756337Skato} 95856337Skato 95956337Skatostatic void 96056337Skatoscterm_notify(scr_stat *scp, int event) 96156337Skato{ 96256337Skato switch (event) { 96356337Skato case SC_TE_NOTIFY_VTSWITCH_IN: 96456337Skato break; 96556337Skato case SC_TE_NOTIFY_VTSWITCH_OUT: 96656337Skato break; 96756337Skato } 96856337Skato} 96956337Skato 97056337Skatostatic int 97156337Skatoscterm_input(scr_stat *scp, int c, struct tty *tp) 97256337Skato{ 97356337Skato return FALSE; 97456337Skato} 97556337Skato 97656337Skato/* 97756337Skato * Calculate hardware attributes word using logical attributes mask and 97856337Skato * hardware colors 97956337Skato */ 98056337Skato 98156337Skato/* FIXME */ 98256337Skatostatic int 98356337Skatomask2attr(term_stat *tcp) 98456337Skato{ 98556337Skato int attr, mask = tcp->attr_mask; 98656337Skato 98756337Skato if (mask & REVERSE_ATTR) { 98856337Skato attr = ((mask & FG_CHANGED) ? 98956337Skato tcp->cur_color.bg : tcp->rev_color.fg) | 99056337Skato (((mask & BG_CHANGED) ? 99156337Skato tcp->cur_color.fg : tcp->rev_color.bg) << 4); 99256337Skato } else 99356337Skato attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); 99456337Skato 99556337Skato /* XXX: underline mapping for Hercules adapter can be better */ 99656337Skato if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) 99756337Skato attr ^= 0x08; 99856337Skato if (mask & BLINK_ATTR) 99956337Skato attr ^= 0x80; 100056337Skato 100156337Skato return (attr << 8); 100256337Skato} 100356337Skato 100456337Skato#ifdef KANJI 100556337Skatostatic u_char 100656337Skatoiskanji1(u_char mode, u_char c) 100756337Skato{ 100856337Skato if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { 100956337Skato /* JIS */ 101056337Skato default_kanji = UJIS; 101156337Skato return KTYPE_7JIS; 101256337Skato } 101356337Skato 101456337Skato if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { 101556337Skato /* JIS HANKAKU */ 101656337Skato default_kanji = UJIS; 101756337Skato return KTYPE_JKANA; 101856337Skato } 101956337Skato 102056337Skato#if 1 102156337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 102256337Skato /* UJIS */ 102356337Skato return KTYPE_UJIS; 102456337Skato } 102556337Skato#endif 102656337Skato 102756337Skato if ((c >= 0x81) && (c <= 0x9f) && (c != 0x8e)) { 102856337Skato /* SJIS */ 102956337Skato default_kanji = SJIS; 103056337Skato return KTYPE_SJIS; 103156337Skato } 103256337Skato 103356337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == SJIS)) { 103456337Skato /* SJIS HANKAKU */ 103556337Skato return KTYPE_KANA; 103656337Skato } 103756337Skato 103856337Skato#if 0 103956337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 104056337Skato /* UJIS */ 104156337Skato return KTYPE_UJIS; 104256337Skato } 104356337Skato#endif 104456337Skato 104556337Skato if ((c >= 0xf0) && (c <= 0xfe)) { 104656337Skato /* UJIS */ 104756337Skato default_kanji = UJIS; 104856337Skato return KTYPE_UJIS; 104956337Skato } 105056337Skato 105156337Skato if ((c >= 0xe0) && (c <= 0xef)) { 105256337Skato /* SJIS or UJIS */ 105356337Skato return KTYPE_SUJIS; 105456337Skato } 105556337Skato 105656337Skato if (c == 0x8e) { 105756337Skato /* SJIS or UJIS HANKAKU */ 105856337Skato return KTYPE_SUKANA; 105956337Skato } 106056337Skato 106156337Skato return KTYPE_ASCII; 106256337Skato} 106356337Skato 106456337Skatostatic u_char 106556337Skatoiskanji2(u_char mode, u_char c) 106656337Skato{ 106756337Skato switch (mode) { 106856337Skato case KTYPE_7JIS: 106956337Skato if ((c >= 0x21) && (c <= 0x7e)) { 107056337Skato /* JIS */ 107156337Skato return KTYPE_7JIS; 107256337Skato } 107356337Skato break; 107456337Skato case KTYPE_SJIS: 107556337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 107656337Skato /* SJIS */ 107756337Skato return KTYPE_SJIS; 107856337Skato } 107956337Skato break; 108056337Skato case KTYPE_UJIS: 108156337Skato if ((c >= 0xa1) && (c <= 0xfe)) { 108256337Skato /* UJIS */ 108356337Skato return KTYPE_UJIS; 108456337Skato } 108556337Skato break; 108656337Skato case KTYPE_SUKANA: 108756337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 108856337Skato /* UJIS HANKAKU */ 108956337Skato return KTYPE_KANA; 109056337Skato } 109156337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 109256337Skato /* SJIS */ 109356337Skato default_kanji = SJIS; 109456337Skato return KTYPE_SJIS; 109556337Skato } 109656337Skato break; 109756337Skato case KTYPE_SUJIS: 109856337Skato if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { 109956337Skato /* SJIS */ 110056337Skato default_kanji = SJIS; 110156337Skato return KTYPE_SJIS; 110256337Skato } 110356337Skato if ((c == 0xfd) || (c == 0xfe)) { 110456337Skato /* UJIS */ 110556337Skato default_kanji = UJIS; 110656337Skato return KTYPE_UJIS; 110756337Skato } 110856337Skato if ((c >= 0xa1) && (c <= 0xfc)) { 110956337Skato if (default_kanji == SJIS) 111056337Skato return KTYPE_SJIS; 111156337Skato if (default_kanji == UJIS) 111256337Skato return KTYPE_UJIS; 111356337Skato } 111456337Skato break; 111556337Skato } 111656337Skato return KTYPE_ASCII; 111756337Skato} 111856337Skato 111956337Skato/* 112056337Skato * JIS X0208-83 keisen conversion table 112156337Skato */ 112256337Skatostatic u_short keiConv[32] = { 112356337Skato 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, 112456337Skato 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, 112556337Skato 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, 112656337Skato 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c 112756337Skato}; 112856337Skato 112956337Skatostatic u_short 113056337Skatokanji_convert(u_char mode, u_char h, u_char l) 113156337Skato{ 113256337Skato u_short tmp, high, low, c; 113356337Skato high = (u_short) h; 113456337Skato low = (u_short) l; 113556337Skato 113656337Skato switch (mode) { 113756337Skato case KTYPE_SJIS: /* SHIFT JIS */ 113856337Skato if (low >= 0xe0) { 113956337Skato low -= 0x40; 114056337Skato } 114156337Skato low = (low - 0x81) * 2 + 0x21; 114256337Skato if (high > 0x7f) { 114356337Skato high--; 114456337Skato } 114556337Skato if (high > 0x9d) { 114656337Skato low++; 114756337Skato high -= 0x9e - 0x21; 114856337Skato } else { 114956337Skato high -= 0x40 - 0x21; 115056337Skato } 115156337Skato high &= 0x7F; 115256337Skato low &= 0x7F; 115356337Skato tmp = ((high << 8) | low) - 0x20; 115456337Skato break; 115556337Skato case KTYPE_7JIS: /* JIS */ 115656337Skato case KTYPE_UJIS: /* UJIS */ 115756337Skato high &= 0x7F; 115856337Skato low &= 0x7F; 115956337Skato tmp = ((high << 8) | low) - 0x20; 116056337Skato break; 116156337Skato default: 116256337Skato tmp = 0; 116356337Skato break; 116456337Skato } 116556337Skato 116656337Skato /* keisen */ 116756337Skato c = ((tmp & 0xff) << 8) | (tmp >> 8); 116856337Skato /* 0x2821 .. 0x2840 */ 116956337Skato if (0x0821 <= c && c <= 0x0840) 117056337Skato tmp = keiConv[c - 0x0821]; 117156337Skato 117256337Skato return (tmp); 117356337Skato} 117456337Skato#endif /* KANJI */ 117556337Skato 117656337Skato#endif /* SC_DUMB_TERMINAL */ 1177