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 static const char *prog_name
;
36 char *path
, *terminal
= NULL
;
38 WMPropList
*RMenu
, *L1Menu
, *L2Menu
, *L3Menu
, *L4Menu
;
40 int main(int argc
, char *argv
[])
44 char *tmp
, *theme_paths
, *style_paths
, *icon_paths
;
46 tmp
= wstrconcat("-noext ", PKGDATADIR
);
47 theme_paths
= wstrconcat(tmp
, "/Themes $HOME/GNUstep/Library/WindowMaker/Themes WITH setstyle");
48 style_paths
= wstrconcat(tmp
, "/Styles $HOME/GNUstep/Library/WindowMaker/Styles WITH setstyle");
49 icon_paths
= wstrconcat(tmp
, "/IconSets $HOME/GNUstep/Library/WindowMaker/IconSets WITH seticons");
51 struct option longopts
[] = {
52 { "version", no_argument
, NULL
, 'v' },
53 { "help", no_argument
, NULL
, 'h' },
58 while ((ch
= getopt_long(argc
, argv
, "hv", longopts
, NULL
)) != -1)
61 printf("%s (Window Maker %s)\n", prog_name
, VERSION
);
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"));
85 bindtextdomain("wmgenmenu", LOCALEDIR
);
87 bind_textdomain_codeset("wmgenmenu", "UTF-8");
88 textdomain("wmgenmenu");
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)
109 * L1Menu Configure Window Maker
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:)")),
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
),
165 WMAddToPLArray(L1Menu
, L2Menu
);
167 /* Root -> Appearance -> Styles */
168 L2Menu
= WMCreatePLArray(
169 WMCreatePLString(_("Styles")),
170 WMCreatePLString("OPEN_MENU"),
171 WMCreatePLString(style_paths
),
174 WMAddToPLArray(L1Menu
, L2Menu
);
176 /* Root -> Appearance -> Icon Sets */
177 L2Menu
= WMCreatePLArray(
178 WMCreatePLString(_("Icon Sets")),
179 WMCreatePLString("OPEN_MENU"),
180 WMCreatePLString(icon_paths
),
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 "\")'"), \
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");
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 "\"'"), \
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)'"),
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");
242 WMAddToPLArray(L2Menu
, L3Menu
);
244 /* Root -> Appearance -> Background -> Images */
245 L3Menu
= WMCreatePLArray(
246 WMCreatePLString(_("Images")),
247 WMCreatePLString("OPEN_MENU"),
248 WMCreatePLString("-noext $HOME/GNUstep/Library/WindowMaker/Backgrounds WITH wmsetbg -u -t"),
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)\""),
262 WMAddToPLArray(L1Menu
, L2Menu
);
264 /* Root -> Appearance -> Save IconSet */
265 L2Menu
= WMCreatePLArray(
266 WMCreatePLString(_("Save IconSet")),
267 WMCreatePLString("SHEXEC"),
268 WMCreatePLString("geticonset $HOME/GNUstep/Library/WindowMaker/IconSets/"
269 "\"%a(IconSet name,Name to save icon set as)\""),
272 WMAddToPLArray(L1Menu
, L2Menu
);
273 WMAddToPLArray(RMenu
, L1Menu
);
275 /* Root -> Workspaces */
276 L1Menu
= WMCreatePLArray(
277 WMCreatePLString(_("Workspaces")),
278 WMCreatePLString("WORKSPACE_MENU"),
281 WMAddToPLArray(RMenu
, L1Menu
);
283 /* Root -> Workspace */
284 L1Menu
= WMCreatePLArray(WMCreatePLString(_("Workspace")), NULL
);
285 L2Menu
= WMCreatePLArray(
286 WMCreatePLString(_("Hide Others")),
287 WMCreatePLString("HIDE_OTHERS"),
290 WMAddToPLArray(L1Menu
, L2Menu
);
292 /* Root -> Workspace -> Show All */
293 L2Menu
= WMCreatePLArray(
294 WMCreatePLString(_("Show All")),
295 WMCreatePLString("SHOW_ALL"),
298 WMAddToPLArray(L1Menu
, L2Menu
);
300 /* Root -> Workspace -> Arrange Icons */
301 L2Menu
= WMCreatePLArray(
302 WMCreatePLString(_("Arrange Icons")),
303 WMCreatePLString("ARRANGE_ICONS"),
306 WMAddToPLArray(L1Menu
, L2Menu
);
308 /* Root -> Workspace -> Refresh */
309 L2Menu
= WMCreatePLArray(
310 WMCreatePLString(_("Refresh")),
311 WMCreatePLString("REFRESH"),
314 WMAddToPLArray(L1Menu
, L2Menu
);
316 /* Root -> Workspace -> Save Session */
317 L2Menu
= WMCreatePLArray(
318 WMCreatePLString(_("Save Session")),
319 WMCreatePLString("SAVE_SESSION"),
322 WMAddToPLArray(L1Menu
, L2Menu
);
324 /* Root -> Workspace -> Clear Session */
325 L2Menu
= WMCreatePLArray(
326 WMCreatePLString(_("Clear Session")),
327 WMCreatePLString("CLEAR_SESSION"),
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"),
340 WMAddToPLArray(RMenu
, L1Menu
);
342 /* Root -> Info Panel */
343 L1Menu
= WMCreatePLArray(
344 WMCreatePLString(_("Info Panel")),
345 WMCreatePLString("INFO_PANEL"),
348 WMAddToPLArray(RMenu
, L1Menu
);
350 /* Root -> Restart Window Maker */
351 L1Menu
= WMCreatePLArray(
352 WMCreatePLString(_("Restart Window Maker")),
353 WMCreatePLString("RESTART"),
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");
364 L1Menu
= WMCreatePLArray(
365 WMCreatePLString(_("Lock Screen")),
366 WMCreatePLString("EXEC"),
367 WMCreatePLString("xlock -allowroot -usefirst -mode matrix"),
370 WMAddToPLArray(RMenu
, L1Menu
);
374 /* Root -> Exit Window Maker */
375 L1Menu
= WMCreatePLArray(
376 WMCreatePLString(_("Exit Window Maker")),
377 WMCreatePLString("EXIT"),
380 WMAddToPLArray(RMenu
, L1Menu
);
382 printf("%s", WMGetPropListDescription(RMenu
, True
));
389 * Creates an L2Menu made of L3Menu items
391 * - make sure previous menus of these levels are
392 * attached to their parent before calling
394 static void find_and_write(const char *group
, char *list
[][2], int this_is_terminals
)
397 char *t
, **argv
, buf
[PATH_MAX
];
399 /* or else pre-existing menus of these levels
400 * will badly disturb empty group detection */
406 /* Before checking if app exists, split its options */
407 wtokensplit(list
[i
][1], &argv
, &argc
);
408 t
= wfindfile(path
, argv
[0]);
410 /* find a terminal to be used for cmnds that need a terminal */
411 if (this_is_terminals
&& !terminal
)
412 terminal
= wstrdup(list
[i
][1]);
413 if (*(argv
[argc
-1]) != '!') {
414 L3Menu
= WMCreatePLArray(
415 WMCreatePLString(_(list
[i
][0])),
416 WMCreatePLString("EXEC"),
417 WMCreatePLString(list
[i
][1]),
421 char comm
[PATH_MAX
- 9], *ptr
;
423 strncpy(comm
, list
[i
][1], sizeof(comm
) - 1);
424 comm
[sizeof(comm
) - 1] = '\0';
426 /* delete character " !" from the command */
427 ptr
= strchr(comm
, '!');
430 if (!isspace(ptr
[-1]))
436 snprintf(buf
, sizeof(buf
), "%s -e %s", terminal
? terminal
: "xterm" , comm
);
438 /* Root -> Applications -> <category> -> <application> */
439 L3Menu
= WMCreatePLArray(
440 WMCreatePLString(_(list
[i
][0])),
441 WMCreatePLString("EXEC"),
442 WMCreatePLString(buf
),
447 L2Menu
= WMCreatePLArray(
448 WMCreatePLString(group
),
451 WMAddToPLArray(L2Menu
, L3Menu
);
457 WMAddToPLArray(L1Menu
, L2Menu
);
461 * Creates an L1Menu made of L2Menu items
462 * - make sure previous menus of these levels are
463 * attached to their parent before calling
466 static void other_window_managers(void)
469 char *t
, buf
[PATH_MAX
];
471 /* or else pre-existing menus of these levels
472 * will badly disturb empty group detection */
477 while (other_wm
[i
][0]) {
478 t
= wfindfile(path
, other_wm
[i
][1]);
480 snprintf(buf
, sizeof(buf
), _("Start %s"), _(other_wm
[i
][0]));
481 /* Root -> Other Window Managers -> <other window manager> */
482 L2Menu
= WMCreatePLArray(
483 WMCreatePLString(buf
),
484 WMCreatePLString("RESTART"),
485 WMCreatePLString(other_wm
[i
][1]),
489 L1Menu
= WMCreatePLArray(
490 WMCreatePLString(_("Other Window Managers")),
493 WMAddToPLArray(L1Menu
, L2Menu
);
499 WMAddToPLArray(RMenu
, L1Menu
);
502 noreturn
void print_help(int print_usage
, int exitval
)
504 printf("Usage: %s [-h] [-v]\n", prog_name
);
506 puts("Writes a menu structure usable as ~/GNUstep/Defaults/WMRootMenu to stdout");
508 puts(" -h, --help display this help and exit");
509 puts(" -v, --version output version information and exit");