diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2014-03-17 22:33:29 -0700 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2014-03-20 15:16:22 -0700 |
commit | 45a79b7e87874eef686463182b90375c402eebdb (patch) | |
tree | fc394de45ec88dfc00e55973c83ab079a00a4f2c | |
parent | b033c5e1d094874da73c11a89ffd32d09936171e (diff) |
xwayland: Use new Xwayland DDXxwayland-ddx
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | protocol/xserver.xml | 18 | ||||
-rw-r--r-- | xwayland/launcher.c | 103 | ||||
-rw-r--r-- | xwayland/window-manager.c | 151 | ||||
-rw-r--r-- | xwayland/xwayland.h | 7 |
6 files changed, 139 insertions, 147 deletions
diff --git a/Makefile.am b/Makefile.am index 5ff4f834..587cc3e6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -700,11 +700,6 @@ xwayland_la_SOURCES = \ xwayland/launcher.c \ xwayland/hash.c \ xwayland/hash.h -nodist_xwayland_la_SOURCES = \ - protocol/xserver-protocol.c \ - protocol/xserver-server-protocol.h - -BUILT_SOURCES += $(nodist_xwayland_la_SOURCES) endif diff --git a/configure.ac b/configure.ac index 4db0ed14..369064ef 100644 --- a/configure.ac +++ b/configure.ac @@ -99,7 +99,7 @@ if test x$enable_xwayland = xyes; then AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH], [Path to X server]), [XSERVER_PATH="$withval"], - [XSERVER_PATH="$bindir/Xorg"]) + [XSERVER_PATH="$bindir/Xwayland"]) AC_SUBST([XSERVER_PATH]) if test x$enable_xwayland_test = xyes; then PKG_CHECK_MODULES([XWAYLAND_TEST], xcb xcb-dri2 libdrm) diff --git a/protocol/xserver.xml b/protocol/xserver.xml deleted file mode 100644 index 9e25f5c0..00000000 --- a/protocol/xserver.xml +++ /dev/null @@ -1,18 +0,0 @@ -<protocol name="xserver"> - - <interface name="xserver" version="1"> - <request name="set_window_id"> - <arg name="surface" type="object" interface="wl_surface"/> - <arg name="id" type="uint"/> - </request> - - <event name="client"> - <arg name="fd" type="fd"/> - </event> - - <event name="listen_socket"> - <arg name="fd" type="fd"/> - </event> - </interface> - -</protocol> diff --git a/xwayland/launcher.c b/xwayland/launcher.c index 0d496478..c08d0422 100644 --- a/xwayland/launcher.c +++ b/xwayland/launcher.c @@ -37,16 +37,35 @@ static int +handle_sigusr1(int signal_number, void *data) +{ + struct weston_xserver *wxs = data; + + /* We'd be safer if we actually had the struct + * signalfd_siginfo from the signalfd data and could verify + * this came from Xwayland.*/ + weston_wm_create(wxs, wxs->wm_fd); + wl_event_source_remove(wxs->sigusr1_source); + + return 1; +} + +static int weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) { struct weston_xserver *wxs = data; - char display[8], s[8]; - int sv[2], client_fd; + char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8]; + int sv[2], wm[2], fd; char *xserver = NULL; struct weston_config_section *section; if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { - weston_log("socketpair failed\n"); + weston_log("wl connection socketpair failed\n"); + return 1; + } + + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) { + weston_log("X wm connection socketpair failed\n"); return 1; } @@ -55,29 +74,52 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) case 0: /* SOCK_CLOEXEC closes both ends, so we need to unset * the flag on the client fd. */ - client_fd = dup(sv[1]); - if (client_fd < 0) - return 1; - - snprintf(s, sizeof s, "%d", client_fd); + fd = dup(sv[1]); + if (fd < 0) + goto fail; + snprintf(s, sizeof s, "%d", fd); setenv("WAYLAND_SOCKET", s, 1); snprintf(display, sizeof display, ":%d", wxs->display); - section = weston_config_get_section(wxs->compositor->config, "xwayland", NULL, NULL); - weston_config_section_get_string(section, "path", &xserver, XSERVER_PATH); + fd = dup(wxs->abstract_fd); + if (fd < 0) + goto fail; + snprintf(abstract_fd, sizeof abstract_fd, "%d", fd); + fd = dup(wxs->unix_fd); + if (fd < 0) + goto fail; + snprintf(unix_fd, sizeof unix_fd, "%d", fd); + fd = dup(wm[1]); + if (fd < 0) + goto fail; + snprintf(wm_fd, sizeof wm_fd, "%d", fd); + + section = weston_config_get_section(wxs->compositor->config, + "xwayland", NULL, NULL); + weston_config_section_get_string(section, "path", + &xserver, XSERVER_PATH); + + /* Ignore SIGUSR1 in the child, which will make thed X + * server will send SIGUSR1 to the parent (weston) so + * we know when it's done with initialization. During + * initialization the X server will round trip and + * block on the wayland compositor, so avoid making + * blocking requests (like xcb_connect_to_fd) until + * it's done with that. */ + signal(SIGUSR1, SIG_IGN); if (execl(xserver, xserver, display, - "-wayland", "-rootless", - "-retro", - "-nolisten", "all", + "-listen", abstract_fd, + "-listen", unix_fd, + "-wm", wm_fd, "-terminate", NULL) < 0) weston_log("exec failed: %m\n"); - free(xserver); + fail: _exit(EXIT_FAILURE); default: @@ -86,6 +128,9 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data) close(sv[1]); wxs->client = wl_client_create(wxs->wl_display, sv[0]); + close(wm[1]); + wxs->wm_fd = wm[0]; + weston_watch_process(&wxs->process); wl_event_source_remove(wxs->abstract_source); @@ -153,32 +198,6 @@ weston_xserver_cleanup(struct weston_process *process, int status) } } -static void -bind_xserver(struct wl_client *client, - void *data, uint32_t version, uint32_t id) -{ - struct weston_xserver *wxs = data; - - /* If it's a different client than the xserver we launched, - * don't start the wm. */ - if (client != wxs->client) - return; - - wxs->resource = - wl_resource_create(client, &xserver_interface, - 1, id); - wl_resource_set_implementation(wxs->resource, &xserver_implementation, - wxs, NULL); - - wxs->wm = weston_wm_create(wxs); - if (wxs->wm == NULL) { - weston_log("failed to create wm\n"); - } - - xserver_send_listen_socket(wxs->resource, wxs->abstract_fd); - xserver_send_listen_socket(wxs->resource, wxs->unix_fd); -} - static int bind_to_abstract_socket(int display) { @@ -380,8 +399,8 @@ module_init(struct weston_compositor *compositor, WL_EVENT_READABLE, weston_xserver_handle_event, wxs); - wl_global_create(display, &xserver_interface, 1, wxs, bind_xserver); - + wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1, + handle_sigusr1, wxs); wxs->destroy_listener.notify = weston_xserver_destroy; wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener); diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 1bb9825d..4e227dd2 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -1283,6 +1283,65 @@ weston_wm_window_handle_state(struct weston_wm_window *window, } static void +surface_destroy(struct wl_listener *listener, void *data) +{ + struct weston_wm_window *window = + container_of(listener, + struct weston_wm_window, surface_destroy_listener); + + wm_log("surface for xid %d destroyed\n", window->id); + + /* This should have been freed by the shell. + * Don't try to use it later. */ + window->shsurf = NULL; + window->surface = NULL; + window->view = NULL; +} + +static void +xserver_map_shell_surface(struct weston_wm *wm, + struct weston_wm_window *window); + +static void +weston_wm_window_handle_window_id(struct weston_wm_window *window, + xcb_client_message_event_t *client_message) +{ + struct weston_wm *wm = window->wm; + struct wl_resource *resource; + struct weston_surface *surface; + uint32_t id; + + /* HACK: We need to dispatch the wl requests from Xwayland + * that creates the surface before we try to look it up. + * Split this function in two and do second half from an idle + * handler instead of looping recursively here. */ + wl_event_loop_dispatch(wm->server->loop, -1); + + id = client_message->data.data32[0]; + resource = wl_client_get_object(wm->server->client, id); + surface = wl_resource_get_user_data(resource); + + wm_log("set_window_id %d for surface %p\n", id, surface); + + weston_wm_window_read_properties(window); + + /* A weston_wm_window may have many different surfaces assigned + * throughout its life, so we must make sure to remove the listener + * from the old surface signal list. */ + if (window->surface) + wl_list_remove(&window->surface_destroy_listener.link); + + window->surface = (struct weston_surface *) surface; + window->surface_destroy_listener.notify = surface_destroy; + wl_signal_add(&surface->destroy_signal, + &window->surface_destroy_listener); + + weston_wm_window_schedule_repaint(window); + xserver_map_shell_surface(wm, window); +} + + +static void weston_wm_handle_client_message(struct weston_wm *wm, xcb_generic_event_t *event) { @@ -1305,6 +1364,8 @@ weston_wm_handle_client_message(struct weston_wm *wm, weston_wm_window_handle_moveresize(window, client_message); else if (client_message->type == wm->atom.net_wm_state) weston_wm_window_handle_state(window, client_message); + else if (client_message->type == wm->atom.wl_surface_id) + weston_wm_window_handle_window_id(window, client_message); } enum cursor_type { @@ -1777,7 +1838,8 @@ weston_wm_get_resources(struct weston_wm *wm) { "XdndStatus", F(atom.xdnd_status) }, { "XdndFinished", F(atom.xdnd_finished) }, { "XdndTypeList", F(atom.xdnd_type_list) }, - { "XdndActionCopy", F(atom.xdnd_action_copy) } + { "XdndActionCopy", F(atom.xdnd_action_copy) }, + { "WL_SURFACE_ID", F(atom.wl_surface_id) } }; #undef F @@ -1899,13 +1961,12 @@ weston_wm_create_wm_window(struct weston_wm *wm) } struct weston_wm * -weston_wm_create(struct weston_xserver *wxs) +weston_wm_create(struct weston_xserver *wxs, int fd) { struct weston_wm *wm; struct wl_event_loop *loop; xcb_screen_iterator_t s; uint32_t values[1]; - int sv[2]; xcb_atom_t supported[3]; wm = zalloc(sizeof *wm); @@ -1919,22 +1980,11 @@ weston_wm_create(struct weston_xserver *wxs) return NULL; } - if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) { - weston_log("socketpair failed\n"); - hash_table_destroy(wm->window_hash); - free(wm); - return NULL; - } - - xserver_send_client(wxs->resource, sv[1]); - wl_client_flush(wl_resource_get_client(wxs->resource)); - close(sv[1]); - /* xcb_connect_to_fd takes ownership of the fd. */ - wm->conn = xcb_connect_to_fd(sv[0], NULL); + wm->conn = xcb_connect_to_fd(fd, NULL); if (xcb_connection_has_error(wm->conn)) { weston_log("xcb_connect_to_fd failed\n"); - close(sv[0]); + close(fd); hash_table_destroy(wm->window_hash); free(wm); return NULL; @@ -1945,7 +1995,7 @@ weston_wm_create(struct weston_xserver *wxs) loop = wl_display_get_event_loop(wxs->wl_display); wm->source = - wl_event_loop_add_fd(loop, sv[0], + wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, weston_wm_handle_event, wm); wl_event_source_check(wm->source); @@ -1965,8 +2015,6 @@ weston_wm_create(struct weston_xserver *wxs) wm->theme = theme_create(); - weston_wm_create_wm_window(wm); - supported[0] = wm->atom.net_wm_moveresize; supported[1] = wm->atom.net_wm_state; supported[2] = wm->atom.net_wm_state_fullscreen; @@ -1997,7 +2045,11 @@ weston_wm_create(struct weston_xserver *wxs) weston_wm_create_cursors(wm); weston_wm_window_set_cursor(wm, wm->screen->root, XWM_CURSOR_LEFT_PTR); - weston_log("created wm\n"); + /* Create wm window and take WM_S0 selection last, which + * signals to Xwayland that we're done with setup. */ + weston_wm_create_wm_window(wm); + + weston_log("created wm, root %d\n", wm->screen->root); return wm; } @@ -2018,22 +2070,6 @@ weston_wm_destroy(struct weston_wm *wm) free(wm); } -static void -surface_destroy(struct wl_listener *listener, void *data) -{ - struct weston_wm_window *window = - container_of(listener, - struct weston_wm_window, surface_destroy_listener); - - wm_log("surface for xid %d destroyed\n", window->id); - - /* This should have been freed by the shell. - Don't try to use it later. */ - window->shsurf = NULL; - window->surface = NULL; - window->view = NULL; -} - static struct weston_wm_window * get_wm_window(struct weston_surface *surface) { @@ -2172,6 +2208,7 @@ legacy_fullscreen(struct weston_wm *wm, return 0; } + static void xserver_map_shell_surface(struct weston_wm *wm, struct weston_wm_window *window) @@ -2224,45 +2261,3 @@ xserver_map_shell_surface(struct weston_wm *wm, shell_interface->set_toplevel(window->shsurf); } } - -static void -xserver_set_window_id(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *surface_resource, uint32_t id) -{ - struct weston_xserver *wxs = wl_resource_get_user_data(resource); - struct weston_wm *wm = wxs->wm; - struct weston_surface *surface = - wl_resource_get_user_data(surface_resource); - struct weston_wm_window *window; - - if (client != wxs->client) - return; - - window = hash_table_lookup(wm->window_hash, id); - if (window == NULL) { - weston_log("set_window_id for unknown window %d\n", id); - return; - } - - wm_log("set_window_id %d for surface %p\n", id, surface); - - weston_wm_window_read_properties(window); - - /* A weston_wm_window may have many different surfaces assigned - * throughout its life, so we must make sure to remove the listener - * from the old surface signal list. */ - if (window->surface) - wl_list_remove(&window->surface_destroy_listener.link); - - window->surface = (struct weston_surface *) surface; - window->surface_destroy_listener.notify = surface_destroy; - wl_signal_add(&surface->destroy_signal, - &window->surface_destroy_listener); - - weston_wm_window_schedule_repaint(window); - xserver_map_shell_surface(wm, window); -} - -const struct xserver_interface xserver_implementation = { - xserver_set_window_id -}; diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h index c684cc51..963107a8 100644 --- a/xwayland/xwayland.h +++ b/xwayland/xwayland.h @@ -39,7 +39,9 @@ struct weston_xserver { struct wl_event_source *abstract_source; int unix_fd; struct wl_event_source *unix_source; + int wm_fd; int display; + struct wl_event_source *sigusr1_source; struct weston_process process; struct wl_resource *resource; struct wl_client *client; @@ -142,6 +144,7 @@ struct weston_wm { xcb_atom_t xdnd_finished; xcb_atom_t xdnd_type_list; xcb_atom_t xdnd_action_copy; + xcb_atom_t wl_surface_id; } atom; }; @@ -158,10 +161,8 @@ int weston_wm_handle_selection_event(struct weston_wm *wm, xcb_generic_event_t *event); -extern const struct xserver_interface xserver_implementation; - struct weston_wm * -weston_wm_create(struct weston_xserver *wxs); +weston_wm_create(struct weston_xserver *wxs, int fd); void weston_wm_destroy(struct weston_wm *wm); |