Sort includes outside src/gromacs
[alexxy/gromacs.git] / src / programs / view / logo.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2013, The GROMACS development team.
6  * Copyright (c) 2013,2014, 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.
10  *
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.
15  *
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.
20  *
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.
25  *
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.
33  *
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.
36  */
37 #include "gmxpre.h"
38
39 #include "logo.h"
40
41 #include <stdlib.h>
42
43 #include "gromacs/legacyheaders/copyrite.h"
44 #include "gromacs/legacyheaders/macros.h"
45 #include "gromacs/utility/real.h"
46 #include "gromacs/utility/smalloc.h"
47
48 #include "Xstuff.h"
49 #include "xutil.h"
50
51 typedef struct {
52     int            x, y, rad;
53     unsigned long *col;
54 } t_circle;
55
56 typedef struct {
57     const char  *text;
58     int          y, h;
59     XFontStruct *fnt;
60 } t_mess;
61
62 void show_logo(t_x11 *x11, t_logo *logo)
63 {
64     XMapWindow(x11->disp, logo->wd.self);
65     XMapSubwindows(x11->disp, logo->wd.self);
66 }
67
68 void hide_logo(t_x11 *x11, t_logo *logo)
69 {
70     XUnmapWindow(x11->disp, logo->wd.self);
71 }
72
73 static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data)
74 {
75     /* Assume window is 100x110 */
76     static bool bFirst = true;
77 #define CSIZE 9
78 #define NSIZE 8
79 #define OSIZE 9
80 #define HSIZE 7
81 #define YOFFS 30
82     static t_circle c[] = {
83         { 10, YOFFS+12, CSIZE, &LIGHTGREEN },
84         { 20, YOFFS+22, CSIZE, &LIGHTGREEN },
85         { 20, YOFFS+34, OSIZE, &LIGHTRED   },
86         { 30, YOFFS+12, NSIZE, &LIGHTCYAN  },
87         { 30, YOFFS+ 2, HSIZE, &WHITE     },
88         { 40, YOFFS+22, CSIZE, &LIGHTGREEN },
89         { 40, YOFFS+34, CSIZE, &LIGHTGREEN },
90         { 50, YOFFS+12, CSIZE, &LIGHTGREEN },
91         { 50, YOFFS,    OSIZE, &LIGHTRED   },
92         { 60, YOFFS+22, NSIZE, &LIGHTCYAN  },
93         { 60, YOFFS+32, HSIZE, &WHITE     },
94         { 70, YOFFS+12, CSIZE, &LIGHTGREEN },
95         { 80, YOFFS+22, CSIZE, &LIGHTGREEN },
96         { 80, YOFFS+34, OSIZE, &LIGHTRED   },
97         { 90, YOFFS+12, NSIZE, &LIGHTCYAN  },
98         { 90, YOFFS+ 2, HSIZE, &WHITE      },
99         {100, YOFFS+22, CSIZE, &LIGHTGREEN }
100     };
101     static int      lines[] = {
102         0, 1, 1, 2, 1, 3, 3, 4, 3, 5, 5, 6, 5, 7, 7, 8, 7, 9,
103         9, 10, 9, 11, 11, 12, 12, 13, 12, 14, 14, 15, 14, 16
104     };
105 #define COFFS 70
106     static t_mess   Mess[] = {
107         { "GROMACS",                         0,       20, NULL },
108         { NULL,                             16,        9, NULL },
109         { "Copyright (c) 1991-2013",        COFFS+ 2,  9, NULL },
110         { "D.v.d.Spoel, E.Lindahl, B.Hess", COFFS+11,  9, NULL },
111         { "& Groningen University ",        COFFS+20,  9, NULL },
112         { "click to dismiss",               COFFS+31,  8, NULL }
113     };
114 #define NMESS asize(Mess)
115     int             i;
116     t_logo         *logo;
117     t_windata      *wd;
118
119     logo = (t_logo *)data;
120     wd   = &(logo->wd);
121     if (bFirst)
122     {
123         const real wfac = wd->width/110.0;
124         const real hfac = wd->height/110.0;
125         for (i = 0; (i < asize(c)); i++)
126         {
127             c[i].x *= wfac;
128             c[i].y *= hfac;
129         }
130         Mess[1].text = GromacsVersion();
131         for (i = 0; (i < NMESS); i++)
132         {
133             Mess[i].y  *= hfac;
134             Mess[i].h  *= hfac;
135             Mess[i].fnt = (i == 0) ? logo->bigfont : (i == NMESS-1) ? x11->font :
136                 logo->smallfont;
137         }
138         bFirst = false;
139     }
140     switch (event->type)
141     {
142         case Expose:
143             XSetForeground(x11->disp, x11->gc, WHITE);
144             XSetLineAttributes(x11->disp, x11->gc, 3, LineSolid, CapNotLast, JoinRound);
145             for (i = 0; (i < asize(lines)); i += 2)
146             {
147                 XDrawLine(x11->disp, wd->self, x11->gc,
148                           c[lines[i]].x, c[lines[i]].y, c[lines[i+1]].x, c[lines[i+1]].y);
149             }
150             XSetLineAttributes(x11->disp, x11->gc, 1, LineSolid, CapNotLast, JoinRound);
151             for (i = 0; (i < asize(c)); i++)
152             {
153                 XSetForeground(x11->disp, x11->gc, *(c[i].col));
154                 XFillCircle(x11->disp, wd->self, x11->gc, c[i].x, c[i].y, c[i].rad);
155             }
156             XSetForeground(x11->disp, x11->gc, BLACK);
157             XDrawRectangle(x11->disp, wd->self, x11->gc, 2, 2, wd->width-5, wd->height-5);
158             for (i = 0; (i < NMESS); i++)
159             {
160                 SpecialTextInRect(x11, Mess[i].fnt, wd->self, Mess[i].text,
161                                   0, Mess[i].y, wd->width, Mess[i].h,
162                                   eXCenter, eYCenter);
163             }
164             XSetForeground(x11->disp, x11->gc, x11->fg);
165             break;
166         case ButtonPress:
167             hide_logo(x11, logo);
168             return logo->bQuitOnClick;
169             break;
170         default:
171             break;
172     }
173
174     return false;
175 }
176
177 t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick)
178 {
179     static const char *bfname[] = {
180         "-b&h-lucida-bold-i-normal-sans-34-240-100-100-p-215-iso8859-1",
181         "-b&h-lucida-bold-i-normal-sans-26-190-100-100-p-166-iso8859-1",
182         "lucidasans-bolditalic-24",
183         "lucidasans-italic-24",
184         "10x20",
185         "fixed"
186     };
187 #define NBF asize(bfname)
188     static const char *sfname[] = {
189         "lucidasans-bold-18",
190         "10x20",
191         "fixed"
192     };
193 #define NSF asize(sfname)
194     unsigned int       i;
195     unsigned long      bg;
196     char              *newcol;
197     t_logo            *logo;
198
199     snew(logo, 1);
200     logo->bQuitOnClick = bQuitOnClick;
201     InitWin(&logo->wd, 0, 0, 360, 270, 1, "GROMACS");
202     bg = LIGHTGREY;
203     if ((newcol = getenv("GMX_LOGO_COLOR")) != NULL)
204     {
205         GetNamedColor(x11, newcol, &bg);
206     }
207     logo->wd.self = XCreateSimpleWindow(x11->disp, parent,
208                                         logo->wd.x, logo->wd.y,
209                                         logo->wd.width, logo->wd.height,
210                                         logo->wd.bwidth, WHITE, bg);
211     for (i = 0, logo->bigfont = NULL; (i < NBF); i++)
212     {
213         if ((logo->bigfont = XLoadQueryFont(x11->disp, bfname[i])) != NULL)
214         {
215             break;
216         }
217     }
218     if (i == NBF)
219     {
220         perror(bfname[i-1]);
221         exit(1);
222     }
223 #ifdef DEBUG
224     fprintf(stderr, "Big Logofont: %s\n", bfname[i]);
225 #endif
226     for (i = 0, logo->smallfont = NULL; (i < NSF); i++)
227     {
228         if ((logo->smallfont = XLoadQueryFont(x11->disp, sfname[i])) != NULL)
229         {
230             break;
231         }
232     }
233     if (i == NSF)
234     {
235         perror(sfname[i-1]);
236         exit(1);
237     }
238 #ifdef DEBUG
239     fprintf(stderr, "Small Logofont: %s\n", sfname[i]);
240 #endif
241     x11->RegisterCallback(x11, logo->wd.self, parent, LogoCallBack, logo);
242     x11->SetInputMask(x11, logo->wd.self, ButtonPressMask | ExposureMask);
243
244     return logo;
245 }
246
247 void done_logo(t_x11 *x11, t_logo *logo)
248 {
249     x11->UnRegisterCallback(x11, logo->wd.self);
250 }