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

📄 window.c

📁 THOMSON-DAVIS用C语言开发的编缉器,简单,易懂.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************  start of original comments  ********************/
/*
 * Written by Douglas Thomson (1989/1990)
 *
 * This source code is released into the public domain.
 */

/*
 * Name:    dte - Doug's Text Editor program - window module
 * Purpose: This file contains the code associated with opening and sizing
 *           windows, and also displaying the help window.
 * File:    window.c
 * Author:  Douglas Thomson
 * System:  this file is intended to be system-independent
 * Date:    October 12, 1989
 */
/*********************  end of original comments   ********************/


/*
 * The window routines have been EXTENSIVELY rewritten.  Some routines were
 * changed so only one logical function is carried out, eg. 'initialize_window'.
 * I like the Microsoft way of resizing windows - just press the up and down
 * arrows to adjust the window to desired size.  I also like pressing one key
 * to change windows.  All of which are implemented in TDE.
 *
 * In TDE, version 1.4, I added support for vertical windows.
 *
 * New editor name:  TDE, the Thomson-Davis Editor.
 * Author:           Frank Davis
 * Date:             June 5, 1991, version 1.0
 * Date:             July 29, 1991, version 1.1
 * Date:             October 5, 1991, version 1.2
 * Date:             January 20, 1992, version 1.3
 * Date:             February 17, 1992, version 1.4
 * Date:             April 1, 1992, version 1.5
 * Date:             June 5, 1992, version 2.0
 * Date:             October 31, 1992, version 2.1
 * Date:             April 1, 1993, version 2.2
 * Date:             June 5, 1993, version 3.0
 *
 * This modification of Douglas Thomson's code is released into the
 * public domain, Frank Davis.  You may distribute it freely.
 */

#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"


/*
 * Name:    initialize_window
 * Purpose: To open a new window
 * Date:    June 5, 1991
 * Returns: OK if window opened successfully
 *          ERROR if anything went wrong
 * Notes:   If this is first window, then set up as normal displayed window;
 *          otherwise, make the present window invisible and open a new
 *          window in the same screen location as the old one.
 */
int  initialize_window( void )
{
int  top;
int  bottom;
int  start_col;
int  end_col;
WINDOW *wp;        /* used for scanning windows */
WINDOW *window;
register file_infos *fp;     /* used for scanning files */
register int rc;
line_list_ptr ll;
line_list_ptr temp_ll;

   rc = OK;
   window = g_status.current_window;
   fp = g_status.current_file;
   if (window == NULL) {
      /*
       * special case if this is the first window on screen.
       */
      top = start_col = 0;
      bottom  = g_display.nlines;
      end_col = g_display.ncols - 1;
   } else {
      /*
       * else put the new window in same place as current window.
       *  make current window invisible.  new window becomes current window.
       */
      top       = window->top_line - 1;
      bottom    = window->bottom_line;
      start_col = window->start_col;
      end_col   = window->end_col;
   }

   assert( top < bottom );
   assert( start_col < end_col );
   assert( fp != NULL );

   if (create_window( &wp, top, bottom, start_col, end_col, fp ) == ERROR) {
      /*
       * out of memory
       */
      error( WARNING, bottom, main4 );

      /*
       * This is a real nuisance. We had room for the file and the
       *  file structure, but not enough for the window as well.
       * Now we must free all the memory that has already been
       *  allocated.
       */
      if (fp->ref_count == 0) {

         /*
          * remove fp from file pointer list.
          */
         if (fp->prev != NULL)
            fp->prev->next = fp->next;
         else
            g_status.file_list = fp->next;

         if (fp->next != NULL)
            fp->next->prev = fp->prev;

         /*
          * free the undo stack, line pointers, and linked list.
          */

         ll = fp->undo_top;
         while (ll != NULL) {
            temp_ll = ll->next;
            if (ll->line != NULL)
               my_free( ll->line );
            my_free( ll );
            ll = temp_ll;
         }

         ll = fp->line_list;
         while (ll != NULL) {
            temp_ll = ll->next;
            if (ll->line != NULL)
               my_free( ll->line );
            my_free( ll );
            ll = temp_ll;
         }

#if defined( __MSC__ )
         _fheapmin( );
#endif

         free( fp );
         wp = g_status.current_window;
         if (wp != NULL && wp->visible)
            g_status.current_file = wp->file_info;
         else
            g_status.stop = TRUE;
      }
      rc = ERROR;
   }

   if (rc != ERROR) {
      /*
       * set up the new cursor position as appropriate
       */
      wp->ccol = wp->start_col;
      wp->rcol = wp->bcol = 0;
      wp->rline = 1L;
      wp->ll    = fp->line_list;
      wp->visible = TRUE;
      wp->letter = fp->next_letter++;
      if (window != NULL)
         window->visible = FALSE;

      /*
       * the new window becomes the current window.
       */
      g_status.current_window = wp;
   }
   return( rc );
}


/*
 * Name:    next_window
 * Purpose: To move to the next visible window.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Start with current window.  If next window exists then go to it
 *           else go to the first (top) window on screen.
 *          When I added vertical windows, finding the "correct" next
 *           window became extremely, unnecessarily, unmanageably complicated.
 *           let's just use a simple procedure to find the first available,
 *           visible, next window.
 */
