Professional GEM - Appendices
Jump to navigation
Jump to search
Appendix I - Sample redraw code
/* >>>>>>>>>>>>>>>>>>>>>>>>> Sample Redraw Code <<<<<<<<<<<<<<<<<<<<<<<<<<< */
VOID
doredraw(wh, area) /* wh = window handle from msg[3] */
WORD wh; /* area = pointer to redraw rect- */
GRECT *area; /* tangle in msg[4] thru msg[7] */
{
GRECT box;
grafmouse(MOFF, 0x0L);
windupdate(BEGUPDATE);
windget(wh, WFFIRSTXYWH, &box.gx, &box.gy, &box.gw, &box.gh);
while ( box.gw && box.gh )
{
if (rcintersect(full, &box)) /* Full is entire screen */
if (rcintersect(area, &box))
{
if (wh == w1handle) /* Test for window 1 handle */
{ /* AES redraw example */
objcdraw(w1tree, ROOT, MAXDEPTH, box.gx,
box.gy, box.gw, box.gh);
}
else if (wh == w2handle) /* Test for window 2 handle */
{ /* VDI redraw example */
setclip(TRUE, &box);
/* Put VDI drawing calls here */
}
/* add more windows here */
}
windget(wh, WFNEXTXYWH, &box.gx, &box.gy, &box.gw,
&box.gh);
}
windupdate(ENDUPDATE);
grafmouse(MON, 0x0L);
}
Appendix I - Utilities used in doredraw
/* >>>>>>>>>>>>>>>>>>>>>>>> Utilities used in doredraw <<<<<<<<<<<<<<<<<<<< */
VOID
setclip(clipflag, area) /* set clip to specified area */
WORD clipflag;
GRECT *area;
{
WORD pxy[4];
grecttoarray(area, pxy);
vsclip(vdihandle, clipflag, pxy);
}
VOID
grecttoarray(area, array) /* convert x,y,w,h to upr lt x,y and */
GRECT *area; /* lwr rt x,y */
WORD *array;
{
*array++ = area->gx;
*array++ = area->gy;
*array++ = area->gx + area->gw - 1;
*array = area->gy + area->gh - 1;
}
WORD
rcintersect(p1, p2) /* compute intersect of two rectangles */
GRECT *p1, *p2;
{
WORD tx, ty, tw, th;
tw = min(p2->gx + p2->gw, p1->gx + p1->gw);
th = min(p2->gy + p2->gh, p1->gy + p1->gh);
tx = max(p2->gx, p1->gx);
ty = max(p2->gy, p1->gy);
p2->gx = tx;
p2->gy = ty;
p2->gw = tw - tx;
p2->gh = th - ty;
return( (tw > tx) && (th > ty) );
}
Appendix I - "Self-redraw" Utility
/* >>>>>>>>>>>>>>>>>>>>>>> "Self-redraw" Utility <<<<<<<<<<<<<<<<<<<<<<<<< */
VOID
sendredraw(wh, p)
WORD wh;
GRECT *p;
{
WORD msg[8];
msg[0] = WMREDRAW; /* Defined in GEMBIND.H */
msg[1] = glapid; /* As returned by applinit */
msg[2] = 0;
msg[3] = wh; /* Handle of window to redraw */
msg[4] = p->gx;
msg[5] = p->gy;
msg[6] = p->gw;
msg[7] = p->gh;
applwrite(glapid, 16, &msg); /* Use ADDR(msg) for portability */
}
Appendix I - Utilities for Window Requests
/* >>>>>>>>>>>>>>>>>>>> Utilities for Window Requests <<<<<<<<<<<<<<<<<< */
VOID
rcconstrain(pc, pt)
GRECT *pc;
GRECT *pt;
{
if (pt->gx < pc->gx)
pt->gx = pc->gx;
if (pt->gy < pc->gy)
pt->gy = pc->gy;
if ((pt->gx + pt->gw) > (pc->gx + pc->gw))
pt->gx = (pc->gx + pc->gw) - pt->gw;
if ((pt->gy + pt->gh) > (pc->gy + pc->gh))
pt->gy = (pc->gy + pc->gh) - pt->gh;
}
WORD
align(x,n) /* Snap position x to an n-bit grid */
WORD x, n; /* Use n = 16 for horizontal word alignment */
{
x += (n >> 2) - 1; /* Round and... */
x = n * (x / n); /* remove residue */
return (x);
}
Appendix I - Window full utility
/* >>>>>>>>>>>>>>>>>>>>>>> Window full utility <<<<<<<<<<<<<<<<<<<<<<< */
VOID
hndlfull(wh) /* depending on current window state, make window */
WORD wh; /* full size -or- return to previous shrunken size */
{ /* graf calls are optional special effects. */
GRECT prev;
GRECT curr;
GRECT full;
windget(wh, WFCXYWH, &curr.gx, &curr.gy, &curr.gw, &curr.gh);
windget(wh, WFPXYWH, &prev.gx, &prev.gy, &prev.gw, &prev.gh);
windget(wh, WFFXYWH, &full.gx, &full.gy, &full.gw, &full.gh);
if ( rcequal(&curr, &full) )
{ /* Is full, change to previous */
grafshrinkbox(prev.gx, prev.gy, prev.gw, prev.gh,
full.gx, full.gy, full.gw, full.gh);
windset(wh, WFCXYWH, prev.gx, prev.gy, prev.gw, prev.gh);
/* put sendredraw here if you need it */
}
else
{ /* is not full, so set to full */
grafgrowbox(curr.gx, curr.gy, curr.gw, curr.gh,
full.gx, full.gy, full.gw, full.gh);
windset(wh, WFCXYWH, full.gx, full.gy, full.gw, full.gh);
}
}
WORD
rcequal(p1, p2) /* tests for two rectangles equal */
GRECT *p1, *p2;
{
if ((p1->gx != p2->gx) ||
(p1->gy != p2->gy) ||
(p1->gw != p2->gw) ||
(p1->gh != p2->gh))
return(FALSE);
return(TRUE);
}
Appendix II - Basic Dialog Handler
/*
>>>>>>>>>>>>>>>>>>>>>>> Basic Dialog Handler <<<<<<<<<<<<<<<<<<<<<<<
*/
WORD
hndldial(tree, def, x, y, w, h)
LONG tree;
WORD def;
WORD x, y, w, h;
{
WORD xdial, ydial, wdial, hdial, exitobj;
formcenter(tree, &xdial, &ydial, &wdial, &hdial);
formdial(0, x, y, w, h, xdial, ydial, wdial, hdial);
formdial(1, x, y, w, h, xdial, ydial, wdial, hdial);
objcdraw(tree, ROOT, MAXDEPTH, xdial, ydial, wdial, hdial);
exitobj = formdo(tree, def) & 0x7FFF;
formdial(2, x, y, w, h, xdial, ydial, wdial, hdial);
formdial(3, x, y, w, h, xdial, ydial, wdial, hdial);
return (exitobj);
}
Appendix II - Object rectangle utility
/*
>>>>>>>>>>>>>>>>>>>>>>> Object rectangle utility <<<<<<<<<<<<<<<<<<<<<<<<<
*/
VOID
objcxywh(tree, obj, p) /* get x,y,w,h for specified object */
LONG tree;
WORD obj;
GRECT *p;
{
objcoffset(tree, obj, &p->gx, &p->gy);
p->gw = LWGET(OBWIDTH(obj));
p->gh = LWGET(OBHEIGHT(obj));
}
Appendix II - Object flag utilities
/*
>>>>>>>>>>>>>>>>>>>>>>> Object flag utilities <<<<<<<<<<<<<<<<<<<<<<<<<<<
*/
VOID
undoobj(tree, which, bit) /* clear specified bit in object state */
LONG tree;
WORD which, bit;
{
WORD state;
state = LWGET(OBSTATE(which));
LWSET(OBSTATE(which), state & ~bit);
}
VOID
deselobj(tree, which) /* turn off selected bit of spcfd object*/
LONG tree;
WORD which;
{
undoobj(tree, which, SELECTED);
}
VOID
doobj(tree, which, bit) /* set specified bit in object state */
LONG tree;
WORD which, bit;
{
WORD state;
state = LWGET(OBSTATE(which));
LWSET(OBSTATE(which), state | bit);
}
VOID
selobj(tree, which) /* turn on selected bit of spcfd object */
LONG tree;
WORD which;
{
doobj(tree, which, SELECTED);
}
BOOLEAN
statep(tree, which, bit)
LONG tree;
WORD which;
WORD bit;
{
return ( (LWGET(OBSTATE(which)) & bit) != 0);
}
BOOLEAN
selectp(tree, which)
LONG tree;
WORD which;
{
return statep(tree, which, SELECTED);
}
Appendix II - Sample radio buttons after dialog
/*
>>>>>>>>>>>>>>>>>>>>>> Sample radio buttons after dialog <<<<<<<<<<<<<<<<<<<<
*/
WORD
encode(tree, ob1st, num)
LONG tree;
WORD ob1st, num;
{
for (; num--; )
if (selectp(ob1st+num))
return(num);
return (-1);
}
Appendix III - Sample C output file from RCS
/*
>>>>>>>>>>>>>>>>>>>>>>>>>> Sample C output file from RCS <<<<<<<<<<<<<<<<<<<<
*/
/* (Comments added) */
BYTE *rsstrings[] = { /* ASCII data */
"Title String",
"Exit",
"Centered Text",
"",
"",
"Butt",
"Tokyo",
"",
"Time: _:_:_",
"999999",
"",
"Time: _:_:_ ",
"999999",
"New York"};
WORD IMAG0[] = { /* Bitmap for GIMAGE */
0x7FF, 0xFFFF, 0xFF80, 0xC00,
0x0, 0xC0, 0x183F, 0xF03F,
0xF060, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x187F, 0xF860,
0x1860, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x187F, 0xF860,
0x1860, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x183F, 0xF03F,
0xF060, 0xC00, 0x0, 0xC0,
0x7FF, 0xFFFF, 0xFF80, 0x0,
0x0, 0x0, 0x3F30, 0xC787,
0x8FE0, 0xC39, 0xCCCC, 0xCC00,
0xC36, 0xCFCC, 0xF80, 0xC30,
0xCCCD, 0xCC00, 0x3F30, 0xCCC7,
0xCFE0, 0x0, 0x0, 0x0};
WORD IMAG1[] = { /* Mask for first icon */
0x0, 0x0, 0x0, 0x0,
0x7FFE, 0x0, 0x1F, 0xFFFF,
0xFC00, 0xFF, 0xFFFF, 0xFF00,
0x3FF, 0xFFFF, 0xFFC0, 0xFFF,
0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,
0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,
0xFFFC, 0xFFF, 0xFFFF, 0xFFF0,
0x3FF, 0xFFFF, 0xFFC0, 0xFF,
0xFFFF, 0xFF00, 0x1F, 0xFFFF,
0xF800, 0x0, 0x7FFE, 0x0};
WORD IMAG2[] = { /* Data for first icon */
0x0, 0x0, 0x0, 0x0,
0x3FFC, 0x0, 0xF, 0xC003,
0xF000, 0x78, 0x180, 0x1E00,
0x180, 0x180, 0x180, 0x603,
0x180, 0xC060, 0x1C00, 0x6,
0x38, 0x3000, 0x18C, 0xC,
0x60C0, 0x198, 0x306, 0x6000,
0x1B0, 0x6, 0x4000, 0x1E0,
0x2, 0xC000, 0x1C0, 0x3,
0xCFC0, 0x180, 0x3F3, 0xC000,
0x0, 0x3, 0x4000, 0x0,
0x2, 0x6000, 0x0, 0x6,
0x60C0, 0x0, 0x306, 0x3000,
0x0, 0xC, 0x1C00, 0x0,
0x38, 0x603, 0x180, 0xC060,
0x180, 0x180, 0x180, 0x78,
0x180, 0x1E00, 0xF, 0xC003,
0xF000, 0x0, 0x3FFC, 0x0};
WORD IMAG3[] = { /* Mask for second icon */
0x0, 0x0, 0x0, 0x0,
0x7FFE, 0x0, 0x1F, 0xFFFF,
0xFC00, 0xFF, 0xFFFF, 0xFF00,
0x3FF, 0xFFFF, 0xFFC0, 0xFFF,
0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,
0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,
0xFFFC, 0xFFF, 0xFFFF, 0xFFF0,
0x3FF, 0xFFFF, 0xFFC0, 0xFF,
0xFFFF, 0xFF00, 0x1F, 0xFFFF,
0xF800, 0x0, 0x7FFE, 0x0};
WORD IMAG4[] = { /* Data for second icon */
0x0, 0x0, 0x0, 0x0,
0x3FFC, 0x0, 0xF, 0xC003,
0xF000, 0x78, 0x180, 0x1E00,
0x180, 0x180, 0x180, 0x603,
0x180, 0xC060, 0x1C00, 0x6,
0x38, 0x3000, 0x18C, 0xC,
0x60C0, 0x198, 0x306, 0x6000,
0x1B0, 0x6, 0x4000, 0x1E0,
0x2, 0xC000, 0x1C0, 0x3,
0xCFC0, 0x180, 0x3F3, 0xC000,
0x0, 0x3, 0x4000, 0x0,
0x2, 0x6000, 0x0, 0x6,
0x60C0, 0x0, 0x306, 0x3000,
0x0, 0xC, 0x1C00, 0x0,
0x38, 0x603, 0x180, 0xC060,
0x180, 0x180, 0x180, 0x78,
0x180, 0x1E00, 0xF, 0xC003,
0xF000, 0x0, 0x3FFC, 0x0};
LONG rsfrstr[] = { /* Free string index - unused */
0};
BITBLK rsbitblk[] = { /* First entry is index to image data */
0L, 6, 24, 0, 0, 0};
LONG rsfrimg[] = { /* Free image index - unused */
0};
ICONBLK rsiconblk[] = {
1L, 2L, 10L, 4096,0,0, 0,0,48,24, 9,24,30,8, /* First pointer is mask */
3L, 4L, 17L, 4864,0,0, 0,0,48,24, 0,24,48,8}; /* Second is data, third */
/* is to title string */
TEDINFO rstedinfo[] = {
2L, 3L, 4L, 3, 6, 2, 0x1180, 0x0, -1, 14,1, /* First pointer is text */
7L, 8L, 9L, 3, 6, 2, 0x2072, 0x0, -3, 11,1, /* Second is template */
11L, 12L, 13L, 3, 6, 0, 0x1180, 0x0, -1, 1,15, /* Third is validation */
14L, 15L, 16L, 3, 6, 1, 0x1173, 0x0, 0, 1,17};
OBJECT rsobject[] = {
-1, 1, 3, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 18,12, /* Pointers are to: */
2, -1, -1, GSTRING, NONE, NORMAL, 0x0L, 3,1, 12,1, /* rsstrings */
3, -1, -1, GBUTTON, 0x7, NORMAL, 0x1L, 5,9, 8,1, /* rsstrings */
0, 4, 4, GBOX, NONE, NORMAL, 0xFF1172L, 3,3, 12,5,
3, -1, -1, GIMAGE, LASTOB, NORMAL, 0x0L, 3,1, 6,3, /* rsbitblk */
-1, 1, 6, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 23,12,
2, -1, -1, GTEXT, NONE, NORMAL, 0x0L, 0,1, 23,1, /* rstedinfo */
6, 3, 5, GIBOX, NONE, NORMAL, 0x1100L, 6,3, 11,5,
4, -1, -1, GBUTTON, 0x11, NORMAL, 0x5L, 0,0, 11,1, /* rsstrings */
5, -1, -1, GBUTTON, 0x11, NORMAL, 0x6L, 0,2, 11,1, /* rsstrings */
2, -1, -1, GBOXCHAR, 0x11, NORMAL, 0x43FF1400L, 0,4, 11,1,
0, -1, -1, GBOXTEXT, 0x27, NORMAL, 0x1L, 5,9, 13,1, /* rstedinfo */
-1, 1, 3, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 32,11,
2, -1, -1, GICON, NONE, NORMAL, 0x0L, 4,1, 6,4, /* rsiconblk */
3, -1, -1, GFTEXT, EDITABLE, NORMAL, 0x2L, 12,2, 14,1, /* rstedinfo */
0, 4, 4, GFBOXTEXT, 0xE, NORMAL, 0x3L, 3,5, 25,4, /* rstedinfo */
3, -1, -1, GICON, LASTOB, NORMAL, 0x1L, 1,0, 6,4}; /* rsiconblk */
LONG rstrindex[] = { /* Points to start of trees in */
0L, /* rsobject */
5L,
12L};
struct foobar { /* Temporary structure used by */
WORD dummy; /* RSCREATE when setting up image */
WORD *image; /* pointers. */
} rsimdope[] = {
0, &IMAG0[0],
0, &IMAG1[0],
0, &IMAG2[0],
0, &IMAG3[0],
0, &IMAG4[0]};
/* Counts of structures defined */
#define NUMSTRINGS 18
#define NUMFRSTR 0
#define NUMIMAGES 5
#define NUMBB 1
#define NUMFRIMG 0
#define NUMIB 2
#define NUMTI 4
#define NUMOBS 17
#define NUMTREE 3
BYTE pname[] = "DEMO.RSC";
Appendix III - Title change utility
/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Title change utility <<<<<<<<<<<<<<<<<<<<<
*/
VOID
settext(tree, obj, str)
LONG tree, str;
WORD obj;
{
LONG obspec;
obspec = LLGET(OBSPEC(obj)); /* Get TEDINFO address */
LLSET(TEPTEXT(obspec), str); /* Set new text pointer */
LWSET(TETXTLEN(obspec), LSTRLEN(str)); /* Set new length */
}
Appendix III - Text edit code segment
/*
>>>>>>>>>>>>>>>>>>>>>> Text edit code segment <<<<<<<<<<<<<<<<<<<<<<<<<<
*/
LONG tree, obspec;
BYTE text[41];
rsrcgaddr(RTREE, DIALOG, &tree); /* Get tree address */
obspec = LLGET(OBSPEC(EDITOBJ)); /* Get TEDINFO address */
LLSET(TEPTEXT(obspec), ADDR(str)); /* Set new text pointer */
LWSET(TETXTLEN(obspec), 41); /* Set max length */
text[0] = '\0'; /* Make empty string */
Appendix III - Sample 68K only source code
/*
>>>>>>>>>>>>>>>>>>>> Sample 68K only source code <<<<<<<<<<<<<<<<<<<<<<
*/
VOID
settext(tree, obj, str)
OBJECT *tree;
WORD obj;
BYTE *str;
{
TEDINFO *obspec;
obspec = (TEDINFO *) (tree + obj)->obspec;
/* Get TEDINFO address */
obspec->teptext = str; /* Set new text pointer */
obspec->tetxtlen = strlen(str); /* Set new length */
}
Appendix III - Symbol definitions
/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Symbol definitions <<<<<<<<<<<<<<<<<<<<<<<<<
*/
/* Window parts */
#define NAME 0x0001
#define CLOSER 0x0002
#define FULLER 0x0004
#define MOVER 0x0008
#define INFO 0x0010
#define SIZER 0x0020
#define UPARROW 0x0040
#define DNARROW 0x0080
#define VSLIDE 0x0100
#define LFARROW 0x0200
#define RTARROW 0x0400
#define HSLIDE 0x0800
#define WFKIND 1 /* windget/set parameters */
#define WFNAME 2
#define WFINFO 3
#define WFWXYWH 4
#define WFCXYWH 5
#define WFPXYWH 6
#define WFFXYWH 7
#define WFHSLIDE 8
#define WFVSLIDE 9
#define WFTOP 10
#define WFFIRSTXYWH 11
#define WFNEXTXYWH 12
#define WFNEWDESK 14
#define WFHSLSIZ 15
#define WFVSLSIZ 16
/* window messages */
#define WMREDRAW 20
#define WMTOPPED 21
#define WMCLOSED 22
#define WMFULLED 23
#define WMARROWED 24
#define WMHSLID 25
#define WMVSLID 26
#define WMSIZED 27
#define WMMOVED 28
#define WMNEWTOP 29
/* arrow messages */
#define WAUPPAGE 0
#define WADNPAGE 1
#define WAUPLINE 2
#define WADNLINE 3
#define WALFPAGE 4
#define WARTPAGE 5
#define WALFLINE 6
#define WARTLINE 7
#define RTREE 0 /* Redraw definitions */
#define ROOT 0
#define MAXDEPTH 8
/* update flags */
#define ENDUPDATE 0
#define BEGUPDATE 1
#define ENDMCTRL 2
#define BEGMCTRL 3
/* Mouse state changes */
#define MOFF 256
#define MON 257
/* Object flags */
#define NONE 0x0
#define SELECTABLE 0x1
#define DEFAULT 0x2
#define EXIT 0x4
#define EDITABLE 0x8
#define RBUTTON 0x10
/* Object states */
#define SELECTED 0x1
#define CROSSED 0x2
#define CHECKED 0x4
#define DISABLED 0x8
#define OUTLINED 0x10
#define SHADOWED 0x20
#define GBOX 20
#define GTEXT 21
#define GBOXTEXT 22
#define GIMAGE 23
#define GIBOX 25
#define GBUTTON 26
#define GBOXCHAR 27
#define GSTRING 28
#define GFTEXT 29
#define GFBOXTEXT 30
#define GICON 31
#define GTITLE 32
/* Data structures */
typedef struct grect
{
int gx;
int gy;
int gw;
int gh;
} GRECT;
typedef struct object
{
int obnext; /* -> object's next sibling */
int obhead; /* -> head of object's children */
int obtail; /* -> tail of object's children */
unsigned int obtype; /* type of object- BOX, CHAR,...*/
unsigned int obflags; /* flags */
unsigned int obstate; /* state- SELECTED, OPEN, ... */
long obspec; /* "out"- -> anything else */
int obx; /* upper left corner of object */
int oby; /* upper left corner of object */
int obwidth; /* width of obj */
int obheight; /* height of obj */
} OBJECT;
typedef struct textedinfo
{
long teptext; /* ptr to text (must be 1st) */
long teptmplt; /* ptr to template */
long tepvalid; /* ptr to validation chrs. */
int tefont; /* font */
int tejunk1; /* junk word */
int tejust; /* justification- left, right...*/
int tecolor; /* color information word */
int tejunk2; /* junk word */
int tethickness; /* border thickness */
int tetxtlen; /* length of text string */
int tetmplen; /* length of template string */
} TEDINFO;
/* "Portable" data definitions */
#define OBNEXT(x) (tree + (x) * sizeof(OBJECT) + 0)
#define OBHEAD(x) (tree + (x) * sizeof(OBJECT) + 2)
#define OBTAIL(x) (tree + (x) * sizeof(OBJECT) + 4)
#define OBTYPE(x) (tree + (x) * sizeof(OBJECT) + 6)
#define OBFLAGS(x) (tree + (x) * sizeof(OBJECT) + 8)
#define OBSTATE(x) (tree + (x) * sizeof(OBJECT) + 10)
#define OBSPEC(x) (tree + (x) * sizeof(OBJECT) + 12)
#define OBX(x) (tree + (x) * sizeof(OBJECT) + 16)
#define OBY(x) (tree + (x) * sizeof(OBJECT) + 18)
#define OBWIDTH(x) (tree + (x) * sizeof(OBJECT) + 20)
#define OBHEIGHT(x) (tree + (x) * sizeof(OBJECT) + 22)
#define TEPTEXT(x) (x)
#define TETXTLEN(x) (x + 24)
Appendix IV - Sample object trees
/*
>>>>>>>>>>>>>>>>>>>>>>>>>>> Sample object trees <<<<<<<<<<<<<<<<<<<<<<<<
*/
OBJECT rsobject[] = {
-1, 1, 3, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 18,12, /* Tree # 1 */
2, -1, -1, GSTRING, NONE, NORMAL, 0x0L, 3,1, 12,1,
3, -1, -1, GBUTTON, 0x7, NORMAL, 0x1L, 5,9, 8,1,
0, 4, 4, GBOX, NONE, NORMAL, 0xFF1172L, 3,3, 12,5,
3, -1, -1, GIMAGE, LASTOB, NORMAL, 0x0L, 3,1, 6,3,
-1, 1, 6, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 23,12, /* Tree # 2 */
2, -1, -1, GTEXT, NONE, NORMAL, 0x0L, 0,1, 23,1,
6, 3, 5, GIBOX, NONE, NORMAL, 0x1100L, 6,3, 11,5,
4, -1, -1, GBUTTON, 0x11, NORMAL, 0x5L, 0,0, 11,1,
5, -1, -1, GBUTTON, 0x11, NORMAL, 0x6L, 0,2, 11,1,
2, -1, -1, GBOXCHAR, 0x11, NORMAL, 0x43FF1400L, 0,4, 11,1,
0, -1, -1, GBOXTEXT, 0x27, NORMAL, 0x1L, 5,9, 13,1,
-1, 1, 3, GBOX, NONE, OUTLINED, 0x21100L, 0,0, 32,11, /* Tree # 3 */
2, -1, -1, GICON, NONE, NORMAL, 0x0L, 4,1, 6,4,
3, -1, -1, GFTEXT, EDITABLE, NORMAL, 0x2L, 12,2, 14,1,
0, 4, 4, GFBOXTEXT, 0xE, NORMAL, 0x3L, 3,5, 25,4,
3, -1, -1, GICON, LASTOB, NORMAL, 0x1L, 1,0, 6,4};
Appendix IV - Object tree walk utility
/*
>>>>>>>>>>>>>>>>>>>>>>>>>> Object tree walk utility <<<<<<<<<<<<<<<<<<<<<<
*/
VOID
maptree(tree, this, last, routine)
LONG tree;
WORD this, last;
WORD (*routine)();
{
WORD tmp1;
tmp1 = this; /* Initialize to impossible value: */
/* TAIL won't point to self! */
/* Look until final node, or off */
/* the end of tree */
while (this != last && this != NIL)
/* Did we 'pop' into this node */
/* for the second time? */
if (LWGET(OBTAIL(this)) != tmp1)
{
tmp1 = this; /* This is a new node */
this = NIL;
/* Apply operation, testing */
/* for rejection of sub-tree */
if ((*routine)(tree, tmp1))
this = LWGET(OBHEAD(tmp1));
/* Subtree path not taken, */
/* so traverse right */
if (this == NIL)
this = LWGET(OBNEXT(tmp1));
}
else /* Revisiting parent: */
/* No operation, move right */
{
tmp1 = this;
this = LWGET(OBNEXT(tmp1));
}
}
Appendix IV - Sample routine to use with maptree()
/*
>>>>>>>>>>>>>>>>>> Sample routine to use with maptree() <<<<<<<<<<<<<<<
*/
VOID
undoobj(tree, which, bit) /* clear specified bit in object state */
LONG tree;
WORD which, bit;
{
WORD state;
state = LWGET(OBSTATE(which));
LWSET(OBSTATE(which), state & ~bit);
}
VOID
deselobj(tree, which) /* turn off selected bit of spcfd object*/
LONG tree;
WORD which;
{
undoobj(tree, which, SELECTED);
return (TRUE);
}
Appendix IV - Sample .ICN Files
/*
>>>>>>>>>>>>>>>>>>>>>>>>>> Sample .ICN Files <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>> Save everything between >>><<< lines as CLOCK.ICN <<<<<<<<<<<<<<
*/
/* GEM Icon Definition: */
#define ICONW 0x0030
#define ICONH 0x0018
#define DATASIZE 0x0048
UWORD clock[DATASIZE] =
{ 0x0000, 0x0000, 0x0000, 0x0000,
0x3FFC, 0x0000, 0x000F, 0xC003,
0xF000, 0x0078, 0x0180, 0x1E00,
0x0180, 0x0180, 0x0180, 0x0603,
0x0180, 0xC060, 0x1C00, 0x0006,
0x0038, 0x3000, 0x018C, 0x000C,
0x60C0, 0x0198, 0x0306, 0x6000,
0x01B0, 0x0006, 0x4000, 0x01E0,
0x0002, 0xC000, 0x01C0, 0x0003,
0xCFC0, 0x0180, 0x03F3, 0xC000,
0x0000, 0x0003, 0x4000, 0x0000,
0x0002, 0x6000, 0x0000, 0x0006,
0x60C0, 0x0000, 0x0306, 0x3000,
0x0000, 0x000C, 0x1C00, 0x0000,
0x0038, 0x0603, 0x0180, 0xC060,
0x0180, 0x0180, 0x0180, 0x0078,
0x0180, 0x1E00, 0x000F, 0xC003,
0xF000, 0x0000, 0x3FFC, 0x0000
};
/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> End of CLOCK.ICN <<<<<<<<<<<<<<<<<<<<<<<<<<
*/
/*
>>>>>>>>> Save everything between >>>><<<<< lines as CLOCKM.ICN <<<<<<<<<<
*/
/* GEM Icon Definition: */
#define ICONW 0x0030
#define ICONH 0x0018
#define DATASIZE 0x0048
UWORD clockm[DATASIZE] =
{ 0x0000, 0x0000, 0x0000, 0x0000,
0x7FFE, 0x0000, 0x001F, 0xFFFF,
0xFC00, 0x00FF, 0xFFFF, 0xFF00,
0x03FF, 0xFFFF, 0xFFC0, 0x0FFF,
0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,
0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,
0xFFFC, 0x0FFF, 0xFFFF, 0xFFF0,
0x03FF, 0xFFFF, 0xFFC0, 0x00FF,
0xFFFF, 0xFF00, 0x001F, 0xFFFF,
0xF800, 0x0000, 0x7FFE, 0x0000
};
/*
>>>>>>>>>>>>>>>>>>>>>>>>> End of CLOCKM.ICN <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*/
Appendix V - MFDB Structure
/* >>>>>>>>>>>>>>>>>>>>>>>>>>> MFDB Structure <<<<<<<<<<<<<<<<<<<<<<<<<< */
/* Memory Form Definition Block */
typedef struct fdbstr
{
long fdaddr; /* Form address */
int fdw; /* Form width in pixels */
int fdh; /* Form height in pixels */
int fdwdwidth; /* Form width in memory words */
int fdstand; /* Standard form flag */
int fdnplanes; /* Number of color planes */
int fdr1; /* Dummy locations: */
int fdr2; /* Reserved for future use */
int fdr3;
} MFDB;
Appendix V - Resource Transform Utilities
/* >>>>>>>>>>>>>>>>>>>> Resource Transform Utilities <<<<<<<<<<<<<<<<<< */
/*------------------------------*/
/* vdifix */
/*------------------------------*/
VOID
vdifix(pfd, theaddr, wb, h) /* This routine loads the MFDB */
MFDB *pfd; /* Input values are the MFDB's */
LONG theaddr; /* address, the form's address,*/
WORD wb, h; /* the form's width in bytes, */
{ /* and the height in pixels */
pfd->fww = wb >> 1;
pfd->fwp = wb << 3;
pfd->fh = h;
pfd->np = 1; /* Monochrome assumed */
pfd->mp = theaddr;
}
/*------------------------------*/
/* vditrans */
/*------------------------------*/
WORD
vditrans(saddr, swb, daddr, dwb, h) /* Transform the standard form */
LONG saddr; /* pointed at by saddr and */
UWORD swb; /* store in the form at daddr */
LONG daddr; /* Byte widths and pixel height*/
UWORD dwb; /* are given */
UWORD h;
{
MFDB src, dst; /* These are on-the-fly MFDBs */
vdifix(&src, saddr, swb, h); /* Load the source MFDB */
src.ff = TRUE; /* Set it's std form flag */
vdifix(&dst, daddr, dwb, h); /* Load the destination MFDB */
dst.ff = FALSE; /* Clear the std flag */
vrtrnfm(vdihandle, &src, &dst ); /* Call the VDI */
}
/*------------------------------*/
/* transbitblk */
/*------------------------------*/
VOID
transbitblk(obspec) /* Transform the image belonging */
LONG obspec; /* to the bitblk pointed to by */
{ /* obspec. This routine may also*/
LONG taddr; /* be used with free images */
WORD wb, hl;
if ( (taddr = LLGET(BIPDATA(obspec))) == -1L)
return; /* Get and validate image address */
wb = LWGET(BIWB(obspec)); /* Extract image dimensions */
hl = LWGET(BIHL(obspec));
vditrans(taddr, wb, taddr, wb, hl); /* Perform a transform */
} /* in place */
/*------------------------------*/
/* transobj */
/*------------------------------*/
VOID
transobj(tree, obj) /* Examine the input object. If */
LONG tree; /* it is an icon or image, trans- */
WORD obj; /* form the associated raster */
{ /* forms in place. */
WORD type, wb, hl; /* This routine may be used with */
LONG taddr, obspec; /* maptree() to transform an */
/* entire resource tree */
type = LLOBT(LWGET(OBTYPE(obj))); /* Load object type */
if ( (obspec = LLGET(OBSPEC(obj))) == -1L) /* Load and check */
return (TRUE); /* obspec pointer */
switch (type) {
case GIMAGE:
transbitblk(obspec); /* Transform image */
return (TRUE);
case GICON: /* Load icon size */
hl = LWGET(IBHICON(obspec));
wb = (LWGET(IBWICON(obspec)) + 7) >> 3;
/* Transform data */
if ( (taddr = LLGET(IBPDATA(obspec))) != -1L)
vditrans(taddr, wb, taddr, wb, hl);
/* Transform mask */
if ( (taddr = LLGET(IBPMASK(obspec))) != -1L)
vditrans(taddr, wb, taddr, wb, hl);
return (TRUE);
default:
return (TRUE);
}
}
/* >>>>>>>>>>>>>>>> Macro definitions for the code above <<<<<<<<<<<<<<< */
#define BIPDATA(x) (x)
#define BIWB(x) (x + 4)
#define BIHL(x) (x + 6)
#define OBTYPE(x) (tree + (x) * sizeof(OBJECT) + 6)
#define OBSPEC(x) (tree + (x) * sizeof(OBJECT) + 12)
#define IBPMASK(x) (x)
#define IBPDATA(x) (x + 4)
#define IBWICON(x) (x + 22)
#define IBHICON(x) (x + 24)
Appendix V - VDI Copy Mode Table
/* >>>>>>>>>>>>>>>>>>>>>>>> VDI Copy Mode Table <<<<<<<<<<<<<<<<<<<<<<<<< */
Symbols: N = new destination pixel value (0 or 1)
D = old destination pixel value (0 or 1)
S = source pixel value (0 or 1)
~ = Boolean not (inversion)
& = Boolean and
| = Boolean or
^ = Boolean xor (exclusive-or)
Mode Number Action
---------- ------
0 N = 0 (USE VBAR INSTEAD)
1 N = S & D
2 N = S & ~D
3 N = S (REPLACE)
4 N = ~S & D (ERASE)
5 N = D (USELESS)
6 N = S ^ D (XOR)
7 N = S | D (TRANSPARENT)
8 N = ~ (S | D)
9 N = ~ (S ^ D)
10 N = ~D (USE VBAR INSTEAD)
11 N = S | ~D
12 N = ~S
13 N = ~S | D (REVERSE TRANSPARENT)
14 N = ~ (S & D)
15 N = 1 (USE VBAR INSTEAD)
/* >>>>>>>>>>>>>>>>>>>>>>>> END OF DOWNLOAD <<<<<<<<<<<<<<<<<<<<<<<<<< */
Appendix VI - Download file for GEM column #7
/*
>>>>>>>>>>>>>>>>>>>>>> Download file for GEM column #7 <<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Sample Menu Tree <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*/
-1, 1, 6, GIBOX, NONE, NORMAL, 0x0L, 0,0, 80,25, /* ROOT */
6, 2, 2, GBOX, NONE, NORMAL, 0x1100L, 0,0, 80,513, /* THE BAR */
1, 3, 5, GIBOX, NONE, NORMAL, 0x0L, 2,0, 20,769, /* THE ACTIVE */
4, -1, -1, GTITLE, NONE, NORMAL, 0x0L, 0,0, 6,769, /* Title #1 */
5, -1, -1, GTITLE, NONE, NORMAL, 0x1L, 6,0, 6,769, /* Title #2 */
2, -1, -1, GTITLE, NONE, NORMAL, 0x2L, 12,0, 8,769, /* Title #3 */
0, 7, 22, GIBOX, NONE, NORMAL, 0x0L, 0,769, 80,19, /* THE SCREEN */
16, 8, 15, GBOX, NONE, NORMAL, 0xFF1100L, 2,0, 20,8, /* Drop-down #1 */
9, -1, -1, GSTRING, NONE, NORMAL, 0x3L, 0,0, 19,1, /* About... entry */
10, -1, -1, GSTRING, NONE, DISABLED, 0x4L, 0,1, 20,1,
11, -1, -1, GSTRING, NONE, NORMAL, 0x5L, 0,2, 20,1, /* Desk acc entries */
12, -1, -1, GSTRING, NONE, NORMAL, 0x6L, 0,3, 20,1,
13, -1, -1, GSTRING, NONE, NORMAL, 0x7L, 0,4, 20,1,
14, -1, -1, GSTRING, NONE, NORMAL, 0x8L, 0,5, 20,1,
15, -1, -1, GSTRING, NONE, NORMAL, 0x9L, 0,6, 20,1,
7, -1, -1, GSTRING, NONE, NORMAL, 0xAL, 0,7, 20,1,
22, 17, 21, GBOX, NONE, NORMAL, 0xFF1100L, 8,0, 13,5, /* Drop-down #2 */
18, -1, -1, GSTRING, NONE, NORMAL, 0xBL, 0,0, 13,1,
19, -1, -1, GSTRING, NONE, DISABLED, 0xCL, 0,1, 13,1,
20, -1, -1, GSTRING, NONE, NORMAL, 0xDL, 0,4, 13,1,
21, -1, -1, GSTRING, NONE, NORMAL, 0xEL, 0,2, 13,1,
16, -1, -1, GSTRING, NONE, DISABLED, 0xFL, 0,3, 13,1,
6, 23, 25, GBOX, NONE, NORMAL, 0xFF1100L, 14,0, 26,3, /* Drop down #3 */
24, -1, -1, GSTRING, NONE, NORMAL, 0x10L, 0,2, 26,1,
25, -1, -1, GSTRING, NONE, NORMAL, 0x11L, 0,0, 26,1,
22, -1, -1, GSTRING, LASTOB, DISABLED, 0x12L, 0,1, 26,1
/*
>>>>>>>>>>>>>>>>>>>>>>>> Menu enable/disable utility <<<<<<<<<<<<<<<<<<<<<<
*/
/*------------------------------*/
/* undoobj */
/*------------------------------*/
VOID
undoobj(tree, which, bit)
LONG tree;
WORD which;
UWORD bit;
{
WORD state;
state = LWGET(OBSTATE(which));
LWSET(OBSTATE(which), state & ~bit);
}
/*------------------------------*/
/* enabobj */
/*------------------------------*/
WORD
enabobj(tree, which)
LONG tree;
WORD which;
{
undoobj(tree, which, (UWORD) DISABLED);
return (TRUE);
}
/*------------------------------*/
/* doobj */
/*------------------------------*/
VOID
doobj(tree, which, bit)
LONG tree;
WORD which;
UWORD bit;
{
WORD state;
state = LWGET(OBSTATE(which));
LWSET(OBSTATE(which), state | bit);
}
/*------------------------------*/
/* disabobj */
/*------------------------------*/
WORD
disabobj(tree, which)
LONG tree;
WORD which;
{
doobj(tree, which, (UWORD) DISABLED);
return (TRUE);
}
/*------------------------------*/
/* setmenu */
/*------------------------------*/
VOID
setmenu(tree, change) /* change[0] TRUE selects all entries*/
LONG tree; /* FALSE deselects all. Change list */
WORD *change; /* of items is then toggled. */
{
WORD dflt, screen, drop, obj;
dflt = *change++; /* What is default? */
screen = LWGET(OBTAIL(ROOT)); /* Get SCREEN */
drop = LWGET(OBHEAD(screen)); /* Get DESK drop-down */
/* and skip it */
for (; (drop = LWGET(OBNEXT(drop))) != screen; )
{
obj = LWGET(OBHEAD(drop));
if (obj != NIL)
if (dflt)
maptree(tree, obj, drop, enabobj);
else
maptree(tree, obj, drop, disabobj);
}
for (; *change; change++)
if (dflt)
disabobj(tree, *change);
else
enabobj(tree, *change);
}
/*
>>>>>>>>>>>>>>>>>>>>> Definitions used in this article <<<<<<<<<<<<<<<<<<<<<<
*/
#define ROOT 0
#define GIBOX 25
#define GSTRING 28
#define GTITLE 32
#define RTREE 0
#define MNSELECTED 10
#define CHECKED 0x4
#define DISABLED 0x8
#define OBNEXT(x) (tree + (x) * sizeof(OBJECT) + 0)
#define OBHEAD(x) (tree + (x) * sizeof(OBJECT) + 2)
#define OBTAIL(x) (tree + (x) * sizeof(OBJECT) + 4)
#define OBTYPE(x) (tree + (x) * sizeof(OBJECT) + 6)
#define OBFLAGS(x) (tree + (x) * sizeof(OBJECT) + 8)
#define OBSTATE(x) (tree + (x) * sizeof(OBJECT) + 10)
#define OBSPEC(x) (tree + (x) * sizeof(OBJECT) + 12)
#define OBX(x) (tree + (x) * sizeof(OBJECT) + 16)
#define OBY(x) (tree + (x) * sizeof(OBJECT) + 18)
#define OBWIDTH(x) (tree + (x) * sizeof(OBJECT) + 20)
#define OBHEIGHT(x) (tree + (x) * sizeof(OBJECT) + 22)
#define MOFF 256
#define MON 257
Appendix VII - Routines to set clip to a GRECT
/*
>>>>>>>>>>>>>>>> Routines to set clip to a GRECT <<<<<<<<<<<<<<<<
*/
VOID
grecttoarray(area, array) /* convert x,y,w,h to upr lt x,y and */
GRECT *area; /* lwr rt x,y */
WORD *array;
{
*array++ = area->gx;
*array++ = area->gy;
*array++ = area->gx + area->gw - 1;
*array = area->gy + area->gh - 1;
}
VOID
setclip(clipflag, sarea) /* set clip to specified area */
WORD clipflag;
GRECT *sarea;
{
WORD pxy[4];
grecttoarray(sarea, pxy);
vsclip(vdihandle, clipflag, pxy);
}
Appendix VII - Routines to set attributes before output
/*
>>>>>>>>>> Routines to set attributes before output <<<<<<<<<<<<
*/
VOID
rrperim(mode, color, type, width, pxy) /* Draw a rounded */
WORD mode, color, width, *pxy; /* rectangle outline */
{
vswrmode(vdihandle, mode);
vslcolor(vdihandle, color);
vsltype(vdihandle, type);
vslwidth(vdihandle, width);
vrbox(vdihandle, pxy);
vswrmode(vdihandle, MDREPLACE);
}
VOID
plperim(mode, type, color, width, npts, pxy) /* Draw a polygonal */
/* figure */
WORD mode, type, color, width, npts, *pxy;
{
vswrmode(vdihandle, mode);
vsltype(vdihandle, type);
vslcolor(vdihandle, color);
vslwidth(vdihandle, width);
vpline(vdihandle, npts, pxy);
}
VOID /* Draw a filled polygonal area */
plfill(mode, perim, color, interior, style, npts, pxy)
WORD mode, perim, color, interior, style, npts, *pxy;
{
vswrmode(vdihandle, mode);
vsfcolor(vdihandle, color);
vsfstyle(vdihandle, style);
vsfinterior(vdihandle, interior);
vsfperimeter(vdihandle, perim);
vfillarea(vdihandle, npts, pxy);
}
VOID /* Draw a filled rectangle */
rectfill(mode, perim, color, interior, style, pxy)
WORD mode, perim, color, style, interior, *pxy;
{
vswrmode(vdihandle, mode);
vsfcolor(vdihandle, color);
vsfstyle(vdihandle, style);
vsfinterior(vdihandle, interior);
vsfperimeter(vdihandle, perim);
vrrecfl(vdihandle, pxy);
}
Appendix VIII - Demonstration of byte alignment of window interior
/*
>>>>>>>>>>> Demonstration of byte alignment of window interior <<<<<<<<<<<
*/
#define FEATURES 0x0fef /* what border features are used */
WORD msg[8]; /* message from evntmulti */
GRECT workarea; /* defines working area */
WORD whndl; /* handle for window being changed */
windcalc(1, FEATURES, msg[4], msg[5], msg[6], msg[7],
&workarea.gx, &workarea.gy, &workarea.gw,
&workarea.gh);
workarea.gx = alignx(workarea.gx);
workarea.gw = alignx(workarea.gw);
windcalc(0, FEATURES, workarea.gx, workarea.gy,
workarea.gw, workarea.gh, &msg[4], &msg[5],
&msg[6], &msg[7]);
windset(whndl, WFCXYWH, msg[4], msg[5], msg[6], msg[7]);
/*
>>>>>>>>>>>>>>>>>>>>> Subroutine for above <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*/
WORD
alignx(x) /* forces word alignment for column position */
WORD x; /* rounding to nearest word */
{
return((x & 0xfff0) + ((x & 0x0008) ? 0x0010 : 0));
}
/*
>>>>>>>>>>>>>>>>>>>>> Standard vgtext binding <<<<<<<<<<<<<<<<<<<<<<<<<
*/
WORD
vgtext( handle, x, y, string)
WORD handle, x, y;
BYTE *string;
{
WORD i;
ptsin[0] = x;
ptsin[1] = y;
i = 0;
while (intin[i++] = *string++) /* Copy characters to intin */
; /* There is NO error checking! */
contrl[0] = 8;
contrl[1] = 1;
contrl[3] = --i;
contrl[6] = handle;
vdi();
}