⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vt.c

📁 这是一个介绍 linux 编程知识的文章。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * KON2 - Kanji ON Console -
 * Copyright (C) 1992-1996 Takashi MANABE (manabe@papilio.tutics.tut.ac.jp)
 *
 * CCE - Console Chinese Environment -
 * Copyright (C) 1998-1999 Rui He (herui@cs.duke.edu)
 *
 * VCOnGUI - Virtual Console On MiniGUI -
 * Copyright (C) 1999 Wei Yongming (ymwei@263.net)
 */

/*
**  This source is free software; you can redistribute it and/or
**  modify it under the terms of the GNU General Public
**  License as published by the Free Software Foundation; either
**  version 2 of the License, or (at your option) any later version.
**
**  This software is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  General Public License for more details.
**
**  You should have received a copy of the GNU General Public
**  License along with this library; if not, write to the Free
**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
**  MA 02111-1307, USA
*/

// Create date: 1999.09.23
//
// Modify records:
//
//  Who             When        Where       For What                Status
//-----------------------------------------------------------------------------
//
// TODO:
//

/* Console driver handling, may have a look at CCE 0.11's console.c
   and Linux kernel source code: /usr/src/linux/drivers/char/console.c

   The below code doesn't handle all of the ANSI required ESC stuff
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/vt.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h>
#include <termio.h>
#include <pthread.h>
#include <semaphore.h>

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>

#include "vcongui.h"
#include "defs.h"
#include "vc.h"
#include "child.h"
#include "terminal.h"
#include "vt.h"

#define CHAR_NUL    '\x00'
#define CHAR_BEL    '\x07'
#define CHAR_BS     '\x08'
#define CHAR_HT     '\x09'
#define CHAR_LF     '\x0A'
#define CHAR_VT     '\x0B'
#define CHAR_FF     '\x0C'
#define CHAR_CR     '\x0D'
#define CHAR_SO     '\x0E'
#define CHAR_SI     '\x0F'
#define CHAR_XON    '\x11'
#define CHAR_XOFF   '\x12'
#define CHAR_CAN    '\x18'
#define CHAR_SUB    '\x1A'
#define CHAR_ESC    '\x1B'
#define CHAR_DEL    '\x7F'
#define CHAR_CSI    '\x9B'
#define CHAR_SS2    '\x8E'

#define LEN_REPORT    9

/*  Call the routines in vc.c
    TextInsertChar/TextDeleteChar
    ScrollUp/ScrollDown
    TextSput/TextWput
    TextMoveUp/TextMoveDown
    TextClearAll/TextClearEol/TextClearEos
*/

/****************************************************************************
 *                         SaveAttr/RestoreAttr                             *
 ****************************************************************************/
static void SaveAttr(CONINFO *con)
{
    struct attrStack *tmp;

    tmp = (struct attrStack *)malloc(sizeof(struct attrStack));
    if (con->saveAttr)
        tmp->prev = con->saveAttr;
    else
        tmp->prev = NULL;
        
    con->saveAttr = tmp;
    con->saveAttr->x = con->x;
    con->saveAttr->y = con->y;
    con->saveAttr->attr = con->attr;
    con->saveAttr->fcol = con->fcol;
    con->saveAttr->bcol = con->bcol;
}

static void RestoreAttr(CONINFO *con)
{
    struct attrStack *tmp;

    if (con->saveAttr) {
        con->x = con->saveAttr->x;
        con->y = con->saveAttr->y;
        con->attr = con->saveAttr->attr;
        con->fcol = con->saveAttr->fcol;
        con->bcol = con->saveAttr->bcol;
        tmp = con->saveAttr;
        con->saveAttr = tmp->prev;
        free(tmp);
    }
}

/**************************************************************************
 *                               EscSetAttr                               *
 **************************************************************************/
