thingmenu

A simple graphical menu launcher for X11.
git clone git://r-36.net/thingmenu
Log | Files | Refs | LICENSE

commit e54f54c03160ab7e6615e15f9ee0984ab5d2e9dc
parent 0255257e75f6f3820d695394eb80cd20dcf78e78
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sat,  4 Aug 2012 22:30:22 +0200

Adding ARGBEGIN for flexible parameter handling and fixing the manpage.

Diffstat:
arg.h | 41+++++++++++++++++++++++++++++++++++++++++
thingmenu.1 | 11++++-------
thingmenu.c | 113++++++++++++++++++++++++++++++++-----------------------------------------------
3 files changed, 91 insertions(+), 74 deletions(-)

diff --git a/arg.h b/arg.h @@ -0,0 +1,41 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef __ARG_H__ +#define __ARG_H__ + +extern char *argv0; + +#define USED(x) ((void)(x)) + +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][1]\ + && argv[0][0] == '-';\ + argc--, argv++) {\ + char _argc;\ + char **_argv;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (argv[0]++, _argv = argv; argv[0][0];\ + argv[0]++) {\ + if (_argv != argv)\ + break;\ + _argc = argv[0][0];\ + switch (_argc) + +#define ARGEND }\ + USED(_argc);\ + }\ + USED(argv);\ + USED(argc); + +#define EARGF(x) ((argv[1] == NULL)? ((x), abort(), (char *)0) :\ + (argc--, argv++, argv[0])) + +#endif + diff --git a/thingmenu.1 b/thingmenu.1 @@ -13,8 +13,8 @@ .Op Fl s .Op Fl o .Op Fl g Ar geometry -.Op Fl ws Ar widthscaling -.Op Fl hs Ar heightscaling +.Op Fl w Ar widthscaling +.Op Fl e Ar heightscaling .Op Fl - .Ar label0 cmd0 [label1 cmd1 ...] .Ek @@ -49,7 +49,6 @@ options and default settings. Do not append a .Qq "Cancel" menu item. -. .Bd -filled .It Fl s Disable the oneshot behaviour. After one button click @@ -66,10 +65,10 @@ Use the horizontal layout. .It Fl g Define the X11 geometry string, which is to be used. . -.It Fl ws +.It Fl w Define the width scaling. . -.It Fl hs +.It Fl e Define the height scaling. . .El @@ -91,7 +90,6 @@ After that the menu will not exit (-s). .Ed .Bd -literal % thingmenu -s -ww 300 -- "Reboot now" reboot - .Ed .Bd -filled This will create a centered menu, which is aligned based on the length of the @@ -99,7 +97,6 @@ label texts. After the first clicked entry it will exit. .Ed .Bd -literal % thingmenu "Force reboot" "reboot -f" Shutdown shutdown - .Ed .Bd -filled An example how to create multi-level menus is shown in the thingmenu-menu.sh diff --git a/thingmenu.c b/thingmenu.c @@ -106,6 +106,10 @@ int nentries = 0; int oneshot = 1; Bool ispressing = 0; +char *argv0; + +#include "arg.h" + /* configuration, allows nested code to access above variables */ #include "config.h" @@ -594,10 +598,10 @@ updateentries(void) } void -usage(char *argv0) +usage(void) { - fprintf(stderr, "usage: %s [-hxso] [-g geometry] [-ws widthscaling] " - "[-hs heightscaling] [--] " + fprintf(stderr, "usage: %s [-hxso] [-g geometry] [-w widthscaling] " + "[-e heightscaling] [--] " "label0 cmd0 [label1 cmd1 ...]\n", argv0); exit(1); } @@ -610,74 +614,49 @@ main(int argc, char *argv[]) int i, xr, yr, bitm; unsigned int wr, hr; + argv0 = argv[0]; addexit = True; if (argc < 2) - usage(argv[0]); - i = 1; - for (; argv[i]; i++) { - if (argv[i][0] != '-') - break; - if (argv[i][1] == '-') { - i++; - break; - } - - switch (argv[i][1]) { - case 'g': - if (i >= argc - 1) - break; - bitm = XParseGeometry(argv[i+1], &xr, &yr, &wr, &hr); - if (bitm & XValue) - wx = xr; - if (bitm & YValue) - wy = yr; - if (bitm & WidthValue) - ww = (int)wr; - if (bitm & HeightValue) - wh = (int)hr; - if (bitm & XNegative && wx == 0) - wx = -1; - if (bitm & YNegative && wy == 0) - wy = -1; - i++; - break; - case 'h': - switch ((i >= argc - 1)? 0 : argv[i][2]) { - case 's': - heightscaling = atof(argv[i+1]); - i++; - break; - default: - usage(argv[0]); - } - break; - case 'o': - horizontal = True; - break; - case 's': - oneshot = 0; - break; - case 'w': - switch ((i >= argc - 1)? 0 : argv[i][2]) { - case 's': - widthscaling = atof(argv[i+1]); - i++; - break; - default: - usage(argv[0]); - } - break; - case 'x': - addexit = False; - break; - default: - usage(argv[0]); - } - } + usage(); + + ARGBEGIN { + case 'g': + bitm = XParseGeometry(EARGF(usage()), &xr, &yr, &wr, &hr); + if (bitm & XValue) + wx = xr; + if (bitm & YValue) + wy = yr; + if (bitm & WidthValue) + ww = (int)wr; + if (bitm & HeightValue) + wh = (int)hr; + if (bitm & XNegative && wx == 0) + wx = -1; + if (bitm & YNegative && wy == 0) + wy = -1; + break; + case 'e': + heightscaling = atof(EARGF(usage())); + break; + case 'o': + horizontal = True; + break; + case 's': + oneshot = 0; + break; + case 'w': + widthscaling = atof(EARGF(usage())); + break; + case 'x': + addexit = False; + break; + default: + usage(); + } ARGEND; - for (; argv[i]; i++) { + for (i = 0; argv[i]; i++) { label = argv[i]; if (!argv[i+1]) break; @@ -696,7 +675,7 @@ main(int argc, char *argv[]) die("strdup returned NULL\n"); } if (nentries < 1) - usage(argv[0]); + usage(); if (addexit) { entries = realloc(entries, sizeof(entries[0])*(++nentries));