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

📄 scrnio.c

📁 arj source code
💻 C
字号:
/* * $Id: scrnio.c,v 1.5 2003/09/14 22:14:48 andrew_belov Exp $ * --------------------------------------------------------------------------- * This module provides basic screen output routines. * */#include "arj.h"#if CONSOLE_SET==CT_NATIVE||TARGET==OS2 #define KNOW_DIMENSIONS#endif#include <stdarg.h>#if CONSOLE_SET==CT_NATIVE #if TARGET==DOS  #include <conio.h>  #include <dos.h> #elif TARGET==OS2 #endif#endifDEBUGHDR(__FILE__)                      /* Debug information block *//* Local variables */#ifdef KNOW_DIMENSIONS static unsigned char w_rows=0, w_columns;#endif#if TARGET==WIN32 static HANDLE hcons;#endif#if CONSOLE_SET==CT_ANSI||CONSOLE_SET==CT_NATIVE static unsigned char curattr=7; #if CONSOLE_SET==CT_ANSI  static char ansicolors[8]={30, 34, 32, 36, 31, 35, 33, 37};  static int background_touched=0; #endif#endifint scr_sentry=0;/* Queries screen dimensions, excluding window region */#ifdef KNOW_DIMENSIONSstatic void get_dimensions(){ #if TARGET==DOS  union REGS r;  r.h.ah=0x0F;  int86(0x10, &r, &r);  w_columns=(unsigned int)r.h.ah;  w_rows=*(unsigned char FAR *)0x00000484L+1; #elif TARGET==OS2  VIOMODEINFO modedata;  modedata.cb=sizeof(modedata);  VioGetMode(&modedata, 0);  w_columns=modedata.col;  w_rows=modedata.row; #elif TARGET==WIN32  CONSOLE_SCREEN_BUFFER_INFO csbi;  GetConsoleScreenBufferInfo(hcons=GetStdHandle(STD_OUTPUT_HANDLE), &csbi);  w_columns=csbi.dwSize.X;  w_rows=csbi.dwSize.Y; #endif}#endif/* Positions the cursor at row y, column x (top-left screen corner is 1, 1) */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_MSGRAPHvoid gotoxy(int x, int y){ #if CONSOLE_SET==CT_NATIVE  #if TARGET==DOS   union REGS r;   r.h.ah=2;   r.h.bh=0;   r.h.dh=(char)y-1;   r.h.dl=(char)x-1;   int86(0x10, &r, &r);  #elif TARGET==OS2   VioSetCurPos((USHORT)y-1, (USHORT)x-1, 0);  #elif TARGET==WIN32   COORD xy;   if(w_rows==0)    get_dimensions();   xy.X=x-1;   xy.Y=y-1;   SetConsoleCursorPosition(hcons, xy);  #endif #elif CONSOLE_SET==CT_ANSI  printf("\x1B[%u;%uH", y, x); #endif}#endif/* Refreshes the ANSI attributes */#if CONSOLE_SET==CT_ANSIstatic void kick_attr(){ if(!background_touched) {  if(curattr%8==7)   printf("\x1B[0m");  else   printf("\x1B[0;%um", (unsigned int)ansicolors[curattr%8]); } else {  printf("\x1B[0;%u;%um", (unsigned int)ansicolors[curattr%8],                          (unsigned int)(ansicolors[(curattr>>4)%8])+10); } if(curattr&8)  printf("\x1B[1m");}#else #define kick_attr()#endif/* Sets the background color to c, color index is the same as on PCs. The   colors 8..15 do NOT enable blinking. */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_MSGRAPHvoid textbackground(int c){ curattr=(curattr%16+(c<<4))%128; kick_attr(); #if CONSOLE_SET==CT_ANSI  background_touched=1; #endif}#endif/* Sets the foreground color to c, 16...31 enables blinking. */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_MSGRAPHvoid textcolor(int c){ curattr=(curattr&112)+((c&16)<<3)+c%16; kick_attr();}#endif/* Sets text attributes */#if CONSOLE_SET!=CT_BORLAND&&SFX_LEVEL>=ARJSFXvoid textattr(int c){ #if CONSOLE_SET==CT_MSGRAPH  _settextcolor((short)((c&128)?16:0)+c%16);  _setbkcolor((short)(c%128)>>4); #elif CONSOLE_SET==CT_NATIVE||CONSOLE_SET==CT_ANSI  curattr=(unsigned char)c; #endif kick_attr();}#endif/* Returns current column, 1...<screen width> */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_ANSIint wherex(){ #if CONSOLE_SET==CT_MSGRAPH  struct rccoord coord;  coord=_gettextposition();  return((int)coord.col); #elif CONSOLE_SET==CT_NATIVE  #if TARGET==DOS   union REGS r;   r.h.ah=3;   r.h.bh=0;   int86(0x10, &r, &r);   return((int)r.h.dl+1);  #elif TARGET==OS2   USHORT x, y;   VioGetCurPos(&y, &x, 0);   return(x+1);  #elif TARGET==WIN32   CONSOLE_SCREEN_BUFFER_INFO csbi;   GetConsoleScreenBufferInfo(hcons, &csbi);   return(csbi.dwCursorPosition.X+1);  #endif #endif}#endif/* Returns current row, 1...<screen height> */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_ANSIint wherey(){ #if CONSOLE_SET==CT_MSGRAPH  struct rccoord coord;  coord=_gettextposition();  return((int)coord.row); #elif CONSOLE_SET==CT_NATIVE  #if TARGET==DOS   union REGS r;   r.h.ah=3;   r.h.bh=0;   int86(0x10, &r, &r);   return((int)r.h.dh+1);  #elif TARGET==OS2   USHORT x, y;   VioGetCurPos(&y, &x, 0);   return(y+1);  #elif TARGET==WIN32   CONSOLE_SCREEN_BUFFER_INFO csbi;   GetConsoleScreenBufferInfo(hcons, &csbi);   return(csbi.dwCursorPosition.Y+1);  #endif #endif}#endif/* Returns the current text attribute */#if SFX_LEVEL>=ARJSFXunsigned char getcurattr(){ #if CONSOLE_SET==CT_BORLAND  struct text_info r;  gettextinfo(&r);  return(r.attribute); #elif CONSOLE_SET==CT_MSGRAPH  unsigned char textcolor;  textcolor=(unsigned char)_gettextcolor();  return(textcolor%16+((unsigned char)_getbkcolor()<<4)+((textcolor&16)?128:0)); #elif CONSOLE_SET==CT_NATIVE||CONSOLE_SET==CT_ANSI  return(curattr); #endif}#endif/* Clears the entire screen or window */#if CONSOLE_SET!=CT_BORLAND&&CONSOLE_SET!=CT_MSGRAPHvoid clrscr(){ #if CONSOLE_SET==CT_NATIVE  #if TARGET==DOS   unsigned int st_x, st_y;   union REGS r;   get_dimensions();   r.x.ax=0x600;   r.h.bh=(unsigned char)curattr;    r.x.cx=0;   r.h.dh=w_rows-1;   r.h.dl=w_columns-1;   int86(0x10, &r, &r);   gotoxy(1, 1);  #elif TARGET==OS2   static BYTE cell[]={' ', 0};   int i;   get_dimensions();   cell[1]=(BYTE)curattr;   for(i=0; i<w_rows; i++)    VioWrtNCell(cell, w_columns, i, 0, 0);   gotoxy(1, 1);  #elif TARGET==WIN32   int i;   DWORD dummy;   COORD xy;   get_dimensions();   xy.X=0;   for(i=0; i<w_rows; i++)   {    xy.Y=i;    FillConsoleOutputCharacter(hcons, 0x20, w_columns, xy, &dummy);    FillConsoleOutputAttribute(hcons, (WORD)curattr, w_columns, xy, &dummy);   };   gotoxy(1, 1);  #endif #elif CONSOLE_SET==CT_ANSI  printf("\x1B[2J"); #endif}#endif/* Clears all characters from current position to the end of line */#if CONSOLE_SET!=CT_BORLANDvoid clreol(){ #if CONSOLE_SET==CT_MSGRAPH  struct videoconfig vc;  struct rccoord st_coord;  short x;  unsigned char c=' ';  _getvideoconfig(&vc);  st_coord=_gettextposition();  for(x=st_coord.col; x<=vc.numtextcols; x++)  {   _settextposition(st_coord.row, x);   _outmem((unsigned char FAR *)&c, 1);  }  _settextposition(st_coord.row, st_coord.col); #elif CONSOLE_SET==CT_NATIVE  unsigned int x, st_x, y;  #if TARGET==DOS   union REGS r;  #elif TARGET==OS2   char c[2]={32, 0};  #endif  y=wherey();  get_dimensions();  for(x=st_x=wherex(); x<=w_columns; x++)  {   #if TARGET==DOS    gotoxy(x, y);    r.x.ax=0x920;    r.x.bx=curattr;    r.x.cx=1;    int86(0x10, &r, &r);   #elif TARGET==OS2    c[1]=curattr;    VioWrtCharStrAtt((PCH)&c, 1, y-1, x-1, &curattr, 0);   #elif TARGET==WIN32    DWORD dummy;    COORD xy;    get_dimensions();    xy.X=x-1;    xy.Y=y-1;    FillConsoleOutputCharacter(hcons, 0x20, w_columns-x, xy, &dummy);    FillConsoleOutputAttribute(hcons, (WORD)curattr, w_columns-x, xy, &dummy);   #endif  }  gotoxy(st_x, y); #elif CONSOLE_SET==CT_ANSI  printf("\x1B[K"); #endif}#endif/* Writes a single character to the console, with scrolling */#if CONSOLE_SET!=CT_BORLANDvoid wputch(int c){ #if CONSOLE_SET==CT_MSGRAPH  char p[2];  p[0]=c;  p[1]='\0';  _outtext((char FAR *)p); #elif CONSOLE_SET==CT_NATIVE  {   unsigned int row, column;   #if TARGET==DOS    union REGS r;   #elif TARGET==OS2    BYTE cell[2];   #elif TARGET==WIN32    CHAR_INFO ci;    COORD xy, xysp;    SMALL_RECT sr;   #endif   if(w_rows==0)    get_dimensions();   row=wherey();   column=wherex();   switch(c)   {    case 8:     if(column>1)      column--;     break;    case 10:     row++;     column=1;     break;    case 13:     column=1;     break;    default:     #if TARGET==DOS      r.h.ah=9;      r.h.al=(unsigned char)c;      r.x.bx=curattr;      r.x.cx=1;      int86(0x10, &r, &r);     #elif TARGET==OS2      VioWrtCharStrAtt((PCH)&c, 1, row-1, column-1, &curattr, 0);     #elif TARGET==WIN32      ci.Char.UnicodeChar=0;      ci.Char.AsciiChar=(CHAR)c;      ci.Attributes=curattr;      xy.X=xy.Y=1;      xysp.X=0;      xysp.Y=0;      sr.Left=sr.Right=column-1;      sr.Top=sr.Bottom=row-1;      WriteConsoleOutput(hcons, &ci, xy, xysp, &sr);     #endif     column++;   }   if(column>w_columns)   {    column=1;    row++;   }   while(row>w_rows)   {    #if TARGET==DOS     r.x.ax=0x601;     r.h.bh=(unsigned char)curattr;     r.x.cx=0x100;     r.h.dh=w_rows-1;     r.h.dl=w_columns-1;     int86(0x10, &r, &r);    #elif TARGET==OS2     cell[0]=' ';     cell[1]=curattr;     VioScrollUp(0, 0, w_rows-1, w_columns-1, 1, cell, 0);    #elif TARGET==WIN32     sr.Top=1;     sr.Left=0;     sr.Right=w_columns-1;     sr.Bottom=w_rows-1;     xy.X=0;     xy.Y=0;     ci.Char.UnicodeChar=0x20;     ci.Attributes=curattr;     ScrollConsoleScreenBuffer(hcons, &sr, NULL, xy, &ci);    #else     #error BUG: wputch() routine not implemented    #endif    row--;   }   gotoxy(column, row);  } #elif CONSOLE_SET==CT_ANSI  putchar(c); #endif}#endif/* High-level functions, dropped for ANSI */#if CONSOLE_SET!=CT_ANSI/* Borland calls this cprintf(). We call this scrprintf(). */#if CONSOLE_SET!=CT_BORLAND&&defined(ARJDISP)void scrprintf(char *fmt, ...){ char text[1024]; va_list marker; va_start(marker, fmt); vsprintf(text, fmt, marker); va_end(marker); scr_out(text);}#endif#endif  /* !CT_ANSI *//* A general routine for outputting unformatted text onto screen */#if defined(ARJDISP)||defined(COLOR_OUTPUT)void scr_out(char *str){ #if CONSOLE_SET==CT_BORLAND  #ifdef ARJDISP   char strform[]="%s";  #endif  kbhit();  cprintf(strform, str); #elif CONSOLE_SET==CT_MSGRAPH  /* Needs a special hack. Microsoft allows the backspace character to be     passed. */  char t[128];  int i=0;  int xpos;  while(str[0]!='\0')  {   kbhit();                             /* To check for Ctrl+C */   while(str[i]!='\0'&&(i<sizeof(t)-1))   {    if(str[i]==8)    {     if(i>0)     {      t[i]='\0';      str+=i;      i=0;      _outtext((char FAR *)t);     }     str++;     xpos=wherex()-1;     _settextposition(wherey(), max(xpos, 1));    }    else    {     t[i]=str[i];     i++;    }   }   t[i]='\0';   _outtext((char FAR *)t);   str+=i;   i=0;  }  if(i>0)  {   t[i]='\0';   _outtext((char FAR *)t);  } #elif CONSOLE_SET==CT_NATIVE||CONSOLE_SET==CT_ANSI  char *t_ptr;  #if TARGET==DOS   kbhit();                             /* To check for Ctrl+C */  #endif  for(t_ptr=str; *t_ptr!='\0'; t_ptr++)   wputch((int)*t_ptr); #else  #error scr_out() not implemented #endif}#endif/* For ANSI, we have to reset the terminal. Do it here (on other console   types, it's a null macro) */#if CONSOLE_SET==CT_ANSIvoid scrn_reset(){ printf("\x1B[0m\n");}#endif/* Helper routine for ARJ to know the screen height */int query_screen_height(){#ifdef KNOW_DIMENSIONS get_dimensions(); return(w_rows);#else return(25);#endif}/* Prepares for wrapping around the right margin if the given length exceeds   it */void check_wrap(int i){ #if SFX_LEVEL>=ARJ&&defined(KNOW_DIMENSIONS)&&(defined(ARJDISP)||defined(COLOR_OUTPUT))  if(wherex()+i>w_columns)   scr_out(lf); #endif}

⌨️ 快捷键说明

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