Difference between revisions of "Professional GEM - Appendices"

From AtariForumWiki2018
Jump to: navigation, search
 
Rb (talk)
Line 1: Line 1:
−
<pre>
+
{{Professional GEM}}
−
 
 
−
 
 
−
        Professional GEM           Appendix I                          78
 
−
 
 
−
 
 
−
                                  Appendix I
 
−
                            Sample Code Part I
 
  
 +
==Appendix I - Sample redraw code==
  
 +
<pre>
  
 
         /* >>>>>>>>>>>>>>>>>>>>>>>>> Sample Redraw Code <<<<<<<<<<<<<<<<<<<<<<<<<<< */
 
         /* >>>>>>>>>>>>>>>>>>>>>>>>> Sample Redraw Code <<<<<<<<<<<<<<<<<<<<<<<<<<< */
Line 48: Line 43:
 
         }
 
         }
  
 +
</pre>
  
  
 +
==Appendix I - Utilities used in doredraw==
  
−
 
+
     
−
 
+
<pre>
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
       
 
−
 
 
−
 
 
−
        Professional GEM          Appendix I                          79
 
−
 
 
  
 
         /* >>>>>>>>>>>>>>>>>>>>>>>> Utilities used in doredraw <<<<<<<<<<<<<<<<<<<< */
 
         /* >>>>>>>>>>>>>>>>>>>>>>>> Utilities used in doredraw <<<<<<<<<<<<<<<<<<<< */
Line 106: Line 92:
 
         }
 
         }
  
 +
</pre>
  
  
 +
==Appendix I - "Self-redraw" Utility==
  
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>>>>> "Self-redraw" Utility <<<<<<<<<<<<<<<<<<<<<<<<< */
  
−
 
+
         VOID
−
 
+
         sendredraw(wh, p)
−
 
+
         WORD    wh;
−
 
+
         GRECT  *p;
−
 
+
         {
−
 
+
                 WORD    msg[8];
−
 
 
−
       
 
−
 
 
−
 
 
−
        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[0] = WMREDRAW;              /* Defined in GEMBIND.H    */
Line 145: Line 120:
 
         }
 
         }
  
 +
</pre>
  
  
 +
==Appendix I - Utilities for Window Requests==
  
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>> 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);
 +
        }     
  
 +
</pre>
  
  
 +
==Appendix I - Window full utility==
  
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>>>>> 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);
 +
        }
  
 +
</pre>
  
  
 +
==Appendix II - Basic Dialog Handler==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>> 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);
 +
        }
  
 +
</pre>
  
  
 +
==Appendix II - Object rectangle utility==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>> 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));
 +
        }
  
 +
</pre>
 +
 +
 +
==Appendix II - Object flag utilities==
  
  
−
       
+
<pre>
−
 
+
 
−
 
+
         /*
−
         Professional GEM          Appendix I                          81
+
         >>>>>>>>>>>>>>>>>>>>>>> Object flag utilities <<<<<<<<<<<<<<<<<<<<<<<<<<<
−
 
+
        */
−
 
 
−
         /* >>>>>>>>>>>>>>>>>>>> Utilities for Window Requests <<<<<<<<<<<<<<<<<< */
 
  
 
         VOID
 
         VOID
−
         rcconstrain(pc, pt)
+
         undoobj(tree, which, bit)       /* clear specified bit in object state  */
−
         GRECT          *pc;
+
         LONG    tree;
−
         GRECT          *pt;
+
         WORD    which, bit;
 
         {
 
         {
−
                 if (pt->gx < pc->gx)
+
                 WORD    state;
−
                    pt->gx = pc->gx;
+
 
−
                 if (pt->gy < pc->gy)
+
                 state = LWGET(OBSTATE(which));
−
                    pt->gy = pc->gy;
+
                 LWSET(OBSTATE(which), state & ~bit);
−
                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
+
         VOID
−
         align(x,n)             /* Snap position x to an n-bit grid        */  
+
         deselobj(tree, which)           /* turn off selected bit of spcfd object*/
−
         WORD    x, n;   /* Use n = 16 for horizontal word alignment */
+
        LONG    tree;
 +
         WORD    which;
 
         {
 
         {
−
                 x += (n >> 2) - 1;              /* Round and... */
+
                 undoobj(tree, which, SELECTED);
−
                x = n * (x / n);                /* remove residue */
+
         }
−
                return (x);
 
−
         }      
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
  
 +
        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);
 +
        }
  
 +
</pre>
  
  
 +
==Appendix II - Sample radio buttons after dialog==
 +
       
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>> 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);
 +
        }
  
 +
