[PATCH] compositor: pass options to the shell process
Pekka Paalanen
ppaalanen at gmail.com
Fri Nov 4 03:33:36 PDT 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-option) which can be used to pass
any number of options to the desktop-shell by using it repeatedly.
Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
compositor/compositor.c | 15 ++++++++++-
compositor/meego-tablet-shell.c | 4 +-
compositor/shell.c | 50 +++++++++++++++++++++++++-------------
3 files changed, 48 insertions(+), 21 deletions(-)
diff --git a/compositor/compositor.c b/compositor/compositor.c
index 53b282a..a516837 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -2159,13 +2159,15 @@ 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, struct wl_array *opts);
struct wlsc_compositor
*(*backend_init)(struct wl_display *display, char *options);
char *backend = NULL;
char *backend_options = "";
char *shell = NULL;
char *p;
+ struct wl_array shell_options; /* contains (char *) */
+ char **pp;
static const char opts[] = "B:b:o:S:i:s:x";
static const struct option longopts[ ] = {
@@ -2174,12 +2176,19 @@ int main(int argc, char *argv[])
{ "socket", 1, NULL, 'S' },
{ "idle-time", 1, NULL, 'i' },
{ "shell", 1, NULL, 's' },
+ { "shell-option", 1, NULL, 'b' },
{ "xserver", 0, NULL, 'x' },
{ NULL, }
};
+ wl_array_init(&shell_options);
+
while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
switch (o) {
+ case 'b':
+ pp = wl_array_add(&shell_options, sizeof *pp);
+ *pp = optarg;
+ break;
case 'B':
backend = optarg;
break;
@@ -2245,7 +2254,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)
@@ -2267,5 +2276,7 @@ int main(int argc, char *argv[])
ec->destroy(ec);
+ wl_array_release(&shell_options);
+
return 0;
}
diff --git a/compositor/meego-tablet-shell.c b/compositor/meego-tablet-shell.c
index 35b9775..368971f 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, struct wl_array *opts);
WL_EXPORT void
-shell_init(struct wlsc_compositor *compositor)
+shell_init(struct wlsc_compositor *compositor, struct wl_array *opts)
{
struct meego_tablet_shell *shell;
struct wl_event_loop *loop;
diff --git a/compositor/shell.c b/compositor/shell.c
index ed2637d..b409d50 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, struct wl_array *opts)
+{
+ char s[32];
+ int flags;
+ char **argv;
+ int nelem = opts ? (opts->size / sizeof *argv) : 0;
+
+ argv = malloc((nelem + 2) * sizeof *argv);
+ argv[0] = (char *)path;
+ if (nelem > 0)
+ memcpy(&argv[1], opts->data, opts->size);
+ argv[nelem + 1] = 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, struct wl_array *opts)
{
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, opts);
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, struct wl_array *opts);
WL_EXPORT int
-shell_init(struct wlsc_compositor *ec)
+shell_init(struct wlsc_compositor *ec, struct wl_array *opts)
{
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, opts) != 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