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