cancoon.c

Go to the documentation of this file.
00001 
00002 /*  $Id: cancoon.c 1254 2006-04-12 20:27:14Z 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 #endif
00034 
00035 #include "memory.h"
00036 #include "dialogs.h"
00037 #include "error.h"
00038 #include "file.h"
00039 #include "font.h"
00040 #include "menu.h"
00041 #include "ops.h"
00042 #include "resources.h"
00043 #include "quickdraw.h"
00044 #include "strings.h"
00045 #include "frontierwindows.h"
00046 #include "shell.h"
00047 #include "shellhooks.h"
00048 #include "shellmenu.h"
00049 #include "shellprivate.h"
00050 #include "shell.rsrc.h"
00051 #include "langexternal.h"
00052 #include "langinternal.h"
00053 #include "langipc.h"
00054 #include "tableinternal.h"
00055 #include "tablestructure.h"
00056 #include "tableverbs.h"
00057 #include "menuverbs.h"
00058 #include "scripts.h"
00059 #include "process.h"
00060 #ifdef fltrialsize
00061     #include "dbinternal.h"
00062 #endif
00063 #include "cancoon.h"
00064 #include "cancooninternal.h"
00065 #include "serialnumber.h"
00066 
00067 #include "WinSockNetEvents.h" /*6.2a14 AR*/
00068 #include "byteorder.h"  /* 2006-04-08 aradke: endianness conversion macros */
00069 
00070 
00071 
00072 hdlcancoonrecord cancoondata = nil;
00073 
00074 hdlwindowinfo cancoonwindowinfo = nil;
00075 
00076 WindowPtr cancoonwindow = nil;
00077 
00078 
00079 hdlcancoonrecord cancoonglobals = nil;
00080 
00081 hdlcancoonrecord supercancoonglobals = nil; /*4.1b4 dmb: only set when globals set via setsuperglobals*/
00082 
00083 
00084 #define maxsavedccglobals 5
00085 
00086 static hdlcancoonrecord ccglobalsstack [maxsavedccglobals];
00087 
00088 static short cctopglobals = 0;
00089 
00090 
00091 static short ccwindowconfigs [] = { /*table to map window info indexes to config ids*/
00092     
00093     idcancoonconfig,
00094     
00095     0, /*idmessageconfig*/
00096     
00097     idlangerrorconfig,
00098     
00099     idcommandconfig,
00100     
00101     idaboutconfig,
00102     
00103     0 /*idpaletteconfig*/
00104     };
00105 
00106 
00107 static boolean fldisablesymbolcallbacks = false;
00108 
00109 
00110 
00111 boolean ccgetwindowinfo (short windowtype, tycancoonwindowinfo *windowinfo) {
00112     
00113     *windowinfo = (**cancoondata).windowinfo [windowtype];
00114     
00115     return (true);  
00116     } /*ccgetwindowinfo*/
00117 
00118 
00119 boolean ccsetwindowinfo (short windowtype, tycancoonwindowinfo windowinfo) {
00120     
00121     (**cancoondata).windowinfo [windowtype] = windowinfo;
00122     
00123     (**cancoondata).fldirty = true;
00124     
00125     return (true);
00126     } /*ccsetwindowinfo*/
00127     
00128 
00129 boolean ccnewsubwindow (hdlwindowinfo hinfo, short windowtype) {
00130     
00131     register hdlwindowinfo hw = hinfo;
00132     tycancoonwindowinfo windowinfo;
00133     
00134     if (!shellpushrootglobals ((**hw).macwindow))
00135         return (false);
00136     
00137     ccgetwindowinfo (windowtype, &windowinfo);
00138         
00139     (**hw).defaultfont = windowinfo.fontnum;
00140     
00141     (**hw).defaultsize = windowinfo.fontsize;
00142     
00143     windowinfo.w = (**hw).macwindow;
00144     
00145     ccsetwindowinfo (windowtype, windowinfo);
00146     
00147     shellpopglobals ();
00148     
00149     return (true);
00150     } /*ccnewsubwindow*/
00151     
00152     
00153 boolean cccopywindowinfo (hdlwindowinfo hinfo, short windowtype) {
00154     
00155     register hdlwindowinfo hw = hinfo;
00156     register hdlcancoonrecord hc;
00157     register boolean fldirty;
00158     tycancoonwindowinfo windowinfo;
00159     Rect r, rwindow;
00160     
00161     if (!shellpushrootglobals ((**hw).macwindow))
00162         return (false);
00163     
00164     hc = cancoondata; /*copy into register*/
00165     
00166     fldirty = (**hc).fldirty; /*initialize*/
00167     
00168     shellgetglobalwindowrect (hw, &r);
00169     
00170     ccgetwindowinfo (windowtype, &windowinfo);
00171     
00172     diskrecttorect (&windowinfo.windowrect, &rwindow);
00173     
00174     if (!equalrects (r, rwindow)) { /*window was moved or resized*/
00175         
00176         recttodiskrect (&r, &windowinfo.windowrect);
00177         
00178         fldirty = true;
00179         }
00180         
00181     if (windowinfo.fontnum != (**hw).defaultfont) {
00182     
00183         windowinfo.fontnum = (**hw).defaultfont;
00184         
00185         fldirty = true;
00186         }
00187     
00188     if (windowinfo.fontsize != (**hw).defaultsize) {
00189     
00190         windowinfo.fontsize = (**hw).defaultsize;
00191         
00192         fldirty = true;
00193         }
00194     
00195     if (fldirty) { /*dirty things up -- everywhere conceivable*/
00196         
00197         (**hc).fldirty = true;
00198         
00199         windowsetchanges (cancoonwindow, true);
00200         }
00201         
00202     ccsetwindowinfo (windowtype, windowinfo);
00203     
00204     shellpopglobals ();
00205     
00206     return (true);
00207     } /*cccopywindowinfo*/
00208 
00209 
00210 boolean ccsubwindowclose (hdlwindowinfo hinfo, short windowtype) {
00211     
00212     tycancoonwindowinfo windowinfo;
00213     
00214     if (!cccopywindowinfo (hinfo, windowtype))
00215         return (false);
00216     
00217     if (!shellpushrootglobals ((**hinfo).macwindow))
00218         return (false);
00219     
00220     ccgetwindowinfo (windowtype, &windowinfo);
00221     
00222     windowinfo.w = nil;
00223     
00224     ccsetwindowinfo (windowtype, windowinfo);
00225     
00226     shellpopglobals ();
00227         
00228     return (true);
00229     } /*ccsubwindowclose*/
00230 
00231 
00232 boolean ccgetwindowrect (short ixwindowinfo, Rect *rwindow) {
00233     
00234     /*
00235     5.1.5b10 dmb: use ccfindrootwindow to avoid guest databases
00236     */
00237     
00238     tyconfigrecord lconfig; // 2006-04-03 - kw --- renamed
00239     hdlwindowinfo hinfo;
00240     
00241 //  if (shellpushfrontrootglobals ())
00242     if (ccfindrootwindow (&hinfo)) {
00243         
00244         tycancoonwindowinfo windowinfo;
00245         
00246         shellpushglobals ((**hinfo).macwindow);
00247         
00248         ccgetwindowinfo (ixwindowinfo, &windowinfo);
00249         
00250         diskrecttorect (&windowinfo.windowrect, rwindow);
00251         
00252         shellpopglobals ();
00253         
00254         return (true);
00255         }
00256     
00257     if (shellgetconfig (ccwindowconfigs [ixwindowinfo], &lconfig)) {
00258     
00259         *rwindow = lconfig.defaultwindowrect;
00260         
00261         return (true);
00262         }
00263     
00264     setrect (rwindow, -1, -1, -1, -1); /*set top, left, bottom, right*/
00265     
00266     return (false);
00267     } /*ccgetwindowrect*/
00268 
00269 
00270 static void ccinitwindowinfo (hdlcancoonrecord hcancoon, short ixwindowinfo) {
00271     
00272     register hdlcancoonrecord hc = hcancoon;        
00273     tycancoonwindowinfo windowinfo;
00274     tyconfigrecord lconfig; // 2006-04-03 - kw --- renamed
00275     Rect r;
00276     
00277     clearbytes (&windowinfo, sizeof (windowinfo));
00278     
00279     if (shellgetconfig (ccwindowconfigs [ixwindowinfo], &lconfig)) {
00280         
00281         recttodiskrect (&lconfig.defaultwindowrect, &windowinfo.windowrect);
00282         
00283         diskgetfontname (lconfig.defaultfont, windowinfo.fontname);
00284         
00285         windowinfo.fontnum = lconfig.defaultfont;
00286     
00287         windowinfo.fontsize = lconfig.defaultsize;
00288         }
00289     else {
00290         setrect (&r, -1, -1, -1, -1);
00291         
00292         recttodiskrect (&r, &windowinfo.windowrect);
00293         
00294         windowinfo.fontnum = systemFont;
00295         
00296         windowinfo.fontsize = 12;
00297         
00298         /*
00299         copystring ("\x07" "Chicago", (ptrstring) windowinfo.fontname);
00300         */
00301         
00302         fontgetname (systemFont, (ptrstring) windowinfo.fontname);
00303         }
00304     
00305     (**hc).windowinfo [ixwindowinfo] = windowinfo;
00306     } /*ccinitwindowinfo*/
00307 
00308 
00309 static void ccupdatewindowinfo (short windowtype, tyversion2cancoonrecord *info) {
00310     
00311     /*
00312     2/8/91 dmb: subwindows now can have a save routine, which we call to 
00313     allow strings to be saved into cancoondata before we update the db
00314     
00315     5.0d14 dmb: clean the window's menu item
00316     */
00317     
00318     tycancoonwindowinfo windowinfo;
00319     Rect r;
00320     
00321     ccgetwindowinfo (windowtype, &windowinfo);
00322     
00323     if (windowinfo.w != nil) {
00324         
00325         shellpushglobals (windowinfo.w);
00326         
00327         (*shellglobals.presaveroutine) ();
00328         
00329         windowinfo.flhidden = (**shellwindowinfo).flhidden;
00330 
00331         shellpopglobals ();
00332         
00333         getglobalwindowrect (windowinfo.w, &r);
00334         
00335         recttodiskrect (&r, &windowinfo.windowrect);
00336         
00337         windowsetchanges (windowinfo.w, false);
00338         }
00339     
00340     diskgetfontname (windowinfo.fontnum, windowinfo.fontname);
00341     
00342     (*info).windowinfo [windowtype] = windowinfo; /*copy into disk record*/
00343     
00344     memtodiskshort ((*info).windowinfo [windowtype].fontsize);
00345     memtodiskshort ((*info).windowinfo [windowtype].fontstyle);
00346     
00347     ccsetwindowinfo (windowtype, windowinfo); /*update in-memory version*/
00348     } /*ccupdatewindowinfo*/
00349 
00350 
00351 static boolean ccactivatemenubar (hdlcancoonrecord hcancoon, boolean flactivate) {
00352     
00353     if (hcancoon == nil)
00354         return (false);
00355     
00356     return (activatemenubarlist ((**hcancoon).hmenubarlist, flactivate));
00357     } /*ccactivatemenubar*/
00358 
00359 
00360 static boolean disposecancoonrecord (hdlcancoonrecord hcancoon) {
00361     
00362     /*
00363     1/21/91 dmb: even though disposing the root table will dispose of 
00364     the menu bar, we need to explicitly deactivate the menu bar here 
00365     in case the language postpones the table disposal until the current 
00366     process terminates (which may be after another menu bar has been 
00367     activated).
00368     
00369     1/28/91 dmb: we were forgeting to dispose the script and message strings.
00370     
00371     5.0.1 dmb: fixed leak - use tabledisposetable, not disposehashtable
00372 
00373     5.1 dmb: fixed leak - disposehandle of the rootvariable itself
00374     */
00375     
00376     register hdlcancoonrecord hc = hcancoon;
00377     
00378     if (hc == nil)
00379         return (false);
00380     
00381     ccactivatemenubar (hc, false);
00382     
00383     disposeprocesslist ((**hc).hprocesslist); /*checks for nil*/
00384     
00385     //setcurrentmenubarlist (nil); /*clear menubar.c global before disposing roottable*/
00386     
00387     disposehandle ((Handle) (**hc).hmenubarlist); /*roottable disposal will do menubars*/
00388     
00389     tabledisposetable ((**hc).hroottable, false); /*yup, checks for nil*/
00390     
00391     disposehandle ((Handle) (**hc).hrootvariable); /*5.1*/
00392 
00393     disposehandle ((Handle) (**hc).hscriptstring); /*always has, always will*/
00394     
00395     disposehandle ((Handle) (**hc).hprimarymsg);
00396     
00397     disposehandle ((Handle) (**hc).hsecondarymsg);
00398     
00399     disposehandle ((Handle) hc);
00400     
00401     return (true);
00402     } /*disposecancoonrecord*/
00403 
00404 
00405 static boolean newcancoonrecord (hdlcancoonrecord *hcancoon) {
00406     
00407     register hdlcancoonrecord hc;
00408     short i;
00409     hdlprocesslist hprocesslist;
00410     hdlmenubarlist hmenubarlist;
00411     
00412     if (!newclearhandle (sizeof (tycancoonrecord), (Handle *) hcancoon))
00413         return (false);
00414     
00415     hc = *hcancoon;
00416     
00417     if (!newprocesslist (&hprocesslist)) 
00418         goto error;
00419     
00420     (**hc).hprocesslist = hprocesslist;
00421     
00422     if (!newmenubarlist (&hmenubarlist))
00423         goto error;
00424     
00425     (**hc).hmenubarlist = hmenubarlist;
00426     
00427     for (i = 0; i < ctwindowinfo; i++) 
00428         ccinitwindowinfo (hc, i);
00429             
00430     return (true);
00431     
00432     error:
00433     
00434     disposecancoonrecord (hc);
00435     
00436     *hcancoon = nil;
00437     
00438     return (false);
00439     } /*newcancoonrecord*/
00440 
00441 
00442 static boolean ccinstalltablestructure (boolean flhavehost) {
00443     
00444     /*
00445     12/31/90 dmb: since this routine can be executing in the background, 
00446     while the language is evaluating an expression, we now use setroothashtable, 
00447     replacing setcurrenthashtable
00448     
00449     1/8/91 dmb: in fact, a cleaner and more reliable solution is to leave it 
00450     up to the language to always push the root table before running any code, 
00451     so setroothashtable is gone.
00452     
00453     5.1b23 dmb: added serial number checking
00454     */
00455     
00456     register hdlcancoonrecord hc = cancoondata;
00457     
00458     assert ((**hc).hroottable == roottable); /*should already be set up*/
00459     
00460     setcurrentprocesslist ((**hc).hprocesslist);
00461     
00462     if (!flhavehost && !validateserialnumber ()) {
00463         
00464         exittooperatingsystem ();
00465 
00466         return (false);
00467         }
00468     
00469     loadsystemscripts (); /*load agents, compile handlers, run startup scripts, etc.*/
00470     
00471 #ifndef PIKE
00472     #if TARGET_API_MAC_CARBON == 0
00473     langipcmenustartup ();
00474     #endif
00475 #endif
00476     
00477     return (true);
00478     } /*ccinstalltablestructure*/
00479 
00480 
00481 static boolean ccinstallmenubar (hdlcancoonrecord hcancoon, hdlmenurecord hmenurecord) {
00482     
00483     /*
00484     5.0d14 dmb: with the introduction of beginner/expert modes, it no longer
00485     makes sense for Frontier to automatically install system.misc.menubar
00486     
00487     5.0a2 dmb: restored functionality, but now we're only called for old odbs
00488     */
00489     
00490     setcurrentmenubarlist ((**hcancoon).hmenubarlist);
00491     
00492     if (hmenurecord == nil) /*we're done*/
00493         return (true);
00494     
00495     assert ((**hmenurecord).hmenustack == nil);
00496     
00497     return (meinstallmenubar (hmenurecord));
00498     } /*ccinstallmenubar*/
00499 
00500 
00501 static boolean ccloadsystemtable (hdlcancoonrecord hcancoon, dbaddress adr, boolean flcreate) {
00502     
00503     /*
00504     some factored code.  try to load the root table from adr and find or 
00505     create the standard global tables
00506     */
00507     
00508     register hdlcancoonrecord hc = hcancoon;
00509     register boolean fl;
00510     Handle hvariable;
00511     hdlhashtable htable;
00512     
00513     fldisablesymbolcallbacks = true; /*so table insertions wont trigger callbacks*/
00514     
00515     fl = tableloadsystemtable (adr, &hvariable, &htable, flcreate);
00516     
00517     if (fl) {
00518         
00519         (**hc).hrootvariable = hvariable;
00520         
00521         (**hc).hroottable = htable;
00522         
00523         assert (tablevalidate (htable, true));
00524         
00525         fl = settablestructureglobals (hvariable, flcreate) || !flcreate;
00526         }
00527     
00528     fldisablesymbolcallbacks = false;
00529     
00530     return (fl);
00531     } /*ccloadsystemtable*/
00532 
00533 
00534 void setcancoonglobals (hdlcancoonrecord hcancoon) {
00535     
00536     /*
00537     5.0a18 dmb: added nil check, set globals to nill in that case
00538     */
00539 
00540     register hdlcancoonrecord hc = hcancoon;
00541     
00542     if (hc != nil) {
00543 
00544         databasedata = (**hc).hdatabase;
00545 
00546         settablestructureglobals ((**hc).hrootvariable, false);
00547 
00548         setcurrentprocesslist ((**hc).hprocesslist);
00549 
00550         setcurrentmenubarlist ((**hc).hmenubarlist);
00551         }
00552     
00553     cancoonglobals = hc; /*this global is independent of shellpush/popglobals*/
00554     } /*setcancoonglobals*/
00555 
00556 
00557 static void clearcancoonglobals (void) {
00558     
00559     databasedata = nil; /*db.c*/
00560     
00561     setcurrentprocesslist (nil); /*agents.c*/
00562     
00563     cleartablestructureglobals (); /*tablestructure.c: roottable, handlertable, etc.*/
00564     
00565     setcurrentmenubarlist (nil); /*menubar.c*/
00566     
00567     cancoonglobals = nil; /*our very own superglobal*/
00568     
00569     supercancoonglobals = nil;  /*the ones swapped in with ccsetsuperglobals*/
00570     } /*clearcancoonglobals*/
00571 
00572 
00573 static boolean loadversion2cancoonfile (dbaddress adr, hdlcancoonrecord hcancoon, boolean flhavehost) {
00574     
00575     /*
00576     5.0d14 dmb: bumped cancoonversionnumber; hscriptstring is now a text handle, 
00577     not a string handle. (no 255 char limit)
00578     
00579     5.0d18 dmb: have to ccwindowsetup _after_ loading system table now
00580     
00581     5.0a2 dmb: install the menubar if the database hasn't been upgraded
00582     
00583     2002-11-11 AR: Added additional asserts to make sure the C compiler chose the
00584     proper byte alignment for the tycancoonwindowinfo and tyversion2cancoonrecord
00585     struct. If it did not, we would end up corrupting any database files we saved.
00586     */
00587     
00588     register hdlcancoonrecord hc;
00589     tyversion2cancoonrecord info;
00590     short i;
00591     hdlmenurecord hmenurecord = nil;
00592     hdlstring hstring;
00593     boolean flguest;
00594     boolean frontier4root;
00595     
00596     assert (sizeof (tycancoonwindowinfo) == 62); /* one padding byte after fontname which is 33 bytes long */
00597     
00598     assert (sizeof (tyversion2cancoonrecord) == 442);
00599     
00600     assert (sizeof (tyversion2cancoonrecord) == sizeof (tyOLD42version2cancoonrecord));
00601     
00602     if (!dbreference (adr, sizeof (info), &info))
00603         return (false);
00604     
00605     disktomemshort (info.versionnumber);
00606     disktomemlong (info.adrroottable);
00607     disktomemlong (info.adrscriptstring);
00608     disktomemshort (info.ixprimaryagent);
00609     
00610     hc = hcancoon; /*copy into register*/
00611     
00612     for (i = 0; i < ctwindowinfo; i++) { /*copy info.windowinfo into hc, with filtering*/
00613         
00614         tycancoonwindowinfo windowinfo;
00615         
00616         windowinfo = info.windowinfo [i]; /*copy record out of its array*/
00617         
00618         disktomemshort (windowinfo.fontsize);
00619         disktomemshort (windowinfo.fontstyle);
00620         
00621         windowinfo.w = nil; /*pointers stored on disk are invalid*/
00622         
00623         diskgetfontnum (windowinfo.fontname, &windowinfo.fontnum);
00624         
00625         (**hc).windowinfo [i] = windowinfo;
00626         } /*for*/
00627     
00628     /*cancooninitwindowinfo (hc, ixunused2);*/ 
00629     
00630     frontier4root = info.versionnumber < 3;
00631     
00632     if (frontier4root) {
00633         
00634         bigstring bsprompt;
00635         
00636         shellgetstring (openolddatabasestring, bsprompt);
00637         
00638         if (!twowaydialog (bsprompt, BIGSTRING ("\x07" "Convert"), BIGSTRING ("\x06" "Cancel")))
00639             return (false);
00640         
00641         dbrefheapstring (info.adrscriptstring, &hstring);
00642         
00643         pullfromhandle ((Handle) hstring, 0, 1, nil); // pluck out the length byte
00644         }
00645     else
00646         dbrefhandle (info.adrscriptstring, (Handle *) &hstring);
00647     
00648     (**hc).hscriptstring = (Handle) hstring;
00649     
00650     (**hc).flflagdisabled = (info.flags & flflagdisabled_mask) != 0;
00651     
00652     (**hc).flpopupdisabled = (info.flags & flpopupdisabled_mask) != 0;
00653     
00654     (**hc).flbigwindow = (info.flags & flbigwindow_mask) != 0;
00655     
00656     ccwindowsetup ((**hc).flbigwindow, frontier4root); /*use info from the windowinfo array*/
00657     
00658     if (!ccloadsystemtable (hc, info.adrroottable, !flhavehost))
00659         return (false);
00660     
00661     flguest = systemtable == nil;
00662     
00663     #ifdef fltrialsize
00664 
00665     if (flguest) {
00666         
00667         (**cancoonwindowinfo).hdata = nil; /*unlink data from window to avoid crash*/
00668         
00669         shelltrialerror (noguestdatabasesstring);
00670 
00671         return (false);
00672         }
00673 
00674     #endif
00675     
00676     if (!flguest) {
00677         
00678         linksystemtablestructure (roottable);
00679         
00680         if (frontier4root) {
00681             
00682             if (resourcestable != nil)
00683                 if (menugetmenubar (resourcestable, namemenubar, false, &hmenurecord))
00684                     ccinstallmenubar (hc, hmenurecord); /*ignore error*/
00685             }
00686         
00687         if (ccinstalltablestructure (flhavehost))
00688             ccsetprimaryagent (info.ixprimaryagent);
00689         else
00690             return (false); /*6.1b4 AR: Fix crash after cancelling serial number dialog (at least on Win32)*/
00691         }
00692     
00693     (**hc).flguestroot = flguest;
00694     
00695     return (true);
00696     } /*loadversion2cancoonfile*/
00697 
00698 
00699 #if 0 //def MACVERSION
00700 
00701 static boolean loadoldcancoonfile (dbaddress adr, hdlcancoonrecord hcancoon) {
00702     
00703     tyfilespec fs, fsold;
00704     boolean fl;
00705     
00706     if (!msgdialog ("\50" "Convert 4.x database to 5.0? (This can take a while. A backup will be retained.)"))
00707         return (false);
00708     
00709     if (!loadversion2cancoonfile (adr, hcancoon))
00710         return (false);
00711     
00712     windowgetfspec (cancoonwindow, &fs);
00713     
00714     fsold = fs;
00715     
00716     pushstring ("\x04" ".v4x", fs.name);
00717     
00718     flconvertingolddatabase = true;
00719     
00720     fl = shellsaveas (cancoonwindow, &fs);
00721     
00722     flconvertingolddatabase = false;
00723     
00724     if (!fl)
00725         return (false);
00726     
00727     oserror (FSpExchangeFiles (&fs, &fsold)); // ignore, but report error
00728     
00729     windowsetfspec (cancoonwindow, &fsold); // the old fspec is now the new file
00730     
00731     return (true);
00732     } /*loadoldcancoonfile*/
00733 
00734 #endif
00735 
00736 #ifdef fltrialsize
00737     
00738 static boolean cctrialviolation (void) {
00739 
00740     long eof;
00741     
00742     dbgeteof (&eof);
00743     
00744     if (eof > 7 * 0x0100000) {
00745         
00746         shelltrialerror (dbsizelimitstring);
00747         
00748         return (true);
00749         }
00750     
00751     return (false);
00752     } /*cctrialviolation*/
00753 
00754 #endif
00755 
00756 boolean ccloadfile (hdlfilenum fnum, short rnum) {
00757 #pragma unused(rnum)
00758 
00759     /*
00760     9/15/92 dmb: removed support for version1 format; it never shipped
00761   
00762     6.1fc2 AR: Don't link cancoondata into (**cancoonwindowinfo).hdata.
00763                This would crash some installations during the initialization
00764                of the serial number dialog.
00765                hdata should be a hdltableformats anyway.
00766     */
00767     
00768     register hdlcancoonrecord hc = nil;
00769     dbaddress adr;
00770     short versionnumber;
00771     hdlcancoonrecord origglobals = cancoonglobals;
00772     boolean flhavehost = origglobals != nil;
00773     boolean flhide;
00774     
00775     cancoondata = nil; /*default error return*/
00776     
00777     if (!dbopenfile (fnum, false))
00778         return (false);
00779     
00780     #ifdef fltrialsize
00781         
00782         if (cctrialviolation ()) {
00783             
00784             if (!flhavehost)
00785                 shellexitmaineventloop ();
00786             
00787             goto error;
00788             }
00789     
00790     #endif
00791     
00792     dbgetview (cancoonview, &adr);
00793     
00794     if (!dbreference (adr, sizeof (versionnumber), &versionnumber))
00795         goto error;
00796     
00797     disktomemshort (versionnumber);
00798 
00799     if (!newcancoonrecord (&cancoondata))
00800         goto error;
00801     
00802     hc = cancoondata; /*copy into register*/
00803     
00804     //(**cancoonwindowinfo).hdata = (Handle) hc; /*link data to window*/
00805     
00806     (**hc).hdatabase = databasedata; /*result from dbopenfile*/
00807     
00808     switch (versionnumber) {
00809         
00810         /*
00811         case 1:
00812             if (!loadversion1cancoonfile (adr, hc))
00813                 goto error;
00814             
00815             return (true);
00816         */
00817         
00818         case 2:
00819         case cancoonversionnumber:
00820             if (!loadversion2cancoonfile (adr, hc, flhavehost))
00821                 goto error;
00822             
00823             if ((**hc).flguestroot)
00824                 setcancoonglobals (origglobals); /*restore databasedata, etc.*/
00825             
00826             else {
00827 
00828                 flhide = !ccinexpertmode () || (**hc).windowinfo [ixcancooninfo].flhidden;
00829                 
00830                 (**cancoonwindowinfo).flhidden = flhide;
00831                 }
00832             
00833             // ccnewfilewindow (idscriptprocessor);
00834             
00835             return (true);
00836         
00837         default:
00838             alertstring (baddatabaseversionstring);
00839             
00840             goto error;
00841         } /*switch*/
00842     
00843     error:
00844     
00845     dbdispose ();
00846     
00847     clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
00848     
00849     disposecancoonrecord (hc); /*checks for nil*/
00850     
00851     setcancoonglobals (origglobals); /*restore databasedata, etc.*/
00852     
00853     return (false);
00854     } /*ccloadfile*/
00855 
00856 
00857 boolean ccloadspecialfile (ptrfilespec fspec, OSType filetype) {
00858 #pragma unused (filetype)
00859 
00860     /*
00861     7/28/92 dmb: use new finder2frontscript to set the Frontier.findertofront 
00862     global, instead of having Frontier.finder2click always set it to true. also, 
00863     handle updates now.
00864     
00865     2.1b3 dmb: only set finder2front to true if the sender of the 'odoc' event  
00866     was the Finder
00867     */
00868     
00869     bigstring bspath;
00870     bigstring bs;
00871     ptrbyte pbool;
00872     
00873     if (!shellsetsuperglobals ()) {
00874         
00875         if (!shellopendefaultfile () || !shellsetsuperglobals ()) {
00876             
00877             getstringlist (langerrorlist, needopendberror, bs);
00878     
00879             shellerrormessage (bs);
00880 
00881             return (false);
00882             }
00883         }
00884     
00885     if (!filespectopath (fspec, bspath)) {
00886         
00887         filenotfounderror ((ptrstring) fsname (fspec));
00888         
00889         return (false);
00890         }
00891     
00892     langdeparsestring (bspath, chclosecurlyquote); /*add needed escape sequences*/
00893     
00894     if (getsystemtablescript (idfinder2frontscript, bs)) { /*frontier.findertofront=^0*/
00895         
00896     #ifdef MACVERSION
00897         if ((shellevent.what == kHighLevelEvent) && ((**landgetglobals ()).maceventsender == 'MACS'))
00898             pbool = bstrue;
00899         else
00900     #endif
00901             pbool = bsfalse;
00902         
00903         parsedialogstring (bs, pbool, nil, nil, nil, bs);
00904         
00905         langrunstringnoerror (bs, bs);
00906         }
00907     
00908     if (!getsystemtablescript (idfinder2clickscript, bs)) /*frontier.finder2click ("^0")*/
00909         return (false);
00910     
00911     parsedialogstring (bs, bspath, nil, nil, nil, bs);
00912     
00913     shellpartialeventloop (updateMask); /*handle updates first*/
00914     
00915     return (processrunstring (bs));
00916     } /*ccloadspecialfile*/
00917 
00918 
00919 boolean ccsavespecialfile (ptrfilespec fs, hdlfilenum fnum, short rnum, boolean flsaveas, boolean flrunnable) {
00920 #pragma unused(flsaveas, rnum)
00921 
00922     /*
00923     6.17.97 dmb: this is called by opverbs, wpverbs, etc. to save a disk file.
00924     we leave it to the system.misc.saveWindow script to package the data, 
00925     but we take care of writing it. (our caller did the file creation.)
00926     
00927     note: if we decide to make this more open architecture, we could add 
00928     another flat for the config record that would prevent the shell from 
00929     opening the data fork for us. then, we'd need to make this callback 
00930     take the destination filespec as a parameter too, and the saveWindow script
00931     would take both the window name and the filespec (which would be the same
00932     for a normal save).
00933     
00934     5.0.2b6 dmb: error checking on openfile
00935     
00936     5.0.2b8 dmb: don't unregister the window until we're about to set the new path
00937     */
00938     
00939     bigstring bs, bspath;
00940     ptrstring bsrunnable;
00941     tyvaluerecord val;
00942     Handle hscript;
00943     boolean fl = false;
00944     boolean flopenedfile = false;
00945     hdlexternalvariable hv;
00946     
00947     (*shellglobals.getvariableroutine) ((Handle *) &hv);
00948     
00949 //  if (hv != nil)
00950 //      langexternalunregisterwindow (shellwindowinfo);
00951     
00952     if (!windowgetpath (shellwindow, bspath))
00953         shellgetwindowtitle (shellwindowinfo, bspath);
00954     
00955     langdeparsestring (bspath, chclosecurlyquote); /*add needed escape sequences*/
00956 
00957     if (!getsystemtablescript (idsavewindowscript, bs)) /*system.misc.saveWindow ("^0","^1")*/
00958         return (false);
00959     
00960     bsrunnable = (flrunnable? bstrue : bsfalse);
00961 
00962     parsedialogstring (bs, bspath, bsrunnable, nil, nil, bs);
00963     
00964     if (!newtexthandle (bs, &hscript))
00965         return (false);
00966     
00967     pushprocess (nil);
00968     
00969     fl = langrun (hscript, &val);
00970     
00971     popprocess ();
00972     
00973     if (!fl)
00974         return (false);
00975     
00976     pushhashtable (roottable); /*need temp stack services*/
00977     
00978     pushvalueontmpstack (&val);
00979     
00980     if (coercetostring (&val)) {
00981         
00982         if (fnum == 0) {
00983         
00984             fl = openfile (fs, &fnum, false);
00985             
00986             flopenedfile = fl;
00987             }
00988         
00989         if (fl)
00990             fl = 
00991                 fileseteof (fnum, 0) &&
00992                 
00993                 filesetposition (fnum, 0) &&
00994                 
00995                 filewritehandle (fnum, val.data.stringvalue);
00996         
00997         if (flopenedfile)
00998             closefile (fnum);
00999         }
01000     
01001     cleartmpstack ();
01002     
01003     pophashtable ();
01004     
01005     if (hv != nil)
01006         langexternalunregisterwindow (shellwindowinfo);
01007     
01008     if (fl)
01009         windowsetfspec (shellwindow, fs);
01010     
01011     if (hv != nil)
01012         langexternalregisterwindow (hv);
01013     
01014     return (fl);
01015     } /*ccsavespecialfile*/
01016 
01017 
01018 boolean ccnewrecord (void) {
01019     
01020     /*
01021     5.1.5b12 dmb: save the new structure after it's created, so if we crash we don't leave junk.
01022     */
01023     
01024     register hdlcancoonrecord hc;
01025     hdlcancoonrecord origglobals = cancoonglobals;
01026     hdltablevariable hvariable;
01027     hdlhashtable htable;
01028     hdlfilenum fnum;
01029     
01030     cancoondata = nil; /*default error return*/
01031     
01032     if (!newcancoonrecord (&cancoondata))
01033         return (false);
01034     
01035     hc = cancoondata; /*copy into register*/
01036     
01037     cancoonglobals = hc; // 5.0a2 dmb: need this for more consistent state
01038     
01039     (**cancoonwindowinfo).hdata = (Handle) hc; /*link data to window*/
01040     
01041     fnum = windowgetfnum (cancoonwindow);
01042     
01043     if (!dbnew (fnum))
01044         goto error;
01045     
01046     dbsetview (cancoonview, nildbaddress);
01047     
01048     (**hc).hdatabase = databasedata;
01049     
01050     ccwindowsetup (false, true); /*init info in the windowinfo array*/
01051     
01052     if (!tablenewtable (&hvariable, &htable)) /*this will be the root table*/
01053         goto error;
01054     
01055     (**hvariable).id = idtableprocessor;
01056     
01057     (**hc).hrootvariable = (Handle) hvariable;
01058     
01059     (**hc).hroottable = htable;
01060     
01061     (**hc).flguestroot = true;
01062     
01063     if (!ccsavefile (nil, fnum, -1, false, false)) // 5.1.5b12
01064         goto error;
01065     
01066     setcancoonglobals (origglobals); /*restore databasedata, etc.*/
01067     
01068     return (true);
01069     
01070     error:
01071     
01072     dbdispose ();
01073     
01074     clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
01075     
01076     disposecancoonrecord (hc);
01077     
01078     setcancoonglobals (origglobals); /*restore databasedata, etc.*/
01079     
01080     return (false);
01081     } /*ccnewrecord*/
01082 
01083 
01084 boolean ccnewfilewindow (tyexternalid id, WindowPtr *w, boolean flhidden) {
01085     
01086     tyvaluerecord val;
01087     hdlwindowinfo hinfo;
01088     
01089     if (!langexternalnewvalue (id, nil, &val))
01090         return (false);
01091     
01092     langexternalsetdirty ((hdlexternalhandle) val.data.externalvalue, false);
01093     
01094     if (!langexternalzoomfilewindow (&val, nil, flhidden)) {
01095         
01096         disposevaluerecord (val, false);
01097         
01098         return (false);
01099         }
01100     
01101     if (!langexternalwindowopen (val, &hinfo)) //shouldn't ever fail
01102         return (false);
01103     
01104     *w = (**hinfo).macwindow;
01105     
01106     return (true);
01107     } /*ccnewfilewindow*/
01108 
01109 
01110 boolean ccsavefile (ptrfilespec fs, hdlfilenum fnum, short rnum, boolean flsaveas, boolean flrunnable) {
01111 #pragma unused(fs, rnum, flrunnable)
01112 
01113     /*
01114     5.0b18 dmb: last-minute fix. we crash when saving while publishing a table.
01115     the problem is that we toss stuff out during a save, and it would be nearly 
01116     impossible to protect against that everywhere. so we use processwaitforquiet
01117     and try to be the only thread using globals
01118     
01119     5.1.5b7 dmb: disabled above "fix". we now rely on shellwindowinfo and 
01120     outlinedata push/pop protection, fldispoosewhenpopped flags
01121     */
01122 
01123     register hdlcancoonrecord hc = cancoondata;
01124     tyversion2cancoonrecord info;
01125     dbaddress adr;
01126     short i;
01127     boolean fl = false;
01128     
01129     databasedata = (**hc).hdatabase;
01130 
01131     if (flsaveas) {
01132         
01133         if (!dbstartsaveas (fnum))
01134             return (false);
01135         
01136         adr = nildbaddress;
01137         }
01138     else
01139         dbgetview (cancoonview, &adr);
01140     
01141     if (adr == nildbaddress)
01142         clearbytes (&info, sizeof (info));
01143     else
01144         if (!dbreference (adr, sizeof (info), &info))
01145             goto exit; 
01146     
01147     disktomemlong (info.adrroottable);
01148     disktomemlong (info.adrscriptstring);
01149 
01150     info.versionnumber = conditionalshortswap (cancoonversionnumber);
01151     
01152     for (i = 0; i < ctwindowinfo; i++) 
01153         ccupdatewindowinfo (i, &info);
01154     
01155     /*
01156     if (!processwaitforquiet (120L)) { //wait up to 2 seconds 
01157         
01158         sysbeep ();
01159 
01160         goto exit;
01161         }
01162     */
01163     
01164     if (!tablesavesystemtable ((**hc).hrootvariable, &info.adrroottable))
01165         goto exit;
01166     
01167 #ifdef version42orgreater
01168     info.windowinfo [ixcancooninfo].flhidden = (**shellwindowinfo).flhidden;
01169 
01170     if (!dbassignhandle ((**hc).hscriptstring, &info.adrscriptstring))
01171         goto exit;
01172 #else
01173     if (!dbassignheapstring (&info.adrscriptstring, (**hc).hscriptstring))
01174         goto exit;
01175 #endif
01176     
01177     memtodisklong (info.adrroottable);
01178     memtodisklong (info.adrscriptstring);
01179 
01180     clearbytes (&info.waste, sizeof (info.waste));
01181     
01182     info.flags = 0;
01183     
01184     if ((**hc).flflagdisabled)
01185         info.flags |= flflagdisabled_mask;
01186     
01187     if ((**hc).flpopupdisabled)
01188         info.flags |= flpopupdisabled_mask;
01189     
01190     if ((**hc).flbigwindow)
01191         info.flags |= flbigwindow_mask;
01192     
01193     ccgetprimaryagent (&info.ixprimaryagent);
01194     
01195     memtodiskshort (info.ixprimaryagent);
01196     
01197     if (!dbassign (&adr, sizeof (info), &info))
01198         goto exit;
01199     
01200     if (!flsaveas)
01201         dbflushreleasestack (); /*release all the db objects that were saved up*/
01202     
01203     dbsetview (cancoonview, adr);
01204     
01205     fl = true; // success!
01206 
01207     #ifdef fltrialsize
01208         
01209         if (cctrialviolation ()) // just issue message
01210             ;
01211     
01212     #endif
01213     
01214     exit:
01215 
01216     if (flsaveas)
01217         dbendsaveas ();
01218     
01219     databasedata = (**cancoonglobals).hdatabase; // may not be same as cancoondata
01220     
01221     return (fl);
01222     } /*ccsavefile*/
01223 
01224 
01225 boolean ccfindusedblocks (void) {
01226     
01227     tyversion2cancoonrecord info;
01228     dbaddress adr;
01229     
01230     dbgetview (cancoonview, &adr);
01231     
01232     if (adr != nildbaddress) {
01233         
01234         if (!dbreference (adr, sizeof (info), &info))
01235             return (false);
01236 
01237         statsblockinuse (adr, nil);
01238         
01239         disktomemlong (info.adrscriptstring);
01240         
01241         if (!statsblockinuse (info.adrscriptstring, nil))
01242             return (false);
01243         }
01244     
01245     return (langexternalfindusedblocks ((hdlexternalvariable) (**cancoonglobals).hrootvariable, nil));
01246     } /*ccfindusedblocks*/
01247 
01248 
01249 boolean ccsetdatabase (void) {
01250 
01251     /*
01252     the cancoon window should be the only one that defines this callback.  it sets 
01253     db.c's global data handle to the database file that stores the menubar structure.
01254     
01255     this is used for other handlers who store data in our database.
01256 
01257     5.0a18 dmb: this is archaic, really. we manage databasedata ourselves, we don't 
01258     rely on the shell. with the new odb hosting feature, we need to wire this off
01259     and add some logic to ccsave
01260     */
01261     
01262     #ifndef version5orgreater
01263         databasedata = (**cancoondata).hdatabase;
01264     #endif
01265     
01266     return (true);
01267     } /*ccsetdatabase*/
01268 
01269 
01270 boolean ccgetdatabase (hdldatabaserecord *hdatabase) {
01271 
01272     /*
01273     5.0.2b21 dmb: the new way to do it
01274     */
01275     
01276     *hdatabase = (**cancoondata).hdatabase;
01277     
01278     return (true);
01279     } /*ccsetdatabase*/
01280 
01281 
01282 boolean ccclose (void) {
01283     
01284     /*
01285     the main window of cancoon is closing.
01286     */
01287     
01288 #ifdef version5orgreater
01289 //  hdlwindowinfo hw = cancoonwindowinfo;
01290 //
01291 //  ccsavefile ((**hw).fnum, (**hw).rnum, false, false);    //odbSaveFile (ccodb);
01292 
01293     if ((cancoondata != nil) && (**cancoondata).flguestroot)  //defensive driving
01294         return (true);
01295 #endif
01296 
01297     runshutdownscripts ();
01298     
01299     langexternalcloseregisteredwindows (false);
01300     
01301     return (true);
01302     } /*ccclose*/
01303 
01304 
01305 static boolean ccverifywindowclose (WindowPtr pwindow) {
01306     
01307     /*
01308     4.0b7 dmb: new feature, run a script before we close a window
01309     */
01310     
01311     if (flinhibitclosedialogs)  /*not allowed to do verification*/
01312         return (true);
01313     
01314     if (flscriptrunning)        /*not a user-generated close*/
01315         return (true);
01316     
01317     return (shellrunwindowconfirmationscript (pwindow, idclosewindowscript));
01318     } /*ccverifywindowclose*/
01319 
01320 
01321 boolean ccpreclose (WindowPtr w) {
01322     
01323     /*
01324     4.1b5 dmb: new callback so we can verify root close (i.e. so 
01325     script can save it first, to avoid dialog
01326     */
01327     
01328     if (!ccverifywindowclose (w))
01329         return (false);
01330     
01331     if (cancoondata == nil) //5.1.5b15 dmb
01332         return (true);
01333     
01334     if ((**cancoondata).flguestroot)
01335         return (true);
01336     
01337     return (langexternalcloseregisteredwindows (true));
01338     } /*ccpreclose*/
01339 
01340 
01341 boolean ccchildclose (WindowPtr w) {
01342     
01343     /*
01344     a child window of cancoon is closing.  
01345     
01346     for now (6/12/90) just call the close routine on the child window.
01347     
01348     9/24/91 dmb: pass through return value from child
01349     
01350     12/5/91 dmb: call the child's dispose record routine too
01351     */
01352     
01353     boolean fl;
01354     
01355     if (!ccverifywindowclose (w))
01356         return (false);
01357     
01358     shellpushglobals (w);
01359     
01360     fl = (*shellglobals.closeroutine) ();
01361     
01362     if (fl) {
01363 
01364         fl = (*shellglobals.disposerecordroutine) ();
01365         
01366         shellclearwindowdata ();
01367         }
01368     
01369     shellpopglobals ();
01370     
01371     return (fl);
01372     } /*ccchildclose*/
01373 
01374 
01375 boolean ccdisposerecord (void) {
01376     
01377     /*
01378     1/22/91 dmb: added scan of new ccglobalsstack
01379     
01380     2.1b5 dmb: set windowinfo's data to nil; fixes revert bug when window is 
01381     updated between disposal & re-opening
01382 
01383     5.1.5b16 dmb: kill dependent processes before swapping in our globals, or
01384     visitprocessthreads will make the current thread appear to be dependent on them.
01385     */
01386     
01387     register hdlcancoonrecord hc = cancoondata;
01388     hdlcancoonrecord origglobals = cancoonglobals;
01389     boolean flguestroot;
01390     
01391     if (hc == NULL)
01392         return (true);
01393     
01394     fwsNetEventShutdownDependentListeners ((long) (**hc).hdatabase);
01395     
01396     killdependentprocesses ((long) hc);
01397 
01398     setcancoonglobals (hc); /*make sure superglobals are ours*/
01399     
01400     flguestroot = (**hc).flguestroot;
01401     
01402 //#ifndef WIN95VERSION
01403     if (!flguestroot)
01404         processyieldtoagents (); /*let them terminate*/
01405 //#endif
01406     
01407     dbdispose (); /*do before clearing globals -- depends on databasedata*/
01408     
01409     fldisablesymbolcallbacks = true;
01410     
01411     if (!flguestroot) {
01412         
01413 #ifndef PIKE
01414         #if TARGET_API_MAC_CARBON == 0
01415         langipcmenushutdown ();
01416         #endif
01417         
01418 #endif
01419         
01420         unlinksystemtablestructure ();
01421         }
01422     
01423     clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
01424     
01425     disposecancoonrecord (hc);
01426     
01427     cancoondata = nil;
01428 
01429     (**cancoonwindowinfo).hdata = nil; /*unlink data from window*/
01430     
01431     fldisablesymbolcallbacks = false;
01432     
01433     bundle { /*scan saved globals so ccrestoreglobals knows when data is valid*/
01434         
01435         register short i;
01436         
01437         for (i = 0; i < cctopglobals; i++)
01438             if (ccglobalsstack [i] == hc)
01439                 ccglobalsstack [i] = nil;
01440         }
01441     
01442     if (origglobals != hc)
01443         setcancoonglobals (origglobals);
01444     
01445     return (true);
01446     } /*ccdisposerecord*/
01447 
01448 
01449 boolean ccdisposefilerecord (void) {
01450     
01451     hdlwindowinfo hw = shellwindowinfo;
01452     Handle x;
01453     tyvaluerecord val;
01454     
01455     if ((**hw).parentwindow != nil) // not standalone, nothing to do
01456         return (true);
01457     
01458     if (!(*shellglobals.getvariableroutine) (&x))
01459         return (false);
01460     
01461     setexternalvalue (x, &val);
01462     
01463     langexternaldisposevalue (val, false);
01464     
01465     shellclearwindowdata (); //shouldn't be necessary, since we're called by a disposerecordroutine
01466     
01467     return (true);
01468     } /*ccdisposefilerecord*/
01469 
01470     
01471 boolean ccsetsuperglobals (void) {
01472     
01473     /*
01474     the cancoon window should be the only one that defines this callback.  it sets
01475     the cancoon.c global "cancoonglobals" to the one linked into our table.
01476     
01477     10/2/90 dmb: this can get called from cancoonbackground on a failure condition 
01478     during cancoonloadfile, so we need to check cancoondata for nil
01479     
01480     10/23/91 dmb: when cancoondata is nil, make sure we clear globals
01481     
01482     4.1b4 dmb: set and respect new supercancoonglobals global so we can handle 
01483     the case where our globals are already set, but they weren't set "super", 
01484     meaning the menubar was activated.
01485     */
01486     
01487     register hdlcancoonrecord hc = cancoondata;
01488     
01489     if (hc == nil) {
01490         
01491         clearcancoonglobals (); /*clears everything relevant*/
01492         
01493         return (false);
01494         }
01495     
01496     if (hc != supercancoonglobals && !(**hc).flguestroot) {
01497         
01498         ccactivatemenubar (cancoonglobals, false);
01499         
01500         setcancoonglobals (hc);
01501         
01502         ccactivatemenubar (hc, true);
01503         
01504         supercancoonglobals = hc;
01505         }
01506     
01507     return (true);
01508     } /*ccsetsuperglobals*/
01509 
01510 
01511 boolean ccbackground (void) {
01512     
01513     /*
01514     2.1b2 dmb: added call to new langerrorflush
01515     */
01516     
01517     if (!shellsetsuperglobals ())
01518         return (false);
01519     
01520     processscheduler (); /*give the next process a shot at the machine*/
01521     
01522     langerrorflush (); /*make sure lang error is displayed*/
01523     
01524     return (true);
01525     } /*ccbackground*/
01526 
01527 
01528 boolean ccfnumchanged (hdlfilenum newfnum) {
01529 #ifdef version5orgreater
01530 #   pragma unused (newfnum)
01531 #endif
01532 
01533     /*
01534     part of the implementation of Save As
01535 
01536     5.0a18 dmb: no, it's not. it's never called.
01537     */
01538     
01539     #ifdef version5orgreater
01540         return (true);
01541     #else
01542         ccsetdatabase ();
01543     
01544         return (dbfnumchanged (newfnum));
01545     #endif
01546     } /*ccfnumchanged*/
01547 
01548 
01549 static boolean ccnewobjectcommand (short ixmenu) {
01550     
01551     /*
01552     "Script", noIcon, "N", noMark, plain,
01553     "WP-Text", noIcon, noKey, noMark, plain,
01554     "Outline", noIcon, noKey, noMark, plain,
01555     "Menubar", noIcon, noKey, noMark, plain,
01556     "Table", noIcon, noKey, noMark, plain,
01557     */
01558     
01559     tyexternalid idobject;
01560     WindowPtr w;
01561     
01562     switch (ixmenu) {
01563         case 1:
01564             idobject = idscriptprocessor;
01565             break;
01566         
01567         case 2:
01568             idobject = idwordprocessor;
01569             break;
01570         
01571         /*
01572         case 3:
01573             idobject = idpictprocessor;
01574             break;
01575         */
01576         
01577         case 3:
01578             idobject = idoutlineprocessor;
01579             break;
01580         
01581         case 4:
01582             idobject = idmenuprocessor;
01583             break;
01584         
01585         case 5:
01586             idobject = idtableprocessor;
01587             break;
01588         
01589         case 7:
01590             return (shellnew ());
01591         
01592         default:
01593             return (false);
01594         }
01595     
01596     return (ccnewfilewindow (idobject, &w, false));
01597     } /*ccnewobjectcommand*/
01598 
01599 
01600 boolean ccinexpertmode (void) {
01601     
01602     /*
01603     5.0a18 dmb: use new langgetuserflag
01604     */
01605     
01606     return (langgetuserflag (idinexpertmodescript, true));
01607     } /*ccinexpertmode*/
01608 
01609 
01610 #if 0
01611 
01612 static boolean cctoggleexpertmode (void) {
01613 
01614     /*
01615     5.0a3 dmb: we now call Frontier.setExpertMode, not system.misc.toggleExpertMode
01616     */
01617     
01618     bigstring bsscript;
01619     boolean flexpert;
01620     ptrstring bsexpert;
01621     
01622     flexpert = !ccinexpertmode ();
01623     
01624     getsystemtablescript (idtoggleexpertmodescript, bsscript);
01625     
01626     bsexpert = (flexpert? bstrue : bsfalse);
01627     
01628     parsedialogstring (bsscript, bsexpert, nil, nil, nil, bsscript);
01629     
01630     langrunstringnoerror (bsscript, bsscript);
01631     
01632     if (ccinexpertmode () != flexpert)
01633         return (false);
01634     
01635     shellwindowmenudirty ();
01636     
01637     return (true);
01638     } /*cctoggleexpertmode*/
01639 
01640 #endif
01641 
01642 
01643 static boolean ccmenuroutine (short idmenu, short ixmenu) {
01644     
01645     /*
01646     this is the only menu handling routine in the program.  we have no idea 
01647     what window is in front, it could be of any type -- so we must get our 
01648     own globals.
01649     
01650     return false if we successfully handle the menu item, so no further 
01651     processing will occur
01652     
01653     7/31/90 dmb:  must return result that is inverse of memenu result to obey 
01654     hook conventions.  we shouldn't assume that we're the only menu hook.
01655     
01656     8/1/90 dmb:  idmenu of zero means update all hooked menus.
01657     
01658     8/31/90 DW: preserve globals around call to memenu.
01659     
01660     9/20/90 dmb:  push frontrootglobals, rather than nil, and test the result
01661     
01662     5.0a18 dmb: disabled expert mode code (added in 5.0a?)
01663     */
01664     
01665     /*
01666     if (idmenu == 0 && ixmenu == 0) {
01667         
01668         hdlmenu hmenu = shellmenuhandle (filemenu);
01669         
01670         enablemenuitem (hmenu, expertitem);
01671         
01672         checkmenuitem (hmenu, expertitem, ccinexpertmode ());
01673         }
01674     
01675     if ((idmenu == filemenu) && (ixmenu == expertitem)) {
01676         
01677         cctoggleexpertmode ();
01678         
01679         return (false);
01680         }
01681     */
01682     
01683     /*
01684     if (!idmenu) { /%request to update all of our menus%/
01685         
01686         /%all our menus are enabled, dmb 8/1/90%/
01687         
01688         mecheckmenubar (); /%see if menubar needs to be redrawn%/
01689         
01690         return (true);
01691         }
01692     */
01693     
01694     if ((idmenu == virtualmenu) && (ixmenu == helpitem))
01695         return (!cchelpcommand ());
01696 
01697 #ifdef newobjectmenu    
01698     if (idmenu == newobjectmenu) {
01699         
01700         ccnewobjectcommand (ixmenu);
01701         
01702         return (false);
01703         }
01704 #endif
01705     
01706     #ifdef fldebug
01707     
01708     if (flscriptrunning && flcanusethreads) {
01709         
01710     // *** need this check? - DebugStr ("\x28" "handling menu w/script running in thread");
01711         
01712         return (true);
01713         }
01714     
01715     #endif
01716     
01717     return (!memenu (idmenu, ixmenu));
01718     } /*ccmenuroutine*/
01719 
01720 
01721 static boolean ccchecktablestructureglobals (hdlhashtable htable) {
01722     
01723     /*
01724     10/25/91 dmb: check table structure when something in the verbs table changes
01725 
01726     5.0a18 dmb: make sure we haven't just unloaded. maybe we're quitting
01727     and agents just terminated
01728     */
01729     
01730     register hdlhashtable ht = htable;
01731     
01732     if (fldisablesymbolcallbacks)
01733         return (false);
01734     
01735     if (roottable == nil)
01736         return (false);
01737 
01738     if ((ht == roottable) || (ht == systemtable) || (ht == verbstable))
01739         return (settablestructureglobals (rootvariable, false));
01740     
01741     return (true);
01742     } /*ccchecktablestructureglobals*/
01743 
01744 
01745 static boolean ccsymbolchanged (hdlhashtable htable, const bigstring bsname, hdlhashnode hnode, boolean flvalue) {
01746     
01747     /*
01748     used as a callback routine.  the value of the indicated variable has changed.
01749     if the cell is being displayed, update the display of it.  this is how the
01750     real-time changing of variables is implemented.
01751     
01752     2/28/91 dmb: also call ccchecktablestructureglobals to make sure our 
01753     globals are up to date
01754     
01755     11/14/01 dmb: also call new langexternalsymbolchanged. we should really create 
01756     a new callback so we don't have to call them explicitly here
01757     */
01758     
01759     if (!ccchecktablestructureglobals (htable))
01760         return (false);
01761     
01762     langipcsymbolchanged (htable, bsname, flvalue);
01763     
01764     langexternalsymbolchanged (htable, bsname, hnode, flvalue);
01765 
01766     return (tablesymbolchanged (htable, bsname, hnode, flvalue));
01767     } /*ccsymbolchanged*/
01768 
01769 
01770 static boolean ccsymbolinserted (hdlhashtable htable, const bigstring bsname, hdlhashnode hnode) {
01771     
01772     if (!ccchecktablestructureglobals (htable))
01773         return (false);
01774     
01775     langipcsymbolinserted (htable, bsname);
01776     
01777     langexternalsymbolinserted (htable, bsname, hnode);
01778 
01779     return (tablesymbolinserted (htable, bsname));
01780     } /*ccsymbolinserted*/
01781 
01782 
01783 static boolean ccsymboldeleted (hdlhashtable htable, const bigstring bsname) {
01784     
01785     if (!ccchecktablestructureglobals (htable))
01786         return (false);
01787     
01788     langipcsymboldeleted (htable, (ptrstring) bsname);
01789     
01790     return (tablesymboldeleted (htable, bsname));
01791     } /*ccsymboldeleted*/
01792     
01793 
01794 static short cccomparenodes (hdlhashtable htable, hdlhashnode hnode1, hdlhashnode hnode2) {
01795     
01796     return (tablecomparenodes (htable, hnode1, hnode2));
01797     } /*cccomparenodes*/
01798 
01799 
01800 static boolean ccsaveglobals (void) {
01801     
01802     assert (cctopglobals <= maxsavedccglobals);
01803     
01804     ccglobalsstack [cctopglobals++] = cancoonglobals;
01805     
01806     return (true);
01807     } /*ccsaveglobals*/
01808 
01809 
01810 static boolean ccrestoreglobals (void) {
01811     
01812     /*
01813     10/23/91 dmb: when stack entry is nil, clear globals before 
01814     returning false; we don't want other globals to remain in place
01815     */
01816     
01817     register hdlcancoonrecord hc = ccglobalsstack [--cctopglobals];
01818     
01819     assert (cctopglobals >= 0);
01820     
01821     if (hc == nil) {
01822         
01823         clearcancoonglobals ();
01824         
01825         return (false);
01826         }
01827     
01828     if (hc != cancoonglobals)
01829         setcancoonglobals (hc);
01830     
01831     return (true);
01832     } /*ccrestoreglobals*/
01833 
01834 
01835 static boolean ccpartialeventloop (short desiredevents) {
01836     
01837     /*
01838     3/23/93 dmb: don't use ccsave/restoreglobals, 'cause we don't want to restore
01839     nil globals (in case we're being called at an odd time, like from an error 
01840     alert during initialization
01841     */
01842     
01843     boolean fl;
01844     hdlcancoonrecord hc;
01845     
01846     hc = cancoonglobals;
01847     
01848     fl = shellpartialeventloop (desiredevents);
01849     
01850     if (hc != cancoonglobals)
01851         setcancoonglobals (hc);
01852     
01853     return (fl);
01854     } /*ccpartialeventloop*/
01855 
01856 
01857 boolean ccstart (void) {
01858     
01859     /*
01860     set up callback routines record, and link our data into the shell's 
01861     data structure.
01862     */
01863     
01864     langcallbacks.symbolchangedcallback = &ccsymbolchanged;
01865     
01866     langcallbacks.symbolunlinkingcallback = &processsymbolunlinking;
01867     
01868     langcallbacks.symboldeletedcallback = &ccsymboldeleted;
01869     
01870     langcallbacks.symbolinsertedcallback = &ccsymbolinserted;
01871     
01872     langcallbacks.comparenodescallback = &cccomparenodes;
01873     
01874     langcallbacks.saveglobalscallback = &ccsaveglobals;
01875     
01876     langcallbacks.restoreglobalscallback = &ccrestoreglobals;
01877     
01878     langcallbacks.partialeventloopcallback = &ccpartialeventloop;
01879     
01880     shellpushmenuhook (&ccmenuroutine);
01881     
01882     return (ccwindowstart ());
01883     } /*ccstart*/
01884 
01885 
01886 
01887 

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