wayland: Refactor MetaWaylandSurfaceRoleCursor
Move into a standalone meta-wayland-surface-role-cursor.[ch], and make generic enough to work for pointe and additional (eg. tablet) cursors. Most notably, the sprite is now kept completely internal to the cursor role, and updates are routed through the given MetaCursorRenderer (which may be the default one for the pointer, or something else). The way cursor updates after cursor surface destruction has also been reworked, the pointer will just keep track of the last cursor surface, so older surfaces being destroyed don't trigger pointer rechecks/updates.
This commit is contained in:
parent
1acfcbda6c
commit
5849275b76
@ -296,6 +296,8 @@ libmutter_la_SOURCES += \
|
|||||||
wayland/meta-wayland-touch.h \
|
wayland/meta-wayland-touch.h \
|
||||||
wayland/meta-wayland-surface.c \
|
wayland/meta-wayland-surface.c \
|
||||||
wayland/meta-wayland-surface.h \
|
wayland/meta-wayland-surface.h \
|
||||||
|
wayland/meta-wayland-surface-role-cursor.c \
|
||||||
|
wayland/meta-wayland-surface-role-cursor.h \
|
||||||
wayland/meta-wayland-types.h \
|
wayland/meta-wayland-types.h \
|
||||||
wayland/meta-wayland-versions.h \
|
wayland/meta-wayland-versions.h \
|
||||||
wayland/meta-wayland-outputs.c \
|
wayland/meta-wayland-outputs.c \
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include "meta-wayland-private.h"
|
#include "meta-wayland-private.h"
|
||||||
#include "meta-wayland-surface.h"
|
#include "meta-wayland-surface.h"
|
||||||
#include "meta-wayland-buffer.h"
|
#include "meta-wayland-buffer.h"
|
||||||
|
#include "meta-wayland-surface-role-cursor.h"
|
||||||
#include "meta-xwayland.h"
|
#include "meta-xwayland.h"
|
||||||
#include "meta-cursor.h"
|
#include "meta-cursor.h"
|
||||||
#include "meta-cursor-tracker-private.h"
|
#include "meta-cursor-tracker-private.h"
|
||||||
@ -73,24 +74,6 @@
|
|||||||
|
|
||||||
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
|
||||||
|
|
||||||
struct _MetaWaylandSurfaceRoleCursor
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRole parent;
|
|
||||||
|
|
||||||
int hot_x;
|
|
||||||
int hot_y;
|
|
||||||
MetaCursorSprite *cursor_sprite;
|
|
||||||
|
|
||||||
MetaWaylandBuffer *buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
|
|
||||||
meta_wayland_surface_role_cursor,
|
|
||||||
META_TYPE_WAYLAND_SURFACE_ROLE);
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
|
|
||||||
|
|
||||||
static MetaWaylandPointerClient *
|
static MetaWaylandPointerClient *
|
||||||
meta_wayland_pointer_client_new (void)
|
meta_wayland_pointer_client_new (void)
|
||||||
{
|
{
|
||||||
@ -501,6 +484,12 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer)
|
|||||||
(gpointer) meta_wayland_pointer_on_cursor_changed,
|
(gpointer) meta_wayland_pointer_on_cursor_changed,
|
||||||
pointer);
|
pointer);
|
||||||
|
|
||||||
|
if (pointer->cursor_surface && pointer->cursor_surface_destroy_id)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (pointer->cursor_surface,
|
||||||
|
pointer->cursor_surface_destroy_id);
|
||||||
|
}
|
||||||
|
|
||||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||||
|
|
||||||
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
|
||||||
@ -928,7 +917,7 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
|||||||
*sy = wl_fixed_from_double (yf);
|
*sy = wl_fixed_from_double (yf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
||||||
{
|
{
|
||||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||||
@ -942,7 +931,7 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
|||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role);
|
META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role);
|
||||||
|
|
||||||
cursor_sprite = cursor_role->cursor_sprite;
|
cursor_sprite = meta_wayland_surface_role_cursor_get_sprite (cursor_role);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
|
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
|
||||||
@ -954,68 +943,14 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_cursor_sprite_texture (MetaWaylandSurface *surface)
|
ensure_update_cursor_surface (MetaWaylandPointer *pointer,
|
||||||
|
MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
MetaCursorRenderer *cursor_renderer =
|
if (pointer->cursor_surface != surface)
|
||||||
meta_backend_get_cursor_renderer (meta_get_backend ());
|
return;
|
||||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
|
||||||
MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite;
|
|
||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
|
||||||
|
|
||||||
g_return_if_fail (!buffer || buffer->texture);
|
pointer->cursor_surface = NULL;
|
||||||
|
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||||
if (buffer)
|
|
||||||
{
|
|
||||||
meta_cursor_sprite_set_texture (cursor_sprite,
|
|
||||||
buffer->texture,
|
|
||||||
cursor_role->hot_x * surface->scale,
|
|
||||||
cursor_role->hot_y * surface->scale);
|
|
||||||
|
|
||||||
if (cursor_role->buffer)
|
|
||||||
{
|
|
||||||
struct wl_resource *buffer_resource;
|
|
||||||
|
|
||||||
g_assert (cursor_role->buffer == buffer);
|
|
||||||
buffer_resource = buffer->resource;
|
|
||||||
meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer,
|
|
||||||
cursor_sprite,
|
|
||||||
buffer_resource);
|
|
||||||
|
|
||||||
meta_wayland_surface_unref_buffer_use_count (surface);
|
|
||||||
g_clear_object (&cursor_role->buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor_sprite == meta_cursor_tracker_get_displayed_cursor (cursor_tracker))
|
|
||||||
meta_cursor_renderer_force_update (cursor_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
|
|
||||||
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
|
|
||||||
MetaDisplay *display = meta_get_display ();
|
|
||||||
MetaScreen *screen = display->screen;
|
|
||||||
const MetaMonitorInfo *monitor;
|
|
||||||
|
|
||||||
if (!meta_xwayland_is_xwayland_surface (surface))
|
|
||||||
{
|
|
||||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
|
||||||
if (monitor)
|
|
||||||
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
|
||||||
(float)monitor->scale / surface->scale);
|
|
||||||
}
|
|
||||||
meta_wayland_surface_update_outputs (surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1025,14 +960,28 @@ meta_wayland_pointer_set_cursor_surface (MetaWaylandPointer *pointer,
|
|||||||
MetaWaylandSurface *prev_cursor_surface;
|
MetaWaylandSurface *prev_cursor_surface;
|
||||||
|
|
||||||
prev_cursor_surface = pointer->cursor_surface;
|
prev_cursor_surface = pointer->cursor_surface;
|
||||||
|
|
||||||
|
if (prev_cursor_surface == cursor_surface)
|
||||||
|
return;
|
||||||
|
|
||||||
pointer->cursor_surface = cursor_surface;
|
pointer->cursor_surface = cursor_surface;
|
||||||
|
|
||||||
if (prev_cursor_surface != cursor_surface)
|
if (prev_cursor_surface)
|
||||||
{
|
{
|
||||||
if (prev_cursor_surface)
|
meta_wayland_surface_update_outputs (prev_cursor_surface);
|
||||||
meta_wayland_surface_update_outputs (prev_cursor_surface);
|
g_signal_handler_disconnect (prev_cursor_surface,
|
||||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
pointer->cursor_surface_destroy_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cursor_surface)
|
||||||
|
{
|
||||||
|
pointer->cursor_surface_destroy_id =
|
||||||
|
g_signal_connect_swapped (cursor_surface, "destroy",
|
||||||
|
G_CALLBACK (ensure_update_cursor_surface),
|
||||||
|
pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_pointer_update_cursor_surface (pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1066,23 +1015,15 @@ pointer_set_cursor (struct wl_client *client,
|
|||||||
|
|
||||||
if (surface)
|
if (surface)
|
||||||
{
|
{
|
||||||
|
MetaCursorRenderer *cursor_renderer =
|
||||||
|
meta_backend_get_cursor_renderer (meta_get_backend ());
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role;
|
MetaWaylandSurfaceRoleCursor *cursor_role;
|
||||||
|
|
||||||
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||||
if (!cursor_role->cursor_sprite)
|
meta_wayland_surface_role_cursor_set_renderer (cursor_role,
|
||||||
{
|
cursor_renderer);
|
||||||
cursor_role->cursor_sprite = meta_cursor_sprite_new ();
|
meta_wayland_surface_role_cursor_set_hotspot (cursor_role,
|
||||||
g_signal_connect_object (cursor_role->cursor_sprite,
|
hot_x, hot_y);
|
||||||
"prepare-at",
|
|
||||||
G_CALLBACK (cursor_sprite_prepare_at),
|
|
||||||
cursor_role,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor_role->hot_x = hot_x;
|
|
||||||
cursor_role->hot_y = hot_y;
|
|
||||||
|
|
||||||
update_cursor_sprite_texture (surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_wayland_pointer_set_cursor_surface (pointer, surface);
|
meta_wayland_pointer_set_cursor_surface (pointer, surface);
|
||||||
@ -1255,136 +1196,3 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer)
|
|||||||
MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer);
|
MetaWaylandSeat *seat = wl_container_of (pointer, seat, pointer);
|
||||||
return seat;
|
return seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
|
||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
|
||||||
|
|
||||||
if (buffer)
|
|
||||||
{
|
|
||||||
g_set_object (&cursor_role->buffer, buffer);
|
|
||||||
meta_wayland_surface_ref_buffer_use_count (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_wayland_surface_queue_pending_frame_callbacks (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cursor_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
|
|
||||||
MetaWaylandPendingState *pending)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
|
||||||
|
|
||||||
if (pending->newly_attached && cursor_role->buffer)
|
|
||||||
{
|
|
||||||
meta_wayland_surface_unref_buffer_use_count (surface);
|
|
||||||
g_clear_object (&cursor_role->buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
|
||||||
MetaWaylandPendingState *pending)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (surface_role);
|
|
||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
|
||||||
|
|
||||||
if (pending->newly_attached)
|
|
||||||
{
|
|
||||||
g_set_object (&cursor_role->buffer, buffer);
|
|
||||||
if (cursor_role->buffer)
|
|
||||||
meta_wayland_surface_ref_buffer_use_count (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
|
||||||
|
|
||||||
if (pending->newly_attached)
|
|
||||||
update_cursor_sprite_texture (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
cursor_surface_role_is_on_output (MetaWaylandSurfaceRole *role,
|
|
||||||
MetaMonitorInfo *monitor)
|
|
||||||
{
|
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (role);
|
|
||||||
MetaWaylandPointer *pointer = &surface->compositor->seat->pointer;
|
|
||||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
|
||||||
MetaCursorRenderer *cursor_renderer =
|
|
||||||
meta_backend_get_cursor_renderer (meta_get_backend ());
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
|
||||||
MetaCursorSprite *displayed_cursor_sprite;
|
|
||||||
MetaRectangle rect;
|
|
||||||
|
|
||||||
if (surface != pointer->cursor_surface)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
displayed_cursor_sprite =
|
|
||||||
meta_cursor_tracker_get_displayed_cursor (cursor_tracker);
|
|
||||||
if (!displayed_cursor_sprite)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (cursor_role->cursor_sprite != displayed_cursor_sprite)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
|
||||||
cursor_role->cursor_sprite);
|
|
||||||
return meta_rectangle_overlap (&rect, &monitor->rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cursor_surface_role_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRoleCursor *cursor_role =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CURSOR (object);
|
|
||||||
MetaWaylandSurface *surface =
|
|
||||||
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
|
|
||||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
|
||||||
MetaWaylandPointer *pointer = &compositor->seat->pointer;
|
|
||||||
|
|
||||||
if (pointer->cursor_surface == surface)
|
|
||||||
pointer->cursor_surface = NULL;
|
|
||||||
meta_wayland_pointer_update_cursor_surface (pointer);
|
|
||||||
|
|
||||||
g_clear_object (&cursor_role->cursor_sprite);
|
|
||||||
|
|
||||||
if (cursor_role->buffer)
|
|
||||||
{
|
|
||||||
meta_wayland_surface_unref_buffer_use_count (surface);
|
|
||||||
g_clear_object (&cursor_role->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
|
|
||||||
{
|
|
||||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
surface_role_class->assigned = cursor_surface_role_assigned;
|
|
||||||
surface_role_class->pre_commit = cursor_surface_role_pre_commit;
|
|
||||||
surface_role_class->commit = cursor_surface_role_commit;
|
|
||||||
surface_role_class->is_on_output = cursor_surface_role_is_on_output;
|
|
||||||
|
|
||||||
object_class->dispose = cursor_surface_role_dispose;
|
|
||||||
}
|
|
||||||
|
@ -32,12 +32,6 @@
|
|||||||
|
|
||||||
#include <meta/meta-cursor-tracker.h>
|
#include <meta/meta-cursor-tracker.h>
|
||||||
|
|
||||||
#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
|
|
||||||
meta_wayland_surface_role_cursor,
|
|
||||||
META, WAYLAND_SURFACE_ROLE_CURSOR,
|
|
||||||
MetaWaylandSurfaceRole);
|
|
||||||
|
|
||||||
struct _MetaWaylandPointerGrabInterface
|
struct _MetaWaylandPointerGrabInterface
|
||||||
{
|
{
|
||||||
void (*focus) (MetaWaylandPointerGrab *grab,
|
void (*focus) (MetaWaylandPointerGrab *grab,
|
||||||
@ -75,6 +69,7 @@ struct _MetaWaylandPointer
|
|||||||
guint32 click_serial;
|
guint32 click_serial;
|
||||||
|
|
||||||
MetaWaylandSurface *cursor_surface;
|
MetaWaylandSurface *cursor_surface;
|
||||||
|
guint cursor_surface_destroy_id;
|
||||||
|
|
||||||
MetaWaylandPointerGrab *grab;
|
MetaWaylandPointerGrab *grab;
|
||||||
MetaWaylandPointerGrab default_grab;
|
MetaWaylandPointerGrab default_grab;
|
||||||
@ -151,4 +146,8 @@ void meta_wayland_relative_pointer_init (MetaWaylandCompositor *compositor);
|
|||||||
|
|
||||||
MetaWaylandSeat *meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer);
|
MetaWaylandSeat *meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer);
|
||||||
|
|
||||||
|
void meta_wayland_surface_cursor_update (MetaWaylandSurface *cursor_surface);
|
||||||
|
|
||||||
|
void meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer);
|
||||||
|
|
||||||
#endif /* META_WAYLAND_POINTER_H */
|
#endif /* META_WAYLAND_POINTER_H */
|
||||||
|
281
src/wayland/meta-wayland-surface-role-cursor.c
Normal file
281
src/wayland/meta-wayland-surface-role-cursor.c
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
/*
|
||||||
|
* Wayland Support
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <cogl/cogl.h>
|
||||||
|
#include <cogl/cogl-wayland-server.h>
|
||||||
|
#include "meta-wayland-surface-role-cursor.h"
|
||||||
|
#include "meta-wayland-buffer.h"
|
||||||
|
#include "meta-xwayland.h"
|
||||||
|
#include "screen-private.h"
|
||||||
|
|
||||||
|
struct _MetaWaylandSurfaceRoleCursor
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRole parent;
|
||||||
|
|
||||||
|
int hot_x;
|
||||||
|
int hot_y;
|
||||||
|
MetaCursorSprite *cursor_sprite;
|
||||||
|
MetaCursorRenderer *cursor_renderer;
|
||||||
|
MetaWaylandBuffer *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||||
|
meta_wayland_surface_role_cursor,
|
||||||
|
META_TYPE_WAYLAND_SURFACE_ROLE)
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
|
||||||
|
{
|
||||||
|
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_role));
|
||||||
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
|
MetaCursorSprite *cursor_sprite = cursor_role->cursor_sprite;
|
||||||
|
|
||||||
|
g_return_if_fail (!buffer || buffer->texture);
|
||||||
|
|
||||||
|
if (!cursor_role->cursor_renderer || !cursor_sprite)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
meta_cursor_sprite_set_texture (cursor_sprite,
|
||||||
|
buffer->texture,
|
||||||
|
cursor_role->hot_x * surface->scale,
|
||||||
|
cursor_role->hot_y * surface->scale);
|
||||||
|
|
||||||
|
if (cursor_role->buffer)
|
||||||
|
{
|
||||||
|
struct wl_resource *buffer_resource;
|
||||||
|
|
||||||
|
g_assert (cursor_role->buffer == buffer);
|
||||||
|
buffer_resource = buffer->resource;
|
||||||
|
meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_role->cursor_renderer,
|
||||||
|
cursor_sprite,
|
||||||
|
buffer_resource);
|
||||||
|
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&cursor_role->buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_cursor_renderer_force_update (cursor_role->cursor_renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
|
||||||
|
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
MetaScreen *screen = display->screen;
|
||||||
|
const MetaMonitorInfo *monitor;
|
||||||
|
|
||||||
|
if (!meta_xwayland_is_xwayland_surface (surface))
|
||||||
|
{
|
||||||
|
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||||
|
if (monitor)
|
||||||
|
meta_cursor_sprite_set_texture_scale (cursor_sprite,
|
||||||
|
(float) monitor->scale / surface->scale);
|
||||||
|
}
|
||||||
|
meta_wayland_surface_update_outputs (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
|
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
g_set_object (&cursor_role->buffer, buffer);
|
||||||
|
meta_wayland_surface_ref_buffer_use_count (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_surface_queue_pending_frame_callbacks (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandPendingState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
|
||||||
|
if (pending->newly_attached && cursor_role->buffer)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&cursor_role->buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandPendingState *pending)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
|
|
||||||
|
if (pending->newly_attached)
|
||||||
|
{
|
||||||
|
g_set_object (&cursor_role->buffer, buffer);
|
||||||
|
if (cursor_role->buffer)
|
||||||
|
meta_wayland_surface_ref_buffer_use_count (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||||
|
|
||||||
|
if (pending->newly_attached)
|
||||||
|
update_cursor_sprite_texture (META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cursor_surface_role_is_on_output (MetaWaylandSurfaceRole *role,
|
||||||
|
MetaMonitorInfo *monitor)
|
||||||
|
{
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (role);
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||||
|
MetaRectangle rect;
|
||||||
|
|
||||||
|
rect = meta_cursor_renderer_calculate_rect (cursor_role->cursor_renderer,
|
||||||
|
cursor_role->cursor_sprite);
|
||||||
|
return meta_rectangle_overlap (&rect, &monitor->rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_surface_role_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleCursor *cursor_role =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CURSOR (object);
|
||||||
|
MetaWaylandSurface *surface =
|
||||||
|
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (cursor_role->cursor_sprite,
|
||||||
|
cursor_sprite_prepare_at, cursor_role);
|
||||||
|
|
||||||
|
g_clear_object (&cursor_role->cursor_renderer);
|
||||||
|
g_clear_object (&cursor_role->cursor_sprite);
|
||||||
|
|
||||||
|
if (cursor_role->buffer)
|
||||||
|
{
|
||||||
|
meta_wayland_surface_unref_buffer_use_count (surface);
|
||||||
|
g_clear_object (&cursor_role->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
|
||||||
|
{
|
||||||
|
role->cursor_sprite = meta_cursor_sprite_new ();
|
||||||
|
g_signal_connect_object (role->cursor_sprite,
|
||||||
|
"prepare-at",
|
||||||
|
G_CALLBACK (cursor_sprite_prepare_at),
|
||||||
|
role,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
|
||||||
|
{
|
||||||
|
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||||
|
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
surface_role_class->assigned = cursor_surface_role_assigned;
|
||||||
|
surface_role_class->pre_commit = cursor_surface_role_pre_commit;
|
||||||
|
surface_role_class->commit = cursor_surface_role_commit;
|
||||||
|
surface_role_class->is_on_output = cursor_surface_role_is_on_output;
|
||||||
|
|
||||||
|
object_class->dispose = cursor_surface_role_dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaCursorSprite *
|
||||||
|
meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role)
|
||||||
|
{
|
||||||
|
return cursor_role->cursor_sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
gint hotspot_x,
|
||||||
|
gint hotspot_y)
|
||||||
|
{
|
||||||
|
if (cursor_role->hot_x == hotspot_x &&
|
||||||
|
cursor_role->hot_y == hotspot_y)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cursor_role->hot_x = hotspot_x;
|
||||||
|
cursor_role->hot_y = hotspot_y;
|
||||||
|
update_cursor_sprite_texture (cursor_role);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
gint *hotspot_x,
|
||||||
|
gint *hotspot_y)
|
||||||
|
{
|
||||||
|
if (hotspot_x)
|
||||||
|
*hotspot_x = cursor_role->hot_x;
|
||||||
|
if (hotspot_y)
|
||||||
|
*hotspot_y = cursor_role->hot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
MetaCursorRenderer *renderer)
|
||||||
|
{
|
||||||
|
if (cursor_role->cursor_renderer == renderer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (renderer)
|
||||||
|
g_object_ref (renderer);
|
||||||
|
if (cursor_role->cursor_renderer)
|
||||||
|
g_object_unref (cursor_role->cursor_renderer);
|
||||||
|
|
||||||
|
cursor_role->cursor_renderer = renderer;
|
||||||
|
update_cursor_sprite_texture (cursor_role);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaCursorRenderer *
|
||||||
|
meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role)
|
||||||
|
{
|
||||||
|
return cursor_role->cursor_renderer;
|
||||||
|
}
|
47
src/wayland/meta-wayland-surface-role-cursor.h
Normal file
47
src/wayland/meta-wayland-surface-role-cursor.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Wayland Support
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_SURFACE_ROLE_CURSOR_H
|
||||||
|
#define META_WAYLAND_SURFACE_ROLE_CURSOR_H
|
||||||
|
|
||||||
|
#include "meta-wayland-surface.h"
|
||||||
|
#include "backends/meta-cursor-renderer.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleCursor,
|
||||||
|
meta_wayland_surface_role_cursor,
|
||||||
|
META, WAYLAND_SURFACE_ROLE_CURSOR,
|
||||||
|
MetaWaylandSurfaceRole);
|
||||||
|
|
||||||
|
MetaCursorSprite * meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role);
|
||||||
|
|
||||||
|
void meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
gint hotspot_x,
|
||||||
|
gint hotspot_y);
|
||||||
|
void meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
gint *hotspot_x,
|
||||||
|
gint *hotspot_y);
|
||||||
|
void meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
|
||||||
|
MetaCursorRenderer *renderer);
|
||||||
|
MetaCursorRenderer * meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_SURFACE_ROLE_CURSOR_H */
|
Loading…
Reference in New Issue
Block a user