summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2019-12-18 10:03:43 +0100
committerOlivier Fourdan <ofourdan@redhat.com>2019-12-20 16:19:01 +0100
commit0617c635fa3577965c5fa198ed4e57da8fee919d (patch)
tree4709637a976fd885fe4e403e5434d5b7f538ad23 /hw
parent211609a9387a5fb0df83ef6ddea59ef817ea2f59 (diff)
xwayland: Separate Xwayland screen code
Move Xwayland screen related code to a separate source file and header. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xwayland/Makefile.am2
-rw-r--r--hw/xwayland/meson.build2
-rw-r--r--hw/xwayland/xwayland-cursor.c1
-rw-r--r--hw/xwayland/xwayland-glamor-eglstream.c1
-rw-r--r--hw/xwayland/xwayland-glamor-gbm.c1
-rw-r--r--hw/xwayland/xwayland-glamor.c1
-rw-r--r--hw/xwayland/xwayland-glx.c2
-rw-r--r--hw/xwayland/xwayland-input.c1
-rw-r--r--hw/xwayland/xwayland-output.c1
-rw-r--r--hw/xwayland/xwayland-present.c1
-rw-r--r--hw/xwayland/xwayland-screen.c641
-rw-r--r--hw/xwayland/xwayland-screen.h130
-rw-r--r--hw/xwayland/xwayland-shm.c1
-rw-r--r--hw/xwayland/xwayland-vidmode.c2
-rw-r--r--hw/xwayland/xwayland-window-buffers.c1
-rw-r--r--hw/xwayland/xwayland-window.c1
-rw-r--r--hw/xwayland/xwayland.c598
-rw-r--r--hw/xwayland/xwayland.h93
18 files changed, 790 insertions, 690 deletions
diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
index 681c61d13..7969edcbc 100644
--- a/hw/xwayland/Makefile.am
+++ b/hw/xwayland/Makefile.am
@@ -19,6 +19,8 @@ Xwayland_SOURCES = \
xwayland-pixmap.c \
xwayland-pixmap.h \
xwayland-present.h \
+ xwayland-screen.c \
+ xwayland-screen.h \
xwayland-shm.c \
xwayland-shm.h \
xwayland-types.h \
diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index d4a4336fe..1718e8883 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -8,6 +8,8 @@ srcs = [
'xwayland-pixmap.c',
'xwayland-pixmap.h',
'xwayland-present.h',
+ 'xwayland-screen.c',
+ 'xwayland-screen.h',
'xwayland-shm.c',
'xwayland-shm.h',
'xwayland-types.h',
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 9c4c86aa2..44ed1fa41 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -35,6 +35,7 @@
#include "xwayland.h"
#include "xwayland-cursor.h"
#include "xwayland-input.h"
+#include "xwayland-screen.h"
#include "xwayland-shm.h"
#include "xwayland-types.h"
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index e052df29c..27190e4a4 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -43,6 +43,7 @@
#include "xwayland.h"
#include "xwayland-glamor.h"
#include "xwayland-pixmap.h"
+#include "xwayland-screen.h"
#include "wayland-eglstream-client-protocol.h"
#include "wayland-eglstream-controller-client-protocol.h"
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 6ed097fc2..6f624f773 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -49,6 +49,7 @@
#include "xwayland.h"
#include "xwayland-glamor.h"
#include "xwayland-pixmap.h"
+#include "xwayland-screen.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 6330b1f4c..e7c984c83 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -39,6 +39,7 @@
#include "xwayland.h"
#include "xwayland-glamor.h"
+#include "xwayland-screen.h"
#include "xwayland-window.h"
static void
diff --git a/hw/xwayland/xwayland-glx.c b/hw/xwayland/xwayland-glx.c
index 0fc2a7d01..c5c634c08 100644
--- a/hw/xwayland/xwayland-glx.c
+++ b/hw/xwayland/xwayland-glx.c
@@ -43,6 +43,8 @@
#include "glamor_context.h"
#include "glamor.h"
+#include "xwayland-screen.h"
+
/* Can't get these from <GL/glx.h> since it pulls in client headers */
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 7f2d4d6a1..a7be75d41 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -43,6 +43,7 @@
#include "xwayland-cursor.h"
#include "xwayland-input.h"
#include "xwayland-window.h"
+#include "xwayland-screen.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
#include "relative-pointer-unstable-v1-client-protocol.h"
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 6f62e5ae7..9778f881a 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -30,6 +30,7 @@
#include "xwayland.h"
#include "xwayland-output.h"
+#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xdg-output-unstable-v1-client-protocol.h"
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 0cf18e7c1..5b9ee201f 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -32,6 +32,7 @@
#include "xwayland.h"
#include "xwayland-present.h"
+#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xwayland-pixmap.h"
#include "glamor.h"
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
new file mode 100644
index 000000000..4932d2cdd
--- /dev/null
+++ b/hw/xwayland/xwayland-screen.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright © 2011-2014 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <xwayland-config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <X11/Xatom.h>
+#include <micmap.h>
+#include <misyncshm.h>
+#include <os.h>
+#include <fb.h>
+#include <dixstruct.h>
+#include <propertyst.h>
+#include <inputstr.h>
+#include <xserver_poll.h>
+
+#include "xwayland-cursor.h"
+#include "xwayland-screen.h"
+#include "xwayland-window.h"
+#include "xwayland-input.h"
+#include "xwayland-output.h"
+#include "xwayland-pixmap.h"
+#include "xwayland-present.h"
+#include "xwayland-shm.h"
+#include "xwayland.h"
+
+#include "xdg-output-unstable-v1-client-protocol.h"
+#include "viewporter-client-protocol.h"
+
+static DevPrivateKeyRec xwl_screen_private_key;
+static DevPrivateKeyRec xwl_client_private_key;
+
+_X_NORETURN
+static void _X_ATTRIBUTE_PRINTF(1, 2)
+xwl_give_up(const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ VErrorFSigSafe(f, args);
+ va_end(args);
+
+ CloseWellKnownConnections();
+ OsCleanup(TRUE);
+ fflush(stderr);
+ exit(1);
+}
+
+struct xwl_client *
+xwl_client_get(ClientPtr client)
+{
+ return dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
+}
+
+struct xwl_screen *
+xwl_screen_get(ScreenPtr screen)
+{
+ return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
+}
+
+Bool
+xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen)
+{
+ return wl_compositor_get_version(xwl_screen->compositor) >=
+ WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION &&
+ xwl_screen->viewporter != NULL;
+}
+
+Bool
+xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
+{
+ /* Resolution change emulation is only supported in rootless mode and
+ * it requires viewport support.
+ */
+ return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
+}
+
+/* Return the output @ 0x0, falling back to the first output in the list */
+struct xwl_output *
+xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
+{
+ struct xwl_output *xwl_output;
+
+ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
+ if (xwl_output->x == 0 && xwl_output->y == 0)
+ return xwl_output;
+ }
+
+ if (xorg_list_is_empty(&xwl_screen->output_list))
+ return NULL;
+
+ return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
+}
+
+static void
+xwl_property_callback(CallbackListPtr *pcbl, void *closure,
+ void *calldata)
+{
+ ScreenPtr screen = closure;
+ PropertyStateRec *rec = calldata;
+ struct xwl_screen *xwl_screen;
+ struct xwl_window *xwl_window;
+
+ if (rec->win->drawable.pScreen != screen)
+ return;
+
+ xwl_window = xwl_window_get(rec->win);
+ if (!xwl_window)
+ return;
+
+ xwl_screen = xwl_screen_get(screen);
+
+ if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
+ xwl_window_update_property(xwl_window, rec);
+}
+
+Bool
+xwl_close_screen(ScreenPtr screen)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_output *xwl_output, *next_xwl_output;
+ struct xwl_seat *xwl_seat, *next_xwl_seat;
+
+ DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen);
+
+ xorg_list_for_each_entry_safe(xwl_output, next_xwl_output,
+ &xwl_screen->output_list, link)
+ xwl_output_destroy(xwl_output);
+
+ xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat,
+ &xwl_screen->seat_list, link)
+ xwl_seat_destroy(xwl_seat);
+
+ xwl_screen_release_tablet_manager(xwl_screen);
+
+ RemoveNotifyFd(xwl_screen->wayland_fd);
+
+ wl_display_disconnect(xwl_screen->display);
+
+ screen->CloseScreen = xwl_screen->CloseScreen;
+ free(xwl_screen);
+
+ return screen->CloseScreen(screen);
+}
+
+static struct xwl_seat *
+xwl_screen_get_default_seat(struct xwl_screen *xwl_screen)
+{
+ if (xorg_list_is_empty(&xwl_screen->seat_list))
+ return NULL;
+
+ return container_of(xwl_screen->seat_list.prev,
+ struct xwl_seat,
+ link);
+}
+
+static void
+xwl_cursor_warped_to(DeviceIntPtr device,
+ ScreenPtr screen,
+ ClientPtr client,
+ WindowPtr window,
+ SpritePtr sprite,
+ int x, int y)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_seat *xwl_seat = device->public.devicePrivate;
+ struct xwl_window *xwl_window;
+ WindowPtr focus;
+
+ if (!xwl_seat)
+ xwl_seat = xwl_screen_get_default_seat(xwl_screen);
+
+ if (!window)
+ window = XYToWindow(sprite, x, y);
+
+ xwl_window = xwl_window_from_window(window);
+ if (!xwl_window && xwl_seat->focus_window) {
+ focus = xwl_seat->focus_window->window;
+
+ /* Warps on non wl_surface backed Windows are only allowed
+ * as long as the pointer stays within the focus window.
+ */
+ if (x >= focus->drawable.x &&
+ y >= focus->drawable.y &&
+ x < focus->drawable.x + focus->drawable.width &&
+ y < focus->drawable.y + focus->drawable.height) {
+ if (!window) {
+ DebugF("Warp relative to pointer, assuming pointer focus\n");
+ xwl_window = xwl_seat->focus_window;
+ } else if (window == screen->root) {
+ DebugF("Warp on root window, assuming pointer focus\n");
+ xwl_window = xwl_seat->focus_window;
+ }
+ }
+ }
+ if (!xwl_window)
+ return;
+
+ xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
+}
+
+static void
+xwl_cursor_confined_to(DeviceIntPtr device,
+ ScreenPtr screen,
+ WindowPtr window)
+{
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+ struct xwl_seat *xwl_seat = device->public.devicePrivate;
+ struct xwl_window *xwl_window;
+
+ if (!xwl_seat)
+ xwl_seat = xwl_screen_get_default_seat(xwl_screen);
+
+ /* xwl_seat hasn't been setup yet, don't do anything just yet */
+ if (!xwl_seat)
+ return;
+
+ if (window == screen->root) {
+ xwl_seat_unconfine_pointer(xwl_seat);
+ return;
+ }
+
+ xwl_window = xwl_window_from_window(window);
+ if (!xwl_window && xwl_seat->focus_window) {
+ /* Allow confining on InputOnly windows, but only if the geometry
+ * is the same than the focus window.
+ */
+ if (window->drawable.class == InputOnly) {
+ DebugF("Confine on InputOnly window, assuming pointer focus\n");
+ xwl_window = xwl_seat->focus_window;
+ }
+ }
+ if (!xwl_window)
+ return;
+
+ xwl_seat_confine_pointer(xwl_seat, xwl_window);
+}
+
+void
+xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
+{
+ struct xwl_window *xwl_window;
+
+ xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window)
+ xwl_window_check_resolution_change_emulation(xwl_window);
+}
+
+static void
+xwl_screen_post_damage(struct xwl_screen *xwl_screen)
+{
+ struct xwl_window *xwl_window, *next_xwl_window;
+
+ xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
+ &xwl_screen->damage_window_list, link_damage) {
+ /* If we're waiting on a frame callback from the server,
+ * don't attach a new buffer. */
+ if (xwl_window->frame_callback)
+ continue;
+
+ if (!xwl_window->allow_commits)
+ continue;
+
+#ifdef XWL_HAS_GLAMOR
+ if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window))
+ continue;
+#endif
+
+ xwl_window_post_damage(xwl_window);
+ }
+}
+
+static void
+registry_global(void *data, struct wl_registry *registry, uint32_t id,
+ const char *interface, uint32_t version)
+{
+ struct xwl_screen *xwl_screen = data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ uint32_t request_version = 1;
+
+ if (version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
+ request_version = WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION;
+
+ xwl_screen->compositor =
+ wl_registry_bind(registry, id, &wl_compositor_interface, request_version);
+ }
+ else if (strcmp(interface, "wl_shm") == 0) {
+ xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
+ }
+ else if (strcmp(interface, "wl_shell") == 0) {
+ xwl_screen->shell =
+ wl_registry_bind(registry, id, &wl_shell_interface, 1);
+ }
+ else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
+ if (xwl_output_create(xwl_screen, id))
+ xwl_screen->expecting_event++;
+ }
+ else if (strcmp(interface, "zxdg_output_manager_v1") == 0) {
+ /* We support xdg-output from version 1 to version 3 */
+ version = min(version, 3);
+ xwl_screen->xdg_output_manager =
+ wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, version);
+ xwl_screen_init_xdg_output(xwl_screen);
+ }
+ else if (strcmp(interface, "wp_viewporter") == 0) {
+ xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
+ }
+#ifdef XWL_HAS_GLAMOR
+ else if (xwl_screen->glamor) {
+ xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
+ version);
+ }
+#endif
+}
+
+static void
+global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+ struct xwl_screen *xwl_screen = data;
+ struct xwl_output *xwl_output, *tmp_xwl_output;
+
+ xorg_list_for_each_entry_safe(xwl_output, tmp_xwl_output,
+ &xwl_screen->output_list, link) {
+ if (xwl_output->server_output_id == name) {
+ xwl_output_remove(xwl_output);
+ break;
+ }
+ }
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_global,
+ global_remove
+};
+
+static void
+xwl_read_events (struct xwl_screen *xwl_screen)
+{
+ int ret;
+
+ if (xwl_screen->wait_flush)
+ return;
+
+ ret = wl_display_read_events(xwl_screen->display);
+ if (ret == -1)
+ xwl_give_up("failed to read Wayland events: %s\n", strerror(errno));
+
+ xwl_screen->prepare_read = 0;
+
+ ret = wl_display_dispatch_pending(xwl_screen->display);
+ if (ret == -1)
+ xwl_give_up("failed to dispatch Wayland events: %s\n", strerror(errno));
+}
+
+static int
+xwl_display_pollout (struct xwl_screen *xwl_screen, int timeout)
+{
+ struct pollfd poll_fd;
+
+ poll_fd.fd = wl_display_get_fd(xwl_screen->display);
+ poll_fd.events = POLLOUT;
+
+ return xserver_poll(&poll_fd, 1, timeout);
+}
+
+static void
+xwl_dispatch_events (struct xwl_screen *xwl_screen)
+{
+ int ret = 0;
+ int ready;
+
+ if (xwl_screen->wait_flush)
+ goto pollout;
+
+ while (xwl_screen->prepare_read == 0 &&
+ wl_display_prepare_read(xwl_screen->display) == -1) {
+ ret = wl_display_dispatch_pending(xwl_screen->display);
+ if (ret == -1)
+ xwl_give_up("failed to dispatch Wayland events: %s\n",
+ strerror(errno));
+ }
+
+ xwl_screen->prepare_read = 1;
+
+pollout:
+ ready = xwl_display_pollout(xwl_screen, 5);
+ if (ready == -1 && errno != EINTR)
+ xwl_give_up("error polling on XWayland fd: %s\n", strerror(errno));
+
+ if (ready > 0)
+ ret = wl_display_flush(xwl_screen->display);
+
+ if (ret == -1 && errno != EAGAIN)
+ xwl_give_up("failed to write to XWayland fd: %s\n", strerror(errno));
+
+ xwl_screen->wait_flush = (ready == 0 || ready == -1 || ret == -1);
+}
+
+static void
+socket_handler(int fd, int ready, void *data)
+{
+ struct xwl_screen *xwl_screen = data;
+
+ xwl_read_events (xwl_screen);
+}
+
+static void
+wakeup_handler(void *data, int err)
+{
+}
+
+static void
+block_handler(void *data, void *timeout)
+{
+ struct xwl_screen *xwl_screen = data;
+
+ xwl_screen_post_damage(xwl_screen);
+ xwl_dispatch_events (xwl_screen);
+}
+
+void
+xwl_sync_events (struct xwl_screen *xwl_screen)
+{
+ xwl_dispatch_events (xwl_screen);
+ xwl_read_events (xwl_screen);
+}
+
+Bool
+xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
+{
+ static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
+ struct xwl_screen *xwl_screen;
+ Pixel red_mask, blue_mask, green_mask;
+ int ret, bpc, green_bpc, i;
+#ifdef XWL_HAS_GLAMOR
+ Bool use_eglstreams = FALSE;
+#endif
+
+ xwl_screen = calloc(1, sizeof *xwl_screen);
+ if (xwl_screen == NULL)
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!xwl_pixmap_init())
+ return FALSE;
+ if (!xwl_window_init())
+ return FALSE;
+ /* There are no easy to use new / delete client hooks, we could use a
+ * ClientStateCallback, but it is easier to let the dix code manage the
+ * memory for us. This will zero fill the initial xwl_client data.
+ */
+ if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT,
+ sizeof(struct xwl_client)))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
+ xwl_screen->screen = pScreen;
+
+#ifdef XWL_HAS_GLAMOR
+ xwl_screen->glamor = 1;
+#endif
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-rootless") == 0) {
+ xwl_screen->rootless = 1;
+ }
+ else if (strcmp(argv[i], "-shm") == 0) {
+ xwl_screen->glamor = 0;
+ }
+ else if (strcmp(argv[i], "-eglstream") == 0) {
+#ifdef XWL_HAS_EGLSTREAM
+ use_eglstreams = TRUE;
+#else
+ ErrorF("xwayland glamor: this build does not have EGLStream support\n");
+#endif
+ }
+ }
+
+#ifdef XWL_HAS_GLAMOR
+ if (xwl_screen->glamor)
+ xwl_glamor_init_backends(xwl_screen, use_eglstreams);
+#endif
+
+ /* In rootless mode, we don't have any screen storage, and the only
+ * rendering should be to redirected mode. */
+ if (xwl_screen->rootless)
+ xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY;
+ else
+ xwl_screen->root_clip_mode = ROOT_CLIP_FULL;
+
+ xorg_list_init(&xwl_screen->output_list);
+ xorg_list_init(&xwl_screen->seat_list);
+ xorg_list_init(&xwl_screen->damage_window_list);
+ xorg_list_init(&xwl_screen->window_list);
+ xwl_screen->depth = 24;
+
+ xwl_screen->display = wl_display_connect(NULL);
+ if (xwl_screen->display == NULL) {
+ ErrorF("could not connect to wayland server\n");
+ return FALSE;
+ }
+
+ if (!xwl_screen_init_output(xwl_screen))
+ return FALSE;
+
+ xwl_screen->expecting_event = 0;
+ xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
+ wl_registry_add_listener(xwl_screen->registry,
+ &registry_listener, xwl_screen);
+ ret = wl_display_roundtrip(xwl_screen->display);
+ if (ret == -1) {
+ ErrorF("could not connect to wayland server\n");
+ return FALSE;
+ }
+
+ while (xwl_screen->expecting_event > 0)
+ wl_display_roundtrip(xwl_screen->display);
+
+ bpc = xwl_screen->depth / 3;
+ green_bpc = xwl_screen->depth - 2 * bpc;
+ blue_mask = (1 << bpc) - 1;
+ green_mask = ((1 << green_bpc) - 1) << bpc;
+ red_mask = blue_mask << (green_bpc + bpc);
+
+ miSetVisualTypesAndMasks(xwl_screen->depth,
+ ((1 << TrueColor) | (1 << DirectColor)),
+ green_bpc, TrueColor,
+ red_mask, green_mask, blue_mask);
+
+ miSetPixmapDepths();
+
+ ret = fbScreenInit(pScreen, NULL,
+ xwl_screen->width, xwl_screen->height,
+ 96, 96, 0,
+ BitsPerPixel(xwl_screen->depth));
+ if (!ret)
+ return FALSE;
+
+ fbPictureInit(pScreen, 0, 0);
+
+#ifdef HAVE_XSHMFENCE
+ if (!miSyncShmScreenInit(pScreen))
+ return FALSE;
+#endif
+
+ xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
+ SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
+ RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
+
+ pScreen->blackPixel = 0;
+ pScreen->whitePixel = 1;
+
+ ret = fbCreateDefColormap(pScreen);
+
+ if (!xwl_screen_init_cursor(xwl_screen))
+ return FALSE;
+
+#ifdef XWL_HAS_GLAMOR
+ if (xwl_screen->glamor) {
+ xwl_glamor_select_backend(xwl_screen, use_eglstreams);
+
+ if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) {
+ ErrorF("Failed to initialize glamor, falling back to sw\n");
+ xwl_screen->glamor = 0;
+ }
+ }
+
+ if (xwl_screen->glamor && xwl_screen->rootless)
+ xwl_screen->present = xwl_present_init(pScreen);
+#endif
+
+ if (!xwl_screen->glamor) {
+ xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = xwl_shm_create_screen_resources;
+ pScreen->CreatePixmap = xwl_shm_create_pixmap;
+ pScreen->DestroyPixmap = xwl_shm_destroy_pixmap;
+ }
+
+ xwl_screen->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = xwl_realize_window;
+
+ xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = xwl_unrealize_window;
+
+ xwl_screen->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = xwl_destroy_window;
+
+ xwl_screen->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xwl_close_screen;
+
+ xwl_screen->ResizeWindow = pScreen->ResizeWindow;
+ pScreen->ResizeWindow = xwl_resize_window;
+
+ if (xwl_screen->rootless) {
+ xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
+ pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
+ }
+
+ pScreen->CursorWarpedTo = xwl_cursor_warped_to;
+ pScreen->CursorConfinedTo = xwl_cursor_confined_to;
+
+ xwl_screen->allow_commits_prop = MakeAtom(allow_commits,
+ strlen(allow_commits),
+ TRUE);
+ if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
+ return FALSE;
+
+ AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
+
+ wl_display_roundtrip(xwl_screen->display);
+ while (xwl_screen->expecting_event)
+ wl_display_roundtrip(xwl_screen->display);
+
+ return ret;
+}
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
new file mode 100644
index 000000000..264c6b515
--- /dev/null
+++ b/hw/xwayland/xwayland-screen.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2011-2014 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef XWAYLAND_SCREEN_H
+#define XWAYLAND_SCREEN_H
+
+#include <xwayland-config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include <dix.h>
+
+#include "xwayland-types.h"
+#include "xwayland-output.h"
+#include "xwayland-glamor.h"
+
+struct xwl_format {
+ uint32_t format;
+ int num_modifiers;
+ uint64_t *modifiers;
+};
+
+struct xwl_screen {
+ int width;
+ int height;
+ int depth;
+ ScreenPtr screen;
+ int expecting_event;
+ enum RootClipMode root_clip_mode;
+
+ int rootless;
+ int glamor;
+ int present;
+
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ XYToWindowProcPtr XYToWindow;
+ SetWindowPixmapProcPtr SetWindowPixmap;
+ ResizeWindowProcPtr ResizeWindow;
+
+ struct xorg_list output_list;
+ struct xorg_list seat_list;
+ struct xorg_list damage_window_list;
+ struct xorg_list window_list;
+
+ int wayland_fd;
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_registry *input_registry;
+ struct wl_compositor *compositor;
+ struct zwp_tablet_manager_v2 *tablet_manager;
+ struct wl_shm *shm;
+ struct wl_shell *shell;
+ struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
+ struct zwp_pointer_constraints_v1 *pointer_constraints;
+ struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
+ struct zxdg_output_manager_v1 *xdg_output_manager;
+ struct wp_viewporter *viewporter;
+ uint32_t serial;
+
+#define XWL_FORMAT_ARGB8888 (1 << 0)
+#define XWL_FORMAT_XRGB8888 (1 << 1)
+#define XWL_FORMAT_RGB565 (1 << 2)
+
+ int prepare_read;
+ int wait_flush;
+
+ uint32_t num_formats;
+ struct xwl_format *formats;
+ void *egl_display, *egl_context;
+
+ struct xwl_egl_backend gbm_backend;
+ struct xwl_egl_backend eglstream_backend;
+ /* pointer to the current backend for creating pixmaps on wayland */
+ struct xwl_egl_backend *egl_backend;
+
+ struct glamor_context *glamor_ctx;
+
+ Atom allow_commits_prop;
+};
+
+/* Apps which use randr/vidmode to change the mode when going fullscreen,
+ * usually change the mode of only a single monitor, so this should be plenty.
+ */
+#define XWL_CLIENT_MAX_EMULATED_MODES 16
+
+struct xwl_client {
+ struct xwl_emulated_mode emulated_modes[XWL_CLIENT_MAX_EMULATED_MODES];
+};
+
+struct xwl_client *xwl_client_get(ClientPtr client);
+struct xwl_screen *xwl_screen_get(ScreenPtr screen);
+Bool xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen);
+Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
+void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
+struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
+Bool xwl_close_screen(ScreenPtr screen);
+Bool xwl_screen_init(ScreenPtr pScreen, int argc, char **argv);
+void xwl_sync_events (struct xwl_screen *xwl_screen);
+void xwl_surface_damage(struct xwl_screen *xwl_screen,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+
+#endif /* XWAYLAND_SCREEN_H */
diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index 995bf64f8..388e0f0f2 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -42,6 +42,7 @@
#include "xwayland.h"
#include "xwayland-pixmap.h"
+#include "xwayland-screen.h"
#include "xwayland-shm.h"
struct xwl_pixmap {
diff --git a/hw/xwayland/xwayland-vidmode.c b/hw/xwayland/xwayland-vidmode.c
index 56aac693a..8ff68ba53 100644
--- a/hw/xwayland/xwayland-vidmode.c
+++ b/hw/xwayland/xwayland-vidmode.c
@@ -39,6 +39,8 @@
#include "randrstr.h"
#include "vidmodestr.h"
+#include "xwayland-screen.h"
+
static DevPrivateKeyRec xwlVidModePrivateKeyRec;
#define xwlVidModePrivateKey (&xwlVidModePrivateKeyRec)
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 6d0eac96e..ff9ed57db 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -30,6 +30,7 @@
#include "xwayland-window.h"
#include "xwayland-pixmap.h"
+#include "xwayland-screen.h"
#include "xwayland-window-buffers.h"
#define BUFFER_TIMEOUT 1 * 1000 /* ms */
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 09ee782e5..fee49c11e 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -38,6 +38,7 @@
#include "xwayland-types.h"
#include "xwayland-input.h"
#include "xwayland-present.h"
+#include "xwayland-screen.h"
#include "xwayland-window.h"
#include "xwayland-window-buffers.h"
#include "xwayland-shm.h"
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index a9d04ddee..d45caffbe 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -37,15 +37,7 @@
#include <propertyst.h>
#include "xwayland.h"
-#include "xwayland-cursor.h"
-#include "xwayland-glamor.h"
-#include "xwayland-input.h"
-#include "xwayland-output.h"
-#include "xwayland-pixmap.h"
-#include "xwayland-present.h"
-#include "xwayland-shm.h"
-#include "xwayland-window-buffers.h"
-#include "xwayland-window.h"
+#include "xwayland-screen.h"
#ifdef XF86VIDMODE
#include <X11/extensions/xf86vmproto.h>
@@ -86,22 +78,6 @@ ddxInputThreadInit(void)
}
#endif
- _X_NORETURN
-static void _X_ATTRIBUTE_PRINTF(1, 2)
-xwl_give_up(const char *f, ...)
-{
- va_list args;
-
- va_start(args, f);
- VErrorFSigSafe(f, args);
- va_end(args);
-
- CloseWellKnownConnections();
- OsCleanup(TRUE);
- fflush(stderr);
- exit(1);
-}
-
void
ddxUseMsg(void)
{
@@ -174,388 +150,6 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 0;
}
-static DevPrivateKeyRec xwl_client_private_key;
-static DevPrivateKeyRec xwl_screen_private_key;
-
-struct xwl_client *
-xwl_client_get(ClientPtr client)
-{
- return dixLookupPrivate(&client->devPrivates, &xwl_client_private_key);
-}
-
-struct xwl_screen *
-xwl_screen_get(ScreenPtr screen)
-{
- return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key);
-}
-
-static Bool
-xwl_screen_has_viewport_support(struct xwl_screen *xwl_screen)
-{
- return wl_compositor_get_version(xwl_screen->compositor) >=
- WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION &&
- xwl_screen->viewporter != NULL;
-}
-
-Bool
-xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
-{
- /* Resolution change emulation is only supported in rootless mode and
- * it requires viewport support.
- */
- return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
-}
-
-/* Return the output @ 0x0, falling back to the first output in the list */
-struct xwl_output *
-xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
-{
- struct xwl_output *xwl_output;
-
- xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) {
- if (xwl_output->x == 0 && xwl_output->y == 0)
- return xwl_output;
- }
-
- if (xorg_list_is_empty(&xwl_screen->output_list))
- return NULL;
-
- return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
-}
-
-static void
-xwl_property_callback(CallbackListPtr *pcbl, void *closure,
- void *calldata)
-{
- ScreenPtr screen = closure;
- PropertyStateRec *rec = calldata;
- struct xwl_screen *xwl_screen;
- struct xwl_window *xwl_window;
-
- if (rec->win->drawable.pScreen != screen)
- return;
-
- xwl_window = xwl_window_get(rec->win);
- if (!xwl_window)
- return;
-
- xwl_screen = xwl_screen_get(screen);
-
- if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
- xwl_window_update_property(xwl_window, rec);
-}
-
-static Bool
-xwl_close_screen(ScreenPtr screen)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_output *xwl_output, *next_xwl_output;
- struct xwl_seat *xwl_seat, *next_xwl_seat;
-
- DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen);
-
- xorg_list_for_each_entry_safe(xwl_output, next_xwl_output,
- &xwl_screen->output_list, link)
- xwl_output_destroy(xwl_output);
-
- xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat,
- &xwl_screen->seat_list, link)
- xwl_seat_destroy(xwl_seat);
-
- xwl_screen_release_tablet_manager(xwl_screen);
-
- RemoveNotifyFd(xwl_screen->wayland_fd);
-
- wl_display_disconnect(xwl_screen->display);
-
- screen->CloseScreen = xwl_screen->CloseScreen;
- free(xwl_screen);
-
- return screen->CloseScreen(screen);
-}
-
-static struct xwl_seat *
-xwl_screen_get_default_seat(struct xwl_screen *xwl_screen)
-{
- if (xorg_list_is_empty(&xwl_screen->seat_list))
- return NULL;
-
- return container_of(xwl_screen->seat_list.prev,
- struct xwl_seat,
- link);
-}
-
-static void
-xwl_cursor_warped_to(DeviceIntPtr device,
- ScreenPtr screen,
- ClientPtr client,
- WindowPtr window,
- SpritePtr sprite,
- int x, int y)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- struct xwl_window *xwl_window;
- WindowPtr focus;
-
- if (!xwl_seat)
- xwl_seat = xwl_screen_get_default_seat(xwl_screen);
-
- if (!window)
- window = XYToWindow(sprite, x, y);
-
- xwl_window = xwl_window_from_window(window);
- if (!xwl_window && xwl_seat->focus_window) {
- focus = xwl_seat->focus_window->window;
-
- /* Warps on non wl_surface backed Windows are only allowed
- * as long as the pointer stays within the focus window.
- */
- if (x >= focus->drawable.x &&
- y >= focus->drawable.y &&
- x < focus->drawable.x + focus->drawable.width &&
- y < focus->drawable.y + focus->drawable.height) {
- if (!window) {
- DebugF("Warp relative to pointer, assuming pointer focus\n");
- xwl_window = xwl_seat->focus_window;
- } else if (window == screen->root) {
- DebugF("Warp on root window, assuming pointer focus\n");
- xwl_window = xwl_seat->focus_window;
- }
- }
- }
- if (!xwl_window)
- return;
-
- xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
-}
-
-static void
-xwl_cursor_confined_to(DeviceIntPtr device,
- ScreenPtr screen,
- WindowPtr window)
-{
- struct xwl_screen *xwl_screen = xwl_screen_get(screen);
- struct xwl_seat *xwl_seat = device->public.devicePrivate;
- struct xwl_window *xwl_window;
-
- if (!xwl_seat)
- xwl_seat = xwl_screen_get_default_seat(xwl_screen);
-
- /* xwl_seat hasn't been setup yet, don't do anything just yet */
- if (!xwl_seat)
- return;
-
- if (window == screen->root) {
- xwl_seat_unconfine_pointer(xwl_seat);
- return;
- }
-
- xwl_window = xwl_window_from_window(window);
- if (!xwl_window && xwl_seat->focus_window) {
- /* Allow confining on InputOnly windows, but only if the geometry
- * is the same than the focus window.
- */
- if (window->drawable.class == InputOnly) {
- DebugF("Confine on InputOnly window, assuming pointer focus\n");
- xwl_window = xwl_seat->focus_window;
- }
- }
- if (!xwl_window)
- return;
-
- xwl_seat_confine_pointer(xwl_seat, xwl_window);
-}
-
-void
-xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen)
-{
- struct xwl_window *xwl_window;
-
- xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window)
- xwl_window_check_resolution_change_emulation(xwl_window);
-}
-
-static void
-xwl_screen_post_damage(struct xwl_screen *xwl_screen)
-{
- struct xwl_window *xwl_window, *next_xwl_window;
-
- xorg_list_for_each_entry_safe(xwl_window, next_xwl_window,
- &xwl_screen->damage_window_list, link_damage) {
- /* If we're waiting on a frame callback from the server,
- * don't attach a new buffer. */
- if (xwl_window->frame_callback)
- continue;
-
- if (!xwl_window->allow_commits)
- continue;
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor && !xwl_glamor_allow_commits(xwl_window))
- continue;
-#endif
-
- xwl_window_post_damage(xwl_window);
- }
-}
-
-static void
-registry_global(void *data, struct wl_registry *registry, uint32_t id,
- const char *interface, uint32_t version)
-{
- struct xwl_screen *xwl_screen = data;
-
- if (strcmp(interface, "wl_compositor") == 0) {
- uint32_t request_version = 1;
-
- if (version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
- request_version = WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION;
-
- xwl_screen->compositor =
- wl_registry_bind(registry, id, &wl_compositor_interface, request_version);
- }
- else if (strcmp(interface, "wl_shm") == 0) {
- xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
- }
- else if (strcmp(interface, "wl_shell") == 0) {
- xwl_screen->shell =
- wl_registry_bind(registry, id, &wl_shell_interface, 1);
- }
- else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
- if (xwl_output_create(xwl_screen, id))
- xwl_screen->expecting_event++;
- }
- else if (strcmp(interface, "zxdg_output_manager_v1") == 0) {
- /* We support xdg-output from version 1 to version 3 */
- version = min(version, 3);
- xwl_screen->xdg_output_manager =
- wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, version);
- xwl_screen_init_xdg_output(xwl_screen);
- }
- else if (strcmp(interface, "wp_viewporter") == 0) {
- xwl_screen->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
- }
-#ifdef XWL_HAS_GLAMOR
- else if (xwl_screen->glamor) {
- xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface,
- version);
- }
-#endif
-}
-
-static void
-global_remove(void *data, struct wl_registry *registry, uint32_t name)
-{
- struct xwl_screen *xwl_screen = data;
- struct xwl_output *xwl_output, *tmp_xwl_output;
-
- xorg_list_for_each_entry_safe(xwl_output, tmp_xwl_output,
- &xwl_screen->output_list, link) {
- if (xwl_output->server_output_id == name) {
- xwl_output_remove(xwl_output);
- break;
- }
- }
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_global,
- global_remove
-};
-
-static void
-xwl_read_events (struct xwl_screen *xwl_screen)
-{
- int ret;
-
- if (xwl_screen->wait_flush)
- return;
-
- ret = wl_display_read_events(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to read Wayland events: %s\n", strerror(errno));
-
- xwl_screen->prepare_read = 0;
-
- ret = wl_display_dispatch_pending(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to dispatch Wayland events: %s\n", strerror(errno));
-}
-
-static int
-xwl_display_pollout (struct xwl_screen *xwl_screen, int timeout)
-{
- struct pollfd poll_fd;
-
- poll_fd.fd = wl_display_get_fd(xwl_screen->display);
- poll_fd.events = POLLOUT;
-
- return xserver_poll(&poll_fd, 1, timeout);
-}
-
-static void
-xwl_dispatch_events (struct xwl_screen *xwl_screen)
-{
- int ret = 0;
- int ready;
-
- if (xwl_screen->wait_flush)
- goto pollout;
-
- while (xwl_screen->prepare_read == 0 &&
- wl_display_prepare_read(xwl_screen->display) == -1) {
- ret = wl_display_dispatch_pending(xwl_screen->display);
- if (ret == -1)
- xwl_give_up("failed to dispatch Wayland events: %s\n",
- strerror(errno));
- }
-
- xwl_screen->prepare_read = 1;
-
-pollout:
- ready = xwl_display_pollout(xwl_screen, 5);
- if (ready == -1 && errno != EINTR)
- xwl_give_up("error polling on XWayland fd: %s\n", strerror(errno));
-
- if (ready > 0)
- ret = wl_display_flush(xwl_screen->display);
-
- if (ret == -1 && errno != EAGAIN)
- xwl_give_up("failed to write to XWayland fd: %s\n", strerror(errno));
-
- xwl_screen->wait_flush = (ready == 0 || ready == -1 || ret == -1);
-}
-
-static void
-socket_handler(int fd, int ready, void *data)
-{
- struct xwl_screen *xwl_screen = data;
-
- xwl_read_events (xwl_screen);
-}
-
-static void
-wakeup_handler(void *data, int err)
-{
-}
-
-static void
-block_handler(void *data, void *timeout)
-{
- struct xwl_screen *xwl_screen = data;
-
- xwl_screen_post_damage(xwl_screen);
- xwl_dispatch_events (xwl_screen);
-}
-
-void
-xwl_sync_events (struct xwl_screen *xwl_screen)
-{
- xwl_dispatch_events (xwl_screen);
- xwl_read_events (xwl_screen);
-}
-
static CARD32
add_client_fd(OsTimerPtr timer, CARD32 time, void *arg)
{
@@ -595,196 +189,6 @@ wm_selection_callback(CallbackListPtr *p, void *data, void *arg)
DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
}
-static Bool
-xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
-{
- static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
- struct xwl_screen *xwl_screen;
- Pixel red_mask, blue_mask, green_mask;
- int ret, bpc, green_bpc, i;
-#ifdef XWL_HAS_GLAMOR
- Bool use_eglstreams = FALSE;
-#endif
-
- xwl_screen = calloc(1, sizeof *xwl_screen);
- if (xwl_screen == NULL)
- return FALSE;
-
- if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!xwl_pixmap_init())
- return FALSE;
- if (!xwl_window_init())
- return FALSE;
- /* There are no easy to use new / delete client hooks, we could use a
- * ClientStateCallback, but it is easier to let the dix code manage the
- * memory for us. This will zero fill the initial xwl_client data.
- */
- if (!dixRegisterPrivateKey(&xwl_client_private_key, PRIVATE_CLIENT,
- sizeof(struct xwl_client)))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
- xwl_screen->screen = pScreen;
-
-#ifdef XWL_HAS_GLAMOR
- xwl_screen->glamor = 1;
-#endif
-
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "-rootless") == 0) {
- xwl_screen->rootless = 1;
- }
- else if (strcmp(argv[i], "-shm") == 0) {
- xwl_screen->glamor = 0;
- }
- else if (strcmp(argv[i], "-eglstream") == 0) {
-#ifdef XWL_HAS_EGLSTREAM
- use_eglstreams = TRUE;
-#else
- ErrorF("xwayland glamor: this build does not have EGLStream support\n");
-#endif
- }
- }
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor)
- xwl_glamor_init_backends(xwl_screen, use_eglstreams);
-#endif
-
- /* In rootless mode, we don't have any screen storage, and the only
- * rendering should be to redirected mode. */
- if (xwl_screen->rootless)
- xwl_screen->root_clip_mode = ROOT_CLIP_INPUT_ONLY;
- else
- xwl_screen->root_clip_mode = ROOT_CLIP_FULL;
-
- xorg_list_init(&xwl_screen->output_list);
- xorg_list_init(&xwl_screen->seat_list);
- xorg_list_init(&xwl_screen->damage_window_list);
- xorg_list_init(&xwl_screen->window_list);
- xwl_screen->depth = 24;
-
- xwl_screen->display = wl_display_connect(NULL);
- if (xwl_screen->display == NULL) {
- ErrorF("could not connect to wayland server\n");
- return FALSE;
- }
-
- if (!xwl_screen_init_output(xwl_screen))
- return FALSE;
-
- xwl_screen->expecting_event = 0;
- xwl_screen->registry = wl_display_get_registry(xwl_screen->display);
- wl_registry_add_listener(xwl_screen->registry,
- &registry_listener, xwl_screen);
- ret = wl_display_roundtrip(xwl_screen->display);
- if (ret == -1) {
- ErrorF("could not connect to wayland server\n");
- return FALSE;
- }
-
- while (xwl_screen->expecting_event > 0)
- wl_display_roundtrip(xwl_screen->display);
-
- bpc = xwl_screen->depth / 3;
- green_bpc = xwl_screen->depth - 2 * bpc;
- blue_mask = (1 << bpc) - 1;
- green_mask = ((1 << green_bpc) - 1) << bpc;
- red_mask = blue_mask << (green_bpc + bpc);
-
- miSetVisualTypesAndMasks(xwl_screen->depth,
- ((1 << TrueColor) | (1 << DirectColor)),
- green_bpc, TrueColor,
- red_mask, green_mask, blue_mask);
-
- miSetPixmapDepths();
-
- ret = fbScreenInit(pScreen, NULL,
- xwl_screen->width, xwl_screen->height,
- 96, 96, 0,
- BitsPerPixel(xwl_screen->depth));
- if (!ret)
- return FALSE;
-
- fbPictureInit(pScreen, 0, 0);
-
-#ifdef HAVE_XSHMFENCE
- if (!miSyncShmScreenInit(pScreen))
- return FALSE;
-#endif
-
- xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
- SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
- RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
-
- pScreen->blackPixel = 0;
- pScreen->whitePixel = 1;
-
- ret = fbCreateDefColormap(pScreen);
-
- if (!xwl_screen_init_cursor(xwl_screen))
- return FALSE;
-
-#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor) {
- xwl_glamor_select_backend(xwl_screen, use_eglstreams);
-
- if (xwl_screen->egl_backend == NULL || !xwl_glamor_init(xwl_screen)) {
- ErrorF("Failed to initialize glamor, falling back to sw\n");
- xwl_screen->glamor = 0;
- }
- }
-
- if (xwl_screen->glamor && xwl_screen->rootless)
- xwl_screen->present = xwl_present_init(pScreen);
-#endif
-
- if (!xwl_screen->glamor) {
- xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = xwl_shm_create_screen_resources;
- pScreen->CreatePixmap = xwl_shm_create_pixmap;
- pScreen->DestroyPixmap = xwl_shm_destroy_pixmap;
- }
-
- xwl_screen->RealizeWindow = pScreen->RealizeWindow;
- pScreen->RealizeWindow = xwl_realize_window;
-
- xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreen->UnrealizeWindow = xwl_unrealize_window;
-
- xwl_screen->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = xwl_destroy_window;
-
- xwl_screen->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xwl_close_screen;
-
- xwl_screen->ResizeWindow = pScreen->ResizeWindow;
- pScreen->ResizeWindow = xwl_resize_window;
-
- if (xwl_screen->rootless) {
- xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
- pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
- }
-
- pScreen->CursorWarpedTo = xwl_cursor_warped_to;
- pScreen->CursorConfinedTo = xwl_cursor_confined_to;
-
- xwl_screen->allow_commits_prop = MakeAtom(allow_commits,
- strlen(allow_commits),
- TRUE);
- if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
- return FALSE;
-
- AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
-
- wl_display_roundtrip(xwl_screen->display);
- while (xwl_screen->expecting_event)
- wl_display_roundtrip(xwl_screen->display);
-
- return ret;
-}
-
_X_NORETURN
static void _X_ATTRIBUTE_PRINTF(1, 0)
xwl_log_handler(const char *format, va_list args)
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index b22b21a19..b084845fc 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -45,105 +45,12 @@
#include "pointer-constraints-unstable-v1-client-protocol.h"
#include "tablet-unstable-v2-client-protocol.h"
#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
-#include "xdg-output-unstable-v1-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
-#include "viewporter-client-protocol.h"
#include "xwayland-types.h"
-#include "xwayland-output.h"
-#include "xwayland-glamor.h"
-
-struct xwl_format {
- uint32_t format;
- int num_modifiers;
- uint64_t *modifiers;
-};
-
-struct xwl_screen {
- int width;
- int height;
- int depth;
- ScreenPtr screen;
- int expecting_event;
- enum RootClipMode root_clip_mode;
-
- int rootless;
- int glamor;
- int present;
-
- CreateScreenResourcesProcPtr CreateScreenResources;
- CloseScreenProcPtr CloseScreen;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- DestroyWindowProcPtr DestroyWindow;
- XYToWindowProcPtr XYToWindow;
- SetWindowPixmapProcPtr SetWindowPixmap;
- ResizeWindowProcPtr ResizeWindow;
-
- struct xorg_list output_list;
- struct xorg_list seat_list;
- struct xorg_list damage_window_list;
- struct xorg_list window_list;
-
- int wayland_fd;
- struct wl_display *display;
- struct wl_registry *registry;
- struct wl_registry *input_registry;
- struct wl_compositor *compositor;
- struct zwp_tablet_manager_v2 *tablet_manager;
- struct wl_shm *shm;
- struct wl_shell *shell;
- struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
- struct zwp_pointer_constraints_v1 *pointer_constraints;
- struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
- struct zxdg_output_manager_v1 *xdg_output_manager;
- struct wp_viewporter *viewporter;
- uint32_t serial;
-
-#define XWL_FORMAT_ARGB8888 (1 << 0)
-#define XWL_FORMAT_XRGB8888 (1 << 1)
-#define XWL_FORMAT_RGB565 (1 << 2)
-
- int prepare_read;
- int wait_flush;
-
- uint32_t num_formats;
- struct xwl_format *formats;
- void *egl_display, *egl_context;
-
- struct xwl_egl_backend gbm_backend;
- struct xwl_egl_backend eglstream_backend;
- /* pointer to the current backend for creating pixmaps on wayland */
- struct xwl_egl_backend *egl_backend;
-
- struct glamor_context *glamor_ctx;
-
- Atom allow_commits_prop;
-};
#define MODIFIER_META 0x01
-/* Apps which use randr/vidmode to change the mode when going fullscreen,
- * usually change the mode of only a single monitor, so this should be plenty.
- */
-#define XWL_CLIENT_MAX_EMULATED_MODES 16
-
-struct xwl_client {
- struct xwl_emulated_mode emulated_modes[XWL_CLIENT_MAX_EMULATED_MODES];
-};
-
-struct xwl_client *xwl_client_get(ClientPtr client);
-
-void xwl_sync_events (struct xwl_screen *xwl_screen);
-void xwl_surface_damage(struct xwl_screen *xwl_screen,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height);
-
-struct xwl_screen *xwl_screen_get(ScreenPtr screen);
-Bool xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen);
-struct xwl_output *xwl_screen_get_first_output(struct xwl_screen *xwl_screen);
-void xwl_screen_check_resolution_change_emulation(struct xwl_screen *xwl_screen);
-
RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
float VRefresh, Bool Reduced, Bool Interlaced);