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-2004, 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
49 #include "gmx_fatal.h"
50 /*****************************
54 ****************************/
55 t_dlgitem *FindItem(t_dlg *dlg, t_id id)
59 for (i = 0; (i < dlg->nitem); i++)
61 if (dlg->dlgitem[i]->ID == id)
63 return dlg->dlgitem[i];
69 t_dlgitem *FindWin(t_dlg *dlg, Window win)
73 for (i = 0; (i < dlg->nitem); i++)
75 if (dlg->dlgitem[i]->win.self == win)
77 return dlg->dlgitem[i];
83 /*****************************
85 * Routines to manipulate items on a dialog box
87 ****************************/
88 bool QueryDlgItemSize(t_dlg *dlg, t_id id, int *w, int *h)
92 if ((dlgitem = FindItem(dlg, id)) != NULL)
94 *w = dlgitem->win.width;
95 *h = dlgitem->win.height;
101 bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0)
105 if ((dlgitem = FindItem(dlg, id)) != NULL)
107 *x0 = dlgitem->win.x;
108 *y0 = dlgitem->win.y;
114 int QueryDlgItemX(t_dlg *dlg, t_id id)
118 if ((dlgitem = FindItem(dlg, id)) != NULL)
120 return dlgitem->win.x;
125 int QueryDlgItemY(t_dlg *dlg, t_id id)
129 if ((dlgitem = FindItem(dlg, id)) != NULL)
131 return dlgitem->win.y;
136 int QueryDlgItemW(t_dlg *dlg, t_id id)
140 if ((dlgitem = FindItem(dlg, id)) != NULL)
142 return dlgitem->win.width;
147 int QueryDlgItemH(t_dlg *dlg, t_id id)
151 if ((dlgitem = FindItem(dlg, id)) != NULL)
153 return dlgitem->win.height;
158 bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h)
165 if ((dlgitem = FindItem(dlg, id)) != NULL)
168 old_w = dlgitem->win.width;
169 old_h = dlgitem->win.height;
173 dlgitem->win.width = w;
177 dlgitem->win.height = h;
180 fprintf(dlg->x11->console,
181 "Size window from: %dx%d to %dx%d\n", old_w, old_h,
182 dlgitem->win.width, dlgitem->win.height);
183 dlg->x11->Flush(dlg->x11);
185 if (dlgitem->win.self)
187 XResizeWindow(dlg->x11->disp, dlgitem->win.self, dlgitem->win.width,
188 dlgitem->win.height);
190 if ((w) && (dlgitem->type == edlgGB))
193 t_id gid = dlgitem->GroupID;
194 t_id id = dlgitem->ID;
195 for (i = 0; (i < dlg->nitem); i++)
197 t_dlgitem *child = dlg->dlgitem[i];
198 if ((child->GroupID == gid) && (child->ID != id))
200 SetDlgItemSize(dlg, child->ID, w-4*OFFS_X, 0);
209 bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0)
214 if ((dlgitem = FindItem(dlg, id)) != NULL)
216 old_x = dlgitem->win.x;
217 old_y = dlgitem->win.y;
221 fprintf(dlg->x11->console,
222 "Move window from: %d,%d to %d,%d\n", old_x, old_y, x0, y0);
223 dlg->x11->Flush(dlg->x11);
225 if (dlgitem->win.self)
227 XMoveWindow(dlg->x11->disp, dlgitem->win.self, x0, y0);
229 if (dlgitem->type == edlgGB)
232 t_id gid = dlgitem->GroupID;
233 t_id id = dlgitem->ID;
234 x = dlgitem->win.x+2*OFFS_X-old_x;
235 y = dlgitem->win.y+2*OFFS_Y-old_y;
236 for (i = 0; (i < dlg->nitem); i++)
238 t_dlgitem *child = dlg->dlgitem[i];
239 if ((child->GroupID == gid) && (child->ID != id))
241 SetDlgItemPos(dlg, child->ID, child->win.x+x, child->win.y+y);
250 /*****************************
252 * Routines to extract information from the dlg proc
253 * after dlg is exec'ed
255 ****************************/
256 bool IsCBChecked(t_dlg *dlg, t_id id)
260 if ((dlgitem = FindItem(dlg, id)) != NULL)
262 if (dlgitem->type == edlgCB)
264 return dlgitem->u.checkbox.bChecked;
271 t_id RBSelected(t_dlg *dlg, int gid)
275 for (i = 0; (i < dlg->nitem); i++)
277 if ((dlg->dlgitem[i]->type == edlgRB) &&
278 (dlg->dlgitem[i]->u.radiobutton.bSelect) &&
279 (dlg->dlgitem[i]->GroupID == gid))
281 return dlg->dlgitem[i]->ID;
288 int EditTextLen(t_dlg *dlg, t_id id)
292 if ((dlgitem = FindItem(dlg, id)) != NULL)
294 if (dlgitem->type == edlgET)
296 return strlen(dlgitem->u.edittext.buf);
303 char *EditText(t_dlg *dlg, t_id id)
307 if ((dlgitem = FindItem(dlg, id)) != NULL)
309 if (dlgitem->type == edlgET)
311 return dlgitem->u.edittext.buf;
318 /*****************************
320 * Exececute the dialog box procedure
321 * Returns when a button is pushed.
322 * return value is the ID of the button
324 ****************************/
325 void ShowDlg(t_dlg *dlg)
330 XMapWindow(dlg->x11->disp, dlg->win.self);
331 XMapSubwindows(dlg->x11->disp, dlg->win.self);
332 for (i = 0; (i < dlg->nitem); i++)
334 LightBorder(dlg->x11->disp, dlg->dlgitem[i]->win.self, dlg->bg);
336 XSetForeground(dlg->x11->disp, dlg->x11->gc, dlg->x11->fg);
337 for (i = 0; (i < dlg->nitem); i++)
339 dlgitem = dlg->dlgitem[i];
340 if ((dlgitem->type == edlgBN) &&
341 (dlgitem->u.button.bDefault))
343 PushMouse(dlg->x11->disp, dlgitem->win.self,
344 dlgitem->win.width/2, dlgitem->win.height/2);
352 void HideDlg(t_dlg *dlg)
356 PopMouse(dlg->x11->disp);
359 XUnmapSubwindows(dlg->x11->disp, dlg->win.self);
360 XUnmapWindow(dlg->x11->disp, dlg->win.self);
363 void NoHelp(t_dlg *dlg)
365 const char *lines[2] = {
367 "No help for this item"
369 MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines,
370 MB_OK | MB_ICONSTOP | MB_APPLMODAL, NULL, NULL);
373 void HelpDlg(t_dlg *dlg)
375 const char *lines[] = {
376 "Place the cursor over one of the items",
377 "and press the F1 key to get more help.",
378 "First press the OK button."
380 MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox",
381 3, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, NULL, NULL);
384 void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem)
397 printf("%s\n", dlgitem->help);
400 fgets2(buf, 79, stdin);
402 fprintf(dlg->x11->console, "buffer: '%s'\n", buf);
403 dlg->x11->Flush(dlg->x11);
405 if (gmx_strcasecmp(buf, "nok") == 0)
407 /* An error occurred */
408 for (i = 0; (i < nlines); i++)
418 bCont = (gmx_strcasecmp(buf, "ok") != 0);
421 srenew(lines, ++nlines);
422 lines[nlines-1] = strdup(buf);
427 MessageBox(dlg->x11, dlg->wDad, "Help",
429 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, NULL, NULL);
430 for (i = 0; (i < nlines); i++)
437 static void EnterDlg(t_dlg *dlg)
439 if (dlg->flags & DLG_APPLMODAL)
441 dlg->bGrab = GrabOK(dlg->x11->console,
442 XGrabPointer(dlg->x11->disp, dlg->win.self,
443 True, 0, GrabModeAsync, GrabModeAsync,
444 dlg->win.self, None, CurrentTime));
446 dlg->x11->Flush(dlg->x11);
449 static void ExitDlg(t_dlg *dlg)
453 XUngrabPointer(dlg->x11->disp, CurrentTime);
457 if (dlg->flags & DLG_FREEONBUTTON)
463 static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data)
465 t_dlg *dlg = (t_dlg *)data;
469 if ((dlgitem = FindWin(dlg, w)) != NULL)
471 nWndProc = (dlgitem->WndProc)(x11, dlgitem, event);
473 fprintf(x11->console,
474 "window: %s, nWndProc: %d\n", dlgitem->win.text, nWndProc);
480 if ((dlgitem->type == edlgBN) && (dlgitem->u.button.bDefault))
484 dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
493 for (i = 0; (i < dlg->nitem); i++)
495 if ((dlg->dlgitem[i]->type == edlgBN) &&
496 (dlg->dlgitem[i]->u.button.bDefault))
498 PushMouse(x11->disp, dlg->dlgitem[i]->win.self,
499 dlg->dlgitem[i]->win.width/2,
500 dlg->dlgitem[i]->win.height/2);
509 dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
518 int gid = dlgitem->GroupID;
519 t_id tid = RBSelected(dlg, gid);
521 fprintf(stderr, "RBPRESSED\n");
525 t_dlgitem *dit = FindItem(dlg, tid);
526 dit->u.radiobutton.bSelect = false;
527 ExposeWin(x11->disp, dit->win.self);
531 gmx_fatal(FARGS, "No RB Selected initially!\n");
533 dlgitem->u.radiobutton.bSelect = true;
534 ExposeWin(x11->disp, dlgitem->win.self);
537 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->win.text, dlg->data);
542 ExposeWin(x11->disp, dlgitem->win.self);
545 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->set, dlg->data);
549 ExposeWin(x11->disp, dlgitem->win.self);
552 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->u.edittext.buf, dlg->data);
556 HelpNow(dlg, dlgitem);
561 gmx_fatal(FARGS, "Invalid return code (%d) from wndproc\n", nWndProc);
564 else if (w == dlg->win.self)
573 if (HelpPressed(event))
579 XBell(x11->disp, 50);
589 /*****************************
591 * Routine to add an item to the dialog box
592 * The pointer to the item is copied to the dlg struct,
593 * the item itself may not be freed until the dlg is done with
595 ****************************/
596 void DoCreateDlg(t_dlg *dlg)
599 XSetWindowAttributes attr;
602 attr.border_pixel = dlg->x11->fg;
603 attr.background_pixel = dlg->bg;
604 attr.override_redirect = False;
605 attr.save_under = True;
606 attr.cursor = XCreateFontCursor(dlg->x11->disp, XC_hand2);
607 Val = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder |
609 dlg->win.self = XCreateWindow(dlg->x11->disp, dlg->wDad,
610 dlg->win.x, dlg->win.y,
611 dlg->win.width, dlg->win.height,
612 dlg->win.bwidth, CopyFromParent,
613 InputOutput, CopyFromParent,
615 dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad,
617 dlg->x11->SetInputMask(dlg->x11, dlg->win.self,
618 ExposureMask | ButtonPressMask | KeyPressMask);
620 if (!CheckWindow(dlg->win.self))
624 hints.x = dlg->win.x;
625 hints.y = dlg->win.y;
626 hints.flags = PPosition;
627 XSetStandardProperties(dlg->x11->disp, dlg->win.self, dlg->title,
628 dlg->title, None, NULL, 0, &hints);
631 void AddDlgItem(t_dlg *dlg, t_dlgitem *item)
633 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
634 #define UserMask (ButtonPressMask | KeyPressMask)
635 static unsigned long InputMask[edlgNR] = {
636 ExposureMask | UserMask | EnterLeaveMask, /* edlgBN */
637 ExposureMask | UserMask | EnterLeaveMask, /* edlgRB */
638 ExposureMask, /* edlgGB */
639 ExposureMask | UserMask | EnterLeaveMask, /* edlgCB */
641 ExposureMask, /* edlgST */
642 ExposureMask | UserMask | EnterLeaveMask /* edlgET */
649 srenew(dlg->dlgitem, dlg->nitem+1);
652 gmx_fatal(FARGS, "dlgitem not allocated");
655 XCreateSimpleWindow(dlg->x11->disp, dlg->win.self, item->win.x, item->win.y,
656 item->win.width, item->win.height,
657 item->win.bwidth, dlg->x11->fg, dlg->x11->bg);
658 CheckWindow(item->win.self);
660 dlg->x11->RegisterCallback(dlg->x11, item->win.self, dlg->win.self,
662 dlg->x11->SetInputMask(dlg->x11, item->win.self, InputMask[item->type]);
667 XSetWindowBackgroundPixmap(dlg->x11->disp, item->win.self, item->u.pixmap.pm);
672 dlg->dlgitem[dlg->nitem] = item;
677 void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[])
681 for (i = 0; (i < nitem); i++)
684 fprintf(dlg->x11->console,
685 "Adding item: %d from group %d\n", item[i]->ID, item[i]->GroupID);
686 dlg->x11->Flush(dlg->x11);
688 AddDlgItem(dlg, item[i]);
692 void FreeDlgItem(t_dlg *dlg, t_id id)
697 if ((dlgitem = FindItem(dlg, id)) != NULL)
699 dlg->x11->UnRegisterCallback(dlg->x11, dlgitem->win.self);
700 if (dlgitem->win.self)
702 XDestroyWindow(dlg->x11->disp, dlgitem->win.self);
704 FreeWin(dlg->x11->disp, &(dlgitem->win));
705 switch (dlgitem->type)
711 sfree(dlgitem->u.groupbox.item);
716 XFreePixmap(dlg->x11->disp, dlgitem->u.pixmap.pm);
719 for (i = 0; (i < dlgitem->u.statictext.nlines); i++)
721 sfree(dlgitem->u.statictext.lines[i]);
723 sfree(dlgitem->u.statictext.lines);
726 sfree(dlgitem->u.edittext.buf);
734 void FreeDlg(t_dlg *dlg)
741 dlg->x11->UnRegisterCallback(dlg->x11, dlg->win.self);
742 for (i = 0; (i < dlg->nitem); i++)
744 FreeDlgItem(dlg, dlg->dlgitem[i]->ID);
747 sfree(dlg->dlgitem[i]);
753 XDestroyWindow(dlg->x11->disp, dlg->win.self);
759 /*****************************
761 * Routine to create the DLG structure, returns NULL on failure
763 ****************************/
764 t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title,
765 int x0, int y0, int w, int h, int bw,
766 DlgCallback *cb, void *data)
777 dlg->title = strdup(title);
794 dlg->xmax = DisplayWidth(x11->disp, x11->screen);
795 dlg->ymax = DisplayHeight(x11->disp, x11->screen);
802 XGetGeometry(x11->disp, Parent, &root, &x, &y,
803 &(dlg->xmax), &(dlg->ymax), &dum, &dum);
805 fprintf(x11->console,
806 "Daddy is %d x %d at %d, %d\n", dlg->xmax, dlg->ymax, x, y);
807 dlg->x11->Flush(dlg->x11);
818 InitWin(&(dlg->win), x, y, w, h, bw, NULL);
819 SetDlgSize(dlg, w, h, x0 || y0);
831 void SetDlgSize(t_dlg *dlg, int w, int h, bool bAutoPosition)
846 fprintf(dlg->x11->console, "SetDlgSize: Dialog is %dx%d, at %d,%d\n",
847 dlg->win.width, dlg->win.height, dlg->win.x, dlg->win.y);
848 dlg->x11->Flush(dlg->x11);
852 XMoveWindow(dlg->x11->disp, dlg->win.self, dlg->win.x, dlg->win.y);
853 XResizeWindow(dlg->x11->disp, dlg->win.self, w, h);