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
++)
60 if (dlg
->dlgitem
[i
]->ID
==id
)
61 return dlg
->dlgitem
[i
];
65 t_dlgitem
*FindWin(t_dlg
*dlg
, Window win
)
69 for(i
=0; (i
<dlg
->nitem
); i
++)
70 if (dlg
->dlgitem
[i
]->win
.self
==win
)
71 return dlg
->dlgitem
[i
];
75 /*****************************
77 * Routines to manipulate items on a dialog box
79 ****************************/
80 bool QueryDlgItemSize(t_dlg
*dlg
,t_id id
,int *w
,int *h
)
84 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
85 *w
=dlgitem
->win
.width
;
86 *h
=dlgitem
->win
.height
;
92 bool QueryDlgItemPos(t_dlg
*dlg
,t_id id
,int *x0
,int *y0
)
96 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
104 int QueryDlgItemX(t_dlg
*dlg
, t_id id
)
108 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
109 return dlgitem
->win
.x
;
113 int QueryDlgItemY(t_dlg
*dlg
, t_id id
)
117 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
118 return dlgitem
->win
.y
;
122 int QueryDlgItemW(t_dlg
*dlg
, t_id id
)
126 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
127 return dlgitem
->win
.width
;
131 int QueryDlgItemH(t_dlg
*dlg
, t_id id
)
135 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
136 return dlgitem
->win
.height
;
140 bool SetDlgItemSize(t_dlg
*dlg
,t_id id
,int w
,int h
)
147 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
149 old_w
=dlgitem
->win
.width
;
150 old_h
=dlgitem
->win
.height
;
153 dlgitem
->win
.width
=w
;
155 dlgitem
->win
.height
=h
;
157 fprintf(dlg
->x11
->console
,
158 "Size window from: %dx%d to %dx%d\n",old_w
,old_h
,
159 dlgitem
->win
.width
,dlgitem
->win
.height
);
160 dlg
->x11
->Flush(dlg
->x11
);
162 if (dlgitem
->win
.self
)
163 XResizeWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,dlgitem
->win
.width
,
164 dlgitem
->win
.height
);
165 if ((w
) && (dlgitem
->type
==edlgGB
)) {
167 t_id gid
=dlgitem
->GroupID
;
169 for (i
=0; (i
<dlg
->nitem
); i
++) {
170 t_dlgitem
*child
=dlg
->dlgitem
[i
];
171 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
172 SetDlgItemSize(dlg
,child
->ID
,w
-4*OFFS_X
,0);
180 bool SetDlgItemPos(t_dlg
*dlg
,t_id id
,int x0
,int y0
)
185 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
186 old_x
=dlgitem
->win
.x
;
187 old_y
=dlgitem
->win
.y
;
191 fprintf(dlg
->x11
->console
,
192 "Move window from: %d,%d to %d,%d\n",old_x
,old_y
,x0
,y0
);
193 dlg
->x11
->Flush(dlg
->x11
);
195 if (dlgitem
->win
.self
)
196 XMoveWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,x0
,y0
);
197 if (dlgitem
->type
==edlgGB
) {
199 t_id gid
=dlgitem
->GroupID
;
201 x
=dlgitem
->win
.x
+2*OFFS_X
-old_x
;
202 y
=dlgitem
->win
.y
+2*OFFS_Y
-old_y
;
203 for (i
=0; (i
<dlg
->nitem
); i
++) {
204 t_dlgitem
*child
=dlg
->dlgitem
[i
];
205 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
206 SetDlgItemPos(dlg
,child
->ID
,child
->win
.x
+x
,child
->win
.y
+y
);
214 /*****************************
216 * Routines to extract information from the dlg proc
217 * after dlg is exec'ed
219 ****************************/
220 bool IsCBChecked(t_dlg
*dlg
,t_id id
)
224 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
225 if (dlgitem
->type
==edlgCB
)
226 return dlgitem
->u
.checkbox
.bChecked
;
231 t_id
RBSelected(t_dlg
*dlg
,int gid
)
235 for(i
=0; (i
<dlg
->nitem
); i
++)
236 if ((dlg
->dlgitem
[i
]->type
==edlgRB
) &&
237 (dlg
->dlgitem
[i
]->u
.radiobutton
.bSelect
) &&
238 (dlg
->dlgitem
[i
]->GroupID
==gid
))
239 return dlg
->dlgitem
[i
]->ID
;
244 int EditTextLen(t_dlg
*dlg
,t_id id
)
248 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
249 if (dlgitem
->type
==edlgET
)
250 return strlen(dlgitem
->u
.edittext
.buf
);
255 char *EditText(t_dlg
*dlg
,t_id id
)
259 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
260 if (dlgitem
->type
==edlgET
)
261 return dlgitem
->u
.edittext
.buf
;
266 /*****************************
268 * Exececute the dialog box procedure
269 * Returns when a button is pushed.
270 * return value is the ID of the button
272 ****************************/
273 void ShowDlg(t_dlg
*dlg
)
278 XMapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
279 XMapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
280 for (i
=0; (i
<dlg
->nitem
); i
++)
281 LightBorder(dlg
->x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,dlg
->bg
);
282 XSetForeground(dlg
->x11
->disp
,dlg
->x11
->gc
,dlg
->x11
->fg
);
283 for(i
=0; (i
<dlg
->nitem
); i
++) {
284 dlgitem
=dlg
->dlgitem
[i
];
285 if ((dlgitem
->type
==edlgBN
) &&
286 (dlgitem
->u
.button
.bDefault
)) {
287 PushMouse(dlg
->x11
->disp
,dlgitem
->win
.self
,
288 dlgitem
->win
.width
/2,dlgitem
->win
.height
/2);
296 void HideDlg(t_dlg
*dlg
)
299 PopMouse(dlg
->x11
->disp
);
301 XUnmapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
302 XUnmapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
305 void NoHelp(t_dlg
*dlg
)
310 lines
[0]=strdup("Error");
311 lines
[1]=strdup("No help for this item");
312 MessageBox(dlg
->x11
,dlg
->wDad
,"No Help",2,lines
,
313 MB_OK
| MB_ICONSTOP
| MB_APPLMODAL
,NULL
,NULL
);
319 void HelpDlg(t_dlg
*dlg
)
322 "Place the cursor over one of the items",
323 "and press the F1 key to get more help.",
324 "First press the OK button."
326 MessageBox(dlg
->x11
,dlg
->win
.self
,"Help Dialogbox",
327 3,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
330 void HelpNow(t_dlg
*dlg
, t_dlgitem
*dlgitem
)
337 if (!dlgitem
->help
) {
342 printf("%s\n",dlgitem
->help
);
344 fgets2(buf
,79,stdin
);
346 fprintf(dlg
->x11
->console
,"buffer: '%s'\n",buf
);
347 dlg
->x11
->Flush(dlg
->x11
);
349 if (strcasecmp(buf
,"nok")==0) {
350 /* An error occurred */
351 for(i
=0; (i
<nlines
); i
++)
358 bCont
=(strcasecmp(buf
,"ok") != 0);
360 srenew(lines
,++nlines
);
361 lines
[nlines
-1]=strdup(buf
);
365 MessageBox(dlg
->x11
,dlg
->wDad
,"Help",
366 nlines
,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
367 for(i
=0; (i
<nlines
); i
++)
372 static void EnterDlg(t_dlg
*dlg
)
374 if (dlg
->flags
& DLG_APPLMODAL
)
375 dlg
->bGrab
=GrabOK(dlg
->x11
->console
,
376 XGrabPointer(dlg
->x11
->disp
,dlg
->win
.self
,
377 True
,0,GrabModeAsync
,GrabModeAsync
,
378 dlg
->win
.self
,None
,CurrentTime
));
379 dlg
->x11
->Flush(dlg
->x11
);
382 static void ExitDlg(t_dlg
*dlg
)
385 XUngrabPointer(dlg
->x11
->disp
,CurrentTime
);
389 if (dlg
->flags
& DLG_FREEONBUTTON
)
393 static bool DlgCB(t_x11
*x11
,XEvent
*event
, Window w
, void *data
)
395 t_dlg
*dlg
=(t_dlg
*)data
;
399 if ((dlgitem
=FindWin(dlg
,w
))!=NULL
) {
400 nWndProc
=(dlgitem
->WndProc
)(x11
,dlgitem
,event
);
402 fprintf(x11
->console
,
403 "window: %s, nWndProc: %d\n",dlgitem
->win
.text
,nWndProc
);
408 if ((dlgitem
->type
==edlgBN
) && (dlgitem
->u
.button
.bDefault
)) {
410 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
415 for(i
=0; (i
<dlg
->nitem
); i
++)
416 if ((dlg
->dlgitem
[i
]->type
==edlgBN
) &&
417 (dlg
->dlgitem
[i
]->u
.button
.bDefault
)) {
418 PushMouse(x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,
419 dlg
->dlgitem
[i
]->win
.width
/2,
420 dlg
->dlgitem
[i
]->win
.height
/2);
427 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
432 int gid
=dlgitem
->GroupID
;
433 t_id tid
=RBSelected(dlg
,gid
);
435 fprintf(stderr
,"RBPRESSED\n");
438 t_dlgitem
*dit
=FindItem(dlg
,tid
);
439 dit
->u
.radiobutton
.bSelect
=FALSE
;
440 ExposeWin(x11
->disp
,dit
->win
.self
);
443 gmx_fatal(FARGS
,"No RB Selected initially!\n");
444 dlgitem
->u
.radiobutton
.bSelect
=TRUE
;
445 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
447 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
451 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
453 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->set
,dlg
->data
);
456 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
458 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->u
.edittext
.buf
,dlg
->data
);
461 HelpNow(dlg
,dlgitem
);
466 gmx_fatal(FARGS
,"Invalid return code (%d) from wndproc\n",nWndProc
);
469 else if (w
==dlg
->win
.self
) {
470 switch(event
->type
) {
476 if (HelpPressed(event
))
488 /*****************************
490 * Routine to add an item to the dialog box
491 * The pointer to the item is copied to the dlg struct,
492 * the item itself may not be freed until the dlg is done with
494 ****************************/
495 void DoCreateDlg(t_dlg
*dlg
)
498 XSetWindowAttributes attr
;
501 attr
.border_pixel
=dlg
->x11
->fg
;
502 attr
.background_pixel
=dlg
->bg
;
503 attr
.override_redirect
=False
;
504 attr
.save_under
=True
;
505 attr
.cursor
=XCreateFontCursor(dlg
->x11
->disp
,XC_hand2
);
506 Val
=CWBackPixel
| CWBorderPixel
| CWOverrideRedirect
| CWSaveUnder
|
508 dlg
->win
.self
=XCreateWindow(dlg
->x11
->disp
,dlg
->wDad
,
509 dlg
->win
.x
,dlg
->win
.y
,
510 dlg
->win
.width
,dlg
->win
.height
,
511 dlg
->win
.bwidth
,CopyFromParent
,
512 InputOutput
,CopyFromParent
,
514 dlg
->x11
->RegisterCallback(dlg
->x11
,dlg
->win
.self
,dlg
->wDad
,
516 dlg
->x11
->SetInputMask(dlg
->x11
,dlg
->win
.self
,
517 ExposureMask
| ButtonPressMask
| KeyPressMask
);
519 if (!CheckWindow(dlg
->win
.self
))
523 hints
.flags
=PPosition
;
524 XSetStandardProperties(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->title
,
525 dlg
->title
,None
,NULL
,0,&hints
);
528 void AddDlgItem(t_dlg
*dlg
, t_dlgitem
*item
)
530 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
531 #define UserMask (ButtonPressMask | KeyPressMask)
532 static unsigned long InputMask
[edlgNR
] = {
533 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgBN */
534 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgRB */
535 ExposureMask
, /* edlgGB */
536 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgCB */
538 ExposureMask
, /* edlgST */
539 ExposureMask
| UserMask
| EnterLeaveMask
/* edlgET */
544 srenew(dlg
->dlgitem
,dlg
->nitem
+1);
546 gmx_fatal(FARGS
,"dlgitem not allocated");
548 XCreateSimpleWindow(dlg
->x11
->disp
,dlg
->win
.self
,item
->win
.x
,item
->win
.y
,
549 item
->win
.width
,item
->win
.height
,
550 item
->win
.bwidth
,dlg
->x11
->fg
,dlg
->x11
->bg
);
551 CheckWindow(item
->win
.self
);
553 dlg
->x11
->RegisterCallback(dlg
->x11
,item
->win
.self
,dlg
->win
.self
,
555 dlg
->x11
->SetInputMask(dlg
->x11
,item
->win
.self
,InputMask
[item
->type
]);
557 switch (item
->type
) {
559 XSetWindowBackgroundPixmap(dlg
->x11
->disp
,item
->win
.self
,item
->u
.pixmap
.pm
);
564 dlg
->dlgitem
[dlg
->nitem
]=item
;
569 void AddDlgItems(t_dlg
*dlg
,int nitem
,t_dlgitem
*item
[])
573 for(i
=0; (i
<nitem
); i
++) {
575 fprintf(dlg
->x11
->console
,
576 "Adding item: %d from group %d\n",item
[i
]->ID
,item
[i
]->GroupID
);
577 dlg
->x11
->Flush(dlg
->x11
);
579 AddDlgItem(dlg
,item
[i
]);
583 void FreeDlgItem(t_dlg
*dlg
, t_id id
)
588 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
589 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlgitem
->win
.self
);
590 if (dlgitem
->win
.self
)
591 XDestroyWindow(dlg
->x11
->disp
,dlgitem
->win
.self
);
592 FreeWin(dlg
->x11
->disp
,&(dlgitem
->win
));
593 switch(dlgitem
->type
) {
598 sfree(dlgitem
->u
.groupbox
.item
);
603 XFreePixmap(dlg
->x11
->disp
,dlgitem
->u
.pixmap
.pm
);
606 for (i
=0; (i
<dlgitem
->u
.statictext
.nlines
); i
++)
607 sfree(dlgitem
->u
.statictext
.lines
[i
]);
608 sfree(dlgitem
->u
.statictext
.lines
);
611 sfree(dlgitem
->u
.edittext
.buf
);
619 void FreeDlg(t_dlg
*dlg
)
625 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlg
->win
.self
);
626 for(i
=0; (i
<dlg
->nitem
); i
++) {
627 FreeDlgItem(dlg
,dlg
->dlgitem
[i
]->ID
);
629 sfree(dlg
->dlgitem
[i
]);
633 XDestroyWindow(dlg
->x11
->disp
,dlg
->win
.self
);
638 /*****************************
640 * Routine to create the DLG structure, returns NULL on failure
642 ****************************/
643 t_dlg
*CreateDlg(t_x11
*x11
, Window Parent
, const char *title
,
644 int x0
,int y0
,int w
,int h
,int bw
, unsigned long fg
, unsigned long bg
,
645 DlgCallback
*cb
,void *data
)
655 dlg
->title
=strdup(title
);
662 dlg
->xmax
=DisplayWidth(x11
->disp
,x11
->screen
);
663 dlg
->ymax
=DisplayHeight(x11
->disp
,x11
->screen
);
669 XGetGeometry(x11
->disp
,Parent
,&root
,&x
,&y
,
670 &(dlg
->xmax
),&(dlg
->ymax
),&dum
,&dum
);
672 fprintf(x11
->console
,
673 "Daddy is %d x %d at %d, %d\n",dlg
->xmax
,dlg
->ymax
,x
,y
);
674 dlg
->x11
->Flush(dlg
->x11
);
679 InitWin(&(dlg
->win
),x
,y
,w
,h
,bw
,NULL
);
680 SetDlgSize(dlg
,w
,h
,x0
|| y0
);
692 void SetDlgSize(t_dlg
*dlg
,int w
,int h
, bool bAutoPosition
)
706 fprintf(dlg
->x11
->console
,"SetDlgSize: Dialog is %dx%d, at %d,%d\n",
707 dlg
->win
.width
,dlg
->win
.height
,dlg
->win
.x
,dlg
->win
.y
);
708 dlg
->x11
->Flush(dlg
->x11
);
711 XMoveWindow(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->win
.x
,dlg
->win
.y
);
712 XResizeWindow(dlg
->x11
->disp
,dlg
->win
.self
,w
,h
);