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