+1 for refactoring in a separate patch.
by merging the change with panel_add_launcher in the same patch, it gets *really* hard to read because of the intertwining.

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.
So we can't really say one if more trendy than the other.
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.

On 14-10-22 11:57 AM, Derek Foreman wrote:
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

Reply via email to