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

📄 ansiesc.c

📁 linux下从网卡远程启动
💻 C
字号:
#include "stddef.h"#include "string.h"#include "etherboot.h"#include "ansiesc.h"/* * This program 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, or (at * your option) any later version. *//* *	Display attributes * *	Code          Effect *	<esc>[0m      normal text *	<esc>[1m      high-intensity on *	<esc>[21m     high-intensity off *	<esc>[5m      blinking on *	<esc>[25m     blinking off *	<esc>[7m      reverse video on *	<esc>[27m     reverse video off *	<esc>[3xm     set foreground color: *	<esc>[4xm     set background color. x can be: *			   0 - black                   4 - blue *			   1 - red                     5 - magenta *			   2 - green                   6 - cyan *			   3 - yellow                  7 - white *	<esc>[=xh     set video mode *			   0 - 40x25 mono     (text)  13 - 40x25 16colors (gfx) *			   1 - 40x25 16colors (text)  14 - 80x25 16colors (gfx) *			   2 - 80x25 mono     (text)  15 - 80x25 mono     (gfx) *			   3 - 80x25 16colors (text)  16 - 80x25 16colors (gfx) *			   4 - 40x25 4colors  (gfx)   17 - 80x30 mono     (gfx) *			   5 - 40x25 mono     (gfx)   18 - 80x30 16colors (gfx) *			   6 - 80x25 mono     (gfx)   19 - 40x25 256colors(gfx) * * *	Cursor control * *	Code          Effect *	<esc>[r;cH    move cursor to row r col c (r and c are both numbers) *	<esc>[r;cf    move cursor to row r col c (r and c are both numbers) *	<esc>[rA      move cursor up r rows *	<esc>[rB      move cursor down r rows *	<esc>[cC      move cursor right c columns *	<esc>[cD      move cursor left c columns *	<esc>[?7l     turn off line wrap *	<esc>[?7h     turn on line wrap *	<esc>[J       clear screen and home cursor *	<esc>[K       clear to end of line *	<esc>[s       save the cursor position *	<esc>[u       return cursor to saved position * *	Extended features * *	Code          Effect *      <esc>[a;b;c;d+<data> *                    draw pixel data; use one byte per pixel. Parameters *                    differ depending on the number of parameters passed: *                    cnt *                      "cnt" bytes follow; they will be drawn to the *                      right of the last graphics position *                    rle;col *                      the next "rle" pixels have the value "col"; they *                      will be drawn to the right of the last graphics *                      position *                    x;y;cnt *                      "cnt" bytes follow; they will be drawn relative to *                      the text cursor position with an offset of (x/y) *                    x;y;rle;col *                      the next "rle" pixels have the value "col"; the *                      will be drawn relative to the text cursor position *                      with an offset of (x/y) *      <esc>[a;b;c;d-<data> *                      same as above, but pack pixels into three bits. * */#define MAXARGS		8#define MAXSTRARGS	1#define MAXSTRARGLEN	40extern union {  struct {    unsigned char al,ah,bl,bh,cl,ch,dl,dh;  } __attribute__ ((packed)) lh;  struct {    unsigned short ax,bx,cx,dx;  } __attribute__ ((packed)) x;  unsigned long axbx;} __attribute__ ((packed)) int10ret;union axbxstruct {  struct {    unsigned char al,ah,bl,bh;  } __attribute__ ((packed)) lh;  struct {    unsigned short ax,bx;  } __attribute__ ((packed)) x;  unsigned long axbx;} __attribute__ ((packed));#define int10(a,b,c,d) _int10((unsigned long)(a)+((unsigned long)(b)<<16), \			      (unsigned long)(c)+((unsigned long)(d)<<16))extern unsigned long _int10(unsigned long axbx,unsigned long cxdx);static enum { esc_init, esc_std, esc_esc, esc_bracket, esc_digit,	      esc_semicolon, esc_str, esc_quote} esc_state = esc_init;/* Don't declare these static, so we can access them from code in other files */unsigned short rows,columns,attr = 7;static unsigned short scr,cx = 0,cy = 0, scx = 0,scy = 0;static int fg = 7, bg = 0, blink = 0,reverse = 0, bright = 0;static int wraparound = 1;static int argn = 0;static int argi[MAXARGS];static char args[MAXSTRARGS][MAXSTRARGLEN];static const unsigned char coltable[9] = "\000\004\002\006\001\005\003\007";#ifdef	GFXstatic unsigned short gfx_rows,gfx_columns,char_width,char_height,gfx_x,gfx_y;static int in_gfx = 0, gfx_packed,gfx_data,gfx_nbits;static int defaultmode = -1, curmode = -1, curmodetype = 0;#endifvoid ansi_reset(void){#ifdef	GFX  /* this will not execute, when the serial console is used, because     both curmode and defaultmode will be -1 */  if (curmode != defaultmode) {    in_gfx = 0;    curmodetype = 0;    int10(curmode = defaultmode,0,0,0);    esc_state = esc_init;    ansi_putc('\010'); /* force reinitialization */ }  return;#endif}void enable_cursor(int enable){#ifdef	GFX  /* this will not execute, when the serial console is used, because     curmodetype will be 0 */  if (curmodetype == 'G' || curmodetype == 'H') {    if (enable)      int10(0x09DB,7,1,0);    else      int10(0x0920,(attr/16)&7,1,0); }  return;#endif}static void docommand(unsigned char ch){#ifdef	GFX  if (ch == '+' || ch == '-') { /* gfx bitmap */    int i;    gfx_packed = ((ch == '-') ? 3 : 8);    gfx_nbits  = 0;    if (argn > 2) {      gfx_x    = argi[0];      gfx_y    = argi[1];      if (curmodetype == 'T') {	gfx_x += cx;	gfx_y += cy; }      else {	gfx_x += cx*char_width;	gfx_y += cy*char_height; }      i        = 2; }    else      i        = 0;    in_gfx   = argi[i+0];    if (argn == i+2)      while (in_gfx)	ansi_putc(argi[i+1]); }  else#endif  if (ch == 'm') { /* set attribute */    int i,j;    for (j = 0; (i = argi[j]), (j++ < argn); )      if (i == 0 ||       /* reset attributes */	  i == 20) {	blink = reverse = bright = bg = 0; fg = 7;	goto doattr; }      else if (i == 1) {  /* high intensity on */	bright = 1;	goto doattr; }      else if (i == 21) { /* high intensity off */	bright = 0;	goto doattr; }      else if (i == 5) {  /* blinking on */	blink = 1;	goto doattr; }      else if (i == 25) { /* blinking off */	blink = 0;	goto doattr; }      else if (i == 7) {  /* reverse video on */	reverse = 1;      isreverse:	attr =#ifdef	GFX	  curmodetype != 'T' ? (fg?128:0)+16*fg+(fg^(8*bright+bg)) :#endif	  128*blink+16*fg+8*bright+bg; }      else if (i == 27) { /* reverse video off */	reverse = 0;      isnormal:	attr =#ifdef	GFX	  curmodetype != 'T' ? (bg?128:0)+16*bg+(bg^(8*bright+fg)) :#endif	  128*blink+16*bg+8*bright+fg; }      else if (i >= 30 && i <= 37) {	fg = coltable[i-30];      doattr:	if (reverse) goto isreverse; else goto isnormal; }      else if (i >= 40 && i <= 47) {	bg = coltable[i-40];	goto doattr; } }  else if (ch == 'H' || /* set cursor position */	   ch == 'f') { /* set cursor position */    cy = argi[0];    cx = argi[1];    updatecursor:    int10(0x0200,256*scr,0,256*cy+cx); }  else if (ch == 'A') { /* move cursor up */    if (cy < argi[0]) cy = 0;    else              cy -= argi[0];    goto updatecursor; }  else if (ch == 'B') { /* move cursor down */    if ((cy += argi[0]) >= rows) cy = rows-1;    goto updatecursor; }  else if (ch == 'C') { /* move cursor right */    if ((cx += argi[0]) >= columns) cx = columns-1;    goto updatecursor; }  else if (ch == 'D') { /* move cursor left */    if (cx < argi[0]) cx = 0;    else              cx -= argi[0];    goto updatecursor; }  else if (ch == 'l') { /* turn off line wrapping or set text mode */    if (argi[0] == 7)      wraparound = 0;#ifdef	GFX    else {  /* text mode */      curmodetype = 0;      int10(curmode = defaultmode,0,0,0);      esc_state = esc_init; }#endif  }  else if (ch == 'h') { /* turn on line wrapping or set graphics mode */    if (argi[0] == 7)      wraparound = 1;#ifdef	GFX    else {  /* graphics mode */      curmodetype = 0;      int10(curmode = argi[0],0,0,0);      esc_state = esc_init; }#endif  }  else if (ch == 'J') { /* clear screen and home cursor */#ifdef	GFX    int10(0x0600,256*(curmodetype != 'T' ? reverse ? fg : bg : attr),0,	  256*(rows-1)+columns-1);#else    int10(0x0600,256*attr,0,256*(rows-1)+columns-1);#endif    cx = cy = 0;    goto updatecursor; }  else if (ch == 'K')   /* clear to end of line */#ifdef	GFX    int10(curmodetype == 'T' ? 0x0920 : 0x09DB,	  curmodetype == 'T' ? 256*scr+attr : reverse ? fg : bg,	  columns-cx,0);#else    int10(0x0920,256*scr+attr,columns-cx,0);#endif  else if (ch == 's') { /* save cursor position */    scx = cx; scy = cy; }  else if (ch == 'u') { /* restore cursor position */    cx = scx; cy = scy;    goto updatecursor; }  return;}void ansi_putc(unsigned int ch){  union axbxstruct u;#ifdef	GFX  if (in_gfx) {    gfx_data   = (gfx_data << 8) | ch;    gfx_nbits += 8;    while (gfx_nbits >= gfx_packed && in_gfx) {      in_gfx--;      ch = (gfx_data >> (gfx_nbits -= gfx_packed)) & ((1 << gfx_packed) - 1);      if (curmodetype == 'T') {	if (gfx_x < columns && gfx_y < rows*2) {	  int pix[2];	  int10(0x0200,256*scr,0,        /* move cursor position */		256*(gfx_y/2)+gfx_x++);	  u.axbx = int10(0x0800,256*scr,0,0);     /* read character/attribute */	  if (u.lh.al == 0xDB)	    pix[0] = pix[1] =  u.lh.ah    &0xF;	  else if (u.lh.al == 0xDC) {	    pix[0] =          (u.lh.ah/16)&0xF;	    pix[1] =           u.lh.ah    &0xF; }	  else	    pix[0] = pix[1] = (u.lh.ah/16)&0xF;	  pix[gfx_y&1] = coltable[ch & 0x7];	  int10(0x0900|                  /* output char */		(pix[0]==pix[1]?0xDB:0xDC),		256*scr+(0x7F&(pix[0]*16+pix[1])),1,0); }	if (!in_gfx)	  int10(0x0200,256*scr,0,        /* restore cursor position */		256*cy+cx); }      else if (gfx_x < gfx_columns && gfx_y < gfx_rows)	int10(0x0C00|                    /* write pixel */	      (ch <= 7 ? coltable[ch] : ch),256*scr,gfx_x++,gfx_y); }    return; }#endif  switch (esc_state) {  case esc_esc:    if (ch == '[') {      esc_state = esc_bracket;      argn = 0;      memset(&argi, 0, sizeof(argi));      memset(args, 0, MAXSTRARGS*MAXSTRARGLEN); }    else {      esc_state = esc_std;      goto doputchar; }    break;  case esc_bracket:  case esc_semicolon:    if (ch == '\'') {      esc_state = esc_str;      break; }    /* fall thru */    if (ch == '=' || ch == '?')      break;    /* fall thru */  case esc_digit:    if (ch >= '0' && ch <= '9') {      esc_state = esc_digit;      if (argn < MAXARGS)	argi[argn] = 10*argi[argn] + ch - '0'; }    else      quote:      if (ch == ';') {      esc_state = esc_semicolon;      argn++; }    else {      if (esc_state == esc_digit || esc_state == esc_quote)	argn++;      esc_state = esc_std;      docommand(ch); }    break;  case esc_str:    if (ch == '\'') {      esc_state = esc_quote;      break; }    { int i;    if (argn < MAXSTRARGS && (i = strlen(args[argn])) < MAXSTRARGLEN-2)      args[argn][i] = ch; }    break;  case esc_quote:    goto quote;  case esc_init: {    int i;    esc_state = esc_std;    u.axbx = int10(0x0F00,0,0,0);                 /* get graphics mode information */#ifdef	GFX    if (defaultmode < 0)      defaultmode = curmode = u.lh.al ? u.lh.al : 3;#endif    columns = u.lh.ah;    scr     = u.lh.bh;    int10(0x0200,256*scr,0,0);           /* put cursor to home position */    for (i = 0; ++i < 100; ) {      int10(0x0E0A,256*scr,0,0);         /* output LF */      int10(0x0300,256*scr,0,0);         /* get cursor position */      if (int10ret.lh.dh != i)	         /* row */	break; }    rows    = i;    int10(0x0200,256*scr,0,0);           /* put cursor to home position */#ifdef	GFX    char_width  = 8;    char_height = *(unsigned char *)0x485;    if (char_height < 8 || char_height > 20)      char_height = 8;    gfx_columns = char_width*columns;    gfx_rows    = char_height*rows;    if (!curmodetype) {      int10(0x0941,256*scr+127,1,0);     /* 'A', bright, white on white */      u.axbx = int10(0x0800,256*scr,0,0);         /* read character/attribute */      if (u.lh.al == 0x41 &&	  u.lh.ah == 127)	curmodetype = 'T';      else {	int10(0x0C40,256*scr,0,0);       /* write pixel */	u.axbx = int10(0x0D00,256*scr,0,0);       /* read pixel color */	if (u.lh.al == 0x40)	  curmodetype = 'H';	else	  curmodetype = 'G'; } }#endif    attr = fg = 7;    cx = cy = scx = scy = bg = blink = reverse = bright = 0;    wraparound = 1;#ifdef	GFX    int10(0x0600,                        /* clear screen */	  curmodetype != 'T' ? 0 : 7*256,0,256*(rows-1)+columns-1); }#else    int10(0x0600,                        /* clear screen */	  7*256,0,256*(rows-1)+columns-1); }#endif    /* fall thru */  default:    if (ch == 0x1B)      esc_state = esc_esc;    else if (ch == '\t') {      int i;      for (i = 8-cx%8; i--; ) ansi_putc(' '); }    else if (ch == '\r') {      cx = 0; goto updatecursor; }    else if (ch == '\n') {      ansi_putc('\r'); goto newline; }    else if (ch == '\010') {      if (cx) {	cx--; goto updatecursor; } }    else {    doputchar:#ifdef	GFX      if (curmodetype == 'G' && (reverse ? fg : bg))	int10(0x09DB,(attr/16)&0x07,1,0);/* set background in gfx mode */#endif#ifdef	GFX      int10(0x0900|ch,                   /* output char */	    curmodetype == 'H' ? reverse ? fg*256+bg : bg*256+fg :	    256*scr+attr,1,0);#else      int10(0x0900|ch,256*scr+attr,1,0); /* output char */#endif      if (++cx == columns) {	if (!wraparound)	  cx--;        else {	  cx = 0;	newline:	  if (++cy == rows)#ifdef	GFX	    int10(0x0601,                /* scroll screen */		  256*(curmodetype != 'T' ? reverse ? fg : bg : attr),0,		  256*--cy+columns-1); }#else	    int10(0x0601,256*attr,0,     /* scroll screen */		  256*--cy+columns-1); }#endif      }    updatecursor:      int10(0x0200,256*scr,0,256*cy+cx); /* update cursor position */ } }  return;}

⌨️ 快捷键说明

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