4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_xdlg_c
= "$Id$";
43 /*****************************
47 ****************************/
48 t_dlgitem
*FindItem(t_dlg
*dlg
, t_id id
)
52 for(i
=0; (i
<dlg
->nitem
); i
++)
53 if (dlg
->dlgitem
[i
]->ID
==id
)
54 return dlg
->dlgitem
[i
];
58 t_dlgitem
*FindWin(t_dlg
*dlg
, Window win
)
62 for(i
=0; (i
<dlg
->nitem
); i
++)
63 if (dlg
->dlgitem
[i
]->win
.self
==win
)
64 return dlg
->dlgitem
[i
];
68 /*****************************
70 * Routines to manipulate items on a dialog box
72 ****************************/
73 bool QueryDlgItemSize(t_dlg
*dlg
,t_id id
,int *w
,int *h
)
77 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
78 *w
=dlgitem
->win
.width
;
79 *h
=dlgitem
->win
.height
;
85 bool QueryDlgItemPos(t_dlg
*dlg
,t_id id
,int *x0
,int *y0
)
89 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
97 int QueryDlgItemX(t_dlg
*dlg
, t_id id
)
101 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
102 return dlgitem
->win
.x
;
106 int QueryDlgItemY(t_dlg
*dlg
, t_id id
)
110 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
111 return dlgitem
->win
.y
;
115 int QueryDlgItemW(t_dlg
*dlg
, t_id id
)
119 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
120 return dlgitem
->win
.width
;
124 int QueryDlgItemH(t_dlg
*dlg
, t_id id
)
128 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
129 return dlgitem
->win
.height
;
133 bool SetDlgItemSize(t_dlg
*dlg
,t_id id
,int w
,int h
)
140 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
142 old_w
=dlgitem
->win
.width
;
143 old_h
=dlgitem
->win
.height
;
146 dlgitem
->win
.width
=w
;
148 dlgitem
->win
.height
=h
;
150 fprintf(dlg
->x11
->console
,
151 "Size window from: %dx%d to %dx%d\n",old_w
,old_h
,
152 dlgitem
->win
.width
,dlgitem
->win
.height
);
153 dlg
->x11
->Flush(dlg
->x11
);
155 if (dlgitem
->win
.self
)
156 XResizeWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,dlgitem
->win
.width
,
157 dlgitem
->win
.height
);
158 if ((w
) && (dlgitem
->type
==edlgGB
)) {
160 t_id gid
=dlgitem
->GroupID
;
162 for (i
=0; (i
<dlg
->nitem
); i
++) {
163 t_dlgitem
*child
=dlg
->dlgitem
[i
];
164 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
165 SetDlgItemSize(dlg
,child
->ID
,w
-4*OFFS_X
,0);
173 bool SetDlgItemPos(t_dlg
*dlg
,t_id id
,int x0
,int y0
)
178 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
179 old_x
=dlgitem
->win
.x
;
180 old_y
=dlgitem
->win
.y
;
184 fprintf(dlg
->x11
->console
,
185 "Move window from: %d,%d to %d,%d\n",old_x
,old_y
,x0
,y0
);
186 dlg
->x11
->Flush(dlg
->x11
);
188 if (dlgitem
->win
.self
)
189 XMoveWindow(dlg
->x11
->disp
,dlgitem
->win
.self
,x0
,y0
);
190 if (dlgitem
->type
==edlgGB
) {
192 t_id gid
=dlgitem
->GroupID
;
194 x
=dlgitem
->win
.x
+2*OFFS_X
-old_x
;
195 y
=dlgitem
->win
.y
+2*OFFS_Y
-old_y
;
196 for (i
=0; (i
<dlg
->nitem
); i
++) {
197 t_dlgitem
*child
=dlg
->dlgitem
[i
];
198 if ((child
->GroupID
==gid
) && (child
->ID
!=id
))
199 SetDlgItemPos(dlg
,child
->ID
,child
->win
.x
+x
,child
->win
.y
+y
);
207 /*****************************
209 * Routines to extract information from the dlg proc
210 * after dlg is exec'ed
212 ****************************/
213 bool IsCBChecked(t_dlg
*dlg
,t_id id
)
217 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
218 if (dlgitem
->type
==edlgCB
)
219 return dlgitem
->u
.checkbox
.bChecked
;
224 t_id
RBSelected(t_dlg
*dlg
,int gid
)
228 for(i
=0; (i
<dlg
->nitem
); i
++)
229 if ((dlg
->dlgitem
[i
]->type
==edlgRB
) &&
230 (dlg
->dlgitem
[i
]->u
.radiobutton
.bSelect
) &&
231 (dlg
->dlgitem
[i
]->GroupID
==gid
))
232 return dlg
->dlgitem
[i
]->ID
;
237 int EditTextLen(t_dlg
*dlg
,t_id id
)
241 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
242 if (dlgitem
->type
==edlgET
)
243 return strlen(dlgitem
->u
.edittext
.buf
);
248 char *EditText(t_dlg
*dlg
,t_id id
)
252 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
)
253 if (dlgitem
->type
==edlgET
)
254 return dlgitem
->u
.edittext
.buf
;
259 /*****************************
261 * Exececute the dialog box procedure
262 * Returns when a button is pushed.
263 * return value is the ID of the button
265 ****************************/
266 void ShowDlg(t_dlg
*dlg
)
271 XMapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
272 XMapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
273 for (i
=0; (i
<dlg
->nitem
); i
++)
274 LightBorder(dlg
->x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,dlg
->bg
);
275 XSetForeground(dlg
->x11
->disp
,dlg
->x11
->gc
,dlg
->x11
->fg
);
276 for(i
=0; (i
<dlg
->nitem
); i
++) {
277 dlgitem
=dlg
->dlgitem
[i
];
278 if ((dlgitem
->type
==edlgBN
) &&
279 (dlgitem
->u
.button
.bDefault
)) {
280 PushMouse(dlg
->x11
->disp
,dlgitem
->win
.self
,
281 dlgitem
->win
.width
/2,dlgitem
->win
.height
/2);
289 void HideDlg(t_dlg
*dlg
)
292 PopMouse(dlg
->x11
->disp
);
294 XUnmapSubwindows(dlg
->x11
->disp
,dlg
->win
.self
);
295 XUnmapWindow(dlg
->x11
->disp
,dlg
->win
.self
);
298 void NoHelp(t_dlg
*dlg
)
303 lines
[0]=strdup("Error");
304 lines
[1]=strdup("No help for this item");
305 MessageBox(dlg
->x11
,dlg
->wDad
,"No Help",2,lines
,
306 MB_OK
| MB_ICONSTOP
| MB_APPLMODAL
,NULL
,NULL
);
312 void HelpDlg(t_dlg
*dlg
)
315 "Place the cursor over one of the items",
316 "and press the F1 key to get more help.",
317 "First press the OK button."
319 MessageBox(dlg
->x11
,dlg
->win
.self
,"Help Dialogbox",
320 3,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
323 void HelpNow(t_dlg
*dlg
, t_dlgitem
*dlgitem
)
330 if (!dlgitem
->help
) {
335 printf("%s\n",dlgitem
->help
);
337 fgets2(buf
,79,stdin
);
339 fprintf(dlg
->x11
->console
,"buffer: '%s'\n",buf
);
340 dlg
->x11
->Flush(dlg
->x11
);
342 if (strcasecmp(buf
,"nok")==0) {
343 /* An error occurred */
344 for(i
=0; (i
<nlines
); i
++)
351 bCont
=(strcasecmp(buf
,"ok") != 0);
353 srenew(lines
,++nlines
);
354 lines
[nlines
-1]=strdup(buf
);
358 MessageBox(dlg
->x11
,dlg
->wDad
,"Help",
359 nlines
,lines
,MB_OK
| MB_ICONINFORMATION
| MB_APPLMODAL
,NULL
,NULL
);
360 for(i
=0; (i
<nlines
); i
++)
365 static void EnterDlg(t_dlg
*dlg
)
367 if (dlg
->flags
& DLG_APPLMODAL
)
368 dlg
->bGrab
=GrabOK(dlg
->x11
->console
,
369 XGrabPointer(dlg
->x11
->disp
,dlg
->win
.self
,
370 True
,0,GrabModeAsync
,GrabModeAsync
,
371 dlg
->win
.self
,None
,CurrentTime
));
372 dlg
->x11
->Flush(dlg
->x11
);
375 static void ExitDlg(t_dlg
*dlg
)
378 XUngrabPointer(dlg
->x11
->disp
,CurrentTime
);
382 if (dlg
->flags
& DLG_FREEONBUTTON
)
386 static bool DlgCB(t_x11
*x11
,XEvent
*event
, Window w
, void *data
)
388 t_dlg
*dlg
=(t_dlg
*)data
;
392 if ((dlgitem
=FindWin(dlg
,w
))!=NULL
) {
393 nWndProc
=(dlgitem
->WndProc
)(x11
,dlgitem
,event
);
395 fprintf(x11
->console
,
396 "window: %s, nWndProc: %d\n",dlgitem
->win
.text
,nWndProc
);
401 if ((dlgitem
->type
==edlgBN
) && (dlgitem
->u
.button
.bDefault
)) {
403 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
408 for(i
=0; (i
<dlg
->nitem
); i
++)
409 if ((dlg
->dlgitem
[i
]->type
==edlgBN
) &&
410 (dlg
->dlgitem
[i
]->u
.button
.bDefault
)) {
411 PushMouse(x11
->disp
,dlg
->dlgitem
[i
]->win
.self
,
412 dlg
->dlgitem
[i
]->win
.width
/2,
413 dlg
->dlgitem
[i
]->win
.height
/2);
420 dlg
->cb(x11
,DLG_EXIT
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
425 int gid
=dlgitem
->GroupID
;
426 t_id tid
=RBSelected(dlg
,gid
);
428 fprintf(stderr
,"RBPRESSED\n");
431 t_dlgitem
*dit
=FindItem(dlg
,tid
);
432 dit
->u
.radiobutton
.bSelect
=FALSE
;
433 ExposeWin(x11
->disp
,dit
->win
.self
);
436 fatal_error(0,"No RB Selected initially!\n");
437 dlgitem
->u
.radiobutton
.bSelect
=TRUE
;
438 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
440 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->win
.text
,dlg
->data
);
444 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
446 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->set
,dlg
->data
);
449 ExposeWin(x11
->disp
,dlgitem
->win
.self
);
451 dlg
->cb(x11
,DLG_SET
,dlgitem
->ID
,dlgitem
->u
.edittext
.buf
,dlg
->data
);
454 HelpNow(dlg
,dlgitem
);
459 fatal_error(0,"Invalid return code (%d) from wndproc\n",nWndProc
);
462 else if (w
==dlg
->win
.self
) {
463 switch(event
->type
) {
469 if (HelpPressed(event
))
481 /*****************************
483 * Routine to add an item to the dialog box
484 * The pointer to the item is copied to the dlg struct,
485 * the item itself may not be freed until the dlg is done with
487 ****************************/
488 void DoCreateDlg(t_dlg
*dlg
)
491 XSetWindowAttributes attr
;
494 attr
.border_pixel
=dlg
->x11
->fg
;
495 attr
.background_pixel
=dlg
->bg
;
496 attr
.override_redirect
=False
;
497 attr
.save_under
=True
;
498 attr
.cursor
=XCreateFontCursor(dlg
->x11
->disp
,XC_hand2
);
499 Val
=CWBackPixel
| CWBorderPixel
| CWOverrideRedirect
| CWSaveUnder
|
501 dlg
->win
.self
=XCreateWindow(dlg
->x11
->disp
,dlg
->wDad
,
502 dlg
->win
.x
,dlg
->win
.y
,
503 dlg
->win
.width
,dlg
->win
.height
,
504 dlg
->win
.bwidth
,CopyFromParent
,
505 InputOutput
,CopyFromParent
,
507 dlg
->x11
->RegisterCallback(dlg
->x11
,dlg
->win
.self
,dlg
->wDad
,
509 dlg
->x11
->SetInputMask(dlg
->x11
,dlg
->win
.self
,
510 ExposureMask
| ButtonPressMask
| KeyPressMask
);
512 if (!CheckWindow(dlg
->win
.self
))
516 hints
.flags
=PPosition
;
517 XSetStandardProperties(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->title
,
518 dlg
->title
,None
,NULL
,0,&hints
);
521 void AddDlgItem(t_dlg
*dlg
, t_dlgitem
*new)
523 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
524 #define UserMask (ButtonPressMask | KeyPressMask)
525 static unsigned long InputMask
[edlgNR
] = {
526 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgBN */
527 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgRB */
528 ExposureMask
, /* edlgGB */
529 ExposureMask
| UserMask
| EnterLeaveMask
, /* edlgCB */
531 ExposureMask
, /* edlgST */
532 ExposureMask
| UserMask
| EnterLeaveMask
/* edlgET */
537 srenew(dlg
->dlgitem
,dlg
->nitem
+1);
540 XCreateSimpleWindow(dlg
->x11
->disp
,dlg
->win
.self
,new->win
.x
,new->win
.y
,
541 new->win
.width
,new->win
.height
,
542 new->win
.bwidth
,dlg
->x11
->fg
,dlg
->x11
->bg
);
543 CheckWindow(new->win
.self
);
545 dlg
->x11
->RegisterCallback(dlg
->x11
,new->win
.self
,dlg
->win
.self
,
547 dlg
->x11
->SetInputMask(dlg
->x11
,new->win
.self
,InputMask
[new->type
]);
551 XSetWindowBackgroundPixmap(dlg
->x11
->disp
,new->win
.self
,new->u
.pixmap
.pm
);
556 dlg
->dlgitem
[dlg
->nitem
]=new;
561 void AddDlgItems(t_dlg
*dlg
,int nitem
,t_dlgitem
*new[])
565 for(i
=0; (i
<nitem
); i
++) {
567 fprintf(dlg
->x11
->console
,
568 "Adding item: %d from group %d\n",new[i
]->ID
,new[i
]->GroupID
);
569 dlg
->x11
->Flush(dlg
->x11
);
571 AddDlgItem(dlg
,new[i
]);
575 void FreeDlgItem(t_dlg
*dlg
, t_id id
)
580 if ((dlgitem
=FindItem(dlg
,id
)) != NULL
) {
581 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlgitem
->win
.self
);
582 if (dlgitem
->win
.self
)
583 XDestroyWindow(dlg
->x11
->disp
,dlgitem
->win
.self
);
584 FreeWin(dlg
->x11
->disp
,&(dlgitem
->win
));
585 switch(dlgitem
->type
) {
590 sfree(dlgitem
->u
.groupbox
.item
);
595 XFreePixmap(dlg
->x11
->disp
,dlgitem
->u
.pixmap
.pm
);
598 for (i
=0; (i
<dlgitem
->u
.statictext
.nlines
); i
++)
599 sfree(dlgitem
->u
.statictext
.lines
[i
]);
600 sfree(dlgitem
->u
.statictext
.lines
);
603 sfree(dlgitem
->u
.edittext
.buf
);
611 void FreeDlg(t_dlg
*dlg
)
617 dlg
->x11
->UnRegisterCallback(dlg
->x11
,dlg
->win
.self
);
618 for(i
=0; (i
<dlg
->nitem
); i
++) {
619 FreeDlgItem(dlg
,dlg
->dlgitem
[i
]->ID
);
621 sfree(dlg
->dlgitem
[i
]);
625 XDestroyWindow(dlg
->x11
->disp
,dlg
->win
.self
);
630 /*****************************
632 * Routine to create the DLG structure, returns NULL on failure
634 ****************************/
635 t_dlg
*CreateDlg(t_x11
*x11
, Window Parent
, char *title
,
636 int x0
,int y0
,int w
,int h
,int bw
, unsigned long fg
, unsigned long bg
,
637 DlgCallback
*cb
,void *data
)
647 dlg
->title
=strdup(title
);
654 dlg
->xmax
=DisplayWidth(x11
->disp
,x11
->screen
);
655 dlg
->ymax
=DisplayHeight(x11
->disp
,x11
->screen
);
661 XGetGeometry(x11
->disp
,Parent
,&root
,&x
,&y
,
662 &(dlg
->xmax
),&(dlg
->ymax
),&dum
,&dum
);
664 fprintf(x11
->console
,
665 "Daddy is %d x %d at %d, %d\n",dlg
->xmax
,dlg
->ymax
,x
,y
);
666 dlg
->x11
->Flush(dlg
->x11
);
671 InitWin(&(dlg
->win
),x
,y
,w
,h
,bw
,NULL
);
672 SetDlgSize(dlg
,w
,h
,x0
|| y0
);
684 void SetDlgSize(t_dlg
*dlg
,int w
,int h
, bool bAutoPosition
)
698 fprintf(dlg
->x11
->console
,"SetDlgSize: Dialog is %dx%d, at %d,%d\n",
699 dlg
->win
.width
,dlg
->win
.height
,dlg
->win
.x
,dlg
->win
.y
);
700 dlg
->x11
->Flush(dlg
->x11
);
703 XMoveWindow(dlg
->x11
->disp
,dlg
->win
.self
,dlg
->win
.x
,dlg
->win
.y
);
704 XResizeWindow(dlg
->x11
->disp
,dlg
->win
.self
,w
,h
);