6705135365fe0e6c5578a9ab32f654e89bc467b1
[alexxy/gromacs.git] / src / ngmx / xdlg.c
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
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.
14
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.
19  *
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.
26  *
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.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include "string2.h"
43 #include "macros.h"
44 #include "smalloc.h"
45 #include "Xstuff.h"
46 #include "xutil.h"
47 #include "xdlg.h"
48 #include "xmb.h"
49 #include "gmx_fatal.h"
50 /*****************************
51  *
52  * Helpful routines
53  *
54  ****************************/
55 t_dlgitem *FindItem(t_dlg *dlg, t_id id)
56 {
57     int i;
58
59     for (i = 0; (i < dlg->nitem); i++)
60     {
61         if (dlg->dlgitem[i]->ID == id)
62         {
63             return dlg->dlgitem[i];
64         }
65     }
66     return NULL;
67 }
68
69 t_dlgitem *FindWin(t_dlg *dlg, Window win)
70 {
71     int i;
72
73     for (i = 0; (i < dlg->nitem); i++)
74     {
75         if (dlg->dlgitem[i]->win.self == win)
76         {
77             return dlg->dlgitem[i];
78         }
79     }
80     return NULL;
81 }
82
83 /*****************************
84  *
85  * Routines to manipulate items on a dialog box
86  *
87  ****************************/
88 gmx_bool QueryDlgItemSize(t_dlg *dlg, t_id id, int *w, int *h)
89 {
90     t_dlgitem *dlgitem;
91
92     if ((dlgitem = FindItem(dlg, id)) != NULL)
93     {
94         *w = dlgitem->win.width;
95         *h = dlgitem->win.height;
96         return TRUE;
97     }
98     return FALSE;
99 }
100
101 gmx_bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0)
102 {
103     t_dlgitem *dlgitem;
104
105     if ((dlgitem = FindItem(dlg, id)) != NULL)
106     {
107         *x0 = dlgitem->win.x;
108         *y0 = dlgitem->win.y;
109         return TRUE;
110     }
111     return FALSE;
112 }
113
114 int QueryDlgItemX(t_dlg *dlg, t_id id)
115 {
116     t_dlgitem *dlgitem;
117
118     if ((dlgitem = FindItem(dlg, id)) != NULL)
119     {
120         return dlgitem->win.x;
121     }
122     return 0;
123 }
124
125 int QueryDlgItemY(t_dlg *dlg, t_id id)
126 {
127     t_dlgitem *dlgitem;
128
129     if ((dlgitem = FindItem(dlg, id)) != NULL)
130     {
131         return dlgitem->win.y;
132     }
133     return 0;
134 }
135
136 int QueryDlgItemW(t_dlg *dlg, t_id id)
137 {
138     t_dlgitem *dlgitem;
139
140     if ((dlgitem = FindItem(dlg, id)) != NULL)
141     {
142         return dlgitem->win.width;
143     }
144     return 0;
145 }
146
147 int QueryDlgItemH(t_dlg *dlg, t_id id)
148 {
149     t_dlgitem *dlgitem;
150
151     if ((dlgitem = FindItem(dlg, id)) != NULL)
152     {
153         return dlgitem->win.height;
154     }
155     return 0;
156 }
157
158 gmx_bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h)
159 {
160     t_dlgitem *dlgitem;
161 #ifdef DEBUG
162     int        old_w, old_h;
163 #endif
164
165     if ((dlgitem = FindItem(dlg, id)) != NULL)
166     {
167 #ifdef DEBUG
168         old_w = dlgitem->win.width;
169         old_h = dlgitem->win.height;
170 #endif
171         if (w)
172         {
173             dlgitem->win.width = w;
174         }
175         if (h)
176         {
177             dlgitem->win.height = h;
178         }
179 #ifdef DEBUG
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);
184 #endif
185         if (dlgitem->win.self)
186         {
187             XResizeWindow(dlg->x11->disp, dlgitem->win.self, dlgitem->win.width,
188                           dlgitem->win.height);
189         }
190         if ((w) && (dlgitem->type == edlgGB))
191         {
192             int  i;
193             t_id gid = dlgitem->GroupID;
194             t_id id  = dlgitem->ID;
195             for (i = 0; (i < dlg->nitem); i++)
196             {
197                 t_dlgitem *child = dlg->dlgitem[i];
198                 if ((child->GroupID == gid) && (child->ID != id))
199                 {
200                     SetDlgItemSize(dlg, child->ID, w-4*OFFS_X, 0);
201                 }
202             }
203         }
204         return TRUE;
205     }
206     return FALSE;
207 }
208
209 gmx_bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0)
210 {
211     t_dlgitem *dlgitem;
212     int        old_x, old_y;
213
214     if ((dlgitem = FindItem(dlg, id)) != NULL)
215     {
216         old_x          = dlgitem->win.x;
217         old_y          = dlgitem->win.y;
218         dlgitem->win.x = x0;
219         dlgitem->win.y = y0;
220 #ifdef DEBUG
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);
224 #endif
225         if (dlgitem->win.self)
226         {
227             XMoveWindow(dlg->x11->disp, dlgitem->win.self, x0, y0);
228         }
229         if (dlgitem->type == edlgGB)
230         {
231             int  i, x, y;
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++)
237             {
238                 t_dlgitem *child = dlg->dlgitem[i];
239                 if ((child->GroupID == gid) && (child->ID != id))
240                 {
241                     SetDlgItemPos(dlg, child->ID, child->win.x+x, child->win.y+y);
242                 }
243             }
244         }
245         return TRUE;
246     }
247     return FALSE;
248 }
249
250 /*****************************
251  *
252  * Routines to extract information from the dlg proc
253  * after dlg is exec'ed
254  *
255  ****************************/
256 gmx_bool IsCBChecked(t_dlg *dlg, t_id id)
257 {
258     t_dlgitem *dlgitem;
259
260     if ((dlgitem = FindItem(dlg, id)) != NULL)
261     {
262         if (dlgitem->type == edlgCB)
263         {
264             return dlgitem->u.checkbox.bChecked;
265         }
266     }
267
268     return FALSE;
269 }
270
271 t_id RBSelected(t_dlg *dlg, int gid)
272 {
273     int i;
274
275     for (i = 0; (i < dlg->nitem); i++)
276     {
277         if ((dlg->dlgitem[i]->type == edlgRB) &&
278             (dlg->dlgitem[i]->u.radiobutton.bSelect) &&
279             (dlg->dlgitem[i]->GroupID == gid))
280         {
281             return dlg->dlgitem[i]->ID;
282         }
283     }
284
285     return -1;
286 }
287
288 int EditTextLen(t_dlg *dlg, t_id id)
289 {
290     t_dlgitem *dlgitem;
291
292     if ((dlgitem = FindItem(dlg, id)) != NULL)
293     {
294         if (dlgitem->type == edlgET)
295         {
296             return strlen(dlgitem->u.edittext.buf);
297         }
298     }
299
300     return 0;
301 }
302
303 char *EditText(t_dlg *dlg, t_id id)
304 {
305     t_dlgitem *dlgitem;
306
307     if ((dlgitem = FindItem(dlg, id)) != NULL)
308     {
309         if (dlgitem->type == edlgET)
310         {
311             return dlgitem->u.edittext.buf;
312         }
313     }
314
315     return NULL;
316 }
317
318 /*****************************
319  *
320  * Exececute the dialog box procedure
321  * Returns when a button is pushed.
322  * return value is the ID of the button
323  *
324  ****************************/
325 void ShowDlg(t_dlg *dlg)
326 {
327     int        i;
328     t_dlgitem *dlgitem;
329
330     XMapWindow(dlg->x11->disp, dlg->win.self);
331     XMapSubwindows(dlg->x11->disp, dlg->win.self);
332     for (i = 0; (i < dlg->nitem); i++)
333     {
334         LightBorder(dlg->x11->disp, dlg->dlgitem[i]->win.self, dlg->bg);
335     }
336     XSetForeground(dlg->x11->disp, dlg->x11->gc, dlg->x11->fg);
337     for (i = 0; (i < dlg->nitem); i++)
338     {
339         dlgitem = dlg->dlgitem[i];
340         if ((dlgitem->type == edlgBN) &&
341             (dlgitem->u.button.bDefault))
342         {
343             PushMouse(dlg->x11->disp, dlgitem->win.self,
344                       dlgitem->win.width/2, dlgitem->win.height/2);
345             dlg->bPop = TRUE;
346             break;
347         }
348     }
349     dlg->bGrab = FALSE;
350 }
351
352 void HideDlg(t_dlg *dlg)
353 {
354     if (dlg->bPop)
355     {
356         PopMouse(dlg->x11->disp);
357     }
358
359     XUnmapSubwindows(dlg->x11->disp, dlg->win.self);
360     XUnmapWindow(dlg->x11->disp, dlg->win.self);
361 }
362
363 void NoHelp(t_dlg *dlg)
364 {
365     char **lines = NULL;
366
367     snew(lines, 2);
368     lines[0] = strdup("Error");
369     lines[1] = strdup("No help for this item");
370     MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines,
371                MB_OK | MB_ICONSTOP | MB_APPLMODAL, NULL, NULL);
372     sfree(lines[0]);
373     sfree (lines[1]);
374     sfree(lines);
375 }
376
377 void HelpDlg(t_dlg *dlg)
378 {
379     char *lines[] = {
380         "Place the cursor over one of the items",
381         "and press the F1 key to get more help.",
382         "First press the OK button."
383     };
384     MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox",
385                3, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, NULL, NULL);
386 }
387
388 void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem)
389 {
390     char     buf[80];
391     gmx_bool bCont = TRUE;
392     int      i, nlines = 0;
393     char   **lines = NULL;
394
395     if (!dlgitem->help)
396     {
397         NoHelp(dlg);
398         return;
399     }
400
401     printf("%s\n", dlgitem->help);
402     do
403     {
404         fgets2(buf, 79, stdin);
405 #ifdef DEBUG
406         fprintf(dlg->x11->console, "buffer: '%s'\n", buf);
407         dlg->x11->Flush(dlg->x11);
408 #endif
409         if (gmx_strcasecmp(buf, "nok") == 0)
410         {
411             /* An error occurred */
412             for (i = 0; (i < nlines); i++)
413             {
414                 sfree(lines[i]);
415             }
416             sfree(lines);
417             NoHelp(dlg);
418             return;
419         }
420         else
421         {
422             bCont = (gmx_strcasecmp(buf, "ok") != 0);
423             if (bCont)
424             {
425                 srenew(lines, ++nlines);
426                 lines[nlines-1] = strdup(buf);
427             }
428         }
429     }
430     while (bCont);
431     MessageBox(dlg->x11, dlg->wDad, "Help",
432                nlines, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, NULL, NULL);
433     for (i = 0; (i < nlines); i++)
434     {
435         sfree(lines[i]);
436     }
437     sfree(lines);
438 }
439
440 static void EnterDlg(t_dlg *dlg)
441 {
442     if (dlg->flags & DLG_APPLMODAL)
443     {
444         dlg->bGrab = GrabOK(dlg->x11->console,
445                             XGrabPointer(dlg->x11->disp, dlg->win.self,
446                                          True, 0, GrabModeAsync, GrabModeAsync,
447                                          dlg->win.self, None, CurrentTime));
448     }
449     dlg->x11->Flush(dlg->x11);
450 }
451
452 static void ExitDlg(t_dlg *dlg)
453 {
454     if (dlg->bGrab)
455     {
456         XUngrabPointer(dlg->x11->disp, CurrentTime);
457         dlg->bGrab = FALSE;
458     }
459     HideDlg(dlg);
460     if (dlg->flags & DLG_FREEONBUTTON)
461     {
462         FreeDlg(dlg);
463     }
464 }
465
466 static gmx_bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data)
467 {
468     t_dlg     *dlg = (t_dlg *)data;
469     int        i, nWndProc;
470     t_dlgitem *dlgitem;
471
472     if ((dlgitem = FindWin(dlg, w)) != NULL)
473     {
474         nWndProc = (dlgitem->WndProc)(x11, dlgitem, event);
475 #ifdef DEBUG
476         fprintf(x11->console,
477                 "window: %s, nWndProc: %d\n", dlgitem->win.text, nWndProc);
478         x11->Flush(x11);
479 #endif
480         switch (nWndProc)
481         {
482             case ENTERPRESSED:
483                 if ((dlgitem->type == edlgBN) && (dlgitem->u.button.bDefault))
484                 {
485                     if (dlg->cb)
486                     {
487                         dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
488                     }
489                     else
490                     {
491                         ExitDlg(dlg);
492                     }
493                 }
494                 else
495                 {
496                     for (i = 0; (i < dlg->nitem); i++)
497                     {
498                         if ((dlg->dlgitem[i]->type == edlgBN) &&
499                             (dlg->dlgitem[i]->u.button.bDefault))
500                         {
501                             PushMouse(x11->disp, dlg->dlgitem[i]->win.self,
502                                       dlg->dlgitem[i]->win.width/2,
503                                       dlg->dlgitem[i]->win.height/2);
504                             break;
505                         }
506                     }
507                 }
508                 break;
509             case BNPRESSED:
510                 if (dlg->cb)
511                 {
512                     dlg->cb(x11, DLG_EXIT, dlgitem->ID, dlgitem->win.text, dlg->data);
513                 }
514                 else
515                 {
516                     ExitDlg(dlg);
517                 }
518                 break;
519             case RBPRESSED:
520             {
521                 int  gid = dlgitem->GroupID;
522                 t_id tid = RBSelected(dlg, gid);
523 #ifdef DEBUG
524                 fprintf(stderr, "RBPRESSED\n");
525 #endif
526                 if (tid != -1)
527                 {
528                     t_dlgitem *dit = FindItem(dlg, tid);
529                     dit->u.radiobutton.bSelect = FALSE;
530                     ExposeWin(x11->disp, dit->win.self);
531                 }
532                 else
533                 {
534                     gmx_fatal(FARGS, "No RB Selected initially!\n");
535                 }
536                 dlgitem->u.radiobutton.bSelect = TRUE;
537                 ExposeWin(x11->disp, dlgitem->win.self);
538                 if (dlg->cb)
539                 {
540                     dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->win.text, dlg->data);
541                 }
542                 break;
543             }
544             case CBPRESSED:
545                 ExposeWin(x11->disp, dlgitem->win.self);
546                 if (dlg->cb)
547                 {
548                     dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->set, dlg->data);
549                 }
550                 break;
551             case ETCHANGED:
552                 ExposeWin(x11->disp, dlgitem->win.self);
553                 if (dlg->cb)
554                 {
555                     dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->u.edittext.buf, dlg->data);
556                 }
557                 break;
558             case HELPPRESSED:
559                 HelpNow(dlg, dlgitem);
560                 break;
561             case ITEMOK:
562                 break;
563             default:
564                 gmx_fatal(FARGS, "Invalid return code (%d) from wndproc\n", nWndProc);
565         }
566     }
567     else if (w == dlg->win.self)
568     {
569         switch (event->type)
570         {
571             case Expose:
572                 EnterDlg(dlg);
573                 break;
574             case ButtonPress:
575             case KeyPress:
576                 if (HelpPressed(event))
577                 {
578                     HelpDlg(dlg);
579                 }
580                 else
581                 {
582                     XBell(x11->disp, 50);
583                 }
584                 break;
585             default:
586                 break;
587         }
588     }
589     return FALSE;
590 }
591
592 /*****************************
593  *
594  * Routine to add an item to the dialog box
595  * The pointer to the item is copied to the dlg struct,
596  * the item itself may not be freed until the dlg is done with
597  *
598  ****************************/
599 void DoCreateDlg(t_dlg *dlg)
600 {
601     XSizeHints           hints;
602     XSetWindowAttributes attr;
603     unsigned long        Val;
604
605     attr.border_pixel      = dlg->x11->fg;
606     attr.background_pixel  = dlg->bg;
607     attr.override_redirect = False;
608     attr.save_under        = True;
609     attr.cursor            = XCreateFontCursor(dlg->x11->disp, XC_hand2);
610     Val                    = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder |
611         CWCursor;
612     dlg->win.self = XCreateWindow(dlg->x11->disp, dlg->wDad,
613                                   dlg->win.x, dlg->win.y,
614                                   dlg->win.width, dlg->win.height,
615                                   dlg->win.bwidth, CopyFromParent,
616                                   InputOutput, CopyFromParent,
617                                   Val, &attr);
618     dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad,
619                                DlgCB, dlg);
620     dlg->x11->SetInputMask(dlg->x11, dlg->win.self,
621                            ExposureMask | ButtonPressMask | KeyPressMask);
622
623     if (!CheckWindow(dlg->win.self))
624     {
625         exit(1);
626     }
627     hints.x     = dlg->win.x;
628     hints.y     = dlg->win.y;
629     hints.flags = PPosition;
630     XSetStandardProperties(dlg->x11->disp, dlg->win.self, dlg->title,
631                            dlg->title, None, NULL, 0, &hints);
632 }
633
634 void AddDlgItem(t_dlg *dlg, t_dlgitem *item)
635 {
636 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
637 #define UserMask (ButtonPressMask | KeyPressMask)
638     static unsigned long InputMask[edlgNR] = {
639         ExposureMask | UserMask | EnterLeaveMask, /* edlgBN */
640         ExposureMask | UserMask | EnterLeaveMask, /* edlgRB */
641         ExposureMask,                             /* edlgGB */
642         ExposureMask | UserMask | EnterLeaveMask, /* edlgCB */
643         0,                                        /* edlgPM */
644         ExposureMask,                             /* edlgST */
645         ExposureMask | UserMask | EnterLeaveMask  /* edlgET */
646     };
647
648     if (!dlg->win.self)
649     {
650         DoCreateDlg(dlg);
651     }
652     srenew(dlg->dlgitem, dlg->nitem+1);
653     if (!item)
654     {
655         gmx_fatal(FARGS, "dlgitem not allocated");
656     }
657     item->win.self =
658         XCreateSimpleWindow(dlg->x11->disp, dlg->win.self, item->win.x, item->win.y,
659                             item->win.width, item->win.height,
660                             item->win.bwidth, dlg->x11->fg, dlg->x11->bg);
661     CheckWindow(item->win.self);
662
663     dlg->x11->RegisterCallback(dlg->x11, item->win.self, dlg->win.self,
664                                DlgCB, dlg);
665     dlg->x11->SetInputMask(dlg->x11, item->win.self, InputMask[item->type]);
666
667     switch (item->type)
668     {
669         case edlgPM:
670             XSetWindowBackgroundPixmap(dlg->x11->disp, item->win.self, item->u.pixmap.pm);
671             break;
672         default:
673             break;
674     }
675     dlg->dlgitem[dlg->nitem] = item;
676
677     dlg->nitem++;
678 }
679
680 void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[])
681 {
682     int i;
683
684     for (i = 0; (i < nitem); i++)
685     {
686 #ifdef DEBUG
687         fprintf(dlg->x11->console,
688                 "Adding item: %d from group %d\n", item[i]->ID, item[i]->GroupID);
689         dlg->x11->Flush(dlg->x11);
690 #endif
691         AddDlgItem(dlg, item[i]);
692     }
693 }
694
695 void FreeDlgItem(t_dlg *dlg, t_id id)
696 {
697     t_dlgitem *dlgitem;
698     int        i;
699
700     if ((dlgitem = FindItem(dlg, id)) != NULL)
701     {
702         dlg->x11->UnRegisterCallback(dlg->x11, dlgitem->win.self);
703         if (dlgitem->win.self)
704         {
705             XDestroyWindow(dlg->x11->disp, dlgitem->win.self);
706         }
707         FreeWin(dlg->x11->disp, &(dlgitem->win));
708         switch (dlgitem->type)
709         {
710             case edlgBN:
711             case edlgRB:
712                 break;
713             case edlgGB:
714                 sfree(dlgitem->u.groupbox.item);
715                 break;
716             case edlgCB:
717                 break;
718             case edlgPM:
719                 XFreePixmap(dlg->x11->disp, dlgitem->u.pixmap.pm);
720                 break;
721             case edlgST:
722                 for (i = 0; (i < dlgitem->u.statictext.nlines); i++)
723                 {
724                     sfree(dlgitem->u.statictext.lines[i]);
725                 }
726                 sfree(dlgitem->u.statictext.lines);
727                 break;
728             case edlgET:
729                 sfree(dlgitem->u.edittext.buf);
730                 break;
731             default:
732                 break;
733         }
734     }
735 }
736
737 void FreeDlg(t_dlg *dlg)
738 {
739     int i;
740
741     if (dlg->dlgitem)
742     {
743         HideDlg(dlg);
744         dlg->x11->UnRegisterCallback(dlg->x11, dlg->win.self);
745         for (i = 0; (i < dlg->nitem); i++)
746         {
747             FreeDlgItem(dlg, dlg->dlgitem[i]->ID);
748             if (dlg->dlgitem[i])
749             {
750                 sfree(dlg->dlgitem[i]);
751             }
752         }
753         sfree(dlg->dlgitem);
754         if (dlg->win.self)
755         {
756             XDestroyWindow(dlg->x11->disp, dlg->win.self);
757         }
758         dlg->dlgitem = NULL;
759     }
760 }
761
762 /*****************************
763  *
764  * Routine to create the DLG structure, returns NULL on failure
765  *
766  ****************************/
767 t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title,
768                  int x0, int y0, int w, int h, int bw, unsigned long fg, unsigned long bg,
769                  DlgCallback *cb, void *data)
770 {
771     t_dlg   *dlg;
772     int      x = 0, y = 0;
773
774     snew(dlg, 1);
775     dlg->x11  = x11;
776     dlg->cb   = cb;
777     dlg->data = data;
778     if (title)
779     {
780         dlg->title = strdup(title);
781     }
782     else
783     {
784         dlg->title = NULL;
785     }
786     if (w == 0)
787     {
788         w = 1;
789     }
790     if (h == 0)
791     {
792         h = 1;
793     }
794     if (!Parent)
795     {
796         Parent    = x11->root;
797         dlg->xmax = DisplayWidth(x11->disp, x11->screen);
798         dlg->ymax = DisplayHeight(x11->disp, x11->screen);
799     }
800     else
801     {
802         Window         root;
803         unsigned int   dum;
804
805         XGetGeometry(x11->disp, Parent, &root, &x, &y,
806                      &(dlg->xmax), &(dlg->ymax), &dum, &dum);
807 #ifdef DEBUG
808         fprintf(x11->console,
809                 "Daddy is %d x %d at %d, %d\n", dlg->xmax, dlg->ymax, x, y);
810         dlg->x11->Flush(dlg->x11);
811 #endif
812     }
813     if (x0)
814     {
815         x = x0;
816     }
817     if (y0)
818     {
819         y = y0;
820     }
821     InitWin(&(dlg->win), x, y, w, h, bw, NULL);
822     SetDlgSize(dlg, w, h, x0 || y0);
823
824     dlg->wDad    = Parent;
825     dlg->fg      = x11->fg;
826     dlg->bg      = x11->bg;
827     dlg->nitem   = 0;
828     dlg->dlgitem = NULL;
829
830     DoCreateDlg(dlg);
831     return dlg;
832 }
833
834 void SetDlgSize(t_dlg *dlg, int w, int h, gmx_bool bAutoPosition)
835 {
836     if (bAutoPosition)
837     {
838         int x, y;
839
840         x          = (dlg->xmax-w)/2;
841         y          = (dlg->ymax-h)/2;
842         dlg->win.x = x;
843         dlg->win.y = y;
844     }
845     dlg->win.width  = w;
846     dlg->win.height = h;
847
848 #ifdef DEBUG
849     fprintf(dlg->x11->console, "SetDlgSize: Dialog is %dx%d, at %d,%d\n",
850             dlg->win.width, dlg->win.height, dlg->win.x, dlg->win.y);
851     dlg->x11->Flush(dlg->x11);
852 #endif
853     if (dlg->win.self)
854     {
855         XMoveWindow(dlg->x11->disp, dlg->win.self, dlg->win.x, dlg->win.y);
856         XResizeWindow(dlg->x11->disp, dlg->win.self, w, h);
857     }
858 }