📄 vt100esc.c
字号:
/* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: $Hdr: vt100esc.c,v 4.300 91/06/09 06:14:59 root Rel41 $ SONY * * @(#)vt100esc.c 8.1 (Berkeley) 6/10/93 *//* * vt100 escape sequence handler */#ifdef IPC_MRX#include "../../h/param.h"#include "../../h/systm.h"#include "../../iop/framebuf.h"#else#include <sys/param.h>#include <sys/systm.h>#include <news3400/iop/framebuf.h>#endif#include <news3400/bm/vt100.h>#include <news3400/bm/bitmapif.h>#include <news3400/fb/fbdefs.h>#ifdef IPC_MRX#include "../../iop/kbreg.h"#include "../../iop/keyboard.h"#else#include <news3400/iop/kbreg.h>#include <news3400/iop/keyboard.h>#endif#if CPU_SINGLE#include <news3400/sio/scc.h>#endif#ifdef IPC_MRX#include "config.h"#define kbd_ioctl(chan, cmd, argp) { \ if (kb_ioctl) \ (*kb_ioctl)(chan, cmd, argp); \}#endif/* * escape sequece functions */int esc_csi();int esc_csi_ansi();int esc_csi_dec();int esc_store_csr();int esc_restore_csr();int esc_index();int esc_next_line();int esc_tab_set();int esc_rev_index();int esc_numeric_kpad();int esc_application_kpad();int esc_line_size();int esc_char_setr();int esc_char_setl();int esc_kanji_set();int esc_parm_set();int esc_pf_define();int esc_ignore();struct esc_sequence esc_seq_table[] = { {'[', "ABCDfgHhJKLlMmnPr", esc_csi}, {'7', "", esc_store_csr}, {'8', "", esc_restore_csr}, {'D', "", esc_index}, {'E', "", esc_next_line}, {'H', "", esc_tab_set}, {'M', "", esc_rev_index}, {'=', "", esc_application_kpad}, {'>', "", esc_numeric_kpad}, {'#', "34568", esc_line_size}, {'(', "0ABJH", esc_char_setr}, {')', "0AB", esc_char_setl}, {'$', "B@", esc_kanji_set}, {'~', "fcpsomdbDiGCBTtE", esc_parm_set}, {'P', "pPZiI", esc_pf_define}, {'\0', "", esc_ignore},};struct key_pad key_pad[] = { { '0', 'p' }, /* 0 */ { '1', 'q' }, /* 1 */ { '2', 'r' }, /* 2 */ { '3', 's' }, /* 3 */ { '4', 't' }, /* 4 */ { '5', 'u' }, /* 5 */ { '6', 'v' }, /* 6 */ { '7', 'w' }, /* 7 */ { '8', 'x' }, /* 8 */ { '9', 'y' }, /* 9 */ { '.', 'n' }, /* period */ { '-', 'm' }, /* minus */ { '+', 'k' }, /* plus */ { ',', 'l' }, /* comma */ { '\n', 'M' }, /* enter */ { 'A', 'A' }, /* cursor up */ { 'B', 'B' }, /* cursor down */ { 'C', 'C' }, /* cursor right */ { 'D', 'D' }, /* cursor left */ { '\0', '\0' } /* */};static char esc_buf[ESC_BUF_SIZ];static char *esc_bp = esc_buf;extern char c_pos_mess[];static change_csr_key_pad(), change_aux_key_pad(), itoa();Key_string key_str;Pfk_string pfk_str;unsigned int first_jcode;/* * put out jis-code kanji */jiskanji(sp, c) register SCREEN *sp; register unsigned int c;{ if (first_jcode) { addch(sp, c | (first_jcode << 8)); first_jcode = 0; } else { first_jcode = c; }}/* * This routine is the command analiser using second character. * If a command has found then switch to particular escape handling * routine, and directly called by mother routine. * The arguments are passed through the routine. */esc_top_level(sp, c) register SCREEN *sp; char c;{ register struct esc_sequence *estp; for (estp = esc_seq_table; estp->command ; estp++) { if (estp->command == c) { /* command found */ sp->s_estp = estp; if (*estp->terminators == '\0') { (*estp->esc_func)(sp); sp->s_current_stat &= ~ESCAPE; } else { sp->s_esc_handler = estp->esc_func; } return; } } sp->s_current_stat &= ~ESCAPE;}/* * Undo the ESCAPE flag, escape buffer * and the esc_handler routine * This routine has to be called when escape sequence has started. */recover(sp) register SCREEN *sp;{ register int *ip = (int *) esc_buf; register int *sup = (int *) (esc_buf + ESC_BUF_SIZ); sp->s_current_stat &= ~ESCAPE; sp->s_esc_handler = esc_top_level; while (ip < sup) *ip++ = 0; esc_bp = esc_buf;}/* * This routine in_str(c, string) returns * if string contains c then TRUE (1) else FALSE (0) */in_str(c, string) char c; register char *string;{ while(*string) if (c == *string++) return(TRUE); return(FALSE);}/* * Control sequence introducer (CSI) * Which begins `^[[' and terminates one of `ABCDfgHhJKLlMmPr' */esc_csi(sp, c) register SCREEN *sp; unsigned int c;{ static int bufc = 0; if (in_str(c, sp->s_estp->terminators)) { esc_csi_ansi(sp, esc_bp, c); sp->s_current_stat &= ~ESCAPE; bufc = 0; return; } /* buffering arguments */ if (bufc < ESC_BUF_SIZ) { if (c >= '0' && c <= '9') { *esc_bp = *esc_bp *10 + (c - '0'); } else if (c == ';') { esc_bp++; bufc++; } else if (c == '?') { if (esc_bp == esc_buf) { sp->s_esc_handler = esc_csi_dec; } else { esc_buf[0] = INVALID; } } else { sp->s_current_stat &= ~ESCAPE; bufc = 0; } }}#ifdef IPC_MRX#define SCC_KEYBOARD 0#endif/* * Ansi standard csi handler */esc_csi_ansi(sp, esc_bp, terminator) register SCREEN *sp; char *esc_bp; char terminator;{ register char *cp = esc_buf; register struct cursor *spc = &sp->s_csr; register char *p; register int i; if (*cp == INVALID) return; cursor_off(); switch (terminator) { case 'A': /* CUU */ if (spc->csr_y < sp->s_region.top_margin) { spc->csr_y = max(spc->csr_y - max(*cp, 1) ,TOP_M); } else { spc->csr_y = max(spc->csr_y - max(*cp, 1) ,sp->s_region.top_margin); } spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; sp->s_current_stat &= ~WRAP; break; case 'B': /* CUD */ if (spc->csr_y > sp->s_region.btm_margin) { spc->csr_y = min(spc->csr_y + max(*cp, 1) ,btm_m); } else { spc->csr_y = min(spc->csr_y + max(*cp, 1) ,sp->s_region.btm_margin); } spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; sp->s_current_stat &= ~WRAP; break; case 'C': /* CUF */ spc->csr_x = min(spc->csr_x + max(*cp, 1), rit_m); spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst; sp->s_current_stat &= ~WRAP; break; case 'D': /* CUB */ spc->csr_x = max(spc->csr_x - max(*cp, 1), LFT_M); spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst; sp->s_current_stat &= ~WRAP; break; case 'g': /* TBC */ switch (*cp) { case 0: sp->s_tab_pos[spc->csr_x] = 0; break; case 3: for (i = 0; i <= rit_m; i++) sp->s_tab_pos[i] = 0; break; default: break; } break; case 'f': /* HVP */ case 'H': /* CUP same as HVP */ csr_pos(sp, cp[1], cp[0]); sp->s_current_stat &= ~WRAP; break; case 'J': /* ED */ erase_disp(sp, cp[0]); sp->s_current_stat &= ~WRAP; break; case 'K': /* EL */ erase_line(sp, cp[0]); sp->s_current_stat &= ~WRAP; break; case 'L': /* IL */ insert_line(sp, cp[0]); break; case 'M': /* DL */ delete_line(sp, cp[0]); break; case 'P': /* DCH */ delete_char(sp, cp[0]); sp->s_current_stat &= ~WRAP; break; case 'r': /* DECSTBM */ cp[2] = max(cp[0] == 0 ? TOP_M: cp[0], TOP_M); cp[3] = min(cp[1] == 0 ? btm_m: cp[1], btm_m); if (cp[2] >= cp[3]) break; sp->s_region.top_margin = cp[2]; sp->s_region.btm_margin = cp[3]; spc->csr_x = LFT_M; spc->csr_p.x = x_ofst; if (sp->s_term_mode & DECOM) { spc->csr_y = sp->s_region.top_margin; spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst; } else { spc->csr_y = TOP_M; spc->csr_p.y = y_ofst; } break; case 'm': /* CRA */ while (cp <= esc_bp) { switch (*cp++) { case 0: spc->csr_attributes &= NORMALM; if (sp->s_term_mode & DECSCNM) { fcolor = sp->s_bgcol; bcolor = sp->s_plane; } else { fcolor = sp->s_plane; bcolor = sp->s_bgcol; } break; case 1: /* bold */ spc->csr_attributes |= BOLD; break; case 4: /* under score */ spc->csr_attributes |= USCORE; break; case 5: /* blinking */ spc->csr_attributes |= BLINK; break; case 7: /* reverse */ spc->csr_attributes |= REVERSE; if (sp->s_term_mode & DECSCNM) { fcolor = sp->s_plane; bcolor = sp->s_bgcol; } else { fcolor = sp->s_bgcol; bcolor = sp->s_plane; } break; case 22: /* unbold */ spc->csr_attributes &= ~BOLD; break; case 24: /* no under score */ spc->csr_attributes &= ~USCORE; break; case 25: /* no blinking */ spc->csr_attributes &= ~BLINK; break; case 27: /* re-reverse */ spc->csr_attributes &= ~REVERSE; if (sp->s_term_mode & DECSCNM) { fcolor = sp->s_bgcol; bcolor = sp->s_plane; } else { fcolor = sp->s_plane; bcolor = sp->s_bgcol; } break; default: break; } } break; case 'n': while (cp <= esc_bp) { /* DSR(status request) */ switch (*cp++) { case 6: /* inquiry cursor position */ key_str.key_string = c_pos_mess; key_str.key_length = spr(c_pos_mess, "\033[%d;%dR", (sp->s_term_mode & DECOM) ? spc->csr_y - sp->s_region.top_margin + 1: spc->csr_y, spc->csr_x); kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str); break; default: break; } } break; case 'h': /* SM */ while (cp <= esc_bp) { switch (*cp++) { case 2: /* Keyboard Action */ sp->s_term_mode |= KAM; break; case 4: /* Insert Replace */ sp->s_term_mode |= IRM; break; case 12: /* Local echo disable */ sp->s_term_mode |= SRM; break; case 20: /* Linefeed newline */ sp->s_term_mode |= LNM; break; default: break; } } break; case 'l': /* RM */ while (cp <= esc_bp) { switch (*cp++) { case 2: /* Keyboard Action */ sp->s_term_mode &= ~KAM; break; case 4: /* Insert Replace */ sp->s_term_mode &= ~IRM; break; case 12: /* Local echo disable */ sp->s_term_mode &= ~SRM; break; case 20: /* Linefeed newline */ sp->s_term_mode &= ~LNM; break; default: break; } } break; default: break; } cursor_on(&spc->csr_p); sp->s_current_stat &= ~ESCAPE;}/* * Cursor position. * csr_pos(sp, x, y) moves the cursor to (x, y). */csr_pos(sp, x, y) register SCREEN *sp; register int x, y;{ if (sp->s_term_mode & DECOM) { sp->s_csr.csr_y = min(sp->s_region.top_margin + max(y, 1) - 1, sp->s_region.btm_margin); } else { sp->s_csr.csr_y = min(TOP_M + max(y, 1) - 1, btm_m); } sp->s_csr.csr_x = max(min(x, rit_m), LFT_M); sp->s_csr.csr_p.x = (sp->s_csr.csr_x -1) * char_w + x_ofst; sp->s_csr.csr_p.y = (sp->s_csr.csr_y -1) * char_h + y_ofst;}/* * Erase in display. * erase_disp(sp, pn) erases display from the cursor to the end, from * the beginning to the cursor or completely according to pn = 0, 1 or 2 * respectively. */erase_disp(sp, pn) register SCREEN *sp; register int pn;{ register struct cursor *spc = &sp->s_csr; switch (pn) { case 0: /* cursor to end */ erase_line(sp, 0); clear_lines(min(spc->csr_y + 1, btm_m), btm_m - spc->csr_y, sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol); break; case 1: /* beginning to cursor */ erase_line(sp, 1); clear_lines(TOP_M, spc->csr_y - TOP_M, sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol); break; case 2: /* whole */ clear_lines(TOP_M, btm_m - TOP_M + 1, sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -