1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12 // putenv should come from stdlib.h
13 // extern "C" int putenv(char*);
14
15 #if defined(HAVE_IOSTREAM)
16 # include <iostream>
17 #else
18 # if defined(HAVE_IOSTREAM_H)
19 # include <iostream.h>
20 # endif
21 # if defined(HAVE_STREAM_H)
22 # include <stream.h>
23 # endif
24 #endif
25
26 #if defined(HAVE_IO_H)
27 #include <io.h>
28 #endif
29
30 #if defined(HAVE_UNISTD_H)
31 #include <unistd.h>
32 #endif
33
34 #if defined(HAVE_SIGNAL_H)
35 #include <signal.h>
36 #endif
37
38 #if defined(HAVE_ERRNO_H)
39 #include <errno.h>
40 #endif
41
42 #if defined(HAVE_CTYPE_H)
43 #include <ctype.h>
44 #endif
45
46 #if defined(HAVE_SYS_TYPES_H)
47 #include <sys/types.h>
48 #endif
49
50 #if defined(HAVE_SYS_STAT_H)
51 #include <sys/stat.h>
52 #endif
53
54 #if defined(HAVE_DIRECT_H)
55 #include <direct.h>
56 #define chdir _chdir
57 #endif
58
59
60 #include "lex.h"
61 #include "DXVersion.h"
62 #include "DXApplication.h"
63 #include "Network.h"
64 #include "JavaNet.h"
65 #include "Client.h"
66 #include "GraphLayout.h"
67
68 #include <Xm/Label.h>
69 #include <X11/cursorfont.h>
70
71
72 #include "oem.h"
73 #include "CommandScope.h"
74 #include "NoUndoDXAppCommand.h"
75 #include "ConfirmedQuitCommand.h"
76 #include "ConfirmedExitCommand.h"
77 #include "NoOpCommand.h"
78 #include "OpenNetworkDialog.h"
79 #include "OpenCommand.h"
80 #include "DisconnectFromServerCommand.h"
81 #include "LoadMacroDialog.h"
82 #include "LoadMDFDialog.h"
83 #include "SaveAsDialog.h"
84 #include "ToolSelector.h"
85 #include "DXAnchorWindow.h"
86
87 #include "../widgets/findcolor.h"
88
89 #include "Dictionary.h"
90 #include "DictionaryIterator.h"
91 #include "DXChild.h"
92 #include "DXExecCtl.h"
93 #include "DXPacketIF.h"
94 #include "ApplicIF.h"
95 #include "EditorWindow.h"
96 #include "HelpWin.h"
97 #include "ImageWindow.h"
98 #include "InfoDialogManager.h"
99 #include "License.h"
100 #include "List.h"
101 #include "ListIterator.h"
102 #include "QuestionDialogManager.h"
103 #include "ErrorDialogManager.h"
104 #include "NDAllocatorDictionary.h"
105 #include "SIAllocatorDictionary.h"
106 #include "CDBAllocatorDictionary.h"
107 #include "ParseMDF.h"
108 #include "InteractorStyle.h" // for BuildtheInteractorStyleDictionary()
109 #include "DecoratorStyle.h" // for BuildtheDecoratorStyleDictionary()
110 #include "StandIn.h"
111 #include "FileDialog.h"
112 #include "StartServerDialog.h"
113 #include "MacroDefinition.h"
114 #include "MsgWin.h"
115 #include "XHandler.h"
116 #include "ProcessGroupAssignDialog.h"
117 #include "ProcessGroupManager.h"
118 #include "WarningDialogManager.h"
119 #include "Node.h"
120 #include "ResourceManager.h"
121
122 #ifdef HAS_CLIPNOTIFY_EXTENSION
123 #include "../widgets/clipnotify.h"
124 #endif
125 #if (XmVersion > 1001)
126 #include "../widgets/Number.h"
127 #endif
128
129
130 #ifdef DXD_WIN
131 #define chdir _chdir
132 #define read _read
133 #endif
134 //
135 // Defines the number of minutes the timed license lasts.
136 //
137 #ifdef DEBUG
138 # define LICENSED_MINUTES 1
139 #else
140 # define LICENSED_MINUTES 5
141 #endif
142
143 //
144 // make the CR key work on the aviion: mapping Return key to Enter key.
145 //
146 #if (XmVersion > 1001)
147 #define XK_MISCELLANY
148 #include <X11/keysym.h>
149 #endif
150
151
152 //
153 // The options that can be used with -forceLicense (dxui) and -license (dx)
154 // options (.i.e. dx -license runtime) .
155 //
156 #define LIC_RT_OPTION "runtime"
157 #define LIC_DEV_OPTION "develop"
158 #define LIC_TIMED_OPTION "timed"
159 #define LIC_VIEWER_OPTION "viewer"
160
161 DXApplication* theDXApplication = NUL(DXApplication*);
162 extern "C" void InstallShutdownTimer(Widget w,
163 XtPointer clientData, XtPointer calldata);
164
165 boolean DXApplication::DXApplicationClassInitialized = FALSE;
166 DXResource DXApplication::resource;
167
168 Symbol DXApplication::MsgExecute = 0;
169 Symbol DXApplication::MsgStandBy = 0;
170 Symbol DXApplication::MsgExecuteDone = 0;
171 Symbol DXApplication::MsgServerDisconnected = 0;
172 Symbol DXApplication::MsgPanelChanged = 0;
173
174 #define IMAGE_ANCHOR_MODE "IMAGE"
175 #define EDIT_ANCHOR_MODE "EDIT"
176 #define MENUBAR_ANCHOR_MODE "MENUBAR"
177
178 // Resources below
179 #if 1
180 static
181 XrmOptionDescRec _DXOptionList[] =
182 {
183 {
184 "-directory",
185 "*directory",
186 XrmoptionSepArg,
187 NULL
188 },
189 {
190 "-edit",
191 "*anchorMode",
192 XrmoptionNoArg,
193 EDIT_ANCHOR_MODE
194 },
195 {
196 "-exec",
197 "*executive",
198 XrmoptionSepArg,
199 NULL
200 },
201 {
202 "-execute",
203 "*executeProgram",
204 XrmoptionNoArg,
205 "True"
206 },
207 {
208 "-execute_on_change",
209 "*executeOnChange",
210 XrmoptionNoArg,
211 "True"
212 },
213 {
214 "-help",
215 "*printHelpMessage",
216 XrmoptionNoArg,
217 "True"
218 },
219 {
220 "-host",
221 "*host",
222 XrmoptionSepArg,
223 NULL
224 },
225 {
226 "-image",
227 "*anchorMode",
228 XrmoptionNoArg,
229 IMAGE_ANCHOR_MODE
230 },
231 {
232 "-kiosk",
233 "*anchorMode",
234 XrmoptionNoArg,
235 MENUBAR_ANCHOR_MODE
236 },
237 {
238 "-menubar",
239 "*anchorMode",
240 XrmoptionNoArg,
241 MENUBAR_ANCHOR_MODE
242 },
243 {
244 "-noAnchorAtStartup",
245 "*noAnchorAtStartup",
246 XrmoptionNoArg,
247 "True"
248 },
249 {
250 "-noConfirmedQuit",
251 "*noConfirmedQuit",
252 XrmoptionNoArg,
253 "True"
254 },
255 {
256 "-local",
257 "*runLocally",
258 XrmoptionNoArg,
259 "True"
260 },
261 {
262 "-macros",
263 "*macros",
264 XrmoptionSepArg,
265 NULL
266 },
267 {
268 "-mdf",
269 "*userModuleDescriptionFile",
270 XrmoptionSepArg,
271 NULL
272 },
273 {
274 "-metric",
275 "*metric",
276 XrmoptionNoArg,
277 "True"
278 },
279 {
280 "-dxmdf",
281 "*executiveModuleDescriptionFile",
282 XrmoptionSepArg,
283 NULL
284 },
285 {
286 "-uimdf",
287 "*uiModuleDescriptionFile",
288 XrmoptionSepArg,
289 NULL
290 },
291 {
292 "-memory",
293 "*memory",
294 XrmoptionSepArg,
295 NULL
296 },
297 {
298 "-port",
299 "*port",
300 XrmoptionSepArg,
301 NULL
302 },
303 {
304 "-printImageCommand",
305 "*printImageCommand",
306 XrmoptionSepArg,
307 NULL
308 },
309 {
310 "-printImageFormat",
311 "*printImageFormat",
312 XrmoptionSepArg,
313 NULL
314 },
315 {
316 "-printImagePageSize",
317 "*printImagePageSize",
318 XrmoptionSepArg,
319 NULL
320 },
321 {
322 "-printImageSize",
323 "*printImageSize",
324 XrmoptionSepArg,
325 NULL
326 },
327 {
328 "-printImageResolution",
329 "*printImageResolution",
330 XrmoptionSepArg,
331 NULL
332 },
333 {
334 "-program",
335 "*program",
336 XrmoptionSepArg,
337 NULL
338 },
339 {
340 "-cfg",
341 "*cfg",
342 XrmoptionSepArg,
343 NULL
344 },
345 {
346 "-saveImageFormat",
347 "*saveImageFormat",
348 XrmoptionSepArg,
349 NULL
350 },
351 {
352 "-saveImagePageSize",
353 "*saveImagePageSize",
354 XrmoptionSepArg,
355 NULL
356 },
357 {
358 "-saveImageSize",
359 "*saveImageSize",
360 XrmoptionSepArg,
361 NULL
362 },
363 {
364 "-saveImageResolution",
365 "*saveImageResolution",
366 XrmoptionSepArg,
367 NULL
368 },
369 {
370 "-suppress",
371 "*suppressStartupWindows",
372 XrmoptionNoArg,
373 "True"
374 },
375 {
376 "-uidebug",
377 "*debugMode",
378 XrmoptionNoArg,
379 "True"
380 },
381 {
382 "-showInstanceNumbers",
383 "*showInstanceNumbers",
384 XrmoptionNoArg,
385 "True"
386 },
387 {
388 "-uionly",
389 "*runUIOnly",
390 XrmoptionNoArg,
391 "True"
392 },
393 {
394 "-uimessages",
395 "*messages",
396 XrmoptionSepArg,
397 NULL
398 },
399 {
400 "-version",
401 "*DXVersion",
402 XrmoptionNoArg,
403 "True"
404 },
405
406 //
407 // Backdoor switches:
408 //
409 {
410 "-restrictionLevel",
411 "*restrictionLevel",
412 XrmoptionSepArg,
413 NULL
414 },
415 {
416 "-appHost",
417 "*applicationHost",
418 XrmoptionSepArg,
419 NULL,
420 },
421 {
422 "-appPort",
423 "*applicationPort",
424 XrmoptionSepArg,
425 NULL,
426 },
427 {
428 "-noDXHelp",
429 "*noDXHelp",
430 XrmoptionNoArg,
431 "True"
432 },
433 {
434 "-noEditorAccess",
435 "*noEditorAccess",
436 XrmoptionNoArg,
437 "True"
438 },
439 {
440 "-notifySaveNet",
441 "*notifySaveNet",
442 XrmoptionNoArg,
443 "True"
444 },
445 {
446 "-noNetworkExecute",
447 "*noNetworkExecute",
448 XrmoptionNoArg,
449 "True"
450 },
451 {
452 "-noImageRWNetFile",
453 "*noImageRWNetFile",
454 XrmoptionNoArg,
455 "True"
456 },
457 {
458 "-noImageLoad",
459 "*noImageLoad",
460 XrmoptionNoArg,
461 "True"
462 },
463 {
464 "-limitImageOptions",
465 "*limitImageOptions",
466 XrmoptionNoArg,
467 "True"
468 },
469 {
470 "-limitedNetFileSelection",// Used to be limitedImageFileSelection
471 "*limitedNetFileSelection",
472 XrmoptionNoArg,
473 "True"
474 },
475 {
476 "-noNetFileSelection",
477 "*noNetFileSelection",
478 XrmoptionNoArg,
479 "True"
480 },
481 {
482 "-noImageSaving",
483 "*noImageSaving",
484 XrmoptionNoArg,
485 "True"
486 },
487 {
488 "-noImagePrinting",
489 "*noImagePrinting",
490 XrmoptionNoArg,
491 "True"
492 },
493 {
494 "-noInteractorEdits",
495 "*noInteractorEdits",
496 XrmoptionNoArg,
497 "True"
498 },
499 {
500 "-noInteractorAttributes",
501 "*noInteractorAttributes",
502 XrmoptionNoArg,
503 "True"
504 },
505 {
506 "-noInteractorMovement",
507 "*noInteractorMovement",
508 XrmoptionNoArg,
509 "True"
510 },
511 {
512 "-noOpenAllPanels",
513 "*noOpenAllPanels",
514 XrmoptionNoArg,
515 "True"
516 },
517 {
518 "-noPanelAccess",
519 "*noPanelAccess",
520 XrmoptionNoArg,
521 "True"
522 },
523 {
524 "-noPanelOptions",
525 "*noPanelOptions",
526 XrmoptionNoArg,
527 "True"
528 },
529 {
530 "-noPanelEdit",
531 "*noPanelEdit",
532 XrmoptionNoArg,
533 "True"
534 },
535 {
536 "-noRWConfig",
537 "*noRWConfig",
538 XrmoptionNoArg,
539 "True"
540 },
541 {
542 "-noScriptCommands",
543 "*noScriptCommands",
544 XrmoptionNoArg,
545 "True"
546 },
547 {
548 "-noMessageInfoOption",
549 "*noMessageInfoOption",
550 XrmoptionNoArg,
551 "True"
552 },
553 {
554 "-noMessageWarningOption",
555 "*noMessageWarningOption",
556 XrmoptionNoArg,
557 "True"
558 },
559 {
560 "-noEditorOnError",
561 "*noEditorOnError",
562 XrmoptionNoArg,
563 "True"
564 },
565 {
566 "-noCMapSetNameOption",
567 "*noCMapSetNameOption",
568 XrmoptionNoArg,
569 "True"
570 },
571 {
572 "-noCMapSaveMap",
573 "*noCMapSaveMap",
574 XrmoptionNoArg,
575 "True"
576 },
577 {
578 "-noWindowPlacement",
579 "*noWindowPlacement",
580 XrmoptionNoArg,
581 "True"
582 },
583 {
584 "-noCMapOpenMap",
585 "*noCMapOpenMap",
586 XrmoptionNoArg,
587 "True"
588 },
589 {
590 "-netPath",
591 "*netPath",
592 XrmoptionSepArg,
593 NULL,
594 },
595 {
596 "-noPGroupAssignment",
597 "*noPGroupAssignment",
598 XrmoptionNoArg,
599 "True"
600 },
601 {
602 "-warning",
603 "*warningEnabled",
604 XrmoptionNoArg,
605 "False"
606 },
607 {
608 "-info",
609 "*infoEnabled",
610 XrmoptionNoArg,
611 "False"
612 },
613 {
614 "-error",
615 "*errorEnabled",
616 XrmoptionNoArg,
617 "False"
618 },
619 {
620 "-forceNetFileEncryption",
621 "*forceNetFileEncryption",
622 XrmoptionSepArg,
623 NULL
624 },
625 {
626 "-cryptKey",
627 "*cryptKey",
628 XrmoptionSepArg,
629 NULL
630 },
631 {
632 "-exitAfter",
633 "*exitAfter",
634 XrmoptionNoArg,
635 "True"
636 },
637 {
638 "-forceLicense",
639 "*forceLicense",
640 XrmoptionSepArg,
641 NULL,
642 },
643 {
644 "-noExecuteMenus",
645 "*noExecuteMenus",
646 XrmoptionNoArg,
647 "True",
648 },
649 {
650 "-noConnectionMenus",
651 "*noConnectionMenus",
652 XrmoptionNoArg,
653 "True",
654 },
655 {
656 "-noWindowsMenus",
657 "*noWindowsMenus",
658 XrmoptionNoArg,
659 "True",
660 },
661 {
662 "-noExitOptions",
663 "*noExitOptions",
664 XrmoptionNoArg,
665 "True",
666 },
667 {
668 "-noImageMenus",
669 "*noImageMenus",
670 XrmoptionNoArg,
671 "True",
672 },
673 {
674 "-view",
675 "*viewDataFile",
676 XrmoptionSepArg,
677 NULL,
678 },
679 {
680 "-noAutoScrollVPE",
681 "*autoScrollVPE",
682 XrmoptionNoArg,
683 "False"
684 },
685 {
686 "-autoLayoutHeight",
687 "*autoLayoutHeight",
688 XrmoptionSepArg,
689 NULL
690 },
691 {
692 "-autoLayoutGroupSpacing",
693 "*autoLayoutGroupSpacing",
694 XrmoptionSepArg,
695 NULL
696 },
697 {
698 "-autoLayoutNodeSpacing",
699 "*autoLayoutNodeSpacing",
700 XrmoptionSepArg,
701 NULL
702 },
703 };
704
705 static
706 XtResource _DXResourceList[] =
707 {
708 {
709 "standInBackground",
710 "StandInBackground",
711 XmRPixel,
712 sizeof(Pixel),
713 XtOffset(DXResource*, standInBackground),
714 XmRImmediate,
715 (XtPointer)"#5F9EA0" // CadetBlue
716 },
717 {
718 "executionHighlightForeground",
719 "Foreground",
720 XmRPixel,
721 sizeof(Pixel),
722 XtOffset(DXResource*, executionHighlightForeground),
723 XmRImmediate,
724 (XtPointer)"#00ff7e"
725 },
726 {
727 "backgroundExecutionForeground",
728 "Foreground",
729 XmRPixel,
730 sizeof(Pixel),
731 XtOffset(DXResource*, backgroundExecutionForeground),
732 XmRImmediate,
733 (XtPointer)"#7e7eb4"
734 },
735 {
736 "errorHighlightForeground",
737 "Foreground",
738 XmRPixel,
739 sizeof(Pixel),
740 XtOffset(DXResource*, errorNodeForeground),
741 XmRImmediate,
742 (XtPointer)"#ff9b00"
743 },
744 {
745 "foreground",
746 "Foreground",
747 XmRPixel,
748 sizeof(Pixel),
749 XtOffset(DXResource*, foreground),
750 XmRImmediate,
751 (XtPointer)"Black"
752 },
753 {
754 "background",
755 "Background",
756 XmRPixel,
757 sizeof(Pixel),
758 XtOffset(DXResource*, background),
759 XmRImmediate,
760 (XtPointer)"#b4b4b4"
761 },
762 {
763 "InsensitiveColor",
764 "Color",
765 XmRPixel,
766 sizeof(Pixel),
767 XtOffset(DXResource*, insensitiveColor),
768 XmRString,
769 (XtPointer)"#888888"
770 },
771 {
772 "anchorMode",
773 "AnchorMode",
774 XmRString,
775 sizeof(String),
776 XtOffset(DXResource*, anchorMode),
777 XmRString,
778 (XtPointer)EDIT_ANCHOR_MODE
779 },
780 {
781 "DXVersion",
782 "Flag",
783 XmRBoolean,
784 sizeof(Boolean),
785 XtOffset(DXResource*, echoVersion),
786 XmRImmediate,
787 (XtPointer)False
788 },
789 {
790 "debugMode",
791 "Flag",
792 XmRBoolean,
793 sizeof(Boolean),
794 XtOffset(DXResource*, debugMode),
795 XmRImmediate,
796 (XtPointer)False
797 },
798 {
799 "showInstanceNumbers",
800 "Flag",
801 XmRBoolean,
802 sizeof(Boolean),
803 XtOffset(DXResource*, showInstanceNumbers),
804 XmRImmediate,
805 (XtPointer)False
806 },
807 {
808 "directory",
809 "Pathname",
810 XmRString,
811 sizeof(String),
812 XtOffset(DXResource*, workingDirectory),
813 XmRString,
814 NULL
815 },
816 {
817 "executive",
818 "Pathname",
819 XmRString,
820 sizeof(String),
821 XtOffset(DXResource*, executive),
822 XmRString,
823 NULL
824 },
825 {
826 "executeProgram",
827 "Flag",
828 XmRBoolean,
829 sizeof(Boolean),
830 XtOffset(DXResource*, executeProgram),
831 XmRImmediate,
832 (XtPointer)False
833 },
834 {
835 "executeOnChange",
836 "Flag",
837 XmRBoolean,
838 sizeof(Boolean),
839 XtOffset(DXResource*, executeOnChange),
840 XmRImmediate,
841 (XtPointer)False
842 },
843 {
844 "printHelpMessage",
845 "Flag",
846 XmRBoolean,
847 sizeof(Boolean),
848 XtOffset(DXResource*, showHelpMessage),
849 XmRImmediate,
850 (XtPointer)False
851 },
852 {
853 "host",
854 "Host",
855 XmRString,
856 sizeof(String),
857 XtOffset(DXResource*, server),
858 XmRString,
859 NULL
860 },
861 {
862 "noAnchorAtStartup",
863 "Flag",
864 XmRBoolean,
865 sizeof(Boolean),
866 XtOffset(DXResource*, noAnchorAtStartup),
867 XmRImmediate,
868 (XtPointer)False
869 },
870 {
871 "noConfirmedQuit",
872 "Flag",
873 XmRBoolean,
874 sizeof(Boolean),
875 XtOffset(DXResource*, noConfirmedQuit),
876 XmRImmediate,
877 (XtPointer)False
878 },
879 {
880 "macros",
881 "Searchlist",
882 XmRString,
883 sizeof(String),
884 XtOffset(DXResource*, macros),
885 XmRString,
886 NULL
887 },
888 {
889 "memory",
890 "Number",
891 XmRInt,
892 sizeof(int),
893 XtOffset(DXResource*, memorySize),
894 XmRInt,
895 0
896 },
897 {
898 "metric",
899 "Flag",
900 XmRBoolean,
901 sizeof(Boolean),
902 XtOffset(DXResource*, isMetric),
903 XmRBoolean,
904 (XtPointer)False
905 },
906 {
907 "messages",
908 "Pathname",
909 XmRString,
910 sizeof(String),
911 XtOffset(DXResource*, errorPath),
912 XmRString,
913 NULL
914 },
915 {
916 "port",
917 "Number",
918 XmRInt,
919 sizeof(int),
920 XtOffset(DXResource*, port),
921 XmRInt,
922 0
923 },
924 {
925 "printImageCommand",
926 "PrintCommand",
927 XmRString,
928 sizeof(String),
929 XtOffset(DXResource*, printImageCommand),
930 XmRString,
931 (XtPointer) "lpr"
932 },
933 {
934 "printImageFormat",
935 "ImageFileFormat",
936 XmRString,
937 sizeof(String),
938 XtOffset(DXResource*, printImageFormat),
939 XmRString,
940 (XtPointer) "PSCOLOR"
941 },
942 {
943 "printImagePageSize",
944 "ImagePageSize",
945 XmRString,
946 sizeof(String),
947 XtOffset(DXResource*, printImagePageSize),
948 XmRString,
949 NULL
950 },
951 {
952 "printImageSize",
953 "ImageSize",
954 XmRString,
955 sizeof(String),
956 XtOffset(DXResource*, printImageSize),
957 XmRString,
958 NULL
959 },
960 {
961 "printImageResolution",
962 "ImageResolution",
963 XmRInt,
964 sizeof(int),
965 XtOffset(DXResource*, printImageResolution),
966 XmRImmediate,
967 (XtPointer)0 // This is 0 (not 300) so that PrintImageDialog can
968 // tell if the user specified this option/resource
969 },
970 {
971 "program",
972 "Pathname",
973 XmRString,
974 sizeof(String),
975 XtOffset(DXResource*, program),
976 XmRString,
977 NULL
978 },
979 {
980 "cfg",
981 "Pathname",
982 XmRString,
983 sizeof(String),
984 XtOffset(DXResource*, cfgfile),
985 XmRString,
986 NULL
987 },
988 {
989 "runLocally",
990 "Flag",
991 XmRBoolean,
992 sizeof(Boolean),
993 XtOffset(DXResource*, runLocally),
994 XmRImmediate,
995 (XtPointer)False
996 },
997 {
998 "runUIOnly",
999 "Flag",
1000 XmRBoolean,
1001 sizeof(Boolean),
1002 XtOffset(DXResource*, runUIOnly),
1003 XmRImmediate,
1004 (XtPointer)False
1005 },
1006 {
1007 "saveImageFormat",
1008 "ImageFileFormat",
1009 XmRString,
1010 sizeof(String),
1011 XtOffset(DXResource*, saveImageFormat),
1012 XmRString,
1013 NULL, // This is NULL (not "PSCOLOR") so that
1014 // SaveImageDialog can tell if the user
1015 // specified this option/resource
1016 },
1017 {
1018 "saveImagePageSize",
1019 "ImagePageSize",
1020 XmRString,
1021 sizeof(String),
1022 XtOffset(DXResource*, saveImagePageSize),
1023 XmRString,
1024 NULL, // This is NULL (not "8.5x11") so that
1025 // SaveImageDialog can tell if the user
1026 // specified this option/resource
1027 },
1028 {
1029 "saveImageSize",
1030 "ImageSize",
1031 XmRString,
1032 sizeof(String),
1033 XtOffset(DXResource*, saveImageSize),
1034 XmRString,
1035 NULL,
1036 },
1037 {
1038 "saveImageResolution",
1039 "ImageResolution",
1040 XmRInt,
1041 sizeof(int),
1042 XtOffset(DXResource*, saveImageResolution),
1043 XmRImmediate,
1044 (XtPointer)0 // This is 0 (not 300) so that SaveImageDialog can
1045 // tell if the user specified this option/resource
1046 },
1047 {
1048 "suppressStartupWindows",
1049 "Flag",
1050 XmRBoolean,
1051 sizeof(Boolean),
1052 XtOffset(DXResource*, suppressStartupWindows),
1053 XmRImmediate,
1054 (XtPointer)False
1055 },
1056 {
1057 "userModuleDescriptionFile",
1058 "Pathname",
1059 XmRString,
1060 sizeof(String),
1061 XtOffset(DXResource*, userModules),
1062 XmRString,
1063 NULL
1064 },
1065 {
1066 "executiveModuleDescriptionFile",
1067 "Pathname",
1068 XmRString,
1069 sizeof(String),
1070 XtOffset(DXResource*, executiveModule),
1071 XmRString,
1072 NULL
1073 },
1074 {
1075 "uiModuleDescriptionFile",
1076 "Pathname",
1077 XmRString,
1078 sizeof(String),
1079 XtOffset(DXResource*, uiModule),
1080 XmRString,
1081 NULL
1082 },
1083 {
1084 "noWindowPlacement",
1085 "WindowPlacement",
1086 XmRBoolean,
1087 sizeof(Boolean),
1088 XtOffset(DXResource*, noWindowPlacement),
1089 XmRImmediate,
1090 (XtPointer)False
1091 },
1092
1093 /*
1094 * Backdoor resources:
1095 */
1096 {
1097 "restrictionLevel",
1098 "Restriction",
1099 XmRString,
1100 sizeof(String),
1101 XtOffset(DXResource*, restrictionLevel),
1102 XmRString,
1103 NULL
1104 },
1105 {
1106 "noRWConfig",
1107 "Flag",
1108 XmRBoolean,
1109 sizeof(Boolean),
1110 XtOffset(DXResource*, noRWConfig),
1111 XmRImmediate,
1112 (XtPointer)False
1113 },
1114 {
1115 "noPanelEdit",
1116 "Flag",
1117 XmRBoolean,
1118 sizeof(Boolean),
1119 XtOffset(DXResource*, noPanelEdit),
1120 XmRImmediate,
1121 (XtPointer)False
1122 },
1123 {
1124 "noInteractorEdits",
1125 "Flag",
1126 XmRBoolean,
1127 sizeof(Boolean),
1128 XtOffset(DXResource*, noInteractorEdits),
1129 XmRImmediate,
1130 (XtPointer)False
1131 },
1132 {
1133 "noInteractorAttributes",
1134 "Flag",
1135 XmRBoolean,
1136 sizeof(Boolean),
1137 XtOffset(DXResource*, noInteractorAttributes),
1138 XmRImmediate,
1139 (XtPointer)False
1140 },
1141 {
1142 "noInteractorMovement",
1143 "Flag",
1144 XmRBoolean,
1145 sizeof(Boolean),
1146 XtOffset(DXResource*, noInteractorMovement),
1147 XmRImmediate,
1148 (XtPointer)False
1149 },
1150 {
1151 "noOpenAllPanels",
1152 "Flag",
1153 XmRBoolean,
1154 sizeof(Boolean),
1155 XtOffset(DXResource*, noOpenAllPanels),
1156 XmRImmediate,
1157 (XtPointer)False
1158 },
1159 {
1160 "noPanelAccess",
1161 "Flag",
1162 XmRBoolean,
1163 sizeof(Boolean),
1164 XtOffset(DXResource*, noPanelAccess),
1165 XmRImmediate,
1166 (XtPointer)False
1167 },
1168 {
1169 "noPanelOptions",
1170 "Flag",
1171 XmRBoolean,
1172 sizeof(Boolean),
1173 XtOffset(DXResource*, noPanelOptions),
1174 XmRImmediate,
1175 (XtPointer)False
1176 },
1177 {
1178 "noMessageInfoOption",
1179 "Flag",
1180 XmRBoolean,
1181 sizeof(Boolean),
1182 XtOffset(DXResource*, noMessageInfoOption),
1183 XmRImmediate,
1184 (XtPointer)False
1185 },
1186 {
1187 "noMessageWarningOption",
1188 "Flag",
1189 XmRBoolean,
1190 sizeof(Boolean),
1191 XtOffset(DXResource*, noMessageWarningOption),
1192 XmRImmediate,
1193 (XtPointer)False
1194 },
1195 {
1196 "noEditorOnError",
1197 "Flag",
1198 XmRBoolean,
1199 sizeof(Boolean),
1200 XtOffset(DXResource*, noEditorOnError),
1201 XmRImmediate,
1202 (XtPointer)False
1203 },
1204 {
1205 "noScriptCommands",
1206 "Flag",
1207 XmRBoolean,
1208 sizeof(Boolean),
1209 XtOffset(DXResource*, noScriptCommands),
1210 XmRImmediate,
1211 (XtPointer)False
1212 },
1213 {
1214 "noPGroupAssignment",
1215 "Flag",
1216 XmRBoolean,
1217 sizeof(Boolean),
1218 XtOffset(DXResource*, noPGroupAssignment),
1219 XmRImmediate,
1220 (XtPointer)False
1221 },
1222 {
1223 "noImageRWNetFile",
1224 "Flag",
1225 XmRBoolean,
1226 sizeof(Boolean),
1227 XtOffset(DXResource*, noImageRWNetFile),
1228 XmRImmediate,
1229 (XtPointer)False
1230 },
1231 {
1232 "limitedNetFileSelection",
1233 "Flag",
1234 XmRBoolean,
1235 sizeof(Boolean),
1236 XtOffset(DXResource*, limitedNetFileSelection),
1237 XmRImmediate,
1238 (XtPointer)False
1239 },
1240 {
1241 "netPath",
1242 "NetPath",
1243 XmRString,
1244 sizeof(String),
1245 XtOffset(DXResource*, netPath),
1246 XmRString,
1247 NULL
1248 },
1249 {
1250 "noImageLoad",
1251 "Flag",
1252 XmRBoolean,
1253 sizeof(Boolean),
1254 XtOffset(DXResource*, noImageLoad),
1255 XmRImmediate,
1256 (XtPointer)False
1257 },
1258 {
1259 "noImageSaving",
1260 "Flag",
1261 XmRBoolean,
1262 sizeof(Boolean),
1263 XtOffset(DXResource*, noImageSaving),
1264 XmRImmediate,
1265 (XtPointer)False
1266 },
1267 {
1268 "noImagePrinting",
1269 "Flag",
1270 XmRBoolean,
1271 sizeof(Boolean),
1272 XtOffset(DXResource*, noImagePrinting),
1273 XmRImmediate,
1274 (XtPointer)False
1275 },
1276 {
1277 "limitImageOptions",
1278 "Flag",
1279 XmRBoolean,
1280 sizeof(Boolean),
1281 XtOffset(DXResource*, limitImageOptions),
1282 XmRImmediate,
1283 (XtPointer)False
1284 },
1285 {
1286 "notifySaveNet",
1287 "Flag",
1288 XmRBoolean,
1289 sizeof(Boolean),
1290 XtOffset(DXResource*, notifySaveNet),
1291 XmRImmediate,
1292 (XtPointer)False
1293 },
1294 {
1295 "noNetworkExecute",
1296 "Flag",
1297 XmRBoolean,
1298 sizeof(Boolean),
1299 XtOffset(DXResource*, noNetworkExecute),
1300 XmRImmediate,
1301 (XtPointer)False
1302 },
1303 {
1304 "noEditorAccess",
1305 "Flag",
1306 XmRBoolean,
1307 sizeof(Boolean),
1308 XtOffset(DXResource*, noEditorAccess),
1309 XmRImmediate,
1310 (XtPointer)False
1311 },
1312 {
1313 "noDXHelp",
1314 "Flag",
1315 XmRBoolean,
1316 sizeof(Boolean),
1317 XtOffset(DXResource*, noDXHelp),
1318 XmRImmediate,
1319 (XtPointer)False
1320 },
1321 {
1322 "noCMapSetNameOption",
1323 "Flag",
1324 XmRBoolean,
1325 sizeof(Boolean),
1326 XtOffset(DXResource*, noCMapSetNameOption),
1327 XmRImmediate,
1328 (XtPointer)False
1329 },
1330 {
1331 "noCMapOpenMap",
1332 "Flag",
1333 XmRBoolean,
1334 sizeof(Boolean),
1335 XtOffset(DXResource*, noCMapOpenMap),
1336 XmRImmediate,
1337 (XtPointer)False
1338 },
1339 {
1340 "noCMapSaveMap",
1341 "Flag",
1342 XmRBoolean,
1343 sizeof(Boolean),
1344 XtOffset(DXResource*, noCMapSaveMap),
1345 XmRImmediate,
1346 (XtPointer)False
1347 },
1348 {
1349 "applicationPort",
1350 "Number",
1351 XmRInt,
1352 sizeof(int),
1353 XtOffset(DXResource*, applicationPort),
1354 XmRInt,
1355 NULL
1356 },
1357 {
1358 "applicationHost",
1359 "ApplicationHost",
1360 XmRString,
1361 sizeof(String),
1362 XtOffset(DXResource*, applicationHost),
1363 XmRString,
1364 NULL
1365 },
1366 {
1367 "infoEnabled",
1368 "InfoEnabled",
1369 XmRBoolean,
1370 sizeof(Boolean),
1371 XtOffset(DXResource*, infoEnabled),
1372 XmRImmediate,
1373 (XtPointer)True
1374 },
1375 {
1376 "warningEnabled",
1377 "WarningEnabled",
1378 XmRBoolean,
1379 sizeof(Boolean),
1380 XtOffset(DXResource*, warningEnabled),
1381 XmRImmediate,
1382 (XtPointer)True
1383 },
1384 {
1385 "errorEnabled",
1386 "ErrorEnabled",
1387 XmRBoolean,
1388 sizeof(Boolean),
1389 XtOffset(DXResource*, errorEnabled),
1390 XmRImmediate,
1391 (XtPointer)True
1392 },
1393 {
1394 "moduleInfoOpensMessage",
1395 "ModuleInfoOpensMessage",
1396 XmRBoolean,
1397 sizeof(Boolean),
1398 XtOffset(DXResource*, moduleInfoOpensMessage),
1399 XmRImmediate,
1400 (XtPointer)True
1401 },
1402 {
1403 "infoOpensMessage",
1404 "InfoOpensMessage",
1405 XmRBoolean,
1406 sizeof(Boolean),
1407 XtOffset(DXResource*, infoOpensMessage),
1408 XmRImmediate,
1409 (XtPointer)False
1410 },
1411 {
1412 "warningOpensMessage",
1413 "WarningOpensMessage",
1414 XmRBoolean,
1415 sizeof(Boolean),
1416 XtOffset(DXResource*, warningOpensMessage),
1417 XmRImmediate,
1418 (XtPointer)False
1419 },
1420 {
1421 "errorOpensMessage",
1422 "ErrorOpensMessage",
1423 XmRBoolean,
1424 sizeof(Boolean),
1425 XtOffset(DXResource*, errorOpensMessage),
1426 XmRImmediate,
1427 (XtPointer)True
1428 },
1429 {
1430 "useWindowSpecs",
1431 "UseWindowSpecs",
1432 XmRBoolean,
1433 sizeof(Boolean),
1434 XtOffset(DXResource*, useWindowSpecs),
1435 XmRImmediate,
1436 (XtPointer)False
1437 },
1438 {
1439 "forceNetFileEncryption",
1440 "ForceNetFileEncryption",
1441 XmRBoolean,
1442 sizeof(Boolean),
1443 XtOffset(DXResource*, forceNetFileEncryption),
1444 XmRImmediate,
1445 (XtPointer)False
1446 },
1447 {
1448 "cryptKey",
1449 "Cryptkey",
1450 XmRString,
1451 sizeof(String),
1452 XtOffset(DXResource*, cryptKey),
1453 XmRString,
1454 NULL
1455 },
1456 {
1457 "exitAfter",
1458 "ExitAfter",
1459 XmRBoolean,
1460 sizeof(Boolean),
1461 XtOffset(DXResource*, exitAfter),
1462 XmRImmediate,
1463 (XtPointer)False
1464 },
1465 {
1466 "forceLicense",
1467 "License",
1468 XmRString,
1469 sizeof(String),
1470 XtOffset(DXResource*, forceFunctionalLicense),
1471 XmRString,
1472 NULL
1473 },
1474 {
1475 "noExecuteMenus",
1476 "NoExecuteMenus",
1477 XmRBoolean,
1478 sizeof(Boolean),
1479 XtOffset(DXResource*, noExecuteMenus),
1480 XmRImmediate,
1481 (XtPointer)False
1482 },
1483 {
1484 "noConnectionMenus",
1485 "NoConnectionMenus",
1486 XmRBoolean,
1487 sizeof(Boolean),
1488 XtOffset(DXResource*, noConnectionMenus),
1489 XmRImmediate,
1490 (XtPointer)False
1491 },
1492 {
1493 "noWindowsMenus",
1494 "NoWindowsMenus",
1495 XmRBoolean,
1496 sizeof(Boolean),
1497 XtOffset(DXResource*, noWindowsMenus),
1498 XmRImmediate,
1499 (XtPointer)False
1500 },
1501 {
1502 "noExitOptions",
1503 "NoExitOptions",
1504 XmRBoolean,
1505 sizeof(Boolean),
1506 XtOffset(DXResource*, noExitOptions),
1507 XmRImmediate,
1508 (XtPointer)False
1509 },
1510 {
1511 "noImageMenus",
1512 "NoMenus",
1513 XmRBoolean,
1514 sizeof(Boolean),
1515 XtOffset(DXResource*, noImageMenus),
1516 XmRImmediate,
1517 (XtPointer)False
1518 },
1519 {
1520 "oemApplicationName",
1521 "ApplicationName",
1522 XmRString,
1523 sizeof(String),
1524 XtOffset(DXResource*, oemApplicationName),
1525 XmRString,
1526 NULL
1527 },
1528 {
1529 "oemApplicationNameCode",
1530 "ApplicationNameCode",
1531 XmRString,
1532 sizeof(String),
1533 XtOffset(DXResource*, oemApplicationNameCode),
1534 XmRString,
1535 NULL
1536 },
1537 {
1538 "oemLicenseCode",
1539 "LicenseCode",
1540 XmRString,
1541 sizeof(String),
1542 XtOffset(DXResource*, oemLicenseCode),
1543 XmRString,
1544 NULL
1545 },
1546 {
1547 "viewDataFile",
1548 "ViewDataFile",
1549 XmRString,
1550 sizeof(String),
1551 XtOffset(DXResource*, viewDataFile),
1552 XmRString,
1553 NULL
1554 },
1555 {
1556 "autoScrollVPE",
1557 "Flag",
1558 XmRBoolean,
1559 sizeof(Boolean),
1560 XtOffset(DXResource*, autoScrollVPEInitVal),
1561 XmRImmediate,
1562 (XtPointer)True
1563 },
1564 {
1565 "autoLayoutHeight",
1566 "Number",
1567 XmRInt,
1568 sizeof(int),
1569 XtOffset(DXResource*, autoLayoutHeight),
1570 XmRInt,
1571 0
1572 },
1573 {
1574 "autoLayoutGroupSpacing",
1575 "Number",
1576 XmRInt,
1577 sizeof(int),
1578 XtOffset(DXResource*, autoLayoutGroupSpacing),
1579 XmRInt,
1580 0
1581 },
1582 {
1583 "autoLayoutNodeSpacing",
1584 "Number",
1585 XmRInt,
1586 sizeof(int),
1587 XtOffset(DXResource*, autoLayoutNodeSpacing),
1588 XmRInt,
1589 0
1590 },
1591 //
1592 // For java
1593 //
1594 {
1595 "cosmoDir",
1596 "CosmoDir",
1597 XmRString,
1598 sizeof(String),
1599 XtOffset(DXResource*, cosmoDir),
1600 XmRString,
1601 (XtPointer) ""
1602 },
1603 {
1604 "jdkDir",
1605 "JdkDir",
1606 XmRString,
1607 sizeof(String),
1608 XtOffset(DXResource*, jdkDir),
1609 XmRString,
1610 (XtPointer) ""
1611 },
1612 {
1613 "htmlDir",
1614 "HtmlDir",
1615 XmRString,
1616 sizeof(String),
1617 XtOffset(DXResource*, htmlDir),
1618 XmRString,
1619 (XtPointer) ""
1620 },
1621 {
1622 "serverDir",
1623 "ServerDir",
1624 XmRString,
1625 sizeof(String),
1626 XtOffset(DXResource*, serverDir),
1627 XmRString,
1628 (XtPointer) ""
1629 },
1630 {
1631 "dxJarFile",
1632 "DxJarFile",
1633 XmRString,
1634 sizeof(String),
1635 XtOffset(DXResource*, dxJarFile),
1636 XmRString,
1637 (XtPointer) ""
1638 },
1639 {
1640 "userHtmlDir",
1641 "UserHtmlDir",
1642 XmRString,
1643 sizeof(String),
1644 XtOffset(DXResource*, userHtmlDir),
1645 XmRString,
1646 (XtPointer) "user"
1647 },
1648 };
1649 #endif
1650
1651
1652 static
1653 const String _defaultDXResources[] =
1654 {
1655 "*quitOption.labelString: Quit",
1656 "*quitOption.mnemonic: Q",
1657 "*quitOption.accelerator: Ctrl<Key>Q",
1658 "*quitOption.acceleratorText: Ctrl+Q",
1659 "*standInBackground: #5F9EA0", // CadetBlue
1660 "*executionHighlightForeground: #00ff7e",
1661 "*backgroundExecutionForeground: #7e7eb4",
1662 "*errorHighlightForeground: #ff9b00",
1663 "*InsensitiveColor: #888888",
1664
1665 // purify <explitive deleted> the bed because of this
1666 // "*tearOffModel: XmTEAR_OFF_ENABLED",
1667 NULL
1668 };
1669
1670 extern "C"
1671 void
TurnOffButtonHelp(Widget,XEvent *,String *,Cardinal *)1672 TurnOffButtonHelp(
1673 Widget /* widget */,
1674 XEvent* /* event */,
1675 String* /* params */,
1676 Cardinal* /* num_params */)
1677 {
1678 return;
1679 }
1680
1681 String DXApplication::ListValuedSettings[] = {
1682 RECENT_NETS,
1683 EXPANDED_CATEGORIES,
1684 NULL
1685 };
1686
DXApplication(char * className)1687 DXApplication::DXApplication(char* className): IBMApplication(className)
1688 {
1689 #if defined(BETA_VERSION) && defined(NOTDEF)
1690 //
1691 // Exit if this is an old BETA copy
1692 //
1693 this->betaTimeoutCheck();
1694 #endif
1695
1696 //
1697 // Set the global DX application pointer.
1698 //
1699 theDXApplication = this;
1700 this->anchor = NULL;
1701 this->appLicenseType = UndeterminedLicense;
1702 this->funcLicenseType = UndeterminedLicense;
1703 this->serverDisconnectScheduled = FALSE;
1704 this->network = NULL;
1705 //
1706 // Create the local command scope.
1707 //
1708 this->commandScope = new CommandScope();
1709
1710 //
1711 // Initialize the packet interface.
1712 //
1713 this->serverInfo.packet = NULL;
1714 this->applicationPacket = NULL;
1715 this->startServerDialog = NULL;
1716 this->loadMacroDialog = NULL;
1717 this->openNetworkDialog = NULL;
1718 this->messageWindow = NULL;
1719 this->loadMDFDialog = NULL;
1720 this->processGroupAssignDialog = NULL;
1721
1722 //
1723 // Create the application commands.
1724 //
1725 this->quitCmd =
1726 new ConfirmedQuitCommand
1727 ("quit",
1728 this->commandScope,
1729 TRUE,
1730 this);
1731
1732 this->exitCmd =
1733 new ConfirmedExitCommand
1734 ("exit",
1735 this->commandScope,
1736 TRUE,
1737 this);
1738
1739 this->openFileCmd =
1740 new OpenCommand("open",
1741 this->commandScope,
1742 TRUE,
1743 this);
1744
1745 this->messageWindowCmd =
1746 new NoUndoDXAppCommand("messageWindowCmd",
1747 this->commandScope,
1748 TRUE,
1749 this,
1750 NoUndoDXAppCommand::OpenMessageWindow);
1751
1752 this->openSequencerCmd =
1753 new NoUndoDXAppCommand("openSequencerCmd",
1754 this->commandScope,
1755 FALSE,
1756 this,
1757 NoUndoDXAppCommand::OpenSequencer);
1758
1759 this->openAllColormapCmd =
1760 new NoUndoDXAppCommand("openAllColormapCmd",
1761 this->commandScope,
1762 FALSE,
1763 this,
1764 NoUndoDXAppCommand::OpenAllColormaps);
1765
1766 this->loadMacroCmd =
1767 new NoUndoDXAppCommand("Load Macro Command",
1768 this->commandScope,
1769 TRUE,
1770 this,
1771 NoUndoDXAppCommand::LoadMacro);
1772
1773 this->executeOnceCmd =
1774 new NoUndoDXAppCommand("Execute Once",
1775 this->commandScope,
1776 FALSE,
1777 this,
1778 NoUndoDXAppCommand::ExecuteOnce);
1779
1780 this->executeOnChangeCmd =
1781 new NoUndoDXAppCommand("Execute On Change",
1782 this->commandScope,
1783 FALSE,
1784 this,
1785 NoUndoDXAppCommand::ExecuteOnChange);
1786
1787 this->endExecutionCmd =
1788 new NoUndoDXAppCommand("End Execution",
1789 this->commandScope,
1790 FALSE,
1791 this,
1792 NoUndoDXAppCommand::EndExecution);
1793
1794 this->connectedToServerCmd =
1795 new NoOpCommand("Connected To Server", this->commandScope, TRUE);
1796
1797 this->disconnectedFromServerCmd =
1798 new NoOpCommand("Disconnected From Server", this->commandScope, TRUE);
1799
1800 this->executingCmd =
1801 new NoOpCommand("executingCmd", this->commandScope, TRUE);
1802 this->notExecutingCmd =
1803 new NoOpCommand("notExecutingCmd", this->commandScope, TRUE);
1804
1805 this->connectToServerCmd =
1806 new NoUndoDXAppCommand("Start Server",
1807 this->commandScope,
1808 TRUE,
1809 this,
1810 NoUndoDXAppCommand::StartServer);
1811
1812 this->resetServerCmd =
1813 new NoUndoDXAppCommand("Reset Server",
1814 this->commandScope,
1815 FALSE,
1816 this,
1817 NoUndoDXAppCommand::ResetServer);
1818
1819 this->disconnectFromServerCmd =
1820 new DisconnectFromServerCommand("Disconnect From Server...",
1821 this->commandScope,
1822 FALSE);
1823
1824 #if USE_REMAP // 6/14/93
1825 this->toggleRemapInteractorsCmd =
1826 new NoUndoDXAppCommand("Remap Interactor Outputs...",
1827 this->commandScope,
1828 TRUE,
1829 this,
1830 NoUndoDXAppCommand::RemapInteractorOutputs);
1831 #endif
1832 this->loadMDFCmd =
1833 new NoUndoDXAppCommand("Load MDF...",
1834 this->commandScope,
1835 TRUE,
1836 this,
1837 NoUndoDXAppCommand::LoadUserMDF);
1838
1839 this->toggleInfoEnable =
1840 new NoUndoDXAppCommand("Enable Information",
1841 this->commandScope,
1842 TRUE,
1843 this,
1844 NoUndoDXAppCommand::ToggleInfoEnable);
1845 this->toggleWarningEnable =
1846 new NoUndoDXAppCommand("Enable Warnings",
1847 this->commandScope,
1848 TRUE,
1849 this,
1850 NoUndoDXAppCommand::ToggleWarningEnable);
1851 this->toggleErrorEnable =
1852 new NoUndoDXAppCommand("Enable Errors",
1853 this->commandScope,
1854 TRUE,
1855 this,
1856 NoUndoDXAppCommand::ToggleErrorEnable);
1857 this->assignProcessGroupCmd =
1858 new NoUndoDXAppCommand("assignProcessGroup",
1859 this->commandScope,
1860 TRUE,
1861 this,
1862 NoUndoDXAppCommand::AssignProcessGroup);
1863
1864 this->connectedToServerCmd->autoActivate(this->executeOnceCmd);
1865 this->connectedToServerCmd->autoActivate(this->executeOnChangeCmd);
1866 this->connectedToServerCmd->autoActivate(this->endExecutionCmd);
1867 this->connectedToServerCmd->autoActivate(this->disconnectFromServerCmd);
1868 this->connectedToServerCmd->autoActivate(this->resetServerCmd);
1869 this->connectedToServerCmd->autoDeactivate(this->connectToServerCmd);
1870
1871
1872 this->disconnectedFromServerCmd->autoActivate(this->connectToServerCmd);
1873 this->disconnectedFromServerCmd->autoDeactivate(this->executeOnceCmd);
1874 this->disconnectedFromServerCmd->autoDeactivate(this->executeOnChangeCmd);
1875 this->disconnectedFromServerCmd->autoDeactivate(this->endExecutionCmd);
1876 this->disconnectedFromServerCmd->autoDeactivate(this->disconnectFromServerCmd);
1877 this->disconnectedFromServerCmd->autoDeactivate(this->resetServerCmd);
1878
1879 //
1880 // Once in execute on change don't allow it again until the user
1881 // does an endExecutionCmd
1882 //
1883 this->executeOnChangeCmd->autoDeactivate(this->executeOnChangeCmd);
1884 this->endExecutionCmd->autoActivate(this->executeOnChangeCmd);
1885 this->openFileCmd->autoActivate(this->executeOnChangeCmd);
1886
1887
1888 //
1889 // Set the automatic activation of any commands that depend on whether
1890 // or not we are currently executing.
1891 //
1892 this->executingCmd->autoDeactivate(this->openFileCmd);
1893 this->notExecutingCmd->autoActivate(this->openFileCmd);
1894 this->executingCmd->autoDeactivate(this->executeOnceCmd);
1895 this->notExecutingCmd->autoActivate(this->executeOnceCmd);
1896
1897 //
1898 // Don't allow execute on change during an execute once.
1899 //
1900 this->executeOnceCmd->autoDeactivate(this->executeOnChangeCmd);
1901 this->notExecutingCmd->autoActivate(this->executeOnChangeCmd);
1902
1903 //
1904 // Initialize the NodeDefinition allocator.
1905 //
1906 theNDAllocatorDictionary = new NDAllocatorDictionary;
1907
1908 this->readFirstNetwork = FALSE;
1909
1910 #if !defined(WORKSPACE_PAGES)
1911 this->PGManager = new ProcessGroupManager(this);
1912 #endif
1913
1914 }
1915
~DXApplication()1916 DXApplication::~DXApplication()
1917 {
1918 #ifdef __PURIFY__
1919 // do not free memory just before exiting (makes termination slow).
1920
1921
1922 //
1923 // This deletes the panels. We need to delete the panels before the
1924 // network is deleted, because the panel's destructor references the
1925 // network which makes Purify unhappy (referencing freed memory).
1926 //
1927 this->network->clear();
1928 this->destroyDumpedObjects();
1929
1930 //
1931 // Delete the anchor window after clearing, but before
1932 // deleting the network.
1933 //
1934 delete this->anchor;
1935 this->anchor = NULL;
1936
1937 Network *n;
1938 ListIterator iterator(this->macroList);
1939 while (n = (Network*)this->macroList.getElement(1)) {
1940 this->macroList.deleteElement(1);
1941 delete n;
1942 }
1943 delete this->network;
1944 this->destroyDumpedObjects();
1945
1946
1947 //
1948 // Delete the packet interfaces after the networks
1949 //
1950 if (this->serverInfo.packet)
1951 {
1952 delete theDXApplication->serverInfo.packet;
1953 theDXApplication->serverInfo.packet = NULL;
1954 theDXApplication->disconnectedFromServerCmd->execute();
1955 }
1956
1957 if (this->applicationPacket)
1958 delete this->applicationPacket;
1959 this->destroyDumpedObjects();
1960
1961 //
1962 // Delete objects that were scheduled for deletion.
1963 // This must be before any of the DXApplication state.
1964 //
1965 this->destroyDumpedObjects();
1966
1967 // Delete the application windows
1968 if (this->messageWindow)
1969 delete this->messageWindow;
1970
1971 //
1972 // Delete the application dialogs
1973 //
1974 if (this->loadMacroDialog)
1975 delete this->loadMacroDialog;
1976 if (this->loadMDFDialog)
1977 delete this->loadMDFDialog;
1978 if (this->startServerDialog)
1979 delete this->startServerDialog;
1980 if (this->openNetworkDialog)
1981 delete this->openNetworkDialog;
1982
1983 //
1984 // Delete the application commands.
1985 //
1986 delete this->quitCmd;
1987 delete this->exitCmd;
1988 delete this->openFileCmd;
1989 delete this->loadMacroCmd;
1990 delete this->executeOnceCmd;
1991 delete this->executeOnChangeCmd;
1992 delete this->endExecutionCmd;
1993 delete this->connectedToServerCmd;
1994 delete this->disconnectedFromServerCmd;
1995 delete this->executingCmd;
1996 delete this->notExecutingCmd;
1997 delete this->connectToServerCmd;
1998 delete this->resetServerCmd;
1999 delete this->disconnectFromServerCmd;
2000 delete this->messageWindowCmd;
2001 delete this->openSequencerCmd;
2002 delete this->openAllColormapCmd;
2003
2004 delete this->loadMDFCmd;
2005 delete this->toggleInfoEnable;
2006 delete this->toggleWarningEnable;
2007 delete this->toggleErrorEnable;
2008 delete this->assignProcessGroupCmd;
2009
2010 #if !defined(WORKSPACE_PAGES)
2011 delete this->PGManager;
2012 #endif
2013
2014 //
2015 // Delete the command scope.
2016 //
2017 delete this->commandScope;
2018
2019 if (this->serverInfo.server)
2020 delete this->serverInfo.server;
2021 if (this->serverInfo.executive)
2022 delete this->serverInfo.executive;
2023 if (this->serverInfo.workingDirectory)
2024 delete this->serverInfo.workingDirectory;
2025 if (this->serverInfo.userModules)
2026 delete this->serverInfo.userModules;
2027
2028
2029 #if 0
2030 if (theCPGroupDialog) {
2031 theCPGroupDialog = NULL;
2032 delete theCPGroupDialog;
2033 }
2034 delete theSIAllocatorDictionary; theSIAllocatorDictionary = NULL;
2035 delete theCDBAllocatorDictionary; theCDBAllocatorDictionary = NULL;
2036 delete theDynamicPackageDictionary; theDynamicPackageDictionary = NULL;
2037 delete theNDAllocatorDictionary; theNDAllocatorDictionary = NULL;
2038 delete theSymbolManager; theSymbolManager = NULL;
2039 delete theInteractorStyleDictionary;theInteractorStyleDictionary = NULL;
2040
2041 DictionaryIterator di(*theNodeDefinitionDictionary);
2042 NodeDefinition *nd;
2043 while (nd = (NodeDefinition*)di.getNextDefinition()) {
2044 delete nd;
2045 delete theNodeDefinitionDictionary; theNodeDefinitionDictionary = NULL;
2046 #endif
2047
2048 ListIterator iter(this->saveResourceValues);
2049 List* resources;
2050 while (resources=(List*)iter.getNext()) {
2051 if (resources) delete resources;
2052 }
2053
2054 #endif // 0 - do not free memory just before terminating (wastes time).
2055
2056 //
2057 // Set the flag to terminate the event processing loop.
2058 //
2059 this->runApplication = FALSE;
2060
2061 theDXApplication = NULL;
2062 }
2063
2064
2065 //
2066 // Read the file that describes modules.
2067 // This is done once at start up and so we load theNodeDefinitionDictionary
2068 // directly with LoadMDFFile.
2069 //
2070 void DXApplication::loadMDF()
2071 {
2072 //
2073 // Read the MDF file.
2074 //
2075 char s[1000];
2076 if (*this->resource.executiveModule == '/' ||
2077 *this->resource.executiveModule == '.')
2078 strcpy(s, this->resource.executiveModule);
2079 else
2080 {
2081 strcpy(s, this->getUIRoot());
2082 strcat(s, "/");
2083 strcat(s, this->resource.executiveModule);
2084 }
2085 Dictionary newdefs;
2086 if (!LoadMDFFile(s,"executive",&newdefs, FALSE))
2087 return;
2088
2089 //
2090 // Mark all of these as system-tools.
2091 //
2092 NodeDefinition *nd;
2093 DictionaryIterator di(newdefs);
2094 while ( (nd = (NodeDefinition*)di.getNextDefinition()) ) {
2095 Symbol s = nd->getNameSymbol();
2096 theNodeDefinitionDictionary->addDefinition(s,(const void*)nd);
2097 nd->setUserTool(FALSE);
2098 }
2099
2100 }
2101 //
2102 // Read the file that describes interactors.
2103 // This is done once at start up and so we load theNodeDefinitionDictionary
2104 // directly with LoadMDFFile.
2105 //
2106 void DXApplication::loadIDF()
2107 {
2108 //
2109 // Read the MDF file.
2110 // Use ui++.mdf until we completely switch over to this UI
2111 // (from the old one which uses ui.mdf)
2112 //
2113 BuildtheInteractorStyleDictionary();
2114
2115 char s[1000];
2116 if (*this->resource.uiModule == '/' ||
2117 *this->resource.uiModule == '.')
2118 strcpy(s, this->resource.uiModule);
2119 else
2120 {
2121 strcpy(s, this->getUIRoot());
2122 strcat(s, "/");
2123 strcat(s, this->resource.uiModule);
2124 }
2125
2126 Dictionary newdefs;
2127 if (!LoadMDFFile(s,"user interface",&newdefs, FALSE))
2128 return;
2129
2130 //
2131 // Mark all of these as system-tools.
2132 //
2133 NodeDefinition *nd;
2134 DictionaryIterator di(newdefs);
2135 while ( (nd = (NodeDefinition*)di.getNextDefinition()) ) {
2136 Symbol s = nd->getNameSymbol();
2137 theNodeDefinitionDictionary->addDefinition(s,(const void*)nd);
2138 nd->setUserTool(FALSE);
2139 }
2140
2141 }
2142
2143 //
2144 // Read the file that describes interactors.
2145 // If dict is not null then fill the given dictionary with the
2146 // NodeDefintions found in the given MDF.
2147 // This is possibly done more than once, so we don't want to load
2148 // theNodeDefinitionDictionary directly. Instead, we load a local dictionary,
2149 // then merge it with theNodeDefinitionDictionary. We then load all the tools
2150 // in the temporary dictionary into the ToolSelector(s).
2151 //
2152 void DXApplication::loadUDF(const char *fileName, Dictionary *dict,
2153 boolean uiLoadedOnly)
2154 {
2155 Dictionary local_dict;
2156 if (!dict)
2157 dict = &local_dict;
2158 if (LoadMDFFile(fileName,"user's",dict, uiLoadedOnly) &&
2159 dict->getSize() > 0) {
2160 Dictionary olddefs;
2161
2162 //
2163 // Replace the old NodeDefinitions with the new ones.
2164 //
2165 theNodeDefinitionDictionary->replaceDefinitions(dict, &olddefs);
2166
2167 //
2168 // Send any new definitions to the server.
2169 //
2170 this->sendNewMDFToServer(dict,&olddefs);
2171
2172 //
2173 // Make sure the tool selectors get updated.
2174 //
2175 ToolSelector::MergeNewTools(dict);
2176
2177 //
2178 // Now ask all the networks to update the node that are contained
2179 // within the network.
2180 //
2181 this->network->redefineNodes(dict,&olddefs);
2182 ListIterator li(this->macroList);
2183 Network *net;
2184 while ( (net = (Network*)li.getNext()) )
2185 net->redefineNodes(dict,&olddefs);
2186
2187 //
2188 // And now we can get rid of the old NodeDefinitions.
2189 //
2190 DictionaryIterator di(olddefs);
2191 NodeDefinition *nd;
2192 while ( (nd = (NodeDefinition*)di.getNextDefinition()) )
2193 delete nd;
2194
2195 }
2196 }
2197
2198
2199 #if defined (SIGDANGER)
2200 extern "C" {
2201 static void
2202 SigDangerHandler(int dummy)
2203 {
2204 char msg[1024];
2205 #if defined(ibm6000)
2206 sprintf(msg,"AIX has notified %s that the User Interface\nis in "
2207 "danger of being killed due to insufficient page space.\n",
2208 theApplication->getInformalName());
2209 #else
2210 sprintf(msg,"The operating system has issued a SIGDANGER to %s\n",
2211 theApplication->getInformalName());
2212 #endif
2213 write(2, msg, STRLEN(msg));
2214 signal(SIGDANGER, SigDangerHandler);
2215 }
2216 }
2217 #endif
2218
2219
2220 // FIXME: We need a place to remove the signal handlers. It's not good
2221 // to leave them installed because a signal might arrive in the middle of
2222 // a destructor. If that happens, then the handler will crash.
2223 void
2224 DXApplication::InitializeSignals(void)
2225 {
2226 // adding a signal handler for SIGABRT does not catch us if
2227 // an assert fails. The function abort does not return.
2228 if (!getenv ("DXUINOCATCHERROR")) {
2229 #if defined(HAVE_SIGDANGER)
2230 signal(SIGDANGER, SigDangerHandler);
2231 #endif
2232 signal (SIGSEGV, DXApplication_HandleCoreDump);
2233 #if defined(HAVE_SIGBUS)
2234 signal (SIGBUS, DXApplication_HandleCoreDump);
2235 #endif
2236 #if defined(HAVE_SIGKILL)
2237 signal (SIGKILL, DXApplication_HandleCoreDump);
2238 #endif
2239 }
2240
2241 }
2242
2243 //
2244 // Install the default resources for this class.
2245 //
2246 void DXApplication::installDefaultResources(Widget baseWidget)
2247 {
2248 this->setDefaultResources(baseWidget, _defaultDXResources);
2249 this->IBMApplication::installDefaultResources(baseWidget);
2250 }
2251 boolean DXApplication::initialize(int* argcp,
2252 char** argv)
2253 {
2254 boolean wasSetBusy = FALSE;
2255
2256 if (!this->IBMApplication::initializeWindowSystem(argcp,argv))
2257 return FALSE;
2258
2259 //
2260 // Color preallocation - necessary only because of the logo
2261 //
2262 int j;
2263 XrmValue from, toinout;
2264 Pixel tmp_pixel;
2265 for (j=0; j<XtNumber(_DXResourceList); j++) {
2266 if (!strcmp(_DXResourceList[j].resource_type, XmRPixel)) {
2267 from.addr = (XPointer)_DXResourceList[j].default_addr;
2268 from.size = strlen((char*)from.addr);
2269 toinout.addr = (XPointer)&tmp_pixel; toinout.size = sizeof(Pixel);
2270 XtConvertAndStore (this->getRootWidget(), XmRString, &from,
2271 XmRPixel, &toinout);
2272 }
2273 }
2274
2275 if (!this->IBMApplication::initialize(argcp,argv))
2276 return FALSE;
2277
2278 #ifdef DIAGNOSTICS
2279 /*
2280 * Set after function for diagnostic purposes only...
2281 */
2282 XSynchronize(this->display, True);
2283 XSetAfterFunction(this->display, DXApplication_DXAfterFunction);
2284 #endif
2285
2286 this->InitializeSignals();
2287
2288 this->parseCommand(argcp, argv, _DXOptionList, XtNumber(_DXOptionList));
2289
2290
2291 //
2292 // Get application resources.
2293 //
2294 if (NOT DXApplication::DXApplicationClassInitialized)
2295 {
2296 this->installDefaultResources(theApplication->getRootWidget());
2297 this->getResources((XtPointer)&DXApplication::resource,
2298 _DXResourceList, XtNumber(_DXResourceList));
2299
2300 DXApplication::MsgExecute =
2301 theSymbolManager->registerSymbol("Execute");
2302 DXApplication::MsgStandBy =
2303 theSymbolManager->registerSymbol("StandBy");
2304 DXApplication::MsgExecuteDone =
2305 theSymbolManager->registerSymbol("ExecuteDone");
2306 DXApplication::MsgServerDisconnected =
2307 theSymbolManager->registerSymbol("ServerDisconnected");
2308 DXApplication::MsgPanelChanged =
2309 theSymbolManager->registerSymbol("PanelChanged");
2310 DXApplication::DXApplicationClassInitialized = TRUE;
2311 }
2312
2313 //
2314 // setup resources that can be environment varialbles.
2315 //
2316 if (DXApplication::resource.executiveModule == NULL)
2317 DXApplication::resource.executiveModule = "lib/dx.mdf";
2318
2319 if (DXApplication::resource.uiModule == NULL)
2320 DXApplication::resource.uiModule = "ui/ui.mdf";
2321
2322 if (DXApplication::resource.userModules == NULL) {
2323 char *s = getenv("DXMDF");
2324 if (s)
2325 // This will show up as a memory leak, not worth worrying about
2326 DXApplication::resource.userModules = DuplicateString(s);
2327 }
2328
2329 if (DXApplication::resource.macros == NULL) {
2330 char *s = getenv("DXMACROS");
2331 if (s)
2332 // This will show up as a memory leak, not worth worrying about
2333 DXApplication::resource.macros = DuplicateString(s);
2334 }
2335
2336 if (DXApplication::resource.server == NULL) {
2337 char *s = getenv("DXHOST");
2338 if (s)
2339 // This will show up as a memory leak, not worth worrying about
2340 DXApplication::resource.server = DuplicateString(s);
2341 else
2342 DXApplication::resource.server = "localhost";
2343 }
2344 // Remove the port number if it exists (i.e DXHOST=slope,1920)
2345 char *p;
2346 if ( (p = strrchr(DXApplication::resource.server,',')) )
2347 *p = '\0';
2348
2349
2350 if (DXApplication::resource.netPath == NULL) {
2351 char *s = getenv("DXNETPATH");
2352 if (s)
2353 // This will show up as a memory leak, not worth worrying about
2354 DXApplication::resource.netPath = DuplicateString(s);
2355 }
2356
2357 if (DXApplication::resource.cryptKey == 0) {
2358 char *s = getenv("DXCRYPTKEY");
2359 if (s) {
2360 DXApplication::resource.cryptKey = DuplicateString(s);
2361 #ifndef DEBUG
2362 // Hide the key so debuggers can't get at it.
2363 s = DuplicateString("DXCRYPTKEY=");
2364 putenv(s);
2365 #endif
2366 }
2367 }
2368
2369 //
2370 // If the app does not allow editor access or we are starting up without
2371 // displaying the anchor window, force one of (image or menubar) mode.
2372 // Note that we also test this below, to check against the functional
2373 // license that was acquired.
2374 //
2375 if ((this->inEditMode() && !this->appAllowsEditorAccess()) ||
2376 DXApplication::resource.noAnchorAtStartup) {
2377 if (this->inMenuBarMode())
2378 DXApplication::resource.anchorMode = MENUBAR_ANCHOR_MODE;
2379 else
2380 DXApplication::resource.anchorMode = IMAGE_ANCHOR_MODE;
2381 }
2382
2383 //
2384 // Echo the resources.
2385 //
2386 if (DXApplication::resource.debugMode)
2387 {
2388 if (DXApplication::resource.port != 0)
2389 printf("port = %d\n", DXApplication::resource.port);
2390 if (DXApplication::resource.memorySize != 0)
2391 printf("memory size = %d\n", DXApplication::resource.memorySize);
2392
2393 if (DXApplication::resource.server)
2394 printf("server = %s\n", DXApplication::resource.server);
2395 if (DXApplication::resource.executive)
2396 printf("executive = %s\n", DXApplication::resource.executive);
2397 if (DXApplication::resource.workingDirectory)
2398 printf("working directory = %s\n",
2399 DXApplication::resource.workingDirectory);
2400 if (DXApplication::resource.netPath)
2401 printf("net path = %s\n", DXApplication::resource.netPath);
2402 if (DXApplication::resource.program)
2403 printf("program = %s\n", DXApplication::resource.program);
2404 if (DXApplication::resource.cfgfile)
2405 printf("cfgfile = %s\n", DXApplication::resource.cfgfile);
2406 if (this->getUIRoot())
2407 printf("root = %s\n", this->getUIRoot());
2408 if (DXApplication::resource.macros)
2409 printf("macros = %s\n", DXApplication::resource.macros);
2410 if (DXApplication::resource.errorPath)
2411 printf("error path = %s\n", DXApplication::resource.errorPath);
2412 if (DXApplication::resource.echoVersion)
2413 printf("echo version\n");
2414 if (DXApplication::resource.anchorMode)
2415 printf("anchor mode = %s\n",DXApplication::resource.anchorMode);
2416 if (DXApplication::resource.noAnchorAtStartup)
2417 printf("hiding anchor at startup\n");
2418 if (DXApplication::resource.debugMode)
2419 printf("debug mode\n");
2420 if (DXApplication::resource.runUIOnly)
2421 printf("run UI only\n");
2422 if (DXApplication::resource.showHelpMessage)
2423 printf("show help message\n");
2424 if (DXApplication::resource.userModules)
2425 printf("user mdf = %s\n", DXApplication::resource.userModules);
2426 if (DXApplication::resource.executiveModule)
2427 printf("executive mdf = %s\n", DXApplication::resource.executiveModule);
2428 if (DXApplication::resource.uiModule)
2429 printf("ui mdf = %s\n", DXApplication::resource.uiModule);
2430 if (DXApplication::resource.suppressStartupWindows)
2431 printf("suppress startup windows\n");
2432
2433 if (DXApplication::resource.applicationPort != 0)
2434 printf("application port = %d\n", DXApplication::resource.applicationPort);
2435 if (DXApplication::resource.applicationHost)
2436 printf("application host = %s\n", DXApplication::resource.applicationHost);
2437
2438 //
2439 // Image printing resources.
2440 //
2441 if (DXApplication::resource.printImageCommand)
2442 printf("print image command = '%s'\n",
2443 DXApplication::resource.printImageCommand);
2444 if (DXApplication::resource.printImageFormat)
2445 printf("print image format = '%s'\n",
2446 DXApplication::resource.printImageFormat);
2447 if (DXApplication::resource.printImagePageSize)
2448 printf("print image page size = '%s'\n",
2449 DXApplication::resource.printImagePageSize);
2450 printf("print image resolution = %d\n",
2451 DXApplication::resource.printImageResolution);
2452
2453 //
2454 // Image saving resources.
2455 //
2456 if (DXApplication::resource.saveImageFormat)
2457 printf("save image format = '%s'\n",
2458 DXApplication::resource.saveImageFormat);
2459 if (DXApplication::resource.saveImagePageSize)
2460 printf("save image page size = '%s'\n",
2461 DXApplication::resource.saveImagePageSize);
2462 printf("save image resolution = %d\n",
2463 DXApplication::resource.saveImageResolution);
2464
2465 //
2466 // UI restrictions
2467 //
2468 if (DXApplication::resource.restrictionLevel)
2469 printf("restriction level %s\n",
2470 DXApplication::resource.restrictionLevel);
2471 if (DXApplication::resource.noEditorAccess)
2472 printf("no editor access\n");
2473 if (DXApplication::resource.limitedNetFileSelection)
2474 printf("limited network file selection\n");
2475 if (DXApplication::resource.noImageRWNetFile)
2476 printf("no net file read/write\n");
2477 if (DXApplication::resource.noImageSaving)
2478 printf("no image saving\n");
2479 if (DXApplication::resource.noImagePrinting)
2480 printf("no image printing\n");
2481 if (DXApplication::resource.noImageLoad)
2482 printf("no image load \n");
2483 if (DXApplication::resource.limitImageOptions)
2484 printf("limit image options\n");
2485 if (DXApplication::resource.noRWConfig)
2486 printf("no cfg save\n");
2487 if (DXApplication::resource.noPanelEdit)
2488 printf("no panel edit\n");
2489 if (DXApplication::resource.noInteractorEdits)
2490 printf("no interactor style\n");
2491 if (DXApplication::resource.noInteractorAttributes)
2492 printf("no interactor attributes\n");
2493 if (DXApplication::resource.noInteractorMovement)
2494 printf("no interactor movement\n");
2495 if (DXApplication::resource.noOpenAllPanels)
2496 printf("no open all panels\n");
2497 if (DXApplication::resource.noPanelAccess)
2498 printf("no panel access\n");
2499 if (DXApplication::resource.noPanelOptions)
2500 printf("no panel options\n");
2501 if (DXApplication::resource.noMessageInfoOption)
2502 printf("no message info option\n");
2503 if (DXApplication::resource.noMessageWarningOption)
2504 printf("no message warning option\n");
2505 if (DXApplication::resource.noDXHelp)
2506 printf("no DX help\n");
2507
2508 //
2509 // automatic graph layout
2510 //
2511 if (DXApplication::resource.autoLayoutHeight > 0)
2512 printf("automatic graph layout height = %d\n",
2513 DXApplication::resource.autoLayoutHeight);
2514 if (DXApplication::resource.autoLayoutGroupSpacing > 0)
2515 printf("automatic graph layout group spacing = %d\n",
2516 DXApplication::resource.autoLayoutGroupSpacing);
2517 if (DXApplication::resource.autoLayoutNodeSpacing > 0)
2518 printf("automatic graph layout node spacing = %d\n",
2519 DXApplication::resource.autoLayoutNodeSpacing);
2520 }
2521
2522 if (this->resource.echoVersion)
2523 {
2524 printf(
2525 #ifdef BETA_VERSION
2526 "%s User Interface, version %02d.%02d.%04d Beta (%s, %s)\n",
2527 #else
2528 "%s User Interface, version %02d.%02d.%04d (%s, %s)\n",
2529 #endif
2530 theApplication->getFormalName(),
2531 DX_MAJOR_VERSION, DX_MINOR_VERSION, DX_MICRO_VERSION,
2532 __TIME__, __DATE__);
2533 exit (0);
2534 }
2535
2536 //
2537 // If the DXApplication does not allow DX help, then turn off middle
2538 // mouse button help which is implemented through the actions added
2539 // in IBMApplication::addActions(). This can't be done in addActions()
2540 // because it is called before the options/resources are parsed.
2541 //
2542 if (!this->appAllowsDXHelp()) {
2543 XtActionsRec action;
2544 action.string = "IBMButtonHelp";
2545 action.proc = TurnOffButtonHelp;
2546 XtAppAddActions(this->applicationContext, &action, 1);
2547 }
2548
2549 //
2550 // Validate and set automatic graph layout values
2551 //
2552 if (DXApplication::resource.autoLayoutHeight > 0) {
2553 const char* errmsg =
2554 GraphLayout::SetHeightPerLevel (DXApplication::resource.autoLayoutHeight);
2555 if (errmsg) {
2556 fprintf (stderr, errmsg);
2557 return FALSE;
2558 }
2559 }
2560 if (DXApplication::resource.autoLayoutGroupSpacing > 0) {
2561 const char* errmsg =
2562 GraphLayout::SetGroupSpacing (DXApplication::resource.autoLayoutGroupSpacing);
2563 if (errmsg) {
2564 fprintf (stderr, errmsg);
2565 return FALSE;
2566 }
2567 }
2568 if (DXApplication::resource.autoLayoutNodeSpacing > 0) {
2569 const char* errmsg =
2570 GraphLayout::SetNodeSpacing (DXApplication::resource.autoLayoutNodeSpacing);
2571 if (errmsg) {
2572 fprintf (stderr, errmsg);
2573 return FALSE;
2574 }
2575 }
2576
2577
2578 //
2579 // Validate the resources and options
2580 //
2581 if (this->inEditMode() && !this->appAllowsEditorAccess()) {
2582 fprintf(stderr,"-edit and -noEditorAccess options are incompatible.\n");
2583 return FALSE;
2584 }
2585
2586
2587 if (this->appAllowsImageRWNetFile() &&
2588 this->appLimitsNetFileSelection() &&
2589 (this->resource.netPath == NULL)) {
2590 fprintf(stderr,
2591 "The \"limitedNetFileSelection\" or \"noImageRWNetFile\" "
2592 "option requires\na directory pathname specified by "
2593 "the \"DXNETPATH\" environment variable, \n"
2594 "the -netPath command line option, or\n"
2595 "the *netPath resource.\n");
2596 return FALSE;
2597 }
2598
2599 //
2600 // Setup Server Information
2601 //
2602
2603 this->serverInfo.autoStart = DXApplication::resource.port <= 0;
2604 this->serverInfo.server = DuplicateString(
2605 DXApplication::resource.server);
2606 this->serverInfo.executive = DuplicateString(
2607 DXApplication::resource.executive);
2608 this->serverInfo.workingDirectory = DuplicateString(
2609 DXApplication::resource.workingDirectory);
2610 this->serverInfo.userModules = DuplicateString(
2611 DXApplication::resource.userModules);
2612 this->serverInfo.port =
2613 DXApplication::resource.port == 0? 1900: DXApplication::resource.port;
2614 this->serverInfo.memorySize = DXApplication::resource.memorySize;
2615 this->serverInfo.executiveFlags = NULL;
2616 int length = 0;
2617 int i;
2618 for (i = 1; i < *argcp; ++i)
2619 {
2620 length += STRLEN(argv[i]) + 1;
2621 if (this->serverInfo.executiveFlags == NULL)
2622 {
2623 this->serverInfo.executiveFlags = (char *)MALLOC (length);
2624 this->serverInfo.executiveFlags[0] = '\0';
2625 }
2626 else
2627 {
2628 this->serverInfo.executiveFlags =
2629 (char *)REALLOC(this->serverInfo.executiveFlags, length);
2630 strcat(this->serverInfo.executiveFlags, " ");
2631 }
2632 strcat(this->serverInfo.executiveFlags, argv[i]);
2633 }
2634
2635
2636 if (this->inDataViewerMode()) {
2637 this->appLicenseType = FullyLicensed;
2638 this->funcLicenseType = ViewerLicense;
2639 char *s;
2640 if ( (s = getenv("DXVIEWERNET")) ) {
2641 this->resource.program = s;
2642 } else {
2643 char *buf = new char[1024];
2644 sprintf(buf,"%s/ui/viewer.net",this->getUIRoot());
2645 this->resource.program = buf;
2646 }
2647 this->resource.executeOnChange = True;
2648 this->resource.noImageRWNetFile = True;
2649 this->resource.noRWConfig = True;
2650 this->resource.noImageLoad = True;
2651 this->resource.noDXHelp = True;
2652 this->resource.noPGroupAssignment = True;
2653 this->resource.limitImageOptions = True;
2654 this->resource.noScriptCommands = True;
2655 this->resource.noConnectionMenus = True;
2656 this->resource.noWindowsMenus = True;
2657 this->resource.anchorMode = IMAGE_ANCHOR_MODE;
2658 this->resource.noAnchorAtStartup= True;
2659 this->resource.suppressStartupWindows = True;
2660 this->resource.noConfirmedQuit = True;
2661 // this->resource.cryptKey = 0x54232419;
2662 // this->resource.forceNetFileEncryption = True;
2663 } else {
2664 //
2665 // Get a license (after parsing resources), and if we can't
2666 // then terminate
2667 //
2668 LicenseTypeEnum app_lic, func_lic;
2669 this->determineUILicense(&app_lic,&func_lic);
2670 this->appLicenseType = app_lic;
2671 this->funcLicenseType = func_lic;
2672 if (this->funcLicenseType == Unlicensed) {
2673 if (this->isFunctionalLicenseForced()) {
2674 fprintf(stderr,"%s could not get the requested license\n",
2675 this->getInformalName());
2676 this->funcLicenseType = this->getForcedFunctionalLicenseEnum();
2677 } else {
2678 this->funcLicenseType = DeveloperLicense;
2679 }
2680 #ifdef GUILT_MESSAGE
2681 // We do this below after the anchor window is up.
2682 //WarningMessage(
2683 // "You are running an unregistered copy of %s\n"
2684 // "Please contact your sales organization to acquire the\n"
2685 // "proper license enabling key.",this->getInformalName());
2686 // this->appLicenseType = FullyLicensed;
2687 } else if (this->appLicenseType == TimedLicense) {
2688 this->funcLicenseType = DeveloperLicense;
2689 #endif // GUILT_MESSAGE
2690 this->appLicenseType = TimedLicense;
2691 InstallShutdownTimer(NULL,(XtPointer)(LICENSED_MINUTES*60),NULL);
2692 }
2693 }
2694
2695
2696 i=0;
2697 ResourceManager::BuildTheResourceManager();
2698 while (DXApplication::ListValuedSettings[i]) {
2699 theResourceManager->registerMultiValued(DXApplication::ListValuedSettings[i]);
2700 i++;
2701 }
2702
2703
2704 #define START_SERVER_EARLY 0 // Not right before 3.1 release
2705 #if START_SERVER_EARLY
2706 DXChild *c = NULL;
2707 if (!this->resource.runUIOnly)
2708 c = this->startServer();
2709 #endif
2710 //
2711 // Create the first/root/anchor network and place it in the
2712 // network list.
2713 this->network = this->newNetwork();
2714
2715
2716 if (this->appAllowsEditorAccess()) {
2717 //
2718 // Initialize the ConfigurationDialog allocator for the editor
2719 //
2720 theCDBAllocatorDictionary = new CDBAllocatorDictionary;
2721
2722 //
2723 // Initialize the StandIn allocator for the editor.
2724 //
2725 theSIAllocatorDictionary = new SIAllocatorDictionary;
2726 }
2727
2728 //
2729 // Move to the indicated directory
2730 //
2731 if (this->serverInfo.workingDirectory &&
2732 (chdir(this->serverInfo.workingDirectory) < 0)) {
2733 fprintf(stderr,"Could not change directory to %s",
2734 this->serverInfo.workingDirectory);
2735 }
2736
2737
2738 //
2739 // Load the MDF files. If there was a user mdf file (i.e. -mdf foo.mdf)
2740 // then assume the exec has loaded it itself.
2741 //
2742 this->loadMDF();
2743 this->loadIDF();
2744 if (this->resource.userModules)
2745 this->loadUDF(this->resource.userModules, NULL, FALSE);
2746
2747
2748 //
2749 // Decorator Styles
2750 //
2751 BuildtheDecoratorStyleDictionary();
2752
2753 #if 0
2754 #if 00 && SYSTEM_MACROS // Net yet, dawood 11/17/94
2755 //
2756 // load the set of system macros from $DXROOT/ui/.
2757 //
2758 char path[1024];
2759 sprintf(path,"%s/ui",this->getUIRoot());
2760 MacroDefinition::LoadMacroDirectories(path, FALSE, NULL, TRUE);
2761 #endif
2762 #endif
2763
2764 //
2765 // load the initial set of user macros.
2766 //
2767 MacroDefinition::LoadMacroDirectories(this->resource.macros);
2768
2769 //
2770 // Create the anchor window.
2771 //
2772 if (!this->inEditMode())
2773 {
2774 if (this->inImageMode())
2775 this->anchor = this->newImageWindow(this->network);
2776 else if (this->inMenuBarMode())
2777 this->anchor = new DXAnchorWindow ("dxAnchor", TRUE, TRUE);
2778 else {
2779 fprintf(stderr,"Unrecognized anchor mode\n");
2780 ASSERT(0);
2781 }
2782 //
2783 // Initialize the anchor window so it can handle reading in the network
2784 // (before being managed).
2785 //
2786 if (this->applyWindowPlacements() ||
2787 DXApplication::resource.noAnchorAtStartup)
2788 this->anchor->initialize();
2789 else {
2790 this->anchor->manage();
2791 this->setBusyCursor(TRUE);
2792 wasSetBusy = TRUE;
2793 }
2794 }
2795 else
2796 {
2797 this->anchor = this->newNetworkEditor(this->network);
2798 if (!this->anchor)
2799 return FALSE; // Expect newNetworkEditor() to issue message.
2800
2801 //
2802 // The editor must always be managed before reading .nets
2803 // (we could do it with some work, but doesn't seem useful especially
2804 // since we don't want error messages coming up behind the VPE).
2805 //
2806 this->anchor->manage();
2807 this->setBusyCursor(TRUE);
2808 wasSetBusy = TRUE;
2809 }
2810
2811
2812 //
2813 // Create the message and debug windows.
2814 //
2815 this->messageWindow = this->newMsgWin();
2816 this->messageWindow->initialize();
2817
2818
2819
2820 //
2821 // If requested, read in the network. This is after opening the anchor
2822 // window because image nodes may wish to bind with the initial image
2823 // window, etc.
2824 if (this->resource.program != NULL)
2825 this->openFile(this->resource.program, this->resource.cfgfile);
2826
2827 if (this->inDataViewerMode()) {
2828 Node *n = this->network->findNode("Import");
2829 if (!n)
2830 ErrorMessage("Can not find Import tool in viewing program");
2831 else {
2832 const char *s = this->getDataViewerImportFile();
2833 ASSERT(s);
2834 n->setInputValue(1,s);
2835 }
2836 }
2837
2838 //
2839 // Display the anchor window (after reading the network which may have
2840 // window sizing information).
2841 //
2842 if (DXApplication::resource.noAnchorAtStartup)
2843 XtRealizeWidget(this->anchor->getRootWidget());
2844 else if (!this->anchor->isManaged()) {
2845 this->anchor->manage();
2846 this->setBusyCursor(TRUE);
2847 wasSetBusy = TRUE;
2848 }
2849
2850 //
2851 // Post the copyright message if the anchor window came up.
2852 //
2853 if (!DXApplication::resource.noAnchorAtStartup)
2854 this->postCopyrightNotice();
2855
2856 #ifdef HAS_CLIPNOTIFY_EXTENSION
2857 //
2858 // If applicable, see if this is an IBM POWER Visualization Server
2859 // Video Controler
2860 //
2861 int majorCode;
2862 int errorCode;
2863 if (this->hasClipnotifyExtension =
2864 XQueryExtension
2865 (this->display,
2866 CLIPNOTIFY_PROTOCOL_NAME,
2867 &majorCode,
2868 &this->clipnotifyEventCode,
2869 &errorCode))
2870 {
2871 XSetWindowAttributes attributes;
2872 Window win =
2873 XCreateWindow
2874 (this->display,
2875 RootWindow(this->display, 0),
2876 0, 0,
2877 10, 10,
2878 2, 8,
2879 CopyFromParent,
2880 CopyFromParent,
2881 NULL,
2882 &attributes);
2883 XClipNotifyAddWin(this->display, win);
2884 }
2885 #endif
2886
2887 //
2888 // Refresh the screen.
2889 //
2890 XmUpdateDisplay(this->getRootWidget());
2891
2892
2893 #ifndef DXD_WIN
2894 //
2895 // Connect to exec first
2896 //
2897 if (!this->resource.runUIOnly)
2898 {
2899 #if !START_SERVER_EARLY
2900 DXChild *c = this->startServer();
2901 #else
2902 ASSERT(c);
2903 #endif
2904 this->completeConnection(c);
2905 }
2906 #endif
2907
2908 //
2909 // If there is an application to talk to, connect to it.
2910 //
2911 if (this->resource.applicationPort != 0)
2912 this->connectToApplication(this->resource.applicationHost,
2913 this->resource.applicationPort);
2914
2915
2916 //
2917 // If this is a demo license, then post a message after the anchor
2918 // has been managed.
2919 //
2920 if (this->appLicenseType == TimedLicense) {
2921 ModalWarningMessage(this->anchor->getRootWidget(),
2922 "You do not have license to run %s.\n"
2923 "However, you have been given a %d minute demonstration license.\n"
2924 "\nNote that this license does NOT allow saving visual programs.",
2925 theDXApplication->getInformalName(), LICENSED_MINUTES);
2926 #ifdef GUILT_MESSAGE
2927 } else if (this->appLicenseType == Unlicensed) {
2928 ModalWarningMessage(this->anchor->getRootWidget(),
2929 "\nYOUR ARE RUNNING AN UNREGISTER COPY OF %s!!!!\n\n"
2930 "Use of this software is governed by your software license\n"
2931 "agreement which you, the user, must abide by. Please contact\n"
2932 "your sales representative and system administrator to properly\n"
2933 "register this copy of the software.",
2934 this->getInformalName());
2935 this->appLicenseType = FullyLicensed;
2936 #endif // GUILT_MESSAGE
2937 }
2938
2939 ASSERT(this->appLicenseType != Unlicensed);
2940
2941 if (wasSetBusy) this->setBusyCursor(FALSE);
2942
2943 #ifdef DXD_WIN
2944 //
2945 // Connect to exec first
2946 //
2947 if (!this->resource.runUIOnly)
2948 {
2949 DXChild *c = this->startServer();
2950 this->completeConnection(c);
2951 }
2952 #endif
2953
2954 return TRUE;
2955 }
2956
2957 #if NEED_TO_WATCH_EVENTS
2958 static void
2959 printEvent (Widget w, XtPointer, String actname, XEvent *xev, String *, Cardinal *)
2960 {
2961 if (xev->type == KeyPress)
2962 printf ("%s for %s\n", actname, XtName(w));
2963 }
2964 #endif
2965
2966 void DXApplication::handleEvents()
2967 {
2968 XEvent event;
2969
2970 #if NEED_TO_WATCH_EVENTS
2971 XtAppAddActionHook (this->applicationContext, (XtActionHookProc)printEvent, NULL);
2972 #endif
2973
2974 //
2975 // Process events while the application is running.
2976 //
2977 this->runApplication = TRUE;
2978 while (this->runApplication)
2979 {
2980 XtAppNextEvent(this->applicationContext, &event);
2981 //
2982 // We check runApplication here because shutdownApplication()
2983 // delivers a bogus event to kick us out of XtAppNextEvent()
2984 // when a socket has been closed during a select().
2985 // All done for DXLExit().
2986 //
2987 if (this->runApplication && XHandler::ProcessEvent(&event))
2988 {
2989 this->handleEvent(&event);
2990 } // Done handling an event
2991
2992 this->destroyDumpedObjects();
2993
2994 if (this->serverDisconnectScheduled) {
2995 this->serverDisconnectScheduled = FALSE;
2996 this->disconnectFromServer();
2997 }
2998
2999 //
3000 // If the user asked the UI to terminate after the first
3001 // execution (if any) then do so.
3002 //
3003 if (this->resource.exitAfter && !this->getExecCtl()->isExecuting())
3004 this->shutdownApplication();
3005 }
3006 }
3007
3008 void
3009 DXApplication::handleEvent (XEvent *xev)
3010 {
3011 #ifdef HAS_CLIPNOTIFY_EXTENSION
3012 if (this->hasClipnotifyExtension && ((xev->type - this->clipnotifyEventCode) ==
3013 ClipNotifyHdrError))
3014 {
3015 char message[1000];
3016 XClipNotifyHdrErrorEvent *pHdr = (XClipNotifyHdrErrorEvent *)xev;
3017 sprintf
3018 (message,
3019 "HPPI header error: "
3020 "serial# = %d, send_event = %d, window = %d",
3021 pHdr->serial, pHdr->send_event, pHdr->window);
3022 XtWarning(message);
3023 }
3024 else if (this->hasClipnotifyExtension &&
3025 ((xev->type - this->clipnotifyEventCode) ==
3026 ClipNotifyDataErrors))
3027 {
3028 char message[1000];
3029 XClipNotifyDataErrorsEvent *pData = (XClipNotifyDataErrorsEvent *) xev;
3030 sprintf
3031 (message,
3032 "HPPI data error: "
3033 "serial# = %d, send_event = %d, window = %d,"
3034 " number of errors = %d, elapsed time in seconds = %d",
3035 pData->serial,
3036 pData->send_event,
3037 pData->window,
3038 pData->num_errors,
3039 pData->etime);
3040 XtWarning(message);
3041 }
3042 #endif
3043 #ifdef sun4
3044 //
3045 // Map Ctl+Delete to Ctl+Del for deleting modules in the VPE
3046 //
3047 if(xev->type == KeyPress && xev->xkey.keycode == 73 // Delete Key
3048 && (xev->xkey.state & ControlMask) != 0 )
3049 {
3050 xev->xkey.keycode = 57; // Del key
3051 }
3052 #endif
3053 this->IBMApplication::handleEvent(xev);
3054 }
3055
3056 static int
3057 testString(char *s)
3058 {
3059 int r;
3060
3061 if (!s)
3062 return 0;
3063
3064 while(isspace(*s)) s++;
3065
3066 r = *s != '\0';
3067 return r;
3068
3069 }
3070
3071 DXChild *DXApplication::startServer()
3072 {
3073
3074 //
3075 // Handling Queued events right here, allows the logo screen to become painted
3076 // before going off to start dxexec. If it's not painted before fork/execing
3077 // dxexec, then it will just sit on the screen blank until the exec is done
3078 // at which point a timeout will immediately remove it from the screen.
3079 //
3080 XSync (XtDisplay(this->getRootWidget()), False);
3081 while (QLength(XtDisplay(this->getRootWidget()))) {
3082 XEvent event;
3083 XtAppNextEvent(this->applicationContext, &event);
3084 switch (event.type) {
3085 case ButtonPress:
3086 case ButtonRelease:
3087 case KeyPress:
3088 case KeyRelease:
3089 break;
3090 default:
3091 this->handleEvent(&event);
3092 break;
3093 }
3094 }
3095
3096 if (this->serverInfo.autoStart)
3097 {
3098 char cmd[2048], args[2048];
3099 if (this->serverInfo.memorySize > 0)
3100 sprintf(args, "-exonly -memory %d -local",
3101 this->serverInfo.memorySize);
3102 else
3103 strcpy(args, "-exonly -local");
3104
3105 if (testString(this->serverInfo.executive))
3106 {
3107 strcat(args, " -exec ");
3108 strcat(args, this->serverInfo.executive);
3109 }
3110 if (testString(this->serverInfo.workingDirectory))
3111 {
3112 strcat(args, " -directory ");
3113 if(strchr(this->serverInfo.workingDirectory, ' ') != NULL) {
3114 strcat(args, "\"");
3115 strcat(args, this->serverInfo.workingDirectory);
3116 strcat(args, "\"");
3117 } else
3118 strcat(args, this->serverInfo.workingDirectory);
3119 }
3120 if (testString(this->serverInfo.userModules))
3121 {
3122 strcat(args, " -mdf ");
3123 strcat(args, this->serverInfo.userModules);
3124 }
3125 #if defined(DXD_LICENSED_VERSION)
3126 const char *l = NULL;
3127 if (this->isFunctionalLicenseForced()) {
3128 switch (this->getForcedFunctionalLicenseEnum()) {
3129 case RunTimeLicense: l = LIC_RT_OPTION; break;
3130 case DeveloperLicense: l = LIC_DEV_OPTION; break;
3131 }
3132 } else {
3133 switch (this->getFunctionalLicenseEnum()) {
3134 case RunTimeLicense: l = LIC_RT_OPTION; break;
3135 case DeveloperLicense: l = LIC_DEV_OPTION; break;
3136 }
3137 }
3138 if (l)
3139 {
3140 strcat(args, " -license ");
3141 strcat(args, l);
3142 }
3143 #endif
3144 if (testString(this->serverInfo.executiveFlags))
3145 {
3146 strcat(args, " ");
3147 strcat(args, this->serverInfo.executiveFlags);
3148 }
3149
3150 sprintf(cmd, "dx %s", args);
3151 DXChild *c = new DXChild(this->serverInfo.server, cmd, FALSE);
3152 if (c->failed()) {
3153 delete c;
3154 sprintf(cmd,"%s/bin/dx %s",this->getUIRoot(),args);
3155 c = new DXChild(this->serverInfo.server, cmd, FALSE);
3156 // If it still fails, let the connectToServer() catch it.
3157 }
3158
3159 this->serverInfo.children.insertElement((const void*)c, 1);
3160
3161 return c;
3162 }
3163 else
3164 return NULL;
3165 }
3166
3167 void DXApplication::QueuedPacketAccept(void *data)
3168 {
3169 DXPacketIF *p = (DXPacketIF *)data;
3170 theDXApplication->packetIFAccept(p);
3171 }
3172
3173 void DXApplication::packetIFAccept(DXPacketIF *p)
3174 {
3175 this->serverInfo.queuedPackets.deleteElement(
3176 this->serverInfo.queuedPackets.getPosition((const void *)p));
3177 if (this->serverInfo.packet)
3178 {
3179 delete this->serverInfo.packet;
3180 this->disconnectedFromServerCmd->execute();
3181 }
3182 this->serverInfo.packet = p;
3183
3184 p->initializePacketIO();
3185
3186 //
3187 // Once we're all set, do the handshake with the exec to make sure
3188 // it has the correct license.
3189 //
3190 if (this->verifyServerLicense()) {
3191
3192 //
3193 // Let the system know that everything's ok.
3194 this->connectedToServerCmd->execute();
3195 this->sendNewMDFToServer(theNodeDefinitionDictionary);
3196
3197 this->getExecCtl()->newConnection();
3198 }
3199
3200
3201 }
3202
3203
3204 //
3205 // Mark all the networks owned by this application as dirty.
3206 //
3207 void DXApplication::markNetworksDirty()
3208 {
3209 // This also effectively marks the parameters as dirty.
3210 this->getExecCtl()->forceFullResend();
3211 }
3212
3213 //
3214 // Utility function to parse the path in the error message.
3215 //
3216 static char* GetErrorNode(char* path, char* name, int* instance)
3217 {
3218 char* nameptr;
3219
3220 if(sscanf(path,"%[^:]:%d", name, instance) < 2)
3221 {
3222 strcpy(name, "\0");
3223 return NULL;
3224 }
3225
3226 if ((nameptr = strchr(name,'_'))
3227 AND (strncmp(nameptr,"_Image",6)==0))
3228 strcpy(name, "Image");
3229
3230 if ( (path = strchr(path,'/')) )
3231 path++;
3232
3233 return (path);
3234 }
3235
3236 void DXApplication::highlightNodes(char* path, int highlightType)
3237 {
3238 char name[500], netname[500];
3239 int instance;
3240 Network *network;
3241 ListIterator li;
3242 EditorWindow* editor;
3243
3244 path = GetErrorNode(path,name,&instance);
3245
3246 network = this->network;
3247 if ( (editor = network->getEditor()) )
3248 editor->highlightNode(name,instance,highlightType);
3249
3250 while (path)
3251 {
3252 li.setList(this->macroList);
3253 strcpy(netname, name);
3254 path = GetErrorNode(path,name,&instance);
3255
3256 for(network = (Network*)li.getNext();
3257 network;
3258 network = (Network*)li.getNext())
3259 {
3260 if(EqualString(network->getNameString(),netname) &&
3261 (editor = network->getEditor()))
3262 {
3263 editor->highlightNode(name,instance,highlightType);
3264 break;
3265 }
3266 }
3267 }
3268 }
3269
3270 void DXApplication::refreshErrorIndicators()
3271 {
3272 const char *s;
3273 ListIterator iterator;
3274
3275
3276 iterator.setList(this->errorList);
3277 while ( (s = (const char *)iterator.getNext()) ) {
3278 this->highlightNodes((char*)s,EditorWindow::ERRORHIGHLIGHT);
3279 }
3280
3281 }
3282 void DXApplication::addErrorList(char *line)
3283
3284 {
3285 char *newLine = strchr(line, '/');
3286 char *p, *second_slash;
3287 //
3288 // Don't handle errors that result from script commands typed directly to
3289 // the executive (i.e. commands without networks) like errors that come
3290 // from within a network.
3291 //
3292 if (newLine && (second_slash = strchr(newLine+1,'/')))
3293 {
3294 newLine++;
3295 const char *name = this->network->getNameString();
3296 if (!EqualSubstring(newLine,name,STRLEN(name)))
3297 return;
3298
3299 char *node_id = second_slash + 1;
3300
3301 this->errorList.appendElement((void*)DuplicateString(node_id));
3302 //
3303 // Don't highlight until after execution.
3304 // Highlighting is now done in DXExecCtl::endLastExecution() by
3305 // calling this->refreshErrorIndicators().
3306 //
3307 if (!this->getExecCtl()->isExecuting())
3308 this->highlightNodes(node_id,EditorWindow::ERRORHIGHLIGHT);
3309 }
3310 // We don't need to save errors that aren't relevant to a tool placed
3311 // on the canvas, so comment out the following.
3312 //else
3313 //{
3314 //j this->errorList.appendElement((void*)DuplicateString(line));
3315 //}
3316 else if ( (p = strstr(line,"PEER ABORT - ")) ) {
3317 //
3318 // One of the distributed peers aborted abnormally.
3319 // Unhighlight all the modules.
3320 // FIXME: If we don't unhighlight, the aborted module is still
3321 // highlighted green, so we could go through the process group
3322 // and mark the greens modules as error modules.
3323 //
3324 Network *n = this->network;
3325 ListIterator li(this->macroList);
3326 while (n) {
3327 EditorWindow *e = n->getEditor();
3328 if (e)
3329 e->highlightNodes(EditorWindow::REMOVEHIGHLIGHT);
3330 n = (Network*)li.getNext();
3331 }
3332 // this->refreshErrorIndicators();
3333
3334 //
3335 // This is similar to a disconnect, so make sure the user knows.
3336 //
3337 ErrorMessage(p+STRLEN("PEER ABORT - "));
3338 }
3339
3340 }
3341
3342 void DXApplication::clearErrorList()
3343 {
3344 char *s;
3345 ListIterator li(this->errorList);
3346 while ((s = (char*)li.getNext()))
3347 {
3348 this->highlightNodes(s, EditorWindow::REMOVEHIGHLIGHT);
3349 delete s;
3350 }
3351 this->errorList.clear();
3352 }
3353
3354 void DXApplication::QueuedPacketCancel(void *data)
3355 {
3356 DXPacketIF *p = (DXPacketIF *)data;
3357 theDXApplication->packetIFCancel(p);
3358 }
3359 void DXApplication::packetIFCancel(DXPacketIF *p)
3360 {
3361 this->serverInfo.queuedPackets.deleteElement(
3362 this->serverInfo.queuedPackets.getPosition((const void *)p));
3363 if (this->serverInfo.packet == p)
3364 {
3365 this->serverInfo.packet = NULL;
3366 this->getExecCtl()->terminateExecution();
3367 this->disconnectedFromServerCmd->execute();
3368 this->notifyClients(DXApplication::MsgServerDisconnected);
3369 }
3370 this->dumpObject(p);
3371 }
3372
3373 int DXApplication::connectToServer(int port, DXChild *c)
3374 {
3375 char *server;
3376 int wasQueued = FALSE;
3377 char s[1000];
3378
3379 if (c)
3380 {
3381 server = (char *)c->getServer();
3382 if ((wasQueued = c->isQueued()) != 0)
3383 {
3384 this->serverInfo.children.deleteElement(
3385 this->serverInfo.children.getPosition((const void *)c));
3386 c->unQueue();
3387 }
3388 }
3389 else
3390 {
3391 server = this->serverInfo.server;
3392 }
3393 DXPacketIF *p = new DXPacketIF(server, port, DXChild::HostIsLocal(server));
3394
3395 if (DXApplication::resource.debugMode)
3396 p->setEchoCallback(DXApplication::DebugEchoCallback,(void*)stderr);
3397
3398 if (p->inError())
3399 {
3400 sprintf(s, "Connection to %s failed.", server);
3401 ErrorMessage(s);
3402
3403 delete p;
3404 return FALSE;
3405 }
3406
3407 //
3408 // Now that we have a connection we can clear the error list.
3409 //
3410 this->clearErrorList();
3411
3412
3413 if (this->serverInfo.packet == NULL)
3414 {
3415 if (wasQueued)
3416 {
3417 sprintf(s, "Your connection to %s has been accepted.", server);
3418 InfoMessage(s);
3419 }
3420 this->packetIFAccept(p);
3421 }
3422 else
3423 {
3424 this->serverInfo.queuedPackets.insertElement((const void *)p, 1);
3425 sprintf(s, "Your connection to server %s has been accepted. Do you want to disconnect from %s and connect to it?", server, this->serverInfo.server);
3426 theQuestionDialogManager->modalPost(this->getRootWidget(),
3427 s,
3428 NULL,
3429 (void *)p,
3430 DXApplication::QueuedPacketAccept,
3431 DXApplication::QueuedPacketCancel,
3432 NULL);
3433 }
3434 return (TRUE);
3435 }
3436
3437 void DXApplication::closeConnection(DXChild *c)
3438 {
3439 if (c->isQueued())
3440 {
3441 this->serverInfo.children.deleteElement(
3442 this->serverInfo.children.getPosition((const void *)c));
3443 // From now on we'll queue deletion of c, in a way that ensures it will
3444 // actually get deleted. Currently it's cast adrift in normal cases.
3445 // If there turns out to be a problem with this, then look for
3446 // DXChild_DeleteObjectWP and stop using it or back out the change to
3447 // DXChild.C
3448 //delete c;
3449 }
3450 }
3451
3452 boolean DXApplication::disconnectFromServer()
3453 {
3454
3455 if (this->serverInfo.packet != NULL)
3456 this->packetIFCancel(this->serverInfo.packet);
3457
3458 //
3459 // Only clear the error list when we ask to be disconnected
3460 // (i.e. don't do it in packetIFCancel() which gets called when
3461 // unexpectedly disconnected from the server).
3462 //
3463 this->clearErrorList();
3464
3465 //
3466 // Make sure we don't disconnect on the next connection.
3467 //
3468 this->serverDisconnectScheduled = FALSE;
3469
3470 return TRUE;
3471 }
3472
3473
3474 boolean DXApplication::openFile(const char *netfile, const char *cfgfile,
3475 boolean resetTheServer)
3476 {
3477 Network *network = this->network;
3478 boolean execOnChange = this->getExecCtl()->inExecOnChange();
3479 boolean result;
3480
3481 if (execOnChange)
3482 this->getExecCtl()->suspendExecOnChange();
3483
3484 if (resetTheServer)
3485 this->resetServer();
3486
3487 //
3488 // We can't do this until after resetting the server, because
3489 // it has to clean up its windows too.
3490 //
3491 network->clear();
3492
3493 if ((result = network->readNetwork(netfile, cfgfile)))
3494 {
3495 if (execOnChange)
3496 {
3497 this->getExecCtl()->updateMacros();
3498 this->getExecCtl()->resumeExecOnChange();
3499 }
3500 this->appendReferencedFile(netfile);
3501 }
3502
3503 this->readFirstNetwork = TRUE;
3504 return result;
3505 }
3506
3507 boolean DXApplication::saveFile(const char *netfile, boolean force)
3508 {
3509 const char *name = netfile;
3510 Network *network = this->network;
3511
3512 if (! name)
3513 name = network->getFileName();
3514
3515 if (! name)
3516 {
3517 ErrorMessage("unable to save file");
3518 return FALSE;
3519 }
3520
3521 return network->saveNetwork(name, force);
3522 }
3523
3524 void DXApplication::DebugEchoCallback(void *clientData, char *echoString)
3525 {
3526 FILE *f = (FILE*)clientData;
3527
3528 //
3529 // We use this test for null as a bit of a hack, but if NULL then
3530 // we assume that the callback is for the ApplicIF and not DXPacketIF.
3531 //
3532 if (f)
3533 fputs(echoString, f);
3534 else
3535 fprintf(stderr,"DXLink::%s",echoString);
3536 }
3537
3538
3539 boolean DXApplication::postStartServerDialog()
3540 {
3541 if (this->startServerDialog == NULL)
3542 this->startServerDialog = new StartServerDialog(this->getRootWidget());
3543 this->markNetworksDirty();
3544 this->startServerDialog->post();
3545 return TRUE;
3546 }
3547 //
3548 // This should be moved to "DXExecCtl"
3549 boolean DXApplication::resetServer()
3550 {
3551 char message[1024];
3552
3553 this->getExecCtl()->terminateExecution();
3554
3555 this->clearErrorList();
3556
3557 this->markNetworksDirty();
3558 this->notifyClients(DXApplication::MsgServerDisconnected);
3559
3560 DXPacketIF *pif = this->getPacketIF();
3561 if (pif) { // pif should really never be NULL, but...
3562
3563
3564 this->flushExecutiveDictionaries(pif);
3565
3566 pif->send(DXPacketIF::FOREGROUND, "Trace(\"memory\", 0);\n" );
3567
3568 sprintf(message,"Executive(\"version %d %d %d\");\n",
3569 PIF_MAJOR_VERSION,PIF_MINOR_VERSION, PIF_MICRO_VERSION);
3570 pif->send(DXPacketIF::FOREGROUND, message);
3571
3572 sprintf(message,"Executive(\"product version %d %d %d\");\n",
3573 DX_MAJOR_VERSION, DX_MINOR_VERSION, DX_MICRO_VERSION);
3574 pif->send(DXPacketIF::FOREGROUND, message);
3575
3576
3577 }
3578
3579
3580 return TRUE;
3581 }
3582
3583 //
3584 // Send the command to the flush the dictionaries.
3585 //
3586 void DXApplication::flushExecutiveDictionaries(DXPacketIF *pif)
3587 {
3588 ASSERT(pif);
3589 pif->send(DXPacketIF::FOREGROUND, "Executive(\"flush dictionary\");\n");
3590 }
3591
3592 void DXApplication::getServerParameters(int *autoStart,
3593 const char **server,
3594 const char **executive,
3595 const char **workingDirectory,
3596 const char **executiveFlags,
3597 int *port,
3598 int *memorySize)
3599 {
3600 if (autoStart)
3601 *autoStart = this->serverInfo.autoStart;
3602 if (server)
3603 *server = this->serverInfo.server;
3604 if (executive)
3605 *executive = this->serverInfo.executive;
3606 if (workingDirectory)
3607 *workingDirectory = this->serverInfo.workingDirectory;
3608 if (executiveFlags)
3609 *executiveFlags = this->serverInfo.executiveFlags;
3610 if (port)
3611 *port = this->serverInfo.port;
3612 if (memorySize)
3613 *memorySize = this->serverInfo.memorySize;
3614 }
3615 void DXApplication::setServerParameters(int autoStart,
3616 const char *server,
3617 const char *executive,
3618 const char *workingDirectory,
3619 const char *executiveFlags,
3620 int port,
3621 int memorySize)
3622 {
3623 char *tserver =
3624 server? DuplicateString(server): NULL;
3625 char *texecutive =
3626 executive? DuplicateString(executive): NULL;
3627 char *tworkingDirectory =
3628 workingDirectory? DuplicateString(workingDirectory): NULL;
3629 char *texecutiveFlags =
3630 executiveFlags? DuplicateString(executiveFlags): NULL;
3631
3632 if (this->serverInfo.server)
3633 delete this->serverInfo.server;
3634 if (this->serverInfo.executive)
3635 delete this->serverInfo.executive;
3636 if (this->serverInfo.workingDirectory)
3637 delete this->serverInfo.workingDirectory;
3638 if (this->serverInfo.executiveFlags)
3639 delete this->serverInfo.executiveFlags;
3640
3641 this->serverInfo.autoStart = autoStart;
3642 this->serverInfo.server = tserver;
3643 this->serverInfo.executive = texecutive;
3644 this->serverInfo.workingDirectory = tworkingDirectory;
3645 this->serverInfo.executiveFlags = texecutiveFlags;
3646 this->serverInfo.port = port;
3647 this->serverInfo.memorySize = memorySize;
3648 }
3649
3650 void DXApplication::completeConnection(DXChild *c)
3651 {
3652 if (c != NULL)
3653 {
3654 char s[1000];
3655 switch(c->waitForConnection()) {
3656 case -1:
3657 sprintf(s, "Connection to server %s failed:\n\n%s",
3658 c->getServer(), c->failed());
3659 ErrorMessage(s);
3660 this->closeConnection(c);
3661 break;
3662
3663 case 0:
3664 if (this->resource.executeProgram)
3665 {
3666 this->getExecCtl()->executeOnce();
3667 }
3668 break;
3669
3670 case 1:
3671 sprintf(s, "Connection to server %s has been queued",
3672 c->getServer());
3673 InfoMessage(s);
3674 break;
3675 }
3676 }
3677 else if (!this->serverInfo.autoStart)
3678 {
3679 this->connectToServer(this->serverInfo.port, NULL);
3680 }
3681
3682 //
3683 // Let the application packet know that a new connection to
3684 // the server has been created.
3685 //
3686 if (this->applicationPacket)
3687 this->applicationPacket->handleServerConnection();
3688
3689
3690 if (DXApplication::resource.executeOnChange)
3691 this->getExecCtl()->enableExecOnChange();
3692 }
3693
3694 void DXApplication::postOpenNetworkDialog()
3695 {
3696 if (this->openNetworkDialog == NULL) {
3697 this->openNetworkDialog = new OpenNetworkDialog(
3698 this->anchor->getRootWidget());
3699
3700 if (this->appLimitsNetFileSelection()) {
3701 ASSERT(this->resource.netPath);
3702 this->openNetworkDialog->setReadOnlyDirectory(
3703 this->resource.netPath);
3704 }
3705
3706 }
3707 this->openNetworkDialog->post();
3708 }
3709
3710 void DXApplication::postLoadMacroDialog()
3711 {
3712 if (this->loadMacroDialog == NULL) {
3713 this->loadMacroDialog = new LoadMacroDialog(
3714 this->anchor->getRootWidget());
3715 }
3716
3717 this->loadMacroDialog->post();
3718 }
3719
3720
3721 MsgWin *DXApplication::newMsgWin()
3722 {
3723 return new MsgWin();
3724 }
3725 ImageWindow *DXApplication::newImageWindow(Network *n)
3726 {
3727 boolean is_anchor;
3728
3729 ASSERT(n);
3730
3731 if (this->anchor == NULL)
3732 is_anchor = TRUE;
3733 else
3734 is_anchor = FALSE;
3735
3736 return new ImageWindow(is_anchor, n);
3737 }
3738
3739 ControlPanel *DXApplication::newControlPanel(Network *n)
3740 {
3741 return new ControlPanel(n);
3742 }
3743
3744 Network *DXApplication::newNetwork(boolean nonJava)
3745 {
3746 Network* n;
3747 if (nonJava)
3748 n = new Network();
3749 else
3750 n = new JavaNet();
3751 return n;
3752 }
3753
3754 //
3755 // Create a new network editor.
3756 // This particular implementation, makes the returned editor an anchor
3757 // if this->anchor is NULL.
3758 // This may return NULL in which case a message dialog is posted to the user.
3759 //
3760 EditorWindow *DXApplication::newNetworkEditor(Network *n)
3761 {
3762 char *msg = "";
3763
3764 ASSERT(n);
3765
3766 if (n->wasNetFileEncoded()) {
3767 msg = "This visual program is encoded and therefore is not "
3768 "viewable in the VPE";
3769 goto error;
3770 } else if (!this->appAllowsEditorAccess()) {
3771 msg = "This invocation of Data Explorer does not allow editor "
3772 "access (-edit).\n"
3773 "Try image mode (-image), or forcing a developer license "
3774 "(-license develop).\n";
3775 goto error;
3776 }
3777
3778 boolean is_anchor;
3779 if (this->anchor == NULL)
3780 is_anchor = TRUE;
3781 else
3782 is_anchor = FALSE;
3783
3784 return new EditorWindow(is_anchor, n);
3785
3786 error:
3787 if (this->anchor)
3788 InfoMessage(msg);
3789 else
3790 fprintf(stderr,msg);
3791
3792 return NULL;
3793 }
3794
3795 void DXApplication::connectToApplication(const char *host, const int port)
3796 {
3797 if (host == NULL)
3798 host = "localhost";
3799
3800 this->applicationPacket = new ApplicIF(host, port,
3801 DXChild::HostIsLocal(host));
3802
3803 this->applicationPacket->initializePacketIO();
3804
3805 if (DXApplication::resource.debugMode)
3806 this->applicationPacket->setEchoCallback(
3807 DXApplication::DebugEchoCallback,(void*)NULL);
3808 }
3809
3810 void DXApplication::disconnectFromApplication(boolean terminate)
3811 {
3812 if (this->applicationPacket) {
3813 this->dumpObject(this->applicationPacket);
3814 this->applicationPacket = NULL;
3815 }
3816
3817 if (terminate)
3818 this->shutdownApplication();
3819 }
3820
3821
3822 //
3823 // Message control functions.
3824 //
3825 boolean DXApplication::isInfoEnabled()
3826 {
3827 return this->resource.infoEnabled;
3828 }
3829 boolean DXApplication::isWarningEnabled()
3830 {
3831 return this->resource.warningEnabled;
3832 }
3833 boolean DXApplication::isErrorEnabled()
3834 {
3835 return this->resource.errorEnabled;
3836 }
3837 boolean DXApplication::doesInfoOpenMessage(boolean fromModule)
3838 {
3839 return (this->resource.infoOpensMessage ||
3840 (fromModule && this->resource.moduleInfoOpensMessage)) &&
3841 this->isInfoEnabled();
3842 }
3843 boolean DXApplication::doesWarningOpenMessage()
3844 {
3845 return this->resource.warningOpensMessage && this->isWarningEnabled();
3846 }
3847 boolean DXApplication::doesErrorOpenMessage()
3848 {
3849 return this->resource.errorOpensMessage && this->isErrorEnabled();
3850 }
3851 int DXApplication::doesErrorOpenVpe(Network *net)
3852 {
3853 if ((!this->isErrorEnabled()) ||
3854 (net->wasNetFileEncoded()) ||
3855 (!this->appAllowsEditorAccess()))
3856 return DXApplication::DontOpenVpe;
3857
3858 if (this->resource.noEditorOnError) {
3859 #if DONT_PROMPT_THE_USER
3860 return DXApplication::DontOpenVpe;
3861 #else
3862 return DXApplication::MayOpenVpe;
3863 #endif
3864 }
3865
3866 return DXApplication::MustOpenVpe;
3867 }
3868 void DXApplication::enableInfo(boolean enable)
3869 {
3870 this->resource.infoEnabled = enable;
3871 }
3872 void DXApplication::enableWarning(boolean enable)
3873 {
3874 this->resource.warningEnabled = enable;
3875 }
3876 void DXApplication::enableError(boolean enable)
3877 {
3878 this->resource.errorEnabled = enable;
3879 }
3880
3881
3882 void DXApplication::dumpObject(Base *object)
3883 {
3884 this->dumpedObjects.appendElement((void*)object);
3885
3886 }
3887
3888
3889 void DXApplication::destroyDumpedObjects()
3890 {
3891 Base *object;
3892 ListIterator li(this->dumpedObjects);
3893
3894 while( (object = (Base*)li.getNext()) )
3895 delete object;
3896
3897 this->dumpedObjects.clear();
3898 }
3899
3900 void DXApplication::postLoadMDFDialog()
3901 {
3902 if (this->loadMDFDialog == NULL) {
3903 this->loadMDFDialog = new LoadMDFDialog( this->anchor->getRootWidget(),
3904 this);
3905 }
3906
3907 this->loadMDFDialog->post();
3908
3909 }
3910
3911 void DXApplication::postProcessGroupAssignDialog()
3912 {
3913 if (NOT this->processGroupAssignDialog)
3914 this->processGroupAssignDialog =
3915 new ProcessGroupAssignDialog(this);
3916
3917 this->processGroupAssignDialog->post();
3918 }
3919
3920 //
3921 // Get selected NodeDefinitoins from the new dictionary and send
3922 // their representative MDF specs to the server if they are
3923 // 1) outboard
3924 // 2) dynamically loaded
3925 // 3) outboardness or dynmacity changes compared to the possibly
3926 // existing definition in the current dictionary.
3927 //
3928 void DXApplication::sendNewMDFToServer(Dictionary *newdefs, Dictionary *current)
3929 {
3930 char *buf = NULL;
3931 boolean sent_stuff = FALSE;
3932 DXPacketIF *pif = this->getPacketIF();
3933
3934 if (!pif)
3935 return;
3936
3937 ASSERT(newdefs);
3938 NodeDefinition *nd;
3939 DictionaryIterator di(*newdefs);
3940 while ( (nd = (NodeDefinition*)di.getNextDefinition()) ) {
3941 char *mdf;
3942 int buflen = 0;
3943 boolean outboard = nd->isOutboard();
3944 boolean dynamic = nd->isDynamicallyLoaded();
3945 // The following requires that the exec sees the -mdf options that
3946 // the UI sees.
3947 boolean send = (outboard || dynamic) && nd->isUILoadedOnly();
3948 //
3949 // See if a definition already existed and if the outboardness or
3950 // the dynamicity changes (e.g. outboard -> inboard) we must resend
3951 // the new definition.
3952 //
3953 if (!send && current) {
3954 Symbol s = nd->getNameSymbol();
3955 NodeDefinition *olddef = (NodeDefinition*)
3956 current->findDefinition(s);
3957 if (olddef) {
3958 //
3959 // Resend if the outboardness or the dynmacity of the module
3960 // changes.
3961 //
3962 send = (olddef->isOutboard() != outboard) ||
3963 (olddef->isDynamicallyLoaded() != dynamic);
3964 }
3965 }
3966 //
3967 // If we're supposed to send this definition and the node has one,
3968 // then lets send it.
3969 //
3970 if (send && (mdf = nd->getMDFString())) {
3971
3972 int mdflen = STRLEN(mdf) + 128; // 64 for "Executive(..."
3973 if (buflen <= mdflen) {
3974 buf = (char*)REALLOC(buf, mdflen + 1);
3975 buflen = mdflen + 1;
3976 }
3977 //
3978 // Copy mdf into buf, expanding newlines in to "\n" and
3979 // " into \"
3980 //
3981 strcpy(buf,"Executive(\"mdf string\",\"");
3982 char *p = buf, *m = mdf;
3983 p += STRLEN(buf);
3984 while (*m) {
3985 if (*m == '\n') {
3986 *p = '\\';
3987 p++;
3988 *p = 'n';
3989 } else if (*m == '"') {
3990 *p = '\\';
3991 p++;
3992 *p = '"';
3993 } else {
3994 *p = *m;
3995 }
3996 p++;
3997 m++;
3998 }
3999 *p = '\0';
4000 strcat(p,"\");\n");
4001 pif->send(DXPacketIF::FOREGROUND, buf);
4002 delete mdf;
4003 sent_stuff = TRUE;
4004 }
4005 }
4006
4007 if (buf) {
4008 //
4009 // Delete the buffer
4010 //
4011 delete buf;
4012 }
4013
4014 const char *file;
4015 int i;
4016 for (i=1 ;
4017 (file = (const char*)theDynamicPackageDictionary->getStringKey(i)) ;
4018 i++) {
4019 char sbuf[1024];
4020 sprintf(sbuf,"Executive(\"package\",\"%s\");\n",file);
4021 pif->send(DXPacketIF::FOREGROUND, sbuf);
4022 sent_stuff = TRUE;
4023 }
4024
4025 if (sent_stuff) {
4026 //
4027 // Make sure the executive processes the Executive() calls
4028 // before parsing ahead.
4029 //
4030 pif->sendImmediate("sync");
4031 }
4032
4033 }
4034
4035 #define FULLY_RESTRICTED 1
4036 #define SOMEWHAT_RESTRICTED 2
4037 #define MINIMALLY_RESTRICTED 3
4038 //
4039 // Define a set of routines that are used to set the level of customization
4040 // and/or the number of features provided by the user-interface.
4041 //
4042
4043 //
4044 // Define a mapping of integer levels and the restriction level names and
4045 // determine if the current restriction level is at the given level.
4046 // The highest level of restriction is 1 the lowest and +infinity.
4047 //
4048 // Currently, we map the following to restriction levels...
4049 //
4050 // Level 1 - "C"
4051 // Level 2 - "B"
4052 // Level 3 - "A"
4053 //
4054 //
4055 boolean DXApplication::isRestrictionLevel(int level)
4056 {
4057 const char *rlev = this->resource.restrictionLevel;
4058
4059 ASSERT(level > 0);
4060
4061 if (!rlev)
4062 return FALSE;
4063
4064 switch (level) {
4065 case 3: if (EqualString("minimum",rlev)) return TRUE;
4066 case 2: if (EqualString("intermediate",rlev)) return TRUE;
4067 case 1: if (EqualString("maximum",rlev)) return TRUE;
4068 default:
4069 return FALSE;
4070 }
4071 return FALSE;
4072
4073 }
4074 boolean DXApplication::appAllowsDXHelp()
4075 {
4076 return !this->resource.noDXHelp && !this->getOEMApplicationName();
4077 }
4078 boolean DXApplication::appAllowsPanelEdit()
4079 {
4080 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4081 !this->resource.noPanelEdit;
4082 }
4083 boolean DXApplication::appAllowsRWConfig()
4084 {
4085 return !this->isRestrictionLevel(FULLY_RESTRICTED) &&
4086 !this->resource.noRWConfig;
4087 }
4088 boolean DXApplication::appAllowsPanelAccess()
4089 {
4090 return !this->isRestrictionLevel(FULLY_RESTRICTED) &&
4091 !this->resource.noPanelAccess;
4092 }
4093 boolean DXApplication::appAllowsOpenAllPanels()
4094 {
4095 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4096 !this->resource.noOpenAllPanels;
4097 }
4098 boolean DXApplication::appAllowsPanelOptions()
4099 {
4100 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4101 !this->resource.noPanelOptions;
4102 }
4103
4104 boolean DXApplication::appAllowsInteractorSelection()
4105 {
4106 return this->appAllowsPanelEdit() ||
4107 this->appAllowsInteractorAttributeChange() ||
4108 this->appAllowsInteractorEdits();
4109 }
4110 boolean DXApplication::appAllowsInteractorMovement()
4111 {
4112 return this->appAllowsPanelEdit() &&
4113 !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4114 !this->resource.noInteractorMovement;
4115 }
4116 boolean DXApplication::appAllowsInteractorAttributeChange()
4117 {
4118 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4119 this->appAllowsPanelEdit() &&
4120 !this->resource.noInteractorAttributes;
4121 }
4122 boolean DXApplication::appAllowsInteractorEdits()
4123 {
4124 return !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4125 this->appAllowsPanelEdit() &&
4126 !this->resource.noInteractorEdits;
4127 }
4128
4129 boolean DXApplication::appLimitsNetFileSelection()
4130 {
4131 return this->resource.limitedNetFileSelection;
4132 }
4133 boolean DXApplication::appAllowsImageRWNetFile()
4134 {
4135 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4136 !this->resource.noImageRWNetFile;
4137 }
4138 boolean DXApplication::appAllowsSavingNetFile(Network *n)
4139 {
4140 return this->appAllowsSavingCfgFile() &&
4141 (!n || !n->wasNetFileEncoded());
4142 }
4143 boolean DXApplication::appAllowsSavingCfgFile()
4144 {
4145 return (this->appLicenseType != TimedLicense) &&
4146 (this->inEditMode() || this->appAllowsImageRWNetFile());
4147 }
4148 boolean DXApplication::appAllowsImageLoad()
4149 {
4150 return !this->isRestrictionLevel(SOMEWHAT_RESTRICTED) &&
4151 !this->resource.noImageLoad;
4152 }
4153 boolean DXApplication::appAllowsImagePrinting()
4154 {
4155 return !this->resource.noImagePrinting;
4156 }
4157 boolean DXApplication::appAllowsImageSaving()
4158 {
4159 return !this->isRestrictionLevel(FULLY_RESTRICTED) &&
4160 !this->resource.noImageSaving;
4161 }
4162 boolean DXApplication::appLimitsImageOptions()
4163 {
4164 return this->isRestrictionLevel(MINIMALLY_RESTRICTED) ||
4165 this->resource.limitImageOptions;
4166 }
4167
4168
4169 boolean DXApplication::appAllowsEditorAccess()
4170 {
4171 LicenseTypeEnum func = this->getFunctionalLicenseEnum();
4172
4173 //
4174 // If the license hasn't yet been acquired, then try the OEM
4175 // license codes.
4176 //
4177 if (func == UndeterminedLicense)
4178 this->verifyOEMLicenseCode(&func);
4179
4180 return !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4181 !this->resource.noEditorAccess &&
4182 (func != RunTimeLicense);
4183 }
4184
4185 boolean DXApplication::appAllowsPGroupAssignmentChange()
4186 {
4187 return !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4188 !this->resource.noPGroupAssignment;
4189 }
4190 boolean DXApplication::appAllowsMessageInfoOption()
4191 {
4192 return !this->resource.noMessageInfoOption;
4193 }
4194 boolean DXApplication::appAllowsMessageWarningOption()
4195 {
4196 return !this->resource.noMessageWarningOption;
4197 }
4198 boolean DXApplication::appAllowsScriptCommands()
4199 {
4200 return !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4201 !this->resource.noScriptCommands;
4202 }
4203 boolean DXApplication::appAllowsCMapSetName()
4204 {
4205 return !this->isRestrictionLevel(MINIMALLY_RESTRICTED) &&
4206 !this->resource.noCMapSetNameOption;
4207 }
4208 boolean DXApplication::appAllowsCMapOpenMap()
4209 {
4210 return !this->isRestrictionLevel(FULLY_RESTRICTED) &&
4211 !this->resource.noCMapOpenMap;
4212 }
4213 boolean DXApplication::appAllowsCMapSaveMap()
4214 {
4215 return !this->isRestrictionLevel(FULLY_RESTRICTED) &&
4216 !this->resource.noCMapSaveMap;
4217 }
4218 boolean DXApplication::appSuppressesStartupWindows()
4219 {
4220 return this->resource.suppressStartupWindows;
4221 }
4222 boolean DXApplication::appAllowsExitOptions()
4223 {
4224 return !this->resource.noExitOptions;
4225 }
4226 boolean DXApplication::appAllowsExecuteMenus()
4227 {
4228 return !this->resource.noExecuteMenus;
4229 }
4230 boolean DXApplication::appAllowsConnectionMenus()
4231 {
4232 return !this->resource.noConnectionMenus;
4233 }
4234 boolean DXApplication::appAllowsWindowsMenus()
4235 {
4236 return !this->resource.noWindowsMenus;
4237 }
4238 boolean DXApplication::appAllowsImageMenus()
4239 {
4240 return !this->resource.noImageMenus;
4241 }
4242 boolean DXApplication::appAllowsConfirmedQuit()
4243 {
4244 return !this->resource.noConfirmedQuit;
4245 }
4246
4247 //
4248 // See if there is an OEM license code (see oemApplicationName and
4249 // oemLicenseCode resources) and if so see if it is valid.
4250 // If so return TRUE and set *func, otherwise return FALSE and leave
4251 // *func untouched.
4252 //
4253 boolean DXApplication::verifyOEMLicenseCode(LicenseTypeEnum *func)
4254 {
4255 char cryptbuf[1024];
4256 boolean r;
4257
4258 ASSERT(func);
4259
4260 if (!this->resource.oemLicenseCode || !this->getOEMApplicationName())
4261 return FALSE;
4262
4263 ScrambleAndEncrypt(this->resource.oemApplicationName,"DEV",cryptbuf);
4264 if (EqualString(cryptbuf,this->resource.oemLicenseCode)) {
4265 *func = DeveloperLicense;
4266 r = TRUE;
4267 } else {
4268 ScrambleAndEncrypt(this->resource.oemApplicationName,"RT",cryptbuf);
4269 if (EqualString(cryptbuf,this->resource.oemLicenseCode)) {
4270 *func = RunTimeLicense;
4271 r = TRUE;
4272 } else
4273 r = FALSE;
4274 }
4275
4276 return r;
4277
4278 }
4279 //
4280 // Check the oemApplicationName and oemApplicationNameCode resources and see
4281 // if an alternate application name can be verified. If so, return it
4282 // otherwise return NULL.
4283 //
4284 const char *DXApplication::getOEMApplicationName()
4285 {
4286 char cryptbuf[1024];
4287
4288 if (!this->resource.oemApplicationName ||
4289 !this->resource.oemApplicationNameCode)
4290 return NULL;
4291
4292 if (STRLEN(this->resource.oemApplicationName) < 3)
4293 return NULL;
4294
4295 ScrambleAndEncrypt(this->resource.oemApplicationName,"DX",cryptbuf);
4296 if (EqualString(cryptbuf,this->resource.oemApplicationNameCode))
4297 return this->resource.oemApplicationName;
4298 else
4299 return NULL;
4300 }
4301 //
4302 // Return the name of the application (i.e. 'Data Explorer',
4303 // 'Data Prompter', 'Medical Visualizer'...).
4304 // If getOEMApplicationName() return !NULL, then use that.
4305 //
4306 const char *DXApplication::getInformalName()
4307 {
4308 const char *s = this->getOEMApplicationName();
4309 if (!s) s = "Data Explorer";
4310 return s;
4311 }
4312 //
4313 // Return the formal name of the application (i.e.
4314 // 'Open Visualization Data Explorer', 'Open Visualization Data Prompter'...)
4315 // If getOEMApplicationName() return !NULL, then use that.
4316 //
4317 const char *DXApplication::getFormalName()
4318 {
4319 const char *s = this->getOEMApplicationName();
4320 if (!s) s = "Open Visualization Data Explorer";
4321 return s;
4322 }
4323 //
4324
4325 // Get the applications copyright notice, for example...
4326 // "Copyright International Business Machines Corporation 1991-1993
4327 // All rights reserved"
4328 // If getOEMApplicationName() return !NULL, then don't use a copyright
4329 // (i.e. return NULL).
4330 //
4331
4332
4333 const char *DXApplication::getCopyrightNotice()
4334 {
4335 const char *s = this->getOEMApplicationName();
4336 if (!s)
4337 return DXD_COPYRIGHT_STRING;
4338 else
4339 return NULL;
4340 }
4341
4342 //
4343 // The new 3rd anchor supplies the copyright message itself. If using such an
4344 // anchor then use only that copyright else use superclass.
4345 //
4346 void DXApplication::postCopyrightNotice()
4347 {
4348 if ((this->anchor) &&
4349 (strcmp (this->anchor->getClassName(), ClassDXAnchorWindow) == 0)) {
4350 DXAnchorWindow *dxa = (DXAnchorWindow*)this->anchor;
4351 dxa->postCopyrightNotice();
4352 } else {
4353 this->IBMApplication::postCopyrightNotice();
4354 }
4355 }
4356
4357
4358 //
4359 // Get the default image printing/saving options specified through
4360 // command line options or resources.
4361 //
4362 String DXApplication::getPrintImageFormat()
4363 { return this->resource.printImageFormat; }
4364 String DXApplication::getPrintImagePageSize()
4365 { return this->resource.printImagePageSize; }
4366 String DXApplication::getPrintImageSize()
4367 { return this->resource.printImageSize; }
4368 int DXApplication::getPrintImageResolution()
4369 { return this->resource.printImageResolution; }
4370 String DXApplication::getPrintImageCommand()
4371 { return this->resource.printImageCommand; }
4372 String DXApplication::getSaveImageFormat()
4373 { return this->resource.saveImageFormat; }
4374 String DXApplication::getSaveImagePageSize()
4375 { return this->resource.saveImagePageSize; }
4376 String DXApplication::getSaveImageSize()
4377 { return this->resource.saveImageSize; }
4378 int DXApplication::getSaveImageResolution()
4379 { return this->resource.saveImageResolution; }
4380
4381 void DXApplication::notifyPanelChanged()
4382 {
4383 this->notifyClients(DXApplication::MsgPanelChanged);
4384 }
4385
4386 //
4387 // Tell the exec to get a license or not based on the type of license
4388 // that we have.
4389 //
4390 boolean DXApplication::verifyServerLicense()
4391 {
4392 #if defined(DXD_LICENSED_VERSION)
4393 DXPacketIF *pif = this->getPacketIF();
4394 if (!pif)
4395 return FALSE;
4396
4397 pif->setHandler(DXPacketIF::INFORMATION,
4398 DXApplication::LicenseMessage,
4399 (void*)this,
4400 "LICENSE:");
4401
4402 pif->sendImmediate("getkey"); // sends back -> 'LICENSE: abcd'
4403 // or 'LICENSE: UNAUTHORIZED
4404
4405 //
4406 // Wait until we get the AUTHORIZED or UNAUTHORIZED message.
4407 //
4408 void *licensed;
4409 boolean r;
4410 if (pif->receiveContinuous(&licensed))
4411 r = (boolean)licensed;
4412 else
4413 r = FALSE;
4414
4415 return r;
4416 #else
4417 return TRUE;
4418 #endif
4419
4420 }
4421
4422 #if defined(DXD_LICENSED_VERSION)
4423 //
4424 // Catch the 'LICENSE:' message from the executive and shake hands with
4425 // it to make sure it got the correct license based on the type of
4426 // license that the UI has.
4427 //
4428 void DXApplication::LicenseMessage(void *, int, void *ptr)
4429 {
4430 char *p = (char*)ptr;
4431 static char *lic_token = "LICENSE:";
4432 DXPacketIF *pif = theDXApplication->getPacketIF();
4433
4434
4435 if (p = strstr(p, lic_token)) {
4436 p += STRLEN(lic_token);
4437 SkipWhiteSpace(p);
4438 if (strstr(p,"AUTHORIZED")) {
4439 boolean licensed;
4440 if (EqualString(p,"UNAUTHORIZED")) {
4441 licensed = FALSE;
4442 theDXApplication->scheduleServerDisconnect();
4443 InfoMessage("A license for the server is not available. "
4444 "Server disconnected.");
4445 } else {
4446 licensed = TRUE;
4447 }
4448
4449 if (pif) // Force ::verifyServerLicense() to return;
4450 pif->endReceiveContinuous((void*)licensed);
4451 } else if (strstr(p,"NO LICENSE")) {
4452 ;
4453 } else if (p) { // FIXME: this could be improved
4454 // Expecting 'LICENSE: xxxx' in *p
4455 LicenseTypeEnum lic = theDXApplication->appLicenseType;
4456 if (lic == TimedLicense)
4457 lic = ConcurrentLicense;
4458 char *outkey = GenerateExecKey(p,lic);
4459 if (outkey) {
4460 char buf[1024];
4461 sprintf(buf,"license %s",outkey);
4462 DXPacketIF *pif = theDXApplication->getPacketIF();
4463 pif->sendImmediate( buf);
4464 delete outkey;
4465 }
4466 }
4467 } else {
4468 fprintf(stderr,"Unauthorized LICENSE message...exiting.\n");
4469 exit (1);
4470 }
4471
4472 }
4473
4474 #endif
4475
4476 void DXApplication::scheduleServerDisconnect()
4477 {
4478 this->serverDisconnectScheduled = TRUE;
4479 }
4480
4481 //
4482 // Manage the software licenses
4483 //
4484 extern "C" void ShutdownTimeout(XtPointer clientData, XtIntervalId *id);
4485 extern "C" void InstallShutdownTimer(Widget w,
4486 XtPointer clientData, XtPointer calldata);
4487 extern "C" void ShutdownApplication(Widget w,
4488 XtPointer clientData, XtPointer callData);
4489
4490 void DXApplication::determineUILicense(LicenseTypeEnum *app,
4491 LicenseTypeEnum *func)
4492 {
4493 #if defined(DXD_LICENSED_VERSION) && DXD_LICENSED_VERSION!=0
4494
4495 # ifdef DEBUG
4496 if (!theDXApplication->appAllowsInteractorMovement()) {
4497 *app = Unlicensed;
4498 *func = RunTimeLicense;
4499 } else if (!theDXApplication->appAllowsPanelEdit()) {
4500 *app = ConcurrentLicense;
4501 *func = RunTimeLicense;
4502 } else if (!theDXApplication->appAllowsPanelAccess()) {
4503 *app = NodeLockedLicense;
4504 *func = RunTimeLicense;
4505 } else if (!theDXApplication->appAllowsCMapSaveMap()) {
4506 *app = TimedLicense;
4507 *func = RunTimeLicense;
4508 } else {
4509 # endif
4510 LicenseTypeEnum oemLic = Unlicensed;
4511 *app = Unlicensed;
4512 if (this->isFunctionalLicenseForced())
4513 *func = this->getForcedFunctionalLicenseEnum();
4514 else
4515 *func = Unlicensed;
4516 if (*func == TimedLicense) {
4517 *app = TimedLicense;
4518 *func = DeveloperLicense;
4519 } else if (this->verifyOEMLicenseCode(&oemLic) &&
4520 ((*func == Unlicensed) || (oemLic == *func))) {
4521 *app = FullyLicensed;
4522 } else
4523 UIGetLicense(this->getUIRoot(), LostLicense, app,func);
4524 # ifdef DEBUG
4525 }
4526 # endif
4527
4528 #else
4529 #if !defined(DXD_WIN) || 1
4530 *app = FullyLicensed;
4531 *func = DeveloperLicense;
4532 #else
4533 UIGetLicense(this->getUIRoot(), LostLicense, app,func);
4534 #endif
4535 #endif // DXD_LICENSED_VERSION
4536 this->appLicenseType = *app;
4537 this->funcLicenseType = *func;
4538 }
4539 boolean DXApplication::isFunctionalLicenseForced()
4540 {
4541 return this->resource.forceFunctionalLicense != NULL;
4542 }
4543 LicenseTypeEnum DXApplication::getFunctionalLicenseEnum()
4544 {
4545 if (this->funcLicenseType == UndeterminedLicense) { // not determined yet
4546 if (this->isFunctionalLicenseForced())
4547 return this->getForcedFunctionalLicenseEnum();
4548 else
4549 return UndeterminedLicense;
4550 } else {
4551 return this->funcLicenseType;
4552 }
4553 }
4554 LicenseTypeEnum DXApplication::getForcedFunctionalLicenseEnum()
4555 {
4556
4557 if (!this->isFunctionalLicenseForced())
4558 return FullFunctionLicense;
4559 const char *s = this->resource.forceFunctionalLicense;
4560 if (EqualString(s, LIC_RT_OPTION))
4561 return RunTimeLicense;
4562 else if (EqualString(s,LIC_DEV_OPTION))
4563 return DeveloperLicense;
4564 else if (EqualString(s,LIC_TIMED_OPTION))
4565 return TimedLicense;
4566 else if (EqualString(s,LIC_VIEWER_OPTION))
4567 return ViewerLicense;
4568 else
4569 return FullFunctionLicense; // User gave unrecognized license name
4570 }
4571
4572
4573 //
4574 // The number of seconds between the first and second warnings about
4575 // losing the license
4576 //
4577 #ifdef DEBUG
4578 # define MAX_INTERVAL 16
4579 #else
4580 # define MAX_INTERVAL 120
4581 #endif
4582 //
4583 // The minimum interval between warnings for which another warning will
4584 // be scheduled instead of saving files automatically.
4585 //
4586 #ifdef DEBUG
4587 # define MIN_INTERVAL 8
4588 #else
4589 # define MIN_INTERVAL 30
4590 #endif
4591 static char *format_seconds(int seconds)
4592 {
4593 static char buf[64];
4594 int minutes, frac = seconds % 60;
4595
4596 if (seconds > 60)
4597 minutes = seconds/60;
4598 else
4599 minutes = 0;
4600
4601 if (minutes == 0)
4602 sprintf(buf,"%d seconds", seconds);
4603 else if (frac > 0)
4604 sprintf(buf,"%d minute%s %d seconds",
4605 minutes, minutes == 1? "": "s", frac);
4606 else
4607 sprintf(buf,"%d minute%s", minutes, minutes == 1? "": "s");
4608
4609 return buf;
4610 }
4611 //
4612 // If seconds is greater then 30, then we issue a warning
4613 // and install this routine as call back for the ok button so that another
4614 // timeout is installed after the ok is hit.
4615 // If seconds is positive and less than 30 seconds, then we save the
4616 // user's work and shutdown the application.
4617 //
4618 extern "C" void ShutdownTimeout(XtPointer clientData, XtIntervalId *id)
4619 {
4620 char buffer[1024];
4621 int seconds = (int)(long) clientData;
4622 boolean can_save = theDXApplication->appAllowsSavingNetFile();
4623
4624 if (seconds > MIN_INTERVAL ) {
4625 seconds = (int)(seconds/2.0);
4626 sprintf(buffer,
4627 "You do not have a license to run %s.\n"
4628 "You have %s %s",
4629 theApplication->getInformalName(),
4630 format_seconds(seconds),
4631 (!can_save ? "before your session is terminated." :
4632 "to save your work and exit."));
4633
4634 theWarningDialogManager->modalPost(
4635 theDXApplication->getAnchor()->getRootWidget(),
4636 buffer,
4637 "WARNING: User Interface License",
4638 (void*) seconds,
4639 NULL, // Ok button
4640 NULL); // Close manager options menu
4641 Widget w = XtParent(theWarningDialogManager->getRootWidget());
4642 ASSERT(XtHasCallbacks(w,XmNpopdownCallback));
4643 XtRemoveCallback(w,XmNpopdownCallback,
4644 InstallShutdownTimer, (XtPointer)(seconds*2));
4645 XtAddCallback(w,XmNpopdownCallback,
4646 InstallShutdownTimer, (XtPointer)seconds);
4647 } else if (can_save) {
4648 ListIterator li;
4649 int i;
4650 boolean save_files = FALSE;
4651 Network *n;
4652 #ifdef DXD_OS_NON_UNIX
4653 // FIXME: suits should use ENV variables to fine tmp path
4654 // char *dirs[2] = { "\\tmp", NULL };
4655 const char *dirs[2];
4656 dirs[0] = theDXApplication->getTmpDirectory();
4657 dirs[1] = NULL;
4658 #else
4659 # if defined(aviion) || defined(hp700)
4660 // These guys won't do aggregate initialization of automatics
4661 char *dirs[3];
4662 dirs[0] = "/tmp";
4663 dirs[1] = "/usr/tmp";
4664 dirs[2] = NULL;
4665 # else
4666 char *dirs[] = { "/tmp", "/usr/tmp" , NULL};
4667 # endif
4668 #endif
4669 //
4670 // Check to see if there are files (networks) that need saving.
4671 //
4672 if (theDXApplication->network->saveToFileRequired() &&
4673 theDXApplication->network->getNodeCount() > 0)
4674 save_files = TRUE;
4675
4676 if (!save_files) {
4677 li.setList(theDXApplication->macroList);
4678 while ( (n = (Network*)li.getNext()) )
4679 if (n->saveToFileRequired() || (n->getNodeCount() > 0))
4680 save_files = TRUE;
4681 }
4682
4683 //
4684 // Save the networks
4685 //
4686 if (save_files) {
4687 char msg[4096];
4688 char buf[1024];
4689 boolean write_error = TRUE;
4690 strcpy(msg,"The following files have been written...\n\n");
4691 for (i=0 ; write_error && dirs[i] ; i++) {
4692 int cnt;
4693 li.setList(theDXApplication->macroList);
4694 for (n=theDXApplication->network, cnt=0, write_error = FALSE;
4695 n && !write_error ;
4696 n = (Network*)li.getNext())
4697 {
4698 if (n->saveToFileRequired()) {
4699 const char *filename = n->getFileName();
4700 char *basename;
4701 if (filename) {
4702 basename = GetFileBaseName(filename, NULL);
4703 } else {
4704 basename = new char[32];
4705 sprintf(basename,"network_%d",++cnt);
4706 }
4707 sprintf(buf,"%s/%s",dirs[i],basename);
4708 strcat(msg,"\t");
4709 strcat(msg,buf);
4710 if (!n->saveNetwork(buf, TRUE)) {
4711 strcat(msg," (error while writing)");
4712 write_error = TRUE;
4713 }
4714 strcat(msg,"\n");
4715 delete basename;
4716 }
4717 }
4718 }
4719 sprintf(buf,"\n%s will now terminate.",
4720 theApplication->getInformalName());
4721 strcat(msg, buf);
4722
4723 theWarningDialogManager->modalPost(
4724 theDXApplication->getAnchor()->getRootWidget(),
4725 msg,
4726 "Terminating",
4727 (void*) theDXApplication,
4728 NULL, // Ok button
4729 NULL); // Close manager options menu
4730 Widget w = XtParent(theWarningDialogManager->getRootWidget());
4731 ASSERT(XtHasCallbacks(w,XmNpopdownCallback));
4732 XtAddCallback(w,XmNpopdownCallback,
4733 ShutdownApplication, (XtPointer)theDXApplication);
4734
4735 } else {
4736 theDXApplication->shutdownApplication();
4737 }
4738 } else {
4739 theDXApplication->shutdownApplication();
4740 }
4741 }
4742 //
4743 // clientData is interpretted as a number of seconds.
4744 // Installs the shutdown timeout function to occur after the indicated
4745 // number of seconds.
4746 //
4747 extern "C" void InstallShutdownTimer(Widget w,
4748 XtPointer clientData, XtPointer calldata)
4749 {
4750 int seconds = (int)(long) clientData;
4751
4752 ASSERT(seconds > 0);
4753
4754 XtAppAddTimeOut(
4755 theApplication->getApplicationContext(),
4756 1000*seconds,
4757 ShutdownTimeout,
4758 (XtPointer)seconds);
4759
4760 }
4761 //
4762 // Called when the license for the user interface has been lost
4763 // This issues a modal warning and installs a callback on the warning, so
4764 // that when the user enters ok, a timer is installed so that the
4765 // system issues more warnings until if finally shuts down.
4766 //
4767 #if 0
4768 static void LostLicense(XtPointer clientData, int *fid, XtInputId *id)
4769 {
4770 XtRemoveInput(*id);
4771
4772 //
4773 // Make sure the keyboard/pointer is grabbed, so that the user
4774 // can respond to a modal dialog.
4775 //
4776 XUngrabPointer(theApplication->getDisplay(), CurrentTime);
4777 XUngrabKeyboard(theApplication->getDisplay(), CurrentTime);
4778
4779 char buf[1024];
4780
4781 sprintf(buf,
4782 "Your %s session has lost its license to run the\n"
4783 "user interface. After closing this dialog, you will be given\n"
4784 "%s with intervening warnings before your session terminates.\n"
4785 "If you do not save your work, it will be saved for you.",
4786 theApplication->getInformalName(),
4787 format_seconds(MAX_INTERVAL));
4788
4789 theWarningDialogManager->modalPost(
4790 theDXApplication->getAnchor()->getRootWidget(),
4791 buf,
4792 "WARNING: User Interface License",
4793 (void*) MAX_INTERVAL,
4794 NULL, // Ok button
4795 NULL); // Close manager options menu
4796 Widget w = XtParent(theWarningDialogManager->getRootWidget());
4797 ASSERT(XtHasCallbacks(w,XmNpopdownCallback));
4798 XtAddCallback(w,XmNpopdownCallback,
4799 InstallShutdownTimer, (XtPointer)MAX_INTERVAL);
4800 }
4801 #endif
4802
4803 //
4804 // Shutdown the application (typically, after the user has hit OK on
4805 // a dialog).
4806 //
4807 extern "C" void ShutdownApplication(Widget w,
4808 XtPointer clientData, XtPointer callData)
4809 {
4810 Application *app = (Application*)clientData;
4811 app->shutdownApplication();
4812 }
4813 extern "C" int DXApplication_DXAfterFunction(Display *display)
4814 {
4815 Window root;
4816 Window child;
4817 int root_x;
4818 int root_y;
4819 int win_x;
4820 int win_y;
4821 unsigned int key_buttons;
4822 Window win;
4823
4824 XSetAfterFunction(display, NULL);
4825
4826 win = RootWindow(display,0);
4827 XQueryPointer(display, win,
4828 &root, &child, &root_x, &root_y,
4829 &win_x, &win_y, &key_buttons);
4830
4831 XSetAfterFunction(display, DXApplication_DXAfterFunction);
4832 return 1;
4833 }
4834
4835 boolean DXApplication::printComment(FILE *f)
4836 {
4837 if ((this->messageWindow && this->messageWindow->isManaged()) ||
4838 (this->helpWindow && this->helpWindow->isManaged())) {
4839 if (this->messageWindow->isManaged()) {
4840 if ((fprintf(f,"// Message Window:\n") < 0) ||
4841 !this->messageWindow->printComment(f))
4842 return FALSE;
4843 }
4844 }
4845
4846 return TRUE;
4847 }
4848 boolean DXApplication::parseComment(const char *comment,
4849 const char *filename, int lineno)
4850 {
4851 if (strstr(comment,"Message Window:")) {
4852 if (!this->messageWindow)
4853 this->messageWindow = this->newMsgWin();
4854 this->messageWindow->useDefaultCommentState();
4855 } else if (this->messageWindow) {
4856 if (!this->messageWindow->parseComment(comment,filename,lineno))
4857 return FALSE;
4858 } else {
4859 return FALSE;
4860 }
4861
4862 return TRUE;
4863 }
4864
4865 //
4866 // Return TRUE if the DXWindows are supposed to use the window placement
4867 // information saved in the .net or .cfg files.
4868 //
4869 boolean DXApplication::applyWindowPlacements()
4870 {
4871 return !this->resource.noWindowPlacement;
4872 }
4873
4874 boolean DXApplication::inEditMode()
4875 {
4876 return EqualString(this->resource.anchorMode,EDIT_ANCHOR_MODE);
4877 }
4878 boolean DXApplication::inImageMode()
4879 {
4880 return EqualString(this->resource.anchorMode,IMAGE_ANCHOR_MODE);
4881 }
4882 boolean DXApplication::inMenuBarMode()
4883 {
4884 return EqualString(this->resource.anchorMode,MENUBAR_ANCHOR_MODE);
4885 }
4886 const char *DXApplication::getDataViewerImportFile()
4887 {
4888 return this->resource.viewDataFile;
4889 }
4890 boolean DXApplication::inDataViewerMode()
4891 {
4892 return this->getDataViewerImportFile() != NULL;
4893 }
4894
4895 void DXApplication::shutdownApplication()
4896 {
4897 XEvent event;
4898 Widget widg = this->getRootWidget();
4899 Window w = XtWindow(widg);
4900
4901 this->runApplication = FALSE;
4902
4903 event.type = KeyPress;
4904
4905 XSendEvent(this->display, w, True, XtBuildEventMask(widg), &event);
4906
4907 if ((this->inEditMode()) && (this->appAllowsSavingNetFile()))
4908 theResourceManager->saveResources();
4909 }
4910
4911 //
4912 // Does this application force the .net files that are read in to be
4913 // encrypted.
4914 //
4915 boolean DXApplication::appForcesNetFileEncryption()
4916 {
4917 return this->resource.forceNetFileEncryption;
4918 }
4919
4920
4921
4922 //
4923 // Write all dirty files into a tmp directory.
4924 //
4925 void DXApplication::emergencySave (char *msg)
4926 {
4927 int i;
4928 boolean write_error = TRUE;
4929
4930 #ifdef DXD_OS_NON_UNIX
4931 #ifdef DXD_WIN
4932 char *dirs[2];
4933 dirs[0] = getenv("TMP");
4934 dirs[1] = NULL;
4935 #else
4936 // FIXME:
4937 char *dirs[2] = { "\\tmp", NULL };
4938 #endif
4939 #else
4940 #if defined(aviion) || defined(hp700)
4941 // These guys won't do aggregate initialization of automatics
4942 char *dirs[3];
4943 dirs[0] = "/tmp";
4944 dirs[1] = "/usr/tmp";
4945 dirs[2] = NULL;
4946 #else
4947 char *dirs[] = { "/tmp", "/usr/tmp" , NULL};
4948 #endif
4949 #endif
4950
4951 char *introMsg = "The following files have been written...\n\n";
4952 Boolean introMsgUsed = False;
4953 char buf[1024];
4954
4955 ASSERT(msg);
4956 msg[0] = 0;
4957
4958 for (i=0 ; write_error && dirs[i] ; i++) {
4959 int cnt;
4960 ListIterator li(theDXApplication->macroList);
4961 write_error = FALSE;
4962 cnt = 0;
4963 Network *n = theDXApplication->network;
4964 while ((n) && (!write_error)) {
4965 if (n->isFileDirty() && n->saveToFileRequired()) {
4966 const char *filename = n->getFileName();
4967 char *basename;
4968 if (filename) {
4969 basename = GetFileBaseName(filename, NULL);
4970 } else {
4971 basename = new char[32];
4972 sprintf(basename,"network_%d",++cnt);
4973 }
4974 #ifdef DXD_WIN
4975 sprintf(buf,"%s\\%s",dirs[i],basename);
4976 #else
4977 sprintf(buf,"%s/%s",dirs[i],basename);
4978 #endif
4979 if (!introMsgUsed) {
4980 strcpy (msg, introMsg);
4981 introMsgUsed = True;
4982 }
4983 strcat(msg,"\t");
4984 strcat(msg,buf);
4985 if (!n->saveNetwork(buf, TRUE)) {
4986 strcat(msg," (error while writing)");
4987 write_error = TRUE;
4988 }
4989 strcat(msg,"\n");
4990 delete basename;
4991 }
4992 n = (Network*)li.getNext();
4993 }
4994 }
4995 if (!introMsgUsed)
4996 strcpy(msg,"No files needed to be saved.\n");
4997 }
4998
4999
5000
5001 // Signal handlers can be called anytime they're installed regardless of the
5002 // lifespan of the object. The check for !theDXApplication really means:
5003 // am I being called after DXApplication::~DXApplication() ?
5004 void
5005 #if defined(ALTERNATE_CXX_SIGNAL)
5006 DXApplication_HandleCoreDump(int dummy, ... )
5007 #else
5008 DXApplication_HandleCoreDump(int dummy)
5009 #endif
5010 {
5011 if (!theDXApplication) exit(1);
5012 boolean can_save = theDXApplication->appAllowsSavingNetFile();
5013
5014 fprintf (stderr, "\n%s has experienced an internal error and will terminate.\n\n",
5015 theApplication->getInformalName());
5016
5017 if (can_save) {
5018 char msg[4096];
5019 fprintf (stderr, "Attempting to save any modified files.\n"
5020 "Please check saved files for integrity by reloading them.\n");
5021 theDXApplication->emergencySave (msg);
5022 fprintf (stderr, msg);
5023 }
5024
5025 fprintf(stderr,"The application will now abort.\n");
5026
5027 fflush(stderr);
5028 fflush(stdout);
5029
5030 exit(1);
5031 }
5032 void DXApplication::abortApplication()
5033 {
5034
5035 if (theDXApplication) {
5036 char msg[4096];
5037 this->emergencySave(msg);
5038 fprintf(stderr, msg);
5039 }
5040
5041 this->IBMApplication::abortApplication();
5042 }
5043
5044
5045 //
5046 // C H E C K B E T A B U I L D D A T E C H E C K B E T A B U I L D D A T E
5047 // C H E C K B E T A B U I L D D A T E C H E C K B E T A B U I L D D A T E
5048 // C H E C K B E T A B U I L D D A T E C H E C K B E T A B U I L D D A T E
5049 // C H E C K B E T A B U I L D D A T E C H E C K B E T A B U I L D D A T E
5050 //
5051 #if defined(BETA_VERSION) && defined(NOTDEF)
5052 #include <time.h>
5053 #ifdef DXD_WIN
5054 #include <sys/timeb.h>
5055 #else
5056 #include <sys/time.h>
5057 #endif
5058 #include <stdlib.h>
5059 #include <stdio.h>
5060 #include <string.h>
5061 #define DAYS_SINCE(year,cumDays) {\
5062 int i;\
5063 cumDays=0;\
5064 for(i=70;i<year;i++){\
5065 if((i&3)==0)cumDays+=366;\
5066 else cumDays+=365;}\
5067 }
5068
5069 #if defined(alphax)
5070 extern "C" int getdate_err;
5071 extern "C" struct tm *getdate(char *string);
5072 #endif
5073
5074 void DXApplication::betaTimeoutCheck()
5075 {
5076 #define BETA_DAYS 60
5077 #define BETA_SECONDS (BETA_DAYS*24*60*60)
5078
5079 #ifdef DXD_WIN
5080 char achDate[64], szDay[32], szMonth[32], szYear[32];
5081 int iMonth, iDaysPassed;
5082 struct tm *when;
5083 time_t now, compile_t;
5084
5085 time(&now); // Get sec. since Jan 1 1970, midnight 00:00:00
5086
5087 sprintf(achDate, "%s", __DATE__);
5088 sscanf(achDate, "%s%s%s", szMonth, szDay, szYear);
5089 iMonth = 0;
5090 if(strnicmp(szMonth, "Jan", 3) == 0) iMonth = 1;
5091 if(strnicmp(szMonth, "Feb", 3) == 0) iMonth = 2;
5092 if(strnicmp(szMonth, "Mar", 3) == 0) iMonth = 3;
5093 if(strnicmp(szMonth, "Apr", 3) == 0) iMonth = 4;
5094 if(strnicmp(szMonth, "May", 3) == 0) iMonth = 5;
5095 if(strnicmp(szMonth, "Jun", 3) == 0) iMonth = 6;
5096 if(strnicmp(szMonth, "Jul", 3) == 0) iMonth = 7;
5097 if(strnicmp(szMonth, "Aug", 3) == 0) iMonth = 8;
5098 if(strnicmp(szMonth, "Sep", 3) == 0) iMonth = 9;
5099 if(strnicmp(szMonth, "Oct", 3) == 0) iMonth = 10;
5100 if(strnicmp(szMonth, "Nov", 3) == 0) iMonth = 11;
5101 if(strnicmp(szMonth, "Dec", 3) == 0) iMonth = 12;
5102
5103 when = localtime(&now);
5104 when->tm_sec = when->tm_hour = when->tm_min = 0;
5105 when->tm_mday = atoi(szDay);
5106 when->tm_mon = iMonth - 1;
5107 when->tm_year = atoi(szYear) - 1900;
5108
5109 compile_t = mktime(when);
5110 if (compile_t == -1)
5111 iDaysPassed = BETA_DAYS * 2;
5112 else
5113 iDaysPassed = (now - compile_t)/ (24*60*60);
5114
5115 if (iDaysPassed > BETA_DAYS) {
5116 fprintf (stderr, "%s\n\texpired %d days after its release.\n",
5117 this->getAboutAppString(), BETA_DAYS);
5118 exit(1);
5119 }
5120
5121
5122
5123 #else // DXD_WIN
5124
5125 #if defined(ibm6000) || defined(sun4)
5126 #define NO_GETDATE
5127 #endif
5128
5129 #if !defined(NO_GETDATE) || !defined(sun4)
5130 #define NORMAL_TIMEZONE_CONVERSION
5131 #endif
5132
5133 #ifndef NORMAL_TIMEZONE_CONVERSION
5134 // J F M A M J J A S O N
5135 static int yday[11] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
5136 static int cum_yday[11]; // { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
5137 #endif
5138
5139
5140
5141 struct tm *comp_time = NULL;
5142 time_t today = time (NULL);
5143 char *compile_date = __DATE__;
5144 char *compile_time = __TIME__;
5145 char date_mask[512];
5146 boolean abort_the_run = FALSE;
5147
5148 //
5149 // just in case
5150 //
5151 if (getenv("TCHK_BAIL_OUT")) return ;
5152
5153 #ifndef NORMAL_TIMEZONE_CONVERSION
5154 int i;
5155 int current_year = localtime(&today)->tm_year;
5156 cum_yday[0] = yday[0];
5157 for (i=1; i<11; i++) {
5158 if ((i==1) && (current_year%4))
5159 cum_yday[i] = cum_yday[i-1] + yday[i] + 1;
5160 else
5161 cum_yday[i] = cum_yday[i-1] + yday[i];
5162 }
5163 #endif
5164
5165 #if !defined(NO_GETDATE)
5166 //
5167 // If the user has a DATEMSK, then save it for later restoration
5168 //
5169 const char *od = getenv("DATEMSK");
5170 char *old_datemsk = NULL;
5171 if ((od) && (od[0])) old_datemsk = DuplicateString(od);
5172
5173 // Make the DATEMSK environment variable point to the format file
5174 // which we'll store in the dx tree.
5175 const char *cp = /*this->getUIRoot();*/getenv("DXROOT");
5176 if ((!cp) || (!cp[0])) cp = "/usr/local/dx";
5177
5178 char *dx = DuplicateString(cp);
5179 strcpy (dx, cp);
5180 int len = strlen(dx);
5181 if (dx[len-1] == '/') dx[len-1] = '\0';
5182 char date_file[512];
5183 sprintf (date_file, "%s/ui/date.fmt", dx);
5184 sprintf (date_mask, "DATEMSK=%s", date_file);
5185 //
5186 // Check for the date.fmt file. If it's not found this scheme will fail.
5187 // The root cause of the problem is an improperly set DXROOT, so tell the
5188 // user. The ui won't start.
5189 //
5190 char* admin_problem = NUL(char*);
5191 struct STATSTRUCT statb;
5192 if (stat (date_file, &statb) == -1)
5193 admin_problem = "Your DXROOT environment variable is set incorrectly.";
5194 delete dx;
5195 #endif
5196
5197 char date_time[128];
5198 sprintf (date_time, "%s %s EDT", compile_date, compile_time);
5199
5200 #ifdef NO_GETDATE
5201 // I don't know of a way to determine if strptime() succeeded or not.
5202 comp_time = new struct tm;
5203 strptime(date_time, "%b %d %Y %H:%M:%S", comp_time);
5204 #ifndef NORMAL_TIMEZONE_CONVERSION
5205 timelocal(comp_time);
5206 #endif
5207 #else
5208 // This is a leak, but without the DuplicateString, putenv trashes the environ
5209 putenv (DuplicateString(date_mask));
5210 comp_time = getdate (date_time);
5211
5212 //
5213 // Retry the time conversion because some systems don't recognize the time
5214 // zone EST5EDT. I don't know why that is. It isn't necessary to use the
5215 // time zone. It provide slightly better accuracy so that a better customer
5216 // can't continue to run an hour or two after the real expiration. The real
5217 // reason for using the timezone in the time calculation is to make it easy
5218 // to test the code.
5219 //
5220 if ((!comp_time) && (admin_problem == NUL(char*))) {
5221 sprintf (date_time, "%s %s", compile_date, compile_time);
5222 comp_time = getdate (date_time);
5223 if (!comp_time)
5224 admin_problem = "System time / compile time comparison failed.";
5225 }
5226 #endif
5227
5228 int seconds = 0;
5229 int days;
5230 if (!comp_time)
5231 abort_the_run = TRUE;
5232 else {
5233
5234
5235 #ifdef NORMAL_TIMEZONE_CONVERSION
5236 DAYS_SINCE(comp_time->tm_year,days);
5237 days+= comp_time->tm_yday;
5238 int hours = (days * 24) + comp_time->tm_hour - (1* (comp_time->tm_isdst>0));
5239 #else
5240 DAYS_SINCE(comp_time->tm_year,days);
5241 days+= (comp_time->tm_mon?cum_yday[comp_time->tm_mon-1]: 0) + comp_time->tm_mday;
5242 int hours = (days * 24) + comp_time->tm_hour;
5243 #endif
5244 int minutes = (hours * 60) + comp_time->tm_min;
5245 #ifdef NORMAL_TIMEZONE_CONVERSION
5246 seconds = minutes * 60 + comp_time->tm_sec + (int)timezone;
5247 #else
5248 seconds = minutes * 60 + comp_time->tm_sec - (int)comp_time->tm_gmtoff;
5249 #endif
5250 if ((today - seconds) > BETA_SECONDS) {
5251 abort_the_run = TRUE;
5252 }
5253 #ifdef DEBUG
5254 int diff_seconds = today-seconds;
5255 int diff_days = diff_seconds/86400;
5256 diff_seconds-= diff_days * 86400;
5257 int diff_hours = diff_seconds/3600;
5258 diff_seconds-= diff_hours*3600;
5259 int diff_minutes = diff_seconds/60;
5260 diff_seconds-= diff_minutes*60;
5261 fprintf(stdout, "%s age(days H:M:S): %d %d:%d:%d\n",
5262 this->getFormalName(), diff_days, diff_hours, diff_minutes, diff_seconds);
5263 #endif
5264 }
5265 if (abort_the_run) {
5266 #if !defined(NO_GETDATE)
5267 if (admin_problem) {
5268 fprintf (stderr, "Beta licensing failed for \n%s\n\t%s\n",
5269 this->getAboutAppString(), admin_problem);
5270 } else
5271 #endif
5272 fprintf (stderr, "%s\n\texpired %d days after its release.\n",
5273 this->getAboutAppString(), BETA_DAYS);
5274 exit(1);
5275 }
5276
5277
5278 #ifdef NO_GETDATE
5279 if (comp_time) delete comp_time;
5280 #else
5281 //
5282 // Restore DATEMSK
5283 //
5284 if (old_datemsk) {
5285 putenv(old_datemsk);
5286 //delete old_datemsk;
5287 }
5288 #endif
5289
5290 #endif // DXD_WIN
5291
5292 #undef BETA_DAYS
5293 #undef BETA_SECONDS
5294 }
5295
5296
5297 #endif
5298
5299
5300 #if WORKSPACE_PAGES
5301 ProcessGroupManager *DXApplication::getProcessGroupManager()
5302 {
5303 return (ProcessGroupManager*)
5304 this->network->groupManagers->findDefinition(PROCESS_GROUP);
5305 }
5306 #endif
5307
5308
5309 //
5310 // Conditionally show the nodes' instance numbers in the vpe. If the setting
5311 // has changed then visit the standins and reshow the standin labels.
5312 //
5313 void DXApplication::showInstanceNumbers(boolean on_or_off)
5314 {
5315 if (on_or_off == this->resource.showInstanceNumbers) return ;
5316 this->resource.showInstanceNumbers = on_or_off;
5317 if (this->inDebugMode()) return ;
5318
5319
5320 //
5321 // Visit every vpe. Start with this->network, then continue with every
5322 // loaded macro. Any macro could have a vpe opened.
5323 //
5324 int i,netcnt = 1;
5325 netcnt+= this->macroList.getSize();
5326
5327 for (i=0; i<netcnt; i++) {
5328 Network *net = NUL(Network*);
5329 if (i == 0) net = this->network;
5330 else net = (Network*)this->macroList.getElement(i);
5331
5332 EditorWindow* ew = net->getEditor();
5333 if (!ew) continue;
5334 ew->beginNetworkChange();
5335
5336 Node* node;
5337 ListIterator it;
5338 FOR_EACH_NETWORK_NODE (net, node, it) {
5339 StandIn* si = node->getStandIn();
5340 if (!si) continue;
5341 si->notifyLabelChange();
5342 }
5343 ew->endNetworkChange();
5344 }
5345 }
5346
5347 void
5348 DXApplication::setServer(char *server)
5349 {
5350 if (this->serverInfo.server)
5351 delete this->serverInfo.server;
5352
5353 this->serverInfo.server = DuplicateString(server);
5354 fprintf(stderr, "exec server set to %s\n", server);
5355 }
5356
5357 void DXApplication::getRecentNets(List& result)
5358 {
5359 theResourceManager->getValue(RECENT_NETS, result);
5360 }
5361
5362 // The call to GetFullFilePath is supposed to take
5363 // care of calling Dos2Unix(). These functions could
5364 // also be written with ifdefs for the pc platform,
5365 // but this way I have better assurance that they're
5366 // working right since there aren't platform dependencies.
5367 void DXApplication::appendReferencedFile(const char* file)
5368 {
5369 //
5370 // Don't include files that go in /tmp. These are files
5371 // that are created as a result of Cut,Copy,Paste and
5372 // Drag-n-Drop and shouldn't be recorded here.
5373 //
5374 const char *tmpdir = theDXApplication->getTmpDirectory();
5375 int tmpdirlen = STRLEN(tmpdir);
5376 if (strncmp (file, tmpdir, tmpdirlen)==0) {
5377 return ;
5378 }
5379
5380 char* cp = GetFullFilePath(file);
5381 theResourceManager->addValue(RECENT_NETS, cp);
5382 delete cp;
5383 }
5384 void DXApplication::removeReferencedFile(const char* file)
5385 {
5386 char* cp = GetFullFilePath(file);
5387 theResourceManager->removeValue(RECENT_NETS, cp);
5388 delete cp;
5389 }
5390