Update Serbian translation from master branch
[wmaker-crm.git] / util / wmgenmenu.c
blob1032d11d663406c4d9e1f8fc39ca04bd6a0c40d1
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 static const char *prog_name;
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;
44 char *tmp, *theme_paths, *style_paths, *icon_paths;
46 tmp = wstrconcat("-noext ", PKGDATADIR);
47 theme_paths = wstrconcat(tmp, "/Themes $HOME/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/" PACKAGE_TARNAME "/Themes WITH setstyle");
48 style_paths = wstrconcat(tmp, "/Styles $HOME/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/" PACKAGE_TARNAME "/Styles WITH setstyle");
49 icon_paths = wstrconcat(tmp, "/IconSets $HOME/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/" PACKAGE_TARNAME "/IconSets WITH seticons");
51 struct option longopts[] = {
52 { "version", no_argument, NULL, 'v' },
53 { "help", no_argument, NULL, 'h' },
54 { NULL, 0, NULL, 0 }
57 prog_name = argv[0];
58 while ((ch = getopt_long(argc, argv, "hv", longopts, NULL)) != -1)
59 switch (ch) {
60 case 'v':
61 printf("%s (Window Maker %s)\n", prog_name, VERSION);
62 return 0;
63 /* NOTREACHED */
64 case 'h':
65 print_help(1, 0);
66 /* NOTREACHED */
67 default:
68 print_help(0, 1);
69 /* NOTREACHED */
72 argc -= optind;
73 argv += optind;
75 if (argc != 0)
76 print_help(0, 1);
78 path = getenv("PATH");
79 setlocale(LC_ALL, "");
81 #if defined(HAVE_LIBINTL_H) && defined(I18N)
82 if (getenv("NLSPATH"))
83 bindtextdomain("wmgenmenu", getenv("NLSPATH"));
84 else
85 bindtextdomain("wmgenmenu", LOCALEDIR);
87 bind_textdomain_codeset("wmgenmenu", "UTF-8");
88 textdomain("wmgenmenu");
89 #endif
92 * The menu generated is a five-level hierarchy, of which the
93 * top level (RMenu) is only used to hold the others (a single
94 * PLString, which will be the title of the root menu)
96 * RMenu Window Maker
97 * L1Menu Applications
98 * L2Menu Terminals
99 * L3Menu XTerm
100 * L3Menu RXVT
101 * L2Menu Internet
102 * L3Menu Firefox
103 * L2Menu E-mail
104 * L1Menu Appearance
105 * L2Menu Themes
106 * L2Menu Background
107 * L3Menu Solid
108 * L4Menu Indigo
109 * L1Menu Configure Window Maker
113 /* Root */
114 RMenu = WMCreatePLArray(WMCreatePLString("Window Maker"), NULL);
116 /* Root -> Applications */
117 L1Menu = WMCreatePLArray(WMCreatePLString(_("Applications")), NULL);
119 /* Root -> Applications -> <category> */
120 find_and_write(_("Terminals"), Terminals, 1); /* always keep terminals the top item */
121 find_and_write(_("Internet"), Internet, 0);
122 find_and_write(_("Email"), Email, 0);
123 find_and_write(_("Mathematics"), Mathematics, 0);
124 find_and_write(_("File Managers"), File_managers, 0);
125 find_and_write(_("Graphics"), Graphics, 0);
126 find_and_write(_("Multimedia"), Multimedia, 0);
127 find_and_write(_("Editors"), Editors, 0);
128 find_and_write(_("Development"), Development, 0);
129 find_and_write("Window Maker", WindowMaker, 0);
130 find_and_write(_("Office"), Office, 0);
131 find_and_write(_("Astronomy"), Astronomy, 0);
132 find_and_write(_("Sound"), Sound, 0);
133 find_and_write(_("Comics"), Comics, 0);
134 find_and_write(_("Viewers"), Viewers, 0);
135 find_and_write(_("Utilities"), Utilities, 0);
136 find_and_write(_("System"), System, 0);
137 find_and_write(_("Video"), Video, 0);
138 find_and_write(_("Chat and Talk"), Chat, 0);
139 find_and_write(_("P2P Network"), P2P, 0);
140 find_and_write(_("Games"), Games, 0);
141 find_and_write("OpenSUSE", OpenSUSE, 0);
142 find_and_write("Mandriva", Mandriva, 0);
144 WMAddToPLArray(RMenu, L1Menu);
146 /* Root -> `Run' dialog */
147 L1Menu = WMCreatePLArray(
148 WMCreatePLString(_("Run...")),
149 WMCreatePLString("SHEXEC"),
150 WMCreatePLString(_("%A(Run, Type command:)")),
151 NULL
153 WMAddToPLArray(RMenu, L1Menu);
155 /* Root -> Appearance */
156 L1Menu = WMCreatePLArray(WMCreatePLString(_("Appearance")), NULL);
158 /* Root -> Appearance -> Themes */
159 L2Menu = WMCreatePLArray(
160 WMCreatePLString(_("Themes")),
161 WMCreatePLString("OPEN_MENU"),
162 WMCreatePLString(theme_paths),
163 NULL
165 WMAddToPLArray(L1Menu, L2Menu);
167 /* Root -> Appearance -> Styles */
168 L2Menu = WMCreatePLArray(
169 WMCreatePLString(_("Styles")),
170 WMCreatePLString("OPEN_MENU"),
171 WMCreatePLString(style_paths),
172 NULL
174 WMAddToPLArray(L1Menu, L2Menu);
176 /* Root -> Appearance -> Icon Sets */
177 L2Menu = WMCreatePLArray(
178 WMCreatePLString(_("Icon Sets")),
179 WMCreatePLString("OPEN_MENU"),
180 WMCreatePLString(icon_paths),
181 NULL
183 WMAddToPLArray(L1Menu, L2Menu);
185 /* Root -> Appearance -> Background */
186 L2Menu = WMCreatePLArray(WMCreatePLString(_("Background")), NULL);
188 /* Root -> Appearance -> Background -> Solid */
189 L3Menu = WMCreatePLArray(WMCreatePLString(_("Solid")), NULL);
191 #define SOLID_BACK(label, colorspec) \
192 L4Menu = WMCreatePLArray( \
193 WMCreatePLString(label), \
194 WMCreatePLString("EXEC"), \
195 WMCreatePLString("wdwrite WindowMaker WorkspaceBack '(solid, \"" colorspec "\")'"), \
196 NULL \
197 ); \
198 WMAddToPLArray(L3Menu, L4Menu)
200 /* Root -> Appearance -> Background -> Solid -> <color> */
201 SOLID_BACK(_("Black"), "black");
202 SOLID_BACK(_("Blue"), "#505075");
203 SOLID_BACK(_("Indigo"), "#243e6c");
204 SOLID_BACK(_("Bluemarine"), "#243e6c");
205 SOLID_BACK(_("Purple"), "#554466");
206 SOLID_BACK(_("Wheat"), "wheat4");
207 SOLID_BACK(_("Dark Gray"), "#333340");
208 SOLID_BACK(_("Wine"), "#400020");
209 #undef SOLID_BACK
210 WMAddToPLArray(L2Menu, L3Menu);
212 /* Root -> Appearance -> Background -> Gradient */
213 L3Menu = WMCreatePLArray(WMCreatePLString(_("Gradient")), NULL);
215 #define GRADIENT_BACK(label, fcolorspec, tcolorspec) \
216 L4Menu = WMCreatePLArray( \
217 WMCreatePLString(label), \
218 WMCreatePLString("EXEC"), \
219 WMCreatePLString("wdwrite WindowMaker WorkspaceBack '(vgradient, \"" \
220 fcolorspec "\", \"" tcolorspec "\")'"), \
221 NULL \
222 ); \
223 WMAddToPLArray(L3Menu, L4Menu)
225 /* Root -> Appearance -> Background -> Gradient -> <color> */
226 L4Menu = WMCreatePLArray(
227 WMCreatePLString(_("Sunset")),
228 WMCreatePLString("EXEC"),
229 WMCreatePLString("wdwrite WindowMaker WorkspaceBack "
230 "'(mvgradient, deepskyblue4, black, deepskyblue4, tomato4)'"),
231 NULL
233 WMAddToPLArray(L3Menu, L4Menu);
234 GRADIENT_BACK(_("Sky"), "blue4", "white");
235 GRADIENT_BACK(_("Blue Shades"), "#7080a5", "#101020");
236 GRADIENT_BACK(_("Indigo Shades"), "#746ebc", "#242e4c");
237 GRADIENT_BACK(_("Purple Shades"), "#654c66", "#151426");
238 GRADIENT_BACK(_("Wheat Shades"), "#a09060", "#302010");
239 GRADIENT_BACK(_("Grey Shades"), "#636380", "#131318");
240 GRADIENT_BACK(_("Wine Shades"), "#600040", "#180010");
241 #undef GRADIENT_BACK
242 WMAddToPLArray(L2Menu, L3Menu);
244 /* Root -> Appearance -> Background -> Images */
245 L3Menu = WMCreatePLArray(
246 WMCreatePLString(_("Images")),
247 WMCreatePLString("OPEN_MENU"),
248 WMCreatePLString("-noext $HOME/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/" PACKAGE_TARNAME "/Backgrounds WITH wmsetbg -u -t"),
249 NULL
251 WMAddToPLArray(L2Menu, L3Menu);
253 WMAddToPLArray(L1Menu, L2Menu);
255 /* Root -> Appearance -> Save Theme */
256 L2Menu = WMCreatePLArray(
257 WMCreatePLString(_("Save Theme")),
258 WMCreatePLString("SHEXEC"),
259 WMCreatePLString("getstyle -p \"%a(Theme name, Name to save theme as)\""),
260 NULL
262 WMAddToPLArray(L1Menu, L2Menu);
264 /* Root -> Appearance -> Save IconSet */
265 L2Menu = WMCreatePLArray(
266 WMCreatePLString(_("Save IconSet")),
267 WMCreatePLString("SHEXEC"),
268 WMCreatePLString("geticonset $HOME/" GSUSER_SUBDIR "/" USERDATA_SUBDIR "/" PACKAGE_TARNAME "/IconSets/"
269 "\"%a(IconSet name,Name to save icon set as)\""),
270 NULL
272 WMAddToPLArray(L1Menu, L2Menu);
273 WMAddToPLArray(RMenu, L1Menu);
275 /* Root -> Workspaces */
276 L1Menu = WMCreatePLArray(
277 WMCreatePLString(_("Workspaces")),
278 WMCreatePLString("WORKSPACE_MENU"),
279 NULL
281 WMAddToPLArray(RMenu, L1Menu);
283 /* Root -> Workspace */
284 L1Menu = WMCreatePLArray(WMCreatePLString(_("Workspace")), NULL);
285 L2Menu = WMCreatePLArray(
286 WMCreatePLString(_("Hide Others")),
287 WMCreatePLString("HIDE_OTHERS"),
288 NULL
290 WMAddToPLArray(L1Menu, L2Menu);
292 /* Root -> Workspace -> Show All */
293 L2Menu = WMCreatePLArray(
294 WMCreatePLString(_("Show All")),
295 WMCreatePLString("SHOW_ALL"),
296 NULL
298 WMAddToPLArray(L1Menu, L2Menu);
300 /* Root -> Workspace -> Arrange Icons */
301 L2Menu = WMCreatePLArray(
302 WMCreatePLString(_("Arrange Icons")),
303 WMCreatePLString("ARRANGE_ICONS"),
304 NULL
306 WMAddToPLArray(L1Menu, L2Menu);
308 /* Root -> Workspace -> Refresh */
309 L2Menu = WMCreatePLArray(
310 WMCreatePLString(_("Refresh")),
311 WMCreatePLString("REFRESH"),
312 NULL
314 WMAddToPLArray(L1Menu, L2Menu);
316 /* Root -> Workspace -> Save Session */
317 L2Menu = WMCreatePLArray(
318 WMCreatePLString(_("Save Session")),
319 WMCreatePLString("SAVE_SESSION"),
320 NULL
322 WMAddToPLArray(L1Menu, L2Menu);
324 /* Root -> Workspace -> Clear Session */
325 L2Menu = WMCreatePLArray(
326 WMCreatePLString(_("Clear Session")),
327 WMCreatePLString("CLEAR_SESSION"),
328 NULL
330 WMAddToPLArray(L1Menu, L2Menu);
331 WMAddToPLArray(RMenu, L1Menu);
333 /* Root -> Configure Window Maker */
334 L1Menu = WMCreatePLArray(
335 WMCreatePLString(_("Configure Window Maker")),
336 WMCreatePLString("EXEC"),
337 WMCreatePLString("WPrefs"),
338 NULL
340 WMAddToPLArray(RMenu, L1Menu);
342 /* Root -> Info Panel */
343 L1Menu = WMCreatePLArray(
344 WMCreatePLString(_("Info Panel")),
345 WMCreatePLString("INFO_PANEL"),
346 NULL
348 WMAddToPLArray(RMenu, L1Menu);
350 /* Root -> Restart Window Maker */
351 L1Menu = WMCreatePLArray(
352 WMCreatePLString(_("Restart Window Maker")),
353 WMCreatePLString("RESTART"),
354 NULL
356 WMAddToPLArray(RMenu, L1Menu);
358 /* Root -> Other Window Managers [-> <other window manager> ...] */
359 other_window_managers();
361 /* Root -> Lock Screen */
362 t = wfindfile(path, "xlock");
363 if (t) {
364 L1Menu = WMCreatePLArray(
365 WMCreatePLString(_("Lock Screen")),
366 WMCreatePLString("EXEC"),
367 WMCreatePLString("xlock -allowroot -usefirst -mode matrix"),
368 NULL
370 WMAddToPLArray(RMenu, L1Menu);
371 wfree(t);
374 /* Root -> Exit Window Maker */
375 L1Menu = WMCreatePLArray(
376 WMCreatePLString(_("Exit Window Maker")),
377 WMCreatePLString("EXIT"),
378 NULL
380 WMAddToPLArray(RMenu, L1Menu);
382 wfree(tmp);
383 wfree(theme_paths);
384 wfree(style_paths);
385 wfree(icon_paths);
387 tmp = WMGetPropListDescription(RMenu, True);
388 printf("%s\n", tmp);
389 wfree(tmp);
391 return 0;
395 * Creates an L2Menu made of L3Menu items
396 * Attaches to L1Menu
397 * - make sure previous menus of these levels are
398 * attached to their parent before calling
400 static void find_and_write(const char *group, char *list[][2], int this_is_terminals)
402 int i, argc;
403 char *t, **argv, buf[PATH_MAX];
405 /* or else pre-existing menus of these levels
406 * will badly disturb empty group detection */
407 L2Menu = NULL;
408 L3Menu = NULL;
410 i = 0;
411 while (list[i][0]) {
412 /* Before checking if app exists, split its options */
413 wtokensplit(list[i][1], &argv, &argc);
414 t = wfindfile(path, argv[0]);
415 if (t) {
416 /* find a terminal to be used for cmnds that need a terminal */
417 if (this_is_terminals && !terminal)
418 terminal = wstrdup(list[i][1]);
419 if (*(argv[argc-1]) != '!') {
420 L3Menu = WMCreatePLArray(
421 WMCreatePLString(_(list[i][0])),
422 WMCreatePLString("EXEC"),
423 WMCreatePLString(list[i][1]),
424 NULL
426 } else {
427 char comm[PATH_MAX - 9], *ptr;
429 strncpy(comm, list[i][1], sizeof(comm) - 1);
430 comm[sizeof(comm) - 1] = '\0';
432 /* delete character " !" from the command */
433 ptr = strchr(comm, '!');
434 if (ptr != NULL) {
435 while (ptr > comm) {
436 if (!isspace(ptr[-1]))
437 break;
438 ptr--;
440 *ptr = '\0';
442 snprintf(buf, sizeof(buf), "%s -e %s", terminal ? terminal : "xterm" , comm);
444 /* Root -> Applications -> <category> -> <application> */
445 L3Menu = WMCreatePLArray(
446 WMCreatePLString(_(list[i][0])),
447 WMCreatePLString("EXEC"),
448 WMCreatePLString(buf),
449 NULL
452 if (!L2Menu)
453 L2Menu = WMCreatePLArray(
454 WMCreatePLString(group),
455 NULL
457 WMAddToPLArray(L2Menu, L3Menu);
458 wfree(t);
460 wtokenfree(argv, argc);
461 i++;
463 if (L2Menu)
464 WMAddToPLArray(L1Menu, L2Menu);
468 * Creates an L1Menu made of L2Menu items
469 * - make sure previous menus of these levels are
470 * attached to their parent before calling
471 * Attaches to RMenu
473 static void other_window_managers(void)
475 int i;
476 char *t, buf[PATH_MAX];
478 /* or else pre-existing menus of these levels
479 * will badly disturb empty group detection */
480 L1Menu = NULL;
481 L2Menu = NULL;
483 i = 0;
484 while (other_wm[i][0]) {
485 t = wfindfile(path, other_wm[i][1]);
486 if (t) {
487 snprintf(buf, sizeof(buf), _("Start %s"), _(other_wm[i][0]));
488 /* Root -> Other Window Managers -> <other window manager> */
489 L2Menu = WMCreatePLArray(
490 WMCreatePLString(buf),
491 WMCreatePLString("RESTART"),
492 WMCreatePLString(other_wm[i][1]),
493 NULL
495 if (!L1Menu)
496 L1Menu = WMCreatePLArray(
497 WMCreatePLString(_("Other Window Managers")),
498 NULL
500 WMAddToPLArray(L1Menu, L2Menu);
501 wfree(t);
503 i++;
505 if (L1Menu)
506 WMAddToPLArray(RMenu, L1Menu);
509 noreturn void print_help(int print_usage, int exitval)
511 printf("Usage: %s [-h] [-v]\n", prog_name);
512 if (print_usage) {
513 puts("Writes a menu structure usable as ~/" GSUSER_SUBDIR "/" DEFAULTS_SUBDIR "/WMRootMenu to stdout");
514 puts("");
515 puts(" -h, --help display this help and exit");
516 puts(" -v, --version output version information and exit");
518 exit(exitval);