home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / other / cled122s / source / cled.c next >
Encoding:
C/C++ Source or Header  |  1991-05-14  |  43.9 KB  |  1,117 lines

  1. /****************************************************************************
  2. PROGRAM     : CLED                   VERSION  : 1.22
  3. AUTHOR      : ROBERT ALLEY           DATE     : 27/04/91
  4.               LOT 1590 GAY STREET
  5.               SOUTHERN RIVER
  6.               WESTERN AUSTRALIA 6110
  7.               PH (09)490-1105
  8. DESCRIPTION : Print cassette box inserts.
  9. LOGIC USED  : STEP 1.   Initialise application, set up some variables, turn
  10.                         on the mouse and display intoduction dialog.  Get
  11.                         system sizes.  Get the address of the tree to use
  12.                         as our new background, install the background, send
  13.                         a redraw for the whole screen, display menu bar.
  14.               STEP 2.   Set the various window structure parameters and open
  15.                         the text and graphic windows.
  16.               STEP 3.   Repeat until 0 is returned from handle_menu (ie. user
  17.                         selects quit).  Wait for an event.  If we get a message
  18.                         handle it.  Get the handle of the top window. If they 
  19.                         havent quit pass event on to the routine which owns
  20.                         the top window.
  21.               STEP 4.   Close and delete both the windows, free resource
  22.                         memory, turn off gem and end.
  23. PARAMETERS  : None.
  24. VARIABLES   : repeat      I    Flag for repeating main loop or not.
  25.               menu        OBJ* Pointer to menu bar object
  26.               dialog      OBJ* Pointer to dialog boxes, (intro etc.)
  27.               textw       WIND Text window info structure
  28.               graphw      WIND Graphic window info structure
  29.               event       I    Event returned by event_multi
  30.               opened      I    Flag for window opening status
  31. REQD. FILES : CLED.RSC  -  Resource file data.
  32.               Optional graphic file to load.
  33. REQD. SUBPG.: check_res();    - Check the resolution being used
  34.               clear_text();   - Clear the text window and storage
  35.               do_redraw();    - Pass out redraw requests
  36.               do_dialog();    - Draw and handle dialogs
  37.               handle_menu()   - Handle pull down menu events
  38.               gem_off();      - Turn off GEM
  39.               gem_on();       - Turn on GEM
  40.               graphic();      - Handle the graphic window events
  41.               hide();         - Hide the mouse pointer
  42.               init_path();    - Initialise the load paths
  43.               load_rsrc();    - Load the resource file
  44.               open_window();  - Open a window
  45.               show();         - Show the mouse pointer
  46.               text();         - Handle the text window
  47.   
  48. NOTES       : (REVISION HISTORY)
  49.               Now split into three sections: the main program (this file)
  50.                                              the files section (files.c)
  51.                                              and gem section (gem.c)
  52.               Compile with : cc -VGEM cled.c files.o gem.o                  ??/??/89
  53.               Menu bar added.                                               ??/??/89
  54.               Dialogs fixed (they now get removed)                          ??/11/89
  55.               Now works in medium and High res.                              2/12/89
  56.               Proper GEM interface started.                                  9/12/89
  57.               Split into four sections, printer section (printer.c) added.
  58.               Compile with : cc -VGEM cled.c files.o gem.o printer.o        11/12/89
  59.               Help dialogs added and mouse bugs fixed.                      12/12/89
  60.               Spine label bug fixed (Middle char was assigned /0), cursor
  61.               fixed so that it no longer gets left behind.
  62.               Graphics update now uses a lookup table for the powers of two
  63.               instead of calculating them on the fly (should be faster)     04/01/90
  64.               Initial window positions changed slightly for HIRES           09/02/90
  65.               Text update now only redraws lines that need it, graphic
  66.               window position moved down slightly.  Directory to search when
  67.               loading and saving now calculated.  (ie. uses default drive)  03/03/90
  68.               Graphic plotting now uses power look up table.  Data array
  69.               (Holds graphic data) changed from integers to characters.     05/03/90
  70.               Windows can now be closed.  Can open or top windows from the
  71.               menu bar.                                                     09/03/90
  72.    1.1        Graphic design may now be rolled left,right,up and down using
  73.               the 4,6,8 and 2 keys repectively. (Temp. user interface).
  74.               Send_redraw subroutine added.  Data array changed to unsigned
  75.               characters.  Using character array had problems, ie. 128
  76.               became -128, why I dont know.  Invert function added for
  77.               graphics window.  Scroll functions etc. placed inside else to
  78.               fix slight bug that appeared when they were added.            23/03/90
  79.    1.11       Scroll functions moved to cursor keys, insert key for invert,
  80.               m to mirror graphic left to right.                            26/03/90
  81.    1.111      Scroll functions etc. moved to GEM.C  Checks added when
  82.               windows are opened (Warns user if window couldnt be opened.)
  83.               Quit logic for handle_menu slightly improved.  Printer
  84.               status now checked before printing.                           28/03/90
  85.    1.111a     GEM.C modified: gem_off was fixed (Missing paranthesis after
  86.               appl_exit call).  No more problems with desk accessories!!!!  31/05/90
  87.               Resource file changed, was causing GEMINI 1.1 to say "The
  88.               Program Damaged Gemini".  Date forgotten.                     ??/06/90
  89.    1.2        Added side labels at top of graphic, modified do_redraw. 
  90.               Changed actions on TAB so that it only goes to a new line if
  91.               the cursor is in the right hand half allreadu.                02/07/90
  92.               Background (Including toolbox) now drawn from resource file.
  93.               Graphics tools now use icons from the toolbox.               
  94.               Fixed a bug in the mirror routine that swapped columns 19 & 20
  95.               twice.  Moved windows to uncover toolbox.  Modified help
  96.               dialog to reflect changes.                                    10/07/90
  97.               Changed mainline so that it gets the top window handle before
  98.               passing control to the graphics or test subprograms.  Subprograms
  99.               only called if their window is open.  Changed logic within
  100.               graphic subprogram.        
  101.    1.21       Started code to allow toolbox to be moved, again, after major
  102.               harddrive crash on the 25 (Yep Christmas day!)                28/12/90
  103.               (Should move this into main program loop instead of graphics
  104.                window handler)
  105.    1.22       Started porting to the GNU compiler, what a hassle, but I     27/04/91
  106.               discovered some lovely little bloopers in my code!
  107. THANKS      : To the many (I mean many!) people who helped me get to grips
  108.               with the intricacies of GEM AES, especially Jim Charlton for
  109.               his excellent XXED source code which helped clear up many
  110.               points.  And Tim Oren for the Pro Gem series of articles.
  111.               Also all those on Paragon BBS who answered my many questions.
  112.               And to Mark Williams Corp. and the Free Software Foundation (GNU)
  113.               for their excellent compilers.
  114. ****************************************************************************/
  115.  
  116. /* INCLUDE FILES                                                     */
  117. #include "define.h"
  118. #include <obdefs.h>
  119. #include <gemdefs.h>
  120. #include <osbind.h>
  121. #include <vdibind.h>
  122. #include <aesbind.h>
  123. #include <stdio.h>
  124. #include <ctype.h>
  125. #include "cled.h"
  126. #include "window.h"
  127. #include "rpcfg.h"
  128.  
  129. /* DEFINES                                                           */
  130. /* window constants */
  131. #define WI_KIND      (FULLER|CLOSER|NAME|MOVER)
  132. #define XPOS         wind->inx+(wind->curx*gl_wchar)+(gl_wchar/2)
  133. #define YPOS         wind->iny+( (wind->cury+3)*gl_hchar)+(gl_hchar/2)
  134. #define CPOS         wind->inx+(column*gl_wchar)+(gl_wchar/2)
  135. #define RPOS         wind->iny+( (row+3)*gl_hchar)+(gl_hchar/2)
  136. /* draw conditions */
  137. #define IN_RANGE   (mx>wind->inx) && (my>wind->iny) && (x>=0) && (x<=39) && (y>=0) && (y<=23)
  138. #define BUT_PRESSED ((button==1)||(button==2))
  139. #define RETURN 13
  140. #define TAB    9
  141. #define HELP   25088
  142. #define UNDO   24832
  143. #define INS    20992
  144. #define CLR    18176
  145. #define UP     18432
  146. #define LEFT   19200
  147. #define DOWN   20480
  148. #define RIGHT  19712
  149. #define BS     8
  150. #define DEL    127
  151. #define ESC    27
  152.  
  153. /* GLOBAL VARIABLES                                                  */
  154.  
  155. char        version[] = "1.22";         /* Current version number           */
  156.  
  157. int         gl_apid;            /* Application ID #                 */
  158. int         gl_hchar, gl_wchar;
  159. int         gl_wbox, gl_hbox;   /* system sizes                     */
  160. int         phys_handle;        /* physical workstation handle      */
  161. int         handle;             /* virtual workstation handle       */
  162. int         wi_handle;          /* window handle                    */
  163. int         graphich, texth;    /* Graphic and text window handles  */
  164. int         xdesk, ydesk, hdesk, wdesk; /* Co-ords and sizes of desktop     */
  165. int         xsize, ysize;       /* X and Y sizes of blocks in graphic */
  166. int         msgbuff[8];         /* event message buffer             */
  167. int         keycode;            /* code returned by event-keyboard  */
  168. int         mx, my;             /* mouse x and y pos.               */
  169. int         button;             /* button pressed                   */
  170. int         butdown;            /* button state tested for, UP/DOWN */
  171. int         ret;                /* dummy return variable            */
  172. int         contrl[12], intin[128];
  173. int         ptsin[128], intout[128];
  174. int         ptsout[128];        /* GEM arrays                       */
  175. int         work_in[11], work_out[57];  /* In/Out to/from GSX param. array  */
  176. int         pxyarray[10];       /* input point array                */
  177. unsigned char data[3][40];      /* storage for graphic data         */
  178. char        songs[16][47];      /* storage for songs & labels       */
  179. unsigned short int power[] = {128, 64, 32, 16, 8, 4, 2, 1};
  180. /* Lookup table for powers of two   */
  181. int         hidden;             /* Mouse hidden flag                */
  182. OBJECT     *screen;             /* Pointer to new background object */
  183. OBJECT     *toolbox;            /* Pointer to toolbox object        */
  184. char        graf_dir[128];
  185. char        prnt_dir[128];
  186. struct COMMAND print_codes[11]; /* Array to hold printer commands */
  187. int         driver_loaded = 0;  /* Did we load a driver, 0=No */
  188. char        print_name[80];     /* Printers name */
  189. int         coloura, quality;   /* Have we got colour, nlq? 0=No */
  190.  
  191. /****************************************************************************
  192. SUBROUTINE  : p_text                 VERSION  : 1.1
  193. AUTHOR      : ROBERT ALLEY           DATE     : 9/12/89
  194. DESCRIPTION : Print text characters on the terminal.
  195. LOGIC USED  : STEP 1.   Assign character to string, display string, add
  196.                         character to songs.  If not at end of line inc.
  197.                         current x position. 
  198. PARAMETERS  : wind         *WIND    Window info structure.
  199.               ch           I        Character to print
  200. VARIABLES   : prin         2CH      String to print.
  201. REQD. SUBPG.: hide()
  202.               show()
  203. USAGE       : p_text( &column, &row, character);
  204. ****************************************************************************/
  205. p_text(wind, ch)
  206.    struct WINDOW *wind;
  207.    int         ch;
  208. {
  209.    char        prin[2];
  210.  
  211.    prin[0] = ch;
  212.    prin[1] = 0;
  213.    hide();
  214.    v_gtext(handle, XPOS, YPOS, prin);
  215.    show();
  216.    songs[wind->cury][wind->curx] = ch;
  217.    if (wind->curx < 45)
  218.       wind->curx += 1;
  219.    if ((wind->curx == 22) && (wind->cury < 13))
  220.       wind->curx += 1;
  221. }
  222.  
  223. /****************************************************************************
  224. SUBROUTINE  : move                   VERSION  : 1.0
  225. AUTHOR      : ROBERT ALLEY           DATE     : 2/12/89
  226. DESCRIPTION : Move a window within the desktop
  227. LOGIC USED  : STEP 1.   Call AES routine to move window, get the new
  228.                         interior co-ordinates.
  229. PARAMETERS  : wind        *WIND  Window info structure.
  230.               x           *I     X co-ord to move to
  231.               y           *I     Y   "       "
  232.               w           *I     Width
  233.               h           *I     Height
  234. USAGE       : move(wind,&x,&y,&w,&h);
  235. ****************************************************************************/
  236. move(wind, x, y, w, h)
  237.    struct WINDOW *wind;
  238.    int        *x, *y, *w, *h;
  239. {
  240.    wind_set(wind->handle, WF_CURRXYWH, *x, *y, *w, *h);
  241.    wind_get(wind->handle, WF_WORKXYWH, &wind->inx, &wind->iny, &wind->inw, &wind->inh);
  242. }
  243.  
  244. /****************************************************************************
  245. SUBROUTINE  : p_contrl               VERSION  : 1.01
  246. AUTHOR      : ROBERT ALLEY           DATE     : 4/1/90
  247. DESCRIPTION : Handle control characters in text window.
  248. LOGIC USED  : STEP 1.   Assign current character to string, set begin point
  249.                         to current x position.  Based on ASCII chars carry
  250.                         out action, otherwise handle others (ie. HELP etc.)
  251. PARAMETERS  : wind        *WIND  Window info structure.
  252.               ch          I      ASCII Code of character
  253.               code        I      Code of character as returned by event.
  254. VARIABLES   : begn        I
  255.               end         I
  256.               print       2 CH   String to print.
  257. REQD. SUBPG.: hide()
  258.               show()
  259. USAGE       : p_contrl( &column, &row, character, code);
  260. ****************************************************************************/
  261. p_contrl(wind, ch, code)
  262.    struct WINDOW *wind;
  263.    int         ch;
  264.    int         code;
  265. {
  266.    int         begn, end;
  267.    char        prin[2];
  268.  
  269.    prin[0] = songs[wind->cury][wind->curx];
  270.    prin[1] = 0;
  271.    begn = wind->curx;
  272.    hide();
  273.    switch (ch) {
  274.    case RETURN:
  275.       if (wind->cury < 15) {
  276.          v_gtext(handle, XPOS, YPOS, prin);
  277.          wind->curx = 0;
  278.          wind->cury = wind->cury + 1;
  279.          if (wind->cury == 13)
  280.             wind->cury = 14;
  281.       }
  282.       break;
  283.    case TAB:
  284.       if (wind->cury < 15) {
  285.          v_gtext(handle, XPOS, YPOS, prin);
  286.          wind->curx = 23;
  287.          if (begn > 22) {
  288.             wind->cury = wind->cury + 1;
  289.             if (wind->cury == 13)
  290.                wind->cury = 14;
  291.             if (wind->cury > 13)
  292.                wind->curx = 0;
  293.          }
  294.       }
  295.       break;
  296.    case BS:
  297.       if (wind->curx == 0)
  298.          break;
  299.       if ((wind->curx == 23) && (wind->cury < 13))
  300.          break;
  301.       begn = wind->curx - 1;
  302.    case DEL:
  303.       if ((wind->curx < 22) && (wind->cury < 13))
  304.          end = 21;
  305.       else
  306.          end = 45;
  307.       for (wind->curx = begn; wind->curx < end; (wind->curx)++) {
  308.          songs[wind->cury][wind->curx] = songs[wind->cury][(wind->curx) + 1];
  309.          prin[0] = songs[wind->cury][wind->curx];
  310.          v_gtext(handle, XPOS, YPOS, prin);
  311.       }
  312.       songs[wind->cury][end] = 32;
  313.       wind->curx = end;
  314.       prin[0] = songs[wind->cury][wind->curx];
  315.       v_gtext(handle, XPOS, YPOS, prin);
  316.       wind->curx = begn;
  317.       break;
  318.    }
  319.    switch (code) {
  320.    case HELP:
  321.       v_gtext(handle, XPOS, YPOS, prin);
  322.       wind->curx = 0;
  323.       wind->cury = 0;
  324.       break;
  325.    case UNDO:
  326.       v_gtext(handle, XPOS, YPOS, prin);
  327.       wind->curx = 23;
  328.       wind->cury = 0;
  329.       break;
  330.    case INS:
  331.       if ((wind->curx < 22) && (wind->cury < 13))
  332.          end = 21;
  333.       else
  334.          end = 45;
  335.       for (wind->curx = end; wind->curx > begn; (wind->curx)--) {
  336.          songs[wind->cury][wind->curx] = songs[wind->cury][(wind->curx) - 1];
  337.          prin[0] = songs[wind->cury][wind->curx];
  338.          v_gtext(handle, XPOS, YPOS, prin);
  339.       }
  340.       wind->curx = begn;
  341.       songs[wind->cury][wind->curx] = 32;
  342.       break;
  343.    case CLR:
  344.       clear_text(wind);
  345.       break;
  346.    case UP:
  347.       if (wind->cury > 0) {
  348.          v_gtext(handle, XPOS, YPOS, prin);
  349.          wind->cury = wind->cury - 1;
  350.          if (wind->cury == 13) {
  351.             wind->cury = 12;
  352.             if (wind->curx == 22)
  353.                wind->curx = 23;
  354.          }
  355.       }
  356.       break;
  357.    case LEFT:
  358.       if (wind->curx > 0) {
  359.          v_gtext(handle, XPOS, YPOS, prin);
  360.          wind->curx = wind->curx - 1;
  361.          if ((wind->curx == 22) && (wind->cury < 14))
  362.             wind->curx = 21;
  363.       }
  364.       break;
  365.    case DOWN:
  366.       if (wind->cury < 15) {
  367.          v_gtext(handle, XPOS, YPOS, prin);
  368.          wind->cury = wind->cury + 1;
  369.          if (wind->cury == 13)
  370.             wind->cury = 14;
  371.       }
  372.       break;
  373.    case RIGHT:
  374.       if (wind->curx < 45) {
  375.          v_gtext(handle, XPOS, YPOS, prin);
  376.          wind->curx = wind->curx + 1;
  377.          if ((wind->curx == 22) && (wind->cury < 14))
  378.             wind->curx = 23;
  379.       }
  380.       break;
  381.    }
  382.    show();
  383. }
  384.  
  385. /****************************************************************************
  386. SUBROUTINE  : clear_text             VERSION  : 1.11
  387. AUTHOR      : ROBERT ALLEY           DATE     : 4/1/90
  388. DESCRIPTION : Clear and initialise text window.
  389. LOGIC USED  : STEP 1.   Loop thru all chars in title list, make them spaces,
  390.                         except the end ones which are zero's (to enable
  391.                         titles to be printed as strings).  Clear the window,
  392.                         draw the label, reset current x and y positions to
  393.                         zero, display cursor.
  394. PARAMETERS  : wind        *WIND  Window info structure.
  395. VARIABLES   : loop        I      Loop counter.
  396.               outloop     I       "      "
  397. REQD. SUBPG.: clear_window()
  398.               d_label()
  399.               hide()
  400.               show()
  401. USAGE       : clear_text( wind );
  402. ****************************************************************************/
  403. clear_text(wind)
  404.    struct WINDOW *wind;
  405. {
  406.    int         loop, outloop;
  407.  
  408.    for (outloop = 0; outloop < 16; outloop++)
  409.       for (loop = 0; loop < 47; loop++) {
  410.          if (((loop == 22) && (outloop < 14)) || (loop == 46))
  411.             songs[outloop][loop] = 0;
  412.          else
  413.             songs[outloop][loop] = 32;
  414.       }
  415.    clear_window(wind);
  416.    d_label(wind);
  417.    wind->curx = 0;
  418.    wind->cury = 0;
  419.    hide();
  420.    v_gtext(handle, XPOS, YPOS, "_");
  421.    show();
  422. }
  423.  
  424. /*******************************************************************************
  425. SUBROUTINE  :  gupdate                VERSION  : 1.1
  426. AUTHOR      :  ROBERT ALLEY           DATE     : 3/3/90
  427. DESCRIPTION :  Update the graphics window.
  428. LOGIC USED  :  STEP 1.  Calculate the start and end block numbers for x and 
  429.                         y (NOTE: +1 at end to ensure a loop occurs when the
  430.                         start and end are equal).
  431.                STEP 2.  Clear the window, loop from 0 to min(24,yend), loop
  432.                         from 0 to min(40,xend).  Check each bit to see if
  433.                         it is set.  If it is plot the point.
  434. PARAMETERS  :  wind        *WIND    Window info structure.
  435.                x1,y1,x2,y2 I        T/L & B/R co-ords of update.
  436. VARIABLES   :  loop,outloopI        Loop counters
  437.                val         I        Bit value to test for
  438.                set         I        Byte and val
  439.                temp        4 I      Holds co-ords to plot
  440.                xstart,xend I        X start and end boxes
  441.                ystart,yend I        Y start and end points.
  442. REQD. SUBPG.:  clear_window()
  443.                hide()
  444.                show()
  445. USAGE       :  gupdate(wind,x1,y1,x2,y2);
  446. *******************************************************************************/
  447. gupdate(wind, x1, y1, x2, y2)
  448.    struct WINDOW *wind;
  449.    int         x1, y1, x2, y2;
  450. {
  451.    register short int loop, outloop;
  452.    register int temp[4];
  453.    int         xstart, xend;
  454.    int         ystart, yend;
  455.  
  456.    /* STEP 1. */
  457.  
  458.    xstart = (x1 - wind->inx) / xsize;
  459.    xend = (x2 - wind->inx) / xsize + 1;
  460.    ystart = (y1 - wind->iny) / ysize;
  461.    yend = (y2 - wind->iny) / ysize + 1;
  462.  
  463.    yend = ((yend > 24) ? 24 : yend);
  464.    xend = ((xend > 40) ? 40 : xend);
  465.  
  466.    /* STEP 2. */
  467.  
  468.    clear_window(wind);
  469.    hide();
  470.    vsf_interior(handle, 2);
  471.    vsf_style(handle, 8);
  472.    vsf_color(handle, 1);
  473.    for (outloop = ystart; outloop < yend; outloop++) {
  474.       for (loop = xstart; loop < xend; loop++) {
  475.          if (data[outloop / 8][loop] & power[(outloop % 8)]) {
  476.             temp[0] = wind->inx + (loop * xsize) + 1;
  477.             temp[1] = wind->iny + (outloop * ysize) + 1;
  478.             temp[2] = temp[0] + (xsize - 2);
  479.             temp[3] = temp[1] + (ysize - 2);
  480.             v_bar(handle, temp);
  481.          }
  482.       }
  483.    }
  484.    show();
  485. }
  486.  
  487. /*******************************************************************************
  488. SUBROUTINE  :  tupdate               VERSION  : 1.1
  489. AUTHOR      :  ROBERT ALLEY          DATE     : 3/3/90
  490. DESCRIPTION :  Update the text window.
  491. LOGIC USED  :  STEP 1.  Clear the window, draw the label, loop thru all the
  492.                         rows, if row 13 (line between titles and spine) skip.
  493.                         Print string beginning at this row.  If were doing
  494.                         titles print string starting at position 23.  End
  495.                         of loop.  Display cursor.
  496. PARAMETERS  :  wind        *WIND    Window info structure.
  497.                x1,y1,x2,y2 I        T/L & B/R co-ords of update area.
  498. VARIABLES   :  row,column  I        Row and column co-ords of string start.
  499. REQD. SUBPG.:  clear_window()
  500.                do_window()
  501.                hide()
  502.                show()
  503. NOTES       :  The use of v_gtext requires null terminated string, hence
  504.                zero's put in columns 22 and 46 by clear_text.
  505. USAGE       :  tupdate(wind,x1,y1,x2,y2);
  506. *******************************************************************************/
  507. tupdate(wind, x1, y1, x2, y2)
  508.    struct WINDOW *wind;
  509.    int         x1, y1, x2, y2;
  510. {
  511.    register int row, column;
  512.    int         rstart, rend, cstart, cend;
  513.  
  514.    cstart = (x1 - wind->inx) / gl_wchar - 1;
  515.    cend = (x2 - wind->inx) / gl_wchar + 1;
  516.    rstart = (y1 - wind->iny) / gl_hchar - 3;
  517.    rend = (y2 - wind->iny) / gl_hchar - 1;
  518.  
  519.    rstart = (rstart < 0) ? 0 : rstart;
  520.    rend = (rend > 16) ? 16 : rend;
  521.    cstart = (cstart < 0) ? 0 : cstart;
  522.  
  523.    clear_window(wind);
  524.    d_label(wind);
  525.    hide();
  526.    for (row = rstart; row < rend; row++) {
  527.       if (row == 13)
  528.          continue;
  529.       if ((row > 13) || (cstart < 22)) {
  530.          column = cstart;
  531.          v_gtext(handle, CPOS, RPOS, &songs[row][column]);
  532.       }
  533.       if ((row < 13) && (cend > 22)) {
  534.          column = 23;
  535.          v_gtext(handle, CPOS, RPOS, &songs[row][column]);
  536.       }
  537.    }
  538.    v_gtext(handle, XPOS, YPOS, "_");
  539.    show();
  540. }
  541.  
  542. /*******************************************************************************
  543. SUBROUTINE  :  do_redraw             VERSION  : 1.11
  544. AUTHOR      :  ROBERT ALLEY          DATE     : 27/04/91
  545. DESCRIPTION :  handle redraw requests.
  546. LOGIC USED  :  STEP 1.  Get handle of window to update, co-ords of update
  547.                         area.  Get the first rectangle to redraw.  While
  548.                         width and height not both zero :  if the rectangles
  549.                         intersect, set clipping to dirty recatngle, call
  550.                         appriopriate update routine.
  551. PARAMETERS  :  twind       *WIND    Text window info structure.
  552.                gwind       *WIND    Graphic window info structure
  553. VARIABLES   :  window      I        Handle of dirty window
  554.                rect        4 I      Total area that needs update.
  555.                redraw      4 I      Dirty rectangle to redraw
  556. REQD. SUBPG.:  gupdate
  557.                tupdate
  558. NOTES       :  Assumes it is passed the window structure (either twind or
  559.                gwind) of the window with handle equal to msgbuff[3]
  560. USAGE       :  do_redraw(twindow,gwindow);
  561. *******************************************************************************/
  562. do_redraw(twind, gwind)
  563.    struct WINDOW *twind, *gwind;
  564. {
  565.    int         window;
  566.  
  567. #ifdef NO_GRECT
  568.    int         redraw[4],rect[4];
  569.  
  570.  
  571.    window = msgbuff[3];
  572.    rect[0] = msgbuff[4];
  573.    rect[1] = msgbuff[5];
  574.    rect[2] = msgbuff[6];
  575.    rect[3] = msgbuff[7];
  576.    wind_get(window, WF_FIRSTXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]);
  577.  
  578.    while (redraw[2] && redraw[3]) {
  579.       if (rc_intersect(rect, redraw)) {
  580.          redraw[2] = redraw[0] + redraw[2] - 1;
  581.          redraw[3] = redraw[1] + redraw[3] - 1;
  582.          vs_clip(handle, 1, redraw);
  583.          if (window == graphich)
  584.             gupdate(gwind, redraw[0], redraw[1], redraw[2], redraw[3]);
  585.          if (window == texth)
  586.             tupdate(twind, redraw[0], redraw[1], redraw[2], redraw[3]);
  587.       }
  588.       wind_get(window, WF_NEXTXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]);
  589.    }
  590.    wind_get(0, WF_WORKXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]);
  591.    redraw[2] = redraw[0] + redraw[2] - 1;
  592.    redraw[3] = redraw[1] + redraw[3] - 1;
  593.    vs_clip(handle, 1, redraw);
  594. }
  595.  
  596. #else
  597.    GRECT       redraw, rect;
  598.    int         clipped[4];
  599.  
  600.    window = msgbuff[3];
  601.    rect.g_x = msgbuff[4];
  602.    rect.g_y = msgbuff[5];
  603.    rect.g_w = msgbuff[6];
  604.    rect.g_h = msgbuff[7];
  605.    wind_get(window, WF_FIRSTXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h);
  606.  
  607.    while (redraw.g_w && redraw.g_h) {
  608.       if (rc_intersect(&rect, &redraw)) {
  609.          clipped[0] = redraw.g_x;
  610.          clipped[1] = redraw.g_y;
  611.          clipped[2] = redraw.g_x + redraw.g_w - 1;
  612.          clipped[3] = redraw.g_y + redraw.g_h - 1;
  613.          vs_clip(handle, 1, clipped);
  614.          if (window == graphich)
  615.             gupdate(gwind, clipped[0], clipped[1], clipped[2], clipped[3]);
  616.          if (window == texth)
  617.             tupdate(twind, clipped[0], clipped[1], clipped[2], clipped[3]);
  618.       }
  619.       wind_get(window, WF_NEXTXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h);
  620.    }
  621.    wind_get(0, WF_WORKXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h);
  622.    clipped[0] = redraw.g_x;
  623.    clipped[1] = redraw.g_y;
  624.    clipped[2] = redraw.g_x+ redraw.g_w - 1;
  625.    clipped[3] = redraw.g_y + redraw.g_h - 1;
  626.    vs_clip(handle, 1, clipped);
  627. }
  628. #endif
  629.  
  630. /****************************************************************************
  631. SUBROUTINE  : d_label                VERSION  : 1.02
  632. AUTHOR      : ROBERT ALLEY           DATE     : 3/3/90
  633. DESCRIPTION : Draw the label outline in the text window and init song titles.
  634. LOGIC USED  : STEP 1.   Calc the begin and end points of each of the lines
  635.                         and draw them.  Calc the co-ords of the side 
  636.                         headings and print them.
  637. PARAMETERS  : wind         *WIND    Pointer to window info structure.
  638. VARIABLES   : coords       I4       Array of coordinates for lines.
  639.               x,y          I        X and Y co-ords of side headings.
  640. REQD> SUBPG.: hide()
  641.               show()
  642. USAGE       : d_label();
  643. ****************************************************************************/
  644. d_label(wind)
  645.    struct WINDOW *wind;
  646. {
  647.    int         coords[4];
  648.    int         x, y;
  649.  
  650.    hide();
  651.    coords[0] = wind->inx;
  652.    coords[1] = wind->iny + (2 * gl_hchar);
  653.    coords[2] = wind->inx + wind->inw - 1;
  654.    coords[3] = wind->iny + (2 * gl_hchar);
  655.    v_pline(handle, 2, coords);
  656.    coords[1] = wind->iny + (16 * gl_hchar);
  657.    coords[3] = wind->iny + (16 * gl_hchar);
  658.    v_pline(handle, 2, coords);
  659.    coords[0] = wind->inx + (23 * gl_wchar);
  660.    coords[1] = wind->iny + (2 * gl_hchar);
  661.    coords[2] = wind->inx + (23 * gl_wchar);
  662.    v_pline(handle, 2, coords);
  663.    x = ((wind->inw / 2) - (6 * gl_wchar)) / 2 + wind->inx;
  664.    y = wind->iny + 1.25 * gl_hchar;
  665.    v_gtext(handle, x, y, "SIDE 1");
  666.    x = x + (wind->inw / 2);
  667.    v_gtext(handle, x, y, "SIDE 2");
  668.    show();
  669. }
  670.  
  671. /****************************************************************************
  672. SUBROUTINE  : text                   VERSION  : 1.1
  673. AUTHOR      : ROBERT ALLEY           DATE     : 9/12/89
  674. DESCRIPTION : Handle events within text window.
  675. LOGIC USED  : STEP 1.   Get the top window.  Set window update flag.  If
  676.                         event was a message handle it.
  677.               STEP 2.   If event was a key and we are the top window,
  678.                         convert key to ASCII, if printable call print
  679.                         procedure otherwise call procedure to handle
  680.                         control characters.  Clear updarte flag.
  681. PARAMETERS  : wind         *WIND    Pointer to window info structure.
  682.               event        I        AES event that occured
  683. VARIABLES   : key          I        ASCII code of key pressed
  684. REQD. SUBPG.: clear_text
  685.               hide
  686.               move
  687.               p_text
  688.               p_control
  689.               show
  690. USAGE       : text(wind,event);
  691. ****************************************************************************/
  692. text(wind, event)
  693.    struct WINDOW *wind;
  694.    int         event;
  695. {
  696.    int         key;
  697.  
  698.    if (event & MU_MESAG) {
  699.       switch (msgbuff[0]) {
  700.       case WM_FULLED:
  701.          clear_text(wind);
  702.          break;
  703.       case WM_MOVED:
  704.          move(wind, &msgbuff[4], &msgbuff[5], &msgbuff[6], &msgbuff[7]);
  705.          break;
  706.       }
  707.    }
  708.    if ((event & MU_KEYBD) && (wi_handle == wind->handle)) {
  709.       key = toascii(keycode);
  710.       if (isprint(key) != 0) {
  711.          p_text(wind, key);
  712.          hide();
  713.          v_gtext(handle, XPOS, YPOS, "_");
  714.          show();
  715.       } else if (iscntrl(key) != 0) {
  716.          p_contrl(wind, key, keycode);
  717.          hide();
  718.          v_gtext(handle, XPOS, YPOS, "_");
  719.          show();
  720.       }
  721.    }
  722. }
  723.  
  724. /****************************************************************************
  725. SUBROUTINE  : clear_graf             VERSION  : 1.01
  726. AUTHOR      : ROBERT ALLEY           DATE     : 2/12/89
  727. DESCRIPTION : Clear the graphics window and data.
  728. LOGIC USED  : STEP 1.   Clear window,  loop thru all bytes, set to 0.
  729. PARAMETERS  : wind         *WIND    Window info structure.
  730. VARIABLES   : loop,outloop I        Loop counters
  731. REQD. SUBPG.: clear_window()
  732. USAGE       : clear_graf(wind);
  733. ****************************************************************************/
  734. clear_graf(wind)
  735.    struct WINDOW *wind;
  736. {
  737.    int         outloop, loop;
  738.  
  739.    clear_window(wind);
  740.    for (outloop = 0; outloop < 3; outloop++) {
  741.       for (loop = 0; loop < 40; loop++) {
  742.          data[outloop][loop] = 0;
  743.       }
  744.    }
  745. }
  746.  
  747. /****************************************************************************
  748. SUBROUTINE  : graphic                VERSION  : 1.31
  749. AUTHOR      : ROBERT ALLEY           DATE     : 28/12/90
  750. DESCRIPTION : Handle events that occur in graphics window.
  751. LOGIC USED  : STEP 1.   Get top window handle, set update flag, get mouse
  752.                         state, calculate box co-ordinates, row and column
  753.                         number.  If a message is sent do it.
  754.               STEP 2.   If the graphics window is the top window
  755.                            If mouse is within the window
  756.                               print co-ordinates to position string.
  757.                               If a mouse button is pressed : 
  758.                                  move co-ords 
  759.                                  into temp, plot box.  Calculate bit/byte for
  760.                                  box, add or remove from data set.
  761.               STEP 3.      Else (out side window) 
  762.                               print zeros to position string
  763.                               If button pressed :
  764.                                  check if a tool is selected, if it is call
  765.                                  appropriate subroutine.
  766.                               If user clicked on toolbox title, draw a 
  767.                                  dragable box, redraw old toobox area and new
  768.                                  area by telling GEM there was a dialog there.
  769.                            print position string.
  770. PARAMETERS  : wind        *WIND   Pointer to window info structure.
  771. VARIABLES   : row         I    Current row position
  772.               column      I    Current column position
  773.               temp        I4   Co-ords of box to plot
  774.               position    C8   String to hold position info
  775.               loop        I
  776.               block       I    Byte of data being accessed
  777.               bit         I    Bit         "
  778.               val         I    Value of byte
  779.               disk        I    Return from alerts for load/save
  780.               event       I    AES event returned by event_multi
  781. REQD. SUBPG.: move
  782.               clear_graf
  783.               plot                   (In gem.c, gem.o)
  784.               scrollv
  785.               scrollh
  786. USAGE       : graphic(wind,event);
  787. ****************************************************************************/
  788. graphic(wind, event)
  789.    struct WINDOW *wind;
  790.    int         event;
  791. {
  792.    int         row, column;
  793.    int         x, y;
  794.    int         temp[4];
  795.    char        position[8];
  796.    int         block, tool;
  797.    int         oldx, oldy;
  798.    int         nx,ny;
  799.  
  800.    /* STEP 1. */
  801.  
  802.    vq_mouse(handle, &button, &mx, &my);
  803.    row = (((my - wind->iny) / ysize) * ysize) + 1;
  804.    column = (((mx - wind->inx) / xsize) * xsize) + 1;
  805.    x = (mx - wind->inx) / xsize;
  806.    y = (my - wind->iny) / ysize;
  807.    if (event & MU_MESAG) {
  808.       switch (msgbuff[0]) {
  809.       case WM_FULLED:
  810.          clear_graf(wind);
  811.          break;
  812.       case WM_MOVED:
  813.          move(wind, &msgbuff[4], &msgbuff[5], &msgbuff[6], &msgbuff[7]);
  814.          break;
  815.       }
  816.    }
  817.    /* STEP 2. */
  818.  
  819.    if (wi_handle == wind->handle) {
  820.       if (IN_RANGE) {
  821.          sprintf(position, "%*d,%*d", 2, x, 2, y);
  822.          if (BUT_PRESSED) {
  823.             temp[0] = wind->inx + column;
  824.             temp[1] = wind->iny + row;
  825.             temp[2] = wind->inx + column + xsize - 2;
  826.             temp[3] = wind->iny + row + ysize - 2;
  827.             plot(button, temp);
  828.             block = y / 8;
  829.             if (button == 1)
  830.                data[block][x] = data[block][x] | power[y % 8];
  831.             if (button == 2)
  832.                data[block][x] = data[block][x] & (255 - power[y % 8]);
  833.          }
  834.       }
  835.       /* STEP 3. */
  836.  
  837.       else {
  838.          sprintf(position, "%*d,%*d", 2, 0, 2, 0);
  839.          if (button == 1) {
  840.             tool = objc_find(screen, 0, 10, mx, my);
  841.             if (tool == SDOWN)
  842.                scrollv(wind, 1);
  843.             else if (tool == SUP)
  844.                scrollv(wind, 2);
  845.             else if (tool == SRIGHT)
  846.                scrollh(wind, 1);
  847.             else if (tool == SLEFT)
  848.                scrollh(wind, 2);
  849.             else if (tool == MIRROR)
  850.                mirror(wind);
  851.             else if (tool == INVERT) {
  852.                for (x = 0; x < 3; x++)
  853.                   for (y = 0; y < 40; y++)
  854.                      data[x][y] = 255 - data[x][y];
  855.                send_redraw(wind);
  856.             } else if (tool == TTITLE) {
  857.                oldx = toolbox->ob_x - 1;
  858.                oldy = toolbox->ob_y - 1;
  859.                graf_dragbox(toolbox->ob_width, toolbox->ob_height,
  860.                             toolbox->ob_x, toolbox->ob_y,
  861.                             0, 0, wdesk, hdesk,
  862.                             &nx, &ny);
  863.                toolbox->ob_x=(short)nx;
  864.                toolbox->ob_y=(short)ny;
  865.                form_dial(3, 0, 0, 0, 0, oldx, oldy, toolbox->ob_width + 2, toolbox->ob_height + 2);
  866.                form_dial(3, 0, 0, 0, 0, toolbox->ob_x - 1, toolbox->ob_y - 1, toolbox->ob_width + 2, toolbox->ob_height + 2);
  867.             }
  868.          }
  869.       }
  870.       v_gtext(handle, (wind->inx + gl_wbox + 1), (wind->iny - 4), position);
  871.    }
  872. }
  873.  
  874.  
  875. /*******************************************************************************
  876. SUBROUTINE  :  handle_menu           VERSION  : 1.023
  877. AUTHOR      :  ROBERT ALLEY          DATE     : 27/04/91
  878. DESCRIPTION :  Handle events concerning the menu bar.
  879. LOGIC USED  :  STEP 1.   If selection was ABOUTCLED, get address of ABOUT
  880.                          dilaog, do it.
  881.                          If LOADGRAPHIC, load it, send redraw for graphic
  882.                          window.
  883.                          If SAVEGRAPHIC, save it.
  884.                          If QUIT, check thety really want to, if they do
  885.                          return a zero to end program.
  886.                          If PRINT, print the label.
  887.                          If one of the window commands, call wind_open with
  888.                          appropriate window structure.
  889.                          If one of the helps, draw the correct dialog, do
  890.                          it, deselect the exit button.
  891.                          Deselect the menu heading, return a 1.
  892. RETURNS     :              I       Equals zero if they quit, otherwise 1.
  893. PARAMETERS  :  menubar     *OBJECT Menubar of event.
  894.                wind        *WIND   Pointer to graphic window info structure.
  895.                wind2       *WIND     "     "  text     "       "      "
  896. VARIABLES   :  dialog      *OBJECT  Dialog to form
  897.                end         I        Quit status
  898.                opened      I        Flag for window open status.
  899. REQD. SUBPG.:  do_dialog
  900.                load_graphic
  901.                save_graphic
  902.                print_label
  903.                open_window
  904.                send_redraw
  905. NOTE        :  The only way it is possible for the wind_open to return -1
  906.                (ie. couldnt open window) to this subroutine is if the window
  907.                has never been opened (couldnt open in mainline) and no others
  908.                have been closed.  Otherwise window handle is preserved when 
  909.                the window is closed, so it can allways be re-opened.
  910. USAGE       :  handle_menu(menubar,wind);
  911. *******************************************************************************/
  912. handle_menu(menubar, wind, wind2)
  913.    OBJECT     *menubar;
  914.    struct WINDOW *wind, *wind2;
  915. {
  916.    OBJECT     *dialog;
  917.    int         end = 1;
  918.    int         opened;
  919.  
  920.    switch (msgbuff[4]) {
  921.    case ABOUTCLE:
  922.       rsrc_gaddr(0, ABOUTME, (OTYPE) &dialog);
  923.       do_dialog(dialog);
  924.       objc_change(dialog, ABEXIT, 0, 0, 0, 0, 0, 0, 0);
  925.       break;
  926.    case LOADGRA:
  927.       load_graphic(graf_dir);
  928.       send_redraw(wind);
  929.       break;
  930.    case SAVEGRA:
  931.       save_graphic(graf_dir);
  932.       break;
  933.    case PRINTLAB:
  934.       if (driver_loaded == 0)
  935.          form_alert(1, "[1][No printer driver| loaded][Cant Print]");
  936.       else
  937.          print_label();
  938.       break;
  939.    case LOADSET:
  940.       load_driver(prnt_dir);
  941.       break;
  942.    case WGRAPH:
  943.       opened = open_window(wind);
  944.       if (opened != 0)
  945.          form_alert(1, "[1][Couldnt open the window|try closing some others][OK]");
  946.       else
  947.          graphich = wind->handle;
  948.       break;
  949.    case WTEXT:
  950.       opened = open_window(wind2);
  951.       if (opened != 0)
  952.          form_alert(1, "[1][Couldnt open the window|try closing some others][OK]");
  953.       else
  954.          texth = wind2->handle;
  955.       break;
  956.    case HGENERAL:
  957.       rsrc_gaddr(0, GENHELP, (OTYPE) &dialog);
  958.       do_dialog(dialog);
  959.       objc_change(dialog, GNHELPOK, 0, 0, 0, 0, 0, 0, 0);
  960.       break;
  961.    case HTHISWIN:
  962.       if (wi_handle == graphich) {
  963.          rsrc_gaddr(0, GRAFHELP, (OTYPE) &dialog);
  964.          do_dialog(dialog);
  965.          objc_change(dialog, GRHELPOK, 0, 0, 0, 0, 0, 0, 0);
  966.       }
  967.       if (wi_handle == texth) {
  968.          rsrc_gaddr(0, TEXTHELP, (OTYPE) &dialog);
  969.          do_dialog(dialog);
  970.          objc_change(dialog, TXHELPOK, 0, 0, 0, 0, 0, 0, 0);
  971.       }
  972.       break;
  973.    case QUIT:
  974.       end = form_alert(2, "[2][Do you really |want to quit][YES|NO]") - 1;
  975.       break;
  976.    }
  977.    menu_tnormal(menubar, msgbuff[3], 1);
  978.    return (end);
  979. }
  980.  
  981.  
  982. /**************************************************************************
  983.                            MAIN PROGRAM LOOP    
  984. **************************************************************************/
  985. main()
  986. {
  987.    OBJECT     *menu;
  988.    int         repeat = 1;
  989.    struct WINDOW textw, graphw;
  990.    int         event, opened;
  991.    OBJECT     *dialog;
  992.  
  993.    /* STEP 1. */
  994.    gem_on();
  995.    graf_mouse(ARROW, 0x0L);
  996.    hidden = 0;
  997.    hide();
  998.    check_res();
  999.    init_path(graf_dir, "*.GRA");
  1000.    init_path(prnt_dir, "*.DRV");
  1001.    xsize = (gl_wchar - 1) * (gl_hchar / gl_wchar);
  1002.    ysize = gl_hchar - 2;
  1003.    load_rsrc();
  1004.    wdesk = work_out[0];
  1005.    hdesk = work_out[1];
  1006.  
  1007.    rsrc_gaddr(0, SCREEN, (OTYPE) &screen);
  1008.    toolbox = screen + TOOLS;
  1009.    wind_set(0, WF_NEWDESK, screen, 0, 0);
  1010.    form_dial(3, 0, 0, 0, 0, 0, 0, wdesk, hdesk);
  1011.    show();
  1012.  
  1013.    load_prn_drv();
  1014.  
  1015.    rsrc_gaddr(0, MENUBAR, (OTYPE) &menu);
  1016.    menu_bar(menu, 1);
  1017.    rsrc_gaddr(0, ABOUTME, (OTYPE) &dialog);
  1018.    ((TEDINFO *) dialog[ABVERS].ob_spec)->te_ptext = version;
  1019.    ((TEDINFO *) dialog[ABVERS].ob_spec)->te_txtlen = strlen(version);
  1020.    rsrc_gaddr(0, INTRO, (OTYPE) &dialog);
  1021.    ((TEDINFO *) dialog[INVERS].ob_spec)->te_ptext = version;
  1022.    ((TEDINFO *) dialog[INVERS].ob_spec)->te_txtlen = strlen(version);
  1023.    do_dialog(dialog);
  1024.  
  1025.    /* STEP 2. */
  1026.  
  1027.    hide();
  1028.    strcpy(graphw.title, "CLED - GRAPHICS");
  1029.    graphw.kind = WI_KIND;
  1030.    graphw.fullx = graphw.outx = 73;
  1031.    graphw.fully = graphw.outy = gl_hchar + 3;
  1032.    graphw.fullw = graphw.outw = (40 * xsize) + 3;
  1033.    graphw.fullh = graphw.outh = (24 * ysize) + gl_hbox + 3;
  1034.    graphw.open = -1;
  1035.    opened = open_window(&graphw);
  1036.    if (opened != 0)
  1037.       form_alert(1, "[1][Couldnt open the window|try closing some others][OK]");
  1038.    else
  1039.       graphich = graphw.handle;
  1040.    clear_graf(&graphw);
  1041.  
  1042.    strcpy(textw.title, "CLED - TEXT");
  1043.    textw.kind = WI_KIND;
  1044.    textw.fullx = textw.outx = 93;
  1045.    textw.fully = textw.outy = 2 * gl_hchar;
  1046.    textw.fullw = textw.outw = 47 * gl_wchar + 2;
  1047.    textw.fullh = textw.outh = 19 * gl_hchar + gl_hchar + 4;
  1048.    textw.open = -1;
  1049.  
  1050.    opened = open_window(&textw);
  1051.    if (opened != 0)
  1052.       form_alert(1, "[1][Couldnt open the window|try closing some others][OK]");
  1053.    else
  1054.       texth = wi_handle = textw.handle;
  1055.    clear_text(&textw);
  1056.    show();
  1057.  
  1058.    /* STEP 3. */
  1059.  
  1060.    while (repeat == 1) {
  1061. #ifdef ONE_LONG
  1062.       event = evnt_multi(MU_KEYBD | MU_MESAG | MU_BUTTON, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, msgbuff, 0L , &mx, &my, &ret, &ret, &keycode, &ret);
  1063. #endif
  1064. #ifdef TWO_INTS
  1065.       event = evnt_multi(MU_KEYBD | MU_MESAG | MU_BUTTON, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, msgbuff, 0, 0, &mx, &my, &ret, &ret, &keycode, &ret);
  1066. #endif
  1067.       wind_update(BEG_UPDATE);
  1068.       wind_get(handle, WF_TOP, &wi_handle, &ret, &ret, &ret);
  1069.       if (event & MU_MESAG) {
  1070.          switch (msgbuff[0]) {
  1071.          case MN_SELECTED:
  1072.             repeat = handle_menu(menu, &graphw, &textw);
  1073.             break;
  1074.          case WM_REDRAW:
  1075.             if (msgbuff[3] == graphw.handle)
  1076.                do_redraw(&textw, &graphw);
  1077.             if (msgbuff[3] == textw.handle)
  1078.                do_redraw(&textw, &graphw);
  1079.             break;
  1080.          case WM_TOPPED:
  1081.             wind_set(msgbuff[3], WF_TOP);
  1082.             wi_handle = msgbuff[3];
  1083.             break;
  1084.          case WM_CLOSED:
  1085.             if (msgbuff[3] == graphw.handle) {
  1086.                wind_close(graphw.handle);
  1087.                graphw.open = 0;
  1088.             }
  1089.             if (msgbuff[3] == textw.handle) {
  1090.                wind_close(textw.handle);
  1091.                textw.open = 0;
  1092.             }
  1093.             break;
  1094.          }
  1095.       }
  1096.       wind_get(handle, WF_TOP, &wi_handle, &ret, &ret, &ret);
  1097.       if (repeat != 0) {
  1098.          if ((wi_handle == graphw.handle) && (graphw.open != 0))
  1099.             graphic(&graphw, event);
  1100.          if ((wi_handle == textw.handle) && (textw.open != 0))
  1101.             text(&textw, event);
  1102.       }
  1103.       wind_update(END_UPDATE);
  1104.    }
  1105.  
  1106.    /* STEP 4. */
  1107.  
  1108.    if (graphw.open == 1)
  1109.       wind_close(graphw.handle);
  1110.    wind_delete(graphw.handle);
  1111.    if (textw.open == 1)
  1112.       wind_close(textw.handle);
  1113.    wind_delete(textw.handle);
  1114.    rsrc_free();
  1115.    gem_off();
  1116. }
  1117.