mirror of
https://github.com/brl/mutter.git
synced 2025-06-29 00:13:04 +00:00
screen-cast-window-stream: Add support for cursor modes
Make the RecordWindow method also understand the 'cursor-mode' property. For 'embedded' the cursor is drawn onto the pixel buffer using cairo, otherwise it works similarly to how RecordMonitor deals with it. https://gitlab.gnome.org/GNOME/mutter/merge_requests/413
This commit is contained in:
@ -383,6 +383,7 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
|
|||||||
GDBusInterfaceSkeleton *interface_skeleton;
|
GDBusInterfaceSkeleton *interface_skeleton;
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
MetaScreenCastCursorMode cursor_mode;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
GVariant *window_id_variant = NULL;
|
GVariant *window_id_variant = NULL;
|
||||||
@ -424,12 +425,28 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_variant_lookup (properties_variant, "cursor-mode", "u", &cursor_mode))
|
||||||
|
{
|
||||||
|
cursor_mode = META_SCREEN_CAST_CURSOR_MODE_HIDDEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!is_valid_cursor_mode (cursor_mode))
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_FAILED,
|
||||||
|
"Unknown cursor mode");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
|
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
|
||||||
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
|
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
|
||||||
|
|
||||||
window_stream = meta_screen_cast_window_stream_new (session,
|
window_stream = meta_screen_cast_window_stream_new (session,
|
||||||
connection,
|
connection,
|
||||||
window,
|
window,
|
||||||
|
cursor_mode,
|
||||||
&error);
|
&error);
|
||||||
if (!window_stream)
|
if (!window_stream)
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "backends/meta-screen-cast-window-stream-src.h"
|
#include "backends/meta-screen-cast-window-stream-src.h"
|
||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
|
#include "backends/meta-screen-cast-session.h"
|
||||||
#include "backends/meta-screen-cast-window.h"
|
#include "backends/meta-screen-cast-window.h"
|
||||||
#include "backends/meta-screen-cast-window-stream.h"
|
#include "backends/meta-screen-cast-window-stream.h"
|
||||||
#include "compositor/meta-window-actor-private.h"
|
#include "compositor/meta-window-actor-private.h"
|
||||||
@ -33,14 +34,32 @@ struct _MetaScreenCastWindowStreamSrc
|
|||||||
|
|
||||||
MetaScreenCastWindow *screen_cast_window;
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
|
|
||||||
|
unsigned long screen_cast_window_before_paint_handler_id;
|
||||||
unsigned long screen_cast_window_after_paint_handler_id;
|
unsigned long screen_cast_window_after_paint_handler_id;
|
||||||
unsigned long screen_cast_window_destroyed_handler_id;
|
unsigned long screen_cast_window_destroyed_handler_id;
|
||||||
|
unsigned long cursor_moved_handler_id;
|
||||||
|
unsigned long cursor_changed_handler_id;
|
||||||
|
|
||||||
|
gboolean actor_was_dirty;
|
||||||
|
gboolean cursor_bitmap_invalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaScreenCastWindowStreamSrc,
|
G_DEFINE_TYPE (MetaScreenCastWindowStreamSrc,
|
||||||
meta_screen_cast_window_stream_src,
|
meta_screen_cast_window_stream_src,
|
||||||
META_TYPE_SCREEN_CAST_STREAM_SRC)
|
META_TYPE_SCREEN_CAST_STREAM_SRC)
|
||||||
|
|
||||||
|
static MetaBackend *
|
||||||
|
get_backend (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||||
|
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||||
|
MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
|
||||||
|
MetaScreenCast *screen_cast =
|
||||||
|
meta_screen_cast_session_get_screen_cast (session);
|
||||||
|
|
||||||
|
return meta_screen_cast_get_backend (screen_cast);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaScreenCastWindowStream *
|
static MetaScreenCastWindowStream *
|
||||||
get_window_stream (MetaScreenCastWindowStreamSrc *window_src)
|
get_window_stream (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
{
|
{
|
||||||
@ -83,11 +102,91 @@ get_stream_height (MetaScreenCastWindowStreamSrc *window_src)
|
|||||||
return meta_screen_cast_window_stream_get_height (window_stream);
|
return meta_screen_cast_window_stream_get_height (window_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maybe_draw_cursor_sprite (MetaScreenCastWindowStreamSrc *window_src,
|
||||||
|
uint8_t *data,
|
||||||
|
MetaRectangle *stream_rect)
|
||||||
|
{
|
||||||
|
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||||
|
MetaBackend *backend = get_backend (window_src);
|
||||||
|
MetaCursorRenderer *cursor_renderer =
|
||||||
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorSprite *cursor_sprite;
|
||||||
|
CoglTexture *cursor_texture;
|
||||||
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
|
ClutterPoint cursor_position;
|
||||||
|
ClutterPoint relative_cursor_position;
|
||||||
|
cairo_surface_t *cursor_surface;
|
||||||
|
uint8_t *cursor_surface_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
cairo_surface_t *stream_surface;
|
||||||
|
int width, height;
|
||||||
|
float scale;
|
||||||
|
int hotspot_x, hotspot_y;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||||
|
if (!cursor_sprite)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cursor_texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||||
|
if (!cursor_texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
screen_cast_window = window_src->screen_cast_window;
|
||||||
|
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
||||||
|
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
|
cursor_sprite,
|
||||||
|
&cursor_position,
|
||||||
|
&scale,
|
||||||
|
&relative_cursor_position))
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_cursor_sprite_get_hotspot (cursor_sprite, &hotspot_x, &hotspot_y);
|
||||||
|
|
||||||
|
width = cogl_texture_get_width (cursor_texture) * scale;
|
||||||
|
height = cogl_texture_get_height (cursor_texture) * scale;
|
||||||
|
cursor_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
cursor_surface_data = cairo_image_surface_get_data (cursor_surface);
|
||||||
|
if (!meta_screen_cast_stream_src_draw_cursor_into (src,
|
||||||
|
cursor_texture,
|
||||||
|
scale,
|
||||||
|
cursor_surface_data,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to draw cursor: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
cairo_surface_destroy (cursor_surface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_surface =
|
||||||
|
cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
|
||||||
|
stream_rect->width,
|
||||||
|
stream_rect->height,
|
||||||
|
stream_rect->width * 4);
|
||||||
|
|
||||||
|
cr = cairo_create (stream_surface);
|
||||||
|
cairo_surface_mark_dirty (cursor_surface);
|
||||||
|
cairo_surface_flush (cursor_surface);
|
||||||
|
cairo_set_source_surface (cr, cursor_surface,
|
||||||
|
relative_cursor_position.x - hotspot_x * scale,
|
||||||
|
relative_cursor_position.y - hotspot_y * scale);
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
cairo_surface_destroy (stream_surface);
|
||||||
|
cairo_surface_destroy (cursor_surface);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
capture_into (MetaScreenCastWindowStreamSrc *window_src,
|
capture_into (MetaScreenCastWindowStreamSrc *window_src,
|
||||||
uint8_t *data)
|
uint8_t *data)
|
||||||
{
|
{
|
||||||
|
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||||
MetaRectangle stream_rect;
|
MetaRectangle stream_rect;
|
||||||
|
MetaScreenCastStream *stream;
|
||||||
|
|
||||||
stream_rect.x = 0;
|
stream_rect.x = 0;
|
||||||
stream_rect.y = 0;
|
stream_rect.y = 0;
|
||||||
@ -97,6 +196,17 @@ capture_into (MetaScreenCastWindowStreamSrc *window_src,
|
|||||||
meta_screen_cast_window_capture_into (window_src->screen_cast_window,
|
meta_screen_cast_window_capture_into (window_src->screen_cast_window,
|
||||||
&stream_rect, data);
|
&stream_rect, data);
|
||||||
|
|
||||||
|
stream = meta_screen_cast_stream_src_get_stream (src);
|
||||||
|
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||||
|
{
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||||
|
maybe_draw_cursor_sprite (window_src, data, &stream_rect);
|
||||||
|
break;
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,9 +249,16 @@ static void
|
|||||||
meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_src)
|
meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
MetaBackend *backend = get_backend (window_src);
|
||||||
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
|
|
||||||
if (!window_src->screen_cast_window)
|
if (!window_src->screen_cast_window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (window_src->screen_cast_window_before_paint_handler_id)
|
||||||
|
g_signal_handler_disconnect (window_src->screen_cast_window,
|
||||||
|
window_src->screen_cast_window_before_paint_handler_id);
|
||||||
|
window_src->screen_cast_window_before_paint_handler_id = 0;
|
||||||
|
|
||||||
if (window_src->screen_cast_window_after_paint_handler_id)
|
if (window_src->screen_cast_window_after_paint_handler_id)
|
||||||
g_signal_handler_disconnect (window_src->screen_cast_window,
|
g_signal_handler_disconnect (window_src->screen_cast_window,
|
||||||
@ -152,23 +269,97 @@ meta_screen_cast_window_stream_src_stop (MetaScreenCastWindowStreamSrc *window_s
|
|||||||
g_signal_handler_disconnect (window_src->screen_cast_window,
|
g_signal_handler_disconnect (window_src->screen_cast_window,
|
||||||
window_src->screen_cast_window_destroyed_handler_id);
|
window_src->screen_cast_window_destroyed_handler_id);
|
||||||
window_src->screen_cast_window_destroyed_handler_id = 0;
|
window_src->screen_cast_window_destroyed_handler_id = 0;
|
||||||
|
|
||||||
|
if (window_src->cursor_moved_handler_id)
|
||||||
|
g_signal_handler_disconnect (cursor_tracker,
|
||||||
|
window_src->cursor_moved_handler_id);
|
||||||
|
window_src->cursor_moved_handler_id = 0;
|
||||||
|
|
||||||
|
if (window_src->cursor_changed_handler_id)
|
||||||
|
g_signal_handler_disconnect (cursor_tracker,
|
||||||
|
window_src->cursor_changed_handler_id);
|
||||||
|
window_src->cursor_changed_handler_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_cast_window_after_paint (MetaScreenCastWindow *screen_cast_window,
|
screen_cast_window_before_paint (MetaScreenCastWindow *screen_cast_window,
|
||||||
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
window_src->actor_was_dirty =
|
||||||
|
meta_screen_cast_window_has_damage (screen_cast_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
screen_cast_window_after_paint (MetaWindowActor *actor,
|
||||||
MetaScreenCastWindowStreamSrc *window_src)
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
if (window_src->actor_was_dirty)
|
||||||
|
{
|
||||||
|
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||||
|
|
||||||
|
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
screen_cast_window_destroyed (MetaWindowActor *actor,
|
||||||
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
meta_screen_cast_window_stream_src_stop (window_src);
|
||||||
|
window_src->screen_cast_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_cursor_in_stream (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
MetaBackend *backend = get_backend (window_src);
|
||||||
|
MetaCursorRenderer *cursor_renderer =
|
||||||
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaCursorSprite *cursor_sprite;
|
||||||
|
ClutterPoint cursor_position;
|
||||||
|
MetaScreenCastWindow *screen_cast_window;
|
||||||
|
|
||||||
|
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||||
|
|
||||||
|
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
||||||
|
|
||||||
|
screen_cast_window = window_src->screen_cast_window;
|
||||||
|
return meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
|
cursor_sprite,
|
||||||
|
&cursor_position,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
{
|
{
|
||||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||||
|
|
||||||
|
if (!is_cursor_in_stream (window_src))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
|
||||||
|
return;
|
||||||
|
|
||||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_cast_window_destroyed (MetaScreenCastWindow *screen_cast_window,
|
cursor_moved (MetaCursorTracker *cursor_tracker,
|
||||||
MetaScreenCastWindowStreamSrc *window_src)
|
float x,
|
||||||
|
float y,
|
||||||
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
{
|
{
|
||||||
meta_screen_cast_window_stream_src_stop (window_src);
|
sync_cursor_state (window_src);
|
||||||
window_src->screen_cast_window = NULL;
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cursor_changed (MetaCursorTracker *cursor_tracker,
|
||||||
|
MetaScreenCastWindowStreamSrc *window_src)
|
||||||
|
{
|
||||||
|
window_src->cursor_bitmap_invalid = TRUE;
|
||||||
|
sync_cursor_state (window_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -176,7 +367,10 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
|
|||||||
{
|
{
|
||||||
MetaScreenCastWindowStreamSrc *window_src =
|
MetaScreenCastWindowStreamSrc *window_src =
|
||||||
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
||||||
|
MetaBackend *backend = get_backend (window_src);
|
||||||
|
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||||
MetaWindowActor *window_actor;
|
MetaWindowActor *window_actor;
|
||||||
|
MetaScreenCastStream *stream;
|
||||||
|
|
||||||
window_actor = meta_window_actor_from_window (get_window (window_src));
|
window_actor = meta_window_actor_from_window (get_window (window_src));
|
||||||
if (!window_actor)
|
if (!window_actor)
|
||||||
@ -184,6 +378,11 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
|
|||||||
|
|
||||||
window_src->screen_cast_window = META_SCREEN_CAST_WINDOW (window_actor);
|
window_src->screen_cast_window = META_SCREEN_CAST_WINDOW (window_actor);
|
||||||
|
|
||||||
|
window_src->screen_cast_window_before_paint_handler_id =
|
||||||
|
g_signal_connect (window_src->screen_cast_window,
|
||||||
|
"paint",
|
||||||
|
G_CALLBACK (screen_cast_window_before_paint),
|
||||||
|
window_src);
|
||||||
window_src->screen_cast_window_after_paint_handler_id =
|
window_src->screen_cast_window_after_paint_handler_id =
|
||||||
g_signal_connect_after (window_src->screen_cast_window,
|
g_signal_connect_after (window_src->screen_cast_window,
|
||||||
"paint",
|
"paint",
|
||||||
@ -195,6 +394,24 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
|
|||||||
"destroy",
|
"destroy",
|
||||||
G_CALLBACK (screen_cast_window_destroyed),
|
G_CALLBACK (screen_cast_window_destroyed),
|
||||||
window_src);
|
window_src);
|
||||||
|
|
||||||
|
stream = meta_screen_cast_stream_src_get_stream (src);
|
||||||
|
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||||
|
{
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||||
|
window_src->cursor_moved_handler_id =
|
||||||
|
g_signal_connect_after (cursor_tracker, "cursor-moved",
|
||||||
|
G_CALLBACK (cursor_moved),
|
||||||
|
window_src);
|
||||||
|
window_src->cursor_changed_handler_id =
|
||||||
|
g_signal_connect_after (cursor_tracker, "cursor-changed",
|
||||||
|
G_CALLBACK (cursor_changed),
|
||||||
|
window_src);
|
||||||
|
break;
|
||||||
|
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -218,6 +435,65 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
|
||||||
|
struct spa_meta_cursor *spa_meta_cursor)
|
||||||
|
{
|
||||||
|
MetaScreenCastWindowStreamSrc *window_src =
|
||||||
|
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
||||||
|
MetaBackend *backend = get_backend (window_src);
|
||||||
|
MetaCursorRenderer *cursor_renderer =
|
||||||
|
meta_backend_get_cursor_renderer (backend);
|
||||||
|
MetaScreenCastWindow *screen_cast_window = window_src->screen_cast_window;
|
||||||
|
MetaCursorSprite *cursor_sprite;
|
||||||
|
ClutterPoint cursor_position;
|
||||||
|
float scale;
|
||||||
|
ClutterPoint relative_cursor_position;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||||
|
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
||||||
|
|
||||||
|
if (!meta_screen_cast_window_transform_cursor_position (screen_cast_window,
|
||||||
|
cursor_sprite,
|
||||||
|
&cursor_position,
|
||||||
|
&scale,
|
||||||
|
&relative_cursor_position))
|
||||||
|
{
|
||||||
|
meta_screen_cast_stream_src_unset_cursor_metadata (src,
|
||||||
|
spa_meta_cursor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = (int) roundf (relative_cursor_position.x);
|
||||||
|
y = (int) roundf (relative_cursor_position.y);
|
||||||
|
|
||||||
|
if (window_src->cursor_bitmap_invalid)
|
||||||
|
{
|
||||||
|
if (cursor_sprite)
|
||||||
|
{
|
||||||
|
meta_screen_cast_stream_src_set_cursor_sprite_metadata (src,
|
||||||
|
spa_meta_cursor,
|
||||||
|
cursor_sprite,
|
||||||
|
x, y,
|
||||||
|
scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src,
|
||||||
|
spa_meta_cursor,
|
||||||
|
x, y);
|
||||||
|
}
|
||||||
|
window_src->cursor_bitmap_invalid = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_screen_cast_stream_src_set_cursor_position_metadata (src,
|
||||||
|
spa_meta_cursor,
|
||||||
|
x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MetaScreenCastWindowStreamSrc *
|
MetaScreenCastWindowStreamSrc *
|
||||||
meta_screen_cast_window_stream_src_new (MetaScreenCastWindowStream *window_stream,
|
meta_screen_cast_window_stream_src_new (MetaScreenCastWindowStream *window_stream,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -230,6 +506,7 @@ meta_screen_cast_window_stream_src_new (MetaScreenCastWindowStream *window_stre
|
|||||||
static void
|
static void
|
||||||
meta_screen_cast_window_stream_src_init (MetaScreenCastWindowStreamSrc *window_src)
|
meta_screen_cast_window_stream_src_init (MetaScreenCastWindowStreamSrc *window_src)
|
||||||
{
|
{
|
||||||
|
window_src->cursor_bitmap_invalid = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -243,4 +520,5 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
|
|||||||
src_class->disable = meta_screen_cast_window_stream_src_disable;
|
src_class->disable = meta_screen_cast_window_stream_src_disable;
|
||||||
src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
|
src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
|
||||||
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
|
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
|
||||||
|
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
|
||||||
}
|
}
|
||||||
|
@ -80,16 +80,18 @@ meta_screen_cast_window_stream_get_height (MetaScreenCastWindowStream *window_st
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaScreenCastWindowStream *
|
MetaScreenCastWindowStream *
|
||||||
meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
|
meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
|
||||||
GDBusConnection *connection,
|
GDBusConnection *connection,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
GError **error)
|
MetaScreenCastCursorMode cursor_mode,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM,
|
return g_initable_new (META_TYPE_SCREEN_CAST_WINDOW_STREAM,
|
||||||
NULL,
|
NULL,
|
||||||
error,
|
error,
|
||||||
"session", session,
|
"session", session,
|
||||||
"connection", connection,
|
"connection", connection,
|
||||||
|
"cursor-mode", cursor_mode,
|
||||||
"window", window,
|
"window", window,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,11 @@ G_DECLARE_FINAL_TYPE (MetaScreenCastWindowStream,
|
|||||||
META, SCREEN_CAST_WINDOW_STREAM,
|
META, SCREEN_CAST_WINDOW_STREAM,
|
||||||
MetaScreenCastStream)
|
MetaScreenCastStream)
|
||||||
|
|
||||||
MetaScreenCastWindowStream * meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
|
MetaScreenCastWindowStream * meta_screen_cast_window_stream_new (MetaScreenCastSession *session,
|
||||||
GDBusConnection *connection,
|
GDBusConnection *connection,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
GError **error);
|
MetaScreenCastCursorMode cursor_mode,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
MetaWindow * meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream);
|
MetaWindow * meta_screen_cast_window_stream_get_window (MetaScreenCastWindowStream *window_stream);
|
||||||
int meta_screen_cast_window_stream_get_width (MetaScreenCastWindowStream *window_stream);
|
int meta_screen_cast_window_stream_get_width (MetaScreenCastWindowStream *window_stream);
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
Available @properties include:
|
Available @properties include:
|
||||||
|
|
||||||
* "window-id" (t): Id of the window to record.
|
* "window-id" (t): Id of the window to record.
|
||||||
|
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see RecordMonitor)
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<method name="RecordWindow">
|
<method name="RecordWindow">
|
||||||
|
Reference in New Issue
Block a user