</pre>
  
  
 +
==Appendix III - Sample C output file from RCS==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>> 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,  
−
        Professional GEM          Appendix I                          82
+
         0xF060, 0x187F, 0xF860, 0x1860,
−
 
+
         0x187F, 0xF860, 0x1860, 0x187F,  
−
 
+
        0xF860, 0x1860, 0x187F, 0xF860,  
−
        /* >>>>>>>>>>>>>>>>>>>>>>> Window full utility <<<<<<<<<<<<<<<<<<<<<<< */
+
        0x1860, 0x187F, 0xF860, 0x1860,  
−
 
+
        0x187F, 0xF860, 0x1860, 0x187F,  
−
         VOID
+
        0xF860, 0x1860, 0x187F, 0xF860,  
−
         hndlfull(wh)            /* depending on current window state, make window    */
+
        0x1860, 0x187F, 0xF860, 0x1860,  
−
         WORD    wh;    /*  full size -or- return to previous shrunken size */
+
        0x187F, 0xF860, 0x1860, 0x187F,  
−
         {              /* graf calls are optional special effects.          */
+
        0xF860, 0x1860, 0x183F, 0xF03F,  
−
                GRECT  prev;
+
        0xF060, 0xC00, 0x0, 0xC0,  
−
                GRECT  curr;
+
        0x7FF, 0xFFFF, 0xFF80, 0x0,  
−
                GRECT  full;
+
        0x0, 0x0, 0x3F30, 0xC787,  
−
 
+
         0x8FE0, 0xC39, 0xCCCC, 0xCC00,
−
                windget(wh, WFCXYWH, &curr.gx, &curr.gy, &curr.gw, &curr.gh);
+
         0xC36, 0xCFCC, 0xF80, 0xC30,
−
                windget(wh, WFPXYWH, &prev.gx, &prev.gy, &prev.gw, &prev.gh);
+
         0xCCCD, 0xCC00, 0x3F30, 0xCCC7,  
−
                windget(wh, WFFXYWH, &full.gx, &full.gy, &full.gw, &full.gh);
+
         0xCFE0, 0x0, 0x0, 0x0};
−
                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);
 
−
        }
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
  
 +
        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};
  
−
         Professional GEM          Appendix II                        83
+
         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    */
  
−
                                  Appendix II
+
        LONG rstrindex[] = {                    /* Points to start of trees in */
−
                            Sample Code Part II
+
        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";
 +
 +
</pre>
  
  
−
        /*
+
==Appendix III - Title change utility==
−
        >>>>>>>>>>>>>>>>>>>>>>> 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);
 
−
        }
 
−
 
 
−
 
 
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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        */
 +
                }
  
 +
</pre>
  
  
 +
==Appendix III - Text edit code segment==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>> 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 */
  
 +
</pre>
 +
       
  
 +
==Appendix III - Sample 68K only source code==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>> 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      */
 +
                }
  
 +
</pre>
  
  
 +
==Appendix III - Symbol definitions==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>>>> 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
−
         Professional GEM          Appendix II                        84
+
         #define GIMAGE  23
−
 
+
         #define GIBOX    25
−
 
+
         #define GBUTTON  26
−
         /*
+
         #define GBOXCHAR 27
−
         >>>>>>>>>>>>>>>>>>>>>>> Object rectangle utility <<<<<<<<<<<<<<<<<<<<<<<<<
+
         #define GSTRING  28
−
         */
+
         #define GFTEXT  29
−
 
+
         #define GFBOXTEXT 30
−
         VOID
+
         #define GICON   31
−
         objcxywh(tree, obj, p)          /* get x,y,w,h for specified object    */
+
         #define GTITLE   32
−
         LONG    tree;
+
                                                        /* Data structures      */
−
         WORD   obj;
+
         typedef struct grect
−
         GRECT   *p;
+
                {
−
         {
+
                 int    gx;
−
                 objcoffset(tree, obj, &p->gx, &p->gy);
+
                int    gy;
−
                 p->gw = LWGET(OBWIDTH(obj));
+
                 int    gw;
−
                 p->gh = LWGET(OBHEIGHT(obj));
+
                 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)
  
 +
</pre>
  
  
 +
==Appendix IV - Sample object trees==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>>> 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};     
  
 +
</pre>
  
  
 +
==Appendix IV - Object tree walk utility==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>> 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));
 +
                                }
 +
                }
 +
 +
</pre>
  
  
 +
==Appendix IV - Sample routine to use with maptree()==
  
−
       
 
−
 
−
 
−
        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
+
<pre>
−
         doobj(tree, which, bit) /* set specified bit in object state   */
