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-2013, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
45 #include "gromacs/utility/cstringutil.h"
46 #include "gromacs/utility/smalloc.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 gmx_unused
*err
, Display
*disp
, const char *name
)
58 XFontStruct
*font
= XLoadQueryFont(disp
, name
);
62 std::fprintf(err
, "Loaded font %s\n", name
);
68 static XFontStruct
*GetFont(FILE *err
, Display
*disp
, char *name
)
70 static const char *fontnames
[] = {
71 "sansb12", "8x13bold", "8x13",
72 "9x15", "6x13", "fixed"
74 #define MAXNAMES (sizeof(fontnames)/sizeof(fontnames[0]))
83 bFont
= ((font
= XLQF(err
, disp
, name
)) != nullptr);
90 for (i
= 0; (!bFont
&& (i
< MAXNAMES
)); i
++)
92 bFont
= ((font
= XLQF(err
, disp
, fontnames
[i
])) != nullptr);
97 fontlist
= XListFonts(disp
, "?", 1, &count
);
100 bFont
= ((font
= XLQF(err
, disp
, fontlist
[0])) != nullptr);
105 fprintf (err
, "Cannot load any suitable font\n");
110 static GC
GetGC(Display
*disp
, XFontStruct
*font
)
114 values
.font
= font
->fid
;
115 values
.foreground
= WhitePixel(disp
, DefaultScreen(disp
));
117 return XCreateGC(disp
, DefaultRootWindow(disp
), GCForeground
|GCFont
, &values
);
120 void GetNamedColor(t_x11
*x11
, const char *name
, unsigned long *col
)
122 /* If name is found than col set to that colour else col is unchanged */
125 if (XAllocNamedColor(x11
->disp
, x11
->cmap
, name
, &clr
, &exact
))
131 std::fprintf(x11
->console
, "No colour %s\n", name
);
135 static t_wlist
*GetWList(t_x11
*x11
, Window w
)
140 while (curs
&& (curs
->w
!= w
))
148 static void MainLoop(t_x11
*x11
)
155 for (bReturn
= false; (!bReturn
); )
159 XNextEvent(x11
->disp
, &event
);
160 w
= event
.xany
.window
;
161 curs
= GetWList(x11
, w
);
171 /* Filter out expose events with non-zero count field */
172 if (event
.xexpose
.count
!= 0)
177 case ConfigureNotify
:
178 /* Check if more are coming...
179 if (XCheckTypedWindowEvent(x11->disp,w,ConfigureNotify,&config))
187 bReturn
= (*curs
->cb
)(x11
, &event
, w
, curs
->data
);
194 static void RegisterCallback(t_x11
*x11
, Window w
, Window Parent
,
195 CallBack cb
, void *data
)
197 t_wlist
*curs
, *item
;
201 item
->Parent
= Parent
;
205 item
->next
= nullptr;
222 static void UnRegisterCallback(t_x11
*x11
, Window w
)
231 x11
->wlist
= curs
->next
;
236 while (curs
->next
&& (curs
->next
->w
!= w
))
242 t_wlist
*tmp
= curs
->next
;
244 curs
->next
= curs
->next
->next
;
251 static void SetInputMask(t_x11
*x11
, Window w
, unsigned long mask
)
255 curs
= GetWList(x11
, w
);
259 XSelectInput(x11
->disp
, w
, (long)mask
);
263 std::fprintf(x11
->console
, "No such window (%d)\n", (int)w
);
267 static unsigned long GetInputMask(t_x11
*x11
, Window w
)
271 curs
= GetWList(x11
, w
);
282 static void CleanUp(t_x11
*x11
)
289 x11
->wlist
= curs
->next
;
290 XDestroyWindow(x11
->disp
, curs
->w
);
294 XCloseDisplay(x11
->disp
);
297 static void Flush(t_x11
*x11
)
299 std::fflush(x11
->console
);
302 t_x11
*GetX11(int *argc
, char *argv
[])
304 static const char *v_name
[] = {
305 "DirectColor", "TrueColor", "PseudoColor",
306 "StaticColor", "GrayScale", "StaticGray"
308 static int v_class
[] = {
309 DirectColor
, TrueColor
, PseudoColor
,
310 StaticColor
, GrayScale
, StaticGray
312 #define NCLASS (sizeof(v_class)/sizeof(v_class[0]))
320 char *title
, *FG
= nullptr, *BG
= nullptr;
321 bool bVerbose
= false;
324 title
= gmx_strdup(argv
[0]);
326 /* First check environment */
327 fontname
= std::getenv("GMX_FONT");
328 display
= std::getenv("DISPLAY");
332 for (i
= 1; (i
< *argc
); i
++)
334 if (argv
[i
][0] == '-')
336 if (strlen(argv
[i
]) > 1)
352 fontname
= argv
[++i
];
361 title
= gmx_strdup(argv
[++i
]);
367 ARGV
[ARGC
++] = argv
[i
];
375 ARGV
[ARGC
++] = argv
[i
];
378 for (i
= 1; (i
< ARGC
); i
++)
383 argv
[ARGC
] = nullptr;
386 x11
->dispname
= display
;
389 x11
->console
= stderr
;
392 if ((x11
->console
= std::fopen("/dev/null", "w")) == nullptr)
394 x11
->console
= stderr
;
397 if ((x11
->disp
= XOpenDisplay(display
)) == nullptr)
401 std::fprintf(x11
->console
, "Display %s invalid\n", display
);
406 if ((x11
->font
= GetFont(x11
->console
, x11
->disp
, fontname
)) == nullptr)
410 if ((x11
->gc
= GetGC(x11
->disp
, x11
->font
)) == nullptr)
415 x11
->root
= DefaultRootWindow(x11
->disp
);
416 x11
->screen
= DefaultScreen(x11
->disp
);
417 x11
->depth
= DefaultDepth(x11
->disp
, x11
->screen
);
418 x11
->cmap
= DefaultColormap(x11
->disp
, x11
->screen
);
420 /* These colours will be mapped to black on a monochrome screen */
421 x11
->fg
= BLACK
= BLUE
= GREEN
= CYAN
= RED
= BROWN
= GREY
= DARKGREY
=
422 BlackPixel(x11
->disp
, x11
->screen
);
424 /* These colours will be mapped to white on a monochrome screen */
426 LIGHTBLUE
= LIGHTGREY
= LIGHTGREEN
= LIGHTCYAN
= LIGHTRED
= VIOLET
= YELLOW
= WHITE
=
427 WhitePixel(x11
->disp
, x11
->screen
);
431 /* Not B & W, Look what kind of screen we've got... */
432 for (i
= 0; (i
< (int)NCLASS
); i
++)
434 if (!XMatchVisualInfo(x11
->disp
, x11
->screen
, x11
->depth
,
435 v_class
[i
], &v_info
))
440 if ((i
== 4) || (i
== 5))
442 std::fprintf(x11
->console
, "Greyscale screen, using B & W only\n");
446 /* We have real color! */
447 std::fprintf(x11
->console
, "%s screen with depth %d.\n",
448 (i
== NCLASS
) ? "Unknown" : v_name
[i
], x11
->depth
);
449 GetNamedColor(x11
, "midnight blue", &BLUE
);
450 GetNamedColor(x11
, "DarkGreen", &GREEN
);
451 GetNamedColor(x11
, "SeaGreen", &CYAN
);
452 GetNamedColor(x11
, "red4", &RED
);
453 GetNamedColor(x11
, "Gray", &GREY
);
454 GetNamedColor(x11
, "Gray", &DARKGREY
);
455 GetNamedColor(x11
, "LightGray", &LIGHTGREY
);
456 GetNamedColor(x11
, "green", &LIGHTGREEN
);
457 GetNamedColor(x11
, "cyan", &LIGHTCYAN
);
458 GetNamedColor(x11
, "tomato1", &LIGHTRED
);
459 GetNamedColor(x11
, "violet", &VIOLET
);
460 GetNamedColor(x11
, "yellow", &YELLOW
);
461 GetNamedColor(x11
, "brown", &BROWN
);
462 GetNamedColor(x11
, "CornFlowerBlue", &LIGHTBLUE
);
467 std::fprintf(x11
->console
, "Monochrome screen.\n");
470 /* We should use Xrm here... */
473 GetNamedColor(x11
, FG
, &(x11
->fg
));
481 GetNamedColor(x11
, BG
, &(x11
->bg
));
487 x11
->title
= gmx_strdup(title
);
489 x11
->wlist
= nullptr;
490 x11
->GetNamedColor
= &GetNamedColor
;
491 x11
->MainLoop
= &MainLoop
;
492 x11
->RegisterCallback
= &RegisterCallback
;
493 x11
->UnRegisterCallback
= &UnRegisterCallback
;
494 x11
->SetInputMask
= &SetInputMask
;
495 x11
->GetInputMask
= &GetInputMask
;
496 x11
->CleanUp
= &CleanUp
;