[mutter/wip/xwayland: 2/5] xwayland: Switch to the new Xwayland DDX



commit 5ee20ea69ace12f9722db54fa879f2b2ab0b1842
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Mar 20 13:12:43 2014 -0400

    xwayland: Switch to the new Xwayland DDX

 configure.ac                     |    2 +-
 src/Makefile.am                  |   10 ++--
 src/core/events.c                |    8 +++-
 src/meta/atomnames.h             |    1 +
 src/wayland/meta-xwayland.c      |  110 +++++++++++++++++++++-----------------
 src/wayland/meta-xwayland.h      |   35 ++++++++++++
 src/wayland/protocol/xserver.xml |   18 ------
 7 files changed, 108 insertions(+), 76 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b5905a7..180af40 100644
--- a/configure.ac
+++ b/configure.ac
@@ -133,7 +133,7 @@ AC_ARG_WITH([wayland-protocols],
 AC_ARG_WITH([xwayland-path],
             [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
             [XWAYLAND_PATH="$withval"],
-            [XWAYLAND_PATH="$bindir/Xorg"])
+            [XWAYLAND_PATH="$bindir/Xwayland"])
 
 AM_GLIB_GNU_GETTEXT
 
diff --git a/src/Makefile.am b/src/Makefile.am
index aacec18..61a14fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,14 +41,11 @@ mutter_built_sources = \
        gtk-shell-protocol.c                    \
        gtk-shell-server-protocol.h             \
        xdg-shell-protocol.c                    \
-       xdg-shell-server-protocol.h             \
-       xserver-protocol.c                      \
-       xserver-server-protocol.h
+       xdg-shell-server-protocol.h
 
 wayland_protocols = \
        wayland/protocol/gtk-shell.xml          \
-       wayland/protocol/xdg-shell.xml          \
-       wayland/protocol/xserver.xml
+       wayland/protocol/xdg-shell.xml
 
 libmutter_wayland_la_SOURCES =                 \
        backends/meta-backend.c                 \
@@ -214,8 +211,9 @@ libmutter_wayland_la_SOURCES =                      \
        wayland/meta-wayland.c                  \
        wayland/meta-wayland.h                  \
        wayland/meta-wayland-private.h          \
-       wayland/meta-xwayland-private.h         \
        wayland/meta-xwayland.c                 \
+       wayland/meta-xwayland.h                 \
+       wayland/meta-xwayland-private.h         \
        wayland/meta-wayland-data-device.c      \
        wayland/meta-wayland-data-device.h      \
        wayland/meta-wayland-keyboard.c         \
diff --git a/src/core/events.c b/src/core/events.c
index afc4999..35e397f 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -39,6 +39,7 @@
 
 #include "x11/window-x11.h"
 #include "x11/xprops.h"
+#include "wayland/meta-xwayland.h"
 #include "wayland/meta-wayland-private.h"
 #include "meta-surface-actor-wayland.h"
 
@@ -1536,7 +1537,12 @@ handle_other_xevent (MetaDisplay *display,
     case ClientMessage:
       if (window)
         {
-          if (!frame_was_receiver)
+          if (event->xclient.message_type == display->atom_WL_SURFACE_ID)
+            {
+              guint32 surface_id = event->xclient.data.l[0];
+              meta_xwayland_handle_wl_surface_id (window, surface_id);
+            }
+          else if (!frame_was_receiver)
             meta_window_x11_client_message (window, event);
         }
       else
diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h
index f93876c..38227de 100644
--- a/src/meta/atomnames.h
+++ b/src/meta/atomnames.h
@@ -81,6 +81,7 @@ item(ATOM_PAIR)
 item(BACKLIGHT)
 item(_XKB_RULES_NAMES)
 item(hotplug_mode_update)
+item(WL_SURFACE_ID)
 
 /* Oddities: These are used, and we need atoms for them,
  * but when we need all _NET_WM hints (i.e. when we're making
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 468f532..d5f735c 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -23,6 +23,7 @@
 
 #include "config.h"
 
+#include "meta-xwayland.h"
 #include "meta-xwayland-private.h"
 
 #include <glib.h>
@@ -36,9 +37,6 @@
 #include <sys/wait.h>
 #include <stdlib.h>
 
-#include "meta-window-actor-private.h"
-#include "xserver-server-protocol.h"
-
 static void
 associate_window_with_surface (MetaWindow         *window,
                                MetaWaylandSurface *surface)
@@ -58,53 +56,63 @@ associate_window_with_surface (MetaWindow         *window,
   meta_compositor_window_surface_changed (display->compositor, window);
 }
 
-static void
-xserver_set_window_id (struct wl_client *client,
-                       struct wl_resource *compositor_resource,
-                       struct wl_resource *surface_resource,
-                       guint32 xid)
+static gboolean
+associate_window_with_surface_id (MetaXWaylandManager *manager,
+                                  MetaWindow          *window,
+                                  guint32              surface_id)
 {
-  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
-  MetaDisplay *display = meta_get_display ();
+  struct wl_resource *resource;
+
+  resource = wl_client_get_object (manager->client, surface_id);
+  if (resource)
+    {
+      MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
+      associate_window_with_surface (window, surface);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+typedef struct {
+  MetaXWaylandManager *manager;
   MetaWindow *window;
+  guint32 surface_id;
+} AssociateWindowWithSurfaceOp;
 
-  window = meta_display_lookup_x_window (display, xid);
-  if (!window)
-    return;
+static gboolean
+associate_window_with_surface_idle (gpointer user_data)
+{
+  AssociateWindowWithSurfaceOp *op = user_data;
+  if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id))
+    {
+      /* Not here? Oh well... nothing we can do */
+      g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc);
+    }
+  g_free (op);
 