+
 
−
        LONG    tree;
+
         /*
−
        WORD    which, bit;
+
        >>>>>>>>>>>>>>>>>> Sample routine to use with maptree() <<<<<<<<<<<<<<<
−
        {
+
        */
 +
                VOID
 +
         undoobj(tree, which, bit)       /* clear specified bit in object state */
 +
                LONG    tree;
 +
                WORD    which, bit;
 +
                {
 
                 WORD    state;
 
                 WORD    state;
  
 
                 state = LWGET(OBSTATE(which));
 
                 state = LWGET(OBSTATE(which));
−
                 LWSET(OBSTATE(which), state | bit);
+
                 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);
 
−
        }
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
  
 +
                VOID
 +
        deselobj(tree, which)          /* turn off selected bit of spcfd object*/
 +
                LONG    tree;
 +
                WORD    which;
 +
                {
 +
                undoobj(tree, which, SELECTED);
 +
                return (TRUE);
 +
                }
  
 +
</pre>
  
  
 +
==Appendix IV - Sample .ICN Files==
  
  
 +
<pre>
  
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>>>>>> 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 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 +
        */
  
 +
</pre>
  
  
 +
==Appendix V - MFDB Structure==
  
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>>>>>>>>> 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;
  
 +
</pre>
  
  
 +
==Appendix V - Resource Transform Utilities==
  
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>> 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)
  
 +
</pre>
  
  
−
       
+
==Appendix V - VDI Copy Mode Table==
−
 
+
          
−
 
 
−
        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);
 
−
         }
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
−
 
 
  
 +
<pre>
  
 +
        /* >>>>>>>>>>>>>>>>>>>>>>>> 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 <<<<<<<<<<<<<<<<<<<<<<<<<< */
  
 +
</pre>
  
  
 +
==Appendix VI - Download file for GEM column #7==
 +
       
  
 +
<pre>
 +
        /*
 +
        >>>>>>>>>>>>>>>>>>>>>> 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
  
−
         Professional GEM          Appendix III                        88
+
         #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 III
+
</pre>
−
                            Sample Code Part IV
+
 
 +
 
 +
==Appendix VII - Routines to set clip to a GRECT==
  
  
 +
<pre>
  
−
        /*
+
/*
−
         >>>>>>>>>>>>>>>>>>>>>>>>>> Sample C output file from RCS <<<<<<<<<<<<<<<<<<<<
+
         >>>>>>>>>>>>>>>> Routines to set clip to a GRECT <<<<<<<<<<<<<<<<
 
         */
 
         */
−
                                                /* (Comments added)    */
 
−
        BYTE *rsstrings[] = {                  /* ASCII data          */
 
−
        "Title String",
 
−
        "Exit",
 
−
        "Centered Text",
 
−
        "",
 
−
        "",
 
−
        "Butt",
 
−
        "Tokyo",
 
−
        "",
 
−
        "Time: _:_:_",
 
−
        "999999",
 
−
        "",
 
−
        "Time: _:_:_  ",
 
−
        "999999",
 
−
        "New York"};
 
  
