File: garlic.c

package info (click to toggle)
garlic 1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 4,516 kB
  • sloc: ansic: 52,465; makefile: 2,254
file content (359 lines) | stat: -rw-r--r-- 11,765 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/*

    o-------------------------------------------------------------------o
    |                                                                   |
    | Copyright (C) 2000-2006 Damir Zucic                               |
    |                                                                   |
    | This program is free software; you can redistribute it and/or     |
    | modify it under the terms of the GNU General Public License       |
    | as published by the Free Software Foundation, version 2.          |
    |                                                                   |
    | This program is distributed in the hope that it will be useful,   |
    | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
    | GNU General Public License for more details.                      |
    |                                                                   |
    | You should have received a copy of the GNU General Public License |
    | along with this program; if not, write to the                     |
    | Free Software Foundation, Inc.,                                   |
    | 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.         |
    |                                                                   |
    o-------------------------------------------------------------------o

*/

/*=============================================================================

				garlic.c
		Molecular visualization and analyzing tool

General description:
	Garlic is molecular visualization program written for investigation
	of membrane proteins.  It may be used to visualize  other proteins,
	as well  as some  geometric  objects.  This version  is  capable to
	recognize the PDB format version 2.1;  check pdb_atom.c for details
	about this format.

Author:
	Damir Zucic (zucic@garlic.mefos.hr), University of Osijek, Croatia.

-------------------------------------------------------------------------------

Naming conventions:
	 (1) xxx_yyy	   Simple variable;  lowercase, underline separates
			   adjacent words.
	 (2) xxx_yyyI	   Index (array index usually).
	 (3) xxx_yyyN	   Number of array elements.
	 (4) xxx_yyyID	   Identifier (integer or long integer).
	 (5) xxx_yyyF	   Flag (usually integer, value 0 or 1).
	 (6) XxxYyyS	   New data type (typedef struct XxxYyyS).
	 (7) xxx_yyyS	   Structure (type: XxxYyyS).
	 (8) xxx_yyyP	   Pointer.
	 (9) xxx_yyySP	   Pointer to structure.
	(10) xxx_yyyA[]	   Array; no space before left bracket.
	(11) xxx_yyyAA[][] Two dimensional array.
	(12) xxx_yyySA[]   Array of structures.
	(13) xxx_yyyPA[]   Array of pointers.
	(14) XXXYYYZZZ	   Symbol (#define).
	(15) XxxYyy_ ()	   Function; the first character in each word is in
			   uppercase;  the last character is underline; one
			   space (exactly one!) used  to separate underline
			   and left parenthesis;  underline is  not used to
			   separate words.
	(16) xxx_yyyGC	 Graphics context (pointer to _XGC structure).

Programming style:
	When this project was started RAM and hard disk became quite cheap.
	Thus:
	(1) Whenever choosing between  brute force and intelligence,  chose
	    force: it is cheaper, simpler and more reliable. Of course, use
	    brain if there is no other choice.
	(2) Comment everything,  including trivial things,  so that hackers
	    find this program disgusting.
	(3) Never put two functions in  the same file,  even if it seems to
	    be reasonable.
	(4) Use verbose function and variable names.
	(5) Indentation is one tab (eight characters),  except in functions
	    which draw atoms and bonds (four characters).
	(6) Each brace should be placed in a separate line.
	(7) Avoid global scope data.
	(8) Use auxiliary structures  when some function requires  a lot of
	    input data.  Pass  pointer  to the structure to  this function,
	    instead of a large number of arguments.

Portability:
	Garlic should be  ANSI C and/or POSIX compliant.  All functions fit
	into one of these standards:
	(1) ANSI C programming language.
	(2) Xlib, X Window System (X11R6).

From /usr/games/fortunes/fortunes file (Linux Slackware 3.4):
"What garlic is to food, insanity is to art."

-------------------------------------------------------------------------------

Purpose of this file:
        The  main function is in this file.  The real job is done by called
	functions.

Return value / exit status:
         (1)    EXIT_SUCCESS on success.
         (2)    EXIT_FAILURE on failure.
         (3)    EXIT_SUCCESS if help, version info or registr. is required.

========includes:============================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======defines:=============================================================*/

