home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c003 / 1.ddi / DEMOS / TUTOR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-01  |  12.5 KB  |  319 lines

  1. /* tutor.c  -- tutorial program for Windows for C                 */
  2. /*
  3.   ************* (C) Copyright Vermont Creative Software 1985 ******************
  4.  
  5. A simple program that establishes two windows, reads lines typed by the user
  6. in one window, and writes the lines in the other window.
  7.  
  8. This program illustrates how windows are initialized, established on the
  9. screen, cleared, written to, scrolled, and removed from the screen.  It shows
  10. how window functions can be used to simplify constructing line editors
  11.  
  12. */
  13.  
  14. #define WN_DEBUG
  15. #include <wfc.h>
  16. #include <wfc_glob.h>
  17. #define MAX_CHAR 73            /*max characters in edit line          */
  18.  
  19.  
  20. WINDOW wn1, wn2;            /*declare two windows              */
  21.  
  22. /*----------------------------------------------------------------------------*/
  23. /*                                          */
  24. /*  The following strings provide the text that will be put into wn2          */
  25. /*  by v_st().                                      */
  26. /*                                          */
  27. /*----------------------------------------------------------------------------*/
  28.  
  29. char *st[] =
  30.     {"To place lines of text into the top window on the screen, ",
  31.     "type the lines here, pressing Enter (Carriage Return) after ",
  32.     "each line:\n"
  33.     };
  34.  
  35. char *st1 = "                     To exit, press 'Escape'.";
  36.  
  37. main()
  38. {
  39.     int i, csr_row, csr_col;
  40.     char line[MAX_CHAR + 1];        /*array for user input of text          */
  41.  
  42. /*----------------------------------------------------------------------------*/
  43. /*  First save the cursor location by calling rd_csr(); then for MSDOS systems*/
  44. /*  save the screen by using the predefined full-screen window wn0;          */
  45. /*  setting wn0 will clear the screen to black, because wn0.att = LDOS.       */
  46. /*  For UNIX systems, simply clear the screen.                      */
  47. /*----------------------------------------------------------------------------*/
  48.  
  49.     init_wfc();             /*always initialize WFC first          */
  50.  
  51.     rd_csr(&csr_row, &csr_col, 0);    /*store cursor location           */
  52.     sw_popup(ON, &wn0);         /*make a popup to save screen          */
  53.     set_wn(&wn0);            /*saves screen and then clears it     */
  54.  
  55. /*----------------------------------------------------------------------------*/
  56. /* Initialize the windows.  Text entered in window 2 will be copied to          */
  57. /* window 1 for display.  When window 1 is full, text will be automatically   */
  58. /* scrolled upward to make room for additional lines of text.              */
  59. /*                                          */
  60. /* Window 1 will have attribute LNORMAL and border attribute LRED.  Margins   */
  61. /* will be 3 on each side.  The border is a double line.              */
  62. /* The window goes from row 3 through row 10, column 20, through column 60.   */
  63. /*                                          */
  64. /* Window 2 will have attributes of LNORMAL for text and LNORMAL for border.  */
  65. /* Margins are 2, 2.  The window has a single line border              */
  66. /* The window goes from row 14 through row 20, column 0, through column 79.   */
  67. /*                                          */
  68. /* Function def_wn(), which allows explicit setting of margins, is used for   */
  69. /* initialization.                                  */
  70. /*----------------------------------------------------------------------------*/
  71.  
  72.     def_wn(&wn1, 3, 10, 20, 60, 3, 3, BDR_DLNP);
  73.     sw_bdratt(LRED, &wn1);              /*change border att from default*/
  74.     def_wn(&wn2, 14, 20, 0, 79, 2, 2, BDR_LNP);
  75.  
  76. /*----------------------------------------------------------------------------*/
  77. /*                                          */
  78. /*  Place the windows on the screen with calls to set_wn.  A pointer to       */
  79. /*  the WINDOW struct must be passed as the calling parameter.              */
  80. /*                                          */
  81. /*  set_wn returns 0 if there is an inconsistency in the initial values       */
  82. /*  of wn.                                      */
  83. /*                                          */
  84. /*  The error message can be written in a window even though it is not "set." */
  85. /*  Setting of a window clears it and sets border and margins, but none of    */
  86. /*  these are essential to the writing of the error message              */
  87. /*                                          */
  88. /*----------------------------------------------------------------------------*/
  89.  
  90.     if(set_wn(&wn1) == 0)
  91.     {
  92.     v_st("wn1 definitions inconsistent",&wn2);
  93.     exit(1);            /*exit to DOS with error code set     */
  94.     }
  95.     if(set_wn(&wn2) == 0)
  96.     {
  97.     v_st("wn2 definitions inconsistent",&wn2);
  98.     exit(1);            /*exit to DOS with error code set     */
  99.     }
  100.  
  101. /*----------------------------------------------------------------------------*/
  102. /*                                          */
  103. /*  Repeated calls to v_st() are made to write the st[] array to wn2.          */
  104. /*                                          */
  105. /*  The initial location of of cs, the virtual cursor is at 0,0; v_st()       */
  106. /*  automatically updates the location of cs so it points to the next          */
  107. /*  space after the last character written.                      */
  108. /*                                          */
  109. /*  After st[] is written, the attribute of wn2 is changed to LERROR and      */
  110. /*  wn.r is advanced by two, moving cs down two rows.                  */
  111. /*                                          */
  112. /*  v_st() is called to write st1, the exit instruction; the attribute is     */
  113. /*  changed to LFIELDA,  the location of cs is moved to the location          */
  114. /*  where the user is to type in text, and the screen cursor is placed at     */
  115. /*  cs by a call to pl_csr().                              */
  116. /*                                          */
  117. /*----------------------------------------------------------------------------*/
  118.  
  119.  
  120.     for(i = 0; i < 3; i++)
  121.     v_st(st[i], &wn2);
  122.  
  123.     wn2.att = LERROR;            /*use LERROR to make prominent          */
  124.     wn2.r += 2;
  125.     v_st(st1, &wn2);
  126.  
  127.     wn2.att = LFIELDA;
  128.     wn2.r -= 2;
  129.     wn2.c = 0;
  130.     pl_csr(&wn2);
  131.  
  132. /*----------------------------------------------------------------------------*/
  133. /*  Clear the edit row to LFIELDA and restore the virtual cursor to the       */
  134. /*  beginning of the row.  Note that the screen cursor is not moved by          */
  135. /*  the call to v_rw().                               */
  136. /*----------------------------------------------------------------------------*/
  137.  
  138.     v_rw(' ', MAX_CHAR, &wn2);
  139.     wn2.c = 0;
  140.  
  141. /*----------------------------------------------------------------------------*/
  142. /*                                          */
  143. /*  The following code sets up a while() loop.    The loop is broken          */
  144. /*  when the user satisfies the exit condition:                   */
  145. /*                                          */
  146. /*  User text is read into line[], using rd_line(), a function defined          */
  147. /*  following main.   Text is read until <Escape> is pressed on an empty line.*/
  148. /*                                          */
  149. /*  Rd_line() returns -1 when <Escape> is pressed; otherwise the number       */
  150. /*  of characters in the returned string (excluding the terminal null)          */
  151. /*  The loop is exited upon the -1  return.                      */
  152. /*                                          */
  153. /*----------------------------------------------------------------------------*/
  154.  
  155.     while(rd_line(line, MAX_CHAR, &wn2) != -1)
  156.     {
  157.  
  158. /*----------------------------------------------------------------------------*/
  159. /*                                          */
  160. /*  The contents of line[] are written to wn1 by a call to v_fst().          */
  161. /*  For strings longer than the width of wn1, v_fst() automatically performs  */
  162. /*  word wrap.                                      */
  163. /*                                          */
  164. /*  When v_fst() fills the window without finishing writing the string, it    */
  165. /*  scrolls the window to make room for the remainder of the string.          */
  166. /*                                          */
  167. /*----------------------------------------------------------------------------*/
  168.  
  169.     v_fst(line, &wn1);
  170.  
  171. /*----------------------------------------------------------------------------*/
  172. /*                                          */
  173. /*  After the line has been transferred to wn1, the user text in wn2 is       */
  174. /*  cleared by writing MAX_CHAR  "spaces" using v_rw().                       */
  175. /*  The virtual cursor and screen cursor are returned to the initial position.*/
  176. /*                                          */
  177. /*----------------------------------------------------------------------------*/
  178.  
  179.     wn2.c = 0;
  180.     v_rw(' ', MAX_CHAR, &wn2);
  181.     wn2.c = 0;
  182.     pl_csr(&wn2);
  183.     }
  184.  
  185. /*----------------------------------------------------------------------------*/
  186. /*                                          */
  187. /*  When this point is reached, the user has requested    exit.              */
  188. /*  The original screen is restored by popping down window wn0.  The cursor   */
  189. /*  is restored to its original location by calling mv_csr() in wn0.          */
  190. /*                                          */
  191. /*----------------------------------------------------------------------------*/
  192.     unset_wn(&wn0);
  193.     mv_csr(csr_row, csr_col, &wn0);
  194.     exit_wfc();
  195.     return(0);
  196. }
  197.  
  198. /*----------------------------------------------------------------------------*/
  199. /*                                          */
  200. /*            The rd_line() function                      */
  201. /*                                          */
  202. /*  The rd_line() function calls ki() to read keystrokes and v_ch() to write  */
  203. /*  the corresponding ASCII character to the window. Backspace and left and   */
  204. /*  right cursor keys are implemented; but not insert and delete.          */
  205. /*                                          */
  206. /*  ki() returns ASCII codes or the IBM "extended codes."  The extended codes */
  207. /*  are returned as negative values.                          */
  208. /*                                          */
  209. /*  Keystrokes are written to the window until <Enter> is pressed,          */
  210. /*  max_q characters have been written to the window,                  */
  211. /*  <Escape> is pressed.                              */
  212. /*                                          */
  213. /*  When <Escape> is pressed, -1 is returned immediately;              */
  214. /*  otherwise the contents of the window row are copied to the passed string. */
  215. /*  Trailing blanks are stripped; if <Enter> was pressed, a newline is          */
  216. /*  inserted prior to the terminal null.                      */
  217. /*                                          */
  218. /*  The number of characters in the string (excluding the null terminator)    */
  219. /*  is returned.                                  */
  220. /*                                          */
  221. /*  The passed string must have at least max_q + 1 spaces in it           */
  222. /*                                          */
  223. /*----------------------------------------------------------------------------*/
  224.  
  225. rd_line(stp, q_max, wnp)
  226. char *stp;
  227. int q_max;
  228. WINDOWPTR wnp;                /*typedef WINDOWPTR is in bios.h      */
  229. {
  230.     int c;
  231.     int kenter;             /*set to TRUE if user pressed <ENTER> */
  232.     int done;                /*set to TRUE when line is full or    */
  233.                     /*user pressed <ENTER>              */
  234.     int count;
  235.     int cmax;                /*maximum value of wn.c           */
  236.  
  237.     cmax = q_max -1;            /*cs has zero origin; so q_max-1      */
  238.     if(q_max < 1)            /*need q = 1 to get 1 char          */
  239.     return(0);
  240.  
  241.     kenter = FALSE;
  242.     done = FALSE;
  243.  
  244.     while(!done)            /*set up loop                  */
  245.     {
  246.     switch(c = ki())
  247.     {
  248.         case K_ENTER:        /*user pressed <ENTER>              */
  249.         kenter = 1;
  250.         done = 1;
  251.         break;
  252.  
  253.         case K_ESC:         /*user aborted                  */
  254.         return(-1);
  255.  
  256.         case K_BACK:        /*handle backspace              */
  257.         if(wnp->c > 0)        /*if not at left boundary          */
  258.         {
  259.             wnp->c--;        /*go back one position              */
  260.             v_ch(' ', wnp);     /*print "space"                       */
  261.             wnp->c--;        /*go back one position              */
  262.             pl_csr(wnp);    /*place screen cursor              */
  263.         }
  264.         else            /*can't backspace beyond left boundary*/
  265.             bell();
  266.         break;
  267.  
  268.         case -K_LEFT:        /*handle left cursor              */
  269.         if(wnp->c > 0)        /*if not at left boundary          */
  270.         {
  271.             wnp->c--;        /*move cursor 1 column left          */
  272.             pl_csr(wnp);    /*place screen cursor              */
  273.         }
  274.         else            /*can't move cursor left              */
  275.             bell();
  276.         break;
  277.  
  278.         case -K_RIGHT:        /*handle right cursor              */
  279.         if(wnp->c < cmax)    /*if not at right boundary          */
  280.         {
  281.             wnp->c++;        /*move cursor 1 column right          */
  282.             pl_csr(wnp);    /*place screen cursor              */
  283.         }
  284.         else            /*can't move cursor right             */
  285.             bell();
  286.         break;
  287.  
  288.         default:            /*handle all other possibilities      */
  289.         if(c > 0)        /*check for printable character       */
  290.         {
  291.             if(wnp->c == cmax)    /*Done. write last char & goto end    */
  292.             {            /*check cs limit first, because wn.c  */
  293.             v_ch(c, wnp);    /*will go to zero if at edge of wind. */
  294.             done = 1;
  295.             }
  296.             else
  297.             {
  298.             v_ch(c, wnp);        /*else write character and continue   */
  299.             pl_csr(wnp);
  300.             }
  301.         }
  302.         else            /* extended code              */
  303.             bell();        /* let user know it's illegal         */
  304.         break;
  305.     }
  306.     }
  307.  
  308.     v_mova(stp, wnp, ROW, OUT);     /*transfer window row to string       */
  309.     strip_wh(stp);            /*strip white spaces from end of strin*/
  310.     count = strlen(stp);
  311.     if(kenter)                /*need to append newline          */
  312.     {
  313.     stp += count++;             /*go to null, increment count     */
  314.     *stp++ = '\n';                      /*append newline                  */
  315.     *stp = '\0';                        /*append null terminator          */
  316.     }
  317.     return(count);            /*return number of char in string     */
  318. }
  319.