/*ScianMain.c Eric Pepke Main routines for SciAn */ #include "Scian.h" #include "ScianTypes.h" #include "ScianArrays.h" #include "ScianLists.h" #include "ScianEvents.h" #include "ScianWindows.h" #include "ScianObjWindows.h" #include "ScianObjFunctions.h" #include "ScianGlobalFunctions.h" #include "ScianWindowFunctions.h" #include "ScianCurrentFunctions.h" #include "ScianVisWindows.h" #include "ScianDialogs.h" #include "ScianDatasets.h" #include "ScianColors.h" #include "ScianControls.h" #include "ScianDrawings.h" #include "ScianIcons.h" #include "ScianRecorders.h" #include "ScianFiles.h" #include "ScianFileSystem.h" #include "ScianGarbageMan.h" #include "ScianScripts.h" #include "ScianTimers.h" #include "ScianErrors.h" #include "ScianIDs.h" #include "ScianSpaces.h" #include "ScianPreferences.h" #include "ScianSciences.h" #include "ScianSnap.h" #include "ScianAxes.h" #include "ScianTextFiles.h" #include "ScianMenus.h" Bool stuffInited = false; Bool runningRemote = false; real missingData = 1.1E37; real plusInf = 1E37; real minusInf = -1E37; Bool scriptSelectP = false; Bool abortScriptP = true; Bool graphicsInited = false; extern Bool runningScript; /*True iff running script*/ struct { char *name; /*Name of window system*/ char *longName; /*Long name of graphics system*/ } windowSystemNames[] = { #ifdef WINDOWS4D {"gl", "SGI Graphics Library windows"}, #else {NULL, NULL}, #endif #ifdef WINDOWSCAVESIM {"cavesim", "CAVE virtual environment simulator"}, #else {NULL, NULL}, #endif #ifdef WINDOWSCAVE {"cave", "CAVE virtual environment"} #else {NULL, NULL}, #endif }; #ifdef GRAPHICS #ifdef CURSORS4D /*Cursors*/ Cursor watchCursor = { 0x07e0, 0x07e0, 0x07e0, 0x07e0, 0x0810, 0x1008, 0x1008, 0x11cc, 0x110c, 0x1108, 0x1108, 0x0810, 0x07e0, 0x07e0, 0x07e0, 0x07e0 }; Cursor questionCursor = { 0x0300, 0x0300, 0x0000, 0x0300, 0x0300, 0x0300, 0x0380, 0x0180, 0x0070, 0x0038, 0x0018, 0x1818, 0x1818, 0x1c38, 0x0ff0, 0x07e0 }; Cursor iconCursor = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; #endif #endif #ifdef PARANOID /*Define tracking memory allocations*/ #define NMEMCHUNKS 257 static long memStats[NMEMCHUNKS][2]; #ifdef CACHEMEMORY static void *memCache[NMEMCHUNKS]; #endif void *Alloc(long n) /*Allocates n bytes*/ { register void *p; if (n < NMEMCHUNKS) { ++memStats[n][0]; #ifdef CACHEMEMORY if (memCache[n]) { p = memCache[n]; memCache[n] = *((void **) p); *((long *) p) = n; return (void *) (((long *) p) + 1); } #endif } else { ++memStats[NMEMCHUNKS - 1][0]; } p = malloc(n + sizeof(long)); *((long *) p) = n; return (void *) (((long *) p) + 1); } void *Realloc(void *p, long n) /*Reallocates p to be n bytes*/ { p = (void *) (((long *) p) - 1); if (*((long *) p) < NMEMCHUNKS) { ++memStats[*((long *) p)][1]; } else { ++memStats[NMEMCHUNKS - 1][1]; } if (n < NMEMCHUNKS) { ++memStats[n][0]; } else { ++memStats[NMEMCHUNKS - 1][0]; } p = realloc(p, n + sizeof(long)); *((long *) p) = n; return (void *) (((long *) p) + 1); } void Free(void *p) /*Frees p*/ { register int n; p = (void *) (((long *) p) - 1); n = *((long *) p); if (n < NMEMCHUNKS) { ++memStats[n][1]; #ifdef CACHEMEMORY *((void **) p) = memCache[n]; memCache[n] = p; #else free(p); #endif } else { ++memStats[NMEMCHUNKS - 1][1]; free(p); } } void PrintMemStats(void) /*Prints memory stats*/ { #ifdef MALLOCH int k; struct mallinfo mi; printf("Size Allocations Deallocations Current\n"); for (k = 0; k < NMEMCHUNKS; ++k) { printf("%4d%c %11d %11d %11d\n", k, k == NMEMCHUNKS - 1 ? '+' : ' ', memStats[k][0], memStats[k][1], memStats[k][0] - memStats[k][1]); } mi = mallinfo(); fprintf(stderr,"arena=%d, ordblks=%d, smblks=%d, hblkhd=%d, hblks=%d\n", mi.arena, mi.ordblks, mi.smblks, mi.hblkhd, mi.hblks); fprintf(stderr,"usmblks=%d, fsmblks=%d, uordblks=%d, fordblks=%d, keepcost=%d\n", mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks, mi.keepcost); #endif } #endif #ifdef HAVE_PROTOTYPES void InitGraphics(void) #else void InitGraphics() #endif /*Initializes graphics*/ { if (!graphicsInited) { graphicsInited = true; switch (windowSystem) { case WS_GLWINDOWS: /*4D window system automatically initializes upon main window*/ #ifdef WINDOWS4D MainWindow(); #endif break; case WS_CAVESIM: /*Initialize cave system and initstuff*/ #ifdef WINDOWSCAVESIM { char *argv[1]; argv[0] = "scian"; cave_simulator_init(1, argv); InitStuff(); } #endif break; case WS_CAVE: /*Initialize cave system and initstuff*/ #ifdef WINDOWSCAVE { char *argv[1]; argv[0] = "scian"; cave_init(1, argv); InitStuff(); } #endif break; } } } /*Read states*/ #define RS_FILE 0 /*Read names as file names*/ #define RS_FORMAT 1 /*Read names as formats*/ #define RS_LOG 2 /*Read names as log files*/ #define RS_SCRIPT 3 /*Read names as script files*/ #define RS_DIRECTORY 4 /*Read names as directory files*/ #define RS_WINDOWSYSTEM 5 /*Read window system*/ #ifdef HAVE_PROTOTYPES void ParseArgs(int argc, char *argv[]) #else void ParseArgs(argc, argv) int argc; char *argv[]; #endif /*Parses the arguments in argc and argv*/ { int k, gs; char format[256]; /*Current file format*/ ObjPtr corral; /*Corral in the datasets window*/ char *a; Bool scriptSet; int readState = RS_FILE; scriptSet = false; strcpy(format, ""); for (k = 1; k < argc; ++k) { /*Go through arguments, parsing them*/ if (readState != RS_FILE) { /*Read this argument as a whatever*/ switch(readState) { case RS_FORMAT: strncpy(format, argv[k], 255); format[255] = 0; break; case RS_SCRIPT: if (scriptSet) { fprintf(stderr, "%s: Only one script can be given on the command line.\n", argv[0]); exit(-1); } scriptSet = true; if (!graphicsInited) { InitGraphics(); } BeginScript(argv[k]); break; case RS_LOG: if (!graphicsInited) { InitGraphics(); } if (strcmp(argv[k], "-") == 0) { OpenLogFile((char *) 0); } else { OpenLogFile(argv[k]); } break; case RS_DIRECTORY: if (!graphicsInited) { InitGraphics(); } { char t[MAXPATHLEN + 1]; if (chdir(argv[k]) == 0) /* check if valid directory */ { getwd(t); /* get expanded name back */ GetFileWindow(t); chdir(dirSave); /* return to original directory */ } else { fprintf(stderr, "%s: '%s' is an invalid directory.\n", argv[0], argv[k]); exit(-1); } } break; case RS_WINDOWSYSTEM: /*Read in a graphics system*/ for (gs = 0; gs < N_WINDOW_SYSTEMS; ++gs) { if (windowSystemNames[gs] . name && 0 == strcmp2(argv[k], windowSystemNames[gs] . name)) { windowSystem = gs; break; } } if (gs >= N_WINDOW_SYSTEMS) { fprintf(stderr, "%s: Undefined window system '%s'\n", argv[0], argv[k]); fprintf(stderr, "Valid options are:\n"); for (gs = 0; gs < N_WINDOW_SYSTEMS; ++gs) { if (windowSystemNames[gs] . name) { fprintf(stderr, "%-12s%s\n", windowSystemNames[gs] . name, windowSystemNames[gs] . longName); } } exit(-1); } break; } readState = RS_FILE; } else if (argv[k][0] == '-') { /*It's a switch*/ readState = RS_FILE; for (a = &(argv[k][1]); *a; ++a) { switch (*a) { case 'f': /*New file format*/ readState = RS_FORMAT; break; case '1': /*One observer, clock, whatever*/ ++a; switch (*a) { case 'c': case 'C': oneClock = true; break; case 'o': case 'O': oneObserver = true; break; case 'l': case 'L': oneLights = true; break; case 'r': case 'R': oneRenderer = true; break; case 'p': case 'P': onePalette = true; break; default: fprintf(stderr, "%s: Unrecognized object type for -1 flag\n", argv[0]); exit(-1); } break; case 's': /*Script to run*/ readState = RS_SCRIPT; break; case 'S': /*Select in scripts*/ scriptSelectP = true; break; case 'C': /*Continue in scripts*/ abortScriptP = false; break; case 'l': /*Open log file*/ readState = RS_LOG; break; case 'v': /*Enable recording*/ #ifdef GRAPHICS #ifdef IRIS blankscreen(FALSE); blanktime(0); #endif #endif recordEnabled = true; break; case 'd': /*Demo mode*/ if (!graphicsInited) { InitGraphics(); } SetDemoFonts(); break; case 'o': /*Open a directory*/ readState = RS_DIRECTORY; break; case 'w': /*Select a graphics system*/ if (graphicsInited) { fprintf(stderr, "%s: Windo system selector -w must appear before graphics initialization.\n", argv[0]); exit(-1); } else { readState = RS_WINDOWSYSTEM; } break; default: /*Undefined switch*/ fprintf(stderr, "%s: Switch %s is undefined.\n", argv[0], argv[k]); exit(-1); } } } else if (argv[k][0] == '+') { if (!graphicsInited) { InitGraphics(); } if (0 == strcmp(argv[k], "+mdoc")) { EmitMenuDoc(); } } else { WinInfoPtr datasetsWindow; /*It must be a file name*/ if (!graphicsInited) { InitGraphics(); } datasetsWindow = DatasetsWindow(); SelWindow(datasetsWindow); IdleAllWindows(); LongOperation(); ReadFile(argv[k], format); } } if (windowSystem < -1) { for (gs = 0; gs < N_WINDOW_SYSTEMS; ++gs) { if (windowSystemNames[gs] . name) { windowSystem = gs; break; } } if (gs >= N_WINDOW_SYSTEMS) { fprintf(stderr, "%s: No window systems defined\n", argv[0]); exit(-1); } } if (!graphicsInited) { InitGraphics(); } } Bool handlingSignals = true; #ifdef SIGNALS #ifdef HAVE_PROTOTYPES void SignalHandler(int sig, int code, struct sigcontext *context) #else void SignalHandler(sig, code, context) int sig; int code; struct sigcontext *context; #endif /*Handles signals*/ { if (0 == handlingSignals) { /*Just expire*/ return; } switch(sig) { #ifdef SIGALRM case SIGALRM: /*Get some new events*/ NewEvents(); { struct itimerval value, ovalue; value . it_interval . tv_sec = 0; value . it_interval . tv_usec = 0; value . it_value . tv_sec = 0; value . it_value . tv_usec = 100000L; setitimer(ITIMER_REAL, &value, &ovalue); } signal(SIGALRM, SignalHandler); break; #endif #ifdef SIGDANGER case SIGDANGER: signal(SIGDANGER, SignalHandler); break; #endif } } #endif TestTextFile() { TextFilePtr file; file = OpenTextFile("testo.txt", TF_READ + TF_CONTINUATION + TF_HASHCOMMENTS); if (file) { char *curLine; while (curLine = GetNextLine(file)) { char *chickenWhere; chickenWhere = strstr(curLine, "chicken"); if (chickenWhere) { CurLineError(file, "'chicken' may not appear", chickenWhere, chickenWhere + strlen("chicken")); } } CloseTextFile(file); } else { perror("testo.txt"); } } main(argc, argv) int argc; char *argv[]; { int k; #ifdef MALLOCH #ifdef M_MXFAST mallopt(M_MXFAST, 1024); #endif #endif #ifdef PARANOID for (k = 0; k < NMEMCHUNKS; ++k) { memStats[k][0] = 0; memStats[k][1] = 0; #ifdef CACHEMEMORY memCache[k] = NULL; #endif } #endif #ifdef GRAPHICS #ifdef IRIS foreground(); #endif #endif #ifdef SIGNALS /*Set up signals*/ #ifdef SIGDANGER signal(SIGDANGER, SignalHandler); #endif #endif #ifndef GETGDESCAFTER GetConfiguration(); #endif InitNames(); InitObjects(); InitTextFiles(); InitArrays(); InitLists(); InitControls(); InitDatabase(); InitSciences(); InitAxes(); InitIcons(); InitDatasets(); InitFilters(); InitFiles(); ParseArgs(argc, argv); InitEvents(); InitSnapshots(); MainLoop(); KillSnapshots(); KillEvents(); CloseAllLogFiles(); #ifdef GRAPHICS #ifdef IRIS if (recordEnabled) { blanktime(100000); } #endif #endif handlingSignals = false; DisposeAllWindows(); switch (windowSystem) { case WS_CAVESIM: /*Exit cave system*/ #ifdef WINDOWSCAVESIM { char *argv[1]; argv[1] = "scian"; cave_simulator_exit(1, argv); } #endif break; case WS_CAVE: /*Exit cave system*/ #ifdef WINDOWSCAVE { char *argv[1]; argv[1] = "scian"; cave_exit(1, argv); } #endif break; } KillWindowFunctions(); KillRepobjFunctions(); KillGlobalFunctions(); KillRecorders(); KillPreferences(); KillColors(); KillDialogs(); KillObjFunctions(); KillCurrentFunctions(); KillMenus(); KillVisWindows(); KillObjWindows(); KillWindows(); KillPictures(); KillVisObjects(); KillTimers(); KillSpaces(); KillFilters(); KillDatasets(); KillGeometry(); KillAnimation(); KillDrawings(); KillIcons(); KillSockets(); KillDraw(); KillAxes(); KillSciences(); KillDatabase(); KillControls(); KillFiles(); KillLists(); KillArrays(); TrashDay(); KillTextFiles(); KillObjects(); KillNames(); exit(0); } #ifdef HAVE_PROTOTYPES static void DefineFunctionKeys(void) #else static void DefineFunctionKeys() #endif /*Defines a bunch of function keys*/ { #ifndef RELEASE DefineFunctionKey(FK_1, 0, GF_UNDO); DefineFunctionKey('p', F_OPTIONDOWN, GF_PALETTES); #endif DefineFunctionKey(FK_2, 0, CF_CUT); DefineFunctionKey(FK_3, 0, CF_COPY); DefineFunctionKey(FK_4, 0, CF_PASTE); DefineFunctionKey(FK_5, 0, OF_SHOW_CONTROLS); DefineFunctionKey(FK_6, 0, WF_HIDEPANEL); DefineFunctionKey(FK_7, 0, OF_PUSHTOBOTTOM); DefineFunctionKey(FK_8, 0, OF_BRINGTOTOP); DefineFunctionKey(FK_9, 0, OF_PICK_UP); #ifdef IRISNTSC DefineFunctionKey(FK_10, 0, GF_TOGGLENTSC); DefineFunctionKey(FK_11, 0, GF_TOGGLESTEREO); #endif DefineFunctionKey(FK_12, 0, GF_CONTEXTHELP); DefineFunctionKey(FK_PRINT_SCREEN, 0, WF_SAVEWINDOW); DefineFunctionKey(FK_PRINT_SCREEN, F_SHIFTDOWN, WF_SAVEFWINDOW); DefineFunctionKey(FK_PRINT_SCREEN, F_OPTIONDOWN, WF_SAVESCREEN); DefineFunctionKey('q', F_OPTIONDOWN, GF_QUIT); #ifndef RELEASE DefineFunctionKey('s', F_OPTIONDOWN, GF_NEWSEQUENCE); #endif } InitStuff() /*Initializes stuff. Has to be called after one window has been opened.*/ { if (!stuffInited) { #ifdef GRAPHICS #ifdef GL4D #ifdef IRIS defaultMonitor = getmonitor(); #else #ifdef HZ60 defaultMonitor = HZ60; #else defaultMonitor = 1; #endif #endif #endif #endif #ifdef GETGDESCAFTER GetConfiguration(); #endif InitDraw(); InitSockets(); InitColors(); InitDrawings(); InitAnimation(); InitSpaces(); InitTimers(); InitGeometry(); InitPictures(); InitFonts(); DefineIconFonts(); InitWindows(); InitObjWindows(); InitMenus(); InitCurrentFunctions(); InitObjFunctions(); InitVisWindows(); InitVisObjects(); InitDialogs(); InitPreferences(); InitRecorders(); InitGlobalFunctions(); InitRepobjFunctions(); InitWindowFunctions(); DefineFunctionKeys(); /*Set up cursors*/ #ifdef GRAPHICS #ifdef CURSORS4D #ifdef GL4D curstype(C16X1); #endif defcursor(WATCHCURSOR, watchCursor); curorigin(WATCHCURSOR, 8, 8); defcursor(QUESTIONCURSOR, questionCursor); curorigin(QUESTIONCURSOR, 8, 8); defcursor(ICONCURSOR, iconCursor); curorigin(ICONCURSOR, 8, 8); #endif #endif stuffInited = true; #ifdef SIGNALS #ifdef SIGALRM signal(SIGALRM, SignalHandler); { struct itimerval value, ovalue; value . it_interval . tv_sec = 0; value . it_interval . tv_usec = 0; value . it_value . tv_sec = 0; value . it_value . tv_usec = 100000L; setitimer(ITIMER_REAL, &value, &ovalue); } #endif #endif } }