2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
52 #include "gmx_fatal.h"
53 /*****************************
57 ****************************/
58 t_dlgitem
*FindItem(t_dlg
*dlg
, t_id id
)
62 for (i
= 0; (i
< dlg
->nitem
); i
++)
64 if (dlg
->dlgitem
[i
]->ID
== id
)
66 return dlg
->dlgitem
[i
];
72 t_dlgitem
*FindWin(t_dlg
*dlg
, Window win
)
76 for (i
= 0; (i
< dlg
->nitem
); i
++)
78 if (dlg
->dlgitem
[i
]->win
.self
== win
)
80 return dlg
->dlgitem
[i
];
86 /*****************************
88 * Routines to manipulate items on a dialog box
90 ****************************/
91 gmx_bool
QueryDlgItemSize(t_dlg
*dlg
, t_id id
, int *w
, int *h
)
95 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
97 *w
= dlgitem
->win
.width
;
98 *h
= dlgitem
->win
.height
;
104 gmx_bool
QueryDlgItemPos(t_dlg
*dlg
, t_id id
, int *x0
, int *y0
)
108 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
110 *x0
= dlgitem
->win
.x
;
111 *y0
= dlgitem
->win
.y
;
117 int QueryDlgItemX(t_dlg
*dlg
, t_id id
)
121 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
123 return dlgitem
->win
.x
;
128 int QueryDlgItemY(t_dlg
*dlg
, t_id id
)
132 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
134 return dlgitem
->win
.y
;
139 int QueryDlgItemW(t_dlg
*dlg
, t_id id
)
143 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
145 return dlgitem
->win
.width
;
150 int QueryDlgItemH(t_dlg
*dlg
, t_id id
)
154 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
156 return dlgitem
->win
.height
;
161 gmx_bool
SetDlgItemSize(t_dlg
*dlg
, t_id id
, int w
, int h
)
168 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
171 old_w
= dlgitem
->win
.width
;
172 old_h
= dlgitem
->win
.height
;
176 dlgitem
->win
.width
= w
;
180 dlgitem
->win
.height
= h
;
183 fprintf(dlg
->x11
->console
,
184 "Size window from: %dx%d to %dx%d\n", old_w
, old_h
,
185 dlgitem
->win
.width
, dlgitem
->win
.height
);
186 dlg
->x11
->Flush(dlg
->x11
);
188 if (dlgitem
->win
.self
)
190 XResizeWindow(dlg
->x11
->disp
, dlgitem
->win
.self
, dlgitem
->win
.width
,
191 dlgitem
->win
.height
);
193 if ((w
) && (dlgitem
->type
== edlgGB
))
196 t_id gid
= dlgitem
->GroupID
;
197 t_id id
= dlgitem
->ID
;
198 for (i
= 0; (i
< dlg
->nitem
); i
++)
200 t_dlgitem
*child
= dlg
->dlgitem
[i
];
201 if ((child
->GroupID
== gid
) && (child
->ID
!= id
))
203 SetDlgItemSize(dlg
, child
->ID
, w
-4*OFFS_X
, 0);
212 gmx_bool
SetDlgItemPos(t_dlg
*dlg
, t_id id
, int x0
, int y0
)
217 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
219 old_x
= dlgitem
->win
.x
;
220 old_y
= dlgitem
->win
.y
;
224 fprintf(dlg
->x11
->console
,
225 "Move window from: %d,%d to %d,%d\n", old_x
, old_y
, x0
, y0
);
226 dlg
->x11
->Flush(dlg
->x11
);
228 if (dlgitem
->win
.self
)
230 XMoveWindow(dlg
->x11
->disp
, dlgitem
->win
.self
, x0
, y0
);
232 if (dlgitem
->type
== edlgGB
)
235 t_id gid
= dlgitem
->GroupID
;
236 t_id id
= dlgitem
->ID
;
237 x
= dlgitem
->win
.x
+2*OFFS_X
-old_x
;
238 y
= dlgitem
->win
.y
+2*OFFS_Y
-old_y
;
239 for (i
= 0; (i
< dlg
->nitem
); i
++)
241 t_dlgitem
*child
= dlg
->dlgitem
[i
];
242 if ((child
->GroupID
== gid
) && (child
->ID
!= id
))
244 SetDlgItemPos(dlg
, child
->ID
, child
->win
.x
+x
, child
->win
.y
+y
);
253 /*****************************
255 * Routines to extract information from the dlg proc
256 * after dlg is exec'ed
258 ****************************/
259 gmx_bool
IsCBChecked(t_dlg
*dlg
, t_id id
)
263 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
265 if (dlgitem
->type
== edlgCB
)
267 return dlgitem
->u
.checkbox
.bChecked
;
274 t_id
RBSelected(t_dlg
*dlg
, int gid
)
278 for (i
= 0; (i
< dlg
->nitem
); i
++)
280 if ((dlg
->dlgitem
[i
]->type
== edlgRB
) &&
281 (dlg
->dlgitem
[i
]->u
.radiobutton
.bSelect
) &&
282 (dlg
->dlgitem
[i
]->GroupID
== gid
))
284 return dlg
->dlgitem
[i
]->ID
;
291 int EditTextLen(t_dlg
*dlg
, t_id id
)
295 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
297 if (dlgitem
->type
== edlgET
)
299 return strlen(dlgitem
->u
.edittext
.buf
);
306 char *EditText(t_dlg
*dlg
, t_id id
)
310 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
312 if (dlgitem
->type
== edlgET
)
314 return dlgitem
->u
.edittext
.buf
;
321 /*****************************
323 * Exececute the dialog box procedure
324 * Returns when a button is pushed.
325 * return value is the ID of the button
327 ****************************/
328 void ShowDlg(t_dlg
*dlg
)
333 XMapWindow(dlg
->x11
->disp
, dlg
->win
.self
);
334 XMapSubwindows(dlg
->x11
->disp
, dlg
->win
.self
);
335 for (i
= 0; (i
< dlg
->nitem
); i
++)
337 LightBorder(dlg
->x11
->disp
, dlg
->dlgitem
[i
]->win
.self
, dlg
->bg
);
339 XSetForeground(dlg
->x11
->disp
, dlg
->x11
->gc
, dlg
->x11
->fg
);
340 for (i
= 0; (i
< dlg
->nitem
); i
++)
342 dlgitem
= dlg
->dlgitem
[i
];
343 if ((dlgitem
->type
== edlgBN
) &&
344 (dlgitem
->u
.button
.bDefault
))
346 PushMouse(dlg
->x11
->disp
, dlgitem
->win
.self
,
347 dlgitem
->win
.width
/2, dlgitem
->win
.height
/2);
355 void HideDlg(t_dlg
*dlg
)
359 PopMouse(dlg
->x11
->disp
);
362 XUnmapSubwindows(dlg
->x11
->disp
, dlg
->win
.self
);
363 XUnmapWindow(dlg
->x11
->disp
, dlg
->win
.self
);
366 void NoHelp(t_dlg
*dlg
)
371 lines
[0] = strdup("Error");
372 lines
[1] = strdup("No help for this item");
373 MessageBox(dlg
->x11
, dlg
->wDad
, "No Help", 2, lines
,
374 MB_OK
| MB_ICONSTOP
| MB_APPLMODAL
, NULL
, NULL
);
380 void HelpDlg(t_dlg
*dlg
)
383 "Place the cursor over one of the items",
384 "and press the F1 key to get more help.",
385 "First press the OK button."
387 MessageBox(dlg
->x11
, dlg
->win
.self
, "Help Dialogbox",
388 3, lines
, MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
, NULL
, NULL
);
391 void HelpNow(t_dlg
*dlg
, t_dlgitem
*dlgitem
)
394 gmx_bool bCont
= TRUE
;
404 printf("%s\n", dlgitem
->help
);
407 fgets2(buf
, 79, stdin
);
409 fprintf(dlg
->x11
->console
, "buffer: '%s'\n", buf
);
410 dlg
->x11
->Flush(dlg
->x11
);
412 if (gmx_strcasecmp(buf
, "nok") == 0)
414 /* An error occurred */
415 for (i
= 0; (i
< nlines
); i
++)
425 bCont
= (gmx_strcasecmp(buf
, "ok") != 0);
428 srenew(lines
, ++nlines
);
429 lines
[nlines
-1] = strdup(buf
);
434 MessageBox(dlg
->x11
, dlg
->wDad
, "Help",
435 nlines
, lines
, MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
, NULL
, NULL
);
436 for (i
= 0; (i
< nlines
); i
++)
443 static void EnterDlg(t_dlg
*dlg
)
445 if (dlg
->flags
& DLG_APPLMODAL
)
447 dlg
->bGrab
= GrabOK(dlg
->x11
->console
,
448 XGrabPointer(dlg
->x11
->disp
, dlg
->win
.self
,
449 True
, 0, GrabModeAsync
, GrabModeAsync
,
450 dlg
->win
.self
, None
, CurrentTime
));
452 dlg
->x11
->Flush(dlg
->x11
);
455 static void ExitDlg(t_dlg
*dlg
)
459 XUngrabPointer(dlg
->x11
->disp
, CurrentTime
);
463 if (dlg
->flags
& DLG_FREEONBUTTON
)
469 static gmx_bool
DlgCB(t_x11
*x11
, XEvent
*event
, Window w
, void *data
)
471 t_dlg
*dlg
= (t_dlg
*)data
;
475 if ((dlgitem
= FindWin(dlg
, w
)) != NULL
)
477 nWndProc
= (dlgitem
->WndProc
)(x11
, dlgitem
, event
);
479 fprintf(x11
->console
,
480 "window: %s, nWndProc: %d\n", dlgitem
->win
.text
, nWndProc
);
486 if ((dlgitem
->type
== edlgBN
) && (dlgitem
->u
.button
.bDefault
))
490 dlg
->cb(x11
, DLG_EXIT
, dlgitem
->ID
, dlgitem
->win
.text
, dlg
->data
);
499 for (i
= 0; (i
< dlg
->nitem
); i
++)
501 if ((dlg
->dlgitem
[i
]->type
== edlgBN
) &&
502 (dlg
->dlgitem
[i
]->u
.button
.bDefault
))
504 PushMouse(x11
->disp
, dlg
->dlgitem
[i
]->win
.self
,
505 dlg
->dlgitem
[i
]->win
.width
/2,
506 dlg
->dlgitem
[i
]->win
.height
/2);
515 dlg
->cb(x11
, DLG_EXIT
, dlgitem
->ID
, dlgitem
->win
.text
, dlg
->data
);
524 int gid
= dlgitem
->GroupID
;
525 t_id tid
= RBSelected(dlg
, gid
);
527 fprintf(stderr
, "RBPRESSED\n");
531 t_dlgitem
*dit
= FindItem(dlg
, tid
);
532 dit
->u
.radiobutton
.bSelect
= FALSE
;
533 ExposeWin(x11
->disp
, dit
->win
.self
);
537 gmx_fatal(FARGS
, "No RB Selected initially!\n");
539 dlgitem
->u
.radiobutton
.bSelect
= TRUE
;
540 ExposeWin(x11
->disp
, dlgitem
->win
.self
);
543 dlg
->cb(x11
, DLG_SET
, dlgitem
->ID
, dlgitem
->win
.text
, dlg
->data
);
548 ExposeWin(x11
->disp
, dlgitem
->win
.self
);
551 dlg
->cb(x11
, DLG_SET
, dlgitem
->ID
, dlgitem
->set
, dlg
->data
);
555 ExposeWin(x11
->disp
, dlgitem
->win
.self
);
558 dlg
->cb(x11
, DLG_SET
, dlgitem
->ID
, dlgitem
->u
.edittext
.buf
, dlg
->data
);
562 HelpNow(dlg
, dlgitem
);
567 gmx_fatal(FARGS
, "Invalid return code (%d) from wndproc\n", nWndProc
);
570 else if (w
== dlg
->win
.self
)
579 if (HelpPressed(event
))
585 XBell(x11
->disp
, 50);
595 /*****************************
597 * Routine to add an item to the dialog box
598 * The pointer to the item is copied to the dlg struct,
599 * the item itself may not be freed until the dlg is done with
601 ****************************/
602 void DoCreateDlg(t_dlg
*dlg
)
605 XSetWindowAttributes attr
;
608 attr
.border_pixel
= dlg
->x11
->fg
;
609 attr
.background_pixel
= dlg
->bg
;
610 attr
.override_redirect
= False
;
611 attr
.save_under
= True
;
612 attr
.cursor
= XCreateFontCursor(dlg
->x11
->disp
, XC_hand2
);
613 Val
= CWBackPixel
| CWBorderPixel
| CWOverrideRedirect
| CWSaveUnder
|
615 dlg
->win
.self
= XCreateWindow(dlg
->x11
->disp
, dlg
->wDad
,
616 dlg
->win
.x
, dlg
->win
.y
,
617 dlg
->win
.width
, dlg
->win
.height
,
618 dlg
->win
.bwidth
, CopyFromParent
,
619 InputOutput
, CopyFromParent
,
621 dlg
->x11
->RegisterCallback(dlg
->x11
, dlg
->win
.self
, dlg
->wDad
,
623 dlg
->x11
->SetInputMask(dlg
->x11
, dlg
->win
.self
,
624 ExposureMask
| ButtonPressMask
| KeyPressMask
);
626 if (!CheckWindow(dlg
->win
.self
))
630 hints
.x
= dlg
->win
.x
;
631 hints
.y
= dlg
->win
.y
;
632 hints
.flags
= PPosition
;
633 XSetStandardProperties(dlg
->x11
->disp
, dlg
->win
.self
, dlg
->title
,
634 dlg
->title
, None
, NULL
, 0, &hints
);
637 void AddDlgItem(t_dlg
*dlg
, t_dlgitem
*item
)
639 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
640 #define UserMask (ButtonPressMask | KeyPressMask)
641 static unsigned long InputMask
[edlgNR
] = {
642 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgBN */
643 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgRB */
644 ExposureMask
, /* edlgGB */
645 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgCB */
647 ExposureMask
, /* edlgST */
648 ExposureMask
| UserMask
| EnterLeaveMask
/* edlgET */
655 srenew(dlg
->dlgitem
, dlg
->nitem
+1);
658 gmx_fatal(FARGS
, "dlgitem not allocated");
661 XCreateSimpleWindow(dlg
->x11
->disp
, dlg
->win
.self
, item
->win
.x
, item
->win
.y
,
662 item
->win
.width
, item
->win
.height
,
663 item
->win
.bwidth
, dlg
->x11
->fg
, dlg
->x11
->bg
);
664 CheckWindow(item
->win
.self
);
666 dlg
->x11
->RegisterCallback(dlg
->x11
, item
->win
.self
, dlg
->win
.self
,
668 dlg
->x11
->SetInputMask(dlg
->x11
, item
->win
.self
, InputMask
[item
->type
]);
673 XSetWindowBackgroundPixmap(dlg
->x11
->disp
, item
->win
.self
, item
->u
.pixmap
.pm
);
678 dlg
->dlgitem
[dlg
->nitem
] = item
;
683 void AddDlgItems(t_dlg
*dlg
, int nitem
, t_dlgitem
*item
[])
687 for (i
= 0; (i
< nitem
); i
++)
690 fprintf(dlg
->x11
->console
,
691 "Adding item: %d from group %d\n", item
[i
]->ID
, item
[i
]->GroupID
);
692 dlg
->x11
->Flush(dlg
->x11
);
694 AddDlgItem(dlg
, item
[i
]);
698 void FreeDlgItem(t_dlg
*dlg
, t_id id
)
703 if ((dlgitem
= FindItem(dlg
, id
)) != NULL
)
705 dlg
->x11
->UnRegisterCallback(dlg
->x11
, dlgitem
->win
.self
);
706 if (dlgitem
->win
.self
)
708 XDestroyWindow(dlg
->x11
->disp
, dlgitem
->win
.self
);
710 FreeWin(dlg
->x11
->disp
, &(dlgitem
->win
));
711 switch (dlgitem
->type
)
717 sfree(dlgitem
->u
.groupbox
.item
);
722 XFreePixmap(dlg
->x11
->disp
, dlgitem
->u
.pixmap
.pm
);
725 for (i
= 0; (i
< dlgitem
->u
.statictext
.nlines
); i
++)
727 sfree(dlgitem
->u
.statictext
.lines
[i
]);
729 sfree(dlgitem
->u
.statictext
.lines
);
732 sfree(dlgitem
->u
.edittext
.buf
);
740 void FreeDlg(t_dlg
*dlg
)
747 dlg
->x11
->UnRegisterCallback(dlg
->x11
, dlg
->win
.self
);
748 for (i
= 0; (i
< dlg
->nitem
); i
++)
750 FreeDlgItem(dlg
, dlg
->dlgitem
[i
]->ID
);
753 sfree(dlg
->dlgitem
[i
]);
759 XDestroyWindow(dlg
->x11
->disp
, dlg
->win
.self
);
765 /*****************************
767 * Routine to create the DLG structure, returns NULL on failure
769 ****************************/
770 t_dlg
*CreateDlg(t_x11
*x11
, Window Parent
, const char *title
,
771 int x0
, int y0
, int w
, int h
, int bw
, unsigned long fg
, unsigned long bg
,
772 DlgCallback
*cb
, void *data
)
783 dlg
->title
= strdup(title
);
800 dlg
->xmax
= DisplayWidth(x11
->disp
, x11
->screen
);
801 dlg
->ymax
= DisplayHeight(x11
->disp
, x11
->screen
);
808 XGetGeometry(x11
->disp
, Parent
, &root
, &x
, &y
,
809 &(dlg
->xmax
), &(dlg
->ymax
), &dum
, &dum
);
811 fprintf(x11
->console
,
812 "Daddy is %d x %d at %d, %d\n", dlg
->xmax
, dlg
->ymax
, x
, y
);
813 dlg
->x11
->Flush(dlg
->x11
);
824 InitWin(&(dlg
->win
), x
, y
, w
, h
, bw
, NULL
);
825 SetDlgSize(dlg
, w
, h
, x0
|| y0
);
837 void SetDlgSize(t_dlg
*dlg
, int w
, int h
, gmx_bool bAutoPosition
)
852 fprintf(dlg
->x11
->console
, "SetDlgSize: Dialog is %dx%d, at %d,%d\n",
853 dlg
->win
.width
, dlg
->win
.height
, dlg
->win
.x
, dlg
->win
.y
);
854 dlg
->x11
->Flush(dlg
->x11
);
858 XMoveWindow(dlg
->x11
->disp
, dlg
->win
.self
, dlg
->win
.x
, dlg
->win
.y
);
859 XResizeWindow(dlg
->x11
->disp
, dlg
->win
.self
, w
, h
);