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