File:  [OS/2 SDKs] / os2sdk / demos / apps / sse / keyfuncs.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:26:05 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
Microsoft OS/2 SDK 03-01-1988

/****** KEYFUNCS.C - a collection of routines to service special keys
 *		     each routine has the name of the key it services
 *
 *  Created by Microsoft Corp. 1987
 */

#define  INCL_SUB

#include <ctype.h>
#include <os2def.h>
#include <bsesub.h>
#include "ssedefs.h"
#include "keydefs.h"


/*** insert(c) - inserts the character c at the current cursor position
 *
 *   This routine is called when any regular printable character is hit.
 *
 *   insert(c) checks to see if there is room in EditBuff[] to insert the
 *   character it is passed by seeing if there is already a printable
 *   character in the 80th column. If so, no character can be inserted
 *   so we just call badkey(). If there is room, insert the character
 *   at the position indicated by CurCol and shift everything past that
 *   over one; mark EditBuff[] as dirty.
 *
 *   If there is text that has been marked, insert() will call del() to
 *   remove it before inserting its character where the marked text was.
 *
 *   The character we are passed has already been checked as being a
 *   valid printable characters.
 *
 *   insert(c)
 *
 *   ENTRY:	  c  -	the validated character to be inserted
 *
 *   EFFECTS:	  EditBuff[]	 - changes its contents if successful
 *		  EditBuffDirty  - sets this flag if EditBuff changed
 *		  LinesMarked	 - clears this if set
 *		  CharsMarked	 - clears this if set
 *		  CurCol	 - increments this one
 *
 *   The effects of del() should also be considered since it may be
 *   called from this function.
 */

insert(c)
    char c;		 /* the character we are to insert, already validated */
    {

    register SHORT i;					 /* indexing variable */

    if (LinesMarked || CharsMarked)	   /* if there is marked text around, */
	del();				   /* we first want to delete it      */

    if ( EditBuff[LINESIZE - 1] == ' ')  /* can only insert when there's room */
	{
	for ( i = 0; i < LINESIZE-CurCol-1; ++i )
	  EditBuff[LINESIZE-i-1] = EditBuff[LINESIZE-i-2];/* shift end by one */
	EditBuff[CurCol] = c;			 /* put in the new character  */
	drawline();
	CurCol += 1;					    /* update display */
	VioSetCurPos( CurRow, CurCol, 0 );
	EditBuffDirty = 1;			 /* mark edit buffer as dirty */
	}

    else badkey();		       /* if no room, exit as for invalid key */

    }


/*** up() - moves the cursor up one row
 *
 *   up() moves the cursor position up one row. If we are at the top of
 *   the screen already, up() scrolls the screen down one line. If we
 *   are at the top of the file, it does nothing. If there is marked text
 *   around, up() will clear it without deleting. Because the current row
 *   in the file is changed by up(), EditBuff[] is flushed and refilled
 *   and line25() is called to update the line information at the bottom
 *   of the screen.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes its current contents and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - if at top of screen, decrements this one
 *		  CurRow	 - otherwise, decrements this one
 */


void up()
    {

    register short i;				      /* indexing variable */

    char buff[2];	      /* local buffer for scrolling fill character */
    buff[0] = 32;	      /*		 character = 32 = <blank>  */
    buff[1] = ForeNorm;       /*		      attribute = normal   */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	 /* redraw the screen	   */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if ( (TopRow + CurRow) != 0 ) {	     /* if top of file, do nothing */
	if ( CurRow == 0 ) {
	    TopRow -= 1;		  /* if top of screen, scroll down */
	    VioScrollDn( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
		       (PBYTE)buff, 0);
	    getline( (TopRow + CurRow), &EditBuff[0] );
	    drawline();
	    }
	else {
	    CurRow -= 1;		  /* otherwise just move cursor up */
	    getline( (TopRow + CurRow), &EditBuff[0] );
	    VioSetCurPos( CurRow, CurCol, 0 );
	    }
	}

    line25();	      /* reset line numbers on 25th line to reflect change */

    }


/*** down() - moves the cursor down one row
 *
 *   down() moves the cursor down one row. If we are at the top of
 *   the screen already, down() scrolls the screen up one line. If we
 *   are at the end of the file, it does nothing. If there is marked text
 *   around, down() will clear it without deleting. Because the current row
 *   in the file is changed by down(), EditBuff[] is flushed and refilled
 *   and line25() is called to update the line information at the bottom
 *   of the screen.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes its current contents and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - if at bottom of screen, increments this one
 *		  CurRow	 - otherwise, increments this one
 */


