Professional GEM - Appendices
Professional GEM Appendix I 78 Appendix I Sample Code Part I /* >>>>>>>>>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix I 79 /* >>>>>>>>>>>>>>>>>>>>>>>> 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) ); } Professional GEM Appendix I 80 /* >>>>>>>>>>>>>>>>>>>>>>> "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 */ } Professional GEM Appendix I 81 /* >>>>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix I 82 /* >>>>>>>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix II 83 Appendix II Sample Code Part II /* >>>>>>>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix II 84 /* >>>>>>>>>>>>>>>>>>>>>>> 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)); } Professional GEM Appendix II 85 /* >>>>>>>>>>>>>>>>>>>>>>> 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 Professional GEM Appendix II 86 selectp(tree, which) LONG tree; WORD which; { return statep(tree, which, SELECTED); } Professional GEM Appendix II 87 /* >>>>>>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix III 88 Appendix III Sample Code Part IV /* >>>>>>>>>>>>>>>>>>>>>>>>>> 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, Professional GEM Appendix III 89 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}; Professional GEM Appendix III 90 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, Professional GEM Appendix III 91 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"; Professional GEM Appendix III 92 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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 */ } Professional GEM Appendix III 93 /* >>>>>>>>>>>>>>>>>>>>>> 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 */ Professional GEM Appendix III 94 /* >>>>>>>>>>>>>>>>>>>> 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 */ } Professional GEM Appendix III 95 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>> 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 Professional GEM Appendix III 96 #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 */ Professional GEM Appendix III 97 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) Professional GEM Appendix IV 98 Appendix IV Sample Code Part V /* >>>>>>>>>>>>>>>>>>>>>>>>>>> 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}; Professional GEM Appendix IV 99 /* >>>>>>>>>>>>>>>>>>>>>>>>>> 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)); } } Professional GEM Appendix IV 100 /* >>>>>>>>>>>>>>>>>> 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); } Professional GEM Appendix IV 101 /* >>>>>>>>>>>>>>>>>>>>>>>>>> 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 <<<<<<<<<<<<<<<<<<<<<<<<<< */ Professional GEM Appendix IV 102 /* >>>>>>>>> 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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ Professional GEM Appendix V 103 Appendix V Sample Code Part VI /* >>>>>>>>>>>>>>>>>>>>>>>>>>> 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; Professional GEM Appendix V 104 /* >>>>>>>>>>>>>>>>>>>> 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)); Professional GEM Appendix V 105 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); } } Professional GEM Appendix V 106 /* >>>>>>>>>>>>>>>> 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) Professional GEM Appendix V 107 /* >>>>>>>>>>>>>>>>>>>>>>>> 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 <<<<<<<<<<<<<<<<<<<<<<<<<< */ Professional GEM Appendix VI 108 Appendix VI Sample Code Part VII /* >>>>>>>>>>>>>>>>>>>>>> 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 Professional GEM Appendix VI 109 /* >>>>>>>>>>>>>>>>>>>>>>>> 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; Professional GEM Appendix VI 110 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); } Professional GEM Appendix VI 111 /* >>>>>>>>>>>>>>>>>>>>> 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 Professional GEM Appendix VII 112 Appendix VII Sample Code Part IX /* >>>>>>>>>>>>>>>> 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); } Professional GEM Appendix VII 113 /* >>>>>>>>>> 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); } Professional GEM Appendix VIII 114 Appendix VIII Sample Code Part X /* >>>>>>>>>>> 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]); Professional GEM Appendix VIII 115 /* >>>>>>>>>>>>>>>>>>>>> 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)); } Professional GEM Appendix VIII 116 /* >>>>>>>>>>>>>>>>>>>>> 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(); }
Back to Professional_GEM