home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / frntsdk1.cpt / Frontier SDK 1.0 ƒ / Applet Toolkit / appletmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-07  |  56.1 KB  |  2,865 lines

  1.  
  2. /*⌐ Copyright 1988 -- 1991 UserLand Software, Inc.  All Rights Reserved.*/
  3.  
  4.  
  5. #include <iac.h>
  6. #include <menusharing.h>
  7.  
  8. #include "appletinternal.h"
  9. #include "ops.h"
  10. #include "bitmaps.h"
  11. #include "quickdraw.h"
  12. #include "scrollbar.h"
  13. #include "font.h"
  14. #include "kb.h"
  15. #include "printing.h"
  16. #include "about.h"
  17. #include "appletmain.h"
  18.  
  19.  
  20. /*
  21. IAC messages implemented by the Applet Toolkit layer.
  22. */
  23.     #define alertdialogtoken    'alrt'
  24.     #define confirmdialogtoken    'cnfm'
  25.     #define enabledialogtoken    'enbd'
  26.     #define geterrorstringtoken    'gers'
  27.     
  28.     #define gettargettoken        'gtrg'
  29.     #define settargettoken         'strg'
  30.     
  31.     #define newwindowtoken         'nwin'
  32.     #define openwindowtoken        'owin'
  33.     #define closewindowtoken    'cwin'
  34.     #define savewindowtoken        'swin'
  35.     #define revertwindowtoken    'rwin'
  36.     #define movewindowtoken        'mwin'
  37.     #define printwindowtoken    'pwin'
  38.     #define selectwindowtoken    'xwin'
  39.     
  40.     #define getfilepathtoken    'gpth'
  41.     #define getwindowpostoken    'gwps'
  42.     #define madechangestoken    'chgs'
  43.  
  44.     #define getpicttoken        'gpic'
  45.     #define gettexttoken        'gtex'
  46.     #define putpicttoken        'ppic'
  47.     #define puttexttoken        'ptex'
  48.     #define selectalltoken        'sela'
  49.     #define haveselectiontoken    'hsel'
  50.     
  51.     #define countwindowstoken    'twin'
  52.     #define nthwindowtoken        'nthw'
  53.     #define quittoken            'quit'
  54.     
  55.     #define perftesttoken         'perf'
  56.     
  57. /*
  58. new undocumented verbs
  59. */
  60.     #define getpagerecttoken    'gprc'
  61.     #define askdialogtoken        'askd'
  62.     #define getwindowrecttoken    'gwrc'
  63.  
  64.     
  65.     
  66. /*
  67. for communication with the applet body code -- it has copies of all the globals,
  68. and pointers to the callback routines that define the applet.
  69. */
  70.     tyappletrecord app;
  71.  
  72. /*
  73. globals used by the window visiter.
  74. */
  75.     bigstring bsvisit;
  76.     short vnumvisit;
  77.     short x1, x2; /*two short registers for visit routines*/
  78.     hdlappwindow lastwindowvisited;
  79.     
  80.     
  81. /*
  82. flag to control whether the user is interacting, or we're responding to an
  83. interapplication message. the error string is saved -- to be accessed by the
  84. GetErrorString verb.
  85. */
  86.     boolean fldialogsenabled = true;
  87.     bigstring bserrorstring;
  88.  
  89.  
  90. typedef struct tyappwindowinfo { /*saved on disk after the applet's data handle*/
  91.     
  92.     short top, left, bottom, right; /*window position, cross-platform*/
  93.     
  94.     char waste [256]; /*room to grow*/
  95.     } tyappwindowinfo;
  96.     
  97. tymouserecord mousestatus;
  98.     
  99. #define applemenu 128
  100. #define aboutitem 1
  101.  
  102. #define filemenu 129
  103. #define newitem 1
  104. #define openitem 2
  105. #define closeitem 3
  106. #define saveitem 5
  107. #define saveasitem 6
  108. #define revertitem 7
  109. #define pagesetupitem 9
  110. #define printitem 10
  111. #define quititem 12
  112.  
  113. #define firstsharedmenu filemenu+1
  114.  
  115. MenuHandle hdlapplemenu, hdlfilemenu;
  116.  
  117.  
  118. boolean flexitmainloop = false;
  119.  
  120. #define nowindowerror 7 /*index into the verb error STR# list*/
  121. #define windowopenerror 8
  122. #define nopictcallbackerror 9
  123. #define notextcallbackerror 10
  124. #define noputtextcallbackerror 11
  125. #define noputpictcallbackerror 12
  126.  
  127.  
  128. bigstring bstargetwindowname; /*title of window that IAC verbs apply to*/
  129.  
  130.  
  131. #define jugglerEvt 15 /*a suspend/resume event from the OS to us*/
  132.  
  133. typedef struct tyjugglermessage {
  134.     
  135.     long eventtype: 8; /*bits 24 -- 31*/
  136.     
  137.     long reservedbits: 22; /*bits 2 -- 23*/
  138.     
  139.     long flconvertclipboard: 1; /*bit 1*/
  140.     
  141.     long flresume: 1; /*bit 0*/
  142.     } tyjugglermessage;
  143.     
  144.  
  145.  
  146. boolean appalert (bs) bigstring bs; {
  147.     
  148.     copystring (bs, bserrorstring);
  149.     
  150.     if (fldialogsenabled)
  151.         return (alertdialog (bs));
  152.     } /*appalert*/
  153.     
  154.     
  155. void drawappgrowicon (appwindow) hdlappwindow appwindow; {
  156.     
  157.     register WindowPtr w = (**appwindow).macwindow;
  158.     
  159.     if (app.vertscroll && app.horizscroll) {
  160.         
  161.         DrawGrowIcon (w);
  162.         }
  163.     else {
  164.         register short width = 15;
  165.         Rect r = (*w).portRect;
  166.         
  167.         r.left = r.right - width;
  168.             
  169.         r.top = r.bottom - width;
  170.         
  171.         pushclip (r);
  172.         
  173.         DrawGrowIcon (w);
  174.         
  175.         popclip ();
  176.         }
  177.     } /*drawappgrowicon*/
  178.     
  179.  
  180. void installmenu (idmenu, hmenu) short idmenu; MenuHandle *hmenu; {
  181.  
  182.     *hmenu = GetMenu (idmenu); 
  183.     
  184.     InsertMenu (*hmenu, 0);
  185.     } /*installmenu*/
  186.     
  187.     
  188. void initmenus (void) {
  189.  
  190.     hdlapplemenu = GetMenu (applemenu); 
  191.  
  192.     AddResMenu (hdlapplemenu, 'DRVR'); 
  193.  
  194.     InsertMenu (hdlapplemenu, 0); 
  195.     
  196.     installmenu (filemenu, &hdlfilemenu);
  197.     
  198.     DrawMenuBar ();
  199.     } /*initmenus*/
  200.  
  201.  
  202. boolean apppushwindow (appwindow) hdlappwindow appwindow; {
  203.     
  204.     return (pushmacport ((**appwindow).macwindow));
  205.     } /*apppushwindow*/
  206.     
  207.  
  208. boolean apppopwindow (void) {
  209.     
  210.     return (popmacport ());
  211.     } /*apppopwindow*/
  212.     
  213.     
  214. boolean apppushorigin (void) {
  215.  
  216.     register hdlappwindow ha = app.appwindow;
  217.     register WindowPtr w = (**ha).macwindow;
  218.     
  219.     SetOrigin ((**ha).scrollorigin.h, (**ha).scrollorigin.v);
  220.     
  221.     OffsetRgn ((*w).clipRgn, (**ha).scrollorigin.h, (**ha).scrollorigin.v);
  222.     } /*apppushorigin*/
  223.     
  224.     
  225. boolean apppoporigin (void) {
  226.  
  227.     register hdlappwindow ha = app.appwindow;
  228.     register WindowPtr w = (**ha).macwindow;
  229.     
  230.     OffsetRgn ((*w).clipRgn, -(**ha).scrollorigin.h, -(**ha).scrollorigin.v);
  231.     
  232.     SetOrigin (0, 0);
  233.     } /*apppoporigin*/
  234.     
  235.     
  236. boolean appopenbitmap (r, appwindow) Rect r; hdlappwindow appwindow; {
  237.     
  238.     return (openbitmap (r, (**appwindow).macwindow));
  239.     } /*appopenbitmap*/
  240.     
  241.  
  242. boolean appclosebitmap (appwindow) hdlappwindow appwindow; {
  243.     
  244.     closebitmap ((**appwindow).macwindow);
  245.     
  246.     return (true);
  247.     } /*appclosebitmap*/
  248.     
  249.  
  250. void getappdata (w, appdata) WindowPtr w; Handle *appdata; {
  251.     
  252.     /*
  253.     a window's refcon field points to the appwindow record, which in turn 
  254.     points to the applet's data in the appdata field.
  255.     */
  256.     
  257.     register hdlappwindow ha = (hdlappwindow) (*(WindowPeek) w).refCon;
  258.     
  259.     if (ha == nil)
  260.         *appdata = nil;
  261.     else
  262.         *appdata = (**ha).appdata;
  263.     } /*getappdata*/
  264.     
  265.     
  266. void getwindowrefcon (w, refcon) WindowPtr w; long *refcon; {
  267.     
  268.     *refcon = (*(WindowPeek) w).refCon;
  269.     } /*getwindowrefcon*/
  270.     
  271.     
  272. void getappwindowtitle (appwindow, bs) hdlappwindow appwindow; bigstring bs; {
  273.     
  274.     if (appwindow == nil)
  275.         setstringlength (bs, 0);
  276.     else
  277.         GetWTitle ((**appwindow).macwindow, bs);
  278.     } /*selectappwindow*/
  279.     
  280.     
  281. void setappwindowtitle (appwindow, bs) hdlappwindow appwindow; bigstring bs; {
  282.     
  283.     SetWTitle ((**appwindow).macwindow, bs);
  284.     } /*setappwindowtitle*/
  285.     
  286.  
  287. void showappwindow (appwindow) hdlappwindow appwindow; {
  288.     
  289.     ShowWindow ((**appwindow).macwindow);
  290.     } /*showappwindow*/
  291.     
  292.     
  293. void selectappwindow (appwindow) hdlappwindow appwindow; {
  294.  
  295.     SelectWindow ((**appwindow).macwindow);
  296.     } /*selectappwindow*/
  297.     
  298.     
  299. void invalappwindow (appwindow, flerase) hdlappwindow appwindow; boolean flerase; {
  300.     
  301.     Rect r;
  302.     
  303.     pushmacport ((**appwindow).macwindow); 
  304.     
  305.     r = (**appwindow).windowrect;
  306.     
  307.     invalrect (r);
  308.     
  309.     if (flerase) {
  310.         
  311.         pushclip (r);
  312.         
  313.         eraserect (r);
  314.         
  315.         popclip ();
  316.         }
  317.         
  318.     popmacport ();
  319.     } /*invalappwindow*/
  320.     
  321.     
  322. void setappwindow (appwindow) hdlappwindow appwindow; {
  323.     
  324.     register hdlappwindow ha = appwindow;
  325.     
  326.     app.appwindow = ha;
  327.         
  328.     if (ha == nil) {
  329.         
  330.         app.appdata = nil;
  331.         }
  332.     else {
  333.         app.appdata = (**ha).appdata;
  334.         
  335.         SetPort ((**ha).macwindow);
  336.         }
  337.     } /*setappwindow*/
  338.     
  339.     
  340. void updateappwindow (appwindow) hdlappwindow appwindow; {
  341.     
  342.     register hdlappwindow ha = appwindow;
  343.     register WindowPtr w = (**ha).macwindow;
  344.     Rect rwindow = (*w).portRect;
  345.     Rect rstatus = (**ha).statusrect;
  346.         
  347.     BeginUpdate (w);
  348.     
  349.     setappwindow (ha);
  350.     
  351.     /*update our stuff*/ {
  352.     
  353.         pushclip (rwindow);
  354.     
  355.         drawappgrowicon (ha);
  356.  
  357.         updateappscrollbars (ha);
  358.         
  359.         if (app.statuspixels > 0) { /*has a status area*/
  360.             
  361.             Rect r = rstatus;
  362.             
  363.             MoveTo (r.left, r.bottom);
  364.     
  365.             LineTo (r.right, r.bottom);
  366.             
  367.             r.bottom += 2;
  368.             
  369.             MoveTo (r.left, r.bottom);
  370.     
  371.             LineTo (r.right, r.bottom);
  372.             }
  373.     
  374.         popclip ();
  375.         }
  376.         
  377.     /*let the applet update his stuff*/ {
  378.     
  379.         pushclip ((**ha).contentrect);
  380.         
  381.         (*app.updatecallback) ();
  382.         
  383.         popclip ();
  384.         }
  385.         
  386.     /*update the status portion of the window*/ {
  387.         
  388.         if (app.statuspixels > 0) { /*has a status area*/
  389.         
  390.             pushclip (rstatus);
  391.         
  392.             (*app.updatestatuscallback) ();
  393.         
  394.             popclip ();
  395.             }
  396.         }
  397.     
  398.     EndUpdate (w);
  399.     } /*updateappwindow*/
  400.     
  401.  
  402. void computewindowinfo (macwindow, appwindow) WindowPtr macwindow; hdlappwindow appwindow; {
  403.     
  404.     register WindowPtr w = macwindow;
  405.     register hdlappwindow ha = appwindow;
  406.     Rect r, rcontent, rstatus;
  407.     
  408.     (**ha).windowrect = r = (*w).portRect;
  409.     
  410.     rcontent = r;
  411.     
  412.     /*take out for scrollbars*/ {
  413.         
  414.         register short scrollbarwidth = getscrollbarwidth ();
  415.         
  416.         if (app.vertscroll)
  417.             rcontent.right -= scrollbarwidth;
  418.         
  419.         if (app.horizscroll)
  420.             rcontent.bottom -= scrollbarwidth;
  421.         }
  422.     
  423.     if (app.statuspixels > 0) /*has a status area*/
  424.         rcontent.top += app.statuspixels + 3; /*a 3-pixel line separates status & content*/
  425.         
  426.     (**ha).contentrect = rcontent;
  427.     
  428.     rstatus = r; /*copy left, right, top*/
  429.     
  430.     rstatus.bottom = rstatus.top + app.statuspixels;
  431.     
  432.     (**ha).statusrect = rstatus;
  433.     
  434.     (**ha).windowvertpixels = r.bottom - r.top;
  435.     
  436.     (**ha).windowhorizpixels = r.right - r.left;
  437.     
  438.     (**ha).defaultfont = geneva;
  439.     
  440.     (**ha).defaultsize = 9;
  441.     
  442.     (**ha).defaultstyle = 0;
  443.     
  444.     pushmacport (w);
  445.     
  446.     pushstyle ((**ha).defaultfont, (**ha).defaultsize, (**ha).defaultstyle);
  447.     
  448.     (**ha).fontheight = globalfontinfo.ascent + globalfontinfo.descent;
  449.     
  450.     popstyle ();
  451.     
  452.     popmacport ();
  453.     
  454.     (**ha).macwindow = w;
  455.     } /*computewindowinfo*/
  456.     
  457.  
  458. void getdesktoprect (appwindow, rwindow) hdlappwindow appwindow; Rect *rwindow; {
  459.     
  460.     register WindowPtr w = (**appwindow).macwindow;
  461.     
  462.     *rwindow = (*w).portRect;
  463.     
  464.     pushmacport (w);
  465.             
  466.     localtoglobalrect (rwindow);
  467.             
  468.     popmacport ();
  469.     } /*getdesktoprect*/
  470.     
  471.     
  472. void disposeappwindow (appwindow) hdlappwindow appwindow; {
  473.  
  474.     register hdlappwindow ha = app.appwindow;
  475.     
  476.     (*app.disposerecordcallback) ();
  477.     
  478.     disposescrollbar ((**ha).vertbar);
  479.     
  480.     disposescrollbar ((**ha).horizbar);
  481.     
  482.     DisposeWindow ((**ha).macwindow);
  483.     
  484.     disposehandle ((Handle) ha);
  485.     } /*disposeappwindow*/
  486.     
  487.  
  488. typedef boolean (*tyvisitapproutine) (hdlappwindow);
  489.  
  490.  
  491. boolean visitappwindows (visitproc) tyvisitapproutine visitproc; {
  492.     
  493.     /*
  494.     visit all the windows from front to back.  call the visitproc for each window, 
  495.     if it returns false we stop the traversal and return false.
  496.     
  497.     the visitproc takes one parameter -- a window pointer, indicating the window
  498.     to be visited.
  499.     
  500.     return true if all the visits returned true.
  501.     
  502.     9/4/91 DW: add lastwindowvisited -- returns nil if no match found, returns
  503.     pointing to the appwindow record for the window that matched the visitproc's
  504.     criteria.
  505.     */
  506.     
  507.     register WindowPtr w = FrontWindow ();
  508.     hdlappwindow appwindow;
  509.     
  510.     lastwindowvisited = nil;
  511.     
  512.     while (w != nil) {
  513.         
  514.         getwindowrefcon (w, (long *) &appwindow);
  515.         
  516.         if (appwindow == nil) /*defensive driving -- no linked data -- skip it*/
  517.             goto next;
  518.         
  519.         if (!(*visitproc) (appwindow)) { /*stop the traversal*/
  520.         
  521.             lastwindowvisited = appwindow; /*set global*/
  522.             
  523.             return (false);
  524.             }
  525.         
  526.         next:
  527.         
  528.         w = (WindowPtr) (*(WindowPeek) w).nextWindow; 
  529.         } /*while*/
  530.         
  531.     return (true); /*completed the traversal*/
  532.     } /*visitappwindows*/
  533.     
  534.  
  535. boolean selectvisit (appwindow) hdlappwindow appwindow; {
  536.     
  537.     bigstring bs;
  538.     
  539.     getappwindowtitle (appwindow, bs);
  540.     
  541.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  542.         return (true);
  543.     
  544.     /*found a match, select the window, stop the traversal*/
  545.     
  546.     selectappwindow (appwindow);
  547.         
  548.     return (false); /*stop the traversal*/
  549.     } /*selectvisit*/
  550.     
  551.     
  552. boolean selectwindowbytitle (bs) bigstring bs; {
  553.  
  554.     /*
  555.     visit all the windows from front to back.  when we encounter one of the 
  556.     app's windows check the window title.  if it equals bs, then select the 
  557.     window and set the globals accordingly.
  558.     
  559.     return false if there is no app window with that name.
  560.     */
  561.     
  562.     copystring (bs, bsvisit); /*copy into global so visit routine can access*/
  563.     
  564.     return (!visitappwindows (&selectvisit));
  565.     } /*selectwindowbytitle*/    
  566.     
  567.     
  568. boolean findbytitlevisit (appwindow) hdlappwindow appwindow; {
  569.     
  570.     bigstring bs;
  571.     
  572.     getappwindowtitle (appwindow, bs);
  573.     
  574.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  575.         return (true);
  576.     
  577.     return (false); /*stop the traversal*/
  578.     } /*findbytitlevisit*/
  579.     
  580.     
  581. boolean findbywindowtitle (bstitle, appwindow) bigstring bstitle; hdlappwindow *appwindow; {
  582.  
  583.     copystring (bstitle, bsvisit); /*copy into global so visit routine can access*/
  584.     
  585.     visitappwindows (&findbytitlevisit);
  586.     
  587.     if (lastwindowvisited == nil)
  588.         return (false);
  589.         
  590.     *appwindow = lastwindowvisited;
  591.     
  592.     return (true);
  593.     } /*findbywindowtitle*/
  594.     
  595.     
  596. boolean findnthvisit (appwindow) hdlappwindow appwindow; {
  597.     
  598.     return (++x2 < x1); /*visit until they're equal*/
  599.     } /*findnthvisit*/
  600.     
  601.     
  602. boolean findnthwindow (n, appwindow) short n; hdlappwindow *appwindow; {
  603.     
  604.     x1 = n; /*copy into a "register" for visit routine*/
  605.     
  606.     x2 = 0; /*another register*/
  607.     
  608.     visitappwindows (&findnthvisit);
  609.     
  610.     *appwindow = lastwindowvisited;
  611.     
  612.     return (lastwindowvisited != nil);
  613.     } /*findbywindowtitle*/
  614.     
  615.     
  616. boolean countwindowsvisit (appwindow) hdlappwindow appwindow; {
  617.     
  618.     x1++;
  619.     
  620.     return (true); /*keep going*/
  621.     } /*countwindowsvisit*/
  622.     
  623.     
  624. short countwindows (void) {
  625.     
  626.     x1 = 0; /*copy into a "register" for visit routine*/
  627.     
  628.     visitappwindows (&countwindowsvisit);
  629.     
  630.     return (x1);
  631.     } /*countwindows*/
  632.     
  633.     
  634. boolean resetdirtyscrollbarsvisit (appwindow) hdlappwindow appwindow; {
  635.     
  636.     register hdlappwindow ha = appwindow;
  637.     
  638.     setappwindow (ha);
  639.     
  640.     if ((**ha).flresetscrollbars) {
  641.         
  642.         resetappscrollbars (ha);
  643.         
  644.         (**ha).flresetscrollbars = false; /*consume it*/
  645.         }
  646.     
  647.     return (true); /*visit all open windows*/
  648.     } /*resetdirtyscrollbarsvisit*/
  649.     
  650.     
  651. boolean resetdirtyscrollbars (void) {
  652.  
  653.     visitappwindows (&resetdirtyscrollbarsvisit);
  654.     } /*resetdirtyscrollbars*/
  655.     
  656.     
  657. boolean getuntitledtitle (bs) bigstring bs; {
  658.     
  659.     register long ct = 1;
  660.     hdlappwindow appwindow;
  661.     
  662.     while (true) {
  663.         
  664.         copystring ("\pUntitled ", bs);
  665.         
  666.         pushlong (ct++, bs);
  667.         
  668.         if (!findbywindowtitle (bs, &appwindow))
  669.             return (true);
  670.         } /*while*/
  671.     } /*getuntitledtitle*/
  672.     
  673.  
  674. boolean findbyfilevisit (appwindow) hdlappwindow appwindow; {
  675.     
  676.     if ((**appwindow).vnum = vnumvisit) {
  677.     
  678.         if (equalstrings ((**appwindow).fname, bsvisit)) 
  679.             return (false);
  680.         }
  681.             
  682.     return (true); /*keep visiting*/
  683.     } /*findbyfilevisit*/
  684.     
  685.     
  686. boolean findbyfile (fname, vnum, appwindow) bigstring fname; short vnum; hdlappwindow *appwindow; {
  687.  
  688.     copystring (fname, bsvisit); /*copy into global so visit routine can access*/
  689.     
  690.     vnumvisit = vnum; /*copy into global*/
  691.     
  692.     visitappwindows (&findbyfilevisit);
  693.     
  694.     if (lastwindowvisited == nil)
  695.         return (false);
  696.         
  697.     *appwindow = lastwindowvisited;
  698.     
  699.     return (true);
  700.     } /*findbyfile*/
  701.     
  702.     
  703. boolean settargetvisit (appwindow) hdlappwindow appwindow; {
  704.     
  705.     bigstring bs;
  706.     
  707.     getappwindowtitle (appwindow, bs);
  708.     
  709.     if (!equalstrings (bsvisit, bs)) /*no match -- keep traversing*/
  710.         return (true);
  711.     
  712.     /*found a match, stop the traversal*/
  713.     
  714.     setappwindow (appwindow);
  715.     
  716.     return (false); /*stop the traversal*/
  717.     } /*settargetvisit*/
  718.     
  719.     
  720. boolean setapptarget (bs) bigstring bs; {
  721.     
  722.     /*
  723.     set the globals for the window with the indicated name without bringing
  724.     the window to the front.
  725.     */
  726.     
  727.     setappwindow (nil);
  728.     
  729.     copystring (bs, bsvisit); /*copy into global so visit routine can access*/
  730.     
  731.     visitappwindows (&settargetvisit);
  732.     
  733.     return (app.appwindow != nil);
  734.     } /*setapptarget*/    
  735.     
  736.  
  737. boolean setfrontglobalsvisit (appwindow) hdlappwindow appwindow; {
  738.     
  739.     setappwindow (appwindow);
  740.     
  741.     return (false); /*stop the traversal*/
  742.     } /*setfrontglobalsvisit*/
  743.     
  744.     
  745. boolean setfrontglobals (void) {
  746.     
  747.     setappwindow (nil);
  748.     
  749.     visitappwindows (&setfrontglobalsvisit);
  750.     
  751.     return (app.appwindow != nil);
  752.     } /*setfrontglobals*/
  753.  
  754.  
  755. static void saveappwindowinfo (hdlappwindow appwindow, tyappwindowinfo *appwindowinfo) {
  756.     
  757.     Rect r;
  758.     
  759.     getdesktoprect (appwindow, &r);
  760.     
  761.     (*appwindowinfo).top = r.top;
  762.     
  763.     (*appwindowinfo).left = r.left;
  764.     
  765.     (*appwindowinfo).bottom = r.bottom;
  766.     
  767.     (*appwindowinfo).right = r.right;
  768.     } /*saveappwindowinfo*/
  769.     
  770.  
  771. void moveappwindow (appwindow, rnew) hdlappwindow appwindow; Rect rnew; {
  772.     
  773.     register WindowPtr w = (**appwindow).macwindow;
  774.     register short t, l, b, r;
  775.     Rect rdesktop;
  776.     
  777.     rdesktop = (**GrayRgn).rgnBBox; 
  778.     
  779.     t = rnew.top;
  780.  
  781.     t = max (t, rdesktop.top); 
  782.     
  783.     l = rnew.left;
  784.     
  785.     l = max (l, rdesktop.left);
  786.     
  787.     b = rnew.bottom;
  788.     
  789.     b = min (b, rdesktop.bottom);
  790.     
  791.     b = max (b, t);
  792.  
  793.     r = rnew.right;
  794.     
  795.     r = min (r, rdesktop.right);
  796.     
  797.     SizeWindow (w, r - l, b - t, true);
  798.     
  799.     MoveWindow (w, l, t, false);
  800.     
  801.     computewindowinfo (w, appwindow);
  802.     
  803.     resizeappscrollbars (appwindow);
  804.     
  805.     resetappscrollbars (appwindow);
  806.     } /*moveappwindow*/
  807.     
  808.  
  809. static void loadappwindowinfo (hdlappwindow appwindow, tyappwindowinfo appwindowinfo) {
  810.     
  811.     Rect rnew;
  812.     
  813.     rnew.top = appwindowinfo.top;
  814.     
  815.     rnew.left = appwindowinfo.left;
  816.     
  817.     rnew.bottom = appwindowinfo.bottom;
  818.     
  819.     rnew.right = appwindowinfo.right;
  820.     
  821.     moveappwindow (appwindow, rnew);
  822.     } /*loadappwindowinfo*/
  823.     
  824.  
  825. boolean savewindow (fname, vnum) bigstring fname; short vnum; {
  826.     
  827.     register hdlappwindow ha = app.appwindow;
  828.     tyappwindowinfo appwindowinfo;
  829.     short versionnumber;
  830.     Handle h = nil;
  831.     long ctbytes;
  832.     
  833.     setstringlength (bserrorstring, 0);
  834.     
  835.     if ((**ha).fnum == 0) { /*file isn't open*/
  836.     
  837.         short fnum;
  838.         
  839.         if (!fileopenorcreate (fname, vnum, app.creator, app.filetype, &fnum)) {
  840.             
  841.             appalert ("\pError saving the front window.");
  842.             
  843.             return (false);
  844.             }
  845.         
  846.         (**ha).fnum = fnum;
  847.         }
  848.     else { /*file is already open*/
  849.         
  850.         if (!fileseteof ((**ha).fnum, (long) 0)) {
  851.             
  852.             appalert ("\pError truncating the file.");
  853.             
  854.             return (false);
  855.             }
  856.         }
  857.     
  858.     if (!(*app.packcallback) (&h)) {
  859.         
  860.         appalert ("\pOut of memory.");
  861.         
  862.         goto error;
  863.         }
  864.     
  865.     ctbytes = GetHandleSize (h);
  866.     
  867.     if (!filewrite ((**ha).fnum, longsizeof (ctbytes), &ctbytes)) {
  868.         
  869.         appalert ("\pError writing to file.");
  870.         
  871.         goto error;
  872.         }
  873.         
  874.     if (!filewritehandle ((**ha).fnum, h)) {
  875.         
  876.         appalert ("\pError writing to file.");
  877.         
  878.         goto error;
  879.         }
  880.         
  881.     versionnumber = 1;
  882.     
  883.     if (!filewrite ((**ha).fnum, longsizeof (versionnumber), &versionnumber)) {
  884.         
  885.         appalert ("\pError writing to file.");
  886.         
  887.         goto error;
  888.         }
  889.         
  890.     saveappwindowinfo (ha, &appwindowinfo);
  891.     
  892.     if (!filewrite ((**ha).fnum, longsizeof (appwindowinfo), &appwindowinfo)) {
  893.         
  894.         appalert ("\pError writing to file.");
  895.         
  896.         goto error;
  897.         }
  898.     
  899.     disposehandle (h);
  900.     
  901.     (**ha).flmadechanges = false;
  902.         
  903.     return (true);
  904.         
  905.     error:
  906.     
  907.     disposehandle (h);
  908.         
  909.     fileclose ((**ha).fnum);
  910.     
  911.     (**ha).fnum = 0;
  912.     
  913.     filedelete (fname, vnum);
  914.     
  915.     return (false);
  916.     } /*savewindow*/
  917.     
  918.     
  919. boolean newappwindow (bstitle, flshowwindow) bigstring bstitle; boolean flshowwindow; {
  920.     
  921.     register hdlappwindow ha = app.appwindow;
  922.     register WindowPtr macwindow;
  923.     register short i;
  924.     register boolean flrelative = false;
  925.     short hwindow, vwindow;
  926.     Rect rwindow;
  927.     bigstring bslastword;
  928.     hdlscrollbar vertbar = nil, horizbar = nil;
  929.     
  930.     if (ha != nil) { /*seed window position from frontmost window*/
  931.         
  932.         getdesktoprect (ha, &rwindow);
  933.         
  934.         hwindow = rwindow.left + 17;
  935.         
  936.         vwindow = rwindow.top + 17;
  937.                 
  938.         flrelative = true;
  939.         }
  940.         
  941.     if (!newclearhandle (longsizeof (tyappwindow), (Handle *) &app.appwindow))
  942.         goto error;
  943.         
  944.     ha = app.appwindow; /*copy into register*/
  945.         
  946.     macwindow = GetNewWindow (128, nil, (WindowPtr) -1);
  947.     
  948.     if (macwindow == nil)
  949.         goto error;
  950.     
  951.     if (app.vertscroll) {
  952.     
  953.         if (!newscrollbar (macwindow, true, &vertbar))
  954.             goto error;
  955.         }
  956.         
  957.     if (app.horizscroll) {
  958.     
  959.         if (!newscrollbar (macwindow, false, &horizbar))
  960.             goto error;
  961.         }
  962.         
  963.     (**ha).vertbar = vertbar;
  964.     
  965.     (**ha).horizbar = horizbar;
  966.         
  967.     if (flrelative) /*position window relative to previous window*/
  968.         MoveWindow (macwindow, hwindow, vwindow, false);
  969.     else
  970.         centerwindow (macwindow, quickdrawglobal (screenBits).bounds);
  971.     
  972.     copystring (bstitle, (**ha).fname);
  973.     
  974.     computewindowinfo (macwindow, ha);
  975.     
  976.     (**ha).macwindow = macwindow;
  977.     
  978.     if (!(*app.newrecordcallback) ()) 
  979.         goto error;
  980.         
  981.     computewindowinfo (macwindow, ha); /*window might have been changed by callback*/
  982.     
  983.     (**ha).appdata = app.appdata; /*copy handle alloc'd by newrecord*/
  984.         
  985.     (*(WindowPeek) macwindow).refCon = (long) ha;
  986.     
  987.     lastword (bstitle, ':', bslastword); /*avoid displaying long paths*/
  988.     
  989.     setappwindowtitle (ha, bslastword);
  990.     
  991.     resizeappscrollbars (ha);
  992.     
  993.     resetappscrollbars (ha);
  994.     
  995.     if (flshowwindow) {
  996.     
  997.         showappwindow (ha);
  998.         
  999.         showappscrollbars (ha);
  1000.         }
  1001.             
  1002.     return (true);
  1003.     
  1004.     error:
  1005.     
  1006.     disposescrollbar (vertbar);
  1007.     
  1008.     disposescrollbar (horizbar);
  1009.     
  1010.     macwindow = (**ha).macwindow;
  1011.     
  1012.     if (macwindow != nil)
  1013.         DisposeWindow (macwindow);
  1014.         
  1015.     disposehandle ((Handle) ha);
  1016.     
  1017.     setappwindow (nil);
  1018.     
  1019.     return (false);
  1020.     } /*newappwindow*/
  1021.     
  1022.     
  1023. boolean newuntitledappwindow (void) {
  1024.         
  1025.     bigstring bstitle;
  1026.     
  1027.     getuntitledtitle (bstitle);
  1028.     
  1029.     return (newappwindow (bstitle, true));
  1030.     } /*newuntitledappwindow*/
  1031.     
  1032.     
  1033. boolean openwindow (fname, vnum) bigstring fname; short vnum; {
  1034.     
  1035.     hdlappwindow appwindow;
  1036.     register hdlappwindow ha;
  1037.     tyappwindowinfo appwindowinfo;
  1038.     short versionnumber;
  1039.     long ctbytes;
  1040.     short fnum;
  1041.     Handle h;
  1042.     
  1043.     setstringlength (bserrorstring, 0);
  1044.     
  1045.     if (findbyfile (fname, vnum, &appwindow)) {
  1046.         
  1047.         appalert ("\pThe file is already open.");
  1048.         
  1049.         selectappwindow (appwindow);
  1050.         
  1051.         return (true);
  1052.         }
  1053.     
  1054.     if (!fileopen (fname, vnum, &fnum)) {
  1055.         
  1056.         appalert ("\pError opening the file.");
  1057.         
  1058.         return (false);
  1059.         }
  1060.         
  1061.     if (!fileread (fnum, longsizeof (ctbytes), &ctbytes)) {
  1062.         
  1063.         appalert ("\pError reading from file.");
  1064.         
  1065.         goto error;
  1066.         }
  1067.         
  1068.     if (!filereadhandle (fnum, ctbytes, &h)) {
  1069.         
  1070.         appalert ("\pError reading from file.");
  1071.         
  1072.         goto error;
  1073.         }
  1074.     
  1075.     if (!fileread (fnum, longsizeof (versionnumber), &versionnumber)) {
  1076.         
  1077.         appalert ("\pError reading from file.");
  1078.         
  1079.         goto error;
  1080.         }
  1081.         
  1082.     if (versionnumber != 1) {
  1083.         
  1084.         appalert ("\pWrong file version number.");
  1085.         
  1086.         goto error;
  1087.         }
  1088.         
  1089.     if (!fileread (fnum, longsizeof (appwindowinfo), &appwindowinfo)) {
  1090.         
  1091.         appalert ("\pError reading from file.");
  1092.         
  1093.         goto error;
  1094.         }
  1095.     
  1096.     if (!newappwindow (fname, false)) {
  1097.         
  1098.         appalert ("\pError creating new window.");
  1099.         
  1100.         goto error;
  1101.         }
  1102.     
  1103.     ha = app.appwindow; /*copy into register*/
  1104.         
  1105.     loadappwindowinfo (ha, appwindowinfo); /*resize window, set fields of ha*/
  1106.     
  1107.     if (!(*app.unpackcallback) (h)) {
  1108.         
  1109.         appalert ("\pError reading from file.");
  1110.         
  1111.         goto error;
  1112.         }
  1113.     
  1114.     disposehandle (h);
  1115.     
  1116.     (**ha).appdata = app.appdata; /*copy from the app to our record*/
  1117.     
  1118.     (**ha).fnum = fnum;
  1119.         
  1120.     copystring (fname, (**ha).fname);
  1121.     
  1122.     showappwindow (ha);
  1123.     
  1124.     resetappscrollbars (ha);
  1125.     
  1126.     showappscrollbars (ha);
  1127.     
  1128.     invalappwindow (ha, false);
  1129.     
  1130.     (**ha).vnum = vnum;
  1131.     
  1132.     return (true);
  1133.     
  1134.     error:
  1135.     
  1136.     disposehandle (h);
  1137.     
  1138.     fileclose (fnum);
  1139.     
  1140.     return (false);
  1141.     } /*openwindow*/
  1142.     
  1143.     
  1144. boolean closewindow (appwindow, fldialog) hdlappwindow appwindow; boolean fldialog; {
  1145.     
  1146.     register hdlappwindow ha = appwindow;
  1147.     
  1148.     if ((**ha).flmadechanges && fldialog && (!app.notsaveable)) {
  1149.         
  1150.         bigstring bs, bstitle;
  1151.         
  1152.         sysbeep; /*call attention to the user*/
  1153.             
  1154.         getappwindowtitle (ha, bstitle);
  1155.         
  1156.         copystring ("\pDiscard changes to ╥", bs);
  1157.         
  1158.         pushstring (bstitle, bs);
  1159.         
  1160.         pushstring ("\p╙?", bs);
  1161.         
  1162.         if (!msgdialog (bs))
  1163.             return (false);
  1164.         }
  1165.     
  1166.     setappwindow (ha);
  1167.     
  1168.     fileclose ((**ha).fnum); 
  1169.  
  1170.     disposeappwindow (ha);
  1171.     
  1172.     return (true);
  1173.     } /*closewindow*/
  1174.     
  1175.  
  1176. boolean closewindowvisit (appwindow) hdlappwindow appwindow; {
  1177.     
  1178.     return (closewindow (appwindow, true));
  1179.     } /*closewindowvisit*/
  1180.     
  1181.  
  1182. boolean closeallwindows (void) {
  1183.     
  1184.     return (visitappwindows (&closewindowvisit));
  1185.     } /*closeallwindows*/
  1186.  
  1187.     
  1188. boolean saveaswindow (fname, vnum) bigstring fname; short vnum; {
  1189.     
  1190.     register hdlappwindow ha = app.appwindow;
  1191.  
  1192.     fileclose ((**ha).fnum); /*close the file if it's open*/
  1193.     
  1194.     (**ha).fnum = 0;
  1195.         
  1196.     if (!savewindow (fname, vnum))
  1197.         return (false);
  1198.         
  1199.     copystring (fname, (**ha).fname);
  1200.     
  1201.     (**ha).vnum = vnum;
  1202.     
  1203.     setappwindowtitle (ha, fname);
  1204.     
  1205.     copystring (fname, bstargetwindowname);
  1206.     
  1207.     return (true);
  1208.     } /*saveaswindow*/
  1209.     
  1210.     
  1211. boolean saveasfrontwindow (void) {
  1212.     
  1213.     register hdlappwindow ha = app.appwindow;
  1214.     bigstring fname;
  1215.     short vnum;
  1216.     
  1217.     copystring ((**ha).fname, fname);
  1218.     
  1219.     vnum = (**ha).vnum;
  1220.     
  1221.     if (!sfdialog (true, fname, &vnum, app.filetype))
  1222.         return (false);
  1223.         
  1224.     return (saveaswindow (fname, vnum));
  1225.     } /*saveasfrontwindow*/
  1226.     
  1227.     
  1228. boolean savefrontwindow (void) {
  1229.     
  1230.     register hdlappwindow ha = app.appwindow;
  1231.     
  1232.     if (ha == nil) /*defensive driving*/
  1233.         return (false);
  1234.     
  1235.     if ((**ha).fnum == 0)
  1236.         return (saveasfrontwindow ());
  1237.         
  1238.     return (savewindow ((**ha).fname, (**ha).vnum));
  1239.     } /*savefrontwindow*/
  1240.     
  1241.     
  1242. boolean closefrontwindow (void) {
  1243.     
  1244.     closewindow (app.appwindow, true);
  1245.     } /*closefrontwindow*/
  1246.     
  1247.  
  1248. boolean openfrontwindow (void) {
  1249.     
  1250.     bigstring fname;
  1251.     short vnum;
  1252.     
  1253.     if (!sfdialog (false, fname, &vnum, app.filetype))
  1254.         return (false);
  1255.         
  1256.     return (openwindow (fname, vnum));
  1257.     } /*openfrontwindow*/
  1258.     
  1259.     
  1260. boolean revertfrontwindow (void) {
  1261.     
  1262.     register hdlappwindow ha = app.appwindow;
  1263.     bigstring fname;
  1264.     short vnum;
  1265.     
  1266.     copystring ((**ha).fname, fname);
  1267.     
  1268.     vnum = (**ha).vnum;
  1269.     
  1270.     if (!closewindow (ha, fldialogsenabled)) /*user declined to discard changes*/
  1271.         return (false);
  1272.         
  1273.     /*
  1274.     11/7/91 DW: prevent a crash in 32-bit mode -- make sure app globals accurately
  1275.     reflect the state of the Applet Toolkit before opening the window. openwindow
  1276.     looks at the window position of the frontmost window, if we don't fix the globals
  1277.     it'll crash when it tries to get the window position of the window we just 
  1278.     closed.
  1279.     */
  1280.     
  1281.     setfrontglobals (); /*seed new window from frontmost window*/
  1282.  
  1283.     return (openwindow (fname, vnum));
  1284.     } /*revertfrontwindow*/
  1285.     
  1286.     
  1287. boolean settargetglobals (void) {
  1288.     
  1289.     /*
  1290.     get ready to do an operation on the target window.  if the name is empty,
  1291.     we do the operation on the frontmost window.
  1292.     
  1293.     the target window name is set using the 'sett' IAC call.
  1294.     
  1295.     return an error to the script if the target window doesn't exist.
  1296.     */
  1297.     
  1298.     if (stringlength (bstargetwindowname) == 0) { /*no target has been established*/
  1299.         
  1300.         if (!setfrontglobals ()) /*no windows are open*/
  1301.             goto error;
  1302.             
  1303.         return (true);
  1304.         }
  1305.         
  1306.     if (!setapptarget (bstargetwindowname)) 
  1307.         goto error;
  1308.         
  1309.     return (true);
  1310.     
  1311.     error:
  1312.     
  1313.     if (app.easywindowcreate) { /*no window open, try to create one automatically*/
  1314.         
  1315.         if (newuntitledappwindow ())
  1316.             return (true);
  1317.         }
  1318.         
  1319.     return (IACreturnerror (nowindowerror, "\pNo window is open."));
  1320.     } /*settargetglobals*/
  1321.     
  1322.     
  1323. boolean exitmainloop (void) {
  1324.     
  1325.     flexitmainloop = closeallwindows ();
  1326.     
  1327.     return (true);
  1328.     } /*exitmainloop*/
  1329.  
  1330.  
  1331. static boolean setwindowtitleverb (void) {
  1332.     
  1333.     /*
  1334.     verb that sets the window title of the target window.
  1335.     */
  1336.     
  1337.     bigstring bs;
  1338.     
  1339.     if (!settargetglobals ()) /*this verb requires an open window*/
  1340.         return (false);
  1341.         
  1342.     if (!IACgetstringparam (keyDirectObject, bs))
  1343.         return (false);
  1344.         
  1345.     setappwindowtitle (app.appwindow, bs);
  1346.     
  1347.     copystring (bs, bstargetwindowname);
  1348.         
  1349.     return (IACreturnboolean (true));
  1350.     } /*setwindowtitleverb*/
  1351.     
  1352.     
  1353. static boolean getwindowrectverb (void) { 
  1354.     
  1355.     register hdlappwindow ha = app.appwindow;
  1356.     Rect r = (**app.appwindow).contentrect;
  1357.     
  1358.     OffsetRect (&r, (**ha).scrollorigin.h, (**ha).scrollorigin.v);
  1359.     
  1360.     return (IACreturnrect (&r));
  1361.     } /*getwindowrectverb*/
  1362.     
  1363.     
  1364. static boolean closewindowverb (void) {
  1365.     
  1366.     /*
  1367.     verb that closes an existing window.  it takes no parameters, the
  1368.     current target window is closed.
  1369.     */
  1370.     
  1371.     register boolean fl = false;
  1372.     register hdlappwindow ha;
  1373.     
  1374.     if (!settargetglobals ()) /*this verb requires an open window*/
  1375.         return (false);
  1376.     
  1377.     ha = app.appwindow;
  1378.     
  1379.     if (ha != nil) { /*a window is open*/
  1380.     
  1381.         fl = closewindow (ha, fldialogsenabled);
  1382.         }
  1383.         
  1384.     return (IACreturnboolean (fl));
  1385.     } /*closewindowverb*/
  1386.     
  1387.     
  1388. static boolean revertverb (void) {
  1389.     
  1390.     if (!settargetglobals ()) /*this verb requires an open window*/
  1391.         return (false);
  1392.         
  1393.     return (IACreturnboolean (revertfrontwindow ()));
  1394.     } /*revertverb*/
  1395.     
  1396.     
  1397. static boolean saveasverb (void) {
  1398.     
  1399.     register boolean fl = false;
  1400.     bigstring path;
  1401.     bigstring fname;
  1402.     short vnum;
  1403.     
  1404.     if (!settargetglobals ()) /*this verb requires an open window*/
  1405.         return (false);
  1406.         
  1407.     if (!IACgetstringparam (keyDirectObject, path))
  1408.         return (false);
  1409.         
  1410.     if (stringlength (path) == 0) {
  1411.     
  1412.         fl = savefrontwindow ();
  1413.         }
  1414.     else {
  1415.         if (pathtofileinfo (path, fname, &vnum))
  1416.             fl = saveaswindow (fname, vnum);
  1417.         }
  1418.         
  1419.     return (IACreturnboolean (fl));
  1420.     } /*saveasverb*/
  1421.     
  1422.     
  1423. static boolean openverb (void) {
  1424.     
  1425.     register boolean fl = false;
  1426.     bigstring path;
  1427.     bigstring fname;
  1428.     short vnum;
  1429.     
  1430.     setstringlength (bserrorstring, 0);
  1431.     
  1432.     if (!IACgetstringparam (keyDirectObject, path))
  1433.         return (false);
  1434.     
  1435.     if (!pathtofileinfo (path, fname, &vnum))
  1436.         appalert ("\pError opening the file.");
  1437.     else
  1438.         fl = openwindow (fname, vnum);
  1439.         
  1440.     return (IACreturnboolean (fl));
  1441.     } /*openverb*/
  1442.     
  1443.     
  1444. static boolean nthwindowverb (void) {
  1445.     
  1446.     bigstring bs;
  1447.     short n;
  1448.     hdlappwindow appwindow;
  1449.     
  1450.     if (!IACgetshortparam (keyDirectObject, &n))
  1451.         return (false);
  1452.         
  1453.     findnthwindow (n, &appwindow);
  1454.     
  1455.     getappwindowtitle (appwindow, bs);
  1456.     
  1457.     return (IACreturnstring (bs));
  1458.     } /*nthwindowverb*/
  1459.     
  1460.     
  1461. static boolean selectwindowverb (void) {
  1462.     
  1463.     /*
  1464.     verb that brings a window to the front, you provide the name of the window in 
  1465.     a string parameter.  side effect -- it also sets the target to that window.
  1466.     */
  1467.     
  1468.     register boolean fl = false;
  1469.     bigstring bs;
  1470.     
  1471.     if (!IACgetstringparam (keyDirectObject, bs))
  1472.         return (false);
  1473.         
  1474.     if (selectwindowbytitle (bs)) {
  1475.         
  1476.         fl = true;
  1477.         
  1478.         copystring (bs, bstargetwindowname);
  1479.         }
  1480.         
  1481.     return (IACreturnboolean (fl));
  1482.     } /*selectwindowverb*/
  1483.     
  1484.     
  1485. static boolean perftestverb (void) {
  1486.     
  1487.     /*
  1488.     this verb supports a performance benchmark script written in Frontier.
  1489.     
  1490.     6/28/91 DW: perform rectangle subtraction on two rectangle params,
  1491.     return the difference.
  1492.     */
  1493.     
  1494.     Rect r1, r2, r;
  1495.     
  1496.     if (!IACgetrectparam ('prm1', &r1))
  1497.         return (false);
  1498.         
  1499.     if (!IACgetrectparam ('prm2', &r2))
  1500.         return (false);
  1501.         
  1502.     r.top = r1.top - r2.top;
  1503.     
  1504.     r.left = r1.left - r2.left;
  1505.     
  1506.     r.bottom = r1.bottom - r2.bottom;
  1507.     
  1508.     r.right = r1.right - r2.right;
  1509.     
  1510.     return (IACreturnrect (&r));
  1511.     } /*perftestverb*/
  1512.  
  1513.  
  1514. static boolean alertdialogverb (void) {
  1515.     
  1516.     /*
  1517.     opens up a modal dialog box with the string parameter displayed, wait for
  1518.     the user to click on OK before returning the value.    
  1519.  
  1520.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  1521.     script writers to be able to transparently talk to the user without Frontier 
  1522.     coming to the front.
  1523.     */
  1524.     
  1525.     bigstring bs;
  1526.     
  1527.     if (!IACgetstringparam (keyDirectObject, bs))
  1528.         return (false);
  1529.         
  1530.     return (IACreturnboolean (alertdialog (bs)));
  1531.     } /*alertdialogverb*/
  1532.     
  1533.     
  1534. static boolean confirmdialogverb (void) {
  1535.     
  1536.     /*
  1537.     opens up a modal dialog box with the string parameter displayed, wait for
  1538.     the user to click on OK before returning the value.    
  1539.  
  1540.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  1541.     script writers to be able to transparently talk to the user without Frontier 
  1542.     coming to the front.
  1543.     */
  1544.     
  1545.     bigstring bs;
  1546.     
  1547.     if (!IACgetstringparam (keyDirectObject, bs))
  1548.         return (false);
  1549.         
  1550.     return (IACreturnboolean (msgdialog (bs)));
  1551.     } /*confirmdialogverb*/
  1552.     
  1553.     
  1554. static boolean askdialogverb (void) {
  1555.     
  1556.     /*
  1557.     to support runtime menus, you wire your dialog boxes to IAC events if you want 
  1558.     script writers to be able to transparently talk to the user without Frontier 
  1559.     coming to the front.
  1560.     */
  1561.     
  1562.     bigstring prompt, answer;
  1563.     boolean fl;
  1564.     
  1565.     if (!IACgetstringparam (keyDirectObject, prompt))
  1566.         return (false);
  1567.         
  1568.     if (!IACgetstringparam ('dflt', answer))
  1569.         return (false);
  1570.         
  1571.     fl = askdialog (prompt, answer);
  1572.         
  1573.     IACglobals.event = IACglobals.reply; /*push the params onto the reply record*/
  1574.     
  1575.     if (!IACpushstringparam (answer, 'ansr'))
  1576.         return (false);
  1577.         
  1578.     return (IACpushbooleanparam (fl, 'ohky'));
  1579.     } /*askdialogverb*/
  1580.  
  1581.     
  1582. static boolean settargetverb (void) {
  1583.     
  1584.     /*
  1585.     set the target of all subsequent verbs to the window named by the string
  1586.     parameter.  
  1587.     
  1588.     special case: set the target string to the empty string if you want verbs 
  1589.     to apply to the frontmost window.
  1590.     
  1591.     returns the title of the target window.
  1592.     */
  1593.     
  1594.     register boolean fl = true;
  1595.     bigstring bs;
  1596.     
  1597.     if (!IACgetstringparam (keyDirectObject, bs))
  1598.         return (false);
  1599.     
  1600.     if (stringlength (bs) == 0) { /*special case*/
  1601.     
  1602.         if (setfrontglobals ())
  1603.             getappwindowtitle (app.appwindow, bs);
  1604.         }
  1605.         
  1606.     else {
  1607.         if (!setapptarget (bs)) 
  1608.             setstringlength (bs, 0);
  1609.         }
  1610.     
  1611.     copystring (bs, bstargetwindowname);
  1612.     
  1613.     return (IACreturnstring (bs));
  1614.     } /*settargetverb*/
  1615.  
  1616.  
  1617. static boolean gettargetverb (void) {
  1618.     
  1619.     /*
  1620.     returns the title of the target window.
  1621.     */
  1622.     
  1623.     bigstring bs;
  1624.     
  1625.     if (!settargetglobals ()) /*this verb requires an open window*/
  1626.         return (false);
  1627.         
  1628.     getappwindowtitle (app.appwindow, bs);
  1629.         
  1630.     return (IACreturnstring (bs));
  1631.     } /*gettargetverb*/
  1632.     
  1633.  
  1634. static boolean newwindowverb (void) {
  1635.     
  1636.     register boolean fl = false;
  1637.     hdlappwindow appwindow;
  1638.     bigstring bs;
  1639.     long ctbars;
  1640.     
  1641.     setstringlength (bserrorstring, 0);
  1642.     
  1643.     if (!IACgetstringparam (keyDirectObject, bs))
  1644.         return (false);
  1645.         
  1646.     if (stringlength (bs) == 0)
  1647.         getuntitledtitle (bs);
  1648.         
  1649.     if (findbywindowtitle (bs, &appwindow)) {
  1650.         
  1651.         appalert ("\pA window with that name is already open.");
  1652.         
  1653.         setstringlength (bs, 0); /*return the empty string to indicate error*/
  1654.         }
  1655.     else {
  1656.         if (newappwindow (bs, true)) {
  1657.             
  1658.             fl = true;
  1659.             
  1660.             copystring (bs, bstargetwindowname);
  1661.             }
  1662.         }
  1663.         
  1664.     return (IACreturnstring (bs));
  1665.     } /*newwindowverb*/
  1666.     
  1667.     
  1668. static boolean madechangesverb (void) {
  1669.  
  1670.     if (!settargetglobals ()) /*this verb requires an open window*/
  1671.         return (false);
  1672.         
  1673.     IACreturnboolean ((**app.appwindow).flmadechanges);
  1674.     } /*madechangesverb*/
  1675.  
  1676.  
  1677. static boolean countwindowsverb (void) {
  1678.  
  1679.     return (IACreturnshort (countwindows ()));
  1680.     } /*countwindowsverb*/
  1681.  
  1682.  
  1683. static boolean selectallverb (void) {
  1684.     
  1685.     register boolean fl;
  1686.     
  1687.     if (!settargetglobals ()) /*this verb requires an open window*/
  1688.         return (false);
  1689.         
  1690.     fl = (*app.selectallcallback) ();
  1691.     
  1692.     return (IACreturnboolean (fl));
  1693.     } /*selectallverb*/
  1694.  
  1695.  
  1696. static boolean haveselectionverb (void) {
  1697.     
  1698.     register boolean fl;
  1699.     
  1700.     if (!settargetglobals ()) /*this verb requires an open window*/
  1701.         return (false);
  1702.         
  1703.     fl = (*app.haveselectioncallback) ();
  1704.     
  1705.     return (IACreturnboolean (fl));
  1706.     } /*haveselectionverb*/
  1707.  
  1708.  
  1709. static boolean printwindowverb (void) {
  1710.  
  1711.     if (!settargetglobals ()) /*this verb requires an open window*/
  1712.         return (false);
  1713.         
  1714.     return (IACreturnboolean (printappwindow (app.appwindow, false)));
  1715.     } /*printwindowverb*/
  1716.  
  1717.  
  1718. static boolean enablealertverb (void) {
  1719.     
  1720.     register boolean fl;
  1721.     Boolean flenabled;
  1722.     
  1723.     if (!IACgetbooleanparam (keyDirectObject, &flenabled))
  1724.         return (false);
  1725.         
  1726.     fl = fldialogsenabled; /*return the original value, per spec*/
  1727.     
  1728.     fldialogsenabled = flenabled;
  1729.     
  1730.     return (IACreturnboolean (fl));
  1731.     } /*enablealertverb*/
  1732.  
  1733.  
  1734. static boolean quitverb (void) {
  1735.     
  1736.     return (IACreturnboolean (exitmainloop ()));
  1737.     } /*quitverb*/
  1738.  
  1739.  
  1740. static boolean geterrorstringverb (void) {
  1741.     
  1742.     return (IACreturnstring (bserrorstring));
  1743.     } /*geterrorstringverb*/
  1744.     
  1745.     
  1746. static void adjustaftergrow (WindowPtr w) {
  1747.     
  1748.     hdlappwindow appwindow;
  1749.     register hdlappwindow ha;
  1750.  
  1751.     getwindowrefcon (w, (long *) &appwindow);
  1752.     
  1753.     ha = appwindow;
  1754.     
  1755.     setappwindow (ha);
  1756.     
  1757.     computewindowinfo (w, ha);
  1758.     
  1759.     (*app.windowresizecallback) ();
  1760.     
  1761.     resizeappscrollbars (ha);
  1762.     
  1763.     resetappscrollbars (ha);
  1764.     
  1765.     invalappwindow (ha, true);
  1766.     
  1767.     (**ha).flmadechanges = true; /*we save window size and position*/
  1768.     } /*adjustaftergrow*/
  1769.  
  1770.  
  1771. static boolean movewindowverb (void) {
  1772.     
  1773.     Rect r;
  1774.     
  1775.     if (!settargetglobals ()) /*this verb requires an open window*/
  1776.         return (false);
  1777.         
  1778.     if (!IACgetrectparam (keyDirectObject, &r))
  1779.         return (false);
  1780.     
  1781.     moveappwindow (app.appwindow, r);
  1782.     
  1783.     adjustaftergrow ((**app.appwindow).macwindow); /*inelegant*/
  1784.         
  1785.     return (IACreturnboolean (true));
  1786.     } /*movewindowverb*/
  1787.     
  1788.     
  1789. static boolean getfilepathverb (void) {
  1790.     
  1791.     register hdlappwindow ha;
  1792.     bigstring path;
  1793.     
  1794.     if (!settargetglobals ()) /*this verb requires an open window*/
  1795.         return (false);
  1796.     
  1797.     ha = app.appwindow;
  1798.     
  1799.     if ((**ha).fnum == 0) /*no file open*/
  1800.         setemptystring (path);
  1801.     else
  1802.         fileinfotopath ((**ha).fname, (**ha).vnum, path);
  1803.     
  1804.     return (IACreturnstring (path));
  1805.     } /*getfilepathverb*/
  1806.     
  1807.     
  1808. static boolean getpictverb (void) {
  1809.  
  1810.     Handle hpict;
  1811.  
  1812.     if (!settargetglobals ()) /*this verb requires an open window*/
  1813.         return (false);
  1814.         
  1815.     if (app.getpictcallback == nil) /*application doesn't support this feature*/
  1816.         return (IACreturnerror (nopictcallbackerror, "\pCan't export a picture."));
  1817.         
  1818.     (*app.getpictcallback) (&hpict); /*hpict is nil if it failed*/
  1819.     
  1820.     return (IACreturnbinary (hpict));
  1821.     } /*getpictverb*/
  1822.  
  1823.  
  1824. static boolean gettextverb (void) {
  1825.  
  1826.     Handle htext;
  1827.  
  1828.     if (!settargetglobals ()) /*this verb requires an open window*/
  1829.         return (false);
  1830.         
  1831.     if (app.gettextcallback == nil) /*application doesn't support this feature*/
  1832.         return (IACreturnerror (notextcallbackerror, "\pCan't export text."));
  1833.         
  1834.     (*app.gettextcallback) (&htext); /*htext is nil if it failed*/
  1835.     
  1836.     return (IACreturnbinary (htext));
  1837.     } /*gettextverb*/
  1838.  
  1839.  
  1840. static boolean putpictverb (void) {
  1841.  
  1842.     Handle hpict;
  1843.     register boolean fl;
  1844.  
  1845.     if (!settargetglobals ()) /*this verb requires an open window*/
  1846.         return (false);
  1847.         
  1848.     if (app.putpictcallback == nil) /*application doesn't support this feature*/
  1849.         return (IACreturnerror (noputpictcallbackerror, "\pCan't import the picture."));
  1850.         
  1851.     if (!IACgetbinaryparam (keyDirectObject, &hpict))
  1852.         return (false);
  1853.         
  1854.     fl = (*app.putpictcallback) (hpict); /*hpict is nil if it failed*/
  1855.     
  1856.     return (IACreturnboolean (fl));
  1857.     } /*putpictverb*/
  1858.  
  1859.  
  1860. static boolean puttextverb (void) {
  1861.  
  1862.     Handle htext;
  1863.     register boolean fl;
  1864.  
  1865.     if (!settargetglobals ()) /*this verb requires an open window*/
  1866.         return (false);
  1867.         
  1868.     if (app.puttextcallback == nil) /*application doesn't support this feature*/
  1869.         return (IACreturnerror (noputtextcallbackerror, "\pCan't import the text."));
  1870.         
  1871.     if (!IACgettextparam (keyDirectObject, &htext))
  1872.         return (false);
  1873.         
  1874.     fl = (*app.puttextcallback) (htext); /*htext is nil if it failed*/
  1875.     
  1876.     return (IACreturnboolean (fl));
  1877.     } /*puttextverb*/
  1878.  
  1879.  
  1880. static boolean getpagerectverb (void) {
  1881.     
  1882.     return (IACreturnrect (&app.printinfo.paperrect));
  1883.     } /*getpagerectverb*/
  1884.     
  1885.  
  1886. static boolean getwindowposverb (void) {
  1887.     
  1888.     Rect r;
  1889.     
  1890.     if (!settargetglobals ()) /*this verb requires an open window*/
  1891.         return (false);
  1892.         
  1893.     r = (**app.appwindow).windowrect;
  1894.     
  1895.     localtoglobalrect (&r);
  1896.         
  1897.     return (IACreturnrect (&r));
  1898.     } /*getwindowposverb*/
  1899.     
  1900.     
  1901. static pascal OSErr handlecustomverb (AppleEvent *event, AppleEvent *reply, long refcon) {
  1902.  
  1903.     if (SharedScriptCancelled (event, reply)) 
  1904.         return (noErr);
  1905.         
  1906.     IACglobals.event = event; 
  1907.     
  1908.     IACglobals.reply = reply;
  1909.     
  1910.     IACglobals.refcon = refcon;
  1911.         
  1912.     return ((*app.iacmessagecallback) ());
  1913.     } /*handlecustomverb*/
  1914.     
  1915.     
  1916. static pascal OSErr handleapp1verb (AppleEvent *event, AppleEvent *reply, long refcon) {
  1917.     
  1918.     /*
  1919.     called by Apple Event Manager when an 'app1' verb arrives.
  1920.     
  1921.     we always return noErr to the Apple Event Manager -- each verb processor
  1922.     may set the error number and string in the reply record by calling 
  1923.     IACreturnerror.
  1924.     */
  1925.     
  1926.     if (SharedScriptCancelled (event, reply)) 
  1927.         return (noErr);
  1928.         
  1929.     IACglobals.event = event; 
  1930.     
  1931.     IACglobals.reply = reply;
  1932.     
  1933.     IACglobals.refcon = refcon;
  1934.         
  1935.     switch (IACgetverbtoken ()) {
  1936.     
  1937.         case newwindowtoken:
  1938.             newwindowverb (); break;
  1939.             
  1940.         case closewindowtoken:
  1941.             closewindowverb (); break;
  1942.         
  1943.         case savewindowtoken:
  1944.             saveasverb (); break;
  1945.             
  1946.         case revertwindowtoken:
  1947.             revertverb (); break;
  1948.             
  1949.         case openwindowtoken:
  1950.             openverb (); break;
  1951.             
  1952.         case gettargettoken:
  1953.             gettargetverb (); break;
  1954.                 
  1955.         case selectwindowtoken:
  1956.             selectwindowverb (); break;
  1957.             
  1958.         case perftesttoken:
  1959.             perftestverb (); break;
  1960.             
  1961.         case alertdialogtoken:
  1962.             alertdialogverb (); break;
  1963.             
  1964.         case askdialogtoken:
  1965.             askdialogverb (); break;
  1966.             
  1967.         case confirmdialogtoken:
  1968.             confirmdialogverb (); break;
  1969.             
  1970.         case settargettoken:
  1971.             settargetverb (); break;
  1972.             
  1973.         case madechangestoken:
  1974.             madechangesverb (); break;
  1975.             
  1976.         case enabledialogtoken:
  1977.             enablealertverb (); break;
  1978.             
  1979.         case geterrorstringtoken:
  1980.             geterrorstringverb (); break;
  1981.             
  1982.         case nthwindowtoken:
  1983.             nthwindowverb (); break;
  1984.             
  1985.         case getfilepathtoken:
  1986.             getfilepathverb (); break;
  1987.             
  1988.         case movewindowtoken:
  1989.             movewindowverb (); break;
  1990.             
  1991.         case printwindowtoken:
  1992.             printwindowverb (); break;
  1993.             
  1994.         case getpagerecttoken:
  1995.             getpagerectverb (); break;
  1996.             
  1997.         case quittoken:
  1998.             quitverb (); break;
  1999.             
  2000.         case getwindowpostoken:
  2001.             getwindowposverb (); break;
  2002.             
  2003.         case countwindowstoken:
  2004.             countwindowsverb (); break;    
  2005.     
  2006.         case getpicttoken:
  2007.             getpictverb (); break;
  2008.         
  2009.         case gettexttoken:
  2010.             gettextverb (); break;
  2011.             
  2012.         case putpicttoken:
  2013.             putpictverb (); break;
  2014.             
  2015.         case puttexttoken:
  2016.             puttextverb (); break;
  2017.             
  2018.         case selectalltoken:
  2019.             selectallverb (); break;
  2020.             
  2021.         case haveselectiontoken:
  2022.             haveselectionverb (); break;
  2023.             
  2024.         case getwindowrecttoken:
  2025.             getwindowrectverb (); break;
  2026.             
  2027.         default:
  2028.             IACnothandlederror (); break;
  2029.         } /*switch*/
  2030.         
  2031.     return (noErr);
  2032.     } /*handleapp1verb*/
  2033.     
  2034.  
  2035. static void handleupdate (EventRecord ev) {
  2036.     
  2037.     register WindowPtr w = (WindowPtr) ev.message;
  2038.     hdlappwindow appwindow;
  2039.     
  2040.     getwindowrefcon (w, (long *) &appwindow);
  2041.     
  2042.     updateappwindow (appwindow);
  2043.     } /*handleupdate*/
  2044.     
  2045.  
  2046. static void handleactivate (EventRecord ev) {
  2047.  
  2048.     register WindowPtr w = (WindowPtr) ev.message;
  2049.     register boolean flactivate = ev.modifiers & activeFlag;
  2050.     hdlappwindow appwindow;
  2051.         
  2052.     getwindowrefcon (w, (long *) &appwindow);
  2053.     
  2054.     setappwindow (appwindow);
  2055.     
  2056.     activateappscrollbars (appwindow, flactivate);
  2057.     
  2058.     (*app.activatecallback) (flactivate);
  2059.     } /*handleactivate*/
  2060.     
  2061.     
  2062. static void handledrag (EventRecord ev, WindowPtr w) {
  2063.     
  2064.     Rect r;
  2065.  
  2066.     r = quickdrawglobal (screenBits).bounds; 
  2067.    
  2068.     r.top = r.top + getmenubarheight (); 
  2069.                
  2070.     r.left = r.left + dragscreenmargin;  
  2071.                
  2072.     r.right = r.right - dragscreenmargin;
  2073.                
  2074.     r.bottom = r.bottom - dragscreenmargin;
  2075.              
  2076.     DragWindow (w, ev.where, &r);   
  2077.     } /*handledrag*/
  2078.     
  2079.     
  2080. static void handlegrow (Point pt, WindowPtr w) {
  2081.     
  2082.     register long x;
  2083.     Rect boundsrect;
  2084.     Rect r;
  2085.     
  2086.     boundsrect.left = 125;                         /*minimum window width*/
  2087.     
  2088.     boundsrect.top = 100;                         /*minimum window height*/
  2089.     
  2090.     r = quickdrawglobal (screenBits).bounds;
  2091.     
  2092.     boundsrect.right = r.right - r.left;         /*maximum window width*/
  2093.     
  2094.     boundsrect.bottom = r.bottom - r.top;         /*maximum window height*/
  2095.     
  2096.     x = GrowWindow (w, pt, &boundsrect);
  2097.     
  2098.     SizeWindow (w, LoWord (x), HiWord (x), false);
  2099.     
  2100.     adjustaftergrow (w);
  2101.     } /*handlegrow*/
  2102.     
  2103.  
  2104. static void handlezoom (EventRecord ev, WindowPtr w, short part) {
  2105.     
  2106.     pushmacport (w);
  2107.     
  2108.     if (TrackBox (w, ev.where, part)) {
  2109.         
  2110.         eraserect ((*w).portRect);
  2111.         
  2112.         ZoomWindow (w, part, true);
  2113.         
  2114.         adjustaftergrow (w);
  2115.         }
  2116.         
  2117.     popmacport ();
  2118.     } /*handlezoom*/
  2119.     
  2120.     
  2121. static void handlemenu (long codeword) {
  2122.  
  2123.     register short idmenu, iditem;
  2124.     
  2125.     iditem = LoWord (codeword);
  2126.  
  2127.     if (iditem <= 0)     
  2128.         goto exit;
  2129.      
  2130.     idmenu = HiWord (codeword); 
  2131.     
  2132.     if (SharedMenuHit (idmenu, iditem)) 
  2133.         goto exit;
  2134.     
  2135.     switch (idmenu) {
  2136.    
  2137.         case applemenu: 
  2138.             switch (iditem) {
  2139.             
  2140.                 case aboutitem:
  2141.                     aboutcommand ();
  2142.                     
  2143.                     break;
  2144.                     
  2145.                 default: {
  2146.                 
  2147.                     bigstring bs;
  2148.                     
  2149.                     GetItem (hdlapplemenu, iditem, bs);
  2150.           
  2151.                     OpenDeskAcc (bs);
  2152.                     
  2153.                     break;
  2154.                     }
  2155.                 } /*switch*/
  2156.             
  2157.             break; /*apple menu*/
  2158.  
  2159.         case filemenu: 
  2160.             switch (iditem) {
  2161.             
  2162.                 case newitem: {
  2163.                     
  2164.                     newuntitledappwindow ();
  2165.                     
  2166.                     break;
  2167.                     }
  2168.                     
  2169.                 case openitem:
  2170.                     openfrontwindow ();
  2171.                     
  2172.                     break;
  2173.                 
  2174.                 case closeitem:
  2175.                     if (optionkeydown ())
  2176.                         closeallwindows ();
  2177.                     else 
  2178.                         closefrontwindow ();
  2179.                     
  2180.                     break;
  2181.                 
  2182.                 case saveitem: 
  2183.                     savefrontwindow ();
  2184.                     
  2185.                     break;
  2186.                     
  2187.                 case saveasitem:
  2188.                     saveasfrontwindow ();
  2189.                     
  2190.                     break;
  2191.                     
  2192.                 case revertitem:
  2193.                     if ((**app.appwindow).flmadechanges)
  2194.                         if (msgdialog ("\pDiscard changes to the file?"))
  2195.                             revertfrontwindow ();
  2196.                     
  2197.                     break;
  2198.                     
  2199.                 case pagesetupitem: 
  2200.                     pagesetup ();
  2201.                     
  2202.                     break;
  2203.                 
  2204.                 case printitem:
  2205.                     printappwindow (app.appwindow, true);
  2206.                     
  2207.                     break;
  2208.                     
  2209.                 case quititem:
  2210.                     exitmainloop ();
  2211.                     
  2212.                     break;
  2213.                 } /*switch*/
  2214.             
  2215.             break; /*file menu*/
  2216.             
  2217.         } /*switching on which menu was invoked*/
  2218.         
  2219.     exit:
  2220.     
  2221.     HiliteMenu (0);
  2222.     } /*handlemenu*/
  2223.  
  2224.  
  2225. static void handlekeystroke (EventRecord ev) {
  2226.     
  2227.     register char ch = ev.message & charCodeMask;
  2228.     register boolean flcmdkey = ev.modifiers & cmdKey;
  2229.     
  2230.     if (SharedScriptRunning ()) { /*cmd-period terminates the script*/
  2231.     
  2232.         if (flcmdkey && (ch == '.')) { 
  2233.             
  2234.             CancelSharedScript (); /*cancel the shared menu script, if one is running*/
  2235.         
  2236.             return;
  2237.             }
  2238.         }
  2239.     
  2240.     if (flcmdkey) {
  2241.     
  2242.         handlemenu (MenuKey (ch));
  2243.         
  2244.         return;
  2245.         }
  2246.     
  2247.     setkeyboardstatus (ev); 
  2248.     
  2249.     (*app.keystrokecallback) ();
  2250.     } /*handlekeystroke*/
  2251.     
  2252.     
  2253. boolean mousetrack (Rect r, void (*displaycallback) (boolean)) {
  2254.     
  2255.     /*
  2256.     hang out in this routine until the mouse button comes up.  return true if
  2257.     the mouse point is in the indicated rectangle when we return.
  2258.     
  2259.     7/17/90 DW: if the mouse wasn't down when we enter, return true.  this is
  2260.     a heuristic that may allow some mouse-dependent routines to be driven by
  2261.     a script.  we figure that if the mouse isn't down now, it never was down,
  2262.     and whether it's inside any particular rectangle is irrelevent.
  2263.     
  2264.     7/17/90 DW: add callback routine to display the object being tracked as
  2265.     the mouse moves in and out of the rectangle.  set it to nil if you don't
  2266.     need this feature.
  2267.     
  2268.     7/17/90 DW: only call the callback when the state of the object changes,
  2269.     assume display is correct when we're entered.
  2270.     */
  2271.     
  2272.     boolean flinrectnow;
  2273.     boolean flwasinrect;
  2274.     
  2275.     if (!StillDown ()) /*see comment above*/
  2276.         return (true);
  2277.     
  2278.     flwasinrect = true; /*at least for the first iteration of loop*/
  2279.     
  2280.     while (StillDown ()) { /*stay in holding pattern*/
  2281.     
  2282.         Point pt;
  2283.         
  2284.         GetMouse (&pt);
  2285.     
  2286.         flinrectnow = PtInRect (pt, &r);
  2287.         
  2288.         if (flinrectnow != flwasinrect) { /*state of object changed*/
  2289.         
  2290.             if (displaycallback != nil)
  2291.                 (*displaycallback) (flinrectnow);
  2292.             }
  2293.             
  2294.         flwasinrect = flinrectnow;
  2295.         } /*while*/
  2296.     
  2297.     return (flwasinrect);
  2298.     } /*mousetrack*/
  2299.  
  2300.  
  2301. static boolean mousedoubleclick (Point pt) {
  2302.  
  2303.     /*
  2304.     using the globals mouseuptime and mouseuppoint determine if a
  2305.     mouseclick at pt, right now, is a double click.
  2306.     
  2307.     dmb 9/6/90:  pt parameter is no longer used.  superceeded by new 
  2308.     mousedown globals
  2309.     */
  2310.     
  2311.     register boolean fldoubleclick;
  2312.     register short diff;
  2313.     
  2314.     fldoubleclick = (mousestatus.mousedowntime - mousestatus.mouseuptime) < GetDblTime ();
  2315.     
  2316.     if (fldoubleclick) { /*qualifies so far*/
  2317.         
  2318.         diff = pointdist (mousestatus.mousedownpoint, mousestatus.mouseuppoint);
  2319.         
  2320.         fldoubleclick = diff < 5; /*keep it set if mouse hasn't wandered too far*/
  2321.         }
  2322.     
  2323.     if (fldoubleclick) { /*user must doubleclick again to get effect*/
  2324.         
  2325.         mousestatus.mouseuptime = 0L;
  2326.         
  2327.         mousestatus.mouseuppoint.h = mousestatus.mouseuppoint.v = 0;
  2328.         }
  2329.     
  2330.     mousestatus.fldoubleclickdisabled = fldoubleclick; /*copy into global*/
  2331.     
  2332.     return (fldoubleclick);
  2333.     } /*mousedoubleclick*/
  2334.  
  2335.  
  2336. static void handlecontent (EventRecord ev, WindowPtr w) {
  2337.     
  2338.     register hdlappwindow ha = app.appwindow;
  2339.     Point pt = ev.where;
  2340.     hdlscrollbar scrollbar;
  2341.     short part;
  2342.         
  2343.     globaltolocalpoint (w, &pt);
  2344.  
  2345.     if (findscrollbar (pt, w, &scrollbar, &part)) { 
  2346.         
  2347.         scrollappwindow (scrollbar == (**ha).vertbar, scrollbar, part, pt);
  2348.         
  2349.         return;
  2350.         }
  2351.         
  2352.     /*send mouse hit to the applet*/
  2353.     
  2354.     mousestatus.localpt = pt;
  2355.     
  2356.     mousestatus.fldoubleclick = mousedoubleclick (ev.where);
  2357.     
  2358.     if (PtInRect (pt, &(**ha).contentrect))
  2359.         (*app.mousecallback) ();
  2360.  
  2361.     if (PtInRect (pt, &(**ha).statusrect))
  2362.         (*app.mouseinstatuscallback) ();
  2363.     } /*handlecontent*/
  2364.     
  2365.  
  2366. static void handlemouseup (EventRecord ev) {
  2367.     
  2368.     /*
  2369.     call this when you receive an mouse up event.  if the last mouse down was
  2370.     a double click, we set things up so that the next single click will not
  2371.     be interpreted as a double click.
  2372.     */
  2373.     
  2374.     if (!mousestatus.fldoubleclickdisabled) {
  2375.         
  2376.         mousestatus.mouseuptime = ev.when;
  2377.         
  2378.         mousestatus.mouseuppoint = ev.where;
  2379.         
  2380.         mousestatus.mousedowntime = 0L; /*hasn't happened yet*/
  2381.         }
  2382.     
  2383.     mousestatus.fldoubleclickdisabled = false; /*next mouse up is important*/
  2384.     } /*handlemouseup*/
  2385.  
  2386.  
  2387. static void handlemousedown (EventRecord ev) {
  2388.  
  2389.     short part;
  2390.     WindowPtr w;
  2391.     
  2392.     mousestatus.mousedowntime = ev.when; /*set globals so we can detect a 2click*/
  2393.     
  2394.     mousestatus.mousedownpoint = ev.where;
  2395.     
  2396.       part = FindWindow (ev.where, &w);
  2397.     
  2398.     if (w != nil) 
  2399.     
  2400.         if (w != FrontWindow ()) { /*just like all other Mac programs*/
  2401.             
  2402.             SelectWindow (w);
  2403.                             
  2404.             return; /*the mouse click is consumed by the bringtofront operation*/
  2405.             }
  2406.     
  2407.     switch (part) {
  2408.     
  2409.         case inMenuBar: 
  2410.             handlemenu (MenuSelect (ev.where)); 
  2411.             
  2412.             break;
  2413.         
  2414.         case inContent:
  2415.             handlecontent (ev, w);
  2416.             
  2417.             break;
  2418.         
  2419.         case inSysWindow:
  2420.             SystemClick (&ev, w); 
  2421.             
  2422.             break;
  2423.         
  2424.         case inDrag:
  2425.             handledrag (ev, w);
  2426.             
  2427.             break;
  2428.             
  2429.         case inGrow:
  2430.             handlegrow (ev.where, w);
  2431.             
  2432.             break;
  2433.             
  2434.         case inGoAway:
  2435.             if (TrackGoAway (w, ev.where)) {
  2436.             
  2437.                 if (optionkeydown ())
  2438.                     closeallwindows ();
  2439.                 else
  2440.                     closefrontwindow ();
  2441.                 }
  2442.                 
  2443.             break;
  2444.         
  2445.         case inZoomOut: case inZoomIn:
  2446.             handlezoom (ev, w, part);
  2447.             
  2448.             break;
  2449.           
  2450.         } /*switch*/
  2451.     } /*handlemousedown*/
  2452.     
  2453.     
  2454. static boolean jugglervisit (hdlappwindow appwindow) {
  2455.     
  2456.     register hdlappwindow ha = appwindow;
  2457.     register boolean fl = x1 && ((**ha).macwindow == FrontWindow ());
  2458.     
  2459.     setappwindow (ha);
  2460.     
  2461.     activateappscrollbars (ha, fl);
  2462.     
  2463.     (*app.activatecallback) (fl);
  2464.     
  2465.     drawappgrowicon (ha);
  2466.     } /*jugglervisit*/
  2467.     
  2468.     
  2469. static void handlejuggler (EventRecord ev) {
  2470.     
  2471.     register boolean flresume;
  2472.     tyjugglermessage jmsg;
  2473.     
  2474.     moveleft (&ev.message, &jmsg, longsizeof (jmsg));
  2475.     
  2476.     if (jmsg.eventtype == 1) { /*suspend or resume subevent*/
  2477.         
  2478.         flresume = jmsg.flresume; /*copy into register*/
  2479.         
  2480.         if (jmsg.flconvertclipboard) { /*11/3/91 DW: get to this later*/
  2481.             }
  2482.         
  2483.         x1 = flresume; /*set global for visit routine*/
  2484.         
  2485.         visitappwindows (&jugglervisit); /*send message to all open windows*/
  2486.         }
  2487.     } /*handlejuggler*/
  2488.     
  2489.  
  2490. static void handleevent (EventRecord ev) {
  2491.     
  2492.     switch (ev.what) {
  2493.     
  2494.         case keyDown: case autoKey: 
  2495.             handlekeystroke (ev);
  2496.             
  2497.             break;
  2498.             
  2499.         case mouseDown:
  2500.             handlemousedown (ev);
  2501.            
  2502.             break;
  2503.             
  2504.         case mouseUp:
  2505.             handlemouseup (ev);
  2506.             
  2507.             break;
  2508.            
  2509.         case activateEvt:
  2510.             handleactivate (ev); 
  2511.            
  2512.             break;
  2513.         
  2514.         case jugglerEvt:
  2515.             handlejuggler (ev);
  2516.             
  2517.             break;
  2518.  
  2519.         case updateEvt:
  2520.             handleupdate (ev);
  2521.            
  2522.             break;
  2523.             
  2524.         case nullEvent:
  2525.             resetdirtyscrollbars ();
  2526.             
  2527.             break;
  2528.             
  2529.         case kHighLevelEvent:
  2530.             AEProcessAppleEvent (&ev);
  2531.             
  2532.             break;
  2533.         } /*switch*/
  2534.     } /*handleevent*/
  2535.     
  2536.     
  2537. void adjustmenus (void) {
  2538.     
  2539.     register boolean flchanges = false;
  2540.     register hdlappwindow ha = app.appwindow;
  2541.     register boolean flwindow = ha != nil;
  2542.     register MenuHandle hmenu = hdlfilemenu;
  2543.     register boolean flsavable = !app.notsaveable;
  2544.     
  2545.     if (flwindow)
  2546.         flchanges = (**ha).flmadechanges;
  2547.         
  2548.     setmenuitemenable (hmenu, newitem, flsavable);
  2549.     
  2550.     setmenuitemenable (hmenu, openitem, flsavable);
  2551.     
  2552.     setmenuitemenable (hmenu, closeitem, flwindow);
  2553.     
  2554.     setmenuitemenable (hmenu, saveitem, flchanges && flsavable);
  2555.     
  2556.     setmenuitemenable (hmenu, saveasitem, flwindow && flsavable);
  2557.     
  2558.     setmenuitemenable (hmenu, revertitem, flchanges && flsavable && ((**ha).fnum != 0));
  2559.     
  2560.     enablemenuitem (hmenu, pagesetupitem);
  2561.     
  2562.     setmenuitemenable (hmenu, printitem, flwindow);
  2563.     
  2564.     enablemenuitem (hmenu, quititem);
  2565.     } /*adjustmenus*/
  2566.  
  2567.  
  2568. boolean maineventhandler (ev) EventRecord ev; {
  2569.     
  2570.     /*
  2571.     if you have an event, and have determined that it's not for you, pass it
  2572.     thru this routine for processing. 
  2573.     
  2574.     we check to see if our Frontier-supplied menus need to be re-installed.  
  2575.     this can happen if a script-writer is making editing changes over in Frontier.  
  2576.     by waiting for real events, we eliminate very annoying delays when editing 
  2577.     in Frontier.
  2578.     
  2579.     returns false if you should break out of your loop, true if you should
  2580.     keep looping.
  2581.     */
  2582.     
  2583.     CheckSharedMenus (firstsharedmenu); 
  2584.         
  2585.     setfrontglobals (); /*event applies to frontmost window*/
  2586.         
  2587.     (*app.adjustcursorcallback) ();
  2588.     
  2589.     adjustmenus ();
  2590.     
  2591.     handleevent (ev); /*might set flexitmainloop true*/
  2592.     
  2593.     return (!flexitmainloop);
  2594.     } /*maineventhandler*/
  2595.  
  2596.  
  2597. void maineventloop (void) {
  2598.     
  2599.     EventRecord ev;
  2600.     
  2601.     while (!flexitmainloop) {
  2602.         
  2603.         WaitNextEvent (everyEvent, &ev, 1, nil);
  2604.         
  2605.         maineventhandler (ev);
  2606.         } /*while*/
  2607.     } /*maineventloop*/
  2608.  
  2609.  
  2610. boolean serviceeventqueue (void) {
  2611.     
  2612.     /*
  2613.     pop and process all waiting events, return true when we get to a null 
  2614.     event. return false if the user selected the quit command, or otherwise
  2615.     wants the program to terminate.
  2616.     */
  2617.     
  2618.     EventRecord ev;
  2619.     
  2620.     while (!flexitmainloop) {
  2621.         
  2622.         WaitNextEvent (everyEvent, &ev, 1, nil);
  2623.         
  2624.         if (ev.what == nullEvent) /*got all the meaningful events*/
  2625.             return (true);
  2626.         
  2627.         maineventhandler (ev);
  2628.         } /*while*/
  2629.         
  2630.     return (false); /*user must have selected the quit command*/
  2631.     } /*serviceeventqueue*/
  2632.  
  2633.  
  2634. static pascal Boolean openfilespec (fs) FSSpec *fs; {
  2635.  
  2636.     bigstring bs;
  2637.     
  2638.     if (!directorytopath ((*fs).parID, (*fs).vRefNum, bs)) 
  2639.         return (false);
  2640.         
  2641.     pushstring ((*fs).name, bs);
  2642.  
  2643.     if (!openwindow (bs, 0)) {
  2644.         
  2645.         IACreturnerror (-1, bserrorstring);
  2646.         
  2647.         return (false);
  2648.         }
  2649.         
  2650.     return (true);
  2651.     } /*openfilespec*/
  2652.     
  2653.  
  2654. static pascal OSErr handleopen (AppleEvent *event, AppleEvent *reply, long refcon) {
  2655.     
  2656.     IACglobals.event = event;
  2657.     
  2658.     IACglobals.reply = reply;
  2659.     
  2660.     IACglobals.refcon = refcon;
  2661.     
  2662.     return (IACdrivefilelist (&openfilespec));
  2663.     } /*handleopen*/
  2664.     
  2665.         
  2666. static pascal Boolean printfilespec (fs) FSSpec *fs; {
  2667.  
  2668.     hdlappwindow appwindow;
  2669.     bigstring fullpath;
  2670.     bigstring fname;
  2671.     short vnum;
  2672.     
  2673.     if (!directorytopath ((*fs).parID, (*fs).vRefNum, fullpath)) 
  2674.         return (false);
  2675.         
  2676.     pushstring ((*fs).name, fullpath);
  2677.  
  2678.     if (!pathtofileinfo (fullpath, fname, &vnum))
  2679.         return (false);
  2680.     
  2681.     if (findbyfile (fname, vnum, &appwindow)) 
  2682.         selectappwindow (appwindow);
  2683.  
  2684.     else {    
  2685.         if (!openwindow (fullpath, 0)) {
  2686.             
  2687.             IACreturnerror (-1, bserrorstring);
  2688.             
  2689.             return (false);
  2690.             }
  2691.         }
  2692.  
  2693.     setfrontglobals (); /*event applies to frontmost window*/
  2694.     
  2695.     return (printappwindow (app.appwindow, false));
  2696.     } /*printfilespec*/
  2697.     
  2698.  
  2699. static pascal OSErr handleprint (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  2700.     
  2701.     IACglobals.event = event;
  2702.     
  2703.     IACglobals.reply = reply;
  2704.     
  2705.     IACglobals.refcon = refcon;
  2706.     
  2707.     return (IACdrivefilelist (&printfilespec));
  2708.     } /*handleprint*/
  2709.     
  2710.         
  2711. static pascal OSErr handlequit (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  2712.     
  2713.     exitmainloop ();
  2714.     
  2715.     return (noErr);
  2716.     } /*handlequit*/
  2717.     
  2718.     
  2719. static pascal OSErr handleopenapp (event, reply, refcon) AEDescList *event, *reply; long refcon; {
  2720.     
  2721.     return (noErr);
  2722.     } /*handleopenapp*/
  2723.     
  2724.     
  2725. static pascal Boolean handlescriptcomplete (void) {
  2726.     
  2727.     resetdirtyscrollbars ();
  2728.     
  2729.     return (true);
  2730.     } /*handlescriptcomplete*/
  2731.     
  2732.  
  2733. static boolean initIAC (void) {
  2734.     
  2735.     setstringlength (bstargetwindowname, 0); /*no target window initially*/
  2736.     
  2737.     if (!InitSharedMenus ()) /*initialize the menusharing routines*/
  2738.         return (false);
  2739.         
  2740.     MSglobals.scriptcompletedcallback = (tyMScallback) &handlescriptcomplete;
  2741.         
  2742.     if (!IACinstallhandler (app1class, typeWildCard, (ProcPtr) &handleapp1verb))
  2743.         return (false);
  2744.  
  2745.     if (!IACinstallhandler (app.creator, typeWildCard, (ProcPtr) &handlecustomverb))
  2746.         return (false);
  2747.  
  2748.     if (!IACinstallhandler (kCoreEventClass, kAEOpenApplication, (ProcPtr) &handleopenapp))
  2749.         return (false);
  2750.     
  2751.     if (!IACinstallhandler (kCoreEventClass, kAEOpenDocuments, (ProcPtr) &handleopen))
  2752.         return (false);
  2753.     
  2754.     if (!IACinstallhandler (kCoreEventClass, kAEPrintDocuments, (ProcPtr) &handleprint))
  2755.         return (false);
  2756.     
  2757.     if (!IACinstallhandler (kCoreEventClass, kAEQuitApplication, (ProcPtr) &handlequit))
  2758.         return (false);
  2759.  
  2760.     return (true);
  2761.     } /*initIAC*/
  2762.     
  2763.  
  2764. static boolean managersinited = false;
  2765.  
  2766.     
  2767. void appletinitmanagers (void) {
  2768.  
  2769.     initmacintosh ();
  2770.     
  2771.     initmenus ();
  2772.     
  2773.     initbitmaps (true);
  2774.     
  2775.     initprint ();
  2776.     
  2777.     initIAC (); 
  2778.     
  2779.     clearbytes (&mousestatus, longsizeof (mousestatus));
  2780.     
  2781.     managersinited = true;
  2782.     } /*appletinitmanagers*/
  2783.     
  2784.     
  2785. static boolean noopcallback (void) {
  2786.     
  2787.     /*sysbeep;*/
  2788.     
  2789.     return (false);
  2790.     } /*noopcallback*/
  2791.     
  2792.     
  2793. static void checkcallback (tyappcallback *cb) {
  2794.     
  2795.     if (*cb == nil) /*the applet doesn't define this callback*/
  2796.         *cb = &noopcallback;
  2797.     } /*checkcallback*/
  2798.     
  2799.     
  2800. static void checknilcallbacks (void) {
  2801.     
  2802.     installscroll (); /*install the default handler if appropriate*/
  2803.     
  2804.     checkcallback (&app.newrecordcallback); 
  2805.     
  2806.     checkcallback (&app.disposerecordcallback); 
  2807.     
  2808.     checkcallback (&app.adjustcursorcallback); 
  2809.     
  2810.     checkcallback ((tyappcallback *) &app.activatecallback);
  2811.     
  2812.     checkcallback (&app.updatecallback);
  2813.     
  2814.     checkcallback (&app.windowresizecallback);
  2815.     
  2816.     checkcallback (&app.iacmessagecallback);
  2817.     
  2818.     checkcallback ((tyappcallback *) &app.packcallback);
  2819.     
  2820.     checkcallback ((tyappcallback *) &app.unpackcallback);
  2821.     
  2822.     checkcallback ((tyappcallback *) &app.gettextcallback); 
  2823.     
  2824.     checkcallback ((tyappcallback *) &app.getpictcallback); 
  2825.     
  2826.     checkcallback (&app.resetscrollbarscallback); 
  2827.     
  2828.     checkcallback ((tyappcallback *) &app.scrollcallback); 
  2829.     
  2830.     checkcallback (&app.pagesetupcallback);
  2831.     
  2832.     checkcallback (&app.openprintcallback);
  2833.     
  2834.     checkcallback ((tyappcallback *) &app.printpagecallback);
  2835.     
  2836.     checkcallback (&app.closeprintcallback);
  2837.     
  2838.     checkcallback ((tyappcallback *) &app.puttextcallback);
  2839.     
  2840.     checkcallback ((tyappcallback *) &app.putpictcallback);
  2841.     
  2842.     checkcallback (&app.haveselectioncallback);
  2843.     
  2844.     checkcallback (&app.selectallcallback);
  2845.     
  2846.     checkcallback (&app.keystrokecallback);
  2847.     
  2848.     checkcallback (&app.mousecallback);
  2849.     
  2850.     checkcallback (&app.mouseinstatuscallback);
  2851.     
  2852.     checkcallback (&app.updatestatuscallback);
  2853.     } /*checknilcallbacks*/
  2854.     
  2855.     
  2856. void runapplet (void) {
  2857.     
  2858.     if (!managersinited) 
  2859.         appletinitmanagers ();
  2860.         
  2861.     checknilcallbacks ();
  2862.         
  2863.     maineventloop ();
  2864.     } /*runapplet*/
  2865.