The %m from glibc would indeed be a portability problem. However, it is already lightly used within wayland (11 occurrences) and heavily in weston (125 occurrences). I suggest you keep them for now, then clean them all up in one patch later - assuming the wayland community and prospective users consider portability a worthwhile effort.
Cheers, Karsten Am 22.10.2014 um 17:57 schrieb Derek Foreman <[email protected]>: > I'd prefer to see the refactor and the new feature in separate patches, > but this is pretty trivial. > > I also have a slight preference for exit(EXIT_FAILURE), which is already > used somewhere else in that file - though there's also precedent for > exit(1), so you make the call. :) > > I'd not seen printf's %m until today - do we want to depend on a gnuism? > I've seen at least some activity towards a freebsd port - I don't > believe %m is supported there? > > > That said, it runs nicely here and does what it says on the tin... > > Reviewed-by: Derek Foreman <[email protected]> > > On 22/10/14 08:53 AM, Pekka Paalanen wrote: >> Process a new section 'autolaunch' from weston.ini, launching all >> programs given there on desktop start-up. >> >> [Frederic Plourde: cut redundancy between do_autolaunch and >> panel_add_launcher] >> --- >> clients/desktop-shell.c | 97 >> ++++++++++++++++++++++++++++++++++++++++++------- >> man/weston.ini.man | 17 +++++++++ >> weston.ini.in | 3 ++ >> 3 files changed, 103 insertions(+), 14 deletions(-) >> >> diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c >> index 961a9b2..a964094 100644 >> --- a/clients/desktop-shell.c >> +++ b/clients/desktop-shell.c >> @@ -597,72 +597,82 @@ load_icon_or_fallback(const char *icon) >> cairo_move_to(cr, 4, 16); >> cairo_line_to(cr, 16, 4); >> cairo_stroke(cr); >> >> cairo_destroy(cr); >> >> return surface; >> } >> >> static void >> -panel_add_launcher(struct panel *panel, const char *icon, const char *path) >> +parse_launcher_path(char *path, struct wl_array *envp_array, struct >> wl_array *argv_array) >> { >> - struct panel_launcher *launcher; >> char *start, *p, *eq, **ps; >> int i, j, k; >> >> - launcher = xzalloc(sizeof *launcher); >> - launcher->icon = load_icon_or_fallback(icon); >> - launcher->path = xstrdup(path); >> + struct wl_array *envp = envp_array; >> + struct wl_array *argv = argv_array; >> >> - wl_array_init(&launcher->envp); >> - wl_array_init(&launcher->argv); >> + wl_array_init(envp); >> + wl_array_init(argv); >> for (i = 0; environ[i]; i++) { >> - ps = wl_array_add(&launcher->envp, sizeof *ps); >> + ps = wl_array_add(envp, sizeof *ps); >> *ps = environ[i]; >> } >> j = 0; >> >> - start = launcher->path; >> + start = path; >> while (*start) { >> for (p = start, eq = NULL; *p && !isspace(*p); p++) >> if (*p == '=') >> eq = p; >> >> if (eq && j == 0) { >> - ps = launcher->envp.data; >> + ps = envp->data; >> for (k = 0; k < i; k++) >> if (strncmp(ps[k], start, eq - start) == 0) { >> ps[k] = start; >> break; >> } >> if (k == i) { >> - ps = wl_array_add(&launcher->envp, sizeof *ps); >> + ps = wl_array_add(envp, sizeof *ps); >> *ps = start; >> i++; >> } >> } else { >> - ps = wl_array_add(&launcher->argv, sizeof *ps); >> + ps = wl_array_add(argv, sizeof *ps); >> *ps = start; >> j++; >> } >> >> while (*p && isspace(*p)) >> *p++ = '\0'; >> >> start = p; >> } >> >> - ps = wl_array_add(&launcher->envp, sizeof *ps); >> + ps = wl_array_add(envp, sizeof *ps); >> *ps = NULL; >> - ps = wl_array_add(&launcher->argv, sizeof *ps); >> + ps = wl_array_add(argv, sizeof *ps); >> *ps = NULL; >> +} >> + >> +static void >> +panel_add_launcher(struct panel *panel, const char *icon, const char *path) >> +{ >> + struct panel_launcher *launcher; >> + >> + launcher = xzalloc(sizeof *launcher); >> + launcher->icon = load_icon_or_fallback(icon); >> + launcher->path = xstrdup(path); >> + >> + parse_launcher_path(launcher->path, &launcher->envp, &launcher->argv); >> >> launcher->panel = panel; >> wl_list_insert(panel->launcher_list.prev, &launcher->link); >> >> launcher->widget = widget_add_widget(panel->widget, launcher); >> widget_set_enter_handler(launcher->widget, >> panel_launcher_enter_handler); >> widget_set_leave_handler(launcher->widget, >> panel_launcher_leave_handler); >> widget_set_button_handler(launcher->widget, >> @@ -1316,20 +1326,77 @@ panel_add_launchers(struct panel *panel, struct >> desktop *desktop) >> } >> >> if (count == 0) { >> /* add default launcher */ >> panel_add_launcher(panel, >> DATADIR "/weston/terminal.png", >> BINDIR "/weston-terminal"); >> } >> } >> >> +static void >> +do_autolaunch(const char *path_arg) >> +{ >> + struct wl_array envp; >> + struct wl_array argv; >> + pid_t pid; >> + char **argvpp; >> + char *path; >> + >> + path = xstrdup(path_arg); >> + >> + parse_launcher_path(path, &envp, &argv); >> + >> + /* panel_launcher_activate */ >> + >> + pid = fork(); >> + if (pid < 0) { >> + fprintf(stderr, "fork failed: %m\n"); >> + goto out; >> + } >> + >> + if (pid) >> + goto out; >> + >> + argvpp = argv.data; >> + if (execve(argvpp[0], argvpp, envp.data) < 0) { >> + fprintf(stderr, "execl '%s' failed: %m\n", argvpp[0]); >> + exit(1); >> + } >> + >> +out: >> + wl_array_release(&argv); >> + wl_array_release(&envp); >> + free(path); >> +} >> + >> +static void >> +process_autolaunch(struct desktop *desktop) >> +{ >> + struct weston_config_section *s; >> + char *path; >> + const char *name; >> + >> + s = NULL; >> + while (weston_config_next_section(desktop->config, &s, &name)) { >> + if (strcmp(name, "autolaunch") != 0) >> + continue; >> + >> + weston_config_section_get_string(s, "path", &path, NULL); >> + if (!path) >> + continue; >> + >> + do_autolaunch(path); >> + free(path); >> + } >> +} >> + >> int main(int argc, char *argv[]) >> { >> struct desktop desktop = { 0 }; >> struct output *output; >> struct weston_config_section *s; >> >> desktop.unlock_task.run = unlock_dialog_finish; >> wl_list_init(&desktop.outputs); >> >> desktop.config = weston_config_parse("weston.ini"); >> @@ -1349,20 +1416,22 @@ int main(int argc, char *argv[]) >> /* Create panel and background for outputs processed before the shell >> * global interface was processed */ >> wl_list_for_each(output, &desktop.outputs, link) >> if (!output->panel) >> output_init(output, &desktop); >> >> grab_surface_create(&desktop); >> >> signal(SIGCHLD, sigchild_handler); >> >> + process_autolaunch(&desktop); >> + >> display_run(desktop.display); >> >> /* Cleanup */ >> grab_surface_destroy(&desktop); >> desktop_destroy_outputs(&desktop); >> if (desktop.unlock_dialog) >> unlock_dialog_destroy(desktop.unlock_dialog); >> desktop_shell_destroy(desktop.shell); >> display_destroy(desktop.display); >> >> diff --git a/man/weston.ini.man b/man/weston.ini.man >> index c05a221..365141c 100644 >> --- a/man/weston.ini.man >> +++ b/man/weston.ini.man >> @@ -66,20 +66,21 @@ Comment lines are ignored: >> .RE >> .PP >> The section headers are: >> .PP >> .RS 4 >> .nf >> .BR "core " "The core modules" >> .BR "libinput " "Input device configuration" >> .BR "shell " "Desktop customization" >> .BR "launcher " "Add launcher to the panel" >> +.BR "autolaunch " "Launch program automatically on startup" >> .BR "screensaver " "Screensaver selection" >> .BR "output " "Output configuration" >> .BR "input-method " "Onscreen keyboard input" >> .BR "keyboard " "Keyboard layouts" >> .BR "terminal " "Terminal application options" >> .BR "xwayland " "XWayland options" >> .BR "screen-share " "Screen sharing options" >> .fi >> .RE >> .PP >> @@ -272,20 +273,36 @@ sets the path to the program that is run by clicking >> on this launcher (string). >> It is possible to pass arguments and environment variables to the program. >> For >> example: >> .nf >> .in +4n >> >> path=GDK_BACKEND=wayland gnome-terminal --full-screen >> .in >> .fi >> .PP >> .RE >> +.SH "AUTOLAUNCH SECTION" >> +There can be multiple autolaunch sections for starting multiple programs. >> +.TP 7 >> +.BI "path=" program >> +sets the path (string) to the program that is run automatically when the >> +desktop is starting. >> +It is possible to pass arguments and environment variables to the program. >> For >> +example: >> +.nf >> +.in +4n >> + >> +path=GDK_BACKEND=wayland gnome-terminal --full-screen >> +.in >> +.fi >> +.PP >> +.RE >> .SH "SCREENSAVER SECTION" >> The >> .B screensaver >> section is used to select and schedule a screensaver. >> The >> .B screensaver >> section is optional, as are all of the entries that may be specified in >> it. >> .TP 7 >> .BI "path=" /usr/libexec/weston-screensaver >> diff --git a/weston.ini.in b/weston.ini.in >> index 4fca0bb..b0cb31f 100644 >> --- a/weston.ini.in >> +++ b/weston.ini.in >> @@ -30,20 +30,23 @@ >> icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png >> path=@bindir@/weston-terminal >> >> [launcher] >> icon=/usr/share/icons/hicolor/24x24/apps/google-chrome.png >> path=/usr/bin/google-chrome >> >> [launcher] >> icon=/usr/share/icons/gnome/24x24/apps/arts.png >> path=@abs_top_builddir@/weston-flower >> >> +#[autolaunch] >> +#path=@bindir@/weston-terminal >> + >> [screensaver] >> # Comment path to disable screensaver >> path=@libexecdir@/weston-screensaver >> duration=600 >> >> [input-method] >> path=@libexecdir@/weston-keyboard >> >> #[output] >> #name=LVDS1 >> > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
