[PATCH] compositor: pass options to the shell process, v2
Pekka Paalanen
ppaalanen at gmail.com
Mon Nov 7 01:06:30 PST 2011
When desktop-shell was changed to be launched by the compositor alone,
we also lost the opportunity to give it arguments, specifically the
background picture.
Add the compositor option -b (--shell-options) for passing arguments to
the shell process. The parameter to -b is a comma-separated list of
arguments to the shell.
Option -b cannot be used multiple times, and it cannot be used to pass
arguments containing commas to the shell.
Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
compositor/compositor.c | 9 +++++-
compositor/meego-tablet-shell.c | 4 +-
compositor/shell.c | 50 +++++++++++++++++++++++++-------------
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/compositor/compositor.c b/compositor/compositor.c
index 53b282a..642022e 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -2159,12 +2159,13 @@ int main(int argc, char *argv[])
struct wl_event_loop *loop;
int o, xserver = 0;
void *shell_module, *backend_module;
- int (*shell_init)(struct wlsc_compositor *ec);
+ int (*shell_init)(struct wlsc_compositor *ec, char *options);
struct wlsc_compositor
*(*backend_init)(struct wl_display *display, char *options);
char *backend = NULL;
char *backend_options = "";
char *shell = NULL;
+ char *shell_options = NULL;
char *p;
static const char opts[] = "B:b:o:S:i:s:x";
@@ -2174,12 +2175,16 @@ int main(int argc, char *argv[])
{ "socket", 1, NULL, 'S' },
{ "idle-time", 1, NULL, 'i' },
{ "shell", 1, NULL, 's' },
+ { "shell-options", 1, NULL, 'b' },
{ "xserver", 0, NULL, 'x' },
{ NULL, }
};
while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
switch (o) {
+ case 'b':
+ shell_options = optarg;
+ break;
case 'B':
backend = optarg;
break;
@@ -2245,7 +2250,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (shell_init(ec) < 0)
+ if (shell_init(ec, shell_options) < 0)
exit(EXIT_FAILURE);
if (xserver)
diff --git a/compositor/meego-tablet-shell.c b/compositor/meego-tablet-shell.c
index 35b9775..9c64405 100644
--- a/compositor/meego-tablet-shell.c
+++ b/compositor/meego-tablet-shell.c
@@ -638,10 +638,10 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
}
void
-shell_init(struct wlsc_compositor *compositor);
+shell_init(struct wlsc_compositor *compositor, char *options);
WL_EXPORT void
-shell_init(struct wlsc_compositor *compositor)
+shell_init(struct wlsc_compositor *compositor, char *options)
{
struct meego_tablet_shell *shell;
struct wl_event_loop *loop;
diff --git a/compositor/shell.c b/compositor/shell.c
index ed2637d..7af2d86 100644
--- a/compositor/shell.c
+++ b/compositor/shell.c
@@ -943,13 +943,39 @@ desktop_shell_sigchld(struct wlsc_process *process, int status)
shell->child.client = NULL; /* already destroyed by wayland */
}
+static void
+child_exec(int sockfd, const char *path, char *options)
+{
+ const int argc_max = 16;
+ char *argv[argc_max + 1];
+ int i = 0;
+ char s[32];
+ int flags;
+
+ argv[i] = (char *)path;
+ while (argv[i] && i < argc_max)
+ argv[++i] = strsep(&options, ",");
+ argv[i] = NULL;
+
+ /* SOCK_CLOEXEC closes both ends, so we need to unset
+ * the flag on the client fd. */
+ flags = fcntl(sockfd, F_GETFD);
+ if (flags != -1)
+ fcntl(sockfd, F_SETFD, flags & ~FD_CLOEXEC);
+
+ snprintf(s, sizeof s, "%d", sockfd);
+ setenv("WAYLAND_SOCKET", s, 1);
+
+ if (execv(path, argv) < 0)
+ fprintf(stderr, "running '%s' failed: %m\n", path);
+}
+
static int
-launch_desktop_shell_process(struct wl_shell *shell)
+launch_desktop_shell_process(struct wl_shell *shell, char *options)
{
const char *shell_exe = "./clients/desktop-shell";
struct wlsc_compositor *compositor = shell->compositor;
- char s[32];
- int sv[2], flags;
+ int sv[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
fprintf(stderr, "socketpair failed\n");
@@ -961,17 +987,7 @@ launch_desktop_shell_process(struct wl_shell *shell)
switch (shell->child.process.pid) {
case 0:
- /* SOCK_CLOEXEC closes both ends, so we need to unset
- * the flag on the client fd. */
- flags = fcntl(sv[1], F_GETFD);
- if (flags != -1)
- fcntl(sv[1], F_SETFD, flags & ~FD_CLOEXEC);
-
- snprintf(s, sizeof s, "%d", sv[1]);
- setenv("WAYLAND_SOCKET", s, 1);
- if (execl(shell_exe, shell_exe, NULL) < 0)
- fprintf(stderr, "%s: running '%s' failed: %m\n",
- __func__, shell_exe);
+ child_exec(sv[1], shell_exe, options);
exit(-1);
default:
@@ -1017,10 +1033,10 @@ bind_desktop_shell(struct wl_client *client,
}
int
-shell_init(struct wlsc_compositor *ec);
+shell_init(struct wlsc_compositor *ec, char *options);
WL_EXPORT int
-shell_init(struct wlsc_compositor *ec)
+shell_init(struct wlsc_compositor *ec, char *options)
{
struct wl_shell *shell;
@@ -1044,7 +1060,7 @@ shell_init(struct wlsc_compositor *ec)
shell, bind_desktop_shell) == NULL)
return -1;
- if (launch_desktop_shell_process(shell) != 0)
+ if (launch_desktop_shell_process(shell, options) != 0)
return -1;
wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER,
--
1.7.3.4
More information about the wayland-devel
mailing list