home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / frntsdk1.cpt / Frontier SDK 1.0 ƒ / Applet Toolkit / ops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-30  |  31.3 KB  |  1,682 lines

  1.  
  2. /*⌐ Copyright 1988-1991 UserLand Software, Inc.  All Rights Reserved.*/
  3.  
  4.  
  5.  
  6. #include "appletinternal.h"
  7. #include "quickdraw.h"
  8. #include "ops.h"
  9.  
  10.  
  11. #ifdef MPWC
  12.  
  13.     #include <osevents.h>
  14.  
  15. #endif
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22. void initmacintosh () {
  23.  
  24.     /*
  25.     the magic stuff that every Macintosh application needs to do 
  26.     before doing anything else.
  27.     */
  28.  
  29.     register short i;
  30.         
  31.     MaxApplZone ();
  32.     
  33.     for (i = 1; i < 11; i++) 
  34.         MoreMasters ();
  35.  
  36.     InitGraf (&quickdrawglobal (thePort));
  37.     
  38.     InitFonts ();
  39.     
  40.     FlushEvents (everyEvent, 0);
  41.     
  42.     InitWindows ();
  43.     
  44.     InitMenus ();
  45.     
  46.     TEInit ();
  47.     
  48.     InitDialogs (nil);
  49.     
  50.     InitCursor ();
  51.     
  52.     for (i = 1; i <= 5; i++) { /*register with Multifinder*/
  53.         
  54.         EventRecord ev;
  55.         
  56.         EventAvail (everyEvent, &ev); /*see TN180 -- splash screen*/
  57.         } /*for*/
  58.     } /*initmacintosh*/
  59.     
  60.  
  61. short minint (x, y) short x, y; {
  62.  
  63.     if (x < y)
  64.         return (x);
  65.     else
  66.         return (y);
  67.     } /*minint*/
  68.     
  69.     
  70. void moveleft (psource, pdest, length) void *psource, *pdest; long length; {
  71.     
  72.     /*
  73.     do a mass memory move with the left edge leading.  good for closing
  74.     up a gap in a buffer, among other things╔
  75.     */
  76.     
  77.     register char *ps, *pd;
  78.     register long ctloops;
  79.     
  80.     ctloops = length;
  81.     
  82.     if (ctloops > 0) {
  83.     
  84.         ps = psource; /*copy into a register*/
  85.     
  86.         pd = pdest; /*copy into a register*/
  87.     
  88.         while (ctloops--) *pd++ = *ps++;
  89.         }
  90.     } /*moveleft*/
  91.     
  92.     
  93. void moveright (psource, pdest, length) void *psource, *pdest; long length; {
  94.     
  95.     /*
  96.     do a mass memory move with the right edge leading.  good for opening
  97.     up a gap in a buffer, among other things╔
  98.     */
  99.     
  100.     register char *ps, *pd;
  101.     register long ctloops;
  102.     
  103.     ctloops = length;
  104.     
  105.     if (ctloops > 0) {
  106.     
  107.         ps = (char *) psource + length - 1; /*right edge of source*/
  108.     
  109.         pd = (char *) pdest + length - 1; /*right edge of destination*/
  110.     
  111.         while (ctloops--) *pd-- = *ps--;
  112.         }
  113.     } /*moveright*/
  114.     
  115.     
  116. void fillchar (pfill, ctfill, chfill) void *pfill; long ctfill; char chfill; {
  117.     
  118.     /*
  119.     do a mass memory fill -- copy ctfill chfills at pfill.
  120.     */
  121.     
  122.     register char *p = pfill;
  123.     register long ct = ctfill;
  124.     register char ch = chfill;
  125.     
  126.     while (ct--) *p++ = (char) ch; /*tight loop*/
  127.     } /*fillchar*/
  128.     
  129.  
  130. void clearbytes (pclear, ctclear) void *pclear; long ctclear; {
  131.     
  132.     /*
  133.     fill memory with 0's.
  134.     */
  135.     
  136.     fillchar (pclear, ctclear, (char) 0);
  137.     } /*clearbytes*/
  138.     
  139.  
  140. void disposehandle (h) Handle h; {
  141.     
  142.     /*
  143.     our own bottleneck for this built-in.  we don't require type coercion
  144.     and we check if its nil.
  145.     */
  146.     
  147.     if (h != nil)
  148.         DisposHandle (h);
  149.     } /*disposehandle*/
  150.     
  151.     
  152. boolean copyhandle (horig, hcopy) Handle horig, *hcopy; {
  153.     
  154.     register Handle h;
  155.     register long ct;
  156.     
  157.     h = NewHandle (ct = GetHandleSize (horig));
  158.     
  159.     if (h == nil)
  160.         return (false);
  161.         
  162.     moveleft (*horig, *h, ct);
  163.     
  164.     *hcopy = h;
  165.     
  166.     return (true);
  167.     } /*copyhandle*/
  168.     
  169.  
  170. boolean enlargehandle (hgrow, ctgrow, newdata) Handle hgrow; long ctgrow; ptrchar newdata; {
  171.     
  172.     /*
  173.     make the handle big enough to hold the new data, and move the new data in
  174.     at the end of the newly enlarged handle.
  175.     */
  176.     
  177.     register Handle h = hgrow;
  178.     register long ct = ctgrow;
  179.     register ptrchar p = newdata;
  180.     register long origsize;
  181.     
  182.     origsize = GetHandleSize (h);
  183.     
  184.     SetHandleSize (h, origsize + ct);
  185.         
  186.     if (MemError () != noErr)
  187.         return (false);
  188.         
  189.     moveleft (p, *h + origsize, ct);
  190.     
  191.     return (true);
  192.     } /*enlargehandle*/ 
  193.     
  194.     
  195. boolean loadfromhandle (hload, ixload, ctload, pdata) Handle hload; long *ixload, ctload; ptrchar pdata; {
  196.     
  197.     /*
  198.     copy the next ctload bytes from hload into pdata and increment the index.
  199.     
  200.     return false if there aren't enough bytes.
  201.     
  202.     start ixload at 0.
  203.     */
  204.     
  205.     register Handle h = hload;
  206.     register ptrchar p = pdata;
  207.     register long ct = ctload;
  208.     register long ix = *ixload;
  209.     register long size;
  210.     
  211.     size = GetHandleSize (h);
  212.     
  213.     if ((ix + ct) > size) /*asked for more bytes than there are*/
  214.         return (false); 
  215.         
  216.     moveleft (*h + ix, p, ct); /*copy out of the handle*/
  217.     
  218.     *ixload = ix + ct; /*increment the index into the handle*/
  219.     
  220.     return (true);
  221.     } /*loadfromhandle*/
  222.     
  223.  
  224. boolean newtexthandle (bs, htext) bigstring bs; Handle *htext; {
  225.     
  226.     /*
  227.     create a new handle to hold the text of the string.
  228.     
  229.     if the string is "\pABC" -- you get a handle of size 3.
  230.     */
  231.     
  232.     register long len;
  233.     register Handle h;
  234.     
  235.     h = NewHandle (len = stringlength (bs));
  236.     
  237.     if (h == nil)
  238.         return (false);
  239.     
  240.     if (len > 0)
  241.         moveleft (&bs [1], *h, len);
  242.     
  243.     *htext = h; /*pass handle back to caller*/
  244.     
  245.     return (true);
  246.     } /*newtexthandle*/
  247.  
  248.  
  249. boolean pushtexthandle (bs, htext) bigstring bs; Handle htext; {
  250.     
  251.     /*
  252.     htext is a handle created with newtexthandle.
  253.     
  254.     increase the size of the handle so we can push the text of bs at 
  255.     the end of the handle (not including length byte).
  256.     */
  257.     
  258.     return (enlargehandle (htext, (long) stringlength (bs), (ptrchar) bs + 1));
  259.     } /*pushtexthandle*/
  260.  
  261.  
  262. void texthandletostring (Handle htext, bigstring bs) {
  263.     
  264.     register long len;
  265.     
  266.     len = GetHandleSize (htext);
  267.     
  268.     if (len > lenbigstring)
  269.         len = lenbigstring;
  270.     
  271.     setstringlength (bs, len);
  272.     
  273.     moveleft (*htext, &bs [1], len);
  274.     } /*texthandletostring*/
  275.     
  276.     
  277. boolean equalstrings (bs1, bs2) bigstring bs1, bs2; {
  278.  
  279.     /*
  280.     return true if the two strings (pascal type, with length-byte) are
  281.     equal.  return false otherwise.
  282.     */
  283.  
  284.     register ptrchar p1 = (ptrchar) bs1, p2 = (ptrchar) bs2;
  285.     register char ct = *p1 + 1;
  286.     
  287.     while (ct--) 
  288.         
  289.         if (*p1++ != *p2++)
  290.         
  291.             return (false);
  292.         
  293.     return (true); /*loop terminated*/
  294.     } /*equalstrings*/
  295.     
  296.     
  297. boolean unicaseequalstrings (bs1, bs2) bigstring bs1, bs2; {
  298.     
  299.     bigstring bscopy1, bscopy2;
  300.     
  301.     copystring (bs1, bscopy1);
  302.     
  303.     copystring (bs2, bscopy2);
  304.     
  305.     alllower (bscopy1);
  306.     
  307.     alllower (bscopy2);
  308.     
  309.     return (equalstrings (bscopy1, bscopy2));
  310.     } /*unicaseequalstrings*/
  311.     
  312.  
  313. void copystring (bssource, bsdest) void *bssource, *bsdest; {
  314.  
  315.     /*
  316.     create a copy of bssource in bsdest.  copy the length byte and
  317.     all the characters in the source string.
  318.  
  319.     assume the strings are pascal strings, with the length byte in
  320.     the first character of the string.
  321.     */
  322.  
  323.     register short i, len;
  324.     
  325.     len = (short) ((char *) bssource) [0];
  326.     
  327.     for (i = 0; i <= len; i++) 
  328.         ((char *) bsdest) [i] = ((char *) bssource) [i];
  329.     } /*copystring*/
  330.  
  331.  
  332. boolean pushstring (bssource, bsdest) bigstring bssource, bsdest; {
  333.  
  334.     /*
  335.     insert the source string at the end of the destination string.
  336.     
  337.     assume the strings are pascal strings, with the length byte in
  338.     the first character of the string.
  339.     */
  340.     
  341.     register short lensource = stringlength (bssource);
  342.     register short lendest = stringlength (bsdest);
  343.     register char *psource, *pdest;
  344.     
  345.     if ((lensource + lendest) > lenbigstring)
  346.         return (false);
  347.         
  348.     pdest = (ptrchar) bsdest + (char) lendest + 1;
  349.     
  350.     psource = (ptrchar) bssource + 1;
  351.     
  352.     bsdest [0] += (char) lensource;
  353.     
  354.     while (lensource--) *pdest++ = *psource++;
  355.     
  356.     return (true);
  357.     } /*pushstring*/
  358.     
  359.     
  360. boolean pushspace (bs) bigstring bs; {
  361.     
  362.     bigstring bsspace;
  363.     
  364.     setstringlength (bsspace, 1);
  365.     
  366.     bsspace [1] = ' ';
  367.     
  368.     return (pushstring (bsspace, bs));
  369.     } /*pushspace*/
  370.     
  371.  
  372. void pushlong (num, bsdest) long num; bigstring bsdest; {
  373.  
  374.     bigstring bsint;
  375.     
  376.     NumToString (num, bsint);
  377.     
  378.     pushstring (bsint, bsdest);
  379.     } /*pushlong*/
  380.     
  381.  
  382. void pushint (num, bsdest) short num; bigstring bsdest; {
  383.     
  384.     pushlong ((long) num, bsdest);
  385.     } /*pushint*/
  386.     
  387.     
  388. void allupper (bs) bigstring bs; {
  389.     
  390.     register char len = bs [0];
  391.     register ptrchar p = (ptrchar) &bs [1];
  392.     register char ch;
  393.     
  394.     while (len--) {
  395.         
  396.         ch = *p;
  397.         
  398.         if ((ch >= 'a') && (ch <= 'z'))
  399.             *p -= 32;
  400.             
  401.         p++;
  402.         } /*while*/
  403.     } /*allupper*/
  404.     
  405.     
  406. void alllower (bs) bigstring bs; {
  407.     
  408.     register char len = bs [0];
  409.     register ptrchar p = (ptrchar) &bs [1];
  410.     register char ch;
  411.     
  412.     while (len--) {
  413.         
  414.         ch = *p;
  415.         
  416.         if ((ch >= 'A') && (ch <= 'Z'))
  417.             *p += 32;
  418.             
  419.         p++;
  420.         } /*while*/
  421.     } /*alllower*/
  422.     
  423.     
  424. boolean stringlessthan (bs1, bs2) bigstring bs1, bs2; {
  425.     
  426.     register short i, ctloops;
  427.     register char ch1, ch2;
  428.     short len1, len2;
  429.     
  430.     len1 = (short) bs1 [0];
  431.     
  432.     len2 = (short) bs2 [0];
  433.     
  434.     ctloops = minint (len1, len2);
  435.     
  436.     for (i = 1; i <= ctloops; i++) {
  437.         
  438.         ch1 = bs1 [i];
  439.         
  440.         ch2 = bs2 [i];
  441.         
  442.         if (ch1 != ch2) /*we have our answer*/
  443.             return (ch1 < ch2);
  444.         } /*for*/
  445.     
  446.     return (len1 < len2); /*loop terminated, strings are equal up to the min length*/
  447.     } /*stringlessthan*/
  448.     
  449.     
  450. void midstring (bssource, ix, len, bsdest) bigstring bssource, bsdest; short ix, len; {
  451.     
  452.     setstringlength (bsdest, len);
  453.     
  454.     moveleft (bssource + ix, bsdest + 1, (long) len);
  455.     } /*midstring*/
  456.     
  457.     
  458. boolean pushchar (ch, bs) byte ch; bigstring bs; {
  459.     
  460.     /*
  461.     insert the character at the end of a pascal string.
  462.     */
  463.     
  464.     register short len;
  465.     
  466.     len = bs [0]; 
  467.     
  468.     if (len >= lenbigstring)
  469.         return (false);
  470.     
  471.     bs [++len] = ch;
  472.     
  473.     bs [0] = len;
  474.     
  475.     return (true);
  476.     } /*pushchar*/
  477.     
  478.     
  479. boolean scanstring (ch, bs, ix) byte ch; bigstring bs; short *ix; {
  480.     
  481.     /*
  482.     return in ix the index in the string of the first occurence of chscan.
  483.     
  484.     return false if it wasn't found, true otherwise.
  485.     
  486.     dmb 10/26/90: p is now initialized correctly to bs + i, not bs + 1
  487.     */
  488.     
  489.     register short i;
  490.     register ptrbyte p;
  491.     register byte c = ch;
  492.     register short len = stringlength (bs);
  493.     
  494.     for (i = *ix, p = bs + i; i <= len; i++) 
  495.         
  496.         if (*p++ == c) {
  497.             
  498.             *ix = i;
  499.             
  500.             return (true);
  501.             }
  502.             
  503.     return (false);
  504.     } /*scanstring*/
  505.  
  506.  
  507. boolean deletestring (bs, ixdelete, ctdelete) bigstring bs; short ixdelete, ctdelete; {
  508.     
  509.     /*
  510.     delete ct chars in the indicated string, starting with the character
  511.     at offset ix.
  512.     */
  513.     
  514.     register short ix = ixdelete;
  515.     register short ct = ctdelete;
  516.     register short len = stringlength (bs);
  517.     register long ctmove;
  518.     register ptrbyte pfrom, pto;        
  519.     
  520.     if ((ix > len) || (ix < 1))
  521.         return (false);
  522.         
  523.     if (ct <= 0)
  524.         return (ct == 0);
  525.         
  526.     ctmove = len - ix - ct + 1;
  527.      
  528.     if (ctmove > 0) {
  529.         
  530.         pfrom = bs + ix + ct;
  531.         
  532.         pto = bs + ix;
  533.         
  534.         moveleft (pfrom, pto, ctmove);
  535.         }
  536.     
  537.     setstringlength (bs, len - ct);
  538.     
  539.     return (true);
  540.     } /*deletestring*/
  541.     
  542.     
  543. boolean firstword (bssource, chdelim, bsdest) bigstring bssource, bsdest; char chdelim; {
  544.     
  545.     /*
  546.     copy the first word from bs, and put it into bsdest.
  547.     
  548.     search forwards from the beginning of the source string until you 
  549.     find chdelim.
  550.     */
  551.     
  552.     register short len = stringlength (bssource);
  553.     register short i;
  554.     register char ch = chdelim;
  555.     
  556.     for (i = 1; i <= len; i++) {
  557.         
  558.         if (bssource [i] == ch) {
  559.             
  560.             midstring (bssource, 1, i - 1, bsdest);
  561.             
  562.             return (true);
  563.             }
  564.         } /*for*/
  565.         
  566.     copystring (bssource, bsdest);
  567.     
  568.     return (true);
  569.     } /*firstword*/
  570.  
  571.  
  572. boolean lastword (bssource, chdelim, bsdest) bigstring bssource, bsdest; char chdelim; {
  573.     
  574.     /*
  575.     copy the last word from bs, and put it into bsdest.
  576.     
  577.     search backwards from the end of the source string until you find
  578.     chdelim.
  579.     */
  580.     
  581.     register short len = stringlength (bssource);
  582.     register short i;
  583.     register char ch = chdelim;
  584.     
  585.     for (i = len; i > 0; i--) {
  586.         
  587.         if (bssource [i] == ch) {
  588.             
  589.             midstring (bssource, i + 1, len - i, bsdest);
  590.             
  591.             return (true);
  592.             }
  593.         } /*for*/
  594.         
  595.     copystring (bssource, bsdest);
  596.     
  597.     return (true);
  598.     } /*lastword*/
  599.     
  600.     
  601. void ellipsize (bs, width) Str255 bs; short width; {
  602.  
  603.     /*
  604.     if the string fits inside the given number of pixels, fine -- do nothing
  605.     and return.
  606.     
  607.     if not, return a string that does fit, with ellipses representing the 
  608.     deleted characters.  ellipses are generated by pressing option-semicolon.
  609.     */
  610.     
  611.     register char len;
  612.     register short newwidth;
  613.     
  614.     if ((newwidth = StringWidth (bs)) <= width) /*nothing to do, the string fits*/
  615.         return;
  616.     
  617.     len = bs [0]; /* current length in characters*/
  618.     
  619.     width -= CharWidth ('╔'); /* subtract width of ellipses*/
  620.         
  621.     do { /*until it fits (or we run out of characters)*/
  622.     
  623.         newwidth -= CharWidth (bs [len]);
  624.         
  625.         --len;
  626.     } while ((newwidth > width) && (len != 0));
  627.     
  628.     ++len; /*make room for the ellipses*/
  629.     
  630.     bs [len] = '╔'; 
  631.     
  632.     bs [0] = (char) len;
  633.     } /*ellipsize*/
  634.     
  635.  
  636. void centerstring (r, bs) Rect r; bigstring bs; {
  637.     
  638.     /*
  639.     draw the string in the current font, size and style, centered inside
  640.     the indicated rectangle.
  641.     */
  642.     
  643.     register short lh = globalfontinfo.ascent + globalfontinfo.descent; /*line height*/
  644.     register short rh = r.bottom - r.top;
  645.     register short rw = r.right - r.left;
  646.     register short h, v;
  647.     
  648.     ellipsize (bs, rw); /*make sure it fits inside the rectangle, width-wise*/
  649.     
  650.     h = r.left + ((rw - StringWidth (bs)) / 2);
  651.     
  652.     v = r.top + ((rh - lh) / 2) + globalfontinfo.ascent;
  653.     
  654.     MoveTo (h, v);
  655.     
  656.     pushclip (r);
  657.     
  658.     DrawString (bs);
  659.     
  660.     popclip ();
  661.     } /*centerstring*/
  662.  
  663.  
  664. void grayrect (r) Rect r; {
  665.  
  666.     pushpen ();
  667.     
  668.     PenMode (patBic);
  669.     
  670.     PenPat (quickdrawglobal (gray));
  671.     
  672.     PaintRect (&r);
  673.     
  674.     poppen ();
  675.     } /*grayrect*/
  676.     
  677.  
  678. void centerwindow (w, rscreen) WindowPtr w; Rect rscreen; {
  679.  
  680.     short h, v;
  681.     Rect r;
  682.     short minv;
  683.     
  684.     r = (*w).portRect;
  685.     
  686.     h = rscreen.left + (((rscreen.right - rscreen.left) - (r.right - r.left)) / 2);
  687.     
  688.     v = rscreen.top + (((rscreen.bottom - rscreen.top) - (r.bottom - r.top)) / 6);
  689.     
  690.     minv = getmenubarheight () + doctitlebarheight + 10;
  691.     
  692.     if (v < minv)
  693.         v = minv;
  694.     
  695.     MoveWindow (w, h, v, false);
  696.     } /*centerwindow*/
  697.  
  698.  
  699. DialogPtr newmodaldialog (short id, short bolditem) {
  700.     
  701.     register DialogPtr pdialog;
  702.     
  703.     pdialog = GetNewDialog (id, nil, (DialogPtr) -1L);
  704.     
  705.     if (pdialog == nil) 
  706.         return (nil);
  707.         
  708.     centerwindow (pdialog, quickdrawglobal (screenBits).bounds);
  709.     
  710.     ShowWindow (pdialog);    
  711.     
  712.     if (bolditem > 0)
  713.         boldenbutton (pdialog, bolditem); 
  714.     
  715.     return (pdialog);
  716.     } /*newmodaldialog*/
  717.     
  718.  
  719. void boldenbutton (pdialog, itemnumber) DialogPtr pdialog; short itemnumber; {
  720.  
  721.     /*
  722.     draw a thick black ring around the OK button in the dialog.  
  723.     */
  724.     
  725.     PenState savePen;
  726.     short itemtype;
  727.     Handle itemhandle;
  728.     Rect itemrect;
  729.     
  730.     pushmacport (pdialog);
  731.     
  732.     GetPenState (&savePen); /*save the old pen state*/
  733.     
  734.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect); /*get the item╒s rect*/
  735.     
  736.     InsetRect (&itemrect, -4, -4);
  737.     
  738.     PenSize (3, 3); /*make the pen fatter*/
  739.     
  740.     FrameRoundRect (&itemrect, 16, 16); /*draw the ring*/
  741.  
  742.     SetPenState (&savePen); /*restore the pen state*/
  743.     
  744.     popmacport ();
  745.     } /*boldenbutton*/
  746.  
  747.  
  748. short runmodaldialog () {
  749.     
  750.     short itemnumber;
  751.     
  752.     ModalDialog (nil, &itemnumber);
  753.     
  754.     return (itemnumber);
  755.     } /*runmodaldialog*/
  756.     
  757.     
  758. void setdialogtext (pdialog, itemnumber, bs) DialogPtr pdialog; short itemnumber; bigstring bs; {
  759.  
  760.     short itemtype;
  761.     Handle itemhandle;
  762.     Rect itemrect;
  763.     
  764.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  765.         
  766.     SetIText (itemhandle, bs); 
  767.     } /*setdialogtext*/
  768.     
  769.     
  770. void getdialogtext (pdialog, itemnumber, bs) DialogPtr pdialog; short itemnumber; bigstring bs; {
  771.  
  772.     short itemtype;
  773.     Handle itemhandle;
  774.     Rect itemrect;
  775.     
  776.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  777.                 
  778.     GetIText (itemhandle, bs); 
  779.     } /*getdialogtext*/
  780.  
  781.  
  782. static void selectdialogtext (DialogPtr pdialog, short itemnumber) {
  783.     
  784.     SelIText (pdialog, itemnumber, 0, infinity); /*select all text*/
  785.     } /*selectdialogtext*/        
  786.  
  787.  
  788. void disabledialogitem (pdialog, itemnumber) DialogPtr pdialog; short itemnumber; {
  789.     
  790.     short itemtype;
  791.     Handle itemhandle;
  792.     Rect itemrect;
  793.  
  794.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  795.     
  796.     if (itemtype < itemDisable) { /*it is enabled, disable it*/
  797.     
  798.         SetDItem (pdialog, itemnumber, itemtype + itemDisable, itemhandle, &itemrect);
  799.         
  800.         grayrect (itemrect);
  801.         }
  802.     } /*disabledialogitem*/
  803.     
  804.  
  805. void enabledialogitem (pdialog, itemnumber) DialogPtr pdialog; short itemnumber; {
  806.     
  807.     short itemtype;
  808.     Handle itemhandle;
  809.     Rect itemrect;
  810.  
  811.     GetDItem (pdialog, itemnumber, &itemtype, &itemhandle, &itemrect);
  812.     
  813.     if (itemtype >= itemDisable) /*it is disabled, enable it*/
  814.     
  815.         SetDItem (pdialog, itemnumber, itemtype - itemDisable, itemhandle, &itemrect);
  816.     } /*disabledialogitem*/
  817.     
  818.  
  819. void dialoggetobjectrect (pdialog, objectnumber, r) DialogPtr pdialog; short objectnumber; Rect *r; {
  820.  
  821.     short itemtype;
  822.     Handle itemhandle;
  823.     
  824.     GetDItem (pdialog, objectnumber, &itemtype, &itemhandle, r);
  825.     } /*dialoggetobjectrect*/
  826.     
  827.     
  828. boolean cometofront () {
  829.     
  830.     register short i;
  831.     ProcessSerialNumber psn;
  832.     EventRecord ev;
  833.     
  834.     GetCurrentProcess (&psn);
  835.     
  836.     SetFrontProcess (&psn);
  837.     
  838.     for (i = 1; i <= 3; i++)
  839.         WaitNextEvent (nullEvent, &ev, 1, nil);    
  840.     } /*cometofront*/
  841.     
  842.     
  843. void arrowcursor () {
  844.     
  845.     SetCursor (&arrow);
  846.     } /*arrowcursor*/
  847.     
  848.     
  849. void watchcursor () {
  850.     
  851.     register CursHandle hcursor;
  852.     
  853.     hcursor = GetCursor (watchCursor);
  854.     
  855.     if (hcursor != nil) 
  856.         SetCursor (*hcursor);
  857.     } /*watchcursor*/
  858.     
  859.     
  860. void parsedialogstring (bigstring bs) {
  861.     
  862.     register short i;
  863.     
  864.     for (i = 1; i <= stringlength (bs); i++) {
  865.         
  866.         if (bs [i] == '¿')
  867.             bs [i] = (char) 13;
  868.         } /*for*/
  869.     } /*parsedialogstring*/
  870.     
  871.     
  872. boolean alertdialog (bs) bigstring bs; {
  873.     
  874.     #define alertdialogid 128 
  875.     #define alertokitem 1
  876.     #define alertmsgitem 3
  877.     register DialogPtr pdialog;
  878.     
  879.     cometofront ();
  880.     
  881.     sysbeep;
  882.     
  883.     arrowcursor ();
  884.     
  885.     parsedialogstring (bs);
  886.     
  887.     if ((pdialog = newmodaldialog (alertdialogid, alertokitem)) == nil)
  888.         return (false);
  889.     
  890.     setdialogtext (pdialog, alertmsgitem, bs);
  891.     
  892.     ShowWindow (pdialog);
  893.     
  894.     runmodaldialog ();
  895.     
  896.     DisposDialog (pdialog);
  897.     
  898.     return (true);
  899.     } /*alertdialog*/
  900.     
  901.     
  902. boolean msgdialog (bs) bigstring bs; {
  903.     
  904.     #define msgdialogid 129 
  905.     #define msgokitem 1
  906.     #define msgcancelitem 2
  907.     #define msgmsgitem 3
  908.     register DialogPtr pdialog;
  909.     register short item;
  910.     
  911.     cometofront ();
  912.     
  913.     arrowcursor ();
  914.     
  915.     parsedialogstring (bs);
  916.     
  917.     if ((pdialog = newmodaldialog (msgdialogid, msgokitem)) == nil)
  918.         return (false);
  919.     
  920.     setdialogtext (pdialog, msgmsgitem, bs);
  921.     
  922.     ShowWindow (pdialog);
  923.     
  924.     item = runmodaldialog ();
  925.     
  926.     DisposDialog (pdialog);
  927.     
  928.     return (item == msgokitem);
  929.     } /*msgdialog*/
  930.  
  931.  
  932. boolean askdialog (bigstring bsprompt, bigstring bsanswer) {
  933.     
  934.     /*
  935.     put up the standard "ask" dialog, with the provided prompt and return
  936.     true if the user clicked on ok.  the answer is in bsanswer.
  937.     */
  938.     
  939.     #define askdialogid 130
  940.     #define askokitem 1
  941.     #define askcancelitem 2
  942.     #define askpromptitem 3
  943.     #define askansweritem 4    
  944.     register DialogPtr pdialog;
  945.     register short itemnumber;
  946.     
  947.     ParamText (bsprompt, emptystring, emptystring, emptystring);
  948.     
  949.     if ((pdialog = newmodaldialog (askdialogid, askokitem)) == nil)
  950.         return (false);
  951.     
  952.     setdialogtext (pdialog, askansweritem, bsanswer);
  953.     
  954.     selectdialogtext (pdialog, askansweritem);
  955.     
  956.     ShowWindow (pdialog);
  957.     
  958.     itemnumber = runmodaldialog ();
  959.     
  960.     getdialogtext (pdialog, askansweritem, bsanswer);
  961.     
  962.     DisposDialog (pdialog);
  963.     
  964.     return (itemnumber == askokitem);
  965.     } /*askdialog*/
  966.  
  967.  
  968. boolean sfdialog (flput, fname, vnum, filetype) 
  969.     
  970.     /*
  971.     return true if the user selected a file with one of the SF routines,
  972.     return false otherwise.
  973.     */
  974.  
  975.     boolean flput; bigstring fname; short *vnum; OSType filetype; {
  976.     
  977.     register DialogTHndl hdialog;
  978.     register short id;
  979.     Rect r, rscreen;
  980.     Point pt;
  981.     SFReply reply;
  982.     SFTypeList typesrec;
  983.  
  984.     cometofront ();
  985.     
  986.     arrowcursor ();
  987.     
  988.     if (flput)
  989.         id = getDlgID;
  990.     else
  991.         id = putDlgID;
  992.         
  993.     hdialog = (DialogTHndl) GetResource ('DLOG', id);
  994.     
  995.     if (hdialog == nil) {
  996.         
  997.         pt.h = pt.v = 85;
  998.         }
  999.     else {
  1000.         r = (**hdialog).boundsRect;
  1001.     
  1002.         rscreen = quickdrawglobal (screenBits).bounds;
  1003.     
  1004.         pt.h = rscreen.left + (((rscreen.right - rscreen.left) - (r.right - r.left)) / 2);
  1005.     
  1006.         pt.v = rscreen.top + ((rscreen.bottom - rscreen.top) - (r.bottom - r.top)) / 3;
  1007.         }
  1008.  
  1009.     if (flput)
  1010.         SFPutFile (pt, (ptrstring) "\p", fname, nil, &reply);
  1011.         
  1012.     else {
  1013.         typesrec [0] = filetype;
  1014.         
  1015.         SFGetFile (pt, (ptrstring) "\p", nil, 1, typesrec, nil, &reply);
  1016.         }
  1017.         
  1018.     if (reply.good) {
  1019.     
  1020.         copystring (reply.fName, fname);
  1021.         
  1022.         *vnum = reply.vRefNum;
  1023.         }
  1024.         
  1025.     return (reply.good);
  1026.     } /*sfdialog*/
  1027.             
  1028.  
  1029. void delayseconds (ct) short ct; {
  1030.     
  1031.     register long tc;
  1032.     
  1033.     tc = TickCount () + (60 * ct);
  1034.     
  1035.     while (TickCount () < tc) {}
  1036.     } /*delayseconds*/
  1037.     
  1038.     
  1039. boolean newclearhandle (ctbytes, hreturned) long ctbytes; Handle *hreturned; {
  1040.     
  1041.     register long ct = ctbytes;
  1042.     register Handle h;
  1043.     
  1044.     *hreturned = h = NewHandle (ct);
  1045.     
  1046.     if (h == nil) 
  1047.         return (false);
  1048.         
  1049.     clearbytes (*h, ct);
  1050.     
  1051.     *hreturned = h;
  1052.     
  1053.     return (true);
  1054.     } /*newclearhandle*/
  1055.     
  1056.     
  1057. boolean newfilledhandle (ptrvoid pdata, long size, Handle *hreturned) {
  1058.     
  1059.     register Handle h;
  1060.     register long ctbytes;
  1061.     
  1062.     ctbytes = size; 
  1063.     
  1064.     h = NewHandle (ctbytes);
  1065.     
  1066.     if (h == nil) {
  1067.         
  1068.         *hreturned = nil;
  1069.         
  1070.         return (false);
  1071.         }
  1072.     
  1073.     moveleft (pdata, *h, ctbytes);
  1074.         
  1075.     *hreturned = h;
  1076.     
  1077.     return (true);
  1078.     } /*newfilledhandle*/
  1079.     
  1080.     
  1081. boolean newheapstring (bigstring bs, hdlstring *hstring) {
  1082.  
  1083.     return (newfilledhandle (bs, (long) stringlength (bs) + 1, (Handle *) hstring));
  1084.     } /*newheapstring*/
  1085.     
  1086.     
  1087. void copyheapstring (hdlstring hstring, bigstring bs) {
  1088.     
  1089.     if (hstring == nil) {
  1090.         
  1091.         setstringlength (bs, 0);
  1092.         
  1093.         return;
  1094.         }
  1095.     
  1096.     lockhandle ((Handle) hstring);
  1097.     
  1098.     copystring (*hstring, bs);
  1099.     
  1100.     unlockhandle ((Handle) hstring);
  1101.     } /*copyheapstring*/
  1102.     
  1103.  
  1104. static boolean keydown (short keycode) {
  1105.  
  1106.     KeyMap keys;
  1107.     
  1108.     GetKeys (&keys);
  1109.     
  1110.     return (BitTst (&keys, keycode));
  1111.     } /*keydown*/
  1112.     
  1113.     
  1114. boolean filedelete (bspath, vnum) bigstring bspath; short vnum; {
  1115.  
  1116.     HParamBlockRec pb;
  1117.     
  1118.     clearbytes (&pb, longsizeof (pb));
  1119.     
  1120.     pb.ioParam.ioNamePtr = bspath;
  1121.     
  1122.     pb.ioParam.ioVRefNum = vnum; 
  1123.     
  1124.     return (PBHDelete (&pb, false) == noErr);
  1125.     } /*filedelete*/
  1126.     
  1127.  
  1128. void fileclose (fnum) short fnum; {
  1129.     
  1130.     if (fnum != 0)
  1131.         FSClose (fnum);
  1132.     } /*fileclose*/
  1133.     
  1134.  
  1135. boolean fileseteof (fnum, eof) short fnum; long eof; {
  1136.     
  1137.     OSErr errcode;
  1138.     
  1139.     if (fnum != 0) {
  1140.     
  1141.         errcode = SetEOF (fnum, eof);
  1142.         
  1143.         return (errcode == noErr);
  1144.         }
  1145.         
  1146.     return (true);
  1147.     } /*fileseteof*/
  1148.     
  1149.  
  1150. boolean fileopenorcreate (bs, vnum, creator, filetype, fnum) bigstring bs; short vnum; OSType creator, filetype; short *fnum; {
  1151.     
  1152.     /*
  1153.     open or create a file indicated by bs and vnum.  if bs is a full path, 
  1154.     set vnum to 0.  return with fnum set to the Mac filesystem's file number
  1155.     for the file.
  1156.     
  1157.     if we open a file, we takes what we get in the creator and filetype department.
  1158.     however, if we create a file it's of the indicated filetype and creator.
  1159.     */
  1160.     
  1161.     if (FSOpen (bs, vnum, fnum) == noErr) /*file exists and is open*/
  1162.         return (true);
  1163.     
  1164.     if (Create (bs, vnum, creator, filetype) != noErr)
  1165.         return (false);
  1166.     
  1167.     if (FSOpen (bs, vnum, fnum) != noErr) {
  1168.     
  1169.         FSClose (*fnum);
  1170.             
  1171.         filedelete (bs, vnum);
  1172.         
  1173.         return (false); /*failed to open the file for writing*/
  1174.         }
  1175.     
  1176.     return (true);
  1177.     } /*fileopenorcreate*/
  1178.     
  1179.     
  1180. boolean fileopen (bs, vnum, fnum) bigstring bs; short vnum; short *fnum; {
  1181.     
  1182.     register OSErr ec;
  1183.     
  1184.     ec = FSOpen (bs, vnum, fnum);
  1185.     
  1186.     return (ec == noErr);
  1187.     } /*fileopen*/
  1188.     
  1189.     
  1190. boolean filenew (bsfname, vnum, creator, filetype, fnum) bigstring bsfname; short vnum; OSType creator, filetype; short *fnum; {
  1191.     
  1192.     register OSErr errcode;
  1193.     
  1194.     if (FSOpen (bsfname, vnum, fnum) == noErr) { /*file exists, delete it*/
  1195.     
  1196.         FSClose (*fnum);
  1197.     
  1198.         filedelete (bsfname, vnum);
  1199.         }
  1200.         
  1201.     errcode = Create (bsfname, vnum, creator, filetype);
  1202.         
  1203.     if (oserror (errcode)) /*failed to open the file for writing*/
  1204.         return (false);
  1205.     
  1206.     errcode = FSOpen (bsfname, vnum, fnum);
  1207.     
  1208.     if (oserror (errcode)) {
  1209.     
  1210.         FSClose (*fnum);
  1211.             
  1212.         filedelete (bsfname, vnum);
  1213.         
  1214.         return (false); /*failed to open the file for writing*/
  1215.         }
  1216.         
  1217.     return (true); /*file exists and its open*/
  1218.     } /*filenew*/
  1219.     
  1220.     
  1221. boolean oserror (errcode) OSErr errcode; {
  1222.     
  1223.     bigstring bs;
  1224.     
  1225.     if (errcode == noErr)
  1226.         return (false);
  1227.     
  1228.     copystring ("\pMacintosh OS Error = ", bs);
  1229.     
  1230.     pushint (errcode, bs);
  1231.     
  1232.     alertdialog (bs);
  1233.     
  1234.     return (true);
  1235.     } /*oserror*/
  1236.     
  1237.     
  1238. boolean filetruncate (fnum) short fnum; {
  1239.     
  1240.     return (SetEOF (fnum, 0) == noErr);
  1241.     } /*filetruncate*/
  1242.  
  1243.  
  1244. boolean filewrite (fnum, ctwrite, buffer) short fnum; long ctwrite; void *buffer; {
  1245.     
  1246.     /*
  1247.     write ctwrite bytes from buffer to the current position in file number
  1248.     fnum.  return true iff successful.
  1249.     */
  1250.  
  1251.     if (ctwrite > 0) 
  1252.  
  1253.         if (FSWrite (fnum, &ctwrite, buffer) != noErr)
  1254.         
  1255.             return (false);
  1256.     
  1257.     return (true);
  1258.     } /*filewrite*/
  1259.     
  1260.     
  1261. boolean fileread (fnum, ctread, buffer) short fnum; long ctread; void *buffer; {
  1262.     
  1263.     /*
  1264.     read ctread bytes from the current position in file number fnum into
  1265.     the buffer.  return true iff successful.
  1266.     */
  1267.  
  1268.     if (ctread > 0)
  1269.         
  1270.         if (oserror (FSRead (fnum, &ctread, buffer)))
  1271.         
  1272.             return (false);
  1273.             
  1274.     return (true);
  1275.     } /*fileread*/
  1276.     
  1277.     
  1278. boolean filegetchar (fnum, buffer) short fnum; byte *buffer; {
  1279.     
  1280.     /*
  1281.     read the next character from the indicated file, returning it in *buffer.
  1282.     
  1283.     return false if we're at the end of the file, without triggering an error
  1284.     dialog.
  1285.     */
  1286.     
  1287.     long fpos, eof;
  1288.     
  1289.     if (GetFPos (fnum, &fpos) != noErr)
  1290.         return (false);
  1291.     
  1292.     if (GetEOF (fnum, &eof) != noErr)
  1293.         return (false);
  1294.     
  1295.     if (fpos == eof)
  1296.         return (false);
  1297.     
  1298.     if (!fileread (fnum, 1L, buffer))
  1299.         return (false);
  1300.         
  1301.     return (true);
  1302.     } /*filegetchar*/
  1303.     
  1304.     
  1305. boolean filewritehandle (fnum, h) short fnum; Handle h; {
  1306.     
  1307.     /*
  1308.     write the indicated handle to the open file indicated by fnum at the
  1309.     current position in the file.
  1310.     */
  1311.     
  1312.     return (filewrite (fnum, GetHandleSize (h), *h));
  1313.     } /*filewritehandle*/
  1314.     
  1315.     
  1316. boolean filereadhandle (fnum, ctbytes, hreturned) short fnum; long ctbytes; Handle *hreturned; {
  1317.     
  1318.     register Handle h;
  1319.     
  1320.     if (!newclearhandle (ctbytes, hreturned))
  1321.         return (false);
  1322.         
  1323.     h = *hreturned; /*copy into register*/
  1324.         
  1325.     if (!fileread (fnum, ctbytes, *h)) {
  1326.         
  1327.         disposehandle (h);
  1328.         
  1329.         return (false);
  1330.         }
  1331.         
  1332.     return (true);
  1333.     } /*filereadhandle*/    
  1334.  
  1335.  
  1336. void setmenuitemenable (hmenu, item, fl) MenuHandle hmenu; short item; boolean fl; {
  1337.     
  1338.     /*
  1339.     enable or disable a menu or a menu item.  if fl is true we enable the item,
  1340.     if false we disable it.
  1341.     
  1342.     if item == 0 we enable or disable the entire menu.
  1343.     
  1344.     dmb 8/1/90:  check for dummy items (negative item numbers)
  1345.     */
  1346.     
  1347.     if (item < 0) /*this item has been dummied out -- do nothing*/
  1348.         return;
  1349.     
  1350.     if (fl)
  1351.         EnableItem (hmenu, item);
  1352.     else
  1353.         DisableItem (hmenu, item);
  1354.     } /*setmenuitemenable*/
  1355.     
  1356.     
  1357. void disablemenuitem (hmenu, item) MenuHandle hmenu; short item; {
  1358.     
  1359.     setmenuitemenable (hmenu, item, false);
  1360.     } /*disablemenuitem*/
  1361.     
  1362.  
  1363. void enablemenuitem (hmenu, item) MenuHandle hmenu; short item; {
  1364.     
  1365.     setmenuitemenable (hmenu, item, true);
  1366.     } /*enablemenuitem*/
  1367.  
  1368.  
  1369. boolean fileparsevolname (bspath, vnum) bigstring bspath; short *vnum; {
  1370.     
  1371.     /*
  1372.     convert a full path, which might contain a volume name at the beginning
  1373.     to a path with no volume name, and it's associated volume number in vnum.
  1374.     
  1375.     example: "Rover¬:MORE Work" will return with bspath = "MORE Work" and
  1376.     vnum = -2 (the Macintosh vrefnum for the second mounted drive).  
  1377.     
  1378.     this combination of information plugs nicely into a lot of the file 
  1379.     manager routines.
  1380.     */
  1381.     
  1382.     short ix = 1;
  1383.     bigstring bsvolname;
  1384.     HParamBlockRec pb;
  1385.     short vrefnum;
  1386.     bigstring bs;
  1387.     
  1388.     copystring (bspath, bs); /*work on a copy*/
  1389.     
  1390.     if (isemptystring (bs))
  1391.         return (false);
  1392.     
  1393.     if (!scanstring (':', bs, &ix)) { /*no colon, the whole thing is a volname*/
  1394.     
  1395.         copystring (bs, bsvolname);
  1396.         
  1397.         pushchar (':', bsvolname);
  1398.         
  1399.         setemptystring (bs);
  1400.         }
  1401.     else {
  1402.         midstring (bs, 1, ix, bsvolname); /*pick off the vol name and the colon*/
  1403.         
  1404.         deletestring (bs, 1, ix);
  1405.         }
  1406.     
  1407.     clearbytes (&pb, longsizeof (pb));
  1408.     
  1409.     pb.volumeParam.ioNamePtr = bsvolname;
  1410.     
  1411.     pb.volumeParam.ioVolIndex = -1; /*force him to use the name pointer only*/
  1412.     
  1413.     if (PBGetVInfo (&pb, false) != noErr)
  1414.         return (false);
  1415.     
  1416.     *vnum = pb.volumeParam.ioVRefNum;
  1417.     
  1418.     return (true);
  1419.     } /*fileparsevolname*/
  1420.  
  1421.  
  1422. boolean filefrompath (path, fname) bigstring path, fname; {
  1423.     
  1424.     /*
  1425.     return all the characters to the right of the colon in the path.
  1426.     
  1427.     example: "Work Disk #1:MORE Work:Status Center" returns "Status Center".
  1428.     */
  1429.     
  1430.     return (lastword (path, ':', fname));
  1431.     } /*filefrompath*/
  1432.     
  1433.     
  1434. boolean folderfrompath (path, folder) bigstring path, folder; {
  1435.     
  1436.     /*
  1437.     return all the characters to the left of the colon, and the colon.
  1438.     
  1439.     example: "Work Disk #1:MORE Work:Status Center" returns "Work Disk #1:MORE Work:".
  1440.     */
  1441.     
  1442.     bigstring bs;
  1443.     
  1444.     lastword (path, ':', bs); /*kind of inefficient, but ensures symmetry*/
  1445.     
  1446.     copystring (path, folder);
  1447.     
  1448.     setstringlength (folder, stringlength (folder) - stringlength (bs));
  1449.     
  1450.     return (true);
  1451.     } /*folderfrompath*/
  1452.     
  1453.     
  1454. boolean pathtofileinfo (path, fname, vnum) bigstring path, fname; short *vnum; {
  1455.     
  1456.     /*
  1457.     convert a Macintosh file path into a file name and a volume number.
  1458.     
  1459.     we also get the directory id of the parent directory, primarily because we
  1460.     have the code here, it supposedly works, and we might need it someday.
  1461.     */
  1462.     
  1463.     CInfoPBRec pb;
  1464.     bigstring folder;
  1465.     long idparent;
  1466.     
  1467.     if (!fileparsevolname (path, vnum)) /*no volume specified*/
  1468.         return (false);
  1469.     
  1470.     folderfrompath (path, folder);
  1471.     
  1472.     filefrompath (path, fname);
  1473.     
  1474.     clearbytes (&pb, longsizeof (pb));
  1475.     
  1476.     pb.dirInfo.ioNamePtr = folder;
  1477.     
  1478.     if (PBGetCatInfo (&pb,false) != noErr)
  1479.         return (false);
  1480.     
  1481.     if (BitTst (&pb.hFileInfo.ioFlAttrib, 3)) /*it's a folder*/
  1482.         idparent = pb.dirInfo.ioDrDirID;
  1483.     else
  1484.         idparent = pb.hFileInfo.ioFlParID;
  1485.     
  1486.     return (true);
  1487.     } /*pathtofileinfo*/
  1488.     
  1489.     
  1490. boolean directorytopath (DirID, vnum, path) long DirID; short vnum; bigstring path; {
  1491.     
  1492.     CInfoPBRec block;
  1493.     bigstring bsdirectory;
  1494.     OSErr errcode;
  1495.     
  1496.     setemptystring (path);
  1497.     
  1498.     clearbytes (&block, longsizeof (block));
  1499.     
  1500.     block.dirInfo.ioNamePtr = bsdirectory;
  1501.     
  1502.     block.dirInfo.ioDrParID = DirID;
  1503.     
  1504.     do {
  1505.         block.dirInfo.ioVRefNum = vnum;
  1506.         
  1507.         block.dirInfo.ioFDirIndex = -1;
  1508.         
  1509.         block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
  1510.         
  1511.         errcode = PBGetCatInfo(&block,false);
  1512.         
  1513.         if (errcode != noErr)
  1514.             return (false);
  1515.         
  1516.         if (!pushchar (':', bsdirectory))
  1517.             return (false);
  1518.             
  1519.         if (!pushstring (path, bsdirectory))
  1520.             return (false);
  1521.         
  1522.         copystring (bsdirectory, path);
  1523.         } while (block.dirInfo.ioDrDirID != fsRtDirID);
  1524.     
  1525.     return (true);
  1526.     } /*directorytopath*/
  1527.  
  1528.  
  1529. static boolean PathNameFromWD (long vnum, bigstring path) {
  1530.     
  1531.     /*
  1532.     PBGetWDInfo has a bug under A/UX 1.1.  If vnum is a real vnum
  1533.     and not a wdRefNum, then it returns garbage.  Since A/UX has only 1
  1534.     volume (in the Macintosh sense) and only 1 root directory, this can
  1535.     occur only when a file has been selected in the root directory (/).
  1536.     So we look for this and hard code the DirID and vnum. 
  1537.     */
  1538.     
  1539.     WDPBRec block;
  1540.     
  1541.     clearbytes (&block, longsizeof (block));
  1542.     
  1543.     block.ioVRefNum = vnum;
  1544.     
  1545.     PBGetWDInfo (&block,false);
  1546.     
  1547.     return (directorytopath (block.ioWDDirID,block.ioWDVRefNum,path));
  1548.     } /*PathNameFromWD*/
  1549.     
  1550.     
  1551. boolean fileinfotopath (fname, vnum, path) bigstring fname; short vnum; bigstring path; {
  1552.     
  1553.     setemptystring (path);
  1554.         
  1555.     if (!PathNameFromWD ((long) vnum, path)) 
  1556.         return (false);
  1557.         
  1558.     pushstring (fname, path);
  1559.     
  1560.     return (true);
  1561.     } /*fileinfotopath*/
  1562.     
  1563.     
  1564. void lockhandle (h) Handle h; {
  1565.     
  1566.     if (h != nil)
  1567.         HLock (h);
  1568.     } /*lockhandle*/
  1569.     
  1570.     
  1571. void unlockhandle (h) Handle h; {
  1572.     
  1573.     if (h != nil)
  1574.         HUnlock (h);
  1575.     } /*unlockhandle*/
  1576.     
  1577.     
  1578. boolean pointinrect (Point pt, Rect r) {
  1579.     
  1580.     return (PtInRect (pt, &r));
  1581.     } /*pointinrect*/
  1582.  
  1583.  
  1584. void validrect (Rect r) {
  1585.     
  1586.     ValidRect (&r);
  1587.     } /*validrect*/
  1588.     
  1589.     
  1590. void zerorect (Rect *rzero) {
  1591.     
  1592.     register Rect *r = rzero;
  1593.     
  1594.     (*r).top = (*r).left = (*r).bottom = (*r).right = 0;
  1595.     } /*zerorect*/
  1596.  
  1597.     
  1598. boolean pushemptyclip (void) {
  1599.     
  1600.     /*
  1601.     set up the clip region so that no display will occur
  1602.     */
  1603.     
  1604.     Rect r;
  1605.     
  1606.     zerorect (&r);
  1607.     
  1608.     return (pushclip (r));
  1609.     } /*pushemptyclip*/
  1610.  
  1611.  
  1612. void globaltolocalpoint (WindowPtr w, Point *pt) {
  1613.     
  1614.     pushmacport (w);
  1615.     
  1616.     GlobalToLocal (pt);
  1617.     
  1618.     popmacport ();
  1619.     } /*globaltolocalpoint*/
  1620.     
  1621.     
  1622. void localtoglobalpoint (WindowPtr w, Point *pt) {
  1623.     
  1624.     pushmacport (w);
  1625.     
  1626.     LocalToGlobal (pt);
  1627.     
  1628.     popmacport ();
  1629.     } /*localtoglobalpoint*/
  1630.     
  1631.     
  1632. void scrollrect (Rect r, short dh, short dv) {
  1633.     
  1634.     /*
  1635.     a front end for the Macintosh routine that scrolls a rectangle of pixels.
  1636.     */
  1637.     
  1638.     register RgnHandle rgn;
  1639.     
  1640.     rgn = NewRgn ();
  1641.     
  1642.     ScrollRect (&r, dh, dv, rgn);
  1643.     
  1644.     InvalRgn (rgn);
  1645.     
  1646.     DisposeRgn (rgn);
  1647.     } /*scrollrect*/
  1648.  
  1649.  
  1650. boolean equalrects (r1, r2) Rect r1, r2; {
  1651.     
  1652.     return (
  1653.         (r1.top == r2.top) && (r1.left == r2.left) && 
  1654.         
  1655.         (r1.bottom == r2.bottom) && (r1.right == r2.right));
  1656.     } /*equalrects*/
  1657.     
  1658.     
  1659. void timestamp (stamp) long *stamp; {
  1660.     
  1661.     GetDateTime (stamp);
  1662.     } /*timestamp*/
  1663.     
  1664.     
  1665. boolean getstringlist (short listnum, short id, bigstring bs) {
  1666.     
  1667.     /*
  1668.     the Mac routine GetIndString doesn't set ResError false when we fall off
  1669.     the end of the indicated list, so we return false if the returned string
  1670.     is of zero length.
  1671.     */
  1672.     
  1673.     GetIndString (bs, listnum, id);
  1674.     
  1675.     return (stringlength (bs) > 0);
  1676.     } /*getstringlist*/
  1677.     
  1678.     
  1679.     
  1680.  
  1681.     
  1682.