X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fmolecule.c;h=85c6317396e6f081bb3d5a5440d941c20b4f98be;hp=39ad1969e7e8d05693c7b0c63e4c63e094199d4b;hb=e4fa2ac140f7bc56571373a7b7eb585fa4500e38;hpb=96a411663168b0ba5432b407a83be55f3df0c802 diff --git a/hacks/glx/molecule.c b/hacks/glx/molecule.c index 39ad1969..85c63173 100644 --- a/hacks/glx/molecule.c +++ b/hacks/glx/molecule.c @@ -1,4 +1,4 @@ -/* molecule, Copyright (c) 2001 Jamie Zawinski +/* molecule, Copyright (c) 2001, 2004 Jamie Zawinski * Draws molecules, based on coordinates from PDB (Protein Data Base) files. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -18,6 +18,10 @@ http://www.sci.ouc.bc.ca/chem/molecule/molecule.html */ +#include +#include +#include +#include #include #define PROGCLASS "Molecule" @@ -115,6 +119,7 @@ typedef struct { static atom_data all_atom_data[] = { { "H", 1.17, 0, "White", "Grey70", { 0, }}, { "C", 1.75, 0, "Grey60", "White", { 0, }}, + { "CA", 1.80, 0, "Blue", "LightBlue", { 0, }}, { "N", 1.55, 0, "LightSteelBlue3", "SlateBlue1", { 0, }}, { "O", 1.40, 0, "Red", "LightPink", { 0, }}, { "P", 1.28, 0, "MediumPurple", "PaleVioletRed", { 0, }}, @@ -204,15 +209,15 @@ static XrmOptionDescRec opts[] = { }; static argtype vars[] = { - {(caddr_t *) &molecule_str, "molecule", "Molecule", DEF_MOLECULE,t_String}, - {(caddr_t *) &timeout, "timeout","Seconds",DEF_TIMEOUT,t_Int}, - {(caddr_t *) &do_spin, "spin", "Spin", DEF_SPIN, t_String}, - {(caddr_t *) &do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, - {(caddr_t *) &do_labels, "labels", "Labels", DEF_LABELS, t_Bool}, - {(caddr_t *) &do_titles, "titles", "Titles", DEF_TITLES, t_Bool}, - {(caddr_t *) &do_atoms, "atoms", "Atoms", DEF_ATOMS, t_Bool}, - {(caddr_t *) &do_bonds, "bonds", "Bonds", DEF_BONDS, t_Bool}, - {(caddr_t *) &do_bbox, "bbox", "BBox", DEF_BBOX, t_Bool}, + {&molecule_str, "molecule", "Molecule", DEF_MOLECULE,t_String}, + {&timeout, "timeout","Seconds",DEF_TIMEOUT,t_Int}, + {&do_spin, "spin", "Spin", DEF_SPIN, t_String}, + {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, + {&do_labels, "labels", "Labels", DEF_LABELS, t_Bool}, + {&do_titles, "titles", "Titles", DEF_TITLES, t_Bool}, + {&do_atoms, "atoms", "Atoms", DEF_ATOMS, t_Bool}, + {&do_bonds, "bonds", "Bonds", DEF_BONDS, t_Bool}, + {&do_bbox, "bbox", "BBox", DEF_BBOX, t_Bool}, }; ModeSpecOpt molecule_opts = {countof(opts), opts, countof(vars), vars, NULL}; @@ -305,7 +310,7 @@ get_atom_data (const char *atom_name) for (i = 0; i < countof(all_atom_data); i++) { d = &all_atom_data[i]; - if (!strcmp (n, all_atom_data[i].name)) + if (!strcasecmp (n, all_atom_data[i].name)) break; } @@ -844,6 +849,12 @@ parse_pdb_data (molecule *m, const char *data, const char *filename, int line) ss = name + strlen(name)-1; while (isspace(*ss) && ss > name) *ss-- = 0; + ss = name + 1; + while(*ss) + { + *ss = tolower(*ss); + ss++; + } sscanf (s + 32, " %f %f %f ", &x, &y, &z); /* fprintf (stderr, "%s: %s: %d: atom: %d \"%s\" %9.4f %9.4f %9.4f\n", @@ -1072,41 +1083,134 @@ load_molecules (ModeInfo *mi) { molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); + Bool verbose_p = False; + int i; if (!molecule_str || !*molecule_str || !strcmp(molecule_str, "(default)")) /* do the builtins */ { - int i; mc->nmolecules = countof(builtin_pdb_data); mc->molecules = (molecule *) calloc (sizeof (molecule), mc->nmolecules); for (i = 0; i < mc->nmolecules; i++) { char name[100]; sprintf (name, "", i); + if (verbose_p) fprintf (stderr, "%s: reading %s\n", progname, name); parse_pdb_data (&mc->molecules[i], builtin_pdb_data[i], name, 1); - generate_molecule_formula (&mc->molecules[i]); - insert_vertical_whitespace ((char *) mc->molecules[i].label); } } else /* Load a file */ { - int i = 0; - mc->nmolecules = 1; - mc->molecules = (molecule *) calloc (sizeof (molecule), mc->nmolecules); - parse_pdb_file (&mc->molecules[i], molecule_str); - generate_molecule_formula (&mc->molecules[i]); - insert_vertical_whitespace ((char *) mc->molecules[i].label); + /* The -molecule option can point to a .pdb file, or to + a directory of them. + */ + struct stat st; + int nfiles = 0; + int list_size = 0; + char **files = 0; + + if (!stat (molecule_str, &st) && + S_ISDIR (st.st_mode)) + { + char buf [255]; + DIR *pdb_dir; + struct dirent *dentry; + + pdb_dir = opendir (molecule_str); + if (! pdb_dir) + { + sprintf (buf, "%.100s: %.100s", progname, molecule_str); + perror (buf); + exit (1); + } + + if (verbose_p) + fprintf (stderr, "%s: directory %s\n", progname, molecule_str); + + nfiles = 0; + list_size = 100; + files = (char **) calloc (sizeof(*files), list_size); + + while ((dentry = readdir (pdb_dir))) + { + int L = strlen (dentry->d_name); + if (L > 4 && !strcasecmp (dentry->d_name + L - 4, ".pdb")) + { + char *fn; + if (nfiles >= list_size-1) + { + list_size = (list_size + 10) * 1.2; + files = (char **) + realloc (files, list_size * sizeof(*files)); + if (!files) + { + OOM: + fprintf (stderr, "%s: out of memory (%d files)\n", + progname, nfiles); + exit (1); + } + } + + fn = (char *) malloc (strlen (molecule_str) + L + 10); + if (!fn) goto OOM; + strcpy (fn, molecule_str); + if (fn[strlen(fn)-1] != '/') strcat (fn, "/"); + strcat (fn, dentry->d_name); + files[nfiles++] = fn; + if (verbose_p) + fprintf (stderr, "%s: file %s\n", progname, fn); + } + } + closedir (pdb_dir); + + if (nfiles == 0) + { + fprintf (stderr, "%s: no .pdb files in directory %s\n", + progname, molecule_str); + exit (1); + } + } + else + { + files = (char **) malloc (sizeof (*files)); + nfiles = 1; + files[0] = strdup (molecule_str); + if (verbose_p) + fprintf (stderr, "%s: file %s\n", progname, molecule_str); + } - if ((wire || !do_atoms) && - !do_labels && - mc->molecules[i].nbonds == 0) + mc->nmolecules = nfiles; + mc->molecules = (molecule *) calloc (sizeof (molecule), mc->nmolecules); + for (i = 0; i < mc->nmolecules; i++) { - /* If we're not drawing atoms (e.g., wireframe mode), and - there is no bond info, then make sure labels are turned on, - or we'll be looking at a black screen... */ - fprintf (stderr, "%s: no bonds: turning -label on.\n", progname); - do_labels = 1; + if (verbose_p) + fprintf (stderr, "%s: reading %s\n", progname, files[i]); + parse_pdb_file (&mc->molecules[i], files[i]); + + if ((wire || !do_atoms) && + !do_labels && + mc->molecules[i].nbonds == 0) + { + /* If we're not drawing atoms (e.g., wireframe mode), and + there is no bond info, then make sure labels are turned on, + or we'll be looking at a black screen... */ + fprintf (stderr, "%s: %s: no bonds: turning -label on.\n", + progname, files[i]); + do_labels = 1; + } + + free (files[i]); + files[i] = 0; } + + free (files); + files = 0; + } + + for (i = 0; i < mc->nmolecules; i++) + { + generate_molecule_formula (&mc->molecules[i]); + insert_vertical_whitespace ((char *) mc->molecules[i].label); } }