−
         WORD IMAG0[] = {                                /* Bitmap for GIMAGE */
+
                VOID
−
        0x7FF, 0xFFFF, 0xFF80, 0xC00,  
+
         grecttoarray(area, array)    /* convert x,y,w,h to upr lt x,y and    */
−
        0x0, 0xC0, 0x183F, 0xF03F,  
+
                GRECT  *area;          /*                    lwr rt x,y        */
−
        0xF060, 0x187F, 0xF860, 0x1860,
+
                WORD    *array;
−
        0x187F, 0xF860, 0x1860, 0x187F,
+
                {
−
        0xF860, 0x1860, 0x187F, 0xF860,
+
                *array++ = area->gx;
−
        0x1860, 0x187F, 0xF860, 0x1860,
+
                *array++ = area->gy;
−
        0x187F, 0xF860, 0x1860, 0x187F,
+
                *array++ = area->gx + area->gw - 1;
−
        0xF860, 0x1860, 0x187F, 0xF860,
+
                *array = area->gy + area->gh - 1;
−
        0x1860, 0x187F, 0xF860, 0x1860,
+
                }
−
        0x187F, 0xF860, 0x1860, 0x187F,
+
 
−
        0xF860, 0x1860, 0x183F, 0xF03F,
+
                VOID
−
         0xF060, 0xC00, 0x0, 0xC0,  
+
         setclip(clipflag, sarea)    /* set clip to specified area          */
−
        0x7FF, 0xFFFF, 0xFF80, 0x0,
+
                WORD    clipflag;
−
        0x0, 0x0, 0x3F30, 0xC787,
+
                GRECT  *sarea;
−
        0x8FE0, 0xC39, 0xCCCC, 0xCC00,
+
                {
−
        0xC36, 0xCFCC, 0xF80, 0xC30,
+
                WORD    pxy[4];
−
        0xCCCD, 0xCC00, 0x3F30, 0xCCC7,
 
−
        0xCFE0, 0x0, 0x0, 0x0};
 
  
−
        WORD IMAG1[] = {                                /* Mask for first icon */
+
                grecttoarray(sarea, pxy);
−
        0x0, 0x0, 0x0, 0x0,  
+
                vsclip(vdihandle, clipflag, pxy);
−
        0x7FFE, 0x0, 0x1F, 0xFFFF,  
+
                }
−
        0xFC00, 0xFF, 0xFFFF, 0xFF00,
 
−
        0x3FF, 0xFFFF, 0xFFC0, 0xFFF,
 
−
        0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
 
−
        0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
 
  
 +
</pre>
  
−
       
 
  
 +
==Appendix VII - Routines to set attributes before output==
  
−
        Professional GEM          Appendix III                        89
 
  
 +
<pre>
  
−
         0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+
         /*
−
         0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+
         >>>>>>>>>> Routines to set attributes before output <<<<<<<<<<<<
−
         0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+
         */
−
         0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
                VOID
−
        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
         rrperim(mode, color, type, width, pxy)      /* Draw a rounded    */
−
        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
                WORD    mode, color, width, *pxy;    /* rectangle outline */
−
        0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,  
+
                {
−
        0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,  
+
                vswrmode(vdihandle, mode);
−
        0xFFFC, 0xFFF, 0xFFFF, 0xFFF0,  
+
                vslcolor(vdihandle, color);
−
        0x3FF, 0xFFFF, 0xFFC0, 0xFF,  
+
                vsltype(vdihandle, type);
−
        0xFFFF, 0xFF00, 0x1F, 0xFFFF,  
+
                vslwidth(vdihandle, width);
−
        0xF800, 0x0, 0x7FFE, 0x0};
+
                vrbox(vdihandle, pxy);
 +
                vswrmode(vdihandle, MDREPLACE);
 +
                }
  
−
        WORD IMAG2[] = {                                /* Data for first icon */
+
                VOID
−
         0x0, 0x0, 0x0, 0x0,  
+
         plperim(mode, type, color, width, npts, pxy)    /* Draw a polygonal */
−
        0x3FFC, 0x0, 0xF, 0xC003,  
+
                                                          /* figure          */
−
        0xF000, 0x78, 0x180, 0x1E00,
+
                WORD    mode, type, color, width, npts, *pxy;
−
        0x180, 0x180, 0x180, 0x603,  
+
                {
−
        0x180, 0xC060, 0x1C00, 0x6,  
+
                vswrmode(vdihandle, mode);
−
        0x38, 0x3000, 0x18C, 0xC,
+
                vsltype(vdihandle, type);
−
        0x60C0, 0x198, 0x306, 0x6000,  
+
                vslcolor(vdihandle, color);
−
        0x1B0, 0x6, 0x4000, 0x1E0,  
+
                vslwidth(vdihandle, width);
−
        0x2, 0xC000, 0x1C0, 0x3,  
+
                vpline(vdihandle, npts, pxy);
−
        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 */
+
                VOID                  /* Draw a filled polygonal area */
−
         0x0, 0x0, 0x0, 0x0,
+
         plfill(mode, perim, color, interior, style, npts, pxy)
−
        0x7FFE, 0x0, 0x1F, 0xFFFF,  
+
                WORD    mode, perim, color, interior, style, npts, *pxy;
−
        0xFC00, 0xFF, 0xFFFF, 0xFF00,  
+
                {
−
        0x3FF, 0xFFFF, 0xFFC0, 0xFFF,  
+
                vswrmode(vdihandle, mode);
−
        0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
+
                vsfcolor(vdihandle, color);
−
        0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,  
+
                vsfstyle(vdihandle, style);
−
        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
                vsfinterior(vdihandle, interior);
−
        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
                vsfperimeter(vdihandle, perim);
−
        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
+
                vfillarea(vdihandle, npts, pxy);
−
        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};
 
  
 +
                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);
 +
                }
  
−
       
+
</pre>
  
  
−
        Professional GEM          Appendix III                        90
+
==Appendix VIII - Demonstration of byte alignment of window interior==
  
  
 +
<pre>
  
