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

📄 slvideo.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 1992, 1995 John E. Davis
 * All rights reserved.
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Perl Artistic License.
 */

#include "config.h"

#include <stdio.h>
#include <string.h>

#include <stdlib.h>

#ifdef __WIN32__
# include <windows.h>
#endif

#ifdef __GO32__
# undef msdos
#endif

#if defined (msdos)
# include <conio.h>
# include <bios.h>
# include <mem.h>
#endif
#if defined (__WATCOMC__)
# include <graph.h>
# define int86	int386		/* simplify code writing */
#endif

#if defined (__GO32__)
# include <pc.h>
# define GO32_VIDEO
#endif

#if defined (__os2__) && !defined (EMX_VIDEO)
# define INCL_BASE
# define INCL_NOPM
# define INCL_VIO
# define INCL_KBD
# include <os2.h>
#else
# if defined (__EMX__)		/* EMX video does both DOS & OS/2 */
#  ifndef EMX_VIDEO
#   define EMX_VIDEO
#  endif
#  include <sys/video.h>
# endif
#endif

#include <dos.h>
#include "slang.h"

#ifdef GO32_VIDEO
# define HAS_SAVE_SCREEN
#endif

/* ------------------------- global variables ------------------------- */

#ifdef WIN32
extern HANDLE hStdout, hStdin;
extern CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
#endif


int SLtt_Term_Cannot_Insert;
int SLtt_Term_Cannot_Scroll;
int SLtt_Ignore_Beep = 3;
int SLtt_Use_Ansi_Colors;

int SLtt_Screen_Rows = 25;
int SLtt_Screen_Cols = 80;

/* ------------------------- local variables -------------------------- */
static int Attribute_Byte;
static int Scroll_r1 = 0, Scroll_r2 = 25;
static int Cursor_Row = 1, Cursor_Col = 1;
static int Current_Color;
static int IsColor = 1;
static int Blink_Killed;	/* high intensity background enabled */

#define JMAX_COLORS	256
#define JNORMAL_COLOR	0
#define JNO_COLOR	-1

static unsigned char Color_Map [JMAX_COLORS] =
{
   0x7, 0x70, 0x70, 0x70, 0x70, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
   0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7
};


#define JMAX_COLOR_NAMES 16
static char *Color_Names [JMAX_COLOR_NAMES] =
{
   "black", "blue", "green", "cyan",
     "red", "magenta", "brown", "lightgray",
     "gray", "brightblue", "brightgreen", "brightcyan",
     "brightred", "brightmagenta", "yellow", "white"
};

/*
 * set_color_from_attribute (int attribute);
 * define the correspondence of color to attribute
 */
#define set_color_from_attribute(a)\
	SLtt_set_color (\
			JNORMAL_COLOR, NULL,\
			Color_Names[(a) & 0xf],\
			Color_Names[(a) >> 4])
/* this is how to make a space character */
#define mkSpaceChar()	(((Attribute_Byte) << 8) | 0x20)

/* buffer to hold a line of character/attribute pairs */
#define MAXCOLS 256
static unsigned char Line_Buffer [MAXCOLS*2];

/*----------------------------------------------------------------------*\
 * define various ways and means of writing to the screen
\*----------------------------------------------------------------------*/
#if defined (__GO32__) || defined (__WATCOMC__)
# if !defined (GO32_VIDEO)
#  define HAS_LINEAR_SCREEN
# endif
#else	/* __GO32__ or __WATCOMC__ */
# if defined (msdos)
#  define USE_ASM
# endif
#endif	/* __GO32__ or __WATCOMC__ */

/* define for direct to memory screen writes */
#if defined (USE_ASM) || defined (HAS_LINEAR_SCREEN)
static unsigned char *Video_Base;
# define mkScreenPointer(row,col)	((unsigned short *)\
					 (Video_Base +\
					  2 * (SLtt_Screen_Cols * (row)\
					       + (col))))
