Remove repeat sfree(state->nosehoover_xi)
[gromacs.git] / src / ngmx / x11.c
blobb5b69972101a8660e2bf7a73948f34d743368b26
1 /*
3 * This source code is part of
5 * G R O M A C S
7 * GROningen MAchine for Chemical Simulations
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 "typedefs.h"
40 #include <Xstuff.h>
41 #include <x11.h>
42 #include "sysstuff.h"
43 #include <string.h>
44 #include "smalloc.h"
45 #include "string2.h"
47 /* These colours will be mapped to black on a monochrome screen */
48 unsigned long BLACK, BLUE, GREEN, CYAN, RED, BROWN, GREY, DARKGREY;
50 /* These colours will be mapped to white on a monochrome screen */
51 unsigned long LIGHTBLUE, LIGHTGREEN, LIGHTGREY, LIGHTCYAN, LIGHTRED, VIOLET, YELLOW, WHITE;
53 static XFontStruct *XLQF(FILE *err, Display *disp, const char *name)
55 XFontStruct *font = XLoadQueryFont(disp, name);
56 #ifdef DEBUG
57 if (font != NULL)
59 fprintf(err, "Loaded font %s\n", name);
61 #endif
62 return font;
65 static XFontStruct *GetFont(FILE *err, Display *disp, char *name)
67 static const char *fontnames[] = {
68 "sansb12", "8x13bold", "8x13",
69 "9x15", "6x13", "fixed"
71 #define MAXNAMES (sizeof(fontnames)/sizeof(fontnames[0]))
72 int i;
73 XFontStruct *font;
74 int count;
75 char **fontlist;
76 gmx_bool bFont = FALSE;
78 if (name)
80 bFont = (gmx_bool) ((font = XLQF(err, disp, name)) != NULL);
82 else
84 font = NULL;
87 for (i = 0; (!bFont && (i < MAXNAMES)); i++)
89 bFont = (gmx_bool) ((font = XLQF(err, disp, fontnames[i])) != NULL);
92 if (!bFont)
94 fontlist = XListFonts(disp, "?", 1, &count);
95 if (count != 0)
97 bFont = (gmx_bool) ((font = XLQF(err, disp, fontlist[0])) != NULL);
100 if (!bFont)
102 fprintf (err, "Cannot load any suitable font\n");
104 return font;
107 static GC GetGC(Display *disp, XFontStruct *font)
109 XGCValues values;
111 values.font = font->fid;
112 values.foreground = WhitePixel(disp, DefaultScreen(disp));
114 return XCreateGC(disp, DefaultRootWindow(disp), GCForeground|GCFont, &values);
117 void GetNamedColor(t_x11 *x11, const char *name, unsigned long *col)
119 /* If name is found than col set to that colour else col is unchanged */
120 XColor exact, clr;
122 if (XAllocNamedColor(x11->disp, x11->cmap, name, &clr, &exact))
124 *col = clr.pixel;
126 else
128 fprintf(x11->console, "No colour %s\n", name);
132 static t_wlist *GetWList(t_x11 *x11, Window w)
134 t_wlist *curs;
136 curs = x11->wlist;
137 while (curs && (curs->w != w))
139 curs = curs->next;
142 return curs;
145 typedef struct {
146 Window w;
147 gmx_bool b;
148 } t_peek;
150 static Bool TestEvent(Display *disp, XEvent *event, char *arg)
152 t_peek *tp;
154 fprintf(stderr, "TestEvent\n");
155 tp = (t_peek *)arg;
156 if ((event->xany.window == tp->w) && (event->type == ConfigureNotify))
158 tp->b = TRUE;
159 return True;
161 return False;
164 static void MainLoop(t_x11 *x11)
166 gmx_bool bReturn;
167 XEvent event;
168 t_wlist *curs;
169 Window w;
171 for (bReturn = FALSE; (!bReturn); )
173 if (x11->wlist)
175 XNextEvent(x11->disp, &event);
176 w = event.xany.window;
177 curs = GetWList(x11, w);
178 if (!curs)
180 bReturn = TRUE;
182 if (!bReturn)
184 switch (event.type)
186 case Expose:
187 /* Filter out expose events with non-zero count field */
188 if (event.xexpose.count != 0)
190 curs = NULL;
192 break;
193 case ConfigureNotify:
194 /* Check if more are coming...
195 if (XCheckTypedWindowEvent(x11->disp,w,ConfigureNotify,&config))
196 curs=NULL; */
197 break;
198 default:
199 break;
201 if (curs)
203 bReturn = (*curs->cb)(x11, &event, w, curs->data);
210 static void RegisterCallback(t_x11 *x11, Window w, Window Parent,
211 CallBack cb, void *data)
213 t_wlist *curs, *item;
215 snew(item, 1);
216 item->w = w;
217 item->Parent = Parent;
218 item->cb = cb;
219 item->mask = 0;
220 item->data = data;
221 item->next = NULL;
223 if (x11->wlist)
225 curs = x11->wlist;
226 while (curs->next)
228 curs = curs->next;
230 curs->next = item;
232 else
234 x11->wlist = item;
238 static void UnRegisterCallback(t_x11 *x11, Window w)
240 t_wlist *curs;
242 curs = x11->wlist;
243 if (curs)
245 if (curs->w == w)
247 x11->wlist = curs->next;
248 sfree(curs);
250 else
252 while (curs->next && (curs->next->w != w))
254 curs = curs->next;
256 if (curs->next)
258 t_wlist *tmp = curs->next;
260 curs->next = curs->next->next;
261 sfree(tmp);
267 static void SetInputMask(t_x11 *x11, Window w, unsigned long mask)
269 t_wlist *curs;
271 curs = GetWList(x11, w);
272 if (curs)
274 curs->mask = mask;
275 XSelectInput(x11->disp, w, (long)mask);
277 else
279 fprintf(x11->console, "No such window (%d)\n", (int)w);
283 static unsigned long GetInputMask(t_x11 *x11, Window w)
285 t_wlist *curs;
287 curs = GetWList(x11, w);
288 if (curs)
290 return curs->mask;
292 else
294 return 0;
298 static void CleanUp(t_x11 *x11)
300 t_wlist *curs;
302 curs = x11->wlist;
303 while (curs)
305 x11->wlist = curs->next;
306 XDestroyWindow(x11->disp, curs->w);
307 sfree(curs);
308 curs = x11->wlist;
310 XCloseDisplay(x11->disp);
313 static void Xrm(int *argc, char *argv[])
316 static XrmOptionDescRec opTable[] = {
317 {"-background", "*background",
318 XrmoptionSepArg, (caddr_t) NULL},
319 {"-bd", "*borderColor",
320 XrmoptionSepArg, (caddr_t) NULL},
321 {"-bg", "*background",
322 XrmoptionSepArg, (caddr_t) NULL},
323 {"-borderwidth", "*TopLevelShell.borderwidth",
324 XrmoptionSepArg, (caddr_t) NULL},
325 {"-bordercolor", "*borderColor",
326 XrmoptionSepArg, (caddr_t) NULL},
327 {"-bw", "*TopLevelShell.borderColor",
328 XrmoptionSepArg, (caddr_t) NULL},
329 {"-display", ".display",
330 XrmoptionSepArg, (caddr_t) NULL},
331 {"-fg", "*foreground",
332 XrmoptionSepArg, (caddr_t) NULL},
333 {"-fn", "*font",
334 XrmoptionSepArg, (caddr_t) NULL},
335 {"-font", "*font",
336 XrmoptionSepArg, (caddr_t) NULL},
337 {"-foreground", "*foreground",
338 XrmoptionSepArg, (caddr_t) NULL},
339 {"-geometry", ".TopLevelShell.geometry",
340 XrmoptionSepArg, (caddr_t) NULL},
341 {"-iconic", ".TopLevelShell.iconic",
342 XrmoptionNoArg, (caddr_t) "on"},
343 {"-name", ".name",
344 XrmoptionSepArg, (caddr_t) NULL},
345 {"-reverse", "*reverseVideo",
346 XrmoptionNoArg, (caddr_t) "on"},
347 {"-rv", "*reverseVideo",
348 XrmoptionNoArg, (caddr_t) "on"},
349 {"-synchronous", ".synchronous",
350 XrmoptionNoArg, (caddr_t) "on"},
351 {"-title", ".TopLevelShell.title",
352 XrmoptionSepArg, (caddr_t) NULL},
353 {"-xrm", NULL,
354 XrmoptionSepArg, (caddr_t) NULL},
356 #define TABLELENGTH (sizeof(opTable)/sizeof(opTable[0]))
357 XrmInitialize();*/
360 static void Flush(t_x11 *x11)
362 fflush(x11->console);
365 t_x11 *GetX11(int *argc, char *argv[])
367 static const char *v_name[] = {
368 "DirectColor", "TrueColor", "PseudoColor",
369 "StaticColor", "GrayScale", "StaticGray"
371 static int v_class[] = {
372 DirectColor, TrueColor, PseudoColor,
373 StaticColor, GrayScale, StaticGray
375 #define NCLASS (sizeof(v_class)/sizeof(v_class[0]))
377 XVisualInfo v_info;
378 t_x11 *x11;
379 int ARGC;
380 char **ARGV;
381 char *display;
382 char *fontname;
383 char *title, *FG = NULL, *BG = NULL;
384 gmx_bool bVerbose = FALSE;
385 int i;
387 title = strdup(argv[0]);
389 /* First check environment */
390 fontname = getenv("GMXFONT");
391 display = getenv("DISPLAY");
393 snew(ARGV, *argc);
394 ARGC = 1;
395 for (i = 1; (i < *argc); i++)
397 if (argv[i][0] == '-')
399 if (strlen(argv[i]) > 1)
401 if ((*argc) > i+1)
403 switch (argv[i][1])
405 case 'b':
406 BG = argv[++i];
407 break;
408 case 'd':
409 display = argv[++i];
410 break;
411 case 'f':
412 switch (argv[i][2])
414 case 'o':
415 fontname = argv[++i];
416 break;
417 case 'g':
418 FG = argv[++i];
419 break;
421 break;
422 case 't':
423 sfree(title);
424 title = strdup(argv[++i]);
425 break;
426 case 'v':
427 bVerbose = TRUE;
428 break;
429 default:
430 ARGV[ARGC++] = argv[i];
431 break;
436 else
438 ARGV[ARGC++] = argv[i];
441 for (i = 1; (i < ARGC); i++)
443 argv[i] = ARGV[i];
445 *argc = ARGC;
446 argv[ARGC] = NULL;
448 snew(x11, 1);
449 x11->dispname = display;
450 if (bVerbose)
452 x11->console = stderr;
454 else
455 if ((x11->console = fopen("/dev/null", "w")) == NULL)
457 x11->console = stderr;
460 if ((x11->disp = XOpenDisplay(display)) == NULL)
462 if (bVerbose)
464 fprintf(x11->console, "Display %s invalid\n", display);
466 return NULL;
469 if ((x11->font = GetFont(x11->console, x11->disp, fontname)) == NULL)
471 return NULL;
473 if ((x11->gc = GetGC(x11->disp, x11->font)) == NULL)
475 return NULL;
478 x11->root = DefaultRootWindow(x11->disp);
479 x11->screen = DefaultScreen(x11->disp);
480 x11->depth = DefaultDepth(x11->disp, x11->screen);
481 x11->cmap = DefaultColormap(x11->disp, x11->screen);
483 /* These colours will be mapped to black on a monochrome screen */
484 x11->fg = BLACK = BLUE = GREEN = CYAN = RED = BROWN = GREY = DARKGREY =
485 BlackPixel(x11->disp, x11->screen);
487 /* These colours will be mapped to white on a monochrome screen */
488 x11->bg =
489 LIGHTBLUE = LIGHTGREY = LIGHTGREEN = LIGHTCYAN = LIGHTRED = VIOLET = YELLOW = WHITE =
490 WhitePixel(x11->disp, x11->screen);
492 if (x11->depth > 1)
494 /* Not B & W, Look what kind of screen we've got... */
495 for (i = 0; (i < NCLASS); i++)
497 if (!XMatchVisualInfo(x11->disp, x11->screen, x11->depth,
498 v_class[i], &v_info))
500 break;
503 if ((i == 4) || (i == 5))
505 fprintf(x11->console, "Greyscale screen, using B & W only\n");
507 else
509 /* We have real color! */
510 fprintf(x11->console, "%s screen with depth %d.\n",
511 (i == NCLASS) ? "Unknown" : v_name[i], x11->depth);
512 GetNamedColor(x11, "midnight blue", &BLUE);
513 GetNamedColor(x11, "DarkGreen", &GREEN);
514 GetNamedColor(x11, "SeaGreen", &CYAN);
515 GetNamedColor(x11, "red4", &RED);
516 GetNamedColor(x11, "Gray", &GREY);
517 GetNamedColor(x11, "Gray", &DARKGREY);
518 GetNamedColor(x11, "LightGray", &LIGHTGREY);
519 GetNamedColor(x11, "green", &LIGHTGREEN);
520 GetNamedColor(x11, "cyan", &LIGHTCYAN);
521 GetNamedColor(x11, "tomato1", &LIGHTRED);
522 GetNamedColor(x11, "violet", &VIOLET);
523 GetNamedColor(x11, "yellow", &YELLOW);
524 GetNamedColor(x11, "brown", &BROWN);
525 GetNamedColor(x11, "CornFlowerBlue", &LIGHTBLUE);
528 else
530 fprintf(x11->console, "Monochrome screen.\n");
533 /* We should use Xrm here... */
534 if (FG)
536 GetNamedColor(x11, FG, &(x11->fg));
538 else
540 x11->fg = BLACK;
542 if (BG)
544 GetNamedColor(x11, BG, &(x11->bg));
546 else
548 x11->bg = LIGHTGREY;
550 x11->title = strdup(title);
551 sfree(title);
552 x11->wlist = NULL;
553 x11->GetNamedColor = &GetNamedColor;
554 x11->MainLoop = &MainLoop;
555 x11->RegisterCallback = &RegisterCallback;
556 x11->UnRegisterCallback = &UnRegisterCallback;
557 x11->SetInputMask = &SetInputMask;
558 x11->GetInputMask = &GetInputMask;
559 x11->CleanUp = &CleanUp;
560 x11->Flush = &Flush;
562 x11->Flush(x11);
564 return x11;