|
|
1.1 root 1: /*** dispatch() - accepts keyboard input and dispatches control to
2: * the appropriate function.
3: *
4: * Wait in a loop for keyboard input, then dispatch to any of several
5: * functions based on what the character code was. Default is insert()
6: * after validating, otherwise it is one of our control keys. There is
7: * a second dispatch function for special keys - those with zero for a
8: * character value. special_dispatch() works based on the scan code.
9: *
10: * EFFECTS: No global variables are directly effected by this function
11: */
12:
13:
14: #include <ctype.h>
15: #include <dos.h>
16: #include <doscalls.h>
17: #include <subcalls.h>
18: #include "ssedefs.h"
19: #include "keydefs.h"
20:
21:
22: void dispatch()
23: {
24:
25: struct KeyData keydata; /* data structure from subcalls.h */
26: struct KbdStatus kbdstatus; /* data structure from subcalls.h */
27:
28: kbdstatus.length = sizeof( kbdstatus );
29: KBDGETSTATUS( &kbdstatus, 0 ); /* set keyboard mode */
30: kbdstatus.bit_mask |= 4;
31: KBDSETSTATUS( &kbdstatus, 0 );
32:
33:
34: /* the following section waits for keyboard input */
35: /* then examines the key received and dispatches us */
36: /* to the appropriate function for the key pressed. */
37:
38:
39: while(1) {
40:
41:
42: KBDCHARIN( &keydata, 0, 0 ); /* get a character from KBD */
43:
44:
45: switch( keydata.char_code ) {
46:
47: default: /* default is not */
48: if ( isprint( keydata.char_code ) ) /* a control key. */
49: insert( keydata.char_code ); /* check validity */
50: else badkey(); /* and if good, */
51: break; /* call insert() */
52:
53: /* "special keys", those with character codes of 00, must */
54: /* be sent to another dispatcher that checks scan codes. */
55:
56: case SPECIAL_KEYS_CHAR:
57: special_dispatch( keydata.scan_code,
58: keydata.shift_state );
59: break;
60:
61: /* all others keys we can dispatch from here. some */
62: /* are easy, just dispatch based on char code... */
63:
64: case CTRL_B_CHAR:
65: ctrl_b();
66: break;
67:
68: case BKSP_CHAR:
69: bksp();
70: break;
71:
72: case TAB_CHAR:
73: tab();
74: break;
75:
76: case CRETURN_CHAR:
77: creturn();
78: break;
79:
80: case CTRL_N_CHAR:
81: ctrl_n();
82: break;
83:
84: case CTRL_Y_CHAR:
85: ctrl_y();
86: break;
87:
88:
89: /* ...for others, we must check the scan code and shift */
90: /* also as the char code may be shared with another key. */
91:
92: case SHIFT_END_CHAR:
93: if ( keydata.scan_code == END_SCAN &&
94: keydata.shift_state < 3 )
95: shift_end();
96: else insert( keydata.char_code );
97: break;
98:
99: case SHIFT_DOWN_CHAR:
100: if ( keydata.scan_code == DOWN_SCAN &&
101: keydata.shift_state < 3 )
102: shift_down();
103: else insert( keydata.char_code );
104: break;
105:
106: case SHIFT_LEFT_CHAR:
107: if ( keydata.scan_code == LEFT_SCAN &&
108: keydata.shift_state < 3 )
109: shift_left();
110: else insert( keydata.char_code );
111: break;
112:
113: case SHIFT_RIGHT_CHAR:
114: if ( keydata.scan_code == RIGHT_SCAN &&
115: keydata.shift_state < 3 )
116: shift_right();
117: else insert( keydata.char_code );
118: break;
119:
120: case SHIFT_HOME_CHAR:
121: if ( keydata.scan_code == HOME_SCAN &&
122: keydata.shift_state < 3 )
123: shift_home();
124: else insert( keydata.char_code );
125: break;
126:
127: case SHIFT_UP_CHAR:
128: if ( keydata.scan_code == UP_SCAN &&
129: keydata.shift_state < 3 )
130: shift_up();
131: else insert( keydata.char_code );
132: break;
133:
134: /* There's one other possibility, that the char code is 0xE0 */
135: /* which indicates an arrow key on the new AT03 keyboard. */
136: /* We will treat these in the same manner as special keys. */
137:
138: case ARROW_CHAR:
139: special_dispatch( keydata.scan_code,
140: keydata.shift_state );
141: break;
142:
143:
144: }
145:
146: }
147:
148: }
149:
150:
151: /*** special_dispatch(c,s) - dispatches control to the appropriate function
152: * based on character and scan codes received
153: *
154: * Characters with zero character codes or character code 0xE0 are sent
155: * here to be dispatched based on their scan code and shift status. These
156: * values are passed to special_dispatch as parameters.
157: *
158: * The left and right arrow keys are handled in this routine rather than
159: * dispatched to their own functions in an attempt to gain some speed.
160: *
161: * ENTRY: scan - scan code of the key press
162: * shift - shift state of the key press
163: *
164: * EFFECTS: No global variables are directly effected by this function
165: * unless the key is an unshifted right or left arrow.
166: * In that case, effects are:
167: *
168: * LinesMarked - this flag is cleared
169: * MarkedLine[] - all cleared
170: * CharsMarked - this flag is cleared
171: * MarkedChar[] - all cleared
172: * EditBuff[] - may be flushed if above were set
173: * EditBuffDirty - cleared if EditBuff[] flushed
174: * CurCol - incremented or decremented
175: */
176:
177: special_dispatch(scan,shift) /* dispatcher for "special keys" based on */
178: /* the scan code and shift code from KBD */
179:
180: unsigned char scan; /* scan code - must be unsigned */
181: unsigned shift; /* shift code */
182:
183: {
184:
185: register short i; /* indexing variable */
186:
187: switch( scan ) { /* dispatch based on what scan code was */
188: /* - check the shift state if necessary */
189: case LEFT_SCAN:
190: if( shift == 0 ) { /* left arrow handled here for speed */
191:
192: if ( LinesMarked || CharsMarked ) {
193: LinesMarked = 0; /* if there's marked */
194: CharsMarked = 0; /* text, clear it */
195: for ( i = 0; i < MAXLINES; i++ )
196: MarkedLine[i] = 0;
197: for ( i = 0; i < LINESIZE; i++ )
198: MarkedChar[i] = 0;
199: if (EditBuffDirty) { /* flush EditBuff before redraw */
200: EditBuffDirty = 0;
201: flushline((TopRow + CurRow), EditBuff);
202: }
203: drawscr(TopRow); /* redraw the screen */
204: }
205:
206: if ( CurCol > 0 ) {
207: CurCol -= 1; /* move cursor left 1 */
208: VIOSETCURPOS( CurRow, CurCol, 0 ); /* if there's room */
209: }
210:
211: }
212:
213: else
214: shift_left();
215: break;
216:
217: case RIGHT_SCAN:
218: if( shift == 0 ) { /* right arrow handled here for speed */
219:
220: if ( LinesMarked || CharsMarked ) {
221: LinesMarked = 0; /* if there's marked */
222: CharsMarked = 0; /* text, clear it */
223: for ( i = 0; i < MAXLINES; i++ )
224: MarkedLine[i] = 0;
225: for ( i = 0; i < LINESIZE; i++ )
226: MarkedChar[i] = 0;
227: if (EditBuffDirty) { /* flush EditBuff before redraw */
228: EditBuffDirty = 0;
229: flushline((TopRow + CurRow), EditBuff);
230: }
231: drawscr(TopRow); /* redraw the screen */
232: }
233:
234: if (CurCol < (LINESIZE -1)) { /* move cursor right one */
235: CurCol += 1; /* column if there's room */
236: VIOSETCURPOS( CurRow, CurCol, 0 );
237: }
238:
239: }
240:
241: else
242: shift_right();
243: break;
244:
245: case UP_SCAN:
246: if( shift == 0 )
247: up();
248: else
249: shift_up();
250: break;
251:
252: case DOWN_SCAN:
253: if( shift == 0 )
254: down();
255: else
256: shift_down();
257: break;
258:
259: case HOME_SCAN:
260: if( shift == 0 )
261: home();
262: else
263: shift_home();
264: break;
265:
266: case END_SCAN:
267: if( shift == 0 )
268: end_();
269: else
270: shift_end();
271: break;
272:
273: case PGUP_SCAN:
274: pgup();
275: break;
276:
277: case PGDN_SCAN:
278: pgdn();
279: break;
280:
281: case CTRL_HOME_SCAN:
282: ctrl_home();
283: break;
284:
285: case CTRL_END_SCAN:
286: ctrl_end();
287: break;
288:
289: case CTRL_PGUP_SCAN:
290: ctrl_pgup();
291: break;
292:
293: case CTRL_PGDN_SCAN:
294: ctrl_pgdn();
295: break;
296:
297: case DEL_SCAN:
298: del();
299: break;
300:
301: case F9_SCAN:
302: F9();
303: break;
304:
305: case F10_SCAN:
306: F10();
307: break;
308:
309: default:
310: badkey();
311:
312: }
313:
314: }
315:
316:
317: /*** badkey() - sounds a beep when an invalid or inappropriate key is hit
318: *
319: * EFFECTS: None
320: */
321:
322: badkey()
323: {
324: DOSBEEP (500, 50); /* frequency = 500 Hertz */
325: } /* duration = 50 milliseconds */
326:
327:
328: /*** clearscr() - clears the screen by writing blanks over entire screen
329: *
330: * clearscr() writes blanks with normal attributes over the entire screen,
331: * effectively clearing it.
332: *
333: * EFFECTS: None
334: */
335:
336: void clearscr()
337: {
338: char buff[2]; /* local buffer for filling cell value */
339:
340: buff[0] = ' '; /* cell to replicate is a blank */
341: buff[1] = BackNorm + ForeNorm; /* with normal attributes */
342:
343: VIOSCROLLUP(0, 0, -1, -1, -1, (char far *)buff, 0);
344:
345: /* when the first 5 parameters are */
346: /* set as above, the entire screen */
347: /* is filled with the cell in buff */
348: }
349:
350:
351: /*** drawscr(startline) - redraws the screen starting at the specified line
352: *
353: * drawscr() redraws the screen starting at the line specified in the
354: * parameter it is passed, startline. The screen is drawn with normal
355: * attributes, since this call will never be made with lines marked.
356: * Nothing is done with EditBuff[], that is left to the caller, as is
357: * the value of TopRow.
358: *
359: * ENTRY: startline - the line in the file which will be at the top of
360: * the screen when redrawn.
361: *
362: * EFFECTS: ScrBuff[][] - gets reloaded
363: */
364:
365: void drawscr(startline)
366:
367: unsigned short startline;
368: {
369:
370: register unsigned short i, j; /* indexing variables */
371:
372: char normal = BackNorm + ForeNorm; /* normal attributes */
373:
374: for ( i = startline, j = 0 ; j < PageSize ; i++, j++)
375: getline( i, &ScrBuff[j][0] ); /* load ScrBuff[][] with the */
376: /* part of the screen we want */
377:
378: VIOWRTCHARSTRATT ( (char far *)ScrBuff, ( PageSize * LINESIZE ), 0, 0,
379: &normal, 0 );
380: /* write it out to the screen */
381: }
382:
383:
384: /*** drawline() - redraws the current line
385: *
386: * drawline() redraws the line the cursor is currently on, using the
387: * contents of EditBuff[]. All marked characters will be drawn with the
388: * appropriate attributes. If the line is marked, all characters are
389: * drawn as marked; if the line is not marked, then the characters marked
390: * flag is checked. If characters are marked, the line is drawn in three
391: * sections - unmarked characters at the front of the line (may be 0),
392: * marked characters in the middle of the line (at least 1), and unmarked
393: * characters at the end of the line (may be 0). If no characters are marked
394: * either, then the line is drawn with all normal attributes.
395: *
396: * EFFECTS: None
397: */
398:
399: drawline()
400: {
401: unsigned short i; /* indexing variables */
402: unsigned short j;
403:
404: char hilite = BackHilite + ForeHilite; /* attributes for marked */
405: char normal = BackNorm + ForeNorm; /* attributes for not marked */
406:
407: if( MarkedLine[TopRow+CurRow] )
408: VIOWRTCHARSTRATT( EditBuff, LINESIZE, CurRow, 0, &hilite, 0);
409: /* if line is marked, do this */
410: else if (CharsMarked) {
411: for( i = 0; !MarkedChar[i] & (i < LINESIZE); i++ );
412: for( j = i; MarkedChar[j] & (j < LINESIZE); j++ );
413: VIOWRTCHARSTRATT( &EditBuff[0], i, CurRow, 0, &normal, 0);
414: VIOWRTCHARSTRATT( &EditBuff[i], (j - i), CurRow, i, &hilite, 0);
415: VIOWRTCHARSTRATT( &EditBuff[j], (LINESIZE - j), CurRow, j,
416: &normal, 0);
417: } /* else if characters marked, do this */
418:
419: else VIOWRTCHARSTRATT( EditBuff, LINESIZE, CurRow, 0, &normal, 0);
420: } /* else if neither marked, do this */
421:
422:
423: /*** line25() - updates line number information on last line
424: *
425: * line25() updates the line numbers maintained in the lower right hand
426: * corner of the screen - current line of cursor and total lines in file.
427: * These numbers are first converted from their zero-based internal values
428: * to a more friendly one-based number. Lots of standing on our heads is
429: * done to get the numbers into decimal characters without using C runtime
430: * routines or doing divisions.
431: *
432: * Note that while the names of these routines refer to the 25th line,
433: * the pagesize is not hardcoded - if we are in 43 line mode, this
434: * information will appear on the 43rd line. However, the spacing within
435: * the line is hardcoded for an 80-column display.
436: *
437: * EFFECTS - None
438: */
439:
440: void line25()
441: {
442:
443: int flag0 = 0; /* flag to aid in supressing leading 0's */
444: int col = 67; /* starting column for this info */
445: int i, n; /* indexing variables */
446: char buff[LINESIZE]; /* buffer to build output string */
447: char attrib = Back25 + Fore25; /* attributes for output string */
448:
449: n = (TopRow + CurRow + 1); /* set n to line number cursor is on */
450:
451: for( i = 0; n > 9999; n -= 10000, i++ );
452: if( i > 0 ) {
453: flag0 = 1; /* 10,000's place of current line */
454: buff[0] = i + 0x30;
455: }
456: else buff[0] = ' ';
457: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
458: col += 1;
459:
460: for( i = 0; n > 999; n -= 1000, i++ );
461: if( i > 0 ) {
462: flag0 = 1; /* 1,000's place of current line */
463: buff[0] = i + 0x30;
464: }
465: else if( flag0 ) buff[0] = '0';
466: else buff[0] = ' ';
467: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
468: col += 1;
469:
470: for( i = 0; n > 99; n -= 100, i++ );
471: if( i > 0 ) {
472: flag0 = 1; /* 100's place of current line */
473: buff[0] = i + 0x30;
474: }
475: else if( flag0 ) buff[0] = '0';
476: else buff[0] = ' ';
477: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
478: col += 1;
479:
480: for( i = 0; n > 9; n -= 10, i++ );
481: if( i > 0 ) {
482: flag0 = 1; /* 10's place of current line */
483: buff[0] = i + 0x30;
484: }
485: else if( flag0 ) buff[0] = '0';
486: else buff[0] = ' ';
487: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
488: col += 1;
489:
490: buff[0] = n + 0x30; /* 1's place of current line */
491: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
492: col += 1;
493:
494: buff[0] = ' ';
495: buff[1] = '/'; /* delimiting characters */
496: buff[2] = ' ';
497: VIOWRTCHARSTRATT( buff, 3, PageSize, col, &attrib, 0 );
498: col += 3;
499:
500: flag0 = 0;
501: n = TotalLines; /* n is total lines in file */
502:
503: for( i = 0; n > 9999; n -= 10000, i++ );
504: if( i > 0 ) {
505: flag0 = 1; /* 10,000's place of total lines */
506: buff[0] = i + 0x30;
507: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
508: col += 1;
509: }
510:
511: for( i = 0; n > 999; n -= 1000, i++ );
512: if( i > 0 ) {
513: flag0 = 1; /* 1,000's place of total lines */
514: buff[0] = i + 0x30;
515: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
516: col += 1;
517: }
518: else if( flag0 ) {
519: buff[0] = '0';
520: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
521: col += 1;
522: }
523:
524: for( i = 0; n > 99; n -= 100, i++ );
525: if( i > 0 ) {
526: flag0 = 1; /* 100's place of total lines */
527: buff[0] = i + 0x30;
528: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
529: col += 1;
530: }
531: else if( flag0 ) {
532: buff[0] = '0';
533: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
534: col += 1;
535: }
536:
537: for( i = 0; n > 9; n -= 10, i++ );
538: if( i > 0 ) {
539: flag0 = 1; /* 10's place of total lines */
540: buff[0] = i + 0x30;
541: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
542: col += 1;
543: }
544: else if( flag0 ) {
545: buff[0] = '0';
546: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
547: col += 1;
548: }
549:
550: buff[0] = n + 0x30; /* 1's place of total lines */
551: VIOWRTCHARSTRATT( buff, 1, PageSize, col, &attrib, 0 );
552:
553: col +=1;
554: n = LINESIZE - col; /* fill rest of line with blanks; n is how many */
555: for( i = 0; i < LINESIZE; buff[i] = ' ', i++ );
556: VIOWRTCHARSTRATT( buff, n, PageSize, col, &attrib, 0 );
557:
558: }
559:
560: /*** name25() - draws prompt and displays filename on 25th line
561: *
562: * This routine draws a prompt line with usage information about some
563: * of the less obvious function keys, and the name of the file currently
564: * being edited. Will be called at the start of execution, and whenever
565: * an error message has been displayed on the 25th line so that we need
566: * to re-draw the usage message after the error is responded to. The
567: * line25() routine takes care of the line numbers at the far right end
568: * of the line.
569: *
570: * Note that while the names of these routines refer to the 25th line,
571: * the pagesize is not hardcoded - if we are in 43 line mode, this
572: * information will appear on the 43rd line. Spacing within the line
573: * is hardcoded for an 80-column display.
574: *
575: * EFFECTS - None
576: */
577:
578: void name25()
579: {
580:
581: static char message[51] = "^N/^B=insert above/below ^Y=delete F9=save F10=quit";
582: char name[16]; /* for holding name of file */
583: char attrib = Back25 + Fore25; /* attributes for message */
584: int i, j, k; /* indexing variables */
585:
586:
587: /* first, print usage message */
588: VIOWRTCHARSTRATT( message, 51, PageSize, 0, &attrib, 0 );
589:
590:
591: /* build filename string */
592:
593: name[0] = ' ';
594: name[1] = ' '; /* some blanks at start and end */
595: name[2] = ' ';
596: name[15] = ' ';
597:
598: for( i = 0; fname[i] != 0; i++); /* find null terminator for fname */
599:
600: if( i > 0 ) i--; /* point i to last letter in fname */
601:
602: for( j = i, k = 14;
603: (fname[j] != '\\') && (fname[j] != ':') && (j >= 0) && (k >= 0);
604: name[k] = fname[j], j--, k-- );
605: /* move the file name into name[] backwards until */
606: /* we hit a backslash, colon or start of the name */
607:
608: for( ; k >= 0; name[k] = ' ', k-- ); /* if any room left, blank fill */
609:
610: VIOWRTCHARSTRATT( name, 16, PageSize, 51, &attrib, 0 ); /* write it */
611:
612: line25(); /* call the line number routine */
613:
614: }
615:
616:
617: /*** error25(error) - displays error messages on 25th line, accepts responses
618: *
619: * error25() displays an error message on the 25th line when any of several
620: * error conditions are encountered, the type of error being passed as a
621: * parameter. In some cases we just abort; in others we accept input from
622: * the user to determine what to do next.
623: *
624: * Note that while the names of these routines refer to the 25th line,
625: * the pagesize is not hardcoded - if we are in 43 line mode, this
626: * information will appear on the 43rd line. Spacing within the line
627: * is hardcoded for an 80-column display.
628: *
629: * ENTRY - Error - an arbitrary number identifying the error encountered
630: *
631: * EFFECTS - May cause us to end execution; otherwise, none
632: */
633:
634: void error25(error)
635: unsigned short error;
636: {
637: static char message1[51] = "ERROR: Out of memory or can't read file ";
638: static char message2[51] = "ERROR: Unable to create backup. Continue? (y/n) ";
639: static char message3[51] = "File not found. Create? (y/n) ";
640: static char message4[51] = "ERROR: Unable to create file ";
641: static char message5[51] = "ERROR: Unable to open file - denied write access ";
642: static char message6[51] = "ERROR: Unable to open file ";
643: static char message7[51] = "ERROR: Out of memory. S = save Q = quit ";
644: static char message8[51] = "ERROR: No filename given on command line ";
645: static char message9[51] = "ERROR: Invalid argument on command line ";
646: static char message10[51] = "ERROR: Too many parameters on command line ";
647: static char message11[51] = "ERROR: Unable to save file. C = continue ";
648: static char message99[51] = "ERROR: Unknown error. Continue? (y/n) ";
649: struct KeyData keydata;
650: char attrib = Back25 + Fore25; /* attributes for our messages */
651:
652:
653: switch( error ) { /* take the appropriate action for the error */
654:
655: case 1:
656: VIOWRTCHARSTRATT( message1, 51, PageSize, 0, &attrib, 0 );
657: quit(1);
658: break; /* 1 -> print message and quit */
659:
660: case 2:
661: VIOWRTCHARSTRATT( message2, 51, PageSize, 0, &attrib, 0 );
662: VIOSETCURPOS( PageSize, 50, 0 );
663:
664: while( 1 ) { /* 2 -> get a character from KBD */
665:
666: KBDCHARIN( &keydata, 0, 0 );
667:
668: if( (keydata.char_code == 'y') || (keydata.char_code == 'Y') ) {
669: name25();
670: break; /* if Y, go ahead */
671: }
672:
673: else if( (keydata.char_code == 'n') || (keydata.char_code == 'N') ) {
674: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 50, &attrib, 0 );
675: quit(1); /* if N, quit with error */
676: break;
677: }
678:
679: else badkey(); /* otherwise wait for another key */
680:
681: }
682: break;
683:
684: case 3:
685: VIOWRTCHARSTRATT( message3, 51, PageSize, 0, &attrib, 0 );
686: VIOSETCURPOS( PageSize, 32, 0 );
687:
688: while( 1 ) { /* 3 -> get a character from KBD */
689:
690: KBDCHARIN( &keydata, 0, 0 );
691:
692: if( (keydata.char_code == 'y') || (keydata.char_code == 'Y') ) {
693: name25();
694: break; /* if Y, go ahead */
695: }
696:
697: else if( (keydata.char_code == 'n') || (keydata.char_code == 'N') ) {
698: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 50, &attrib, 0 );
699: quit(1); /* if N, quit with error */
700: break;
701: }
702:
703: else badkey(); /* otherwise wait for another key */
704:
705: }
706: break;
707:
708: case 4:
709: VIOWRTCHARSTRATT( message4, 51, PageSize, 0, &attrib, 0 );
710: quit(1);
711: break; /* 4 -> print message and quit */
712:
713: case 5:
714: VIOWRTCHARSTRATT( message5, 51, PageSize, 0, &attrib, 0 );
715: quit(1);
716: break; /* 5 -> print message and quit */
717:
718: case 6:
719: VIOWRTCHARSTRATT( message6, 51, PageSize, 0, &attrib, 0 );
720: quit(1);
721: break; /* 6 -> print message and quit */
722:
723: case 7:
724: VIOWRTCHARSTRATT( message7, 51, PageSize, 0, &attrib, 0 );
725: VIOSETCURPOS( PageSize, 44, 0 );
726:
727: while( 1 ) { /* 7 -> get a character from KBD */
728:
729: KBDCHARIN( &keydata, 0, 0 );
730:
731: if( (keydata.char_code == 's') || (keydata.char_code == 'S') ) {
732: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 50, &attrib, 0 );
733: if ( !savefile(fhandle)) { /* if S, save file and quit */
734: freesegs();
735: VIOSETCURPOS( PageSize, 0, 0 );
736: quit(1);
737: }
738: else
739: error25(11); /* call error 11 if can't save */
740: }
741:
742: else if( (keydata.char_code == 'q') || (keydata.char_code == 'Q') ) {
743: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 50, &attrib, 0 );
744: quit(1); /* if Q, quit with error */
745: break;
746: }
747:
748: else badkey(); /* otherwise wait for another key */
749:
750: }
751: break;
752:
753: case 8:
754: VIOWRTCHARSTRATT( message8, 51, PageSize, 0, &attrib, 0 );
755: quit(1);
756: break; /* 8 -> print message and quit */
757:
758: case 9:
759: VIOWRTCHARSTRATT( message9, 51, PageSize, 0, &attrib, 0 );
760: quit(1);
761: break; /* 9 -> print message and quit */
762:
763: case 10:
764: VIOWRTCHARSTRATT( message10, 51, PageSize, 0, &attrib, 0 );
765: quit(1);
766: break; /* 10 -> print message and quit */
767:
768: case 11:
769: VIOWRTCHARSTRATT( message11, 51, PageSize, 0, &attrib, 0 );
770: VIOSETCURPOS( PageSize, 45, 0 );
771:
772: while( 1 ) { /* 11 -> get a character from KBD */
773:
774: KBDCHARIN( &keydata, 0, 0 );
775:
776: if( (keydata.char_code == 'c') || (keydata.char_code == 'C') ) {
777: name25();
778: break; /* C means continue */
779: }
780: else badkey(); /* otherwise wait for another key */
781:
782: }
783: break;
784:
785: default:
786: VIOWRTCHARSTRATT( message99, 51, PageSize, 0, &attrib, 0 );
787: VIOSETCURPOS( PageSize, 40, 0 );
788:
789: while( 1 ) { /* UNKNOWN error number! */
790: /* get a character from KBD */
791: KBDCHARIN( &keydata, 0, 0 );
792:
793: if( (keydata.char_code == 'y') || (keydata.char_code == 'Y') ) {
794: name25();
795: break; /* if Y, go ahead */
796: }
797:
798: else if( (keydata.char_code == 'n') || (keydata.char_code == 'N') ) {
799: VIOWRTCHARSTRATT( &keydata.char_code, 1, PageSize, 50, &attrib, 0 );
800: quit(1); /* if N, quit with error */
801: break;
802: }
803:
804: else badkey(); /* otherwise wait for another key */
805:
806: }
807: break;
808:
809: }
810:
811: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.