shell.c

Go to the documentation of this file.
00001 
00002 /*  $Id: shell.c 1328 2006-04-24 20:02:59Z sethdill $    */
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 #ifdef MACVERSION 
00032 #include <land.h>
00033 #include <SetUpA5.h>
00034 #include "player.h" /*7.0b4 PBS*/
00035 #endif
00036 
00037 #include "frontierconfig.h"
00038 #include "about.h"
00039 #include "bitmaps.h"
00040 #include "cursor.h"
00041 #include "dialogs.h"
00042 #include "error.h"
00043 #include "font.h"
00044 #include "kb.h"
00045 #include "launch.h"
00046 #include "mac.h"
00047 #include "memory.h"
00048 #include "menu.h"
00049 #include "mouse.h"
00050 #include "ops.h"
00051 #include "quickdraw.h"
00052 #include "search.h"
00053 #include "scrap.h"
00054 #include "smallicon.h"
00055 #include "strings.h"
00056 #include "timedate.h"
00057 #include "frontierwindows.h"
00058 #include "zoom.h"
00059 #include "file.h"
00060 #include "resources.h"
00061 #include "shell.h"
00062 #include "shellbuttons.h"
00063 #include "shellmenu.h"
00064 #include "shellhooks.h"
00065 #include "shell.rsrc.h"
00066 #include "shellprint.h"
00067 #include "shellundo.h"
00068 #include "shellprivate.h"
00069 #define __APPLEEVENTS__
00070 #include "lang.h"
00071 #include "langipc.h"
00072 #include "process.h"
00073 #include "kernelverbs.h"
00074 #include "scripts.h"
00075 #include "tablestructure.h"
00076 #include "wpengine.h"
00077 #include "frontierdebug.h" /*6.2b7 AR*/
00078 #include "dockmenu.h"
00079 #include "services.h"
00080 #include "WinSockNetEvents.h"
00081 #include "langdll.h" /*2004-11-29 aradke: for dllinitverbs*/
00082 
00083 #ifdef flcomponent
00084     #include <uisharing.h>
00085     #include "osacomponent.h"
00086 #endif
00087 
00088 #ifdef fliowa
00089     #include "iowaverbs.h" /*3/18/92 dmb*/
00090 #endif
00091 
00092 #ifdef iowaRuntime
00093     #include "iowainit.h"
00094 #endif
00095 
00096 #ifdef WIN95VERSION
00097     #include "FrontierWinMain.h"
00098 
00099     HWND findreplacewindow = NULL;
00100 #endif
00101 
00102 EventRecord shellevent; /*the last event received by the shell*/
00103 
00104 WindowPtr shellwindow = nil; /*the window whose globals are currently loaded*/
00105 
00106 hdlwindowinfo shellwindowinfo = nil; /*the windowinfo record for the globals*/
00107 
00108 //changed this to nil to prevent the idler routine from firing
00109 //until they are installed.
00110 tyshellglobals shellglobals; /*holds the globals, callback pointers, everything*/
00111 
00112 
00113 static boolean flexitmaineventloop = false;
00114 
00115 static boolean flshellimmediatebackground = false; /*service the background queue immediately*/
00116 
00117 static unsigned long timelastevent = 0; /*the timestamp, last event received*/
00118 
00119 static unsigned long timenextbackground = 0;
00120 
00121 static Point adjustcursorlastpoint = {-1, -1}; /*optimizes adjustcursor routine*/
00122 
00123 static boolean floverridebeachball = false; /*set true when user action occurs*/
00124 
00125 static boolean flipcstarted = false;
00126 
00127 static boolean flbackgroundtasksdisabled = true; /*will be set to false when initialization is complete*/
00128 
00129 static boolean flshelleventposted = false;
00130 
00131 
00132 boolean shellgetstring (short id, bigstring bs) {
00133     
00134     return (getstringlist (interfacelistnumber, id, bs));
00135     } /*shellgetstring*/
00136 
00137 
00138 void shellerrormessage (bigstring bs) {
00139     
00140     /*
00141     all normal error messages -- memory, i/o, resource -- go through 
00142     here.  this allows errors to be rechannelled, for instance to the 
00143     langerror dialog window.
00144     */
00145     
00146     if (!shellcallerrorhooks (bs))
00147         return;
00148     
00149     flbackgroundtasksdisabled = true; /*error condition, don't want modal backgrounding*/
00150     
00151     alertdialog (bs);
00152 
00153     flbackgroundtasksdisabled = false;
00154     } /*shellerrormessage*/
00155 
00156 
00157 #ifdef fltrialsize
00158 
00159 void shelltrialerror (short id) {
00160 
00161     bigstring bs, bsbuy;
00162     
00163     getstringlist (trialsizelistnumber, id, bs);
00164     
00165     getstringlist (trialsizelistnumber, buyfrontierstring, bsbuy);
00166     
00167     pushstring (bsbuy, bs);
00168     
00169     shellerrormessage (bs);
00170     } /*shelltrialerror*/
00171 
00172 #endif
00173 
00174 
00175 #ifdef fldebug
00176 
00177 void shellinternalerrormessage (bigstring bserror) {
00178     
00179     bigstring bs;
00180     
00181     copystring ((ptrstring) "\x10" "Internal error: ", bs);
00182     
00183     pushstring (bserror, bs);
00184     
00185     shellerrormessage (bs);
00186     } /*shellinternalerrormessage*/
00187 
00188 #else
00189 
00190 void shellinternalerrormessage (short iderror) {
00191     
00192     bigstring bs, bsnum;
00193     
00194     shellgetstring (internalerrorstring, bs);
00195     
00196     numbertostring (iderror, bsnum);
00197     
00198     parsedialogstring (bs, bsnum, nil, nil, nil, bs);
00199     
00200     shellerrormessage (bs);
00201     } /*shellinternalerrormessage*/
00202 
00203 #endif
00204 
00205 
00206 extern void shellshutdownscroll ();
00207 
00208 
00209 boolean shellshutdown (void) {
00210     
00211     /*
00212     4/30/91 dmb: write out scrap before exiting
00213     
00214     1/3/92 dmb: commented-out the Quit dialog
00215     
00216     3.0b15 dmb: if fldialog is false, don't verify component shutdown; 
00217     they have no choice.
00218     */
00219     
00220     if (!shellcloseall (nil, false))
00221         return (false);
00222     
00223     shellwritescrap (anyscraptype);
00224     
00225     #ifdef iowaRuntime
00226     
00227         iowaClose ();
00228     
00229     #endif
00230     
00231     if (flipcstarted)
00232         langipcshutdown ();
00233     
00234     #ifdef flcomponent
00235         
00236         osacomponentshutdown ();
00237         
00238     #endif
00239     
00240     #ifdef MACVERSION
00241     
00242         fwsNetEventQuit ();
00243     
00244     #endif
00245     
00246     processclose ();
00247     
00248     logshutdown ();
00249     
00250 //  wpshutdown (); /*dmb 12/5/96*/
00251 
00252     //Code change by Timothy Paustian Wednesday, July 26, 2000 9:24:46 PM
00253     //added code to free action procs for scroll bars.
00254     #if TARGET_API_MAC_CARBON == 1
00255         shellshutdownscroll();
00256         fileshutdown();
00257         UnregisterAppearanceClient();
00258     #endif
00259 
00260     exittooperatingsystem (); /*doesn't return*/
00261     
00262     return (true); /*satisfy the compiler -- not a void function*/
00263     } /*shellshutdown*/
00264 
00265 
00266 boolean shellquit (void) {
00267     
00268     #ifdef flcomponent
00269         
00270         if (!osacomponentverifyshutdown ()) /*may return false if there are clients*/
00271             return (false);
00272     
00273     #endif
00274     
00275     if (!shellcloseall (nil, true)) /*user hit Cancel button in save dialog*/
00276         return (false);
00277     
00278     shellexitmaineventloop (); //sets flag for next iteration
00279     
00280     return (true);
00281     } /*shellquit*/
00282 
00283 
00284 #if defined(MACVERSION) && TARGET_API_MAC_OS8
00285 static void shellhandlediskinsertion (void) {
00286     //Code change by Timothy Paustian Friday, June 16, 2000 2:21:17 PM
00287     //Changed to Opaque call for Carbon
00288     //The system takes care of bad mounted disks, we don't need to.
00289     Point pt = {0, 0};
00290     
00291     if (HiWord (shellevent.message) != 0)
00292         DIBadMount (pt, shellevent.message);
00293 
00294     } /*shellhandlediskinsertion*/
00295 #endif
00296 
00297 
00298 static void shellhandleevent (void) {
00299     
00300     /*
00301     12/6/96 dmb: let shellhandlemouse call mousedown itself
00302     */
00303     
00304     register WindowPtr w = (WindowPtr) shellevent.message;
00305     
00306     switch (shellevent.what) {
00307     
00308         case keyDown: case autoKey:
00309             //shellforcemenuadjust (); /*RAB 01/31/01: not needed, was a performance hit.*/
00310             
00311             floverridebeachball = true; /*beachball must be reset after user action*/
00312             
00313             if (!shellcalleventhooks (&shellevent, getfrontwindow ()))
00314                 break;
00315             
00316             shellhandlekeystroke ();
00317             
00318             break;
00319         
00320         case mouseDown:
00321     #ifdef WIN95VERSION
00322         case rmouseDown:
00323         case cmouseDown:
00324         case wmouseDown:
00325     #endif
00326             //shellforcemenuadjust (); /*RAB 01/31/01: not needed, was a performance hit.*/
00327             
00328             floverridebeachball = true; /*beachball must be reset after user action*/
00329             
00330             shellhandlemouse ();
00331             
00332             break;
00333         
00334         case mouseUp:
00335             shellhandlemouseup ();
00336             
00337             break;
00338 
00339     #ifdef WIN95VERSION
00340         case menuEvt:
00341             shellforcemenuadjust ();
00342 
00343             shellpushglobals (w); /*following mouse operations assume globals are pushed*/
00344             
00345             shellhandlemenu (shellevent.modifiers);
00346             
00347             shellpopglobals ();
00348             break;
00349 
00350         case scrollEvt:
00351             shellpushglobals (w); /*following mouse operations assume globals are pushed*/
00352 
00353             winscroll ((boolean) shellevent.modifiers, shellevent.where.v, shellevent.where.h);
00354             
00355             shellpopglobals ();
00356             break;
00357     #endif
00358 
00359         case activateEvt:
00360             shellforcemenuadjust ();
00361 
00362             if (!shellcalleventhooks (&shellevent, w))
00363                 break;
00364             
00365             shellactivatewindow (w, (shellevent.modifiers & activeFlag) != 0);
00366             
00367             break;
00368         
00369         case jugglerEvt:
00370             shellcalleventhooks (&shellevent, getfrontwindow ());
00371             
00372             shellhandlejugglerevent ();
00373             
00374             break;
00375         
00376         case updateEvt:
00377             if (!shellcalleventhooks (&shellevent, w))
00378                 break;
00379             
00380             shellhandleupdate ();
00381             
00382             break;
00383 
00384     #ifdef MACVERSION
00385         case diskEvt:
00386             //Code change by Timothy Paustian Friday, June 16, 2000 2:22:47 PM
00387             //Changed to Opaque call for Carbon
00388             #if TARGET_API_MAC_OS8
00389             shellhandlediskinsertion ();
00390             #endif
00391 
00392             break;
00393     #endif
00394             
00395         default:
00396             shellcalleventhooks (&shellevent, nil); /*don't pass specific window for other events*/
00397             
00398             break;
00399         } /*switch*/
00400     } /*shellhandleevent*/
00401 
00402 
00403 void shellforcecursoradjust (void) {
00404     
00405     adjustcursorlastpoint.h -= 100;
00406     } /*shellforcecursoradjust*/
00407 
00408 
00409 void shelladjustcursor (void) {
00410     
00411     /*
00412     assumes the globals for the front window have been pushed.
00413     
00414     10/3/92 dmb: check for nil windowinfo instead of emptywindowlist
00415     
00416     5/20/92 dmb: if processbusy, don't touch the cursor
00417     
00418     1/26/93 dmb: make check of 5/92 smarter; check for beachball specifically, 
00419     and roll it if active
00420     
00421     2/9/93 dmb: make check of 1/26 a little smarter too: check for user action
00422 
00423     5.0a8 dmb: rewrote using new getmousewindowposition, so we get right cursor
00424     shape in non-front windows for non-Mac OSs
00425     */
00426     
00427     register hdlwindowinfo hw;
00428     WindowPtr w;
00429     Point pt;
00430     boolean flnotfrontwindow;
00431     
00432     getmousewindowpos (&w, &pt);
00433     
00434     if (equalpoints (pt, adjustcursorlastpoint)) /*mouse hasn't moved, save cycles*/
00435         return;
00436     
00437     if (processbusy () && beachballcursor ()) { /*a script started the beachball rolling*/
00438         
00439         if (!floverridebeachball) { /*user action hasn't intervened*/
00440             
00441             rollbeachball ();
00442             
00443             return;
00444             }
00445         }
00446     
00447     floverridebeachball = false; /*clear flag every time -- setting cursor will stop beachball*/
00448     
00449     adjustcursorlastpoint = pt; /*remember for next call*/
00450     
00451     if (w == nil || !isshellwindow (w)) { /*not over a window, or desk accessory or special window in front*/
00452         
00453         #ifdef MACVERSION
00454             setcursortype (cursorisarrow);
00455         #endif
00456         
00457         return;
00458         }
00459     
00460     flnotfrontwindow = shellwindow != w; /*not over the front shell window*/
00461 
00462     #ifdef MACVERSION
00463         if (flnotfrontwindow) {
00464 
00465             setcursortype (cursorisarrow);
00466             
00467             return;
00468             }
00469     #endif
00470     
00471     if (flnotfrontwindow)
00472         shellpushglobals (w);
00473     
00474     hw = shellwindowinfo;
00475 
00476     if (pointinrect (pt, (**hw).contentrect)) {
00477         
00478         (*shellglobals.adjustcursorroutine) (pt);
00479         }
00480     
00481     else if (pointinrect (pt, (**hw).buttonsrect)) {
00482         
00483         shellbuttonadjustcursor (pt);
00484         }
00485     
00486     else {
00487         /* Under Windows, if it is not in our content - don't changeit */
00488         #ifdef MACVERSION
00489             setcursortype (cursorisarrow); /*not a special cursor*/
00490         #endif
00491         }
00492     
00493     if (flnotfrontwindow) /*not over the front shell window*/
00494         shellpopglobals ();
00495     
00496     } /*shelladjustcursor*/
00497 
00498 
00499 void shellidle (void) {
00500     
00501     (*shellglobals.idleroutine) ();
00502     } /*shellidle*/
00503 
00504 
00505 #ifdef WIN95VERSION
00506 
00507 void shelldestoycaretinmainthread (void) {
00508     
00509     /*
00510     called by wpengine.c, Paige is going to destroy the caret, but
00511     we may not be in the main thread, and it doesn't work from other
00512     threads.
00513     */
00514     
00515     if (flscriptrunning) {
00516         
00517         releasethreadglobals ();
00518         
00519         SendMessage (shellframewindow, wm_destroycaret, 0, 0);
00520         
00521         grabthreadglobals ();
00522         }
00523     } /*shelldestoycaretinmainthread*/
00524 
00525 #endif
00526 
00527 boolean shellyield (boolean flresting) {
00528     
00529     /*
00530     5.0.2b6 dmb: this could end up begin a generally-useful routine, 
00531     but right now it's being written for opening edit windows under WinOS, 
00532     to allow for overlapping edit calls. We're yielding to allow the main
00533     thread to get a WM_CREATE message.
00534     */
00535 
00536     boolean fl;
00537     
00538     if (flscriptrunning)
00539         fl = langerrorenabled () && langbackgroundtask (flresting);
00540     else
00541         fl = processyield ();
00542 
00543     return (fl);
00544     } /*shellyield*/
00545 
00546 
00547 void shellforcebackgroundtask (void) {
00548     
00549     /*
00550     make sure that we run background tasks at the earliest opportunity
00551     */
00552     
00553     flshellimmediatebackground = true;
00554     } /*shellforcebackgroundtask*/
00555 
00556 
00557 boolean shellbackgroundtask (void) {
00558     
00559     /*
00560     anyway.  this is called from the main event loop, and can be called by any
00561     code whenever you want to make sure that background UserLand tasks get a 
00562     shot at running....
00563     */
00564     
00565     unsigned long tc;
00566     
00567     if (flbackgroundtasksdisabled)
00568         return (true);
00569     
00570     tc = gettickcount ();
00571     
00572     if (flshellimmediatebackground) {
00573         
00574         flshellimmediatebackground = false; /*must be reset every time*/
00575         }
00576         
00577     else {
00578         if ((tc < timenextbackground) && (timenextbackground - tc < 60)) {
00579             
00580             #ifdef MACVERSION
00581                 return (processyield ());
00582             #endif
00583             #ifdef WIN95VERSION
00584                 return (true);
00585             #endif
00586             }
00587 
00588         if (tc < (timelastkeystroke + 15) && (tc > timelastkeystroke)) /*heuristic -- the user is busy typing*/
00589             return (true);
00590         }
00591     
00592     timenextbackground = tc + 60; /*check task queue no more often than once a second*/
00593     
00594     if (shellpushdefaultglobals ()) {
00595         
00596         (*shellglobals.backgroundroutine) ();
00597         
00598         shellpopglobals ();
00599         }
00600     
00601     shellforcecursoradjust (); /*a script is allowed to change the cursor*/
00602     
00603     return (true);
00604     } /*shellbackgroundtask*/
00605     
00606 
00607 boolean shellprocessevent (EventRecord *ev) {
00608     
00609     /*
00610     called externally, we process an event fielded elsewhere (within IAC TK)
00611 
00612     5.0.2 rab: set shellevent after grabbing threadglobals
00613     */
00614     
00615     grabthreadglobals ();
00616 
00617     shellevent = *ev;
00618     
00619     shellhandleevent ();
00620     
00621     releasethreadglobals ();
00622 
00623     return (true);
00624     } /*shellprocessevent*/
00625 
00626 
00627 boolean shellpostevent (EventRecord *ev) {
00628     
00629     /*
00630     9/25/92 dmb: this is being thrown in to support the HyperCard 2.0 event 
00631     callback in langxcmd.c. the mechanism is informal right now; we're not 
00632     checking to see if events are blocked, or if the particular event type is 
00633     currently being masked out. so there are probably bug scenarios in this 
00634     somewhere, but I think the odds are with us on it working reasonably well.
00635     
00636     btw, if the caller is in another thread, it must yield before the event 
00637     will be processed.
00638     */
00639     
00640     if (flshelleventposted) /*can't stack up these calls*/
00641         return (false);
00642     
00643     shellevent = *ev;
00644     
00645     flshelleventposted = true;
00646     
00647     return (true);
00648     } /*shellpostevent*/
00649 
00650     
00651 static short shellgeteventmask (void) {
00652     
00653     return (everyEvent - shellblockedevents ());
00654     } /*shellgeteventmask*/
00655 
00656 #ifdef MACVERSION
00657 static boolean shellgetevent (void) {
00658     
00659     /*
00660     return true if an operating system event is available in the shellevent global,
00661     false if no event is available.
00662     
00663     6/27/91 dmb: we're now doing more intelligent stuff with high-level events 
00664     on system 7, so we only want to call landeventfilter here for null events 
00665     to cover system 6.
00666     
00667     2/11/92 dmb: set sleep to a larger number when we're not active so we don't 
00668     hog the processor
00669     */
00670     
00671     register boolean fl;
00672     register unsigned long sleep;
00673     boolean flcloseallwindows;
00674     extern boolean isModelessCardEvent (EventRecord *, boolean *);  // can't #include iowaruntime.h here
00675 
00676     
00677     if (shelleventsblocked ()) /*all events are blocked -- don't ask the OS for any*/
00678         return (false);
00679     
00680     if (flshelleventposted) {
00681         
00682         flshelleventposted = false; /*consumed*/
00683         
00684         fl = true;
00685         }
00686     else {
00687         
00688         if (shellisactive () || flshellimmediatebackground || processrunning ())
00689             sleep = 1;
00690         else
00691             sleep = min (30, maxint (1, (long) timenextbackground - gettickcount () - 20));
00692         
00693         fl = WaitNextEvent (shellgeteventmask (), &shellevent, sleep, nil);
00694         
00695         #ifdef MACVERSION
00696         
00697             if (isplayerevent ()) /*7.0b4 PBS: QuickTime catches some events.*/
00698         
00699                 fl = false;
00700                 }
00701         #endif
00702     
00703     if (flipcstarted && !fl)
00704         if (landeventfilter (&shellevent)) /*event consumed by IAC toolkit*/
00705             fl = false;
00706     
00707     #ifdef MACVERSION
00708     
00709         /*
00710         if (uisHandleEvent (&shellevent, &flcloseallwindows)) // event consumed by window sharing server
00711             fl = false;
00712         */
00713 
00714         if (isModelessCardEvent (&shellevent, &flcloseallwindows)) {
00715             
00716             fl = false;
00717             
00718             if (flcloseallwindows)  // user option-clicked in close box of a card window
00719                 shellcloseall (nil, true);
00720             }
00721         
00722 
00723     #endif
00724     
00725     return (fl);
00726     } /*shellgetevent*/
00727 #endif
00728 
00729 static boolean shelleventavail (void) {
00730     
00731     EventRecord ev;
00732     
00733     if (shelleventsblocked ()) /*all events are blocked -- don't ask the OS for any*/
00734         return (false);
00735     
00736     if (EventAvail (shellgeteventmask (), &ev))
00737         return (true);
00738     
00739     #ifdef landinclude
00740         if (flipcstarted)
00741             landeventfilter (&ev); /*event consumed by IAC toolkit*/
00742     #endif
00743     
00744     return (false);
00745     } /*shelleventavail*/
00746 
00747 
00748 static void shellhandlenullevent (boolean * flbackground) {
00749 
00750     /*
00751     5.0b9 dmb: update menus even when there's nothing open
00752     */
00753 
00754     unsigned long tc;
00755     boolean fl;
00756 
00757     tc = gettickcount ();
00758     
00759     grabthreadglobals ();
00760 
00761         fl = shellpushfrontglobals () || shellpushfrontrootglobals ();
00762         
00763         if (tc > (timelastevent + tickstoupdatemenus)) 
00764             shellupdatemenus (); 
00765         
00766         if (fl && (*shellglobals.dataholder != NULL)) { // 5.6.97 dmb: window has content
00767 
00768             if (tc > (timelastevent + tickstoidle)) {
00769                 
00770                 if (fl)
00771                     shellidle ();
00772                 
00773                 shelladjustcursor ();
00774                 
00775                 *flbackground = true;
00776                 }
00777             }
00778         
00779         if (fl)
00780             shellpopglobals ();
00781     
00782     processchecktimeouts ();
00783     
00784     if (*flbackground || flshellimmediatebackground)
00785         shellbackgroundtask ();
00786     else
00787     {
00788         int i = 0;
00789         i++;
00790     }
00791     shellcheckdirtyscrollbars (); /*scroll pos may change in background too*/
00792 
00793     releasethreadglobals ();
00794     } /*shellhandlenullevent*/
00795 
00796 
00797 boolean shelleventloop (callback breakproc) {
00798     
00799     /*
00800     sit in an event loop, responding to the user's input.  if our breakproc
00801     routine returns false, we break out immediately.  this allows callers to
00802     view the evenloop as a co-routine.  necessary for the implementation of
00803     the script debugger.
00804     
00805     8/21/90 dmb:  check background task, scrollbars in one place, whether or 
00806     not there was an event
00807     */
00808     
00809     boolean flbackground = false;
00810 
00811     #ifdef WIN95VERSION
00812         #define NULLTIMERID 42
00813         MSG msg;
00814         UINT timerID;
00815 
00816         timerID = SetTimer (shellframewindow, NULLTIMERID, 80, NULL);
00817 
00818         if (timerID == 0)
00819             return (false);
00820 
00821     #endif
00822 
00823     while (true) {
00824         
00825         if (!(*breakproc) ()) /*caller is forcing us out of event loop*/
00826             return (true);
00827         
00828     #ifdef MACVERSION
00829         if (shellgetevent ()) { /*if true, global shellevent holds event info*/
00830             
00831             shellhandleevent ();
00832                         
00833             timelastevent = gettickcount ();
00834             }
00835         
00836         //Code change by Tim Paustian
00837         //we are going to use a timer to 
00838         //handle these things so we don't want them
00839         //in carbon
00840         //#if TARGET_API_MAC_CARBON == 0
00841         fwsNetEventCheckAndAcceptSocket ();
00842         shellhandlenullevent (&flbackground);
00843         
00844         //#endif
00845         
00846     #endif
00847 
00848     #ifdef WIN95VERSION
00849         /*Note: GetMessage can return 3 values, TRUE, FALSE or -1 which is why we code == TRUE */
00850 
00851         if (GetMessage (&msg, NULL, 0, 0) == TRUE) {
00852 
00853             if (msg.message == WM_QUIT) {
00854                 KillTimer (shellframewindow, NULLTIMERID);
00855                 return (true);
00856                 }
00857 
00858             if ((msg.message == WM_TIMER) && (msg.wParam == NULLTIMERID)) {
00859                 shellhandlenullevent (&flbackground);
00860             //  continue;
00861                 }
00862 
00863             if (findreplacewindow != NULL) {
00864                 if (IsDialogMessage (findreplacewindow, &msg) != 0) {  /* we have processed the message */
00865                     continue;
00866                     }
00867                 }
00868 
00869             if ( !TranslateMDISysAccel (hwndMDIClient, &msg) &&
00870                   !TranslateAccelerator (shellframewindow, hAccel, &msg)) {
00871 
00872                 TranslateMessage (&msg);
00873 
00874                 DispatchMessage (&msg);
00875                 }
00876             }
00877         else {
00878             KillTimer (shellframewindow, NULLTIMERID);
00879             return (false);
00880             }
00881     #endif
00882 
00883         } /*while*/
00884     } /*shelleventloop*/
00885 
00886 
00887 static boolean shellshortbreakproc (void) {
00888     
00889     return (shelleventavail ());
00890     
00891     /*
00892     EventRecord ev;
00893     
00894     if (shelleventsblocked ()) /%all events are blocked -- don't ask the OS for any%/
00895         return (false);
00896     
00897     if (EventAvail (shellgeteventmask (), &ev))
00898         return (true);
00899     
00900     return (landeventfilter (&ev)); /%null event consumed by IAC toolkit%/
00901     */
00902     
00903     } /*shellshortbreakproc*/
00904 
00905 
00906 boolean shellshorteventloop (void) {
00907     
00908     /*
00909     handle all events, as long as events are available.  allows the user to 
00910     interact with the environment while a script is active.  very interesting!
00911     */
00912     
00913     assert (iscurrentapplication (langipcself));    // 4.1b6 dmb: was checking infrontierthread.
00914     
00915     return (shelleventloop (&shellshortbreakproc));
00916     } /*shellshorteventloop*/
00917 
00918 
00919 boolean shellpartialeventloop (short desiredevents) {
00920     
00921     /*
00922     handle all activate and update events, as long as events are available.
00923     */
00924     
00925     register boolean fl;
00926     
00927     shellpushblock (everyEvent - desiredevents, true);
00928     
00929     fl = shellshorteventloop ();
00930     
00931     shellpopblock ();
00932     
00933     return (fl);
00934     } /*shellpartialeventloop*/
00935 
00936 
00937 static boolean shellmainbreakproc (void) {
00938     
00939     /*
00940     allows us to insert a little housekeeping in the main event loop.
00941     */
00942     
00943     keyboardclearescape (); /*consume any un-handled cmd-periods*/
00944     
00945     /*
00946     if (fltrialversion) {
00947     
00948         if (timenow () - timeshellstarted > (2 * 60 * 60)) {
00949         
00950             shellerrormessage ("\pThe trial version of Frontier can not run for more than two hours at a time.");
00951             
00952             flexitmaineventloop = true;
00953             }
00954         }
00955     */
00956     
00957     return (!flexitmaineventloop); /*keep going through the loop*/
00958     } /*shellmainbreakproc*/
00959 
00960 
00961 void shellmaineventloop (void) {
00962     
00963     /*
00964     4/7/97 dmb: no longer do startup here
00965 
00966     5.0a22 dmb: need thread globals to shutdown
00967     */
00968     
00969     //shellpushblock (networkMask, true); /*for network toolkit; block network events%/
00970     
00971 #if defined(MACVERSION) && TARGET_API_MAC_OS8
00972     UnloadSeg (&initsegment);
00973 #endif
00974     
00975     shelleventloop (&shellmainbreakproc);
00976     
00977     grabthreadglobals ();
00978 
00979     shellshutdown ();
00980     
00981     releasethreadglobals ();
00982     /* Windows version is inverted from MAC so we don't "loop" here */
00983     } /*shellmaineventloop*/
00984 
00985 
00986 void shellexitmaineventloop (void) {
00987     
00988     /*
00989     call this to force the program to exit the next time it hits the 
00990     main event loop
00991     */
00992     
00993     flexitmaineventloop = true;
00994     } /*shellexitmaineventloop*/
00995 
00996 
00997 boolean shellstart (void) {
00998     
00999     /*
01000     4/7/97 dmb: broke code out of shellmaineventloop
01001     */
01002 
01003     shellpatchnilroutines (); /*make sure that all nil handlers point to something*/
01004     
01005     shellloadbuttonlists (); /*for windows types that have buttons attached*/
01006     
01007     shellinithandlers (); /*call the initroutines for all window types*/
01008     
01009     if (keyboardescape ()) /*give user chance to abort booting process*/
01010         shellshutdown ();
01011         
01012     drawmenubar (); /*don't show menubar until it is available*/
01013 
01014     #if TARGET_API_MAC_CARBON == 1 /*OS X PBS: delete Preferences and separator menu items.*/
01015     
01016         {
01017     
01018         MenuRef hmenu;
01019         long itemIndex = 1;
01020         OSErr err = noErr;
01021         
01022         err = GetIndMenuItemWithCommandID (NULL, kHICommandPreferences, 1, &hmenu, (MenuItemIndex*) &itemIndex);
01023     
01024         if (err == noErr) {
01025             deletemenuitem (hmenu, itemIndex);
01026             deletemenuitem (hmenu, itemIndex);
01027             } /*if*/
01028     
01029         }
01030     
01031     #endif
01032         
01033     shelladjustmenus ();
01034     
01035     #ifdef MACVERSION
01036     //#ifndef PIKE
01037         closeabout (false, 120); /*close the about window, don't zoom, make sure two seconds have elapsed*/
01038     //#endif
01039     #endif
01040     
01041     #ifdef flsystem6
01042         if ((**landgetglobals ()).transport != macsystem7) /*under system 7, we wait for appleevents*/
01043             shellopeninitialfiles ();
01044     #endif
01045 
01046     #ifdef WIN95VERSION
01047         shellopeninitialfiles ();
01048     #endif
01049     
01050     flbackgroundtasksdisabled = false; /*ready to multitask!*/
01051 
01052     return (true);
01053     } /*shellstart*/
01054 
01055 
01056 #ifdef fltrialsize
01057 
01058 static boolean shellinitclock (void) {
01059     
01060     /*
01061     this version expires Septermber 8, 1998
01062     */
01063     
01064     unsigned long now;
01065     short day, month, year, hour, minute, second;
01066     
01067     now = timenow ();
01068     
01069     secondstodatetime (now, &day, &month, &year, &hour, &minute, &second);
01070     
01071     if (year > 1998)
01072         return (false);
01073     
01074     /*
01075     if (month > 9)
01076         return (false);
01077     
01078     if (month == 9)
01079         if (day > 7)
01080             return (false);
01081     */
01082 
01083     return (true);
01084     } /*shellinitclock*/
01085 
01086 #endif
01087 
01088 
01089 /*
01090 static shelltrashresource (OSType type, short id) {
01091     
01092     register Handle h;
01093     
01094     h = GetResource (type, id);
01095     
01096     clearhandle (h);
01097     
01098     ChangedResource (h);
01099     } /%shelltrashresource%/
01100 */
01101 
01102 #ifdef MACVERSION
01103 static pascal long shellgrowzone (Size ctbytesneeded) {
01104     
01105     long ctstillneeded = ctbytesneeded;
01106     
01107     #if TARGET_API_MAC_OS8
01108     long curA5 = SetUpAppA5 ();
01109     #endif
01110     
01111     shellcallmemoryhooks (&ctstillneeded);
01112     
01113     #if TARGET_API_MAC_OS8
01114     RestoreA5 (curA5);
01115     #endif
01116         
01117     return (ctbytesneeded - ctstillneeded);
01118     } /*shellgrowzone*/
01119 #endif
01120 
01121 static boolean shellinitmemory (void) {
01122     
01123     /*
01124     12/4/91 dmb: hook into the memory manager's growzone proc.
01125     
01126     this could be moved into memory.c
01127     
01128     3.0.2b1 dmb: remember the app a5 so we can set it up in the growzone. 
01129     there's a Memory Manager TN that warns about this being necessary.
01130     */
01131 
01132 #ifdef MACVERSION   
01133     //Code change by Timothy Paustian Friday, June 16, 2000 2:23:28 PM
01134     //Changed to Opaque call for Carbon
01135     //we don't need this for carbon
01136     #if !TARGET_API_MAC_CARBON
01137         RememberA5 ();
01138     #endif
01139 
01140     #if TARGET_API_MAC_CARBON
01141 
01142         SetGrowZone (NewGrowZoneUPP (shellgrowzone));
01143     
01144     #else
01145     
01146         SetGrowZone (NewGrowZoneProc (shellgrowzone));
01147         
01148     #endif
01149     
01150 #endif
01151     
01152     return (initmemory ());
01153     } /*shellinitmemory*/
01154 
01155 
01156 static boolean showerrorandexit (short iderror) {
01157     
01158     alertstring (iderror);
01159     
01160     return (false);
01161     } /*showerrorandexit*/
01162 
01163 
01164 extern void shellinitscroll ();
01165 
01166 
01167 boolean shellinit (void) {
01168     
01169     /*
01170     2.1b5 dmb: added small first steps towards starting up with a clean heap.
01171     rearrange the load order slightly and added "ctreservebytes" parameter to 
01172     openabout
01173     */
01174     
01175     if (!initmacintosh ())
01176         return (showerrorandexit (notenoughmemorystring));
01177 
01178     #ifdef MACVERSION   
01179         //Code change by Timothy Paustian Friday, June 9, 2000 2:36:02 PM
01180         //Changed because using SysEnvisons and SysEnvRec is like Really old style
01181         //This was changed to Gestalt calls with two new globals see mac.c initmacintosh
01182     
01183         if (gSystemVersion < 0x0700)
01184             return (showerrorandexit (archaicsystemstring));
01185         
01186         initfsdefault (); /* 2005-07-18 creedon, karstenw - init fsdefault here, don't leave it up to an
01187                        FSMakeFSSpec call at some unknown time, see
01188                        < http://sourceforge.net/tracker/index.php?func=detail&aid=1239991&group_id=120666&atid=687798 > */
01189         
01190     #endif
01191 
01192     if (keyboardescape ()) /*check for command-period for accidental launch*/
01193         return (false);
01194     
01195     langipcinit (); /*must do first to allow permanant event hook to be installed*/
01196     
01197     if (!shellinitmemory ())
01198         return (showerrorandexit (notenoughmemorystring));
01199     
01200     clearbytes (&globalsarray, sizeof (globalsarray));
01201     
01202     initfile (); /*do this before about to filegetprogramversion will work*/
01203 
01204     #ifdef MACVERSION
01205         aboutsegment ();
01206     #endif  
01207     
01208     initquickdraw ();
01209     
01210     initfonts ();
01211 
01212     initconfig (); 
01213     
01214     initerror ();
01215     
01216     zoominit ();
01217     
01218     initdialogs ();
01219     
01220     initscrollbars (); /*7.0b18 PBS*/
01221     
01222     #ifdef MACVERSION
01223         initmouse ();
01224     #endif
01225     
01226     #ifdef fltrialsize
01227     
01228     if (!shellinitclock ()) {
01229         bigstring bs;
01230         
01231         getstringlist (trialsizelistnumber, expirationstring, bs);
01232         
01233         parsedialogstring (bs, "\x06" "1/1/99", nil, nil, nil, bs);
01234 
01235         shellerrormessage (bs);
01236 
01237         return (false);
01238         }
01239     
01240     //alertdialog ("\x30" "This version of Frontier expires on July 1, 1998");
01241     
01242     #endif
01243     
01244     #ifdef MACVERSION
01245     //#ifndef PIKE
01246         openabout (true, macmemoryconfig.reserveforcode); /*show about window, do zoom -- closed by shellmaineventloop*/
01247     //#endif
01248     
01249         FastInitialize(); /*2005-01-14 aradke: init timer, may take up to a second to callibrate*/
01250     
01251     #endif
01252     
01253     #ifdef WIN95VERSION
01254     //  openabout (true, 0);
01255     #endif
01256     
01257     initmenusystem ();
01258     
01259     initsmallicons ();
01260     
01261     initstrings ();
01262     
01263     initundo ();
01264     
01265     initscrap ();
01266     
01267     if (!shellinitmenus ()) { /*the resource fork is damaged or possibly already open*/
01268         
01269         sysbeep ();
01270         
01271         return (false);
01272         }
01273     
01274     //RAB: 1/19/98 moved printing init to the bottom of the chain
01275     //shellinitprint (); /*get set up for printing*/
01276     
01277     initsearch ();
01278     
01279     #if TARGET_API_MAC_CARBON == 1 /*7.0b48: bitmaps off in OS X*/
01280     
01281         initbitmaps (false);
01282         
01283     #else
01284     
01285         initbitmaps (true);
01286         
01287     #endif
01288     
01289     #if TARGET_API_MAC_CARBON == 1
01290     
01291     initservices ();
01292 
01293 #endif
01294 
01295 #if isFrontier || flruntime || winhybrid
01296 
01297     initlang (); /*init callbacks and other basic inits*/
01298 
01299     langcallbacks.processeventcallback = &shellprocessevent; /*4.1b13 dmb - new*/
01300     
01301     if (!inittablestructure ()) /*create initial hashtable structure*/
01302         return (false);
01303     
01304     initscripts (); /*set up global debugger data*/
01305     
01306     langinitverbs ();
01307     
01308     dbinitverbs (); // 4.1b4 dmb
01309     
01310     shellinitverbs ();
01311     
01312     fileinitverbs (); 
01313     
01314     stringinitverbs (); 
01315     
01316     windowinitverbs ();
01317     
01318     xmlinitverbs ();
01319     
01320     htmlinitverbs ();
01321 
01322 #ifdef flregexpverbs
01323     regexpinitverbs (); /* 2003-04-23 AR: langregexp.c */
01324 #endif
01325     
01326 #ifdef MACVERSION /*7.0b4 PBS: initialize QuickTime verbs*/
01327     
01328     quicktimeinitverbs ();
01329     
01330 #endif
01331     
01332     mathinitverbs (); /*2004-12-30 smd: langmath.c*/
01333     
01334     dllinitverbs (); /*2004-11-29 aradke: langdll.c*/
01335     
01336     cryptinitverbs (); /* 2006-03-07 creedon: langcrypt.c */
01337     
01338     if (keyboardescape ()) /*check again before landinit; after this, must do shellquit*/
01339         exittooperatingsystem ();
01340     
01341     flipcstarted = langipcstart ();
01342     
01343     initprocess ();
01344 
01345     //RAB: 1/19/98 - moved print init here so that Windows will have enough setup before using the dialog.
01346     shellinitprint (); /*get set up for printing*/
01347 
01348 #else
01349 
01350     flipcstarted = langipcstart ();
01351 
01352 #endif
01353 
01354     //Code change by Timothy Paustian Wednesday, July 26, 2000 9:23:50 PM
01355     //added init code for scroll proc
01356 
01357     #if TARGET_API_MAC_CARBON == 1
01358     
01359         shellinitscroll();
01360         //Ok we now need to set up a timer for handling idle and network processes
01361         {
01362         //EventLoopRef      mainLoop;
01363         //EventLoopTimerUPP timerUPP;
01364         //EventLoopTimerRef theTimer;
01365         //OSStatus          anErr = noErr;
01366         
01367         //get a reference to the main loop
01368         //this is where we will handle the timer from
01369         //mainLoop = GetMainEventLoop();
01370         //create a UPP to the routine idleTimer that will actually do our stuff
01371         //timerUPP = NewEventLoopTimerUPP(idleTimer);
01372         /*anErr = InstallEventLoopTimer(    mainLoop,
01373                                         5 * kEventDurationSecond, //how long till it fires, do we need this
01374                                         kEventDurationSecond/6, //this fire 10 times a second as the idle proc wants.
01375                                         timerUPP,
01376                                         NULL,
01377                                         &theTimer);*/
01378                                         
01379     /*Install dock menu handler.*/
01380         
01381     EventHandlerUPP dockmenuUPP;                                        
01382     OSStatus ec = noErr;
01383     EventTypeSpec eventTypes [1];
01384 
01385     eventTypes[0].eventClass = kEventClassApplication;
01386     eventTypes[0].eventKind  = kEventAppGetDockTileMenu;
01387 
01388     dockmenuUPP = NewEventHandlerUPP (dockmenuhandler);
01389 
01390     ec = InstallApplicationEventHandler (dockmenuUPP, 1, eventTypes, NULL, NULL);
01391 
01392     /*If it fails, oh well, there's nothing to be done. So ec isn't checked.*/
01393     }
01394     
01395     #endif
01396 
01397     fileinit();
01398     return (true);
01399 
01400     } /*shellinit*/
01401 
01402 #if 0 //TARGET_API_MAC_CARBON == 1
01403 static pascal void idleTimer (EventLoopTimerRef theTimer, void * userData)
01404 {
01405     //I hate warnings, shut up the compiler
01406     #pragma unused(theTimer)
01407     #pragma unused(userData)
01408     
01409     boolean flbackground;
01410     
01411     fwsNetEventCheckAndAcceptSocket ();
01412         
01413     shellhandlenullevent (&flbackground);
01414     
01415 }
01416 #endif
01417 

Generated on Wed May 31 18:20:01 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6