4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-2001
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * Do check out http://www.gromacs.org , or mail us at gromacs@gromacs.org .
34 * Good gRace! Old Maple Actually Chews Slate
36 static char *SRCID_xdlg_c = "$Id$";
49 /*****************************
53 ****************************/
54 t_dlgitem *FindItem(t_dlg *dlg, t_id id)
58 for(i=0; (i<dlg->nitem); i++)
59 if (dlg->dlgitem[i]->ID==id)
60 return dlg->dlgitem[i];
64 t_dlgitem *FindWin(t_dlg *dlg, Window win)
68 for(i=0; (i<dlg->nitem); i++)
69 if (dlg->dlgitem[i]->win.self==win)
70 return dlg->dlgitem[i];
74 /*****************************
76 * Routines to manipulate items on a dialog box
78 ****************************/
79 bool QueryDlgItemSize(t_dlg *dlg,t_id id,int *w,int *h)
83 if ((dlgitem=FindItem(dlg,id)) != NULL) {
84 *w=dlgitem->win.width;
85 *h=dlgitem->win.height;
91 bool QueryDlgItemPos(t_dlg *dlg,t_id id,int *x0,int *y0)
95 if ((dlgitem=FindItem(dlg,id)) != NULL) {
103 int QueryDlgItemX(t_dlg *dlg, t_id id)
107 if ((dlgitem=FindItem(dlg,id)) != NULL)
108 return dlgitem->win.x;
112 int QueryDlgItemY(t_dlg *dlg, t_id id)
116 if ((dlgitem=FindItem(dlg,id)) != NULL)
117 return dlgitem->win.y;
121 int QueryDlgItemW(t_dlg *dlg, t_id id)
125 if ((dlgitem=FindItem(dlg,id)) != NULL)
126 return dlgitem->win.width;
130 int QueryDlgItemH(t_dlg *dlg, t_id id)
134 if ((dlgitem=FindItem(dlg,id)) != NULL)
135 return dlgitem->win.height;
139 bool SetDlgItemSize(t_dlg *dlg,t_id id,int w,int h)
146 if ((dlgitem=FindItem(dlg,id)) != NULL) {
148 old_w=dlgitem->win.width;
149 old_h=dlgitem->win.height;
152 dlgitem->win.width=w;
154 dlgitem->win.height=h;
156 fprintf(dlg->x11->console,
157 "Size window from: %dx%d to %dx%d\n",old_w,old_h,
158 dlgitem->win.width,dlgitem->win.height);
159 dlg->x11->Flush(dlg->x11);
161 if (dlgitem->win.self)
162 XResizeWindow(dlg->x11->disp,dlgitem->win.self,dlgitem->win.width,
163 dlgitem->win.height);
164 if ((w) && (dlgitem->type==edlgGB)) {
166 t_id gid=dlgitem->GroupID;
168 for (i=0; (i<dlg->nitem); i++) {
169 t_dlgitem *child=dlg->dlgitem[i];
170 if ((child->GroupID==gid) && (child->ID!=id))
171 SetDlgItemSize(dlg,child->ID,w-4*OFFS_X,0);
179 bool SetDlgItemPos(t_dlg *dlg,t_id id,int x0,int y0)
184 if ((dlgitem=FindItem(dlg,id)) != NULL) {
185 old_x=dlgitem->win.x;
186 old_y=dlgitem->win.y;
190 fprintf(dlg->x11->console,
191 "Move window from: %d,%d to %d,%d\n",old_x,old_y,x0,y0);
192 dlg->x11->Flush(dlg->x11);
194 if (dlgitem->win.self)
195 XMoveWindow(dlg->x11->disp,dlgitem->win.self,x0,y0);
196 if (dlgitem->type==edlgGB) {
198 t_id gid=dlgitem->GroupID;
200 x=dlgitem->win.x+2*OFFS_X-old_x;
201 y=dlgitem->win.y+2*OFFS_Y-old_y;
202 for (i=0; (i<dlg->nitem); i++) {
203 t_dlgitem *child=dlg->dlgitem[i];
204 if ((child->GroupID==gid) && (child->ID!=id))
205 SetDlgItemPos(dlg,child->ID,child->win.x+x,child->win.y+y);
213 /*****************************
215 * Routines to extract information from the dlg proc
216 * after dlg is exec'ed
218 ****************************/
219 bool IsCBChecked(t_dlg *dlg,t_id id)
223 if ((dlgitem=FindItem(dlg,id)) != NULL)
224 if (dlgitem->type==edlgCB)
225 return dlgitem->u.checkbox.bChecked;
230 t_id RBSelected(t_dlg *dlg,int gid)
234 for(i=0; (i<dlg->nitem); i++)
235 if ((dlg->dlgitem[i]->type==edlgRB) &&
236 (dlg->dlgitem[i]->u.radiobutton.bSelect) &&
237 (dlg->dlgitem[i]->GroupID==gid))
238 return dlg->dlgitem[i]->ID;
243 int EditTextLen(t_dlg *dlg,t_id id)
247 if ((dlgitem=FindItem(dlg,id)) != NULL)
248 if (dlgitem->type==edlgET)
249 return strlen(dlgitem->u.edittext.buf);
254 char *EditText(t_dlg *dlg,t_id id)
258 if ((dlgitem=FindItem(dlg,id)) != NULL)
259 if (dlgitem->type==edlgET)
260 return dlgitem->u.edittext.buf;
265 /*****************************
267 * Exececute the dialog box procedure
268 * Returns when a button is pushed.
269 * return value is the ID of the button
271 ****************************/
272 void ShowDlg(t_dlg *dlg)
277 XMapWindow(dlg->x11->disp,dlg->win.self);
278 XMapSubwindows(dlg->x11->disp,dlg->win.self);
279 for (i=0; (i<dlg->nitem); i++)
280 LightBorder(dlg->x11->disp,dlg->dlgitem[i]->win.self,dlg->bg);
281 XSetForeground(dlg->x11->disp,dlg->x11->gc,dlg->x11->fg);
282 for(i=0; (i<dlg->nitem); i++) {
283 dlgitem=dlg->dlgitem[i];
284 if ((dlgitem->type==edlgBN) &&
285 (dlgitem->u.button.bDefault)) {
286 PushMouse(dlg->x11->disp,dlgitem->win.self,
287 dlgitem->win.width/2,dlgitem->win.height/2);
295 void HideDlg(t_dlg *dlg)
298 PopMouse(dlg->x11->disp);
300 XUnmapSubwindows(dlg->x11->disp,dlg->win.self);
301 XUnmapWindow(dlg->x11->disp,dlg->win.self);
304 void NoHelp(t_dlg *dlg)
309 lines[0]=strdup("Error");
310 lines[1]=strdup("No help for this item");
311 MessageBox(dlg->x11,dlg->wDad,"No Help",2,lines,
312 MB_OK | MB_ICONSTOP | MB_APPLMODAL,NULL,NULL);
318 void HelpDlg(t_dlg *dlg)
321 "Place the cursor over one of the items",
322 "and press the F1 key to get more help.",
323 "First press the OK button."
325 MessageBox(dlg->x11,dlg->win.self,"Help Dialogbox",
326 3,lines,MB_OK | MB_ICONINFORMATION | MB_APPLMODAL,NULL,NULL);
329 void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem)
336 if (!dlgitem->help) {
341 printf("%s\n",dlgitem->help);
343 fgets2(buf,79,stdin);
345 fprintf(dlg->x11->console,"buffer: '%s'\n",buf);
346 dlg->x11->Flush(dlg->x11);
348 if (strcasecmp(buf,"nok")==0) {
349 /* An error occurred */
350 for(i=0; (i<nlines); i++)
357 bCont=(strcasecmp(buf,"ok") != 0);
359 srenew(lines,++nlines);
360 lines[nlines-1]=strdup(buf);
364 MessageBox(dlg->x11,dlg->wDad,"Help",
365 nlines,lines,MB_OK | MB_ICONINFORMATION | MB_APPLMODAL,NULL,NULL);
366 for(i=0; (i<nlines); i++)
371 static void EnterDlg(t_dlg *dlg)
373 if (dlg->flags & DLG_APPLMODAL)
374 dlg->bGrab=GrabOK(dlg->x11->console,
375 XGrabPointer(dlg->x11->disp,dlg->win.self,
376 True,0,GrabModeAsync,GrabModeAsync,
377 dlg->win.self,None,CurrentTime));
378 dlg->x11->Flush(dlg->x11);
381 static void ExitDlg(t_dlg *dlg)
384 XUngrabPointer(dlg->x11->disp,CurrentTime);
388 if (dlg->flags & DLG_FREEONBUTTON)
392 static bool DlgCB(t_x11 *x11,XEvent *event, Window w, void *data)
394 t_dlg *dlg=(t_dlg *)data;
398 if ((dlgitem=FindWin(dlg,w))!=NULL) {
399 nWndProc=(dlgitem->WndProc)(x11,dlgitem,event);
401 fprintf(x11->console,
402 "window: %s, nWndProc: %d\n",dlgitem->win.text,nWndProc);
407 if ((dlgitem->type==edlgBN) && (dlgitem->u.button.bDefault)) {
409 dlg->cb(x11,DLG_EXIT,dlgitem->ID,dlgitem->win.text,dlg->data);
414 for(i=0; (i<dlg->nitem); i++)
415 if ((dlg->dlgitem[i]->type==edlgBN) &&
416 (dlg->dlgitem[i]->u.button.bDefault)) {
417 PushMouse(x11->disp,dlg->dlgitem[i]->win.self,
418 dlg->dlgitem[i]->win.width/2,
419 dlg->dlgitem[i]->win.height/2);
426 dlg->cb(x11,DLG_EXIT,dlgitem->ID,dlgitem->win.text,dlg->data);
431 int gid=dlgitem->GroupID;
432 t_id tid=RBSelected(dlg,gid);
434 fprintf(stderr,"RBPRESSED\n");
437 t_dlgitem *dit=FindItem(dlg,tid);
438 dit->u.radiobutton.bSelect=FALSE;
439 ExposeWin(x11->disp,dit->win.self);
442 fatal_error(0,"No RB Selected initially!\n");
443 dlgitem->u.radiobutton.bSelect=TRUE;
444 ExposeWin(x11->disp,dlgitem->win.self);
446 dlg->cb(x11,DLG_SET,dlgitem->ID,dlgitem->win.text,dlg->data);
450 ExposeWin(x11->disp,dlgitem->win.self);
452 dlg->cb(x11,DLG_SET,dlgitem->ID,dlgitem->set,dlg->data);
455 ExposeWin(x11->disp,dlgitem->win.self);
457 dlg->cb(x11,DLG_SET,dlgitem->ID,dlgitem->u.edittext.buf,dlg->data);
460 HelpNow(dlg,dlgitem);
465 fatal_error(0,"Invalid return code (%d) from wndproc\n",nWndProc);
468 else if (w==dlg->win.self) {
469 switch(event->type) {
475 if (HelpPressed(event))
487 /*****************************
489 * Routine to add an item to the dialog box
490 * The pointer to the item is copied to the dlg struct,
491 * the item itself may not be freed until the dlg is done with
493 ****************************/
494 void DoCreateDlg(t_dlg *dlg)
497 XSetWindowAttributes attr;
500 attr.border_pixel=dlg->x11->fg;
501 attr.background_pixel=dlg->bg;
502 attr.override_redirect=False;
503 attr.save_under=True;
504 attr.cursor=XCreateFontCursor(dlg->x11->disp,XC_hand2);
505 Val=CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder |
507 dlg->win.self=XCreateWindow(dlg->x11->disp,dlg->wDad,
508 dlg->win.x,dlg->win.y,
509 dlg->win.width,dlg->win.height,
510 dlg->win.bwidth,CopyFromParent,
511 InputOutput,CopyFromParent,
513 dlg->x11->RegisterCallback(dlg->x11,dlg->win.self,dlg->wDad,
515 dlg->x11->SetInputMask(dlg->x11,dlg->win.self,
516 ExposureMask | ButtonPressMask | KeyPressMask);
518 if (!CheckWindow(dlg->win.self))
522 hints.flags=PPosition;
523 XSetStandardProperties(dlg->x11->disp,dlg->win.self,dlg->title,
524 dlg->title,None,NULL,0,&hints);
527 void AddDlgItem(t_dlg *dlg, t_dlgitem *new)
529 #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask)
530 #define UserMask (ButtonPressMask | KeyPressMask)
531 static unsigned long InputMask[edlgNR] = {
532 ExposureMask | UserMask | EnterLeaveMask, /* edlgBN */
533 ExposureMask | UserMask | EnterLeaveMask, /* edlgRB */
534 ExposureMask, /* edlgGB */
535 ExposureMask | UserMask | EnterLeaveMask, /* edlgCB */
537 ExposureMask, /* edlgST */
538 ExposureMask | UserMask | EnterLeaveMask /* edlgET */
543 srenew(dlg->dlgitem,dlg->nitem+1);
546 XCreateSimpleWindow(dlg->x11->disp,dlg->win.self,new->win.x,new->win.y,
547 new->win.width,new->win.height,
548 new->win.bwidth,dlg->x11->fg,dlg->x11->bg);
549 CheckWindow(new->win.self);
551 dlg->x11->RegisterCallback(dlg->x11,new->win.self,dlg->win.self,
553 dlg->x11->SetInputMask(dlg->x11,new->win.self,InputMask[new->type]);
557 XSetWindowBackgroundPixmap(dlg->x11->disp,new->win.self,new->u.pixmap.pm);
562 dlg->dlgitem[dlg->nitem]=new;
567 void AddDlgItems(t_dlg *dlg,int nitem,t_dlgitem *new[])
571 for(i=0; (i<nitem); i++) {
573 fprintf(dlg->x11->console,
574 "Adding item: %d from group %d\n",new[i]->ID,new[i]->GroupID);
575 dlg->x11->Flush(dlg->x11);
577 AddDlgItem(dlg,new[i]);
581 void FreeDlgItem(t_dlg *dlg, t_id id)
586 if ((dlgitem=FindItem(dlg,id)) != NULL) {
587 dlg->x11->UnRegisterCallback(dlg->x11,dlgitem->win.self);
588 if (dlgitem->win.self)
589 XDestroyWindow(dlg->x11->disp,dlgitem->win.self);
590 FreeWin(dlg->x11->disp,&(dlgitem->win));
591 switch(dlgitem->type) {
596 sfree(dlgitem->u.groupbox.item);
601 XFreePixmap(dlg->x11->disp,dlgitem->u.pixmap.pm);
604 for (i=0; (i<dlgitem->u.statictext.nlines); i++)
605 sfree(dlgitem->u.statictext.lines[i]);
606 sfree(dlgitem->u.statictext.lines);
609 sfree(dlgitem->u.edittext.buf);
617 void FreeDlg(t_dlg *dlg)
623 dlg->x11->UnRegisterCallback(dlg->x11,dlg->win.self);
624 for(i=0; (i<dlg->nitem); i++) {
625 FreeDlgItem(dlg,dlg->dlgitem[i]->ID);
627 sfree(dlg->dlgitem[i]);
631 XDestroyWindow(dlg->x11->disp,dlg->win.self);
636 /*****************************
638 * Routine to create the DLG structure, returns NULL on failure
640 ****************************/
641 t_dlg *CreateDlg(t_x11 *x11, Window Parent, char *title,
642 int x0,int y0,int w,int h,int bw, unsigned long fg, unsigned long bg,
643 DlgCallback *cb,void *data)
653 dlg->title=strdup(title);
660 dlg->xmax=DisplayWidth(x11->disp,x11->screen);
661 dlg->ymax=DisplayHeight(x11->disp,x11->screen);
667 XGetGeometry(x11->disp,Parent,&root,&x,&y,
668 &(dlg->xmax),&(dlg->ymax),&dum,&dum);
670 fprintf(x11->console,
671 "Daddy is %d x %d at %d, %d\n",dlg->xmax,dlg->ymax,x,y);
672 dlg->x11->Flush(dlg->x11);
677 InitWin(&(dlg->win),x,y,w,h,bw,NULL);
678 SetDlgSize(dlg,w,h,x0 || y0);
690 void SetDlgSize(t_dlg *dlg,int w,int h, bool bAutoPosition)
704 fprintf(dlg->x11->console,"SetDlgSize: Dialog is %dx%d, at %d,%d\n",
705 dlg->win.width,dlg->win.height,dlg->win.x,dlg->win.y);
706 dlg->x11->Flush(dlg->x11);
709 XMoveWindow(dlg->x11->disp,dlg->win.self,dlg->win.x,dlg->win.y);
710 XResizeWindow(dlg->x11->disp,dlg->win.self,w,h);