/* See defines.h for all other symbols! */

/*======function prototypes:=================================================*/

void		PrintUsage_ (void);
void		PrintHelp_ (void);
void		PrintVersion_ (void);
int		Register_ (void);
void		ErrorMessage_ (char *, char *, char *,
			       char *, char *, char *, char *);
void		WarningMessage_ (char *, char *, char *,
				 char *, char *, char *, char *);
GUIS		*AllocateGUIS_ (void);
ConfigS		*AllocateConfigS_ (void);
MolComplexS	*AllocateMolComplexSA_ (size_t);
void		FreeMemory_ (GUIS *, MolComplexS *, int,
			     NearestAtomS *, size_t *);
int		ReadConfig_ (ConfigS *);
int		ExtractArgs_ (ConfigS *, GUIS *, char *, int, char **);
void		PrintCursorNames_ (void);
int		DisplayInit_ (GUIS *);
int		DisplayColorCapabilities_ (GUIS *);
int		ParseOptions_ (GUIS *, ConfigS *);
int		CreateWindows_ (GUIS *, ConfigS *, int, char **);
int		CalculateParameters_ (ConfigS *, GUIS *);
void		PrintConfig_ (ConfigS *, GUIS *);
int		LoadComplex_ (int *, MolComplexS *, int *, int *,
			      char *, ConfigS *, GUIS *);
NearestAtomS	*AllocateNearest_ (size_t *, GUIS *);
void		InitNearest_ (NearestAtomS *, size_t);
int		ColorSchemes_ (MolComplexS *, int, ConfigS *,
			       GUIS *, char *, int);
int		IdentifyButton_ (XButtonEvent *, GUIS *);
int		EventLoop_ (MolComplexS *, int *, int *,
			    NearestAtomS **, size_t *, ConfigS *, GUIS *);

/*======main:================================================================*/

