Version:
~ [ 10.0 ] ~
** Warning: Cannot open xref database.
1
2 /* $Id: cancoon.c,v 1.6 2005/01/24 02:56:57 terry_teague Exp $ */
3
4 /******************************************************************************
5
6 UserLand Frontier(tm) -- High performance Web content management,
7 object database, system-level and Internet scripting environment,
8 including source code editing and debugging.
9
10 Copyright (C) 1992-2004 UserLand Software, Inc.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 ******************************************************************************/
27
28 #include "frontier.h"
29 #include "standard.h"
30
31 #ifdef MACVERSION
32 #include <land.h>
33 #endif
34
35 #include "memory.h"
36 #include "dialogs.h"
37 #include "error.h"
38 #include "file.h"
39 #include "font.h"
40 #include "menu.h"
41 #include "ops.h"
42 #include "resources.h"
43 #include "quickdraw.h"
44 #include "strings.h"
45 #include "frontierwindows.h"
46 #include "shell.h"
47 #include "shellhooks.h"
48 #include "shellmenu.h"
49 #include "shellprivate.h"
50 #include "shell.rsrc.h"
51 #include "langexternal.h"
52 #include "langinternal.h"
53 #include "langipc.h"
54 #include "tableinternal.h"
55 #include "tablestructure.h"
56 #include "tableverbs.h"
57 #include "menuverbs.h"
58 #include "scripts.h"
59 #include "process.h"
60 #ifdef fltrialsize
61 #include "dbinternal.h"
62 #endif
63 #include "cancoon.h"
64 #include "cancooninternal.h"
65 #include "serialnumber.h"
66
67 #include "WinSockNetEvents.h" /*6.2a14 AR*/
68
69
70
71 hdlcancoonrecord cancoondata = nil;
72
73 hdlwindowinfo cancoonwindowinfo = nil;
74
75 WindowPtr cancoonwindow = nil;
76
77
78 hdlcancoonrecord cancoonglobals = nil;
79
80 hdlcancoonrecord supercancoonglobals = nil; /*4.1b4 dmb: only set when globals set via setsuperglobals*/
81
82
83 #define maxsavedccglobals 5
84
85 static hdlcancoonrecord ccglobalsstack [maxsavedccglobals];
86
87 static short cctopglobals = 0;
88
89
90 static short ccwindowconfigs [] = { /*table to map window info indexes to config ids*/
91
92 idcancoonconfig,
93
94 0, /*idmessageconfig*/
95
96 idlangerrorconfig,
97
98 idcommandconfig,
99
100 idaboutconfig,
101
102 0 /*idpaletteconfig*/
103 };
104
105
106 static boolean fldisablesymbolcallbacks = false;
107
108
109
110 boolean ccgetwindowinfo (short windowtype, tycancoonwindowinfo *windowinfo) {
111
112 *windowinfo = (**cancoondata).windowinfo [windowtype];
113
114 return (true);
115 } /*ccgetwindowinfo*/
116
117
118 boolean ccsetwindowinfo (short windowtype, tycancoonwindowinfo windowinfo) {
119
120 (**cancoondata).windowinfo [windowtype] = windowinfo;
121
122 (**cancoondata).fldirty = true;
123
124 return (true);
125 } /*ccsetwindowinfo*/
126
127
128 boolean ccnewsubwindow (hdlwindowinfo hinfo, short windowtype) {
129
130 register hdlwindowinfo hw = hinfo;
131 tycancoonwindowinfo windowinfo;
132
133 if (!shellpushrootglobals ((**hw).macwindow))
134 return (false);
135
136 ccgetwindowinfo (windowtype, &windowinfo);
137
138 (**hw).defaultfont = windowinfo.fontnum;
139
140 (**hw).defaultsize = windowinfo.fontsize;
141
142 windowinfo.w = (**hw).macwindow;
143
144 ccsetwindowinfo (windowtype, windowinfo);
145
146 shellpopglobals ();
147
148 return (true);
149 } /*ccnewsubwindow*/
150
151
152 boolean cccopywindowinfo (hdlwindowinfo hinfo, short windowtype) {
153
154 register hdlwindowinfo hw = hinfo;
155 register hdlcancoonrecord hc;
156 register boolean fldirty;
157 tycancoonwindowinfo windowinfo;
158 Rect r, rwindow;
159
160 if (!shellpushrootglobals ((**hw).macwindow))
161 return (false);
162
163 hc = cancoondata; /*copy into register*/
164
165 fldirty = (**hc).fldirty; /*initialize*/
166
167 shellgetglobalwindowrect (hw, &r);
168
169 ccgetwindowinfo (windowtype, &windowinfo);
170
171 diskrecttorect (&windowinfo.windowrect, &rwindow);
172
173 if (!equalrects (r, rwindow)) { /*window was moved or resized*/
174
175 recttodiskrect (&r, &windowinfo.windowrect);
176
177 fldirty = true;
178 }
179
180 if (windowinfo.fontnum != (**hw).defaultfont) {
181
182 windowinfo.fontnum = (**hw).defaultfont;
183
184 fldirty = true;
185 }
186
187 if (windowinfo.fontsize != (**hw).defaultsize) {
188
189 windowinfo.fontsize = (**hw).defaultsize;
190
191 fldirty = true;
192 }
193
194 if (fldirty) { /*dirty things up -- everywhere conceivable*/
195
196 (**hc).fldirty = true;
197
198 windowsetchanges (cancoonwindow, true);
199 }
200
201 ccsetwindowinfo (windowtype, windowinfo);
202
203 shellpopglobals ();
204
205 return (true);
206 } /*cccopywindowinfo*/
207
208
209 boolean ccsubwindowclose (hdlwindowinfo hinfo, short windowtype) {
210
211 tycancoonwindowinfo windowinfo;
212
213 if (!cccopywindowinfo (hinfo, windowtype))
214 return (false);
215
216 if (!shellpushrootglobals ((**hinfo).macwindow))
217 return (false);
218
219 ccgetwindowinfo (windowtype, &windowinfo);
220
221 windowinfo.w = nil;
222
223 ccsetwindowinfo (windowtype, windowinfo);
224
225 shellpopglobals ();
226
227 return (true);
228 } /*ccsubwindowclose*/
229
230
231 boolean ccgetwindowrect (short ixwindowinfo, Rect *rwindow) {
232
233 /*
234 5.1.5b10 dmb: use ccfindrootwindow to avoid guest databases
235 */
236
237 tyconfigrecord config;
238 hdlwindowinfo hinfo;
239
240 // if (shellpushfrontrootglobals ())
241 if (ccfindrootwindow (&hinfo)) {
242
243 tycancoonwindowinfo windowinfo;
244
245 shellpushglobals ((**hinfo).macwindow);
246
247 ccgetwindowinfo (ixwindowinfo, &windowinfo);
248
249 diskrecttorect (&windowinfo.windowrect, rwindow);
250
251 shellpopglobals ();
252
253 return (true);
254 }
255
256 if (shellgetconfig (ccwindowconfigs [ixwindowinfo], &config)) {
257
258 *rwindow = config.defaultwindowrect;
259
260 return (true);
261 }
262
263 setrect (rwindow, -1, -1, -1, -1); /*set top, left, bottom, right*/
264
265 return (false);
266 } /*ccgetwindowrect*/
267
268
269 static void ccinitwindowinfo (hdlcancoonrecord hcancoon, short ixwindowinfo) {
270
271 register hdlcancoonrecord hc = hcancoon;
272 tycancoonwindowinfo windowinfo;
273 tyconfigrecord config;
274 Rect r;
275
276 clearbytes (&windowinfo, sizeof (windowinfo));
277
278 if (shellgetconfig (ccwindowconfigs [ixwindowinfo], &config)) {
279
280 recttodiskrect (&config.defaultwindowrect, &windowinfo.windowrect);
281
282 diskgetfontname (config.defaultfont, windowinfo.fontname);
283
284 windowinfo.fontnum = config.defaultfont;
285
286 windowinfo.fontsize = config.defaultsize;
287 }
288 else {
289 setrect (&r, -1, -1, -1, -1);
290
291 recttodiskrect (&r, &windowinfo.windowrect);
292
293 windowinfo.fontnum = systemFont;
294
295 windowinfo.fontsize = 12;
296
297 /*
298 copystring ("\x07" "Chicago", (ptrstring) windowinfo.fontname);
299 */
300
301 fontgetname (systemFont, (ptrstring) windowinfo.fontname);
302 }
303
304 (**hc).windowinfo [ixwindowinfo] = windowinfo;
305 } /*ccinitwindowinfo*/
306
307
308 static void ccupdatewindowinfo (short windowtype, tyversion2cancoonrecord *info) {
309
310 /*
311 2/8/91 dmb: subwindows now can have a save routine, which we call to
312 allow strings to be saved into cancoondata before we update the db
313
314 5.0d14 dmb: clean the window's menu item
315 */
316
317 tycancoonwindowinfo windowinfo;
318 Rect r;
319
320 ccgetwindowinfo (windowtype, &windowinfo);
321
322 if (windowinfo.w != nil) {
323
324 shellpushglobals (windowinfo.w);
325
326 (*shellglobals.presaveroutine) ();
327
328 windowinfo.flhidden = (**shellwindowinfo).flhidden;
329
330 shellpopglobals ();
331
332 getglobalwindowrect (windowinfo.w, &r);
333
334 recttodiskrect (&r, &windowinfo.windowrect);
335
336 windowsetchanges (windowinfo.w, false);
337 }
338
339 diskgetfontname (windowinfo.fontnum, windowinfo.fontname);
340
341 (*info).windowinfo [windowtype] = windowinfo; /*copy into disk record*/
342
343 memtodiskshort ((*info).windowinfo [windowtype].fontsize);
344 memtodiskshort ((*info).windowinfo [windowtype].fontstyle);
345
346 ccsetwindowinfo (windowtype, windowinfo); /*update in-memory version*/
347 } /*ccupdatewindowinfo*/
348
349
350 static boolean ccactivatemenubar (hdlcancoonrecord hcancoon, boolean flactivate) {
351
352 if (hcancoon == nil)
353 return (false);
354
355 return (activatemenubarlist ((**hcancoon).hmenubarlist, flactivate));
356 } /*ccactivatemenubar*/
357
358
359 static boolean disposecancoonrecord (hdlcancoonrecord hcancoon) {
360
361 /*
362 1/21/91 dmb: even though disposing the root table will dispose of
363 the menu bar, we need to explicitly deactivate the menu bar here
364 in case the language postpones the table disposal until the current
365 process terminates (which may be after another menu bar has been
366 activated).
367
368 1/28/91 dmb: we were forgeting to dispose the script and message strings.
369
370 5.0.1 dmb: fixed leak - use tabledisposetable, not disposehashtable
371
372 5.1 dmb: fixed leak - disposehandle of the rootvariable itself
373 */
374
375 register hdlcancoonrecord hc = hcancoon;
376
377 if (hc == nil)
378 return (false);
379
380 ccactivatemenubar (hc, false);
381
382 disposeprocesslist ((**hc).hprocesslist); /*checks for nil*/
383
384 //setcurrentmenubarlist (nil); /*clear menubar.c global before disposing roottable*/
385
386 disposehandle ((Handle) (**hc).hmenubarlist); /*roottable disposal will do menubars*/
387
388 tabledisposetable ((**hc).hroottable, false); /*yup, checks for nil*/
389
390 disposehandle ((Handle) (**hc).hrootvariable); /*5.1*/
391
392 disposehandle ((Handle) (**hc).hscriptstring); /*always has, always will*/
393
394 disposehandle ((Handle) (**hc).hprimarymsg);
395
396 disposehandle ((Handle) (**hc).hsecondarymsg);
397
398 disposehandle ((Handle) hc);
399
400 return (true);
401 } /*disposecancoonrecord*/
402
403
404 static boolean newcancoonrecord (hdlcancoonrecord *hcancoon) {
405
406 register hdlcancoonrecord hc;
407 short i;
408 hdlprocesslist hprocesslist;
409 hdlmenubarlist hmenubarlist;
410
411 if (!newclearhandle (sizeof (tycancoonrecord), (Handle *) hcancoon))
412 return (false);
413
414 hc = *hcancoon;
415
416 if (!newprocesslist (&hprocesslist))
417 goto error;
418
419 (**hc).hprocesslist = hprocesslist;
420
421 if (!newmenubarlist (&hmenubarlist))
422 goto error;
423
424 (**hc).hmenubarlist = hmenubarlist;
425
426 for (i = 0; i < ctwindowinfo; i++)
427 ccinitwindowinfo (hc, i);
428
429 return (true);
430
431 error:
432
433 disposecancoonrecord (hc);
434
435 *hcancoon = nil;
436
437 return (false);
438 } /*newcancoonrecord*/
439
440
441 static boolean ccinstalltablestructure (boolean flhavehost) {
442
443 /*
444 12/31/90 dmb: since this routine can be executing in the background,
445 while the language is evaluating an expression, we now use setroothashtable,
446 replacing setcurrenthashtable
447
448 1/8/91 dmb: in fact, a cleaner and more reliable solution is to leave it
449 up to the language to always push the root table before running any code,
450 so setroothashtable is gone.
451
452 5.1b23 dmb: added serial number checking
453 */
454
455 register hdlcancoonrecord hc = cancoondata;
456
457 assert ((**hc).hroottable == roottable); /*should already be set up*/
458
459 setcurrentprocesslist ((**hc).hprocesslist);
460
461 if (!flhavehost && !validateserialnumber ()) {
462
463 exittooperatingsystem ();
464
465 return (false);
466 }
467
468 loadsystemscripts (); /*load agents, compile handlers, run startup scripts, etc.*/
469
470 #ifndef PIKE
471 #if TARGET_API_MAC_CARBON == 0
472 langipcmenustartup ();
473 #endif
474 #endif
475
476 return (true);
477 } /*ccinstalltablestructure*/
478
479
480 static boolean ccinstallmenubar (hdlcancoonrecord hcancoon, hdlmenurecord hmenurecord) {
481
482 /*
483 5.0d14 dmb: with the introduction of beginner/expert modes, it no longer
484 makes sense for Frontier to automatically install system.misc.menubar
485
486 5.0a2 dmb: restored functionality, but now we're only called for old odbs
487 */
488
489 setcurrentmenubarlist ((**hcancoon).hmenubarlist);
490
491 if (hmenurecord == nil) /*we're done*/
492 return (true);
493
494 assert ((**hmenurecord).hmenustack == nil);
495
496 return (meinstallmenubar (hmenurecord));
497 } /*ccinstallmenubar*/
498
499
500 static boolean ccloadsystemtable (hdlcancoonrecord hcancoon, dbaddress adr, boolean flcreate) {
501
502 /*
503 some factored code. try to load the root table from adr and find or
504 create the standard global tables
505 */
506
507 register hdlcancoonrecord hc = hcancoon;
508 register boolean fl;
509 Handle hvariable;
510 hdlhashtable htable;
511
512 fldisablesymbolcallbacks = true; /*so table insertions wont trigger callbacks*/
513
514 fl = tableloadsystemtable (adr, &hvariable, &htable, flcreate);
515
516 if (fl) {
517
518 (**hc).hrootvariable = hvariable;
519
520 (**hc).hroottable = htable;
521
522 assert (tablevalidate (htable, true));
523
524 fl = settablestructureglobals (hvariable, flcreate) || !flcreate;
525 }
526
527 fldisablesymbolcallbacks = false;
528
529 return (fl);
530 } /*ccloadsystemtable*/
531
532
533 void setcancoonglobals (hdlcancoonrecord hcancoon) {
534
535 /*
536 5.0a18 dmb: added nil check, set globals to nill in that case
537 */
538
539 register hdlcancoonrecord hc = hcancoon;
540
541 if (hc != nil) {
542
543 databasedata = (**hc).hdatabase;
544
545 settablestructureglobals ((**hc).hrootvariable, false);
546
547 setcurrentprocesslist ((**hc).hprocesslist);
548
549 setcurrentmenubarlist ((**hc).hmenubarlist);
550 }
551
552 cancoonglobals = hc; /*this global is independent of shellpush/popglobals*/
553 } /*setcancoonglobals*/
554
555
556 static void clearcancoonglobals (void) {
557
558 databasedata = nil; /*db.c*/
559
560 setcurrentprocesslist (nil); /*agents.c*/
561
562 cleartablestructureglobals (); /*tablestructure.c: roottable, handlertable, etc.*/
563
564 setcurrentmenubarlist (nil); /*menubar.c*/
565
566 cancoonglobals = nil; /*our very own superglobal*/
567
568 supercancoonglobals = nil; /*the ones swapped in with ccsetsuperglobals*/
569 } /*clearcancoonglobals*/
570
571
572 static boolean loadversion2cancoonfile (dbaddress adr, hdlcancoonrecord hcancoon, boolean flhavehost) {
573
574 /*
575 5.0d14 dmb: bumped cancoonversionnumber; hscriptstring is now a text handle,
576 not a string handle. (no 255 char limit)
577
578 5.0d18 dmb: have to ccwindowsetup _after_ loading system table now
579
580 5.0a2 dmb: install the menubar if the database hasn't been upgraded
581
582 2002-11-11 AR: Added additional asserts to make sure the C compiler chose the
583 proper byte alignment for the tycancoonwindowinfo and tyversion2cancoonrecord
584 struct. If it did not, we would end up corrupting any database files we saved.
585 */
586
587 register hdlcancoonrecord hc;
588 tyversion2cancoonrecord info;
589 short i;
590 hdlmenurecord hmenurecord = nil;
591 hdlstring hstring;
592 boolean flguest;
593 boolean frontier4root;
594
595 assert (sizeof (tycancoonwindowinfo) == 62); /* one padding byte after fontname which is 33 bytes long */
596
597 assert (sizeof (tyversion2cancoonrecord) == 442);
598
599 assert (sizeof (tyversion2cancoonrecord) == sizeof (tyOLD42version2cancoonrecord));
600
601 if (!dbreference (adr, sizeof (info), &info))
602 return (false);
603
604 disktomemshort (info.versionnumber);
605 disktomemlong (info.adrroottable);
606 disktomemlong (info.adrscriptstring);
607 disktomemshort (info.ixprimaryagent);
608
609 hc = hcancoon; /*copy into register*/
610
611 for (i = 0; i < ctwindowinfo; i++) { /*copy info.windowinfo into hc, with filtering*/
612
613 tycancoonwindowinfo windowinfo;
614
615 windowinfo = info.windowinfo [i]; /*copy record out of its array*/
616
617 disktomemshort (windowinfo.fontsize);
618 disktomemshort (windowinfo.fontstyle);
619
620 windowinfo.w = nil; /*pointers stored on disk are invalid*/
621
622 diskgetfontnum (windowinfo.fontname, &windowinfo.fontnum);
623
624 (**hc).windowinfo [i] = windowinfo;
625 } /*for*/
626
627 /*cancooninitwindowinfo (hc, ixunused2);*/
628
629 frontier4root = info.versionnumber < 3;
630
631 if (frontier4root) {
632
633 bigstring bsprompt;
634
635 shellgetstring (openolddatabasestring, bsprompt);
636
637 if (!twowaydialog (bsprompt, "\x07" "Convert", "\x06" "Cancel"))
638 return (false);
639
640 dbrefheapstring (info.adrscriptstring, &hstring);
641
642 pullfromhandle ((Handle) hstring, 0, 1, nil); // pluck out the length byte
643 }
644 else
645 dbrefhandle (info.adrscriptstring, (Handle *) &hstring);
646
647 (**hc).hscriptstring = (Handle) hstring;
648
649 (**hc).flflagdisabled = (info.flags & flflagdisabled_mask) != 0;
650
651 (**hc).flpopupdisabled = (info.flags & flpopupdisabled_mask) != 0;
652
653 (**hc).flbigwindow = (info.flags & flbigwindow_mask) != 0;
654
655 ccwindowsetup ((**hc).flbigwindow, frontier4root); /*use info from the windowinfo array*/
656
657 if (!ccloadsystemtable (hc, info.adrroottable, !flhavehost))
658 return (false);
659
660 flguest = systemtable == nil;
661
662 #ifdef fltrialsize
663
664 if (flguest) {
665
666 (**cancoonwindowinfo).hdata = nil; /*unlink data from window to avoid crash*/
667
668 shelltrialerror (noguestdatabasesstring);
669
670 return (false);
671 }
672
673 #endif
674
675 if (!flguest) {
676
677 linksystemtablestructure (roottable);
678
679 if (frontier4root) {
680
681 if (resourcestable != nil)
682 if (menugetmenubar (resourcestable, namemenubar, false, &hmenurecord))
683 ccinstallmenubar (hc, hmenurecord); /*ignore error*/
684 }
685
686 if (ccinstalltablestructure (flhavehost))
687 ccsetprimaryagent (info.ixprimaryagent);
688 else
689 return (false); /*6.1b4 AR: Fix crash after cancelling serial number dialog (at least on Win32)*/
690 }
691
692 (**hc).flguestroot = flguest;
693
694 return (true);
695 } /*loadversion2cancoonfile*/
696
697
698 #if 0 //def MACVERSION
699
700 static boolean loadoldcancoonfile (dbaddress adr, hdlcancoonrecord hcancoon) {
701
702 tyfilespec fs, fsold;
703 boolean fl;
704
705 if (!msgdialog ("\5" "Convert 4.x database to 5.0? (This can take a while. A backup will be retained.)"))
706 return (false);
707
708 if (!loadversion2cancoonfile (adr, hcancoon))
709 return (false);
710
711 windowgetfspec (cancoonwindow, &fs);
712
713 fsold = fs;
714
715 pushstring ("\x04" ".v4x", fs.name);
716
717 flconvertingolddatabase = true;
718
719 fl = shellsaveas (cancoonwindow, &fs);
720
721 flconvertingolddatabase = false;
722
723 if (!fl)
724 return (false);
725
726 oserror (FSpExchangeFiles (&fs, &fsold)); // ignore, but report error
727
728 windowsetfspec (cancoonwindow, &fsold); // the old fspec is now the new file
729
730 return (true);
731 } /*loadoldcancoonfile*/
732
733 #endif
734
735 #ifdef fltrialsize
736
737 static boolean cctrialviolation (void) {
738
739 long eof;
740
741 dbgeteof (&eof);
742
743 if (eof > 7 * 0x0100000) {
744
745 shelltrialerror (dbsizelimitstring);
746
747 return (true);
748 }
749
750 return (false);
751 } /*cctrialviolation*/
752
753 #endif
754
755 boolean ccloadfile (hdlfilenum fnum, short rnum) {
756
757 /*
758 9/15/92 dmb: removed support for version1 format; it never shipped
759
760 6.1fc2 AR: Don't link cancoondata into (**cancoonwindowinfo).hdata.
761 This would crash some installations during the initialization
762 of the serial number dialog.
763 hdata should be a hdltableformats anyway.
764 */
765
766 register hdlcancoonrecord hc = nil;
767 dbaddress adr;
768 short versionnumber;
769 hdlcancoonrecord origglobals = cancoonglobals;
770 boolean flhavehost = origglobals != nil;
771 boolean flhide;
772
773 cancoondata = nil; /*default error return*/
774
775 if (!dbopenfile (fnum, false))
776 return (false);
777
778 #ifdef fltrialsize
779
780 if (cctrialviolation ()) {
781
782 if (!flhavehost)
783 shellexitmaineventloop ();
784
785 goto error;
786 }
787
788 #endif
789
790 dbgetview (cancoonview, &adr);
791
792 if (!dbreference (adr, sizeof (versionnumber), &versionnumber))
793 goto error;
794
795 disktomemshort (versionnumber);
796
797 if (!newcancoonrecord (&cancoondata))
798 goto error;
799
800 hc = cancoondata; /*copy into register*/
801
802 //(**cancoonwindowinfo).hdata = (Handle) hc; /*link data to window*/
803
804 (**hc).hdatabase = databasedata; /*result from dbopenfile*/
805
806 switch (versionnumber) {
807
808 /*
809 case 1:
810 if (!loadversion1cancoonfile (adr, hc))
811 goto error;
812
813 return (true);
814 */
815
816 case 2:
817 case cancoonversionnumber:
818 if (!loadversion2cancoonfile (adr, hc, flhavehost))
819 goto error;
820
821 if ((**hc).flguestroot)
822 setcancoonglobals (origglobals); /*restore databasedata, etc.*/
823
824 else {
825
826 flhide = !ccinexpertmode () || (**hc).windowinfo [ixcancooninfo].flhidden;
827
828 (**cancoonwindowinfo).flhidden = flhide;
829 }
830
831 // ccnewfilewindow (idscriptprocessor);
832
833 return (true);
834
835 default:
836 alertstring (baddatabaseversionstring);
837
838 goto error;
839 } /*switch*/
840
841 error:
842
843 dbdispose ();
844
845 clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
846
847 disposecancoonrecord (hc); /*checks for nil*/
848
849 setcancoonglobals (origglobals); /*restore databasedata, etc.*/
850
851 return (false);
852 } /*ccloadfile*/
853
854
855 boolean ccloadspecialfile (ptrfilespec fspec, OSType filetype) {
856
857 /*
858 7/28/92 dmb: use new finder2frontscript to set the Frontier.findertofront
859 global, instead of having Frontier.finder2click always set it to true. also,
860 handle updates now.
861
862 2.1b3 dmb: only set finder2front to true if the sender of the 'odoc' event
863 was the Finder
864 */
865
866 bigstring bspath;
867 bigstring bs;
868 ptrbyte pbool;
869
870 if (!shellsetsuperglobals ()) {
871
872 if (!shellopendefaultfile () || !shellsetsuperglobals ()) {
873
874 getstringlist (langerrorlist, needopendberror, bs);
875
876 shellerrormessage (bs);
877
878 return (false);
879 }
880 }
881
882 if (!filespectopath (fspec, bspath)) {
883
884 filenotfounderror ((ptrstring) fsname (fspec));
885
886 return (false);
887 }
888
889 langdeparsestring (bspath, chclosecurlyquote); /*add needed escape sequences*/
890
891 if (getsystemtablescript (idfinder2frontscript, bs)) { /*frontier.findertofront=^0*/
892
893 #ifdef MACVERSION
894 if ((shellevent.what == kHighLevelEvent) && ((**landgetglobals ()).maceventsender == 'MACS'))
895 pbool = bstrue;
896 else
897 #endif
898 pbool = bsfalse;
899
900 parsedialogstring (bs, pbool, nil, nil, nil, bs);
901
902 langrunstringnoerror (bs, bs);
903 }
904
905 if (!getsystemtablescript (idfinder2clickscript, bs)) /*frontier.finder2click ("^0")*/
906 return (false);
907
908 parsedialogstring (bs, bspath, nil, nil, nil, bs);
909
910 shellpartialeventloop (updateMask); /*handle updates first*/
911
912 return (processrunstring (bs));
913 } /*ccloadspecialfile*/
914
915
916 boolean ccsavespecialfile (ptrfilespec fs, hdlfilenum fnum, short rnum, boolean flsaveas, boolean flrunnable) {
917
918 /*
919 6.17.97 dmb: this is called by opverbs, wpverbs, etc. to save a disk file.
920 we leave it to the system.misc.saveWindow script to package the data,
921 but we take care of writing it. (our caller did the file creation.)
922
923 note: if we decide to make this more open architecture, we could add
924 another flat for the config record that would prevent the shell from
925 opening the data fork for us. then, we'd need to make this callback
926 take the destination filespec as a parameter too, and the saveWindow script
927 would take both the window name and the filespec (which would be the same
928 for a normal save).
929
930 5.0.2b6 dmb: error checking on openfile
931
932 5.0.2b8 dmb: don't unregister the window until we're about to set the new path
933 */
934
935 bigstring bs, bspath;
936 ptrstring bsrunnable;
937 tyvaluerecord val;
938 Handle hscript;
939 boolean fl = false;
940 boolean flopenedfile = false;
941 hdlexternalvariable hv;
942
943 (*shellglobals.getvariableroutine) ((Handle *) &hv);
944
945 // if (hv != nil)
946 // langexternalunregisterwindow (shellwindowinfo);
947
948 if (!windowgetpath (shellwindow, bspath))
949 shellgetwindowtitle (shellwindowinfo, bspath);
950
951 langdeparsestring (bspath, chclosecurlyquote); /*add needed escape sequences*/
952
953 if (!getsystemtablescript (idsavewindowscript, bs)) /*system.misc.saveWindow ("^0","^1")*/
954 return (false);
955
956 bsrunnable = (flrunnable? bstrue : bsfalse);
957
958 parsedialogstring (bs, bspath, bsrunnable, nil, nil, bs);
959
960 if (!newtexthandle (bs, &hscript))
961 return (false);
962
963 pushprocess (nil);
964
965 fl = langrun (hscript, &val);
966
967 popprocess ();
968
969 if (!fl)
970 return (false);
971
972 pushhashtable (roottable); /*need temp stack services*/
973
974 pushvalueontmpstack (&val);
975
976 if (coercetostring (&val)) {
977
978 if (fnum == 0) {
979
980 fl = openfile (fs, &fnum, false);
981
982 flopenedfile = fl;
983 }
984
985 if (fl)
986 fl =
987 fileseteof (fnum, 0) &&
988
989 filesetposition (fnum, 0) &&
990
991 filewritehandle (fnum, val.data.stringvalue);
992
993 if (flopenedfile)
994 closefile (fnum);
995 }
996
997 cleartmpstack ();
998
999 pophashtable ();
1000
1001 if (hv != nil)
1002 langexternalunregisterwindow (shellwindowinfo);
1003
1004 if (fl)
1005 windowsetfspec (shellwindow, fs);
1006
1007 if (hv != nil)
1008 langexternalregisterwindow (hv);
1009
1010 return (fl);
1011 } /*ccsavespecialfile*/
1012
1013
1014 boolean ccnewrecord (void) {
1015
1016 /*
1017 5.1.5b12 dmb: save the new structure after it's created, so if we crash we don't leave junk.
1018 */
1019
1020 register hdlcancoonrecord hc;
1021 hdlcancoonrecord origglobals = cancoonglobals;
1022 hdltablevariable hvariable;
1023 hdlhashtable htable;
1024 hdlfilenum fnum;
1025
1026 cancoondata = nil; /*default error return*/
1027
1028 if (!newcancoonrecord (&cancoondata))
1029 return (false);
1030
1031 hc = cancoondata; /*copy into register*/
1032
1033 cancoonglobals = hc; // 5.0a2 dmb: need this for more consistent state
1034
1035 (**cancoonwindowinfo).hdata = (Handle) hc; /*link data to window*/
1036
1037 fnum = windowgetfnum (cancoonwindow);
1038
1039 if (!dbnew (fnum))
1040 goto error;
1041
1042 dbsetview (cancoonview, nildbaddress);
1043
1044 (**hc).hdatabase = databasedata;
1045
1046 ccwindowsetup (false, true); /*init info in the windowinfo array*/
1047
1048 if (!tablenewtable (&hvariable, &htable)) /*this will be the root table*/
1049 goto error;
1050
1051 (**hvariable).id = idtableprocessor;
1052
1053 (**hc).hrootvariable = (Handle) hvariable;
1054
1055 (**hc).hroottable = htable;
1056
1057 (**hc).flguestroot = true;
1058
1059 if (!ccsavefile (nil, fnum, -1, false, false)) // 5.1.5b12
1060 goto error;
1061
1062 setcancoonglobals (origglobals); /*restore databasedata, etc.*/
1063
1064 return (true);
1065
1066 error:
1067
1068 dbdispose ();
1069
1070 clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
1071
1072 disposecancoonrecord (hc);
1073
1074 setcancoonglobals (origglobals); /*restore databasedata, etc.*/
1075
1076 return (false);
1077 } /*ccnewrecord*/
1078
1079
1080 boolean ccnewfilewindow (tyexternalid id, WindowPtr *w, boolean flhidden) {
1081
1082 tyvaluerecord val;
1083 hdlwindowinfo hinfo;
1084
1085 if (!langexternalnewvalue (id, nil, &val))
1086 return (false);
1087
1088 langexternalsetdirty ((hdlexternalhandle) val.data.externalvalue, false);
1089
1090 if (!langexternalzoomfilewindow (&val, nil, flhidden)) {
1091
1092 disposevaluerecord (val, false);
1093
1094 return (false);
1095 }
1096
1097 if (!langexternalwindowopen (val, &hinfo)) //shouldn't ever fail
1098 return (false);
1099
1100 *w = (**hinfo).macwindow;
1101
1102 return (true);
1103 } /*ccnewfilewindow*/
1104
1105
1106 boolean ccsavefile (ptrfilespec fs, hdlfilenum fnum, short rnum, boolean flsaveas, boolean flrunnable) {
1107
1108 /*
1109 5.0b18 dmb: last-minute fix. we crash when saving while publishing a table.
1110 the problem is that we toss stuff out during a save, and it would be nearly
1111 impossible to protect against that everywhere. so we use processwaitforquiet
1112 and try to be the only thread using globals
1113
1114 5.1.5b7 dmb: disabled above "fix". we now rely on shellwindowinfo and
1115 outlinedata push/pop protection, fldispoosewhenpopped flags
1116 */
1117
1118 register hdlcancoonrecord hc = cancoondata;
1119 tyversion2cancoonrecord info;
1120 dbaddress adr;
1121 short i;
1122 boolean fl = false;
1123
1124 databasedata = (**hc).hdatabase;
1125
1126 if (flsaveas) {
1127
1128 if (!dbstartsaveas (fnum))
1129 return (false);
1130
1131 adr = nildbaddress;
1132 }
1133 else
1134 dbgetview (cancoonview, &adr);
1135
1136 if (adr == nildbaddress)
1137 clearbytes (&info, sizeof (info));
1138 else
1139 if (!dbreference (adr, sizeof (info), &info))
1140 goto exit;
1141
1142 disktomemlong (info.adrroottable);
1143 disktomemlong (info.adrscriptstring);
1144
1145 info.versionnumber = conditionalshortswap (cancoonversionnumber);
1146
1147 for (i = 0; i < ctwindowinfo; i++)
1148 ccupdatewindowinfo (i, &info);
1149
1150 /*
1151 if (!processwaitforquiet (120L)) { //wait up to 2 seconds
1152
1153 sysbeep ();
1154
1155 goto exit;
1156 }
1157 */
1158
1159 if (!tablesavesystemtable ((**hc).hrootvariable, &info.adrroottable))
1160 goto exit;
1161
1162 #ifdef version42orgreater
1163 info.windowinfo [ixcancooninfo].flhidden = (**shellwindowinfo).flhidden;
1164
1165 if (!dbassignhandle ((**hc).hscriptstring, &info.adrscriptstring))
1166 goto exit;
1167 #else
1168 if (!dbassignheapstring (&info.adrscriptstring, (**hc).hscriptstring))
1169 goto exit;
1170 #endif
1171
1172 memtodisklong (info.adrroottable);
1173 memtodisklong (info.adrscriptstring);
1174
1175 clearbytes (&info.waste, sizeof (info.waste));
1176
1177 info.flags = 0;
1178
1179 if ((**hc).flflagdisabled)
1180 info.flags |= flflagdisabled_mask;
1181
1182 if ((**hc).flpopupdisabled)
1183 info.flags |= flpopupdisabled_mask;
1184
1185 if ((**hc).flbigwindow)
1186 info.flags |= flbigwindow_mask;
1187
1188 ccgetprimaryagent (&info.ixprimaryagent);
1189
1190 memtodiskshort (info.ixprimaryagent);
1191
1192 if (!dbassign (&adr, sizeof (info), &info))
1193 goto exit;
1194
1195 if (!flsaveas)
1196 dbflushreleasestack (); /*release all the db objects that were saved up*/
1197
1198 dbsetview (cancoonview, adr);
1199
1200 fl = true; // success!
1201
1202 #ifdef fltrialsize
1203
1204 if (cctrialviolation ()) // just issue message
1205 ;
1206
1207 #endif
1208
1209 exit:
1210
1211 if (flsaveas)
1212 dbendsaveas ();
1213
1214 databasedata = (**cancoonglobals).hdatabase; // may not be same as cancoondata
1215
1216 return (fl);
1217 } /*ccsavefile*/
1218
1219
1220 boolean ccfindusedblocks (void) {
1221
1222 tyversion2cancoonrecord info;
1223 dbaddress adr;
1224
1225 dbgetview (cancoonview, &adr);
1226
1227 if (adr != nildbaddress) {
1228
1229 if (!dbreference (adr, sizeof (info), &info))
1230 return (false);
1231
1232 statsblockinuse (adr, nil);
1233
1234 disktomemlong (info.adrscriptstring);
1235
1236 if (!statsblockinuse (info.adrscriptstring, nil))
1237 return (false);
1238 }
1239
1240 return (langexternalfindusedblocks ((hdlexternalvariable) (**cancoonglobals).hrootvariable, nil));
1241 } /*ccfindusedblocks*/
1242
1243
1244 boolean ccsetdatabase (void) {
1245
1246 /*
1247 the cancoon window should be the only one that defines this callback. it sets
1248 db.c's global data handle to the database file that stores the menubar structure.
1249
1250 this is used for other handlers who store data in our database.
1251
1252 5.0a18 dmb: this is archaic, really. we manage databasedata ourselves, we don't
1253 rely on the shell. with the new odb hosting feature, we need to wire this off
1254 and add some logic to ccsave
1255 */
1256
1257 #ifndef version5orgreater
1258 databasedata = (**cancoondata).hdatabase;
1259 #endif
1260
1261 return (true);
1262 } /*ccsetdatabase*/
1263
1264
1265 boolean ccgetdatabase (hdldatabaserecord *hdatabase) {
1266
1267 /*
1268 5.0.2b21 dmb: the new way to do it
1269 */
1270
1271 *hdatabase = (**cancoondata).hdatabase;
1272
1273 return (true);
1274 } /*ccsetdatabase*/
1275
1276
1277 boolean ccclose (void) {
1278
1279 /*
1280 the main window of cancoon is closing.
1281 */
1282
1283 #ifdef version5orgreater
1284 // hdlwindowinfo hw = cancoonwindowinfo;
1285 //
1286 // ccsavefile ((**hw).fnum, (**hw).rnum, false, false); //odbSaveFile (ccodb);
1287
1288 if ((cancoondata != nil) && (**cancoondata).flguestroot) //defensive driving
1289 return (true);
1290 #endif
1291
1292 runshutdownscripts ();
1293
1294 langexternalcloseregisteredwindows (false);
1295
1296 return (true);
1297 } /*ccclose*/
1298
1299
1300 static boolean ccverifywindowclose (WindowPtr pwindow) {
1301
1302 /*
1303 4.0b7 dmb: new feature, run a script before we close a window
1304 */
1305
1306 if (flinhibitclosedialogs) /*not allowed to do verification*/
1307 return (true);
1308
1309 if (flscriptrunning) /*not a user-generated close*/
1310 return (true);
1311
1312 return (shellrunwindowconfirmationscript (pwindow, idclosewindowscript));
1313 } /*ccverifywindowclose*/
1314
1315
1316 boolean ccpreclose (WindowPtr w) {
1317
1318 /*
1319 4.1b5 dmb: new callback so we can verify root close (i.e. so
1320 script can save it first, to avoid dialog
1321 */
1322
1323 if (!ccverifywindowclose (w))
1324 return (false);
1325
1326 if (cancoondata == nil) //5.1.5b15 dmb
1327 return (true);
1328
1329 if ((**cancoondata).flguestroot)
1330 return (true);
1331
1332 return (langexternalcloseregisteredwindows (true));
1333 } /*ccpreclose*/
1334
1335
1336 boolean ccchildclose (WindowPtr w) {
1337
1338 /*
1339 a child window of cancoon is closing.
1340
1341 for now (6/12/90) just call the close routine on the child window.
1342
1343 9/24/91 dmb: pass through return value from child
1344
1345 12/5/91 dmb: call the child's dispose record routine too
1346 */
1347
1348 boolean fl;
1349
1350 if (!ccverifywindowclose (w))
1351 return (false);
1352
1353 shellpushglobals (w);
1354
1355 fl = (*shellglobals.closeroutine) ();
1356
1357 if (fl) {
1358
1359 fl = (*shellglobals.disposerecordroutine) ();
1360
1361 shellclearwindowdata ();
1362 }
1363
1364 shellpopglobals ();
1365
1366 return (fl);
1367 } /*ccchildclose*/
1368
1369
1370 boolean ccdisposerecord (void) {
1371
1372 /*
1373 1/22/91 dmb: added scan of new ccglobalsstack
1374
1375 2.1b5 dmb: set windowinfo's data to nil; fixes revert bug when window is
1376 updated between disposal & re-opening
1377
1378 5.1.5b16 dmb: kill dependent processes before swapping in our globals, or
1379 visitprocessthreads will make the current thread appear to be dependent on them.
1380 */
1381
1382 register hdlcancoonrecord hc = cancoondata;
1383 hdlcancoonrecord origglobals = cancoonglobals;
1384 boolean flguestroot;
1385
1386 if (hc == NULL)
1387 return (true);
1388
1389 fwsNetEventShutdownDependentListeners ((long) (**hc).hdatabase);
1390
1391 killdependentprocesses ((long) hc);
1392
1393 setcancoonglobals (hc); /*make sure superglobals are ours*/
1394
1395 flguestroot = (**hc).flguestroot;
1396
1397 //#ifndef WIN95VERSION
1398 if (!flguestroot)
1399 processyieldtoagents (); /*let them terminate*/
1400 //#endif
1401
1402 dbdispose (); /*do before clearing globals -- depends on databasedata*/
1403
1404 fldisablesymbolcallbacks = true;
1405
1406 if (!flguestroot) {
1407
1408 #ifndef PIKE
1409 #if TARGET_API_MAC_CARBON == 0
1410 langipcmenushutdown ();
1411 #endif
1412
1413 #endif
1414
1415 unlinksystemtablestructure ();
1416 }
1417
1418 clearcancoonglobals (); /*do this now to avoid debug check in disposehashtable*/
1419
1420 disposecancoonrecord (hc);
1421
1422 cancoondata = nil;
1423
1424 (**cancoonwindowinfo).hdata = nil; /*unlink data from window*/
1425
1426 fldisablesymbolcallbacks = false;
1427
1428 bundle { /*scan saved globals so ccrestoreglobals knows when data is valid*/
1429
1430 register short i;
1431
1432 for (i = 0; i < cctopglobals; i++)
1433 if (ccglobalsstack [i] == hc)
1434 ccglobalsstack [i] = nil;
1435 }
1436
1437 if (origglobals != hc)
1438 setcancoonglobals (origglobals);
1439
1440 return (true);
1441 } /*ccdisposerecord*/
1442
1443
1444 boolean ccdisposefilerecord (void) {
1445
1446 hdlwindowinfo hw = shellwindowinfo;
1447 Handle x;
1448 tyvaluerecord val;
1449
1450 if ((**hw).parentwindow != nil) // not standalone, nothing to do
1451 return (true);
1452
1453 if (!(*shellglobals.getvariableroutine) (&x))
1454 return (false);
1455
1456 setexternalvalue (x, &val);
1457
1458 langexternaldisposevalue (val, false);
1459
1460 shellclearwindowdata (); //shouldn't be necessary, since we're called by a disposerecordroutine
1461
1462 return (true);
1463 } /*ccdisposefilerecord*/
1464
1465
1466 boolean ccsetsuperglobals (void) {
1467
1468 /*
1469 the cancoon window should be the only one that defines this callback. it sets
1470 the cancoon.c global "cancoonglobals" to the one linked into our table.
1471
1472 10/2/90 dmb: this can get called from cancoonbackground on a failure condition
1473 during cancoonloadfile, so we need to check cancoondata for nil
1474
1475 10/23/91 dmb: when cancoondata is nil, make sure we clear globals
1476
1477 4.1b4 dmb: set and respect new supercancoonglobals global so we can handle
1478 the case where our globals are already set, but they weren't set "super",
1479 meaning the menubar was activated.
1480 */
1481
1482 register hdlcancoonrecord hc = cancoondata;
1483
1484 if (hc == nil) {
1485
1486 clearcancoonglobals (); /*clears everything relevant*/
1487
1488 return (false);
1489 }
1490
1491 if (hc != supercancoonglobals && !(**hc).flguestroot) {
1492
1493 ccactivatemenubar (cancoonglobals, false);
1494
1495 setcancoonglobals (hc);
1496
1497 ccactivatemenubar (hc, true);
1498
1499 supercancoonglobals = hc;
1500 }
1501
1502 return (true);
1503 } /*ccsetsuperglobals*/
1504
1505
1506 boolean ccbackground (void) {
1507
1508 /*
1509 2.1b2 dmb: added call to new langerrorflush
1510 */
1511
1512 if (!shellsetsuperglobals ())
1513 return (false);
1514
1515 processscheduler (); /*give the next process a shot at the machine*/
1516
1517 langerrorflush (); /*make sure lang error is displayed*/
1518
1519 return (true);
1520 } /*ccbackground*/
1521
1522
1523 boolean ccfnumchanged (hdlfilenum newfnum) {
1524
1525 /*
1526 part of the implementation of Save As
1527
1528 5.0a18 dmb: no, it's not. it's never called.
1529 */
1530
1531 #ifdef version5orgreater
1532 return (true);
1533 #else
1534 ccsetdatabase ();
1535
1536 return (dbfnumchanged (newfnum));
1537 #endif
1538 } /*ccfnumchanged*/
1539
1540
1541 static boolean ccnewobjectcommand (short ixmenu) {
1542
1543 /*
1544 "Script", noIcon, "N", noMark, plain,
1545 "WP-Text", noIcon, noKey, noMark, plain,
1546 "Outline", noIcon, noKey, noMark, plain,
1547 "Menubar", noIcon, noKey, noMark, plain,
1548 "Table", noIcon, noKey, noMark, plain,
1549 */
1550
1551 tyexternalid idobject;
1552 WindowPtr w;
1553
1554 switch (ixmenu) {
1555 case 1:
1556 idobject = idscriptprocessor;
1557 break;
1558
1559 case 2:
1560 idobject = idwordprocessor;
1561 break;
1562
1563 /*
1564 case 3:
1565 idobject = idpictprocessor;
1566 break;
1567 */
1568
1569 case 3:
1570 idobject = idoutlineprocessor;
1571 break;
1572
1573 case 4:
1574 idobject = idmenuprocessor;
1575 break;
1576
1577 case 5:
1578 idobject = idtableprocessor;
1579 break;
1580
1581 case 7:
1582 return (shellnew ());
1583
1584 default:
1585 return (false);
1586 }
1587
1588 return (ccnewfilewindow (idobject, &w, false));
1589 } /*ccnewobjectcommand*/
1590
1591
1592 boolean ccinexpertmode (void) {
1593
1594 /*
1595 5.0a18 dmb: use new langgetuserflag
1596 */
1597
1598 return (langgetuserflag (idinexpertmodescript, true));
1599 } /*ccinexpertmode*/
1600
1601
1602 #if 0
1603
1604 static boolean cctoggleexpertmode (void) {
1605
1606 /*
1607 5.0a3 dmb: we now call Frontier.setExpertMode, not system.misc.toggleExpertMode
1608 */
1609
1610 bigstring bsscript;
1611 boolean flexpert;
1612 ptrstring bsexpert;
1613
1614 flexpert = !ccinexpertmode ();
1615
1616 getsystemtablescript (idtoggleexpertmodescript, bsscript);
1617
1618 bsexpert = (flexpert? bstrue : bsfalse);
1619
1620 parsedialogstring (bsscript, bsexpert, nil, nil, nil, bsscript);
1621
1622 langrunstringnoerror (bsscript, bsscript);
1623
1624 if (ccinexpertmode () != flexpert)
1625 return (false);
1626
1627 shellwindowmenudirty ();
1628
1629 return (true);
1630 } /*cctoggleexpertmode*/
1631
1632 #endif
1633
1634
1635 static boolean ccmenuroutine (short idmenu, short ixmenu) {
1636
1637 /*
1638 this is the only menu handling routine in the program. we have no idea
1639 what window is in front, it could be of any type -- so we must get our
1640 own globals.
1641
1642 return false if we successfully handle the menu item, so no further
1643 processing will occur
1644
1645 7/31/90 dmb: must return result that is inverse of memenu result to obey
1646 hook conventions. we shouldn't assume that we're the only menu hook.
1647
1648 8/1/90 dmb: idmenu of zero means update all hooked menus.
1649
1650 8/31/90 DW: preserve globals around call to memenu.
1651
1652 9/20/90 dmb: push frontrootglobals, rather than nil, and test the result
1653
1654 5.0a18 dmb: disabled expert mode code (added in 5.0a?)
1655 */
1656
1657 /*
1658 if (idmenu == 0 && ixmenu == 0) {
1659
1660 hdlmenu hmenu = shellmenuhandle (filemenu);
1661
1662 enablemenuitem (hmenu, expertitem);
1663
1664 checkmenuitem (hmenu, expertitem, ccinexpertmode ());
1665 }
1666
1667 if ((idmenu == filemenu) && (ixmenu == expertitem)) {
1668
1669 cctoggleexpertmode ();
1670
1671 return (false);
1672 }
1673 */
1674
1675 /*
1676 if (!idmenu) { /%request to update all of our menus%/
1677
1678 /%all our menus are enabled, dmb 8/1/90%/
1679
1680 mecheckmenubar (); /%see if menubar needs to be redrawn%/
1681
1682 return (true);
1683 }
1684 */
1685
1686 if ((idmenu == virtualmenu) && (ixmenu == helpitem))
1687 return (!cchelpcommand ());
1688
1689 if (idmenu == newobjectmenu) {
1690
1691 ccnewobjectcommand (ixmenu);
1692
1693 return (false);
1694 }
1695
1696 #ifdef fldebug
1697
1698 if (flscriptrunning && flcanusethreads) {
1699
1700 // *** need this check? - DebugStr ("\x28" "handling menu w/script running in thread");
1701
1702 return (true);
1703 }
1704
1705 #endif
1706
1707 return (!memenu (idmenu, ixmenu));
1708 } /*ccmenuroutine*/
1709
1710
1711 static boolean ccchecktablestructureglobals (hdlhashtable htable) {
1712
1713 /*
1714 10/25/91 dmb: check table structure when something in the verbs table changes
1715
1716 5.0a18 dmb: make sure we haven't just unloaded. maybe we're quitting
1717 and agents just terminated
1718 */
1719
1720 register hdlhashtable ht = htable;
1721
1722 if (fldisablesymbolcallbacks)
1723 return (false);
1724
1725 if (roottable == nil)
1726 return (false);
1727
1728 if ((ht == roottable) || (ht == systemtable) || (ht == verbstable))
1729 return (settablestructureglobals (rootvariable, false));
1730
1731 return (true);
1732 } /*ccchecktablestructureglobals*/
1733
1734
1735 static boolean ccsymbolchanged (hdlhashtable htable, const bigstring bsname, hdlhashnode hnode, boolean flvalue) {
1736
1737 /*
1738 used as a callback routine. the value of the indicated variable has changed.
1739 if the cell is being displayed, update the display of it. this is how the
1740 real-time changing of variables is implemented.
1741
1742 2/28/91 dmb: also call ccchecktablestructureglobals to make sure our
1743 globals are up to date
1744
1745 11/14/01 dmb: also call new langexternalsymbolchanged. we should really create
1746 a new callback so we don't have to call them explicitly here
1747 */
1748
1749 if (!ccchecktablestructureglobals (htable))
1750 return (false);
1751
1752 langipcsymbolchanged (htable, bsname, flvalue);
1753
1754 langexternalsymbolchanged (htable, bsname, hnode, flvalue);
1755
1756 return (tablesymbolchanged (htable, bsname, hnode, flvalue));
1757 } /*ccsymbolchanged*/
1758
1759
1760 static boolean ccsymbolinserted (hdlhashtable htable, const bigstring bsname, hdlhashnode hnode) {
1761
1762 if (!ccchecktablestructureglobals (htable))
1763 return (false);
1764
1765 langipcsymbolinserted (htable, bsname);
1766
1767 langexternalsymbolinserted (htable, bsname, hnode);
1768
1769 return (tablesymbolinserted (htable, bsname));
1770 } /*ccsymbolinserted*/
1771
1772
1773 static boolean ccsymboldeleted (hdlhashtable htable, const bigstring bsname) {
1774
1775 if (!ccchecktablestructureglobals (htable))
1776 return (false);
1777
1778 langipcsymboldeleted (htable, (ptrstring) bsname);
1779
1780 return (tablesymboldeleted (htable, bsname));
1781 } /*ccsymboldeleted*/
1782
1783
1784 static short cccomparenodes (hdlhashtable htable, hdlhashnode hnode1, hdlhashnode hnode2) {
1785
1786 return (tablecomparenodes (htable, hnode1, hnode2));
1787 } /*cccomparenodes*/
1788
1789
1790 static boolean ccsaveglobals (void) {
1791
1792 assert (cctopglobals <= maxsavedccglobals);
1793
1794 ccglobalsstack [cctopglobals++] = cancoonglobals;
1795
1796 return (true);
1797 } /*ccsaveglobals*/
1798
1799
1800 static boolean ccrestoreglobals (void) {
1801
1802 /*
1803 10/23/91 dmb: when stack entry is nil, clear globals before
1804 returning false; we don't want other globals to remain in place
1805 */
1806
1807 register hdlcancoonrecord hc = ccglobalsstack [--cctopglobals];
1808
1809 assert (cctopglobals >= 0);
1810
1811 if (hc == nil) {
1812
1813 clearcancoonglobals ();
1814
1815 return (false);
1816 }
1817
1818 if (hc != cancoonglobals)
1819 setcancoonglobals (hc);
1820
1821 return (true);
1822 } /*ccrestoreglobals*/
1823
1824
1825 static boolean ccpartialeventloop (short desiredevents) {
1826
1827 /*
1828 3/23/93 dmb: don't use ccsave/restoreglobals, 'cause we don't want to restore
1829 nil globals (in case we're being called at an odd time, like from an error
1830 alert during initialization
1831 */
1832
1833 boolean fl;
1834 hdlcancoonrecord hc;
1835
1836 hc = cancoonglobals;
1837
1838 fl = shellpartialeventloop (desiredevents);
1839
1840 if (hc != cancoonglobals)
1841 setcancoonglobals (hc);
1842
1843 return (fl);
1844 } /*ccpartialeventloop*/
1845
1846
1847 boolean ccstart (void) {
1848
1849 /*
1850 set up callback routines record, and link our data into the shell's
1851 data structure.
1852 */
1853
1854 langcallbacks.symbolchangedcallback = &ccsymbolchanged;
1855
1856 langcallbacks.symbolunlinkingcallback = &processsymbolunlinking;
1857
1858 langcallbacks.symboldeletedcallback = &ccsymboldeleted;
1859
1860 langcallbacks.symbolinsertedcallback = &ccsymbolinserted;
1861
1862 langcallbacks.comparenodescallback = &cccomparenodes;
1863
1864 langcallbacks.saveglobalscallback = &ccsaveglobals;
1865
1866 langcallbacks.restoreglobalscallback = &ccrestoreglobals;
1867
1868 langcallbacks.partialeventloopcallback = &ccpartialeventloop;
1869
1870 shellpushmenuhook (&ccmenuroutine);
1871
1872 return (ccwindowstart ());
1873 } /*ccstart*/
1874
1875
1876
1877
1878
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.