Tons of small fixes to documentation.
[alexxy/gromacs.git] / src / ngmx / ngmx.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <ctype.h>
40 #include <string.h>
41
42 #include "sysstuff.h"
43 #include "macros.h"
44 #include "smalloc.h"
45 #include "gmx_fatal.h"
46 #include "typedefs.h"
47 #include "string2.h"
48 #include "statutil.h"
49 #include "Xstuff.h"
50 #include "gromacs.bm"
51 #include "copyrite.h"
52 #include "confio.h"
53 #include "dialogs.h"
54 #include "writeps.h"
55 #include "molps.h"
56 #include "nmol.h"
57 #include "tpxio.h"
58
59 /* Forward declarations: I Don't want all that init shit here */
60 void init_gmx(t_x11 *x11,char *program,int nfile,t_filenm fnm[],
61               const output_env_t oenv);
62
63 int EventSignaller(t_manager *man);
64
65 static void dump_xw(char *dispname,Window w,char *fn)
66 {
67   char comm[256];
68   int  rc;
69
70   sprintf(comm,"xwd -id %d -display %s > %s",(int)w,dispname,fn);
71
72 #ifdef GMX_NO_SYSTEM
73   printf("Warning-- No calls to system(3) supported on this platform.");
74   printf("Warning-- Skipping execution of 'system(\"%s\")'.", buf);
75 #else
76   rc=system(comm);
77 #endif
78 }
79
80 static void dump_it(t_manager *man)
81 {
82   t_psdata ps;
83   
84   ps=ps_open("ngmx.ps",0,0,man->molw->wd.width,man->molw->wd.height);
85   ps_draw_mol(ps,man);
86   ps_close(ps);
87 }
88
89 static void done_gmx(t_x11 *x11,t_gmx *gmx)
90 {
91   done_logo(x11,gmx->logo);
92   done_pd(x11,gmx->pd);
93   done_man(x11,gmx->man);
94   done_dlgs(gmx);
95   x11->UnRegisterCallback(x11,gmx->wd->self);
96 }
97
98 static void move_gmx(t_x11 *x11,t_gmx *gmx,int width,int height,
99                      gmx_bool bSizePD)
100 {
101   int y0,wl,hl;
102 #ifdef DEBUG
103   fprintf(stderr,"Move gmx %dx%d\n",width,height);
104 #endif
105   y0=XTextHeight(x11->font);
106   /* Resize PD-Menu */
107   if (bSizePD)
108     XResizeWindow(x11->disp,gmx->pd->wd.self,width,y0);
109
110   XMoveWindow(x11->disp,gmx->man->wd.self,0,y0+1);
111   XResizeWindow(x11->disp,gmx->man->wd.self,width,height-y0-1);
112   
113   wl=gmx->logo->wd.width;
114   hl=gmx->logo->wd.height;
115   XMoveWindow(x11->disp,gmx->logo->wd.self,(width-wl)/2,(height-y0-hl)/2);
116 }
117
118 static gmx_bool HandleClient(t_x11 *x11,int ID,t_gmx *gmx)
119 {
120   t_pulldown *pd;
121   
122   pd=gmx->pd;
123   
124   switch(ID) {
125     /* File Menu */
126   case IDDUMPWIN:
127     write_gmx(x11,gmx,IDDODUMP);
128     break;
129   case IDDODUMP:
130     if (gmx->man->bAnimate) 
131       hide_but(x11,gmx->man->vbox);
132     dump_it(gmx->man);
133     if (gmx->man->bAnimate) 
134       show_but(x11,gmx->man->vbox);
135     break;
136   case IDCLOSE:
137   case IDIMPORT:
138   case IDEXPORT: 
139     ShowDlg(gmx->dlgs[edExport]);
140     break;
141   case IDDOEXPORT:
142     write_sto_conf(gmx->confout,*gmx->man->top.name,
143                    &(gmx->man->top.atoms),
144                    gmx->man->x,NULL,gmx->man->molw->ePBC,gmx->man->box);
145     break;
146   case IDQUIT:
147     show_mb(gmx,emQuit);
148     break;
149   case IDTERM:
150     done_gmx(x11,gmx);
151     return TRUE;
152     
153     /* Edit Menu */
154   case IDEDITTOP: 
155     edit_file("topol.gmx");
156     break;
157   case IDEDITCOORDS: 
158     edit_file("confin.gmx");
159     break;
160   case IDEDITPARAMS: 
161     edit_file("mdparin.gmx");
162     break;
163     
164     /* Display Menu */
165   case IDFILTER:
166     if (gmx->filter)
167       ShowDlg(gmx->dlgs[edFilter]);
168     break;
169   case IDDOFILTER:
170     do_filter(x11,gmx->man,gmx->filter);
171     break;
172   case IDANIMATE: 
173     check_pd_item(pd,IDANIMATE,toggle_animate(x11,gmx->man));
174     break;
175   case IDLABELSOFF:
176     no_labels(x11,gmx->man);
177     break;
178   case IDRESETVIEW: 
179     reset_view(gmx->man->view);
180     ExposeWin(x11->disp,gmx->man->molw->wd.self);
181     break;
182   case IDPHOTO:
183     show_mb(gmx,emNotImplemented);
184     break;
185   case IDBONDOPTS:
186     ShowDlg(gmx->dlgs[edBonds]);
187     break;
188   case IDTHIN:
189     set_bond_type(x11,gmx->man->molw,eBThin);
190     break;
191   case IDFAT:
192     set_bond_type(x11,gmx->man->molw,eBFat);
193     break;
194   case IDVERYFAT:
195     set_bond_type(x11,gmx->man->molw,eBVeryFat);
196     break;
197   case IDBALLS:
198     set_bond_type(x11,gmx->man->molw,eBSpheres);
199     break;
200   case IDNOBOX:
201     set_box_type(x11,gmx->man->molw,esbNone);
202     break;
203   case IDRECTBOX:
204     set_box_type(x11,gmx->man->molw,esbRect);
205     break;
206   case IDTRIBOX:
207     set_box_type(x11,gmx->man->molw,esbTri);
208     break;
209   case IDTOBOX:
210     set_box_type(x11,gmx->man->molw,esbTrunc);
211     break;
212     
213     /* Analysis Menu */
214   case IDBOND: 
215   case IDANGLE: 
216   case IDDIH: 
217   case IDRMS:
218   case IDRDF:
219   case IDENERGIES: 
220   case IDCORR:
221     show_mb(gmx,emNotImplemented);
222     break;
223     
224     /* Help Menu */
225   case IDHELP:
226     show_mb(gmx,emHelp);
227     break;
228   case IDABOUT:
229     show_logo(x11,gmx->logo);
230     break;
231       
232   default:
233     break;
234   }
235   return FALSE;
236 }
237
238 static gmx_bool MainCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
239 {
240   t_gmx *gmx;
241   int   nsel,width,height;
242   gmx_bool  result;
243
244   result = FALSE;
245   gmx=(t_gmx *)data;
246   switch(event->type) {
247   case ButtonRelease:
248     hide_pd(x11,gmx->pd);
249     break;
250   case ConfigureNotify:
251     width=event->xconfigure.width;
252     height=event->xconfigure.height;
253     if ((width!=gmx->wd->width) || (height!=gmx->wd->height))
254       move_gmx(x11,gmx,width,height,TRUE);
255     break;
256   case ClientMessage:
257     hide_pd(x11,gmx->pd);
258     nsel=event->xclient.data.l[0];
259     result = HandleClient(x11,nsel,gmx);
260     break;
261   default:
262     break;
263   }
264   return result;
265 }
266
267 int main(int argc, char *argv[])
268 {
269   const char *desc[] = {
270     "[TT]ngmx[tt] is the GROMACS trajectory viewer. This program reads a",
271     "trajectory file, a run input file and an index file and plots a",
272     "3D structure of your molecule on your standard X Window",
273     "screen. No need for a high end graphics workstation, it even",
274     "works on Monochrome screens.[PAR]",
275     "The following features have been implemented:",
276     "3D view, rotation, translation and scaling of your molecule(s),",
277     "labels on atoms, animation of trajectories,",
278     "hardcopy in PostScript format, user defined atom-filters",
279     "runs on MIT-X (real X), open windows and motif,",
280     "user friendly menus, option to remove periodicity, option to",
281     "show computational box.[PAR]",
282     "Some of the more common X command line options can be used: ",
283     "[TT]-bg[tt], [TT]-fg[tt] change colors, [TT]-font fontname[tt] changes the font."
284   };
285   const char *bugs[] = {
286     "Balls option does not work",
287     "Some times dumps core without a good reason"
288   };
289
290   output_env_t oenv;
291   t_x11 *x11;
292   t_filenm fnm[] = {
293     { efTRX, "-f", NULL, ffREAD },
294     { efTPX, NULL, NULL, ffREAD },
295     { efNDX, NULL, NULL, ffOPTRD }
296   };
297 #define NFILE asize(fnm)
298   
299   CopyRight(stdout,argv[0]);
300   parse_common_args(&argc,argv,PCA_CAN_TIME,NFILE,fnm,
301                     0,NULL,asize(desc),desc,asize(bugs),bugs,&oenv);
302   
303   if ((x11=GetX11(&argc,argv))==NULL) {
304     fprintf(stderr,"Can't connect to X Server.\n"
305             "Check your DISPLAY environment variable\n");
306     exit(1);
307   }
308   init_gmx(x11,argv[0],NFILE,fnm,oenv);
309
310   x11->MainLoop(x11);
311   x11->CleanUp(x11);
312
313   thanx(stderr);
314   
315   return 0;
316 }
317
318 static t_mentry FileMenu[] = {
319   { 0,  IDEXPORT,       FALSE,  "Export..." },
320   { 0,  IDDUMPWIN,      FALSE,  "Print"     },
321   { 0,  IDQUIT,         FALSE,  "Quit"      }
322 };
323
324 static t_mentry DispMenu[] = {
325   { 0,  IDFILTER,       FALSE,  "Filter..." },
326   { 0,  IDANIMATE,      FALSE,  "Animate"   },
327   { 0,  IDLABELSOFF,    FALSE,  "Labels Off"},  
328   { 0,  IDRESETVIEW,    FALSE,  "Reset View"},
329   { 0,  IDBONDOPTS,     FALSE,  "Options..."}
330 };
331
332 static t_mentry HelpMenu[] = {
333   { 0,  IDHELP,         FALSE,  "Help"             },
334   { 0,  IDABOUT,        FALSE,  "About Gromacs..." }
335 };
336
337 static t_mentry *gmx_pd[] = { FileMenu, DispMenu, HelpMenu };
338
339 #define MSIZE asize(gmx_pd)
340
341 static int gmx_pd_size[MSIZE] = {
342   asize(FileMenu), asize(DispMenu), asize(HelpMenu)
343 };
344
345 static const char *MenuTitle[MSIZE] = {
346   "File", "Display", "Help"
347 };
348
349 void init_gmx(t_x11 *x11,char *program,int nfile,t_filenm fnm[], 
350               const output_env_t oenv)
351 {
352   Pixmap               pm;
353   t_gmx                *gmx;
354   XSizeHints           hints;
355   int                  w0,h0;
356   int                  natom,nre,natom_trx;
357   t_topology           top;
358   int                  ePBC;
359   matrix               box;
360   t_trxframe           fr;
361   t_trxstatus          *status;
362   char                 quote[256];
363   
364   snew(gmx,1);
365   snew(gmx->wd,1);
366
367   ePBC = read_tpx_top(ftp2fn(efTPX,nfile,fnm),
368                       NULL,box,&natom,NULL,NULL,NULL,&top);
369
370   read_first_frame(oenv,&status,ftp2fn(efTRX,nfile,fnm),&fr,TRX_DONT_SKIP);
371   close_trx(status);
372   natom_trx = fr.natoms;
373            
374   /* Creates a simple window */
375   w0=DisplayWidth(x11->disp,x11->screen)-132;
376   h0=DisplayHeight(x11->disp,x11->screen)-140;
377   bromacs(quote,255);
378   InitWin(gmx->wd,0,0,w0,h0,3,quote);
379   gmx->wd->self=XCreateSimpleWindow(x11->disp,x11->root,
380                                     gmx->wd->x, gmx->wd->y,
381                                     gmx->wd->width,gmx->wd->height,
382                                     gmx->wd->bwidth,WHITE,BLACK);
383   pm=XCreatePixmapFromBitmapData(x11->disp,x11->root,
384                                  (char *)gromacs_bits,gromacs_width,
385                                  gromacs_height,
386                                  WHITE,BLACK,1);
387   hints.flags=PMinSize;
388   hints.min_width=2*EWIDTH+40;
389   hints.min_height=EHEIGHT+LDHEIGHT+LEGHEIGHT+40;
390   XSetStandardProperties(x11->disp,gmx->wd->self,gmx->wd->text,program,
391                          pm,NULL,0,&hints);
392   
393   x11->RegisterCallback(x11,gmx->wd->self,x11->root,MainCallBack,gmx);
394   x11->SetInputMask(x11,gmx->wd->self,
395                     ButtonPressMask     | ButtonReleaseMask |
396                     OwnerGrabButtonMask | ExposureMask      |
397                     StructureNotifyMask);
398
399   /* The order of creating windows is important here! */
400   /* Manager */
401   gmx->man  = init_man(x11,gmx->wd->self,0,0,1,1,WHITE,BLACK,ePBC,box,oenv);
402   gmx->logo = init_logo(x11,gmx->wd->self,FALSE);
403
404   /* Now put all windows in the proper place */
405   move_gmx(x11,gmx,w0,h0,FALSE);
406   
407   XMapWindow(x11->disp,gmx->wd->self);
408   map_man(x11,gmx->man);
409
410   /* Pull Down menu */
411   gmx->pd=init_pd(x11,gmx->wd->self,gmx->wd->width,
412                   XTextHeight(x11->font),x11->fg,x11->bg,
413                   MSIZE,gmx_pd_size,gmx_pd,MenuTitle);
414
415   /* Dialogs & Filters */
416
417   gmx->filter=init_filter(&(top.atoms),ftp2fn_null(efNDX,nfile,fnm),
418                           natom_trx);
419   
420   init_dlgs(x11,gmx);
421
422   /* Now do file shit */
423   set_file(x11,gmx->man,ftp2fn(efTRX,nfile,fnm),ftp2fn(efTPX,nfile,fnm));
424
425   /*show_logo(x11,gmx->logo);*/
426   
427   ShowDlg(gmx->dlgs[edFilter]);
428 }
429