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

📄 vt.c

📁 这是一个介绍 linux 编程知识的文章。
💻 C
📖 第 1 页 / 共 2 页
字号:
        
    case 'A':
    case 'J':
    case 'B':
        break;
    }
    
    con->trans = con->g[1];
    con->esc = NULL;
}

/* Escape code handling */
static void EscStart (CONINFO *con, u_char ch)
{
    con->esc = NULL;
    
    switch (ch) {
    case '[':
        con->esc = EscBracket;
    break;
    
    case '$':/* Set Double Byte Code */
        con->esc = EscSetDCodeG0;
    break;
    
    case '(':/* Set 94 to G0 */
    case ',':/* Set 96 to G0 */
        con->esc = EscSetSCodeG0;
    break;
    
    case ')':/* Set G1 */
        con->esc = EscSetSCodeG1;
    break;
    
    case 'E':
        con->x = 0;
        con->wrap = false;
    case 'D':
        if (con->y == con->ymax)
            con->scroll ++;
        else
            con->y ++;
        break;
        
    case 'M':
        if (con->y == con->ymin)
            con->scroll --;
        else
            con->y --;
        break;

    case 'c':  /* reset terminal */
        con->fcol = 7;
        con->attr = 0;
#ifdef USECCEWAY
        con->knj1 = 0;
#endif
        con->bcol = 0;
        con->wrap = false;
        con->trans = CS_LEFT;
        con->sb = 0;
        con->db = LATCH_1;
        
    case '*':
        con->x = con->y = 0;
        con->wrap = false;
        TextClearAll (con);
        break;
    
    case '7':
        SaveAttr (con);
        break;
        
    case '8':
        RestoreAttr (con);
        con->wrap = false;
        break;
    }
}

static inline bool iskanji_byte1 (PCONINFO con, u_char c)
{
    switch(con->sysCoding) {
    case CODE_SJIS:
        return (c >=0x81 && c<=0x9F) || (c >=0xE0 && c <=0xFC);
    case CODE_GB:
        return (c >= 0xA1 && c <= 0xFE);
    case CODE_BIG5:
       return (c >=0xa1 && c<=0xfe);  //first byte
    default:
        return (c & 0x80);
    }
}

static inline bool iskanji_byte2 (PCONINFO con, u_char c)
{
    switch(con->sysCoding) {
    case CODE_SJIS:
        return (c >=0x81 && c<=0x9F) || (c >=0xE0 && c <=0xFC);
    case CODE_GB:
        return (c >= 0xA1 && c <= 0xFE);
    case CODE_BIG5:
       return ((c >=0x40 && c<=0x7e) || (c >=0xa1 && c<=0xfe)); // second byte
    default:
        return (c & 0x80);
    }
}

static inline bool iskanji (PCONINFO con, u_char c)
{
    switch(con->sysCoding) {
    case CODE_SJIS:
        return (c >=0x81 && c<=0x9F) || (c >=0xE0 && c <=0xFC);
    case CODE_GB:
        return (c >= 0xA1 && c <= 0xFE);
    case CODE_BIG5:
       return ((c >=0xa1 && c<=0xfe) 
                || (c >=0x40 && c<=0x7e) 
                || (c >=0xa1 && c<=0xfe));
    default:
        return (c & 0x80);
    }
}

static inline u_int text_offset (CONINFO *con, u_int x, u_int y)
{
    return (con->textHead + x + y * con->dispxmax) % con->textSize;
}

int FirstOrSecondByte (CONINFO* con, u_char ch)
{
    u_int prev_addr = -1;
    
    if (con->x == 0) {
        if (con->y > con->ymin) {
            prev_addr = text_offset (con, con->xmax, con->y - 1);
        }
    }
    else
        prev_addr = text_offset (con, con->x - 1, con->y);

    if (prev_addr != -1) {
        if (con->flagBuff [prev_addr] & CODEIS_1)
            return CODEIS_2;
        else
            return CODEIS_1;
    }

    return CODEIS_1;
}

void RearrangeLineWhenInsSB (CONINFO* con)
{
    u_int addr;
    int i;
    int prev = CODEIS_S;
    u_char ch;
    
    addr = text_offset (con, con->x, con->y) + 1;

    for (i = 0; i < con->xmax - con->x - 1; i++) {
        ch = con->textBuff [addr + i];
        if (iskanji (con, ch)) {
            switch (prev) {
            case CODEIS_S:
            case CODEIS_2:
                con->flagBuff [addr + i] = con->db | LATCH_1;
                prev = CODEIS_1;
                break;
            case CODEIS_1:
                con->flagBuff [addr + i] = con->db | LATCH_2;
                prev = CODEIS_1;
                break;
            }
        }
        else if (ch) {
            con->flagBuff [addr + i] = con->sb | LATCH_S;
            prev = CODEIS_S;
        }
        else
            prev = CODEIS_S;
    }
}