void down()
    {

    register short i;				      /* indexing variable */

    char buff[2];	      /* local buffer for scrolling fill character */
    buff[0] = 32;	      /*		  character = 32 = <blank> */
    buff[1] = ForeNorm;       /*		       attribute = normal  */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	 /* redraw the screen	   */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if ( (TopRow + CurRow) < (TotalLines) ) {	     /* if EOF, do nothing */
	if ( CurRow == (PageSize - 1) ) {   /* if end of screen, scroll up */
	    TopRow += 1;
	    VioScrollUp( 0, 0, CurRow, (LINESIZE - 1), 1,
		       (PBYTE)buff, 0);
	    getline( (TopRow + CurRow), &EditBuff[0] );
	    drawline();
	    }
	else {
	    CurRow += 1;			  /* else move cursor down */
	    getline( (TopRow + CurRow), &EditBuff[0] );
	    VioSetCurPos( CurRow, CurCol, 0 );
	    }
	}

    line25();	      /* reset line numbers on 25th line to reflect change */

    }


/*** home() - moves the cursor to beginning of the line
 *
 *   home() moves the cursor to the position of the first printable character
 *   in the current line. If there is marked text, home() will clear it
 *   without deleting. We need to be able to get correct information about
 *   the length of the current line from LineTable[], so we flush EditBuff[]
 *   on entry; but since the current line does not get changed, we do not
 *   reload it (current contents remain correct) and we do not call line25().
 *
 *   EFFECTS:	  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  CurCol	 - set to position of first printable character
 */

void home()
    {

    register short i, j;			       /* indexing variables */


    if (EditBuffDirty) {			   /* this call will need to */
	EditBuffDirty = 0;			   /* get correct info on    */
	flushline((TopRow + CurRow), EditBuff);    /* line length, so flush  */
	}					   /* edit buffer if dirty   */

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			   /* if there's marked text */
	CharsMarked = 0;			   /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	   /* redraw the screen      */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if( (TopRow + CurRow) < TotalLines ) {
	i = LineTable[TopRow + CurRow]->linelength;	/* i is position of  */
	i--;						/* last char in line */
	}
    else i = 0; 	    /* if we're off the end of the file, that's 0... */


    for( j = 0; ( j <= i )  &&	!isgraph(EditBuff[j]); j++ );

    CurCol = j; 					 /* j is position of */
    VioSetCurPos( CurRow, CurCol, 0 );			 /* first non-blank  */

    }


/*** end_() - moves the cursor to one position past the end of the current line
 *
 *   end_() moves the cursor to one position beyond the position of the last
 *   printable character in the current line. If the last printable character
 *   is already in column 80, we just go there. If there is marked text,
 *   end_() will clear it without deleting. We need to be able to get correct
 *   information about the length of the current line from LineTable[], so
 *   we flush EditBuff[] on entry; but since the current line does not get
 *   changed, we do not reload it (current contents remain correct) and we
 *   do not call line25(). Note that this routine had to be named end_() not
 *   end() since that is a reserved word under the compiler used.
 *
 *   EFFECTS:	  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  CurCol	 - set to position of last printable
 *				   character, plus one if possible
 */

void end_()
    {

    register short i;				       /* indexing variable */

    if (EditBuffDirty) {			  /* this call will need to */
	EditBuffDirty = 0;			  /* get correct info on    */
	flushline((TopRow + CurRow), EditBuff);   /* line length, so flush  */
	}					  /* edit buffer if dirty   */

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			  /* if there's marked text */
	CharsMarked = 0;			  /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	  /* redraw the screen	    */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if( (TopRow + CurRow) < TotalLines ) {
	i = LineTable[TopRow + CurRow]->linelength;    /* i is position of  */
	}					       /* last char in line */
    else i = 0;

    CurCol = i;
    VioSetCurPos( CurRow, CurCol, 0 );

    }


/*** pgup() - moves up one screen
 *
 *   pgup() subtracts PageSize from the current value of TopRow and then
 *   redraws the screen, effectively moving us up one screen. If TopRow
 *   is less than PageSize, we just go to the start of the file. The
 *   position of the cursor on the screen is not altered. If there is marked
 *   text, pgup() will clear it without deleting. Because this call changes
 *   the current line, we flush and reload EditBuff[].
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - gets PageSize subtracted from it
 *				   if possible, otherwise set to 0.
 */

void pgup()
    {

    register short i;				      /* indexing variable */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	 /* redraw the screen	   */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	}

    if ( TopRow >= PageSize )		 /* go up one page if there's room */
	TopRow -= PageSize;
    else {
	TopRow = 0;		       /* otherwise just go to top of file */
	CurRow = 0;
	VioSetCurPos( CurRow, CurCol, 0 );
	}

    drawscr(TopRow);				     /* redraw screen and  */
    getline( (TopRow + CurRow), &EditBuff[0] );      /* update edit buffer */
    line25();	      /* reset line numbers on 25th line to reflect change */

    }


/*** pgdn() - moves down one screen
 *
 *   pgdn() adds PageSize to the current value of TopRow and then
 *   redraws the screen, effectively moving us down one screen. If the
 *   result of adding TopRow and PageSize is greater than TotalLines
 *   (in other words, we would be moving off the end of the file), then
 *   we just move to one beyond the end of the file. The position of the
 *   cursor on the screen is not altered. If there is marked text,
 *   pgdn() will clear it without deleting. Because this call changes
 *   the current line, we flush and reload EditBuff[].
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - gets PageSize added to it if possible,
 *				   otherwise set to TotalLines - PageSize - 1.
 */