-  associate_window_with_surface (window, surface);
+  return G_SOURCE_REMOVE;
 }
 
-static const struct xserver_interface xserver_implementation = {
-  xserver_set_window_id
-};
-
-static void
-bind_xserver (struct wl_client *client,
-             void *data,
-              guint32 version,
-              guint32 id)
+void
+meta_xwayland_handle_wl_surface_id (MetaWindow *window,
+                                    guint32     surface_id)
 {
-  MetaXWaylandManager *manager = data;
-
-  /* If it's a different client than the xserver we launched,
-   * just freeze up... */
-  if (client != manager->client)
-    return;
-
-  manager->xserver_resource = wl_resource_create (client, &xserver_interface,
-                                                  MIN (META_XSERVER_VERSION, version), id);
-  wl_resource_set_implementation (manager->xserver_resource,
-                                 &xserver_implementation, manager, NULL);
-
-  xserver_send_listen_socket (manager->xserver_resource, manager->abstract_fd);
-  xserver_send_listen_socket (manager->xserver_resource, manager->unix_fd);
-
-  /* Make sure xwayland will recieve the above sockets in a finite
-   * time before unblocking the initialization mainloop since we are
-   * then going to immediately try and connect to those as the window
-   * manager. */
-  wl_client_flush (client);
+  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+  MetaXWaylandManager *manager = &compositor->xwayland_manager;
+
+  if (!associate_window_with_surface_id (manager, window, surface_id))
+    {
+      /* No surface ID yet... it should arrive after the next
+       * iteration through the loop, so queue an idle and see
+       * what happens.
+       */
+      AssociateWindowWithSurfaceOp *op = g_new0 (AssociateWindowWithSurfaceOp, 1);
+      op->manager = manager;
+      op->window = window;
+      op->surface_id = surface_id;
+      g_idle_add (associate_window_with_surface_idle, op);
+    }
 }
 
 static char *
@@ -359,15 +367,11 @@ meta_xwayland_start (MetaXWaylandManager *manager,
 {
   int sp[2];
   int fd;
-  char *socket_fd;
+  char *socket_fd, *unix_fd, *abstract_fd;
 
   if (!choose_xdisplay (manager))
     return FALSE;
 
-  wl_global_create (wl_display, &xserver_interface,
-                   META_XSERVER_VERSION,
-                   manager, bind_xserver);
-
   /* We want xwayland to be a wayland client so we make a socketpair to setup a
    * wayland protocol connection. */
   if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp) < 0)
@@ -387,6 +391,12 @@ meta_xwayland_start (MetaXWaylandManager *manager,
       setenv ("WAYLAND_SOCKET", socket_fd, TRUE);
       g_free (socket_fd);
 
+      fd = dup (manager->abstract_fd);
+      abstract_fd = g_strdup_printf ("%d", fd);
+
+      fd = dup (manager->unix_fd);
+      unix_fd = g_strdup_printf ("%d", fd);
+
       /* xwayland, please. */
       if (g_getenv ("XWAYLAND_STFU"))
         {
@@ -403,10 +413,10 @@ meta_xwayland_start (MetaXWaylandManager *manager,
 
       if (execl (XWAYLAND_PATH, XWAYLAND_PATH,
                  manager->display_name,
-                 "-wayland",
                  "-rootless",
                  "-noreset",
-                 "-nolisten", "all",
+                 "-listen", abstract_fd,
+                 "-listen", unix_fd,
                  NULL) < 0)
         {
           g_warning ("Failed to spawn XWayland: %m");
diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h
new file mode 100644
index 0000000..5308f29
--- /dev/null
+++ b/src/wayland/meta-xwayland.h
@@ -0,0 +1,35 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2014 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef META_XWAYLAND_H
+#define META_XWAYLAND_H
+
+#include <glib.h>
+#include <meta/types.h>
+
+void
+meta_xwayland_handle_wl_surface_id (MetaWindow *window,
+                                    guint32     surface_id);
+
+#endif /* META_XWAYLAND_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]