commit 2011cc741cc12b50f6d85529a898b378ae78bd8d
parent 390414c4377966c1ac051bfb049d7c24c1a99eff
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 2 Nov 2018 19:02:57 -0700
Remove xwayland support
I'm not using any X applications under swc anymore, so this code
is likely to become broken without anyone using it.
Diffstat:
10 files changed, 0 insertions(+), 974 deletions(-)
diff --git a/Makefile b/Makefile
@@ -35,14 +35,6 @@ PACKAGES := \
wld \
xkbcommon
-ifeq ($(ENABLE_XWAYLAND),1)
-PACKAGES += \
- xcb \
- xcb-composite \
- xcb-ewmh \
- xcb-icccm
-endif
-
ifeq ($(ENABLE_LIBUDEV),1)
PACKAGES += libudev
endif
diff --git a/README.md b/README.md
@@ -24,10 +24,6 @@ Dependencies
For input hotplugging, the following is also required:
* libudev
-For XWayland support, the following are also required:
-* libxcb
-* xcb-util-wm
-
Implementing a window manager using swc
---------------------------------------
You must implement two callback functions, `new_window` and `new_screen`, which
diff --git a/config.mk b/config.mk
@@ -17,5 +17,4 @@ ENABLE_DEBUG = 1
ENABLE_STATIC = 1
ENABLE_SHARED = 1
ENABLE_LIBUDEV = 1
-ENABLE_XWAYLAND = 1
diff --git a/libswc/internal.h b/libswc/internal.h
@@ -45,10 +45,6 @@ struct swc {
struct swc_compositor *const compositor;
struct swc_shm *const shm;
struct swc_drm *const drm;
-
-#ifdef ENABLE_XWAYLAND
- const struct swc_xserver *const xserver;
-#endif
};
extern struct swc swc;
diff --git a/libswc/local.mk b/libswc/local.mk
@@ -62,15 +62,6 @@ $(dir)_CFLAGS += -DENABLE_LIBUDEV
$(dir)_PACKAGES += libudev
endif
-ifeq ($(ENABLE_XWAYLAND),1)
-$(dir)_CFLAGS += -DENABLE_XWAYLAND
-$(dir)_PACKAGES += xcb xcb-composite xcb-ewmh xcb-icccm
-
-SWC_SOURCES += \
- libswc/xserver.c \
- libswc/xwm.c
-endif
-
SWC_STATIC_OBJECTS = $(SWC_SOURCES:%.c=%.o)
SWC_SHARED_OBJECTS = $(SWC_SOURCES:%.c=%.lo)
diff --git a/libswc/swc.c b/libswc/swc.c
@@ -40,9 +40,6 @@
#include "util.h"
#include "window.h"
#include "xdg_shell.h"
-#ifdef ENABLE_XWAYLAND
-# include "xserver.h"
-#endif
extern struct swc_launch swc_launch;
extern const struct swc_seat swc_seat;
@@ -50,9 +47,6 @@ extern const struct swc_bindings swc_bindings;
extern struct swc_compositor swc_compositor;
extern struct swc_drm swc_drm;
extern struct swc_shm swc_shm;
-#ifdef ENABLE_XWAYLAND
-extern struct swc_xserver swc_xserver;
-#endif
extern struct pointer_handler screens_pointer_handler;
@@ -62,9 +56,6 @@ struct swc swc = {
.compositor = &swc_compositor,
.drm = &swc_drm,
.shm = &swc_shm,
-#ifdef ENABLE_XWAYLAND
- .xserver = &swc_xserver,
-#endif
};
static void
@@ -179,21 +170,10 @@ swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop, con
goto error11;
}
-#ifdef ENABLE_XWAYLAND
- if (!xserver_initialize()) {
- ERROR("Could not initialize xwayland\n");
- goto error12;
- }
-#endif
-
setup_compositor();
return true;
-#ifdef ENABLE_XWAYLAND
-error12:
- panel_manager_finalize();
-#endif
error11:
xdg_shell_finalize();
error10:
@@ -223,9 +203,6 @@ error0:
EXPORT void
swc_finalize(void)
{
-#ifdef ENABLE_XWAYLAND
- xserver_finalize();
-#endif
panel_manager_finalize();
shell_finalize();
seat_finalize();
diff --git a/libswc/xserver.c b/libswc/xserver.c
@@ -1,319 +0,0 @@
-/* swc: libswc/xserver.c
- *
- * Copyright (c) 2013 Michael Forney
- *
- * Based in part upon xwayland/launcher.c from weston, which is
- *
- * Copyright © 2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "xserver.h"
-#include "internal.h"
-#include "util.h"
-#include "xwm.h"
-
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <wayland-server.h>
-
-#define LOCK_FMT "/tmp/.X%d-lock"
-#define SOCKET_DIR "/tmp/.X11-unix"
-#define SOCKET_FMT SOCKET_DIR "/X%d"
-
-static struct {
- struct wl_resource *resource;
- struct wl_event_source *usr1_source;
- int display;
- char display_name[16];
- int abstract_fd, unix_fd, wm_fd;
- bool xwm_initialized;
-} xserver;
-
-struct swc_xserver swc_xserver;
-
-static int
-open_socket(struct sockaddr_un *addr)
-{
- int fd;
-
- if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
- goto error0;
-
- /* Unlink the socket location in case it was being used by a process which
- * left around a stale lockfile. */
- unlink(addr->sun_path);
-
- if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0)
- goto error1;
-
- if (listen(fd, 1) < 0)
- goto error2;
-
- return fd;
-
-error2:
- if (addr->sun_path[0])
- unlink(addr->sun_path);
-error1:
- close(fd);
-error0:
- return -1;
-}
-
-static bool
-open_display(void)
-{
- char lock_name[64], pid[12];
- int lock_fd;
- struct sockaddr_un addr = {.sun_family = AF_LOCAL};
-
- xserver.display = 0;
-
- /* Create X lockfile and server sockets */
- goto begin;
-
-retry2:
- close(xserver.abstract_fd);
-retry1:
- unlink(lock_name);
-retry0:
- if (++xserver.display > 32) {
- ERROR("No open display in first 32\n");
- return false;
- }
-
-begin:
- snprintf(lock_name, sizeof(lock_name), LOCK_FMT, xserver.display);
- lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444);
-
- if (lock_fd == -1) {
- char *end;
- pid_t owner;
-
- /* Check if the owning process is still alive. */
- if ((lock_fd = open(lock_name, O_RDONLY)) == -1)
- goto retry0;
-
- if (read(lock_fd, pid, sizeof(pid) - 1) != sizeof(pid) - 1)
- goto retry0;
-
- owner = strtol(pid, &end, 10);
-
- if (end != pid + 10)
- goto retry0;
-
- if (kill(owner, 0) == 0 || errno != ESRCH)
- goto retry0;
-
- if (unlink(lock_name) != 0)
- goto retry0;
-
- goto begin;
- }
-
- snprintf(pid, sizeof(pid), "%10d\n", getpid());
- if (write(lock_fd, pid, sizeof(pid) - 1) != sizeof(pid) - 1) {
- ERROR("Failed to write PID file\n");
- unlink(lock_name);
- close(lock_fd);
- return false;
- }
-
- close(lock_fd);
-
- /* Bind to abstract socket */
- addr.sun_path[0] = '\0';
- snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1, SOCKET_FMT, xserver.display);
- if ((xserver.abstract_fd = open_socket(&addr)) < 0)
- goto retry1;
-
- /* Bind to unix socket */
- mkdir(SOCKET_DIR, 0777);
- snprintf(addr.sun_path, sizeof(addr.sun_path), SOCKET_FMT, xserver.display);
- if ((xserver.unix_fd = open_socket(&addr)) < 0)
- goto retry2;
-
- snprintf(xserver.display_name, sizeof(xserver.display_name), ":%d", xserver.display);
- setenv("DISPLAY", xserver.display_name, true);
-
- return true;
-}
-
-static void
-close_display(void)
-{
- char path[64];
-
- close(xserver.abstract_fd);
- close(xserver.unix_fd);
-
- snprintf(path, sizeof(path), SOCKET_FMT, xserver.display);
- unlink(path);
- snprintf(path, sizeof(path), LOCK_FMT, xserver.display);
- unlink(path);
-
- unsetenv("DISPLAY");
-}
-
-static int
-handle_usr1(int signal_number, void *data)
-{
- if (xwm_initialize(xserver.wm_fd)) {
- xserver.xwm_initialized = true;
- } else {
- ERROR("Failed to initialize X window manager\n");
- /* XXX: How do we handle this case? */
- }
-
- wl_event_source_remove(xserver.usr1_source);
-
- return 0;
-}
-
-static void
-handle_client_destroy(struct wl_listener *listener, void *data) {
- swc_xserver.client = NULL;
-}
-
-static struct wl_listener client_destroy_listener = {
- .notify = handle_client_destroy,
-};
-
-bool
-xserver_initialize(void)
-{
- int wl[2], wm[2];
-
- /* Open an X display */
- if (!open_display()) {
- ERROR("Failed to get X lockfile and sockets\n");
- goto error0;
- }
-
- xserver.usr1_source = wl_event_loop_add_signal(swc.event_loop, SIGUSR1, &handle_usr1, NULL);
-
- if (!xserver.usr1_source) {
- ERROR("Failed to create SIGUSR1 event source\n");
- goto error1;
- }
-
- /* Open a socket for the Wayland connection from Xwayland. */
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wl) != 0) {
- ERROR("Failed to create socketpair: %s\n", strerror(errno));
- goto error2;
- }
-
- /* Open a socket for the X connection to Xwayland. */
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) != 0) {
- ERROR("Failed to create socketpair: %s\n", strerror(errno));
- goto error3;
- }
-
- if (!(swc_xserver.client = wl_client_create(swc.display, wl[0])))
- goto error4;
-
- wl_client_add_destroy_listener(swc_xserver.client, &client_destroy_listener);
- xserver.wm_fd = wm[0];
-
- /* Start the X server */
- switch (fork()) {
- case 0: {
- int fds[] = { wl[1], wm[1], xserver.abstract_fd, xserver.unix_fd };
- char strings[ARRAY_LENGTH(fds)][16];
- unsigned index;
- struct sigaction action = {.sa_handler = SIG_IGN };
-
- /* Unset the FD_CLOEXEC flag on the FDs that will get passed to Xwayland. */
- for (index = 0; index < ARRAY_LENGTH(fds); ++index) {
- if (fcntl(fds[index], F_SETFD, 0) != 0) {
- ERROR("fcntl() failed: %s\n", strerror(errno));
- goto fail;
- }
-
- if (snprintf(strings[index], sizeof(strings[index]), "%d", fds[index]) >= sizeof(strings[index])) {
- ERROR("FD is too large\n");
- goto fail;
- }
- }
-
- /* Ignore the USR1 signal so that Xwayland will send a USR1 signal to the
- * parent process (us) after it finishes initializing. See Xserver(1) for
- * more details. */
- if (sigaction(SIGUSR1, &action, NULL) != 0) {
- ERROR("Failed to set SIGUSR1 handler to SIG_IGN: %s\n", strerror(errno));
- goto fail;
- }
-
- setenv("WAYLAND_SOCKET", strings[0], true);
- execlp("Xwayland", "Xwayland",
- xserver.display_name,
- "-rootless",
- "-terminate",
- "-listen", strings[2],
- "-listen", strings[3],
- "-wm", strings[1],
- NULL);
-
- fail:
- exit(EXIT_FAILURE);
- }
- case -1:
- ERROR("fork() failed when trying to start X server: %s\n", strerror(errno));
- goto error5;
- }
-
- close(wl[1]);
- close(wm[1]);
-
- return true;
-
-error5:
- wl_client_destroy(swc_xserver.client);
-error4:
- close(wm[1]);
- close(wm[0]);
-error3:
- close(wl[1]);
- close(wl[0]);
-error2:
- wl_event_source_remove(xserver.usr1_source);
-error1:
- close_display();
-error0:
- return false;
-}
-
-void
-xserver_finalize(void)
-{
- if (xserver.xwm_initialized)
- xwm_finalize();
- if (swc_xserver.client)
- wl_client_destroy(swc_xserver.client);
- close_display();
-}
diff --git a/libswc/xserver.h b/libswc/xserver.h
@@ -1,36 +0,0 @@
-/* swc: libswc/xserver.h
- *
- * Copyright (c) 2013, 2014 Michael Forney
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef SWC_XSERVER_H
-#define SWC_XSERVER_H
-
-#include <stdbool.h>
-
-struct swc_xserver {
- struct wl_client *client;
-};
-
-bool xserver_initialize(void);
-void xserver_finalize(void);
-
-#endif
diff --git a/libswc/xwm.c b/libswc/xwm.c
@@ -1,538 +0,0 @@
-/* swc: libswc/xwm.c
- *
- * Copyright (c) 2013, 2014 Michael Forney
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "xwm.h"
-#include "compositor.h"
-#include "internal.h"
-#include "surface.h"
-#include "swc.h"
-#include "util.h"
-#include "view.h"
-#include "window.h"
-#include "xserver.h"
-
-#include <stdio.h>
-#include <xcb/composite.h>
-#include <xcb/xcb_ewmh.h>
-#include <xcb/xcb_icccm.h>
-
-struct xwl_window {
- xcb_window_t id;
- uint32_t surface_id;
- bool override_redirect, supports_delete;
- struct wl_list link;
-
- /* Only used for paired windows. */
- struct {
- struct window window;
- struct wl_listener surface_destroy_listener;
- };
-};
-
-enum atom {
- ATOM_WL_SURFACE_ID,
- ATOM_WM_DELETE_WINDOW,
- ATOM_WM_PROTOCOLS,
- ATOM_WM_S0,
-};
-
-static struct {
- xcb_connection_t *connection;
- xcb_ewmh_connection_t ewmh;
- xcb_screen_t *screen;
- xcb_window_t window;
- struct xwl_window *focus;
- struct wl_event_source *source;
- struct wl_list windows, unpaired_windows;
- union {
- const char *name;
- xcb_intern_atom_cookie_t cookie;
- xcb_atom_t value;
- } atoms[4];
-} xwm = {
- .atoms = {
- [ATOM_WL_SURFACE_ID] = "WL_SURFACE_ID",
- [ATOM_WM_DELETE_WINDOW] = "WM_DELETE_WINDOW",
- [ATOM_WM_PROTOCOLS] = "WM_PROTOCOLS",
- [ATOM_WM_S0] = "WM_S0",
- }
-};
-
-static void
-update_name(struct xwl_window *xwl_window)
-{
- xcb_get_property_cookie_t wm_name_cookie;
- xcb_ewmh_get_utf8_strings_reply_t wm_name_reply;
-
- wm_name_cookie = xcb_ewmh_get_wm_name(&xwm.ewmh, xwl_window->id);
-
- if (xcb_ewmh_get_wm_name_reply(&xwm.ewmh, wm_name_cookie, &wm_name_reply, NULL)) {
- window_set_title(&xwl_window->window, wm_name_reply.strings, wm_name_reply.strings_len);
- xcb_ewmh_get_utf8_strings_reply_wipe(&wm_name_reply);
- } else {
- window_set_title(&xwl_window->window, NULL, 0);
- }
-}
-
-static void
-update_protocols(struct xwl_window *xwl_window)
-{
- xcb_get_property_cookie_t cookie;
- xcb_icccm_get_wm_protocols_reply_t reply;
- unsigned index;
-
- cookie = xcb_icccm_get_wm_protocols(xwm.connection, xwl_window->id, xwm.atoms[ATOM_WM_PROTOCOLS].value);
- xwl_window->supports_delete = true;
-
- if (!xcb_icccm_get_wm_protocols_reply(xwm.connection, cookie, &reply, NULL))
- return;
-
- for (index = 0; index < reply.atoms_len; ++index) {
- if (reply.atoms[index] == xwm.atoms[ATOM_WM_DELETE_WINDOW].value)
- xwl_window->supports_delete = true;
- }
-
- xcb_icccm_get_wm_protocols_reply_wipe(&reply);
-}
-
-static struct xwl_window *
-find_window(struct wl_list *list, xcb_window_t id)
-{
- struct xwl_window *window;
-
- wl_list_for_each (window, list, link) {
- if (window->id == id)
- return window;
- }
-
- return NULL;
-}
-
-static struct xwl_window *
-find_window_by_surface_id(struct wl_list *list, uint32_t id)
-{
- struct xwl_window *window;
-
- wl_list_for_each (window, list, link) {
- if (window->surface_id == id)
- return window;
- }
-
- return NULL;
-}
-
-static void
-move(struct window *window, int32_t x, int32_t y)
-{
- uint32_t mask, values[2];
- struct xwl_window *xwl_window = wl_container_of(window, xwl_window, window);
-
- mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
- values[0] = x;
- values[1] = y;
-
- xcb_configure_window(xwm.connection, xwl_window->id, mask, values);
- xcb_flush(xwm.connection);
-}
-
-static void
-configure(struct window *window, uint32_t width, uint32_t height)
-{
- uint32_t mask, values[2];
- struct xwl_window *xwl_window = wl_container_of(window, xwl_window, window);
-
- mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
- values[0] = width;
- values[1] = height;
-
- window->configure.acknowledged = true;
- xcb_configure_window(xwm.connection, xwl_window->id, mask, values);
- xcb_flush(xwm.connection);
-}
-
-static void
-focus(struct window *window)
-{
- struct xwl_window *xwl_window = wl_container_of(window, xwl_window, window);
-
- xcb_set_input_focus(xwm.connection, XCB_INPUT_FOCUS_NONE, xwl_window->id, XCB_CURRENT_TIME);
- xcb_flush(xwm.connection);
- xwm.focus = xwl_window;
-}
-
-static void
-unfocus(struct window *window)
-{
- struct xwl_window *xwl_window = wl_container_of(window, xwl_window, window);
-
- /* If the window we are unfocusing is the latest xwl_window to be focused, we
- * know we have transitioned to some other window type, so the X11 focus can
- * be set to XCB_NONE. Otherwise, we have transitioned to another X11 window,
- * and the X11 focus has already been updated. */
- if (xwl_window == xwm.focus) {
- xcb_set_input_focus(xwm.connection, XCB_INPUT_FOCUS_NONE, XCB_NONE, XCB_CURRENT_TIME);
- xcb_flush(xwm.connection);
- }
-}
-
-static void
-close(struct window *window)
-{
- struct xwl_window *xwl_window = wl_container_of(window, xwl_window, window);
-
- if (xwl_window->supports_delete) {
- xcb_client_message_event_t event = {
- .response_type = XCB_CLIENT_MESSAGE,
- .format = 32,
- .window = xwl_window->id,
- .type = xwm.atoms[ATOM_WM_PROTOCOLS].value,
- .data.data32 = {
- xwm.atoms[ATOM_WM_DELETE_WINDOW].value,
- XCB_CURRENT_TIME,
- },
- };
-
- xcb_send_event(xwm.connection, false, xwl_window->id, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
- } else {
- xcb_kill_client(xwm.connection, xwl_window->id);
- }
-
- xcb_flush(xwm.connection);
-}
-
-static const struct window_impl xwl_window_handler = {
- .move = move,
- .configure = configure,
- .focus = focus,
- .unfocus = unfocus,
- .close = close,
-};
-
-static void
-handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct xwl_window *xwl_window = wl_container_of(listener, xwl_window, surface_destroy_listener);
-
- if (xwm.focus == xwl_window)
- xwm.focus = NULL;
-
- window_finalize(&xwl_window->window);
- wl_list_remove(&xwl_window->link);
- wl_list_insert(&xwm.unpaired_windows, &xwl_window->link);
- xwl_window->surface_id = 0;
-}
-
-static bool
-manage_window(struct xwl_window *xwl_window)
-{
- struct wl_resource *resource;
- struct surface *surface;
- xcb_get_geometry_cookie_t geometry_cookie;
- xcb_get_geometry_reply_t *geometry_reply;
-
- resource = wl_client_get_object(swc.xserver->client, xwl_window->surface_id);
-
- if (!resource)
- return false;
-
- surface = wl_resource_get_user_data(resource);
- geometry_cookie = xcb_get_geometry(xwm.connection, xwl_window->id);
-
- window_initialize(&xwl_window->window, &xwl_window_handler, surface);
- xwl_window->surface_destroy_listener.notify = &handle_surface_destroy;
- wl_resource_add_destroy_listener(surface->resource, &xwl_window->surface_destroy_listener);
-
- if ((geometry_reply = xcb_get_geometry_reply(xwm.connection, geometry_cookie, NULL))) {
- view_move(surface->view, geometry_reply->x, geometry_reply->y);
- free(geometry_reply);
- }
-
- if (xwl_window->override_redirect) {
- compositor_view_show(xwl_window->window.view);
- } else {
- uint32_t mask, values[1];
-
- mask = XCB_CW_EVENT_MASK;
- values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
- xcb_change_window_attributes(xwm.connection, xwl_window->id, mask, values);
- mask = XCB_CONFIG_WINDOW_BORDER_WIDTH;
- values[0] = 0;
- xcb_configure_window(xwm.connection, xwl_window->id, mask, values);
- update_name(xwl_window);
- update_protocols(xwl_window);
- window_manage(&xwl_window->window);
- }
-
- wl_list_remove(&xwl_window->link);
- wl_list_insert(&xwm.windows, &xwl_window->link);
-
- return true;
-}
-
-static void
-handle_new_surface(struct wl_listener *listener, void *data)
-{
- struct surface *surface = data;
- struct xwl_window *window;
-
- window = find_window_by_surface_id(&xwm.unpaired_windows, wl_resource_get_id(surface->resource));
-
- if (!window)
- return;
-
- manage_window(window);
-}
-
-static struct wl_listener new_surface_listener = {
- .notify = &handle_new_surface
-};
-
-/* X event handlers */
-static void
-create_notify(xcb_create_notify_event_t *event)
-{
- struct xwl_window *xwl_window;
-
- if (!(xwl_window = malloc(sizeof *xwl_window)))
- return;
-
- xwl_window->id = event->window;
- xwl_window->surface_id = 0;
- xwl_window->override_redirect = event->override_redirect;
- wl_list_insert(&xwm.unpaired_windows, &xwl_window->link);
-}
-
-static void
-destroy_notify(xcb_destroy_notify_event_t *event)
-{
- struct xwl_window *xwl_window;
-
- if ((xwl_window = find_window(&xwm.windows, event->window))) {
- wl_list_remove(&xwl_window->surface_destroy_listener.link);
- window_finalize(&xwl_window->window);
- } else if (!(xwl_window = find_window(&xwm.unpaired_windows, event->window))) {
- return;
- }
-
- wl_list_remove(&xwl_window->link);
- free(xwl_window);
-}
-
-static void
-map_request(xcb_map_request_event_t *event)
-{
- xcb_map_window(xwm.connection, event->window);
-}
-
-static void
-configure_request(xcb_configure_request_event_t *event)
-{
-}
-
-static void
-property_notify(xcb_property_notify_event_t *event)
-{
- struct xwl_window *xwl_window;
-
- if (!(xwl_window = find_window(&xwm.windows, event->window)))
- return;
-
- if (event->atom == xwm.ewmh._NET_WM_NAME && event->state == XCB_PROPERTY_NEW_VALUE)
- update_name(xwl_window);
- else if (event->atom == xwm.atoms[ATOM_WM_PROTOCOLS].value)
- update_protocols(xwl_window);
-}
-
-static void
-client_message(xcb_client_message_event_t *event)
-{
- if (event->type == xwm.atoms[ATOM_WL_SURFACE_ID].value) {
- struct xwl_window *xwl_window;
-
- if (!(xwl_window = find_window(&xwm.unpaired_windows, event->window)))
- return;
-
- xwl_window->surface_id = event->data.data32[0];
- manage_window(xwl_window);
- }
-}
-
-static int
-connection_data(int fd, uint32_t mask, void *data)
-{
- xcb_generic_event_t *event;
- uint32_t count = 0;
-
- while ((event = xcb_poll_for_event(xwm.connection))) {
- switch (event->response_type & ~0x80) {
- case XCB_CREATE_NOTIFY:
- create_notify((xcb_create_notify_event_t *)event);
- break;
- case XCB_DESTROY_NOTIFY:
- destroy_notify((xcb_destroy_notify_event_t *)event);
- break;
- case XCB_MAP_REQUEST:
- map_request((xcb_map_request_event_t *)event);
- break;
- case XCB_CONFIGURE_REQUEST:
- configure_request((xcb_configure_request_event_t *)event);
- break;
- case XCB_PROPERTY_NOTIFY:
- property_notify((xcb_property_notify_event_t *)event);
- break;
- case XCB_CLIENT_MESSAGE:
- client_message((xcb_client_message_event_t *)event);
- break;
- }
-
- free(event);
- ++count;
- }
-
- xcb_flush(xwm.connection);
-
- return count;
-}
-
-bool
-xwm_initialize(int fd)
-{
- const xcb_setup_t *setup;
- xcb_screen_iterator_t screen_iterator;
- uint32_t mask;
- uint32_t values[1];
- xcb_void_cookie_t change_attributes_cookie, redirect_subwindows_cookie;
- xcb_generic_error_t *error;
- xcb_intern_atom_cookie_t *ewmh_cookies;
- xcb_intern_atom_reply_t *atom_reply;
- unsigned index;
- const char *name;
- const xcb_query_extension_reply_t *composite_extension;
-
- xwm.connection = xcb_connect_to_fd(fd, NULL);
-
- if (xcb_connection_has_error(xwm.connection)) {
- ERROR("xwm: Could not connect to X server\n");
- goto error0;
- }
-
- xcb_prefetch_extension_data(xwm.connection, &xcb_composite_id);
- ewmh_cookies = xcb_ewmh_init_atoms(xwm.connection, &xwm.ewmh);
-
- if (!ewmh_cookies) {
- ERROR("xwm: Failed to initialize EWMH atoms\n");
- goto error1;
- }
-
- for (index = 0; index < ARRAY_LENGTH(xwm.atoms); ++index) {
- name = xwm.atoms[index].name;
- xwm.atoms[index].cookie = xcb_intern_atom(xwm.connection, 0, strlen(name), name);
- }
-
- setup = xcb_get_setup(xwm.connection);
- screen_iterator = xcb_setup_roots_iterator(setup);
- xwm.screen = screen_iterator.data;
-
- /* Try to select for substructure redirect. */
- mask = XCB_CW_EVENT_MASK;
- values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
- change_attributes_cookie = xcb_change_window_attributes(xwm.connection, xwm.screen->root, mask, values);
-
- xwm.source = wl_event_loop_add_fd(swc.event_loop, fd, WL_EVENT_READABLE, &connection_data, NULL);
- wl_list_init(&xwm.windows);
- wl_list_init(&xwm.unpaired_windows);
-
- if (!xwm.source) {
- ERROR("xwm: Failed to create X connection event source\n");
- goto error2;
- }
-
- composite_extension = xcb_get_extension_data(xwm.connection, &xcb_composite_id);
-
- if (!composite_extension->present) {
- ERROR("xwm: X server does not have composite extension\n");
- goto error3;
- }
-
- redirect_subwindows_cookie = xcb_composite_redirect_subwindows_checked(xwm.connection, xwm.screen->root, XCB_COMPOSITE_REDIRECT_MANUAL);
-
- if ((error = xcb_request_check(xwm.connection, change_attributes_cookie))) {
- ERROR("xwm: Another window manager is running\n");
- free(error);
- goto error3;
- }
-
- if ((error = xcb_request_check(xwm.connection, redirect_subwindows_cookie))) {
- ERROR("xwm: Could not redirect subwindows of root for compositing\n");
- free(error);
- goto error3;
- }
-
- xwm.window = xcb_generate_id(xwm.connection);
- xcb_create_window(xwm.connection, 0, xwm.window, xwm.screen->root,
- 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- XCB_COPY_FROM_PARENT, 0, NULL);
-
- xcb_ewmh_init_atoms_replies(&xwm.ewmh, ewmh_cookies, &error);
-
- if (error) {
- ERROR("xwm: Failed to get EWMH atom replies: %u\n", error->error_code);
- goto error3;
- }
-
- for (index = 0; index < ARRAY_LENGTH(xwm.atoms); ++index) {
- atom_reply = xcb_intern_atom_reply(xwm.connection, xwm.atoms[index].cookie, &error);
-
- if (error) {
- ERROR("xwm: Failed to get atom reply: %u\n", error->error_code);
- return false;
- }
-
- xwm.atoms[index].value = atom_reply->atom;
- free(atom_reply);
- }
-
- xcb_set_selection_owner(xwm.connection, xwm.window, xwm.atoms[ATOM_WM_S0].value, XCB_CURRENT_TIME);
- xcb_flush(xwm.connection);
-
- wl_signal_add(&swc.compositor->signal.new_surface, &new_surface_listener);
-
- return true;
-
-error3:
- wl_event_source_remove(xwm.source);
-error2:
- xcb_ewmh_connection_wipe(&xwm.ewmh);
-error1:
- xcb_disconnect(xwm.connection);
-error0:
- return false;
-}
-
-void
-xwm_finalize(void)
-{
- wl_event_source_remove(xwm.source);
- xcb_ewmh_connection_wipe(&xwm.ewmh);
- xcb_disconnect(xwm.connection);
-}
diff --git a/libswc/xwm.h b/libswc/xwm.h
@@ -1,32 +0,0 @@
-/* swc: libswc/xwm.h
- *
- * Copyright (c) 2013 Michael Forney
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef SWC_XWM_H
-#define SWC_XWM_H
-
-#include <stdbool.h>
-
-bool xwm_initialize(int fd);
-void xwm_finalize(void);
-
-#endif