void pgdn()
    {

    register short i;					/* indexing variable */

    if (EditBuffDirty) {			    /* this call will change */
	EditBuffDirty = 0;			    /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);     /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			   /* if there's marked text */
	CharsMarked = 0;			   /* around, clear it	     */
	for ( i = 0; i < MAXLINES; i++ )
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	}

    TopRow += PageSize; 				/* go down one page  */
    if ( TopRow > (TotalLines - (PageSize -1)) ) {	/* if there's room,  */
	TopRow = (TotalLines - (PageSize -1));		/* else stop at last */
	CurRow = (PageSize -1); 			/* full page	     */
	VioSetCurPos(CurRow, CurCol, 0);
	}

    drawscr(TopRow);				       /* redraw screen and  */
    getline( (TopRow + CurRow), &EditBuff[0] );        /* update edit buffer */
    line25();		/* reset line numbers on 25th line to reflect change */

    }


/*** bksp() - deletes character to right of the cursor; moves cursor right one
 *
 *   bksp() clears any marked text without deleting it, flushes EditBuff[],
 *   moves the cursor right one position and calls del(). If we're at the
 *   beginning of a line so there's nothing to our right, calls badkey().
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  CurCol	 - decrements if possible
 *
 *   The effects of del() should also be considered since it may be
 *   called from this function.
 */

void bksp()
    {

    register short i;				       /* indexing variable */

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			  /* if there's marked text */
	CharsMarked = 0;			  /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	  /* redraw the screen	    */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;

	if (EditBuffDirty) {			     /* flush before redraw */
	    EditBuffDirty = 0;			     /* to get any changes  */
	    flushline((TopRow + CurRow), EditBuff);
	    }
	drawscr(TopRow);
	}

    if( CurCol == 0 )		 /* can't backspace if already at left edge */
	badkey();
    else {
	CurCol -= 1;			/* otherwise, move left one and del */
	VioSetCurPos( CurRow, CurCol, 0 );
	del();
	}
    }


/*** del() - deletes all indicated text
 *
 *   del() is the function for deleting text. What gets deleted depends on
 *   what is marked. If there are marked lines around (as indicated by the
 *   LinesMarked flag) then we delete the marked lines, clear all the line
 *   marking flags, and adjust LineTable[] to reflect the change. Note that
 *   if there are lines marked, there cannot be characters marked too. If
 *   there are no lines marked, but characters marked, these characters are
 *   deleted and EditBuff[] is adjusted to reflect the change and flagged
 *   as dirty. If there are no lines or characters marked, then the character
 *   under the cursor is deleted and EditBuff[] is adjusted accordingly and
 *   marked as dirty.
 *
 *   EFFECTS:	  EditBuff[]	 - contents altered if no lines were marked
 *		  EditBuffDirty  - set if no lines were marked
 *		  LineTable[]	 - contents altered if lines were marked
 *		  TotalLines	 - altered if lines were marked
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - may change, depending on what's marked
 *		  CurRow	 - may change, depending on what's marked
 *
 */

void del()
    {

    register short i, j;				/* indexing variables */

    if (LinesMarked) {			      /* if lines are marked, do this */
	for( i = 0; !MarkedLine[i]; i++ );
	j = i;				   /* i, j refer to first marked line */
	if( i <= TopRow ) {
	    if( i != 0 ) {
		TopRow = i - 1; 	  /* if first line to be deleted is   */
		CurRow = 1;		  /* off the top of the screen, then  */
		}			  /* set TopRow to last unmarked line */
	    else {
		TopRow = 0;		   /* or if there are no unmarked     */
		CurRow = 0;		   /* lines ahead of the marked ones, */
		}			   /* set TopRow to start of the file */
	    }
	else CurRow = i - TopRow;
	for( ; MarkedLine[i]; i++ )		   /* delete all marked lines */
	    deleteline( i );		   /* i refers to first unmarked line */
	for( ; i < TotalLines; i++,j++ )		/* adjust LineTable[] */
	    LineTable[j] = LineTable[i];
	TotalLines -= ( i - j );			 /* adjust TotalLines */
	LinesMarked = 0;
	for( i = 0; i < MAXLINES; i++ ) 	  /* clear line marking flags */
	    MarkedLine[i] = 0;
	drawscr(TopRow);				     /* redraw screen */
	VioSetCurPos(CurRow, CurCol, 0);
	getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload EditBuff[] */
	}

    else if (CharsMarked) {   /* if no lines marked but chars marked, do this */
	for( i = 0; !MarkedChar[i] & ( i < LINESIZE ); i++ );
	j = i;			      /* i, j refer to first marked character */
	CurCol = j;
	VioSetCurPos(CurRow, CurCol, 0);	    /* adjust cursor position */
	for( ; MarkedChar[i] & (i < LINESIZE); i++ ); /* i now first unmarked */
	for( ; i < LINESIZE; i++, j++ )
	    EditBuff[j] = EditBuff[i];	 /* remove characters between i and j */
	for( ; j < LINESIZE; j++ )
	    EditBuff[j] = ' ';		      /* fill end of line with blanks */
	CharsMarked = 0;
	for( i = 0; i < LINESIZE; i++ )  /* clear all character marking flags */
	    MarkedChar[i] = 0;
	drawline();					       /* redraw line */
	EditBuffDirty = 1;			  /* mark EditBuff[] as dirty */
	}

    else {			      /* if no lines or chars marked, do this */
	for( i = (CurCol + 1); i < LINESIZE; i++ )
	   EditBuff[i-1] = EditBuff[i];      /* remove character under cursor */
	EditBuff[LINESIZE-1] = ' ';	       /* fill end of line with blank */
	drawline();					       /* redraw line */
	EditBuffDirty = 1;			  /* mark EditBuff[] as dirty */
	}

    line25();		/* reset line numbers on 25th line to reflect changes */

    }