/****************************************************************************
 *               very important interface, output the buff                  *
 ****************************************************************************/
void VtWrite (CONINFO *con, const char *buff, int nchars)
{
    u_char    ch;

  /* This is all the esc sequence strings */
#if 0
    {
    FILE *fff;
    int i;

    fff = fopen("/tmp/ccegb-esc.log", "a");
    for(i = 0; i < nchars; i++)
        fprintf (fff, "%c", buff[i]);
        fprintf (fff," (%d, %d)\n", con->x, con->y);
	fclose (fff);
    }
#endif

    while (nchars-- > 0) {
        ch = *buff++;
        
        if (!ch)
            continue;

        if (con->esc) 
            con->esc (con, ch);   // in escape mode, parse the parameters
        else {
            switch (ch)
            {
            case CHAR_BEL:  // 0x07
                Ping ();
                break;
                
            case CHAR_DEL:  // 0x7F
                break;
                
            case CHAR_BS:   // 0x08
                if (con->x)
                    con->x--;
                con->wrap = false;
            break;
            
            case CHAR_HT:  //0x09
                con->x += con->tab - (con->x % con->tab);
                con->wrap = false;
                if (con->x > con->xmax)
                    con->x -= con->xmax + 1;
                else
                    break;
                    
            case CHAR_VT:  // 0x0B
            case CHAR_FF:  // 0x0C
#if 1
                con->trans = CS_LEFT;
                con->sb = 0;
                con->db = LATCH_1;
                /* no break? */
#endif

            case CHAR_LF:   // 0x0A
                con->wrap = false;
                if (con->y == con->ymax)
                    con->scroll ++;
                else
                    con->y ++;
                break;
                
            case CHAR_CR:  // 0x0D
                con->x = 0;
                con->wrap = false;
                break;
                
            case CHAR_ESC:  // 0x1B
                con->esc = EscStart;
                continue;
                
            case CHAR_SO:  // 0x0E
                con->trans = con->g[1] | G1_SET;
                continue;
                
            case CHAR_SI:  // 0x0F
                con->trans = con->g[0];
                continue;
            
            default:
                if (con->x == con->xmax + 1) {
                    con->wrap = true;
                    con->x --;
                }

                if (con->wrap) {
                    con->x -= con->xmax;
                    if (con->y == con->ymax)
                        con->scroll ++;
                    else
                        con->y ++;
                    con->wrap = false;
                    buff --;
                    nchars ++;

#ifdef USECCEWAY
                    /* Upate position of second half of the double-byte char */
                    if (con->knj1) {
                        con->knj1x = con->x;
                        con->knj1y = con->y;
                        con->knj2x = con->x + 1;
                        con->knj2y = con->y;
                    }
#endif
                    break;
                }

#ifndef USECCEWAY
                if (iskanji (con, ch)) {
                    if (con->ins)
                        TextInsertChar (con, 1);
                    
                    switch (FirstOrSecondByte (con, ch)) {
                    case CODEIS_1:
                        TextWput1 (con, ch);
                        break;
                    case CODEIS_2:
                        TextWput2 (con, ch);
                        break;
                    default:
                        TextSput (con, ch);
                        RearrangeLineWhenInsSB (con);
                        break;
                    }

                    con->x ++;
                    continue;
                }
                else {
                    if (con->ins)
                        TextInsertChar (con, 1);
                        
                    TextSput (con, ch);
                    RearrangeLineWhenInsSB (con);

                    con->x ++;
                    continue;
                }
#else
                if ( con->knj1 && iskanji_byte2 (con, ch)
                  && ( ((con->x == con->knj2x) && (con->y == con->knj2y))
                    || ((con->x == con->knj1x) && (con->y == con->knj1y))
                     )
                   ) {
                    short oldx, oldy;
                    
                    /* special handling for Japanese char */
                    if (con->knj1 & 0x80) {
                        switch(con->sysCoding) 
                        {
                        case CODE_EUC:
                            if (con->knj1 == (u_char)CHAR_SS2) {
                                /* handling 'kata-kana' */
                                if (con->ins)
                                    TextInsertChar (con, 1);
                                TextSput (con, ch);
                                con->x ++;
                                con->knj1 = 0;
                                continue;
                            }
                            con->knj1 &= 0x7F;
                            ch &= 0x7F;
                            break;
                            
                        case CODE_SJIS:
                            sjistojis (con->knj1, ch);
                            break;
                        }  // case
                    }
                    else {
                        if (con->db == (DF_BIG5_0|LATCH_1))
                            muletobig5 (con->db, con->knj1, ch);
                    }
                    
                    oldx = con->x; oldy = con->y;
                    con->x = con->knj1x; con->y = con->knj1y;

                    if (con->ins)
                        TextInsertChar (con, 2);
                        
                    TextWput (con, con->knj1, ch);
                    
                    con->x = oldx + 2;
                    con->y = oldy;
                    con->knj1 = 0;
                    continue;
                }
                else if (con->trans == CS_DBCS
                       || (iskanji (con, ch) && con->trans == CS_LEFT)) {
                    if (con->x == con->xmax)
                        con->wrap = true;
                    else {
                        con->knj1x = con->x;
                        con->knj1y = con->y;

                        con->knj2x = con->x + 1;
                        con->knj2y = con->y;
                    }

                    /* First Half of the double-byte char */
                    con->knj1 = ch;
                    continue;
                }
                else {
                    if (con->ins)
                        TextInsertChar (con, 1);
                    TextSput (con, con->trans == CS_RIGHT ? ch | 0x80: ch);
                    con->x ++;
                    continue;
                }
#endif

            }  /* switch */
        }

        if (con->scroll > 0) 
            ScrollUp (con, con->scroll);
        else if (con->scroll < 0)
            ScrollDown (con, -con->scroll);
        con->scroll = 0;
    }  /* while */
}

