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