/*** F9() - saves the file being edited and exits
 *
 *   F9() save the file being edited with any changes that have been made
 *   and exits the editor. The user is given a prompt to be sure they want
 *   to quit; hitting carriage return goes ahead with the save-and-quit,
 *   while any other key returns you to the editor.
 *
 *   EFFECTS:	  If quit not completed:    EditBuff[]	  -  gets flushed
 *					    EditBuffDirty -  gets cleared
 */

void F9()
    {

    static char message[LINESIZE] = "Save file as:";
    KBDKEYINFO keydata;
    char attrib = Fore25 + Back25;
    int i;

    if (EditBuffDirty) {		   /* flush the edit buffer if dirty */
	EditBuffDirty = 0;		   /* so all editting will be saved  */
	flushline((TopRow + CurRow), EditBuff);
	}

    for( i = 0; (i < 65) && (fname[i] != 0); message[i + 14] = fname[i], i++ );
					/* copy filename into prompt message */

    VioWrtCharStrAtt( message, 80, PageSize, 0, &attrib, 0 );
							/* write out message */

    KbdCharIn( &keydata, 0, 0 );		   /* wait for user response */

    if( keydata.chChar == CRETURN_CHAR ) {     /* if response was <CR>... */
	if ( !savefile(fhandle)) {
	    freesegs();
	    VioSetCurPos( 24, 0, 0 );		    /* ... clean up and quit */
	    quit(0);
	    }
	else error25(11);
	}
    name25();				 /* ... otherwise restore message on */
					 /* 25th line and return to editor   */
    }


/*** F10() - exits the editor without saving the file being edited
 *
 *   F10() exits from the editor without saving back the file being edited,
 *   leaving the file as it was before the editor was invoked. A prompt
 *   will be issued to give the user a chance to change their mind before
 *   all editing is lost.
 *
 *   EFFECTS:	  If quit not completed:    EditBuff[]	  -  gets flushed
 *					    EditBuffDirty -  gets cleared
 */


void F10()
    {
    static char message[51] = "WARNING: Any edits will be lost   (y/n)?           ";
    KBDKEYINFO keydata;
    char attrib = Fore25 + Back25;		   /* attributes for message */
    int  row, col;			  /* to save current cursor position */
    int  done = 0;		/* flag to be set when have a valid response */

    if (EditBuffDirty) {			/* flush EditBuff[] if dirty */
	EditBuffDirty = 0;
	flushline((TopRow + CurRow), EditBuff);
	}

    VioWrtCharStrAtt( message, 51, PageSize, 0, &attrib, 0 );
    VioGetCurPos( &row, &col, 0 );		    /* print prompt and set  */
    VioSetCurPos( PageSize, 42, 0 );		    /* cursor to await reply */

    while( !done ) {

	KbdCharIn( &keydata, 0, 0 );		 /* get a character from KBD */

	if( (keydata.chChar == 'y') || (keydata.chChar == 'Y') ) {
	    VioWrtCharStrAtt( &keydata.chChar, 1, PageSize, 42, &attrib, 0 );
	    freesegs();
	    quit(0);				/* if Y, quit without saving */
	    }
	else if( (keydata.chChar == 'n') || (keydata.chChar == 'N') ) {
	    VioSetCurPos( row, col, 0 );
	    name25();
	    done = 1;				   /* if N, return to editor */
	    }
	else badkey();			   /* otherwise wait for another key */

	}

    }


/*** ctrl_home() - repositions cursor to upper left hand corner of screen
 *
 *   ctrl_home() moves the cursor to the upper left hand corner of the
 *   screen, coordinate position (0,0). Since the current cursor line is
 *   probably changed, we flush and reload EditBuff[]. If there is any
 *   text marked, this call will clear the marking without deleting.
 *   Line number information on 25th line is redrawn to reflect changes.
 *   The actual content of the screen - i.e. the value of TopRow - is
 *   unchanged by this call.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  CurRow	 - set to 0
 *		  CurCol	 - set to 0
 */

