|
|
DataMuseum.dkPresents historical artifacts from the history of: RegneCentralen RC759 "Piccoline" |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RegneCentralen RC759 "Piccoline" Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 60928 (0xee00)
Types: TextFile
Names: »DEMO.C«
└─⟦33b70227c⟧ Bits:30003931/GEM_Develop_disk_3_CDOS.imd Disketter indleveret af Steffen Jensen (Piccolo/Piccoline)
└─⟦this⟧ »DEMO.C«
└─⟦f18477172⟧ Bits:30003931/GEM_Develop_disk_1_CDOS.imd Disketter indleveret af Steffen Jensen (Piccolo/Piccoline)
└─⟦this⟧ »SAMP\DEMO.C«
/************************************************************************/
/* File: demo.c */
/************************************************************************/
/* */
/* GGGGG EEEEEEEE MM MM */
/* GG EE MMMM MMMM */
/* GG GGG EEEEE MM MM MM */
/* GG GG EE MM MM */
/* GGGGG EEEEEEEE MM MM */
/* */
/************************************************************************/
/* */
/* +--------------------------+ */
/* ø Digital Research, Inc. ø */
/* ø 60 Garden Court ø */
/* ø Monterey, CA. 93940 ø */
/* +--------------------------+ */
/* */
/* The source code contained in this listing is a non-copyrighted */
/* work which can be freely used. In applications of this source */
/* code you are requested to acknowledge Digital Research, Inc. as */
/* the originator of this code. */
/* */
/* Author: Tom Rolander, Tim Oren */
/* PRODUCT: GEM Sample Application */
/* Module: DEMO.C */
/* Version: 2.1 */
/* Modified: Mitch Smith, April 25, 1986 */
/* */
/************************************************************************/
/*
\f
Page*/
/*------------------------------*/
/* includes */
/*------------------------------*/
#include "portab.h" /* portable coding conv */
#include "machine.h" /* machine depndnt conv */
#include "obdefs.h" /* object definitions */
#include "treeaddr.h" /* tree address macros */
#include "gembind.h" /* gem binding structs */
#include "demo.h" /* demo apl resource */
/**/ /* file offsets */
/*------------------------------*/
/* defines */
/*------------------------------*/
#define ARROW 0 /* mouse forms */
#define HOUR_GLASS 2
#define DESK 0 /* Desktop window handle */
#define END_UPDATE 0 /* Window Update Flags */
#define BEG_UPDATE 1
#define PEN_INK BLACK
#define PEN_ERASER WHITE
#define PEN_FINE 1
#define PEN_MEDIUM 5
#define PEN_BROAD 9
#define X_FWD 0x0100 /* extended object types */
#define X_BAK 0x0200 /* used with scrolling */
#define X_SEL 0x0300 /* selectors */
#define N_COLORS 15L
#define YSCALE(x) UMUL_DIV(x, scrn_xsize, scrn_ysize)
#define TE_TXTLEN(x) (x + 24) /* TEDINFO text length */
#define BI_PDATA(x) (x) /* BITBLK - image data */
#define BI_WB(x) (x + 4) /* width in bytes */
#define BI_HL(x) (x + 6) /* height - scan lines */
#define IB_PMASK(x) (x) /* ICONBLK - icon mask */
#define IB_PDATA(x) (x + 4) /* icon data */
#define IB_WB(x) (x + 22) /* width in pixels */
#define IB_HL(x) (x + 24) /* height - scan lines */
/*------------------------------*/
/* External Functions */
/*------------------------------*/
EXTERN LONG dos_alloc(); /* in DOSBIND.C */
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Data Structures ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* Extrnl Data Structures */
/*------------------------------*/
EXTERN UWORD DOS_ERR; /* in DOSBIND.C */
EXTERN LONG drawaddr; /* in FARDRAW.ASM */
/*------------------------------*/
/* Global Data Structures */
/*------------------------------*/
GLOBAL WORD contrlÆ11Å; /* control inputs */
GLOBAL WORD intinÆ80Å; /* max string length */
GLOBAL WORD ptsinÆ256Å; /* polygon fill points */
GLOBAL WORD intoutÆ45Å; /* open workstation output */
GLOBAL WORD ptsoutÆ12Å;
/*------------------------------*/
/* Local Data Structures */
/*------------------------------*/
WORD gl_wchar; /* character width */
WORD gl_hchar; /* character height */
WORD gl_wbox; /* box (cell) width */
WORD gl_hbox; /* box (cell) height */
WORD gl_hspace; /* height of space between lines*/
WORD gem_handle; /* GEM vdi handle */
WORD vdi_handle; /* demo vdi handle */
WORD work_outÆ57Å; /* open virt workstation values */
GRECT scrn_area; /* whole screen area */
GRECT work_area; /* drawing area of main window */
GRECT undo_area; /* area equal to work_area */
GRECT save_area; /* save area for full/unfulling */
WORD gl_rmsgÆ8Å; /* message buffer */
LONG ad_rmsg; /* LONG pointer to message bfr */
LONG gl_menu; /* menu tree address */
WORD gl_apid; /* application ID */
WORD gl_xfull; /* full window 'x' */
WORD gl_yfull; /* full window 'y' */
WORD gl_wfull; /* full window 'w' */
WORD gl_hfull; /* full window 'h' */
WORD scrn_width; /* screen width in pixels */
WORD scrn_height; /* screen height in pixels */
WORD scrn_planes; /* number of color planes */
WORD scrn_xsize; /* width of one pixel */
WORD scrn_ysize; /* height of one pixel */
UWORD m_out = FALSE; /* mouse in/out of window flag */
WORD ev_which; /* event multi return state(s) */
UWORD mousex, mousey; /* mouse x,y position */
UWORD bstate, bclicks; /* button state, & # of clicks */
UWORD kstate, kreturn; /* key state and keyboard char */
MFDB undo_mfdb; /* undo buffer mmry frm def blk */
MFDB scrn_mfdb; /* screen memory form defn blk */
LONG buff_size; /* buffer size req'd for screen */
LONG buff_location; /* screen buffer pointer */
WORD demo_whndl; /* demo window handle */
WORD demo_shade = PEN_INK; /* demo current pen shade */
WORD pen_shade = PEN_INK; /* saved pen shade */
WORD demo_pen = 1; /* demo current pen width */
WORD demo_height = 4; /* demo current char height */
WORD char_fine; /* character height for fine */
WORD char_medium; /* character height for medium */
WORD char_broad; /* character height for broad */
WORD monumber = 5; /* mouse form number */
LONG mofaddr = 0x0L; /* mouse form address */
WORD file_handle; /* file handle -> pict ld/sv */
BYTE file_nameÆ64Å = ""; /* current pict file name */
BYTE nameÆ13Å = ""; /* Save As pict file name */
BOOLEAN key_input; /* key inputting state */
WORD key_xbeg; /* x position for line beginning*/
WORD key_ybeg; /* y position for line beginning*/
WORD key_xcurr; /* current x position */
WORD key_ycurr; /* current y position */
/* demo window title */
BYTE *wdw_title = " GEM Demo Window ";
WORD usercolorÆ2Å = æ1, 0å;
MFDB userbrush_mfdb; /* MFDB for Prog def objects */
APPLBLK brushabÆ6Å; /* 6 Programmer defined objects */
LONG color_selÆN_COLORS+1Å = æ /* data for scrolling */
/**/ /* color selector */
N_COLORS,
0x31FF1071L,
0x32FF1072L,
0x33FF1073L,
0x34FF1074L,
0x35FF1075L,
0x36FF1076L,
0x37FF1077L,
0x38FF1078L,
0x39FF1079L,
0x41FF107AL,
0x42FF107BL,
0x43FF107CL,
0x44FF107DL,
0x45FF107EL,
0x46FF107FL
å;
/*
\f
Page*/
/*------------------------------*/
/* Mouse Data Structures */
/*------------------------------*/
WORD erase_broadÆ37Å = /* mouse form for broad eraser */
æ
7, 7, 1, 0, 1,
0x0000, 0x0000, 0x0000, 0x0000, /* mask */
0x0000, 0x1ff0, 0x1ff0, 0x1ff0,
0x1ff0, 0x1ff0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, /* data */
0x7ffc, 0x600c, 0x600c, 0x600c,
0x600c, 0x600c, 0x7ffc, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000
å;
WORD erase_mediumÆ37Å = /* mouse form for medium eraser */
æ
7, 7, 1, 0, 1,
0x0000, 0x0000, 0x0000, 0x0000, /* mask */
0x0000, 0x0000, 0x07c0, 0x07c0,
0x07c0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, /* data */
0x0000, 0x1ff0, 0x1830, 0x1830,
0x1830, 0x1ff0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000
å;
WORD erase_fineÆ37Å = /* mouse form for fine eraser */
æ
7, 7, 1, 0, 1,
0x0000, 0x0000, 0x0000, 0x0000, /* mask */
0x0000, 0x0000, 0x0000, 0x0100,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, /* data */
0x0000, 0x0000, 0x07c0, 0x06c0,
0x07c0, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000
å;
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Local Procedures ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* min */
/*------------------------------*/
WORD
min(a, b) /* return min of two values */
WORD a, b;
æ
return( (a < b) ? a : b );
å
/*------------------------------*/
/* max */
/*------------------------------*/
WORD
max(a, b) /* return max of two values */
WORD a, b;
æ
return( (a > b) ? a : b );
å
/*------------------------------*/
/* string_addr */
/*------------------------------*/
LONG
string_addr(which) /* returns a tedinfo LONG string addr */
WORD which;
æ
LONG where;
rsrc_gaddr(R_STRING, which, &where);
return (where);
å
/*------------------------------*/
/* rc_equal */
/*------------------------------*/
WORD
rc_equal(p1, p2) /* tests for two rectangles equal */
GRECT *p1, *p2;
æ
if ((p1->g_x != p2->g_x) øø
(p1->g_y != p2->g_y) øø
(p1->g_w != p2->g_w) øø
(p1->g_h != p2->g_h))
return(FALSE);
return(TRUE);
å
/*------------------------------*/
/* rc_copy */
/*------------------------------*/
VOID
rc_copy(psbox, pdbox) /* copy source to destination rectangle */
GRECT *psbox;
GRECT *pdbox;
æ
pdbox->g_x = psbox->g_x;
pdbox->g_y = psbox->g_y;
pdbox->g_w = psbox->g_w;
pdbox->g_h = psbox->g_h;
å
/*------------------------------*/
/* rc_intersect */
/*------------------------------*/
WORD
rc_intersect(p1, p2) /* compute intersect of two rectangles */
GRECT *p1, *p2;
æ
WORD tx, ty, tw, th;
tw = min(p2->g_x + p2->g_w, p1->g_x + p1->g_w);
th = min(p2->g_y + p2->g_h, p1->g_y + p1->g_h);
tx = max(p2->g_x, p1->g_x);
ty = max(p2->g_y, p1->g_y);
p2->g_x = tx;
p2->g_y = ty;
p2->g_w = tw - tx;
p2->g_h = th - ty;
return( (tw > tx) && (th > ty) );
å
/*------------------------------*/
/* inside */
/*------------------------------*/
UWORD
inside(x, y, pt) /* determine if x,y is in rectangle */
UWORD x, y;
GRECT *pt;
æ
if ( (x >= pt->g_x) && (y >= pt->g_y) &&
(x < pt->g_x + pt->g_w) && (y < pt->g_y + pt->g_h) )
return(TRUE);
else
return(FALSE);
å /* inside */
/*------------------------------*/
/* grect_to_array */
/*------------------------------*/
VOID
grect_to_array(area, array) /* convert x,y,w,h to upper left x,y */
GRECT *area; /* and lower right x,y for raster ops */
WORD *array; /* and for clipping */
æ
*array++ = area->g_x;
*array++ = area->g_y;
*array++ = area->g_x + area->g_w - 1;
*array = area->g_y + area->g_h - 1;
å
/*------------------------------*/
/* rast_op */
/*------------------------------*/
VOID
rast_op(mode, s_area, s_mfdb, d_area, d_mfdb) /* bit block level trns */
WORD mode;
GRECT *s_area, *d_area;
MFDB *s_mfdb, *d_mfdb;
æ
WORD pxyÆ8Å;
grect_to_array(s_area, pxy);
grect_to_array(d_area, &pxyÆ4Å);
/* pixel for pixel source */
/**/ /* to destination copy */
vro_cpyfm(vdi_handle, mode, pxy, s_mfdb, d_mfdb);
å
/*------------------------------*/
/* vdi_fix */
/*------------------------------*/
VOID
vdi_fix(pfd, theaddr, wb, h) /* set up MFDB for transform */
MFDB *pfd;
LONG theaddr;
WORD wb, h;
æ
pfd->fww = wb >> 1; /* # of bytes to words */
pfd->fwp = wb << 3; /* # of bytes to to pixels */
pfd->fh = h; /* height in scan lines */
pfd->np = 1; /* number of planes */
pfd->mp = theaddr; /* memory pointer */
å
/*------------------------------*/
/* vdi_trans */
/*------------------------------*/
WORD
vdi_trans(saddr, swb, daddr, dwb, h) /* 'on the fly' transform */
LONG saddr;
WORD swb;
LONG daddr;
WORD dwb;
WORD h;
æ
MFDB src, dst; /* local MFDB */
vdi_fix(&src, saddr, swb, h);
src.ff = TRUE; /* standard format */
vdi_fix(&dst, daddr, dwb, h);
dst.ff = FALSE; /* transform to device */
/**/ /* specific format */
vr_trnfm(vdi_handle, &src, &dst );
å
/*------------------------------*/
/* trans_gimage */
/*------------------------------*/
VOID
trans_gimage(tree, obj) /* transform bit images and icons */
LONG tree;
WORD obj;
æ
LONG taddr, obspec;
WORD wb, hl, type;
obspec = LLGET(OB_SPEC(obj));
type = LWGET(OB_TYPE(obj));
if ( type == G_ICON )
æ
taddr = LLGET(IB_PMASK(obspec)); /* pointer to icon mask*/
wb = LWGET(IB_WB(obspec));
wb = wb >> 3; /* pixels to bytes */
hl = LWGET(IB_HL(obspec)); /* height in scan lines */
vdi_trans(taddr, wb, taddr, wb, hl); /* transform mask */
taddr = LLGET(IB_PDATA(obspec)); /* pointer to icon data*/
å
else
æ
taddr = LLGET(BI_PDATA(obspec)); /* pointer to image */
wb = LWGET(BI_WB(obspec)); /* width in bytes */
hl = LWGET(BI_HL(obspec)); /* height in scan lines*/
å
vdi_trans(taddr, wb, taddr, wb, hl); /* transform image or */
/**/ /* icon data */
å
/*------------------------------*/
/* do_open */
/*------------------------------*/
VOID
do_open(wh, org_x, org_y, x, y, w, h) /* grow and open specified wdw */
WORD wh;
WORD org_x, org_y;
WORD x, y, w, h;
æ
graf_growbox(org_x, org_y, 21, 21, x, y, w, h);
wind_open(wh, x, y, w, h);
å
/*------------------------------*/
/* do_close */
/*------------------------------*/
VOID
do_close(wh, org_x, org_y) /* close and shrink specified window */
WORD wh;
WORD org_x, org_y;
æ
WORD x, y, w, h;
wind_get(wh, WF_CXYWH, &x, &y, &w, &h);
wind_close(wh);
graf_shrinkbox(org_x, org_y, 21, 21, x, y, w, h);
å
/*------------------------------*/
/* set_clip */
/*------------------------------*/
VOID
set_clip(clip_flag, s_area) /* set clip to specified area */
WORD clip_flag;
GRECT *s_area;
æ
WORD pxyÆ4Å;
grect_to_array(s_area, pxy);
vs_clip(vdi_handle, clip_flag, pxy);
å
/*------------------------------*/
/* draw_rect */
/*------------------------------*/
VOID
draw_rect(area) /* used by dr_code() to draw a */
GRECT *area; /* rectangle around pen/eraser */
æ
WORD pxyÆ10Å;
pxyÆ0Å = area->g_x;
pxyÆ1Å = area->g_y;
pxyÆ2Å = area->g_x + area->g_w - 1;
pxyÆ3Å = area->g_y + area->g_h - 1;
pxyÆ4Å = pxyÆ2Å;
pxyÆ5Å = pxyÆ3Å;
pxyÆ3Å = pxyÆ1Å;
pxyÆ6Å = pxyÆ0Å;
pxyÆ7Å = pxyÆ5Å;
pxyÆ8Å = pxyÆ0Å;
pxyÆ9Å = pxyÆ1Å;
v_pline(vdi_handle, 5, pxy);
å
/*------------------------------*/
/* align_x */
/*------------------------------*/
WORD
align_x(x) /* forces word alignment for column position */
WORD x; /* rounding to nearest word */
æ
return((x & 0xfff0) + ((x & 0x000c) ? 0x0010 : 0));
å
/*------------------------------*/
/* do_top */
/*------------------------------*/
VOID
do_top(wdw_hndl) /* top the window if not already active */
WORD wdw_hndl;
æ
WORD active, dummy;
wind_get(wdw_hndl, WF_TOP, &active, &dummy, &dummy, &dummy);
if ( wdw_hndl != active )
wind_set(wdw_hndl, WF_TOP, 0, 0, 0, 0);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Advanced Dialog Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* set_select */
/*------------------------------*/
VOID
set_select(tree, obj, init_no, bind, arry) /* intialize the color */
LONG tree, bindÆÅ, arryÆÅ; /* selector objects in */
WORD obj, init_no; /* Pen/Eraser Dialog */
æ
WORD n, nobj, cobj, count;
indir_obj(tree, obj);
bindÆ0Å = LLGET(OB_SPEC(obj));
LLSET(OB_SPEC(obj), ADDR(bind));
bindÆ1Å = ADDR(arry);
n = (WORD) arryÆ0Å;
count = 0;
for (cobj = LWGET(OB_HEAD(obj)); cobj != obj;
cobj = LWGET(OB_NEXT(cobj)))
æ /* loop to init color selector with colors 1 to 4 */
indir_obj(tree, cobj);
LLSET(OB_SPEC(cobj), ADDR( &arryÆcount + 1Å ));
count = (count + 1) % n;
å
nobj = LWGET(OB_NEXT(obj)); /* set pointer to current color */
indir_obj(tree, nobj);
LLSET(OB_SPEC(nobj), ADDR( &arryÆ1 + init_no % nÅ ));
å
/*------------------------------*/
/* get_select */
/*------------------------------*/
WORD
get_select(tree, obj) /* Get the Current pen color */
LONG tree; /* selection. Used after Pen/Eraser */
WORD obj; /* Dialog interaction */
æ
WORD nobj, cobj;
LONG bind, arry, temp;
bind = LLGET(OB_SPEC(obj));
dir_obj(tree, obj);
LLSET(OB_SPEC(obj), LLGET(bind));
arry = LLGET(bind + sizeof(LONG) );
for (cobj = LWGET(OB_HEAD(obj)); cobj != obj;
cobj = LWGET(OB_NEXT(cobj)))
æ
dir_obj(tree, cobj);
LLSET(OB_SPEC(cobj), LLGET(LLGET(OB_SPEC(cobj))));
å
nobj = LWGET(OB_NEXT(obj));
dir_obj(tree, nobj);
temp = LLGET(OB_SPEC(nobj));
LLSET(OB_SPEC(nobj), LLGET(temp));
return (WORD) (temp - arry) / sizeof(LONG) - 1;
å
/*------------------------------*/
/* move_do */
/*------------------------------*/
VOID
move_do(tree, obj, inc) /* routine to scroll the color selector */
LONG tree; /* in the Pen/Eraser Dialog */
WORD obj, inc;
æ
WORD cobj;
LONG n, bind, arry, limit, obspec;
obj = get_parent(tree, obj);
obj = LWGET(OB_NEXT(obj));
bind = LLGET(OB_SPEC(obj));
arry = LLGET(bind + sizeof(LONG));
n = LLGET(arry) * sizeof(LONG);
limit = arry + n;
for (cobj = LWGET(OB_HEAD(obj)); cobj != obj;
cobj = LWGET(OB_NEXT(cobj)))
æ
obspec = LLGET(OB_SPEC(cobj));
obspec += inc * sizeof(LONG);
while (obspec <= arry øø obspec > limit)
obspec += n * ((obspec > limit)? -1: 1);
LLSET(OB_SPEC(cobj), obspec);
å
redraw_do(tree, obj);
å
/*------------------------------*/
/* redraw_do */
/*------------------------------*/
VOID
redraw_do(tree, obj) /* Routine to draw a specified object */
LONG tree; /* in a tree */
æ
GRECT o;
objc_xywh(tree, obj, &o);
o.g_x -= 3; o.g_y -= 3; o.g_w += 6; o.g_h += 6;
objc_draw(tree, ROOT, MAX_DEPTH, o.g_x, o.g_y, o.g_w, o.g_h);
å
/*------------------------------*/
/* xtend_do */
/*------------------------------*/
WORD
xtend_do(tree, obj, xtype) /* called by hndl_dial() if extended */
LONG tree; /* type object is the exit object */
WORD obj, xtype;
æ
LONG obspec;
switch (xtype) æ
case X_SEL: /* selected color */
obspec = LLGET(OB_SPEC(obj));
obj = get_parent(tree, obj);
obj = LWGET(OB_NEXT(obj));
LLSET(OB_SPEC(obj), obspec);
redraw_do(tree, obj);
break;
case X_FWD: /* forward arrow */
move_do(tree, obj, 1);
redraw_do(tree, obj);
break;
case X_BAK: /* backward arrow */
move_do(tree, obj, -1);
redraw_do(tree, obj);
break;
default:
break;
å
return(FALSE);
å
/*------------------------------*/
/* hndl_dial */
/*------------------------------*/
WORD
hndl_dial(tree, def, x, y, w, h) /* general purpose dialog */
LONG tree; /* handler. Provides for */
WORD def; /* extended object type */
WORD x, y, w, h; /* checking and 'local' */
æ /* processing of extended */
/* type objects */
WORD xdial, ydial, wdial, hdial, exitobj;
WORD xtype;
form_center(tree, &xdial, &ydial, &wdial, &hdial); /* returns */
/**/ /* screen center x,y,w,h */
form_dial(0, x, y, w, h, xdial, ydial, wdial, hdial);/* reserves*/
/**/ /* screen space for dialog box */
form_dial(1, x, y, w, h, xdial, ydial, wdial, hdial);/* draws */
/**/ /* expanding box */
objc_draw(tree, ROOT, MAX_DEPTH, xdial, ydial, wdial, hdial);
FOREVER
æ
exitobj = form_do(tree, def) & 0x7FFF;
xtype = LWGET(OB_TYPE(exitobj)) & 0xFF00;
if (!xtype) /* is not extended type */
break;
if (xtend_do(tree, exitobj, xtype))
break;
å
form_dial(2, x, y, w, h, xdial, ydial, wdial, hdial);/* draws a */
/**/ /* shrinking box */
form_dial(3, x, y, w, h, xdial, ydial, wdial, hdial);/* free */
/**/ /* screen space, causes redraw */
return (exitobj);
å
/*------------------------------*/
/* dr_code */
/*------------------------------*/
WORD
dr_code(pparms) /* called by FARDRAW.ASM when */
LONG pparms; /* drawing Programmer Defined */
æ /* objects in Pen/Eraser Dialog */
PARMBLK pb;
WORD pxyÆ10Å, hl, wb;
LONG taddr;
LBCOPY(ADDR(&pb), pparms, sizeof(PARMBLK)); /* copy PARMBLK */
set_clip(TRUE, (GRECT *) &pb.pb_xc);
taddr = pb.pb_parm; /* original obspec */
userbrush_mfdb.mp = LLGET(BI_PDATA(taddr)); /* point to data */
hl = LWGET(BI_HL(taddr)); /* height in scan lines */
wb = LWGET(BI_WB(taddr)); /* width in bytes */
userbrush_mfdb.fwp = wb << 3; /* set up the MFDB */
userbrush_mfdb.fww = wb >> 1; /* in preparation */
userbrush_mfdb.fh = hl; /* for a transform */
userbrush_mfdb.np = 1; /* monochrome assumed */
userbrush_mfdb.ff = 0; /* Device specific format */
pxyÆ0Å = pxyÆ1Å = 0;
pxyÆ2Å = (wb << 3) - 1;
pxyÆ3Å = hl - 1;
pxyÆ4Å = pb.pb_x;
pxyÆ5Å = pb.pb_y;
pxyÆ6Å = pxyÆ4Å + pb.pb_w - 1;
pxyÆ7Å = pxyÆ5Å + pb.pb_h - 1;
/* Copy Raster Transparent */
vrt_cpyfm(vdi_handle, 2, pxy, &userbrush_mfdb, &scrn_mfdb, usercolor);
if((pb.pb_currstate!=pb.pb_prevstate)øø(pb.pb_currstate&SELECTED))
æ
if (pb.pb_currstate & SELECTED)
vsl_color(vdi_handle,BLACK);
else
vsl_color(vdi_handle,WHITE);
vsl_width(vdi_handle, 1);
vsl_type(vdi_handle, FIS_SOLID);
pb.pb_x--;
pb.pb_y--;
pb.pb_w++;
pb.pb_h++;
draw_rect((GRECT *) &pb.pb_x);
å
set_clip(FALSE, (GRECT *) &work_area);
return(0); /* always return 0 from prog def drawing code */
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Work Area Management ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* set_work */
/*------------------------------*/
VOID
set_work(slider_update) /* update undo area, clamping to page */
BOOLEAN slider_update; /* edges, and updt sliders if req'd */
æ
WORD i;
wind_get(demo_whndl, WF_WXYWH,
&work_area.g_x, &work_area.g_y,
&work_area.g_w, &work_area.g_h);
undo_area.g_w = work_area.g_w;
undo_area.g_h = work_area.g_h;
/**/ /* clamp work area to page edges */
undo_area.g_x = align_x(undo_area.g_x);
if ((i = undo_mfdb.fwp - (undo_area.g_x + undo_area.g_w)) < 0)
undo_area.g_x += i;
if ((i = undo_mfdb.fh - (undo_area.g_y + undo_area.g_h)) < 0)
undo_area.g_y += i;
if (slider_update)
æ /* set slider positions */
wind_set(demo_whndl, WF_HSLIDE, UMUL_DIV(undo_area.g_x, 1000,
undo_mfdb.fwp - undo_area.g_w), 0, 0, 0);
wind_set(demo_whndl, WF_VSLIDE, UMUL_DIV(undo_area.g_y, 1000,
undo_mfdb.fh - undo_area.g_h), 0, 0, 0);
wind_set(demo_whndl, WF_HSLSIZ, UMUL_DIV(work_area.g_w, 1000,
undo_mfdb.fwp), 0, 0, 0);
wind_set(demo_whndl, WF_VSLSIZ, UMUL_DIV(work_area.g_h, 1000,
undo_mfdb.fh), 0, 0, 0);
å
/* only use portion of work_area on screen */
rc_intersect(&scrn_area, &work_area);
undo_area.g_w = work_area.g_w;
undo_area.g_h = work_area.g_h;
å
/*------------------------------*/
/* save_work */
/*------------------------------*/
VOID
save_work() /* copy work_area to undo_area buffer */
æ
GRECT tmp_area;
rc_copy(&work_area,&tmp_area);
rc_intersect(&scrn_area,&tmp_area);
graf_mouse(M_OFF, 0x0L);/* turn mouse off */
rast_op(3, &tmp_area, &scrn_mfdb, &undo_area, &undo_mfdb);
graf_mouse(M_ON, 0x0L); /* turn mouse on */
å
/*------------------------------*/
/* restore_work */
/*------------------------------*/
VOID
restore_work() /* restore work_area from undo_area */
æ
GRECT tmp_area;
rc_copy(&work_area,&tmp_area);
rc_intersect(&scrn_area,&tmp_area);
graf_mouse(M_OFF, 0x0L);
rast_op(3, &undo_area, &undo_mfdb, &tmp_area, &scrn_mfdb);
graf_mouse(M_ON, 0x0L);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Object Tree Manipulation ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* do_obj */
/*------------------------------*/
VOID
do_obj(tree, which, bit) /* set specified bit in object state */
LONG tree;
WORD which, bit;
æ
WORD state;
state = LWGET(OB_STATE(which));
LWSET(OB_STATE(which), state ø bit);
å
/*------------------------------*/
/* undo_obj */
/*------------------------------*/
VOID
undo_obj(tree, which, bit) /* clear specified bit in object state */
LONG tree;
WORD which, bit;
æ
WORD state;
state = LWGET(OB_STATE(which));
LWSET(OB_STATE(which), state & übit);
å
/*------------------------------*/
/* sel_obj */
/*------------------------------*/
VOID
sel_obj(tree, which) /* turn on selected bit of spcfd object */
LONG tree;
WORD which;
æ
do_obj(tree, which, SELECTED);
å
/*------------------------------*/
/* desel_obj */
/*------------------------------*/
VOID
desel_obj(tree, which) /* turn off selected bit of spcfd object*/
LONG tree;
WORD which;
æ
undo_obj(tree, which, SELECTED);
å
/*------------------------------*/
/* enab_menu */
/*------------------------------*/
VOID
enab_menu(which) /* enable specified menu item */
WORD which;
æ
undo_obj(gl_menu, which, DISABLED);
å
/*------------------------------*/
/* disab_menu */
/*------------------------------*/
VOID
disab_menu(which) /* disable specified menu item */
WORD which;
æ
do_obj(gl_menu, which, DISABLED);
å
/*------------------------------*/
/* unflag_obj */
/*------------------------------*/
VOID
unflag_obj(tree, which, bit)
LONG tree;
WORD which, bit;
æ
WORD flags;
flags = LWGET(OB_FLAGS(which));
LWSET(OB_FLAGS(which), flags & übit);
å
/*------------------------------*/
/* flag_obj */
/*------------------------------*/
VOID
flag_obj(tree, which, bit)
LONG tree;
WORD which, bit;
æ
WORD flags;
flags = LWGET(OB_FLAGS(which));
LWSET(OB_FLAGS(which), flags ø bit);
å
/*------------------------------*/
/* indir_obj */
/*------------------------------*/
VOID
indir_obj(tree, which)
LONG tree;
WORD which;
æ
flag_obj(tree, which, INDIRECT);
å
/*------------------------------*/
/* dir_obj */
/*------------------------------*/
VOID
dir_obj(tree, which)
LONG tree;
WORD which;
æ
unflag_obj(tree, which, INDIRECT);
å
/*------------------------------*/
/* get_parent */
/*------------------------------*/
/*
* Routine that will find the parent of a given object. The
* idea is to walk to the end of our siblings and return
* our parent. If object is the root then return NIL as parent.
*/
WORD
get_parent(tree, obj)
LONG tree;
WORD obj;
æ
WORD pobj;
if (obj == NIL)
return (NIL);
pobj = LWGET(OB_NEXT(obj));
if (pobj != NIL)
æ
while( LWGET(OB_TAIL(pobj)) != obj )
æ
obj = pobj;
pobj = LWGET(OB_NEXT(obj));
å
å
return(pobj);
å
/*------------------------------*/
/* objc_xywh */
/*------------------------------*/
VOID
objc_xywh(tree, obj, p) /* get x,y,w,h for specified object */
LONG tree;
WORD obj;
GRECT *p;
æ
objc_offset(tree, obj, &p->g_x, &p->g_y);
p->g_w = LWGET(OB_WIDTH(obj));
p->g_h = LWGET(OB_HEIGHT(obj));
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** File Path Name Functions ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* dial_name */
/*------------------------------*/
WORD
dial_name ( name ) /* dialogue box input filename */
BYTE *name;
æ
LONG tree ;
LONG ted_addr ;
BYTE c ;
WORD i, j;
GRECT box;
objc_xywh(gl_menu, DEMOFILE, &box);
rsrc_gaddr( R_TREE, DEMOSVAD, &tree) ;
ted_addr = LLGET(OB_SPEC(DEMONAME)); /* get obspec pointer */
LLSET( ted_addr, ADDR(name) ) ; /* set obspec pointer */
LWSET( TE_TXTLEN(ted_addr),9); /* 1 more than */
nameÆ0Å = 'Ø0'; /* null to clear edit field and position cursor */
if (hndl_dial(tree, DEMONAME, box.g_x, box.g_y, box.g_w, box.g_h)
== DEMOSOK)
æ
i =
j = 0;
while (TRUE) /* parse filename string */
æ
c = nameÆi++Å;
if (!c)
break ;
if ( (c != ' ') && (c != '_') )
nameÆj++Å = c ;
å
if ( *name )
strcpy( &nameÆjÅ, ".DOO" ); /* add extension */
desel_obj(tree, DEMOSOK);
return (TRUE);
å
else
æ
desel_obj(tree, DEMOSCNL);
return (FALSE);
å
å
/*------------------------------*/
/* get_path */
/*------------------------------*/
VOID
get_path(tmp_path, spec) /* get directory path name */
BYTE *tmp_path, *spec;
æ
WORD cur_drv;
cur_drv = dos_gdrv();
tmp_pathÆ0Å = cur_drv + 'A';
tmp_pathÆ1Å = ':';
tmp_pathÆ2Å = 'ØØ';
dos_gdir(cur_drv+1, ADDR(&tmp_pathÆ3Å));
if (strlen(tmp_path) > 3)
strcat(tmp_path, "ØØ");
else
tmp_pathÆ2Å = 'Ø0';
strcat(tmp_path, spec);
å
/*------------------------------*/
/* add_file_name */
/*------------------------------*/
VOID
add_file_name(dname, fname) /* replace name at end of input file spec*/
BYTE *dname, *fname;
æ
BYTE c;
WORD ii;
ii = strlen(dname);
while (ii && (((c = dnameÆii-1Å) != 'ØØ') && (c != ':')))
ii--;
dnameÆiiÅ = 'Ø0';
strcat(dname, fname);
å
/*------------------------------*/
/* get_file */
/*------------------------------*/
WORD
get_file(loop) /* use file selector to get input file */
BOOLEAN loop;
æ
WORD fs_iexbutton;
BYTE fs_iinselÆ13Å;
while (TRUE)
æ
get_path(file_name, "*.DOO");
fs_iinselÆ0Å = 'Ø0';
fsel_input(ADDR(file_name), ADDR(fs_iinsel), &fs_iexbutton);
if (fs_iexbutton)
æ
add_file_name(file_name, fs_iinsel);
file_handle = dos_open(ADDR(file_name),2);
if (!loop øø (loop && !DOS_ERR))
return(1);
å
else
æ
disab_menu(DEMOSAVE);
disab_menu(DEMOABAN);
return(0);
å
å
å /* get_file */
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Soft Cursor Support ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* cursor */
/*------------------------------*/
VOID
cursor(color) /* turn cursor on, color = BLACK */
WORD color; /* or cursor off, color = WHITE */
æ
WORD pxyÆ4Å;
pxyÆ0Å = key_xcurr + 1;
pxyÆ1Å = key_ycurr + gl_hspace;
pxyÆ2Å = key_xcurr + 1;
pxyÆ3Å = key_ycurr - gl_hbox;
vsl_color(vdi_handle,color);
vswr_mode(vdi_handle,MD_REPLACE);
vsl_type (vdi_handle,FIS_SOLID);
vsl_width (vdi_handle,PEN_FINE);
graf_mouse(M_OFF, 0x0L);
set_clip(TRUE, &work_area);
v_pline(vdi_handle, 2, pxy);
set_clip(FALSE, &work_area);
graf_mouse(M_ON, 0x0L);
å
/*------------------------------*/
/* curs_on */
/*------------------------------*/
VOID
curs_on() /* turn 'soft' cursor 'on' */
æ
cursor(pen_shade);
å
/*------------------------------*/
/* curs_off */
/*------------------------------*/
VOID
curs_off() /* turn 'soft' cursor 'off' */
æ
cursor(PEN_ERASER);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Menu Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* hndl_menu */
/*------------------------------*/
WORD
hndl_menu(title, item)
WORD title, item;
æ
WORD done;
graf_mouse(ARROW, 0x0L);
done = FALSE;
switch (title) æ
case DEMODESK: /* Desk menu */
if (item == DEMOINFO) /* 'About Demo' menu item */
do_about();
break;
case DEMOFILE: /* File menu */
switch (item)
æ
case DEMOLOAD: /* Load File */
do_load(TRUE);
break;
case DEMOSAVE: /* Save File */
do_save();
break;
case DEMOSVAS: /* Save File As */
do_svas();
break;
case DEMOABAN: /* Abandon File */
file_handle = dos_open(ADDR(file_name),2);
do_load(FALSE);
break;
case DEMOQUIT: /* Quit - Exit back to Desktop */
done = TRUE;
break;
å
case DEMOOPTS: /* Options menu */
switch (item)
æ
case DEMOPENS: /* Pen/Eraser Selection */
do_penselect();
break;
case DEMOERAP: /* Erase Picture */
do_top(demo_whndl);
do_erase();
break;
å
å
menu_tnormal(gl_menu,title,TRUE);
graf_mouse(monumber, mofaddr);
return (done);
å
/*------------------------------*/
/* do_about */
/*------------------------------*/
VOID
do_about() /* display Demo Info... */
æ
LONG tree;
GRECT box;
objc_xywh(gl_menu, DEMODESK, &box); /* DESK menu title xywh */
rsrc_gaddr(R_TREE, DEMOINFD, &tree); /* address of DEMOINFD */
hndl_dial(tree, 0, box.g_x, box.g_y, box.g_w, box.g_h);
desel_obj(tree, DEMOOK); /* deselect OK button */
å
/*------------------------------*/
/* do_load */
/*------------------------------*/
VOID
do_load(need_name) /* load demo picture file */
BOOLEAN need_name;
æ
if (!need_name øø get_file(TRUE))
æ
if (!DOS_ERR)
æ
dos_read(file_handle, buff_size,buff_location);
dos_close(file_handle);
enab_menu(DEMOSAVE);
enab_menu(DEMOABAN);
restore_work();
å
å
å
/*------------------------------*/
/* do_save */
/*------------------------------*/
WORD
do_save() /* save current named demo picture */
æ
if (*file_name)
æ
file_handle = dos_open(ADDR(file_name),2);
if (!DOS_ERR)
æ /* File already exists */
if (form_alert(1, string_addr(DEMOOVWR)) == 2)
æ /* Cancel - dont't overwrite */
dos_close(file_handle);
return(FALSE);
å
å
if(DOS_ERR)
file_handle = dos_create(ADDR(file_name),0);
if(DOS_ERR)
æ /* disable Save and Abandon */
disab_menu(DEMOSAVE);
disab_menu(DEMOABAN);
return(FALSE);
å
dos_write(file_handle, buff_size, buff_location);
enab_menu(DEMOSAVE);
enab_menu(DEMOABAN);
dos_close(file_handle);
return(TRUE);
å
å
/*------------------------------*/
/* do_save_as */
/*------------------------------*/
VOID
do_svas() /* save demo picture as named */
æ
if (dial_name(name))
æ
if (nameÆ0Å != 'Ø0')
æ
add_file_name(file_name, name);
do_save();
å
å
å
/*------------------------------*/
/* set_pen */
/*------------------------------*/
VOID
set_pen(pen, height) /* set pen width and height */
WORD pen, height;
æ
demo_pen = pen;
demo_height = height;
monumber = 5; /* thin cross hair */
mofaddr = 0x0L;
å
/*------------------------------*/
/* set_eraser */
/*------------------------------*/
VOID
set_eraser(pen, height, eraser) /* set mouse form to eraser */
WORD pen, height;
BYTE *eraser;
æ
demo_pen = pen;
demo_height = height;
demo_shade = PEN_ERASER;
monumber = 255;
mofaddr = ADDR(eraser);
å
/*------------------------------*/
/* set_color */
/*------------------------------*/
VOID
set_color(tree, obj, color_num, bind) /* Set Pen Color Selection */
LONG tree, *bind;
WORD obj, color_num;
æ
set_select(tree, obj, color_num - 1, bind, color_sel);
å
/*------------------------------*/
/* get_color */
/*------------------------------*/
WORD
get_color(tree, obj) /* Get Pen Color Selection */
LONG tree;
WORD obj;
æ
return get_select(tree, obj) + 1;
å
/*------------------------------*/
/* do_penselect */
/*------------------------------*/
VOID
do_penselect() /* use dialogue box to input selection */
æ /* of specified pen/eraser */
WORD exit_obj, psel_obj, color;
LONG tree, bindÆ2Å;
GRECT box;
objc_xywh(gl_menu, DEMOPENS, &box);
rsrc_gaddr(R_TREE, DEMOPEND, &tree);
/**/ /* first setup current selection state */
switch (demo_pen) æ
case PEN_FINE:
sel_obj(tree, (demo_shade != PEN_ERASER)?
DEMOPFIN: DEMOEFIN);
break;
case PEN_MEDIUM:
sel_obj(tree, (demo_shade != PEN_ERASER)?
DEMOPMED: DEMOEMED);
break;
case PEN_BROAD:
sel_obj(tree, (demo_shade != PEN_ERASER)?
DEMOPBRD: DEMOEBRD);
break;
å
set_color(tree, DEMOPCLR, pen_shade, bind);
/**/ /* get dialogue box input */
exit_obj = hndl_dial(tree, 0, box.g_x, box.g_y, box.g_w, box.g_h);
for (psel_obj = DEMOPFIN; psel_obj <= DEMOEBRD; psel_obj++)
if (LWGET(OB_STATE(psel_obj)) & SELECTED)
æ
desel_obj(tree, psel_obj);
break;
å
color = get_color(tree, DEMOPCLR);
if (exit_obj == DEMOPSOK)
æ
switch (psel_obj) æ
case DEMOPFIN:
set_pen(PEN_FINE, char_fine);
demo_shade = color;
break;
case DEMOPMED:
set_pen(PEN_MEDIUM, char_medium);
demo_shade = color;
break;
case DEMOPBRD:
set_pen(PEN_BROAD, char_broad);
demo_shade = color;
break;
case DEMOEFIN:
set_eraser(PEN_FINE, char_fine,
(BYTE *) erase_fine);
break;
case DEMOEMED:
set_eraser(PEN_MEDIUM, char_medium,
(BYTE *) erase_medium);
break;
case DEMOEBRD:
set_eraser(PEN_BROAD, char_broad,
(BYTE *) erase_broad);
break;
å
pen_shade = color;
desel_obj(tree, DEMOPSOK);
å
else
desel_obj(tree, DEMOCNCL);
å
/*------------------------------*/
/* do_erase */
/*------------------------------*/
VOID
do_erase() /* clear the screen and the undo buffer */
æ
rast_op(0, &scrn_area, &scrn_mfdb, &scrn_area, &undo_mfdb);
restore_work();
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Keyboard Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* hndl_keyboard */
/*------------------------------*/
WORD
hndl_keyboard()
æ
WORD i;
BYTE strÆ2Å;
GRECT lttr, test;
if ((strÆ0Å = kreturn & 0xff) == 0x03) /* Ctrl C */
return(TRUE);
graf_mouse(M_OFF, 0x0L);
if (!key_input)
æ
vswr_mode(vdi_handle, MD_REPLACE);
vst_color(vdi_handle, pen_shade);
/* set text height, then calculate space between lines */
vst_height(vdi_handle, demo_height,
&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
gl_hspace = gl_hbox - gl_hchar;
/* set text alignment to left justification, bottom */
vst_alignment(vdi_handle, 0, 3, &i, &i);
/* get current mouse location, button and keybd state */
graf_mkstate(&key_xbeg, &key_ybeg, &i, &i);
key_xcurr = ++key_xbeg;
key_ycurr = --key_ybeg;
å
else
curs_off();
strÆ1Å = 'Ø0';
if (strÆ0Å == 0x1A) /* Ctrl Z */
æ
save_work(); /* update undo area from work area */
graf_mouse(M_ON, 0x0L);
return(key_input = FALSE);
å
else
if (strÆ0Å == 0x0D) /* carriage return */
æ
/* adjust x,y */
key_ycurr += gl_hbox + gl_hspace;
key_xcurr = key_xbeg;
å
else
if (strÆ0Å == 0x08) /* backspace */
æ
if (key_input && (key_xcurr != key_xbeg))
æ /* 'back up' */
for (i = 0; i < gl_wbox; i++)
æ
key_xcurr--;
curs_off();
å
å
å
else
if ((strÆ0Å >= ' ') && (strÆ0Å <= 'z'))
æ /* output character so long as it */
/**/ /* fits in the work area */
lttr.g_x = key_xcurr;
lttr.g_y = key_ycurr - gl_hbox;
lttr.g_w = gl_wbox;
lttr.g_h = gl_hbox;
rc_copy(<tr, &test);
rc_intersect(&work_area, &test);
if (!rc_equal(<tr, &test))
æ
graf_mouse(M_ON, 0x0L);
return (FALSE);
å
set_clip(TRUE, &work_area);
v_gtext(vdi_handle, key_xcurr,
key_ycurr, str);
set_clip(FALSE, &work_area);
/* update x position */
key_xcurr += gl_wbox;
å
if (!key_input)
æ
key_input = TRUE;
å
curs_on();
graf_mouse(M_ON, 0x0L);
return(FALSE);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Message Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* hndl_msg */
/*------------------------------*/
/*MLOCAL*/ BOOLEAN hndl_msg()
æ
BOOLEAN done;
WORD wdw_hndl;
GRECT work;
done = FALSE;
wdw_hndl = gl_rmsgÆ3Å;
switch( gl_rmsgÆ0Å )
æ
case MN_SELECTED:
done = hndl_menu(wdw_hndl, gl_rmsgÆ4Å);/* Title, Item */
break;
case WM_REDRAW:
do_redraw(wdw_hndl, (GRECT *) &gl_rmsgÆ4Å);/* x,y,w,h */
break;
case WM_TOPPED:
if(wdw_hndl == demo_whndl) /* make sure it's my window */
wind_set(wdw_hndl, WF_TOP, 0, 0, 0, 0);
break;
case WM_CLOSED:
done = TRUE; /* terminate, exit back to DESKTOP.APP */
break;
case WM_FULLED:
do_full(wdw_hndl); /* toggle between full and previous */
break;
case WM_ARROWED: /* calculate new undo_area x,y */
switch(gl_rmsgÆ4Å) /* requested action */
æ
case WA_UPPAGE: /* page up */
undo_area.g_y = max(undo_area.g_y - undo_area.g_h, 0);
break;
case WA_DNPAGE: /* page down */
undo_area.g_y += undo_area.g_h;
break;
case WA_UPLINE: /* row up */
undo_area.g_y = max(undo_area.g_y - YSCALE(16), 0);
break;
case WA_DNLINE: /* row down */
undo_area.g_y += YSCALE(16);
break;
case WA_LFPAGE: /* page left */
undo_area.g_x = max(undo_area.g_x - undo_area.g_w, 0);
break;
case WA_RTPAGE: /* page right */
undo_area.g_x += undo_area.g_w;
break;
case WA_LFLINE: /* column left */
undo_area.g_x = max(undo_area.g_x - 16, 0);
break;
case WA_RTLINE: /* column right */
undo_area.g_x += 16;
break;
å
set_work(TRUE); /* update slider positions */
restore_work(); /* update screen from undo_area */
break;
case WM_HSLID: /* horizontal slider */
undo_area.g_x = align_x(UMUL_DIV(undo_mfdb.fwp - undo_area.g_w,
gl_rmsgÆ4Å, 1000));
set_work(TRUE);
restore_work();
break;
case WM_VSLID: /* vertical slider */
undo_area.g_y = UMUL_DIV(undo_mfdb.fh - undo_area.g_h,
gl_rmsgÆ4Å,1000);
set_work(TRUE);
restore_work();
break;
case WM_SIZED: /* new window size requested */
/* get work area x,y,w,h */
wind_calc(1, 0x0fef, gl_rmsgÆ4Å, gl_rmsgÆ5Å, gl_rmsgÆ6Å,
gl_rmsgÆ7Å, &work.g_x, &work.g_y, &work.g_w,
&work.g_h);
work.g_x = align_x(work.g_x); /* WORD alignment */
work.g_w = align_x(work.g_w); /* for performance */
/* get border area x, y, w, h */
wind_calc(0, 0x0fef, work.g_x, work.g_y, work.g_w, work.g_h,
&gl_rmsgÆ4Å, &gl_rmsgÆ5Å, &gl_rmsgÆ6Å, &gl_rmsgÆ7Å);
/* set current x,y,w,h - borders, title bar, (info) */
wind_set(wdw_hndl, WF_CXYWH, gl_rmsgÆ4Å,
gl_rmsgÆ5Å, gl_rmsgÆ6Å, gl_rmsgÆ7Å);
set_work(TRUE); /* update slider positions */
break;
case WM_MOVED: /* user moved the window */
gl_rmsgÆ4Å = align_x(gl_rmsgÆ4Å);
wind_set(wdw_hndl, WF_CXYWH, align_x(gl_rmsgÆ4Å) - 1,
gl_rmsgÆ5Å, gl_rmsgÆ6Å, gl_rmsgÆ7Å);
set_work(FALSE); /* NO slider update */
break;
å /* switch */
return(done);
å /* hndl_msg */
/*------------------------------*/
/* do_redraw */
/*------------------------------*/
VOID
do_redraw(wh, area) /* redraw specified area from undo bfr */
WORD wh;
GRECT *area;
æ
GRECT box;
GRECT dirty_source, dirty_dest;
graf_mouse(M_OFF, 0x0L); /* turn mouse off */
/* get the coordinates of the first rectangle in the window's */
/**/ /* rectangle list */
wind_get(wh, WF_FIRSTXYWH, &box.g_x, &box.g_y, &box.g_w, &box.g_h);
while ( box.g_w && box.g_h )
æ /* AES returns zero width and height when no more rectangles*/
if (rc_intersect(area, &box))
æ
if (wh == demo_whndl)
æ
/* copy rectangle list x,y,w,h to dirty_dest */
rc_copy(&box, &dirty_dest);
if (rc_intersect(&work_area, &dirty_dest))
æ
/* calculate dirty_source x and y */
dirty_source.g_x = (dirty_dest.g_x - work_area.g_x)
+ undo_area.g_x;
dirty_source.g_y = (dirty_dest.g_y - work_area.g_y)
+ undo_area.g_y;
/* window rectangle w and h to dirty_source */
dirty_source.g_w = dirty_dest.g_w;
dirty_source.g_h = dirty_dest.g_h;
/* pixel for pixel source to dest copy */
rast_op(3, &dirty_source, &undo_mfdb,
&dirty_dest, &scrn_mfdb);
å
å
å
/* get next rectangle in window's rectangle list */
wind_get(wh, WF_NEXTXYWH, &box.g_x, &box.g_y, &box.g_w, &box.g_h);
å
/* done walking the rectangle list - turn mouse back on */
graf_mouse(M_ON, 0x0L);
å
/*------------------------------*/
/* do_full */
/*------------------------------*/
VOID
do_full(wh) /* depending on current window state, either make window*/
WORD wh; /* full size -or- return to previous shrunken size */
æ
GRECT prev;
GRECT curr;
GRECT full;
graf_mouse(M_OFF,0x0L);
wind_get(wh, WF_CXYWH, &curr.g_x, &curr.g_y, &curr.g_w, &curr.g_h);
wind_get(wh, WF_PXYWH, &prev.g_x, &prev.g_y, &prev.g_w, &prev.g_h);
wind_get(wh, WF_FXYWH, &full.g_x, &full.g_y, &full.g_w, &full.g_h);
if ( rc_equal(&curr, &full) )
æ /* is full now so change*/
/**/ /* to previous */
graf_shrinkbox(prev.g_x, prev.g_y, prev.g_w, prev.g_h,
full.g_x, full.g_y, full.g_w, full.g_h);
wind_set(wh, WF_CXYWH, prev.g_x, prev.g_y, prev.g_w, prev.g_h);
rc_copy(&save_area, &undo_area);
å
else
æ /* is not full so make */
/**/ /* it full */
rc_copy(&save_area, &undo_area);
graf_growbox(curr.g_x, curr.g_y, curr.g_w, curr.g_h,
full.g_x, full.g_y, full.g_w, full.g_h);
wind_set(wh, WF_CXYWH, full.g_x, full.g_y, full.g_w, full.g_h);
å
set_work(TRUE);
graf_mouse(M_ON,0x0L);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Mouse Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* hndl_mouse */
/*------------------------------*/
WORD
hndl_mouse() /* change mouse form depending on */
æ /* whether it's in or out of window */
BOOLEAN done;
if (m_out)
graf_mouse(ARROW, 0x0L);
else
graf_mouse(monumber, mofaddr);
m_out = !m_out; /* change MU_M1 entry/exit flag */
done = FALSE;
return(done);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Button Handling ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* hndl_button */
/*------------------------------*/
WORD
hndl_button()
æ
WORD done;
done = FALSE;
if (inside(mousex, mousey, &work_area))
draw_pencil(mousex, mousey);
return(done);
å
/*------------------------------*/
/* draw_pencil */
/*------------------------------*/
WORD
draw_pencil(x, y)
UWORD x, y;
æ
UWORD pxyÆ4Å;
WORD done;
UWORD mflags;
UWORD locount, hicount;
UWORD ev_which, bbutton, kstate, kreturn, breturn;
set_clip(TRUE, &work_area);
pxyÆ0Å = x;
pxyÆ1Å = y;
vsl_color(vdi_handle,demo_shade); /* set line color */
vswr_mode(vdi_handle,MD_REPLACE); /* replace writing mode */
vsl_type (vdi_handle,FIS_SOLID); /* solid line type */
if (demo_shade != PEN_ERASER)
æ
vsl_width (vdi_handle,demo_pen); /* set line width */
vsl_ends(vdi_handle, 2, 2); /* rounded end style */
hicount = 0; /* MU_TIMER high */
locount = 125; /* and low count */
mflags = MU_BUTTON ø MU_M1 ø MU_TIMER;
graf_mouse(M_OFF, 0x0L); /* turn mouse 'off' */
å
else
æ
vsf_interior(vdi_handle, 1); /* solid interior fill */
vsf_color(vdi_handle, WHITE); /* fill color */
mflags = MU_BUTTON ø MU_M1;
å
done = FALSE;
while (!done)
æ
ev_which = evnt_multi(mflags,
0x01, 0x01, 0x00, /* 1 click, 1 button, button up */
1, pxyÆ0Å, pxyÆ1Å, 1, 1,
0, 0, 0, 0, 0,
ad_rmsg, locount, hicount,
&pxyÆ2Å, &pxyÆ3Å, &bbutton, &kstate,
&kreturn, &breturn);
if (ev_which & MU_BUTTON)
æ
if (!(mflags & MU_TIMER))
graf_mouse(M_OFF, 0x0L);
if (demo_shade != PEN_ERASER)
v_pline(vdi_handle, 2, (WORD *) pxy);
else
eraser((WORD) pxyÆ2Å, (WORD) pxyÆ3Å);
graf_mouse(M_ON, 0x0L);
done = TRUE;
å
else
if (ev_which & MU_TIMER)
æ
graf_mouse(M_ON, 0x0L);
mflags = MU_BUTTON ø MU_M1;
å
else
æ
if (!(mflags & MU_TIMER))
graf_mouse(M_OFF, 0x0L);
if (demo_shade != PEN_ERASER)
æ
v_pline(vdi_handle, 2, (WORD *) pxy);
mflags = MU_BUTTON ø MU_M1 ø MU_TIMER;
å
else
æ
eraser((WORD) pxyÆ2Å, (WORD) pxyÆ3Å);
graf_mouse(M_ON,0x0L);
å
pxyÆ0Å = pxyÆ2Å;
pxyÆ1Å = pxyÆ3Å;
å
å /* while */
set_clip(FALSE, &work_area);
save_work();
å
/*------------------------------*/
/* eraser */
/*------------------------------*/
VOID
eraser(x, y) /* erase rectangle of eraser size at x,y*/
WORD x, y;
æ
WORD erase_xyÆ4Å;
if (demo_pen == PEN_FINE) /* 5 x 3 */
æ
erase_xyÆ0Å = x - 2;
erase_xyÆ1Å = y - 1;
erase_xyÆ2Å = x + 2;
erase_xyÆ3Å = y + 1;
å
else
if (demo_pen == PEN_MEDIUM) /* 9 x 5 */
æ
erase_xyÆ0Å = x - 4;
erase_xyÆ1Å = y - 2;
erase_xyÆ2Å = x + 4;
erase_xyÆ3Å = y + 2;
å
else /* 13 x 7 */
æ
erase_xyÆ0Å = x - 6;
erase_xyÆ1Å = y - 3;
erase_xyÆ2Å = x + 6;
erase_xyÆ3Å = y + 3;
å
vr_recfl(vdi_handle, erase_xy);
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Demo Event Handler ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* demo */
/*------------------------------*/
demo() /* main event multi loop */
æ
BOOLEAN done;
key_input = FALSE;
done = FALSE;
FOREVER
æ /* wait for Button , Message, 1 Mouse,keyboard */
/* Event Event Rect Event */
ev_which = evnt_multi(MU_BUTTON ø MU_MESAG ø MU_M1 ø MU_KEYBD,
0x02, 0x01, 0x01, /* 2 clicks, 1 button, button down */
m_out, /* entry , work_area x,y,w,h */
(UWORD) work_area.g_x, (UWORD) work_area.g_y,
(UWORD) work_area.g_w, (UWORD) work_area.g_h,
/* mouse rect 2 flags , x,y,w,h */
0, 0, 0, 0, 0,
/* Message buffer, timer low count , high count */
ad_rmsg, 0, 0,
/* mouse posit , btn state, r & lshift, Ctrl, Alt */
&mousex, &mousey, &bstate, &kstate,
/* keybd key,# btn clicks */
&kreturn, &bclicks);
wind_update(BEG_UPDATE);
if (!(ev_which & MU_KEYBD)) /* not KEYBD event */
æ
if (key_input) /* key_input TRUE? */
æ
curs_off(); /* turn cursor off */
key_input = FALSE;
save_work();
å
å
if (ev_which & MU_MESAG)
if (hndl_msg())
break;
if (ev_which & MU_BUTTON)
if (hndl_button())
break;
if (ev_which & MU_M1)
if (hndl_mouse())
break;
if (ev_which & MU_KEYBD)
if (hndl_keyboard())
break;
wind_update(END_UPDATE);
å
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Termination ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* demo_term */
/*------------------------------*/
demo_term(term_type)
WORD term_type;
æ
switch (term_type) /* NOTE: all cases fall through */
æ
case (0 /* normal termination */):
do_close(demo_whndl, gl_wfull/2, gl_hfull/2);
wind_delete(demo_whndl);
case (3 /* no window available */):
menu_bar(0x0L, FALSE);
dos_free(undo_mfdb.mp);
case (2 /* not enough memory */):
graf_mouse(ARROW, 0x0L);
v_clsvwk( vdi_handle );
case (1 /* no .RSC file or no virt wksta */):
wind_update(END_UPDATE);
appl_exit();
case (4 /* appl_init() failed */):
break;
å
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Initialization ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* pict_init */
/*------------------------------*/
VOID
pict_init() /* transform IMAGES and ICONS */
æ /* set up Programmer Defined */
LONG tree; /* objects */
WORD tr_obj, nobj;
rsrc_gaddr(R_TREE, DEMOINFD, &tree);
trans_gimage(tree, DEMOIMG);
rsrc_gaddr(R_TREE, DEMOPEND, &tree);
for (tr_obj = DEMOPFIN; tr_obj <= DEMOEBRD; tr_obj++)
æ
/* loop through Pen/Eraser Dialog objects transforming */
/* them, setting type to G_PROGDEF, establishing the */
/* address of the drawing code and setting the obspec */
/* pointer for each */
trans_gimage(tree, tr_obj);
LWSET(OB_TYPE(tr_obj), G_PROGDEF);
nobj = tr_obj - DEMOPFIN;
brushabÆnobjÅ.ab_code = drawaddr;
brushabÆnobjÅ.ab_parm = LLGET(OB_SPEC(tr_obj));
LLSET(OB_SPEC(tr_obj), ADDR(&brushabÆnobjÅ));
å
å
/*------------------------------*/
/* demo_init */
/*------------------------------*/
WORD
demo_init()
æ
WORD work_inÆ11Å;
WORD i;
gl_apid = appl_init(); /* init application */
if (gl_apid == -1)
return(4);
wind_update(BEG_UPDATE);
graf_mouse(HOUR_GLASS, 0x0L);
if (!rsrc_load( ADDR("DEMO.RSC") ))
æ
/* No Resource File */
graf_mouse(ARROW, 0x0L);
form_alert(1,
ADDR("Æ3ÅÆFatal Error !øDEMO.RSCøFile Not FoundÅÆ Abort Å"));
return(1);
å
/* open virtual workstation */
for (i=0; i<10; i++)
æ
work_inÆiÅ=1; /* initial defaults: line style,color,etc */
å
work_inÆ10Å=2; /* raster coordinates */
/* Get the VDI handle for GEM AES screen workstation */
gem_handle = graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
vdi_handle = gem_handle;
v_opnvwk(work_in,&vdi_handle,work_out);
if (vdi_handle == 0)
return(1);
scrn_width = work_outÆ0Å + 1; /* # of pixels wide */
scrn_height = work_outÆ1Å + 1; /* # of pixels high */
scrn_xsize = work_outÆ3Å; /* pixel width (microns)*/
scrn_ysize = work_outÆ4Å; /* pixel height(microns)*/
char_fine = work_outÆ46Å; /* minimum char height */
char_medium = work_outÆ48Å; /* maximum char height */
char_broad = char_medium * 2;
vq_extnd(vdi_handle, 1, work_out); /* extended inquire */
scrn_planes = work_outÆ4Å; /* # of planes */
undo_mfdb.fwp = scrn_width; /* width in pixels */
undo_mfdb.fww = undo_mfdb.fwp >> 4; /* width in words */
undo_mfdb.fh = scrn_height; /* form height */
undo_mfdb.np = scrn_planes; /* # of planes */
undo_mfdb.ff = 0;
buff_size = (LONG)(undo_mfdb.fwp>>3) * /* # of bytes */
(LONG)undo_mfdb.fh * /* form height */
(LONG)undo_mfdb.np; /* # of planes */
buff_location =
undo_mfdb.mp = dos_alloc(buff_size);
if (undo_mfdb.mp == 0)
return(2); /* not enough memory */
scrn_area.g_x = 0;
scrn_area.g_y = 0;
scrn_area.g_w = scrn_width;
scrn_area.g_h = scrn_height;
scrn_mfdb.mp = 0x0L;
rc_copy(&scrn_area, &undo_area);
rast_op(0, &undo_area, &scrn_mfdb, &undo_area, &undo_mfdb);
pict_init(); /* transforms & programmer defined objects */
ad_rmsg = ADDR((BYTE *) &gl_rmsgÆ0Å); /* init message address */
/* Get Desktop work area */
wind_get(DESK, WF_WXYWH, &gl_xfull, &gl_yfull, &gl_wfull, &gl_hfull);
/* initialize menu */
rsrc_gaddr(R_TREE, DEMOMENU, &gl_menu);
/* show menu */
menu_bar(gl_menu, TRUE);
/* create window with all components except info line */
demo_whndl = wind_create(0x0fef, gl_xfull - 1, gl_yfull,
gl_wfull, gl_hfull);
if (demo_whndl == -1)
æ
/* No Window Available */
form_alert(1, string_addr(DEMONWDW));
return(3);
å
wind_set(demo_whndl, WF_NAME, ADDR(wdw_title), 0, 0);
gl_xfull = align_x(gl_xfull);
do_open(demo_whndl, gl_wfull/2, gl_hfull/2, align_x(gl_xfull)-1,
gl_yfull, gl_wfull, gl_hfull);
/* get work area of window */
wind_get(demo_whndl, WF_WXYWH,
&work_area.g_x, &work_area.g_y,
&work_area.g_w, &work_area.g_h);
set_work(TRUE); /* initial slider positions */
rc_copy (&undo_area, &save_area);/* save_area used by do_full() */
graf_mouse(ARROW, 0x0L);
wind_update(END_UPDATE);
return(0); /* successful initialization */
å
/*
\f
Page*/
/************************************************************************/
/************************************************************************/
/**** ****/
/**** Main Program ****/
/**** ****/
/************************************************************************/
/************************************************************************/
/*------------------------------*/
/* GEMAIN */
/*------------------------------*/
GEMAIN()
æ
WORD term_type;
if (!(term_type = demo_init()))
demo();
demo_term(term_type);
å
«eof»