00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 
00026 #if defined(_MSC_VER)
00027 #include "win32vmdstart.h"
00028 #endif
00029 
00030 #if !defined(VMDNOMACBUNDLE) && defined(__APPLE__)
00031 #include "macosxvmdstart.h"
00032 #endif
00033 
00034 #include "vmd.h"
00035 #include "VMDApp.h"
00036 #include "utilities.h"  
00037 #include "config.h"     
00038 #include "WKFThreads.h"
00039 #include "Inform.h"
00040 #include "CommandQueue.h"
00041 #include "TextEvent.h"
00042 #include "MaterialList.h" 
00043 #include "SymbolTable.h"  
00044 
00045 #include "ProfileHooks.h" 
00046 
00047 #if defined(VMDTKCON)
00048 #include "vmdconsole.h"
00049 #endif
00050 
00051 #ifdef VMDFLTK
00052 #include <FL/Fl.H>
00053 #endif
00054 
00055 #ifdef VMDOPENGL        // OpenGL-specific files
00056 #ifdef VMDCAVE          // CAVE-specific files
00057 #include "cave_ogl.h"
00058 #include "CaveRoutines.h"
00059 #endif
00060 #ifdef VMDFREEVR        // FreeVR-specific files
00061 #include "freevr.h"
00062 #include "FreeVRRoutines.h"
00063 #endif
00064 #endif
00065 
00066 #ifdef VMDMPI
00067 #include "VMDMPI.h"
00068 #endif
00069 
00070 #ifdef VMDTCL
00071 #include <tcl.h>
00072 #include <signal.h>
00073 
00074 
00075 
00076 
00077 static Tcl_AsyncHandler tclhandler;
00078 
00079 extern "C" {
00080   typedef void (*sighandler_t)(int);
00081 
00082   void VMDTclSigHandler(int) {
00083     Tcl_AsyncMark(tclhandler);
00084   }
00085 
00086   int VMDTclAsyncProc(ClientData, Tcl_Interp *, int) {
00087     signal(SIGINT, (sighandler_t) VMDTclSigHandler);
00088     return TCL_ERROR;
00089   }
00090 
00091 }
00092 #endif // VMDTCL
00093 
00094 
00097 static const char *vmd_initialize_tcl(const char *argv0) {
00098 #ifdef VMDTCL
00099 
00100 #if defined(_MSC_VER)
00101   static char buffer[MAX_PATH +1];
00102   char *p;
00103 
00104   
00105   GetModuleFileName(NULL, buffer, sizeof(buffer));
00106 
00107   
00108   for (p = buffer; *p != '\0'; p++) {
00109     if (*p == '\\') {
00110       *p = '/';
00111     }
00112   }
00113 
00114   Tcl_FindExecutable(buffer); 
00115   return buffer;
00116 #else
00117   if (argv0) {
00118     Tcl_FindExecutable(argv0);
00119   }
00120   return argv0;
00121 #endif
00122 
00123 #else  // no Tcl
00124   return "";
00125 #endif
00126 
00127 }
00128 
00131 static void vmd_finalize_tcl() {
00132 #ifdef VMDTCL
00133   Tcl_Finalize();
00134 #endif
00135 }
00136 
00137 
00138 extern "C" {
00139 
00140 
00141 void * (*vmd_alloc)(size_t);
00142 void (*vmd_dealloc)(void *);
00143 void * (*vmd_realloc)(void *, size_t);
00144 
00145 
00146 
00147 void * vmd_resize_alloc(void *ptr, size_t oldsize, size_t newsize) {
00148   void *newptr=NULL;
00149 
00150   if (ptr == NULL) { 
00151     newptr = vmd_alloc(newsize);
00152     return newptr; 
00153   }
00154 
00155   if (vmd_realloc != NULL) {
00156     newptr = vmd_realloc(ptr, newsize);
00157   }
00158 
00159   if (newptr == NULL) {
00160     newptr = vmd_alloc(newsize);
00161     if (newptr != NULL) {
00162       memcpy(newptr, ptr, oldsize);
00163       vmd_dealloc(ptr);
00164     }
00165   }
00166 
00167   return newptr;
00168 }
00169 
00170 } 
00171 
00172 extern void VMDupdateFltk() {
00173 #ifdef VMDFLTK
00174 #if (defined(__APPLE__)) && defined(VMDTCL)
00175   
00176   Fl::flush();
00177 #else
00178   Fl::wait(0);
00179 #endif
00180 #endif
00181 }
00182 
00183 
00184 
00185 
00186 
00187   
00188 
00189 
00190 
00191 
00192 
00193 
00194 enum DisplayTypes { 
00195   DISPLAY_WIN,         
00196   DISPLAY_WINOGL,      
00197   DISPLAY_OGLPBUFFER,  
00198   DISPLAY_CAVE,        
00199   DISPLAY_TEXT,        
00200   DISPLAY_CAVEFORMS,   
00201   DISPLAY_FREEVR,      
00202   DISPLAY_FREEVRFORMS, 
00203   NUM_DISPLAY_TYPES
00204 };
00205 
00206 static const char *displayTypeNames[NUM_DISPLAY_TYPES] = {
00207   "WIN",  "OPENGL", "OPENGLPBUFFER", 
00208   "CAVE", "TEXT", "CAVEFORMS", "FREEVR", "FREEVRFORMS"
00209 };
00210 
00211 #define DISPLAY_USES_WINDOW(d) ((d) == DISPLAY_WIN || (d) == DISPLAY_WINOGL)
00212 #define DISPLAY_USES_CAVE(d) ((d) == DISPLAY_CAVE || (d) == DISPLAY_CAVEFORMS)
00213 #define DISPLAY_USES_FREEVR(d) ((d) == DISPLAY_FREEVR || (d) == DISPLAY_FREEVRFORMS)
00214 #define DISPLAY_USES_GUI(d) (DISPLAY_USES_WINDOW(d) || (d) == DISPLAY_CAVEFORMS || (d) == DISPLAY_FREEVRFORMS)
00215 
00216 
00217 enum TitleTypes { 
00218   TITLE_OFF, TITLE_ON, NUM_TITLE_TYPES 
00219 };
00220 
00221 static const char *titleTypeNames[NUM_TITLE_TYPES] = {
00222   "OFF", "ON"
00223 };
00224 
00225 
00226 static int   showTitle      = INIT_DEFTITLE;   
00227 static int   which_display  = INIT_DEFDISPLAY;     
00228 static float displayHeight  = INIT_DEFHEIGHT;
00229 static float displayDist    = INIT_DEFDIST;
00230 static int   displaySize[2] = { -1, -1 };
00231 static int   displayLoc[2]  = { -1, -1 };
00232 
00233 
00234 static const char *startupFileStr;
00235 static const char *beginCmdFile;
00236 
00237 
00238 
00239 static int cmdFileUsesPython;
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 static int loadAsMolecules = 0;
00248 static int startNewMolecule = 1;
00249 static ResizeArray<int> startNewMoleculeFlags;
00250 static ResizeArray<const char *>initFilenames;
00251 static ResizeArray<const char *>initFiletypes;
00252 
00253 
00254 static int eofexit  = 0;       
00255 static int just_print_help = 0;
00256 static ResizeArray<char *>customArgv;
00257 
00258 
00259 static void VMDtitle();
00260 static void VMDGetOptions(int, char **, int mpienabled);
00261 
00262 
00263 int VMDinitialize(int *argc, char ***argv, int mpienabled) {
00264   int i;
00265 
00266   PROFILE_PUSH_RANGE("VMDinitialize()", 1);
00267 
00268 #if defined(VMDMPI)
00269   if (mpienabled) {
00270     
00271     for (i=0; i<(*argc); i++) {
00272       if(!strupcmp((*argv)[i], "-vmddir")) {
00273         if((*argc) > (i + 1)) {
00274           setenv("VMDDIR", (*argv)[++i], 1);
00275         } else {
00276           msgErr << "-vmddir must specify a fully qualified path." << sendmsg;
00277         }
00278       }
00279     }
00280 
00281     vmd_mpi_init(argc, argv);  
00282   }
00283 #endif
00284 
00285 #if defined(_MSC_VER) && !defined(VMDSEPARATESTARTUP)
00286   win32vmdstart(); 
00287 #endif
00288 
00289 #if !defined(VMDNOMACBUNDLE) && defined(__APPLE__)
00290   macosxvmdstart(*argc, *argv); 
00291 #endif
00292 
00293   
00294   const char *argv0 = vmd_initialize_tcl((*argv)[0]);
00295 
00296 #ifdef VMDTCL
00297   
00298   tclhandler = Tcl_AsyncCreate(VMDTclAsyncProc, (ClientData)NULL); 
00299   signal(SIGINT, (sighandler_t) VMDTclSigHandler);  
00300 #endif
00301 
00302   
00303   VMDtitle();
00304 
00305   
00306   
00307   
00308   customArgv.append((char *)argv0);
00309   VMDGetOptions(*argc, *argv, mpienabled); 
00310 
00311 #if (!defined(__APPLE__) && !defined(_MSC_VER)) && (defined(VMDOPENGL) || defined(VMDFLTK))
00312   
00313   
00314   
00315   if ((which_display == DISPLAY_WIN) && (getenv("DISPLAY") == NULL)) {
00316     which_display = DISPLAY_TEXT;
00317   }
00318 #endif
00319 
00320 #if defined(VMDTKCON)
00321   vmdcon_init();
00322   msgInfo << "Using VMD Console redirection interface." << sendmsg;
00323   
00324   
00325   
00326   if ((which_display == DISPLAY_TEXT) || (which_display == DISPLAY_OGLPBUFFER) 
00327        || just_print_help) {
00328     vmdcon_use_text(NULL);
00329     vmdcon_purge();
00330   } else {
00331     vmdcon_use_widget(NULL);
00332   }
00333 #endif
00334 
00335 #ifdef VMDFLTK
00336   
00337   if ((which_display != DISPLAY_TEXT) && (which_display != DISPLAY_OGLPBUFFER)) {
00338     
00339     
00340     if (!Fl::visual(FL_DOUBLE | FL_RGB8)) {
00341       if (!Fl::visual(FL_RGB8)) {
00342         Fl::visual(FL_RGB); 
00343       }
00344     }
00345 
00346     
00347     
00348     Fl::visible_focus(0);
00349 
00350     
00351     
00352     Fl::dnd_text_ops(0);
00353   }
00354 #endif
00355 
00356   
00357   if (just_print_help) {
00358     vmd_sleep(10);  
00359                     
00360 
00361     PROFILE_POP_RANGE();
00362     return 0;
00363   }
00364 
00365   
00366   vmd_alloc   = malloc;  
00367   vmd_dealloc = free;    
00368   vmd_realloc = realloc; 
00369 
00370   
00371   if (DISPLAY_USES_CAVE(which_display)) {
00372 #ifdef VMDCAVE
00373     
00374     int megs = 2048;
00375     if (getenv("VMDCAVEMEM") != NULL) {
00376       megs = atoi(getenv("VMDCAVEMEM"));
00377     } 
00378     msgInfo << "Attempting to get " << megs << 
00379             "MB of CAVE Shared Memory" << sendmsg;
00380     grab_CAVE_memory(megs);
00381 
00382     CAVEConfigure(argc, *argv, NULL); 
00383 
00384     
00385     vmd_alloc = malloc_from_CAVE_memory;
00386     vmd_dealloc = free_to_CAVE_memory;
00387     vmd_realloc = NULL; 
00388 #else
00389     msgErr << "Not compiled with the CAVE options set." << sendmsg;
00390     which_display = DISPLAY_WIN;    
00391 #endif
00392   }
00393 
00394   
00395   if (DISPLAY_USES_FREEVR(which_display)) {
00396 #ifdef VMDFREEVR
00397     int megs = 2048;
00398     if (getenv("VMDFREEVRMEM") != NULL) {
00399       megs = atoi(getenv("VMDFREEVRMEM"));
00400     } 
00401     msgInfo << "Attempting to get " << megs << 
00402             "MB of FreeVR Shared Memory" << sendmsg;
00403     grab_FreeVR_memory(megs); 
00404                               
00405     vrConfigure(NULL, NULL, NULL); 
00406 
00407     
00408     vmd_alloc = malloc_from_FreeVR_memory;
00409     vmd_dealloc = free_to_FreeVR_memory;
00410     vmd_realloc = NULL; 
00411 #else
00412     msgErr << "Not compiled with the FREEVR options set." << sendmsg;
00413     which_display = DISPLAY_WIN;    
00414 #endif
00415   }
00416 
00417   
00418   *argc = customArgv.num();
00419   for (i=0; i<customArgv.num(); i++) {
00420     (*argv)[i] = customArgv[i];
00421   }
00422 
00423   PROFILE_POP_RANGE();
00424 
00425   return 1; 
00426 }
00427 
00428 const char *VMDgetDisplayTypeName() {
00429   return displayTypeNames[which_display];
00430 }
00431 
00432 void VMDgetDisplayFrame(int *loc, int *size) {
00433   for (int i=0; i<2; i++) {
00434     loc[i] = displayLoc[i];
00435     size[i] = displaySize[i];
00436   }
00437 }
00438 
00439 void VMDshutdown(int mpienabled) {
00440   vmd_finalize_tcl();  
00441 
00442 #ifdef VMDCAVE
00443   if (DISPLAY_USES_CAVE(which_display)) {  
00444     CAVEExit();
00445   }
00446 #endif
00447 #ifdef VMDFREEVR
00448   if (DISPLAY_USES_FREEVR(which_display)) {  
00449     vrExit();
00450   }
00451 #endif
00452 #ifdef VMDMPI
00453   if (mpienabled) {
00454     vmd_mpi_fini();
00455   }
00456 #endif
00457 }
00458 
00459 static void VMDtitle() {
00460   msgInfo << VERSION_MSG << "\n";
00461   msgInfo << "http://www.ks.uiuc.edu/Research/vmd/                         \n";
00462   msgInfo << "Email questions and bug reports to vmd@ks.uiuc.edu           \n";
00463   msgInfo << "Please include this reference in published work using VMD:   \n";
00464   msgInfo << "   Humphrey, W., Dalke, A. and Schulten, K., `VMD - Visual   \n";
00465   msgInfo << "   Molecular Dynamics', J. Molec. Graphics 1996, 14.1, 33-38.\n";
00466   msgInfo << "-------------------------------------------------------------\n";
00467   msgInfo << sendmsg;
00468 }
00469 
00471 
00472 
00473 
00474 
00475 
00476 
00477 static void VMDGetOptions(int argc, char **argv, int mpienabled) {
00478   char *envtxt;
00479 
00480   
00481   
00482   
00483   if((envtxt = getenv("VMDDISPLAYDEVICE"))) {
00484     for(int i=0; i < NUM_DISPLAY_TYPES; i++) {
00485       if(!strupcmp(envtxt, displayTypeNames[i])) {
00486         which_display = i;
00487         break;
00488       }
00489     }
00490   }
00491 
00492   
00493   
00494   
00495   if((envtxt = getenv("VMDTITLE"))) {
00496     for(int i=0; i < NUM_TITLE_TYPES; i++) {
00497       if(!strupcmp(envtxt, titleTypeNames[i])) {
00498         showTitle = i;
00499         break;
00500       }
00501     }
00502   }
00503 
00504   
00505   
00506   
00507   if((envtxt = getenv("VMDSCRHEIGHT")))
00508     displayHeight = (float) atof(envtxt);
00509 
00510   
00511   
00512   
00513   if((envtxt = getenv("VMDSCRDIST")))
00514     displayDist = (float) atof(envtxt); 
00515 
00516   
00517   
00518   
00519   if((envtxt = getenv("VMDSCRPOS"))) {
00520     char * dispStr = NULL;
00521     char * dispArgv[64];
00522     int dispArgc;
00523 
00524     if((dispStr = str_tokenize(envtxt, &dispArgc, dispArgv)) != NULL
00525                 && dispArgc == 2) {
00526       displayLoc[0] = atoi(dispArgv[0]);
00527       displayLoc[1] = atoi(dispArgv[1]);
00528     } else {
00529       msgErr << "Illegal VMDSCRPOS environment variable setting '" 
00530              << envtxt << "'." << sendmsg;
00531     }
00532     if(dispStr)  delete [] dispStr;
00533   }
00534 
00535   
00536   
00537   
00538   if((envtxt = getenv("VMDSCRSIZE"))) {
00539     char * dispStr = NULL;
00540     char * dispArgv[64];
00541     int dispArgc;
00542     if((dispStr = str_tokenize(envtxt, &dispArgc, dispArgv)) != NULL
00543                 && dispArgc == 2) {
00544       displaySize[0] = atoi(dispArgv[0]);
00545       displaySize[1] = atoi(dispArgv[1]);
00546  
00547       
00548       if (displaySize[0] < 100) 
00549         displaySize[0] = 100; 
00550       if (displaySize[1] < 100) 
00551         displaySize[1] = 100; 
00552 
00553     } else {
00554       msgErr << "Illegal VMDSCRSIZE environment variable setting '" 
00555              << envtxt << "'." << sendmsg;
00556     }
00557     if(dispStr)  delete [] dispStr;
00558   }
00559 
00560   
00561   
00562 
00563   
00564   int ev = 1;
00565   while(ev < argc) {
00566     if(!strupcmp(argv[ev], "-dist")) {
00567       if(argc > (ev + 1)) {
00568         displayDist = (float) atof(argv[++ev]);
00569       } else
00570         msgErr << "-dist must also specify a distance." << sendmsg;
00571 
00572     } else if(!strupcmp(argv[ev], "-e")) {
00573       if(argc > (ev + 1)) {
00574         beginCmdFile = argv[++ev];
00575       } else
00576         msgErr << "-e must also specify a filename." << sendmsg;
00577 
00578     } else if(!strupcmp(argv[ev], "-height")) {
00579       if(argc > (ev + 1)) {
00580         displayHeight = (float) atof(argv[++ev]);
00581       } else
00582         msgErr << "-height must also specify a distance." << sendmsg;
00583 
00584     } else if(!strupcmp(argv[ev], "-pos")) {
00585       if(argc > (ev + 2) && *(argv[ev+1]) != '-' && *(argv[ev+2]) != '-') {
00586         displayLoc[0] = atoi(argv[++ev]);
00587         displayLoc[1] = atoi(argv[++ev]);
00588       } else
00589         msgErr << "-pos must also specify an X Y pair." << sendmsg;
00590 
00591     } else if(!strupcmp(argv[ev], "-size")) {
00592       if(argc > (ev + 2) && *(argv[ev+1]) != '-' && *(argv[ev+2]) != '-') {
00593         displaySize[0] = atoi(argv[++ev]);
00594         displaySize[1] = atoi(argv[++ev]);
00595       } else
00596         msgErr << "-size must also specify an X Y pair." << sendmsg;
00597 
00598     } else if(!strupcmp(argv[ev], "-startup")) {
00599       
00600       if(argc > (ev + 1))
00601         startupFileStr = argv[++ev];
00602       else
00603         msgErr << "-startup must also have a new file name specified."
00604                << sendmsg;
00605 
00606     } else if(!strupcmp(argv[ev], "-nt")) {
00607       
00608       showTitle = TITLE_OFF;
00609 
00610     } else if (!strupcmp(argv[ev], "-dispdev")) {  
00611       ev++;
00612       if (argc > ev) {
00613         if (!strupcmp(argv[ev], "cave")) {  
00614           which_display = DISPLAY_CAVE;        
00615         } else if (!strupcmp(argv[ev], "win")) {       
00616           which_display = DISPLAY_WIN;         
00617         } else if (!strupcmp(argv[ev], "opengl")) {  
00618           which_display = DISPLAY_WINOGL;      
00619         } else if (!strupcmp(argv[ev], "openglpbuffer")) {  
00620           which_display = DISPLAY_OGLPBUFFER;  
00621         } else if (!strupcmp(argv[ev], "text")) {
00622           which_display = DISPLAY_TEXT;        
00623         } else if (!strupcmp(argv[ev], "caveforms")) {
00624           which_display = DISPLAY_CAVEFORMS;   
00625         } else if (!strupcmp(argv[ev], "freevr")) {
00626           which_display = DISPLAY_FREEVR;      
00627         } else if (!strupcmp(argv[ev], "freevrforms")) {
00628           which_display = DISPLAY_FREEVRFORMS; 
00629         } else if (!strupcmp(argv[ev], "none")) {      
00630           which_display = DISPLAY_TEXT;        
00631         } else {
00632           msgErr << "-dispdev options are 'win' 'opengl' (default), 'openglpbuffer', 'cave', 'caveforms', 'freevr', 'freevrforms', or 'text | none'" << sendmsg;
00633         }
00634       } else {
00635         msgErr << "-dispdev options are 'win' 'opengl' (default), 'openglpbuffer', 'cave', 'caveforms', 'freevr', 'freevrforms', or 'text | none'" << sendmsg;
00636       }
00637     } else if (!strupcmp(argv[ev], "-h") || !strupcmp(argv[ev], "--help")) {
00638       
00639       msgInfo << "Available command-line options:" << sendmsg;
00640       msgInfo << "\t-dispdev <win | cave | text | none> Specify display device";
00641       msgInfo << sendmsg;
00642       msgInfo << "\t-dist <d>           Distance from origin to screen";
00643       msgInfo << sendmsg;
00644       msgInfo << "\t-e <filename>       Execute commands in <filename>\n";
00645       msgInfo << "\t-python             Use Python for -e file and subsequent text input\n";
00646       msgInfo << "\t-eofexit            Exit when end-of-file occurs on input\n";
00647       msgInfo << "\t-h | --help         Display this command-line summary\n";
00648       msgInfo << "\t-height <h>         Height of display screen";
00649       msgInfo << sendmsg;
00650       msgInfo << "\t-pos <X> <Y>        Lower-left corner position of display";
00651       msgInfo << sendmsg;
00652       msgInfo << "\t-nt                 No title display at start" << sendmsg;
00653       msgInfo << "\t-size <X> <Y>       Size of display" << sendmsg;
00654       msgInfo << "\t-startup <filename> Specify startup script file" << sendmsg;
00655       msgInfo << "\t-m                  Load subsequent files as separate molecules\n";
00656       msgInfo << "\t-f                  Load subsequent files into the same molecule\n";
00657       msgInfo << "\t<filename>          Load file using best-guess file type\n";
00658       msgInfo << "\t-<type> <filename>  Load file using specified file type\n";
00659       msgInfo << "\t-args               Pass subsequent arguments to text interpreter\n";
00660       msgInfo << sendmsg;
00661       just_print_help = 1;
00662     } else if (!strupcmp(argv[ev], "-eofexit")) {  
00663       eofexit = 1;
00664     } else if (!strupcmp(argv[ev], "-node")) { 
00665       
00666       ev++; 
00667     } else if (!strupcmp(argv[ev], "-webhelper")) { 
00668       
00669       
00670       
00671       
00672     } else if (!strupcmp(argv[ev], "-python")) {
00673       cmdFileUsesPython = 1;
00674     } else if (!strupcmp(argv[ev], "-args")) {
00675       
00676       
00677       while (++ev < argc)
00678         customArgv.append(argv[ev]);
00679 
00680     } else if (!strupcmp(argv[ev], "-m")) {
00681       loadAsMolecules = 1;
00682       startNewMolecule = 1;
00683     } else if (!strupcmp(argv[ev], "-f")) {
00684       loadAsMolecules = 0;
00685       startNewMolecule = 1;
00686 #ifdef VMDMPI
00687     } else if (mpienabled && !strupcmp(argv[ev], "-vmddir")) {
00688       ev++; 
00689             
00690 #endif
00691     } else {
00692       
00693       
00694       const char *filename, *filetype;
00695       if (argv[ev][0] == '-') {
00696         
00697         if (argc > ev+1) {
00698           filetype = argv[ev]+1;
00699           filename = argv[ev+1];
00700           ev++;
00701         } else {
00702           msgErr << "filetype argument '" << argv[ev] << "' needs a filename."
00703             << sendmsg;
00704           ev++;  
00705           continue; 
00706         }
00707       } else {
00708         
00709         filename = argv[ev];
00710         filetype = NULL;
00711       }
00712       initFilenames.append(filename);
00713       initFiletypes.append(filetype);
00714       startNewMoleculeFlags.append(startNewMolecule);
00715       if (!loadAsMolecules) startNewMolecule = 0;
00716     }
00717     ev++;
00718   }
00719 
00720   
00721   
00722   
00723 }
00724 
00725 static int parseColorDefs(const char *path, VMDApp *app) {
00726   FILE *fd = fopen(path, "rt");
00727   char buf[256];
00728   memset(buf, 0, sizeof(buf));
00729 
00730   int success = TRUE;
00731 
00732   if (!fd) {
00733     msgErr << "Color definitions file '" << path << "' does not exist." << sendmsg;
00734     return FALSE;
00735   }
00736   while (fgets(buf, sizeof(buf), fd)) {
00737     if (buf[0] == '\0' || buf[0] == '#') continue;
00738     char first[128], second[128], third[128], fourth[128];
00739     memset(first, 0, sizeof(first));
00740     memset(second, 0, sizeof(second));
00741     memset(third, 0, sizeof(third));
00742     memset(fourth, 0, sizeof(fourth));
00743 
00744     
00745     int rc = sscanf(buf, "%s { %s %s %s", first, second, third, fourth);
00746     if (rc == 4) {
00747       char *right = strchr(third, '}');
00748       if (right) *right = '\0';
00749       strcat(second, " ");
00750       strcat(second, third);
00751       if (!app->color_add_item(first, second, fourth)) {
00752         msgErr << "Failed to add color definition: '" << buf << "'" << sendmsg;
00753         success = FALSE;
00754       }
00755     } else if (sscanf(buf, "%s %s %s", first, second, third) == 3) {
00756       if (!app->color_add_item(first, second, third)) {
00757         msgErr << "Failed to add color definition: '" << buf << "'" << sendmsg;
00758         success = FALSE;
00759       }
00760     }
00761   }
00762   fclose(fd);
00763   return success;
00764 }
00765 
00766 static int parseMaterialDefs(const char *path, VMDApp *app) {
00767   FILE *fd = fopen(path, "rt");
00768   char buf[256] = { 0 };
00769   int success = TRUE;
00770 
00771   if (!fd) {
00772     msgErr << "Material definitions file '" << path << "' does not exist." << sendmsg;
00773     return FALSE;
00774   }
00775   while (fgets(buf, sizeof(buf), fd)) {
00776     if (buf[0] == '\0' || buf[0] == '#') continue;
00777     char name[100] = { 0 };
00778     float vals[10] = { 0 };
00779     int readcount;
00780 
00781     memset(vals, 0, sizeof(vals));
00782     readcount=sscanf(buf, "%s %f %f %f %f %f %f %f %f %f", 
00783                      name, vals, vals+1, vals+2, vals+3, vals+4, 
00784                      vals+5, vals+6, vals+7, vals+8);
00785     if ((readcount < 7) || (readcount > 10))
00786       continue; 
00787 
00788     if (!app->material_add(name, NULL)) {
00789       msgErr << "Failed to add material '" << name << "'" << sendmsg;
00790       success = FALSE;
00791       continue;
00792     }
00793     app->material_change(name, MAT_AMBIENT, vals[0]);
00794     app->material_change(name, MAT_DIFFUSE, vals[1]);
00795     app->material_change(name, MAT_SPECULAR, vals[2]);
00796     app->material_change(name, MAT_SHININESS, vals[3]);
00797     app->material_change(name, MAT_MIRROR, vals[4]);
00798     app->material_change(name, MAT_OPACITY, vals[5]);
00799     app->material_change(name, MAT_OUTLINE, vals[6]);
00800     app->material_change(name, MAT_OUTLINEWIDTH, vals[7]);
00801     app->material_change(name, MAT_TRANSMODE, vals[8]);
00802   }
00803   fclose(fd);
00804   return success;
00805 }
00806 
00807 static int parseRestypes(const char *path, VMDApp *app) {
00808   FILE *fd = fopen(path, "rt");
00809   char buf[256];
00810   memset(buf, 0, sizeof(buf));
00811   int success = TRUE;
00812 
00813   if (!fd) {
00814     msgErr << "Residue types file '" << path << "' does not exist." << sendmsg;
00815     return FALSE;
00816   }
00817   while (fgets(buf, sizeof(buf), fd)) {
00818     if (buf[0] == '\0' || buf[0] == '#') continue;
00819     char name[64], type[64];
00820     memset(name, 0, sizeof(name));
00821     memset(type, 0, sizeof(type));
00822 
00823     if (sscanf(buf, "%s %s", name, type) != 2) continue;
00824 
00825     if (!app->color_set_restype(name, type)) {
00826       msgErr << "Failed to add residue type '" << buf << "'" << sendmsg;
00827       success = FALSE;
00828     }
00829   }
00830   fclose(fd);
00831   return success;
00832 }
00833 
00834 static int parseAtomselMacros(const char *path, VMDApp *app) {
00835   char buf[256];
00836   memset(buf, 0, sizeof(buf));
00837 
00838   FILE *fd = fopen(path, "rt");
00839   if (!fd) {
00840     msgErr << "Atomselection macro file '" << path << "' does not exist." << sendmsg;
00841     return FALSE;
00842   }
00843   int success= TRUE;
00844   while (fgets(buf, sizeof(buf), fd)) {
00845     if (buf[0] == '\0' || buf[0] == '#' || isspace(buf[0])) continue;
00846     char *macro = strchr(buf, ' ');
00847     if (!macro) continue;
00848     *macro = '\0';
00849     macro++;
00850 
00851     
00852     macro[strcspn(macro, "\r\n")] = 0;
00853 
00854     if (!app->atomSelParser->add_custom_singleword(buf, macro)) {
00855       msgErr << "Failed to add macro '" << buf << "'" << sendmsg;
00856       success = FALSE;
00857     }
00858   }
00859   fclose(fd);
00860   return success;
00861 }
00862 
00863 
00864 void VMDreadInit(VMDApp *app) {
00865   char path[4096];
00866   
00867   const char *vmddir = getenv("VMDDIR"); 
00868   if (vmddir == NULL) {
00869     msgErr << "VMDDIR undefined, startup failure likely." << sendmsg;
00870 #if defined(_MSC_VER)
00871     vmddir = "c:/program files/university of illinois/vmd";
00872 #else
00873     vmddir = "/usr/local/lib/vmd";
00874 #endif
00875   } 
00876   sprintf(path, "%s/scripts/vmd/colordefs.dat", vmddir);
00877   if (!parseColorDefs(path, app)) {
00878     msgErr << "Parsing color definitions failed." << sendmsg;
00879   }
00880   sprintf(path, "%s/scripts/vmd/materials.dat", vmddir);
00881   if (!parseMaterialDefs(path, app)) {
00882     msgErr << "Parsing material definitions failed." << sendmsg;
00883   }
00884   sprintf(path, "%s/scripts/vmd/restypes.dat", vmddir);
00885   if (!parseRestypes(path, app)) {
00886     msgErr << "Parsing residue types failed." << sendmsg;
00887   }
00888   sprintf(path, "%s/scripts/vmd/atomselmacros.dat", vmddir);
00889   if (!parseAtomselMacros(path, app)) {
00890     msgErr << "Parsing atomselection macros failed." << sendmsg;
00891   }
00892 }
00893 
00894 
00895 
00896 
00897 
00898 
00899 
00900 
00901 
00902 void VMDreadStartup(VMDApp *app) {
00903   char namebuf[512] = { 0 };
00904   char *envtxt;
00905   int found = FALSE;
00906   FILE * tfp;
00907   char *DataPath; 
00908 
00909   
00910   app->display_set_screen_height(displayHeight);
00911   app->display_set_screen_distance(displayDist);
00912   app->set_eofexit(eofexit);
00913   if (showTitle == TITLE_ON && (which_display != DISPLAY_TEXT) && 
00914       (which_display != DISPLAY_OGLPBUFFER)) {
00915     app->display_titlescreen();
00916   }
00917 
00918   if ((envtxt = getenv("VMDDIR")) != NULL)
00919     DataPath = stringdup(envtxt);
00920   else
00921     DataPath = stringdup(DEF_VMDENVVAR);
00922   stripslashes(DataPath); 
00923 
00924   
00925   if (startupFileStr) { 
00926     if ((tfp = fopen(startupFileStr, "rb")) != NULL) {
00927       found = TRUE;
00928       fclose(tfp);
00929       strcpy(namebuf, startupFileStr);
00930     }
00931   } else {      
00932     const char *def_startup = VMD_STARTUP;
00933     
00934     strcpy(namebuf, def_startup);
00935     if ((tfp = fopen(namebuf, "rb")) != NULL) {
00936       found = TRUE;
00937       fclose(tfp);
00938     } else {
00939       
00940       if ((envtxt = getenv("HOME")) != NULL)
00941         strcpy(namebuf, envtxt);
00942       else
00943         strcpy(namebuf, ".");
00944       strcat(namebuf, "/");
00945       strcat(namebuf, def_startup);
00946       if ((tfp = fopen(namebuf, "rb")) != NULL) {
00947         found = TRUE;
00948         fclose(tfp);
00949       } else {
00950         
00951         strcpy(namebuf, DataPath);
00952         strcat(namebuf, "/");
00953         strcat(namebuf, def_startup);
00954         if ((tfp = fopen(namebuf, "rb")) != NULL) {
00955           found = TRUE;
00956           fclose(tfp);
00957         }
00958       }
00959     }
00960   }
00961   delete [] DataPath; DataPath = NULL;
00962 
00963   
00964   
00965   
00966   
00967   PROFILE_PUSH_RANGE("VMDreadStartup(): process cmd args", 4);
00968 
00969   
00970   FileSpec spec;
00971   spec.waitfor = -1; 
00972   int molid = -1;    
00973 
00974   if (startNewMoleculeFlags.num() > 0) {
00975     msgInfo << "File loading in progress, please wait." << sendmsg;
00976   }
00977 
00978   for (int i=0; i<startNewMoleculeFlags.num(); i++) {
00979     const char *filename = initFilenames[i];
00980     const char *filetype = initFiletypes[i];
00981     if (!filetype) {
00982       filetype = app->guess_filetype(filename);
00983       if (!filetype) {
00984         
00985         msgErr << "Unable to determine file type for file '"
00986           << filename << "'.  Assuming pdb." << sendmsg;
00987         filetype = "pdb";
00988       }
00989     }
00990     if (startNewMoleculeFlags[i]) {
00991       molid = app->molecule_load(-1, filename, filetype, &spec);
00992     } else {
00993       molid = app->molecule_load(molid, filename, filetype, &spec);
00994     }
00995     if (molid < 0) {
00996       msgErr  << "Loading of startup molecule files aborted." << sendmsg;
00997       break;
00998     }
00999   }
01000 
01001   PROFILE_POP_RANGE();
01002   PROFILE_PUSH_RANGE("VMDreadStartup(): process " VMD_STARTUP, 3);
01003 
01004   
01005   if (found) {
01006     app->logfile_read(namebuf);
01007   }
01008 
01009   PROFILE_POP_RANGE();
01010   PROFILE_PUSH_RANGE("VMDreadStartup(): load plugins", 5);
01011 
01012   
01013   
01014   app->commandQueue->runcommand(
01015     new TclEvalEvent("vmd_load_extension_packages"));   
01016   
01017   PROFILE_POP_RANGE();
01018   PROFILE_PUSH_RANGE("VMDreadStartup(): start Python", 1);
01019 
01020   
01021   if (cmdFileUsesPython) {
01022     if (!app->textinterp_change("python")) {
01023       
01024       msgErr << "Skipping startup script because Python could not be started." 
01025              << sendmsg;
01026       return;
01027     }
01028   }
01029 
01030   PROFILE_POP_RANGE();
01031   PROFILE_PUSH_RANGE("VMDreadStartup(): process cmd scripts", 1);
01032 
01033   
01034   
01035   if (beginCmdFile) {
01036     app->logfile_read(beginCmdFile);
01037   } 
01038 
01039   PROFILE_POP_RANGE();
01040 }
01041