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, 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
++)
63 if (dlg
->dlgitem
[i
]->ID
==id
)
64 return dlg
->dlgitem
[i
];
68 t_dlgitem
*FindWin(t_dlg
*dlg
, Window win
)
72 for(i
=0; (i
<dlg
->nitem
); i
++)
73 if (dlg
->dlgitem
[i
]->win
.self
==win
)
74 return dlg
->dlgitem
[i
];
78 /*****************************
80 * Routines to manipulate items on a dialog box
82 ****************************/
83 gmx_bool
QueryDlgItemSize(t_dlg
*dlg
,t_id id
,int *w
,int *h
)
87 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
88 *w
=dlgitem
->win
.width
;
89 *h
=dlgitem
->win
.height
;
95 gmx_bool
QueryDlgItemPos(t_dlg
*dlg
,t_id id
,int *x0
,int *y0
)
99 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
107 int QueryDlgItemX(t_dlg
*dlg
, t_id id
)
111 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
112 return dlgitem
->win
.x
;
116 int QueryDlgItemY(t_dlg
*dlg
, t_id id
)
120 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
121 return dlgitem
->win
.y
;
125 int QueryDlgItemW(t_dlg
*dlg
, t_id id
)
129 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
130 return dlgitem
->win
.width
;
134 int QueryDlgItemH(t_dlg
*dlg
, t_id id
)
138 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
139 return dlgitem
->win
.height
;
143 gmx_bool
SetDlgItemSize(t_dlg
*dlg
,t_id id
,int w
,int h
)
150 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
152 old_w
=dlgitem
->win
.width
;
153 old_h
=dlgitem
->win
.height
;
156 dlgitem
->win
.width
=w
;
158 dlgitem
->win
.height
=h
;
160 fprintf(dlg
->x11
->console
,
161 "Size window from: %dx%d to %dx%d\n",old_w
,old_h
,
162 dlgitem
->win
.width
,dlgitem
->win
.height
);
163 dlg
->x11
->Flush(dlg
->x11
);
165 if (dlgitem
->win
.self
)
166 XResizeWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,dlgitem
->win
.width
,
167 dlgitem
->win
.height
);
168 if ((w
) && (dlgitem
->type
==edlgGB
)) {
170 t_id gid
=dlgitem
->GroupID
;
172 for (i
=0; (i
<dlg
->nitem
); i
++) {
173 t_dlgitem
*child
=dlg
->dlgitem
[i
];
174 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
175 SetDlgItemSize(dlg
,child
->ID
,w
-4*OFFS_X
,0);
183 gmx_bool
SetDlgItemPos(t_dlg
*dlg
,t_id id
,int x0
,int y0
)
188 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
189 old_x
=dlgitem
->win
.x
;
190 old_y
=dlgitem
->win
.y
;
194 fprintf(dlg
->x11
->console
,
195 "Move window from: %d,%d to %d,%d\n",old_x
,old_y
,x0
,y0
);
196 dlg
->x11
->Flush(dlg
->x11
);
198 if (dlgitem
->win
.self
)
199 XMoveWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,x0
,y0
);
200 if (dlgitem
->type
==edlgGB
) {
202 t_id gid
=dlgitem
->GroupID
;
204 x
=dlgitem
->win
.x
+2*OFFS_X
-old_x
;
205 y
=dlgitem
->win
.y
+2*OFFS_Y
-old_y
;
206 for (i
=0; (i
<dlg
->nitem
); i
++) {
207 t_dlgitem
*child
=dlg
->dlgitem
[i
];
208 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
209 SetDlgItemPos(dlg
,child
->ID
,child
->win
.x
+x
,child
->win
.y
+y
);
217 /*****************************
219 * Routines to extract information from the dlg proc
220 * after dlg is exec'ed
222 ****************************/
223 gmx_bool
IsCBChecked(t_dlg
*dlg
,t_id id
)
227 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
228 if (dlgitem
->type
==edlgCB
)
229 return dlgitem
->u
.checkbox
.bChecked
;
234 t_id
RBSelected(t_dlg
*dlg
,int gid
)
238 for(i
=0; (i
<dlg
->nitem
); i
++)
239 if ((dlg
->dlgitem
[i
]->type
==edlgRB
) &&
240 (dlg
->dlgitem
[i
]->u
.radiobutton
.bSelect
) &&
241 (dlg
->dlgitem
[i
]->GroupID
==gid
))
242 return dlg
->dlgitem
[i
]->ID
;
247 int EditTextLen(t_dlg
*dlg
,t_id id
)
251 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
252 if (dlgitem
->type
==edlgET
)
253 return strlen(dlgitem
->u
.edittext
.buf
);
258 char *EditText(t_dlg
*dlg
,t_id id
)
262 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
263 if (dlgitem
->type
==edlgET
)
264 return dlgitem
->u
.edittext
.buf
;
269 /*****************************
271 * Exececute the dialog box procedure
272 * Returns when a button is pushed.
273 * return value is the ID of the button
275 ****************************/
276 void ShowDlg(t_dlg
*dlg
)
281 XMapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
282 XMapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
283 for (i
=0; (i
<dlg
->nitem
); i
++)
284 LightBorder(dlg
->x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,dlg
->bg
);
285 XSetForeground(dlg
->x11
->disp
,dlg
->x11
->gc
,dlg
->x11
->fg
);
286 for(i
=0; (i
<dlg
->nitem
); i
++) {
287 dlgitem
=dlg
->dlgitem
[i
];
288 if ((dlgitem
->type
==edlgBN
) &&
289 (dlgitem
->u
.button
.bDefault
)) {
290 PushMouse(dlg
->x11
->disp
,dlgitem
->win
.self
,
291 dlgitem
->win
.width
/2,dlgitem
->win
.height
/2);
299 void HideDlg(t_dlg
*dlg
)
302 PopMouse(dlg
->x11
->disp
);
304 XUnmapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
305 XUnmapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
308 void NoHelp(t_dlg
*dlg
)
313 lines
[0]=strdup("Error");
314 lines
[1]=strdup("No help for this item");
315 MessageBox(dlg
->x11
,dlg
->wDad
,"No Help",2,lines
,
316 MB_OK
| MB_ICONSTOP
| MB_APPLMODAL
,NULL
,NULL
);
322 void HelpDlg(t_dlg
*dlg
)
325 "Place the cursor over one of the items",
326 "and press the F1 key to get more help.",
327 "First press the OK button."
329 MessageBox(dlg
->x11
,dlg
->win
.self
,"Help Dialogbox",
330 3,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
333 void HelpNow(t_dlg
*dlg
, t_dlgitem
*dlgitem
)
340 if (!dlgitem
->help
) {
345 printf("%s\n",dlgitem
->help
);
347 fgets2(buf
,79,stdin
);
349 fprintf(dlg
->x11
->console
,"buffer: '%s'\n",buf
);
350 dlg
->x11
->Flush(dlg
->x11
);
352 if (gmx_strcasecmp(buf
,"nok")==0) {
353 /* An error occurred */
354 for(i
=0; (i
<nlines
); i
++)
361 bCont
=(gmx_strcasecmp(buf
,"ok") != 0);
363 srenew(lines
,++nlines
);
364 lines
[nlines
-1]=strdup(buf
);
368 MessageBox(dlg
->x11
,dlg
->wDad
,"Help",
369 nlines
,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
370 for(i
=0; (i
<nlines
); i
++)
375 static void EnterDlg(t_dlg
*dlg
)
377 if (dlg
->flags
& DLG_APPLMODAL
)
378 dlg
->bGrab
=GrabOK(dlg
->x11
->console
,
379 XGrabPointer(dlg
->x11
->disp
,dlg
->win
.self
,
380 True
,0,GrabModeAsync
,GrabModeAsync
,
381 dlg
->win
.self
,None
,CurrentTime
));
382 dlg
->x11
->Flush(dlg
->x11
);
385 static void ExitDlg(t_dlg
*dlg
)
388 XUngrabPointer(dlg
->x11
->disp
,CurrentTime
);
392 if (dlg
->flags
& DLG_FREEONBUTTON
)
396 static gmx_bool
DlgCB(t_x11
*x11
,XEvent
*event
, Window w
, void *data
)
398 t_dlg
*dlg
=(t_dlg
*)data
;
402 if ((dlgitem
=FindWin(dlg
,w
))!=NULL
) {
403 nWndProc
=(dlgitem
->WndProc
)(x11
,dlgitem
,event
);
405 fprintf(x11
->console
,
406 "window: %s, nWndProc: %d\n",dlgitem
->win
.text
,nWndProc
);
411 if ((dlgitem
->type
==edlgBN
) && (dlgitem
->u
.button
.bDefault
)) {
413 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
418 for(i
=0; (i
<dlg
->nitem
); i
++)
419 if ((dlg
->dlgitem
[i
]->type
==edlgBN
) &&
420 (dlg
->dlgitem
[i
]->u
.button
.bDefault
)) {
421 PushMouse(x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,
422 dlg
->dlgitem
[i
]->win
.width
/2,
423 dlg
->dlgitem
[i
]->win
.height
/2);
430 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
435 int gid
=dlgitem
->GroupID
;
436 t_id tid
=RBSelected(dlg
,gid
);
438 fprintf(stderr
,"RBPRESSED\n");
441 t_dlgitem
*dit
=FindItem(dlg
,tid
);
442 dit
->u
.radiobutton
.bSelect
=FALSE
;
443 ExposeWin(x11
->disp
,dit
->win
.self
);
446 gmx_fatal(FARGS
,"No RB Selected initially!\n");
447 dlgitem
->u
.radiobutton
.bSelect
=TRUE
;
448 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
450 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
454 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
456 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->set
,dlg
->data
);
459 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
461 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->u
.edittext
.buf
,dlg
->data
);
464 HelpNow(dlg
,dlgitem
);
469 gmx_fatal(FARGS
,"Invalid return code (%d) from wndproc\n",nWndProc
);
472 else if (w
==dlg
->win
.self
) {
473 switch(event
->type
) {
479 if (HelpPressed(event
))
491 /*****************************
493 * Routine to add an item to the dialog box
494 * The pointer to the item is copied to the dlg struct,
495 * the item itself may not be freed until the dlg is done with
497 ****************************/
498 void DoCreateDlg(t_dlg
*dlg
)
501 XSetWindowAttributes attr
;
504 attr
.border_pixel
=dlg
->x11
->fg
;
505 attr
.background_pixel
=dlg
->bg
;
506 attr
.override_redirect
=False
;
507 attr
.save_under
=True
;
508 attr
.cursor
=XCreateFontCursor(dlg
->x11
->disp
,XC_hand2
);
509 Val
=CWBackPixel
| CWBorderPixel
| CWOverrideRedirect
| CWSaveUnder
|
511 dlg
->win
.self
=XCreateWindow(dlg
->x11
->disp
,dlg
->wDad
,
512 dlg
->win
.x
,dlg
->win
.y
,
513 dlg
->win
.width
,dlg
->win
.height
,
514 dlg
->win
.bwidth
,CopyFromParent
,
515 InputOutput
,CopyFromParent
,
517 dlg
->x11
->RegisterCallback(dlg
->x11
,dlg
->win
.self
,dlg
->wDad
,
519 dlg
->x11
->SetInputMask(dlg
->x11
,dlg
->win
.self
,
520 ExposureMask
| ButtonPressMask
| KeyPressMask
);
522 if (!CheckWindow(dlg
->win
.self
))
526 hints
.flags
=PPosition
;
527 XSetStandardProperties(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->title
,
528 dlg
->title
,None
,NULL
,0,&hints
);
531 void AddDlgItem(t_dlg
*dlg
, t_dlgitem
*item
)
533 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
534 #define UserMask (ButtonPressMask | KeyPressMask)
535 static unsigned long InputMask
[edlgNR
] = {
536 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgBN */
537 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgRB */
538 ExposureMask
, /* edlgGB */
539 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgCB */
541 ExposureMask
, /* edlgST */
542 ExposureMask
| UserMask
| EnterLeaveMask
/* edlgET */
547 srenew(dlg
->dlgitem
,dlg
->nitem
+1);
549 gmx_fatal(FARGS
,"dlgitem not allocated");
551 XCreateSimpleWindow(dlg
->x11
->disp
,dlg
->win
.self
,item
->win
.x
,item
->win
.y
,
552 item
->win
.width
,item
->win
.height
,
553 item
->win
.bwidth
,dlg
->x11
->fg
,dlg
->x11
->bg
);
554 CheckWindow(item
->win
.self
);
556 dlg
->x11
->RegisterCallback(dlg
->x11
,item
->win
.self
,dlg
->win
.self
,
558 dlg
->x11
->SetInputMask(dlg
->x11
,item
->win
.self
,InputMask
[item
->type
]);
560 switch (item
->type
) {
562 XSetWindowBackgroundPixmap(dlg
->x11
->disp
,item
->win
.self
,item
->u
.pixmap
.pm
);
567 dlg
->dlgitem
[dlg
->nitem
]=item
;
572 void AddDlgItems(t_dlg
*dlg
,int nitem
,t_dlgitem
*item
[])
576 for(i
=0; (i
<nitem
); i
++) {
578 fprintf(dlg
->x11
->console
,
579 "Adding item: %d from group %d\n",item
[i
]->ID
,item
[i
]->GroupID
);
580 dlg
->x11
->Flush(dlg
->x11
);
582 AddDlgItem(dlg
,item
[i
]);
586 void FreeDlgItem(t_dlg
*dlg
, t_id id
)
591 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
592 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlgitem
->win
.self
);
593 if (dlgitem
->win
.self
)
594 XDestroyWindow(dlg
->x11
->disp
,dlgitem
->win
.self
);
595 FreeWin(dlg
->x11
->disp
,&(dlgitem
->win
));
596 switch(dlgitem
->type
) {
601 sfree(dlgitem
->u
.groupbox
.item
);
606 XFreePixmap(dlg
->x11
->disp
,dlgitem
->u
.pixmap
.pm
);
609 for (i
=0; (i
<dlgitem
->u
.statictext
.nlines
); i
++)
610 sfree(dlgitem
->u
.statictext
.lines
[i
]);
611 sfree(dlgitem
->u
.statictext
.lines
);
614 sfree(dlgitem
->u
.edittext
.buf
);
622 void FreeDlg(t_dlg
*dlg
)
628 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlg
->win
.self
);
629 for(i
=0; (i
<dlg
->nitem
); i
++) {
630 FreeDlgItem(dlg
,dlg
->dlgitem
[i
]->ID
);
632 sfree(dlg
->dlgitem
[i
]);
636 XDestroyWindow(dlg
->x11
->disp
,dlg
->win
.self
);
641 /*****************************
643 * Routine to create the DLG structure, returns NULL on failure
645 ****************************/
646 t_dlg
*CreateDlg(t_x11
*x11
, Window Parent
, const char *title
,
647 int x0
,int y0
,int w
,int h
,int bw
, unsigned long fg
, unsigned long bg
,
648 DlgCallback
*cb
,void *data
)
658 dlg
->title
=strdup(title
);
665 dlg
->xmax
=DisplayWidth(x11
->disp
,x11
->screen
);
666 dlg
->ymax
=DisplayHeight(x11
->disp
,x11
->screen
);
672 XGetGeometry(x11
->disp
,Parent
,&root
,&x
,&y
,
673 &(dlg
->xmax
),&(dlg
->ymax
),&dum
,&dum
);
675 fprintf(x11
->console
,
676 "Daddy is %d x %d at %d, %d\n",dlg
->xmax
,dlg
->ymax
,x
,y
);
677 dlg
->x11
->Flush(dlg
->x11
);
682 InitWin(&(dlg
->win
),x
,y
,w
,h
,bw
,NULL
);
683 SetDlgSize(dlg
,w
,h
,x0
|| y0
);
695 void SetDlgSize(t_dlg
*dlg
,int w
,int h
, gmx_bool bAutoPosition
)
709 fprintf(dlg
->x11
->console
,"SetDlgSize: Dialog is %dx%d, at %d,%d\n",
710 dlg
->win
.width
,dlg
->win
.height
,dlg
->win
.x
,dlg
->win
.y
);
711 dlg
->x11
->Flush(dlg
->x11
);
714 XMoveWindow(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->win
.x
,dlg
->win
.y
);
715 XResizeWindow(dlg
->x11
->disp
,dlg
->win
.self
,w
,h
);