home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / tde221.zip / HWIND.C < prev    next >
C/C++ Source or Header  |  1993-04-01  |  14KB  |  518 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.  * Date:             October 31, 1992, version 2.1
  45.  * Date:             April 1, 1993, version 2.2
  46.  *
  47.  * This modification of Douglas Thomson's code is released into the
  48.  * public domain, Frank Davis.  You may distribute it freely.
  49.  */
  50.  
  51. #include <bios.h>       /* for REGS */
  52. #include <dos.h>        /* for intdos */
  53.  
  54. #include "tdestr.h"
  55. #include "common.h"
  56. #include "tdefunc.h"
  57. #include "define.h"
  58.  
  59.  
  60. /*
  61.  * Name:    get_date
  62.  * Purpose: get system date from DOS
  63.  * Date:    June 5, 1992
  64.  * Passed:  year:  pointer to integer to store year
  65.  *          month: pointer to integer to store month
  66.  *          day:   pointer to integer to store day
  67.  *          day_of_week:  pointer to integer to store dow
  68.  * Notes:   call standard DOS interrupt 0x21, function 0x2a to get the date.
  69.  */
  70. void get_date( int *year, int *month, int *day, int *day_of_week  )
  71. {
  72. union REGS inregs, outregs;
  73.  
  74.    inregs.h.ah = 0x2a;
  75.    intdos( &inregs, &outregs );
  76.    *year        = (int)outregs.x.cx;
  77.    *month       = (int)outregs.h.dh;
  78.    *day         = (int)outregs.h.dl;
  79.    *day_of_week = (int)outregs.h.al;
  80. }
  81.  
  82.  
  83. /*
  84.  * Name:    get_time
  85.  * Purpose: get system time from DOS
  86.  * Date:    June 5, 1992
  87.  * Passed:  hour:  pointer to integer to store hour - system returns 24 hour
  88.  *          minutes:  pointer to integer to store minutes
  89.  *          seconds:  pointer to integer to store seconds
  90.  *          hundredths:  pointer to integer to store hundredths of second
  91.  * Notes:   call standard DOS interrupt 0x21, function 0x2c to get the time.
  92.  */
  93. void get_time( int *hour, int *minutes, int *seconds, int *hundredths  )
  94. {
  95. union REGS inregs, outregs;
  96.  
  97.    inregs.h.ah = 0x2c;
  98.    intdos( &inregs, &outregs );
  99.    *hour       = (int)outregs.h.ch;
  100.    *minutes    = (int)outregs.h.cl;
  101.    *seconds    = (int)outregs.h.dh;
  102.    *hundredths = (int)outregs.h.dl;
  103. }
  104.  
  105.  
  106. /*
  107.  * Name:    show_modes
  108.  * Purpose: show current editor modes in lite bar at bottom of screen
  109.  * Date:    June 5, 1991
  110.  */
  111. void show_modes( void )
  112. {
  113. char status_line[MAX_COLS+2];
  114.  
  115.    memset( status_line, ' ', MAX_COLS );
  116.    status_line[MAX_COLS] = '\0';
  117.    s_output( status_line, g_display.mode_line, 0, g_display.mode_color );
  118.    s_output( "F=   W=", g_display.mode_line, 1, g_display.mode_color );
  119.    s_output( "m=", g_display.mode_line, 12, g_display.mode_color );
  120.    show_window_count( g_status.window_count );
  121.    show_file_count( g_status.file_count );
  122.    show_avail_mem( );
  123.    show_tab_modes( );
  124.    show_indent_mode( );
  125.    show_sync_mode( );
  126.    show_control_z( );
  127.    show_insert_mode( );
  128.    show_search_case( );
  129.    show_wordwrap_mode( );
  130.    show_trailing( );
  131. }
  132.  
  133.  
  134. /*
  135.  * Name:    show_file_count
  136.  * Purpose: show number of open files in lite bar at bottom of screen
  137.  * Passed:  fc:  file count - number of open files
  138.  * Date:    June 5, 1991
  139.  */
  140. void show_file_count( int fc )
  141. {
  142. char status_line[MAX_COLS+2];
  143.  
  144.    s_output( "  ", g_display.mode_line, 3, g_display.mode_color );
  145.    s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3,
  146.              g_display.mode_color );
  147. }
  148.  
  149.  
  150. /*
  151.  * Name:    show_window_count
  152.  * Purpose: show total number of windows in lite bar at bottom of screen
  153.  * Passed:  wc:  window count - visible and hidden.
  154.  * Date:    September 13, 1991
  155.  */
  156. void show_window_count( int wc )
  157. {
  158. char status_line[MAX_COLS+2];
  159.  
  160.    s_output( "  ", g_display.mode_line, 8, g_display.mode_color );
  161.    s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8,
  162.              g_display.mode_color );
  163. }
  164.  
  165.  
  166. /*
  167.  * Name:    show_avail_mem
  168.  * Purpose: show available free memory in lite bar at bottom of screen
  169.  * Date:    June 5, 1991
  170.  */
  171. void show_avail_mem( void )
  172. {
  173. char line[MAX_COLS+2];
  174. unsigned long avail_mem;
  175.  
  176. #if defined( __MSC__ )
  177. unsigned paragraphs;
  178.  
  179.    _dos_allocmem( 0xffff, ¶graphs );
  180.    /*
  181.     * A paragraph is 16 bytes.  Convert paragraphs to bytes by shifting left
  182.     * 4 bits.
  183.     */
  184.    avail_mem = (long)paragraphs << 4;
  185. #else
  186.    avail_mem = farcoreleft( );
  187. #endif
  188.  
  189.    s_output( "        ", g_display.mode_line, 14, g_display.mode_color );
  190.    ultoa( avail_mem, line, 10 );
  191.    s_output( line, g_display.mode_line, 14,
  192.              g_display.mode_color );
  193. }
  194.  
  195.  
  196. /*
  197.  * Name:    show_tab_modes
  198.  * Purpose: show smart tab mode in lite bar at bottom of screen
  199.  * Date:    October 31, 1992
  200.  */
  201. void show_tab_modes( void )
  202. {
  203. char *blank_tab = "   ";
  204. char ascii_tab[10];
  205.  
  206.    s_output( tabs, g_display.mode_line, 22, g_display.mode_color );
  207.    s_output( mode.smart_tab ? smart : fixed, g_display.mode_line, 27,
  208.              g_display.mode_color );
  209.    s_output( mode.inflate_tabs ? intab : outtab, g_display.mode_line, 28,
  210.              g_display.mode_color );
  211.    s_output( blank_tab, g_display.mode_line, 29, g_display.mode_color );
  212.    s_output( itoa( mode.ptab_size, ascii_tab, 10), g_display.mode_line, 29,
  213.              g_display.mode_color );
  214. }
  215.  
  216.  
  217. /*
  218.  * Name:    show_indent_mode
  219.  * Purpose: show indent mode in lite bar at bottom of screen
  220.  * Date:    June 5, 1991
  221.  */
  222. void show_indent_mode( void )
  223. {
  224.    s_output( mode.indent ? indent : blank, g_display.mode_line, 32,
  225.              g_display.mode_color );
  226. }
  227.  
  228.  
  229. /*
  230.  * Name:    show_search_case
  231.  * Purpose: show search mode in lite bar
  232.  * Date:    June 5, 1991
  233.  */
  234. void show_search_case( void )
  235. {
  236.    s_output( mode.search_case == IGNORE ? ignore : match, g_display.mode_line,
  237.              40, g_display.mode_color );
  238. }
  239.  
  240.  
  241. /*
  242.  * Name:    show_sync_mode
  243.  * Purpose: show sync mode in lite bar
  244.  * Date:    January 15, 1992
  245.  */
  246. void show_sync_mode( void )
  247. {
  248.    s_output( mode.sync ? sync_on : sync_off, g_display.mode_line, 48,
  249.              g_display.mode_color );
  250. }
  251.  
  252.  
  253. /*
  254.  * Name:    show_wordwrap_mode
  255.  * Purpose: display state of word wrap mode
  256.  * Date:    June 5, 1991
  257.  */
  258. void show_wordwrap_mode( void )
  259. {
  260.    s_output( ww_mode[mode.word_wrap], g_display.mode_line, 54,
  261.              g_display.mode_color );
  262. }
  263.  
  264.  
  265. /*
  266.  * Name:    show_trailing
  267.  * Purpose: show state of trailing flag
  268.  * Date:    June 5, 1991
  269.  */
  270. void show_trailing( void )
  271. {
  272.    c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line,
  273.              g_display.mode_color );
  274. }
  275.  
  276.  
  277. /*
  278.  * Name:    show_control_z
  279.  * Purpose: show state of control z flag
  280.  * Date:    June 5, 1991
  281.  */
  282. void show_control_z( void )
  283. {
  284.    c_output( mode.control_z ? 'Z' : ' ', 77, g_display.mode_line,
  285.              g_display.mode_color );
  286. }
  287.  
  288.  
  289. /*
  290.  * Name:    show_insert_mode
  291.  * Purpose: show insert mode in lite bar
  292.  * Date:    June 5, 1991
  293.  */
  294. void show_insert_mode( void )
  295. {
  296.    c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line,
  297.              g_display.mode_color );
  298. }
  299.  
  300.  
  301. /*
  302.  * Name:    my_scroll_down
  303.  * Purpose: display a portion of a window
  304.  * Date:    June 5, 1991
  305.  * Passed:  window:  pointer to current window
  306.  * Notes:   Using the bios scroll functions causes a slightly noticable
  307.  *            "flicker", even on fast VGA monitors.  This is caused by changing
  308.  *            the high-lited cursor line to text color then calling the bios
  309.  *            function to scroll.  Then, the current line must then be
  310.  *            hilited.
  311.  *          This function assumes that win->cline is the current line.
  312.  */
  313. void my_scroll_down( WINDOW *window )
  314. {
  315. int  i;
  316. int  curl;
  317. int  eof;
  318. WINDOW w;              /* scratch window struct for dirty work */
  319.  
  320.    dup_window_info( &w, window );
  321.    curl = i = window->bottom_line + 1 - window->cline;
  322.    eof = FALSE;
  323.    for (; i>0; i--) {
  324.       if (w.ll->len != EOF) {
  325.          /*
  326.           * if this is window->cline, do not show the line because we
  327.           * show the curl at the end of this function.  don't show it twice
  328.           */
  329.          if (i != curl)
  330.             update_line( &w );
  331.       } else if (eof == FALSE) {
  332.          show_eof( &w );
  333.          eof = TRUE;
  334.       } else
  335.          window_eol_clear( &w, COLOR_TEXT );
  336.       if (w.ll->next != NULL)
  337.          w.ll = w.ll->next;
  338.       ++w.cline;
  339.       ++w.rline;
  340.    }
  341.    show_curl_line( window );
  342. }
  343.  
  344.  
  345. /*
  346.  * Name:    combine_strings
  347.  * Purpose: stick 3 strings together
  348.  * Date:    June 5, 1991
  349.  * Passed:  buff:    buffer to hold concatenation of 3 strings
  350.  *          s1:  pointer to string 1
  351.  *          s2:  pointer to string 2
  352.  *          s3:  pointer to string 3
  353.  */
  354. void combine_strings( char *buff, char *s1, char *s2, char *s3 )
  355. {
  356.    assert( strlen( s1 ) + strlen( s2 ) + strlen( s3 ) < MAX_COLS );
  357.    strcpy( buff, s1 );
  358.    strcat( buff, s2 );
  359.    strcat( buff, s3 );
  360. }
  361.  
  362.  
  363. /*
  364.  * Name:    make_ruler
  365.  * Purpose: make ruler with tabs, tens, margins, etc...
  366.  * Date:    June 5, 1991
  367.  * Passed:  window:  pointer to current window
  368.  */
  369. void make_ruler( WINDOW *window )
  370. {
  371. register WINDOW *win;
  372. char num[20];
  373. register unsigned char *p;
  374. int  len;
  375. int  col;
  376. int  i;
  377. int  mod;
  378.  
  379.    win = window;
  380.  
  381.    /*
  382.     * need to have a least two lines in a window when we display a ruler.
  383.     */
  384.    if (win->bottom_line - win->top_line < 1)
  385.       win->ruler = FALSE;
  386.    if (win->ruler) {
  387.  
  388.       /*
  389.        * find the width of the window and fill the ruler with dots.
  390.        */
  391.       len = win->end_col + 1 - win->start_col;
  392.  
  393.       assert( len >= 0 );
  394.       assert( len <= MAX_COLS );
  395.  
  396.       memset( win->ruler_line, RULER_FILL, len );
  397.       win->ruler_line[len] = '\0';
  398.       col = win->bcol+1;
  399.  
  400.       assert( col >= 1 );
  401.       assert( col <= MAX_LINE_LENGTH );
  402.  
  403.       for (p=(unsigned char *)win->ruler_line; *p; col++, p++) {
  404.  
  405.          /*
  406.           * put a tens digit in the tens column
  407.           */
  408.          mod = col % 10;
  409.          if (mod == 0) {
  410.             itoa( col/10, num, 10 );
  411.  
  412.             /*
  413.              * let the margin chars have precidence over tens digit
  414.              */
  415.             for (i=0; num[i] && *p; col++, i++) {
  416.                if (col == mode.left_margin+1)
  417.                   *p = LM_CHAR;
  418.                else if (col == mode.right_margin+1) {
  419.                   if (mode.right_justify == TRUE)
  420.                      *p = RM_CHAR_JUS;
  421.                   else
  422.                      *p = RM_CHAR_RAG;
  423.                } else if (col == mode.parg_margin+1)
  424.                   *p = PGR_CHAR;
  425.                else
  426.                   *p = num[i];
  427.                p++;
  428.             }
  429.  
  430.             /*
  431.              * we may have come to the end of the ruler in the for loop.
  432.              */
  433.             if (*p == '\0')
  434.                break;
  435.          } else if (mod == 5)
  436.             *p = RULER_TICK;
  437.          if (col == mode.parg_margin+1)
  438.             *p = PGR_CHAR;
  439.          if (col == mode.left_margin+1)
  440.             *p = LM_CHAR;
  441.          else if (col == mode.right_margin+1) {
  442.             if (mode.right_justify == TRUE)
  443.                *p = RM_CHAR_JUS;
  444.             else
  445.                *p = RM_CHAR_RAG;
  446.          }
  447.       }
  448.    }
  449. }
  450.  
  451.  
  452. /*
  453.  * Name:    show_ruler
  454.  * Purpose: show ruler with tens, margins, etc...
  455.  * Date:    June 5, 1991
  456.  * Passed:  window:  pointer to current window
  457.  */
  458. void show_ruler( WINDOW *window )
  459. {
  460.    if (window->ruler && window->visible)
  461.       s_output( window->ruler_line, window->top_line, window->start_col,
  462.                 g_display.ruler_color );
  463. }
  464.  
  465.  
  466. /*
  467.  * Name:    show_ruler_char
  468.  * Purpose: show ruler character under ruler pointer
  469.  * Date:    June 5, 1991
  470.  * Passed:  window:  pointer to current window
  471.  */
  472. void show_ruler_char( WINDOW *window )
  473. {
  474. register WINDOW *win;
  475. char c;
  476.  
  477.    win = window;
  478.    if (win->ruler && win->visible) {
  479.       c = win->ruler_line[win->ccol - win->start_col];
  480.       c_output( c, win->ccol, win->top_line, g_display.ruler_color );
  481.    }
  482. }
  483.  
  484.  
  485. /*
  486.  * Name:    show_ruler_pointer
  487.  * Purpose: show ruler pointer
  488.  * Date:    June 5, 1991
  489.  * Passed:  window:  pointer to current window
  490.  */
  491. void show_ruler_pointer( WINDOW *window )
  492. {
  493.    if (window->ruler && window->visible)
  494.       c_output( RULER_PTR, window->ccol, window->top_line,
  495.                 g_display.ruler_pointer );
  496. }
  497.  
  498.  
  499. /*
  500.  * Name:    show_all_rulers
  501.  * Purpose: make and show all rulers in all visible windows
  502.  * Date:    June 5, 1991
  503.  */
  504. void show_all_rulers( void )
  505. {
  506. register WINDOW *wp;
  507.  
  508.    wp = g_status.window_list;
  509.    while (wp != NULL) {
  510.       make_ruler( wp );
  511.       if (wp->visible) {
  512.          show_ruler( wp );
  513.          show_ruler_pointer( wp );
  514.       }
  515.       wp = wp->next;
  516.    }
  517. }
  518.