void ctrl_home()
    {

    register short i;				      /* indexing variable */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	 /* redraw the screen	   */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if ( CurRow != 0  ||  CurCol != 0 ) {
	CurRow = 0;				    /* reposition to (0,0) */
	CurCol = 0;
	VioSetCurPos( CurRow, CurCol, 0 );
	getline( (TopRow + CurRow), &EditBuff[0] );
	}

    line25();	    /* update line numbers on 25th line to reflect changes */

    }


/*** ctrl_end() - repositions cursor to lower left hand corner of screen
 *
 *   ctrl_end() moves the cursor to the lower left hand corner of the
 *   screen. Since the current cursor line is probably changed, we flush
 *   and reload EditBuff[]. If there is any text marked, this call will
 *   clear the marking without deleting. Line number information on 25th
 *   line is redrawn to reflect changes. The actual content of the screen
 *   is unchanged by this call.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  CurRow	 - set to PAGESIZE - 1
 *		  CurCol	 - set to 0
 */

void ctrl_end()
    {

    register short i;

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it and   */
	for ( i = 0; i < MAXLINES; i++ )	 /* redraw the screen	   */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	drawscr(TopRow);
	}

    if( CurRow != (PageSize - 1) || CurCol != 0 ) {
	CurRow = (PageSize - 1);		      /* reposition cursor */
	CurCol = 0;
	VioSetCurPos( CurRow, CurCol, 0 );
	getline( (TopRow + CurRow), &EditBuff[0] );
	}

    line25();	    /* update line numbers on 25th line to reflect changes */

    }


/*** ctrl_pgup() - repositions cursor to beginning of file
 *
 *   ctrl_pgup() redraws the screen with the first screenfull of the file
 *   and moves the cursor to the upper left hand corner of the screen,
 *   coordinate position (0,0). Since the current cursor line is
 *   probably changed, we flush and reload EditBuff[]. If there is any
 *   text marked, this call will clear the marking without deleting.
 *   Line number information on 25th line is redrawn to reflect changes.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - set to 0
 *		  CurRow	 - set to 0
 *		  CurCol	 - set to 0
 */

void ctrl_pgup()
    {

    register short i;				      /* indexing variable */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it - no  */
	for ( i = 0; i < MAXLINES; i++ )	 /* need to redraw screen  */
	    MarkedLine[i] = 0;
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	}

    TopRow = 0;
    CurRow = 0; 				  /* reposition and redraw */
    CurCol = 0;
    VioSetCurPos( CurRow, CurCol, 0 );
    drawscr(TopRow);
    getline( (TopRow + CurRow), &EditBuff[0] );       /* reload EditBuff[] */
    line25();					       /* update 25th line */

    }


/*** ctrl_pgdn() - repositions cursor to beginning of file
 *
 *   ctrl_pgdn() redraws the screen with the last screenfull of the file
 *   and moves the cursor to the lower left hand corner of the screen,
 *   one line past the end of the file. Since the current cursor line is
 *   probably changed, we flush and reload EditBuff[]. If there is any
 *   text marked, this call will clear the marking without deleting.
 *   Line number information on 25th line is redrawn to reflect changes.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears this flag
 *		  LinesMarked	 - clears this flag
 *		  MarkedLine[]	 - clears all
 *		  CharsMarked	 - clears this flag
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - set to TotalLines - (PageSize - 1)
 *		  CurRow	 - set to end of file + 1
 *		  CurCol	 - set to 0
 */

void ctrl_pgdn()
    {
    register short i;				      /* indexing variable */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( LinesMarked || CharsMarked ) {
	LinesMarked = 0;			 /* if there's marked text */
	CharsMarked = 0;			 /* around, clear it - no  */
	for ( i = 0; i < MAXLINES; i++ )	 /* need to redraw screen  */
	    MarkedLine[i] = 0;			 /* as it gets done later  */
	for ( i = 0; i < LINESIZE; i++ )
	    MarkedChar[i] = 0;
	}
    if (TotalLines > (PageSize - 1))
	TopRow = TotalLines - (PageSize - 1);	     /* recalculate TopRow */
    else TopRow = 0;
    CurRow = TotalLines - TopRow;	      /* set cursor row and column */
    CurCol = 0;
    VioSetCurPos( CurRow, CurCol, 0 );
    getline( (TopRow + CurRow), &EditBuff[0] );       /* reload EditBuff[] */
    drawscr(TopRow);					  /* redraw screen */
    line25();					       /* update 25th line */

    }


/*** shift_left() - moves cursor left one and marks that character for deletion.
 *
 *   shift_left() moves the cursor one position to the left. If we are on
 *   a line that is already marked, that's all it does - just like regular
 *   left, but markings are not cleared. If we are not on a marked line,
 *   then the character we just moved to is marked for deletion. Unless it
 *   already was marked for deletion, in which case it gets un-marked.
 *
 *   EFFECTS:	  CharsMarked	 - sets this flag if LinesMarked not set
 *		  MarkedChar[]	 - sets this for the character we just moved to
 *		  CurCol	 - decremented one
 */

