1 /* Copyright (C) 2010 Carlos R. Mafra */
4 #define _GNU_SOURCE /* getopt_long */
17 #ifdef HAVE_STDNORETURN
18 #include <stdnoreturn.h>
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
[])
45 struct option longopts
[] = {
46 { "version", no_argument
, NULL
, 'v' },
47 { "help", no_argument
, NULL
, 'h' },
51 while ((ch
= getopt_long(argc
, argv
, "hv", longopts
, NULL
)) != -1)
54 printf("%s (Window Maker %s)\n", __progname
, VERSION
);
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"));
78 bindtextdomain("wmgenmenu", LOCALEDIR
);
80 bind_textdomain_codeset("wmgenmenu", "UTF-8");
81 textdomain("wmgenmenu");
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)
102 * L1Menu Configure Window Maker
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:)")),
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"),
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"),
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"),
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 "\")'"), \
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");
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 "\"'"), \
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)'"),
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");
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"),
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)\""),
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)\""),
265 WMAddToPLArray(L1Menu
, L2Menu
);
266 WMAddToPLArray(RMenu
, L1Menu
);
268 /* Root -> Workspaces */
269 L1Menu
= WMCreatePLArray(
270 WMCreatePLString(_("Workspaces")),
271 WMCreatePLString("WORKSPACE_MENU"),
274 WMAddToPLArray(RMenu
, L1Menu
);
276 /* Root -> Workspace */
277 L1Menu
= WMCreatePLArray(WMCreatePLString(_("Workspace")), NULL
);
278 L2Menu
= WMCreatePLArray(
279 WMCreatePLString(_("Hide Others")),
280 WMCreatePLString("HIDE_OTHERS"),
283 WMAddToPLArray(L1Menu
, L2Menu
);
285 /* Root -> Workspace -> Show All */
286 L2Menu
= WMCreatePLArray(
287 WMCreatePLString(_("Show All")),
288 WMCreatePLString("SHOW_ALL"),
291 WMAddToPLArray(L1Menu
, L2Menu
);
293 /* Root -> Workspace -> Arrange Icons */
294 L2Menu
= WMCreatePLArray(
295 WMCreatePLString(_("Arrange Icons")),
296 WMCreatePLString("ARRANGE_ICONS"),
299 WMAddToPLArray(L1Menu
, L2Menu
);
301 /* Root -> Workspace -> Refresh */
302 L2Menu
= WMCreatePLArray(
303 WMCreatePLString(_("Refresh")),
304 WMCreatePLString("REFRESH"),
307 WMAddToPLArray(L1Menu
, L2Menu
);
309 /* Root -> Workspace -> Save Session */
310 L2Menu
= WMCreatePLArray(
311 WMCreatePLString(_("Save Session")),
312 WMCreatePLString("SAVE_SESSION"),
315 WMAddToPLArray(L1Menu
, L2Menu
);
317 /* Root -> Workspace -> Clear Session */
318 L2Menu
= WMCreatePLArray(
319 WMCreatePLString(_("Clear Session")),
320 WMCreatePLString("CLEAR_SESSION"),
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"),
333 WMAddToPLArray(RMenu
, L1Menu
);
335 /* Root -> Info Panel */
336 L1Menu
= WMCreatePLArray(
337 WMCreatePLString(_("Info Panel")),
338 WMCreatePLString("INFO_PANEL"),
341 WMAddToPLArray(RMenu
, L1Menu
);
343 /* Root -> Restart Window Maker */
344 L1Menu
= WMCreatePLArray(
345 WMCreatePLString(_("Restart Window Maker")),
346 WMCreatePLString("RESTART"),
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");
357 L1Menu
= WMCreatePLArray(
358 WMCreatePLString(_("Lock Screen")),
359 WMCreatePLString("EXEC"),
360 WMCreatePLString("xlock -allowroot -usefirst -mode matrix"),
363 WMAddToPLArray(RMenu
, L1Menu
);
367 /* Root -> Exit Window Maker */
368 L1Menu
= WMCreatePLArray(
369 WMCreatePLString(_("Exit Window Maker")),
370 WMCreatePLString("EXIT"),
373 WMAddToPLArray(RMenu
, L1Menu
);
375 printf("%s", WMGetPropListDescription(RMenu
, True
));
382 * Creates an L2Menu made of L3Menu items
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
)
390 char *t
, **argv
, buf
[PATH_MAX
];
392 /* or else pre-existing menus of these levels
393 * will badly disturb empty group detection */
399 /* Before checking if app exists, split its options */
400 wtokensplit(list
[i
][1], &argv
, &argc
);
401 t
= wfindfile(path
, argv
[0]);
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]),
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
)))
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
),
431 L2Menu
= WMCreatePLArray(
432 WMCreatePLString(group
),
435 WMAddToPLArray(L2Menu
, L3Menu
);
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
450 static void other_window_managers(void)
453 char *t
, buf
[PATH_MAX
];
455 /* or else pre-existing menus of these levels
456 * will badly disturb empty group detection */
461 while (other_wm
[i
][0]) {
462 t
= wfindfile(path
, other_wm
[i
][1]);
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]),
473 L1Menu
= WMCreatePLArray(
474 WMCreatePLString(_("Other Window Managers")),
477 WMAddToPLArray(L1Menu
, L2Menu
);
483 WMAddToPLArray(RMenu
, L1Menu
);
486 noreturn
void print_help(int print_usage
, int exitval
)
488 printf("Usage: %s [-h] [-v]\n", __progname
);
490 puts("Writes a menu structure usable as ~/GNUstep/Defaults/WMRootMenu to stdout");
492 puts(" -h, --help display this help and exit");
493 puts(" -v, --version output version information and exit");