# if defined (USE_ASM)
int SLtt_Msdos_Cheap_Video = 0;
static int Video_Status_Port;

#  define MONO_STATUS	0x3BA
#  define CGA_STATUS	0x3DA
#  define CGA_SETMODE	0x3D8

#  define SNOW_CHECK \
if (SLtt_Msdos_Cheap_Video)\
{ while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); }
# endif	/* USE_ASM */
#endif	/* USE_ASM or HAS_LINEAR_SCREEN */


/* -------------------------------------------------------------------- */
#if defined (__WATCOMC__)
# define ScreenPrimary	(0xb800 << 4)
# define ScreenSize	(SLtt_Screen_Cols * SLtt_Screen_Rows)
# define ScreenSetCursor (x,y) _settextposition (x+1,y+1)
void ScreenGetCursor (int *x, int *y)
{
   struct rccoord rc = _gettextposition ();
   *x = rc.row - 1;
   *y = rc.col - 1;
}
void ScreenRetrieve (unsigned char *dest)
{
   memcpy (dest, (unsigned char *) ScreenPrimary, 2 * ScreenSize);
}
void ScreenUpdate (unsigned char *src)
{
   memcpy ((unsigned char *) ScreenPrimary, src, 2 * ScreenSize);
}
#endif	/* __WATCOMC__ */

#ifdef HAS_SAVE_SCREEN
static void *Saved_Screen_Buffer;
static int Saved_Cursor_Row;

static void save_screen (void)
{
   int row, col;

   if (Saved_Screen_Buffer != NULL)
     {
	SLFREE (Saved_Screen_Buffer);
	Saved_Screen_Buffer = NULL;
     }
#ifdef GO32_VIDEO
   Saved_Screen_Buffer = SLMALLOC (sizeof (short) *
				   ScreenCols () * ScreenRows ());

   if (Saved_Screen_Buffer == NULL)
     return;

   ScreenRetrieve (Saved_Screen_Buffer);
   ScreenGetCursor (&row, &col);
   Saved_Cursor_Row = row;
#endif

}

static void restore_screen (void)
{
   if (Saved_Screen_Buffer == NULL) return;
#ifdef GO32_VIDEO
   ScreenUpdate (Saved_Screen_Buffer);
   SLtt_goto_rc (Saved_Cursor_Row, 0);
#endif

}
#endif				       /* HAS_SAVE_SCREEN */
/*----------------------------------------------------------------------*\
 * Function:	void SLtt_write_string (char *str);
 *
 * put string STR to 'stdout'
\*----------------------------------------------------------------------*/
void SLtt_write_string (char *str)
{
#ifdef WIN32
   unsigned long bytes;

   (void) WriteConsole(hStdout, str, strlen(str), &bytes, NULL);
#else
   fputs (str, stdout);
#endif
}

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_set_scroll_region (int r1, int r2);
 *
 * define a scroll region of top_row to bottom_row
\*----------------------------------------------------------------------*/
void SLtt_set_scroll_region (int top_row, int bottom_row)
{
   Scroll_r1 = top_row;
   Scroll_r2 = bottom_row;
}

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_reset_scroll_region (void);
 *
 * reset the scrol region to be the entire screen,
 * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows);
\*----------------------------------------------------------------------*/
void SLtt_reset_scroll_region (void)
{
   Scroll_r1 = 0;
   Scroll_r2 = SLtt_Screen_Rows;
}

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_goto_rc (int row, int col);
 *
 * move the terminal cursor to x,y position COL, ROW and record the
 * position in Cursor_Row, Cursor_Col
\*----------------------------------------------------------------------*/
void SLtt_goto_rc (int row, int col)
{
#ifdef WIN32
   COORD newPosition;
   newPosition.X = col;
   newPosition.Y = row;
#endif

#if !defined (USE_ASM)
   if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
   if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
# if defined (EMX_VIDEO)
   v_gotoxy (col, Scroll_r1 + row);
# else /* EMX_VIDEO_ */
#  if defined (__os2__)
   VioSetCurPos (Scroll_r1 + row, col, 0);
#  elif defined(WIN32)
   (void) SetConsoleCursorPosition(hStdout, newPosition);
#  else /* __os2__ */
#   if defined (__GO32__) || defined (__WATCOMC__)
   ScreenSetCursor(Scroll_r1 + row, col);
#   endif	/* __GO32__ or __WATCOMC__ */
#  endif /* __os2__ */
# endif /* EMX_VIDEO_ */
   Cursor_Row = row;
   Cursor_Col = col;
#else	/* USE_ASM */
   /* if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1; */
   asm  mov ax, row
     asm  mov bx, SLtt_Screen_Rows
     asm  dec bx
     asm  cmp ax, bx
     asm  jle L1
     asm  mov ax, bx
     L1:
   /* if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1; */
   asm  mov cx, SLtt_Screen_Cols
     asm  dec cx
     asm  mov bx, col
     asm  cmp bx, cx
     asm  jle L2
     asm  mov bx, cx
     L2:
   asm  mov Cursor_Row, ax
     asm  mov Cursor_Col, bx
     asm  add ax, Scroll_r1
     asm  xor dx, dx
     asm  mov dh, al
     asm  mov dl, bl
     asm  xor bx, bx
     asm  mov ax, 0x200
     asm  int 0x10
#endif	/* USE_ASM */
}

/*----------------------------------------------------------------------*\
 * Function:	static void slvid_getxy (void);
 *
 * retrieve the cursor position into Cursor_Row, Cursor_Col
\*----------------------------------------------------------------------*/
static void slvid_getxy (void)
{
#if !defined (USE_ASM)
# if defined (EMX_VIDEO)
   v_getxy (&Cursor_Col, &Cursor_Row);
# else	/* EMX_VIDEO */
#  if defined (__os2__)
   VioGetCurPos ((USHORT*) &Cursor_Row, (USHORT*) &Cursor_Col, 0);
#  elif defined(WIN32)
   CONSOLE_SCREEN_BUFFER_INFO screenInfo;
   if (GetConsoleScreenBufferInfo(hStdout, &screenInfo) == TRUE)
     {
	Cursor_Row = screenInfo.dwCursorPosition.Y;
	Cursor_Col = screenInfo.dwCursorPosition.X;
     }
#  else	/* __os2__ */
#   if defined (__GO32__) || defined (__WATCOMC__)
   ScreenGetCursor (&Cursor_Row, &Cursor_Col);
#   endif	/* __GO32__ or __WATCOMC__ */
#  endif	/* __os2__ */
# endif	/* EMX_VIDEO */
#else	/* USE_ASM */
   asm  mov ah, 3
     asm  mov bh, 0
     asm  int 10h
     asm  xor ax, ax
     asm  mov al, dh
     asm  mov Cursor_Row, ax
     asm  xor ax, ax
     asm  mov al, dl
     asm  mov Cursor_Col, ax
#endif	/* USE_ASM */
}

/*----------------------------------------------------------------------*\
 * static void slvid_deleol (int x);
 *
 * write space characters from column X of row Cursor_Row through to
 * SLtt_Screen_Cols using the current Attribute_Byte
\*----------------------------------------------------------------------*/
#if defined (GO32_VIDEO)
static void slvid_deleol (int x)
{
   while (x < SLtt_Screen_Cols)
     ScreenPutChar (32, Attribute_Byte, x++, Cursor_Row);
}
#endif
#if defined (EMX_VIDEO)
static void slvid_deleol (int x)
{
   unsigned char *p, *pmax;
   int w = mkSpaceChar ();
   int count = SLtt_Screen_Cols - x;

   p = Line_Buffer;
   pmax = p + 2 * count;

   while (p < pmax)
     {
	*p++ = (unsigned char) w;
	*p++ = (unsigned char) (w >> 8);
     }

   v_putline (Line_Buffer, x, Cursor_Row, count);
}
#endif	/* EMX_VIDEO */

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_begin_insert (void);
 *
 * insert a single space, moving everything right 1 character to make room
\*----------------------------------------------------------------------*/
void SLtt_begin_insert (void)
{
#if !defined (GO32_VIDEO)
# if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM)
   unsigned short *p;
#  if defined (HAS_LINEAR_SCREEN)
   unsigned short *pmin;
#  endif
# endif
   int n;
   slvid_getxy ();
   n = SLtt_Screen_Cols - Cursor_Col;
   /* Msdos_Insert_Mode = 1; */

# ifndef WIN32
#  if defined (EMX_VIDEO)
   v_getline (Line_Buffer, Cursor_Col, Cursor_Row, n);
   v_putline (Line_Buffer, Cursor_Col+1, Cursor_Row, n - 1);
#  else	/* EMX_VIDEO */
#   if defined (__os2__)
   n = 2 * (n - 1);
   VioReadCellStr ((PCH)Line_Buffer, (USHORT*) &n, Cursor_Row, Cursor_Col, 0);
   VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col + 1, 0);
#   else	/* __os2__ */
   p = mkScreenPointer (Cursor_Row, SLtt_Screen_Cols - 1);

#    if defined (HAS_LINEAR_SCREEN)
   /* pmin = p - (n-1); */
   pmin = mkScreenPointer (Cursor_Row, Cursor_Col);
   while (p-- > pmin) *(p + 1) = *p;
#    else
   SNOW_CHECK;
   asm  mov ax, ds
     asm  mov bx, di
     asm  mov dx, si

     asm  mov cx, n
     asm  les di, p
     asm  lds si, p
     asm  sub si, 2
     asm  std
     asm  rep movsw

     asm  mov ds, ax
     asm  mov di, bx
     asm  mov si, dx
#    endif	/* HAS_LINEAR_SCREEN */
#   endif  /* __os2__ */
#  endif	/* EMX_VIDEO */

# endif  /* WIN32 */

#endif	/* not GO32_VIDEO */
}

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_end_insert (void);
 *
 * any cleanup after insert a blank column
\*----------------------------------------------------------------------*/
void SLtt_end_insert (void)
{
}

/*----------------------------------------------------------------------*\
 * Function:	void SLtt_delete_char (void);
 *
 * delete a single character, moving everything left 1 column to take
 * up the room
\*----------------------------------------------------------------------*/
void SLtt_delete_char (void)
{
#if !defined (GO32_VIDEO)
# if defined (HAS_LINEAR_SCREEN) || defined (USE_ASM)
   unsigned short *p;
#  if defined (HAS_LINEAR_SCREEN)
   register unsigned short *p1;
#  endif
# endif
   int n;

   slvid_getxy ();
   n = SLtt_Screen_Cols - Cursor_Col - 1;

# ifndef WIN32

#  if defined (EMX_VIDEO)
   v_getline (Line_Buffer, Cursor_Col+1, Cursor_Row, n);
   v_putline (Line_Buffer, Cursor_Col, Cursor_Row, n);
#  else	/* EMX_VIDEO */
#   if defined (__os2__)
   n *= 2;
   VioReadCellStr ((PCH)Line_Buffer, (USHORT*)&n, Cursor_Row, Cursor_Col + 1, 0);
   VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col, 0);
   return;
#   else	/* __os2__ */
   p = mkScreenPointer (Cursor_Row, Cursor_Col);

#    if defined (HAS_LINEAR_SCREEN)
   while (n--)
     {
	p1 = p + 1;
	*p = *p1;
	p++;
     }
#    else	/* HAS_LINEAR_SCREEN */
   SNOW_CHECK;
   asm  mov ax, ds
     asm  mov bx, si
     asm  mov dx, di

     asm  mov cx, n
     asm  les di, p

⌨️ 快捷键说明

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