home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / EXAMPLES / DEMOTTY.C < prev    next >
C/C++ Source or Header  |  1991-03-09  |  11KB  |  373 lines

  1. /*
  2.     demotty.c
  3.  
  4.     jmd 8/06/89
  5.     Fun with tty cmap windows
  6.  
  7.     C-scape 3.2    Example Program
  8.     Copyright (c) 1990 by Oakland Group, Inc.
  9.     ALL RIGHTS RESERVED.
  10.  
  11.     This program demonstrates the use of a character map (cmap) window.
  12.     The function cmap_PlotTTY is called to output text to the window in
  13.     TTY fashion.  See cmap_PlotTTY in the OWL file CMWINTTY.C for details.
  14.  
  15.     Also demostrated here is attaching a border to the window; setting the
  16.     border title and prompt; enabling mouse features in the border; 
  17.     positioning the window; and connecting an auxiliary function to a window
  18.     to process keystrokes via the WINA_GO message.
  19.  
  20.     You may call this program with an ASCII file as an argument and see
  21.     the text roll thru the window:
  22.  
  23.         demotty mytext.txt
  24.  
  25.     Or, you may invoke it with no argument and enter text from the
  26.     keyboard.
  27.  
  28.     Revision History:
  29.     -----------------
  30.      1/31/90 jmd    added use of wingo_func
  31.      4/01/90 jmd    ansi-fied
  32.      6/05/90 jmd    added more commentary on go_funcs
  33.      6/06/90 jmd    changed main to return an int
  34.      9/14/90 bkd    changed to use exit(0) instead of return(0).
  35.      9/24/90 jmd    added use of aux funcs
  36.     10/19/90 pmcm    included ostdlib.h for exit(), added return(1)
  37.     12/01/90 ted    added oak_notused() macro to suppress warnings.
  38.     12/04/90 ted    restored "" includes for C-scape headers (not <> includes).
  39.      12/6/90 bkd    switched order of oak.h and ostdlib.h
  40.     ---------------------------------------------------------------------------
  41.  
  42.     Seds are windows of the sedwin_Class.  This is the most common C-scape
  43.     window.  There are other window types available in the Oakland Windowing
  44.     Library (OWL), however.
  45.  
  46.     One of these other windows is a cmap window, or cmwin.   The forthcoming 
  47.     Oakland Advanced Programming Guide is the manual for the OWL and will 
  48.     provide a more in-depth look at window classes and objects.  Here we 
  49.     present the rudiments.
  50.  
  51.     Character map (cmap) windows are of the cmwin_Class.  A character map is 
  52.     a two-dimensional array of characters and attributes.
  53.  
  54.     You can create a window with win_Open.  This routine creates an object of
  55.     class winclass.  The starting size and position (in display coordinates) is
  56.     given by the ocbox cboxp.  The window is placed in the unemployed window
  57.     list.   win_Open returns a pointer to the newly created window or NULL if
  58.     unsuccessful.
  59.  
  60.          win_type win_Open(class_fptr winclass, ocbox *cboxp);  
  61.  
  62.  
  63.     You employ the window  - painting it to the display - with win_Employ.
  64.  
  65.          boolean win_Employ(win_tye win);
  66.  
  67.  
  68.     The window is fired - removing it from the display without destroying it -
  69.     by calling with win_UnEmploy.
  70.  
  71.          boolean win_UnEmploy(win_type win);
  72.  
  73.  
  74.     You can destroy the window with win_Close.  This removes the window from
  75.     the display and deallocates its storage.
  76.  
  77.          void win_Close(win_type win);
  78.  
  79.     You can connect a auxiliary function to a window with obj_SetAux().
  80.     When you call win_Go on a non-sed window, its aux function gets
  81.     sent a WINA_GO message:
  82.  
  83.         obj_SetAux(win, my_aux);
  84.         win_Go(win);
  85.  
  86.     Note that a window is a kind of "object" and that all "objects"
  87.     have aux functions.  We must use the function obj_SetAux to attach an
  88.     aux function to the window.  sed_SetAux is simply a macro to
  89.     obj_SetAux
  90.  
  91.     When the aux function receives the WINA_GO message it should
  92.     handle input to the window (similar    to a C-scape fkey function):
  93.  
  94.         int my_aux(win_type win, int msg, VOID *indata, VOID *outdata)
  95.         {
  96.             boolean quit = FALSE;
  97.             int baton = 0;
  98.  
  99.             switch(msg) {
  100.  
  101.             case WINA_GO:
  102.                 while (!quit) {
  103.  
  104.                     kb_Read();
  105.                       ...
  106.                 }
  107.  
  108.                 return(baton);
  109.  
  110.             default:
  111.                 return(1);
  112.         }
  113.  
  114.     The return value of the aux function is returned from win_Go (just
  115.     as a baton value is returned from sed_Go()).
  116.  
  117.     Some common additional functions enable you to attached a border, set the
  118.     window position, and create a bob from the window so that you may nest it
  119.     within a sed.
  120.  
  121.          boolean win_SetBorder(win_type win, class_fptr bd);
  122.  
  123.          void win_SetPosition(win_type win, int row, int col);
  124.  
  125.  
  126.          bob_type win_CreateBob(win_type win, int depend);
  127.  
  128.              
  129.              depend is either BOB_DEPEND or BOB_INDEPENDENT
  130.              bobs move when the parent is moved
  131.              a dependent bob will be painted with its parent
  132.              an independent bob must be painted separately
  133.              
  134.  
  135.     You can display text in the cmap window by drawing the text string in the
  136.     cmap:
  137.  
  138.          char *cmwin_DrawString(win_type     cmwin,
  139.                                 int         row, 
  140.                                 int         col, 
  141.                                 char         *string,
  142.                                  byte         attr,
  143.                                 int         slen);
  144.          
  145.              Places string within window's cmap, clipping against cmap edges.
  146.              Puts blanks from end of string to slen if string was too short.
  147.              String is not read after a newline or a '\0'.
  148.              Coords are relative to cmap.
  149.              For blanks past the end of the string, attribute 'attr' is used.
  150.              Returns pointer to char after last one put into cmap.
  151.          
  152.  
  153.  
  154.     You initially paint the window to the display with win_Employ, as mentioned
  155.     above.
  156.  
  157.     You can refresh the display of a cmap window with win_Paint.
  158.     win_Paint only paints the window.  If you wish to paint the border, any
  159.     window shadow, and the window then call bord_Paint.  In general, win_ calls
  160.     affect only the window; bord_ calls affect the window and border.  If you
  161.     have nested it by the use of win_CreateBob, call sed_Repaint.
  162.  
  163.         void win_Paint(win_type win);
  164.  
  165.         void bord_Paint(win_type win);
  166.  
  167.  
  168.     cmwins have an associated data store (cmap) that determine what is painted
  169.     to the display.  (seds are similar, in that    the sed, menu, and field data 
  170.     structures tell a sed how to paint itself).
  171.  
  172.  
  173.     When a cmwin is opened the size of its cmap is determined by the dimensions
  174.     of the window.  By default, when the cmwin is made re-sized smaller the
  175.     cmap stays anchored in the upper left corner of the window.   Its re-
  176.     size flag is FALSE.  You may change this behaviour so that the anchor is 
  177.     in the lower right corner by setting its resize flag TRUE.  These 
  178.     functions get and set the resize flag.
  179.  
  180.         boolean cmwin_GetResize(win_type cmwin);
  181.  
  182.         void cmwin_SetResize(win_type cmwin, boolean b);
  183.  
  184.  
  185.     You may consult the source for the cmwin_Class in CMWIN.C.
  186.     The headers CMWINOBJ.H will give you some listing of function macros 
  187.     pertinent to this window class.
  188.  
  189. */
  190.  
  191. /*
  192.     if you had included cscape.h you wouldn't have to include oak.h, 
  193.     odisp.h or bordobj.h.
  194. */
  195.  
  196. #include <stdio.h>
  197. #include <ctype.h>        /* for isprint() */
  198.  
  199. #include "oak.h"
  200. #include "ostdlib.h"    /*    for exit() */
  201. #include "odisp.h"
  202.  
  203. #include "cmwinobj.h"    /* for cmwin stuff */
  204. #include "bordobj.h"    /* for border stuff */
  205.  
  206. #include "scancode.h"    /* for referring to keyboard */
  207.  
  208. /*** Function prototypes ***/
  209.  
  210. /* Turbo C++ complains if main is prototyped */
  211. #ifndef TCP
  212. int main(int argc, char *argv[]);
  213. #endif
  214.  
  215. aux_func (aux_TTY);
  216.  
  217. #define FEATURE     (BD_MOVE | BD_RESIZE | BD_OUTLINE)
  218. #define BORDER      bd_prompt
  219.  
  220. /* file pointer: global so that gofunc can refer to it */
  221. FILE *fp = NULL;
  222.  
  223. int main(int argc, char *argv[])
  224. {
  225.     win_type    win;
  226.     ocbox       cbox;
  227.  
  228.     /* open file specified on command line for reading */
  229.  
  230.     if (argc > 1) {
  231.         fp = fopen(argv[1], "r");
  232.     }
  233.  
  234.     /* use the current video mode */
  235.     disp_Init(def_ModeCurrent, FNULL);
  236.  
  237.     /* initialize the mouse */
  238.     hard_InitMouse();
  239.     cmwin_MouseInit();
  240.  
  241.     /* set up for a window with half as many row & cols as display */
  242.     cbox.toprow   = 1;
  243.     cbox.leftcol  = 1;
  244.     cbox.botrow   = (int) (disp_GetHeight() / 2);
  245.     cbox.rightcol = (int) (disp_GetWidth() / 2);
  246.  
  247.     /* create the window and attach the border */
  248.  
  249.     /* Create a cmap window */
  250.     win = win_Open(cmwin_Class, &cbox);
  251.     win_SetPosition(win, (int)(disp_GetHeight() / 4), (int)(disp_GetWidth() / 4));
  252.  
  253.     /* attach a border to the window */
  254.     win_SetBorder(win, BORDER);
  255.     bord_SetFeature(win, FEATURE);
  256.     bord_SendMsg(win, BDM_SETTITLE, "Character map (cmap) TTY window", NULL);
  257.  
  258.     /* attach our auxilary function to our window */
  259.     obj_SetAux(win, aux_TTY);
  260.  
  261.     /* employ the window and paint it to the display */
  262.     win_Employ(win);
  263.  
  264.     /* call go on the window (this passes control to our wingo_func) */
  265.     win_Go(win);
  266.  
  267.     /* close the OWL and the input file, if present */
  268.     disp_Close();
  269.  
  270.     if (fp != NULL) {
  271.         fclose(fp);
  272.     }
  273.  
  274.     exit(0);
  275.     return(0);
  276. }
  277.  
  278. int aux_TTY(win_type win, int msg, VOID *indata, VOID *outdata)
  279. /*
  280.     The auxiliary function for our cmap window.
  281.     This function gets called with a WINA_GO message
  282.     when we call win_Go on the cmap window.
  283.  
  284.     It handles the character input.
  285.     (similar to a C-scape fkey function)
  286.  
  287.     Note: this is the same as a regular C-scape auxiliary function.
  288. */
  289. {
  290.     char        buffer[501];
  291.     boolean     done;
  292.     SIZE_T      len;
  293.     int         scancode;
  294.  
  295.     oak_notused(indata);
  296.     oak_notused(outdata);
  297.  
  298.     if (msg == WINA_GO) {
  299.  
  300.         if (fp == NULL) {
  301.             done = FALSE;               /* read keys if no input file given */
  302.             bord_SendMsg(win, BDM_PROMPT, "Ready for keybd input!  ESC=quit", NULL);
  303.             while(!done) {
  304.                 switch (scancode = kb_Read()) {
  305.                 case ESC:
  306.                     done = TRUE;                /* ESC to quit */
  307.                     buffer[0] = '\0';
  308.                     break;
  309.  
  310.                 case ENTER:                     /* CR and LF */
  311.                     buffer[0] = '\n';
  312.                     buffer[1] = '\0';
  313.                     break;
  314.  
  315.                 case BACKSPACE:                 /* back up one col in row */
  316.                     buffer[0] = '\b';
  317.                     buffer[1] = '\0';
  318.                     break;
  319.  
  320.                 case UP:                        /* reverse linefeed */
  321.                     buffer[0] = '\v';
  322.                     buffer[1] = '\0';
  323.                     break;
  324.  
  325.                 case RIGHT:                     /* move left one col in row */
  326.                     buffer[0] = ' ';
  327.                     buffer[1] = '\0';
  328.                     break;
  329.  
  330.                 case TAB:                       /* tab */
  331.                     buffer[0] = '\t';
  332.                     buffer[1] = '\0';
  333.                     break;
  334.  
  335.                 case PGDN:                      /* form feed (the height of win) */
  336.                     buffer[0] = '\f';
  337.                     buffer[1] = '\0';
  338.                     break;
  339.                     /* print whats printable */
  340.                 default:
  341.                     buffer[0] = (isprint(ascii(scancode))) ? (char) ascii(scancode) : '\0';
  342.                     buffer[1] = '\0';
  343.                     break;                                     
  344.                 }
  345.                 cmwin_PlotTTY(win, buffer);
  346.             }
  347.         }
  348.  
  349.         else {                                  /* if we have an input file */
  350.  
  351.             bord_SendMsg(win, BDM_PROMPT, "Press a key to begin!", NULL);
  352.             kb_Read();                          /* wait for a starting keypress */  
  353.             bord_SendMsg(win, BDM_PROMPT, "ESC=quit", NULL);
  354.  
  355.             do {                                /* then read file 500 at a shot */
  356.                 len = fread(buffer, 1, 500, fp);
  357.                 buffer[len] = '\0';
  358.                 cmwin_PlotTTY(win, buffer);     /* and show */
  359.  
  360.             } while (len == 500);               /* till done */
  361.  
  362.             kb_Read();
  363.         }
  364.  
  365.         /* the return value is returned via win_Go */
  366.         return(0);
  367.     }
  368.  
  369.     /* all other messages, return 1 */
  370.     return(1);
  371. }
  372.  
  373.