Don't use POSIX fnmatch() for pattern matching.
[gromacs/qmmm-gamess-us.git] / src / ngmx / popup.c
blob19c2d362c589ac893cda772b5f93818a9929b6a7
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.
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
32 * And Hey:
33 * Gyas ROwers Mature At Cryogenic Speed
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <string.h>
40 #include <math.h>
41 #include <macros.h>
42 #include <smalloc.h>
43 #include <x11.h>
44 #include <xutil.h>
45 #include "popup.h"
47 bool ChildCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
49 t_child *child;
50 t_mentry *m;
51 t_windata *wd;
52 XEvent letter;
54 child=(t_child *)data;
55 m=child->m;
56 wd=&(child->wd);
57 switch (event->type) {
58 case Expose:
59 XSetForeground(x11->disp,x11->gc,x11->fg);
60 TextInRect(x11,w,m->str,16,0,wd->width-16-2,wd->height-2,
61 eXLeft,eYCenter);
62 if (m->bChecked) {
63 int y=x11->font->ascent;
64 XDrawLine(x11->disp,w,x11->gc,2,(y*2)/3,6,y);
65 XDrawLine(x11->disp,w,x11->gc,3,(y*2)/3,7,y);
66 XDrawLine(x11->disp,w,x11->gc,7,y,12,2);
68 break;
69 case EnterNotify:
70 LightBorder(x11->disp,w,x11->fg);
71 break;
72 case LeaveNotify:
73 LightBorder(x11->disp,w,x11->bg);
74 break;
75 case ButtonRelease:
76 letter.type=ClientMessage;
77 letter.xclient.display=x11->disp;
78 letter.xclient.window=m->send_to ? m->send_to : child->Parent;
79 letter.xclient.message_type=0;
80 letter.xclient.format=32;
81 letter.xclient.data.l[0]=m->nreturn;
82 XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
83 break;
84 default:
85 break;
87 return FALSE;
90 bool MenuCallBack(t_x11 *x11,XEvent *event, Window w, void *data)
92 t_menu *m;
94 m=(t_menu *)data;
95 switch(event->type) {
96 case Expose:
97 /* Nothing to be done */
98 if (m->bGrabbed)
99 m->bGrabbed=
100 GrabOK(stderr,XGrabPointer(x11->disp,m->wd.self,True,
101 ButtonReleaseMask,GrabModeAsync,
102 GrabModeAsync,m->wd.self,None,CurrentTime));
103 break;
104 case ButtonRelease:
105 hide_menu(x11,m);
106 break;
107 case ClientMessage:
108 event->xclient.window=m->Parent;
109 XSendEvent(x11->disp,m->Parent,True,0,event);
110 break;
111 default:
112 break;
114 return FALSE;
117 t_menu *init_menu(t_x11 *x11,Window Parent,unsigned long fg,unsigned long bg,
118 int nent,t_mentry ent[],int ncol)
120 int i,mlen,mht,area,ht;
121 int j,k,l;
122 int frows,fcol;
123 t_menu *m;
124 t_child *kid;
125 t_windata *w;
127 snew(m,1);
128 m->nitem=nent;
129 m->Parent=Parent;
131 /* Calculate dimensions of the menu */
132 mlen=0;
133 for(i=0; (i<nent); i++)
134 mlen=max(mlen,XTextWidth(x11->font,ent[i].str,strlen(ent[i].str)));
135 mht=XTextHeight(x11->font);
136 /* Now we have the biggest single box, add a border of 2 pixels */
137 mlen+=20; /* We need extra space at the left for checkmarks */
138 mht+=4;
139 /* Calculate the area of the menu */
140 area=mlen*mht;
141 ht=sqrt(area);
142 /* No the number of rows per column, only beyond 8 rows */
143 if (ncol == 0) {
144 if (nent > 8)
145 frows=(1+ht/mht);
146 else
147 frows=nent;
148 fcol=nent/frows;
150 else {
151 fcol=ncol;
152 frows=nent/ncol;
153 if (nent % ncol)
154 frows++;
156 InitWin(&(m->wd),10,10,fcol*mlen,frows*mht,1,"Menu");
157 snew(m->item,nent);
158 m->wd.self=XCreateSimpleWindow(x11->disp,Parent,
159 m->wd.x, m->wd.y,
160 m->wd.width,m->wd.height,
161 m->wd.bwidth,fg,bg);
162 x11->RegisterCallback(x11,m->wd.self,Parent,MenuCallBack,m);
163 x11->SetInputMask(x11,m->wd.self,ExposureMask |
164 OwnerGrabButtonMask | ButtonReleaseMask);
166 for(j=l=0; (j<fcol); j++)
167 for(k=0; (k<frows) && (l<nent); k++,l++) {
168 kid=&(m->item[l]);
169 kid->m=&(ent[l]);
170 kid->Parent=Parent;
171 w=&(kid->wd);
172 InitWin(w,j*mlen,k*mht,mlen-2,mht-2,1,NULL);
173 w->self=XCreateSimpleWindow(x11->disp,m->wd.self,
174 w->x,w->y,w->width,w->height,
175 w->bwidth,bg,bg);
176 x11->RegisterCallback(x11,w->self,m->wd.self,
177 ChildCallBack,kid);
178 x11->SetInputMask(x11,w->self,
179 ButtonPressMask | ButtonReleaseMask |
180 OwnerGrabButtonMask | ExposureMask |
181 EnterWindowMask | LeaveWindowMask);
184 return m;
187 void show_menu(t_x11 *x11,t_menu *m,int x,int y,bool bGrab)
189 XMoveWindow(x11->disp,m->wd.self,x,y);
190 m->bGrabbed=bGrab;
191 XMapWindow(x11->disp,m->wd.self);
192 XMapSubwindows(x11->disp,m->wd.self);
195 void hide_menu(t_x11 *x11,t_menu *m)
197 if (m->bGrabbed)
198 XUngrabPointer(x11->disp,CurrentTime);
199 XUnmapWindow(x11->disp,m->wd.self);
202 void check_menu_item(t_menu *m,int nreturn,bool bStatus)
204 int i;
206 for(i=0; (i<m->nitem); i++)
207 if(m->item[i].m->nreturn==nreturn)
208 m->item[i].m->bChecked=bStatus;
211 void done_menu(t_x11 *x11,t_menu *m)
213 int i;
215 for(i=0; (i<m->nitem); i++)
216 x11->UnRegisterCallback(x11,m->item[i].wd.self);
217 sfree(m->item);
218 x11->UnRegisterCallback(x11,m->wd.self);
219 sfree(m);
222 int menu_width(t_menu *m)
224 return m->wd.width;
227 int menu_height(t_menu *m)
229 return m->wd.height;