swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 28dcc02fff6729df6a593bf92fc9ffd66019fa59
parent 4ab4400c59c1166c996a23f019f9b535cc8954e0
Author: Michael Forney <mforney@mforney.org>
Date:   Mon, 25 Nov 2013 18:54:43 -0800

Initial xwayland support

Diffstat:
Mconfig.mk | 1+
Mlibswc/Makefile.local | 14++++++++++++++
Mlibswc/swc.c | 16++++++++++++++++
Alibswc/xserver.c | 293+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/xserver.h | 33+++++++++++++++++++++++++++++++++
Alibswc/xwm.c | 361+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibswc/xwm.h | 38++++++++++++++++++++++++++++++++++++++
Mprotocol/Makefile.local | 5+++--
Aprotocol/xserver.xml | 18++++++++++++++++++
9 files changed, 777 insertions(+), 2 deletions(-)

diff --git a/config.mk b/config.mk @@ -14,4 +14,5 @@ WAYLAND_SCANNER ?= wayland-scanner ENABLE_STATIC = 1 ENABLE_SHARED = 1 +ENABLE_XWAYLAND = 1 diff --git a/libswc/Makefile.local b/libswc/Makefile.local @@ -61,12 +61,26 @@ SWC_SOURCES += \ libswc/shell_surface.c \ libswc/bindings.c +ifeq ($(ENABLE_XWAYLAND),1) +$(dir)_CFLAGS += -DENABLE_XWAYLAND +$(dir)_PACKAGES += \ + xcb \ + xcb-composite \ + xcb-ewmh + +SWC_SOURCES += \ + libswc/xserver.c \ + libswc/xwm.c \ + protocol/xserver-protocol.c +endif + SWC_STATIC_OBJECTS = $(SWC_SOURCES:%.c=%.o) SWC_SHARED_OBJECTS = $(SWC_SOURCES:%.c=%.lo) # Explicitly state dependencies on generated files objects = $(foreach obj,$(1),$(dir)/$(obj).o $(dir)/$(obj.lo)) $(call objects,drm drm_buffer): protocol/wayland-drm-server-protocol.h +$(call objects,xserver): protocol/xserver-server-protocol.h $(dir)/libswc.a: $(SWC_STATIC_OBJECTS) $(call quiet,AR) cru $@ $^ diff --git a/libswc/swc.c b/libswc/swc.c @@ -30,6 +30,9 @@ #include "seat.h" #include "shell.h" #include "window.h" +#ifdef ENABLE_XWAYLAND +# include "xserver.h" +#endif #include <libudev.h> @@ -94,10 +97,20 @@ bool swc_initialize(struct wl_display * display, goto error4; } +#ifdef ENABLE_XWAYLAND + if (!swc_xserver_initialize()) + { + fprintf(stderr, "Could not initialize xwayland\n"); + goto error5; + } +#endif + setup_compositor(); return true; + error5: + swc_shell_finalize(); error4: swc_compositor_finish(&compositor); error3: @@ -113,6 +126,9 @@ bool swc_initialize(struct wl_display * display, EXPORT void swc_finalize() { +#ifdef ENABLE_XWAYLAND + swc_xserver_finalize(); +#endif swc_shell_finalize(); swc_compositor_finish(&compositor); swc_bindings_finalize(); diff --git a/libswc/xserver.c b/libswc/xserver.c @@ -0,0 +1,293 @@ +/* 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 <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> +#include "protocol/xserver-server-protocol.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_global * global; + struct wl_client * client; + struct wl_resource * resource; + int display; + char display_name[16]; + int abstract_socket, unix_socket; +} xserver; + +static char * xserver_command[] = { + "X", "-wayland", "-rootless", "-nolisten", "all", xserver.display_name, NULL +}; + +static void set_window_id(struct wl_client * client, + struct wl_resource * resource, + struct wl_resource * surface_resource, uint32_t id) +{ + struct swc_surface * surface = wl_resource_get_user_data(surface_resource); + + swc_xwm_manage_window(id, surface); +} + +const static struct xserver_interface xserver_implementation = { + .set_window_id = &set_window_id +}; + +static int open_socket(struct sockaddr_un * addr, size_t path_size) +{ + int fd; + socklen_t size = OFFSET_OF(typeof(*addr), sun_path) + path_size + 1; + + if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) + goto error0; + + if (bind(fd, (struct sockaddr *) addr, size) < 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() +{ + char lock_name[64], pid[12]; + int lock_fd; + struct sockaddr_un addr = { .sun_family = AF_LOCAL }; + size_t path_size; + + xserver.display = 0; + + /* Create X lockfile and server sockets */ + goto begin; + + retry2: + close(xserver.abstract_socket); + 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); + + /* XXX: Stale lockfile handling? */ + if (lock_fd < 0) + goto retry0; + + snprintf(pid, sizeof pid, "%10d\n", getpid()); + if (write(lock_fd, pid, sizeof pid) != sizeof pid) + { + 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'; + path_size = snprintf(addr.sun_path + 1, sizeof addr.sun_path - 1, + SOCKET_FMT, xserver.display); + if ((xserver.abstract_socket = open_socket(&addr, path_size)) < 0) + goto retry1; + + /* Bind to unix socket */ + mkdir(SOCKET_DIR, 0777); + path_size = snprintf(addr.sun_path, sizeof addr.sun_path, + SOCKET_FMT, xserver.display); + if ((xserver.unix_socket = open_socket(&addr, path_size)) < 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() +{ + char path[64]; + + close(xserver.abstract_socket); + close(xserver.unix_socket); + + snprintf(path, sizeof path, SOCKET_FMT, xserver.display); + unlink(path); + snprintf(path, sizeof path, LOCK_FMT, xserver.display); + unlink(path); + + unsetenv("DISPLAY"); +} + +static void bind_xserver(struct wl_client * client, void * data, + uint32_t version, uint32_t id) +{ + int sv[2]; + + if (client != xserver.client) + return; + + if (version >= 1) + version = 1; + + DEBUG("Binding X server\n"); + + xserver.resource = wl_resource_create(client, &xserver_interface, + version, id); + wl_resource_set_implementation(xserver.resource, &xserver_implementation, + NULL, NULL); + + /* Start the X window manager */ + socketpair(AF_UNIX, SOCK_STREAM, 0, sv); + xserver_send_client(xserver.resource, sv[1]); + close(sv[1]); + + /* Need to flush the xserver client so the X window manager can connect to + * it's socket. */ + wl_client_flush(xserver.client); + swc_xwm_initialize(sv[0]); + + xserver_send_listen_socket(xserver.resource, xserver.abstract_socket); + xserver_send_listen_socket(xserver.resource, xserver.unix_socket); +} + +static bool start_xserver() +{ + int sv[2]; + + /* Open an X display */ + if (!open_display()) + { + ERROR("Failed to get X lockfile and sockets\n"); + goto error0; + } + + /* Start the X server */ + if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) == -1) + { + ERROR("Failed to create socketpair: %s\n", strerror(errno)); + goto error1; + } + + if (!(xserver.client = wl_client_create(swc.display, sv[0]))) + goto error2; + + switch (fork()) + { + case 0: + { + int socket_fd; + char socket_string[32]; + + if (!(socket_fd = dup(sv[1]))) + exit(EXIT_FAILURE); + + snprintf(socket_string, sizeof socket_string, "%d", socket_fd); + setenv("WAYLAND_SOCKET", socket_string, true); + + execvp(xserver_command[0], xserver_command); + exit(EXIT_FAILURE); + + break; + } + case -1: + ERROR("fork() failed when trying to start X server: %s\n", + strerror(errno)); + goto error2; + } + + close(sv[1]); + + return true; + + error2: + close(sv[1]); + close(sv[0]); + error1: + close_display(); + error0: + return false; +} + +bool swc_xserver_initialize() +{ + xserver.global = wl_global_create(swc.display, &xserver_interface, 1, + NULL, &bind_xserver); + + if (!xserver.global) + goto error0; + + if (!start_xserver()) + goto error1; + + return true; + + error1: + wl_global_destroy(xserver.global); + error0: + return false; +} + +void swc_xserver_finalize() +{ + swc_xwm_finalize(); + close_display(); + wl_global_destroy(xserver.global); +} + diff --git a/libswc/xserver.h b/libswc/xserver.h @@ -0,0 +1,33 @@ +/* swc: libswc/xserver.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_XSERVER_H +#define SWC_XSERVER_H + +#include <stdbool.h> + +bool swc_xserver_initialize(); +void swc_xserver_finalize(); + +#endif + diff --git a/libswc/xwm.c b/libswc/xwm.c @@ -0,0 +1,361 @@ +/* swc: libswc/xwm.c + * + * 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. + */ + +#include "xwm.h" +#include "compositor_surface.h" +#include "internal.h" +#include "surface.h" +#include "swc.h" +#include "util.h" +#include "window.h" + +#include <stdio.h> +#include <xcb/composite.h> +#include <xcb/xcb_ewmh.h> + +struct xwl_window +{ + xcb_window_t id; + struct swc_window_internal window; + struct wl_listener surface_destroy_listener; +}; + +struct xwl_window_entry +{ + xcb_window_t id; + bool override_redirect; + struct xwl_window * xwl_window; +}; + +static struct +{ + xcb_connection_t * connection; + xcb_ewmh_connection_t ewmh; + xcb_screen_t * screen; + struct wl_event_source * source; + struct wl_array windows; +} xwm; + +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); + xcb_ewmh_get_wm_name_reply(&xwm.ewmh, wm_name_cookie, + &wm_name_reply, NULL); + + swc_window_set_title(&xwl_window->window.base, + wm_name_reply.strings, wm_name_reply.strings_len); +} + +static struct xwl_window_entry * find_window(xcb_window_t id) +{ + struct xwl_window_entry * entry; + + wl_array_for_each(entry, &xwm.windows) + { + if (entry->id == id) + return entry; + } + + return NULL; +} + +/* X event handlers */ +void create_notify(xcb_create_notify_event_t * event) +{ + struct xwl_window_entry * entry; + + if (!(entry = wl_array_add(&xwm.windows, sizeof *entry))) + return; + + entry->id = event->window; + entry->override_redirect = event->override_redirect; + entry->xwl_window = NULL; +} + +void destroy_notify(xcb_destroy_notify_event_t * event) +{ + struct xwl_window_entry * entry; + + if (!(entry = find_window(event->window))) + return; + + swc_array_remove(&xwm.windows, entry, sizeof *entry); +} + +void map_request(xcb_map_request_event_t * event) +{ + xcb_map_window(xwm.connection, event->window); +} + +void configure_request(xcb_configure_request_event_t * event) +{ +} + +void property_notify(xcb_property_notify_event_t * event) +{ + struct xwl_window_entry * entry; + + if (!(entry = find_window(event->window)) || !entry->xwl_window) + return; + + if (event->atom == xwm.ewmh._NET_WM_NAME + && event->state == XCB_PROPERTY_NEW_VALUE) + { + update_name(entry->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); + } + + ++count; + } + + xcb_flush(xwm.connection); + + return count; +} + +bool swc_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; + 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; + } + + 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_array_init(&xwm.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; + } + + if (!xcb_ewmh_init_atoms_replies(&xwm.ewmh, ewmh_cookies, NULL)) + { + ERROR("xwm: Failed to get EWMH atom replies\n"); + goto error3; + } + + 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 swc_xwm_finalize() +{ + wl_array_release(&xwm.windows); + wl_event_source_remove(xwm.source); + xcb_ewmh_connection_wipe(&xwm.ewmh); + xcb_disconnect(xwm.connection); +} + +static void configure(struct swc_window * window, + const struct swc_rectangle * geometry) +{ + uint32_t mask, values[4]; + struct xwl_window * xwl_window + = CONTAINER_OF(window, typeof(*xwl_window), window.base); + + mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y + | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; + values[0] = geometry->x; + values[1] = geometry->y; + values[2] = geometry->width; + values[3] = geometry->height; + + xcb_configure_window(xwm.connection, xwl_window->id, mask, values); + xcb_flush(xwm.connection); +} + +static void focus(struct swc_window * window) +{ + struct xwl_window * xwl_window + = CONTAINER_OF(window, typeof(*xwl_window), window.base); + + xcb_set_input_focus(xwm.connection, XCB_INPUT_FOCUS_NONE, + xwl_window->id, XCB_CURRENT_TIME); + xcb_flush(xwm.connection); +} + +static const struct swc_window_impl xwl_window_handler = { + .configure = &configure, + .focus = &focus +}; + +static void handle_surface_destroy(struct wl_listener * listener, void * data) +{ + struct xwl_window_entry * entry; + struct xwl_window * xwl_window + = CONTAINER_OF(listener, typeof(*xwl_window), surface_destroy_listener); + + swc_window_finalize(&xwl_window->window.base); + free(xwl_window); + + wl_array_for_each(entry, &xwm.windows) + { + if (entry->xwl_window == xwl_window) + { + entry->xwl_window = NULL; + break; + } + } +} + +void swc_xwm_manage_window(xcb_window_t id, struct swc_surface * surface) +{ + struct xwl_window_entry * entry; + struct xwl_window * xwl_window; + xcb_get_geometry_cookie_t geometry_cookie; + xcb_get_geometry_reply_t * geometry_reply; + + if (!(entry = find_window(id))) + return; + + if (!(xwl_window = malloc(sizeof *xwl_window))) + return; + + geometry_cookie = xcb_get_geometry(xwm.connection, id); + + xwl_window->id = id; + xwl_window->surface_destroy_listener.notify = &handle_surface_destroy; + wl_resource_add_destroy_listener(surface->resource, + &xwl_window->surface_destroy_listener); + swc_window_initialize(&xwl_window->window.base, + &xwl_window_handler, surface); + + entry->xwl_window = xwl_window; + + if ((geometry_reply = xcb_get_geometry_reply(xwm.connection, + geometry_cookie, NULL))) + { + swc_surface_move(surface, geometry_reply->x, geometry_reply->y); + } + + if (entry->override_redirect) + swc_compositor_surface_show(surface); + else + { + uint32_t mask, values[1]; + + mask = XCB_CW_EVENT_MASK; + values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE; + xcb_change_window_attributes(xwm.connection, id, mask, values); + update_name(xwl_window); + + swc_window_set_state(&xwl_window->window.base, + SWC_WINDOW_STATE_TOPLEVEL); + } +} + diff --git a/libswc/xwm.h b/libswc/xwm.h @@ -0,0 +1,38 @@ +/* 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> +#include <xcb/xcb.h> + +struct swc_surface; + +bool swc_xwm_initialize(int fd); +void swc_xwm_finalize(); + +void swc_xwm_manage_window(xcb_window_t window, struct swc_surface * surface); + +#endif + diff --git a/protocol/Makefile.local b/protocol/Makefile.local @@ -2,8 +2,9 @@ dir := protocol -PROTOCOL_EXTENSIONS = \ - $(dir)/wayland-drm.xml +PROTOCOL_EXTENSIONS = \ + $(dir)/wayland-drm.xml \ + $(dir)/xserver.xml $(dir)_TARGETS := $(PROTOCOL_EXTENSIONS:%.xml=%-protocol.c) \ $(PROTOCOL_EXTENSIONS:%.xml=%-server-protocol.h) diff --git a/protocol/xserver.xml b/protocol/xserver.xml @@ -0,0 +1,18 @@ +<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>