4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_nmol_c
= "$Id$";
45 static bool MWCallBack(t_x11
*x11
,XEvent
*event
, Window w
, void *data
)
53 letter
.type
=ClientMessage
;
54 letter
.xclient
.display
=x11
->disp
;
55 letter
.xclient
.window
=To
;
56 letter
.xclient
.message_type
=0;
57 letter
.xclient
.format
=32;
60 /* Do Not draw anything, but signal parent instead, he will
63 letter
.xclient
.data
.l
[0]=IDDRAWMOL
;
64 letter
.xclient
.data
.l
[1]=Button1
;
65 XSendEvent(x11
->disp
,To
,True
,0,&letter
);
69 printf("Molwindow: Buttonpress\n");
71 letter
.xclient
.data
.l
[0]=IDLABEL
;
72 letter
.xclient
.data
.l
[1]=(long)event
->xbutton
.button
;
73 letter
.xclient
.data
.l
[2]=event
->xbutton
.x
;
74 letter
.xclient
.data
.l
[3]=event
->xbutton
.y
;
75 XSendEvent(x11
->disp
,To
,True
,0,&letter
);
78 mw
->wd
.width
=event
->xconfigure
.width
;
79 mw
->wd
.height
=event
->xconfigure
.height
;
87 void set_def (t_molwin
*mw
)
89 mw
->bShowHydrogen
=TRUE
;
94 t_molwin
*init_mw(t_x11
*x11
,Window Parent
,
95 int x
,int y
,int width
,int height
,
96 unsigned long fg
,unsigned long bg
)
103 InitWin(&mw
->wd
,x
,y
,width
,height
,1,"Mol Window");
105 mw
->wd
.Parent
=Parent
;
106 mw
->wd
.self
=XCreateSimpleWindow(x11
->disp
,Parent
,x
,y
,width
,height
,1,fg
,bg
);
107 x11
->RegisterCallback(x11
,mw
->wd
.self
,Parent
,MWCallBack
,mw
);
108 x11
->SetInputMask(x11
,mw
->wd
.self
,
109 ExposureMask
| StructureNotifyMask
|
114 void map_mw(t_x11
*x11
,t_molwin
*mw
)
116 XMapWindow(x11
->disp
,mw
->wd
.self
);
119 bool toggle_hydrogen(t_x11
*x11
,t_molwin
*mw
)
121 mw
->bShowHydrogen
=!mw
->bShowHydrogen
;
122 ExposeWin(x11
->disp
,mw
->wd
.self
);
124 return mw
->bShowHydrogen
;
127 void set_bond_type(t_x11
*x11
,t_molwin
*mw
,int bt
)
129 if (bt
!= mw
->bond_type
) {
131 ExposeWin(x11
->disp
,mw
->wd
.self
);
135 bool toggle_box (t_x11
*x11
,t_molwin
*mw
)
137 mw
->bBoxSelect
=! mw
->bBoxSelect
;
138 ExposeWin(x11
->disp
,mw
->wd
.self
);
140 return mw
->bBoxSelect
;
143 void done_mw(t_x11
*x11
,t_molwin
*mw
)
145 x11
->UnRegisterCallback(x11
,mw
->wd
.self
);
149 static void draw_atom(Display
*disp
,Window w
,GC gc
,
150 atom_id ai
,iv2 vec2
[],unsigned long col
[],int size
[],
151 bool bBall
,bool bPlus
)
157 XSetForeground(disp
,gc
,col
[ai
]);
159 XFillCircle(disp
,w
,gc
,xi
,yi
,size
[ai
]-1);
160 XSetForeground(disp
,gc
,BLACK
);
161 XDrawCircle(disp
,w
,gc
,xi
,yi
,size
[ai
]);
162 /* XSetForeground(disp,gc,WHITE);
163 XFillCircle(disp,w,gc,xi+4,yi-4,4); */
166 XDrawLine(disp
,w
,gc
,xi
-MSIZE
,yi
,xi
+MSIZE
+1,yi
);
167 XDrawLine(disp
,w
,gc
,xi
,yi
-MSIZE
,xi
,yi
+MSIZE
+1);
170 XDrawLine(disp
,w
,gc
,xi
-1,yi
,xi
+1,yi
);
174 /* Global variables */
175 static rvec gl_fbox
,gl_hbox
,gl_mhbox
;
177 static void init_pbc(matrix box
)
181 for(i
=0; (i
<DIM
); i
++) {
182 gl_fbox
[i
] = box
[i
][i
];
183 gl_hbox
[i
] = gl_fbox
[i
]*0.5;
184 gl_mhbox
[i
] = -gl_hbox
[i
];
188 static bool local_pbc_dx(rvec x1
, rvec x2
)
193 for(i
=0; (i
<DIM
); i
++) {
197 else if (dx
<= gl_mhbox
[i
])
203 static void draw_bond(Display
*disp
,Window w
,GC gc
,
204 atom_id ai
,atom_id aj
,iv2 vec2
[],
205 rvec x
[],unsigned long col
[],int size
[],bool bBalls
)
212 draw_atom(disp
,w
,gc
,ai
,vec2
,col
,size
,TRUE
,FALSE
);
213 draw_atom(disp
,w
,gc
,aj
,vec2
,col
,size
,TRUE
,FALSE
);
216 if (local_pbc_dx(x
[ai
],x
[aj
])) {
228 XSetForeground(disp
,gc
,ic
);
229 XDrawLine(disp
,w
,gc
,xi
,yi
,xm
,ym
);
230 XSetForeground(disp
,gc
,jc
);
231 XDrawLine(disp
,w
,gc
,xm
,ym
,xj
,yj
);
234 XSetForeground(disp
,gc
,ic
);
235 XDrawLine(disp
,w
,gc
,xi
,yi
,xj
,yj
);
241 int compare_obj(const void *a
,const void *b
)
259 void create_visibility(t_manager
*man
)
264 for(i
=0,obj
=man
->obj
; (i
<man
->nobj
); i
++,obj
++)
265 if (obj
->eV
!= eVHidden
) {
266 man
->bVis
[obj
->ai
]=TRUE
;
270 man
->bVis
[obj
->aj
]=TRUE
;
278 void z_fill(t_manager
*man
, real
*zz
)
283 for(i
=0,obj
=man
->obj
; (i
<man
->nobj
); i
++,obj
++)
286 obj
->z
= zz
[obj
->ai
];
290 obj
->z
= (zz
[obj
->ai
] + zz
[obj
->aj
]) * 0.5;
297 int filter_vis(t_manager
*man
)
299 int i
,nobj
,nvis
,nhide
;
311 for(i
=0; (i
<nobj
); i
++,obj
++) {
315 if (obj
->eO
!= eOSingle
)
320 newobj
[nhide
--]=*obj
;
328 void draw_objects(Display
*disp
,Window w
,GC gc
,int nobj
,
329 t_object objs
[],iv2 vec2
[],rvec x
[],
330 unsigned long col
[],int size
[],bool bShowHydro
,int bond_type
,
340 XSetLineAttributes(disp
,gc
,1,LineSolid
,CapNotLast
,JoinRound
);
343 XSetLineAttributes(disp
,gc
,3,LineSolid
,CapNotLast
,JoinRound
);
346 XSetLineAttributes(disp
,gc
,5,LineSolid
,CapNotLast
,JoinRound
);
353 fatal_error(0,"Invalid bond_type selected: %d\n",bond_type
);
356 for(i
=0; (i
<nobj
); i
++) {
360 draw_atom(disp
,w
,gc
,obj
->ai
,vec2
,col
,size
,bBalls
,bPlus
);
363 draw_bond(disp
,w
,gc
,obj
->ai
,obj
->aj
,vec2
,x
,col
,size
,bBalls
);
367 draw_bond(disp
,w
,gc
,obj
->ai
,obj
->aj
,vec2
,x
,col
,size
,bBalls
);
373 XSetLineAttributes(disp
,gc
,1,LineSolid
,CapNotLast
,JoinRound
);
376 static void v4_to_iv2(vec4 x4
,iv2 v2
,int x0
,int y0
,real sx
,real sy
)
381 v2
[XX
]=x0
+sx
*x4
[XX
]*inv_z
;
382 v2
[YY
]=y0
-sy
*x4
[YY
]*inv_z
;
385 static void draw_box(t_x11
*x11
,Window w
,t_3dview
*view
,matrix box
,
386 int x0
,int y0
,real sx
,real sy
)
389 { 0,0,0,1 }, { 1,0,0,1 }, { 1,1,0,1 }, { 0,1,0,1 },
390 { 0,0,1,1 }, { 1,0,1,1 }, { 1,1,1,1 }, { 0,1,1,1 }
393 { 0,1 }, { 1,2 }, { 2,3 }, { 3,0 },
394 { 4,5 }, { 5,6 }, { 6,7 }, { 7,4 },
395 { 0,4 }, { 1,5 }, { 2,6 }, { 3,7 }
402 for (i
=0; (i
<8); i
++) {
403 for (j
=0; (j
<DIM
); j
++)
404 corner
[i
][j
] = ivec
[i
][j
]*box
[j
][j
];
405 m4_op(view
->proj
,corner
[i
],x4
);
406 v4_to_iv2(x4
,vec2
[i
],x0
,y0
,sx
,sy
);
408 XSetForeground(x11
->disp
,x11
->gc
,YELLOW
);
409 for (i
=0; (i
<12); i
++)
410 XDrawLine(x11
->disp
,w
,x11
->gc
,
411 vec2
[bonds
[i
][0]][XX
],vec2
[bonds
[i
][0]][YY
],
412 vec2
[bonds
[i
][1]][XX
],vec2
[bonds
[i
][1]][YY
]);
415 void set_sizes(t_manager
*man
,real sx
,real sy
)
419 for(i
=0; (i
<man
->natom
); i
++)
421 man
->size
[i
]=180*man
->vdw
[i
];
424 void draw_mol(t_x11
*x11
,t_manager
*man
)
426 static char tstr
[2][20];
436 if (man
->status
== -1)
447 sx
=win
->width
/2*view
->sc_x
;
448 sy
=win
->height
/2*view
->sc_y
;
452 /* create_visibility(man); */
454 for(i
=0; (i
<man
->natom
); i
++) {
456 m4_op(view
->proj
,man
->x
[i
],x4
);
458 v4_to_iv2(x4
,vec2
[i
],x0
,y0
,sx
,sy
);
461 set_sizes(man
,sx
,sy
);
463 z_fill (man
,man
->zz
);
466 XClearWindow(x11
->disp
,win
->self
);
469 sprintf(tstr
[ntime
],"Time: %.3f ps",man
->time
);
470 if (strcmp(tstr
[ntime
],tstr
[1-ntime
]) != 0) {
471 set_vbtime(x11
,man
->vbox
,tstr
[ntime
]);
476 draw_box(x11
,win
->self
,view
,man
->box
,x0
,y0
,sx
,sy
);
478 /* Should sort on Z-Coordinates here! */
479 nvis
=filter_vis(man
);
480 if (nvis
&& man
->bSort
)
481 qsort(man
->obj
,nvis
,sizeof(man
->obj
[0]),compare_obj
);
483 /* Draw the objects */
484 draw_objects(x11
->disp
,win
->self
,x11
->gc
,
485 nvis
,man
->obj
,man
->ix
,man
->x
,man
->col
,man
->size
,
486 mw
->bShowHydrogen
,mw
->bond_type
,man
->bPlus
);
488 /* Draw the labels */
489 XSetForeground(x11
->disp
,x11
->gc
,WHITE
);
490 for(i
=0; (i
<man
->natom
); i
++) {
491 if (man
->bLabel
[i
] && man
->bVis
[i
]) {
492 XDrawString(x11
->disp
,win
->self
,x11
->gc
,vec2
[i
][XX
]+2,vec2
[i
][YY
]-2,
493 man
->szLab
[i
],strlen(man
->szLab
[i
]));
497 XSetForeground(x11
->disp
,x11
->gc
,x11
->fg
);