home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 024 / window.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  39KB  |  1,248 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    dte - Doug's Text Editor program - window module
  10.  * Purpose: This file contains the code associated with opening and sizing
  11.  *           windows, and also displaying the help window.
  12.  * File:    window.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 12, 1989
  16.  */
  17. /*********************  end of original comments   ********************/
  18.  
  19.  
  20. /*
  21.  * The window routines have been EXTENSIVELY rewritten.  Some routines were
  22.  * changed so only one logical function is carried out, eg. 'initialize_window'.
  23.  * I like the Microsoft way of resizing windows - just press the up and down
  24.  * arrows to adjust the window to desired size.  I also like pressing one key
  25.  * to change windows.  All of which are implemented in TDE.
  26.  *
  27.  * In TDE, version 1.4, I added support for vertical windows.
  28.  *
  29.  * New editor name:  TDE, the Thomson-Davis Editor.
  30.  * Author:           Frank Davis
  31.  * Date:             June 5, 1991, version 1.0
  32.  * Date:             July 29, 1991, version 1.1
  33.  * Date:             October 5, 1991, version 1.2
  34.  * Date:             January 20, 1992, version 1.3
  35.  * Date:             February 17, 1992, version 1.4
  36.  * Date:             April 1, 1992, version 1.5
  37.  * Date:             June 5, 1992, version 2.0
  38.  * Date:             October 31, 1992, version 2.1
  39.  * Date:             April 1, 1993, version 2.2
  40.  * Date:             June 5, 1993, version 3.0
  41.  *
  42.  * This modification of Douglas Thomson's code is released into the
  43.  * public domain, Frank Davis.  You may distribute it freely.
  44.  */
  45.  
  46. #include "tdestr.h"
  47. #include "common.h"
  48. #include "define.h"
  49. #include "tdefunc.h"
  50.  
  51.  
  52. /*
  53.  * Name:    initialize_window
  54.  * Purpose: To open a new window
  55.  * Date:    June 5, 1991
  56.  * Returns: OK if window opened successfully
  57.  *          ERROR if anything went wrong
  58.  * Notes:   If this is first window, then set up as normal displayed window;
  59.  *          otherwise, make the present window invisible and open a new
  60.  *          window in the same screen location as the old one.
  61.  */
  62. int  initialize_window( void )
  63. {
  64. int  top;
  65. int  bottom;
  66. int  start_col;
  67. int  end_col;
  68. WINDOW *wp;        /* used for scanning windows */
  69. WINDOW *window;
  70. register file_infos *fp;     /* used for scanning files */
  71. register int rc;
  72. line_list_ptr ll;
  73. line_list_ptr temp_ll;
  74.  
  75.    rc = OK;
  76.    window = g_status.current_window;
  77.    fp = g_status.current_file;
  78.    if (window == NULL) {
  79.       /*
  80.        * special case if this is the first window on screen.
  81.        */
  82.       top = start_col = 0;
  83.       bottom  = g_display.nlines;
  84.       end_col = g_display.ncols - 1;
  85.    } else {
  86.       /*
  87.        * else put the new window in same place as current window.
  88.        *  make current window invisible.  new window becomes current window.
  89.        */
  90.       top       = window->top_line - 1;
  91.       bottom    = window->bottom_line;
  92.       start_col = window->start_col;
  93.       end_col   = window->end_col;
  94.    }
  95.  
  96.    assert( top < bottom );
  97.    assert( start_col < end_col );
  98.    assert( fp != NULL );
  99.  
  100.    if (create_window( &wp, top, bottom, start_col, end_col, fp ) == ERROR) {
  101.       /*
  102.        * out of memory
  103.        */
  104.       error( WARNING, bottom, main4 );
  105.  
  106.       /*
  107.        * This is a real nuisance. We had room for the file and the
  108.        *  file structure, but not enough for the window as well.
  109.        * Now we must free all the memory that has already been
  110.        *  allocated.
  111.        */
  112.       if (fp->ref_count == 0) {
  113.  
  114.          /*
  115.           * remove fp from file pointer list.
  116.           */
  117.          if (fp->prev != NULL)
  118.             fp->prev->next = fp->next;
  119.          else
  120.             g_status.file_list = fp->next;
  121.  
  122.          if (fp->next != NULL)
  123.             fp->next->prev = fp->prev;
  124.  
  125.          /*
  126.           * free the undo stack, line pointers, and linked list.
  127.           */
  128.  
  129.          ll = fp->undo_top;
  130.          while (ll != NULL) {
  131.             temp_ll = ll->next;
  132.             if (ll->line != NULL)
  133.                my_free( ll->line );
  134.             my_free( ll );
  135.             ll = temp_ll;
  136.          }
  137.  
  138.          ll = fp->line_list;
  139.          while (ll != NULL) {
  140.             temp_ll = ll->next;
  141.             if (ll->line != NULL)
  142.                my_free( ll->line );
  143.             my_free( ll );
  144.             ll = temp_ll;
  145.          }
  146.  
  147. #if defined( __MSC__ )
  148.          _fheapmin( );
  149. #endif
  150.  
  151.          free( fp );
  152.          wp = g_status.current_window;
  153.          if (wp != NULL && wp->visible)
  154.             g_status.current_file = wp->file_info;
  155.          else
  156.             g_status.stop = TRUE;
  157.       }
  158.       rc = ERROR;
  159.    }
  160.  
  161.    if (rc != ERROR) {
  162.       /*
  163.        * set up the new cursor position as appropriate
  164.        */
  165.       wp->ccol = wp->start_col;
  166.       wp->rcol = wp->bcol = 0;
  167.       wp->rline = 1L;
  168.       wp->ll    = fp->line_list;
  169.       wp->visible = TRUE;
  170.       wp->letter = fp->next_letter++;
  171.       if (window != NULL)
  172.          window->visible = FALSE;
  173.  
  174.       /*
  175.        * the new window becomes the current window.
  176.        */
  177.       g_status.current_window = wp;
  178.    }
  179.    return( rc );
  180. }
  181.  
  182.  
  183. /*
  184.  * Name:    next_window
  185.  * Purpose: To move to the next visible window.
  186.  * Date:    June 5, 1991
  187.  * Passed:  window:  pointer to current window
  188.  * Notes:   Start with current window.  If next window exists then go to it
  189.  *           else go to the first (top) window on screen.
  190.  *          When I added vertical windows, finding the "correct" next
  191.  *           window became extremely, unnecessarily, unmanageably complicated.
  192.  *           let's just use a simple procedure to find the first available,
  193.  *           visible, next window.
  194.  */
  195. int  next_window( WINDOW *window )
  196. {
  197. register WINDOW *wp;
  198. int  change;
  199.  
  200.    if (window != NULL) {
  201.       change = FALSE;
  202.       /*
  203.        * start with current window and look for first next
  204.        *  visible window
  205.        */
  206.       wp = window->next;
  207.       while (wp != NULL) {
  208.          if (wp->visible) {
  209.             change = TRUE;
  210.             break;
  211.          }
  212.          wp = wp->next;
  213.       }
  214.  
  215.       /*
  216.        * if we haven't found a visible window yet, go to the beginning of
  217.        *  the list until we find a visible window.
  218.        */
  219.       if (!change) {
  220.          wp = g_status.window_list;
  221.          while (wp != window) {
  222.             if (wp->visible) {
  223.                change = TRUE;
  224.                break;
  225.             }
  226.             wp = wp->next;
  227.          }
  228.       }
  229.       if (change == TRUE) {
  230.          entab_linebuff( );
  231.          un_copy_line( window->ll, window, TRUE );
  232.          g_status.current_window = wp;
  233.          g_status.current_file = wp->file_info;
  234.       }
  235.    }
  236.    return( OK );
  237. }
  238.  
  239.  
  240. /*
  241.  * Name:    prev_window
  242.  * Purpose: To move to the previous visible window.
  243.  * Date:    June 5, 1991
  244.  * Passed:  window:  pointer to current window
  245.  * Notes:   Start with current window.  If previous window exists then go to
  246.  *           it else go to the last (bottom) window on screen.  Opposite of
  247.  *           next_window.
  248.  *          when I added vertical windows, finding the "correct" previous
  249.  *           window became extremely, unnecessarily, unmanageably complicated.
  250.  *           let's just use a simple procedure to find the first available,
  251.  *           visible, previous window.
  252.  */
  253. int  prev_window( WINDOW *window )
  254. {
  255. register WINDOW *wp;
  256. int  change;
  257.  
  258.    if (window != NULL) {
  259.       change = FALSE;
  260.  
  261.       /*
  262.        * start with current window and look for first previous
  263.        *  visible window
  264.        */
  265.       wp = window->prev;
  266.       while (wp != NULL) {
  267.          if (wp->visible) {
  268.             change = TRUE;
  269.             break;
  270.          }
  271.          wp = wp->prev;
  272.       }
  273.  
  274.       /*
  275.        * if we haven't found a visible window yet, go to the end of
  276.        *  the list and work backwards until we find a visible window.
  277.        */
  278.       if (!change) {
  279.