Annotation of os2sdk/demos/apps/sse/keyfuncs.c, revision 1.1

1.1     ! root        1: /****** KEYFUNCS.C - a collection of routines to service special keys
        !             2:  *                  each routine has the name of the key it services
        !             3:  */
        !             4: 
        !             5: #include <ctype.h>
        !             6: #include <dos.h>
        !             7: #include <doscalls.h>
        !             8: #include <subcalls.h>
        !             9: #include "ssedefs.h"
        !            10: #include "keydefs.h"
        !            11: 
        !            12: 
        !            13: /*** insert(c) - inserts the character c at the current cursor position
        !            14:  *
        !            15:  *   This routine is called when any regular printable character is hit.
        !            16:  *
        !            17:  *   insert(c) checks to see if there is room in EditBuff[] to insert the
        !            18:  *   character it is passed by seeing if there is already a printable
        !            19:  *   character in the 80th column. If so, no character can be inserted
        !            20:  *   so we just call badkey(). If there is room, insert the character
        !            21:  *   at the position indicated by CurCol and shift everything past that
        !            22:  *   over one; mark EditBuff[] as dirty.
        !            23:  *
        !            24:  *   If there is text that has been marked, insert() will call del() to
        !            25:  *   remove it before inserting its character where the marked text was.
        !            26:  *
        !            27:  *   The character we are passed has already been checked as being a
        !            28:  *   valid printable characters.
        !            29:  *
        !            30:  *   insert(c)
        !            31:  *
        !            32:  *   ENTRY:      c  -  the validated character to be inserted
        !            33:  *
        !            34:  *   EFFECTS:    EditBuff[]     - changes its contents if successful
        !            35:  *               EditBuffDirty  - sets this flag if EditBuff changed
        !            36:  *               LinesMarked    - clears this if set
        !            37:  *               CharsMarked    - clears this if set
        !            38:  *               CurCol         - increments this one
        !            39:  *
        !            40:  *   The effects of del() should also be considered since it may be
        !            41:  *   called from this function.
        !            42:  */
        !            43: 
        !            44: insert(c)
        !            45:     char c;             /* the character we are to insert, already validated */
        !            46:     {
        !            47: 
        !            48:     register short i;                                   /* indexing variable */
        !            49: 
        !            50:     if (LinesMarked || CharsMarked)       /* if there is marked text around, */
        !            51:        del();                             /* we first want to delete it      */
        !            52: 
        !            53:     if ( EditBuff[LINESIZE - 1] == ' ')  /* can only insert when there's room */
        !            54:        {
        !            55:        for ( i = (LINESIZE - 1); i > CurCol; i-- )
        !            56:            EditBuff[i] = EditBuff[i-1];         /* shift everything over one */
        !            57:        EditBuff[CurCol] = c;                    /* put in the new character  */
        !            58:        drawline();
        !            59:        CurCol += 1;                                        /* update display */
        !            60:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !            61:        EditBuffDirty = 1;                       /* mark edit buffer as dirty */
        !            62:        }
        !            63: 
        !            64:     else badkey();                    /* if no room, exit as for invalid key */
        !            65: 
        !            66:     }
        !            67: 
        !            68: 
        !            69: /*** up() - moves the cursor up one row
        !            70:  *
        !            71:  *   up() moves the cursor position up one row. If we are at the top of
        !            72:  *   the screen already, up() scrolls the screen down one line. If we
        !            73:  *   are at the top of the file, it does nothing. If there is marked text
        !            74:  *   around, up() will clear it without deleting. Because the current row
        !            75:  *   in the file is changed by up(), EditBuff[] is flushed and refilled
        !            76:  *   and line25() is called to update the line information at the bottom
        !            77:  *   of the screen.
        !            78:  *
        !            79:  *   EFFECTS:    EditBuff[]     - flushes its current contents and reloads
        !            80:  *               EditBuffDirty  - clears this flag
        !            81:  *               LinesMarked    - clears this flag
        !            82:  *               MarkedLine[]   - clears all
        !            83:  *               CharsMarked    - clears this flag
        !            84:  *               MarkedChar[]   - clears all
        !            85:  *               TopRow         - if at top of screen, decrements this one
        !            86:  *               CurRow         - otherwise, decrements this one
        !            87:  */
        !            88: 
        !            89: 
        !            90: void up()
        !            91:     {
        !            92: 
        !            93:     register short i;                                /* indexing variable */
        !            94: 
        !            95:     char buff[2];            /* local buffer for scrolling fill character */
        !            96:     buff[0] = 32;            /*                 character = 32 = <blank>  */
        !            97:     buff[1] = ForeNorm;       /*                     attribute = normal   */
        !            98: 
        !            99:     if (EditBuffDirty) {                         /* this call will change */
        !           100:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           101:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           102:        }
        !           103: 
        !           104:     if ( LinesMarked || CharsMarked ) {
        !           105:        LinesMarked = 0;                         /* if there's marked text */
        !           106:        CharsMarked = 0;                         /* around, clear it and   */
        !           107:        for ( i = 0; i < MAXLINES; i++ )         /* redraw the screen      */
        !           108:            MarkedLine[i] = 0;
        !           109:        for ( i = 0; i < LINESIZE; i++ )
        !           110:            MarkedChar[i] = 0;
        !           111:        drawscr(TopRow);
        !           112:        }
        !           113: 
        !           114:     if ( (TopRow + CurRow) != 0 ) {         /* if top of file, do nothing */
        !           115:        if ( CurRow == 0 ) {
        !           116:            TopRow -= 1;                  /* if top of screen, scroll down */
        !           117:            VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
        !           118:                       (char far *)buff, 0);
        !           119:            getline( (TopRow + CurRow), &EditBuff[0] );
        !           120:            drawline();
        !           121:            }
        !           122:        else {
        !           123:            CurRow -= 1;                  /* otherwise just move cursor up */
        !           124:            getline( (TopRow + CurRow), &EditBuff[0] );
        !           125:            VIOSETCURPOS( CurRow, CurCol, 0 );
        !           126:            }
        !           127:        }
        !           128: 
        !           129:     line25();        /* reset line numbers on 25th line to reflect change */
        !           130: 
        !           131:     }
        !           132: 
        !           133: 
        !           134: /*** down() - moves the cursor up one row
        !           135:  *
        !           136:  *   down() moves the cursor down one row. If we are at the top of
        !           137:  *   the screen already, down() scrolls the screen up one line. If we
        !           138:  *   are at the end of the file, it does nothing. If there is marked text
        !           139:  *   around, down() will clear it without deleting. Because the current row
        !           140:  *   in the file is changed by down(), EditBuff[] is flushed and refilled
        !           141:  *   and line25() is called to update the line information at the bottom
        !           142:  *   of the screen.
        !           143:  *
        !           144:  *   EFFECTS:    EditBuff[]     - flushes its current contents and reloads
        !           145:  *               EditBuffDirty  - clears this flag
        !           146:  *               LinesMarked    - clears this flag
        !           147:  *               MarkedLine[]   - clears all
        !           148:  *               CharsMarked    - clears this flag
        !           149:  *               MarkedChar[]   - clears all
        !           150:  *               TopRow         - if at bottom of screen, increments this one
        !           151:  *               CurRow         - otherwise, increments this one
        !           152:  */
        !           153: 
        !           154: 
        !           155: void down()
        !           156:     {
        !           157: 
        !           158:     register short i;                                /* indexing variable */
        !           159: 
        !           160:     char buff[2];            /* local buffer for scrolling fill character */
        !           161:     buff[0] = 32;            /*                  character = 32 = <blank> */
        !           162:     buff[1] = ForeNorm;       /*                      attribute = normal  */
        !           163: 
        !           164:     if (EditBuffDirty) {                         /* this call will change */
        !           165:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           166:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           167:        }
        !           168: 
        !           169:     if ( LinesMarked || CharsMarked ) {
        !           170:        LinesMarked = 0;                         /* if there's marked text */
        !           171:        CharsMarked = 0;                         /* around, clear it and   */
        !           172:        for ( i = 0; i < MAXLINES; i++ )         /* redraw the screen      */
        !           173:            MarkedLine[i] = 0;
        !           174:        for ( i = 0; i < LINESIZE; i++ )
        !           175:            MarkedChar[i] = 0;
        !           176:        drawscr(TopRow);
        !           177:        }
        !           178: 
        !           179:     if ( (TopRow + CurRow) < (TotalLines) ) {       /* if EOF, do nothing */
        !           180:        if ( CurRow == (PageSize - 1) ) {   /* if end of screen, scroll up */
        !           181:            TopRow += 1;
        !           182:            VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1,
        !           183:                       (char far *)buff, 0);
        !           184:            getline( (TopRow + CurRow), &EditBuff[0] );
        !           185:            drawline();
        !           186:            }
        !           187:        else {
        !           188:            CurRow += 1;                          /* else move cursor down */
        !           189:            getline( (TopRow + CurRow), &EditBuff[0] );
        !           190:            VIOSETCURPOS( CurRow, CurCol, 0 );
        !           191:            }
        !           192:        }
        !           193: 
        !           194:     line25();        /* reset line numbers on 25th line to reflect change */
        !           195: 
        !           196:     }
        !           197: 
        !           198: 
        !           199: /*** home() - moves the cursor to beginning of the line
        !           200:  *
        !           201:  *   home() moves the cursor to the position of the first printable character
        !           202:  *   in the current line. If there is marked text, home() will clear it
        !           203:  *   without deleting. We need to be able to get correct information about
        !           204:  *   the length of the current line from LineTable[], so we flush EditBuff[]
        !           205:  *   on entry; but since the current line does not get changed, we do not
        !           206:  *   reload it (current contents remain correct) and we do not call line25().
        !           207:  *
        !           208:  *   EFFECTS:    EditBuffDirty  - clears this flag
        !           209:  *               LinesMarked    - clears this flag
        !           210:  *               MarkedLine[]   - clears all
        !           211:  *               CharsMarked    - clears this flag
        !           212:  *               MarkedChar[]   - clears all
        !           213:  *               CurCol         - set to position of first printable character
        !           214:  */
        !           215: 
        !           216: void home()
        !           217:     {
        !           218: 
        !           219:     register short i, j;                              /* indexing variables */
        !           220: 
        !           221: 
        !           222:     if (EditBuffDirty) {                          /* this call will need to */
        !           223:        EditBuffDirty = 0;                         /* get correct info on    */
        !           224:        flushline((TopRow + CurRow), EditBuff);    /* line length, so flush  */
        !           225:        }                                          /* edit buffer if dirty   */
        !           226: 
        !           227:     if ( LinesMarked || CharsMarked ) {
        !           228:        LinesMarked = 0;                           /* if there's marked text */
        !           229:        CharsMarked = 0;                           /* around, clear it and   */
        !           230:        for ( i = 0; i < MAXLINES; i++ )           /* redraw the screen      */
        !           231:            MarkedLine[i] = 0;
        !           232:        for ( i = 0; i < LINESIZE; i++ )
        !           233:            MarkedChar[i] = 0;
        !           234:        drawscr(TopRow);
        !           235:        }
        !           236: 
        !           237:     if( (TopRow + CurRow) < TotalLines ) {
        !           238:        i = LineTable[TopRow + CurRow]->linelength;     /* i is position of  */
        !           239:        i--;                                            /* last char in line */
        !           240:        }
        !           241:     else i = 0;            /* if we're off the end of the file, that's 0... */
        !           242: 
        !           243: 
        !           244:     for( j = 0; ( j <= i )  && !isgraph(EditBuff[j]); j++ );
        !           245: 
        !           246:     CurCol = j;                                         /* j is position of */
        !           247:     VIOSETCURPOS( CurRow, CurCol, 0 );                  /* first non-blank  */
        !           248: 
        !           249:     }
        !           250: 
        !           251: 
        !           252: /*** end_() - moves the cursor to one position past the end of the current line
        !           253:  *
        !           254:  *   end_() moves the cursor to one position beyond the position of the last
        !           255:  *   printable character in the current line. If the last printable character
        !           256:  *   is already in column 80, we just go there. If there is marked text,
        !           257:  *   end_() will clear it without deleting. We need to be able to get correct
        !           258:  *   information about the length of the current line from LineTable[], so
        !           259:  *   we flush EditBuff[] on entry; but since the current line does not get
        !           260:  *   changed, we do not reload it (current contents remain correct) and we
        !           261:  *   do not call line25(). Note that this routine had to be named end_() not
        !           262:  *   end() since that is a reserved word under the compiler used.
        !           263:  *
        !           264:  *   EFFECTS:    EditBuffDirty  - clears this flag
        !           265:  *               LinesMarked    - clears this flag
        !           266:  *               MarkedLine[]   - clears all
        !           267:  *               CharsMarked    - clears this flag
        !           268:  *               MarkedChar[]   - clears all
        !           269:  *               CurCol         - set to position of last printable
        !           270:  *                                character, plus one if possible
        !           271:  */
        !           272: 
        !           273: void end_()
        !           274:     {
        !           275: 
        !           276:     register short i;                                 /* indexing variable */
        !           277: 
        !           278:     if (EditBuffDirty) {                         /* this call will need to */
        !           279:        EditBuffDirty = 0;                        /* get correct info on    */
        !           280:        flushline((TopRow + CurRow), EditBuff);   /* line length, so flush  */
        !           281:        }                                         /* edit buffer if dirty   */
        !           282: 
        !           283:     if ( LinesMarked || CharsMarked ) {
        !           284:        LinesMarked = 0;                          /* if there's marked text */
        !           285:        CharsMarked = 0;                          /* around, clear it and   */
        !           286:        for ( i = 0; i < MAXLINES; i++ )          /* redraw the screen      */
        !           287:            MarkedLine[i] = 0;
        !           288:        for ( i = 0; i < LINESIZE; i++ )
        !           289:            MarkedChar[i] = 0;
        !           290:        drawscr(TopRow);
        !           291:        }
        !           292: 
        !           293:     if( (TopRow + CurRow) < TotalLines ) {
        !           294:        i = LineTable[TopRow + CurRow]->linelength;    /* i is position of  */
        !           295:        }                                              /* last char in line */
        !           296:     else i = 0;
        !           297: 
        !           298:     CurCol = i;
        !           299:     VIOSETCURPOS( CurRow, CurCol, 0 );
        !           300: 
        !           301:     }
        !           302: 
        !           303: 
        !           304: /*** pgup() - moves up one screen
        !           305:  *
        !           306:  *   pgup() subtracts PageSize from the current value of TopRow and then
        !           307:  *   redraws the screen, effectively moving us up one screen. If TopRow
        !           308:  *   is less than PageSize, we just go to the start of the file. The
        !           309:  *   position of the cursor on the screen is not altered. If there is marked
        !           310:  *   text, pgup() will clear it without deleting. Because this call changes
        !           311:  *   the current line, we flush and reload EditBuff[].
        !           312:  *
        !           313:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           314:  *               EditBuffDirty  - clears this flag
        !           315:  *               LinesMarked    - clears this flag
        !           316:  *               MarkedLine[]   - clears all
        !           317:  *               CharsMarked    - clears this flag
        !           318:  *               MarkedChar[]   - clears all
        !           319:  *               TopRow         - gets PageSize subtracted from it
        !           320:  *                                if possible, otherwise set to 0.
        !           321:  */
        !           322: 
        !           323: void pgup()
        !           324:     {
        !           325: 
        !           326:     register short i;                                /* indexing variable */
        !           327: 
        !           328:     if (EditBuffDirty) {                         /* this call will change */
        !           329:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           330:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           331:        }
        !           332: 
        !           333:     if ( LinesMarked || CharsMarked ) {
        !           334:        LinesMarked = 0;                         /* if there's marked text */
        !           335:        CharsMarked = 0;                         /* around, clear it and   */
        !           336:        for ( i = 0; i < MAXLINES; i++ )         /* redraw the screen      */
        !           337:            MarkedLine[i] = 0;
        !           338:        for ( i = 0; i < LINESIZE; i++ )
        !           339:            MarkedChar[i] = 0;
        !           340:        }
        !           341: 
        !           342:     if ( TopRow >= PageSize )           /* go up one page if there's room */
        !           343:        TopRow -= PageSize;
        !           344:     else {
        !           345:        TopRow = 0;                    /* otherwise just go to top of file */
        !           346:        CurRow = 0;
        !           347:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !           348:        }
        !           349: 
        !           350:     drawscr(TopRow);                                /* redraw screen and  */
        !           351:     getline( (TopRow + CurRow), &EditBuff[0] );      /* update edit buffer */
        !           352:     line25();        /* reset line numbers on 25th line to reflect change */
        !           353: 
        !           354:     }
        !           355: 
        !           356: 
        !           357: /*** pgdn() - moves down one screen
        !           358:  *
        !           359:  *   pgdn() adds PageSize to the current value of TopRow and then
        !           360:  *   redraws the screen, effectively moving us down one screen. If the
        !           361:  *   result of adding TopRow and PageSize is greater than TotalLines
        !           362:  *   (in other words, we would be moving off the end of the file), then
        !           363:  *   we just move to one beyond the end of the file. The position of the
        !           364:  *   cursor on the screen is not altered. If there is marked text,
        !           365:  *   pgdn() will clear it without deleting. Because this call changes
        !           366:  *   the current line, we flush and reload EditBuff[].
        !           367:  *
        !           368:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           369:  *               EditBuffDirty  - clears this flag
        !           370:  *               LinesMarked    - clears this flag
        !           371:  *               MarkedLine[]   - clears all
        !           372:  *               CharsMarked    - clears this flag
        !           373:  *               MarkedChar[]   - clears all
        !           374:  *               TopRow         - gets PageSize added to it if possible,
        !           375:  *                                otherwise set to TotalLines - PageSize - 1.
        !           376:  */
        !           377: 
        !           378: void pgdn()
        !           379:     {
        !           380: 
        !           381:     register short i;                                  /* indexing variable */
        !           382: 
        !           383:     if (EditBuffDirty) {                           /* this call will change */
        !           384:        EditBuffDirty = 0;                          /* cursor line, so flush */
        !           385:        flushline((TopRow + CurRow), EditBuff);     /* edit buffer if dirty  */
        !           386:        }
        !           387: 
        !           388:     if ( LinesMarked || CharsMarked ) {
        !           389:        LinesMarked = 0;                           /* if there's marked text */
        !           390:        CharsMarked = 0;                           /* around, clear it       */
        !           391:        for ( i = 0; i < MAXLINES; i++ )
        !           392:            MarkedLine[i] = 0;
        !           393:        for ( i = 0; i < LINESIZE; i++ )
        !           394:            MarkedChar[i] = 0;
        !           395:        }
        !           396: 
        !           397:     TopRow += PageSize;                                /* go down one page  */
        !           398:     if ( TopRow > (TotalLines - (PageSize -1)) ) {     /* if there's room,  */
        !           399:        TopRow = (TotalLines - (PageSize -1));          /* else stop at last */
        !           400:        CurRow = (PageSize -1);                         /* full page         */
        !           401:        VIOSETCURPOS(CurRow, CurCol, 0);
        !           402:        }
        !           403: 
        !           404:     drawscr(TopRow);                                  /* redraw screen and  */
        !           405:     getline( (TopRow + CurRow), &EditBuff[0] );        /* update edit buffer */
        !           406:     line25();          /* reset line numbers on 25th line to reflect change */
        !           407: 
        !           408:     }
        !           409: 
        !           410: 
        !           411: /*** bksp() - deletes character to right of the cursor; moves cursor right one
        !           412:  *
        !           413:  *   bksp() clears any marked text without deleting it, flushes EditBuff[],
        !           414:  *   moves the cursor right one position and calls del(). If we're at the
        !           415:  *   beginning of a line so there's nothing to our right, calls badkey().
        !           416:  *
        !           417:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           418:  *               EditBuffDirty  - clears this flag
        !           419:  *               LinesMarked    - clears this flag
        !           420:  *               MarkedLine[]   - clears all
        !           421:  *               CharsMarked    - clears this flag
        !           422:  *               MarkedChar[]   - clears all
        !           423:  *               CurCol         - decrements if possible
        !           424:  *
        !           425:  *   The effects of del() should also be considered since it may be
        !           426:  *   called from this function.
        !           427:  */
        !           428: 
        !           429: void bksp()
        !           430:     {
        !           431: 
        !           432:     register short i;                                 /* indexing variable */
        !           433: 
        !           434:     if ( LinesMarked || CharsMarked ) {
        !           435:        LinesMarked = 0;                          /* if there's marked text */
        !           436:        CharsMarked = 0;                          /* around, clear it and   */
        !           437:        for ( i = 0; i < MAXLINES; i++ )          /* redraw the screen      */
        !           438:            MarkedLine[i] = 0;
        !           439:        for ( i = 0; i < LINESIZE; i++ )
        !           440:            MarkedChar[i] = 0;
        !           441: 
        !           442:        if (EditBuffDirty) {                         /* flush before redraw */
        !           443:            EditBuffDirty = 0;                       /* to get any changes  */
        !           444:            flushline((TopRow + CurRow), EditBuff);
        !           445:            }
        !           446:        drawscr(TopRow);
        !           447:        }
        !           448: 
        !           449:     if( CurCol == 0 )           /* can't backspace if already at left edge */
        !           450:        badkey();
        !           451:     else {
        !           452:        CurCol -= 1;                    /* otherwise, move left one and del */
        !           453:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !           454:        del();
        !           455:        }
        !           456:     }
        !           457: 
        !           458: 
        !           459: /*** del() - deletes all indicated text
        !           460:  *
        !           461:  *   del() is the function for deleting text. What gets deleted depends on
        !           462:  *   what is marked. If there are marked lines around (as indicated by the
        !           463:  *   LinesMarked flag) then we delete the marked lines, clear all the line
        !           464:  *   marking flags, and adjust LineTable[] to reflect the change. Note that
        !           465:  *   if there are lines marked, there cannot be characters marked too. If
        !           466:  *   there are no lines marked, but characters marked, these characters are
        !           467:  *   deleted and EditBuff[] is adjusted to reflect the change and flagged
        !           468:  *   as dirty. If there are no lines or characters marked, then the character
        !           469:  *   under the cursor is deleted and EditBuff[] is adjusted accordingly and
        !           470:  *   marked as dirty.
        !           471:  *
        !           472:  *   EFFECTS:    EditBuff[]     - contents altered if no lines were marked
        !           473:  *               EditBuffDirty  - set if no lines were marked
        !           474:  *               LineTable[]    - contents altered if lines were marked
        !           475:  *               TotalLines     - altered if lines were marked
        !           476:  *               LinesMarked    - clears this flag
        !           477:  *               MarkedLine[]   - clears all
        !           478:  *               CharsMarked    - clears this flag
        !           479:  *               MarkedChar[]   - clears all
        !           480:  *               TopRow         - may change, depending on what's marked
        !           481:  *               CurRow         - may change, depending on what's marked
        !           482:  *
        !           483:  */
        !           484: 
        !           485: void del()
        !           486:     {
        !           487: 
        !           488:     register short i, j;                               /* indexing variables */
        !           489: 
        !           490:     if (LinesMarked) {                       /* if lines are marked, do this */
        !           491:        for( i = 0; !MarkedLine[i]; i++ );
        !           492:        j = i;                             /* i, j refer to first marked line */
        !           493:        if( i <= TopRow ) {
        !           494:            if( i != 0 ) {
        !           495:                TopRow = i - 1;           /* if first line to be deleted is   */
        !           496:                CurRow = 1;               /* off the top of the screen, then  */
        !           497:                }                         /* set TopRow to last unmarked line */
        !           498:            else {
        !           499:                TopRow = 0;                /* or if there are no unmarked     */
        !           500:                CurRow = 0;                /* lines ahead of the marked ones, */
        !           501:                }                          /* set TopRow to start of the file */
        !           502:            }
        !           503:        else CurRow = i - TopRow;
        !           504:        for( ; MarkedLine[i]; i++ )                /* delete all marked lines */
        !           505:            deleteline( i );               /* i refers to first unmarked line */
        !           506:        for( ; i < TotalLines; i++,j++ )                /* adjust LineTable[] */
        !           507:            LineTable[j] = LineTable[i];
        !           508:        TotalLines -= ( i - j );                         /* adjust TotalLines */
        !           509:        LinesMarked = 0;
        !           510:        for( i = 0; i < MAXLINES; i++ )           /* clear line marking flags */
        !           511:            MarkedLine[i] = 0;
        !           512:        drawscr(TopRow);                                     /* redraw screen */
        !           513:        VIOSETCURPOS(CurRow, CurCol, 0);
        !           514:        getline( (TopRow + CurRow), &EditBuff[0] );      /* reload EditBuff[] */
        !           515:        }
        !           516: 
        !           517:     else if (CharsMarked) {   /* if no lines marked but chars marked, do this */
        !           518:        for( i = 0; !MarkedChar[i] & ( i < LINESIZE ); i++ );
        !           519:        j = i;                        /* i, j refer to first marked character */
        !           520:        CurCol = j;
        !           521:        VIOSETCURPOS(CurRow, CurCol, 0);            /* adjust cursor position */
        !           522:        for( ; MarkedChar[i] & (i < LINESIZE); i++ ); /* i now first unmarked */
        !           523:        for( ; i < LINESIZE; i++, j++ )
        !           524:            EditBuff[j] = EditBuff[i];   /* remove characters between i and j */
        !           525:        for( ; j < LINESIZE; j++ )
        !           526:            EditBuff[j] = ' ';                /* fill end of line with blanks */
        !           527:        CharsMarked = 0;
        !           528:        for( i = 0; i < LINESIZE; i++ )  /* clear all character marking flags */
        !           529:            MarkedChar[i] = 0;
        !           530:        drawline();                                            /* redraw line */
        !           531:        EditBuffDirty = 1;                        /* mark EditBuff[] as dirty */
        !           532:        }
        !           533: 
        !           534:     else {                           /* if no lines or chars marked, do this */
        !           535:        for( i = (CurCol + 1); i < LINESIZE; i++ )
        !           536:           EditBuff[i-1] = EditBuff[i];      /* remove character under cursor */
        !           537:        EditBuff[LINESIZE-1] = ' ';            /* fill end of line with blank */
        !           538:        drawline();                                            /* redraw line */
        !           539:        EditBuffDirty = 1;                        /* mark EditBuff[] as dirty */
        !           540:        }
        !           541: 
        !           542:     line25();          /* reset line numbers on 25th line to reflect changes */
        !           543: 
        !           544:     }
        !           545: 
        !           546: 
        !           547: /*** F9() - saves the file being edited and exits
        !           548:  *
        !           549:  *   F9() save the file being edited with any changes that have been made
        !           550:  *   and exits the editor. The user is given a prompt to be sure they want
        !           551:  *   do quit; hitting carriage return goes ahead with the save-and-quit,
        !           552:  *   while any other key returns you to the editor.
        !           553:  *
        !           554:  *   EFFECTS:    If quit not completed:    EditBuff[]    -  gets flushed
        !           555:  *                                         EditBuffDirty -  gets cleared
        !           556:  */
        !           557: 
        !           558: void F9()
        !           559:     {
        !           560: 
        !           561:     static char message[LINESIZE] = "Save file as:";
        !           562:     struct  KeyData keydata;
        !           563:     char attrib = Fore25 + Back25;
        !           564:     int i;
        !           565: 
        !           566:     if (EditBuffDirty) {                  /* flush the edit buffer if dirty */
        !           567:        EditBuffDirty = 0;                 /* so all editting will be saved  */
        !           568:        flushline((TopRow + CurRow), EditBuff);
        !           569:        }
        !           570: 
        !           571:     for( i = 0; (i < 65) && (fname[i] != 0); message[i + 14] = fname[i], i++ );
        !           572:                                        /* copy filename into prompt message */
        !           573: 
        !           574:     VIOWRTCHARSTRATT( message, 80, PageSize, 0, &attrib, 0 );
        !           575:                                                        /* write out message */
        !           576: 
        !           577:     KBDCHARIN( &keydata, 0, 0 );                  /* wait for user response */
        !           578: 
        !           579:     if( keydata.char_code == CRETURN_CHAR ) {    /* if response was <CR>... */
        !           580:        if ( !savefile(fhandle)) {
        !           581:            freesegs();
        !           582:            VIOSETCURPOS( 24, 0, 0 );               /* ... clean up and quit */
        !           583:            quit(0);
        !           584:            }
        !           585:        else error25(11);
        !           586:        }
        !           587:     name25();                           /* ... otherwise restore message on */
        !           588:                                         /* 25th line and return to editor   */
        !           589:     }
        !           590: 
        !           591: 
        !           592: /*** F10() - exits the editor without saving the file being edited
        !           593:  *
        !           594:  *   F10() exits from the editor without saving back the file being edited,
        !           595:  *   leaving the file as it was before the editor was invoked. A prompt
        !           596:  *   will be issued to give the user a chance to change their mind before
        !           597:  *   all editing is lost.
        !           598:  *
        !           599:  *   EFFECTS:    If quit not completed:    EditBuff[]    -  gets flushed
        !           600:  *                                         EditBuffDirty -  gets cleared
        !           601:  */
        !           602: 
        !           603: 
        !           604: void F10()
        !           605:     {
        !           606:     static char message[51] = "WARNING: Any edits will be lost   (y/n)?           ";
        !           607:     struct  KeyData keydata;
        !           608:     char attrib = Fore25 + Back25;                /* attributes for message */
        !           609:     int  row, col;                       /* to save current cursor position */
        !           610:     int  done = 0;             /* flag to be set when have a valid response */
        !           611: 
        !           612:     if (EditBuffDirty) {                       /* flush EditBuff[] if dirty */
        !           613:        EditBuffDirty = 0;
        !           614:        flushline((TopRow + CurRow), EditBuff);
        !           615:        }
        !           616: 
        !           617:     VIOWRTCHARSTRATT( message, 51, PageSize, 0, &attrib, 0 );
        !           618:     VIOGETCURPOS( &row, &col, 0 );                 /* print prompt and set  */
        !           619:     VIOSETCURPOS( PageSize, 42, 0 );               /* cursor to await reply */
        !           620: 
        !           621:     while( !done ) {
        !           622: 
        !           623:        KBDCHARIN( &keydata, 0, 0 );             /* get a character from KBD */
        !           624: 
        !           625:        if( (keydata.char_code == 'y') || (keydata.char_code == 'Y') ) {
        !           626:            VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 42, &attrib, 0 );
        !           627:            freesegs();
        !           628:            quit(0);                            /* if Y, quit without saving */
        !           629:            }
        !           630:        else if( (keydata.char_code == 'n') || (keydata.char_code == 'N') ) {
        !           631:            VIOSETCURPOS( row, col, 0 );
        !           632:            name25();
        !           633:            done = 1;                              /* if N, return to editor */
        !           634:            }
        !           635:        else badkey();                     /* otherwise wait for another key */
        !           636: 
        !           637:        }
        !           638: 
        !           639:     }
        !           640: 
        !           641: 
        !           642: /*** ctrl_home() - repositions cursor to upper left hand corner of screen
        !           643:  *
        !           644:  *   ctrl_home() moves the cursor to the upper left hand corner of the
        !           645:  *   screen, coordinate position (0,0). Since the current cursor line is
        !           646:  *   probably changed, we flush and reload EditBuff[]. If there is any
        !           647:  *   text marked, this call will clear the marking without deleting.
        !           648:  *   Line number information on 25th line is redrawn to reflect changes.
        !           649:  *   The actual content of the screen - i.e. the value of TopRow - is
        !           650:  *   unchanged by this call.
        !           651:  *
        !           652:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           653:  *               EditBuffDirty  - clears this flag
        !           654:  *               LinesMarked    - clears this flag
        !           655:  *               MarkedLine[]   - clears all
        !           656:  *               CharsMarked    - clears this flag
        !           657:  *               MarkedChar[]   - clears all
        !           658:  *               CurRow         - set to 0
        !           659:  *               CurCol         - set to 0
        !           660:  */
        !           661: 
        !           662: void ctrl_home()
        !           663:     {
        !           664: 
        !           665:     register short i;                                /* indexing variable */
        !           666: 
        !           667:     if (EditBuffDirty) {                         /* this call will change */
        !           668:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           669:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           670:        }
        !           671: 
        !           672:     if ( LinesMarked || CharsMarked ) {
        !           673:        LinesMarked = 0;                         /* if there's marked text */
        !           674:        CharsMarked = 0;                         /* around, clear it and   */
        !           675:        for ( i = 0; i < MAXLINES; i++ )         /* redraw the screen      */
        !           676:            MarkedLine[i] = 0;
        !           677:        for ( i = 0; i < LINESIZE; i++ )
        !           678:            MarkedChar[i] = 0;
        !           679:        drawscr(TopRow);
        !           680:        }
        !           681: 
        !           682:     if ( CurRow != 0  ||  CurCol != 0 ) {
        !           683:        CurRow = 0;                                 /* reposition to (0,0) */
        !           684:        CurCol = 0;
        !           685:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !           686:        getline( (TopRow + CurRow), &EditBuff[0] );
        !           687:        }
        !           688: 
        !           689:     line25();      /* update line numbers on 25th line to reflect changes */
        !           690: 
        !           691:     }
        !           692: 
        !           693: 
        !           694: /*** ctrl_end() - repositions cursor to lower left hand corner of screen
        !           695:  *
        !           696:  *   ctrl_end() moves the cursor to the lower left hand corner of the
        !           697:  *   screen. Since the current cursor line is probably changed, we flush
        !           698:  *   and reload EditBuff[]. If there is any text marked, this call will
        !           699:  *   clear the marking without deleting. Line number information on 25th
        !           700:  *   line is redrawn to reflect changes. The actual content of the screen
        !           701:  *   is unchanged by this call.
        !           702:  *
        !           703:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           704:  *               EditBuffDirty  - clears this flag
        !           705:  *               LinesMarked    - clears this flag
        !           706:  *               MarkedLine[]   - clears all
        !           707:  *               CharsMarked    - clears this flag
        !           708:  *               MarkedChar[]   - clears all
        !           709:  *               CurRow         - set to PAGESIZE - 1
        !           710:  *               CurCol         - set to 0
        !           711:  */
        !           712: 
        !           713: void ctrl_end()
        !           714:     {
        !           715: 
        !           716:     register short i;
        !           717: 
        !           718:     if (EditBuffDirty) {                         /* this call will change */
        !           719:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           720:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           721:        }
        !           722: 
        !           723:     if ( LinesMarked || CharsMarked ) {
        !           724:        LinesMarked = 0;                         /* if there's marked text */
        !           725:        CharsMarked = 0;                         /* around, clear it and   */
        !           726:        for ( i = 0; i < MAXLINES; i++ )         /* redraw the screen      */
        !           727:            MarkedLine[i] = 0;
        !           728:        for ( i = 0; i < LINESIZE; i++ )
        !           729:            MarkedChar[i] = 0;
        !           730:        drawscr(TopRow);
        !           731:        }
        !           732: 
        !           733:     if( CurRow != (PageSize - 1) || CurCol != 0 ) {
        !           734:        CurRow = (PageSize - 1);                      /* reposition cursor */
        !           735:        CurCol = 0;
        !           736:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !           737:        getline( (TopRow + CurRow), &EditBuff[0] );
        !           738:        }
        !           739: 
        !           740:     line25();      /* update line numbers on 25th line to reflect changes */
        !           741: 
        !           742:     }
        !           743: 
        !           744: 
        !           745: /*** ctrl_pgup() - repositions cursor to beginning of file
        !           746:  *
        !           747:  *   ctrl_pgup() redraws the screen with the first screenfull of the file
        !           748:  *   and moves the cursor to the upper left hand corner of the screen,
        !           749:  *   coordinate position (0,0). Since the current cursor line is
        !           750:  *   probably changed, we flush and reload EditBuff[]. If there is any
        !           751:  *   text marked, this call will clear the marking without deleting.
        !           752:  *   Line number information on 25th line is redrawn to reflect changes.
        !           753:  *
        !           754:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           755:  *               EditBuffDirty  - clears this flag
        !           756:  *               LinesMarked    - clears this flag
        !           757:  *               MarkedLine[]   - clears all
        !           758:  *               CharsMarked    - clears this flag
        !           759:  *               MarkedChar[]   - clears all
        !           760:  *               TopRow         - set to 0
        !           761:  *               CurRow         - set to 0
        !           762:  *               CurCol         - set to 0
        !           763:  */
        !           764: 
        !           765: void ctrl_pgup()
        !           766:     {
        !           767: 
        !           768:     register short i;                                /* indexing variable */
        !           769: 
        !           770:     if (EditBuffDirty) {                         /* this call will change */
        !           771:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           772:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           773:        }
        !           774: 
        !           775:     if ( LinesMarked || CharsMarked ) {
        !           776:        LinesMarked = 0;                         /* if there's marked text */
        !           777:        CharsMarked = 0;                         /* around, clear it - no  */
        !           778:        for ( i = 0; i < MAXLINES; i++ )         /* need to redraw screen  */
        !           779:            MarkedLine[i] = 0;
        !           780:        for ( i = 0; i < LINESIZE; i++ )
        !           781:            MarkedChar[i] = 0;
        !           782:        }
        !           783: 
        !           784:     TopRow = 0;
        !           785:     CurRow = 0;                                  /* reposition and redraw */
        !           786:     CurCol = 0;
        !           787:     VIOSETCURPOS( CurRow, CurCol, 0 );
        !           788:     drawscr(TopRow);
        !           789:     getline( (TopRow + CurRow), &EditBuff[0] );       /* reload EditBuff[] */
        !           790:     line25();                                         /* update 25th line */
        !           791: 
        !           792:     }
        !           793: 
        !           794: 
        !           795: /*** ctrl_pgdn() - repositions cursor to beginning of file
        !           796:  *
        !           797:  *   ctrl_pgdn() redraws the screen with the last screenfull of the file
        !           798:  *   and moves the cursor to the lower left hand corner of the screen,
        !           799:  *   one line past the end of the file. Since the current cursor line is
        !           800:  *   probably changed, we flush and reload EditBuff[]. If there is any
        !           801:  *   text marked, this call will clear the marking without deleting.
        !           802:  *   Line number information on 25th line is redrawn to reflect changes.
        !           803:  *
        !           804:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           805:  *               EditBuffDirty  - clears this flag
        !           806:  *               LinesMarked    - clears this flag
        !           807:  *               MarkedLine[]   - clears all
        !           808:  *               CharsMarked    - clears this flag
        !           809:  *               MarkedChar[]   - clears all
        !           810:  *               TopRow         - set to TotalLines - (PageSize - 1)
        !           811:  *               CurRow         - set to end of file + 1
        !           812:  *               CurCol         - set to 0
        !           813:  */
        !           814: 
        !           815: void ctrl_pgdn()
        !           816:     {
        !           817:     register short i;                                /* indexing variable */
        !           818: 
        !           819:     if (EditBuffDirty) {                         /* this call will change */
        !           820:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           821:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           822:        }
        !           823: 
        !           824:     if ( LinesMarked || CharsMarked ) {
        !           825:        LinesMarked = 0;                         /* if there's marked text */
        !           826:        CharsMarked = 0;                         /* around, clear it - no  */
        !           827:        for ( i = 0; i < MAXLINES; i++ )         /* need to redraw screen  */
        !           828:            MarkedLine[i] = 0;                   /* as it gets done later  */
        !           829:        for ( i = 0; i < LINESIZE; i++ )
        !           830:            MarkedChar[i] = 0;
        !           831:        }
        !           832:     if (TotalLines > (PageSize - 1))
        !           833:        TopRow = TotalLines - (PageSize - 1);        /* recalculate TopRow */
        !           834:     else TopRow = 0;
        !           835:     CurRow = TotalLines - TopRow;            /* set cursor row and column */
        !           836:     CurCol = 0;
        !           837:     VIOSETCURPOS( CurRow, CurCol, 0 );
        !           838:     getline( (TopRow + CurRow), &EditBuff[0] );       /* reload EditBuff[] */
        !           839:     drawscr(TopRow);                                     /* redraw screen */
        !           840:     line25();                                         /* update 25th line */
        !           841: 
        !           842:     }
        !           843: 
        !           844: 
        !           845: /*** shift_left() - moves cursor left one and marks that character for deletion.
        !           846:  *
        !           847:  *   shift_left() moves the cursor one position to the left. If we are on
        !           848:  *   a line that is already marked, that's all it does - just like regular
        !           849:  *   left, but markings are not cleared. If we are not on a marked line,
        !           850:  *   then the character we just moved to is marked for deletion. Unless it
        !           851:  *   already was marked for deletion, in which case it gets un-marked.
        !           852:  *
        !           853:  *   EFFECTS:    CharsMarked    - sets this flag if LinesMarked not set
        !           854:  *               MarkedChar[]   - sets this for the character we just moved to
        !           855:  *               CurCol         - decremented one
        !           856:  */
        !           857: 
        !           858: void shift_left()
        !           859:     {
        !           860: 
        !           861:     if ( LinesMarked ) {          /* if this line is marked, just move left */
        !           862:        if ( CurCol > 0 ) {
        !           863:            CurCol -= 1;
        !           864:            VIOSETCURPOS( CurRow, CurCol, 0 );
        !           865:            }
        !           866:        }
        !           867:     else if( CurCol > 0 ) {            /* otherwise, see if there's room... */
        !           868:        CurCol -= 1;
        !           869:        VIOSETCURPOS( CurRow, CurCol, 0 );             /* ...if so move left */
        !           870:        CharsMarked = 1;
        !           871:        if (MarkedChar[CurCol])
        !           872:            MarkedChar[CurCol] = 0;    /* and set marking for that character */
        !           873:        else MarkedChar[CurCol] = 1;
        !           874:        drawline();                        /* redraw line to update markings */
        !           875:        }
        !           876: 
        !           877:     }
        !           878: 
        !           879: 
        !           880: /*** shift_right() - moves cursor right one and marks the character
        !           881:  *                  we were previously on for deletion.
        !           882:  *
        !           883:  *   shift_right() moves the cursor one position to the right. If we are on
        !           884:  *   a line that is already marked, that's all it does - just like regular
        !           885:  *   right, but markings are not cleared. If we are not on a marked line,
        !           886:  *   then the character we just moved from is marked for deletion. Unless it
        !           887:  *   already was marked for deletion, in which case it gets un-marked.
        !           888:  *
        !           889:  *   EFFECTS:    CharsMarked    - sets this flag if LinesMarked not set
        !           890:  *               MarkedChar[]   - sets this for the character we just left
        !           891:  *               CurCol         - incremented one
        !           892:  */
        !           893: 
        !           894: void shift_right()
        !           895:     {
        !           896: 
        !           897:     if ( LinesMarked ) {            /* if this line marked, just move right */
        !           898:        if (CurCol < (LINESIZE - 1)) {
        !           899:            CurCol += 1;
        !           900:            VIOSETCURPOS( CurRow, CurCol, 0 );
        !           901:            }
        !           902:        }
        !           903:     else if( CurCol < (LINESIZE - 1)) {  /* otherwise, see if there's room.. */
        !           904:        CharsMarked = 1;
        !           905:        if (MarkedChar[CurCol])            /* if so, mark character we're on */
        !           906:            MarkedChar[CurCol] = 0;
        !           907:        else MarkedChar[CurCol] = 1;
        !           908:        CurCol += 1;                                  /* then move right one */
        !           909:        VIOSETCURPOS( CurRow, CurCol, 0 );
        !           910:        drawline();                                       /* and redraw line */
        !           911:        }
        !           912: 
        !           913:     }
        !           914: 
        !           915: 
        !           916: /*** shift_up() - moves cursor up one line and marks lines for deletion
        !           917:  *
        !           918:  *   shift_up() moves the cursor one line up. If no lines are marked, then
        !           919:  *   both the previous line and the line moved to get marked for deletion.
        !           920:  *   If lines are already marked, and were marked starting with another
        !           921:  *   shift_up, then only the line we move to gets marked (the one we just
        !           922:  *   left would already be marked). If there are lines marked but they
        !           923:  *   were marked starting with a shift_down, then we un-mark the line we
        !           924:  *   just left and do nothing to the line moved to. Unless the line moved
        !           925:  *   to is the last one marked, in which case we un-mark it also to clear all
        !           926:  *   markings. To determine how lines first got marked - by a shift_up or
        !           927:  *   shift_down - we give the flag LinesMarked two different TRUE values,
        !           928:  *   1 or 2 respectively.
        !           929:  *
        !           930:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !           931:  *               EditBuffDirty  - clears
        !           932:  *               LinesMarked    - sets this flag, unless un-marking only
        !           933:  *                                marked line present, in which case clears it
        !           934:  *               MarkedLine[]   - may set or clear this
        !           935:  *               CharsMarked    - clears this flag as we now have marked lines
        !           936:  *               MarkedChar[]   - clears all
        !           937:  *               TopRow         - decremented one if at top of page
        !           938:  *               CurRow         - decremented one if not at top of page
        !           939:  */
        !           940: 
        !           941: void shift_up()
        !           942:     {
        !           943:     register short i;                                /* indexing variable */
        !           944: 
        !           945:     char buff[2];            /* local buffer for scrolling fill character */
        !           946:     buff[0] = 32;                             /* character = 32 = <blank> */
        !           947:     buff[1] = ForeHilite + BackHilite;        /*  attribute = highlighted */
        !           948: 
        !           949:     if (EditBuffDirty) {                         /* this call will change */
        !           950:        EditBuffDirty = 0;                        /* cursor line, so flush */
        !           951:        flushline((TopRow + CurRow), EditBuff);   /* edit buffer if dirty  */
        !           952:        }
        !           953: 
        !           954:     if ( CharsMarked ) {                       /* clear CharsMarked flags */
        !           955:        CharsMarked = 0;                        /* since we now will have  */
        !           956:        for ( i = 0; i < LINESIZE; i++ )        /* the whole line marked.  */
        !           957:            MarkedChar[i] = 0;
        !           958:        }
        !           959: 
        !           960:   /* if no lines currently marked, do this */
        !           961:     if( !LinesMarked ) {
        !           962:        LinesMarked = 1;        /* set flag to indicate marking started UP */
        !           963:        MarkedLine[ TopRow + CurRow ] = 1;                    /* mark line */
        !           964:        drawline();                                           /* redraw it */
        !           965:        if ( (TopRow + CurRow) != 0 ) {                /* if there's room, */
        !           966:            MarkedLine[ TopRow + CurRow - 1 ] = 1;      /* mark line above */
        !           967:            if ( CurRow == 0 ) {
        !           968:                TopRow -= 1;                      /* ...may have to scroll */
        !           969:                VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
        !           970:                           (char far *)buff, 0);
        !           971:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !           972:                }
        !           973:            else {                         /* ...or may not have to scroll */
        !           974:                CurRow -= 1;
        !           975:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !           976:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !           977:                }
        !           978:            drawline();                                 /* redraw new line */
        !           979:            }
        !           980:        }
        !           981: 
        !           982:   /* if lines marked, and shift_up started marking, do this */
        !           983:     else if( LinesMarked == 1 ) {
        !           984:        if ( (TopRow + CurRow) != 0 ) {        /* if not at top of screen, */
        !           985:            MarkedLine[ TopRow + CurRow - 1 ] = 1;    /* mark next line up */
        !           986:            if ( CurRow == 0 ) {
        !           987:                TopRow -= 1;                      /* ...may have to scroll */
        !           988:                VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
        !           989:                           (char far *)buff, 0);
        !           990:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !           991:                }
        !           992:            else {
        !           993:                CurRow -= 1;               /* ...or may not have to scroll */
        !           994:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !           995:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !           996:                }
        !           997:            drawline();                             /* redraw line move to */
        !           998:            }
        !           999:        }
        !          1000: 
        !          1001:   /* if lines marked, and shift_down started marking, do this */
        !          1002:     else if( LinesMarked == 2 ) {
        !          1003:        MarkedLine[ TopRow + CurRow ] = 0;         /* un-mark current line */
        !          1004:        drawline();                                           /* redraw it */
        !          1005:        if( (TopRow + CurRow) != 0 ) {
        !          1006:            if( CurRow == 0 ) {              /* ...may have to scroll down */
        !          1007:                TopRow -= 1;
        !          1008:                VIOSCROLLDN( 0, 0, (PageSize - 1), (LINESIZE - 1), 1,
        !          1009:                           (char far *)buff, 0);
        !          1010:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !          1011:                }
        !          1012:            else {                       /* or may not have to scroll down */
        !          1013:                CurRow -= 1;
        !          1014:                getline( (TopRow + CurRow), &EditBuff[0] );      /* reload */
        !          1015:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1016:                }
        !          1017:            if( !MarkedLine[ TopRow + CurRow - 1 ] ) { /* if line moved to */
        !          1018:                MarkedLine[ TopRow + CurRow ] = 0;     /* is last marked,  */
        !          1019:                LinesMarked = 0;                       /* clear it too     */
        !          1020:                drawline();
        !          1021:                }
        !          1022:            }
        !          1023:        }
        !          1024: 
        !          1025:     line25();      /* update line numbers on 25th line to reflect changes */
        !          1026: 
        !          1027:     }
        !          1028: 
        !          1029: 
        !          1030: /*** shift_down() - moves cursor down one line and marks lines for deletion
        !          1031:  *
        !          1032:  *   shift_down() moves the cursor one line down. If no lines are marked, then
        !          1033:  *   both the previous line and the line moved to get marked for deletion.
        !          1034:  *   If lines are already marked, and were marked starting with another
        !          1035:  *   shift_down, then only the line we move to gets marked (the one we just
        !          1036:  *   left would already be marked). If there are lines marked but they
        !          1037:  *   were marked starting with a shift_up, then we un-mark the line we
        !          1038:  *   just left and do nothing to the line moved to. Unless the line moved
        !          1039:  *   to is the last one marked, in which case we un-mark it also to clear all
        !          1040:  *   markings. To determine how lines first got marked - by a shift_up or
        !          1041:  *   shift_down - we give the flag LinesMarked two different TRUE values,
        !          1042:  *   1 or 2 respectively.
        !          1043:  *
        !          1044:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !          1045:  *               EditBuffDirty  - clears
        !          1046:  *               LinesMarked    - sets this flag, unless un-marking only
        !          1047:  *                                marked line present, in which case clears it
        !          1048:  *               MarkedLine[]   - may set or clear this
        !          1049:  *               CharsMarked    - clears this flag as we now have marked lines
        !          1050:  *               MarkedChar[]   - clears all
        !          1051:  *               TopRow         - incremented one if at bottom of page
        !          1052:  *               CurRow         - incremented one if not at bottom of page
        !          1053:  */
        !          1054: 
        !          1055: void shift_down()
        !          1056:     {
        !          1057:     register short i;                                  /* indexing variable */
        !          1058: 
        !          1059:     char buff[2];                        /* local buffer for fill character */
        !          1060:     buff[0] = 32;                               /* character = 32 = <blank> */
        !          1061:     buff[1] = ForeHilite + BackHilite;          /* attribute =  highlighted */
        !          1062: 
        !          1063:     if (EditBuffDirty) {                           /* this call will change */
        !          1064:        EditBuffDirty = 0;                          /* cursor line, so flush */
        !          1065:        flushline((TopRow + CurRow), EditBuff);     /* edit buffer if dirty  */
        !          1066:        }
        !          1067: 
        !          1068:     if ( CharsMarked ) {                            /* clear all character  */
        !          1069:        CharsMarked = 0;                             /* markings, since line */
        !          1070:        for ( i = 0; i < LINESIZE; i++ )             /* is now marked.       */
        !          1071:            MarkedChar[i] = 0;
        !          1072:        }
        !          1073: 
        !          1074:   /* if no lines are currently marked, do this */
        !          1075:     if( !LinesMarked ) {
        !          1076:        LinesMarked = 2;       /* set flag to show marking started with DOWN */
        !          1077:        MarkedLine[ TopRow + CurRow ] = 1;              /* mark current line */
        !          1078:        drawline();                                         /* and redraw it */
        !          1079:        if( ( TopRow + CurRow ) < TotalLines ) {    /* if room to move down, */
        !          1080:            MarkedLine[ TopRow + CurRow + 1 ] = 1;        /* mark line below */
        !          1081:            if ( CurRow == (PageSize - 1) ) {
        !          1082:                TopRow += 1;                        /* ...may have to scroll */
        !          1083:                VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1,
        !          1084:                           (char far *)buff, 0);
        !          1085:                getline( (TopRow + CurRow), &EditBuff[0] );        /* reload */
        !          1086:                }
        !          1087:            else {                           /* ...or may not have to scroll */
        !          1088:                CurRow += 1;
        !          1089:                getline( (TopRow + CurRow), &EditBuff[0] );        /* reload */
        !          1090:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1091:                }
        !          1092:            drawline();                                   /* redraw new line */
        !          1093:            }
        !          1094:        }
        !          1095: 
        !          1096:   /* if lines are marked, and first marking was another shift_down, do this */
        !          1097:     else if( LinesMarked == 2 ) {
        !          1098:        if ( (TopRow + CurRow) < TotalLines ) {     /* if room to move down */
        !          1099:            MarkedLine[ TopRow + CurRow + 1 ] = 1;       /* mark line below */
        !          1100:            if ( CurRow == (PageSize - 1) ) {
        !          1101:                TopRow += 1;                       /* ...may have to scroll */
        !          1102:                VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1,
        !          1103:                           (char far *)buff, 0);
        !          1104:                getline( (TopRow + CurRow), &EditBuff[0] );       /* reload */
        !          1105:                }
        !          1106:            else {                          /* ...or may not have to scroll */
        !          1107:                CurRow += 1;
        !          1108:                getline( (TopRow + CurRow), &EditBuff[0] );       /* reload */
        !          1109:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1110:                }
        !          1111:            drawline();         /* redraw the current line to show markings */
        !          1112:            }
        !          1113:        }
        !          1114: 
        !          1115:   /* if lines are marked, and first marking was a shift_up, do this */
        !          1116:     else if( LinesMarked == 1 ) {
        !          1117:        MarkedLine[ TopRow + CurRow ] = 0;          /* un-mark current line */
        !          1118:        drawline();                                        /* and redraw it */
        !          1119:        if ( (TopRow + CurRow) < TotalLines ) {
        !          1120:            if ( CurRow == (PageSize - 1) ) {
        !          1121:                TopRow += 1;                       /* ...may have to scroll */
        !          1122:                VIOSCROLLUP( 0, 0, CurRow, (LINESIZE - 1), 1,
        !          1123:                           (char far *)buff, 0);
        !          1124:                getline( (TopRow + CurRow), &EditBuff[0] );       /* reload */
        !          1125:                }
        !          1126:            else {                          /* ...or may not have to scroll */
        !          1127:                CurRow += 1;
        !          1128:                getline( (TopRow + CurRow), &EditBuff[0] );       /* reload */
        !          1129:                VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1130:                }
        !          1131:            }
        !          1132:        if( (TopRow + CurRow) < TotalLines ) {
        !          1133:            if( !MarkedLine[ TopRow + CurRow + 1 ] ) {
        !          1134:                MarkedLine[ TopRow + CurRow ] = 0;
        !          1135:                LinesMarked = 0;                     /* if only 1 line left */
        !          1136:                }                                 /* marked, un-mark it too */
        !          1137:            }
        !          1138:        drawline();                      /* redraw line to reflect markings */
        !          1139: 
        !          1140:        }
        !          1141: 
        !          1142:     line25();           /* update line info on bottom line to show changes */
        !          1143: 
        !          1144:     }
        !          1145: 
        !          1146: 
        !          1147: /*** shift_home() - moves cursor to first character in current line and
        !          1148:  *                 marks all characters in between for deletion
        !          1149:  *
        !          1150:  *   shift_down() moves the cursor to the first printable character in the
        !          1151:  *   current line. If the line is already marked, that's all it does, just
        !          1152:  *   like a regular home except markings are not cleared. Otherwise, all
        !          1153:  *   characters between the cursor position when the function is called and
        !          1154:  *   the first character in the line get their markings toggled - that is, if
        !          1155:  *   they are not marked they get marked, if they are already marked they
        !          1156:  *   get un-marked.
        !          1157:  *
        !          1158:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !          1159:  *               EditBuffDirty  - clears
        !          1160:  *               CharsMarked    - sets this flag unless line is marked
        !          1161:  *               MarkedChar[]   - sets for all appropriate characters
        !          1162:  *               CurCol         - set to position of first printable character
        !          1163:  */
        !          1164: 
        !          1165: void shift_home()
        !          1166:     {
        !          1167: 
        !          1168:     register short i, j;                              /* indexing variables */
        !          1169: 
        !          1170:     if (EditBuffDirty) {                          /* this call will need to */
        !          1171:        EditBuffDirty = 0;                         /* get correct info on    */
        !          1172:        flushline((TopRow + CurRow), EditBuff);    /* line length, so flush  */
        !          1173:        }                                          /* edit buffer if dirty   */
        !          1174: 
        !          1175:     if( (TopRow + CurRow) < TotalLines ) {
        !          1176:        i = LineTable[TopRow + CurRow]->linelength;     /* i is position + 1 */
        !          1177:        }                                               /* last char in line */
        !          1178:     else i = 0;
        !          1179: 
        !          1180:     for( j = 0; ( j < i )  &&  !isgraph(EditBuff[j]); j++ );
        !          1181:                                                         /* j is position of */
        !          1182:                                                         /* first non-blank  */
        !          1183:     if( !LinesMarked ) {                         /* if no lines marked,     */
        !          1184:        if( j < CurCol ) {                        /* flag everything between */
        !          1185:            CharsMarked = 1;                      /* CurCol and j as Marked  */
        !          1186:            for( i = j; i < CurCol; i++ ) {
        !          1187:                if( !MarkedChar[i] )
        !          1188:                    MarkedChar[i] = 1;           /* may be moving forward... */
        !          1189:                else MarkedChar[i] = 0;
        !          1190:                }
        !          1191:            }
        !          1192:        else if( j > CurCol ) {
        !          1193:            CharsMarked = 1;
        !          1194:            for( i = CurCol; i < j; i++ ) {               /* ... or backward */
        !          1195:                if( !MarkedChar[i] )
        !          1196:                    MarkedChar[i] = 1;
        !          1197:                else MarkedChar[i] = 0;
        !          1198:                }
        !          1199:            }
        !          1200:        }
        !          1201: 
        !          1202:     CurCol = j;                           /* if lines are marked, just move */
        !          1203:     VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1204:     drawline();                             /* redraw line to show markings */
        !          1205: 
        !          1206:     }
        !          1207: 
        !          1208: 
        !          1209: /*** shift_end() - moves cursor to one beyond last character in current line
        !          1210:  *                and marks all characters in between for deletion
        !          1211:  *
        !          1212:  *   shift_down() moves the cursor to one position beyond the last printable
        !          1213:  *   character in the current line. If the line is already marked, that's all
        !          1214:  *   it does, just like a regular end_ except markings are not cleared.
        !          1215:  *   Otherwise, all characters between the cursor position when the function
        !          1216:  *   is called and the final cursor position get their markings toggled - that
        !          1217:  *   is, if they are not marked they get marked, if they are already marked
        !          1218:  *   they get un-marked.
        !          1219:  *
        !          1220:  *   EFFECTS:    EditBuff[]     - flushes and reloads
        !          1221:  *               EditBuffDirty  - clears
        !          1222:  *               CharsMarked    - sets this flag unless line is marked
        !          1223:  *               MarkedChar[]   - sets for all appropriate characters
        !          1224:  *               CurCol         - set to one beyond position of
        !          1225:  *                                last printable character
        !          1226:  */
        !          1227: 
        !          1228: void shift_end()
        !          1229:     {
        !          1230: 
        !          1231:     register short i, j;                             /* indexing variables */
        !          1232: 
        !          1233:     if (EditBuffDirty) {                         /* this call will need to */
        !          1234:        EditBuffDirty = 0;                        /* get correct info on    */
        !          1235:        flushline((TopRow + CurRow), EditBuff);   /* line length, so flush  */
        !          1236:        }                                         /* edit buffer if dirty   */
        !          1237: 
        !          1238:     if( (TopRow + CurRow) < TotalLines ) {
        !          1239:        i = LineTable[TopRow + CurRow]->linelength;    /* i is position + 1 */
        !          1240:        }                                              /* last char in line */
        !          1241:     else i = 0;
        !          1242: 
        !          1243:     if( !LinesMarked ) {                        /* if no lines marked,     */
        !          1244:        if( i < CurCol ) {                       /* flag everything between */
        !          1245:            CharsMarked = 1;                     /* CurCol and i as Marked  */
        !          1246:            for( j = i; j < CurCol; j++ ) {
        !          1247:                if( !MarkedChar[j] )                /* may move forwards... */
        !          1248:                    MarkedChar[j] = 1;
        !          1249:                else MarkedChar[j] = 0;
        !          1250:                }
        !          1251:            }
        !          1252:        else if( i > CurCol ) {
        !          1253:            CharsMarked = 1;                            /* ... or backwards */
        !          1254:            for( j = CurCol; j < i; j++ ) {
        !          1255:                if( !MarkedChar[j] )
        !          1256:                    MarkedChar[j] = 1;
        !          1257:                else MarkedChar[j] = 0;
        !          1258:                }
        !          1259:            }
        !          1260:        }
        !          1261: 
        !          1262:     CurCol = i;                            /* if line is marked, just move */
        !          1263:     VIOSETCURPOS( CurRow, CurCol, 0 );
        !          1264:     drawline();                                                  /* redraw */
        !          1265: 
        !          1266:     }

unix.superglobalmegacorp.com

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