/**************************************************************************** PROGRAM : CLED VERSION : 1.22 AUTHOR : ROBERT ALLEY DATE : 27/04/91 LOT 1590 GAY STREET SOUTHERN RIVER WESTERN AUSTRALIA 6110 PH (09)490-1105 DESCRIPTION : Print cassette box inserts. LOGIC USED : STEP 1. Initialise application, set up some variables, turn on the mouse and display intoduction dialog. Get system sizes. Get the address of the tree to use as our new background, install the background, send a redraw for the whole screen, display menu bar. STEP 2. Set the various window structure parameters and open the text and graphic windows. STEP 3. Repeat until 0 is returned from handle_menu (ie. user selects quit). Wait for an event. If we get a message handle it. Get the handle of the top window. If they havent quit pass event on to the routine which owns the top window. STEP 4. Close and delete both the windows, free resource memory, turn off gem and end. PARAMETERS : None. VARIABLES : repeat I Flag for repeating main loop or not. menu OBJ* Pointer to menu bar object dialog OBJ* Pointer to dialog boxes, (intro etc.) textw WIND Text window info structure graphw WIND Graphic window info structure event I Event returned by event_multi opened I Flag for window opening status REQD. FILES : CLED.RSC - Resource file data. Optional graphic file to load. REQD. SUBPG.: check_res(); - Check the resolution being used clear_text(); - Clear the text window and storage do_redraw(); - Pass out redraw requests do_dialog(); - Draw and handle dialogs handle_menu() - Handle pull down menu events gem_off(); - Turn off GEM gem_on(); - Turn on GEM graphic(); - Handle the graphic window events hide(); - Hide the mouse pointer init_path(); - Initialise the load paths load_rsrc(); - Load the resource file open_window(); - Open a window show(); - Show the mouse pointer text(); - Handle the text window NOTES : (REVISION HISTORY) Now split into three sections: the main program (this file) the files section (files.c) and gem section (gem.c) Compile with : cc -VGEM cled.c files.o gem.o ??/??/89 Menu bar added. ??/??/89 Dialogs fixed (they now get removed) ??/11/89 Now works in medium and High res. 2/12/89 Proper GEM interface started. 9/12/89 Split into four sections, printer section (printer.c) added. Compile with : cc -VGEM cled.c files.o gem.o printer.o 11/12/89 Help dialogs added and mouse bugs fixed. 12/12/89 Spine label bug fixed (Middle char was assigned /0), cursor fixed so that it no longer gets left behind. Graphics update now uses a lookup table for the powers of two instead of calculating them on the fly (should be faster) 04/01/90 Initial window positions changed slightly for HIRES 09/02/90 Text update now only redraws lines that need it, graphic window position moved down slightly. Directory to search when loading and saving now calculated. (ie. uses default drive) 03/03/90 Graphic plotting now uses power look up table. Data array (Holds graphic data) changed from integers to characters. 05/03/90 Windows can now be closed. Can open or top windows from the menu bar. 09/03/90 1.1 Graphic design may now be rolled left,right,up and down using the 4,6,8 and 2 keys repectively. (Temp. user interface). Send_redraw subroutine added. Data array changed to unsigned characters. Using character array had problems, ie. 128 became -128, why I dont know. Invert function added for graphics window. Scroll functions etc. placed inside else to fix slight bug that appeared when they were added. 23/03/90 1.11 Scroll functions moved to cursor keys, insert key for invert, m to mirror graphic left to right. 26/03/90 1.111 Scroll functions etc. moved to GEM.C Checks added when windows are opened (Warns user if window couldnt be opened.) Quit logic for handle_menu slightly improved. Printer status now checked before printing. 28/03/90 1.111a GEM.C modified: gem_off was fixed (Missing paranthesis after appl_exit call). No more problems with desk accessories!!!! 31/05/90 Resource file changed, was causing GEMINI 1.1 to say "The Program Damaged Gemini". Date forgotten. ??/06/90 1.2 Added side labels at top of graphic, modified do_redraw. Changed actions on TAB so that it only goes to a new line if the cursor is in the right hand half allreadu. 02/07/90 Background (Including toolbox) now drawn from resource file. Graphics tools now use icons from the toolbox. Fixed a bug in the mirror routine that swapped columns 19 & 20 twice. Moved windows to uncover toolbox. Modified help dialog to reflect changes. 10/07/90 Changed mainline so that it gets the top window handle before passing control to the graphics or test subprograms. Subprograms only called if their window is open. Changed logic within graphic subprogram. 1.21 Started code to allow toolbox to be moved, again, after major harddrive crash on the 25 (Yep Christmas day!) 28/12/90 (Should move this into main program loop instead of graphics window handler) 1.22 Started porting to the GNU compiler, what a hassle, but I 27/04/91 discovered some lovely little bloopers in my code! THANKS : To the many (I mean many!) people who helped me get to grips with the intricacies of GEM AES, especially Jim Charlton for his excellent XXED source code which helped clear up many points. And Tim Oren for the Pro Gem series of articles. Also all those on Paragon BBS who answered my many questions. And to Mark Williams Corp. and the Free Software Foundation (GNU) for their excellent compilers. ****************************************************************************/ /* INCLUDE FILES */ #include "define.h" #include #include #include #include #include #include #include #include "cled.h" #include "window.h" #include "rpcfg.h" /* DEFINES */ /* window constants */ #define WI_KIND (FULLER|CLOSER|NAME|MOVER) #define XPOS wind->inx+(wind->curx*gl_wchar)+(gl_wchar/2) #define YPOS wind->iny+( (wind->cury+3)*gl_hchar)+(gl_hchar/2) #define CPOS wind->inx+(column*gl_wchar)+(gl_wchar/2) #define RPOS wind->iny+( (row+3)*gl_hchar)+(gl_hchar/2) /* draw conditions */ #define IN_RANGE (mx>wind->inx) && (my>wind->iny) && (x>=0) && (x<=39) && (y>=0) && (y<=23) #define BUT_PRESSED ((button==1)||(button==2)) #define RETURN 13 #define TAB 9 #define HELP 25088 #define UNDO 24832 #define INS 20992 #define CLR 18176 #define UP 18432 #define LEFT 19200 #define DOWN 20480 #define RIGHT 19712 #define BS 8 #define DEL 127 #define ESC 27 /* GLOBAL VARIABLES */ char version[] = "1.22"; /* Current version number */ int gl_apid; /* Application ID # */ int gl_hchar, gl_wchar; int gl_wbox, gl_hbox; /* system sizes */ int phys_handle; /* physical workstation handle */ int handle; /* virtual workstation handle */ int wi_handle; /* window handle */ int graphich, texth; /* Graphic and text window handles */ int xdesk, ydesk, hdesk, wdesk; /* Co-ords and sizes of desktop */ int xsize, ysize; /* X and Y sizes of blocks in graphic */ int msgbuff[8]; /* event message buffer */ int keycode; /* code returned by event-keyboard */ int mx, my; /* mouse x and y pos. */ int button; /* button pressed */ int butdown; /* button state tested for, UP/DOWN */ int ret; /* dummy return variable */ int contrl[12], intin[128]; int ptsin[128], intout[128]; int ptsout[128]; /* GEM arrays */ int work_in[11], work_out[57]; /* In/Out to/from GSX param. array */ int pxyarray[10]; /* input point array */ unsigned char data[3][40]; /* storage for graphic data */ char songs[16][47]; /* storage for songs & labels */ unsigned short int power[] = {128, 64, 32, 16, 8, 4, 2, 1}; /* Lookup table for powers of two */ int hidden; /* Mouse hidden flag */ OBJECT *screen; /* Pointer to new background object */ OBJECT *toolbox; /* Pointer to toolbox object */ char graf_dir[128]; char prnt_dir[128]; struct COMMAND print_codes[11]; /* Array to hold printer commands */ int driver_loaded = 0; /* Did we load a driver, 0=No */ char print_name[80]; /* Printers name */ int coloura, quality; /* Have we got colour, nlq? 0=No */ /**************************************************************************** SUBROUTINE : p_text VERSION : 1.1 AUTHOR : ROBERT ALLEY DATE : 9/12/89 DESCRIPTION : Print text characters on the terminal. LOGIC USED : STEP 1. Assign character to string, display string, add character to songs. If not at end of line inc. current x position. PARAMETERS : wind *WIND Window info structure. ch I Character to print VARIABLES : prin 2CH String to print. REQD. SUBPG.: hide() show() USAGE : p_text( &column, &row, character); ****************************************************************************/ p_text(wind, ch) struct WINDOW *wind; int ch; { char prin[2]; prin[0] = ch; prin[1] = 0; hide(); v_gtext(handle, XPOS, YPOS, prin); show(); songs[wind->cury][wind->curx] = ch; if (wind->curx < 45) wind->curx += 1; if ((wind->curx == 22) && (wind->cury < 13)) wind->curx += 1; } /**************************************************************************** SUBROUTINE : move VERSION : 1.0 AUTHOR : ROBERT ALLEY DATE : 2/12/89 DESCRIPTION : Move a window within the desktop LOGIC USED : STEP 1. Call AES routine to move window, get the new interior co-ordinates. PARAMETERS : wind *WIND Window info structure. x *I X co-ord to move to y *I Y " " w *I Width h *I Height USAGE : move(wind,&x,&y,&w,&h); ****************************************************************************/ move(wind, x, y, w, h) struct WINDOW *wind; int *x, *y, *w, *h; { wind_set(wind->handle, WF_CURRXYWH, *x, *y, *w, *h); wind_get(wind->handle, WF_WORKXYWH, &wind->inx, &wind->iny, &wind->inw, &wind->inh); } /**************************************************************************** SUBROUTINE : p_contrl VERSION : 1.01 AUTHOR : ROBERT ALLEY DATE : 4/1/90 DESCRIPTION : Handle control characters in text window. LOGIC USED : STEP 1. Assign current character to string, set begin point to current x position. Based on ASCII chars carry out action, otherwise handle others (ie. HELP etc.) PARAMETERS : wind *WIND Window info structure. ch I ASCII Code of character code I Code of character as returned by event. VARIABLES : begn I end I print 2 CH String to print. REQD. SUBPG.: hide() show() USAGE : p_contrl( &column, &row, character, code); ****************************************************************************/ p_contrl(wind, ch, code) struct WINDOW *wind; int ch; int code; { int begn, end; char prin[2]; prin[0] = songs[wind->cury][wind->curx]; prin[1] = 0; begn = wind->curx; hide(); switch (ch) { case RETURN: if (wind->cury < 15) { v_gtext(handle, XPOS, YPOS, prin); wind->curx = 0; wind->cury = wind->cury + 1; if (wind->cury == 13) wind->cury = 14; } break; case TAB: if (wind->cury < 15) { v_gtext(handle, XPOS, YPOS, prin); wind->curx = 23; if (begn > 22) { wind->cury = wind->cury + 1; if (wind->cury == 13) wind->cury = 14; if (wind->cury > 13) wind->curx = 0; } } break; case BS: if (wind->curx == 0) break; if ((wind->curx == 23) && (wind->cury < 13)) break; begn = wind->curx - 1; case DEL: if ((wind->curx < 22) && (wind->cury < 13)) end = 21; else end = 45; for (wind->curx = begn; wind->curx < end; (wind->curx)++) { songs[wind->cury][wind->curx] = songs[wind->cury][(wind->curx) + 1]; prin[0] = songs[wind->cury][wind->curx]; v_gtext(handle, XPOS, YPOS, prin); } songs[wind->cury][end] = 32; wind->curx = end; prin[0] = songs[wind->cury][wind->curx]; v_gtext(handle, XPOS, YPOS, prin); wind->curx = begn; break; } switch (code) { case HELP: v_gtext(handle, XPOS, YPOS, prin); wind->curx = 0; wind->cury = 0; break; case UNDO: v_gtext(handle, XPOS, YPOS, prin); wind->curx = 23; wind->cury = 0; break; case INS: if ((wind->curx < 22) && (wind->cury < 13)) end = 21; else end = 45; for (wind->curx = end; wind->curx > begn; (wind->curx)--) { songs[wind->cury][wind->curx] = songs[wind->cury][(wind->curx) - 1]; prin[0] = songs[wind->cury][wind->curx]; v_gtext(handle, XPOS, YPOS, prin); } wind->curx = begn; songs[wind->cury][wind->curx] = 32; break; case CLR: clear_text(wind); break; case UP: if (wind->cury > 0) { v_gtext(handle, XPOS, YPOS, prin); wind->cury = wind->cury - 1; if (wind->cury == 13) { wind->cury = 12; if (wind->curx == 22) wind->curx = 23; } } break; case LEFT: if (wind->curx > 0) { v_gtext(handle, XPOS, YPOS, prin); wind->curx = wind->curx - 1; if ((wind->curx == 22) && (wind->cury < 14)) wind->curx = 21; } break; case DOWN: if (wind->cury < 15) { v_gtext(handle, XPOS, YPOS, prin); wind->cury = wind->cury + 1; if (wind->cury == 13) wind->cury = 14; } break; case RIGHT: if (wind->curx < 45) { v_gtext(handle, XPOS, YPOS, prin); wind->curx = wind->curx + 1; if ((wind->curx == 22) && (wind->cury < 14)) wind->curx = 23; } break; } show(); } /**************************************************************************** SUBROUTINE : clear_text VERSION : 1.11 AUTHOR : ROBERT ALLEY DATE : 4/1/90 DESCRIPTION : Clear and initialise text window. LOGIC USED : STEP 1. Loop thru all chars in title list, make them spaces, except the end ones which are zero's (to enable titles to be printed as strings). Clear the window, draw the label, reset current x and y positions to zero, display cursor. PARAMETERS : wind *WIND Window info structure. VARIABLES : loop I Loop counter. outloop I " " REQD. SUBPG.: clear_window() d_label() hide() show() USAGE : clear_text( wind ); ****************************************************************************/ clear_text(wind) struct WINDOW *wind; { int loop, outloop; for (outloop = 0; outloop < 16; outloop++) for (loop = 0; loop < 47; loop++) { if (((loop == 22) && (outloop < 14)) || (loop == 46)) songs[outloop][loop] = 0; else songs[outloop][loop] = 32; } clear_window(wind); d_label(wind); wind->curx = 0; wind->cury = 0; hide(); v_gtext(handle, XPOS, YPOS, "_"); show(); } /******************************************************************************* SUBROUTINE : gupdate VERSION : 1.1 AUTHOR : ROBERT ALLEY DATE : 3/3/90 DESCRIPTION : Update the graphics window. LOGIC USED : STEP 1. Calculate the start and end block numbers for x and y (NOTE: +1 at end to ensure a loop occurs when the start and end are equal). STEP 2. Clear the window, loop from 0 to min(24,yend), loop from 0 to min(40,xend). Check each bit to see if it is set. If it is plot the point. PARAMETERS : wind *WIND Window info structure. x1,y1,x2,y2 I T/L & B/R co-ords of update. VARIABLES : loop,outloopI Loop counters val I Bit value to test for set I Byte and val temp 4 I Holds co-ords to plot xstart,xend I X start and end boxes ystart,yend I Y start and end points. REQD. SUBPG.: clear_window() hide() show() USAGE : gupdate(wind,x1,y1,x2,y2); *******************************************************************************/ gupdate(wind, x1, y1, x2, y2) struct WINDOW *wind; int x1, y1, x2, y2; { register short int loop, outloop; register int temp[4]; int xstart, xend; int ystart, yend; /* STEP 1. */ xstart = (x1 - wind->inx) / xsize; xend = (x2 - wind->inx) / xsize + 1; ystart = (y1 - wind->iny) / ysize; yend = (y2 - wind->iny) / ysize + 1; yend = ((yend > 24) ? 24 : yend); xend = ((xend > 40) ? 40 : xend); /* STEP 2. */ clear_window(wind); hide(); vsf_interior(handle, 2); vsf_style(handle, 8); vsf_color(handle, 1); for (outloop = ystart; outloop < yend; outloop++) { for (loop = xstart; loop < xend; loop++) { if (data[outloop / 8][loop] & power[(outloop % 8)]) { temp[0] = wind->inx + (loop * xsize) + 1; temp[1] = wind->iny + (outloop * ysize) + 1; temp[2] = temp[0] + (xsize - 2); temp[3] = temp[1] + (ysize - 2); v_bar(handle, temp); } } } show(); } /******************************************************************************* SUBROUTINE : tupdate VERSION : 1.1 AUTHOR : ROBERT ALLEY DATE : 3/3/90 DESCRIPTION : Update the text window. LOGIC USED : STEP 1. Clear the window, draw the label, loop thru all the rows, if row 13 (line between titles and spine) skip. Print string beginning at this row. If were doing titles print string starting at position 23. End of loop. Display cursor. PARAMETERS : wind *WIND Window info structure. x1,y1,x2,y2 I T/L & B/R co-ords of update area. VARIABLES : row,column I Row and column co-ords of string start. REQD. SUBPG.: clear_window() do_window() hide() show() NOTES : The use of v_gtext requires null terminated string, hence zero's put in columns 22 and 46 by clear_text. USAGE : tupdate(wind,x1,y1,x2,y2); *******************************************************************************/ tupdate(wind, x1, y1, x2, y2) struct WINDOW *wind; int x1, y1, x2, y2; { register int row, column; int rstart, rend, cstart, cend; cstart = (x1 - wind->inx) / gl_wchar - 1; cend = (x2 - wind->inx) / gl_wchar + 1; rstart = (y1 - wind->iny) / gl_hchar - 3; rend = (y2 - wind->iny) / gl_hchar - 1; rstart = (rstart < 0) ? 0 : rstart; rend = (rend > 16) ? 16 : rend; cstart = (cstart < 0) ? 0 : cstart; clear_window(wind); d_label(wind); hide(); for (row = rstart; row < rend; row++) { if (row == 13) continue; if ((row > 13) || (cstart < 22)) { column = cstart; v_gtext(handle, CPOS, RPOS, &songs[row][column]); } if ((row < 13) && (cend > 22)) { column = 23; v_gtext(handle, CPOS, RPOS, &songs[row][column]); } } v_gtext(handle, XPOS, YPOS, "_"); show(); } /******************************************************************************* SUBROUTINE : do_redraw VERSION : 1.11 AUTHOR : ROBERT ALLEY DATE : 27/04/91 DESCRIPTION : handle redraw requests. LOGIC USED : STEP 1. Get handle of window to update, co-ords of update area. Get the first rectangle to redraw. While width and height not both zero : if the rectangles intersect, set clipping to dirty recatngle, call appriopriate update routine. PARAMETERS : twind *WIND Text window info structure. gwind *WIND Graphic window info structure VARIABLES : window I Handle of dirty window rect 4 I Total area that needs update. redraw 4 I Dirty rectangle to redraw REQD. SUBPG.: gupdate tupdate NOTES : Assumes it is passed the window structure (either twind or gwind) of the window with handle equal to msgbuff[3] USAGE : do_redraw(twindow,gwindow); *******************************************************************************/ do_redraw(twind, gwind) struct WINDOW *twind, *gwind; { int window; #ifdef NO_GRECT int redraw[4],rect[4]; window = msgbuff[3]; rect[0] = msgbuff[4]; rect[1] = msgbuff[5]; rect[2] = msgbuff[6]; rect[3] = msgbuff[7]; wind_get(window, WF_FIRSTXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]); while (redraw[2] && redraw[3]) { if (rc_intersect(rect, redraw)) { redraw[2] = redraw[0] + redraw[2] - 1; redraw[3] = redraw[1] + redraw[3] - 1; vs_clip(handle, 1, redraw); if (window == graphich) gupdate(gwind, redraw[0], redraw[1], redraw[2], redraw[3]); if (window == texth) tupdate(twind, redraw[0], redraw[1], redraw[2], redraw[3]); } wind_get(window, WF_NEXTXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]); } wind_get(0, WF_WORKXYWH, &redraw[0], &redraw[1], &redraw[2], &redraw[3]); redraw[2] = redraw[0] + redraw[2] - 1; redraw[3] = redraw[1] + redraw[3] - 1; vs_clip(handle, 1, redraw); } #else GRECT redraw, rect; int clipped[4]; window = msgbuff[3]; rect.g_x = msgbuff[4]; rect.g_y = msgbuff[5]; rect.g_w = msgbuff[6]; rect.g_h = msgbuff[7]; wind_get(window, WF_FIRSTXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h); while (redraw.g_w && redraw.g_h) { if (rc_intersect(&rect, &redraw)) { clipped[0] = redraw.g_x; clipped[1] = redraw.g_y; clipped[2] = redraw.g_x + redraw.g_w - 1; clipped[3] = redraw.g_y + redraw.g_h - 1; vs_clip(handle, 1, clipped); if (window == graphich) gupdate(gwind, clipped[0], clipped[1], clipped[2], clipped[3]); if (window == texth) tupdate(twind, clipped[0], clipped[1], clipped[2], clipped[3]); } wind_get(window, WF_NEXTXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h); } wind_get(0, WF_WORKXYWH, &redraw.g_x, &redraw.g_y, &redraw.g_w, &redraw.g_h); clipped[0] = redraw.g_x; clipped[1] = redraw.g_y; clipped[2] = redraw.g_x+ redraw.g_w - 1; clipped[3] = redraw.g_y + redraw.g_h - 1; vs_clip(handle, 1, clipped); } #endif /**************************************************************************** SUBROUTINE : d_label VERSION : 1.02 AUTHOR : ROBERT ALLEY DATE : 3/3/90 DESCRIPTION : Draw the label outline in the text window and init song titles. LOGIC USED : STEP 1. Calc the begin and end points of each of the lines and draw them. Calc the co-ords of the side headings and print them. PARAMETERS : wind *WIND Pointer to window info structure. VARIABLES : coords I4 Array of coordinates for lines. x,y I X and Y co-ords of side headings. REQD> SUBPG.: hide() show() USAGE : d_label(); ****************************************************************************/ d_label(wind) struct WINDOW *wind; { int coords[4]; int x, y; hide(); coords[0] = wind->inx; coords[1] = wind->iny + (2 * gl_hchar); coords[2] = wind->inx + wind->inw - 1; coords[3] = wind->iny + (2 * gl_hchar); v_pline(handle, 2, coords); coords[1] = wind->iny + (16 * gl_hchar); coords[3] = wind->iny + (16 * gl_hchar); v_pline(handle, 2, coords); coords[0] = wind->inx + (23 * gl_wchar); coords[1] = wind->iny + (2 * gl_hchar); coords[2] = wind->inx + (23 * gl_wchar); v_pline(handle, 2, coords); x = ((wind->inw / 2) - (6 * gl_wchar)) / 2 + wind->inx; y = wind->iny + 1.25 * gl_hchar; v_gtext(handle, x, y, "SIDE 1"); x = x + (wind->inw / 2); v_gtext(handle, x, y, "SIDE 2"); show(); } /**************************************************************************** SUBROUTINE : text VERSION : 1.1 AUTHOR : ROBERT ALLEY DATE : 9/12/89 DESCRIPTION : Handle events within text window. LOGIC USED : STEP 1. Get the top window. Set window update flag. If event was a message handle it. STEP 2. If event was a key and we are the top window, convert key to ASCII, if printable call print procedure otherwise call procedure to handle control characters. Clear updarte flag. PARAMETERS : wind *WIND Pointer to window info structure. event I AES event that occured VARIABLES : key I ASCII code of key pressed REQD. SUBPG.: clear_text hide move p_text p_control show USAGE : text(wind,event); ****************************************************************************/ text(wind, event) struct WINDOW *wind; int event; { int key; if (event & MU_MESAG) { switch (msgbuff[0]) { case WM_FULLED: clear_text(wind); break; case WM_MOVED: move(wind, &msgbuff[4], &msgbuff[5], &msgbuff[6], &msgbuff[7]); break; } } if ((event & MU_KEYBD) && (wi_handle == wind->handle)) { key = toascii(keycode); if (isprint(key) != 0) { p_text(wind, key); hide(); v_gtext(handle, XPOS, YPOS, "_"); show(); } else if (iscntrl(key) != 0) { p_contrl(wind, key, keycode); hide(); v_gtext(handle, XPOS, YPOS, "_"); show(); } } } /**************************************************************************** SUBROUTINE : clear_graf VERSION : 1.01 AUTHOR : ROBERT ALLEY DATE : 2/12/89 DESCRIPTION : Clear the graphics window and data. LOGIC USED : STEP 1. Clear window, loop thru all bytes, set to 0. PARAMETERS : wind *WIND Window info structure. VARIABLES : loop,outloop I Loop counters REQD. SUBPG.: clear_window() USAGE : clear_graf(wind); ****************************************************************************/ clear_graf(wind) struct WINDOW *wind; { int outloop, loop; clear_window(wind); for (outloop = 0; outloop < 3; outloop++) { for (loop = 0; loop < 40; loop++) { data[outloop][loop] = 0; } } } /**************************************************************************** SUBROUTINE : graphic VERSION : 1.31 AUTHOR : ROBERT ALLEY DATE : 28/12/90 DESCRIPTION : Handle events that occur in graphics window. LOGIC USED : STEP 1. Get top window handle, set update flag, get mouse state, calculate box co-ordinates, row and column number. If a message is sent do it. STEP 2. If the graphics window is the top window If mouse is within the window print co-ordinates to position string. If a mouse button is pressed : move co-ords into temp, plot box. Calculate bit/byte for box, add or remove from data set. STEP 3. Else (out side window) print zeros to position string If button pressed : check if a tool is selected, if it is call appropriate subroutine. If user clicked on toolbox title, draw a dragable box, redraw old toobox area and new area by telling GEM there was a dialog there. print position string. PARAMETERS : wind *WIND Pointer to window info structure. VARIABLES : row I Current row position column I Current column position temp I4 Co-ords of box to plot position C8 String to hold position info loop I block I Byte of data being accessed bit I Bit " val I Value of byte disk I Return from alerts for load/save event I AES event returned by event_multi REQD. SUBPG.: move clear_graf plot (In gem.c, gem.o) scrollv scrollh USAGE : graphic(wind,event); ****************************************************************************/ graphic(wind, event) struct WINDOW *wind; int event; { int row, column; int x, y; int temp[4]; char position[8]; int block, tool; int oldx, oldy; int nx,ny; /* STEP 1. */ vq_mouse(handle, &button, &mx, &my); row = (((my - wind->iny) / ysize) * ysize) + 1; column = (((mx - wind->inx) / xsize) * xsize) + 1; x = (mx - wind->inx) / xsize; y = (my - wind->iny) / ysize; if (event & MU_MESAG) { switch (msgbuff[0]) { case WM_FULLED: clear_graf(wind); break; case WM_MOVED: move(wind, &msgbuff[4], &msgbuff[5], &msgbuff[6], &msgbuff[7]); break; } } /* STEP 2. */ if (wi_handle == wind->handle) { if (IN_RANGE) { sprintf(position, "%*d,%*d", 2, x, 2, y); if (BUT_PRESSED) { temp[0] = wind->inx + column; temp[1] = wind->iny + row; temp[2] = wind->inx + column + xsize - 2; temp[3] = wind->iny + row + ysize - 2; plot(button, temp); block = y / 8; if (button == 1) data[block][x] = data[block][x] | power[y % 8]; if (button == 2) data[block][x] = data[block][x] & (255 - power[y % 8]); } } /* STEP 3. */ else { sprintf(position, "%*d,%*d", 2, 0, 2, 0); if (button == 1) { tool = objc_find(screen, 0, 10, mx, my); if (tool == SDOWN) scrollv(wind, 1); else if (tool == SUP) scrollv(wind, 2); else if (tool == SRIGHT) scrollh(wind, 1); else if (tool == SLEFT) scrollh(wind, 2); else if (tool == MIRROR) mirror(wind); else if (tool == INVERT) { for (x = 0; x < 3; x++) for (y = 0; y < 40; y++) data[x][y] = 255 - data[x][y]; send_redraw(wind); } else if (tool == TTITLE) { oldx = toolbox->ob_x - 1; oldy = toolbox->ob_y - 1; graf_dragbox(toolbox->ob_width, toolbox->ob_height, toolbox->ob_x, toolbox->ob_y, 0, 0, wdesk, hdesk, &nx, &ny); toolbox->ob_x=(short)nx; toolbox->ob_y=(short)ny; form_dial(3, 0, 0, 0, 0, oldx, oldy, toolbox->ob_width + 2, toolbox->ob_height + 2); form_dial(3, 0, 0, 0, 0, toolbox->ob_x - 1, toolbox->ob_y - 1, toolbox->ob_width + 2, toolbox->ob_height + 2); } } } v_gtext(handle, (wind->inx + gl_wbox + 1), (wind->iny - 4), position); } } /******************************************************************************* SUBROUTINE : handle_menu VERSION : 1.023 AUTHOR : ROBERT ALLEY DATE : 27/04/91 DESCRIPTION : Handle events concerning the menu bar. LOGIC USED : STEP 1. If selection was ABOUTCLED, get address of ABOUT dilaog, do it. If LOADGRAPHIC, load it, send redraw for graphic window. If SAVEGRAPHIC, save it. If QUIT, check thety really want to, if they do return a zero to end program. If PRINT, print the label. If one of the window commands, call wind_open with appropriate window structure. If one of the helps, draw the correct dialog, do it, deselect the exit button. Deselect the menu heading, return a 1. RETURNS : I Equals zero if they quit, otherwise 1. PARAMETERS : menubar *OBJECT Menubar of event. wind *WIND Pointer to graphic window info structure. wind2 *WIND " " text " " " VARIABLES : dialog *OBJECT Dialog to form end I Quit status opened I Flag for window open status. REQD. SUBPG.: do_dialog load_graphic save_graphic print_label open_window send_redraw NOTE : The only way it is possible for the wind_open to return -1 (ie. couldnt open window) to this subroutine is if the window has never been opened (couldnt open in mainline) and no others have been closed. Otherwise window handle is preserved when the window is closed, so it can allways be re-opened. USAGE : handle_menu(menubar,wind); *******************************************************************************/ handle_menu(menubar, wind, wind2) OBJECT *menubar; struct WINDOW *wind, *wind2; { OBJECT *dialog; int end = 1; int opened; switch (msgbuff[4]) { case ABOUTCLE: rsrc_gaddr(0, ABOUTME, (OTYPE) &dialog); do_dialog(dialog); objc_change(dialog, ABEXIT, 0, 0, 0, 0, 0, 0, 0); break; case LOADGRA: load_graphic(graf_dir); send_redraw(wind); break; case SAVEGRA: save_graphic(graf_dir); break; case PRINTLAB: if (driver_loaded == 0) form_alert(1, "[1][No printer driver| loaded][Cant Print]"); else print_label(); break; case LOADSET: load_driver(prnt_dir); break; case WGRAPH: opened = open_window(wind); if (opened != 0) form_alert(1, "[1][Couldnt open the window|try closing some others][OK]"); else graphich = wind->handle; break; case WTEXT: opened = open_window(wind2); if (opened != 0) form_alert(1, "[1][Couldnt open the window|try closing some others][OK]"); else texth = wind2->handle; break; case HGENERAL: rsrc_gaddr(0, GENHELP, (OTYPE) &dialog); do_dialog(dialog); objc_change(dialog, GNHELPOK, 0, 0, 0, 0, 0, 0, 0); break; case HTHISWIN: if (wi_handle == graphich) { rsrc_gaddr(0, GRAFHELP, (OTYPE) &dialog); do_dialog(dialog); objc_change(dialog, GRHELPOK, 0, 0, 0, 0, 0, 0, 0); } if (wi_handle == texth) { rsrc_gaddr(0, TEXTHELP, (OTYPE) &dialog); do_dialog(dialog); objc_change(dialog, TXHELPOK, 0, 0, 0, 0, 0, 0, 0); } break; case QUIT: end = form_alert(2, "[2][Do you really |want to quit][YES|NO]") - 1; break; } menu_tnormal(menubar, msgbuff[3], 1); return (end); } /************************************************************************** MAIN PROGRAM LOOP **************************************************************************/ main() { OBJECT *menu; int repeat = 1; struct WINDOW textw, graphw; int event, opened; OBJECT *dialog; /* STEP 1. */ gem_on(); graf_mouse(ARROW, 0x0L); hidden = 0; hide(); check_res(); init_path(graf_dir, "*.GRA"); init_path(prnt_dir, "*.DRV"); xsize = (gl_wchar - 1) * (gl_hchar / gl_wchar); ysize = gl_hchar - 2; load_rsrc(); wdesk = work_out[0]; hdesk = work_out[1]; rsrc_gaddr(0, SCREEN, (OTYPE) &screen); toolbox = screen + TOOLS; wind_set(0, WF_NEWDESK, screen, 0, 0); form_dial(3, 0, 0, 0, 0, 0, 0, wdesk, hdesk); show(); load_prn_drv(); rsrc_gaddr(0, MENUBAR, (OTYPE) &menu); menu_bar(menu, 1); rsrc_gaddr(0, ABOUTME, (OTYPE) &dialog); ((TEDINFO *) dialog[ABVERS].ob_spec)->te_ptext = version; ((TEDINFO *) dialog[ABVERS].ob_spec)->te_txtlen = strlen(version); rsrc_gaddr(0, INTRO, (OTYPE) &dialog); ((TEDINFO *) dialog[INVERS].ob_spec)->te_ptext = version; ((TEDINFO *) dialog[INVERS].ob_spec)->te_txtlen = strlen(version); do_dialog(dialog); /* STEP 2. */ hide(); strcpy(graphw.title, "CLED - GRAPHICS"); graphw.kind = WI_KIND; graphw.fullx = graphw.outx = 73; graphw.fully = graphw.outy = gl_hchar + 3; graphw.fullw = graphw.outw = (40 * xsize) + 3; graphw.fullh = graphw.outh = (24 * ysize) + gl_hbox + 3; graphw.open = -1; opened = open_window(&graphw); if (opened != 0) form_alert(1, "[1][Couldnt open the window|try closing some others][OK]"); else graphich = graphw.handle; clear_graf(&graphw); strcpy(textw.title, "CLED - TEXT"); textw.kind = WI_KIND; textw.fullx = textw.outx = 93; textw.fully = textw.outy = 2 * gl_hchar; textw.fullw = textw.outw = 47 * gl_wchar + 2; textw.fullh = textw.outh = 19 * gl_hchar + gl_hchar + 4; textw.open = -1; opened = open_window(&textw); if (opened != 0) form_alert(1, "[1][Couldnt open the window|try closing some others][OK]"); else texth = wi_handle = textw.handle; clear_text(&textw); show(); /* STEP 3. */ while (repeat == 1) { #ifdef ONE_LONG 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); #endif #ifdef TWO_INTS 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); #endif wind_update(BEG_UPDATE); wind_get(handle, WF_TOP, &wi_handle, &ret, &ret, &ret); if (event & MU_MESAG) { switch (msgbuff[0]) { case MN_SELECTED: repeat = handle_menu(menu, &graphw, &textw); break; case WM_REDRAW: if (msgbuff[3] == graphw.handle) do_redraw(&textw, &graphw); if (msgbuff[3] == textw.handle) do_redraw(&textw, &graphw); break; case WM_TOPPED: wind_set(msgbuff[3], WF_TOP); wi_handle = msgbuff[3]; break; case WM_CLOSED: if (msgbuff[3] == graphw.handle) { wind_close(graphw.handle); graphw.open = 0; } if (msgbuff[3] == textw.handle) { wind_close(textw.handle); textw.open = 0; } break; } } wind_get(handle, WF_TOP, &wi_handle, &ret, &ret, &ret); if (repeat != 0) { if ((wi_handle == graphw.handle) && (graphw.open != 0)) graphic(&graphw, event); if ((wi_handle == textw.handle) && (textw.open != 0)) text(&textw, event); } wind_update(END_UPDATE); } /* STEP 4. */ if (graphw.open == 1) wind_close(graphw.handle); wind_delete(graphw.handle); if (textw.open == 1) wind_close(textw.handle); wind_delete(textw.handle); rsrc_free(); gem_off(); }