Add missing defines to PKG_CFLAGS
[gromacs.git] / src / ngmx / x11.c
blob31b099634ad0715355c6dc0e2b382385699d99d7
1 /*
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.
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
42 #include "typedefs.h"
43 #include <Xstuff.h>
44 #include <x11.h>
45 #include "sysstuff.h"
46 #include <string.h>
47 #include "smalloc.h"
48 #include "string2.h"
50 /* These colours will be mapped to black on a monochrome screen */
51 unsigned long BLACK,BLUE,GREEN,CYAN,RED,BROWN,GREY,DARKGREY;
53 /* These colours will be mapped to white on a monochrome screen */
54 unsigned long LIGHTBLUE,LIGHTGREEN,LIGHTGREY,LIGHTCYAN,LIGHTRED,VIOLET,YELLOW,WHITE;
56 static XFontStruct *XLQF(FILE *err, Display *disp, const char *name)
58 XFontStruct *font=XLoadQueryFont(disp,name);
59 #ifdef DEBUG
60 if (font != NULL)
61 fprintf(err, "Loaded font %s\n",name);
62 #endif
63 return font;
66 static XFontStruct *GetFont(FILE *err, Display *disp, char *name)
68 static const char *fontnames[] = {
69 "sansb12","8x13bold","8x13",
70 "9x15","6x13","fixed"
72 #define MAXNAMES (sizeof(fontnames)/sizeof(fontnames[0]))
73 int i;
74 XFontStruct *font;
75 int count;
76 char **fontlist;
77 gmx_bool bFont = FALSE;
79 if (name)
80 bFont=(gmx_bool) ((font=XLQF(err,disp,name))!=NULL);
81 else
82 font=NULL;
84 for (i=0; (!bFont && (i<MAXNAMES)); i++)
85 bFont=(gmx_bool) ((font=XLQF(err,disp,fontnames[i]))!=NULL);
87 if (!bFont) {
88 fontlist=XListFonts(disp,"?",1,&count);
89 if (count!=0)
90 bFont=(gmx_bool) ((font=XLQF(err,disp,fontlist[0]))!=NULL);
92 if (!bFont)
93 fprintf (err, "Cannot load any suitable font\n");
94 return font;
97 static GC GetGC(Display *disp, XFontStruct *font)
99 XGCValues values;
101 values.font = font->fid;
102 values.foreground = WhitePixel(disp,DefaultScreen(disp));
104 return XCreateGC(disp,DefaultRootWindow(disp),GCForeground|GCFont,&values);
107 void GetNamedColor(t_x11 *x11,const char *name,unsigned long *col)
109 /* If name is found than col set to that colour else col is unchanged */
110 XColor exact,clr;
112 if (XAllocNamedColor(x11->disp,x11->cmap,name,&clr,&exact))
113 *col=clr.pixel;
114 else
115 fprintf(x11->console,"No colour %s\n",name);
118 static t_wlist *GetWList(t_x11 *x11, Window w)
120 t_wlist *curs;
122 curs=x11->wlist;
123 while (curs && (curs->w != w))
124 curs=curs->next;
126 return curs;
129 typedef struct {
130 Window w;
131 gmx_bool b;
132 } t_peek;
134 static Bool TestEvent(Display *disp,XEvent *event,char *arg)
136 t_peek *tp;
138 fprintf(stderr,"TestEvent\n");
139 tp=(t_peek *)arg;
140 if ((event->xany.window==tp->w) && (event->type==ConfigureNotify)) {
141 tp->b=TRUE;
142 return True;
144 return False;
147 static void MainLoop(t_x11 *x11)
149 gmx_bool bReturn;
150 XEvent event;
151 t_wlist *curs;
152 Window w;
154 for (bReturn=FALSE; (!bReturn); ) {
155 if (x11->wlist) {
156 XNextEvent(x11->disp,&event);
157 w=event.xany.window;
158 curs=GetWList(x11,w);
159 if (!curs)
160 bReturn=TRUE;
161 if (!bReturn) {
162 switch (event.type) {
163 case Expose:
164 /* Filter out expose events with non-zero count field */
165 if (event.xexpose.count != 0)
166 curs=NULL;
167 break;
168 case ConfigureNotify:
169 /* Check if more are coming...
170 if (XCheckTypedWindowEvent(x11->disp,w,ConfigureNotify,&config))
171 curs=NULL; */
172 break;
173 default:
174 break;
176 if (curs)
177 bReturn=(*curs->cb)(x11,&event,w,curs->data);
183 static void RegisterCallback(t_x11 *x11,Window w,Window Parent,
184 CallBack cb, void *data)
186 t_wlist *curs,*item;
188 snew(item,1);
189 item->w=w;
190 item->Parent=Parent;
191 item->cb=cb;
192 item->mask=0;
193 item->data=data;
194 item->next=NULL;
196 if (x11->wlist) {
197 curs=x11->wlist;
198 while(curs->next)
199 curs=curs->next;
200 curs->next=item;
202 else
203 x11->wlist=item;
206 static void UnRegisterCallback(t_x11 *x11, Window w)
208 t_wlist *curs;
210 curs=x11->wlist;
211 if (curs) {
212 if (curs->w==w) {
213 x11->wlist=curs->next;
214 sfree(curs);
216 else {
217 while (curs->next && (curs->next->w != w))
218 curs=curs->next;
219 if (curs->next) {
220 t_wlist *tmp=curs->next;
222 curs->next=curs->next->next;
223 sfree(tmp);
229 static void SetInputMask(t_x11 *x11, Window w, unsigned long mask)
231 t_wlist *curs;
233 curs=GetWList(x11,w);
234 if (curs) {
235 curs->mask=mask;
236 XSelectInput(x11->disp,w,(long)mask);
238 else
239 fprintf(x11->console,"No such window (%d)\n",(int)w);
242 static unsigned long GetInputMask(t_x11 *x11, Window w)
244 t_wlist *curs;
246 curs=GetWList(x11,w);
247 if (curs)
248 return curs->mask;
249 else
250 return 0;
253 static void CleanUp(t_x11 *x11)
255 t_wlist *curs;
257 curs=x11->wlist;
258 while (curs) {
259 x11->wlist=curs->next;
260 XDestroyWindow(x11->disp,curs->w);
261 sfree(curs);
262 curs=x11->wlist;
264 XCloseDisplay(x11->disp);
267 static void Xrm(int *argc, char *argv[])
270 static XrmOptionDescRec opTable[] = {
271 {"-background", "*background",
272 XrmoptionSepArg, (caddr_t) NULL},
273 {"-bd", "*borderColor",
274 XrmoptionSepArg, (caddr_t) NULL},
275 {"-bg", "*background",
276 XrmoptionSepArg, (caddr_t) NULL},
277 {"-borderwidth", "*TopLevelShell.borderwidth",
278 XrmoptionSepArg, (caddr_t) NULL},
279 {"-bordercolor", "*borderColor",
280 XrmoptionSepArg, (caddr_t) NULL},
281 {"-bw", "*TopLevelShell.borderColor",
282 XrmoptionSepArg, (caddr_t) NULL},
283 {"-display", ".display",
284 XrmoptionSepArg, (caddr_t) NULL},
285 {"-fg", "*foreground",
286 XrmoptionSepArg, (caddr_t) NULL},
287 {"-fn", "*font",
288 XrmoptionSepArg, (caddr_t) NULL},
289 {"-font", "*font",
290 XrmoptionSepArg, (caddr_t) NULL},
291 {"-foreground", "*foreground",
292 XrmoptionSepArg, (caddr_t) NULL},
293 {"-geometry", ".TopLevelShell.geometry",
294 XrmoptionSepArg, (caddr_t) NULL},
295 {"-iconic", ".TopLevelShell.iconic",
296 XrmoptionNoArg, (caddr_t) "on"},
297 {"-name", ".name",
298 XrmoptionSepArg, (caddr_t) NULL},
299 {"-reverse", "*reverseVideo",
300 XrmoptionNoArg, (caddr_t) "on"},
301 {"-rv", "*reverseVideo",
302 XrmoptionNoArg, (caddr_t) "on"},
303 {"-synchronous", ".synchronous",
304 XrmoptionNoArg, (caddr_t) "on"},
305 {"-title", ".TopLevelShell.title",
306 XrmoptionSepArg, (caddr_t) NULL},
307 {"-xrm", NULL,
308 XrmoptionSepArg, (caddr_t) NULL},
310 #define TABLELENGTH (sizeof(opTable)/sizeof(opTable[0]))
311 XrmInitialize();*/
314 static void Flush(t_x11 *x11)
316 fflush(x11->console);
319 t_x11 *GetX11(int *argc, char *argv[])
321 static const char *v_name[] = {
322 "DirectColor","TrueColor", "PseudoColor",
323 "StaticColor","GrayScale", "StaticGray"
325 static int v_class[] = {
326 DirectColor,TrueColor, PseudoColor,
327 StaticColor,GrayScale, StaticGray
329 #define NCLASS (sizeof(v_class)/sizeof(v_class[0]))
331 XVisualInfo v_info;
332 t_x11 *x11;
333 int ARGC;
334 char **ARGV;
335 char *display;
336 char *fontname;
337 char *title,*FG=NULL,*BG=NULL;
338 gmx_bool bVerbose=FALSE;
339 int i;
341 title=strdup(argv[0]);
343 /* First check environment */
344 fontname=getenv("GMXFONT");
345 display=getenv("DISPLAY");
347 snew(ARGV,*argc);
348 ARGC=1;
349 for(i=1; (i < *argc); i++) {
350 if (argv[i][0]=='-') {
351 if (strlen(argv[i]) > 1) {
352 if ((*argc)>i+1)
353 switch(argv[i][1]) {
354 case 'b':
355 BG=argv[++i];
356 break;
357 case 'd':
358 display=argv[++i];
359 break;
360 case 'f':
361 switch(argv[i][2]) {
362 case 'o':
363 fontname=argv[++i];
364 break;
365 case 'g':
366 FG=argv[++i];
367 break;
369 break;
370 case 't':
371 sfree(title);
372 title=strdup(argv[++i]);
373 break;
374 case 'v':
375 bVerbose=TRUE;
376 break;
377 default:
378 ARGV[ARGC++]=argv[i];
379 break;
383 else
384 ARGV[ARGC++]=argv[i];
386 for (i=1; (i<ARGC); i++)
387 argv[i]=ARGV[i];
388 *argc=ARGC;
389 argv[ARGC]=NULL;
391 snew(x11,1);
392 x11->dispname=display;
393 if (bVerbose)
394 x11->console=stderr;
395 else
396 if ((x11->console=fopen("/dev/null","w"))== NULL)
397 x11->console=stderr;
399 if ((x11->disp=XOpenDisplay(display))==NULL) {
400 if (bVerbose)
401 fprintf(x11->console,"Display %s invalid\n",display);
402 return NULL;
405 if ((x11->font=GetFont(x11->console,x11->disp,fontname))==NULL)
406 return NULL;
407 if ((x11->gc=GetGC(x11->disp,x11->font))==NULL)
408 return NULL;
410 x11->root=DefaultRootWindow(x11->disp);
411 x11->screen=DefaultScreen(x11->disp);
412 x11->depth=DefaultDepth(x11->disp,x11->screen);
413 x11->cmap=DefaultColormap(x11->disp,x11->screen);
415 /* These colours will be mapped to black on a monochrome screen */
416 x11->fg=BLACK=BLUE=GREEN=CYAN=RED=BROWN=GREY=DARKGREY=
417 BlackPixel(x11->disp,x11->screen);
419 /* These colours will be mapped to white on a monochrome screen */
420 x11->bg=
421 LIGHTBLUE=LIGHTGREY=LIGHTGREEN=LIGHTCYAN=LIGHTRED=VIOLET=YELLOW=WHITE=
422 WhitePixel(x11->disp,x11->screen);
424 if (x11->depth > 1) {
425 /* Not B & W, Look what kind of screen we've got... */
426 for (i=0; (i < NCLASS); i++)
427 if (!XMatchVisualInfo(x11->disp,x11->screen,x11->depth,
428 v_class[i],&v_info))
429 break;
430 if ((i==4) || (i==5))
431 fprintf(x11->console,"Greyscale screen, using B & W only\n");
432 else {
433 /* We have real color! */
434 fprintf(x11->console,"%s screen with depth %d.\n",
435 (i==NCLASS)?"Unknown":v_name[i],x11->depth);
436 GetNamedColor(x11,"midnight blue",&BLUE);
437 GetNamedColor(x11,"DarkGreen",&GREEN);
438 GetNamedColor(x11,"SeaGreen",&CYAN);
439 GetNamedColor(x11,"red4",&RED);
440 GetNamedColor(x11,"Gray",&GREY);
441 GetNamedColor(x11,"Gray",&DARKGREY);
442 GetNamedColor(x11,"LightGray",&LIGHTGREY);
443 GetNamedColor(x11,"green",&LIGHTGREEN);
444 GetNamedColor(x11,"cyan",&LIGHTCYAN);
445 GetNamedColor(x11,"tomato1",&LIGHTRED);
446 GetNamedColor(x11,"violet",&VIOLET);
447 GetNamedColor(x11,"yellow",&YELLOW);
448 GetNamedColor(x11,"brown",&BROWN);
449 GetNamedColor(x11,"CornFlowerBlue",&LIGHTBLUE);
452 else
453 fprintf(x11->console,"Monochrome screen.\n");
455 /* We should use Xrm here... */
456 if (FG)
457 GetNamedColor(x11,FG,&(x11->fg));
458 else
459 x11->fg=BLACK;
460 if (BG)
461 GetNamedColor(x11,BG,&(x11->bg));
462 else
463 x11->bg=LIGHTGREY;
464 x11->title=strdup(title);
465 sfree(title);
466 x11->wlist=NULL;
467 x11->GetNamedColor=&GetNamedColor;
468 x11->MainLoop=&MainLoop;
469 x11->RegisterCallback=&RegisterCallback;
470 x11->UnRegisterCallback=&UnRegisterCallback;
471 x11->SetInputMask=&SetInputMask;
472 x11->GetInputMask=&GetInputMask;
473 x11->CleanUp=&CleanUp;
474 x11->Flush=&Flush;
476 x11->Flush(x11);
478 return x11;