SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / programs / view / dialogs.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,2015,2016,2017 by the GROMACS development team.
7  * Copyright (c) 2019,2020, by the GROMACS development team, led by
8  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9  * and including many others, as listed in the AUTHORS file in the
10  * top-level source directory and at http://www.gromacs.org.
11  *
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.
16  *
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.
21  *
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.
26  *
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.
34  *
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.
37  */
38 #include "gmxpre.h"
39
40 #include "dialogs.h"
41
42 #include "config.h"
43
44 #include <cstdio>
45 #include <cstdlib>
46 #include <cstring>
47
48 #ifdef HAVE_UNISTD_H
49 #    include <unistd.h> // for fork()
50 #endif
51
52 #include "gromacs/mdtypes/md_enums.h"
53 #include "gromacs/utility/arraysize.h"
54 #include "gromacs/utility/cstringutil.h"
55 #include "gromacs/utility/dir_separator.h"
56 #include "gromacs/utility/fatalerror.h"
57 #include "gromacs/utility/futil.h"
58 #include "gromacs/utility/smalloc.h"
59
60 #include "manager.h"
61 #include "nmol.h"
62 #include "x11.h"
63 #include "xdlghi.h"
64 #include "xmb.h"
65
66 #define MBFLAGS /* MB_APPLMODAL | */ MB_DONTSHOW
67
68 void write_gmx(t_x11* x11, t_gmx* gmx, int mess)
69 {
70     XEvent letter;
71
72     letter.type                 = ClientMessage;
73     letter.xclient.display      = x11->disp;
74     letter.xclient.window       = gmx->wd->self;
75     letter.xclient.message_type = 0;
76     letter.xclient.format       = 32;
77     letter.xclient.data.l[0]    = mess;
78     letter.xclient.data.l[1]    = Button1;
79     XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter);
80 }
81
82 static void shell_comm(const char* title, const char* script, int nsleep)
83 {
84     FILE* tfil;
85     char  command[STRLEN];
86     char  tmp[32];
87
88     std::strcpy(tmp, "dialogXXXXXX");
89     tfil = gmx_fopen_temporary(tmp);
90
91     fprintf(tfil, "%s\n", script);
92     fprintf(tfil, "sleep %d\n", nsleep);
93     gmx_ffclose(tfil);
94
95     std::sprintf(command, "xterm -title %s -e sh %s", title, tmp);
96 #ifdef DEBUG
97     std::fprintf(stderr, "command: %s\n", command);
98 #endif
99
100     if (0 != std::system(command))
101     {
102         gmx_fatal(FARGS, "Failed to execute command: %s", command);
103     }
104
105 #ifdef DEBUG
106     unlink(tmp)
107 #endif
108 }
109
110 void show_mb(t_gmx* gmx, int mb)
111 {
112     if (mb >= 0 && mb < emNR)
113     {
114         gmx->which_mb = mb;
115         ShowDlg(gmx->mboxes[mb]);
116     }
117 }
118
119 static void hide_mb(t_gmx* gmx)
120 {
121     if (gmx->which_mb >= 0 && gmx->which_mb < emNR)
122     {
123         HideDlg(gmx->mboxes[gmx->which_mb]);
124         gmx->which_mb = -1;
125     }
126 }
127
128 static void MBCallback(t_x11* /*x11*/, int dlg_mess, int /*item_id*/, char* /*set*/, void* data)
129 {
130     t_gmx* gmx;
131
132     gmx = static_cast<t_gmx*>(data);
133     if (dlg_mess == DLG_EXIT)
134     {
135         hide_mb(gmx);
136     }
137 }
138
139 static t_dlg* about_mb(t_x11* x11, t_gmx* gmx)
140 {
141     const char* lines[] = { "         G R O M A C S",
142                             " Machine for Simulating Chemistry",
143                             "       Copyright (c) 1992-2013",
144                             "  Berk Hess, David van der Spoel, Erik Lindahl",
145                             "        and many collaborators!" };
146
147     return MessageBox(
148             x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONGMX | MBFLAGS, MBCallback, gmx);
149 }
150
151 static void QuitCB(t_x11* x11, int dlg_mess, int /*item_id*/, char* set, void* data)
152 {
153     t_gmx* gmx;
154     gmx = static_cast<t_gmx*>(data);
155
156     hide_mb(gmx);
157     if (dlg_mess == DLG_EXIT)
158     {
159         if (gmx_strcasecmp("yes", set) == 0)
160         {
161             write_gmx(x11, gmx, IDTERM);
162         }
163     }
164 }
165
166 static t_dlg* quit_mb(t_x11* x11, t_gmx* gmx)
167 {
168     const char* lines[] = { " Do you really want to Quit ?" };
169
170     return MessageBox(
171             x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_YESNO | MB_ICONSTOP | MBFLAGS, QuitCB, gmx);
172 }
173
174 static t_dlg* help_mb(t_x11* x11, t_gmx* gmx)
175 {
176     const char* lines[] = { " Help will soon be added" };
177
178     return MessageBox(
179             x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONINFORMATION | MBFLAGS, MBCallback, gmx);
180 }
181
182 static t_dlg* ni_mb(t_x11* x11, t_gmx* gmx)
183 {
184     const char* lines[] = { " This feature has not been", " implemented yet." };
185
186     return MessageBox(
187             x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, MB_OK | MB_ICONEXCLAMATION | MBFLAGS, MBCallback, gmx);
188 }
189
190 enum
191 {
192     eExE,
193     eExGrom,
194     eExPdb,
195     eExConf,
196     eExNR
197 };
198
199 static void ExportCB(t_x11* x11, int dlg_mess, int item_id, char* set, void* data)
200 {
201     bool   bOk;
202     t_gmx* gmx;
203     t_dlg* dlg;
204
205     gmx = static_cast<t_gmx*>(data);
206     dlg = gmx->dlgs[edExport];
207     switch (dlg_mess)
208     {
209         case DLG_SET:
210             switch (item_id)
211             {
212                 case eExGrom: gmx->ExpMode = eExpGromos; break;
213                 case eExPdb: gmx->ExpMode = eExpPDB; break;
214                 default: break;
215             }
216 #ifdef DEBUG
217             std::fprintf(stderr, "exportcb: item_id=%d\n", item_id);
218 #endif
219             break;
220         case DLG_EXIT:
221             if ((bOk = gmx_strcasecmp("ok", set)) == 0)
222             {
223                 std::strcpy(gmx->confout, EditText(dlg, eExConf));
224             }
225             HideDlg(dlg);
226             if (bOk)
227             {
228                 write_gmx(x11, gmx, IDDOEXPORT);
229             }
230             break;
231     }
232 }
233
234 enum
235 {
236     eg0,
237     egTOPOL,
238     egCONFIN,
239     egPARAM,
240     eg1,
241     eg1PROC,
242     eg32PROC
243 };
244
245 enum bond_set
246 {
247     ebShowH = 11,
248     ebDPlus,
249     ebRMPBC,
250     ebCue,
251     ebSkip,
252     ebWait
253 };
254
255 static void BondsCB(t_x11* x11, int dlg_mess, int item_id, char* set, void* data)
256 {
257     static int ebond = -1;
258     static int ebox  = -1;
259     bool       bOk, bBond = false;
260     int        nskip, nwait;
261     t_gmx*     gmx;
262     char*      endptr;
263
264     gmx = static_cast<t_gmx*>(data);
265     if (ebond == -1)
266     {
267         ebond = gmx->man->molw->bond_type;
268         ebox  = gmx->man->molw->boxtype;
269     }
270     switch (dlg_mess)
271     {
272         case DLG_SET:
273             if (item_id <= eBNR)
274             {
275                 ebond = item_id - 1;
276                 bBond = false;
277             }
278             else if (item_id <= eBNR + esbNR + 1)
279             {
280                 ebox  = item_id - eBNR - 2;
281                 bBond = true;
282             }
283             else
284             {
285
286 #define DO_NOT(b) (b) = (!(b))
287
288                 switch (item_id)
289                 {
290                     case ebShowH: toggle_hydrogen(x11, gmx->man->molw); break;
291                     case ebDPlus: DO_NOT(gmx->man->bPlus);
292 #ifdef DEBUG
293                         std::fprintf(stderr, "gmx->man->bPlus=%s\n", gmx->man->bPlus ? "true" : "false");
294 #endif
295                         break;
296                     case ebRMPBC: toggle_pbc(gmx->man); break;
297                     case ebCue: DO_NOT(gmx->man->bSort);
298 #ifdef DEBUG
299                         std::fprintf(stderr, "gmx->man->bSort=%s\n", gmx->man->bSort ? "true" : "false");
300 #endif
301                         break;
302                     case ebSkip:
303                         nskip = std::strtol(set, &endptr, 10);
304                         if (endptr != set)
305                         {
306 #ifdef DEBUG
307                             std::fprintf(stderr, "nskip: %d frames\n", nskip);
308 #endif
309                             if (nskip >= 0)
310                             {
311                                 gmx->man->nSkip = nskip;
312                             }
313                         }
314                         break;
315                     case ebWait:
316                         nwait = std::strtol(set, &endptr, 10);
317                         if (endptr != set)
318                         {
319 #ifdef DEBUG
320                             std::fprintf(stderr, "wait: %d ms\n", nwait);
321 #endif
322                             if (nwait >= 0)
323                             {
324                                 gmx->man->nWait = nwait;
325                             }
326                         }
327                     default:
328 #ifdef DEBUG
329                         std::fprintf(stderr, "item_id: %d, set: %s\n", item_id, set);
330 #endif
331                         break;
332                 }
333             }
334             break;
335         case DLG_EXIT:
336             bOk = (gmx_strcasecmp("ok", set) == 0);
337             HideDlg(gmx->dlgs[edBonds]);
338             if (bOk)
339             {
340                 if (bBond)
341                 {
342                     switch (ebond)
343                     {
344                         case eBThin: write_gmx(x11, gmx, IDTHIN); break;
345                         case eBFat: write_gmx(x11, gmx, IDFAT); break;
346                         case eBVeryFat: write_gmx(x11, gmx, IDVERYFAT); break;
347                         case eBSpheres: write_gmx(x11, gmx, IDBALLS); break;
348                         default:
349                             gmx_fatal(FARGS, "Invalid bond type %d at %s, %d", ebond, __FILE__, __LINE__);
350                     }
351                 }
352                 else
353                 {
354                     switch (ebox)
355                     {
356                         case esbNone: write_gmx(x11, gmx, IDNOBOX); break;
357                         case esbRect: write_gmx(x11, gmx, IDRECTBOX); break;
358                         case esbTri: write_gmx(x11, gmx, IDTRIBOX); break;
359                         case esbTrunc: write_gmx(x11, gmx, IDTOBOX); break;
360                         default:
361                             gmx_fatal(FARGS, "Invalid box type %d at %s, %d", ebox, __FILE__, __LINE__);
362                     }
363                 }
364             }
365             break;
366     }
367 }
368
369 enum
370 {
371     esFUNCT = 1,
372     esBSHOW,
373     esINFIL,
374     esINDEXFIL,
375     esLSQ,
376     esSHOW,
377     esPLOTFIL
378 };
379
380 typedef t_dlg* t_mmb(t_x11* x11, t_gmx* gmx);
381
382 typedef struct
383 {
384     const char*  dlgfile;
385     DlgCallback* cb;
386 } t_dlginit;
387
388 void init_dlgs(t_x11* x11, t_gmx* gmx)
389 {
390     static t_dlginit di[]     = { { "export.dlg", ExportCB }, { "bonds.dlg", BondsCB } };
391     static t_mmb*    mi[emNR] = { quit_mb, help_mb, about_mb, ni_mb };
392
393     snew(gmx->dlgs, edNR);
394     for (int i = 0; (i < asize(di)); i++)
395     {
396         gmx->dlgs[i] = ReadDlg(
397                 x11, gmx->wd->self, di[i].dlgfile, di[i].dlgfile, 0, 0, true, false, di[i].cb, gmx);
398     }
399
400     gmx->dlgs[edFilter] = select_filter(x11, gmx);
401
402     snew(gmx->mboxes, emNR);
403     for (int i = 0; (i < emNR); i++)
404     {
405         gmx->mboxes[i] = mi[i](x11, gmx);
406     }
407     gmx->which_mb = -1;
408 }
409
410 void done_dlgs(t_gmx* gmx)
411 {
412     int i;
413
414     for (i = 0; (i < edNR); i++)
415     {
416         FreeDlg(gmx->dlgs[i]);
417     }
418     for (i = 0; (i < emNR); i++)
419     {
420         FreeDlg(gmx->mboxes[i]);
421     }
422 }
423
424 void edit_file(const char* fn)
425 {
426     if (fork() == 0)
427     {
428         char script[256];
429
430         std::sprintf(script, "vi  %s", fn);
431         shell_comm(fn, script, 0);
432         std::exit(0);
433     }
434 }