Annotation of os2sdk/demos/apps/sse/keyfuncs.c, revision 1.1.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.