−
        WORD IMAG4[] = {                        /* Data for second icon */
+
         /*
−
        0x0, 0x0, 0x0, 0x0,
+
         >>>>>>>>>>> Demonstration of byte alignment of window interior <<<<<<<<<<<
−
        0x3FFC, 0x0, 0xF, 0xC003,
+
         */
−
        0xF000, 0x78, 0x180, 0x1E00,
+
 
−
        0x180, 0x180, 0x180, 0x603,
+
         #define FEATURES    0x0fef      /* what border features are used  */
−
        0x180, 0xC060, 0x1C00, 0x6,
+
         WORD    msg[8];                /* message from evntmulti          */
−
        0x38, 0x3000, 0x18C, 0xC,
+
         GRECT  workarea;              /* defines working area            */
−
        0x60C0, 0x198, 0x306, 0x6000,
+
         WORD    whndl;                  /* handle for window being changed */
−
        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
 
  
 +
                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]);
  
 
         /*
 
         /*
Line 2,234: Line 1,405:
 
                 return((x & 0xfff0) + ((x & 0x0008) ? 0x0010 : 0));
 
                 return((x & 0xfff0) + ((x & 0x0008) ? 0x0010 : 0));
 
                 }       
 
                 }       
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
       
 
−
 
−
 
−
        Professional GEM          Appendix VIII                      116
 
−
 
  
 
         /*
 
         /*
Line 2,306: Line 1,427:
 
                 }
 
                 }
  
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
 
−
       
 
 
</pre>
 
</pre>
−
 
−
Back to [[Professional_GEM]]
 

Revision as of 01:05, 13 October 2006

Professional GEM
[[Professional GEM - Part I - Windows|Part I Template:-- Windows]]
In the beginning ♦ Open sesame ♦ Cleaning up ♦ Those fat sliders ♦ Coming up next ♦ Feedback
[[Professional GEM - Part II - Windows|Part II Template:-- Windows]]
Excelsior ♦ Redrawing windows ♦ Caveat emptor ♦ Into the bits ♦ A small confession ♦ Window control request ♦ Window slider messages ♦ A common bug ♦ Dept. of dirty tricks ♦ A sin of omission ♦ Coming soon
[[Professional GEM - Part III - The dialog handler|Part III Template:-- The dialog handler]]
A meaningful dialog ♦ Defining terms ♦ Bug alert! ♦ A handy trick ♦ Clean up ♦ Recap ♦ Button Button ♦ Who's got the button? ♦ Coming up next ♦ Dispell gremlins
[[Professional GEM - Part IV - Resource structure|Part IV Template:-- Resource structure]]
A maze of twisty little passages ♦ Putting it to work ♦ Letters, we get letters ♦ Straw poll! ♦ Stay tuned!
[[Professional GEM - Part V - Resource tree structures|Part V Template:-- Resource tree structures]]
How GEM does it ♦ Thought experiments ♦ A treewalker of our own
[[Professional GEM - Part VI - Raster operations|Part VI Template:-- Raster operations]]
Seasons greetings ♦ Defining terms ♦ Monochrome vs. color ♦ Standard vs. device-specific format ♦ Even-word vs. fringes ♦ MFDB's ♦ Let's operate ♦ Transform form ♦ Copy raster opaque ♦ Copy raster transparent ♦ The mode parameter ♦ Replace mode ♦ Erase mode ♦ Xor mode ♦ Transparent mode ♦ Reverse transparent mode ♦ The problem of color ♦ Optimizing raster operations ♦ Avoid merged copies ♦ Move to corresponding pixels ♦ Avoid fringes ♦ Use another method ♦ Feedback results ♦ The next question ♦ Coming up soon
[[Professional GEM - Part VII - Menu structures|Part VII Template:-- Menu structures]]
Happy new year ♦ Menu basics ♦ Menu structures ♦ Using the menu ♦ Getting fancy ♦ Check please? ♦ Now you see it now you don't ♦ Lunch and dinner menus ♦ Do it yourself ♦ Make pretty ♦ That's it for now!
[[Professional GEM - Part VIII - User interfaces|Part VIII Template:-- User interfaces]]
And now for something completely different! ♦ Credit where it's due ♦ Fingertips ♦ Muscles ♦ Eyes ♦ Short-term memory ♦ Chunking ♦ Think! ♦ Are we not men? ♦ Of modes and bandwidth ♦ To do is to be! ♦ Amen...
[[Professional GEM - Part IX - VDI Graphics: Lines and solids|Part IX Template:-- VDI Graphics: Lines and solids]]
A bit of history ♦ The line forms on the left ♦ Solids ♦ To be continued
Appendices
Main page

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();
                }