int main (int argc, char *argv[])
{
int			mainI = 0;		/* Positive on success */
int			n;			/* Auxiliary integer */
static GUIS		*guiSP;			/* See typedefs.h */
static ConfigS		*configSP;		/* Read from .garlicrc */
static char		mol_file_nameA[STRINGSIZE];       /* Input file name */
static MolComplexS	*mol_complexSP;		/* Macromolecular data */
int			mol_complexesN = 0;	/* Number of  mol. complexes */
int			next_mol_complexID = 1;	/* Initial value should be 1 */
static NearestAtomS	*nearest_atomSP;	/* Replaces depth sorting */
size_t			pixelsN;		/* The number of pixels */
int			dummy_groupF;		/* Has no special meaning */

/* Write brief introduction - if requested - and exit: */
for (n = 0; n < argc; n++)
	{
	if ((strcmp (argv[n], "-h") == 0) ||
	    (strcmp (argv[n], "--help") == 0) ||
	    (strcmp (argv[n], "-help") == 0))
		{
		PrintHelp_ ();
		exit (EXIT_SUCCESS);
		}
	}

/* Print version information - if requested - and exit: */
for (n = 0; n < argc; n++)
	{
	if ((strcmp (argv[n], "-v") == 0) ||
	    (strcmp (argv[n], "--version") == 0))
		{
		PrintVersion_ ();
		exit (EXIT_SUCCESS);
		}
	}

/* Register user (send e-mail to the author) - if requested - and exit: */
for (n = 0; n < argc; n++)
	{
	if ((strcmp (argv[n], "-r") == 0) ||
	    (strcmp (argv[n], "--register") == 0))
		{
		Register_ ();
		fprintf (stdout, "A short e-mail message with registration");
		fprintf (stdout, " was send to the author.\n");
		exit (EXIT_SUCCESS);
		}
	}

/* Formal, single pass loop (many things happen here): */
do
	{
	/* Allocate memory for GUI data: */
	mainI--;
	guiSP = AllocateGUIS_ ();
	if (guiSP == NULL) break;

	/* Initialize the main window refreshing flag: */
	mainI--;
	guiSP->main_window_refreshF = 1;

	/* Initialize the main window drawing mode index: */
	mainI--;
	guiSP->main_window_modeI = 0;

	/* Allocate memory for configuration data: */
	mainI--;
	configSP = AllocateConfigS_ ();
	if (configSP == NULL) break;

	/* Allocate memory for macromolecular data: */
	mainI--;
	mol_complexSP = AllocateMolComplexSA_ (MAXCOMPLEXES);
	if (mol_complexSP == NULL) break;

	/* Read configuration from $HOME.garlicrc file: */
	mainI--;
	n = ReadConfig_ (configSP);

	/* Extract command line arguments: */
	mainI--;
	n = ExtractArgs_ (configSP, guiSP, mol_file_nameA, argc, argv);
	if (n < 0) break;

	/* Print cursor names and exit on request: */
	mainI--;
	if (configSP->print_cursor_namesF)
		{
		PrintCursorNames_ ();
		break;
		}

	/* Display related initializations: */
	mainI--;
	n = DisplayInit_ (guiSP);
	if (n < 0)
		{
		PrintUsage_ ();
		fprintf (stderr, "\nUnable to connect to  X  server,");
		fprintf (stderr, "  exiting ...\n");
		break;
		}

	/* Display color properties: */
	mainI--;
	n = DisplayColorCapabilities_ (guiSP); 
	if (n < 0) break;

	/* Parse options which require connection to X server: */
	mainI--;
	n = ParseOptions_ (guiSP, configSP);
	if (n < 0) break;

	/* Create windows: */
	mainI--;
	n = CreateWindows_ (guiSP, configSP, argc, argv);
	if (n < 0) break;

	/* Calculate the remaining parameters: */
	mainI--;
	n = CalculateParameters_ (configSP, guiSP);
	if (n < 0) break;

	/* Load macromolecular complex if input file name is specified: */
	mainI--;
	LoadComplex_ (&dummy_groupF,
		      mol_complexSP, &mol_complexesN, &next_mol_complexID,
		      mol_file_nameA, configSP, guiSP);

	/* Print configuration data, if requested: */
	mainI--;
	if (configSP->print_configF)
		{
		PrintConfig_ (configSP, guiSP);
		mainI *= -1;
		break;
		}

	/* Allocate the array of NeareastAtomS structures: */
	mainI--;
	nearest_atomSP = AllocateNearest_ (&pixelsN, guiSP);
	if (nearest_atomSP == NULL) break;

	/* Initialize the array of NearestAtomS structures: */
	InitNearest_ (nearest_atomSP, pixelsN);

	/* Prepare the simple color schemes: */
	mainI--;
	ColorSchemes_ (mol_complexSP, mol_complexesN, configSP,
		       guiSP, "dummy", 0);

	/* Initialize default colors for molecular surfaces: */
	mainI--;
	ColorSchemes_ (mol_complexSP, mol_complexesN, configSP,
		       guiSP, configSP->surface_outer_color_schemeA, 1);
	ColorSchemes_ (mol_complexSP, mol_complexesN, configSP,
		       guiSP, configSP->surface_inner_color_schemeA, 2);

	/* Define dummy buttons in control window: */
	mainI--;
	IdentifyButton_ ((XButtonEvent *) NULL, guiSP);

	/* Take and process events: */
	mainI--;
	n = EventLoop_ (mol_complexSP, &mol_complexesN, &next_mol_complexID,
			&nearest_atomSP, &pixelsN, configSP, guiSP);
	if (n < 0) break;

	/* If this point is reached, everything worked */
	/* fine; change the sign of mainI to positive: */
	mainI *= -1;
	} while (0);

/* Free storage used for pixmaps and other data: */
FreeMemory_ (guiSP, mol_complexSP, mol_complexesN, nearest_atomSP, &pixelsN);

/* Close connection to X server: */
if (guiSP->displaySP) XCloseDisplay (guiSP->displaySP);

/* Free the array of MolComplexS structures: */
if (mol_complexSP) free (mol_complexSP);

/* Close log file if used at all: */
if (configSP->log_fileF != 0) fclose (configSP->log_fileP);

/* Free ConfigS structure: */
if (configSP) free (configSP);

/* Free GUIS structure: */
if (guiSP) free (guiSP);

/* Return on failure: */
if (mainI < 0) return EXIT_FAILURE;

/* Return on success: */
return EXIT_SUCCESS;
}

/*===========================================================================*/