Fixed a few improper macro usages
[wmaker-crm.git] / util / wmgenmenu.c
blob056eba99a1439c40418590ddfc0b7600ea88cdfe
1 /* Copyright (C) 2010 Carlos R. Mafra */
3 #ifdef __GLIBC__
4 #define _GNU_SOURCE /* getopt_long */
5 #endif
7 #include "config.h"
9 #include <ctype.h>
10 #include <getopt.h>
11 #include <limits.h>
12 #include <locale.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
17 #ifdef HAVE_STDNORETURN
18 #include <stdnoreturn.h>
19 #endif
21 #include <WINGs/WUtil.h>
23 #include "../src/wconfig.h"
25 #define MAX_NR_APPS 128 /* Maximum number of entries in each apps list */
26 #define MAX_WMS 10 /* Maximum number of other window managers to check */
28 #include "wmgenmenu.h"
30 static void find_and_write(const char *group, char *list[][2], int this_is_terminals);
31 static void other_window_managers(void);
32 static void print_help(int print_usage, int exitval);
34 extern char *__progname;
36 char *path, *terminal = NULL;
38 WMPropList *RMenu, *L1Menu, *L2Menu, *L3Menu, *L4Menu;
40 int main(int argc, char *argv[])
42 char *t;
43 int ch;
45 struct option longopts[] = {
46 { "version", no_argument, NULL, 'v' },
47 { "help", no_argument, NULL, 'h' },
48 { NULL, 0, NULL, 0 }
51 while ((ch = getopt_long(argc, argv, "hv", longopts, NULL)) != -1)
52 switch (ch) {
53 case 'v':
54 printf("%s (Window Maker %s)\n", __progname, VERSION);
55 return 0;
56 /* NOTREACHED */
57 case 'h':
58 print_help(1, 0);
59 /* NOTREACHED */
60 default:
61 print_help(0, 1);
62 /* NOTREACHED */
65 argc -= optind;
66 argv += optind;
68 if (argc != 0)
69 print_help(0, 1);
71 path = getenv("PATH");
72 setlocale(LC_ALL, "");
74 #if defined(HAVE_LIBINTL_H) && defined(I18N)
75 if (getenv("NLSPATH"))
76 bindtextdomain("wmgenmenu", getenv("NLSPATH"));
77 else
78 bindtextdomain("wmgenmenu", LOCALEDIR);
80 bind_textdomain_codeset("wmgenmenu", "UTF-8");
81 textdomain("wmgenmenu");
82 #endif
85 * The menu generated is a five-level hierarchy, of which the
86 * top level (RMenu) is only used to hold the others (a single
87 * PLString, which will be the title of the root menu)
89 * RMenu Window Maker
90 * L1Menu Applications
91 * L2Menu Terminals
92 * L3Menu XTerm
93 * L3Menu RXVT
94 * L2Menu Internet
95 * L3Menu Firefox
96 * L2Menu E-mail
97 * L1Menu Appearance
98 * L2Menu Themes
99 * L2Menu Background
100 * L3Menu Solid
101 * L4Menu Indigo
102 * L1Menu Configure Window Maker
106 /* Root */
107 RMenu = WMCreatePLArray(WMCreatePLString("Window Maker"), NULL);
109 /* Root -> Applications */
110 L1Menu = WMCreatePLArray(WMCreatePLString(_("Applications")), NULL);
112 /* Root -> Applications -> <category> */
113 find_and_write(_("Terminals"), Terminals, 1); /* always keep terminals the top item */
114 find_and_write(_("Internet"), Internet, 0);
115 find_and_write(_("Email"), Email, 0);
116 find_and_write(_("Mathematics"), Mathematics, 0);
117 find_and_write(_("File Managers"), File_managers, 0);
118 find_and_write(_("Graphics"), Graphics, 0);
119 find_and_write(_("Multimedia"), Multimedia, 0);
120 find_and_write(_("Editors"), Editors, 0);
121 find_and_write(_("Development"), Development, 0);
122 find_and_write("Window Maker", WindowMaker, 0);
123 find_and_write(_("Office"), Office, 0);
124 find_and_write(_("Astronomy"), Astronomy, 0);
125 find_and_write(_("Sound"), Sound, 0);
126 find_and_write(_("Comics"), Comics, 0);
127 find_and_write(_("Viewers"), Viewers, 0);
128 find_and_write(_("Utilities"), Utilities, 0);
129 find_and_write(_("System"), System, 0);
130 find_and_write(_("Video"), Video, 0);
131 find_and_write(_("Chat and Talk"), Chat, 0);
132 find_and_write(_("P2P Network"), P2P, 0);
133 find_and_write(_("Games"), Games, 0);
134 find_and_write("OpenSUSE", OpenSUSE, 0);
135 find_and_write("Mandriva", Mandriva, 0);
137 WMAddToPLArray(RMenu, L1Menu);
139 /* Root -> `Run' dialog */
140 L1Menu = WMCreatePLArray(
141 WMCreatePLString(_("Run...")),
142 WMCreatePLString("SHEXEC"),
143 WMCreatePLString(_("%A(Run, Type command:)")),
144 NULL
146 WMAddToPLArray(RMenu, L1Menu);
148 /* Root -> Appearance */
149 L1Menu = WMCreatePLArray(WMCreatePLString(_("Appearance")), NULL);
151 /* Root -> Appearance -> Themes */
152 L2Menu = WMCreatePLArray(
153 WMCreatePLString(_("Themes")),
154 WMCreatePLString("OPEN_MENU"),
155 WMCreatePLString("-noext /usr/local/share/WindowMaker/Themes $HOME/GNUstep/Library/WindowMaker/Themes WITH setstyle"),
156 NULL
158 WMAddToPLArray(L1Menu, L2Menu);
160 /* Root -> Appearance -> Styles */
161 L2Menu = WMCreatePLArray(
162 WMCreatePLString(_("Styles")),
163 WMCreatePLString("OPEN_MENU"),
164 WMCreatePLString("-noext /usr/local/share/WindowMaker/Styles $HOME/GNUstep/Library/WindowMaker/Styles WITH setstyle"),
165 NULL
167 WMAddToPLArray(L1Menu, L2Menu);
169 /* Root -> Appearance -> Icon Sets */
170 L2Menu = WMCreatePLArray(
171 WMCreatePLString(_("Icon Sets")),
172 WMCreatePLString("OPEN_MENU"),
173 WMCreatePLString("-noext /usr/local/share/WindowMaker/IconSets $HOME/GNUstep/Library/WindowMaker/IconSets WITH seticons"),
174 NULL
176 WMAddToPLArray(L1Menu, L2Menu);
178 /* Root -> Appearance -> Background */
179 L2Menu = WMCreatePLArray(WMCreatePLString(_("Background")), NULL);
181 /* Root -> Appearance -> Background -> Solid */
182 L3Menu = WMCreatePLArray(WMCreatePLString(_("Solid")), NULL);
184 #define SOLID_BACK(label, colorspec) \
185 L4Menu = WMCreatePLArray( \
186 WMCreatePLString(label), \
187 WMCreatePLString("EXEC"), \
188 WMCreatePLString("wdwrite WindowMaker WorkspaceBack '(solid, \"" colorspec "\")'"), \
189 NULL \
190 ); \
191 WMAddToPLArray(L3Menu, L4Menu)
193 /* Root -> Appearance -> Background -> Solid -> <color> */
194 SOLID_BACK(_("Black"), "black");
195 SOLID_BACK(_("Blue"), "#505075");
196 SOLID_BACK(_("Indigo"), "#243e6c");
197 SOLID_BACK(_("Bluemarine"), "#243e6c");
198 SOLID_BACK(_("Purple"), "#554466");
199 SOLID_BACK(_("Wheat"), "wheat4");
200 SOLID_BACK(_("Dark Gray"), "#333340");
201 SOLID_BACK(_("Wine"), "#400020");
202 #undef SOLID_BACK
203 WMAddToPLArray(L2Menu, L3Menu);
205 /* Root -> Appearance -> Background -> Gradient */
206 L3Menu = WMCreatePLArray(WMCreatePLString(_("Gradient")), NULL);
208 #define GRADIENT_BACK(label, fcolorspec, tcolorspec) \
209 L4Menu = WMCreatePLArray( \
210 WMCreatePLString(label), \
211 WMCreatePLString("EXEC"), \
212 WMCreatePLString("wdwrite WindowMaker WorkspaceBack '(vgradient, \"" \
213 fcolorspec "\", \"" tcolorspec "\"'"), \
214 NULL \
215 ); \
216 WMAddToPLArray(L3Menu, L4Menu)
218 /* Root -> Appearance -> Background -> Gradient -> <color> */
219 L4Menu = WMCreatePLArray(
220 WMCreatePLString(_("Sunset")),
221 WMCreatePLString("EXEC"),
222 WMCreatePLString("wdwrite WindowMaker WorkspaceBack "
223 "'(mvgradient, deepskyblue4, black, deepskyblue4, tomato4)'"),
224 NULL
226 WMAddToPLArray(L3Menu, L4Menu);
227 GRADIENT_BACK(_("Sky"), "blue4", "white");
228 GRADIENT_BACK(_("Blue Shades"), "#7080a5", "#101020");
229 GRADIENT_BACK(_("Indigo Shades"), "#746ebc", "#242e4c");
230 GRADIENT_BACK(_("Purple Shades"), "#654c66", "#151426");
231 GRADIENT_BACK(_("Wheat Shades"), "#a09060", "#302010");
232 GRADIENT_BACK(_("Grey Shades"), "#636380", "#131318");
233 GRADIENT_BACK(_("Wine Shades"), "#600040", "#180010");
234 #undef GRADIENT_BACK
235 WMAddToPLArray(L2Menu, L3Menu);
237 /* Root -> Appearance -> Background -> Images */
238 L3Menu = WMCreatePLArray(
239 WMCreatePLString(_("Images")),
240 WMCreatePLString("OPEN_MENU"),
241 WMCreatePLString("-noext $HOME/GNUstep/Library/WindowMaker/Backgrounds WITH wmsetbg -u -t"),
242 NULL
244 WMAddToPLArray(L2Menu, L3Menu);
246 WMAddToPLArray(L1Menu, L2Menu);
248 /* Root -> Appearance -> Save Theme */
249 L2Menu = WMCreatePLArray(
250 WMCreatePLString(_("Save Theme")),
251 WMCreatePLString("SHEXEC"),
252 WMCreatePLString("getstyle -p \"%a(Theme name, Name to save theme as)\""),
253 NULL
255 WMAddToPLArray(L1Menu, L2Menu);
257 /* Root -> Appearance -> Save IconSet */
258 L2Menu = WMCreatePLArray(
259 WMCreatePLString(_("Save IconSet")),
260 WMCreatePLString("SHEXEC"),
261 WMCreatePLString("geticonset $HOME/GNUstep/Library/WindowMaker/IconSets/"
262 "\"%a(IconSet name,Name to save icon set as)\""),
263 NULL
265 WMAddToPLArray(L1Menu, L2Menu);
266 WMAddToPLArray(RMenu, L1Menu);
268 /* Root -> Workspaces */
269 L1Menu = WMCreatePLArray(
270 WMCreatePLString(_("Workspaces")),
271 WMCreatePLString("WORKSPACE_MENU"),
272 NULL
274 WMAddToPLArray(RMenu, L1Menu);
276 /* Root -> Workspace */
277 L1Menu = WMCreatePLArray(WMCreatePLString(_("Workspace")), NULL);
278 L2Menu = WMCreatePLArray(
279 WMCreatePLString(_("Hide Others")),
280 WMCreatePLString("HIDE_OTHERS"),
281 NULL
283 WMAddToPLArray(L1Menu, L2Menu);
285 /* Root -> Workspace -> Show All */
286 L2Menu = WMCreatePLArray(
287 WMCreatePLString(_("Show All")),
288 WMCreatePLString("SHOW_ALL"),
289 NULL
291 WMAddToPLArray(L1Menu, L2Menu);
293 /* Root -> Workspace -> Arrange Icons */
294 L2Menu = WMCreatePLArray(
295 WMCreatePLString(_("Arrange Icons")),
296 WMCreatePLString("ARRANGE_ICONS"),
297 NULL
299 WMAddToPLArray(L1Menu, L2Menu);
301 /* Root -> Workspace -> Refresh */
302 L2Menu = WMCreatePLArray(
303 WMCreatePLString(_("Refresh")),
304 WMCreatePLString("REFRESH"),
305 NULL
307 WMAddToPLArray(L1Menu, L2Menu);
309 /* Root -> Workspace -> Save Session */
310 L2Menu = WMCreatePLArray(
311 WMCreatePLString(_("Save Session")),
312 WMCreatePLString("SAVE_SESSION"),
313 NULL
315 WMAddToPLArray(L1Menu, L2Menu);
317 /* Root -> Workspace -> Clear Session */
318 L2Menu = WMCreatePLArray(
319 WMCreatePLString(_("Clear Session")),
320 WMCreatePLString("CLEAR_SESSION"),
321 NULL
323 WMAddToPLArray(L1Menu, L2Menu);
324 WMAddToPLArray(RMenu, L1Menu);
326 /* Root -> Configure Window Maker */
327 L1Menu = WMCreatePLArray(
328 WMCreatePLString(_("Configure Window Maker")),
329 WMCreatePLString("EXEC"),
330 WMCreatePLString("WPrefs"),
331 NULL
333 WMAddToPLArray(RMenu, L1Menu);
335 /* Root -> Info Panel */
336 L1Menu = WMCreatePLArray(
337 WMCreatePLString(_("Info Panel")),
338 WMCreatePLString("INFO_PANEL"),
339 NULL
341 WMAddToPLArray(RMenu, L1Menu);
343 /* Root -> Restart Window Maker */
344 L1Menu = WMCreatePLArray(
345 WMCreatePLString(_("Restart Window Maker")),
346 WMCreatePLString("RESTART"),
347 NULL
349 WMAddToPLArray(RMenu, L1Menu);
351 /* Root -> Other Window Managers [-> <other window manager> ...] */
352 other_window_managers();
354 /* Root -> Lock Screen */
355 t = wfindfile(path, "xlock");
356 if (t) {
357 L1Menu = WMCreatePLArray(
358 WMCreatePLString(_("Lock Screen")),
359 WMCreatePLString("EXEC"),
360 WMCreatePLString("xlock -allowroot -usefirst -mode matrix"),
361 NULL
363 WMAddToPLArray(RMenu, L1Menu);
364 wfree(t);
367 /* Root -> Exit Window Maker */
368 L1Menu = WMCreatePLArray(
369 WMCreatePLString(_("Exit Window Maker")),
370 WMCreatePLString("EXIT"),
371 NULL
373 WMAddToPLArray(RMenu, L1Menu);
375 printf("%s", WMGetPropListDescription(RMenu, True));
376 puts("");
378 return 0;
382 * Creates an L2Menu made of L3Menu items
383 * Attaches to L1Menu
384 * - make sure previous menus of these levels are
385 * attached to their parent before calling
387 static void find_and_write(const char *group, char *list[][2], int this_is_terminals)
389 int i, argc;
390 char *t, **argv, buf[PATH_MAX];
392 /* or else pre-existing menus of these levels
393 * will badly disturb empty group detection */
394 L2Menu = NULL;
395 L3Menu = NULL;
397 i = 0;
398 while (list[i][0]) {
399 /* Before checking if app exists, split its options */
400 wtokensplit(list[i][1], &argv, &argc);
401 t = wfindfile(path, argv[0]);
402 if (t) {
403 /* find a terminal to be used for cmnds that need a terminal */
404 if (this_is_terminals && !terminal)
405 terminal = wstrdup(list[i][1]);
406 if (*(argv[argc-1]) != '!') {
407 L3Menu = WMCreatePLArray(
408 WMCreatePLString(_(list[i][0])),
409 WMCreatePLString("EXEC"),
410 WMCreatePLString(list[i][1]),
411 NULL
413 } else {
414 char comm[PATH_MAX], *ptr;
416 strcpy(comm, list[i][1]);
417 /* delete character " !" from the command */
418 ptr = strchr(comm, '!');
419 while (ptr >= comm && (*ptr == '!' || isspace(*ptr)))
420 *ptr-- = '\0';
421 snprintf(buf, sizeof(buf), "%s -e %s", terminal ? terminal : "xterm" , comm);
422 /* Root -> Applications -> <category> -> <application> */
423 L3Menu = WMCreatePLArray(
424 WMCreatePLString(_(list[i][0])),
425 WMCreatePLString("EXEC"),
426 WMCreatePLString(buf),
427 NULL
430 if (!L2Menu)
431 L2Menu = WMCreatePLArray(
432 WMCreatePLString(group),
433 NULL
435 WMAddToPLArray(L2Menu, L3Menu);
436 wfree(t);
438 i++;
440 if (L2Menu)
441 WMAddToPLArray(L1Menu, L2Menu);
445 * Creates an L1Menu made of L2Menu items
446 * - make sure previous menus of these levels are
447 * attached to their parent before calling
448 * Attaches to RMenu
450 static void other_window_managers(void)
452 int i;
453 char *t, buf[PATH_MAX];
455 /* or else pre-existing menus of these levels
456 * will badly disturb empty group detection */
457 L1Menu = NULL;
458 L2Menu = NULL;
460 i = 0;
461 while (other_wm[i][0]) {
462 t = wfindfile(path, other_wm[i][1]);
463 if (t) {
464 snprintf(buf, sizeof(buf), _("Start %s"), _(other_wm[i][0]));
465 /* Root -> Other Window Managers -> <other window manager> */
466 L2Menu = WMCreatePLArray(
467 WMCreatePLString(buf),
468 WMCreatePLString("RESTART"),
469 WMCreatePLString(other_wm[i][1]),
470 NULL
472 if (!L1Menu)
473 L1Menu = WMCreatePLArray(
474 WMCreatePLString(_("Other Window Managers")),
475 NULL
477 WMAddToPLArray(L1Menu, L2Menu);
478 wfree(t);
480 i++;
482 if (L1Menu)
483 WMAddToPLArray(RMenu, L1Menu);
486 noreturn void print_help(int print_usage, int exitval)
488 printf("Usage: %s [-h] [-v]\n", __progname);
489 if (print_usage) {
490 puts("Writes a menu structure usable as ~/GNUstep/Defaults/WMRootMenu to stdout");
491 puts("");
492 puts(" -h, --help display this help and exit");
493 puts(" -v, --version output version information and exit");
495 exit(exitval);