scterm-sck.c revision 59778
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 59778 2000-04-30 08:40:43Z 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 29358381Snyan case 'c': /* Clear screen & home */ 29458381Snyan sc_clear_screen(scp); 29558381Snyan break; 29656337Skato 29758381Snyan case '(': /* iso-2022: designate 94 character set to G0 */ 29856337Skato#ifdef KANJI 29958381Snyan tcp->kanji_type = KTYPE_ASCIN; 30056337Skato#else 30158381Snyan tcp->esc = 5; 30256337Skato#endif 30358381Snyan return; 30456337Skato } 30558381Snyan } else if (tcp->esc == 2) { /* seen ESC [ */ 30658381Snyan if (c >= '0' && c <= '9') { 30758381Snyan if (tcp->num_param < MAX_ESC_PAR) { 30858381Snyan if (tcp->last_param != tcp->num_param) { 30958381Snyan tcp->last_param = tcp->num_param; 31058381Snyan tcp->param[tcp->num_param] = 0; 31158381Snyan } else { 31258381Snyan tcp->param[tcp->num_param] *= 10; 31358381Snyan } 31458381Snyan tcp->param[tcp->num_param] += c - '0'; 31558381Snyan return; 31658381Snyan } 31758381Snyan } 31858381Snyan tcp->num_param = tcp->last_param + 1; 31958381Snyan switch (c) { 32056337Skato 32158381Snyan case ';': 32258381Snyan if (tcp->num_param < MAX_ESC_PAR) 32358381Snyan return; 32458381Snyan break; 32556337Skato 32658381Snyan case '=': 32758381Snyan tcp->esc = 3; 32858381Snyan tcp->last_param = -1; 32958381Snyan for (i = tcp->num_param; i < MAX_ESC_PAR; i++) 33058381Snyan tcp->param[i] = 1; 33158381Snyan tcp->num_param = 0; 33258381Snyan return; 33356337Skato 33458381Snyan case 'A': /* up n rows */ 33558381Snyan sc_term_up(scp, tcp->param[0], 0); 33658381Snyan break; 33756337Skato 33858381Snyan case 'B': /* down n rows */ 33958381Snyan sc_term_down(scp, tcp->param[0], 0); 34058381Snyan break; 34156337Skato 34258381Snyan case 'C': /* right n columns */ 34358381Snyan sc_term_right(scp, tcp->param[0]); 34458381Snyan break; 34556337Skato 34658381Snyan case 'D': /* left n columns */ 34758381Snyan sc_term_left(scp, tcp->param[0]); 34858381Snyan break; 34956337Skato 35058381Snyan case 'E': /* cursor to start of line n lines down */ 35158381Snyan n = tcp->param[0]; 35258381Snyan if (n < 1) 35358381Snyan n = 1; 35458381Snyan sc_move_cursor(scp, 0, scp->ypos + n); 35558381Snyan break; 35656337Skato 35758381Snyan case 'F': /* cursor to start of line n lines up */ 35858381Snyan n = tcp->param[0]; 35958381Snyan if (n < 1) 36058381Snyan n = 1; 36158381Snyan sc_move_cursor(scp, 0, scp->ypos - n); 36258381Snyan break; 36356337Skato 36458381Snyan case 'f': /* Cursor move */ 36558381Snyan case 'H': 36658381Snyan if (tcp->num_param == 0) 36758381Snyan sc_move_cursor(scp, 0, 0); 36858381Snyan else if (tcp->num_param == 2) 36958381Snyan sc_move_cursor(scp, tcp->param[1] - 1, 37058381Snyan tcp->param[0] - 1); 37158381Snyan break; 37256337Skato 37358381Snyan case 'J': /* Clear all or part of display */ 37458381Snyan if (tcp->num_param == 0) 37558381Snyan n = 0; 37658381Snyan else 37758381Snyan n = tcp->param[0]; 37858381Snyan sc_term_clr_eos(scp, n, sc->scr_map[0x20], 37958381Snyan tcp->cur_attr); 38058381Snyan break; 38156337Skato 38258381Snyan case 'K': /* Clear all or part of line */ 38358381Snyan if (tcp->num_param == 0) 38458381Snyan n = 0; 38558381Snyan else 38658381Snyan n = tcp->param[0]; 38758381Snyan sc_term_clr_eol(scp, n, sc->scr_map[0x20], 38858381Snyan tcp->cur_attr); 38958381Snyan break; 39056337Skato 39158381Snyan case 'L': /* Insert n lines */ 39258381Snyan sc_term_ins_line(scp, scp->ypos, tcp->param[0], 39358381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 39458381Snyan break; 39556337Skato 39658381Snyan case 'M': /* Delete n lines */ 39758381Snyan sc_term_del_line(scp, scp->ypos, tcp->param[0], 39858381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 39958381Snyan break; 40056337Skato 40158381Snyan case 'P': /* Delete n chars */ 40258381Snyan sc_term_del_char(scp, tcp->param[0], 40358381Snyan sc->scr_map[0x20], tcp->cur_attr); 40458381Snyan break; 40556337Skato 40658381Snyan case '@': /* Insert n chars */ 40758381Snyan sc_term_ins_char(scp, tcp->param[0], 40858381Snyan sc->scr_map[0x20], tcp->cur_attr); 40958381Snyan break; 41056337Skato 41158381Snyan case 'S': /* scroll up n lines */ 41258381Snyan sc_term_del_line(scp, 0, tcp->param[0], 41358381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 41458381Snyan break; 41556337Skato 41658381Snyan case 'T': /* scroll down n lines */ 41758381Snyan sc_term_ins_line(scp, 0, tcp->param[0], 41858381Snyan sc->scr_map[0x20], tcp->cur_attr, 0); 41958381Snyan break; 42056337Skato 42158381Snyan case 'X': /* erase n characters in line */ 42258381Snyan n = tcp->param[0]; 42358381Snyan if (n < 1) 42458381Snyan n = 1; 42558381Snyan if (n > scp->xsize - scp->xpos) 42658381Snyan n = scp->xsize - scp->xpos; 42758381Snyan sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, 42858381Snyan sc->scr_map[0x20], tcp->cur_attr); 42958381Snyan mark_for_update(scp, scp->cursor_pos); 43058381Snyan mark_for_update(scp, scp->cursor_pos + n - 1); 43158381Snyan break; 43256337Skato 43358381Snyan case 'Z': /* move n tabs backwards */ 43458381Snyan sc_term_backtab(scp, tcp->param[0]); 43558381Snyan break; 43656337Skato 43758381Snyan case '`': /* move cursor to column n */ 43858381Snyan sc_term_col(scp, tcp->param[0]); 43958381Snyan break; 44056337Skato 44158381Snyan case 'a': /* move cursor n columns to the right */ 44258381Snyan sc_term_right(scp, tcp->param[0]); 44358381Snyan break; 44456337Skato 44558381Snyan case 'd': /* move cursor to row n */ 44658381Snyan sc_term_row(scp, tcp->param[0]); 44758381Snyan break; 44856337Skato 44958381Snyan case 'e': /* move cursor n rows down */ 45058381Snyan sc_term_down(scp, tcp->param[0], 0); 45158381Snyan break; 45256337Skato 45358381Snyan case 'm': /* change attribute */ 45458381Snyan if (tcp->num_param == 0) { 45558381Snyan tcp->attr_mask = NORMAL_ATTR; 45658381Snyan tcp->cur_color = tcp->std_color; 45758381Snyan tcp->cur_attr = mask2attr(tcp); 45858381Snyan break; 45958381Snyan } 46058381Snyan for (i = 0; i < tcp->num_param; i++) { 46158381Snyan switch (n = tcp->param[i]) { 46258381Snyan case 0: /* back to normal */ 46358381Snyan tcp->attr_mask = NORMAL_ATTR; 46458381Snyan tcp->cur_color = tcp->std_color; 46558381Snyan tcp->cur_attr = mask2attr(tcp); 46658381Snyan break; 46758381Snyan case 1: /* bold */ 46858381Snyan tcp->attr_mask |= BOLD_ATTR; 46958381Snyan tcp->cur_attr = mask2attr(tcp); 47058381Snyan break; 47158381Snyan case 4: /* underline */ 47258381Snyan tcp->attr_mask |= UNDERLINE_ATTR; 47358381Snyan tcp->cur_attr = mask2attr(tcp); 47458381Snyan break; 47558381Snyan case 5: /* blink */ 47658381Snyan tcp->attr_mask |= BLINK_ATTR; 47758381Snyan tcp->cur_attr = mask2attr(tcp); 47858381Snyan break; 47958381Snyan case 7: /* reverse video */ 48058381Snyan tcp->attr_mask |= REVERSE_ATTR; 48158381Snyan tcp->cur_attr = mask2attr(tcp); 48258381Snyan break; 48358381Snyan case 30: case 31: /* set fg color */ 48458381Snyan case 32: case 33: case 34: 48558381Snyan case 35: case 36: case 37: 48658381Snyan tcp->attr_mask |= FG_CHANGED; 48758381Snyan tcp->cur_color.fg = ansi_col[n - 30]; 48858381Snyan tcp->cur_attr = mask2attr(tcp); 48958381Snyan break; 49058381Snyan case 40: case 41: /* set bg color */ 49158381Snyan case 42: case 43: case 44: 49258381Snyan case 45: case 46: case 47: 49358381Snyan tcp->attr_mask |= BG_CHANGED; 49458381Snyan tcp->cur_color.bg = ansi_col[n - 40]; 49558381Snyan tcp->cur_attr = mask2attr(tcp); 49658381Snyan break; 49758381Snyan } 49858381Snyan } 49958381Snyan break; 50056337Skato 50158381Snyan case 's': /* Save cursor position */ 50258381Snyan tcp->saved_xpos = scp->xpos; 50358381Snyan tcp->saved_ypos = scp->ypos; 50458381Snyan break; 50556337Skato 50658381Snyan case 'u': /* Restore saved cursor position */ 50758381Snyan if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) 50858381Snyan sc_move_cursor(scp, tcp->saved_xpos, 50958381Snyan tcp->saved_ypos); 51058381Snyan break; 51156337Skato 51258381Snyan case 'x': 51358381Snyan if (tcp->num_param == 0) 51458381Snyan n = 0; 51558381Snyan else 51658381Snyan n = tcp->param[0]; 51758381Snyan switch (n) { 51858381Snyan case 0: /* reset attributes */ 51958381Snyan tcp->attr_mask = NORMAL_ATTR; 52058381Snyan tcp->cur_color = tcp->std_color = 52158381Snyan tcp->dflt_std_color; 52258381Snyan tcp->rev_color = tcp->dflt_rev_color; 52358381Snyan tcp->cur_attr = mask2attr(tcp); 52458381Snyan break; 52558381Snyan case 1: /* set ansi background */ 52658381Snyan tcp->attr_mask &= ~BG_CHANGED; 52758381Snyan tcp->cur_color.bg = tcp->std_color.bg = 52858381Snyan ansi_col[tcp->param[1] & 0x0f]; 52958381Snyan tcp->cur_attr = mask2attr(tcp); 53058381Snyan break; 53158381Snyan case 2: /* set ansi foreground */ 53258381Snyan tcp->attr_mask &= ~FG_CHANGED; 53358381Snyan tcp->cur_color.fg = tcp->std_color.fg = 53458381Snyan ansi_col[tcp->param[1] & 0x0f]; 53558381Snyan tcp->cur_attr = mask2attr(tcp); 53658381Snyan break; 53758381Snyan case 3: /* set ansi attribute directly */ 53858381Snyan tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); 53958381Snyan tcp->cur_color.fg = tcp->std_color.fg = 54058381Snyan tcp->param[1] & 0x0f; 54158381Snyan tcp->cur_color.bg = tcp->std_color.bg = 54258381Snyan (tcp->param[1] >> 4) & 0x0f; 54358381Snyan tcp->cur_attr = mask2attr(tcp); 54458381Snyan break; 54558381Snyan case 5: /* set ansi reverse video background */ 54658381Snyan tcp->rev_color.bg = 54758381Snyan ansi_col[tcp->param[1] & 0x0f]; 54858381Snyan tcp->cur_attr = mask2attr(tcp); 54958381Snyan break; 55058381Snyan case 6: /* set ansi reverse video foreground */ 55158381Snyan tcp->rev_color.fg = 55258381Snyan ansi_col[tcp->param[1] & 0x0f]; 55358381Snyan tcp->cur_attr = mask2attr(tcp); 55458381Snyan break; 55558381Snyan case 7: /* set ansi reverse video directly */ 55658381Snyan tcp->rev_color.fg = tcp->param[1] & 0x0f; 55758381Snyan tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; 55858381Snyan tcp->cur_attr = mask2attr(tcp); 55958381Snyan break; 56058381Snyan } 56158381Snyan break; 56256337Skato 56358381Snyan case 'z': /* switch to (virtual) console n */ 56458381Snyan if (tcp->num_param == 1) 56558381Snyan sc_switch_scr(sc, tcp->param[0]); 56658381Snyan break; 56756337Skato } 56858381Snyan } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ 56958381Snyan if (c >= '0' && c <= '9') { 57058381Snyan if (tcp->num_param < MAX_ESC_PAR) { 57158381Snyan if (tcp->last_param != tcp->num_param) { 57258381Snyan tcp->last_param = tcp->num_param; 57358381Snyan tcp->param[tcp->num_param] = 0; 57458381Snyan } else { 57558381Snyan tcp->param[tcp->num_param] *= 10; 57658381Snyan } 57758381Snyan tcp->param[tcp->num_param] += c - '0'; 57858381Snyan return; 57958381Snyan } 58058381Snyan } 58158381Snyan tcp->num_param = tcp->last_param + 1; 58258381Snyan switch (c) { 58356337Skato 58458381Snyan case ';': 58558381Snyan if (tcp->num_param < MAX_ESC_PAR) 58658381Snyan return; 58758381Snyan break; 58856337Skato 58958381Snyan case 'A': /* set display border color */ 59058381Snyan if (tcp->num_param == 1) { 59158381Snyan scp->border=tcp->param[0] & 0xff; 59258381Snyan if (scp == sc->cur_scp) 59358381Snyan sc_set_border(scp, scp->border); 59458381Snyan } 59558381Snyan break; 59656337Skato 59758381Snyan case 'B': /* set bell pitch and duration */ 59858381Snyan if (tcp->num_param == 2) { 59958381Snyan scp->bell_pitch = tcp->param[0]; 60058381Snyan scp->bell_duration = tcp->param[1]; 60158381Snyan } 60258381Snyan break; 60356337Skato 60458381Snyan case 'C': /* set cursor type & shape */ 60558381Snyan i = spltty(); 60658381Snyan if (!ISGRAPHSC(sc->cur_scp)) 60758381Snyan sc_remove_cursor_image(sc->cur_scp); 60858381Snyan if (tcp->num_param == 1) { 60958381Snyan if (tcp->param[0] & 0x01) 61058381Snyan sc->flags |= SC_BLINK_CURSOR; 61158381Snyan else 61258381Snyan sc->flags &= ~SC_BLINK_CURSOR; 61358381Snyan if (tcp->param[0] & 0x02) 61458381Snyan sc->flags |= SC_CHAR_CURSOR; 61558381Snyan else 61658381Snyan sc->flags &= ~SC_CHAR_CURSOR; 61758381Snyan } else if (tcp->num_param == 2) { 61858381Snyan sc->cursor_base = scp->font_size 61958381Snyan - (tcp->param[1] & 0x1F) - 1; 62058381Snyan sc->cursor_height = (tcp->param[1] & 0x1F) 62158381Snyan - (tcp->param[0] & 0x1F) + 1; 62258381Snyan } 62358381Snyan /* 62458381Snyan * The cursor shape is global property; 62558381Snyan * all virtual consoles are affected. 62658381Snyan * Update the cursor in the current console... 62758381Snyan */ 62858381Snyan if (!ISGRAPHSC(sc->cur_scp)) { 62958381Snyan sc_set_cursor_image(sc->cur_scp); 63058381Snyan sc_draw_cursor_image(sc->cur_scp); 63158381Snyan } 63258381Snyan splx(i); 63358381Snyan break; 63456337Skato 63558381Snyan case 'F': /* set ansi foreground */ 63658381Snyan if (tcp->num_param == 1) { 63758381Snyan tcp->attr_mask &= ~FG_CHANGED; 63858381Snyan tcp->cur_color.fg = tcp->std_color.fg = 63958381Snyan tcp->param[0] & 0x0f; 64058381Snyan tcp->cur_attr = mask2attr(tcp); 64158381Snyan } 64258381Snyan break; 64356337Skato 64458381Snyan case 'G': /* set ansi background */ 64558381Snyan if (tcp->num_param == 1) { 64658381Snyan tcp->attr_mask &= ~BG_CHANGED; 64758381Snyan tcp->cur_color.bg = tcp->std_color.bg = 64858381Snyan tcp->param[0] & 0x0f; 64958381Snyan tcp->cur_attr = mask2attr(tcp); 65058381Snyan } 65158381Snyan break; 65256337Skato 65358381Snyan case 'H': /* set ansi reverse video foreground */ 65458381Snyan if (tcp->num_param == 1) { 65558381Snyan tcp->rev_color.fg = tcp->param[0] & 0x0f; 65658381Snyan tcp->cur_attr = mask2attr(tcp); 65758381Snyan } 65858381Snyan break; 65956337Skato 66058381Snyan case 'I': /* set ansi reverse video background */ 66158381Snyan if (tcp->num_param == 1) { 66258381Snyan tcp->rev_color.bg = tcp->param[0] & 0x0f; 66358381Snyan tcp->cur_attr = mask2attr(tcp); 66458381Snyan } 66558381Snyan break; 66658381Snyan } 66756337Skato#if notyet 66858381Snyan } else if (tcp->esc == 4) { /* seen ESC Q */ 66958381Snyan /* to be filled */ 67056337Skato#endif 67158381Snyan } else if (tcp->esc == 5) { /* seen ESC ( */ 67258381Snyan switch (c) { 67358381Snyan case 'B': /* iso-2022: desginate ASCII into G0 */ 67458381Snyan break; 67558381Snyan /* other items to be filled */ 67658381Snyan default: 67758381Snyan break; 67858381Snyan } 67956337Skato } 68058381Snyan tcp->esc = 0; 68156337Skato} 68256337Skato 68356337Skatostatic void 68456337Skatoscterm_puts(scr_stat *scp, u_char *buf, int len) 68556337Skato{ 68656337Skato term_stat *tcp = scp->ts; 68756337Skato u_char *ptr = buf; 68856337Skato#ifdef KANJI 68956337Skato u_short kanji_code; 69056337Skato#endif 69156337Skato 69256337Skatooutloop: 69358381Snyan scp->sc->write_in_progress++; 69456337Skato 69558381Snyan if (tcp->esc) { 69658381Snyan scterm_scan_esc(scp, tcp, *ptr++); 69758381Snyan len--; 69858381Snyan } else if (PRINTABLE(*ptr)) { /* Print only printables */ 69958381Snyan vm_offset_t p; 70058381Snyan u_char *map; 70158381Snyan int attr; 70258381Snyan int i; 70356337Skato#ifdef KANJI 70458381Snyan u_char c; 70556337Skato#else 70658381Snyan int cnt; 70756337Skato#endif 70856337Skato 70958381Snyan p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); 71058381Snyan map = scp->sc->scr_map; 71158381Snyan attr = tcp->cur_attr; 71256337Skato 71356337Skato#ifdef KANJI 71458381Snyan c = *ptr; 71558381Snyan if (tcp->kanji_1st_char == 0) { 71658381Snyan tcp->kanji_type = iskanji1(tcp->kanji_type, c); 71758381Snyan if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { 71858381Snyan /* not Ascii & not HANKAKU */ 71958381Snyan tcp->kanji_1st_char = c; 72058381Snyan goto kanji_end; 72158381Snyan } else { 72258381Snyan tcp->kanji_1st_char = 0; 72356337Skato } 72458381Snyan } else { 72558381Snyan if ((tcp->kanji_type = 72658381Snyan iskanji2(tcp->kanji_type, c)) & 0xee) { 72758381Snyan /* print kanji on TEXT VRAM */ 72858381Snyan kanji_code = kanji_convert(tcp->kanji_type, c, 72958381Snyan tcp->kanji_1st_char); 73058381Snyan mark_for_update(scp, scp->cursor_pos); 73158381Snyan for (i = 0; i < 2; i++) { 73258381Snyan /* *cursor_pos = (kanji_code | (i*0x80)); */ 73358381Snyan p = sc_vtb_putchar(&scp->vtb, p, 73458381Snyan kanji_code | ((i == 0) ? 0x00 : 0x80), attr); 73558381Snyan ++scp->cursor_pos; 73658381Snyan if (++scp->xpos >= scp->xsize) { 73758381Snyan scp->xpos = 0; 73858381Snyan scp->ypos++; 73958381Snyan } 74058381Snyan } 74158381Snyan mark_for_update(scp, scp->cursor_pos - 1); 74258381Snyan KTYPE_MASK_CTRL(tcp->kanji_type); 74358381Snyan tcp->kanji_1st_char = 0; 74458381Snyan goto kanji_end; 74558381Snyan } else { 74658381Snyan tcp->kanji_1st_char = 0; 74758381Snyan } 74858381Snyan } 74958381Snyan if (IS_KTYPE_KANA(tcp->kanji_type)) 75058381Snyan c |= 0x80; 75156337Skato KTYPE_MASK_CTRL(tcp->kanji_type); 75258381Snyan sc_vtb_putchar(&scp->vtb, p, map[c], attr); 75358381Snyan mark_for_update(scp, scp->cursor_pos); 75458381Snyan mark_for_update(scp, scp->cursor_pos); 75558381Snyan ++scp->cursor_pos; 75658381Snyan ++scp->xpos; 75756337Skatokanji_end: 75858381Snyan ++ptr; 75958381Snyan --len; 76056337Skato#else /* !KANJI */ 76158381Snyan cnt = imin(len, scp->xsize - scp->xpos); 76258381Snyan i = cnt; 76358381Snyan do { 76458381Snyan /* 76558381Snyan * gcc-2.6.3 generates poor (un)sign extension code. 76658381Snyan * Casting the pointers in the following to volatile should 76758381Snyan * have no effect, but in fact speeds up this inner loop 76858381Snyan * from 26 to 18 cycles (+ cache misses) on i486's. 76958381Snyan */ 77056337Skato#define UCVP(ucp) ((u_char volatile *)(ucp)) 77158381Snyan p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], 77258381Snyan attr); 77358381Snyan ++ptr; 77458381Snyan --i; 77558381Snyan } while (i > 0 && PRINTABLE(*ptr)); 77656337Skato 77758381Snyan len -= cnt - i; 77858381Snyan mark_for_update(scp, scp->cursor_pos); 77958381Snyan scp->cursor_pos += cnt - i; 78058381Snyan mark_for_update(scp, scp->cursor_pos - 1); 78158381Snyan scp->xpos += cnt - i; 78256337Skato#endif /* !KANJI */ 78356337Skato 78458381Snyan if (scp->xpos >= scp->xsize) { 78558381Snyan scp->xpos = 0; 78658381Snyan scp->ypos++; 78756337Skato } 78858381Snyan } else { 78958381Snyan switch (*ptr) { 79058381Snyan case 0x07: 79158381Snyan sc_bell(scp, scp->bell_pitch, scp->bell_duration); 79258381Snyan break; 79356337Skato 79458381Snyan case 0x08: /* non-destructive backspace */ 79558381Snyan if (scp->cursor_pos > 0) { 79658381Snyan mark_for_update(scp, scp->cursor_pos); 79758381Snyan scp->cursor_pos--; 79858381Snyan mark_for_update(scp, scp->cursor_pos); 79958381Snyan if (scp->xpos > 0) 80058381Snyan scp->xpos--; 80158381Snyan else { 80258381Snyan scp->xpos += scp->xsize - 1; 80358381Snyan scp->ypos--; 80458381Snyan } 80558381Snyan } 80658381Snyan break; 80756337Skato 80858381Snyan case 0x09: /* non-destructive tab */ 80958381Snyan mark_for_update(scp, scp->cursor_pos); 81058381Snyan scp->cursor_pos += (8 - scp->xpos % 8u); 81158381Snyan scp->xpos += (8 - scp->xpos % 8u); 81258381Snyan if (scp->xpos >= scp->xsize) { 81358381Snyan scp->xpos = 0; 81458381Snyan scp->ypos++; 81558381Snyan scp->cursor_pos = scp->xsize * scp->ypos; 81658381Snyan } 81758381Snyan mark_for_update(scp, scp->cursor_pos); 81858381Snyan break; 81956337Skato 82058381Snyan case 0x0a: /* newline, same pos */ 82158381Snyan mark_for_update(scp, scp->cursor_pos); 82258381Snyan scp->cursor_pos += scp->xsize; 82358381Snyan mark_for_update(scp, scp->cursor_pos); 82458381Snyan scp->ypos++; 82558381Snyan break; 82656337Skato 82758381Snyan case 0x0c: /* form feed, clears screen */ 82858381Snyan sc_clear_screen(scp); 82958381Snyan break; 83056337Skato 83158381Snyan case 0x0d: /* return, return to pos 0 */ 83258381Snyan mark_for_update(scp, scp->cursor_pos); 83358381Snyan scp->cursor_pos -= scp->xpos; 83458381Snyan mark_for_update(scp, scp->cursor_pos); 83558381Snyan scp->xpos = 0; 83658381Snyan break; 83758381Snyan 83856337Skato#ifdef PC98 83958381Snyan case 0x0e: /* ^N */ 84058381Snyan tcp->kanji_type = KTYPE_JKANA; 84158381Snyan tcp->esc = 0; 84258381Snyan tcp->kanji_1st_char = 0; 84358381Snyan break; 84456337Skato 84558381Snyan case 0x0f: /* ^O */ 84658381Snyan tcp->kanji_type = KTYPE_ASCII; 84758381Snyan tcp->esc = 0; 84858381Snyan tcp->kanji_1st_char = 0; 84958381Snyan break; 85056337Skato#endif /* PC98 */ 85156337Skato 85258381Snyan case 0x1b: /* start escape sequence */ 85358381Snyan tcp->esc = 1; 85458381Snyan tcp->num_param = 0; 85558381Snyan break; 85658381Snyan } 85758381Snyan ptr++; 85858381Snyan len--; 85956337Skato } 86056337Skato 86158381Snyan sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); 86256337Skato 86358381Snyan scp->sc->write_in_progress--; 86458381Snyan if (len) 86558381Snyan goto outloop; 86656337Skato} 86756337Skato 86856337Skatostatic int 86956337Skatoscterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, 87056337Skato int flag, struct proc *p) 87156337Skato{ 87256337Skato term_stat *tcp = scp->ts; 87356337Skato vid_info_t *vi; 87456337Skato 87556337Skato switch (cmd) { 87656337Skato case GIO_ATTR: /* get current attributes */ 87756337Skato /* FIXME: */ 87856337Skato *(int*)data = (tcp->cur_attr >> 8) & 0xff; 87956337Skato return 0; 88056337Skato case CONS_GETINFO: /* get current (virtual) console info */ 88156337Skato vi = (vid_info_t *)data; 88256337Skato if (vi->size != sizeof(struct vid_info)) 88356337Skato return EINVAL; 88456337Skato vi->mv_norm.fore = tcp->std_color.fg; 88556337Skato vi->mv_norm.back = tcp->std_color.bg; 88656337Skato vi->mv_rev.fore = tcp->rev_color.fg; 88756337Skato vi->mv_rev.back = tcp->rev_color.bg; 88856337Skato /* 88956337Skato * The other fields are filled by the upper routine. XXX 89056337Skato */ 89156337Skato return ENOIOCTL; 89256337Skato } 89356337Skato return ENOIOCTL; 89456337Skato} 89556337Skato 89656337Skatostatic int 89756337Skatoscterm_reset(scr_stat *scp, int code) 89856337Skato{ 89956337Skato /* FIXME */ 90056337Skato return 0; 90156337Skato} 90256337Skato 90356337Skatostatic void 90456337Skatoscterm_default_attr(scr_stat *scp, int color, int rev_color) 90556337Skato{ 90656337Skato term_stat *tcp = scp->ts; 90756337Skato 90856337Skato tcp->dflt_std_color.fg = color & 0x0f; 90956337Skato tcp->dflt_std_color.bg = (color >> 4) & 0x0f; 91056337Skato tcp->dflt_rev_color.fg = rev_color & 0x0f; 91156337Skato tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; 91256337Skato tcp->std_color = tcp->dflt_std_color; 91356337Skato tcp->rev_color = tcp->dflt_rev_color; 91456337Skato tcp->cur_color = tcp->std_color; 91556337Skato tcp->cur_attr = mask2attr(tcp); 91656337Skato} 91756337Skato 91856337Skatostatic void 91956337Skatoscterm_clear(scr_stat *scp) 92056337Skato{ 92156337Skato term_stat *tcp = scp->ts; 92256337Skato 92356337Skato sc_move_cursor(scp, 0, 0); 92456337Skato sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); 92556337Skato mark_all(scp); 92656337Skato} 92756337Skato 92856337Skatostatic void 92956337Skatoscterm_notify(scr_stat *scp, int event) 93056337Skato{ 93156337Skato switch (event) { 93256337Skato case SC_TE_NOTIFY_VTSWITCH_IN: 93356337Skato break; 93456337Skato case SC_TE_NOTIFY_VTSWITCH_OUT: 93556337Skato break; 93656337Skato } 93756337Skato} 93856337Skato 93956337Skatostatic int 94056337Skatoscterm_input(scr_stat *scp, int c, struct tty *tp) 94156337Skato{ 94256337Skato return FALSE; 94356337Skato} 94456337Skato 94556337Skato/* 94656337Skato * Calculate hardware attributes word using logical attributes mask and 94756337Skato * hardware colors 94856337Skato */ 94956337Skato 95056337Skato/* FIXME */ 95156337Skatostatic int 95256337Skatomask2attr(term_stat *tcp) 95356337Skato{ 95456337Skato int attr, mask = tcp->attr_mask; 95556337Skato 95656337Skato if (mask & REVERSE_ATTR) { 95756337Skato attr = ((mask & FG_CHANGED) ? 95856337Skato tcp->cur_color.bg : tcp->rev_color.fg) | 95956337Skato (((mask & BG_CHANGED) ? 96056337Skato tcp->cur_color.fg : tcp->rev_color.bg) << 4); 96156337Skato } else 96256337Skato attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); 96356337Skato 96456337Skato /* XXX: underline mapping for Hercules adapter can be better */ 96556337Skato if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) 96656337Skato attr ^= 0x08; 96756337Skato if (mask & BLINK_ATTR) 96856337Skato attr ^= 0x80; 96956337Skato 97056337Skato return (attr << 8); 97156337Skato} 97256337Skato 97356337Skato#ifdef KANJI 97456337Skatostatic u_char 97556337Skatoiskanji1(u_char mode, u_char c) 97656337Skato{ 97756337Skato if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { 97856337Skato /* JIS */ 97956337Skato default_kanji = UJIS; 98056337Skato return KTYPE_7JIS; 98156337Skato } 98256337Skato 98356337Skato if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { 98456337Skato /* JIS HANKAKU */ 98556337Skato default_kanji = UJIS; 98656337Skato return KTYPE_JKANA; 98756337Skato } 98856337Skato 98956337Skato#if 1 99056337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 99156337Skato /* UJIS */ 99256337Skato return KTYPE_UJIS; 99356337Skato } 99456337Skato#endif 99556337Skato 99656337Skato if ((c >= 0x81) && (c <= 0x9f) && (c != 0x8e)) { 99756337Skato /* SJIS */ 99856337Skato default_kanji = SJIS; 99956337Skato return KTYPE_SJIS; 100056337Skato } 100156337Skato 100256337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == SJIS)) { 100356337Skato /* SJIS HANKAKU */ 100456337Skato return KTYPE_KANA; 100556337Skato } 100656337Skato 100756337Skato#if 0 100856337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 100956337Skato /* UJIS */ 101056337Skato return KTYPE_UJIS; 101156337Skato } 101256337Skato#endif 101356337Skato 101456337Skato if ((c >= 0xf0) && (c <= 0xfe)) { 101556337Skato /* UJIS */ 101656337Skato default_kanji = UJIS; 101756337Skato return KTYPE_UJIS; 101856337Skato } 101956337Skato 102056337Skato if ((c >= 0xe0) && (c <= 0xef)) { 102156337Skato /* SJIS or UJIS */ 102256337Skato return KTYPE_SUJIS; 102356337Skato } 102456337Skato 102556337Skato if (c == 0x8e) { 102656337Skato /* SJIS or UJIS HANKAKU */ 102756337Skato return KTYPE_SUKANA; 102856337Skato } 102956337Skato 103056337Skato return KTYPE_ASCII; 103156337Skato} 103256337Skato 103356337Skatostatic u_char 103456337Skatoiskanji2(u_char mode, u_char c) 103556337Skato{ 103656337Skato switch (mode) { 103756337Skato case KTYPE_7JIS: 103856337Skato if ((c >= 0x21) && (c <= 0x7e)) { 103956337Skato /* JIS */ 104056337Skato return KTYPE_7JIS; 104156337Skato } 104256337Skato break; 104356337Skato case KTYPE_SJIS: 104456337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 104556337Skato /* SJIS */ 104656337Skato return KTYPE_SJIS; 104756337Skato } 104856337Skato break; 104956337Skato case KTYPE_UJIS: 105056337Skato if ((c >= 0xa1) && (c <= 0xfe)) { 105156337Skato /* UJIS */ 105256337Skato return KTYPE_UJIS; 105356337Skato } 105456337Skato break; 105556337Skato case KTYPE_SUKANA: 105656337Skato if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { 105756337Skato /* UJIS HANKAKU */ 105856337Skato return KTYPE_KANA; 105956337Skato } 106056337Skato if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { 106156337Skato /* SJIS */ 106256337Skato default_kanji = SJIS; 106356337Skato return KTYPE_SJIS; 106456337Skato } 106556337Skato break; 106656337Skato case KTYPE_SUJIS: 106756337Skato if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { 106856337Skato /* SJIS */ 106956337Skato default_kanji = SJIS; 107056337Skato return KTYPE_SJIS; 107156337Skato } 107256337Skato if ((c == 0xfd) || (c == 0xfe)) { 107356337Skato /* UJIS */ 107456337Skato default_kanji = UJIS; 107556337Skato return KTYPE_UJIS; 107656337Skato } 107756337Skato if ((c >= 0xa1) && (c <= 0xfc)) { 107856337Skato if (default_kanji == SJIS) 107956337Skato return KTYPE_SJIS; 108056337Skato if (default_kanji == UJIS) 108156337Skato return KTYPE_UJIS; 108256337Skato } 108356337Skato break; 108456337Skato } 108556337Skato return KTYPE_ASCII; 108656337Skato} 108756337Skato 108856337Skato/* 108956337Skato * JIS X0208-83 keisen conversion table 109056337Skato */ 109156337Skatostatic u_short keiConv[32] = { 109256337Skato 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, 109356337Skato 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, 109456337Skato 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, 109556337Skato 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c 109656337Skato}; 109756337Skato 109856337Skatostatic u_short 109956337Skatokanji_convert(u_char mode, u_char h, u_char l) 110056337Skato{ 110156337Skato u_short tmp, high, low, c; 110256337Skato high = (u_short) h; 110356337Skato low = (u_short) l; 110456337Skato 110556337Skato switch (mode) { 110656337Skato case KTYPE_SJIS: /* SHIFT JIS */ 110756337Skato if (low >= 0xe0) { 110856337Skato low -= 0x40; 110956337Skato } 111056337Skato low = (low - 0x81) * 2 + 0x21; 111156337Skato if (high > 0x7f) { 111256337Skato high--; 111356337Skato } 111456337Skato if (high > 0x9d) { 111556337Skato low++; 111656337Skato high -= 0x9e - 0x21; 111756337Skato } else { 111856337Skato high -= 0x40 - 0x21; 111956337Skato } 112056337Skato high &= 0x7F; 112156337Skato low &= 0x7F; 112256337Skato tmp = ((high << 8) | low) - 0x20; 112356337Skato break; 112456337Skato case KTYPE_7JIS: /* JIS */ 112556337Skato case KTYPE_UJIS: /* UJIS */ 112656337Skato high &= 0x7F; 112756337Skato low &= 0x7F; 112856337Skato tmp = ((high << 8) | low) - 0x20; 112956337Skato break; 113056337Skato default: 113156337Skato tmp = 0; 113256337Skato break; 113356337Skato } 113456337Skato 113556337Skato /* keisen */ 113656337Skato c = ((tmp & 0xff) << 8) | (tmp >> 8); 113756337Skato /* 0x2821 .. 0x2840 */ 113856337Skato if (0x0821 <= c && c <= 0x0840) 113956337Skato tmp = keiConv[c - 0x0821]; 114056337Skato 114156337Skato return (tmp); 114256337Skato} 114356337Skato#endif /* KANJI */ 114456337Skato 114556337Skato#endif /* SC_DUMB_TERMINAL */ 1146