xwayland: Switch to the new Xwayland DDX
This commit is contained in:
parent
43730f1660
commit
be02fa1120
@ -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
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
MetaWindow *window;
|
||||
struct wl_resource *resource;
|
||||
|
||||
window = meta_display_lookup_x_window (display, xid);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
associate_window_with_surface (window, surface);
|
||||
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;
|
||||
}
|
||||
|
||||
static const struct xserver_interface xserver_implementation = {
|
||||
xserver_set_window_id
|
||||
};
|
||||
typedef struct {
|
||||
MetaXWaylandManager *manager;
|
||||
MetaWindow *window;
|
||||
guint32 surface_id;
|
||||
} AssociateWindowWithSurfaceOp;
|
||||
|
||||
static void
|
||||
bind_xserver (struct wl_client *client,
|
||||
void *data,
|
||||
guint32 version,
|
||||
guint32 id)
|
||||
static gboolean
|
||||
associate_window_with_surface_idle (gpointer user_data)
|
||||
{
|
||||
MetaXWaylandManager *manager = 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);
|
||||
|
||||
/* If it's a different client than the xserver we launched,
|
||||
* just freeze up... */
|
||||
if (client != manager->client)
|
||||
return;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
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);
|
||||
void
|
||||
meta_xwayland_handle_wl_surface_id (MetaWindow *window,
|
||||
guint32 surface_id)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaXWaylandManager *manager = &compositor->xwayland_manager;
|
||||
|
||||
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);
|
||||
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 *
|
||||
@ -363,10 +371,6 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
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)
|
||||
@ -379,7 +383,7 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
manager->pid = fork ();
|
||||
if (manager->pid == 0)
|
||||
{
|
||||
char socket_fd[8];
|
||||
char socket_fd[8], unix_fd[8], abstract_fd[8];
|
||||
|
||||
/* We passed SOCK_CLOEXEC, so dup the FD so it isn't
|
||||
* closed on exec.. */
|
||||
@ -387,6 +391,12 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
snprintf (socket_fd, sizeof (socket_fd), "%d", fd);
|
||||
setenv ("WAYLAND_SOCKET", socket_fd, TRUE);
|
||||
|
||||
fd = dup (manager->abstract_fd);
|
||||
snprintf (abstract_fd, sizeof (abstract_fd), "%d", fd);
|
||||
|
||||
fd = dup (manager->unix_fd);
|
||||
snprintf (unix_fd, sizeof (unix_fd), "%d", fd);
|
||||
|
||||
/* xwayland, please. */
|
||||
if (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_error ("Failed to spawn XWayland: %m");
|
||||
|
35
src/wayland/meta-xwayland.h
Normal file
35
src/wayland/meta-xwayland.h
Normal file
@ -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 */
|
@ -1,18 +0,0 @@
|
||||
<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>
|
Loading…
Reference in New Issue
Block a user