void shift_left()
    {

    if ( LinesMarked ) {	   /* if this line is marked, just move left */
	if ( CurCol > 0 ) {
	    CurCol -= 1;
	    VioSetCurPos( CurRow, CurCol, 0 );
	    }
	}
    else if( CurCol > 0 ) {		/* otherwise, see if there's room... */
	CurCol -= 1;
	VioSetCurPos( CurRow, CurCol, 0 );	       /* ...if so move left */
	CharsMarked = 1;
	if (MarkedChar[CurCol])
	    MarkedChar[CurCol] = 0;    /* and set marking for that character */
	else MarkedChar[CurCol] = 1;
	drawline();			   /* redraw line to update markings */
	}

    }


/*** shift_right() - moves cursor right one and marks the character
 *		     we were previously on for deletion.
 *
 *   shift_right() moves the cursor one position to the right. If we are on
 *   a line that is already marked, that's all it does - just like regular
 *   right, but markings are not cleared. If we are not on a marked line,
 *   then the character we just moved from is marked for deletion. Unless it
 *   already was marked for deletion, in which case it gets un-marked.
 *
 *   EFFECTS:	  CharsMarked	 - sets this flag if LinesMarked not set
 *		  MarkedChar[]	 - sets this for the character we just left
 *		  CurCol	 - incremented one
 */

void shift_right()
    {

    if ( LinesMarked ) {	     /* if this line marked, just move right */
	if (CurCol < (LINESIZE - 1)) {
	    CurCol += 1;
	    VioSetCurPos( CurRow, CurCol, 0 );
	    }
	}
    else if( CurCol < (LINESIZE - 1)) {  /* otherwise, see if there's room.. */
	CharsMarked = 1;
	if (MarkedChar[CurCol]) 	   /* if so, mark character we're on */
	    MarkedChar[CurCol] = 0;
	else MarkedChar[CurCol] = 1;
	CurCol += 1;				      /* then move right one */
	VioSetCurPos( CurRow, CurCol, 0 );
	drawline();					  /* and redraw line */
	}

    }


/*** shift_up() - moves cursor up one line and marks lines for deletion
 *
 *   shift_up() moves the cursor one line up. If no lines are marked, then
 *   both the previous line and the line moved to get marked for deletion.
 *   If lines are already marked, and were marked starting with another
 *   shift_up, then only the line we move to gets marked (the one we just
 *   left would already be marked). If there are lines marked but they
 *   were marked starting with a shift_down, then we un-mark the line we
 *   just left and do nothing to the line moved to. Unless the line moved
 *   to is the last one marked, in which case we un-mark it also to clear all
 *   markings. To determine how lines first got marked - by a shift_up or
 *   shift_down - we give the flag LinesMarked two different TRUE values,
 *   1 or 2 respectively.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears
 *		  LinesMarked	 - sets this flag, unless un-marking only
 *				   marked line present, in which case clears it
 *		  MarkedLine[]	 - may set or clear this
 *		  CharsMarked	 - clears this flag as we now have marked lines
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - decremented one if at top of page
 *		  CurRow	 - decremented one if not at top of page
 */