bool VtStart (PCONINFO con)
{
   /* A serious and strange bug here, at first ymin and knj1 is not
      initialized to 0, it works fine in Linux (maybe the malloc in
      Linux will automatically zero the memory), but doesn't work in
      FreeBSD. FreeBSD's calloc zero the memory, but malloc not!!!
      So I need to initialize all the member here */

    con->x = con->y = 0;
    con->dispxmax = con->cols;
    con->dispymax = con->rows;
    con->xmax = con->cols - 1;
    con->ymax = con->rows - 1;
    con->ymin = 0;
    con->tab = 8;
    con->fcol = 7;
    con->bcol = 0;
    con->attr = 0;
    con->esc = NULL;
    con->g[0] = con->g[1] = CS_LEFT;
    con->trans = CS_LEFT;
    con->soft = con->ins = con->wrap = false;
    con->sb = 0;
    con->db = LATCH_1;

#ifdef USECCEWAY
    con->knj1 = 0;
    con->knj1x = con->knj1y = 0;
#endif

    con->cursorsw = true;

    con->textBuff = (u_char *)calloc (con->cols, con->rows);
    con->attrBuff = (u_char *)calloc (con->cols, con->rows);
    con->flagBuff = (u_char *)calloc (con->cols, con->rows);
    if (con->textBuff == NULL || con->attrBuff == NULL ||
        con->flagBuff == NULL)
        return false;
    
    con->textSize = con->cols * (con->rows);

    con->currentScroll = con->scrollLine = 0;
    con->scroll = 0;
    con->textHead = 0;

    con->textClear = false;
    con->terminate = 0;

    con->sysCoding = CODE_GB;
    memset (con->varg, MAX_NARG, 0);
    con->narg = 0;
    con->question = 0;

    con->m_captured = false;
    con->m_oldx = con->m_oldy = 0;
    con->m_origx = con->m_origy = -1;

    return true;
}

bool VtChangeWindowSize (PCONINFO con, int new_row, int new_col)
{
    int i, j;
    int text_size = new_row * new_col;
    char* textBuff, *attrBuff, *flagBuff;

    textBuff = (u_char *)calloc (text_size, 1);
    attrBuff = (u_char *)calloc (text_size, 1);
    flagBuff = (u_char *)calloc (text_size, 1);
    
    if (textBuff == NULL || attrBuff == NULL || flagBuff == NULL)
        return false;
    
    for (i = 0; i < min (new_row, con->rows); i++)
        for (j = 0; j < min (new_col, con->cols); j++) {
            textBuff [i*new_col + j] = con->textBuff [i*con->cols +j];
            attrBuff [i*new_col + j] = con->attrBuff [i*con->cols +j];
            flagBuff [i*new_col + j] = con->flagBuff [i*con->cols +j];
        }
    
    free (con->textBuff);
    free (con->attrBuff);
    free (con->flagBuff);

    con->rows = new_row;
    con->cols = new_col;
    con->textSize = text_size;
    con->textBuff = textBuff;
    con->attrBuff = attrBuff;
    con->flagBuff = flagBuff;
    con->dispxmax = con->cols;
    con->dispymax = con->rows;
    con->xmax = con->cols - 1;
    con->ymax = con->rows - 1;

    if (con->x > con->xmax) con->x = con->xmax;
    if (con->y > con->ymax) con->y = con->ymax;

    return true;
}

void VtCleanup (PCONINFO con)
{
    if (con == NULL)
        return;

    con->scrollLine = con->textHead = con->currentScroll = 0;
    con->scroll = 0;
    
    SafeFree ((void **)&(con->textBuff));
    SafeFree ((void **)&(con->attrBuff));
    SafeFree ((void **)&(con->flagBuff));
}

⌨️ 快捷键说明

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