static void EscSetAttr (CONINFO *con, int col)
{
    static const u_char table[] = {0, 4, 2, 6, 1, 5, 3, 7};
    u_char    swp;
    
    switch(col) {
    case 0:    /* off all attributes */
        con->bcol = 0;
        con->fcol = 7;
        con->attr = 0;
        break;
        
    case 1:  // highlight, fcolor
        con->attr |= ATTR_HIGH;
        con->fcol |= 8;
        break;
        
    case 21:  // clear highlight
        con->attr &= ~ATTR_HIGH;
        con->fcol &= ~8;
        break;
        
    case 4:    // underline, bcolor
        con->attr |= ATTR_ULINE;
        con->bcol |= 8;
        break;

    case 24:   // clear underline
        con->attr &= ~ATTR_ULINE;
        con->bcol &= ~8;
        break;
        
    case 7:  // reverse
        if (!(con->attr & ATTR_REVERSE)) {
            con->attr |= ATTR_REVERSE;
            swp = con->fcol & 7;
            
            if (con->attr & ATTR_ULINE)
                swp |= 8;
                
            con->fcol = con->bcol & 7;
            if ((con->attr & ATTR_HIGH) && con->fcol)
                con->fcol |= 8;
            con->bcol = swp;
        }
        break;
        
    case 27:  // clear reverse
        if (con->attr & ATTR_REVERSE) {
            con->attr &= ~ATTR_REVERSE;
            swp = con->fcol & 7;
            if (con->attr & ATTR_ULINE)
                swp |= 8;
            con->fcol = con->bcol & 7;
            if ((con->attr & ATTR_HIGH) && con->fcol)
                con->fcol |= 8;
            con->bcol = swp;
        }
        break;
        
    default:
        if (col >= 30 && col <= 37)  // assign foreground color
        {
            swp = table[col - 30];
            if (con->attr & ATTR_REVERSE) {
                if (con->attr & ATTR_ULINE)
                    swp |= 8;
                con->bcol = swp;
            } 
            else {
                if (con->attr & ATTR_HIGH)
                    swp |= 8;
                con->fcol = swp;
            }
        } 
        else if (col >= 40 && col <= 47)  // assign background color
        {
            swp = table[col - 40];
            if (con->attr & ATTR_REVERSE) {
                if (con->attr & ATTR_HIGH)
                    swp |= 8;
                con->fcol = swp;
            }
            else {
                if (con->attr & ATTR_ULINE)
                    swp |= 8;
                con->bcol = swp;
            }
        }
        break;

    }
}

static void VtSetMode (CONINFO *con, u_char mode, bool sw)
{
    switch(mode) {
    case 4:
        con->ins = sw;
        break;

    case 25:
        con->cursorsw = sw;
        break;
    }
}

static void EscReport (CONINFO *con, u_char mode, u_short arg)
{
    char report[LEN_REPORT];
    
    switch(mode) {
    case 'n':
        if (arg == 6) {
            int x = (con->x < con->xmax) ? con->x : con->xmax;
            int y = (con->y < con->ymax) ? con->y : con->ymax;
            
            sprintf(report, "\x1B[%d;%dR", y + 1, x + 1);
        }
        else if (arg == 5)
            strcpy(report, "\x1B[0n\0");
        break;
    case 'c':
        if (arg == 0)
            strcpy(report, "\x1B[?6c\0");
        break;
    }

    write (con->masterPty, report, strlen (report));
}

/* ESC [ ..... */
static void EscBracket (CONINFO *con, u_char ch)
{
    u_char    n;

    if (ch >= '0' && ch <= '9') {
        con->varg[con->narg] = (con->varg[con->narg] * 10) + (ch - '0');
    }
    else if (ch == ';') {
        if (con->narg < MAX_NARG)
            con->narg ++;
        else
            con->esc = NULL;
    }
    else {
        con->esc = NULL;
        switch (ch) 
        {
        case 'K':
            TextClearEol (con, con->varg[0]);
            break;
            
        case 'J':
            TextClearEos (con, con->varg[0]);
            break;

        // ESC[%dX - I can't find it in /etc/termcap, but dialog-based
        // program used it. - holly
        case 'X':
            TextClearChars (con, con->varg[0]);
            break;
            
        case 'A':
            con->y -= con->varg[0] ? con->varg[0]: 1;
            if (con->y < con->ymin) {
                con->scroll -= con->y - con->ymin;
                con->y = con->ymin;
            }
            break;
            
        case 'B':
            con->y += con->varg[0] ? con->varg[0]: 1;
            if (con->y > con->ymax) {
                con->scroll += con->y - con->ymin;
                con->y = con->ymax;
            }
            break;
            
        case 'C':
            con->x += con->varg[0] ? con->varg[0]: 1;
            con->wrap = false;
            break;
            
        case 'D':
            con->x -= con->varg[0] ? con->varg[0]: 1;
            con->wrap = false;
            break;
            
        case 'G':
            con->x = con->varg[0] ? con->varg[0] - 1: 0;
            con->wrap = false;
            break;
            
        case 'P':
            TextDeleteChar (con, con->varg[0] ? con->varg[0]: 1);
            break;
            
        case '@':
            TextInsertChar (con, con->varg[0] ? con->varg[0]: 1);
            break;
            
        case 'L':
            TextMoveDown (con, con->y, con->ymax, con->varg[0]?con->varg[0]:1);
            break;
            
        case 'M':
            TextMoveUp (con, con->y, con->ymax, con->varg[0]?con->varg[0]:1);
            break;
            
        case 'H':
        case 'f':
            if (con->varg[1])
                con->x = con->varg[1] - 1;
            else 
                con->x = 0;
            con->wrap = false;
            
        case 'd':
            con->y = con->varg[0] ? con->varg[0] - 1: 0;
            break;
            
        case 'm':
            for (n = 0; n <= con->narg; n ++)
                EscSetAttr (con, con->varg[n]);
            break;
            
        case 'r':
            con->ymin = con->varg[0]? (con->varg[0] - 1): 0;
            con->ymax = con->varg[1]? (con->varg[1] - 1): (con->dispymax - 1);
            con->x = 0;
            con->y = con->ymin;
            con->wrap = false;
#if 1
            if (con->ymin || (con->ymax != con->dispymax - 1))
                con->soft = true;
            else
                con->soft = false;
#endif
            break;
            
        case 'l':
            for (n = 0; n <= con->narg; n ++)
                VtSetMode (con, con->varg[n], false);
            break;
            
        case 'h':
            for (n = 0; n <= con->narg; n ++)
                VtSetMode (con, con->varg[n], true);
            break;
            
        case '?':
            con->question = true;
            con->esc = EscBracket;
            break;
            
        case 's':
            SaveAttr (con);
            break;
            
        case 'u':
            RestoreAttr (con);
            break;
            
        case 'n':
        case 'c':
            if (con->question != true)
                EscReport (con, ch, con->varg[0]);
            break;
            
        case 'R':
            break;
        }

        if (con->esc == NULL) {
            con->question = false;
            con->narg = 0;
            for ( n = 0; n < MAX_NARG; n++ )
                con->varg[n] = 0;
        }
    }
}

