iowacore.c

Go to the documentation of this file.
00001 
00002 /*  $Id: iowacore.c 1295 2006-04-18 18:34:24Z andreradke $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "shelltypes.h"
00032 #include "byteorder.h"
00033 
00034 #ifdef iowaRuntime
00035 
00036     #include <appletdefs.h>
00037     #include <appletquickdraw.h>
00038     #include <appletkb.h>
00039     #include <appletfont.h>
00040     #include <appletops.h>
00041     #include <appletmenuops.h>
00042     #include <appletfrontier.h>
00043 
00044 #else
00045 
00046     #include <applet.h>
00047     #include <appletmenuops.h>
00048     
00049 #endif
00050 
00051 #ifndef iowacoreinclude
00052 
00053     #include "iowacore.h"
00054 
00055 #endif
00056 
00057 #include "iowascript.h"
00058 #include "iowaparser.h"
00059 #include "iowafrontier.h"
00060 
00061 
00062 #ifndef iowaRuntime
00063 
00064     #include "iowaattributes.h"
00065     #include "iowainfowindow.h"
00066     #include "iowaiac.h"
00067 
00068 #endif
00069 
00070 
00071 boolean displaydebug = false;
00072 
00073 hdlcard iowadata = nil; /*points to a card record, the one we're currently editing*/
00074 
00075 typedef struct tylookup {
00076     
00077     bigstring name; /*the name we're looking for*/
00078     
00079     hdlobject h; /*the object we found, nil if not found*/
00080     } tylookup;
00081     
00082 tylookup lookup;
00083 
00084 
00085 tyunpackglobals unpack = {nil, nil};
00086 
00087 
00088 typedef struct tyautoname { 
00089     
00090     char untitledstring [32];
00091     
00092     long highestnum; /*dmb 1.0b20 - was short*/
00093     } tyautoname;
00094     
00095 static tyautoname autoname;
00096 
00097 
00098 boolean flalertdialogrunning = false;
00099         
00100 static unsigned long now;
00101 
00102 static boolean specialflag1 = false; /*true when we're drawing objects that can't be drawn in bitmaps*/
00103 
00104 
00105 boolean unpacklist (hdlobject *);
00106 
00107 boolean unpackobject (hdlobject *, boolean *);
00108 
00109 boolean unpacksingleobject (Handle, hdlobject *);
00110 
00111 
00112 
00113 
00114 
00115 
00116 static void iowareadclock (void) {
00117     
00118     GetDateTime (&now);
00119     } /*iowareadclock*/
00120     
00121 
00122 void editclickbottleneck (Point pt, boolean flshiftkey, hdleditrecord hbuffer) {
00123     
00124     /*
00125     new in 1.0b15 -- when the user cmd-2clicks on any text, we shoot it thru
00126     Frontier to open the object or the file.
00127     */
00128     
00129     #ifndef iowaRuntime
00130         Handle htext;
00131     #endif
00132     
00133     editclick (pt, flshiftkey, hbuffer);
00134     
00135     #ifndef iowaRuntime
00136     
00137         if (!keyboardstatus.flcmdkey)
00138             return;
00139         
00140         if (!editgetselectedtexthandle (hbuffer, &htext)) /*error allocating handle*/
00141             return;
00142         
00143         if (gethandlesize (htext) == 0) { /*selection is empty, nothing to jump to*/
00144             
00145             disposehandle (htext);
00146             
00147             return;
00148             }
00149         
00150         apppostcallback ();
00151         
00152         FrontierJump (htext);
00153         
00154         appprecallback ();
00155     
00156     #endif
00157     } /*editclickbottleneck*/
00158 
00159 
00160 boolean runcardscript (Handle hscript, long idlanguage, boolean flgetreturn, bigstring errorstring, Handle *hreturns) {
00161 
00162     /*
00163     dmb 1.0b20 -- added this wrapper to save iowadata
00164     */
00165     
00166     boolean fl;
00167     hdlcard saveiowadata = iowadata;
00168     
00169     fl = runlangscript (hscript, (**iowadata).tablename, idlanguage, flgetreturn, errorstring, hreturns);
00170     
00171     iowadata = saveiowadata;
00172     
00173     return (fl);
00174     } /*runcardscript*/
00175 
00176     
00177 boolean cardFastScript (bigstring bspre, Handle hmid, bigstring bspost) {
00178     
00179     /*
00180     a jacket for sending a fast do-script message to Frontier.
00181     
00182     the three bits of text are concatenated and sent to Frontier for execution.
00183     
00184     if an error happens, we display it and return false.
00185     */
00186     
00187     Handle h;
00188     bigstring errorstring;
00189     Handle htoss;
00190     
00191     if (flalertdialogrunning)
00192         return (false);
00193     
00194     if (!newtexthandle (bspre, &h))
00195         return (false);
00196         
00197     if (!pushhandleonhandle (hmid, h))
00198         goto error;
00199         
00200     if (!pushtexthandle (bspost, h))
00201         goto error;
00202         
00203     if (!runcardscript (h, idUserTalk, true, errorstring, &htoss)) {
00204         
00205         if (stringlength (errorstring) > 0) {
00206         
00207             flalertdialogrunning = true;
00208         
00209             alertdialog (errorstring); 
00210         
00211             flalertdialogrunning = false;
00212             }
00213         
00214         return (false);
00215         }
00216     
00217     return (true);
00218     
00219     error:
00220     
00221     disposehandle (h);
00222     
00223     return (false);
00224     } /*cardFastScript*/
00225     
00226 
00227 short makemultiple (short val, short factor) {
00228     
00229     /*
00230     return a multiple of factor, round up in all cases -- that is, if
00231     it's even one more than the nearest multiple, return the next one.
00232     */
00233     
00234     if ((val % factor) == 0) /*it's already a multiple, nothing to do*/
00235         return (val);
00236         
00237     val = ((val / factor) + 1) * factor;
00238     
00239     if (val == 0)
00240         val = factor;
00241         
00242     return (val);
00243     } /*makemultiple*/
00244     
00245     
00246 short closestmultiple (short val, short factor) {
00247     
00248     /*
00249     return a multiple of factor, round to the nearest multiple.
00250     */
00251     
00252     short x, diff;
00253     
00254     if ((val % factor) == 0) /*it's already a multiple, nothing to do*/
00255         return (val);
00256     
00257     x = (val / factor) * factor;
00258     
00259     diff = val - x;
00260     
00261     if (diff >= (factor / 2)) /*move to the next stop up*/
00262         x += factor;
00263         
00264     return (x);
00265     } /*closestmultiple*/
00266     
00267 
00268 void pushtemphandle (Handle h) {
00269     
00270     hdlcard hc = iowadata;
00271     short i;
00272     
00273     for (i = 0; i < cttemphandles; i++) {
00274     
00275         if ((**hc).temphandles [i] == nil) {
00276             
00277             (**hc).temphandles [i] = h;
00278             
00279             return;
00280             }
00281         } /*for*/
00282         
00283     DebugStr ("\pDW: increase size of temphandle array.");
00284     } /*pushtemphandle*/
00285     
00286     
00287 void releasetemphandles (void) {
00288     
00289     hdlcard hc = iowadata;
00290     short i;
00291     
00292     for (i = 0; i < cttemphandles; i++) {
00293     
00294         if ((**hc).temphandles [i] != nil) {
00295             
00296             disposehandle ((**hc).temphandles [i]);
00297             
00298             (**hc).temphandles [i] = nil;
00299             }
00300         } /*for*/
00301     } /*releasetemphandles*/
00302     
00303     
00304 void disposetemphandle (Handle h) {
00305     
00306     hdlcard hc = iowadata;
00307     short i;
00308     
00309     disposehandle (h);
00310     
00311     for (i = 0; i < cttemphandles; i++) {
00312     
00313         if ((**hc).temphandles [i] == h) {
00314             
00315             (**hc).temphandles [i] = nil;
00316             
00317             return;
00318             }
00319         } /*for*/
00320     } /*disposetemphandle*/
00321     
00322     
00323 void pushobjectstyle (hdlobject h) {
00324     
00325     RGBColor forecolor;
00326     
00327     pushstyle ((**h).objectfont, (**h).objectfontsize, (**h).objectstyle);
00328     
00329     if (!(**h).objectenabled)
00330         forecolor = graycolor;
00331     else
00332         forecolor = (**h).objecttextcolor;
00333         
00334     pushcolors (&forecolor, &(**h).objectfillcolor);
00335     } /*pushobjectstyle*/
00336     
00337     
00338 void popobjectstyle (void) {
00339     
00340     popstyle ();
00341     
00342     popcolors ();
00343     } /*popobjectstyle*/
00344     
00345     
00346 static boolean autonamevisit (hdlobject h) {
00347     
00348     bigstring bs, bsuntitled;
00349     
00350     texthandletostring ((**h).objectname, bs);
00351     
00352     copystring (autoname.untitledstring, bsuntitled);
00353     
00354     if (patternmatch (bsuntitled, bs) == 1) {
00355         
00356         long x;
00357         
00358         deletestring (bs, 1, stringlength (bsuntitled));
00359         
00360         if ((bs [1] >= '0') && (bs [1] <= '9')) { /*dmb 1.0b20 - make sure it's a number*/
00361             
00362             StringToNum (bs, &x);
00363             
00364             if (x > autoname.highestnum)
00365                 autoname.highestnum = x;
00366             }
00367         }
00368     
00369     return (true);
00370     } /*autonamevisit*/
00371     
00372     
00373 boolean autonameobject (hdlobject h) {
00374     
00375     bigstring bs, bsnum;
00376     Handle htext;
00377     
00378     iowagetstring (untitledobjectname, bs);
00379     
00380     copystring (bs, autoname.untitledstring);
00381     
00382     autoname.highestnum = 0;
00383     
00384     visitobjects ((**iowadata).objectlist, &autonamevisit);
00385     
00386     NumToString (autoname.highestnum + 1, bsnum);
00387     
00388     pushstring (bsnum, bs);
00389     
00390     if (!newtexthandle (bs, &htext))
00391         return (false);
00392     
00393     setobjectname (h, htext);
00394     
00395     return (true);
00396     } /*autonameobject*/
00397 
00398 
00399 static short framevertinset (void) {
00400 
00401     return (((globalfontinfo.ascent + globalfontinfo.descent) / 2) + textvertinset);
00402     } /*framevertinset*/
00403     
00404     
00405 void toggleobjectflag (hdlobject h) {
00406     
00407     (**h).objectflag = !(**h).objectflag;
00408     } /*toggleobjectflag*/
00409     
00410 
00411 void getlastinlist (hdlobject h, hdlobject *hlast) {
00412     
00413     hdlobject nomad = h;
00414     
00415     while (nomad != nil) {
00416         
00417         *hlast = nomad;
00418         
00419         nomad = (**nomad).nextobject;
00420         } /*while*/
00421     } /*getlastinlist*/
00422     
00423     
00424 boolean inselection (hdlobject x) {
00425     
00426     hdlobject nomad = (**iowadata).selectionlist;
00427     
00428     while (nomad != nil) {
00429         
00430         if (nomad == x) /*it's in the list, therefore it is selected*/
00431             return (true);
00432             
00433         nomad = (**nomad).nextselectedobject;
00434         } /*while*/
00435         
00436     return (false); /*it wasn't in the list*/
00437     } /*inselection*/
00438     
00439 
00440 short countobjects (hdlobject hlist) {
00441 
00442     hdlobject x = hlist;
00443     short ct = 0;
00444     
00445     while (x != nil) { /*count the objects in the list*/
00446         
00447         ct++;
00448         
00449         x = (**x).nextobject;
00450         } /*while*/
00451     
00452     return (ct);
00453     } /*countobjects*/
00454     
00455     
00456 boolean getnthobject (hdlobject hlist, short n, hdlobject *h) {
00457     
00458     hdlobject x;
00459     short ct;
00460     short i;
00461     
00462     ct = countobjects (hlist) - n;
00463     
00464     if (ct < 0) /*not enough objects*/
00465         return (false);
00466         
00467     x = hlist;
00468     
00469     for (i = 1; i <= ct; i++) 
00470         x = (**x).nextobject;
00471         
00472     *h = x;
00473     
00474     return (true);
00475     } /*getnthobject*/
00476     
00477     
00478 boolean findobject (Point pt, hdlobject hlist, hdlobject *h) {
00479     
00480     short i = 1;
00481     hdlobject nthobject;
00482     Rect r;
00483     
00484     while (getnthobject (hlist, i++, &nthobject)) {
00485         
00486         if (getobjectrect (nthobject, &r)) {
00487         
00488             if (PtInRect (pt, &r)) {
00489                 
00490                 *h = nthobject;
00491                 
00492                 return (true);
00493                 }
00494             }
00495         } /*while*/
00496         
00497     /*1.0b15 -- some objects, e.g. frames, draw text outside the object rect*/
00498     
00499     i = 1;
00500     
00501     while (getnthobject (hlist, i++, &nthobject)) {
00502         
00503         if (geteditrect (nthobject, &r)) {
00504         
00505             if (PtInRect (pt, &r)) {
00506                 
00507                 *h = nthobject;
00508                 
00509                 return (true);
00510                 }
00511             }
00512         } /*while*/
00513         
00514     return (false);
00515     } /*findobject*/
00516 
00517 
00518 void getchildobjectlist (hdlobject h, hdlobject *childobjectlist) {
00519     
00520     *childobjectlist = (**h).childobjectlist;
00521     } /*getchildobjectlist*/
00522     
00523     
00524 boolean findterminalobject (Point pt, hdlobject listhead, hdlobject *hparent, hdlobject *hobject) {
00525     
00526     hdlobject x;
00527     
00528     while (true) { 
00529         
00530         if (!findobject (pt, listhead, &x))
00531             return (false);
00532             
00533         if ((**x).objecttype != grouptype) { /*at a terminal node*/
00534             
00535             *hparent = listhead;
00536             
00537             *hobject = x;
00538             
00539             return (true);
00540             }
00541         
00542         getchildobjectlist (x, &listhead);
00543         } /*while*/
00544     } /*findterminalobject*/
00545     
00546 
00547 boolean visitobjects (hdlobject listhead, tyobjectvisitroutine visit) {
00548     
00549     /*
00550     visits all terminal nodes at all levels. we don't call the visit routine
00551     on group nodes.
00552     */
00553     
00554     hdlobject nomad = listhead;
00555     hdlobject nextnomad;
00556     
00557     while (nomad != nil) {
00558         
00559         nextnomad = (**nomad).nextobject;
00560         
00561         if ((**nomad).objecttype == grouptype) {
00562         
00563             if (!visitobjects ((**nomad).childobjectlist, visit))
00564                 return (false);
00565             }
00566             
00567         if (!(*visit) (nomad))
00568             return (false);
00569             
00570         nomad = nextnomad;
00571         } /*while*/
00572     
00573     return (true);
00574     } /*visitobjects*/
00575     
00576     
00577 boolean visittoplevelobjects (hdlobject listhead, tyobjectvisitroutine visit) {
00578     
00579     /*
00580     visit all nodes in the list, including groups. but don't dive into groups.
00581     */
00582     
00583     hdlobject nomad = listhead;
00584     hdlobject nextnomad;
00585     
00586     while (nomad != nil) {
00587         
00588         nextnomad = (**nomad).nextobject;
00589         
00590         if (!(*visit) (nomad))
00591             return (false);
00592             
00593         nomad = nextnomad;
00594         } /*while*/
00595     
00596     return (true);
00597     } /*visittoplevelobjects*/
00598     
00599     
00600 static boolean cleartmpbitvisit (hdlobject h) {
00601     
00602     (**h).objecttmpbit = false;
00603     
00604     return (true);
00605     } /*cleartmpbitvisit*/
00606     
00607     
00608 void clearalltmpbits (void) {
00609 
00610     visitobjects ((**iowadata).objectlist, &cleartmpbitvisit);
00611     } /*clearalltmpbits*/
00612     
00613 
00614 boolean derefclone (hdlobject *hsource) {
00615     
00616     /*
00617     if the object is a clone, return true, and set *h to the 
00618     thing the clone points to. loop until you find something that
00619     isn't a clone, allows clones to point to clones and on and on.
00620     */
00621     
00622     hdlobject nomad = *hsource;
00623     boolean flclone = false;
00624     
00625     while ((**nomad).objecttype == clonetype) {
00626         
00627         hdlobject hdata = (hdlobject) (**nomad).objectdata;
00628         
00629         if (hdata == nil) /*encountered an unresolved clone*/
00630             return (false);
00631         
00632         nomad = hdata;
00633         
00634         flclone = true;
00635         } /*while*/
00636     
00637     *hsource = nomad;
00638     
00639     return (flclone);
00640     } /*derefclone*/
00641     
00642 
00643 void turnoffallexclusiveobjects (hdlobject firstobject) {
00644     
00645     hdlobject x = firstobject;
00646     
00647     while (x != nil) {
00648         
00649         derefclone (&x);
00650         
00651         if (callmutallyexclusive (x)) {
00652             
00653             (**x).objectflag = false;
00654             
00655             invalobject (x);
00656             }
00657     
00658         x = (**x).nextobject;
00659         } /*while*/
00660     } /*turnoffallexclusiveobjects*/
00661     
00662     
00663 void turnonfirstexclusiveobject (hdlobject firstobject) {
00664     
00665     /*
00666     12/29/92 DW: upgraded to turn on the upper, leftmost object
00667     in the list. before it was essentially a random selection as
00668     far as the user is concerned. a nose-hair.
00669     
00670     1/17/93 DW: make it general, it handles any exclusive type, but
00671     only one type per group.
00672     */
00673     
00674     hdlobject x = firstobject;
00675     hdlobject hsmallest = nil;
00676     Rect rsmallest;
00677     
00678     while (x != nil) {
00679         
00680         if (!(**x).objectenabled)
00681             goto next;
00682             
00683         derefclone (&x);
00684         
00685         if (!(**x).objectenabled)
00686             goto next;
00687             
00688         if (callmutallyexclusive (x)) {
00689             
00690             Rect r = (**x).objectrect;
00691             
00692             if (hsmallest == nil) {
00693                 
00694                 rsmallest = r;
00695                 
00696                 hsmallest = x;
00697                 }
00698             else {
00699                 if (rectlessthan (r, rsmallest)) {
00700                     
00701                     rsmallest = r;
00702                     
00703                     hsmallest = x;
00704                     }
00705                 }
00706                 
00707             (**x).objectflag = false;
00708             
00709             invalobject (x);
00710             }
00711         
00712         next:
00713         
00714         x = (**x).nextobject;
00715         } /*while*/
00716         
00717     if (hsmallest != nil) 
00718         (**hsmallest).objectflag = true;
00719     } /*turnonfirstexclusiveobject*/
00720     
00721     
00722 boolean initexclusiveobjectsvisit (hdlobject h) {
00723     
00724     /*
00725     turn on the first mutually exclusive object in each group, turn 
00726     all others off.
00727     */
00728     
00729     derefclone (&h);
00730     
00731     if ((**h).objecttype == grouptype) 
00732         turnonfirstexclusiveobject ((**h).childobjectlist);
00733         
00734     return (true);
00735     } /*initexclusiveobjectsvisit*/
00736     
00737     
00738 boolean recalcbottleneck (hdlobject h, boolean flmajorrecalc) {
00739     
00740     if ((**h).objectrecalcscript == nil) /*save a bunch of effort, it wasn't meant to be recalcd*/
00741         return (true);
00742     
00743     iowareadclock ();
00744     
00745     (**h).objectnextruntime = now + (**h).objectrecalcperiod;
00746     
00747     #ifdef iowaRuntime
00748     
00749         return (callrecalcobject (h, flmajorrecalc));
00750     
00751     #else 
00752         if ((**iowadata).runmode)
00753             return (callrecalcobject (h, flmajorrecalc));
00754             
00755         #ifdef iowaRuntimeInApp
00756             return (callrecalcobject (h, flmajorrecalc));
00757         #else
00758             (**h).objecttmpbit = flmajorrecalc;
00759         
00760             (**h).owningcard = iowadata;
00761         
00762             return (uisRecalcObject ((Handle) h));
00763         #endif
00764     #endif
00765     } /*recalcbottleneck*/
00766     
00767 
00768 boolean minorrecalcvisit (hdlobject h) {
00769     
00770     if (h == (**iowadata).recalcobject) /*dmb 1.0b20 - don't recalc the source of the recalc*/
00771         return (true);
00772     
00773     if ((**h).objectrecalcstatus >= changerecalc) {
00774     
00775         derefclone (&h);
00776     
00777         recalcbottleneck (h, false);
00778         }
00779         
00780     return (true); /*keep visiting*/
00781     } /*minorrecalcvisit*/
00782     
00783 
00784 boolean majorrecalcvisit (hdlobject h) {
00785 
00786     switch ((**h).objecttype) {
00787         
00788         case clonetype:
00789             recalcclone (h);
00790             
00791             break;
00792             
00793         default:
00794             if ((**h).objectrecalcstatus >= initrecalc)
00795                 recalcbottleneck (h, true);
00796             
00797             break;
00798         } /*switch*/
00799     
00800     return (true); /*keep visiting*/    
00801     } /*majorrecalcvisit*/
00802     
00803 
00804 static boolean flsomethingrecalcd = false;
00805 
00806 
00807 static boolean checkagentvisit (hdlobject h) {
00808     
00809     if ((**h).objectrecalcstatus < timerecalc)
00810         return (true);
00811     
00812     if (now < (**h).objectnextruntime)
00813         return (true);
00814     
00815     if (!flsomethingrecalcd) {
00816     
00817         frontSetRuntimeCard (true, false);
00818             
00819         flsomethingrecalcd = true;
00820         }
00821     
00822     recalcbottleneck (h, true); /*also sets objectnextruntime*/
00823     
00824     return (true); /*keep visiting*/    
00825     } /*checkagentvisit*/
00826     
00827 
00828 void checkrecalc (void) {
00829 
00830     if ((**iowadata).recalcneeded) {
00831         
00832         if (TickCount () >= (**iowadata).recalctickcount) {
00833             
00834             frontSetRuntimeCard (true, false);
00835             
00836             visitobjects ((**iowadata).objectlist, &minorrecalcvisit);
00837             
00838             (**iowadata).recalcneeded = false;
00839             }
00840         }
00841     
00842     flsomethingrecalcd = false;
00843     
00844     iowareadclock ();
00845     
00846     visitobjects ((**iowadata).objectlist, &checkagentvisit);
00847     
00848     if (flsomethingrecalcd)
00849         iowaupdatenow ();
00850     } /*checkrecalc*/
00851 
00852 
00853 void schedulerecalc (hdlobject h, short ctticks) {
00854     
00855     /*
00856     if ctticks == 0: schedule a minor recalc next time 
00857     thru the event loop.
00858     
00859     usually ctticks is 0, the only exception is when 
00860     the user is interacting and a delay could be 
00861     disruptive. an example, editing text in cardrunner.
00862     
00863     1.0b20 dmb: added hdlobject parameter, the object that
00864     caused the recalc and should not be recalced again.
00865     */
00866 
00867     (**iowadata).recalcneeded = true;
00868     
00869     (**iowadata).recalctickcount = TickCount () + ctticks;
00870     
00871     (**iowadata).recalcobject = h;
00872     } /*schedulerecalc*/
00873     
00874     
00875 void recalcobject (hdlobject h) {
00876     
00877     majorrecalcvisit (h);
00878 
00879     schedulerecalc (h, 0); /*do a minor recalc*/
00880     } /*recalcobject*/
00881     
00882     
00883 void getgrouprect (hdlobject h, Rect *r) {
00884     
00885     hdlobject nomad;
00886     Rect robject, runion, rgroup;
00887     boolean flfirstloop = true;
00888     
00889     nomad = (**h).childobjectlist;
00890     
00891     while (nomad != nil) {
00892         
00893         getobjectrect (nomad, &robject);
00894         
00895         if (flfirstloop) {
00896             
00897             rgroup = robject;
00898             
00899             flfirstloop = false;
00900             }
00901         else {
00902             UnionRect (&robject, &rgroup, &runion);
00903         
00904             rgroup = runion;
00905             }
00906         
00907         nomad = (**nomad).nextobject;
00908         } /*while*/
00909     
00910     if ((**h).objecthasframe) {
00911         
00912         Rect tempRect; // 2006-04-03 - kw ---renamed from robject - shadowwarning
00913         
00914         tempRect = (**h).objectrect;
00915         
00916         if (!EmptyRect (&tempRect)) { /*user has changed its rect, it takes precedence*/
00917             
00918             rgroup = tempRect;
00919             
00920             goto exit;
00921             }
00922             
00923         pushobjectstyle (h);
00924         
00925         rgroup.top -= framevertinset () * 2;
00926         
00927         rgroup.bottom += framevertinset ();
00928         
00929         rgroup.left -= 8;
00930         
00931         rgroup.right += 24;
00932         
00933         popobjectstyle ();
00934         }
00935     
00936     exit:
00937     
00938     *r = rgroup;
00939     } /*getgrouprect*/
00940     
00941     
00942 boolean getobjectrect (hdlobject h, Rect *robject) {
00943     
00944     Rect r;
00945     
00946     r = (**h).objectrect;
00947     
00948     switch ((**h).objecttype) {
00949     
00950         case grouptype:
00951             getgrouprect (h, &r);
00952             
00953             break;
00954         } /*switch*/
00955         
00956     *robject = r;
00957     
00958     return (true);
00959     } /*getobjectrect*/
00960     
00961     
00962 void getobjectnamestring (hdlobject h, bigstring bs) {
00963     
00964     /*
00965     object names are limited to 255 characters. 
00966     
00967     doesn't seem like too onerous a limitation. 7/6/92 DW.
00968     */
00969     
00970     texthandletostring ((**h).objectname, bs);
00971     } /*getobjectnamestring*/
00972     
00973     
00974 void getobjectvalue (hdlobject h, Handle *hvalue) {
00975 
00976     if (h == (**iowadata).activetextobject)
00977         editgettexthandle ((hdleditrecord) (**h).objecteditrecord, hvalue);
00978     else
00979         *hvalue = (**h).objectvalue;
00980     
00981     if (*hvalue == nil)
00982         newemptyhandle (hvalue);
00983     } /*getobjectvalue*/
00984     
00985     
00986 void getobjectsize (hdlobject h, short *height, short *width) {
00987     
00988     /*
00989     12/19/92 DW: what if htext is nil? at first it seemed best to set 
00990     height and width to 0. but there extra smartness in editgetsize. 
00991     so we allocate an empty handle and pass it to editgetsize and
00992     release it when we're done.
00993     */
00994     
00995     Handle htext;
00996     boolean flrelease = false;
00997     
00998     getobjectvalue (h, &htext); 
00999     
01000     if (htext == nil) {
01001         
01002         if (!newclearhandle (0, &htext)) { /*fail gracefully*/
01003         
01004             *height = *width = 0;
01005         
01006             return;
01007             }
01008         
01009         flrelease = true;
01010         }
01011         
01012     pushobjectstyle (h);
01013 
01014     editgetsize (htext, height, width);
01015     
01016     popobjectstyle ();
01017     
01018     if (flrelease)
01019         disposehandle (htext);
01020     } /*getobjectsize*/
01021     
01022     
01023 void getobjectname (hdlobject h, Handle *hname) {
01024 
01025     *hname = (**h).objectname;
01026     } /*getobjectname*/
01027     
01028 
01029 void getobjectscript (hdlobject h, Handle *hscript) {
01030 
01031     *hscript = (**h).objectscript;
01032     } /*getobjectscript*/
01033     
01034 
01035 void getobjectrecalcscript (hdlobject h, Handle *hscript) {
01036 
01037     *hscript = (**h).objectrecalcscript;
01038     } /*getobjectrecalcscript*/
01039     
01040 
01041 void setobjectvalue (hdlobject h, Handle hvalue) {
01042     
01043     /*
01044     DW 8/24/93: if it's the active text object, also set the text
01045     displayed in the edit buffer.
01046     
01047     8/12/96 dmb: just like setCardValue, we must force the object to
01048     update. Brent's Fortune Generator cards revealed this bug under 
01049     MacBird Runtime; calling setObjectAttributes to change the fortune 
01050     text (which ends up calling this routine) would not force an update. 
01051     I suspect that under Iowa, the object must be the active text object, 
01052     which would always be updated above.
01053     */
01054     
01055     if (h == (**iowadata).activetextobject)
01056         editsettexthandle ((hdleditrecord) (**h).objecteditrecord, hvalue, true);
01057     else {
01058         
01059         (**h).objectinval = true; /*8/12/96 dmb: force update*/
01060         
01061         (**iowadata).needsupdate = true;
01062         }
01063     
01064     disposehandle ((**h).objectvalue);
01065     
01066     (**h).objectvalue = hvalue;
01067     
01068     schedulerecalc (h, 0);
01069     } /*setobjectvalue*/
01070     
01071     
01072 void setobjectscript (hdlobject h, Handle hscript) {
01073     
01074     disposehandle ((**h).objectscript);
01075     
01076     if (hscript != nil) {
01077     
01078         if (GetHandleSize (hscript) == 0) { /*empty scripts are represented by a nil handle*/
01079             
01080             disposehandle (hscript);
01081             
01082             hscript = nil;
01083             }
01084         }
01085     
01086     (**h).objectscript = hscript;
01087     
01088     recalcobject (h);
01089     
01090     schedulerecalc (h, 0);  
01091     } /*setobjectscript*/
01092     
01093     
01094 void setobjectrecalcscript (hdlobject h, Handle hscript) {
01095     
01096     disposehandle ((**h).objectrecalcscript);
01097     
01098     if (hscript != nil) {
01099     
01100         if (GetHandleSize (hscript) == 0) { /*empty scripts are represented by a nil handle*/
01101             
01102             disposehandle (hscript);
01103             
01104             hscript = nil;
01105             }
01106         }
01107     
01108     (**h).objectrecalcscript = hscript;
01109     
01110     recalcobject (h);
01111     
01112     schedulerecalc (h, 0);  
01113     } /*setobjectrecalcscript*/
01114     
01115     
01116 void setobjectname (hdlobject h, Handle hname) {
01117     
01118     disposehandle ((**h).objectname);
01119     
01120     (**h).objectname = hname;
01121     
01122     schedulerecalc (h, 0);
01123     } /*setobjectname*/
01124     
01125     
01126 void setobjecterrormessage (hdlobject h, Handle herrorstring) {
01127     
01128     disposehandle ((**h).objecterrormessage);
01129     
01130     (**h).objecterrormessage = herrorstring;
01131     
01132     #ifndef iowaRuntime 
01133         
01134         reseterrorinfowindow ();
01135 
01136     #endif
01137     } /*setobjecterrormessage*/
01138     
01139     
01140 void waitfornexttick (void) {
01141     
01142     /*
01143     call this before drawing to avoid flicker in displaying stuff where
01144     flickering is a problem. should be rarely used. the theory is that 
01145     if the tick count just rolled over, the vertical blanking interval
01146     code just ran. it's fair to assume we can still get a few more things
01147     to happen before the screen starts refreshing again.
01148     */
01149 
01150     unsigned long tc = TickCount ();
01151 
01152     while (TickCount () == tc) {} 
01153     } /*waitfornexttick*/
01154     
01155     
01156 void debugrect (Rect r) {
01157 
01158     if (displaydebug) {
01159         //Code change by Timothy Paustian Monday, June 26, 2000 2:46:27 PM
01160         //
01161         #if TARGET_API_MAC_CARBON == 1
01162         {
01163         Pattern gray;
01164         GetQDGlobalsGray(&gray);
01165         FillRect(&r, &gray);
01166         }
01167         #else
01168         FillRect (&r, &quickdrawglobal (gray));
01169         #endif
01170         /*FrameRect (&r);*/
01171         
01172         waitfornexttick ();
01173         }
01174     } /*debugrect*/
01175     
01176 
01177 boolean iowagetstring (short ix, bigstring bs) {
01178     
01179     GetIndString (bs, uistringlist, ix);
01180     
01181     return (true);
01182     } /*iowagetstring*/
01183 
01184 
01185 void iowainvalrect (Rect *rinval) {
01186     
01187     Rect r = *rinval;
01188     //Code change by Timothy Paustian Friday, May 5, 2000 10:48:00 PM
01189     //Changed to Opaque call for Carbon
01190     if (!(IsWindowVisible((**iowadata).drawwindow))) /*dmb 1.0b24*/
01191         return;
01192     
01193     if (r.left < 0) /*avoid invalidating part of the tool palette*/
01194         r.left = 0;
01195     
01196     if (r.top < 0) /*avoid invalidating part of the status bar*/
01197         r.top = 0;
01198         
01199     if (!emptyrect (r)) {
01200     
01201         debugrect (r);
01202         
01203         InsetRect (&r, -1, -1); /*1.0b14 -- hide grid display glitchiness*/
01204     
01205         #if TARGET_API_MAC_CARBON == 1
01206         if((**iowadata).drawwindow != nil)
01207             InvalWindowRect((**iowadata).drawwindow, &r);
01208         #else
01209         InvalRect (&r);
01210         #endif
01211         
01212         }
01213     } /*iowainvalrect*/
01214     
01215     
01216 void getobjectinvalrect (hdlobject h, Rect *r) {
01217     
01218     callgetinvalrect (h, r);
01219     
01220     (*r).right += (**h).objectdropshadowdepth;
01221     
01222     (*r).bottom += (**h).objectdropshadowdepth;
01223 
01224     switch ((**h).objecttype) {
01225         
01226         case clonetype: 
01227             if (derefclone (&h)) {
01228             
01229                 Rect rtarget;
01230             
01231                 callgetinvalrect (h, &rtarget);
01232             
01233                 rtarget.right += (**h).objectdropshadowdepth;
01234     
01235                 rtarget.bottom += (**h).objectdropshadowdepth;
01236                 
01237                 UnionRect (r, &rtarget, r);
01238                 }
01239             
01240             break;
01241             
01242         case grouptype: {
01243             hdlobject nomad = (**h).childobjectlist;
01244         
01245             zerorect (r);
01246         
01247             while (nomad != nil) {
01248             
01249                 Rect rnomad;
01250             
01251                 getobjectinvalrect (nomad, &rnomad);
01252             
01253                 UnionRect (r, &rnomad, r);
01254             
01255                 nomad = (**nomad).nextobject;
01256                 } /*while*/
01257             
01258             break;
01259             }
01260         } /*switch*/
01261     } /*getobjectinvalrect*/
01262     
01263 
01264 void invalobject (hdlobject h) {
01265     
01266     Rect r;
01267     
01268     if (h == nil) /*defensive driving, needed for clones, 1/25/93 DW*/
01269         return;
01270     
01271     getobjectinvalrect (h, &r);
01272     
01273     iowainvalrect (&r);
01274     
01275     if ((**h).objecttype == clonetype)
01276         invalobject ((hdlobject) (**h).objectdata);
01277     } /*invalobject*/
01278     
01279     
01280 void validobject (hdlobject h) {
01281 
01282     Rect r;
01283     
01284     if (h == nil)
01285         return;
01286     
01287     getobjectinvalrect (h, &r);
01288     //Code change by Timothy Paustian Monday, June 26, 2000 2:53:26 PM
01289     //
01290     #if TARGET_API_MAC_CARBON == 1
01291     if((**iowadata).drawwindow != nil)
01292         ValidWindowRect((**iowadata).drawwindow, &r);
01293     #else   
01294     ValidRect (&r);
01295     #endif
01296         
01297     (**h).objectinval = false; /*cancel any pending update*/
01298     } /*validobject*/
01299     
01300             
01301 boolean unlinkobject (hdlobject x) {
01302     
01303     /*
01304     unlink the indicated object from the object list.
01305     */
01306 
01307     hdlobject nomad = (**iowadata).objectlist;
01308     hdlobject prevnomad = nil, nextnomad;
01309     
01310     while (nomad != nil) {
01311         
01312         nextnomad = (**nomad).nextobject;
01313         
01314         if (nomad == x) {
01315             
01316             if (prevnomad == nil)
01317                 (**iowadata).objectlist = nextnomad;
01318             else
01319                 (**prevnomad).nextobject = nextnomad;
01320             
01321             return (true);
01322             }
01323         
01324         prevnomad = nomad;
01325         
01326         nomad = nextnomad;
01327         } /*while*/
01328     
01329     return (false);
01330     } /*unlinkobject*/
01331 
01332 
01333 void movegroupto (hdlobject x, short h, short v) {
01334     
01335     hdlobject childobjectlist;
01336     hdlobject nomad;
01337     Rect r;
01338     short hdiff, vdiff;
01339     
01340     getobjectrect (x, &r);
01341     
01342     hdiff = h - r.left;
01343         
01344     vdiff = v - r.top;
01345     
01346     getchildobjectlist (x, &childobjectlist);
01347     
01348     nomad = childobjectlist;
01349     
01350     while (nomad != nil) {
01351         
01352         getobjectrect (nomad, &r);
01353         
01354         OffsetRect (&r, hdiff, vdiff);
01355         
01356         putobjectrect (nomad, r);
01357         
01358         nomad = (**nomad).nextobject;
01359         } /*while*/
01360     } /*movegroupto*/
01361 
01362 
01363 boolean putobjectrect (hdlobject h, Rect r) {
01364     
01365     if ((**h).objecttype == grouptype) { 
01366         
01367         movegroupto (h, r.left, r.top);
01368         
01369         (**h).objectrect = r;
01370         
01371         return (true);
01372         }
01373     
01374     (**h).objectrect = r;
01375     
01376     return (true);
01377     } /*putobjectrect*/
01378 
01379 
01380 static boolean preupdatevisit (hdlobject h) {
01381     
01382     if ((**h).objectinval) {
01383         
01384         (**h).objectinval = false;
01385         
01386         invalobject (h);
01387         
01388         debugrect ((**h).objectrect);
01389         }
01390         
01391     return (true);
01392     } /*preupdatevisit*/
01393     
01394     
01395 boolean iowapreupdate (void) {
01396     
01397     if (iowadata != nil)
01398         visitobjects ((**iowadata).objectlist, &preupdatevisit);
01399     
01400     return (true);
01401     } /*iowapreupdate*/
01402     
01403     
01404 void disposeobjectlist (hdlobject hlist) {
01405     
01406     hdlobject nomad = hlist;
01407     hdlobject nextnomad;
01408     
01409     while (nomad != nil) { 
01410         
01411         nextnomad = (**nomad).nextobject;
01412         
01413         disposeobject (nomad);
01414         
01415         nomad = nextnomad;
01416         } /*while*/
01417     } /*disposeobjectlist*/
01418     
01419 
01420 void disposeobject (hdlobject h) {
01421     
01422     if (h == nil)
01423         return;
01424     
01425     if ((**h).objecttype == clonetype) 
01426         disposeobject ((hdlobject) (**h).objectdata);
01427     else {
01428         calldisposedata (h);
01429         
01430         disposehandle ((**h).objectdata);
01431         }
01432         
01433     disposeobjectlist ((**h).childobjectlist);
01434     
01435     disposehandle ((Handle) (**h).objectname);
01436     
01437     disposehandle ((Handle) (**h).objectvalue);
01438     
01439     disposehandle ((Handle) (**h).objectscript);
01440     
01441     disposehandle ((Handle) (**h).objecterrormessage);
01442     
01443     disposehandle ((Handle) h);
01444     } /*disposeobject*/
01445     
01446     
01447 boolean iowadisposerecord (void) {
01448 
01449     /*
01450     DW 1/14/95: Card Editor must run even if Frontier
01451     isn't running.
01452     */
01453     
01454     releasetemphandles ();
01455     
01456     if (findlangcomponent (idfrontier) != 0) /*DW 1/14/95*/
01457         frontDeleteCardTable (); /*call a script that deletes the table*/
01458     
01459     disposeobjectlist ((**iowadata).objectlist);
01460     
01461     disposehandle ((**iowadata).embeddedtable);
01462 
01463     disposehandle ((**iowadata).tablename);
01464     
01465     disposehandle ((Handle) iowadata);
01466         
01467     return (true);
01468     } /*iowadisposerecord*/
01469     
01470     
01471 boolean geteditrect (hdlobject h, Rect *redit) {
01472     
01473     /*
01474     return false if the object can't be edited.
01475     */
01476     
01477     Rect r;
01478     boolean fl = true;
01479     
01480     if (h == nil) /*defensive driving*/
01481         return (false);
01482     
01483     getobjectrect (h, &r); 
01484     
01485     switch ((**h).objecttype) {
01486         
01487         case grouptype: 
01488             fl = false; /*can't edit the text of a group*/
01489             
01490             break;
01491             
01492         case clonetype:
01493             fl = false; /*text can't be edited*/
01494             
01495             break;
01496             
01497         default:
01498             pushobjectstyle (h);
01499             
01500             fl = callgeteditrect (h, &r);
01501             
01502             popobjectstyle ();
01503             
01504             break;
01505         } /*switch*/
01506         
01507     *redit = r;
01508     
01509     return (fl);
01510     } /*geteditrect*/
01511     
01512     
01513 void getobjectframe (hdlobject h, Rect *r) {
01514     
01515     getobjectrect (h, r);
01516     
01517     /*
01518     if ((**h).objecttype == frametype) {
01519         
01520         pushobjectstyle (h);
01521         
01522         (*r).top += framevertinset ();
01523         
01524         popobjectstyle ();
01525         }
01526     */
01527     } /*getobjectframe*/
01528     
01529     
01530 boolean iowaopenbitmap (Rect r) {
01531     
01532     boolean fl;
01533     
01534     if (displaydebug)
01535         return (false);
01536         
01537     if ((**iowadata).bitmapactive)
01538         return (false);
01539         
01540     fl = openbitmap (r, (**iowadata).drawwindow);
01541         
01542     (**iowadata).bitmapactive = fl;
01543     
01544     return (fl);
01545     } /*iowaopenbitmap*/
01546     
01547     
01548 boolean iowaclosebitmap (void) {
01549     
01550     closebitmap ((**iowadata).drawwindow);
01551     
01552     (**iowadata).bitmapactive = false;
01553     
01554     return (true);
01555     } /*iowaclosebitmap*/
01556     
01557 
01558 static void checkminmax (Point pt) {
01559 
01560     Rect r = (**iowadata).pictrect;
01561     
01562     if (pt.h < r.left)
01563         r.left = pt.h;
01564     
01565     if (pt.h > r.right)
01566         r.right = pt.h;
01567     
01568     if (pt.v < r.top)
01569         r.top = pt.v;
01570     
01571     if (pt.v > r.bottom)
01572         r.bottom = pt.v;
01573     
01574     (**iowadata).pictrect = r;
01575     } /*checkminmax*/
01576     
01577     
01578 static void checkrectoperation (Rect r) {
01579     
01580     Point pt;
01581     
01582     pt.v = r.top;
01583     
01584     pt.h = r.left;
01585     
01586     checkminmax (pt);
01587     
01588     pt.v = r.bottom;
01589     
01590     pt.h = r.right;
01591     
01592     checkminmax (pt);
01593     } /*checkrectoperation*/
01594     
01595 
01596 #if 0
01597     
01598 static boolean trackingandhot (void) {
01599 
01600     return ((**iowadata).tracking && (**iowadata).trackerpressed);
01601     } /*trackingandhot*/
01602 
01603 #endif
01604     
01605     
01606 static void resetclonerect (hdlobject h) {
01607     
01608     /*
01609     set the rectangle of the target of the clone object as a function
01610     of the rect of the clone object.
01611     */
01612     
01613     hdlobject htarget = (hdlobject) (**h).objectdata;
01614     Rect r, rtarget;
01615     
01616     if ((**h).objecttype != clonetype)
01617         return;
01618         
01619     if (htarget == nil)
01620         return;
01621     
01622     getobjectrect (h, &r);
01623     
01624     getobjectrect (htarget, &rtarget);
01625     
01626     if ((**h).objectjustification == centerjustified)
01627         centerrect (&rtarget, r);
01628     else
01629         OffsetRect (&rtarget, r.left - rtarget.left, r.top - rtarget.top);
01630     
01631     putobjectrect (htarget, rtarget); 
01632     } /*resetclonerect*/
01633     
01634     
01635 static void drawclone (hdlobject h) {
01636     
01637     hdlobject htarget = (hdlobject) (**h).objectdata;
01638     Rect r;
01639     
01640     getobjectrect (h, &r);
01641     
01642     if (!(**h).objecttransparent)
01643         EraseRect (&r);
01644     
01645     if (htarget == nil)
01646         return;
01647     
01648     resetclonerect (h); /*set the rectangle of htarget*/
01649     
01650     drawobject (htarget);
01651     } /*drawclone*/
01652 
01653 
01654 void drawobject (hdlobject h) { 
01655     
01656     hdlcard hc = iowadata;
01657     Rect objectrect, rdraw, rinval;
01658     boolean flbitmap;
01659     tyobjecttype objecttype = (**h).objecttype;
01660     short shadowdepth = (**h).objectdropshadowdepth;
01661     boolean flframe;
01662     boolean fldrawselectionframe = true;
01663     
01664     getobjectrect (h, &objectrect); 
01665     
01666     rdraw = objectrect;
01667     
01668     callgetinvalrect (h, &rinval); /*allow for objects that draw outside their rects*/
01669     
01670     UnionRect (&rinval, &rdraw, &rdraw);
01671     
01672     rdraw.bottom += shadowdepth;
01673     
01674     rdraw.right += shadowdepth;
01675         
01676     checkrectoperation (rdraw);
01677     
01678     if ((**hc).dontdraw)
01679         return;
01680         
01681     if (!(**h).objectvisible) {
01682         
01683         #ifndef iowaRuntime /*4/11/93 DW*/
01684             
01685             if (inselection (h))
01686                 drawselectionframe (h, objectrect, true);
01687             
01688         #endif
01689         
01690         return;
01691         }
01692     
01693     if (!SectRect (&rdraw, &(**hc).updaterect, &rdraw)) /*no intersection, save time!*/
01694         return;
01695     
01696     flbitmap = false;
01697     
01698     /*new fancier logic governing bitmaps -- 12/16/93 DW*/ {
01699         
01700         boolean cantbitmap = callcantdrawinbitmap (h);
01701         boolean bitmapactive = (**iowadata).bitmapactive;
01702         
01703         if (cantbitmap && bitmapactive)
01704             return;
01705             
01706         if ((!cantbitmap) && specialflag1) /*it's already been drawn in previous pass*/
01707             return;
01708             
01709         if ((!bitmapactive) && (!cantbitmap))
01710             flbitmap = iowaopenbitmap (rdraw);
01711         }
01712     
01713     pushobjectstyle (h);
01714     
01715     if ((**h).objecttransparent)
01716         pushbackcolor (&(**hc).backcolor);
01717     
01718     (**hc).flskiptext = h == (**hc).activetextobject; 
01719     
01720     switch (objecttype) {
01721     
01722         case clonetype:
01723             drawclone (h);
01724             
01725             break;
01726             
01727         case grouptype: {
01728             boolean x;
01729             
01730             if ((!(**h).objecttransparent) && (!(**h).objecthasframe))
01731                 EraseRect (&objectrect);
01732     
01733             x = (**hc).flskiptext; /*must save and restore*/
01734             
01735             drawobjectlist ((**h).childobjectlist);
01736             
01737             (**hc).flskiptext = x;
01738             
01739             break;
01740             }
01741             
01742         default:
01743             (**h).objecttmpbit = false; /*turn it on (rare case) if you don't want a frame*/
01744             
01745             calldrawobject (h);
01746             
01747             fldrawselectionframe = !(**h).objecttmpbit;
01748             
01749             break;
01750         } /*switch*/
01751         
01752     flframe = (**h).objecthasframe;
01753     
01754     if ((**hc).flskiptext) {
01755         
01756         hdleditrecord hedit = (hdleditrecord) (**h).objecteditrecord;
01757         
01758         if ((**hc).bitmapactive) /*defer updating until bitmap is closed*/
01759             (**hc).updatethiseditbuffer = (Handle) hedit;
01760         else
01761             editupdate (hedit);
01762             
01763         if (callframewhenediting (h)) { /*it has a frame when it's being edited*/
01764         
01765             Rect editrect;
01766             
01767             geteditrect (h, &editrect);
01768     
01769             FrameRect (&editrect);
01770             }
01771             
01772         flframe = false; /*we've already drawn it*/
01773         
01774         (**hc).flskiptext = false; 
01775         }
01776     
01777     if (flframe) {
01778         
01779         pushforecolor (&(**h).objectframecolor);
01780         
01781         if (objecttype != grouptype)
01782             FrameRect (&objectrect);
01783         
01784         popforecolor ();
01785         }
01786     
01787     pushforecolor (&(**h).objectframecolor);
01788         
01789     if (shadowdepth > 0)
01790         dropshadowrect (objectrect, shadowdepth, false);
01791         
01792     popforecolor ();
01793     
01794     #ifndef iowaRuntime
01795     
01796         if (inselection (h))
01797             drawselectionframe (h, objectrect, fldrawselectionframe);
01798         
01799     #endif
01800         
01801     if ((**h).objecttransparent)
01802         popbackcolor ();
01803         
01804     popobjectstyle ();
01805     
01806     if (flbitmap) 
01807         iowaclosebitmap ();
01808     } /*drawobject*/
01809 
01810 
01811 void drawobjectnow (hdlobject h) {
01812 
01813     Rect oldupdaterect = (**iowadata).updaterect;
01814     Rect r;
01815     
01816     getobjectrect (h, &r); 
01817     
01818     (**iowadata).updaterect = r;
01819     
01820     drawobject (h);
01821     
01822     (**iowadata).updaterect = oldupdaterect;
01823     } /*drawobjectnow*/
01824     
01825     
01826 void drawobjectlist (hdlobject x) {
01827     
01828     while (x != nil) {
01829         
01830         drawobject (x);
01831         
01832         x = (**x).nextobject; 
01833         } /*while*/
01834     } /*drawobjectlist*/
01835     
01836 
01837 #ifndef isFrontier
01838 static boolean iscolorport (GrafPtr pport) {
01839 
01840     return ((*(CGrafPtr) pport).portVersion < 0);
01841     } /*iscolorport*/
01842 #endif
01843 
01844 
01845 #ifndef iowaRuntime
01846     
01847     void setnubonborder (void) {
01848     
01849         hdlcard hc = iowadata;
01850         boolean flbordernub;
01851         hdleditinfo he;
01852         short rb = (**hc).rightborder;
01853         short bb = (**hc).bottomborder;
01854         Rect r;
01855         
01856         if ((**hc).runmode)
01857             return;
01858         
01859         he = (hdleditinfo) (**hc).refcon;
01860         
01861         assert (he != nil);
01862         
01863         flbordernub = ((**hc).selectionlist == nil) && ((**hc).activetextobject == nil);
01864         
01865         if (flbordernub == (**he).flnubonborder) /*no change*/
01866             return;
01867         
01868         (**he).flnubonborder = flbordernub;
01869             
01870         r.right = rb;
01871         
01872         r.left = rb - nubsize;
01873         
01874         r.bottom = bb;
01875         
01876         r.top = bb - nubsize;
01877     
01878         iowainvalrect (&r); 
01879         } /*setnubonborder*/
01880         
01881     
01882     static void voidrect (Rect *rvoid) {
01883                 
01884         pushbackcolor (&whitecolor);
01885         
01886         pushforecolor (&whitecolor);
01887     
01888         FillRect (rvoid, &quickdrawglobal (gray)); 
01889         
01890         popforecolor ();
01891     
01892         popbackcolor ();
01893         } /*voidrect*/
01894     
01895 
01896     static void drawgrid (void) {
01897         
01898         hdlcard hc = iowadata;
01899         boolean flcolor;
01900         short gridunits = (**hc).gridunits;
01901         short hmax, vmax;
01902         Rect r = (**hc).updaterect;
01903         short x;
01904         
01905         flcolor = iscolorport ((**hc).drawwindow);
01906         
01907         flcolor = colorenabled ();
01908         
01909         if (flcolor)
01910             pushgridcolor (&(**hc).backcolor);
01911         else {
01912             pushpen ();
01913         
01914             PenPat (&quickdrawglobal (gray));
01915             }
01916         
01917         x = (r.left / gridunits) * gridunits;   
01918         
01919         x += gridunits; /*skip the first one*/
01920         
01921         hmax = minint (r.right, (**hc).rightborder);
01922         
01923         vmax = minint (r.bottom, (**hc).bottomborder);
01924         
01925         while (x < hmax) {
01926             
01927             MoveTo (x, r.top);
01928             
01929             LineTo (x, vmax);
01930             
01931             x += gridunits;
01932             } /*while*/
01933             
01934         x = (r.top / gridunits) * gridunits;    
01935         
01936         x += gridunits; /*skip the first one*/
01937         
01938         while (x < vmax) {
01939         
01940             MoveTo (r.left, x);
01941             
01942             LineTo (hmax, x);
01943             
01944             x += gridunits;
01945             } /*while*/
01946         
01947         if (flcolor)    
01948             popforecolor ();
01949         else
01950             poppen ();
01951         } /*drawgrid*/
01952         
01953         
01954     static void drawborder (void) {
01955     
01956         hdlcard hc = iowadata;
01957         hdleditinfo he = (hdleditinfo) (**hc).refcon;
01958         short rb = (**hc).rightborder;
01959         short bb = (**hc).bottomborder;
01960         Rect r;
01961         
01962         pushpen ();
01963     
01964         PenPat (&quickdrawglobal (black));
01965         
01966         MoveTo (rb, 0);
01967         
01968         LineTo (rb, bb);
01969         
01970         LineTo (0, bb);
01971         
01972         poppen ();
01973         
01974         if ((**he).flnubonborder) {
01975         
01976             r.right = rb;
01977             
01978             r.left = rb - nubsize;
01979             
01980             r.bottom = bb;
01981             
01982             r.top = bb - nubsize;
01983         
01984             FillRect (&r, &quickdrawglobal (black)); 
01985             }
01986         } /*drawborder*/
01987 
01988 #endif
01989 
01990 
01991 static void runmodedrawbackground (Rect rdraw) {
01992 
01993     hdlcard hc = iowadata;
01994 
01995     pushbackcolor (&(**hc).backcolor);
01996 
01997     EraseRect (&rdraw);
01998 
01999     popbackcolor ();
02000     } /*runmodedrawbackground*/
02001     
02002     
02003 static void drawbackground (Rect rdraw) {
02004 
02005     #ifdef iowaRuntime
02006     
02007         runmodedrawbackground (rdraw);
02008         
02009         return;
02010     
02011     #else /*in Card Editor*/
02012     
02013         hdlcard hc = iowadata;
02014         Rect rborders, rsect, rvoid;
02015         
02016         if ((**hc).runmode) {
02017         
02018             runmodedrawbackground (rdraw);
02019         
02020             return;
02021             }
02022         
02023         rborders.top = rborders.left = 0;
02024         
02025         rborders.bottom = (**hc).bottomborder;
02026         
02027         rborders.right = (**hc).rightborder;
02028         
02029         if (SectRect (&rdraw, &rborders, &rsect)) {
02030     
02031             pushbackcolor (&(**hc).backcolor);
02032         
02033             EraseRect (&rsect);
02034         
02035             popbackcolor ();
02036             }
02037         
02038         rvoid = rdraw; /*white out everything to the right of the drawing area*/
02039         
02040         rvoid.left = (**hc).rightborder;
02041         
02042         if (!EmptyRect (&rvoid)) 
02043             voidrect (&rvoid);
02044             
02045         rvoid = rdraw; /*white out everything below the drawing area*/
02046         
02047         rvoid.top = (**hc).bottomborder;
02048         
02049         if (!EmptyRect (&rvoid)) 
02050             voidrect (&rvoid);
02051             
02052     #endif
02053     } /*drawbackground*/
02054     
02055     
02056 boolean iowaupdate (void) {
02057     
02058     hdlcard hc = iowadata;
02059     boolean flbitmap = false;
02060     Rect r;
02061     
02062     r = (**hc).updaterect;
02063     
02064     flbitmap = iowaopenbitmap (r);
02065     
02066     drawbackground (r);
02067     
02068     #ifndef iowaRuntime
02069         
02070         if (!(**hc).runmode) {
02071         
02072             if (!(**hc).flinvisiblegrid) /*dmb 1.0b20 -- don't require (**hc).flgrid to draw grid*/
02073                 drawgrid ();
02074             
02075             drawborder ();
02076             }
02077     
02078     #endif
02079     
02080     (**hc).updatethiseditbuffer = nil;
02081     
02082     drawobjectlist ((**hc).objectlist);
02083     
02084     if (flbitmap)
02085         iowaclosebitmap ();
02086     
02087     /*special second pass for objects that can't be drawn in offscreen bitmaps*/ {
02088     
02089         specialflag1 = true;
02090     
02091         drawobjectlist ((**hc).objectlist);
02092     
02093         specialflag1 = false;
02094         }
02095         
02096     editupdate ((hdleditrecord) (**hc).updatethiseditbuffer);
02097     
02098     return (true);
02099     } /*iowaupdate*/
02100     
02101     
02102 static boolean showinvisiblesvisit (hdlobject h) {
02103     
02104     derefclone (&h);
02105     
02106     if (!(**h).objectvisible) {
02107         
02108         Rect r;
02109         
02110         getobjectrect (h, &r);
02111         
02112         pushpen ();
02113         //Code change by Timothy Paustian Monday, June 26, 2000 2:51:24 PM
02114         //
02115         #if TARGET_API_MAC_CARBON == 1
02116         {
02117         Pattern gray;
02118         GetQDGlobalsGray(&gray);
02119         PenPat(&gray);
02120         }
02121         #else       
02122         PenPat (&quickdrawglobal (gray)); 
02123         #endif
02124         
02125         FrameRect (&r);
02126         
02127         poppen ();
02128         //Code change by Timothy Paustian Monday, June 26, 2000 2:52:22 PM
02129         //
02130         #if TARGET_API_MAC_CARBON == 1
02131         if((**iowadata).drawwindow != nil)
02132             InvalWindowRect((**iowadata).drawwindow, &r);
02133         #else
02134         InvalRect (&r);
02135         #endif
02136         
02137         }
02138         
02139     return (true);
02140     } /*showinvisiblesvisit*/
02141     
02142 
02143 boolean showinvisiblesloop (void) {
02144     
02145     boolean firstloop = true;
02146     
02147     if (iowadata == nil) /*defensive, it can happen*/
02148         return (false);
02149     
02150     while (cmdkeydown () && optionkeydown ()) {
02151         
02152         if (firstloop) {
02153         
02154             visitobjects ((**iowadata).objectlist, &showinvisiblesvisit);
02155             
02156             firstloop = false;
02157             }
02158         } /*while*/
02159         
02160     return (!firstloop); /*return true if window needs updating*/
02161     } /*showinvisiblesloop*/
02162 
02163 
02164 boolean setactivetextobject (hdlobject h) {
02165 
02166     hdlcard hc = iowadata;
02167     hdleditrecord hedit;
02168     Handle htext;
02169     boolean fl;
02170     Rect r;
02171     
02172     if (!geteditrect (h, &r))
02173         return (false);
02174     
02175     getobjectvalue (h, &htext); 
02176     
02177     pushobjectstyle (h);
02178     
02179     debugrect (r);
02180     
02181     fl = editnewbufferfromhandle (r, true, htext, &hedit);
02182     
02183     popobjectstyle ();
02184     
02185     if (!fl)
02186         return (false);
02187         
02188     editsetjustification ((**h).objectjustification, hedit);
02189         
02190     (**h).objecteditrecord = (Handle) hedit;
02191     
02192     invalobject (h);
02193     
02194     (**hc).activetextobject = h;
02195     
02196     #ifndef iowaRuntime
02197         setnubonborder ();
02198     #endif
02199     
02200     return (true);
02201     } /*setactivetextobject*/
02202     
02203 
02204 void clearactivetextobject (void) {
02205 
02206     hdlcard hc = iowadata;
02207     hdlobject h = (**hc).activetextobject;
02208     hdleditrecord hedit;
02209     Handle hvalue;
02210     
02211     if (h == nil) /*no text object is active*/
02212         return;
02213         
02214     invalobject (h); /*force update*/
02215     
02216     hedit = (hdleditrecord) (**h).objecteditrecord;
02217     
02218     editgettexthandlecopy (hedit, &hvalue);
02219     
02220     editdispose (hedit);
02221     
02222     (**h).objecteditrecord = nil;
02223     
02224     /*(**h).objectautosize = false;*/ /*never 2B true again*/
02225     
02226     (**hc).activetextobject = nil;
02227     
02228     setobjectvalue (h, hvalue);
02229     
02230     invalobject (h);
02231     
02232     #ifndef iowaRuntime
02233         setnubonborder ();
02234     #endif
02235     } /*clearactivetextobject*/
02236     
02237 
02238 hdleditrecord getactiveeditrecord (void) {
02239     
02240     /*
02241     factor a common piece of code. all textedit.c routines must be
02242     prepared to receive a nil editrecord handle.
02243     */
02244 
02245     hdlcard hc = iowadata;
02246     hdlobject h;
02247     
02248     if (hc == nil)
02249         return (nil);
02250         
02251     h = (**hc).activetextobject;
02252     
02253     if (h == nil)
02254         return (nil);
02255         
02256     return ((hdleditrecord) (**h).objecteditrecord);
02257     } /*getactiveeditrecord*/
02258     
02259     
02260 static boolean lookupvisit (hdlobject h) {
02261     
02262     bigstring bs;
02263     
02264     getobjectnamestring (h, bs); 
02265     
02266     allupper (bs);
02267     
02268     if (!equalstrings (bs, lookup.name)) /*continue traversal*/
02269         return (true);
02270         
02271     lookup.h = h;
02272     
02273     return (false); /*terminate the traversal*/
02274     } /*lookupvisit*/
02275     
02276     
02277 boolean lookupname (bigstring bsname, hdlobject *h) {
02278     
02279     hdlcard hc = iowadata;
02280 
02281     copystring (bsname, lookup.name);
02282     
02283     allupper (lookup.name); /*lookup is unicase*/
02284     
02285     lookup.h = nil;
02286     
02287     visitobjects ((**hc).objectlist, &lookupvisit);
02288     
02289     *h = lookup.h;
02290     
02291     return (lookup.h != nil);
02292     } /*lookupname*/
02293     
02294     
02295 boolean iowagetbooleanvalue (hdlobject hobj, Handle *hvalue) {
02296 
02297     bigstring bs;
02298     
02299     if ((**hobj).objectflag)
02300         copystring ("\ptrue", bs);
02301     else
02302         copystring ("\pfalse", bs);
02303         
02304     if (!newtexthandle (bs, hvalue))
02305         return (false);
02306         
02307     pushtemphandle (*hvalue);
02308     
02309     return (true);
02310     } /*iowagetbooleanvalue*/
02311 
02312 
02313 boolean iowasetbooleanvalue (hdlobject h, Handle hvalue) {
02314 
02315     /*
02316     1.0b15 DW -- if the handle is nil, don't touch the value.
02317     
02318     this allows radio buttons with no script attached to stay properly
02319     initialized.
02320     */
02321             
02322     bigstring bs;
02323     
02324     if (hvalue == nil)
02325         return (true);
02326     
02327     texthandletostring (hvalue, bs);
02328     
02329     disposehandle (hvalue);
02330     
02331     (**h).objectflag = unicaseequalstrings ("\ptrue", bs);
02332     
02333     return (true);
02334     } /*iowasetbooleanvalue*/
02335 
02336 
02337 boolean iowagetstringvalue (hdlobject hobj, Handle *hvalue) {
02338 
02339     /*
02340     dmb 1.0b21 - use curly quotes instead of straight quotes. not as
02341     thorough as replacing all quotes with \", but very easy and fast
02342     */
02343     
02344     Handle h, hval;
02345     
02346     if (!newtexthandle ("\p", &h))
02347         return (false);
02348         
02349     pushtemphandle (h);
02350     
02351     getobjectvalue (hobj, &hval);
02352     
02353     if (!pushhandleonhandle (hval, h))
02354         return (false);
02355     
02356     if (!pushtexthandle ("\p", h))
02357         return (false);
02358     
02359     *hvalue = h;
02360     
02361     return (true);
02362     } /*iowagetstringvalue*/
02363     
02364     
02365 boolean iowasetpictrect (void) {
02366 
02367     hdlcard hc = iowadata;
02368     Rect r;
02369     
02370     r.left = r.top = intinfinity;
02371     
02372     r.right = r.bottom = intminusinfinity;
02373     
02374     (**hc).pictrect = r;
02375     
02376     (**hc).dontdraw = true;
02377     
02378     drawobjectlist ((**hc).objectlist);
02379     
02380     (**hc).dontdraw = false;
02381     
02382     if (equalrects ((**hc).pictrect, r)) 
02383         zerorect (&(**hc).pictrect);
02384     
02385     return (true);
02386     } /*iowasetpictrect*/
02387     
02388 
02389 void sortobjectlist (void) {
02390     
02391     hdlcard hc = iowadata;
02392     hdlobject listhead = (**hc).objectlist;
02393     hdlobject nomad = listhead;
02394     short ct = 0, i;
02395     
02396     while (nomad != nil) {
02397         
02398         (**nomad).sorttag = 0; /*indicate that it hasn't been sorted yet*/
02399         
02400         ct++;
02401         
02402         nomad = (**nomad).nextobject;
02403         } /*while*/
02404         
02405     for (i = 1; i <= ct; i++) {
02406         
02407         Rect rfirst, rnomad;
02408         hdlobject hfirst = nil;
02409         
02410         nomad = listhead; /*start at the head of the list each time*/
02411         
02412         rfirst.top = rfirst.bottom = rfirst.left = rfirst.right = infinity;
02413         
02414         while (nomad != nil) { /*find the "smallest" rectangle*/
02415             
02416             if ((**nomad).sorttag == 0) { /*hasn't been sorted yet*/
02417                 
02418                 getobjectrect (nomad, &rnomad);
02419                 
02420                 if (rectlessthan (rnomad, rfirst)) { /*it's the new candidate*/
02421                     
02422                     rfirst = rnomad;
02423                     
02424                     hfirst = nomad;
02425                     }
02426                 }
02427                 
02428             nomad = (**nomad).nextobject;
02429             } /*while*/
02430             
02431         (**hfirst).sorttag = i;
02432         } /*for*/
02433     } /*sortobjectlist*/
02434     
02435     
02436 typedef struct tythread { 
02437     
02438     hdlobject h;
02439     } tythread;
02440     
02441 tythread thread;
02442 
02443 
02444 static boolean laythreadvisit (hdlobject h) {
02445     
02446     if (thread.h != nil) 
02447         (**thread.h).nextinthread = h;
02448         
02449     thread.h = h;
02450     
02451     return (true);
02452     } /*laythreadvisit*/
02453     
02454     
02455 void laythread (void) {
02456     
02457     /*
02458     sometimes we can avoid hairy traversals by laying a a flat thread
02459     thru the grouped hierarchic structure of objects. 
02460     */
02461     
02462     hdlcard hc = iowadata;
02463     
02464     thread.h = nil;
02465     
02466     visitobjects ((**hc).objectlist, &laythreadvisit);
02467     
02468     if (thread.h != nil)
02469         (**thread.h).nextinthread = nil; /*nil-terminated list*/    
02470     } /*laythread*/
02471     
02472     
02473 void iowaupdatenow (void) {
02474     
02475     /*
02476     some operations need the window updated right now, they can't wait for
02477     the program to go back thru its main event loop.
02478     */
02479     
02480     hdlcard hc = iowadata;
02481     
02482     (*(**hc).updatecallback) ();
02483     } /*iowaupdatenow*/
02484     
02485 
02486 boolean recalcobjectvalue (hdlobject h) {
02487     
02488     /*
02489     a common bottleneck for all object types whose value is 
02490     the result of running its script.
02491     */
02492     
02493     Handle hscript, hcopy, hvalue;
02494     bigstring errorstring;
02495     
02496     getobjectrecalcscript (h, &hscript); 
02497     
02498     if (hscript == nil) /*no linked script, nothing to do*/
02499         return (true);
02500     
02501     if (!preparseScript (h, hscript, &hcopy))
02502         return (false);
02503         
02504     disposehandle ((**h).objecterrormessage); /*DW 3/18/93 -- unconditionally dispose*/
02505     
02506     (**h).objecterrormessage = nil; /*DW 3/18/93 -- by default, no error message*/
02507         
02508     if (!runcardscript (hcopy, (**h).objectlanguage, true, errorstring, &hvalue)) {
02509         
02510         Handle htext;
02511         
02512         newtexthandle (errorstring, &htext);
02513         
02514         setobjecterrormessage (h, htext);
02515         
02516         newtexthandle ("\pERROR", &hvalue);
02517         }
02518     
02519     setobjectvalue (h, hvalue); /*1.0b20 dmb -- handles active edit object, invals*/
02520     
02521     /*
02522     disposehandle ((**h).objectvalue);
02523             
02524     (**h).objectvalue = hvalue;
02525     
02526     invalobject (h);
02527     */
02528     
02529     return (true); 
02530     } /*recalcobjectvalue*/
02531 
02532 
02533 static boolean evalscript (hdlobject hself, Handle hscript, Handle *hvalue, OSType idlanguage, bigstring errorstring) {
02534     
02535     /*
02536     for the IOA components to call back to.
02537     */
02538     
02539     Handle hcopy;
02540     
02541     *hvalue = nil;
02542     
02543     if (hscript == nil) 
02544         return (true);
02545     
02546     if (!preparseScript (hself, hscript, &hcopy))
02547         return (false);
02548     
02549     return (runcardscript (hcopy, idlanguage, true, errorstring, hvalue));
02550     } /*evalscript*/
02551     
02552     
02553 boolean runbuttonscript (hdlobject h) {
02554     
02555     Handle hscript, hcopy, htoss;
02556     bigstring errorstring;
02557     
02558     getobjectscript (h, &hscript); 
02559     
02560     if (hscript == nil) /*no script linked into object*/
02561         return (true);
02562     
02563     if (!preparseScript (h, hscript, &hcopy))
02564         return (false);
02565     
02566     frontSetRuntimeCard (true, false); /*the button script runs in the context of the embedded table*/
02567     
02568     if (!runcardscript (hcopy, (**h).objectlanguage, false, errorstring, &htoss)) {
02569     
02570         alertdialog (errorstring);
02571         
02572         return (false);
02573         }
02574     
02575     return (true);
02576     } /*runbuttonscript*/
02577     
02578 
02579 #if 0
02580 
02581 static boolean afterclonevisit (hdlobject h) {
02582     
02583     if ((**h).objecttmpbit) {
02584         
02585         (**h).objecttmpbit = false;
02586         }
02587     
02588     return (true);
02589     } /*afterclonevisit*/
02590 
02591 #endif
02592     
02593     
02594 boolean recalcclone (hdlobject h) {
02595 
02596     tyobjecttype type = (**h).objecttype;
02597     Handle hcopy, hpackedobject;
02598     bigstring errorstring;
02599     OSType binarytype;
02600     
02601     if (type != clonetype)
02602         return (true);
02603         
02604     if (!recalcobjectvalue (h))
02605         return (false);
02606         
02607     getobjectvalue (h, &hcopy);
02608     
02609     if (!copyhandle (hcopy, &hcopy))
02610         return (false);
02611     
02612     if (!FrontierGetObject (hcopy, errorstring, &hpackedobject, &binarytype)) {
02613         
02614         alertdialog (errorstring);
02615         
02616         goto error;
02617         }
02618         
02619     /*unpack the object*/ {
02620         
02621         hdlobject hlinked;
02622         
02623         if (!unpacksingleobject (hpackedobject, &hlinked))
02624             goto error;
02625             
02626         disposeobject ((hdlobject) (**h).objectdata);
02627         
02628         (**h).objectdata = (Handle) hlinked; /*link into object*/
02629         
02630         resetclonerect (h);
02631         
02632         invalobject (h);
02633         
02634         majorrecalcvisit ((hdlobject) hlinked); /*1.0b11*/
02635         }
02636     
02637     return (true); 
02638     
02639     error:
02640     
02641     return (false);
02642     } /*recalcclone*/
02643     
02644 
02645 static boolean unpackhandle (long ctbytes, Handle *h) {
02646     
02647     if (ctbytes == 0) {
02648         
02649         *h = nil;
02650         
02651         return (true);
02652         }
02653         
02654     if (unpack.p >= unpack.lastp) 
02655         return (false); 
02656         
02657     if (!newfilledhandle (unpack.p, ctbytes, h))
02658         return (false);
02659         
02660     unpack.p += ctbytes;
02661     
02662     return (true);
02663     } /*unpackhandle*/
02664 
02665 
02666 static hdlobject hcheck;
02667 
02668 
02669 static boolean checkobjectnamevisit (hdlobject h) {
02670     
02671     if (h != hcheck) {
02672     
02673         if (equalhandles ((**hcheck).objectname, (**h).objectname)) { /*2 objects with same name*/
02674             
02675             disposehandle ((**hcheck).objectname);
02676             
02677             (**hcheck).objectname = nil;
02678             
02679             autonameobject (hcheck);
02680             
02681             return (false); /*stop traversing*/
02682             }
02683         }
02684     
02685     return (true); /*keep visiting*/
02686     } /*checkobjectnamevisit*/
02687     
02688 
02689 static boolean uniqueobjectname (hdlobject h) {
02690 
02691     if ((**h).objectname == nil)
02692         autonameobject (h);
02693     else {
02694         hcheck = h;
02695     
02696         visitobjects ((**iowadata).objectlist, &checkobjectnamevisit);
02697         }
02698     
02699     return (true);
02700     } /*uniqueobjectname*/
02701     
02702     
02703 static void checkobjectnames (void) {
02704     
02705     visitobjects ((**iowadata).objectlist, &uniqueobjectname);
02706     } /*checkobjectnames*/
02707     
02708     
02709 static void postunpackfilter (hdlobject h) {
02710     
02711     OffsetRect (&(**h).objectrect, unpack.hoffset, unpack.voffset);
02712     
02713     switch ((**h).objecttype) {
02714         
02715         case clonetype: /*force a recalc of the object*/
02716             disposehandle ((**h).objectdata);
02717             
02718             (**h).objectdata = nil;
02719             
02720             break;
02721             
02722         default:
02723             callunpackdata (h);
02724             
02725             break;
02726         } /*switch*/
02727     } /*postunpackfilter*/
02728     
02729 
02730 boolean unpackobject (hdlobject *hobject, boolean *lastinlist) {
02731     
02732     /*
02733     2006-04-17 aradke: must convert packed data to native byte-order on Intel Macs 
02734     */
02735     
02736     tydiskobject info;
02737     tyobject obj;
02738     hdlobject h;
02739     
02740     moveleft (unpack.p, &info, longsizeof (info));
02741     
02742     disktomemshort (info.versionnumber);
02743     
02744     disktomemshort (info.objectrect.top);
02745     disktomemshort (info.objectrect.left);
02746     disktomemshort (info.objectrect.bottom);
02747     disktomemshort (info.objectrect.right);
02748 
02749     disktomemlong (info.lenname);
02750     disktomemlong (info.lenvalue);
02751     disktomemlong (info.lenscript);
02752     disktomemlong (info.lendata);
02753     
02754     disktomemshort (info.objectfontsize);
02755     disktomemshort (info.objectstyle);
02756     disktomemshort (info.objectjustification);
02757     disktomemshort (info.objectrecalcstatus);
02758     disktomemshort (info.objectrecalcperiod);
02759     disktomemshort (info.unused1);
02760     disktomemshort (info.objectdropshadowdepth);
02761     disktomemshort (info.objectlinespacing);
02762     disktomemshort (info.objectindentation);
02763     
02764     /* 
02765     2006-04-17 aradke: The info.objecthasframe etc. bit-field doesn't need to be byte-swapped,
02766         because this is already taken care of via the endian-specific definition in iowacore.h.
02767     */
02768     
02769     disktomemlong (info.objecttype);
02770     
02771     disktomemshort (info.objectfillcolor.red);
02772     disktomemshort (info.objectfillcolor.green);
02773     disktomemshort (info.objectfillcolor.blue);
02774     
02775     disktomemshort (info.objecttextcolor.red);
02776     disktomemshort (info.objecttextcolor.green);
02777     disktomemshort (info.objecttextcolor.blue);
02778     
02779     disktomemshort (info.objectframecolor.red);
02780     disktomemshort (info.objectframecolor.green);
02781     disktomemshort (info.objectframecolor.blue);
02782     
02783     disktomemlong (info.objectlanguage);
02784     disktomemlong (info.lenrecalcscript);
02785 
02786     if (info.versionnumber == 1) /*record format changed to allow 4 bytes for object type*/
02787         info.objecttype = (unsigned long) info.v1objecttype;
02788         
02789     if (info.versionnumber <= 2) { /*used to use a short index to store colors, now use RGB's*/
02790         
02791         oldclutconverter (info.objectrecalcstatus, &info.objectfillcolor);
02792         
02793         oldclutconverter (info.objectrecalcperiod, &info.objecttextcolor);
02794         
02795         oldclutconverter (info.unused1, &info.objectframecolor);        
02796         }
02797     
02798     clearbytes (&obj, longsizeof (obj));
02799     
02800     obj.objecttype = info.objecttype;
02801     
02802     obj.objectrect = info.objectrect;
02803     
02804     obj.objectflag = info.objectflag;
02805     
02806     obj.objectvisible = !info.objectinvisible;
02807     
02808     obj.objectenabled = !info.objectdisabled;
02809     
02810     obj.objecttransparent = info.objecttransparent;
02811     
02812     GetFNum ((ConstStr255Param) info.objectfont, &obj.objectfont);
02813     
02814     obj.objectfontsize = info.objectfontsize;
02815     
02816     obj.objectstyle = info.objectstyle;
02817     
02818     obj.objectjustification = (tyjustification) info.objectjustification;
02819     
02820     obj.objectfillcolor = info.objectfillcolor;
02821     
02822     obj.objecttextcolor = info.objecttextcolor;
02823     
02824     obj.objectframecolor = info.objectframecolor;
02825     
02826     obj.objecthasframe = info.objecthasframe;
02827     
02828     obj.objectdropshadowdepth = info.objectdropshadowdepth;
02829     
02830     obj.objectlinespacing = info.objectlinespacing;
02831     
02832     obj.objectindentation = info.objectindentation;
02833     
02834     obj.objectlanguage = info.objectlanguage;
02835     
02836     obj.objectrecalcstatus = info.objectrecalcstatus;
02837     
02838     if ((obj.objectrecalcstatus < neverrecalc) || (obj.objectrecalcstatus > timerecalc))
02839         obj.objectrecalcstatus = neverrecalc;
02840     
02841     obj.objectrecalcperiod = info.objectrecalcperiod;
02842     
02843     if (obj.objectlanguage == 0) /*converting an earlier object*/
02844         obj.objectlanguage = idUserTalk;
02845     
02846     obj.objecttmpbit = true;
02847 
02848     unpack.p += longsizeof (info);
02849     
02850     if (!unpackhandle (info.lenname, &obj.objectname))
02851         goto error;
02852     
02853     if (!unpackhandle (info.lenvalue, &obj.objectvalue))
02854         goto error;
02855         
02856     if (!unpackhandle (info.lenscript, &obj.objectscript))
02857         goto error;
02858     
02859     if (!unpackhandle (info.lenrecalcscript, &obj.objectrecalcscript))
02860         goto error;
02861     
02862     if (!unpackhandle (info.lendata, &obj.objectdata)) 
02863         goto error;
02864         
02865     obj.owningcard = iowadata;
02866     
02867     if (!newfilledhandle (&obj, longsizeof (tyobject), (Handle *) &h))
02868         goto error;
02869 
02870     postunpackfilter (h); /*do editing on newly unpacked object*/
02871     
02872     if (obj.objecttype == grouptype) {
02873         
02874         hdlobject firstchild;
02875         
02876         if (!unpacklist (&firstchild))
02877             return (false);
02878         
02879         (**h).childobjectlist = firstchild;
02880         }
02881     
02882     *hobject = h;
02883     
02884     *lastinlist = info.lastinlist;
02885     
02886     return (true);
02887         
02888     error:
02889     
02890     disposehandle (obj.objectname);
02891     
02892     disposehandle (obj.objectvalue);
02893     
02894     disposehandle (obj.objectscript);
02895     
02896     disposehandle (obj.objectdata);
02897     
02898     return (false);
02899     } /*unpackobject*/
02900     
02901     
02902 boolean unpacklist (hdlobject *firstobject) {
02903     
02904     hdlobject lastobject = nil;
02905     hdlobject h;
02906     boolean lastinlist;
02907     
02908     while (true) {
02909         
02910         if (!unpackobject (&h, &lastinlist))
02911             return (false);
02912         
02913         if (lastobject == nil)
02914             *firstobject = h;
02915         else
02916             (**lastobject).nextobject = h;
02917             
02918         lastobject = h;
02919         
02920         if (lastinlist) /*it was the last guy in his group's list*/
02921             return (true);
02922             
02923         if (unpack.p >= unpack.lastp) 
02924             return (true);
02925         } /*while*/
02926 
02927     return (false);
02928     } /*unpacklist*/
02929     
02930     
02931 boolean unpacksingleobject (Handle hpacked, hdlobject *hobject) {
02932     
02933     boolean fl, lastinlist;
02934     
02935     lockhandle (hpacked);
02936     
02937     unpack.p = *hpacked;
02938     
02939     unpack.lastp = unpack.p + GetHandleSize (hpacked);
02940     
02941     fl = unpackobject (hobject, &lastinlist);
02942     
02943     unlockhandle (hpacked);
02944     
02945     return (fl);
02946     } /*unpacksingleobject*/
02947     
02948     
02949 boolean iowaunpack (Handle hpacked) {
02950 
02951     /*
02952     2006-04-17 aradke: must convert packed data to native byte-order on Intel Macs 
02953     */
02954     
02955     hdlcard hc = iowadata;
02956     hdlobject newlist;
02957     tydiskheader header;
02958     
02959     initIOAcallbacks (); /*set up callbacks in iowadata*/
02960     
02961     clearalltmpbits ();
02962     
02963     lockhandle (hpacked);
02964     
02965     unpack.p = *hpacked;
02966     
02967     unpack.lastp = unpack.p + GetHandleSize (hpacked);
02968     
02969     moveleft (unpack.p, &header, longsizeof (header));
02970     
02971     unpack.p += longsizeof (header);
02972     
02973     disktomemshort (header.versionnumber);
02974     
02975     if (header.versionnumber < 4) { /*the header grew by 66 bytes in version 4*/
02976         
02977         header.lenwindowtitle = 0;
02978         
02979         unpack.p -= 66;
02980         }
02981     
02982     disktomemshort (header.v2backcolor);
02983 
02984     disktomemlong (header.lenembeddedtable);
02985 
02986     disktomemshort (header.defaultfillcolor);
02987     disktomemshort (header.defaulttextcolor);
02988     disktomemshort (header.defaultframecolor);
02989     
02990     /* 
02991     2006-04-17 aradke: The header.defaulthasframe etc. bit-field doesn't need to be byte-swapped,
02992         because this is already taken care of via the endian-specific definition in iowacore.h.
02993     */
02994     
02995     disktomemshort (header.gridunits);
02996     disktomemshort (header.rightborder);
02997     disktomemshort (header.bottomborder);
02998 
02999     disktomemshort (header.backcolor.red);
03000     disktomemshort (header.backcolor.green);
03001     disktomemshort (header.backcolor.blue);
03002 
03003     disktomemlong (header.idwindow);
03004     disktomemlong (header.lenwindowtitle);
03005     
03006     if (header.versionnumber <= 2) /*back color was stored as an index, now stored as a RGBColor*/
03007         oldclutconverter (header.v2backcolor, &header.backcolor);
03008     
03009     switch (header.versionnumber) {
03010         
03011         case 1:
03012             break;
03013             
03014         case 2: case 3: case 4: {
03015             Handle htable;
03016             
03017             if (header.flselection) /*we're unpacking for a paste operation*/
03018                 break;
03019             
03020             if (!unpackhandle (header.lenembeddedtable, &htable))
03021                 goto error;
03022                 
03023             (**iowadata).embeddedtable = htable;
03024             
03025             break;
03026             }
03027             
03028         default:
03029             goto error;
03030         } /*switch*/
03031     
03032     /*DW 12/12/93 -- unpack the card's window title*/ {
03033         
03034         Handle hwindowtitle;
03035         
03036         if (!header.flselection) {
03037         
03038             if (!unpackhandle (header.lenwindowtitle, &hwindowtitle))
03039                 goto error;
03040         
03041             (**iowadata).windowtitle = hwindowtitle;
03042             }
03043         }
03044             
03045     if (unpack.lastp > unpack.p) { /*a non-empty card*/
03046     
03047         if (!unpacklist (&newlist))
03048             goto error;
03049         }
03050     else
03051         newlist = nil;
03052         
03053     unlockhandle (hpacked);
03054     
03055     if ((**hc).objectlist == nil)
03056         (**hc).objectlist = newlist;
03057     else {
03058         hdlobject lastobject;
03059         
03060         getlastinlist ((**hc).objectlist, &lastobject);
03061         
03062         (**lastobject).nextobject = newlist;
03063         }
03064     
03065     laythread (); /*re-establish the flat thread thru all non-group objects*/
03066     
03067     sortobjectlist ();
03068     
03069     if (!header.flselection) {
03070     
03071         (**hc).backcolor = header.backcolor;
03072         
03073         (**hc).flgrid = header.flgrid;
03074         
03075         (**hc).flinvisiblegrid = header.flinvisiblegrid;
03076         
03077         if (header.gridunits == 0) /*be kind with old files*/
03078             header.gridunits = 12;
03079             
03080         (**hc).gridunits = header.gridunits;
03081         
03082         if (header.rightborder == 0) /*be kind with old files*/
03083             header.rightborder = 250;
03084             
03085         (**hc).rightborder = header.rightborder;
03086          
03087         if (header.bottomborder == 0) /*be kind with old files*/
03088             header.bottomborder = 250;
03089             
03090         (**hc).bottomborder = header.bottomborder;
03091         
03092         (**hc).floater = header.floater;
03093         
03094         if (header.idwindow == 0) /*be kind with old files*/
03095             header.idwindow = 128;
03096             
03097         (**hc).idwindow = header.idwindow;
03098         }
03099     
03100     checkobjectnames ();
03101     
03102     return (true);
03103     
03104     error:
03105     
03106     unlockhandle (hpacked);
03107     
03108     return (false);
03109     } /*iowaunpack*/
03110     
03111     
03112 boolean setCardValue (bigstring name, Handle hvalue) {
03113     
03114     hdlcard hc = iowadata;
03115     hdlobject h;
03116     
03117     if (!lookupname (name, &h))
03118         return (false);
03119         
03120     callsetvalue (h, hvalue);
03121         
03122     (**h).objectinval = true; /*force update*/
03123     
03124     (**hc).needsupdate = true; /*we watch for this in idle callback*/
03125     
03126     return (true);
03127     } /*setCardValue*/
03128     
03129         
03130 boolean setCardValueCopy (bigstring name, Handle hvalue) {
03131     
03132     Handle hcopy;
03133     
03134     if (!copyhandle (hvalue, &hcopy))
03135         return (false);
03136         
03137     return (setCardValue (name, hcopy));
03138     } /*setCardValueCopy*/
03139     
03140     
03141 boolean setCardString (bigstring name, bigstring value) {
03142     
03143     Handle hvalue;
03144     
03145     if (!newtexthandle (value, &hvalue))
03146         return (false);
03147         
03148     if (!setCardValue (name, hvalue)) {
03149         
03150         disposehandle (hvalue);
03151         
03152         return (false);
03153         }
03154     
03155     return (true);
03156     } /*setCardString*/
03157     
03158     
03159 boolean getCardValue (bigstring name, Handle *hvalue) {
03160     
03161     hdlobject h;
03162     
03163     if (!lookupname (name, &h))
03164         return (false);
03165         
03166     getobjectvalue (h, hvalue);
03167     
03168     return (true);
03169     } /*getCardValue*/
03170     
03171     
03172 boolean getCardValueCopy (bigstring name, Handle *hcopy) {
03173     
03174     Handle hvalue;
03175     
03176     if (!getCardValue (name, &hvalue))
03177         return (false);
03178         
03179     if (!copyhandle (hvalue, hcopy))
03180         return (false);
03181         
03182     releasetemphandles ();
03183     
03184     return (true);
03185     } /*getCardValueCopy*/
03186     
03187     
03188 boolean setCardFlag (bigstring name, boolean fl) {
03189     
03190     hdlcard hc = iowadata;
03191     hdlobject h;    
03192     
03193     if (!lookupname (name, &h))
03194         return (false);
03195         
03196     (**h).objectflag = fl;
03197     
03198     (**h).objectinval = true; 
03199     
03200     (**hc).needsupdate = true; 
03201     
03202     return (true);
03203     } /*setCardFlag*/
03204     
03205 
03206 boolean getCardFlag (bigstring name, boolean *fl) {
03207 
03208     hdlobject h;
03209     
03210     if (!lookupname (name, &h))
03211         return (false);
03212         
03213     *fl = (**h).objectflag;
03214         
03215     return (true);
03216     } /*getCardFlag*/
03217     
03218     
03219 static boolean getnthstring (hdlobject h, short n, bigstring bs) {
03220     
03221     /*
03222     get the nth semicolon-delimited string from the object's 
03223     value text handle. n is 1-based.
03224     */
03225     
03226     Handle htext = (**h).objectvalue;
03227     short i;
03228     short ctchars;
03229     short itemnum = 1;
03230     
03231     ctchars = GetHandleSize (htext);
03232     
03233     setstringlength (bs, 0);
03234         
03235     for (i = 0; i < ctchars; i++) {
03236         
03237         char ch = (*htext) [i];
03238         
03239         if (ch == ';') {
03240             
03241             if (itemnum == n)
03242                 return (true);
03243                 
03244             itemnum++;
03245             
03246             setstringlength (bs, 0);
03247             }
03248         else 
03249             pushchar (ch, bs);
03250         } /*for*/
03251     
03252     return ((itemnum == n) && (stringlength (bs) > 0));
03253     } /*getnthstring*/
03254     
03255         
03256 void geteventwindow (EventRecord *ev, WindowPtr *eventwindow) {
03257     
03258     /*
03259     returns the window that the event applies to. nil if it doesn't
03260     apply to us.
03261     
03262     we chose this way of breaking things up to mimic the Mac dialog 
03263     manager, so that developers who are comfortable with it will know
03264     how to use this stuff.
03265     */
03266     
03267     WindowPtr w;
03268     WindowPtr wfront;
03269     
03270     wfront = FrontWindow ();
03271     
03272     w = nil; /*default*/
03273     
03274     switch ((*ev).what) { /*some events apply to windows other than the frontmost*/
03275         
03276         case nullEvent: 
03277             w = wfront; 
03278             
03279             break;
03280             
03281         case keyDown: case autoKey: case keyUp:
03282             w = wfront;
03283             
03284             /*
03285             setkeyboardstatus (*ev); 
03286         
03287             if (keyboardstatus.flcmdkey) 
03288                 if (keyboardstatus.chkb != '.') 
03289                     w = nil;
03290             */
03291                 
03292             break;
03293 
03294         case mouseDown: case mouseUp:
03295             FindWindow ((*ev).where, &w);
03296             
03297             break;
03298             
03299         case updateEvt: case activateEvt:
03300             w = (WindowPtr) (*ev).message;
03301             
03302             break;
03303             
03304         default: /*we don't handle other events*/
03305             break;
03306         } /*switch*/
03307         
03308     *eventwindow = w;
03309     } /*geteventwindow*/
03310     
03311     
03312 #if defined (coderesource) && !defined (IOAinsideApp) && !__powerc
03313 
03314     /*
03315     2/1/93 dmb: callback routines need to have a4 set up. we could create a 
03316     wrapper for each routine that declares matching parameters, but the marcros 
03317     below automate things a bit while decreasing overhead. after setting up a4, 
03318     the a4callback macro calls the real callback with the actual parameters passed 
03319     in by the caller.  It then restores a4 and the return address before exiting.
03320     */
03321     
03322     static void __GetA4etc (void)
03323     {
03324         asm {
03325             bsr.s   @1
03326             dc.l    0           ;  store our A4 here
03327             dc.l    0           ;  store ioa A4 here
03328             dc.l    0           ;  store return here
03329     @1      move.l  (sp)+,a1
03330         }
03331     }
03332     
03333     #define RememberA4()    do { __GetA4etc(); asm { move.l a4,(a1) } } while (0)
03334     
03335     
03336     #define a4callback(x) \
03337         a4##x (void) { \
03338             asm { jsr __GetA4etc } \
03339             asm { move.l (sp)+,8(a1) } \
03340             asm { move.l a4,4(a1) } \
03341             asm { move.l (a1),a4 } \
03342             asm { jsr x } \
03343             asm { jsr __GetA4etc } \
03344             asm { move.l 4(a1),a4 } \
03345             asm { move.l 8(a1),-(sp) } \
03346             }
03347     
03348     static void a4callback (getobjectsize)
03349     static void a4callback (iowagetstringvalue)
03350     static void a4callback (pushforecolor)
03351     static void a4callback (popforecolor)
03352     static void a4callback (pushbackcolor)
03353     static void a4callback (popbackcolor)
03354     static void a4callback (runbuttonscript)
03355     static void a4callback (iowagetbooleanvalue)
03356     static void a4callback (iowasetbooleanvalue)
03357     static void a4callback (recalcobjectvalue)
03358     static void a4callback (evalscript)
03359     static void a4callback (invalobject)
03360     static void a4callback (setobjectvalue)
03361     static void a4callback (clearactivetextobject)
03362     static void a4callback (setactivetextobject)
03363     static void a4callback (editdrawtexthandle)
03364     static void a4callback (editclickbottleneck)
03365     static void a4callback (editselectall)
03366     static void a4callback (editidle)
03367     static void a4callback (editkeystroke)
03368     static void a4callback (getactiveeditrecord)
03369     static void a4callback (getnthstring)
03370 
03371 
03372 void initIOAcallbacks (void) {
03373     
03374     /*
03375     initialize the IOA callback routines
03376     */ 
03377     
03378     hdlcard hc = iowadata;
03379     
03380     RememberA4 ();
03381     
03382     (**hc).IOAgetobjectsizeCallback = (tygetobjectsizecallback) a4getobjectsize;
03383     
03384     (**hc).IOAgetstringvalueCallback = (tyobjectptrhandlecallback) a4getstringvalue;
03385     
03386     (**hc).IOApushforecolorCallback = (tyRGBcallback) a4pushforecolor;
03387     
03388     (**hc).IOApopforecolorCallback = (tyvoidcallback) a4popforecolor;
03389     
03390     (**hc).IOApushbackcolorCallback = (tyRGBcallback) a4pushbackcolor;
03391     
03392     (**hc).IOApopbackcolorCallback = (tyvoidcallback) a4popbackcolor;
03393     
03394     (**hc).IOArunbuttonscriptCallback = (tyobjectcallback) a4runbuttonscript;
03395     
03396     (**hc).IOAiowagetbooleanvalueCallback = (tyobjectptrhandlecallback) a4iowagetbooleanvalue;
03397     
03398     (**hc).IOAsetbooleanvalueCallback = (tyobjecthandlecallback) a4setbooleanvalue;
03399     
03400     (**hc).IOArecalcobjectvalueCallback = (tyobjectcallback) a4recalcobjectvalue;
03401     
03402     (**hc).IOAevalscriptCallback = (tyevalscriptcallback) a4evalscript;
03403     
03404     (**hc).IOAinvalobjectCallback = (tyobjectcallback) a4invalobject;
03405     
03406     (**hc).IOAsetobjectvalueCallback = (tyobjecthandlecallback) a4setobjectvalue;
03407     
03408     (**hc).IOAclearactivetextobjectCallback = (tyvoidcallback) a4clearactivetextobject;
03409     
03410     (**hc).IOAsetactivetextobjectCallback = (tyobjectcallback) a4setactivetextobject;
03411     
03412     (**hc).IOAeditdrawtexthandleCallback = (tydrawtexthandlecallback) a4editdrawtexthandle; 
03413     
03414     (**hc).IOAeditclickCallback = (tyeditclickcallback) a4editclickbottleneck; 
03415     
03416     (**hc).IOAeditselectallCallback = (tyhandlecallback) a4editselectall; 
03417     
03418     (**hc).IOAeditidleCallback = (tyhandlecallback) a4editidle; 
03419     
03420     (**hc).IOAeditkeystrokeCallback = (tycharhandlecallback) a4editkeystroke; 
03421     
03422     (**hc).IOAgetactiveeditrecordCallback = (tyreturnshandlecallback) a4getactiveeditrecord;
03423     
03424     (**hc).IOAgetnthstringCallback = (tygetnthstringcallback) a4getnthstring;
03425     } /*initIOAcallbacks*/
03426 
03427 #else
03428 
03429 void initIOAcallbacks (void) {
03430     
03431     /*
03432     initialize the IOA callback routines
03433     */ 
03434     
03435     hdlcard hc = iowadata;
03436     
03437     (**hc).IOAgetobjectsizeCallback = getobjectsize;
03438     
03439     (**hc).IOAgetstringvalueCallback = iowagetstringvalue;
03440     
03441     (**hc).IOApushforecolorCallback = pushforecolor;
03442     
03443     (**hc).IOApopforecolorCallback = popforecolor;
03444     
03445     (**hc).IOApushbackcolorCallback = pushbackcolor;
03446     
03447     (**hc).IOApopbackcolorCallback = popbackcolor;
03448     
03449     (**hc).IOArunbuttonscriptCallback = runbuttonscript;
03450     
03451     (**hc).IOAgetbooleanvalueCallback = iowagetbooleanvalue;
03452     
03453     (**hc).IOAsetbooleanvalueCallback = iowasetbooleanvalue;
03454     
03455     (**hc).IOArecalcobjectvalueCallback = recalcobjectvalue;
03456     
03457     (**hc).IOAevalscriptCallback = evalscript;
03458     
03459     (**hc).IOAinvalobjectCallback = (tyobjectcallback) invalobject;
03460     
03461     (**hc).IOAsetobjectvalueCallback = (tyobjecthandlecallback) setobjectvalue;
03462     
03463     (**hc).IOAclearactivetextobjectCallback = (tyvoidcallback) clearactivetextobject;
03464     
03465     (**hc).IOAsetactivetextobjectCallback = setactivetextobject;
03466     
03467     (**hc).IOAeditdrawtexthandleCallback = editdrawtexthandle; 
03468     
03469     (**hc).IOAeditclickCallback = (tyeditclickcallback) editclickbottleneck; 
03470     
03471     (**hc).IOAeditselectallCallback = (tyhandlecallback) editselectall; 
03472     
03473     (**hc).IOAeditidleCallback = (tyhandlecallback) editidle; 
03474     
03475     (**hc).IOAeditkeystrokeCallback = (tycharhandlecallback) editkeystroke; 
03476     
03477     (**hc).IOAgetactiveeditrecordCallback = (tyreturnshandlecallback) getactiveeditrecord;
03478     
03479     (**hc).IOAgetnthstringCallback = getnthstring;
03480     } /*initIOAcallbacks*/
03481 
03482 #endif
03483 
03484 
03485 

Generated on Wed May 31 18:19:49 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6