diff options
author | Dominique Martinet <asmadeus@codewreck.org> | 2017-08-19 21:25:26 +0200 |
---|---|---|
committer | Dominique Martinet <asmadeus@codewreck.org> | 2017-08-23 22:03:49 +0200 |
commit | b2bab1af5c34b785a9b08db04af1330e61dd210c (patch) | |
tree | b898d84f0d9ab9ed4bf1243f93b481f2ff8a12d0 /xwayland | |
parent | 60451521bd6bd7d03255a206e35b0f88d5328311 (diff) |
xwayland: split xwm structure out, initial xwm.c
Diffstat (limited to 'xwayland')
-rw-r--r-- | xwayland/meson.build | 4 | ||||
-rw-r--r-- | xwayland/xwayland.c | 18 | ||||
-rw-r--r-- | xwayland/xwm.c | 69 |
3 files changed, 88 insertions, 3 deletions
diff --git a/xwayland/meson.build b/xwayland/meson.build index d43ace9b..6f75e23a 100644 --- a/xwayland/meson.build +++ b/xwayland/meson.build @@ -1,5 +1,7 @@ lib_wlr_xwayland = static_library('wlr_xwayland', files( 'sockets.c', 'xwayland.c', + 'xwm.c', ), - include_directories: wlr_inc) + include_directories: wlr_inc, + dependencies: [wayland_server, xcb, pixman]) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 49173ace..e9bdfcc5 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -76,6 +76,8 @@ static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) { wlr_xwayland->display, wlr_xwayland->x_fd[0], wlr_xwayland->x_fd[1], wlr_xwayland->wm_fd[1]); + // TODO: close stdout/err depending on log level + execvpe("Xwayland", argv, envp); } @@ -88,7 +90,8 @@ static void xwayland_destroy_event(struct wl_listener *listener, void *data) { wlr_xwayland_finish(wlr_xwayland); if (wlr_xwayland->server_start - time(NULL) > 5) { - wlr_xwayland_init(wlr_xwayland, wlr_xwayland->wl_display); + wlr_xwayland_init(wlr_xwayland, wlr_xwayland->wl_display, + wlr_xwayland->compositor); } } @@ -103,6 +106,8 @@ void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) { wl_client_destroy(wlr_xwayland->client); } + xwm_destroy(wlr_xwayland->xwm); + safe_close(wlr_xwayland->x_fd[0]); safe_close(wlr_xwayland->x_fd[1]); safe_close(wlr_xwayland->wl_fd[0]); @@ -116,8 +121,10 @@ void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) { } bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, - struct wl_display *wl_display) { + struct wl_display *wl_display, struct wlr_compositor *compositor) { + memset(wlr_xwayland, 0, sizeof(struct wlr_xwayland)); wlr_xwayland->wl_display = wl_display; + wlr_xwayland->compositor = compositor; wlr_xwayland->x_fd[0] = wlr_xwayland->x_fd[1] = -1; wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; @@ -162,9 +169,16 @@ bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, if (!(wlr_xwayland->client = wl_client_create(wl_display, wlr_xwayland->wl_fd[0]))) { wlr_log_errno(L_ERROR, "wl_client_create failed"); wlr_xwayland_finish(wlr_xwayland); + return false; } wl_client_add_destroy_listener(wlr_xwayland->client, &xwayland_destroy_listener); + wlr_xwayland->xwm = xwm_create(wlr_xwayland); + if (!wlr_xwayland->xwm) { + wlr_xwayland_finish(wlr_xwayland); + return false; + } + return true; } diff --git a/xwayland/xwm.c b/xwayland/xwm.c new file mode 100644 index 00000000..d39527c5 --- /dev/null +++ b/xwayland/xwm.c @@ -0,0 +1,69 @@ +#include <stdlib.h> +#include "wlr/util/log.h" +#include "wlr/types/wlr_surface.h" +#include "wlr/xwayland.h" +#include "xwayland/internals.h" + +#define SEND_EVENT_MASK 0x80 +static int x11_event_handler(int fd, uint32_t mask, void *data) { + int count = 0; + xcb_generic_event_t *event; + struct wlr_xwayland *wlr_xwayland = data; + struct wlr_xwm *xwm = wlr_xwayland->xwm; + + while ((event = xcb_poll_for_event(xwm->xcb_connection))) { + wlr_log(L_DEBUG, "X11 event: %d", event->response_type & ~SEND_EVENT_MASK); + count++; + // TODO: actually do stuff! + } + return count; +} + +static void create_surface_handler(struct wl_listener *listener, void *data) +{ + struct wlr_surface *surface = data; + struct wlr_xwm *xwm = wl_container_of(listener, xwm, surface_listener); + + if (wl_resource_get_client(surface->resource) != xwm->xwayland->client) { + return; + } + + wlr_log(L_DEBUG, "new x11 surface: %p", surface); + + // TODO: look for unpaired window, and assign +} + +void xwm_destroy(struct wlr_xwm *xwm) { + if (xwm->event_source) { + wl_event_source_remove(xwm->event_source); + } + + free(xwm); +} + +struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { + struct wlr_xwm *xwm = calloc(1, sizeof(struct wlr_xwm)); + + xwm->xwayland = wlr_xwayland; + + xwm->xcb_connection = xcb_connect_to_fd(wlr_xwayland->wm_fd[0], NULL); + if (xcb_connection_has_error(xwm->xcb_connection)) { + return NULL; + } + + // TODO more xcb init + // xcb_prefetch_extension_data(xwm->xcb_connection, &xcb_composite_id); + + struct wl_event_loop *event_loop = wl_display_get_event_loop(wlr_xwayland->wl_display); + xwm->event_source = wl_event_loop_add_fd(event_loop, wlr_xwayland->wm_fd[0], + WL_EVENT_READABLE, x11_event_handler, wlr_xwayland); + // probably not needed + // wl_event_source_check(xwm->event_source); + + + xwm->surface_listener.notify = create_surface_handler; + //wl_signal_add(&wlr_xwayland->compositor->create_surface_signal, + // &xwm->surface_listener); + + return xwm; +} |