CODINGINFO SCodingInfo [] = {
    /* latin1(French, Spanish, ...) */
    {"ISO8859-1", 'B', 'A'},
    /* latin2 */
    {"ISO8859-2", 'B', 'B'},
    /* latin3 */
    {"ISO8859-3", 'B', 'C'},
    /* latin4 */
    {"ISO8859-4", 'B', 'D'},
    /* Russian */
    {"ISO8859-5", 'B', 'L'},
    /* Arabic */
    {"ISO8859-6", 'B', 'G'},
    /* Greek */
    {"ISO8859-7", 'B', 'F'},
    /* Hebrew */
    {"ISO8859-8", 'B', 'H'},
    /* latin5 */
    {"ISO8859-9", 'B', 'M'},
    /* Japanese */
    {"JISX0201.1976-0", 'J', 'I'},
    /* DUMB */
    {NULL, 0, 0}
};

CODINGINFO DCodingInfo [] = {
    /* DF_GB2312 */
    {"GB2312.1980-0", 'A', 0},
    /* DF_JISX0208 */
    {"JISX0208.1983-0", 'B', 0},
    /* DF_KSC5601 */
    { "KSC5601.1987-0", 'C', 0},
    /* DF_JISX0212 */
    {"JISX0212", 'D', 0, },
    /* DF_BIG5_0 */
    {"BIG5.HKU-0", '0', 0},
    /* DF_BIG5_1 */
    {"BIG5.HKU-0", '1', 0},
    /* DUMB */
    {NULL, 0, 0}
};

static void EscSetDCodeG0 (CONINFO *con, u_char ch)
{
    int i = 0;
    
    switch(ch) {
    case '(': /* EscSetDCodeG0 */
    case ')': /* EscSetDCodeG1 */
        return;
        
    case '@':
        ch = 'B';
        
    default:
    	while (DCodingInfo [i].sign0) {
	        if (DCodingInfo[i].sign0 == ch) {
		        con->db = (u_char)i|LATCH_1;
		        break;
	        }
	        i ++;
	    }
	    con->trans = CS_DBCS;
	    break;
    }
    con->esc = NULL;
}

static void EscSetSCodeG0 (CONINFO *con, u_char ch)
{
    int i = 0;
    
    switch(ch) {
    case 'U':
        con->g[0] = CS_GRAPH;
        break;
        
    default:
    	while (SCodingInfo [i].sign0) {
	        if (SCodingInfo [i].sign0 == ch) {
		        con->sb = (u_char)i;
		        con->g[0] = CS_LEFT;
		        break;
	        }
            else if (SCodingInfo [i].sign1 == ch) {
		        con->sb = (u_char)i;
		        con->g[0] = CS_RIGHT;
		        break;
	        }
	        i ++;
	    }
    }

    con->trans = con->g[0];
    con->esc = NULL;
}

static void EscSetSCodeG1 (CONINFO *con, u_char ch)
{
    switch(ch) {
    case 'U':
        con->g[1] = CS_LEFT;
        break;
        
    case '0':
        con->g[1] = CS_GRAPH;
        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -