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

📄 console.c

📁 dos下一个强大的文本编辑器,支持多文档、多窗口、二进制文件编辑。
💻 C
📖 第 1 页 / 共 4 页
字号:
      else if (scan == 15) {
         lo = 268;
      }

      /*
       * if scan code is not 0, then a Control key was pressed.  Map
       *  those keys to the WordStar commands.
       */
      else if (scan > 0)
         lo += 430;

   } else if (!num_lock) {
      switch (scan) {
         /*
          * scan code for grey - == 74.  if num_lock is not toggled, assign it
          *  to the scroll line up function.
          */
         case 74 :
            lo = 423;
            break;

         /*
          * scan code for grey + == 78.  if num_lock is not toggled, assign it
          *  to the scroll line down function.  if shift grey + then stationary
          *  scroll down.
          */
         case 78 :
            lo = 424;
            break;
      }
   }


   /*
    * let's set up for the Shift+Alt and Control+Alt keys.
    *  With these key combinations, we can do the International keyboard
    *  stuff, see the Microsoft MS DOS 5.0 manual pages 623-637.
    */
   if (lo > 256 && (shift || control)) {

      /*
       * add 55 to Ctrl+Left thru Ctrl+Home when the shift key is pressed.
       *  this is not part of the International keyboard stuff, just a way
       *  to assign the horizontal scroll left and right funcs to cursor keys.
       */
      if (shift) {
         if (lo >= 371 && lo <= 374)
            lo += 55;

         /*
          * if shift is down, map alt 1! thru alt =+ to shift alt 1! thru alt =+
          */
         else if (lo >= 376 && lo <= 387)
            lo += 86;

         /*
          * internation keyboard stuff
          */
         else if (lo >= 272 && lo <= 309)
            lo += 202;
      }
   }

   /*
    * map the enter key to line feed.
    */
   if (lo == 10  &&  scan != 0)
      lo = 425;
   return( lo );
}


/*
 * Name:    waitkey
 * Purpose: call the BIOS keyboard status subfunction
 * Date:    October 31, 1992
 * Passed:  enh_keyboard:  boolean - TRUE if 101 keyboard, FALSE otherwise
 * Returns: 1 if no key ready, 0 if key is waiting
 * Notes:   lets get the keyboard status so we can spin on this function until
 *           the user presses a key.  some OS replacements for DOS want
 *           application programs to poll the keyboard instead of rudely
 *           sitting on the BIOS read key function.
 */
int  waitkey( int enh_keyboard )
{
   return( _bios_keybrd( enh_keyboard ? 0x11 : 0x01 ) == 0 ? 1 : 0 );
}


/*
 * Name:    getfunc
 * Purpose: get the function assigned to key c
 * Date:    July 11, 1991
 * Passed:  c:  key just pressed
 * Notes:   key codes less than 256 or 0x100 are not assigned a function.
 *           The codes in the range 0-255 are ASCII and extended ASCII chars.
 */
int getfunc( int c )
{
register int i = c;
int  key_found;

   if (!g_status.key_pending) {
      i = c;
      if (i <= 256)
         i = 0;
      else
         i = key_func.key[i-256];
   } else {

      /*
       * allow the user to enter two-key combinations
       */
      key_found = FALSE;
      for (i=0; i < MAX_TWO_KEYS; i++) {
         if (g_status.first_key == two_key_list.key[i].parent_key &&
                               c == two_key_list.key[i].child_key) {
            i = two_key_list.key[i].func;
            key_found = TRUE;
            break;
         }
      }
      if (key_found == FALSE)
         i = ERROR;
   }
   return( i );
}


/*
 * Name:    two_key
 * Purpose: set the two_key flag and prompt for the next key.
 * Date:    April 1, 1992
 * Notes:   this function accepts two key commands.
 */
int  two_key( WINDOW *arg_filler )
{
   s_output( "Next Key..", g_display.mode_line, 67, g_display.diag_color );
   g_status.key_pending = TRUE;
   g_status.first_key = g_status.key_pressed;
   return( OK );
}


/*
 * Name:    flush_keyboard
 * Purpose: flush keys from the keyboard buffer
 * Date:    June 5, 1993
 * Passed:  enh_keyboard:  boolean - TRUE if 101 keyboard, FALSE otherwise
 * Returns: 1 if no key ready, 0 if key is waiting
 * Notes:   lets get the keyboard status so we can spin on this function until
 *           the user presses a key.  some OS replacements for DOS want
 *           application programs to poll the keyboard instead of rudely
 *           sitting on the BIOS read key function.
 */
void flush_keyboard( void )
{
   if (mode.enh_kbd) {
      while (!waitkey( mode.enh_kbd ))
         _bios_keybrd( 0x10 );
   } else {
      while (!waitkey( mode.enh_kbd ))
         _bios_keybrd( 0 );
   }
}


/*********************************************/
/*                                           */
/*  3) video output routines, PC specific    */
/*                                           */
/*********************************************/


/*
 * Name:    xygoto
 * Purpose: To move the cursor to the required column and line.
 * Date:    September 28, 1991
 * Passed:  col:    desired column (0 up to max)
 *          line:   desired line (0 up to max)
 * Notes;   use standard BIOS video interrupt 0x10 to set the set.
 */
void xygoto( int col, int line )
{
union REGS inregs, outregs;

   inregs.h.ah = 2;
   inregs.h.bh = 0;
   inregs.h.dh = (unsigned char)line;
   inregs.h.dl = (unsigned char)col;
   int86( 0x10, &inregs, &outregs );
}


/*
 * Name:    update_line
 * Purpose: Display the current line in window
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Show string starting at column zero and if needed blank rest
 *           of line.  Put max_col in cx and count down.  When we run into
 *           len, cx contains number of columns to blank out.  Use the
 *           fast 'rep stosw' to clear the end of line.
 *          The C routine was probably fast enough, but let's do some
 *           assembly because it's so fun.
 *          To handle line lengths longer than 255 characters,
 *           block begin and end columns were changed from real
 *           to virtual columns in this display routine.
 */
void update_line( WINDOW *window )
{
text_ptr text;      /* current character of orig begin considered */
char far *screen_ptr;
int  off;
int  attr;
int  line;
int  col;
int  bcol;
int  bc;
int  ec;
int  normal;
int  block;
int  max_col;
int  block_line;
int  len;
int  show_eol;
int  c;
long rline;
file_infos *file;

   if (window->rline > window->file_info->length || window->ll->len == EOF
             || !g_status.screen_display)
      return;
   file = window->file_info;
   max_col = window->end_col + 1 - window->start_col;
   line = window->cline;
   normal = window->ll->dirty == FALSE ? g_display.text_color : g_display.dirty_color;
   block = g_display.block_color;
   show_eol = mode.show_eol;

   /*
    * set the screen pointer to physical screen memory.
    *       160 = 80 chars + 80 attr  for each line
    */
   screen_ptr = g_display.display_address;
   off = line * 160 + window->start_col * 2;

   /*
    * figure which line to display.
    * actually, we could be displaying any line in any file.  we display
    *  the line_buffer only if window->ll == g_status.buff_node
    *  and window->ll-line has been copied to g_status.line_buff.
    */
   text = window->ll->line;
   len  = window->ll->len;
   if (g_status.copied && ptoul( window->ll ) == ptoul( g_status.buff_node )) {
      text = (text_ptr)g_status.line_buff;
      len  = g_status.line_buff_len;
   }
   if (mode.inflate_tabs)
      text = tabout( text, &len );

   /*
    * lets look at the base column.  if the line to display is shorter
    *  than the base column, then set text to eol and we can't see the
    *  eol either.
    */
   bc = window->bcol;
   if (bc > 0) {
      if (text == NULL) {
         show_eol = FALSE;
         len = 0;
      } else {
         if ((col = len) < bc) {
            bc = col;
            show_eol = FALSE;
         }
         text += bc;
         len  -= bc;
      }
   }

   /*
    * for display purposes, set the line length to screen width if line
    *  is longer than screen.  our assembly routine uses bytes and the
    *  the line length can be longer than a byte.
    */
   if (len > max_col)
      len = max_col;

   bcol = window->bcol;
   rline = window->rline;
   if (file->block_type && rline >= file->block_br && rline <= file->block_er)
      block_line = TRUE;
   else
      block_line = FALSE;

   /*
    * do this if 1) a box block is marked, or 2) a stream block begins
    *  and ends on the same line.
    */
   if (block_line == TRUE && (file->block_type == BOX ||
         (file->block_type == STREAM &&
         rline == file->block_br && rline == file->block_er))) {

      /*
       * start with the bc and ec equal to physical block marker.
       */
      bc = file->block_bc;
      ec = file->block_ec;
      if (ec < bcol || bc >= bcol + max_col)
         /*
          * we can't see block if ending column is less than the base col or
          *  the beginning column is greater than max_col.
          */
         ec = bc = max_col + 1;
      else if (ec < bcol + max_col) {
         /*
          * if the ec is less than the max column, make ec relative to
          *  base column then figure the bc.
          */
         ec = ec - bcol;
         if (bc < bcol)
            bc = 0;
         else
            bc = bc - bcol;
      } else if (bc < bcol + max_col) {
         /*
          * if the bc is less than the max column, make bc relative to
          *  base column then figure the ec.
          */
         bc = bc - bcol;
         if (ec > bcol + max_col)
            ec = max_col;
         else
            ec = ec - bcol;
      } else if (bc < bcol  &&  ec >= bcol + max_col) {
         /*
          * if the block is wider than the screen, make bc start at the
          *  logical begin and make ec end at the logical end of the
          *  window.
          */
         bc = 0;
         ec = max_col;
      }


   ASSEMBLE {
        /*
        ; Register strategy:
        ;   bl == beginning column
        ;   bh == ending column
        ;   dl == normal text attribute
        ;   dh == block attribute
        ;   cl == current virtual column
        ;   ch == maximum columns in window
        ;   ES:DI == screen pointer (destination)
        ;   DS:SI == text pointer (source)
        ;   [bp+show_eol]  == access for local C variable
        */


        push    ds                      /* MUST save ds - push it on stack */
        push    si                      /* save si on stack */
        push    di                      /* save di on stack */

/*
;
; set up local register variables
;
*/
        mov     ax, WORD PTR bc         /* get beginning column */
        mov     bl, al                  /* keep it in bl */
        mov     ax, WORD PTR ec         /* get ending column */
        mov     bh, al                  /* keep it in bh */
        mov     ax, WORD PTR normal     /* get normal attribute */

⌨️ 快捷键说明

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