2012-01-07 22:21:32 +00:00
|
|
|
/*
|
|
|
|
* Wayland Support
|
|
|
|
*
|
|
|
|
* Copyright (C) 2012,2013 Intel Corporation
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2014-10-07 20:05:57 -07:00
|
|
|
#include "config.h"
|
|
|
|
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland.h"
|
2012-01-07 22:21:32 +00:00
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <wayland-server.h>
|
|
|
|
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "clutter/clutter.h"
|
2021-05-06 12:12:34 +02:00
|
|
|
#include "cogl/cogl-egl.h"
|
2020-10-22 23:16:28 +02:00
|
|
|
#include "compositor/meta-surface-actor-wayland.h"
|
2022-05-09 11:48:57 +02:00
|
|
|
#include "core/events.h"
|
2021-03-02 10:21:20 +01:00
|
|
|
#include "core/meta-context-private.h"
|
2020-10-09 16:23:32 +02:00
|
|
|
#include "wayland/meta-wayland-activation.h"
|
2019-09-18 16:18:58 +02:00
|
|
|
#include "wayland/meta-wayland-buffer.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland-data-device.h"
|
|
|
|
#include "wayland/meta-wayland-dma-buf.h"
|
|
|
|
#include "wayland/meta-wayland-egl-stream.h"
|
2023-01-27 15:16:14 +01:00
|
|
|
#include "wayland/meta-wayland-filter-manager.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h"
|
|
|
|
#include "wayland/meta-wayland-inhibit-shortcuts.h"
|
2020-02-06 02:00:56 -05:00
|
|
|
#include "wayland/meta-wayland-legacy-xdg-foreign.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland-outputs.h"
|
2020-10-07 12:02:41 +03:00
|
|
|
#include "wayland/meta-wayland-presentation-time-private.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland-private.h"
|
|
|
|
#include "wayland/meta-wayland-region.h"
|
|
|
|
#include "wayland/meta-wayland-seat.h"
|
|
|
|
#include "wayland/meta-wayland-subsurface.h"
|
|
|
|
#include "wayland/meta-wayland-tablet-manager.h"
|
2021-05-30 15:00:13 +02:00
|
|
|
#include "wayland/meta-wayland-transaction.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-wayland-xdg-foreign.h"
|
2022-06-13 10:09:26 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_XWAYLAND
|
2023-02-01 17:55:41 +01:00
|
|
|
#include "wayland/meta-wayland-x11-interop.h"
|
2018-07-10 10:36:24 +02:00
|
|
|
#include "wayland/meta-xwayland-grab-keyboard.h"
|
|
|
|
#include "wayland/meta-xwayland-private.h"
|
|
|
|
#include "wayland/meta-xwayland.h"
|
2022-06-13 10:09:26 +02:00
|
|
|
#endif
|
2017-08-27 20:44:58 +02:00
|
|
|
|
2021-10-14 18:36:43 +02:00
|
|
|
#ifdef HAVE_NATIVE_BACKEND
|
2023-02-11 07:02:40 +01:00
|
|
|
#include "backends/native/meta-frame-native.h"
|
2021-10-14 18:36:43 +02:00
|
|
|
#include "backends/native/meta-renderer-native.h"
|
|
|
|
#endif
|
|
|
|
|
2022-06-15 13:12:35 +02:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PREPARE_SHUTDOWN,
|
|
|
|
|
|
|
|
N_SIGNALS
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint signals[N_SIGNALS];
|
|
|
|
|
2016-12-05 21:23:46 +08:00
|
|
|
static char *_display_name_override;
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2022-05-13 21:51:53 +02:00
|
|
|
typedef struct _MetaWaylandCompositorPrivate
|
|
|
|
{
|
|
|
|
gboolean is_wayland_egl_display_bound;
|
2023-01-27 15:16:14 +01:00
|
|
|
|
|
|
|
MetaWaylandFilterManager *filter_manager;
|
2023-02-11 07:02:40 +01:00
|
|
|
GHashTable *frame_callback_sources;
|
2022-05-13 21:51:53 +02:00
|
|
|
} MetaWaylandCompositorPrivate;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandCompositor, meta_wayland_compositor,
|
|
|
|
G_TYPE_OBJECT)
|
2018-08-23 15:49:17 +02:00
|
|
|
|
2014-10-07 20:50:57 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GSource source;
|
|
|
|
struct wl_display *display;
|
|
|
|
} WaylandEventSource;
|
|
|
|
|
2023-02-11 07:02:40 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GSource source;
|
|
|
|
|
|
|
|
MetaWaylandCompositor *compositor;
|
|
|
|
ClutterStageView *stage_view;
|
|
|
|
int64_t target_presentation_time_us;
|
|
|
|
} FrameCallbackSource;
|
|
|
|
|
2012-01-07 22:21:32 +00:00
|
|
|
static gboolean
|
2017-06-05 20:09:01 +08:00
|
|
|
wayland_event_source_prepare (GSource *base,
|
|
|
|
int *timeout)
|
2012-01-07 22:21:32 +00:00
|
|
|
{
|
|
|
|
WaylandEventSource *source = (WaylandEventSource *)base;
|
|
|
|
|
|
|
|
*timeout = -1;
|
|
|
|
|
|
|
|
wl_display_flush_clients (source->display);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2017-06-05 20:09:01 +08:00
|
|
|
wayland_event_source_dispatch (GSource *base,
|
2012-01-07 22:21:32 +00:00
|
|
|
GSourceFunc callback,
|
2017-06-05 20:09:01 +08:00
|
|
|
void *data)
|
2012-01-07 22:21:32 +00:00
|
|
|
{
|
|
|
|
WaylandEventSource *source = (WaylandEventSource *)base;
|
|
|
|
struct wl_event_loop *loop = wl_display_get_event_loop (source->display);
|
|
|
|
|
|
|
|
wl_event_loop_dispatch (loop, 0);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSourceFuncs wayland_event_source_funcs =
|
|
|
|
{
|
|
|
|
wayland_event_source_prepare,
|
2014-12-15 14:42:33 -08:00
|
|
|
NULL,
|
2012-01-07 22:21:32 +00:00
|
|
|
wayland_event_source_dispatch,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static GSource *
|
|
|
|
wayland_event_source_new (struct wl_display *display)
|
|
|
|
{
|
2021-07-12 13:54:26 +03:00
|
|
|
GSource *source;
|
|
|
|
WaylandEventSource *wayland_source;
|
2012-01-07 22:21:32 +00:00
|
|
|
struct wl_event_loop *loop = wl_display_get_event_loop (display);
|
|
|
|
|
2021-07-12 13:54:26 +03:00
|
|
|
source = g_source_new (&wayland_event_source_funcs,
|
|
|
|
sizeof (WaylandEventSource));
|
|
|
|
g_source_set_name (source, "[mutter] Wayland events");
|
|
|
|
wayland_source = (WaylandEventSource *) source;
|
|
|
|
wayland_source->display = display;
|
|
|
|
g_source_add_unix_fd (&wayland_source->source,
|
2014-12-15 14:42:33 -08:00
|
|
|
wl_event_loop_get_fd (loop),
|
|
|
|
G_IO_IN | G_IO_ERR);
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2021-07-12 13:54:26 +03:00
|
|
|
return &wayland_source->source;
|
2012-01-07 22:21:32 +00:00
|
|
|
}
|
|
|
|
|
2023-02-11 07:02:40 +01:00
|
|
|
static void
|
|
|
|
emit_frame_callbacks_for_stage_view (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterStageView *stage_view)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
int64_t now_us;
|
|
|
|
|
|
|
|
now_us = g_get_monotonic_time ();
|
|
|
|
|
|
|
|
l = compositor->frame_callback_surfaces;
|
|
|
|
while (l)
|
|
|
|
{
|
|
|
|
GList *l_cur = l;
|
|
|
|
MetaWaylandSurface *surface = l->data;
|
|
|
|
MetaSurfaceActor *actor;
|
|
|
|
MetaWaylandActorSurface *actor_surface;
|
|
|
|
|
|
|
|
l = l->next;
|
|
|
|
|
|
|
|
actor = meta_wayland_surface_get_actor (surface);
|
|
|
|
if (!actor)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!meta_surface_actor_wayland_is_view_primary (actor,
|
|
|
|
stage_view))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
actor_surface = META_WAYLAND_ACTOR_SURFACE (surface->role);
|
|
|
|
meta_wayland_actor_surface_emit_frame_callbacks (actor_surface,
|
|
|
|
now_us / 1000);
|
|
|
|
|
|
|
|
compositor->frame_callback_surfaces =
|
|
|
|
g_list_delete_link (compositor->frame_callback_surfaces, l_cur);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
frame_callback_source_dispatch (GSource *source,
|
|
|
|
GSourceFunc callback,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
FrameCallbackSource *frame_callback_source = (FrameCallbackSource *) source;
|
|
|
|
MetaWaylandCompositor *compositor = frame_callback_source->compositor;
|
|
|
|
ClutterStageView *stage_view = frame_callback_source->stage_view;
|
|
|
|
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
g_source_set_ready_time (source, -1);
|
|
|
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
frame_callback_source_finalize (GSource *source)
|
|
|
|
{
|
|
|
|
FrameCallbackSource *frame_callback_source = (FrameCallbackSource *) source;
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_data (frame_callback_source->stage_view,
|
|
|
|
source);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSourceFuncs frame_callback_source_funcs = {
|
|
|
|
.dispatch = frame_callback_source_dispatch,
|
|
|
|
.finalize = frame_callback_source_finalize,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_stage_view_destroy (ClutterStageView *stage_view,
|
|
|
|
GSource *source)
|
|
|
|
{
|
|
|
|
FrameCallbackSource *frame_callback_source = (FrameCallbackSource *) source;
|
|
|
|
MetaWaylandCompositor *compositor = frame_callback_source->compositor;
|
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
|
|
|
|
|
|
|
g_hash_table_remove (priv->frame_callback_sources, stage_view);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSource*
|
|
|
|
frame_callback_source_new (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterStageView *stage_view)
|
|
|
|
{
|
|
|
|
FrameCallbackSource *frame_callback_source;
|
|
|
|
g_autofree char *name = NULL;
|
|
|
|
GSource *source;
|
|
|
|
|
|
|
|
source = g_source_new (&frame_callback_source_funcs,
|
|
|
|
sizeof (FrameCallbackSource));
|
|
|
|
frame_callback_source = (FrameCallbackSource *) source;
|
|
|
|
|
|
|
|
name =
|
|
|
|
g_strdup_printf ("[mutter] Wayland frame callbacks for stage view (%p)",
|
|
|
|
stage_view);
|
|
|
|
g_source_set_name (source, name);
|
|
|
|
g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
|
|
|
|
g_source_set_can_recurse (source, FALSE);
|
|
|
|
|
|
|
|
frame_callback_source->compositor = compositor;
|
|
|
|
frame_callback_source->stage_view = stage_view;
|
|
|
|
|
|
|
|
g_signal_connect (stage_view,
|
|
|
|
"destroy",
|
|
|
|
G_CALLBACK (on_stage_view_destroy),
|
|
|
|
source);
|
|
|
|
|
|
|
|
return &frame_callback_source->source;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSource*
|
|
|
|
ensure_source_for_stage_view (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterStageView *stage_view)
|
|
|
|
{
|
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
|
|
|
GSource *source;
|
|
|
|
|
|
|
|
source = g_hash_table_lookup (priv->frame_callback_sources, stage_view);
|
|
|
|
if (!source)
|
|
|
|
{
|
|
|
|
source = frame_callback_source_new (compositor, stage_view);
|
|
|
|
g_hash_table_insert (priv->frame_callback_sources, stage_view, source);
|
|
|
|
g_source_attach (source, NULL);
|
|
|
|
g_source_unref (source);
|
|
|
|
}
|
|
|
|
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_after_update (ClutterStage *stage,
|
|
|
|
ClutterStageView *stage_view,
|
|
|
|
ClutterFrame *frame,
|
|
|
|
MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
#if defined(HAVE_NATIVE_BACKEND)
|
|
|
|
MetaContext *context = meta_wayland_compositor_get_context (compositor);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
|
|
|
MetaFrameNative *frame_native;
|
|
|
|
FrameCallbackSource *frame_callback_source;
|
|
|
|
GSource *source;
|
|
|
|
int64_t min_render_time_allowed_us;
|
|
|
|
|
|
|
|
if (!META_IS_BACKEND_NATIVE (backend))
|
|
|
|
{
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
frame_native = meta_frame_native_from_frame (frame);
|
|
|
|
|
|
|
|
source = ensure_source_for_stage_view (compositor, stage_view);
|
|
|
|
frame_callback_source = (FrameCallbackSource *) source;
|
|
|
|
|
|
|
|
if (meta_frame_native_had_kms_update (frame_native) ||
|
|
|
|
!clutter_frame_get_min_render_time_allowed (frame,
|
|
|
|
&min_render_time_allowed_us))
|
|
|
|
{
|
|
|
|
g_source_set_ready_time (source, -1);
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int64_t target_presentation_time_us;
|
|
|
|
int64_t source_ready_time_us;
|
|
|
|
|
|
|
|
if (!clutter_frame_get_target_presentation_time (frame,
|
|
|
|
&target_presentation_time_us))
|
|
|
|
target_presentation_time_us = 0;
|
|
|
|
|
|
|
|
if (g_source_get_ready_time (source) != -1 &&
|
|
|
|
frame_callback_source->target_presentation_time_us <
|
|
|
|
target_presentation_time_us)
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
|
|
|
|
source_ready_time_us = target_presentation_time_us -
|
|
|
|
min_render_time_allowed_us;
|
|
|
|
|
|
|
|
if (source_ready_time_us <= g_get_monotonic_time ())
|
|
|
|
{
|
|
|
|
g_source_set_ready_time (source, -1);
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frame_callback_source->target_presentation_time_us =
|
|
|
|
target_presentation_time_us;
|
|
|
|
g_source_set_ready_time (source, source_ready_time_us);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
emit_frame_callbacks_for_stage_view (compositor, stage_view);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-05-03 18:51:22 +01:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
2022-05-18 13:51:44 +02:00
|
|
|
MetaWaylandSurface *surface;
|
2013-05-03 18:51:22 +01:00
|
|
|
|
2022-05-18 13:51:44 +02:00
|
|
|
if (window)
|
|
|
|
surface = meta_window_get_wayland_surface (window);
|
|
|
|
else
|
|
|
|
surface = NULL;
|
2014-07-10 10:13:54 -04:00
|
|
|
meta_wayland_seat_set_input_focus (compositor->seat, surface);
|
2013-05-03 18:51:22 +01:00
|
|
|
}
|
|
|
|
|
2014-10-07 20:08:31 -07:00
|
|
|
static void
|
2017-06-05 20:09:01 +08:00
|
|
|
wl_compositor_create_surface (struct wl_client *client,
|
2014-10-07 20:08:31 -07:00
|
|
|
struct wl_resource *resource,
|
2017-06-05 20:09:01 +08:00
|
|
|
uint32_t id)
|
2014-10-07 20:08:31 -07:00
|
|
|
{
|
|
|
|
MetaWaylandCompositor *compositor = wl_resource_get_user_data (resource);
|
2017-06-05 20:09:01 +08:00
|
|
|
|
2014-10-07 20:08:31 -07:00
|
|
|
meta_wayland_surface_create (compositor, client, resource, id);
|
|
|
|
}
|
|
|
|
|
2012-01-07 22:21:32 +00:00
|
|
|
static void
|
2017-06-05 20:09:01 +08:00
|
|
|
wl_compositor_create_region (struct wl_client *client,
|
2014-10-07 20:12:36 -07:00
|
|
|
struct wl_resource *resource,
|
2017-06-05 20:09:01 +08:00
|
|
|
uint32_t id)
|
2012-01-07 22:21:32 +00:00
|
|
|
{
|
2014-10-07 20:12:36 -07:00
|
|
|
MetaWaylandCompositor *compositor = wl_resource_get_user_data (resource);
|
2017-06-05 20:09:01 +08:00
|
|
|
|
2014-10-07 20:12:36 -07:00
|
|
|
meta_wayland_region_create (compositor, client, resource, id);
|
2012-01-07 22:21:32 +00:00
|
|
|
}
|
|
|
|
|
2015-09-24 01:20:33 +02:00
|
|
|
static const struct wl_compositor_interface meta_wayland_wl_compositor_interface = {
|
2014-08-04 10:26:55 -04:00
|
|
|
wl_compositor_create_surface,
|
|
|
|
wl_compositor_create_region
|
2012-01-07 22:21:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
compositor_bind (struct wl_client *client,
|
2017-06-05 20:09:01 +08:00
|
|
|
void *data,
|
|
|
|
uint32_t version,
|
|
|
|
uint32_t id)
|
2012-01-07 22:21:32 +00:00
|
|
|
{
|
|
|
|
MetaWaylandCompositor *compositor = data;
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2014-08-04 10:24:59 -04:00
|
|
|
resource = wl_resource_create (client, &wl_compositor_interface, version, id);
|
2017-06-05 20:09:01 +08:00
|
|
|
wl_resource_set_implementation (resource,
|
|
|
|
&meta_wayland_wl_compositor_interface,
|
|
|
|
compositor, NULL);
|
2012-01-07 22:21:32 +00:00
|
|
|
}
|
|
|
|
|
2014-03-18 18:00:48 +01:00
|
|
|
/**
|
|
|
|
* meta_wayland_compositor_update:
|
|
|
|
* @compositor: the #MetaWaylandCompositor instance
|
|
|
|
* @event: the #ClutterEvent used to update @seat's state
|
|
|
|
*
|
|
|
|
* This is used to update display server state like updating cursor
|
|
|
|
* position and keeping track of buttons and keys pressed. It must be
|
|
|
|
* called for all input events coming from the underlying devices.
|
|
|
|
*/
|
2013-11-13 21:41:29 +01:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
|
|
|
const ClutterEvent *event)
|
2013-08-23 15:07:57 +02:00
|
|
|
{
|
2015-01-09 17:29:06 +01:00
|
|
|
if (meta_wayland_tablet_manager_consumes_event (compositor->tablet_manager, event))
|
|
|
|
meta_wayland_tablet_manager_update (compositor->tablet_manager, event);
|
|
|
|
else
|
|
|
|
meta_wayland_seat_update (compositor->seat, event);
|
2013-08-23 15:07:57 +02:00
|
|
|
}
|
|
|
|
|
2020-10-08 15:34:28 +03:00
|
|
|
static MetaWaylandOutput *
|
|
|
|
get_output_for_stage_view (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterStageView *stage_view)
|
|
|
|
{
|
|
|
|
MetaCrtc *crtc;
|
|
|
|
MetaOutput *output;
|
|
|
|
MetaMonitor *monitor;
|
|
|
|
|
|
|
|
crtc = meta_renderer_view_get_crtc (META_RENDERER_VIEW (stage_view));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All outputs occupy the same region of the screen, as their contents are
|
|
|
|
* the same, so pick the first one.
|
|
|
|
*/
|
|
|
|
output = meta_crtc_get_outputs (crtc)->data;
|
|
|
|
|
|
|
|
monitor = meta_output_get_monitor (output);
|
2021-02-05 17:22:30 +01:00
|
|
|
return g_hash_table_lookup (compositor->outputs,
|
|
|
|
meta_monitor_get_spec (monitor));
|
2020-10-08 15:34:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_presented (ClutterStage *stage,
|
|
|
|
ClutterStageView *stage_view,
|
|
|
|
ClutterFrameInfo *frame_info,
|
|
|
|
MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
MetaWaylandPresentationFeedback *feedback, *next;
|
|
|
|
struct wl_list *feedbacks;
|
|
|
|
MetaWaylandOutput *output;
|
|
|
|
|
|
|
|
feedbacks =
|
|
|
|
meta_wayland_presentation_time_ensure_feedbacks (&compositor->presentation_time,
|
|
|
|
stage_view);
|
|
|
|
|
|
|
|
output = get_output_for_stage_view (compositor, stage_view);
|
|
|
|
|
|
|
|
wl_list_for_each_safe (feedback, next, feedbacks, link)
|
|
|
|
{
|
|
|
|
meta_wayland_presentation_feedback_present (feedback,
|
|
|
|
frame_info,
|
|
|
|
output);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-18 18:00:48 +01:00
|
|
|
/**
|
|
|
|
* meta_wayland_compositor_handle_event:
|
|
|
|
* @compositor: the #MetaWaylandCompositor instance
|
|
|
|
* @event: the #ClutterEvent to be sent
|
|
|
|
*
|
|
|
|
* This method sends events to the focused wayland client, if any.
|
|
|
|
*
|
|
|
|
* Return value: whether @event was sent to a wayland client.
|
|
|
|
*/
|
2013-10-04 02:29:43 -04:00
|
|
|
gboolean
|
|
|
|
meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
|
|
|
const ClutterEvent *event)
|
2013-05-03 18:51:22 +01:00
|
|
|
{
|
2015-01-09 17:29:06 +01:00
|
|
|
if (meta_wayland_tablet_manager_handle_event (compositor->tablet_manager,
|
|
|
|
event))
|
|
|
|
return TRUE;
|
|
|
|
|
2013-10-04 02:33:10 -04:00
|
|
|
return meta_wayland_seat_handle_event (compositor->seat, event);
|
2013-05-03 18:51:22 +01:00
|
|
|
}
|
|
|
|
|
2015-08-21 16:25:53 -04:00
|
|
|
/* meta_wayland_compositor_update_key_state:
|
|
|
|
* @compositor: the #MetaWaylandCompositor
|
|
|
|
* @key_vector: bit vector of key states
|
|
|
|
* @key_vector_len: length of @key_vector
|
|
|
|
* @offset: the key for the first evdev keycode is found at this offset in @key_vector
|
|
|
|
*
|
|
|
|
* This function is used to resynchronize the key state that Mutter
|
|
|
|
* is tracking with the actual keyboard state. This is useful, for example,
|
|
|
|
* to handle changes in key state when a nested compositor doesn't
|
|
|
|
* have focus. We need to fix up the XKB modifier tracking and deliver
|
|
|
|
* any modifier changes to clients.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_wayland_compositor_update_key_state (MetaWaylandCompositor *compositor,
|
|
|
|
char *key_vector,
|
|
|
|
int key_vector_len,
|
|
|
|
int offset)
|
|
|
|
{
|
2016-04-01 16:39:30 +08:00
|
|
|
meta_wayland_keyboard_update_key_state (compositor->seat->keyboard,
|
2015-08-21 16:25:53 -04:00
|
|
|
key_vector, key_vector_len, offset);
|
|
|
|
}
|
|
|
|
|
2015-02-25 16:26:01 +01:00
|
|
|
void
|
2020-04-27 15:43:19 +02:00
|
|
|
meta_wayland_compositor_add_frame_callback_surface (MetaWaylandCompositor *compositor,
|
|
|
|
MetaWaylandSurface *surface)
|
2015-02-25 16:26:01 +01:00
|
|
|
{
|
2020-04-27 15:43:19 +02:00
|
|
|
if (g_list_find (compositor->frame_callback_surfaces, surface))
|
|
|
|
return;
|
2015-02-25 16:26:01 +01:00
|
|
|
|
2020-04-27 15:43:19 +02:00
|
|
|
compositor->frame_callback_surfaces =
|
|
|
|
g_list_prepend (compositor->frame_callback_surfaces, surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_compositor_remove_frame_callback_surface (MetaWaylandCompositor *compositor,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
|
|
|
compositor->frame_callback_surfaces =
|
|
|
|
g_list_remove (compositor->frame_callback_surfaces, surface);
|
2015-02-25 16:26:01 +01:00
|
|
|
}
|
|
|
|
|
2020-10-08 15:41:31 +03:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_add_presentation_feedback_surface (MetaWaylandCompositor *compositor,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
|
|
|
if (g_list_find (compositor->presentation_time.feedback_surfaces, surface))
|
|
|
|
return;
|
|
|
|
|
|
|
|
compositor->presentation_time.feedback_surfaces =
|
|
|
|
g_list_prepend (compositor->presentation_time.feedback_surfaces, surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_compositor_remove_presentation_feedback_surface (MetaWaylandCompositor *compositor,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
|
|
|
compositor->presentation_time.feedback_surfaces =
|
|
|
|
g_list_remove (compositor->presentation_time.feedback_surfaces, surface);
|
|
|
|
}
|
|
|
|
|
2021-05-30 15:00:13 +02:00
|
|
|
GQueue *
|
|
|
|
meta_wayland_compositor_get_committed_transactions (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return &compositor->committed_transactions;
|
|
|
|
}
|
|
|
|
|
2013-08-20 18:03:26 +02:00
|
|
|
static void
|
|
|
|
set_gnome_env (const char *name,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
GDBusConnection *session_bus;
|
2014-03-26 12:02:08 -04:00
|
|
|
GError *error = NULL;
|
2020-01-24 18:47:43 +01:00
|
|
|
g_autoptr (GVariant) result = NULL;
|
2013-08-20 18:03:26 +02:00
|
|
|
|
|
|
|
setenv (name, value, TRUE);
|
|
|
|
|
|
|
|
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
|
|
g_assert (session_bus);
|
|
|
|
|
2020-01-24 18:47:43 +01:00
|
|
|
result = g_dbus_connection_call_sync (session_bus,
|
2013-08-20 18:03:26 +02:00
|
|
|
"org.gnome.SessionManager",
|
|
|
|
"/org/gnome/SessionManager",
|
|
|
|
"org.gnome.SessionManager",
|
|
|
|
"Setenv",
|
|
|
|
g_variant_new ("(ss)", name, value),
|
|
|
|
NULL,
|
2014-05-15 14:16:20 -04:00
|
|
|
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
2013-08-20 18:03:26 +02:00
|
|
|
-1, NULL, &error);
|
|
|
|
if (error)
|
|
|
|
{
|
2017-11-06 20:37:34 +01:00
|
|
|
char *remote_error;
|
|
|
|
|
|
|
|
remote_error = g_dbus_error_get_remote_error (error);
|
|
|
|
if (g_strcmp0 (remote_error, "org.gnome.SessionManager.NotInInitialization") != 0)
|
2020-10-02 17:47:22 +02:00
|
|
|
{
|
|
|
|
meta_warning ("Failed to set environment variable %s for gnome-session: %s",
|
|
|
|
name, error->message);
|
|
|
|
}
|
2014-03-26 12:02:08 -04:00
|
|
|
|
2017-11-06 20:37:34 +01:00
|
|
|
g_free (remote_error);
|
2014-03-26 12:02:08 -04:00
|
|
|
g_error_free (error);
|
2013-08-20 18:03:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 16:47:45 +01:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_init_display (MetaWaylandCompositor *compositor,
|
|
|
|
MetaDisplay *display)
|
|
|
|
{
|
2022-06-13 10:09:26 +02:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2021-03-23 16:47:45 +01:00
|
|
|
meta_xwayland_init_display (&compositor->xwayland_manager, display);
|
2022-06-13 10:09:26 +02:00
|
|
|
#endif
|
2021-03-23 16:47:45 +01:00
|
|
|
}
|
|
|
|
|
2015-09-24 01:18:15 +02:00
|
|
|
static void meta_wayland_log_func (const char *, va_list) G_GNUC_PRINTF (1, 0);
|
|
|
|
|
2013-11-19 20:04:49 -05:00
|
|
|
static void
|
|
|
|
meta_wayland_log_func (const char *fmt,
|
|
|
|
va_list arg)
|
|
|
|
{
|
|
|
|
char *str = g_strdup_vprintf (fmt, arg);
|
|
|
|
g_warning ("WL: %s", str);
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
|
2021-03-03 22:00:05 +01:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_prepare_shutdown (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
2022-06-15 13:12:35 +02:00
|
|
|
g_signal_emit (compositor, signals[PREPARE_SHUTDOWN], 0, NULL);
|
2021-03-03 22:00:05 +01:00
|
|
|
|
|
|
|
if (compositor->wayland_display)
|
|
|
|
wl_display_destroy_clients (compositor->wayland_display);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_compositor_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
MetaWaylandCompositor *compositor = META_WAYLAND_COMPOSITOR (object);
|
2023-01-27 15:16:14 +01:00
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
2022-07-23 16:37:15 +02:00
|
|
|
MetaBackend *backend = meta_context_get_backend (compositor->context);
|
|
|
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
|
|
|
|
2022-07-23 16:52:52 +02:00
|
|
|
meta_wayland_activation_finalize (compositor);
|
2022-07-23 17:06:59 +02:00
|
|
|
meta_wayland_outputs_finalize (compositor);
|
2022-07-23 17:00:09 +02:00
|
|
|
meta_wayland_presentation_time_finalize (compositor);
|
2022-07-23 17:13:21 +02:00
|
|
|
meta_wayland_tablet_manager_finalize (compositor);
|
2022-07-23 16:52:52 +02:00
|
|
|
|
2022-07-23 16:42:56 +02:00
|
|
|
g_hash_table_destroy (compositor->scheduled_surface_associations);
|
|
|
|
|
2022-07-23 16:37:15 +02:00
|
|
|
g_signal_handlers_disconnect_by_func (stage, on_after_update, compositor);
|
|
|
|
g_signal_handlers_disconnect_by_func (stage, on_presented, compositor);
|
2021-03-03 22:00:05 +01:00
|
|
|
|
2021-05-30 15:00:13 +02:00
|
|
|
meta_wayland_transaction_finalize (compositor);
|
|
|
|
|
2021-08-06 15:23:15 +02:00
|
|
|
g_clear_object (&compositor->dma_buf_manager);
|
2021-08-04 10:12:33 +02:00
|
|
|
|
2021-03-03 22:00:05 +01:00
|
|
|
g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
|
|
|
|
|
2023-01-27 15:16:14 +01:00
|
|
|
g_clear_pointer (&priv->filter_manager, meta_wayland_filter_manager_free);
|
2023-02-11 07:02:40 +01:00
|
|
|
g_clear_pointer (&priv->frame_callback_sources, g_hash_table_destroy);
|
2023-01-27 15:16:14 +01:00
|
|
|
|
2021-03-03 22:00:05 +01:00
|
|
|
g_clear_pointer (&compositor->display_name, g_free);
|
|
|
|
g_clear_pointer (&compositor->wayland_display, wl_display_destroy);
|
2021-10-28 15:30:41 +02:00
|
|
|
g_clear_pointer (&compositor->source, g_source_destroy);
|
2021-03-03 22:00:05 +01:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (meta_wayland_compositor_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2014-08-18 16:54:15 -04:00
|
|
|
static void
|
|
|
|
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
2023-01-27 15:16:14 +01:00
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
|
|
|
|
2018-04-06 15:47:50 +02:00
|
|
|
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
2014-08-18 16:54:15 -04:00
|
|
|
|
|
|
|
wl_log_set_handler_server (meta_wayland_log_func);
|
2012-01-07 22:21:32 +00:00
|
|
|
|
|
|
|
compositor->wayland_display = wl_display_create ();
|
|
|
|
if (compositor->wayland_display == NULL)
|
2014-08-18 16:54:15 -04:00
|
|
|
g_error ("Failed to create the global wl_display");
|
2023-01-27 15:16:14 +01:00
|
|
|
|
|
|
|
priv->filter_manager = meta_wayland_filter_manager_new (compositor);
|
2023-02-11 07:02:40 +01:00
|
|
|
priv->frame_callback_sources =
|
|
|
|
g_hash_table_new_full (NULL, NULL, NULL,
|
|
|
|
(GDestroyNotify) g_source_destroy);
|
2018-08-23 15:49:17 +02:00
|
|
|
}
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2018-08-23 15:49:17 +02:00
|
|
|
static void
|
|
|
|
meta_wayland_compositor_class_init (MetaWaylandCompositorClass *klass)
|
|
|
|
{
|
2021-03-03 22:00:05 +01:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->finalize = meta_wayland_compositor_finalize;
|
2022-06-15 13:12:35 +02:00
|
|
|
|
|
|
|
signals[PREPARE_SHUTDOWN] =
|
|
|
|
g_signal_new ("prepare-shutdown",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
2018-08-23 15:49:17 +02:00
|
|
|
}
|
|
|
|
|
2016-12-05 21:23:46 +08:00
|
|
|
void
|
2019-01-20 11:46:46 +01:00
|
|
|
meta_wayland_override_display_name (const char *display_name)
|
2016-12-05 21:23:46 +08:00
|
|
|
{
|
2017-08-18 14:18:14 +08:00
|
|
|
g_clear_pointer (&_display_name_override, g_free);
|
2016-12-05 21:23:46 +08:00
|
|
|
_display_name_override = g_strdup (display_name);
|
|
|
|
}
|
|
|
|
|
2021-05-06 12:12:34 +02:00
|
|
|
static void
|
|
|
|
meta_wayland_init_egl (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
2022-05-13 21:51:53 +02:00
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
2022-05-30 23:48:44 +02:00
|
|
|
MetaContext *context = meta_wayland_compositor_get_context (compositor);
|
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2021-05-06 12:12:34 +02:00
|
|
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
|
|
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
|
|
|
CoglContext *cogl_context =
|
|
|
|
clutter_backend_get_cogl_context (clutter_backend);
|
|
|
|
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
|
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
|
|
|
if (!meta_egl_has_extensions (egl, egl_display, NULL,
|
|
|
|
"EGL_WL_bind_wayland_display",
|
|
|
|
NULL))
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WAYLAND,
|
|
|
|
"Not binding Wayland display, missing extension");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_WAYLAND,
|
|
|
|
"Binding Wayland EGL display");
|
|
|
|
|
2022-05-13 21:51:53 +02:00
|
|
|
if (meta_egl_bind_wayland_display (egl,
|
|
|
|
egl_display,
|
|
|
|
compositor->wayland_display,
|
|
|
|
&error))
|
|
|
|
priv->is_wayland_egl_display_bound = TRUE;
|
|
|
|
else
|
2021-05-06 12:12:34 +02:00
|
|
|
g_warning ("Failed to bind Wayland display: %s", error->message);
|
|
|
|
}
|
|
|
|
|
2021-08-04 10:12:33 +02:00
|
|
|
static void
|
|
|
|
init_dma_buf_support (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
|
|
|
compositor->dma_buf_manager = meta_wayland_dma_buf_manager_new (compositor,
|
|
|
|
&error);
|
|
|
|
if (!compositor->dma_buf_manager)
|
|
|
|
{
|
|
|
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_WAYLAND,
|
|
|
|
"Wayland DMA buffer protocol support not enabled: %s",
|
|
|
|
error->message);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_warning ("Wayland DMA buffer protocol support not enabled: %s",
|
|
|
|
error->message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-06 16:02:34 +02:00
|
|
|
MetaWaylandCompositor *
|
|
|
|
meta_wayland_compositor_new (MetaContext *context)
|
2014-08-18 16:54:15 -04:00
|
|
|
{
|
2021-05-06 16:02:34 +02:00
|
|
|
MetaBackend *backend = meta_context_get_backend (context);
|
2021-03-03 22:00:05 +01:00
|
|
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
2021-05-06 16:02:34 +02:00
|
|
|
MetaWaylandCompositor *compositor;
|
2014-08-18 16:54:15 -04:00
|
|
|
GSource *wayland_event_source;
|
2023-02-10 16:15:40 +01:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2021-04-16 20:34:29 +02:00
|
|
|
MetaX11DisplayPolicy x11_display_policy;
|
2023-02-10 16:15:40 +01:00
|
|
|
#endif
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2021-05-06 16:02:34 +02:00
|
|
|
compositor = g_object_new (META_TYPE_WAYLAND_COMPOSITOR, NULL);
|
|
|
|
compositor->context = context;
|
|
|
|
|
2014-07-10 11:05:59 -04:00
|
|
|
wayland_event_source = wayland_event_source_new (compositor->wayland_display);
|
2012-01-07 22:21:32 +00:00
|
|
|
|
|
|
|
/* XXX: Here we are setting the wayland event source to have a
|
|
|
|
* slightly lower priority than the X event source, because we are
|
|
|
|
* much more likely to get confused being told about surface changes
|
|
|
|
* relating to X clients when we don't know what's happened to them
|
|
|
|
* according to the X protocol.
|
2014-10-07 20:51:28 -07:00
|
|
|
*/
|
2022-05-09 11:48:57 +02:00
|
|
|
g_source_set_priority (wayland_event_source, META_PRIORITY_EVENTS + 1);
|
2014-07-10 11:05:59 -04:00
|
|
|
g_source_attach (wayland_event_source, NULL);
|
2021-10-28 15:30:41 +02:00
|
|
|
compositor->source = wayland_event_source;
|
|
|
|
g_source_unref (wayland_event_source);
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2020-06-03 11:38:32 +02:00
|
|
|
g_signal_connect (stage, "after-update",
|
|
|
|
G_CALLBACK (on_after_update), compositor);
|
2020-10-08 15:34:28 +03:00
|
|
|
g_signal_connect (stage, "presented",
|
|
|
|
G_CALLBACK (on_presented), compositor);
|
2020-06-03 11:38:32 +02:00
|
|
|
|
2014-10-07 20:54:28 -07:00
|
|
|
if (!wl_global_create (compositor->wayland_display,
|
2022-01-03 19:36:26 +01:00
|
|
|
&wl_compositor_interface,
|
|
|
|
META_WL_COMPOSITOR_VERSION,
|
|
|
|
compositor, compositor_bind))
|
2014-10-07 20:54:28 -07:00
|
|
|
g_error ("Failed to register the global wl_compositor");
|
|
|
|
|
2021-05-06 12:12:34 +02:00
|
|
|
meta_wayland_init_egl (compositor);
|
2019-09-18 16:18:58 +02:00
|
|
|
meta_wayland_init_shm (compositor);
|
2014-08-19 18:27:21 -04:00
|
|
|
|
2014-04-22 18:05:44 -04:00
|
|
|
meta_wayland_outputs_init (compositor);
|
|
|
|
meta_wayland_data_device_manager_init (compositor);
|
2020-05-13 18:07:27 +02:00
|
|
|
meta_wayland_data_device_primary_manager_init (compositor);
|
2017-12-20 17:40:22 +08:00
|
|
|
meta_wayland_subsurfaces_init (compositor);
|
2014-04-22 18:05:44 -04:00
|
|
|
meta_wayland_shell_init (compositor);
|
2015-07-22 16:50:20 +02:00
|
|
|
meta_wayland_pointer_gestures_init (compositor);
|
2015-01-09 17:28:42 +01:00
|
|
|
meta_wayland_tablet_manager_init (compositor);
|
2014-04-22 18:05:44 -04:00
|
|
|
meta_wayland_seat_init (compositor);
|
2015-06-02 16:26:34 +08:00
|
|
|
meta_wayland_relative_pointer_init (compositor);
|
2015-06-17 12:10:52 +08:00
|
|
|
meta_wayland_pointer_constraints_init (compositor);
|
2015-09-24 08:05:25 +08:00
|
|
|
meta_wayland_xdg_foreign_init (compositor);
|
2020-02-06 02:00:56 -05:00
|
|
|
meta_wayland_legacy_xdg_foreign_init (compositor);
|
2021-08-04 10:12:33 +02:00
|
|
|
init_dma_buf_support (compositor);
|
2022-01-19 11:49:32 +01:00
|
|
|
meta_wayland_init_single_pixel_buffer_manager (compositor);
|
2017-03-21 11:47:16 +01:00
|
|
|
meta_wayland_keyboard_shortcuts_inhibit_init (compositor);
|
2017-06-14 11:27:14 +02:00
|
|
|
meta_wayland_surface_inhibit_shortcuts_dialog_init ();
|
2018-08-13 18:59:02 +02:00
|
|
|
meta_wayland_text_input_init (compositor);
|
2020-10-07 12:02:41 +03:00
|
|
|
meta_wayland_init_presentation_time (compositor);
|
2020-10-09 16:23:32 +02:00
|
|
|
meta_wayland_activation_init (compositor);
|
2021-05-30 15:00:13 +02:00
|
|
|
meta_wayland_transaction_init (compositor);
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2018-11-06 17:09:03 +01:00
|
|
|
#ifdef HAVE_WAYLAND_EGLSTREAM
|
2022-01-03 19:36:26 +01:00
|
|
|
{
|
|
|
|
gboolean should_enable_eglstream_controller = TRUE;
|
2021-10-14 18:36:43 +02:00
|
|
|
#if defined(HAVE_EGL_DEVICE) && defined(HAVE_NATIVE_BACKEND)
|
2022-01-03 19:36:26 +01:00
|
|
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
2021-10-14 18:36:43 +02:00
|
|
|
|
2022-01-03 19:36:26 +01:00
|
|
|
if (META_IS_RENDERER_NATIVE (renderer))
|
|
|
|
{
|
|
|
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
2021-10-14 18:36:43 +02:00
|
|
|
|
2022-01-03 19:36:26 +01:00
|
|
|
if (meta_renderer_native_get_mode (renderer_native) ==
|
|
|
|
META_RENDERER_NATIVE_MODE_GBM)
|
|
|
|
should_enable_eglstream_controller = FALSE;
|
|
|
|
}
|
2021-10-14 18:36:43 +02:00
|
|
|
#endif /* defined(HAVE_EGL_DEVICE) && defined(HAVE_NATIVE_BACKEND) */
|
|
|
|
|
2022-01-03 19:36:26 +01:00
|
|
|
if (should_enable_eglstream_controller)
|
|
|
|
meta_wayland_eglstream_controller_init (compositor);
|
|
|
|
}
|
2021-10-14 18:36:43 +02:00
|
|
|
#endif /* HAVE_WAYLAND_EGLSTREAM */
|
2017-06-27 16:37:30 -07:00
|
|
|
|
2023-02-10 16:15:40 +01:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2023-02-01 17:55:41 +01:00
|
|
|
meta_wayland_x11_interop_init (compositor);
|
|
|
|
|
2021-04-16 20:34:29 +02:00
|
|
|
x11_display_policy =
|
|
|
|
meta_context_get_x11_display_policy (compositor->context);
|
|
|
|
if (x11_display_policy != META_X11_DISPLAY_POLICY_DISABLED)
|
2017-08-27 20:44:58 +02:00
|
|
|
{
|
2020-12-08 17:42:05 +01:00
|
|
|
g_autoptr (GError) error = NULL;
|
|
|
|
|
|
|
|
if (!meta_xwayland_init (&compositor->xwayland_manager,
|
2021-05-06 18:49:25 +02:00
|
|
|
compositor,
|
2020-12-08 17:42:05 +01:00
|
|
|
compositor->wayland_display,
|
|
|
|
&error))
|
|
|
|
g_error ("Failed to start X Wayland: %s", error->message);
|
2017-08-27 20:44:58 +02:00
|
|
|
}
|
2022-06-13 10:09:26 +02:00
|
|
|
#endif
|
2015-07-02 10:41:37 +02:00
|
|
|
|
2016-12-05 21:23:46 +08:00
|
|
|
if (_display_name_override)
|
|
|
|
{
|
2017-08-18 14:18:14 +08:00
|
|
|
compositor->display_name = g_steal_pointer (&_display_name_override);
|
2016-12-05 21:23:46 +08:00
|
|
|
|
|
|
|
if (wl_display_add_socket (compositor->wayland_display,
|
2017-08-18 14:18:14 +08:00
|
|
|
compositor->display_name) != 0)
|
2016-12-05 21:23:46 +08:00
|
|
|
g_error ("Failed to create_socket");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-04 12:32:53 +08:00
|
|
|
const char *display_name;
|
|
|
|
|
|
|
|
display_name = wl_display_add_socket_auto (compositor->wayland_display);
|
|
|
|
if (!display_name)
|
2016-12-05 21:23:46 +08:00
|
|
|
g_error ("Failed to create socket");
|
2017-09-04 12:32:53 +08:00
|
|
|
|
|
|
|
compositor->display_name = g_strdup (display_name);
|
2016-12-05 21:23:46 +08:00
|
|
|
}
|
2012-01-07 22:21:32 +00:00
|
|
|
|
2020-10-20 21:38:05 +02:00
|
|
|
g_message ("Using Wayland display name '%s'", compositor->display_name);
|
|
|
|
|
2023-02-10 16:15:40 +01:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2021-04-16 20:34:29 +02:00
|
|
|
if (x11_display_policy != META_X11_DISPLAY_POLICY_DISABLED)
|
2019-06-18 16:12:46 +02:00
|
|
|
{
|
2019-11-14 23:51:45 +01:00
|
|
|
set_gnome_env ("GNOME_SETUP_DISPLAY", compositor->xwayland_manager.private_connection.name);
|
2019-07-19 22:50:31 +02:00
|
|
|
set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
|
2023-02-10 16:15:40 +01:00
|
|
|
set_gnome_env ("XAUTHORITY", compositor->xwayland_manager.auth_file);
|
2019-06-18 16:12:46 +02:00
|
|
|
}
|
2023-02-10 16:15:40 +01:00
|
|
|
#endif
|
2017-08-27 20:44:58 +02:00
|
|
|
|
2014-09-11 10:07:34 -04:00
|
|
|
set_gnome_env ("WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor));
|
2021-05-06 16:02:34 +02:00
|
|
|
|
|
|
|
return compositor;
|
2014-09-11 10:07:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return compositor->display_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
2021-01-21 18:56:18 +01:00
|
|
|
meta_wayland_get_public_xwayland_display_name (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return compositor->xwayland_manager.public_connection.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
meta_wayland_get_private_xwayland_display_name (MetaWaylandCompositor *compositor)
|
2014-09-11 10:07:34 -04:00
|
|
|
{
|
2019-07-19 22:50:31 +02:00
|
|
|
return compositor->xwayland_manager.private_connection.name;
|
2012-01-07 22:21:32 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 13:34:52 +01:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_restore_shortcuts (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterInputDevice *source)
|
|
|
|
{
|
|
|
|
MetaWaylandKeyboard *keyboard;
|
|
|
|
|
|
|
|
/* Clutter is not multi-seat aware yet, use the default seat instead */
|
|
|
|
keyboard = compositor->seat->keyboard;
|
|
|
|
if (!keyboard || !keyboard->focus_surface)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface,
|
|
|
|
compositor->seat))
|
|
|
|
return;
|
|
|
|
|
|
|
|
meta_wayland_surface_restore_shortcuts (keyboard->focus_surface,
|
|
|
|
compositor->seat);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_compositor_is_shortcuts_inhibited (MetaWaylandCompositor *compositor,
|
|
|
|
ClutterInputDevice *source)
|
|
|
|
{
|
|
|
|
MetaWaylandKeyboard *keyboard;
|
|
|
|
|
|
|
|
/* Clutter is not multi-seat aware yet, use the default seat instead */
|
|
|
|
keyboard = compositor->seat->keyboard;
|
|
|
|
if (keyboard && keyboard->focus_surface != NULL)
|
|
|
|
return meta_wayland_surface_is_shortcuts_inhibited (keyboard->focus_surface,
|
|
|
|
compositor->seat);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-08-18 14:16:22 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
wl_display_flush_clients (compositor->wayland_display);
|
|
|
|
}
|
2018-04-06 15:47:50 +02:00
|
|
|
|
|
|
|
static void on_scheduled_association_unmanaged (MetaWindow *window,
|
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_wayland_compositor_remove_surface_association (MetaWaylandCompositor *compositor,
|
|
|
|
int id)
|
|
|
|
{
|
|
|
|
MetaWindow *window;
|
|
|
|
|
|
|
|
window = g_hash_table_lookup (compositor->scheduled_surface_associations,
|
|
|
|
GINT_TO_POINTER (id));
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (window,
|
|
|
|
on_scheduled_association_unmanaged,
|
|
|
|
GINT_TO_POINTER (id));
|
|
|
|
g_hash_table_remove (compositor->scheduled_surface_associations,
|
|
|
|
GINT_TO_POINTER (id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_scheduled_association_unmanaged (MetaWindow *window,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2022-05-30 23:48:44 +02:00
|
|
|
MetaDisplay *display = meta_window_get_display (window);
|
|
|
|
MetaContext *context = meta_display_get_context (display);
|
|
|
|
MetaWaylandCompositor *compositor =
|
|
|
|
meta_context_get_wayland_compositor (context);
|
2018-04-06 15:47:50 +02:00
|
|
|
|
|
|
|
meta_wayland_compositor_remove_surface_association (compositor,
|
|
|
|
GPOINTER_TO_INT (user_data));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
|
|
|
|
int id,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
|
|
|
g_signal_connect (window, "unmanaged",
|
|
|
|
G_CALLBACK (on_scheduled_association_unmanaged),
|
|
|
|
GINT_TO_POINTER (id));
|
|
|
|
g_hash_table_insert (compositor->scheduled_surface_associations,
|
|
|
|
GINT_TO_POINTER (id), window);
|
|
|
|
}
|
|
|
|
|
2022-06-13 10:09:26 +02:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2018-04-06 15:47:50 +02:00
|
|
|
void
|
|
|
|
meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
|
|
|
|
int id,
|
|
|
|
MetaWaylandSurface *surface)
|
|
|
|
{
|
|
|
|
MetaWindow *window;
|
|
|
|
|
|
|
|
window = g_hash_table_lookup (compositor->scheduled_surface_associations,
|
|
|
|
GINT_TO_POINTER (id));
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
meta_xwayland_associate_window_with_surface (window, surface);
|
|
|
|
meta_wayland_compositor_remove_surface_association (compositor, id);
|
|
|
|
}
|
|
|
|
}
|
2022-06-13 10:09:26 +02:00
|
|
|
#endif
|
2022-05-13 21:51:53 +02:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_compositor_is_egl_display_bound (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
|
|
|
|
|
|
|
return priv->is_wayland_egl_display_bound;
|
|
|
|
}
|
2022-04-05 23:43:38 +02:00
|
|
|
|
2022-06-13 10:09:26 +02:00
|
|
|
#ifdef HAVE_XWAYLAND
|
2022-04-05 23:43:38 +02:00
|
|
|
MetaXWaylandManager *
|
|
|
|
meta_wayland_compositor_get_xwayland_manager (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return &compositor->xwayland_manager;
|
|
|
|
}
|
2022-06-13 10:09:26 +02:00
|
|
|
#endif
|
2022-08-01 21:18:42 +02:00
|
|
|
|
|
|
|
MetaContext *
|
|
|
|
meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return compositor->context;
|
|
|
|
}
|
2022-09-29 15:05:10 +02:00
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return meta_wayland_seat_is_grabbed (compositor->seat);
|
|
|
|
}
|
2023-01-27 15:15:15 +01:00
|
|
|
|
|
|
|
struct wl_display *
|
|
|
|
meta_wayland_compositor_get_wayland_display (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
return compositor->wayland_display;
|
|
|
|
}
|
2023-01-27 15:16:14 +01:00
|
|
|
|
|
|
|
MetaWaylandFilterManager *
|
|
|
|
meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor)
|
|
|
|
{
|
|
|
|
MetaWaylandCompositorPrivate *priv =
|
|
|
|
meta_wayland_compositor_get_instance_private (compositor);
|
|
|
|
|
|
|
|
return priv->filter_manager;
|
|
|
|
}
|