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

Reply via email to