Fix detection of i386 in tmpi
[gromacs/AngularHB.git] / src / ngmx / xdlg.c
blob7168637934833acdf6688c82da4c54ed89aa6a59
1 /*
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.
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include "string2.h"
46 #include "macros.h"
47 #include "smalloc.h"
48 #include "Xstuff.h"
49 #include "xutil.h"
50 #include "xdlg.h"
51 #include "xmb.h"
52 #include "gmx_fatal.h"
53 /*****************************
55 * Helpful routines
57 ****************************/
58 t_dlgitem *FindItem(t_dlg *dlg, t_id id)
60 int i;
62 for (i = 0; (i < dlg->nitem); i++)
64 if (dlg->dlgitem[i]->ID == id)
66 return dlg->dlgitem[i];
69 return NULL;
72 t_dlgitem *FindWin(t_dlg *dlg, Window win)
74 int i;
76 for (i = 0; (i < dlg->nitem); i++)
78 if (dlg->dlgitem[i]->win.self == win)
80 return dlg->dlgitem[i];
83 return NULL;
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)
93 t_dlgitem *dlgitem;
95 if ((dlgitem = FindItem(dlg, id)) != NULL)
97 *w = dlgitem->win.width;
98 *h = dlgitem->win.height;
99 return TRUE;
101 return FALSE;
104 gmx_bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0)
106 t_dlgitem *dlgitem;
108 if ((dlgitem = FindItem(dlg, id)) != NULL)
110 *x0 = dlgitem->win.x;
111 *y0 = dlgitem->win.y;
112 return TRUE;
114 return FALSE;
117 int QueryDlgItemX(t_dlg *dlg, t_id id)
119 t_dlgitem *dlgitem;
121 if ((dlgitem = FindItem(dlg, id)) != NULL)
123 return dlgitem->win.x;
125 return 0;
128 int QueryDlgItemY(t_dlg *dlg, t_id id)
130 t_dlgitem *dlgitem;
132 if ((dlgitem = FindItem(dlg, id)) != NULL)
134 return dlgitem->win.y;
136 return 0;
139 int QueryDlgItemW(t_dlg *dlg, t_id id)
141 t_dlgitem *dlgitem;
143 if ((dlgitem = FindItem(dlg, id)) != NULL)
145 return dlgitem->win.width;
147 return 0;
150 int QueryDlgItemH(t_dlg *dlg, t_id id)
152 t_dlgitem *dlgitem;
154 if ((dlgitem = FindItem(dlg, id)) != NULL)
156 return dlgitem->win.height;
158 return 0;
161 gmx_bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h)
163 t_dlgitem *dlgitem;
164 #ifdef DEBUG
165 int old_w, old_h;
166 #endif
168 if ((dlgitem = FindItem(dlg, id)) != NULL)
170 #ifdef DEBUG
171 old_w = dlgitem->win.width;
172 old_h = dlgitem->win.height;
173 #endif
174 if (w)
176 dlgitem->win.width = w;
178 if (h)
180 dlgitem->win.height = h;
182 #ifdef DEBUG
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);
187 #endif
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))
195 int i;
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);
207 return TRUE;
209 return FALSE;
212 gmx_bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0)
214 t_dlgitem *dlgitem;
215 int old_x, old_y;
217 if ((dlgitem = FindItem(dlg, id)) != NULL)
219 old_x = dlgitem->win.x;
220 old_y = dlgitem->win.y;
221 dlgitem->win.x = x0;
222 dlgitem->win.y = y0;
223 #ifdef DEBUG
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);
227 #endif
228 if (dlgitem->win.self)
230 XMoveWindow(dlg->x11->disp, dlgitem->win.self, x0, y0);
232 if (dlgitem->type == edlgGB)
234 int i, x, y;
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);
248 return TRUE;
250 return FALSE;
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)
261 t_dlgitem *dlgitem;
263 if ((dlgitem = FindItem(dlg, id)) != NULL)
265 if (dlgitem->type == edlgCB)
267 return dlgitem->u.checkbox.bChecked;
271 return FALSE;
274 t_id RBSelected(t_dlg *dlg, int gid)
276 int i;
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;
288 return -1;
291 int EditTextLen(t_dlg *dlg, t_id id)
293 t_dlgitem *dlgitem;
295 if ((dlgitem = FindItem(dlg, id)) != NULL)
297 if (dlgitem->type == edlgET)
299 return strlen(dlgitem->u.edittext.buf);
303 return 0;
306 char *EditText(t_dlg *dlg, t_id id)
308 t_dlgitem *dlgitem;
310 if ((dlgitem = FindItem(dlg, id)) != NULL)
312 if (dlgitem->type == edlgET)
314 return dlgitem->u.edittext.buf;
318 return NULL;
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)
330 int i;
331 t_dlgitem *dlgitem;
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);
348 dlg->bPop = TRUE;
349 break;
352 dlg->bGrab = FALSE;
355 void HideDlg(t_dlg *dlg)
357 if (dlg->bPop)
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)
368 char **lines = NULL;
370 snew(lines, 2);
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);
375 sfree(lines[0]);
376 sfree (lines[1]);
377 sfree(lines);
380 void HelpDlg(t_dlg *dlg)
382 char *lines[] = {
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)
393 char buf[80];
394 gmx_bool bCont = TRUE;
395 int i, nlines = 0;
396 char **lines = NULL;
398 if (!dlgitem->help)
400 NoHelp(dlg);
401 return;
404 printf("%s\n", dlgitem->help);
407 fgets2(buf, 79, stdin);
408 #ifdef DEBUG
409 fprintf(dlg->x11->console, "buffer: '%s'\n", buf);
410 dlg->x11->Flush(dlg->x11);
411 #endif
412 if (gmx_strcasecmp(buf, "nok") == 0)
414 /* An error occurred */
415 for (i = 0; (i < nlines); i++)
417 sfree(lines[i]);
419 sfree(lines);
420 NoHelp(dlg);
421 return;
423 else
425 bCont = (gmx_strcasecmp(buf, "ok") != 0);
426 if (bCont)
428 srenew(lines, ++nlines);
429 lines[nlines-1] = strdup(buf);
433 while (bCont);
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++)
438 sfree(lines[i]);
440 sfree(lines);
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)
457 if (dlg->bGrab)
459 XUngrabPointer(dlg->x11->disp, CurrentTime);
460 dlg->bGrab = FALSE;
462 HideDlg(dlg);
463 if (dlg->flags & DLG_FREEONBUTTON)
465 FreeDlg(dlg);
469 static gmx_bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data)
471 t_dlg *dlg = (t_dlg *)data;
472 int i, nWndProc;
473 t_dlgitem *dlgitem;
475 if ((dlgitem = FindWin(dlg, w)) != NULL)
477 nWndProc = (dlgitem->WndProc)(x11, dlgitem, event);
478 #ifdef DEBUG
479 fprintf(x11->console,
480 "window: %s, nWndProc: %d\n", dlgitem->win.text, nWndProc);
481 x11->Flush(x11);
482 #endif
483 switch (nWndProc)
485 case ENTERPRESSED:
486 if ((dlgitem->type == edlgBN) && (dlgitem->u.button.bDefault))
488 if (dlg->cb)
490 dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
492 else
494 ExitDlg(dlg);
497 else
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);
507 break;
511 break;
512 case BNPRESSED:
513 if (dlg->cb)
515 dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
517 else
519 ExitDlg(dlg);
521 break;
522 case RBPRESSED:
524 int gid = dlgitem->GroupID;
525 t_id tid = RBSelected(dlg, gid);
526 #ifdef DEBUG
527 fprintf(stderr, "RBPRESSED\n");
528 #endif
529 if (tid != -1)
531 t_dlgitem *dit = FindItem(dlg, tid);
532 dit->u.radiobutton.bSelect = FALSE;
533 ExposeWin(x11->disp, dit->win.self);
535 else
537 gmx_fatal(FARGS, "No RB Selected initially!\n");
539 dlgitem->u.radiobutton.bSelect = TRUE;
540 ExposeWin(x11->disp, dlgitem->win.self);
541 if (dlg->cb)
543 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->win.text, dlg->data);
545 break;
547 case CBPRESSED:
548 ExposeWin(x11->disp, dlgitem->win.self);
549 if (dlg->cb)
551 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->set, dlg->data);
553 break;
554 case ETCHANGED:
555 ExposeWin(x11->disp, dlgitem->win.self);
556 if (dlg->cb)
558 dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->u.edittext.buf, dlg->data);
560 break;
561 case HELPPRESSED:
562 HelpNow(dlg, dlgitem);
563 break;
564 case ITEMOK:
565 break;
566 default:
567 gmx_fatal(FARGS, "Invalid return code (%d) from wndproc\n", nWndProc);
570 else if (w == dlg->win.self)
572 switch (event->type)
574 case Expose:
575 EnterDlg(dlg);
576 break;
577 case ButtonPress:
578 case KeyPress:
579 if (HelpPressed(event))
581 HelpDlg(dlg);
583 else
585 XBell(x11->disp, 50);
587 break;
588 default:
589 break;
592 return FALSE;
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)
604 XSizeHints hints;
605 XSetWindowAttributes attr;
606 unsigned long Val;
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 |
614 CWCursor;
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,
620 Val, &attr);
621 dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad,
622 DlgCB, dlg);
623 dlg->x11->SetInputMask(dlg->x11, dlg->win.self,
624 ExposureMask | ButtonPressMask | KeyPressMask);
626 if (!CheckWindow(dlg->win.self))
628 exit(1);
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 */
646 0, /* edlgPM */
647 ExposureMask, /* edlgST */
648 ExposureMask | UserMask | EnterLeaveMask /* edlgET */
651 if (!dlg->win.self)
653 DoCreateDlg(dlg);
655 srenew(dlg->dlgitem, dlg->nitem+1);
656 if (!item)
658 gmx_fatal(FARGS, "dlgitem not allocated");
660 item->win.self =
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,
667 DlgCB, dlg);
668 dlg->x11->SetInputMask(dlg->x11, item->win.self, InputMask[item->type]);
670 switch (item->type)
672 case edlgPM:
673 XSetWindowBackgroundPixmap(dlg->x11->disp, item->win.self, item->u.pixmap.pm);
674 break;
675 default:
676 break;
678 dlg->dlgitem[dlg->nitem] = item;
680 dlg->nitem++;
683 void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[])
685 int i;
687 for (i = 0; (i < nitem); i++)
689 #ifdef DEBUG
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);
693 #endif
694 AddDlgItem(dlg, item[i]);
698 void FreeDlgItem(t_dlg *dlg, t_id id)
700 t_dlgitem *dlgitem;
701 int i;
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)
713 case edlgBN:
714 case edlgRB:
715 break;
716 case edlgGB:
717 sfree(dlgitem->u.groupbox.item);
718 break;
719 case edlgCB:
720 break;
721 case edlgPM:
722 XFreePixmap(dlg->x11->disp, dlgitem->u.pixmap.pm);
723 break;
724 case edlgST:
725 for (i = 0; (i < dlgitem->u.statictext.nlines); i++)
727 sfree(dlgitem->u.statictext.lines[i]);
729 sfree(dlgitem->u.statictext.lines);
730 break;
731 case edlgET:
732 sfree(dlgitem->u.edittext.buf);
733 break;
734 default:
735 break;
740 void FreeDlg(t_dlg *dlg)
742 int i;
744 if (dlg->dlgitem)
746 HideDlg(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);
751 if (dlg->dlgitem[i])
753 sfree(dlg->dlgitem[i]);
756 sfree(dlg->dlgitem);
757 if (dlg->win.self)
759 XDestroyWindow(dlg->x11->disp, dlg->win.self);
761 dlg->dlgitem = NULL;
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)
774 t_dlg *dlg;
775 int x = 0, y = 0;
777 snew(dlg, 1);
778 dlg->x11 = x11;
779 dlg->cb = cb;
780 dlg->data = data;
781 if (title)
783 dlg->title = strdup(title);
785 else
787 dlg->title = NULL;
789 if (w == 0)
791 w = 1;
793 if (h == 0)
795 h = 1;
797 if (!Parent)
799 Parent = x11->root;
800 dlg->xmax = DisplayWidth(x11->disp, x11->screen);
801 dlg->ymax = DisplayHeight(x11->disp, x11->screen);
803 else
805 Window root;
806 unsigned int dum;
808 XGetGeometry(x11->disp, Parent, &root, &x, &y,
809 &(dlg->xmax), &(dlg->ymax), &dum, &dum);
810 #ifdef DEBUG
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);
814 #endif
816 if (x0)
818 x = x0;
820 if (y0)
822 y = y0;
824 InitWin(&(dlg->win), x, y, w, h, bw, NULL);
825 SetDlgSize(dlg, w, h, x0 || y0);
827 dlg->wDad = Parent;
828 dlg->fg = x11->fg;
829 dlg->bg = x11->bg;
830 dlg->nitem = 0;
831 dlg->dlgitem = NULL;
833 DoCreateDlg(dlg);
834 return dlg;
837 void SetDlgSize(t_dlg *dlg, int w, int h, gmx_bool bAutoPosition)
839 if (bAutoPosition)
841 int x, y;
843 x = (dlg->xmax-w)/2;
844 y = (dlg->ymax-h)/2;
845 dlg->win.x = x;
846 dlg->win.y = y;
848 dlg->win.width = w;
849 dlg->win.height = h;
851 #ifdef DEBUG
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);
855 #endif
856 if (dlg->win.self)
858 XMoveWindow(dlg->x11->disp, dlg->win.self, dlg->win.x, dlg->win.y);
859 XResizeWindow(dlg->x11->disp, dlg->win.self, w, h);