home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / editors / tde150.arj / HWIND.C < prev    next >
Text File  |  1992-04-01  |  16KB  |  600 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:    hardware independent screen IO module
  10.  * Purpose: This file contains the code to interface the rest of the
  11.  *           editor to the display and input hardware.
  12.  * File:    hwind.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 2, 1989
  16.  * Notes:   This is the only module that is allowed to call the hardware
  17.  *           dependent display IO library.
  18.  *          Typically, functions here check whether any action is
  19.  *           necessary (for example, the cursor may already happen to be
  20.  *           in the required position), call hardware dependent functions
  21.  *           to achieve the required effect, and finally update status
  22.  *           information about the current state of the terminal display.
  23.  *          The idea behind this approach is to keep the hardware
  24.  *           dependent code as small and simple as possible, thus making
  25.  *           porting the code easier.
  26.  */
  27. /*********************  end of original comments   ********************/
  28.  
  29.  
  30. /*
  31.  * Some routines were added to display current editor modes in the lite bar
  32.  * at the bottom of the screen. Other routines were rewritten in assembly.
  33.  * I feel the need for speed.
  34.  *
  35.  * New editor name:  tde, the Thomson-Davis Editor.
  36.  * Author:           Frank Davis
  37.  * Date:             June 5, 1991, version 1.0
  38.  * Date:             July 29, 1991, version 1.1
  39.  * Date:             October 5, 1991, version 1.2
  40.  * Date:             January 20, 1992, version 1.3
  41.  * Date:             February 17, 1992, version 1.4
  42.  * Date:             April 1, 1992, version 1.5
  43.  *
  44.  * This modification of Douglas Thomson's code is released into the
  45.  * public domain, Frank Davis.  You may distribute it freely.
  46.  */
  47.  
  48. #include <bios.h>       /* for REGS */
  49.  
  50. #include "tdestr.h"
  51. #include "common.h"
  52. #include "tdefunc.h"
  53. #include "define.h"
  54.  
  55.  
  56. /*
  57.  * Name:    xygoto
  58.  * Purpose: To move the cursor to the required column and line.
  59.  * Date:    September 28, 1991
  60.  * Passed:  col:    desired column (0 up to max)
  61.  *          line:   desired line (0 up to max)
  62.  */
  63. void xygoto( int col, int line )
  64. {
  65. union REGS inregs, outregs;
  66.  
  67.    inregs.h.ah = 2;
  68.    inregs.h.bh = 0;
  69.    inregs.h.dh = (unsigned char)line;
  70.    inregs.h.dl = (unsigned char)col;
  71.    int86( 0x10, &inregs, &outregs );
  72. }
  73.  
  74.  
  75. /*
  76.  * Name:    save_screen_line
  77.  * Purpose: To save the characters and attributes of a line on screen.
  78.  * Date:    June 5, 1991
  79.  * Passed:  col:    desired column, usually always zero
  80.  *          line:   line to save (0 up to max)
  81.  *          screen_buffer:  buffer for screen contents, must be 160 chars
  82.  * Notes:   Save the contents of the line on screen where prompt is
  83.  *          to be displayed
  84.  */
  85. void save_screen_line( int col, int line, char *screen_buffer )
  86. {
  87. char far *p;
  88.  
  89.    p = g_display.display_address + line * 160 + col * 2;
  90.    _fmemcpy( screen_buffer, p, 160 );
  91. }
  92.  
  93.  
  94. /*
  95.  * Name:    restore_screen_line
  96.  * Purpose: To restore the characters and attributes of a line on screen.
  97.  * Date:    June 5, 1991
  98.  * Passed:  col:    usually always zero
  99.  *          line:   line to restore (0 up to max)
  100.  *          screen_buffer:  buffer for screen contents
  101.  * Notes:   Restore the contents of the line on screen where the prompt
  102.  *          was displayed
  103.  */
  104. void restore_screen_line( int col, int line, char *screen_buffer )
  105. {
  106. char far *p;
  107.  
  108.    p = g_display.display_address + line * 160 + col * 2;
  109.    _fmemcpy( p, screen_buffer, 160 );
  110. }
  111.  
  112.  
  113. /*
  114.  * Name:    cls
  115.  * Purpose: clear screen
  116.  * Date:    June 5, 1991
  117.  * Notes:   Call the video BIOS routine to clear the screen.
  118.  */
  119. void cls( void )
  120. {
  121. int line;
  122.  
  123.    line = g_display.nlines+1;
  124.    _asm {
  125.         xor     ch, ch                  ; starting row in ch = 0
  126.         xor     cl, cl                  ; starting column in cl = 0
  127.         mov     ax, WORD PTR line       ; get ending row
  128.         mov     dh, al                  ; put it in dh
  129.         mov     dl, 79                  ; ending column in dl = 79
  130.         mov     bh, 7                   ; attribute in bh  = 7 (normal)
  131.         mov     al, 0                   ; get number of lines
  132.         mov     ah, 6                   ; get function number
  133.         push    bp                      ; some BIOS versions wipe out bp
  134.         int     0x10
  135.         pop     bp
  136.    }
  137. }
  138.  
  139.  
  140. /*
  141.  * Name:    initialize
  142.  * Purpose: To initialize all the screen status info that is not hardware
  143.  *           dependent, and call the hardware initialization routine to
  144.  *           pick up the hardware dependent stuff.
  145.  * Date:    June 5, 1991
  146.  * Returns: [g_status and g_display]: all set up ready to go
  147.  * Notes:   It is assumed that g_status and g_display are all \0's to begin
  148.  *           with (the default if they use static storage). If this may
  149.  *           not be the case, then clear them explicitly here.
  150.  */
  151. void initialize( void )
  152. {
  153.    /*
  154.     * we do not know where the cursor is yet
  155.     */
  156.    g_display.col = -1;
  157.    g_display.line = -1;
  158.  
  159.    /*
  160.     * do the hardware initialization first, since this allocates the main
  161.     *  text buffer and sets up other info needed here.
  162.     */
  163.    hw_initialize( );
  164.  
  165.    bm.search_defined = ERROR;
  166.    bm.search_case = IGNORE;
  167.    /*
  168.     * the main text buffer must be preceded by a ^Z, so that backward
  169.     *  searches can see the start of the text buffer
  170.     */
  171.    *g_status.start_mem++ = CONTROL_Z;
  172.  
  173.    /*
  174.     * most of the system's text pointers are safer set to the start
  175.     *  of the text buffer - some of these may not be strictly
  176.     *  necessary.
  177.     */
  178.    g_status.temp_end = g_status.start_mem;
  179.    g_status.end_mem = g_status.start_mem;
  180.  
  181.    /*
  182.     * initialize pointers and counters
  183.     */
  184.    g_status.marked = FALSE;
  185.    g_status.marked_file = NULL;
  186.  
  187.    g_status.current_window = NULL;
  188.    g_status.current_file = NULL;
  189.    g_status.window_list = NULL;
  190.    g_status.file_list = NULL;
  191.    g_status.window_count = 0;
  192.    g_status.file_count = 0;
  193.    g_status.undo_head  = -1;
  194.  
  195.    /*
  196.     * set the number of lines from one page that should still be visible
  197.     *  on the next page after page up or page down.
  198.     */
  199.    g_status.overlap = 1;
  200.  
  201.    /*
  202.     * start out with no wrapped error message.
  203.     */
  204.    g_status.wrapped = FALSE;
  205.  
  206.    g_status.recording_key = 0;
  207.    connect_macros( );
  208.  
  209.  
  210.    /*
  211.     * clear the screen and show the author's names
  212.     */
  213.    cls( );
  214.    show_credits( );
  215. }
  216.  
  217.  
  218. /*
  219.  * Name:    show_modes
  220.  * Purpose: show current editor modes in lite bar at bottom of screen
  221.  * Date:    June 5, 1991
  222.  */
  223. void show_modes( void )
  224. {
  225. char status_line[MAX_COLS+2];
  226.  
  227.    memset( status_line, ' ', MAX_COLS );
  228.    status_line[MAX_COLS] = '\0';
  229.    s_output( status_line, g_display.mode_line, 0, g_display.mode_color );
  230.    s_output( "F=   W=", g_display.mode_line, 1, g_display.mode_color );
  231.    s_output( "mem=", g_display.mode_line, 11, g_display.mode_color );
  232.    show_window_count( g_status.window_count );
  233.    show_file_count( g_status.file_count );
  234.    show_avail_mem( );
  235.    show_indent_mode( );
  236.    show_sync_mode( );
  237.    show_control_z( );
  238.    show_insert_mode( );
  239.    show_search_case( );
  240.    show_wordwrap_mode( );
  241.    show_crlf_mode( );
  242.    show_trailing( );
  243. }
  244.  
  245.  
  246. /*
  247.  * Name:    show_file_count
  248.  * Purpose: show number of open files in lite bar at bottom of screen
  249.  * Passed:  fc:  file count - number of open files
  250.  * Date:    June 5, 1991
  251.  */
  252. void show_file_count( int fc )
  253. {
  254. char status_line[MAX_COLS+2];
  255.  
  256.    s_output( "  ", g_display.mode_line, 3, g_display.mode_color );
  257.    s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3,
  258.              g_display.mode_color );
  259. }
  260.  
  261.  
  262. /*
  263.  * Name:    show_window_count
  264.  * Purpose: show total number of windows in lite bar at bottom of screen
  265.  * Passed:  wc:  window count - visible and hidden.
  266.  * Date:    September 13, 1991
  267.  */
  268. void show_window_count( int wc )
  269. {
  270. char status_line[MAX_COLS+2];
  271.  
  272.    s_output( "  ", g_display.mode_line, 8, g_display.mode_color );
  273.    s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8,
  274.              g_display.mode_color );
  275. }
  276.  
  277.  
  278. /*
  279.  * Name:    show_avail_mem
  280.  * Purpose: show available free memory in lite bar at bottom of screen
  281.  * Date:    June 5, 1991
  282.  */
  283. void show_avail_mem( void )
  284. {
  285. char memory[MAX_COLS+2];
  286. long avail;
  287.  
  288.    avail = ptoul( g_status.max_mem ) - ptoul( g_status.end_mem );
  289.    ltoa( avail, memory, 10 );
  290.    s_output( "        ", g_display.mode_line, 15, g_display.mode_color );
  291.    s_output( memory, g_display.mode_line, 15, g_display.mode_color );
  292. }
  293.  
  294.  
  295. /*
  296.  * Name:    show_indent_mode
  297.  * Purpose: show indent mode in lite bar at bottom of screen
  298.  * Date:    June 5, 1991
  299.  */
  300. void show_indent_mode( void )
  301. {
  302. char *indent = "Indent";
  303. char *blank  = "      ";
  304.  
  305.    s_output( mode.indent ? indent : blank, g_display.mode_line, 34,
  306.              g_display.mode_color );
  307. }
  308.  
  309.  
  310. /*
  311.  * Name:    show_search_case
  312.  * Purpose: show search mode in lite bar
  313.  * Date:    June 5, 1991
  314.  */
  315. void show_search_case( void )
  316. {
  317. char *ignore = "Ignore";
  318. char *match  = "Match ";
  319.  
  320.    s_output( bm.search_case == IGNORE ? ignore : match, g_display.mode_line,
  321.              42, g_display.mode_color );
  322. }
  323.  
  324.  
  325. /*
  326.  * Name:    show_sync_mode
  327.  * Purpose: show sync mode in lite bar
  328.  * Date:    January 15, 1992
  329.  */
  330. void show_sync_mode( void )
  331. {
  332. char *no_sync = "    ";
  333. char *sync    = "Sync";
  334.  
  335.    s_output( mode.sync ? sync : no_sync, g_display.mode_line, 50,
  336.              g_display.mode_color );
  337. }
  338.  
  339.  
  340. /*
  341.  * Name:    show_wordwrap_mode
  342.  * Purpose: display state of word wrap mode
  343.  * Date:    June 5, 1991
  344.  */
  345. void show_wordwrap_mode( void )
  346. {
  347. char *ww_on  = "WW";
  348. char *ww_off = "  ";
  349.  
  350.    s_output( mode.word_wrap ? ww_on : ww_off, g_display.mode_line, 56,
  351.              g_display.mode_color );
  352. }
  353.  
  354.  
  355. /*
  356.  * Name:    show_crlf_mode
  357.  * Purpose: display state of crlf flag
  358.  * Date:    June 5, 1991
  359.  */
  360. void show_crlf_mode( void )
  361. {
  362. char *crlf = "CRLF";
  363. char *lf   = "LF  ";
  364.  
  365.    s_output( mode.crlf == CRLF ? crlf : lf, g_display.mode_line, 60,
  366.              g_display.mode_color );
  367. }
  368.  
  369.  
  370. /*
  371.  * Name:    show_trailing
  372.  * Purpose: show state of trailing flag
  373.  * Date:    June 5, 1991
  374.  */
  375. void show_trailing( void )
  376. {
  377.    c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line,
  378.              g_display.mode_color );
  379. }
  380.  
  381.  
  382. /*
  383.  * Name:    show_control_z
  384.  * Purpose: show state of control z flag
  385.  * Date:    June 5, 1991
  386.  */
  387. void show_control_z( void )
  388. {
  389.    c_output( mode.control_z ? ' ' : 'Z', 77, g_display.mode_line,
  390.              g_display.mode_color );
  391. }
  392.  
  393.  
  394. /*
  395.  * Name:    show_insert_mode
  396.  * Purpose: show insert mode in lite bar
  397.  * Date:    June 5, 1991
  398.  */
  399. void show_insert_mode( void )
  400. {
  401.    c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line,
  402.              g_display.mode_color );
  403. }
  404.  
  405.  
  406. /*
  407.  * Name:    my_scroll_down
  408.  * Purpose: display a portion of a window
  409.  * Date:    June 5, 1991
  410.  * Passed:  window: information allowing access to the current window
  411.  * Notes:   Using the bios scroll functions causes a slightly noticable
  412.  *            "flicker", even on fast VGA monitors.  This is caused by changing
  413.  *            the high-lited cursor line to text color then calling the bios
  414.  *            function to scroll.  Then, the current line must then be displayed
  415.  *            in the curl color.
  416.  *          This function assumes that win->cline is the current line.
  417.  */
  418. void my_scroll_down( WINDOW *window )
  419. {
  420. int i;
  421. int curl;
  422. long length;
  423. WINDOW w;              /* scratch window struct for dirty work */
  424. register WINDOW *win;  /* put window pointer in a register */
  425.  
  426.    win = window;
  427.    length = win->file_info->length;
  428.    dup_window_info( &w, win );
  429.    curl = i = win->bottom_line + 1 - win->cline;
  430.    for (; i>0; i--) {
  431.       if (w.cursor) {
  432.          if (w.rline <= length) {
  433.             if (i != curl)
  434.                update_line( &w );
  435.          } else
  436.             show_eof( &w );
  437.          w.cursor = find_next( w.cursor );
  438.       } else
  439.          window_eol_clear( &w, COLOR_TEXT );
  440.       ++w.cline;
  441.       ++w.rline;
  442.    }
  443.    show_curl_line( win );
  444. }
  445.  
  446.  
  447. /*
  448.  * Name:    combine_strings
  449.  * Purpose: stick 3 strings together
  450.  * Date:    June 5, 1991
  451.  * Passed:  buff:    buffer to hold concatenation of 3 strings
  452.  *          s1:  pointer to string 1
  453.  *          s2:  pointer to string 2
  454.  *          s3:  pointer to string 3
  455.  */
  456. void combine_strings( char *buff, char *s1, char *s2, char *s3 )
  457. {
  458.    strcpy( buff, s1 );
  459.    strcat( buff, s2 );
  460.    strcat( buff, s3 );
  461. }
  462.  
  463.  
  464. /*
  465.  * Name:    make_ruler
  466.  * Purpose: make ruler with tabs, tens, margins, etc...
  467.  * Date:    June 5, 1991
  468.  */
  469. void make_ruler( WINDOW *window )
  470. {
  471. register WINDOW *win;
  472. char num[20];
  473. register char *p;
  474. int len;
  475. int col;
  476. int i;
  477. int mod;
  478.  
  479.    win = window;
  480.  
  481.    /*
  482.     * need to have a least two lines in a window when we display a ruler.
  483.     */
  484.    if (win->bottom_line - win->top_line < 1)
  485.       win->ruler = FALSE;
  486.    if (win->ruler) {
  487.  
  488.       /*
  489.        * find the width of the window and fill the ruler with dots.
  490.        */
  491.       len = win->end_col + 1 - win->start_col;
  492.       memset( win->ruler_line, '.', len );
  493.       win->ruler_line[len] = '\0';
  494.       col = win->bcol+1;
  495.       for (p=win->ruler_line; *p; col++, p++) {
  496.  
  497.          /*
  498.           * put a tens digit in the tens column
  499.           */
  500.          mod = col % 10;
  501.          if (mod == 0) {
  502.             itoa( col/10, num, 10 );
  503.  
  504.             /*
  505.              * let the margin chars have precidence over tens digit
  506.              */
  507.             for (i=0; num[i] && *p; col++, i++) {
  508.                if (col == mode.left_margin+1)
  509.                   *p = '┤';
  510.                else if (col == mode.right_margin+1)
  511.                   *p = '├';
  512.                else if (col == mode.parg_margin+1)
  513.                   *p = '';
  514.                else
  515.                   *p = num[i];
  516.                p++;
  517.             }
  518.  
  519.             /*
  520.              * we may have come to the end of the ruler in the for loop.
  521.              */
  522.             if (*p == '\0')
  523.                break;
  524.          } else if (mod == 5)
  525.             *p = '';
  526.          if (col == mode.parg_margin+1)
  527.             *p = '';
  528.          if (col == mode.left_margin+1)
  529.             *p = '┤';
  530.          else if (col == mode.right_margin+1)
  531.             *p = '├';
  532.       }
  533.    }
  534. }
  535.  
  536.  
  537. /*
  538.  * Name:    show_ruler
  539.  * Purpose: show ruler with tens, margins, etc...
  540.  * Date:    June 5, 1991
  541.  */
  542. void show_ruler( WINDOW *window )
  543. {
  544.    if (window->ruler && window->visible)
  545.       s_output( window->ruler_line, window->top_line, window->start_col,
  546.                 g_display.ruler_color );
  547. }
  548.  
  549.  
  550. /*
  551.  * Name:    show_ruler_char
  552.  * Purpose: show ruler character under ruler pointer
  553.  * Date:    June 5, 1991
  554.  */
  555. void show_ruler_char( WINDOW *window )
  556. {
  557. register WINDOW *win;
  558. char c;
  559.  
  560.    win = window;
  561.    if (win->ruler && win->visible) {
  562.       c = win->ruler_line[win->ccol - win->start_col];
  563.       c_output( c, win->ccol, win->top_line, g_display.ruler_color );
  564.    }
  565. }
  566.  
  567.  
  568. /*
  569.  * Name:    show_ruler_pointer
  570.  * Purpose: show ruler pointer
  571.  * Date:    June 5, 1991
  572.  */
  573. void show_ruler_pointer( WINDOW *window )
  574. {
  575.    if (window->ruler && window->visible)
  576.       c_output( RULER_CHAR, window->ccol, window->top_line,
  577.                 g_display.ruler_pointer );
  578. }
  579.  
  580.  
  581. /*
  582.  * Name:    show_all_rulers
  583.  * Purpose: make and show all rulers
  584.  * Date:    June 5, 1991
  585.  */
  586. void show_all_rulers( void )
  587. {
  588. register WINDOW *wp;
  589.  
  590.    wp = g_status.window_list;
  591.    while (wp != NULL) {
  592.       make_ruler( wp );
  593.       if (wp->visible) {
  594.          show_ruler( wp );
  595.          show_ruler_pointer( wp );
  596.       }
  597.       wp = wp->next;
  598.    }
  599. }
  600.