1 #ifndef XMENU_H
2 #define XMENU_H
3 #include "xio.h"
4 #include "config.h"
5 
6 struct uih_context;
7 typedef union {
8     char *dstring;
9     int dint;
10     number_t number;
11     number_t dcoord[2];
12     xio_path dpath;
13     void *dummy;
14 } dialogparam;
15 typedef struct dialog {
16     const char *question;
17     int type;
18     int defint;
19     const char *defstr;
20     number_t deffloat;
21     number_t deffloat2;
22 } menudialog;
23 
24 typedef char *(*tokenfunc)(struct uih_context *c);
25 #define DIALOG_INT 1
26 #define DIALOG_FLOAT 2
27 #define DIALOG_STRING 3
28 #define DIALOG_KEYSTRING 4
29 #define DIALOG_IFILE 5
30 #define DIALOG_OFILE 6
31 #define DIALOG_CHOICE 7
32 #define DIALOG_ONOFF 8
33 #define DIALOG_COORD 9
34 #define DIALOG_PALSLIDER 10
35 #define DIALOG_PALPICKER 11
36 #define DIALOG_IFILES 12
37 #define DIALOG_LIST 13
38 
39 #define DIALOGIFILE(question, filename)                                        \
40     {                                                                          \
41         question, DIALOG_IFILE, 0, filename                                    \
42     }
43 #define DIALOGOFILE(question, filename)                                        \
44     {                                                                          \
45         question, DIALOG_OFILE, 0, filename                                    \
46     }
47 #define DIALOGSTR(question, default)                                           \
48     {                                                                          \
49         question, DIALOG_STRING, 0, default                                    \
50     }
51 #define DIALOGKEYSTR(question, default)                                        \
52     {                                                                          \
53         question, DIALOG_KEYSTRING, 0, default                                 \
54     }
55 #define DIALOGINT(question, default)                                           \
56     {                                                                          \
57         question, DIALOG_INT, default                                          \
58     }
59 #define DIALOGONOFF(question, default)                                         \
60     {                                                                          \
61         question, DIALOG_ONOFF, default                                        \
62     }
63 #define DIALOGFLOAT(question, default)                                         \
64     {                                                                          \
65         question, DIALOG_FLOAT, 0, NULL, default                               \
66     }
67 #define DIALOGCHOICE(question, table, default)                                 \
68     {                                                                          \
69         question, DIALOG_CHOICE, default, (const char *)table                  \
70     }
71 #define DIALOGCOORD(question, default1, default2)                              \
72     {                                                                          \
73         question, DIALOG_COORD, 0, NULL, default1, default2                    \
74     }
75 #define DIALOGPALSLIDER(question, default)                                     \
76     {                                                                          \
77         question, DIALOG_SLIDER, default                                       \
78     }
79 #define DIALOGIFILES(question, filenames)                                      \
80     {                                                                          \
81         question, DIALOG_IFILES, 0, filenames                                  \
82     }
83 #define DIALOGLIST(question, default)                                          \
84     {                                                                          \
85         question, DIALOG_LIST, 0, default                                      \
86     }
87 
88 #define DIALOGIFILE_I(_question, _filename)                                    \
89     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
90     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_IFILE;                 \
91     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
92     menudialogs_i18n[no_menudialogs_i18n].defstr = _filename;                  \
93     menudialogs_i18n[no_menudialogs_i18n].deffloat = 0;                        \
94     menudialogs_i18n[no_menudialogs_i18n].deffloat2 = 0;                       \
95     ++no_menudialogs_i18n;
96 
97 #define DIALOGOFILE_I(_question, _filename)                                    \
98     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
99     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_OFILE;                 \
100     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
101     menudialogs_i18n[no_menudialogs_i18n].defstr = _filename;                  \
102     ++no_menudialogs_i18n;
103 
104 #define DIALOGKEYSTR_I(_question, _default)                                    \
105     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
106     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_KEYSTRING;             \
107     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
108     menudialogs_i18n[no_menudialogs_i18n].defstr = _default;                   \
109     ++no_menudialogs_i18n;
110 
111 #define DIALOGSTR_I(_question, _default)                                       \
112     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
113     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_STRING;                \
114     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
115     menudialogs_i18n[no_menudialogs_i18n].defstr = _default;                   \
116     ++no_menudialogs_i18n;
117 
118 #define DIALOGINT_I(_question, _default)                                       \
119     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
120     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_INT;                   \
121     menudialogs_i18n[no_menudialogs_i18n].defint = _default;                   \
122     ++no_menudialogs_i18n;
123 
124 #define DIALOGONOFF_I(_question, _default)                                     \
125     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
126     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_ONOFF;                 \
127     menudialogs_i18n[no_menudialogs_i18n].defint = _default;                   \
128     ++no_menudialogs_i18n;
129 
130 #define DIALOGFLOAT_I(_question, _default)                                     \
131     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
132     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_FLOAT;                 \
133     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
134     menudialogs_i18n[no_menudialogs_i18n].defstr = NULL;                       \
135     menudialogs_i18n[no_menudialogs_i18n].deffloat = _default;                 \
136     ++no_menudialogs_i18n;
137 
138 #define DIALOGCHOICE_I(_question, _table, _default)                            \
139     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
140     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_CHOICE;                \
141     menudialogs_i18n[no_menudialogs_i18n].defint = _default;                   \
142     menudialogs_i18n[no_menudialogs_i18n].defstr = (const char *)_table;       \
143     ++no_menudialogs_i18n;
144 
145 #define DIALOGCOORD_I(_question, _default1, _default2)                         \
146     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
147     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_COORD;                 \
148     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
149     menudialogs_i18n[no_menudialogs_i18n].defstr = NULL;                       \
150     menudialogs_i18n[no_menudialogs_i18n].deffloat = _default1;                \
151     menudialogs_i18n[no_menudialogs_i18n].deffloat2 = _default2;               \
152     ++no_menudialogs_i18n;
153 
154 #define DIALOGPALSLIDER_I(_question, _default)                                 \
155     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
156     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_PALSLIDER;             \
157     menudialogs_i18n[no_menudialogs_i18n].defint = _default;                   \
158     ++no_menudialogs_i18n;
159 
160 #define DIALOGPALPICKER_I(_question, _default)                                 \
161     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
162     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_PALPICKER;             \
163     menudialogs_i18n[no_menudialogs_i18n].defint = _default;                   \
164     ++no_menudialogs_i18n;
165 
166 #define DIALOGIFILES_I(_question, _filenames)                                  \
167     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
168     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_IFILES;                \
169     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
170     menudialogs_i18n[no_menudialogs_i18n].defstr = _filenames;                 \
171     ++no_menudialogs_i18n;
172 
173 #define DIALOGLIST_I(_question, _default)                                      \
174     menudialogs_i18n[no_menudialogs_i18n].question = _question;                \
175     menudialogs_i18n[no_menudialogs_i18n].type = DIALOG_LIST;                  \
176     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
177     menudialogs_i18n[no_menudialogs_i18n].defstr = _default;                   \
178     ++no_menudialogs_i18n;
179 
180 #define NULL_I()                                                               \
181     menudialogs_i18n[no_menudialogs_i18n].question = NULL;                     \
182     menudialogs_i18n[no_menudialogs_i18n].type = 0;                            \
183     menudialogs_i18n[no_menudialogs_i18n].defint = 0;                          \
184     menudialogs_i18n[no_menudialogs_i18n].defstr = NULL;                       \
185     menudialogs_i18n[no_menudialogs_i18n].deffloat = 0;                        \
186     menudialogs_i18n[no_menudialogs_i18n].deffloat2 = 0;                       \
187     ++no_menudialogs_i18n;
188 
189 typedef struct menuitem {
190     const char *menuname;
191     const char *key;
192     const char *name;
193     const char *shortname;
194     int type;
195     int flags;
196     void (*function)(void);
197     int iparam;
198     const void *pparam;
199     int (*control)(void);
200     const menudialog *(*dialog)(struct uih_context *);
201 } menuitem;
202 
203 #define MENU_NOPARAM 1
204 #define MENU_SUBMENU 2
205 #define MENU_INT 3
206 #define MENU_STRING 4
207 #define MENU_DIALOG 6
208 #define MENU_CUSTOMDIALOG 7
209 #define MENU_SEPARATOR 8
210 
211 /* Definitions for static menuitems. These items cannot be internationalized.
212 All of these definitions will become obsolete soon: */
213 
214 #define MENUNOP(menuname, key, name, shortname, flags, function)               \
215     {                                                                          \
216         menuname, key, name, shortname, MENU_NOPARAM, flags,                   \
217             (void (*)(void))function                                           \
218     }
219 #define MENUNOPCB(menuname, key, name, shortname, flags, function,             \
220                   checkbutton)                                                 \
221     {                                                                          \
222         menuname, key, name, shortname, MENU_NOPARAM,                          \
223             (flags) | MENUFLAG_CHECKBOX, (void (*)(void))function, 0, NULL,    \
224             (int (*)(void))checkbutton                                         \
225     }
226 #define MENUCOORDCB(menuname, key, name, shortname, flags, function,           \
227                     checkbutton)                                               \
228     {                                                                          \
229         menuname, key, name, shortname, MENU_COORD,                            \
230             (flags) | MENUFLAG_CHECKBOX, (void (*)(void))function, 0, NULL,    \
231             (int (*)(void))checkbutton                                         \
232     }
233 #define MENUCOORD(menuname, key, name, shortname, flags, function)             \
234     {                                                                          \
235         menuname, key, name, shortname, MENU_COORD, flags,                     \
236             (void (*)(void))function                                           \
237     }
238 
239 #define MENUINT(menuname, key, name, shortname, flags, function, param)        \
240     {                                                                          \
241         menuname, key, name, shortname, MENU_INT, flags,                       \
242             (void (*)(void))function, param                                    \
243     }
244 #define MENUINTRB(menuname, key, name, shortname, flags, function, param,      \
245                   checkbutton)                                                 \
246     {                                                                          \
247         menuname, key, name, shortname, MENU_INT, (flags) | MENUFLAG_RADIO,    \
248             (void (*)(void))function, param, NULL, (int (*)(void))checkbutton  \
249     }
250 #define SUBMENU(menuname, key, name, param)                                    \
251     {                                                                          \
252         menuname, key, name, param, MENU_SUBMENU, 0, NULL, 0, NULL, NULL, NULL \
253     }
254 
255 #define MENUSEPARATOR(menuname)                                                \
256     {                                                                          \
257         menuname, 0, "", NULL, MENU_SEPARATOR, 0, NULL, 0, NULL                \
258     }
259 #define SUBMENUNOOPT(menuname, key, name, param)                               \
260     {                                                                          \
261         menuname, key, name, param, MENU_SUBMENU, MENUFLAG_NOOPTION, NULL, 0,  \
262             NULL                                                               \
263     }
264 #define MENUDIALOG(menuname, key, name, shortname, flags, function, param)     \
265     {                                                                          \
266         menuname, key, name, shortname, MENU_DIALOG, flags,                    \
267             (void (*)(void))function, 0, param                                 \
268     }
269 #define MENUDIALOGCB(menuname, key, name, shortname, flags, function, param,   \
270                      check)                                                    \
271     {                                                                          \
272         menuname, key, name, shortname, MENU_DIALOG,                           \
273             flags | MENUFLAG_CHECKBOX, (void (*)(void))function, 0, param,     \
274             (int (*)(void))check                                               \
275     }
276 #define MENUCDIALOG(menuname, key, name, shortname, flags, function, param)    \
277     {                                                                          \
278         menuname, key, name, shortname, MENU_CUSTOMDIALOG, flags,              \
279             (void (*)(void))function, 0, NULL, NULL,                           \
280             (const menudialog *(*)(struct uih_context *))param                 \
281     }
282 #define MENUCDIALOGCB(menuname, key, name, shortname, flags, function, param,  \
283                       check)                                                   \
284     {                                                                          \
285         menuname, key, name, shortname, MENU_CUSTOMDIALOG,                     \
286             flags | MENUFLAG_CHECKBOX, (void (*)(void))function, 0, NULL,      \
287             (int (*)(void))check,                                              \
288             (const menudialog *(*)(struct uih_context *))param                 \
289     }
290 #define MENUSTRING(menuname, key, name, shortname, flags, function, param)     \
291     {                                                                          \
292         menuname, key, name, shortname, MENU_STRING, flags,                    \
293             (void (*)(void))function, 0, param                                 \
294     }
295 
296 /* Definitions for internationalized menus. All of them must be defined
297 dynamically because TR() cannot be used within a static
298 variable. Usage (example):
299 
300 SUBMENU_I("file", "q", "Quit", "quitmenu")
301 
302 See ui/ui.c, ui_registermenus_i18n() for further details. */
303 
304 #define MENUNOP_I(_menuname, _key, _name, _shortname, _flags, _function)       \
305     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
306     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
307     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
308     menuitems_i18n[no_menuitems_i18n].type = MENU_NOPARAM;                     \
309     menuitems_i18n[no_menuitems_i18n].flags = _flags;                          \
310     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
311     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
312     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
313     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
314     ++no_menuitems_i18n;
315 
316 #define MENUNOPCB_I(_menuname, _key, _name, _shortname, _flags, _function,     \
317                     _checkbutton)                                              \
318     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
319     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
320     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
321     menuitems_i18n[no_menuitems_i18n].type = MENU_NOPARAM;                     \
322     menuitems_i18n[no_menuitems_i18n].flags = (_flags) | MENUFLAG_CHECKBOX;    \
323     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
324     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
325     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
326     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
327     menuitems_i18n[no_menuitems_i18n].control = (int (*)(void))_checkbutton;   \
328     ++no_menuitems_i18n;
329 
330 #define MENUINT_I(_menuname, _key, _name, _shortname, _flags, _function,       \
331                   _param)                                                      \
332     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
333     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
334     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
335     menuitems_i18n[no_menuitems_i18n].type = MENU_INT;                         \
336     menuitems_i18n[no_menuitems_i18n].flags = _flags;                          \
337     menuitems_i18n[no_menuitems_i18n].iparam = _param;                         \
338     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
339     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
340     ++no_menuitems_i18n;
341 
342 #define MENUINTRB_I(_menuname, _key, _name, _shortname, _flags, _function,     \
343                     _param, _checkbutton)                                      \
344     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
345     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
346     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
347     menuitems_i18n[no_menuitems_i18n].type = MENU_INT;                         \
348     menuitems_i18n[no_menuitems_i18n].flags = (_flags) | MENUFLAG_RADIO;       \
349     menuitems_i18n[no_menuitems_i18n].iparam = _param;                         \
350     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
351     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
352     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
353     menuitems_i18n[no_menuitems_i18n].control = (int (*)(void))_checkbutton;   \
354     ++no_menuitems_i18n;
355 
356 #define SUBMENU_I(_menuname, _key, _name, _param)                              \
357     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
358     menuitems_i18n[no_menuitems_i18n].shortname = _param;                      \
359     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
360     menuitems_i18n[no_menuitems_i18n].type = MENU_SUBMENU;                     \
361     menuitems_i18n[no_menuitems_i18n].flags = 0;                               \
362     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
363     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
364     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
365     menuitems_i18n[no_menuitems_i18n].function = NULL;                         \
366     ++no_menuitems_i18n;
367 
368 #define MENUDIALOG_I(_menuname, _key, _name, _shortname, _flags, _function,    \
369                      _param)                                                   \
370     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
371     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
372     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
373     menuitems_i18n[no_menuitems_i18n].type = MENU_DIALOG;                      \
374     menuitems_i18n[no_menuitems_i18n].flags = _flags;                          \
375     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
376     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
377     menuitems_i18n[no_menuitems_i18n].pparam = (const void *)_param;           \
378     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
379     ++no_menuitems_i18n;
380 
381 #define MENUDIALOGCB_I(_menuname, _key, _name, _shortname, _flags, _function,  \
382                        _param, _check)                                         \
383     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
384     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
385     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
386     menuitems_i18n[no_menuitems_i18n].type = MENU_DIALOG;                      \
387     menuitems_i18n[no_menuitems_i18n].flags = (_flags) | MENUFLAG_CHECKBOX;    \
388     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
389     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
390     menuitems_i18n[no_menuitems_i18n].pparam = (const void *)_param;           \
391     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
392     menuitems_i18n[no_menuitems_i18n].control = (int (*)(void))_check;         \
393     ++no_menuitems_i18n;
394 
395 #define MENUCDIALOG_I(_menuname, _key, _name, _shortname, _flags, _function,   \
396                       _param)                                                  \
397     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
398     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
399     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
400     menuitems_i18n[no_menuitems_i18n].type = MENU_CUSTOMDIALOG;                \
401     menuitems_i18n[no_menuitems_i18n].flags = _flags;                          \
402     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
403     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
404     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
405     menuitems_i18n[no_menuitems_i18n].control = NULL;                          \
406     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
407     menuitems_i18n[no_menuitems_i18n].dialog =                                 \
408         (const menudialog *(*)(struct uih_context *))_param;                   \
409     ++no_menuitems_i18n;
410 
411 #define MENUCDIALOGCB_I(_menuname, _key, _name, _shortname, _flags, _function, \
412                         _param, _check)                                        \
413     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
414     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
415     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
416     menuitems_i18n[no_menuitems_i18n].type = MENU_CUSTOMDIALOG;                \
417     menuitems_i18n[no_menuitems_i18n].flags = (_flags) | MENUFLAG_CHECKBOX;    \
418     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
419     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
420     menuitems_i18n[no_menuitems_i18n].pparam = (const void *)_param;           \
421     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
422     menuitems_i18n[no_menuitems_i18n].control = (int (*)(void))_check;         \
423     menuitems_i18n[no_menuitems_i18n].dialog =                                 \
424         (const menudialog *(*)(struct uih_context *))_param;                   \
425     ++no_menuitems_i18n;
426 
427 #define MENUSEPARATOR_I(_menuname)                                             \
428     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
429     menuitems_i18n[no_menuitems_i18n].shortname = NULL;                        \
430     menuitems_i18n[no_menuitems_i18n].key = 0;                                 \
431     menuitems_i18n[no_menuitems_i18n].type = MENU_SEPARATOR;                   \
432     menuitems_i18n[no_menuitems_i18n].flags = 0;                               \
433     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
434     menuitems_i18n[no_menuitems_i18n].name = "";                               \
435     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
436     menuitems_i18n[no_menuitems_i18n].function = NULL;                         \
437     ++no_menuitems_i18n;
438 
439 #define SUBMENUNOOPT_I(_menuname, _key, _name, _param)                         \
440     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
441     menuitems_i18n[no_menuitems_i18n].shortname = _param;                      \
442     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
443     menuitems_i18n[no_menuitems_i18n].type = MENU_SUBMENU;                     \
444     menuitems_i18n[no_menuitems_i18n].flags = MENUFLAG_NOOPTION;               \
445     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
446     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
447     menuitems_i18n[no_menuitems_i18n].pparam = NULL;                           \
448     menuitems_i18n[no_menuitems_i18n].function = NULL;                         \
449     ++no_menuitems_i18n;
450 
451 #define MENUSTRING_I(_menuname, _key, _name, _shortname, _flags, _function,    \
452                      _param)                                                   \
453     menuitems_i18n[no_menuitems_i18n].menuname = _menuname;                    \
454     menuitems_i18n[no_menuitems_i18n].shortname = _shortname;                  \
455     menuitems_i18n[no_menuitems_i18n].key = _key;                              \
456     menuitems_i18n[no_menuitems_i18n].type = MENU_STRING;                      \
457     menuitems_i18n[no_menuitems_i18n].flags = _flags;                          \
458     menuitems_i18n[no_menuitems_i18n].iparam = 0;                              \
459     menuitems_i18n[no_menuitems_i18n].name = _name;                            \
460     menuitems_i18n[no_menuitems_i18n].pparam = (const void *)_param;           \
461     menuitems_i18n[no_menuitems_i18n].function = (void (*)(void))_function;    \
462     ++no_menuitems_i18n;
463 
464 /* End of i18n definitions. */
465 
466 #define MENUFLAG_CHECKBOX 1
467 #define MENUFLAG_RADIO 2
468 #define MENUFLAG_INTERRUPT 4
469 #define MENUFLAG_INCALC 8
470 #define MENUFLAG_NOMENU 16
471 #define MENUFLAG_NOOPTION 32
472 #define MENUFLAG_NOPLAY 64
473 #define MENUFLAG_ATSTARTUP 128
474 #define MENUFLAG_DIALOGATDISABLE 256
475 
476 #define NITEMS(n) (sizeof(n) / sizeof(menuitem))
477 #define menu_getdialog(context, m)                                             \
478     ((m)->type == MENU_DIALOG ? (const menudialog *)(m)->pparam                \
479                               : (m)->dialog(context))
480 
481 void menu_add(const menuitem *item, int n);
482 void menu_insert(const menuitem *item, const char *before, int n);
483 const menuitem *menu_findkey(const char *key, const char *root);
484 const menuitem *menu_findcommand(const char *name);
485 const char *menu_fullname(const char *menu);
486 const menuitem *menu_item(const char *menu, int n);
487 void menu_delete(const menuitem *items, int n);
488 int menu_enabled(const menuitem *item, struct uih_context *c);
489 void menu_activate(const menuitem *item, struct uih_context *c, dialogparam *d);
490 const menuitem *
491 menu_genernumbered(int n, const char *menuname, const char *const *const names,
492                    const char *keys, int type, int flags,
493                    void (*fint)(struct uih_context *context, int),
494                    int (*cint)(struct uih_context *context, int),
495                    const char *prefix);
496 void menu_delnumbered(int n, const char *name);
497 void menu_addqueue(const menuitem *item, dialogparam *d);
498 const menuitem *menu_delqueue(dialogparam **d);
499 void menu_destroydialog(const menuitem *item, dialogparam *d,
500                         struct uih_context *uih);
501 int menu_havedialog(const menuitem *item, struct uih_context *c);
502 int menu_available(const menuitem *item, const char *root);
503 const char *menu_processcommand(struct uih_context *uih, tokenfunc f,
504                                 int scheme, int mask, const char *root);
505 void menu_printhelp(void);
506 
507 number_t menu_getfloat(const char *s, const char **error);
508 const char *menu_fillparam(struct uih_context *uih, tokenfunc f,
509                            const menudialog *d, dialogparam *p);
510 int menu_processargs(int n, int argc, char **argv);
511 void menu_forall(struct uih_context *c,
512                  void (*callback)(struct uih_context *c, const menuitem *item));
513 #endif
514