home *** CD-ROM | disk | FTP | other *** search
- /* tutor.c -- tutorial program for Windows for C */
- /*
- ************* (C) Copyright Vermont Creative Software 1985 ******************
-
- A simple program that establishes two windows, reads lines typed by the user
- in one window, and writes the lines in the other window.
-
- This program illustrates how windows are initialized, established on the
- screen, cleared, written to, scrolled, and removed from the screen. It shows
- how window functions can be used to simplify constructing line editors
-
- */
-
- #define WN_DEBUG
- #include <wfc.h>
- #include <wfc_glob.h>
- #define MAX_CHAR 73 /*max characters in edit line */
-
-
- WINDOW wn1, wn2; /*declare two windows */
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* The following strings provide the text that will be put into wn2 */
- /* by v_st(). */
- /* */
- /*----------------------------------------------------------------------------*/
-
- char *st[] =
- {"To place lines of text into the top window on the screen, ",
- "type the lines here, pressing Enter (Carriage Return) after ",
- "each line:\n"
- };
-
- char *st1 = " To exit, press 'Escape'.";
-
- main()
- {
- int i, csr_row, csr_col;
- char line[MAX_CHAR + 1]; /*array for user input of text */
-
- /*----------------------------------------------------------------------------*/
- /* First save the cursor location by calling rd_csr(); then for MSDOS systems*/
- /* save the screen by using the predefined full-screen window wn0; */
- /* setting wn0 will clear the screen to black, because wn0.att = LDOS. */
- /* For UNIX systems, simply clear the screen. */
- /*----------------------------------------------------------------------------*/
-
- init_wfc(); /*always initialize WFC first */
-
- rd_csr(&csr_row, &csr_col, 0); /*store cursor location */
- sw_popup(ON, &wn0); /*make a popup to save screen */
- set_wn(&wn0); /*saves screen and then clears it */
-
- /*----------------------------------------------------------------------------*/
- /* Initialize the windows. Text entered in window 2 will be copied to */
- /* window 1 for display. When window 1 is full, text will be automatically */
- /* scrolled upward to make room for additional lines of text. */
- /* */
- /* Window 1 will have attribute LNORMAL and border attribute LRED. Margins */
- /* will be 3 on each side. The border is a double line. */
- /* The window goes from row 3 through row 10, column 20, through column 60. */
- /* */
- /* Window 2 will have attributes of LNORMAL for text and LNORMAL for border. */
- /* Margins are 2, 2. The window has a single line border */
- /* The window goes from row 14 through row 20, column 0, through column 79. */
- /* */
- /* Function def_wn(), which allows explicit setting of margins, is used for */
- /* initialization. */
- /*----------------------------------------------------------------------------*/
-
- def_wn(&wn1, 3, 10, 20, 60, 3, 3, BDR_DLNP);
- sw_bdratt(LRED, &wn1); /*change border att from default*/
- def_wn(&wn2, 14, 20, 0, 79, 2, 2, BDR_LNP);
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* Place the windows on the screen with calls to set_wn. A pointer to */
- /* the WINDOW struct must be passed as the calling parameter. */
- /* */
- /* set_wn returns 0 if there is an inconsistency in the initial values */
- /* of wn. */
- /* */
- /* The error message can be written in a window even though it is not "set." */
- /* Setting of a window clears it and sets border and margins, but none of */
- /* these are essential to the writing of the error message */
- /* */
- /*----------------------------------------------------------------------------*/
-
- if(set_wn(&wn1) == 0)
- {
- v_st("wn1 definitions inconsistent",&wn2);
- exit(1); /*exit to DOS with error code set */
- }
- if(set_wn(&wn2) == 0)
- {
- v_st("wn2 definitions inconsistent",&wn2);
- exit(1); /*exit to DOS with error code set */
- }
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* Repeated calls to v_st() are made to write the st[] array to wn2. */
- /* */
- /* The initial location of of cs, the virtual cursor is at 0,0; v_st() */
- /* automatically updates the location of cs so it points to the next */
- /* space after the last character written. */
- /* */
- /* After st[] is written, the attribute of wn2 is changed to LERROR and */
- /* wn.r is advanced by two, moving cs down two rows. */
- /* */
- /* v_st() is called to write st1, the exit instruction; the attribute is */
- /* changed to LFIELDA, the location of cs is moved to the location */
- /* where the user is to type in text, and the screen cursor is placed at */
- /* cs by a call to pl_csr(). */
- /* */
- /*----------------------------------------------------------------------------*/
-
-
- for(i = 0; i < 3; i++)
- v_st(st[i], &wn2);
-
- wn2.att = LERROR; /*use LERROR to make prominent */
- wn2.r += 2;
- v_st(st1, &wn2);
-
- wn2.att = LFIELDA;
- wn2.r -= 2;
- wn2.c = 0;
- pl_csr(&wn2);
-
- /*----------------------------------------------------------------------------*/
- /* Clear the edit row to LFIELDA and restore the virtual cursor to the */
- /* beginning of the row. Note that the screen cursor is not moved by */
- /* the call to v_rw(). */
- /*----------------------------------------------------------------------------*/
-
- v_rw(' ', MAX_CHAR, &wn2);
- wn2.c = 0;
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* The following code sets up a while() loop. The loop is broken */
- /* when the user satisfies the exit condition: */
- /* */
- /* User text is read into line[], using rd_line(), a function defined */
- /* following main. Text is read until <Escape> is pressed on an empty line.*/
- /* */
- /* Rd_line() returns -1 when <Escape> is pressed; otherwise the number */
- /* of characters in the returned string (excluding the terminal null) */
- /* The loop is exited upon the -1 return. */
- /* */
- /*----------------------------------------------------------------------------*/
-
- while(rd_line(line, MAX_CHAR, &wn2) != -1)
- {
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* The contents of line[] are written to wn1 by a call to v_fst(). */
- /* For strings longer than the width of wn1, v_fst() automatically performs */
- /* word wrap. */
- /* */
- /* When v_fst() fills the window without finishing writing the string, it */
- /* scrolls the window to make room for the remainder of the string. */
- /* */
- /*----------------------------------------------------------------------------*/
-
- v_fst(line, &wn1);
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* After the line has been transferred to wn1, the user text in wn2 is */
- /* cleared by writing MAX_CHAR "spaces" using v_rw(). */
- /* The virtual cursor and screen cursor are returned to the initial position.*/
- /* */
- /*----------------------------------------------------------------------------*/
-
- wn2.c = 0;
- v_rw(' ', MAX_CHAR, &wn2);
- wn2.c = 0;
- pl_csr(&wn2);
- }
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* When this point is reached, the user has requested exit. */
- /* The original screen is restored by popping down window wn0. The cursor */
- /* is restored to its original location by calling mv_csr() in wn0. */
- /* */
- /*----------------------------------------------------------------------------*/
- unset_wn(&wn0);
- mv_csr(csr_row, csr_col, &wn0);
- exit_wfc();
- return(0);
- }
-
- /*----------------------------------------------------------------------------*/
- /* */
- /* The rd_line() function */
- /* */
- /* The rd_line() function calls ki() to read keystrokes and v_ch() to write */
- /* the corresponding ASCII character to the window. Backspace and left and */
- /* right cursor keys are implemented; but not insert and delete. */
- /* */
- /* ki() returns ASCII codes or the IBM "extended codes." The extended codes */
- /* are returned as negative values. */
- /* */
- /* Keystrokes are written to the window until <Enter> is pressed, */
- /* max_q characters have been written to the window, */
- /* <Escape> is pressed. */
- /* */
- /* When <Escape> is pressed, -1 is returned immediately; */
- /* otherwise the contents of the window row are copied to the passed string. */
- /* Trailing blanks are stripped; if <Enter> was pressed, a newline is */
- /* inserted prior to the terminal null. */
- /* */
- /* The number of characters in the string (excluding the null terminator) */
- /* is returned. */
- /* */
- /* The passed string must have at least max_q + 1 spaces in it */
- /* */
- /*----------------------------------------------------------------------------*/
-
- rd_line(stp, q_max, wnp)
- char *stp;
- int q_max;
- WINDOWPTR wnp; /*typedef WINDOWPTR is in bios.h */
- {
- int c;
- int kenter; /*set to TRUE if user pressed <ENTER> */
- int done; /*set to TRUE when line is full or */
- /*user pressed <ENTER> */
- int count;
- int cmax; /*maximum value of wn.c */
-
- cmax = q_max -1; /*cs has zero origin; so q_max-1 */
- if(q_max < 1) /*need q = 1 to get 1 char */
- return(0);
-
- kenter = FALSE;
- done = FALSE;
-
- while(!done) /*set up loop */
- {
- switch(c = ki())
- {
- case K_ENTER: /*user pressed <ENTER> */
- kenter = 1;
- done = 1;
- break;
-
- case K_ESC: /*user aborted */
- return(-1);
-
- case K_BACK: /*handle backspace */
- if(wnp->c > 0) /*if not at left boundary */
- {
- wnp->c--; /*go back one position */
- v_ch(' ', wnp); /*print "space" */
- wnp->c--; /*go back one position */
- pl_csr(wnp); /*place screen cursor */
- }
- else /*can't backspace beyond left boundary*/
- bell();
- break;
-
- case -K_LEFT: /*handle left cursor */
- if(wnp->c > 0) /*if not at left boundary */
- {
- wnp->c--; /*move cursor 1 column left */
- pl_csr(wnp); /*place screen cursor */
- }
- else /*can't move cursor left */
- bell();
- break;
-
- case -K_RIGHT: /*handle right cursor */
- if(wnp->c < cmax) /*if not at right boundary */
- {
- wnp->c++; /*move cursor 1 column right */
- pl_csr(wnp); /*place screen cursor */
- }
- else /*can't move cursor right */
- bell();
- break;
-
- default: /*handle all other possibilities */
- if(c > 0) /*check for printable character */
- {
- if(wnp->c == cmax) /*Done. write last char & goto end */
- { /*check cs limit first, because wn.c */
- v_ch(c, wnp); /*will go to zero if at edge of wind. */
- done = 1;
- }
- else
- {
- v_ch(c, wnp); /*else write character and continue */
- pl_csr(wnp);
- }
- }
- else /* extended code */
- bell(); /* let user know it's illegal */
- break;
- }
- }
-
- v_mova(stp, wnp, ROW, OUT); /*transfer window row to string */
- strip_wh(stp); /*strip white spaces from end of strin*/
- count = strlen(stp);
- if(kenter) /*need to append newline */
- {
- stp += count++; /*go to null, increment count */
- *stp++ = '\n'; /*append newline */
- *stp = '\0'; /*append null terminator */
- }
- return(count); /*return number of char in string */
- }