3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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-2013, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * Gyas ROwers Mature At Cryogenic Speed
46 #include "gmx_fatal.h"
56 static bool MWCallBack(t_x11
*x11
, XEvent
*event
, Window w
, void *data
)
62 mw
= (t_molwin
*)data
;
64 letter
.type
= ClientMessage
;
65 letter
.xclient
.display
= x11
->disp
;
66 letter
.xclient
.window
= To
;
67 letter
.xclient
.message_type
= 0;
68 letter
.xclient
.format
= 32;
72 /* Do Not draw anything, but signal parent instead, he will
75 letter
.xclient
.data
.l
[0] = IDDRAWMOL
;
76 letter
.xclient
.data
.l
[1] = Button1
;
77 XSendEvent(x11
->disp
, To
, True
, 0, &letter
);
81 printf("Molwindow: Buttonpress\n");
83 letter
.xclient
.data
.l
[0] = IDLABEL
;
84 letter
.xclient
.data
.l
[1] = (long)event
->xbutton
.button
;
85 letter
.xclient
.data
.l
[2] = event
->xbutton
.x
;
86 letter
.xclient
.data
.l
[3] = event
->xbutton
.y
;
87 XSendEvent(x11
->disp
, To
, True
, 0, &letter
);
90 mw
->wd
.width
= event
->xconfigure
.width
;
91 mw
->wd
.height
= event
->xconfigure
.height
;
99 void set_def (t_molwin
*mw
, int ePBC
, matrix box
)
101 mw
->bShowHydrogen
= true;
102 mw
->bond_type
= eBFat
;
104 mw
->boxtype
= esbRect
;
105 mw
->realbox
= TRICLINIC(box
) ? esbTri
: esbRect
;
108 t_molwin
*init_mw(t_x11
*x11
, Window Parent
,
109 int x
, int y
, int width
, int height
,
110 unsigned long fg
, unsigned long bg
,
111 int ePBC
, matrix box
)
116 set_def(mw
, ePBC
, box
);
118 InitWin(&mw
->wd
, x
, y
, width
, height
, 1, "Mol Window");
120 mw
->wd
.Parent
= Parent
;
121 mw
->wd
.self
= XCreateSimpleWindow(x11
->disp
, Parent
, x
, y
, width
, height
, 1, fg
, bg
);
122 x11
->RegisterCallback(x11
, mw
->wd
.self
, Parent
, MWCallBack
, mw
);
123 x11
->SetInputMask(x11
, mw
->wd
.self
,
124 ExposureMask
| StructureNotifyMask
|
129 void map_mw(t_x11
*x11
, t_molwin
*mw
)
131 XMapWindow(x11
->disp
, mw
->wd
.self
);
134 bool toggle_hydrogen(t_x11
*x11
, t_molwin
*mw
)
136 mw
->bShowHydrogen
= !mw
->bShowHydrogen
;
137 ExposeWin(x11
->disp
, mw
->wd
.self
);
139 return mw
->bShowHydrogen
;
142 void set_bond_type(t_x11
*x11
, t_molwin
*mw
, int bt
)
144 if (bt
!= mw
->bond_type
)
147 ExposeWin(x11
->disp
, mw
->wd
.self
);
151 void set_box_type (t_x11
*x11
, t_molwin
*mw
, int bt
)
154 fprintf(stderr
, "mw->boxtype = %d, bt = %d\n", mw
->boxtype
, bt
);
156 if (bt
!= mw
->boxtype
)
158 if ((bt
== esbTrunc
&& mw
->realbox
== esbTri
) || bt
== esbTri
|| bt
== esbNone
)
161 ExposeWin(x11
->disp
, mw
->wd
.self
);
165 fprintf(stderr
, "Can not change rectangular box to truncated octahedron\n");
170 void done_mw(t_x11
*x11
, t_molwin
*mw
)
172 x11
->UnRegisterCallback(x11
, mw
->wd
.self
);
176 static void draw_atom(Display
*disp
, Window w
, GC gc
,
177 atom_id ai
, iv2 vec2
[], unsigned long col
[], int size
[],
178 bool bBall
, bool bPlus
)
184 XSetForeground(disp
, gc
, col
[ai
]);
187 XFillCircle(disp
, w
, gc
, xi
, yi
, size
[ai
]-1);
188 XSetForeground(disp
, gc
, BLACK
);
189 XDrawCircle(disp
, w
, gc
, xi
, yi
, size
[ai
]);
190 /* XSetForeground(disp,gc,WHITE);
191 XFillCircle(disp,w,gc,xi+4,yi-4,4); */
195 XDrawLine(disp
, w
, gc
, xi
-MSIZE
, yi
, xi
+MSIZE
+1, yi
);
196 XDrawLine(disp
, w
, gc
, xi
, yi
-MSIZE
, xi
, yi
+MSIZE
+1);
200 XDrawLine(disp
, w
, gc
, xi
-1, yi
, xi
+1, yi
);
205 /* Global variables */
206 static rvec gl_fbox
, gl_hbox
, gl_mhbox
;
208 static void my_init_pbc(matrix box
)
212 for (i
= 0; (i
< DIM
); i
++)
214 gl_fbox
[i
] = box
[i
][i
];
215 gl_hbox
[i
] = gl_fbox
[i
]*0.5;
216 gl_mhbox
[i
] = -gl_hbox
[i
];
220 static bool local_pbc_dx(rvec x1
, rvec x2
)
225 for (i
= 0; (i
< DIM
); i
++)
232 else if (dx
<= gl_mhbox
[i
])
240 static void draw_bond(Display
*disp
, Window w
, GC gc
,
241 atom_id ai
, atom_id aj
, iv2 vec2
[],
242 rvec x
[], unsigned long col
[], int size
[], bool bBalls
)
244 unsigned long ic
, jc
;
250 draw_atom(disp
, w
, gc
, ai
, vec2
, col
, size
, true, false);
251 draw_atom(disp
, w
, gc
, aj
, vec2
, col
, size
, true, false);
255 if (local_pbc_dx(x
[ai
], x
[aj
]))
269 XSetForeground(disp
, gc
, ic
);
270 XDrawLine(disp
, w
, gc
, xi
, yi
, xm
, ym
);
271 XSetForeground(disp
, gc
, jc
);
272 XDrawLine(disp
, w
, gc
, xm
, ym
, xj
, yj
);
276 XSetForeground(disp
, gc
, ic
);
277 XDrawLine(disp
, w
, gc
, xi
, yi
, xj
, yj
);
283 int compare_obj(const void *a
, const void *b
)
307 void create_visibility(t_manager
*man
)
312 for (i
= 0, obj
= man
->obj
; (i
< man
->nobj
); i
++, obj
++)
314 if (obj
->eV
!= eVHidden
)
316 man
->bVis
[obj
->ai
] = true;
321 man
->bVis
[obj
->aj
] = true;
330 void z_fill(t_manager
*man
, real
*zz
)
335 for (i
= 0, obj
= man
->obj
; (i
< man
->nobj
); i
++, obj
++)
340 obj
->z
= zz
[obj
->ai
];
344 obj
->z
= (zz
[obj
->ai
] + zz
[obj
->aj
]) * 0.5;
352 int filter_vis(t_manager
*man
)
354 int i
, nobj
, nvis
, nhide
;
366 for (i
= 0; (i
< nobj
); i
++, obj
++)
372 if (obj
->eO
!= eOSingle
)
374 bAdd
= bVis
[obj
->aj
];
379 newobj
[nvis
++] = *obj
;
383 newobj
[nhide
--] = *obj
;
392 void draw_objects(Display
*disp
, Window w
, GC gc
, int nobj
,
393 t_object objs
[], iv2 vec2
[], rvec x
[],
394 unsigned long col
[], int size
[], bool bShowHydro
, int bond_type
,
405 XSetLineAttributes(disp
, gc
, 1, LineSolid
, CapNotLast
, JoinRound
);
408 XSetLineAttributes(disp
, gc
, 3, LineSolid
, CapNotLast
, JoinRound
);
411 XSetLineAttributes(disp
, gc
, 5, LineSolid
, CapNotLast
, JoinRound
);
418 gmx_fatal(FARGS
, "Invalid bond_type selected: %d\n", bond_type
);
421 for (i
= 0; (i
< nobj
); i
++)
427 draw_atom(disp
, w
, gc
, obj
->ai
, vec2
, col
, size
, bBalls
, bPlus
);
430 draw_bond(disp
, w
, gc
, obj
->ai
, obj
->aj
, vec2
, x
, col
, size
, bBalls
);
435 draw_bond(disp
, w
, gc
, obj
->ai
, obj
->aj
, vec2
, x
, col
, size
, bBalls
);
442 XSetLineAttributes(disp
, gc
, 1, LineSolid
, CapNotLast
, JoinRound
);
445 static void v4_to_iv2(vec4 x4
, iv2 v2
, int x0
, int y0
, real sx
, real sy
)
450 v2
[XX
] = x0
+sx
*x4
[XX
]*inv_z
;
451 v2
[YY
] = y0
-sy
*x4
[YY
]*inv_z
;
454 static void draw_box(t_x11
*x11
, Window w
, t_3dview
*view
, matrix box
,
455 int x0
, int y0
, real sx
, real sy
, int boxtype
)
458 { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 },
459 { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 }
461 int tr_bonds
[12][2] = {
462 { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 },
463 { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 },
464 { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
466 static int *edge
= NULL
;
468 rvec corner
[NCUCEDGE
], box_center
;
470 iv2 vec2
[NCUCEDGE
], tv2
;
472 calc_box_center(view
->ecenter
, box
, box_center
);
473 if (boxtype
== esbTrunc
)
475 calc_compact_unitcell_vertices(view
->ecenter
, box
, corner
);
478 edge
= compact_unitcell_edges();
481 for (i
= 0; (i
< NCUCEDGE
); i
++)
483 m4_op(view
->proj
, corner
[i
], x4
);
484 v4_to_iv2(x4
, vec2
[i
], x0
, y0
, sx
, sy
);
486 XSetForeground(x11
->disp
, x11
->gc
, YELLOW
);
487 for (i
= 0; i
< NCUCEDGE
; i
++)
491 XDrawLine(x11
->disp
, w
, x11
->gc
,
492 vec2
[i0
][XX
], vec2
[i0
][YY
], vec2
[i1
][XX
], vec2
[i1
][YY
]);
497 if (boxtype
== esbRect
)
499 for (j
= 0; (j
< DIM
); j
++)
501 box_center
[j
] -= 0.5*box
[j
][j
];
506 for (i
= 0; (i
< DIM
); i
++)
508 for (j
= 0; (j
< DIM
); j
++)
510 box_center
[j
] -= 0.5*box
[i
][j
];
514 for (i
= 0; (i
< 8); i
++)
516 clear_rvec(corner
[i
]);
517 for (j
= 0; (j
< DIM
); j
++)
519 if (boxtype
== esbTri
)
521 for (k
= 0; (k
< DIM
); k
++)
523 corner
[i
][k
] += rect_tri
[i
][j
]*box
[j
][k
];
528 corner
[i
][j
] = rect_tri
[i
][j
]*box
[j
][j
];
531 rvec_inc(corner
[i
], box_center
);
532 m4_op(view
->proj
, corner
[i
], x4
);
533 v4_to_iv2(x4
, vec2
[i
], x0
, y0
, sx
, sy
);
537 pr_rvecs(debug
, 0, "box", box
, DIM
);
538 pr_rvecs(debug
, 0, "corner", corner
, 8);
540 XSetForeground(x11
->disp
, x11
->gc
, YELLOW
);
541 for (i
= 0; (i
< 12); i
++)
545 XDrawLine(x11
->disp
, w
, x11
->gc
,
546 vec2
[i0
][XX
], vec2
[i0
][YY
], vec2
[i1
][XX
], vec2
[i1
][YY
]);
551 void set_sizes(t_manager
*man
, real sx
, real sy
)
555 for (i
= 0; (i
< man
->natom
); i
++)
559 man
->size
[i
] = 180*man
->vdw
[i
];
564 void draw_mol(t_x11
*x11
, t_manager
*man
)
566 static char tstr
[2][20];
567 static int ntime
= 0;
589 sx
= win
->width
/2*view
->sc_x
;
590 sy
= win
->height
/2*view
->sc_y
;
592 my_init_pbc(man
->box
);
594 /* create_visibility(man); */
596 for (i
= 0; (i
< man
->natom
); i
++)
600 m4_op(view
->proj
, man
->x
[i
], x4
);
602 v4_to_iv2(x4
, vec2
[i
], x0
, y0
, sx
, sy
);
605 set_sizes(man
, sx
, sy
);
607 z_fill (man
, man
->zz
);
610 XClearWindow(x11
->disp
, win
->self
);
613 sprintf(tstr
[ntime
], "Time: %.3f ps", man
->time
);
614 if (strcmp(tstr
[ntime
], tstr
[1-ntime
]) != 0)
616 set_vbtime(x11
, man
->vbox
, tstr
[ntime
]);
620 if (mw
->boxtype
!= esbNone
)
622 draw_box(x11
, win
->self
, view
, man
->box
, x0
, y0
, sx
, sy
, mw
->boxtype
);
625 /* Should sort on Z-Coordinates here! */
626 nvis
= filter_vis(man
);
627 if (nvis
&& man
->bSort
)
629 qsort(man
->obj
, nvis
, sizeof(man
->obj
[0]), compare_obj
);
632 /* Draw the objects */
633 draw_objects(x11
->disp
, win
->self
, x11
->gc
,
634 nvis
, man
->obj
, man
->ix
, man
->x
, man
->col
, man
->size
,
635 mw
->bShowHydrogen
, mw
->bond_type
, man
->bPlus
);
637 /* Draw the labels */
638 XSetForeground(x11
->disp
, x11
->gc
, WHITE
);
639 for (i
= 0; (i
< man
->natom
); i
++)
641 if (man
->bLabel
[i
] && man
->bVis
[i
])
643 XDrawString(x11
->disp
, win
->self
, x11
->gc
, vec2
[i
][XX
]+2, vec2
[i
][YY
]-2,
644 man
->szLab
[i
], strlen(man
->szLab
[i
]));
648 XSetForeground(x11
->disp
, x11
->gc
, x11
->fg
);