<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">+1 for refactoring in a separate patch.<br>
      by merging the change with panel_add_launcher in the same patch,
      it gets *really* hard to read because of the intertwining.<br>
      <br>
      now, for exit(<int>) instead of using EXIT_FAILURE/SUCCESS,
      currently there is roughly 50 usages of exit(<int>) out of
      100 total calls to exit() in Weston codebase.<br>
      So we can't really say one if more trendy than the other.<br>
      I'd suggest we leave that as is for now in this patch and open up
      another bug to change all of them separately someday.<br>
      <div class="moz-signature">
        <meta http-equiv="content-type" content="text/html;
          charset=windows-1252">
        <br>
        <div class="moz-signature">
          <meta http-equiv="CONTENT-TYPE" content="text/html;
            charset=windows-1252">
          <title></title>
          <meta name="GENERATOR" content="LibreOffice 4.1-6 (Linux)">
          <meta name="CREATED" content="0;0">
          <meta name="CHANGEDBY" content="Frederic Plourde">
          <meta name="CHANGED" content="20141022;112439857100097">
          <style type="text/css">
        <!--
                P { color: #000000 }
                BLOCKQUOTE { color: #000000 }
        --></style></div>
      </div>
      On 14-10-22 11:57 AM, Derek Foreman wrote:<br>
    </div>
    <blockquote cite="mid:5447D3DC.1090207@osg.samsung.com" type="cite">
      <pre wrap="">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 <a class="moz-txt-link-rfc2396E" href="mailto:derekf@osg.samsung.com"><derekf@osg.samsung.com></a>

On 22/10/14 08:53 AM, Pekka Paalanen wrote:
</pre>
      <blockquote type="cite">
        <pre wrap="">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

</pre>
      </blockquote>
      <pre wrap="">
_______________________________________________
wayland-devel mailing list
<a class="moz-txt-link-abbreviated" href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a>
<a class="moz-txt-link-freetext" href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>