home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * GENERATR.C | The Degas Elite Image Toolkit | December 9, 1988 *
- * ------------------------------------------------------------- *
- * Programmed by Robert M. Birmingham and Richard C. Leinecker. *
- ****************************************************************/
-
- #include <obdefs.h>
- #include <define.h>
- #include <osbind.h>
- #include <gemdefs.h>
-
- /* define the array positions for each box... */
- #define SCRN1 0
- #define SCRN2 1
- #define SCRN3 2
- #defe SCRN4 333
- #define SCRN5 4
- #define SCRN6 5
- #define SCRN7 6
- #define SCRN8 7
- #define CUTIMAGE 8
- #define TO_C 9
- #define TO_ASM 10
- #define TO_GFA 11
- #define TO_DATA 12
-
- /* define mixinum and maximum for window redraw code... */
- #define maximum(x,y) (((x) > (y)) ? (x) : (y))
- #define minimum(x,y) (((x) < (y)) ? (x) : (y))
-
- /* define the type of window to use... */
- #define WI_KIND ( CLOSER | MOVER | NAME | FULLER )
-
- /* global application ID number */
- extern int gl_apid;
-
- /* arrays for GEM bindings... */
- int contrl[12];
- int intin[128];
- int ptsin[128];
- int intout[128];
- int ptsout[128];
- int work_in[11];
- int work_out[57];
-
- char pathname[128]; /* pathname for file selector */
- char filename[128]; /* filename for saving the image */
-
- int handle; /* workstation handle */
- int menu_id; /* accessory menu ID number */
- int degas_id; /* application ID of Degas Elite */
- int wi_handle; /* calculator window handle */
- int gr_hwchar; /* width of a character cell */
- int gr_hhchar; /* height of a character cell */
- int mx, my, button; /* mouse position and button */
- int rx1,ry1,rx2,ry2; /* rectangle for cut image coord */
- int xwork, ywork; /* position of window work area */
- int wwork, hwork; /* width and height of work area */
- int ax, ay, aw, ah; /* accessory window coordinates */
- int rez; /* current system resolution */
- int cutflag; /* buffer undefined/defined flag */
- int cur_screen; /* currently selected screen box */
- int msgbuff[16]; /* evnt_multi() message buffer */
-
- long *scrn_pntrs; /* pointer to screen pointer list */
- long scrn_array[8]; /* holds DE's screen pointers 1-8 */
- long temp_scrn; /* pointer to DE's work screen */
- long undo_scrn; /* pointer to DE's UNDO buffer */
-
- char image_names[800]; /* array for array names entered */
- int names; /* number of array names entered */
-
- /* declare an array of structures to hold the box information... */
- struct boxdefs
- {
- int x, y;
- int w, h;
- char *string;
- } boxes[] = {
-
- 1, 0, 11, 1, " Screen #1",
- 1, 2, 11, 1, " Screen #2",
- 1, 4, 11, 1, " Screen #3",
- 1, 6, 11, 1, " Screen #4",
- 14, 0, 11, 1, " Screen #5",
- 14, 2, 11, 1, " Screen #6",
- 14, 4, 11, 1, " Screen #7",
- 14, 6, 11, 1, " Screen #8",
- 1, 8, 24, 1, "Cut Image",
- 1, 10, 24, 1, "Buffer to C",
- 1, 12, 24, 1, "Buffer to Assembly",
- 1, 14, 24, 1, "Buffer to GFA Basic",
- 1, 16, 24, 1, "Buffer to Data File"
- };
-
- /* Initialize the key enabled/disabled bitmapped fields... */
- int boxflags[] = { 0x0100, 0x1f00 };
-
- main()
- {
- initialize(); /* initialize the accessory */
- do_event(); /* handle the message events */
- }
-
-
- /********************************************************
- * do_event(): *
- * This routine waits for an event, then calls a routine *
- * to handle the message event that was returned. *
- ********************************************************/
-
- do_event()
- {
- int i; /* miscellaneous variable */
- int mx, my; /* mouse position variables */
- int event; /* event returned by evnt_multi() */
-
-
- graf_mouse( ARROW, 0x0L );
-
- /* good accessories never die! */
- while( TRUE )
- {
- /* wait for a message or button event */
- event = evnt_multi( MU_BUTTON | MU_MESAG, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- msgbuff, 0, 0, &mx, &my,
- &i, &i, &i, &i );
-
- /* process the event returned */
- if( event & MU_MESAG ) do_message( msgbuff );
- if( event & MU_BUTTON ) check_box( mx, my );
- }
-
- } /* End of - do_event() */
-
-
- /*************************************************************
- * do_message(): *
- * This routine calls the appropriate window event handler *
- * with the information contained in the event message buffer *
- *************************************************************/
-
- do_message( msgbuff )
- int msgbuff[];
- {
- switch( msgbuff[0] )
- {
- case AC_OPEN: acc_open( msgbuff ); break;
- case AC_CLOSE: acc_close( msgbuff ); break;
- case WM_MOVED: move_window(msgbuff); break;
- case WM_CLOSED: close_window( msgbuff ); break;
- case WM_NEWTOP: top_window( msgbuff ); break;
- case WM_TOPPED: top_window( msgbuff ); break;
- case WM_FULLED: show_authors( msgbuff ); break;
- case WM_REDRAW: redraw( msgbuff ); break;
- }
-
- } /* End of - do_message() */
-
-
- /*************************************
- * acc_open(): *
- * This routine opens the accessory *
- * and ask DE for the necessary info. *
- *************************************/
-
- acc_open( msgbuff )
- int msgbuff[];
- {
- static char not_found[] = "[1][|Could not find Degas Elite!][ Ok ]";
-
- int i; /* miscellaneous variable */
- int event; /* event returned by evnt_multi() */
- int demsg[16]; /* buffer for degas elite messages */
-
-
- /* return if the open command is not for us! */
- if( msgbuff[4] != menu_id ) return(0);
-
- /* if the window is already open, just top it and leave! */
- if( wi_handle != -1 )
- {
- wind_set( wi_handle, WF_TOP, 0, 0, 0, 0 );
- return(0);
- }
-
- /* otherwise, try to find Degas Elite and get it's ID # */
- degas_id = appl_find( "DEGELITE" );
-
- /* leave if an invalid ID # is returned */
- if( degas_id < 0 )
- {
- form_alert( 1, not_found );
- return(0);
- }
-
- /* Make sure DE is there! */
- demsg[0] = 0xDE00;
- demsg[1] = gl_apid;
- demsg[2] = 0;
- i = appl_write( degas_id, 16, demsg );
-
- /* wait for a reply from DE, or for a timer to elapse */
- event = evnt_multi( MU_MESAG|MU_TIMER, -1, -1, -1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- demsg, 2000, 0,
- &i, &i, &i, &i, &i, &i );
-
- /* if the timer elapsed, then DE didn't respond! */
- if( event & MU_TIMER )
- {
- form_alert( 1, not_found );
- return(0);
- }
-
- /* I think it's ok to ignore if the message isn't of interest */
- if( demsg[0] != 0xDE80 ) return(0);
-
- /* otherwise, ask Degas Elite for the buffer pointers */
- demsg[0] = 0xDE00;
- demsg[1] = gl_apid;
- demsg[2] = 0;
- appl_write( degas_id, 16, demsg );
-
- /* wait for a reply from DE */
- do{ evnt_mesag( demsg ); } while( demsg[0] != 0xDE80 );
-
- /* grab the pointer to the array of screen pointers */
- scrn_pntrs = (long *)(((long)demsg[3] << 16) |
- (((long)demsg[4]) & 0x0000ffffL));
-
- /* copy the drawing screen pointers to my array */
- scrn_array[ SCRN1 ] = scrn_pntrs[ 1 ];
- scrn_array[ SCRN2 ] = scrn_pntrs[ 2 ];
- scrn_array[ SCRN3 ] = scrn_pntrs[ 7 ];
- scrn_array[ SCRN4 ] = scrn_pntrs[ 8 ];
- scrn_array[ SCRN5 ] = scrn_pntrs[ 9 ];
- scrn_array[ SCRN6 ] = scrn_pntrs[ 10 ];
- scrn_array[ SCRN7 ] = scrn_pntrs[ 11 ];
- scrn_array[ SCRN8 ] = scrn_pntrs[ 12 ];
-
- /* get the addresses of the work buffers */
- temp_scrn = scrn_pntrs[ 5 ];
- undo_scrn = scrn_pntrs[ 6 ];
-
- /*
- ** set the box flags to enabled/disabled depending
- ** on whether the screen buffer was allocated!
- */
-
- boxflags[0] = boxflags[0] & 0xff00;
- boxflags[1] = boxflags[1] & 0xff00;
-
- for( i = 0; i < 8; i++ )
- {
- if( scrn_array[i] != 0L )
- {
- boxflags[0] = boxflags[0] | (1 << i);
- boxflags[1] = boxflags[1] | (1 << i);
- }
- }
-
- /* get the currently selected screen */
- demsg[0] = 0xDE01;
- demsg[1] = gl_apid;
- demsg[2] = 0;
- appl_write( degas_id, 16, demsg );
-
- do{ evnt_mesag( demsg ); } while( demsg[0] != 0xDE81 );
-
- /* adjust the screen number returned to ignore the work buffers */
- if( demsg[3] < 3 )
- cur_screen = demsg[3] - 1;
- else
- cur_screen = demsg[3] - 5;
-
- /* put an asterisk in front of the screen string if not empty */
- for( i = 0; i < 8; i++ )
- {
- if( scrn_array[i] != 0L )
- {
- if( search_blank( scrn_array[i] ) )
- boxes[i].string[0] = '*';
- else
- boxes[i].string[0] = ' ';
- }
- }
-
- /* open the accessory */
- cutflag = 0;
- open_vwork();
- open_window();
-
- } /* End of - acc_open() */
-
-
- /**************************************
- * acc_close(): *
- * This routine closes the workstation *
- **************************************/
-
- acc_close( msgbuff )
- int msgbuff[];
- {
- if( msgbuff[3] == menu_id && wi_handle != -1 )
- {
- v_clsvwk( handle );
- wi_handle = -1;
- }
- }
-
-
- /***********************************************************************
- * move_window(): *
- * This routine moves the window to the position specified in msgbuff[] *
- ***********************************************************************/
-
- move_window( msgbuff )
- int msgbuff[];
- {
- /* return if move message is not for my window */
- if( msgbuff[3] != wi_handle ) return(0);
-
- /* update the accessory position variables */
- ax = msgbuff[4];
- ay = msgbuff[5];
- aw = msgbuff[6];
- ah = msgbuff[7];
-
- /* set the window position */
- wind_set( msgbuff[3], WF_CURRXYWH, ax, ay, aw, ah );
-
- /* call routine to store work area position in global variables */
- get_workarea();
- }
-
-
- /************************************************************
- * close_window(): *
- * This routine closes the window and closes the workstation *
- ************************************************************/
-
- close_window( msgbuff )
- int msgbuff[];
- {
- /* return if the close message is not for this window */
- if( msgbuff[3] != wi_handle ) return(0);
-
- /* otherwise, close it! */
- wind_close( wi_handle );
- wind_delete( wi_handle );
- v_clsvwk( handle );
- wi_handle = -1;
- }
-
-
- /****************************************************
- * top_window(): *
- * This routine sets the accessory window to the top *
- ****************************************************/
-
- top_window( msgbuff )
- int msgbuff[];
- {
- /* return if the top command is not for my window */
- if( msgbuff[3] != wi_handle ) return(0);
-
- wind_set( wi_handle, WF_TOP, 0, 0, 0, 0 );
- }
-
-
- /*********************************************************
- * show_authors(): *
- * This routine resorts to some shameless self-promotion! *
- *********************************************************/
-
- show_authors( msgbuff )
- int msgbuff[];
- {
- static char authors[] = "[1][The Degas Elite Image Generator|\
- Written by|\
- Robert M. Birmingham|\
- and|\
- Richard C. Leinecker][ Ok! ]";
-
- /* return if the top command is not for my window */
- if( msgbuff[3] != wi_handle ) return(0);
-
- form_alert( 1, authors );
- }
-
-
- /*************************************************
- * redraw(): *
- * This routine redraws sections of the window by *
- * stepping through the window rectangle list. *
- *************************************************/
-
- redraw( msgbuff )
- int msgbuff[];
- {
- int w[4]; /* holds rectangle coord's from window list */
-
-
- /* return if the redraw message isn't for this window */
- if( msgbuff[3] != wi_handle ) return(0);
-
- wind_update(1);
-
- /* get the first rectangle from the window list */
- wind_get( msgbuff[3], WF_FIRSTXYWH, &w[0], &w[1], &w[2], &w[3] );
-
- while( w[2] && w[3] )
- {
- if( b_intersect( &msgbuff[4], w ) ) draw_window( w );
- wind_get( msgbuff[3], WF_NEXTXYWH, &w[0], &w[1], &w[2], &w[3] );
- }
-
- wind_update(0);
-
- } /* End of - redraw() */
-
-
- /******************************************************
- * get_workarea(): *
- * This routine gets the window's work area dimensions *
- ******************************************************/
-
- get_workarea()
- {
- wind_get( wi_handle, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork );
- }
-
-
- /**********************************************
- * check_box(): *
- * This routine processes the box index passed *
- **********************************************/
-
- check_box( mx, my )
- int mx, my;
- {
- int i; /* miscellaneous */
- int box_index; /* index of box selected */
- int button; /* mouse button state */
-
-
- /* see if the mouse was clicked on an accessory box */
- if( ( box_index = scan_boxes( mx, my ) ) < 0 ) return(0);
-
- /* do nothing if the box is the screen selected */
- if( box_index == cur_screen ) return(0);
-
- /* if the box is disabled then return */
- if(((boxflags[cutflag] >> (box_index-SCRN1)) & 0x0001) == 0) return(0);
-
- /* lock out AES messages */
- wind_update(1);
-
- /*
- ** set the clipping rectangle so the boxes
- ** won't be drawn off the edge of the screen
- */
-
- set_clip( 0, 0, work_out[0], work_out[1], 1 );
-
- /* highlight the box selected */
- draw_box( box_index, 1 );
-
- /* find out which box was pressed */
- if( box_index >= SCRN1 && box_index <= SCRN8 )
- {
- draw_box( cur_screen, 0 );
- cur_screen = box_index;
- }
- else if( box_index == CUTIMAGE )
- {
- cutflag = cut_image( scrn_array[cur_screen], cutflag );
-
- for( i = TO_C; i <= TO_DATA; i++ )
- {
- if( i == cur_screen )
- draw_box( i, 1 );
- else
- draw_box( i, 0 );
- }
- }
- else
- image( scrn_array[ cur_screen ], box_index );
-
- /* wait for the mouse button to be released */
- do{ graf_mkstate( &i, &i, &button, &i ); } while( button );
-
- /* reset the box unless it's a 'screen' box */
- if( box_index != cur_screen ) draw_box( box_index, 0 );
-
- /* clear the clipping rectangle */
- set_clip( 0, 0, work_out[0], work_out[1], 0 );
-
- /* enable AES messages */
- wind_update(0);
-
- } /* End of - check_box() */
-
-
- /**********************************************************
- * scan_boxes(): *
- * Returns the box under the mouse position passed, if any *
- **********************************************************/
-
- scan_boxes( x, y )
- int x, y;
- {
- int i;
-
- /* see if the mouse cursor is inside a box */
- for( i = SCRN1; i <= TO_DATA; i++ )
- {
- if( x >= xwork + boxes[i].x &&
- y >= ywork + boxes[i].y &&
- x <= xwork + boxes[i].x + boxes[i].w &&
- y <= ywork + boxes[i].y + boxes[i].h )
- return(i);
- }
-
- return(-1);
-
- } /* End of - scan_boxes() */
-
-
- /*******************************************
- * draw_window(): *
- * This routine redraws the accesory window *
- *******************************************/
-
- draw_window( w )
- int w[];
- {
- int i; /* general purpose variable */
- int pxyarray[4]; /* used to clear the window */
- int clip[4]; /* clipping rectangle to set */
-
-
- /* set the clipping rectangle */
- clip[0] = w[0];
- clip[1] = w[1];
- clip[2] = w[0] + w[2] - 1;
- clip[3] = w[1] + w[3] - 1;
- vs_clip( handle, 1, clip );
-
- /* clear the work area */
- pxyarray[0] = xwork;
- pxyarray[1] = ywork;
- pxyarray[2] = xwork + wwork - 1;
- pxyarray[3] = ywork + hwork - 1;
-
- /* set the various attributes for the box */
- v_hide_c( handle );
- vsf_color( handle, 0 );
- vsf_interior( handle, 2 );
- vsf_style( handle, 8 );
- vr_recfl( handle, pxyarray );
-
- /* redraw each box (highlight the active screen box) */
- for( i = SCRN1; i <= TO_DATA; i++ )
- {
- if( i == cur_screen )
- draw_box( i, 1 );
- else
- draw_box( i, 0 );
- }
-
- /* reset the clipping rectangle */
- vs_clip( handle, 0, clip );
- v_show_c( handle, 0 );
-
- } /* End of - draw_window() */
-
-
- /******************************************************************
- * draw_box(): *
- * This routine redraws the box whose array index number is passed *
- ******************************************************************/
-
- draw_box( idx, flag )
- int idx, flag;
- {
- int pxyarray[4]; /* rectangle for drawing box */
- int shadow[4]; /* rectangle for box's shadow */
- int x, y; /* position of box's text */
-
-
- /* use the box flags to see if the box should be enabled/disabled */
- if( ((boxflags[cutflag] >> (idx-SCRN1)) & 0x0001) == 0 )
- vst_effects( handle, 2 );
- else
- vst_effects( handle, 0 );
-
- /* get the box's coordinates */
- pxyarray[0] = xwork + boxes[ idx ].x;
- pxyarray[1] = ywork + boxes[ idx ].y;
- pxyarray[2] = pxyarray[0] + boxes[ idx ].w;
- pxyarray[3] = pxyarray[1] + boxes[ idx ].h;
-
- /* set the shadow box coodinates */
- shadow[0] = pxyarray[0] + 2;
- shadow[1] = pxyarray[1] + 2;
- shadow[2] = pxyarray[2] + 2;
- shadow[3] = pxyarray[3] + 2;
-
- /* draw the shadow of the box */
- v_hide_c( handle );
- vswr_mode( handle, 1 );
- vsf_perimeter( handle, 1 );
- vsf_color( handle, 1 );
- vsf_interior( handle, 1 );
- v_bar( handle, shadow );
-
- /* draw it as an outline, or as selected based on the flag */
- vsf_interior( handle, flag );
- v_bar( handle, pxyarray );
-
- /* print the string in the box */
- x = (boxes[idx].w / 2) - ((strlen(boxes[idx].string) * gr_hwchar)/2);
- x = pxyarray[0] + x;
- y = pxyarray[3] - 3;
-
- vswr_mode( handle, 3 );
- v_gtext( handle, x, y, boxes[idx].string );
- vswr_mode( handle, 1 );
- vst_effects( handle, 0 );
- v_show_c( handle, 1 );
-
- } /* End of - draw_box() */
-
-
- /************************************************************
- * initialize(): *
- * This routine initializes the box array and opens a window *
- ************************************************************/
-
- initialize()
- {
- int i, a; /* miscellaneous variables */
-
-
- /* tell GEM we're here, and install our DESK item... */
- appl_init();
- handle = graf_handle( &gr_hwchar, &gr_hhchar, &i, &i );
- menu_id = menu_register( gl_apid, " The Generator..." );
-
- rez = Getrez(); /* get the current screen resolution */
- cur_screen = SCRN1; /* set the initial screen selected */
- wi_handle = -1; /* indicate no window is open! */
-
- /* initialize the box position array... */
- for( a = SCRN1; a <= TO_DATA; a++ )
- {
- boxes[ a ].x = boxes[ a ].x * gr_hwchar;
- boxes[ a ].y = (gr_hhchar/2 ) + (boxes[ a ].y * gr_hhchar);
- boxes[ a ].w = boxes[ a ].w * gr_hwchar;
- boxes[ a ].h = boxes[ a ].h * gr_hhchar + 3;
- }
-
- /* calculate the initial window position and dimension */
- ax = 5 * gr_hwchar;
- ay = 2 * gr_hhchar;
- aw = boxes[TO_DATA].x+boxes[TO_DATA].w+gr_hwchar+2;
- ah = boxes[TO_DATA].y+boxes[TO_DATA].h+gr_hhchar+(gr_hhchar/2)+6;
-
- } /* End of - initialize() */
-
-
- /*******************************************************
- * open_vwork(): *
- * This routine opens the workstation for the accessory *
- *******************************************************/
-
- open_vwork()
- {
- int i;
-
- for( i = 0; i < 10; work_in[ i++ ] = 1 );
- work_in[ 10 ] = 2;
- v_opnvwk( work_in, &handle, work_out );
- }
-
-
- /*******************************************************
- * open_window(): *
- * This routine opens the window used for the accessory *
- *******************************************************/
-
- open_window()
- {
- /* create, then open the accessory window */
- wi_handle = wind_create( WI_KIND, 0, 0, aw, ah );
- wind_set( wi_handle, WF_NAME, "DE Image Generator", 0, 0 );
- wind_open( wi_handle, ax, ay, aw, ah );
- get_workarea();
- }
-
-
- /**********************************************************
- * set_clip(): *
- * This routine enables or disables the clipping rectangle *
- **********************************************************/
-
- set_clip( x, y, w, h, flag )
- int x, y, w, h, flag;
- {
- int clip[4];
-
- clip[0] = x;
- clip[1] = y;
- clip[2] = x + w;
- clip[3] = y + h;
-
- vs_clip( handle, flag, clip );
- }
-
-
- /*********************************************************
- * rectangle intersection routines for the window redraws *
- *********************************************************/
-
- int b_intersect( bin, bout )
- int bin[], bout[];
- {
- return r_intersect(bin[0],bin[1],bin[2],bin[3],
- &bout[0],&bout[1],&bout[2],&bout[3] );
- }
-
-
- r_intersect( bx, by, bw, bh, ox, oy, ow, oh )
- int bx, by, bw, bh, *ox, *oy, *ow, *oh;
- {
- int x, y, w, h;
-
-
- w = minimum( bx + bw, *ox + *ow );
- h = minimum( by + bh, *oy + *oh );
- x = maximum( *ox, bx );
- y = maximum( *oy, by );
-
- *ox = x;
- *oy = y;
- *ow = w - x;
- *oh = h - y;
-
- return w > x && h > y;
- }
-
-