From bcacef19b032d1162120c4a48412bb62b90ad61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 11 Mar 2012 21:05:57 -0400 Subject: [PATCH] Add an option parser On one hand, getopt (in particular the -o suboption syntax) sucks on the server side, and on the client side we would like to avoid the glib dependency. We can roll out own option parser and solve both problems and save a few lines of code total. --- clients/Makefile.am | 5 ++- clients/clickdot.c | 2 +- clients/desktop-shell.c | 2 +- clients/dnd.c | 2 +- clients/eventdemo.c | 47 +++++++++-------------- clients/flower.c | 2 +- clients/gears.c | 2 +- clients/image.c | 6 +-- clients/resizor.c | 2 +- clients/smoke.c | 2 +- clients/tablet-shell.c | 2 +- clients/terminal.c | 11 +++--- clients/view.c | 11 +++--- clients/window.c | 36 ++++-------------- clients/window.h | 4 +- clients/wscreensaver.c | 11 +++--- shared/Makefile.am | 1 + shared/config-parser.h | 18 +++++++++ shared/option-parser.c | 82 ++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 5 ++- src/compositor-drm.c | 37 ++++++------------ src/compositor-openwfd.c | 33 +++++----------- src/compositor-wayland.c | 35 ++++++----------- src/compositor-x11.c | 35 +++++------------ src/compositor.c | 75 ++++++++++++------------------------ src/compositor.h | 4 ++ 26 files changed, 229 insertions(+), 243 deletions(-) create mode 100644 shared/option-parser.c diff --git a/clients/Makefile.am b/clients/Makefile.am index d7a6cbf6..eab8939d 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -57,8 +57,9 @@ libtoytoolkit_a_SOURCES = \ cairo-util.c \ cairo-util.h -toolkit_libs = \ - libtoytoolkit.a \ +toolkit_libs = \ + libtoytoolkit.a \ + ../shared/libconfig-parser.la \ $(CLIENT_LIBS) $(CAIRO_EGL_LIBS) -lrt -lm flower_SOURCES = flower.c diff --git a/clients/clickdot.c b/clients/clickdot.c index cf35faaa..3b7210e3 100644 --- a/clients/clickdot.c +++ b/clients/clickdot.c @@ -164,7 +164,7 @@ main(int argc, char *argv[]) struct display *display; struct clickdot *clickdot; - display = display_create(&argc, &argv, NULL); + display = display_create(argc, argv); if (display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 15dc7ac3..881bf7c4 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -707,7 +707,7 @@ int main(int argc, char *argv[]) desktop.unlock_task.run = unlock_dialog_finish; wl_list_init(&desktop.outputs); - desktop.display = display_create(&argc, &argv, NULL); + desktop.display = display_create(argc, argv); if (desktop.display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/dnd.c b/clients/dnd.c index 5e1696b2..66ba2ce1 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -561,7 +561,7 @@ main(int argc, char *argv[]) { struct display *d; - d = display_create(&argc, &argv, NULL); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/eventdemo.c b/clients/eventdemo.c index 7d591a78..5d0cc909 100644 --- a/clients/eventdemo.c +++ b/clients/eventdemo.c @@ -315,36 +315,20 @@ eventdemo_create(struct display *d) } /** * \brief command line options for eventdemo - * - * see - * http://developer.gimp.org/api/2.0/glib/glib-Commandline-option-parser.html */ -static const GOptionEntry option_entries[] = { - {"title", 0, 0, G_OPTION_ARG_STRING, - &title, "Set the window title to TITLE", "TITLE"}, - {"width", 'w', 0, G_OPTION_ARG_INT, - &width, "Set the window's width to W", "W"}, - {"height", 'h', 0, G_OPTION_ARG_INT, - &height, "Set the window's height to H", "H"}, - {"maxwidth", 0, 0, G_OPTION_ARG_INT, - &width_max, "Set the window's maximum width to W", "W"}, - {"maxheight", 0, 0, G_OPTION_ARG_INT, - &height_max, "Set the window's maximum height to H", "H"}, - {"noborder", 'b', 0, G_OPTION_ARG_NONE, - &noborder, "Don't draw window borders", 0}, - {"log-redraw", 0, 0, G_OPTION_ARG_NONE, - &log_redraw, "Log redraw events to stdout", 0}, - {"log-resize", 0, 0, G_OPTION_ARG_NONE, - &log_resize, "Log resize events to stdout", 0}, - {"log-focus", 0, 0, G_OPTION_ARG_NONE, - &log_focus, "Log keyboard focus events to stdout", 0}, - {"log-key", 0, 0, G_OPTION_ARG_NONE, - &log_key, "Log key events to stdout", 0}, - {"log-button", 0, 0, G_OPTION_ARG_NONE, - &log_button, "Log button events to stdout", 0}, - {"log-motion", 0, 0, G_OPTION_ARG_NONE, - &log_motion, "Log motion events to stdout", 0}, - {NULL} +static const struct weston_option eventdemo_options[] = { + { WESTON_OPTION_STRING, "title", 0, &title }, + { WESTON_OPTION_INTEGER, "width", 'w', &width }, + { WESTON_OPTION_INTEGER, "height", 'h', &height }, + { WESTON_OPTION_INTEGER, "max-width", 0, &width_max }, + { WESTON_OPTION_INTEGER, "max-height", 0, &height_max }, + { WESTON_OPTION_BOOLEAN, "no-border", 'b', &noborder }, + { WESTON_OPTION_BOOLEAN, "log-redraw", '0', &log_redraw }, + { WESTON_OPTION_BOOLEAN, "log-resize", '0', &log_resize }, + { WESTON_OPTION_BOOLEAN, "log-focus", '0', &log_focus }, + { WESTON_OPTION_BOOLEAN, "log-key", '0', &log_key }, + { WESTON_OPTION_BOOLEAN, "log-button", '0', &log_button }, + { WESTON_OPTION_BOOLEAN, "log-motion", '0', &log_motion }, }; /** @@ -357,8 +341,11 @@ main(int argc, char *argv[]) struct display *d; struct eventdemo *e; + argc = parse_options(eventdemo_options, + ARRAY_LENGTH(eventdemo_options), argc, argv); + /* Connect to the display and have the arguments parsed */ - d = display_create(&argc, &argv, option_entries); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/flower.c b/clients/flower.c index 0565eea6..7a346161 100644 --- a/clients/flower.c +++ b/clients/flower.c @@ -168,7 +168,7 @@ int main(int argc, char *argv[]) struct display *d; struct timeval tv; - d = display_create(&argc, &argv, NULL); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/gears.c b/clients/gears.c index 2353837d..1aecd45e 100644 --- a/clients/gears.c +++ b/clients/gears.c @@ -369,7 +369,7 @@ int main(int argc, char *argv[]) { struct display *d; - d = display_create(&argc, &argv, NULL); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/image.c b/clients/image.c index 8f621eb7..10588478 100644 --- a/clients/image.c +++ b/clients/image.c @@ -220,17 +220,13 @@ image_create(struct display *display, const char *filename) return image; } -static const GOptionEntry option_entries[] = { - { NULL } -}; - int main(int argc, char *argv[]) { struct display *d; int i; - d = display_create(&argc, &argv, option_entries); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/resizor.c b/clients/resizor.c index 9f9e1b5f..67d4899d 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -242,7 +242,7 @@ main(int argc, char *argv[]) struct display *display; struct resizor *resizor; - display = display_create(&argc, &argv, NULL); + display = display_create(argc, argv); if (display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/smoke.c b/clients/smoke.c index 6f800546..d6181008 100644 --- a/clients/smoke.c +++ b/clients/smoke.c @@ -283,7 +283,7 @@ int main(int argc, char *argv[]) struct display *d; int size; - d = display_create(&argc, &argv, NULL); + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c index fd772af6..89dfc3fe 100644 --- a/clients/tablet-shell.c +++ b/clients/tablet-shell.c @@ -316,7 +316,7 @@ int main(int argc, char *argv[]) uint32_t id; struct tablet_shell *shell; - display = display_create(&argc, &argv, NULL); + display = display_create(argc, argv); if (display == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/terminal.c b/clients/terminal.c index 65fec38b..45d4f128 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -2362,10 +2362,8 @@ terminal_run(struct terminal *terminal, const char *path) return 0; } -static const GOptionEntry option_entries[] = { - { "fullscreen", 'f', 0, G_OPTION_ARG_NONE, - &option_fullscreen, "Run in fullscreen mode" }, - { NULL } +static const struct weston_option terminal_options[] = { + { WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &option_fullscreen }, }; int main(int argc, char *argv[]) @@ -2374,7 +2372,10 @@ int main(int argc, char *argv[]) struct terminal *terminal; const char *shell; - d = display_create(&argc, &argv, option_entries); + argc = parse_options(terminal_options, + ARRAY_LENGTH(terminal_options), argc, argv); + + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/view.c b/clients/view.c index 918d22fe..61a3d5cb 100644 --- a/clients/view.c +++ b/clients/view.c @@ -252,10 +252,8 @@ view_create(struct display *display, static int option_fullscreen; -static const GOptionEntry option_entries[] = { - { "fullscreen", 'f', 0, G_OPTION_ARG_NONE, - &option_fullscreen, "Run in fullscreen mode" }, - { NULL } +static const struct weston_option view_options[] = { + { WESTON_OPTION_BOOLEAN, "fullscreen", 0, &option_fullscreen }, }; int @@ -264,7 +262,10 @@ main(int argc, char *argv[]) struct display *d; int i; - d = display_create(&argc, &argv, option_entries); + argc = parse_options(view_options, + ARRAY_LENGTH(view_options), argc, argv); + + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return -1; diff --git a/clients/window.c b/clients/window.c index 5465c2dc..09d5ab14 100644 --- a/clients/window.c +++ b/clients/window.c @@ -231,14 +231,10 @@ const char *option_xkb_layout = "us"; const char *option_xkb_variant = ""; const char *option_xkb_options = ""; -static const GOptionEntry xkb_option_entries[] = { - { "xkb-layout", 0, 0, G_OPTION_ARG_STRING, - &option_xkb_layout, "XKB Layout" }, - { "xkb-variant", 0, 0, G_OPTION_ARG_STRING, - &option_xkb_variant, "XKB Variant" }, - { "xkb-options", 0, 0, G_OPTION_ARG_STRING, - &option_xkb_options, "XKB Options" }, - { NULL } +static const struct weston_option xkb_options[] = { + { WESTON_OPTION_STRING, "xkb-layout", 0, &option_xkb_layout }, + { WESTON_OPTION_STRING, "xkb-variant", 0, &option_xkb_variant }, + { WESTON_OPTION_STRING, "xkb-options", 0, &option_xkb_options }, }; static const cairo_user_data_key_t surface_data_key; @@ -2921,32 +2917,14 @@ handle_display_data(struct task *task, uint32_t events) } struct display * -display_create(int *argc, char **argv[], const GOptionEntry *option_entries) +display_create(int argc, char *argv[]) { struct display *d; - GOptionContext *context; - GOptionGroup *xkb_option_group; - GError *error; g_type_init(); - context = g_option_context_new(NULL); - if (option_entries) - g_option_context_add_main_entries(context, option_entries, "Wayland View"); - - xkb_option_group = g_option_group_new("xkb", - "Keyboard options", - "Show all XKB options", - NULL, NULL); - g_option_group_add_entries(xkb_option_group, xkb_option_entries); - g_option_context_add_group (context, xkb_option_group); - - if (!g_option_context_parse(context, argc, argv, &error)) { - fprintf(stderr, "option parsing failed: %s\n", error->message); - exit(EXIT_FAILURE); - } - - g_option_context_free(context); + argc = parse_options(xkb_options, + ARRAY_LENGTH(xkb_options), argc, argv); d = malloc(sizeof *d); if (d == NULL) diff --git a/clients/window.h b/clients/window.h index eb33eedf..e6b7b4bd 100644 --- a/clients/window.h +++ b/clients/window.h @@ -24,9 +24,9 @@ #define _WINDOW_H_ #include -#include #include #include +#include "../shared/config-parser.h" struct window; struct widget; @@ -47,7 +47,7 @@ struct rectangle { }; struct display * -display_create(int *argc, char **argv[], const GOptionEntry *option_entries); +display_create(int argc, char *argv[]); void display_destroy(struct display *display); diff --git a/clients/wscreensaver.c b/clients/wscreensaver.c index 5342b336..21cc41e6 100644 --- a/clients/wscreensaver.c +++ b/clients/wscreensaver.c @@ -296,10 +296,8 @@ global_handler(struct wl_display *display, uint32_t id, } } -static const GOptionEntry option_entries[] = { - { "demo", 0, 0, G_OPTION_ARG_NONE, &demo_mode, - "Run as a regular application, not a screensaver.", NULL }, - { NULL } +static const struct weston_option wscreensaver_options[] = { + { WESTON_OPTION_BOOLEAN, "demo", 0, &demo_mode }, }; int main(int argc, char *argv[]) @@ -309,7 +307,10 @@ int main(int argc, char *argv[]) init_frand(); - d = display_create(&argc, &argv, option_entries); + argc = parse_options(wscreensaver_options, + ARRAY_LENGTH(wscreensaver_options), argc, argv); + + d = display_create(argc, argv); if (d == NULL) { fprintf(stderr, "failed to create display: %m\n"); return EXIT_FAILURE; diff --git a/shared/Makefile.am b/shared/Makefile.am index 79568b65..0b8ec1bd 100644 --- a/shared/Makefile.am +++ b/shared/Makefile.am @@ -1,4 +1,5 @@ noinst_LTLIBRARIES = libconfig-parser.la libconfig_parser_la_SOURCES = \ config-parser.c \ + option-parser.c \ config-parser.h diff --git a/shared/config-parser.h b/shared/config-parser.h index 27f528db..0619bb47 100644 --- a/shared/config-parser.h +++ b/shared/config-parser.h @@ -51,5 +51,23 @@ parse_config_file(const char *path, char * config_file_path(const char *name); +enum weston_option_type { + WESTON_OPTION_INTEGER, + WESTON_OPTION_UNSIGNED_INTEGER, + WESTON_OPTION_STRING, + WESTON_OPTION_BOOLEAN, +}; + +struct weston_option { + enum weston_option_type type; + const char *name; + int short_name; + void *data; +}; + +int +parse_options(const struct weston_option *options, + int count, int argc, char *argv[]); + #endif /* CONFIGPARSER_H */ diff --git a/shared/option-parser.c b/shared/option-parser.c new file mode 100644 index 00000000..600f1107 --- /dev/null +++ b/shared/option-parser.c @@ -0,0 +1,82 @@ +/* + * Copyright © 2012 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "config-parser.h" + +static void +handle_option(const struct weston_option *option, char *value) +{ + switch (option->type) { + case WESTON_OPTION_INTEGER: + * (int32_t *) option->data = strtol(value, NULL, 0); + return; + case WESTON_OPTION_UNSIGNED_INTEGER: + * (uint32_t *) option->data = strtoul(value, NULL, 0); + return; + case WESTON_OPTION_STRING: + * (char **) option->data = strdup(value); + return; + case WESTON_OPTION_BOOLEAN: + * (int32_t *) option->data = 1; + return; + default: + assert(0); + } +} + +int +parse_options(const struct weston_option *options, + int count, int argc, char *argv[]) +{ + int i, j, k, len = 0; + + for (i = 1, j = 1; i < argc; i++) { + for (k = 0; k < count; k++) { + if (options[k].name) + len = strlen(options[k].name); + if (options[k].name && + argv[i][0] == '-' && + argv[i][1] == '-' && + strncmp(options[k].name, &argv[i][2], len) == 0 && + (argv[i][len + 2] == '=' || argv[i][len + 2] == '\0')) { + handle_option(&options[k], &argv[i][len + 3]); + break; + } else if (options[k].short_name && + argv[i][0] == '-' && + options[k].short_name == argv[i][1]) { + handle_option(&options[k], &argv[i][2]); + break; + } + } + if (k == count) + argv[j++] = argv[i]; + } + argv[j] = NULL; + + return j; +} diff --git a/src/Makefile.am b/src/Makefile.am index f1003f70..4a93d51a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,8 +9,9 @@ AM_CPPFLAGS = \ weston_LDFLAGS = -export-dynamic weston_CFLAGS = $(GCC_CFLAGS) -weston_LDADD = \ - $(COMPOSITOR_LIBS) $(DLOPEN_LIBS) $(XSERVER_LAUNCHER_LIBS) -lm +weston_LDADD = \ + $(COMPOSITOR_LIBS) $(DLOPEN_LIBS) $(XSERVER_LAUNCHER_LIBS) -lm \ + ../shared/libconfig-parser.la weston_SOURCES = \ compositor.c \ diff --git a/src/compositor-drm.c b/src/compositor-drm.c index edeb0ab6..ba7e6429 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1639,34 +1639,19 @@ drm_compositor_create(struct wl_display *display, return &ec->base; } -struct weston_compositor * -backend_init(struct wl_display *display, char *options); - WL_EXPORT struct weston_compositor * -backend_init(struct wl_display *display, char *options) +backend_init(struct wl_display *display, int argc, char *argv[]) { - int connector = 0, i; - const char *seat; - char *p, *value; - int tty = 0; - - static char * const tokens[] = { "connector", "seat", "tty", NULL }; - - p = options; - seat = default_seat; - while (i = getsubopt(&p, tokens, &value), i != -1) { - switch (i) { - case 0: - connector = strtol(value, NULL, 0); - break; - case 1: - seat = value; - break; - case 2: - tty = strtol(value, NULL, 0); - break; - } - } + int connector = 0, tty = 0; + const char *seat = default_seat; + + const struct weston_option drm_options[] = { + { WESTON_OPTION_INTEGER, "connector", 0, &connector }, + { WESTON_OPTION_STRING, "seat", 0, &seat }, + { WESTON_OPTION_INTEGER, "tty", 0, &tty }, + }; + + parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv); return drm_compositor_create(display, connector, seat, tty); } diff --git a/src/compositor-openwfd.c b/src/compositor-openwfd.c index eae1e662..2dba07d0 100644 --- a/src/compositor-openwfd.c +++ b/src/compositor-openwfd.c @@ -663,34 +663,19 @@ wfd_compositor_create(struct wl_display *display, return &ec->base; } -struct weston_compositor * -backend_init(struct wl_display *display, char *options); - WL_EXPORT struct weston_compositor * -backend_init(struct wl_display *display, char *options) +backend_init(struct wl_display *display, int argc, char *argv[]) { - int connector = 0, i; + int connector = 0, tty = 0; const char *seat; - char *p, *value; - int tty = 0; - static char * const tokens[] = { "connector", "seat", "tty", NULL }; - - p = options; - seat = default_seat; - while (i = getsubopt(&p, tokens, &value), i != -1) { - switch (i) { - case 0: - connector = strtol(value, NULL, 0); - break; - case 1: - seat = value; - break; - case 2: - tty = strtol(value, NULL, 0); - break; - } - } + const struct weston_option wfd_options[] = { + { WESTON_OPTION_INTEGER, "connector", 0, &connector }, + { WESTON_OPTION_STRING, "seat", 0, &seat }, + { WESTON_OPTION_INTEGER, "tty", 0, &tty }, + }; + + parse_options(&wfd_options, ARRAY_LENGTH(wfd_options), argc, argv); return wfd_compositor_create(display, connector, seat, tty); } diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index f23c357c..48358e30 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -721,31 +721,20 @@ wayland_compositor_create(struct wl_display *display, return &c->base; } -struct weston_compositor * -backend_init(struct wl_display *display, char *options); - WL_EXPORT struct weston_compositor * -backend_init(struct wl_display *display, char *options) +backend_init(struct wl_display *display, int argc, char *argv[]) { - int width = 1024, height = 640, i; - char *p, *value, *display_name = NULL; - - static char * const tokens[] = { "width", "height", "display", NULL }; - - p = options; - while (i = getsubopt(&p, tokens, &value), i != -1) { - switch (i) { - case 0: - width = strtol(value, NULL, 0); - break; - case 1: - height = strtol(value, NULL, 0); - break; - case 2: - display_name = strdup(value); - break; - } - } + int width = 1024, height = 640; + char *display_name = NULL; + + const struct weston_option wayland_options[] = { + { WESTON_OPTION_INTEGER, "width", 0, &width }, + { WESTON_OPTION_INTEGER, "height", 0, &height }, + { WESTON_OPTION_STRING, "display", 0, &display_name }, + }; + + parse_options(wayland_options, + ARRAY_LENGTH(wayland_options), argc, argv); return wayland_compositor_create(display, width, height, display_name); } diff --git a/src/compositor-x11.c b/src/compositor-x11.c index fe147c71..9d813de6 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -817,36 +817,19 @@ x11_compositor_create(struct wl_display *display, return &c->base; } -struct weston_compositor * -backend_init(struct wl_display *display, char *options); - WL_EXPORT struct weston_compositor * -backend_init(struct wl_display *display, char *options) +backend_init(struct wl_display *display, int argc, char *argv[]) { - int width = 1024, height = 640, fullscreen = 0, count = 1, i; - char *p, *value; + int width = 1024, height = 640, fullscreen = 0, count = 1; - static char * const tokens[] = { - "width", "height", "fullscreen", "output-count", NULL + const struct weston_option x11_options[] = { + { WESTON_OPTION_INTEGER, "width", 0, &width }, + { WESTON_OPTION_INTEGER, "height", 0, &height }, + { WESTON_OPTION_BOOLEAN, "fullscreen", 0, &fullscreen }, + { WESTON_OPTION_INTEGER, "output-count", 0, &count }, }; - - p = options; - while (i = getsubopt(&p, tokens, &value), i != -1) { - switch (i) { - case 0: - width = strtol(value, NULL, 0); - break; - case 1: - height = strtol(value, NULL, 0); - break; - case 2: - fullscreen = 1; - break; - case 3: - count = strtol(value, NULL, 0); - break; - } - } + + parse_options(x11_options, ARRAY_LENGTH(x11_options), argc, argv); return x11_compositor_create(display, width, height, count, fullscreen); diff --git a/src/compositor.c b/src/compositor.c index 50eb0182..f2ae2f64 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -50,8 +49,6 @@ #include #include "compositor.h" -static const char *option_socket_name = NULL; - static struct wl_list child_process_list; static jmp_buf segv_jmp_buf; @@ -2460,57 +2457,28 @@ int main(int argc, char *argv[]) struct wl_event_source *signals[4]; struct wl_event_loop *loop; struct sigaction segv_action; - int o, xserver = 0; void *shell_module, *backend_module; int (*shell_init)(struct weston_compositor *ec); struct weston_compositor - *(*backend_init)(struct wl_display *display, char *options); + *(*backend_init)(struct wl_display *display, + int argc, char *argv[]); + int i; char *backend = NULL; - char *backend_options = ""; char *shell = NULL; - char *p; - int option_idle_time = 300; - int i; - - static const char opts[] = "B:b:o:S:i:s:x"; - static const struct option longopts[ ] = { - { "backend", 1, NULL, 'B' }, - { "backend-options", 1, NULL, 'o' }, - { "socket", 1, NULL, 'S' }, - { "idle-time", 1, NULL, 'i' }, - { "shell", 1, NULL, 's' }, - { "xserver", 0, NULL, 'x' }, - { NULL, } + int32_t idle_time = 300; + int32_t xserver; + char *socket_name = NULL; + + const struct weston_option core_options[] = { + { WESTON_OPTION_STRING, "backend", 'B', &backend }, + { WESTON_OPTION_STRING, "socket", 'S', &socket_name }, + { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time }, + { WESTON_OPTION_STRING, "shell", 's', &shell }, + { WESTON_OPTION_BOOLEAN, "xserver", 0, &xserver }, }; - while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) { - switch (o) { - case 'B': - backend = optarg; - break; - case 'o': - backend_options = optarg; - break; - case 'S': - option_socket_name = optarg; - break; - case 'i': - option_idle_time = strtol(optarg, &p, 0); - if (*p != '\0') { - fprintf(stderr, - "invalid idle time option: %s\n", - optarg); - exit(EXIT_FAILURE); - } - break; - case 's': - shell = optarg; - break; - case 'x': - xserver = 1; - break; - } - } + argc = parse_options(core_options, + ARRAY_LENGTH(core_options), argc, argv); display = wl_display_create(); @@ -2553,14 +2521,19 @@ int main(int argc, char *argv[]) if (!shell_init) exit(EXIT_FAILURE); - ec = backend_init(display, backend_options); + ec = backend_init(display, argc, argv); if (ec == NULL) { fprintf(stderr, "failed to create compositor\n"); exit(EXIT_FAILURE); } - ec->option_idle_time = option_idle_time; - ec->idle_time = option_idle_time; + for (i = 1; argv[i]; i++) + fprintf(stderr, "unhandled option: %s\n", argv[i]); + if (argv[1]) + exit(EXIT_FAILURE); + + ec->option_idle_time = idle_time; + ec->idle_time = idle_time; #ifdef BUILD_XSERVER_LAUNCHER if (xserver) @@ -2570,7 +2543,7 @@ int main(int argc, char *argv[]) if (shell_init(ec) < 0) exit(EXIT_FAILURE); - if (wl_display_add_socket(display, option_socket_name)) { + if (wl_display_add_socket(display, socket_name)) { fprintf(stderr, "failed to add socket: %m\n"); exit(EXIT_FAILURE); } diff --git a/src/compositor.h b/src/compositor.h index b94731b8..b5ba7b25 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -34,6 +34,7 @@ #include #include "matrix.h" +#include "../shared/config-parser.h" struct weston_transform { struct weston_matrix matrix; @@ -552,4 +553,7 @@ weston_surface_set_color(struct weston_surface *surface, void weston_surface_destroy(struct weston_surface *surface); +struct weston_compositor * +backend_init(struct wl_display *display, int argc, char *argv[]); + #endif