int  next_window( WINDOW *window )
{
register WINDOW *wp;
int  change;

   if (window != NULL) {
      change = FALSE;
      /*
       * start with current window and look for first next
       *  visible window
       */
      wp = window->next;
      while (wp != NULL) {
         if (wp->visible) {
            change = TRUE;
            break;
         }
         wp = wp->next;
      }

      /*
       * if we haven't found a visible window yet, go to the beginning of
       *  the list until we find a visible window.
       */
      if (!change) {
         wp = g_status.window_list;
         while (wp != window) {
            if (wp->visible) {
               change = TRUE;
               break;
            }
            wp = wp->next;
         }
      }
      if (change == TRUE) {
         entab_linebuff( );
         un_copy_line( window->ll, window, TRUE );
         g_status.current_window = wp;
         g_status.current_file = wp->file_info;
      }
   }
   return( OK );
}


/*
 * Name:    prev_window
 * Purpose: To move to the previous visible window.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   Start with current window.  If previous window exists then go to
 *           it else go to the last (bottom) window on screen.  Opposite of
 *           next_window.
 *          when I added vertical windows, finding the "correct" previous
 *           window became extremely, unnecessarily, unmanageably complicated.
 *           let's just use a simple procedure to find the first available,
 *           visible, previous window.
 */
int  prev_window( WINDOW *window )
{
register WINDOW *wp;
int  change;

   if (window != NULL) {
      change = FALSE;

      /*
       * start with current window and look for first previous
       *  visible window
       */
      wp = window->prev;
      while (wp != NULL) {
         if (wp->visible) {
            change = TRUE;
            break;
         }
         wp = wp->prev;
      }

      /*
       * if we haven't found a visible window yet, go to the end of
       *  the list and work backwards until we find a visible window.
       */
      if (!change) {
         wp = window->next;
         if (wp != NULL) {
            while (wp->next != NULL)
               wp = wp->next;
            while (wp != window) {
               if (wp->visible) {
                  change = TRUE;
                  break;
               }
               wp = wp->prev;
            }
         }
      }
      if (change == TRUE) {
         entab_linebuff( );
         un_copy_line( window->ll, window, TRUE );
         g_status.current_window = wp;
         g_status.current_file = wp->file_info;
      }
   }
   return( OK );
}


/*
 * Name:    split_horizontal
 * Purpose: To split screen horizontally at the cursor.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   split the screen horizontally at the cursor position.
 */
int  split_horizontal( WINDOW *window )
{
register WINDOW *wp;
register WINDOW *win;   /* register pointer for window */
WINDOW *temp;
file_infos *file;       /* file structure for file belonging to new window */
int  rc;

   rc = OK;
   win = window;
   if ( win != NULL) {

      /*
       * check that there is room for the window
       */
      if (win->bottom_line - win->cline < 2) {
         /*
          * move cursor up first
          */
         error( WARNING, win->bottom_line, win1 );
         rc = ERROR;
      } else {
         file = win->file_info;

         assert( file != NULL );

         if (create_window( &temp, win->cline+1, win->bottom_line,
                            win->start_col, win->end_col, file ) == ERROR) {
            /*
             * out of memory
             */
            error( WARNING, win->bottom_line, main4 );
            rc = ERROR;
         }
         if (rc == OK  &&  temp != NULL) {
            entab_linebuff( );
            un_copy_line( win->ll, win, TRUE );
            wp = temp;
            /*
             * record that the current window has lost some lines from
             *  the bottom for the new window, and adjust its page size
             *  etc accordingly.
             */
            win->bottom_line = win->cline;
            setup_window( win );
            display_current_window( win );

            /*
             * set up the new cursor position as appropriate
             */
            wp->rcol = win->rcol;
            wp->ccol = win->ccol;
            wp->bcol = win->bcol;
            wp->rline = win->rline;
            wp->bin_offset = win->bin_offset;
            wp->ll    = win->ll;
            wp->cline = wp->cline + win->cline - (win->top_line + win->ruler);
            if (wp->cline > wp->bottom_line)
               wp->cline = wp->bottom_line;
            wp->visible = TRUE;
            wp->vertical = win->vertical;
            wp->letter = file->next_letter++;
            wp->ruler  = mode.ruler;

            /*
             * the new window becomes the current window.
             */
            g_status.current_window = wp;

            show_window_count( g_status.window_count );
            show_window_header( wp );
            display_current_window( wp );
            if (wp->vertical)
               show_vertical_separator( wp );
            make_ruler( wp );
            show_ruler( wp );
            rc = OK;
         }
      }
   } else
      rc = ERROR;
   return( rc );
}


/*
 * Name:    split_vertical
 * Purpose: To split screen vertically at the cursor.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   split the screen vertically at the cursor position.
 */
int  split_vertical( WINDOW *window )
{
register WINDOW *wp;
register WINDOW *win;   /* register pointer for window */
WINDOW *temp;
file_infos *file;       /* file structure for file belonging to new window */
int  rc;

   rc = OK;
   win = window;
   if (win != NULL) {

      /*
       * check that there is room for the window
       */
      if (win->start_col + 15 > win->ccol) {
         /*
          * move cursor right first
          */
         error( WARNING, win->bottom_line, win2 );
         rc = ERROR;
      } else if (win->end_col - 15 < win->ccol) {

⌨️ 快捷键说明

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