void shift_up()
    {
    register short i;				      /* indexing variable */

    char buff[2];	      /* local buffer for scrolling fill character */
    buff[0] = 32;			       /* character = 32 = <blank> */
    buff[1] = ForeHilite + BackHilite;	       /*  attribute = highlighted */

    if (EditBuffDirty) {			  /* this call will change */
	EditBuffDirty = 0;			  /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
	}

    if ( CharsMarked ) {			/* clear CharsMarked flags */
	CharsMarked = 0;			/* since we now will have  */
	for ( i = 0; i < LINESIZE; i++ )	/* the whole line marked.  */
	    MarkedChar[i] = 0;
	}

  /* if no lines currently marked, do this */
    if( !LinesMarked ) {
	LinesMarked = 1;	/* set flag to indicate marking started UP */
	MarkedLine[ TopRow + CurRow ] = 1;		      /* mark line */
	drawline();					      /* redraw it */
	if ( (TopRow + CurRow) != 0 ) { 	       /* if there's room, */
	    MarkedLine[ TopRow + CurRow - 1 ] = 1;	/* mark line above */
	    if ( CurRow == 0 ) {
		TopRow -= 1;			  /* ...may have to scroll */
		VioScrollDn( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		}
	    else {			   /* ...or may not have to scroll */
		CurRow -= 1;
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    drawline(); 				/* redraw new line */
	    }
	}

  /* if lines marked, and shift_up started marking, do this */
    else if( LinesMarked == 1 ) {
	if ( (TopRow + CurRow) != 0 ) {        /* if not at top of screen, */
	    MarkedLine[ TopRow + CurRow - 1 ] = 1;    /* mark next line up */
	    if ( CurRow == 0 ) {
		TopRow -= 1;			  /* ...may have to scroll */
		VioScrollDn( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		}
	    else {
		CurRow -= 1;		   /* ...or may not have to scroll */
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    drawline(); 			    /* redraw line move to */
	    }
	}

  /* if lines marked, and shift_down started marking, do this */
    else if( LinesMarked == 2 ) {
	MarkedLine[ TopRow + CurRow ] = 0;	   /* un-mark current line */
	drawline();					      /* redraw it */
	if( (TopRow + CurRow) != 0 ) {
	    if( CurRow == 0 ) { 	     /* ...may have to scroll down */
		TopRow -= 1;
		VioScrollDn( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		}
	    else {			 /* or may not have to scroll down */
		CurRow -= 1;
		getline( (TopRow + CurRow), &EditBuff[0] );	 /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    if( !MarkedLine[ TopRow + CurRow - 1 ] ) { /* if line moved to */
		MarkedLine[ TopRow + CurRow ] = 0;     /* is last marked,  */
		LinesMarked = 0;		       /* clear it too	   */
		drawline();
		}
	    }
	}

    line25();	    /* update line numbers on 25th line to reflect changes */

    }


/*** shift_down() - moves cursor down one line and marks lines for deletion
 *
 *   shift_down() moves the cursor one line down. If no lines are marked, then
 *   both the previous line and the line moved to get marked for deletion.
 *   If lines are already marked, and were marked starting with another
 *   shift_down, then only the line we move to gets marked (the one we just
 *   left would already be marked). If there are lines marked but they
 *   were marked starting with a shift_up, then we un-mark the line we
 *   just left and do nothing to the line moved to. Unless the line moved
 *   to is the last one marked, in which case we un-mark it also to clear all
 *   markings. To determine how lines first got marked - by a shift_up or
 *   shift_down - we give the flag LinesMarked two different TRUE values,
 *   1 or 2 respectively.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears
 *		  LinesMarked	 - sets this flag, unless un-marking only
 *				   marked line present, in which case clears it
 *		  MarkedLine[]	 - may set or clear this
 *		  CharsMarked	 - clears this flag as we now have marked lines
 *		  MarkedChar[]	 - clears all
 *		  TopRow	 - incremented one if at bottom of page
 *		  CurRow	 - incremented one if not at bottom of page
 */

void shift_down()
    {
    register short i;					/* indexing variable */

    char buff[2];			  /* local buffer for fill character */
    buff[0] = 32;				 /* character = 32 = <blank> */
    buff[1] = ForeHilite + BackHilite;		 /* attribute =  highlighted */

    if (EditBuffDirty) {			    /* this call will change */
	EditBuffDirty = 0;			    /* cursor line, so flush */
	flushline((TopRow + CurRow), EditBuff);     /* edit buffer if dirty  */
	}

    if ( CharsMarked ) {			     /* clear all character  */
	CharsMarked = 0;			     /* markings, since line */
	for ( i = 0; i < LINESIZE; i++ )	     /* is now marked.	     */
	    MarkedChar[i] = 0;
	}

  /* if no lines are currently marked, do this */
    if( !LinesMarked ) {
	LinesMarked = 2;       /* set flag to show marking started with DOWN */
	MarkedLine[ TopRow + CurRow ] = 1;		/* mark current line */
	drawline();					    /* and redraw it */
	if( ( TopRow + CurRow ) < TotalLines ) {    /* if room to move down, */
	    MarkedLine[ TopRow + CurRow + 1 ] = 1;	  /* mark line below */
	    if ( CurRow == (PageSize - 1) ) {
		TopRow += 1;			    /* ...may have to scroll */
		VioScrollUp( 0, 0, CurRow, (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	   /* reload */
		}
	    else {			     /* ...or may not have to scroll */
		CurRow += 1;
		getline( (TopRow + CurRow), &EditBuff[0] );	   /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    drawline(); 				  /* redraw new line */
	    }
	}

  /* if lines are marked, and first marking was another shift_down, do this */
    else if( LinesMarked == 2 ) {
	if ( (TopRow + CurRow) < TotalLines ) {     /* if room to move down */
	    MarkedLine[ TopRow + CurRow + 1 ] = 1;	 /* mark line below */
	    if ( CurRow == (PageSize - 1) ) {
		TopRow += 1;			   /* ...may have to scroll */
		VioScrollUp( 0, 0, CurRow, (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	  /* reload */
		}
	    else {			    /* ...or may not have to scroll */
		CurRow += 1;
		getline( (TopRow + CurRow), &EditBuff[0] );	  /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    drawline(); 	/* redraw the current line to show markings */
	    }
	}

  /* if lines are marked, and first marking was a shift_up, do this */
    else if( LinesMarked == 1 ) {
	MarkedLine[ TopRow + CurRow ] = 0;	    /* un-mark current line */
	drawline();					   /* and redraw it */
	if ( (TopRow + CurRow) < TotalLines ) {
	    if ( CurRow == (PageSize - 1) ) {
		TopRow += 1;			   /* ...may have to scroll */
		VioScrollUp( 0, 0, CurRow, (LINESIZE - 1), 1,
			     buff, 0);
		getline( (TopRow + CurRow), &EditBuff[0] );	  /* reload */
		}
	    else {			    /* ...or may not have to scroll */
		CurRow += 1;
		getline( (TopRow + CurRow), &EditBuff[0] );	  /* reload */
		VioSetCurPos( CurRow, CurCol, 0 );
		}
	    }
	if( (TopRow + CurRow) < TotalLines ) {
	    if( !MarkedLine[ TopRow + CurRow + 1 ] ) {
		MarkedLine[ TopRow + CurRow ] = 0;
		LinesMarked = 0;		     /* if only 1 line left */
		}				  /* marked, un-mark it too */
	    }
	drawline();			 /* redraw line to reflect markings */

	}

    line25();		 /* update line info on bottom line to show changes */

    }


/*** shift_home() - moves cursor to first character in current line and
 *		    marks all characters in between for deletion
 *
 *   shift_down() moves the cursor to the first printable character in the
 *   current line. If the line is already marked, that's all it does, just
 *   like a regular home except markings are not cleared. Otherwise, all
 *   characters between the cursor position when the function is called and
 *   the first character in the line get their markings toggled - that is, if
 *   they are not marked they get marked, if they are already marked they
 *   get un-marked.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears
 *		  CharsMarked	 - sets this flag unless line is marked
 *		  MarkedChar[]	 - sets for all appropriate characters
 *		  CurCol	 - set to position of first printable character
 */

void shift_home()
    {

    register short i, j;			       /* indexing variables */

    if (EditBuffDirty) {			   /* this call will need to */
	EditBuffDirty = 0;			   /* get correct info on    */
	flushline((TopRow + CurRow), EditBuff);    /* line length, so flush  */
	}					   /* edit buffer if dirty   */

    if( (TopRow + CurRow) < TotalLines ) {
	i = LineTable[TopRow + CurRow]->linelength;	/* i is position + 1 */
	}						/* last char in line */
    else i = 0;

    for( j = 0; ( j < i )  &&  !isgraph(EditBuff[j]); j++ );
							 /* j is position of */
							 /* first non-blank  */
    if( !LinesMarked ) {			  /* if no lines marked,     */
	if( j < CurCol ) {			  /* flag everything between */
	    CharsMarked = 1;			  /* CurCol and j as Marked  */
	    for( i = j; i < CurCol; i++ ) {
		if( !MarkedChar[i] )
		    MarkedChar[i] = 1;		 /* may be moving forward... */
		else MarkedChar[i] = 0;
		}
	    }
	else if( j > CurCol ) {
	    CharsMarked = 1;
	    for( i = CurCol; i < j; i++ ) {		  /* ... or backward */
		if( !MarkedChar[i] )
		    MarkedChar[i] = 1;
		else MarkedChar[i] = 0;
		}
	    }
	}

    CurCol = j; 			   /* if lines are marked, just move */
    VioSetCurPos( CurRow, CurCol, 0 );
    drawline(); 			     /* redraw line to show markings */

    }


/*** shift_end() - moves cursor to one beyond last character in current line
 *		   and marks all characters in between for deletion
 *
 *   shift_down() moves the cursor to one position beyond the last printable
 *   character in the current line. If the line is already marked, that's all
 *   it does, just like a regular end_ except markings are not cleared.
 *   Otherwise, all characters between the cursor position when the function
 *   is called and the final cursor position get their markings toggled - that
 *   is, if they are not marked they get marked, if they are already marked
 *   they get un-marked.
 *
 *   EFFECTS:	  EditBuff[]	 - flushes and reloads
 *		  EditBuffDirty  - clears
 *		  CharsMarked	 - sets this flag unless line is marked
 *		  MarkedChar[]	 - sets for all appropriate characters
 *		  CurCol	 - set to one beyond position of
 *				   last printable character
 */

void shift_end()
    {

    register short i, j;			      /* indexing variables */

    if (EditBuffDirty) {			  /* this call will need to */
	EditBuffDirty = 0;			  /* get correct info on    */
	flushline((TopRow + CurRow), EditBuff);   /* line length, so flush  */
	}					  /* edit buffer if dirty   */

    if( (TopRow + CurRow) < TotalLines ) {
	i = LineTable[TopRow + CurRow]->linelength;    /* i is position + 1 */
	}					       /* last char in line */
    else i = 0;

    if( !LinesMarked ) {			 /* if no lines marked,     */
	if( i < CurCol ) {			 /* flag everything between */
	    CharsMarked = 1;			 /* CurCol and i as Marked  */
	    for( j = i; j < CurCol; j++ ) {
		if( !MarkedChar[j] )		    /* may move forwards... */
		    MarkedChar[j] = 1;
		else MarkedChar[j] = 0;
		}
	    }
	else if( i > CurCol ) {
	    CharsMarked = 1;				/* ... or backwards */
	    for( j = CurCol; j < i; j++ ) {
		if( !MarkedChar[j] )
		    MarkedChar[j] = 1;
		else MarkedChar[j] = 0;
		}
	    }
	}

    CurCol = i; 			    /* if line is marked, just move */
    VioSetCurPos( CurRow, CurCol, 0 );
    drawline(); 						  /* redraw */

    }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.