/******************* start of original comments ********************/ /* * Written by Douglas Thomson (1989/1990) * * This source code is released into the public domain. */ /* * Name: hardware independent screen IO module * Purpose: This file contains the code to interface the rest of the * editor to the display and input hardware. * File: hwind.c * Author: Douglas Thomson * System: this file is intended to be system-independent * Date: October 2, 1989 * Notes: This is the only module that is allowed to call the hardware * dependent display IO library. * Typically, functions here check whether any action is * necessary (for example, the cursor may already happen to be * in the required position), call hardware dependent functions * to achieve the required effect, and finally update status * information about the current state of the terminal display. * The idea behind this approach is to keep the hardware * dependent code as small and simple as possible, thus making * porting the code easier. */ /********************* end of original comments ********************/ /* * Some routines were added to display current editor modes in the lite bar * at the bottom of the screen. Other routines were rewritten in assembly. * I feel the need for speed. * * New editor name: tde, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * * This modification of Douglas Thomson's code is released into the * public domain, Frank Davis. You may distribute it freely. */ #include /* for REGS */ #include /* for intdos */ #include "tdestr.h" #include "common.h" #include "tdefunc.h" #include "define.h" /* * Name: get_date * Purpose: get system date from DOS * Date: June 5, 1992 * Passed: year: pointer to integer to store year * month: pointer to integer to store month * day: pointer to integer to store day * day_of_week: pointer to integer to store dow * Notes: call standard DOS interrupt 0x21, function 0x2a to get the date. */ void get_date( int *year, int *month, int *day, int *day_of_week ) { union REGS inregs, outregs; inregs.h.ah = 0x2a; intdos( &inregs, &outregs ); *year = (int)outregs.x.cx; *month = (int)outregs.h.dh; *day = (int)outregs.h.dl; *day_of_week = (int)outregs.h.al; } /* * Name: get_time * Purpose: get system time from DOS * Date: June 5, 1992 * Passed: hour: pointer to integer to store hour - system returns 24 hour * minutes: pointer to integer to store minutes * seconds: pointer to integer to store seconds * hundredths: pointer to integer to store hundredths of second * Notes: call standard DOS interrupt 0x21, function 0x2c to get the time. */ void get_time( int *hour, int *minutes, int *seconds, int *hundredths ) { union REGS inregs, outregs; inregs.h.ah = 0x2c; intdos( &inregs, &outregs ); *hour = (int)outregs.h.ch; *minutes = (int)outregs.h.cl; *seconds = (int)outregs.h.dh; *hundredths = (int)outregs.h.dl; } /* * Name: xygoto * Purpose: To move the cursor to the required column and line. * Date: September 28, 1991 * Passed: col: desired column (0 up to max) * line: desired line (0 up to max) * Notes; use standard BIOS video interrupt 0x10 to set the set. */ void xygoto( int col, int line ) { union REGS inregs, outregs; inregs.h.ah = 2; inregs.h.bh = 0; inregs.h.dh = (unsigned char)line; inregs.h.dl = (unsigned char)col; int86( 0x10, &inregs, &outregs ); } /* * Name: save_screen_line * Purpose: To save the characters and attributes of a line on screen. * Date: June 5, 1991 * Passed: col: desired column, usually always zero * line: line on screen to save (0 up to max) * screen_buffer: buffer for screen contents, must be 160 chars * Notes: Save the contents of the line on screen where prompt is * to be displayed */ void save_screen_line( int col, int line, char *screen_buffer ) { char far *p; p = g_display.display_address + line * 160 + col * 2; _fmemcpy( screen_buffer, p, 160 ); } /* * Name: restore_screen_line * Purpose: To restore the characters and attributes of a line on screen. * Date: June 5, 1991 * Passed: col: usually always zero * line: line to restore (0 up to max) * screen_buffer: buffer for screen contents * Notes: Restore the contents of the line on screen where the prompt * was displayed */ void restore_screen_line( int col, int line, char *screen_buffer ) { char far *p; p = g_display.display_address + line * 160 + col * 2; _fmemcpy( p, screen_buffer, 160 ); } /* * Name: initialize * Purpose: To initialize all the screen status info that is not hardware * dependent, and call the hardware initialization routine to * pick up the hardware dependent stuff. * Date: June 5, 1991 * Returns: [g_status and g_display]: all set up ready to go * Notes: It is assumed that g_status and g_display are all \0's to begin * with (the default if they use static storage). If this may * not be the case, then clear them explicitly here. */ void initialize( void ) { /* * do the hardware initialization first. this allocates the main * text buffer and sets up other info needed here. */ hw_initialize( ); bm.search_defined = ERROR; bm.search_case = IGNORE; /* * the main text buffer must be preceded by a ^Z, so that backward * searches can see the start of the text buffer */ *g_status.start_mem++ = CONTROL_Z; /* * most of the system's text pointers are safer set to the start * of the text buffer - some of these may not be strictly * necessary. */ g_status.temp_end = g_status.start_mem; g_status.end_mem = g_status.start_mem; /* * initialize the undo buffer similiar to the the main text buffer. * put a ^Z as the first in the undo buffer so that backward * searches can see the start of the undo buffer. */ g_status.top_stack = (text_ptr)g_status.undo_buffer; *g_status.top_stack = CONTROL_Z; g_status.top_stack = nptos( g_status.top_stack ) + 1; g_status.bot_stack = NULL; g_status.max_stack = (text_ptr)&g_status.undo_buffer[UNDO_MAX-1][BUFF_SIZE-1]; /* * initialize pointers and counters */ g_status.marked = FALSE; g_status.marked_file = NULL; g_status.current_window = NULL; g_status.current_file = NULL; g_status.window_list = NULL; g_status.file_list = NULL; g_status.window_count = 0; g_status.file_count = 0; /* * set the number of lines from one page that should still be visible * on the next page after page up or page down. */ g_status.overlap = 1; /* * start out with no wrapped error message. */ g_status.wrapped = FALSE; /* * no macro is executing */ g_status.macro_executing = FALSE; g_status.recording_key = 0; connect_macros( ); /* * clear the screen and show the author's names */ cls( ); show_credits( ); } /* * Name: show_modes * Purpose: show current editor modes in lite bar at bottom of screen * Date: June 5, 1991 */ void show_modes( void ) { char status_line[MAX_COLS+2]; memset( status_line, ' ', MAX_COLS ); status_line[MAX_COLS] = '\0'; s_output( status_line, g_display.mode_line, 0, g_display.mode_color ); s_output( "F= W=", g_display.mode_line, 1, g_display.mode_color ); s_output( "mem=", g_display.mode_line, 11, g_display.mode_color ); show_window_count( g_status.window_count ); show_file_count( g_status.file_count ); show_avail_mem( ); show_smarttab_mode( ); show_indent_mode( ); show_sync_mode( ); show_control_z( ); show_insert_mode( ); show_search_case( ); show_wordwrap_mode( ); show_crlf_mode( ); show_trailing( ); } /* * Name: show_file_count * Purpose: show number of open files in lite bar at bottom of screen * Passed: fc: file count - number of open files * Date: June 5, 1991 */ void show_file_count( int fc ) { char status_line[MAX_COLS+2]; s_output( " ", g_display.mode_line, 3, g_display.mode_color ); s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3, g_display.mode_color ); } /* * Name: show_window_count * Purpose: show total number of windows in lite bar at bottom of screen * Passed: wc: window count - visible and hidden. * Date: September 13, 1991 */ void show_window_count( int wc ) { char status_line[MAX_COLS+2]; s_output( " ", g_display.mode_line, 8, g_display.mode_color ); s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8, g_display.mode_color ); } /* * Name: show_avail_mem * Purpose: show available free memory in lite bar at bottom of screen * Date: June 5, 1991 */ void show_avail_mem( void ) { char memory[MAX_COLS+2]; long avail; avail = ptoul( g_status.max_mem ) - ptoul( g_status.end_mem ); ltoa( avail, memory, 10 ); s_output( " ", g_display.mode_line, 15, g_display.mode_color ); s_output( memory, g_display.mode_line, 15, g_display.mode_color ); } /* * Name: show_smarttab_mode * Purpose: show smart tab mode in lite bar at bottom of screen * Date: June 5, 1992 */ void show_smarttab_mode( void ) { s_output( mode.smart_tab ? smart : blank, g_display.mode_line, 27, g_display.mode_color ); } /* * Name: show_indent_mode * Purpose: show indent mode in lite bar at bottom of screen * Date: June 5, 1991 */ void show_indent_mode( void ) { s_output( mode.indent ? indent : blank, g_display.mode_line, 34, g_display.mode_color ); } /* * Name: show_search_case * Purpose: show search mode in lite bar * Date: June 5, 1991 */ void show_search_case( void ) { s_output( bm.search_case == IGNORE ? ignore : match, g_display.mode_line, 42, g_display.mode_color ); } /* * Name: show_sync_mode * Purpose: show sync mode in lite bar * Date: January 15, 1992 */ void show_sync_mode( void ) { s_output( mode.sync ? sync_on : sync_off, g_display.mode_line, 50, g_display.mode_color ); } /* * Name: show_wordwrap_mode * Purpose: display state of word wrap mode * Date: June 5, 1991 */ void show_wordwrap_mode( void ) { s_output( ww_mode[mode.word_wrap], g_display.mode_line, 56, g_display.mode_color ); } /* * Name: show_crlf_mode * Purpose: display state of crlf flag * Date: June 5, 1991 */ void show_crlf_mode( void ) { s_output( mode.crlf == CRLF ? crlf : lf, g_display.mode_line, 60, g_display.mode_color ); } /* * Name: show_trailing * Purpose: show state of trailing flag * Date: June 5, 1991 */ void show_trailing( void ) { c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line, g_display.mode_color ); } /* * Name: show_control_z * Purpose: show state of control z flag * Date: June 5, 1991 */ void show_control_z( void ) { c_output( mode.control_z ? ' ' : 'Z', 77, g_display.mode_line, g_display.mode_color ); } /* * Name: show_insert_mode * Purpose: show insert mode in lite bar * Date: June 5, 1991 */ void show_insert_mode( void ) { c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line, g_display.mode_color ); } /* * Name: my_scroll_down * Purpose: display a portion of a window * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Using the bios scroll functions causes a slightly noticable * "flicker", even on fast VGA monitors. This is caused by changing * the high-lited cursor line to text color then calling the bios * function to scroll. Then, the current line must then be * hilited. * This function assumes that win->cline is the current line. */ void my_scroll_down( WINDOW *window ) { int i; int curl; long length; WINDOW w; /* scratch window struct for dirty work */ register WINDOW *win; /* put window pointer in a register */ win = window; length = win->file_info->length; dup_window_info( &w, win ); curl = i = win->bottom_line + 1 - win->cline; for (; i>0; i--) { if (w.cursor) { if (w.rline <= length) { if (i != curl) update_line( &w ); } else show_eof( &w ); w.cursor = find_next( w.cursor ); } else window_eol_clear( &w, COLOR_TEXT ); ++w.cline; ++w.rline; } show_curl_line( win ); } /* * Name: combine_strings * Purpose: stick 3 strings together * Date: June 5, 1991 * Passed: buff: buffer to hold concatenation of 3 strings * s1: pointer to string 1 * s2: pointer to string 2 * s3: pointer to string 3 */ void combine_strings( char *buff, char *s1, char *s2, char *s3 ) { strcpy( buff, s1 ); strcat( buff, s2 ); strcat( buff, s3 ); } /* * Name: make_ruler * Purpose: make ruler with tabs, tens, margins, etc... * Date: June 5, 1991 * Passed: window: pointer to current window */ void make_ruler( WINDOW *window ) { register WINDOW *win; char num[20]; register char *p; int len; int col; int i; int mod; win = window; /* * need to have a least two lines in a window when we display a ruler. */ if (win->bottom_line - win->top_line < 1) win->ruler = FALSE; if (win->ruler) { /* * find the width of the window and fill the ruler with dots. */ len = win->end_col + 1 - win->start_col; memset( win->ruler_line, '.', len ); win->ruler_line[len] = '\0'; col = win->bcol+1; for (p=win->ruler_line; *p; col++, p++) { /* * put a tens digit in the tens column */ mod = col % 10; if (mod == 0) { itoa( col/10, num, 10 ); /* * let the margin chars have precidence over tens digit */ for (i=0; num[i] && *p; col++, i++) { if (col == mode.left_margin+1) *p = '´'; else if (col == mode.right_margin+1) *p = 'Ã'; else if (col == mode.parg_margin+1) *p = ''; else *p = num[i]; p++; } /* * we may have come to the end of the ruler in the for loop. */ if (*p == '\0') break; } else if (mod == 5) *p = ''; if (col == mode.parg_margin+1) *p = ''; if (col == mode.left_margin+1) *p = '´'; else if (col == mode.right_margin+1) *p = 'Ã'; } } } /* * Name: show_ruler * Purpose: show ruler with tens, margins, etc... * Date: June 5, 1991 * Passed: window: pointer to current window */ void show_ruler( WINDOW *window ) { if (window->ruler && window->visible) s_output( window->ruler_line, window->top_line, window->start_col, g_display.ruler_color ); } /* * Name: show_ruler_char * Purpose: show ruler character under ruler pointer * Date: June 5, 1991 * Passed: window: pointer to current window */ void show_ruler_char( WINDOW *window ) { register WINDOW *win; char c; win = window; if (win->ruler && win->visible) { c = win->ruler_line[win->ccol - win->start_col]; c_output( c, win->ccol, win->top_line, g_display.ruler_color ); } } /* * Name: show_ruler_pointer * Purpose: show ruler pointer * Date: June 5, 1991 * Passed: window: pointer to current window */ void show_ruler_pointer( WINDOW *window ) { if (window->ruler && window->visible) c_output( RULER_CHAR, window->ccol, window->top_line, g_display.ruler_pointer ); } /* * Name: show_all_rulers * Purpose: make and show all rulers in all visible windows * Date: June 5, 1991 */ void show_all_rulers( void ) { register WINDOW *wp; wp = g_status.window_list; while (wp != NULL) { make_ruler( wp ); if (wp->visible) { show_ruler( wp ); show_ruler_pointer( wp ); } wp = wp->next; } }