📄 vt.c
字号:
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 + -