Compare commits

..

2 Commits

Author SHA1 Message Date
Carlos Garnacho
6dda417773 backends/input-mapper: Add some g_debug() traces to MetaInputMapper
Add some debug statements to mapping_helper_apply(), enough to work out
the heuristic decisions that were taken.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1202
2020-04-16 16:31:45 +02:00
Carlos Garnacho
d4bc355ee9 backends/input-mapper: Implement score mechanism to assign the most relevant output
We used to pick the "best" output for each builtin/size/edid categories,
and then pick the "best" (in that order) of those for each input device.
This is most often enough, but is prone to wrong results in some corner
cases (eg. 2 outputs with the exact same dimensions).

Change this to a score mechanism that doesn't leave outputs out. The
weights are the same, but the score is accumulated if an output matches
multiple categories. All outputs are evaluated and sorted by score, and
input devices with the best matches are applied first (as they already
did).

This should break the tie if eg. there's 2 outputs with similar dimensions,
but one of them has some EDID match in addition. The output with multiple
matches will score higher up, while it might have been entirely discarded
with the previous implementation.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1175

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1202
2020-04-16 16:31:14 +02:00
125 changed files with 2170 additions and 6206 deletions

33
NEWS
View File

@@ -1,36 +1,3 @@
3.37.1
======
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
* Make window-aliveness checks less aggressive [Jonas Å.; !1182]
* Fix stylus coordinates when using screen rotation [Jonas T.; #1118]
* Preserve keyboard state on VT switch [Olivier; !1185]
* Remove Clutter's drag and drop actions [Jonas D.; !789]
* Cancel clicks/gestures actions on disable [Georges; !1188]
* Fix various clipboard issues [Carlos; !1186, !1198, !1203, !1204, !1206]
* Fix trackball button scrolling [Phillip; #1120]
* Fix tiled monitor support [Jonas; !1199]
* Support unredirecting fullscreen wayland surfaces [Jonas Å.; !798]
* Support area screencasts [Jonas Å.; !1207]
* Synchronize shadows to server-side decorations [Olivier; !1214]
* Allow inhibiting remote access [Jonas Å.; !1212]
* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219]
* Fixed crashes [Jonas, D., Carlos; !1173, !1183, !1012]
* Misc. bug fixes and cleanups [Andre, Georges, Christian, Jonas Å., Andre,
Simon, Florian, Carlos, Adam, Marco, Thomas, Elias, Pekka, Jonas D.,
Laurent; !1169, !1168, !1166, !1170, !1167, !1172, !1175, !1176, !1184,
!1126, !1187, !1191, !1195, !1179, !1200, !1193, !1209, !1213, !1208,
#1074, !1223]
Contributors:
Marco Trevisan (Treviño), Elias Aebi, Thomas Hindoe Paaboel Andersen,
Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
Adam Jackson, Andre Moreira Magalhaes, Simon McVittie, Florian Müllner,
Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger,
Phillip Wood, Jonas Ådahl
Translators:
Dušan Kazik [sk], Christian Kirbach [de]
3.36.0
======
* Fix placement of popup windows in multi-monitor setups [Jonas; !1110]

View File

@@ -19960,23 +19960,6 @@ clutter_actor_get_transition (ClutterActor *self,
return clos->transition;
}
/**
* clutter_actor_has_transitions: (skip)
*/
gboolean
clutter_actor_has_transitions (ClutterActor *self)
{
const ClutterAnimationInfo *info;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
info = _clutter_actor_get_animation_info_or_defaults (self);
if (info->transitions == NULL)
return FALSE;
return g_hash_table_size (info->transitions) > 0;
}
/**
* clutter_actor_save_easing_state:
* @self: a #ClutterActor

View File

@@ -9,13 +9,7 @@
G_BEGIN_DECLS
#mesondefine CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#mesondefine CLUTTER_WINDOWING_X11
#mesondefine CLUTTER_INPUT_X11
#mesondefine CLUTTER_WINDOWING_GLX
#mesondefine CLUTTER_WINDOWING_EGL
#mesondefine CLUTTER_INPUT_EVDEV
#mesondefine CLUTTER_INPUT_NULL
@CLUTTER_CONFIG_DEFINES@
G_END_DECLS

View File

@@ -36,9 +36,6 @@
#include "cogl/clutter-stage-cogl.h"
#include "clutter/x11/clutter-backend-x11.h"
CLUTTER_EXPORT
GList * clutter_stage_peek_stage_views (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
@@ -51,23 +48,6 @@ void clutter_stage_capture_into (ClutterStage *stage,
cairo_rectangle_int_t *rect,
uint8_t *data);
CLUTTER_EXPORT
void clutter_stage_paint_to_framebuffer (ClutterStage *stage,
CoglFramebuffer *framebuffer,
const cairo_rectangle_int_t *rect,
float scale,
ClutterPaintFlag paint_flags);
CLUTTER_EXPORT
gboolean clutter_stage_paint_to_buffer (ClutterStage *stage,
const cairo_rectangle_int_t *rect,
float scale,
uint8_t *data,
int stride,
CoglPixelFormat format,
ClutterPaintFlag paint_flags,
GError **error);
CLUTTER_EXPORT
void clutter_stage_freeze_updates (ClutterStage *stage);
@@ -77,16 +57,9 @@ void clutter_stage_thaw_updates (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_update_resource_scales (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
CoglScanout *scanout);
CLUTTER_EXPORT
gboolean clutter_actor_has_damage (ClutterActor *actor);
CLUTTER_EXPORT
gboolean clutter_actor_has_transitions (ClutterActor *actor);
#undef __CLUTTER_H_INSIDE__
#endif /* __CLUTTER_MUTTER_H__ */

View File

@@ -21,8 +21,7 @@
#include "clutter-paint-context.h"
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags);
const cairo_region_t *redraw_clip);
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);

View File

@@ -23,8 +23,6 @@ struct _ClutterPaintContext
{
grefcount ref_count;
ClutterPaintFlag paint_flags;
GList *framebuffers;
ClutterStageView *view;
@@ -38,8 +36,7 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
ClutterPaintContext *
clutter_paint_context_new_for_view (ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags)
const cairo_region_t *redraw_clip)
{
ClutterPaintContext *paint_context;
CoglFramebuffer *framebuffer;
@@ -48,7 +45,6 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
g_ref_count_init (&paint_context->ref_count);
paint_context->view = view;
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
paint_context->paint_flags = paint_flags;
framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
@@ -60,16 +56,12 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
* clutter_paint_context_new_for_framebuffer: (skip)
*/
ClutterPaintContext *
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags)
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
{
ClutterPaintContext *paint_context;
paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count);
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
paint_context->paint_flags = paint_flags;
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
@@ -178,12 +170,3 @@ clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context)
return !paint_context->view;
}
/**
* clutter_paint_context_get_paint_flags: (skip)
*/
ClutterPaintFlag
clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context)
{
return paint_context->paint_flags;
}

View File

@@ -29,21 +29,13 @@
typedef struct _ClutterPaintContext ClutterPaintContext;
typedef enum _ClutterPaintFlag
{
CLUTTER_PAINT_FLAG_NONE = 0,
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
} ClutterPaintFlag;
#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ())
CLUTTER_EXPORT
GType clutter_paint_context_get_type (void);
CLUTTER_EXPORT
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
const cairo_region_t *redraw_clip,
ClutterPaintFlag paint_flags);
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer);
CLUTTER_EXPORT
ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context);
@@ -70,7 +62,4 @@ void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context);
CLUTTER_EXPORT
ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context);
#endif /* CLUTTER_PAINT_CONTEXT_H */

View File

@@ -139,6 +139,8 @@ void _clutter_stage_presented (ClutterStage *stag
CoglFrameEvent frame_event,
ClutterFrameInfo *frame_info);
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
ClutterActor *actor);

View File

@@ -43,6 +43,4 @@ const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *vi
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@@ -24,8 +24,6 @@
#include <math.h>
#include "clutter/clutter-private.h"
#include "clutter/clutter-mutter.h"
#include "cogl/cogl.h"
enum
{
@@ -54,8 +52,6 @@ typedef struct _ClutterStageViewPrivate
CoglOffscreen *shadowfb;
CoglPipeline *shadowfb_pipeline;
CoglScanout *next_scanout;
gboolean has_redraw_clip;
cairo_region_t *redraw_clip;
@@ -411,25 +407,6 @@ clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *vie
cogl_matrix_init_identity (matrix);
}
void
clutter_stage_view_assign_next_scanout (ClutterStageView *view,
CoglScanout *scanout)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
g_set_object (&priv->next_scanout, scanout);
}
CoglScanout *
clutter_stage_view_take_scanout (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return g_steal_pointer (&priv->next_scanout);
}
static void
clutter_stage_view_get_property (GObject *object,
guint prop_id,

View File

@@ -552,7 +552,7 @@ clutter_stage_add_redraw_clip (ClutterStage *stage,
{
GList *l;
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
@@ -924,8 +924,7 @@ clutter_stage_do_paint_view (ClutterStage *stage,
ClutterPaintContext *paint_context;
cairo_rectangle_int_t clip_rect;
paint_context = clutter_paint_context_new_for_view (view, redraw_clip,
CLUTTER_PAINT_FLAG_NONE);
paint_context = clutter_paint_context_new_for_view (view, redraw_clip);
cairo_region_get_extents (redraw_clip, &clip_rect);
setup_view_for_pick_or_paint (stage, view, &clip_rect);
@@ -1573,7 +1572,7 @@ is_full_stage_redraw_queued (ClutterStage *stage)
{
GList *l;
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
@@ -4164,97 +4163,6 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
return TRUE;
}
void
clutter_stage_paint_to_framebuffer (ClutterStage *stage,
CoglFramebuffer *framebuffer,
const cairo_rectangle_int_t *rect,
float scale,
ClutterPaintFlag paint_flags)
{
ClutterStagePrivate *priv = stage->priv;
ClutterPaintContext *paint_context;
cairo_region_t *redraw_clip;
redraw_clip = cairo_region_create_rectangle (rect);
paint_context =
clutter_paint_context_new_for_framebuffer (framebuffer,
redraw_clip,
paint_flags);
cairo_region_destroy (redraw_clip);
cogl_framebuffer_push_matrix (framebuffer);
cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
cogl_framebuffer_set_viewport (framebuffer,
-(rect->x * scale),
-(rect->y * scale),
priv->viewport[2] * scale,
priv->viewport[3] * scale);
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
cogl_framebuffer_pop_matrix (framebuffer);
clutter_paint_context_destroy (paint_context);
}
gboolean
clutter_stage_paint_to_buffer (ClutterStage *stage,
const cairo_rectangle_int_t *rect,
float scale,
uint8_t *data,
int stride,
CoglPixelFormat format,
ClutterPaintFlag paint_flags,
GError **error)
{
ClutterBackend *clutter_backend = clutter_get_default_backend ();
CoglContext *cogl_context =
clutter_backend_get_cogl_context (clutter_backend);
int texture_width, texture_height;
CoglTexture2D *texture;
CoglOffscreen *offscreen;
CoglFramebuffer *framebuffer;
CoglBitmap *bitmap;
texture_width = (int) ceilf (rect->width * scale);
texture_height = (int) ceilf (rect->height * scale);
texture = cogl_texture_2d_new_with_size (cogl_context,
texture_width,
texture_height);
if (!texture)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Failed to create %dx%d texture",
texture_width, texture_height);
return FALSE;
}
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
framebuffer = COGL_FRAMEBUFFER (offscreen);
cogl_object_unref (texture);
if (!cogl_framebuffer_allocate (framebuffer, error))
return FALSE;
clutter_stage_paint_to_framebuffer (stage, framebuffer,
rect, scale, paint_flags);
bitmap = cogl_bitmap_new_for_data (cogl_context,
texture_width, texture_height,
format,
stride,
data);
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
0, 0,
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
cogl_object_unref (framebuffer);
return TRUE;
}
static void
capture_view_into (ClutterStage *stage,
gboolean paint,
@@ -4402,11 +4310,8 @@ clutter_stage_thaw_updates (ClutterStage *stage)
}
}
/**
* clutter_stage_peek_stage_views: (skip)
*/
GList *
clutter_stage_peek_stage_views (ClutterStage *stage)
_clutter_stage_peek_stage_views (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;

View File

@@ -375,11 +375,15 @@ static gboolean
swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_region_t *swap_region,
gboolean swap_with_damage)
gboolean swap_with_damage,
cairo_region_t *queued_redraw_clip)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
int *damage, n_rects, i;
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
paint_damage_region (stage_window, view, swap_region, queued_redraw_clip);
n_rects = cairo_region_num_rectangles (swap_region);
damage = g_newa (int, n_rects * 4);
for (i = 0; i < n_rects; i++)
@@ -616,7 +620,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
gboolean swap_with_damage;
ClutterActor *wrapper;
cairo_region_t *redraw_clip;
cairo_region_t *queued_redraw_clip = NULL;
cairo_region_t *queued_redraw_clip;
cairo_region_t *fb_clip_region;
cairo_region_t *swap_region;
cairo_rectangle_int_t redraw_rect;
@@ -640,8 +644,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
redraw_clip = clutter_stage_view_take_redraw_clip (view);
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
queued_redraw_clip = cairo_region_copy (redraw_clip);
/* NB: a NULL redraw clip == full stage redraw */
if (!redraw_clip)
@@ -709,6 +711,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
redraw_clip = cairo_region_create_rectangle (&view_rect);
}
queued_redraw_clip = cairo_region_copy (redraw_clip);
if (may_use_clipped_redraw &&
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
use_clipped_redraw = TRUE;
@@ -918,6 +922,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
g_clear_pointer (&redraw_clip, cairo_region_destroy);
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
if (do_swap_buffer)
@@ -938,17 +943,11 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
swap_region = transformed_swap_region;
}
if (queued_redraw_clip)
{
paint_damage_region (stage_window, view,
swap_region, queued_redraw_clip);
cairo_region_destroy (queued_redraw_clip);
}
res = swap_framebuffer (stage_window,
view,
swap_region,
swap_with_damage);
swap_with_damage,
queued_redraw_clip);
cairo_region_destroy (swap_region);
@@ -956,25 +955,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
else
{
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
return FALSE;
}
}
static void
clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
CoglScanout *scanout)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
CoglOnscreen *onscreen;
g_return_if_fail (cogl_is_onscreen (framebuffer));
onscreen = COGL_ONSCREEN (framebuffer);
cogl_onscreen_direct_scanout (onscreen, scanout);
}
static void
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{
@@ -987,23 +971,11 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;
g_autoptr (CoglScanout) scanout = NULL;
if (!clutter_stage_view_has_redraw_clip (view))
continue;
scanout = clutter_stage_view_take_scanout (view);
if (scanout)
{
clutter_stage_cogl_scanout_view (stage_cogl,
view,
scanout);
swap_event = TRUE;
}
else
{
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
}
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
}
_clutter_stage_emit_after_paint (stage_cogl->wrapper);

View File

@@ -337,20 +337,35 @@ clutter_build_config_h = configure_file(
)
clutter_built_private_headers += clutter_build_config_h
cdata = configuration_data()
clutter_config_defines = []
if have_wayland
cdata.set10('CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT', true)
clutter_config_defines += [
'#define CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT 1',
]
endif
if have_x11
cdata.set_quoted('CLUTTER_WINDOWING_X11', 'x11')
cdata.set_quoted('CLUTTER_INPUT_X11', 'x11')
cdata.set_quoted('CLUTTER_WINDOWING_GLX', 'glx')
clutter_config_defines += [
'#define CLUTTER_WINDOWING_X11 "x11"',
'#define CLUTTER_INPUT_X11 "x11"',
'#define CLUTTER_WINDOWING_GLX "glx"',
]
endif
if have_native_backend
cdata.set_quoted('CLUTTER_WINDOWING_EGL', 'eglnative')
cdata.set_quoted('CLUTTER_INPUT_EVDEV', 'evdev')
clutter_config_defines += [
'#define CLUTTER_WINDOWING_EGL "eglnative"',
'#define CLUTTER_INPUT_EVDEV "evdev"',
]
endif
cdata.set_quoted('CLUTTER_INPUT_NULL', 'null')
clutter_config_defines += [
'#define CLUTTER_INPUT_NULL "null"',
]
clutter_config_defines_string = ''
foreach clutter_config_define : clutter_config_defines
clutter_config_defines_string += clutter_config_define + '\n'
endforeach
cdata = configuration_data()
cdata.set('CLUTTER_CONFIG_DEFINES', clutter_config_defines_string)
clutter_config_h = configure_file(
input: 'clutter-config.h.in',

View File

@@ -405,27 +405,6 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
return winsys->onscreen_get_buffer_age (onscreen);
}
void
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
CoglScanout *scanout)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
const CoglWinsysVtable *winsys;
CoglFrameInfo *info;
g_return_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
g_return_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT));
info = _cogl_frame_info_new ();
info->frame_counter = onscreen->frame_counter;
g_queue_push_tail (&onscreen->pending_frame_infos, info);
winsys = _cogl_framebuffer_get_winsys (framebuffer);
winsys->onscreen_direct_scanout (onscreen, scanout);
onscreen->frame_counter++;
}
#ifdef COGL_HAS_X11_SUPPORT
uint32_t
cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)

View File

@@ -50,8 +50,6 @@ G_BEGIN_DECLS
typedef struct _CoglOnscreen CoglOnscreen;
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
typedef struct _CoglScanout CoglScanout;
/**
* cogl_onscreen_get_gtype:
*
@@ -286,13 +284,6 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
const int *rectangles,
int n_rectangles);
/**
* cogl_onscreen_direct_scanout: (skip)
*/
COGL_EXPORT void
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
CoglScanout *scanout);
/**
* cogl_onscreen_swap_region:
* @onscreen: A #CoglOnscreen framebuffer

View File

@@ -1,27 +0,0 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cogl-config.h"
#include "cogl-scanout.h"
G_DEFINE_INTERFACE (CoglScanout, cogl_scanout, G_TYPE_OBJECT)
static void
cogl_scanout_default_init (CoglScanoutInterface *iface)
{
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2019 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COGL_SCANOUT_H
#define COGL_SCANOUT_H
#include "cogl/cogl-types.h"
#include <glib-object.h>
#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ())
COGL_EXPORT
G_DECLARE_INTERFACE (CoglScanout, cogl_scanout,
COGL, SCANOUT, GObject)
struct _CoglScanoutInterface
{
GTypeInterface parent_iface;
};
#endif /* COGL_SCANOUT_H */

View File

@@ -122,7 +122,6 @@
#include <cogl/cogl-fence.h>
#include <cogl/cogl-glib-source.h>
#include <cogl/cogl-trace.h>
#include <cogl/cogl-scanout.h>
/* XXX: This will definitly go away once all the Clutter winsys
* code has been migrated down into Cogl! */
#include <cogl/deprecated/cogl-clutter.h>

View File

@@ -122,7 +122,6 @@ cogl_nonintrospected_headers = [
'cogl-version.h',
'cogl-gtype-private.h',
'cogl-glib-source.h',
'cogl-scanout.h',
]
cogl_nodist_headers = [
@@ -348,7 +347,6 @@ cogl_sources = [
'cogl-closure-list.c',
'cogl-fence.c',
'cogl-fence-private.h',
'cogl-scanout.c',
'deprecated/cogl-material-compat.c',
'deprecated/cogl-program.c',
'deprecated/cogl-program-private.h',

View File

@@ -33,7 +33,6 @@
#include "cogl-renderer.h"
#include "cogl-onscreen.h"
#include "cogl-scanout.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include "cogl-texture-pixmap-x11-private.h"
@@ -118,10 +117,6 @@ typedef struct _CoglWinsysVtable
const int *rectangles,
int n_rectangles);
void
(*onscreen_direct_scanout) (CoglOnscreen *onscreen,
CoglScanout *scanout);
void
(*onscreen_set_visibility) (CoglOnscreen *onscreen,
gboolean visibility);

View File

@@ -70,12 +70,3 @@
/* Whether Xwayland has -initfd option */
#mesondefine HAVE_XWAYLAND_INITFD
/* Whether the mkostemp function exists */
#mesondefine HAVE_MKOSTEMP
/* Whether the posix_fallocate function exists */
#mesondefine HAVE_POSIX_FALLOCATE
/* Whether the memfd_create function exists */
#mesondefine HAVE_MEMFD_CREATE

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.37.1',
version: '3.37.0',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)
@@ -408,20 +408,6 @@ if have_wayland
endif
endif
optional_functions = [
'mkostemp',
'posix_fallocate',
'memfd_create',
]
foreach function : optional_functions
if cc.has_function(function)
cdata.set('HAVE_' + function.to_upper(), 1)
else
message('Optional function ' + function + ' missing')
endif
endforeach
xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules')
cdata.set_quoted('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES',
xwayland_grab_default_access_rules)

View File

@@ -13,8 +13,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2020-03-30 20:11+0000\n"
"PO-Revision-Date: 2020-04-06 23:13+0200\n"
"POT-Creation-Date: 2019-08-06 00:49+0000\n"
"PO-Revision-Date: 2019-09-05 23:42+0200\n"
"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: de\n"
@@ -22,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.3\n"
"X-Generator: Poedit 2.2.1\n"
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
@@ -435,33 +435,20 @@ msgstr "Zusatztaste zum Finden des Zeigers"
msgid "This key will initiate the “locate pointer” action."
msgstr "Diese Taste wird die Aktion »Zeiger finden« auslösen."
#: data/org.gnome.mutter.gschema.xml.in:142
msgid "Timeout for check-alive ping"
msgstr "Reaktionsschwellwert bei Kontaktkontrolle"
#: data/org.gnome.mutter.gschema.xml.in:143
msgid ""
"Number of milliseconds a client has to respond to a ping request in order to "
"not be detected as frozen. Using 0 will disable the alive check completely."
msgstr ""
"Zeit in Millisekunden, innerhalb welcher ein Client auf eine "
"Kontaktkontrolle antworten muss, um nicht als abgestürzt zu gelten. »0« "
"bedeutet, dass die Kontaktkontrolle ausgeschaltet wird."
#: data/org.gnome.mutter.gschema.xml.in:165
#: data/org.gnome.mutter.gschema.xml.in:155
msgid "Select window from tab popup"
msgstr "Fenster aus Tab-Anzeige auswählen"
#: data/org.gnome.mutter.gschema.xml.in:170
#: data/org.gnome.mutter.gschema.xml.in:160
msgid "Cancel tab popup"
msgstr "Tab-Anzeige abbrechen"
#: data/org.gnome.mutter.gschema.xml.in:175
#: data/org.gnome.mutter.gschema.xml.in:165
msgid "Switch monitor configurations"
msgstr "Bildschirmkonfigurationen wechseln"
# Ich denke nicht, dass »rotate« hier die Bildschirmdrehung meint, sondern eher eine Liste aus Konfigurationen rotiert (d.h. umgewälzt) wird.
#: data/org.gnome.mutter.gschema.xml.in:180
#: data/org.gnome.mutter.gschema.xml.in:170
msgid "Rotates the built-in monitor configuration"
msgstr "Wechselt die Konfiguration des eingebauten Bildschirms"
@@ -582,7 +569,7 @@ msgstr ""
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2631
#: src/backends/meta-input-settings.c:2531
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Moduswechsel (Gruppe %d)"
@@ -590,34 +577,34 @@ msgstr "Moduswechsel (Gruppe %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2654
#: src/backends/meta-input-settings.c:2554
msgid "Switch monitor"
msgstr "Bildschirm wechseln"
#: src/backends/meta-input-settings.c:2656
#: src/backends/meta-input-settings.c:2556
msgid "Show on-screen help"
msgstr "Bildschirmhilfe anzeigen"
#: src/backends/meta-monitor.c:226
#: src/backends/meta-monitor.c:223
msgid "Built-in display"
msgstr "Eingebaute Anzeige"
#: src/backends/meta-monitor.c:255
#: src/backends/meta-monitor.c:252
msgid "Unknown"
msgstr "Unbekannt"
#: src/backends/meta-monitor.c:257
#: src/backends/meta-monitor.c:254
msgid "Unknown Display"
msgstr "Unbekannte Anzeige"
#: src/backends/meta-monitor.c:265
#: src/backends/meta-monitor.c:262
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor.c:273
#: src/backends/meta-monitor.c:270
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
@@ -627,13 +614,13 @@ msgstr "%s %s"
# https://de.wikipedia.org/wiki/Composition-Manager
#. Translators: this string will appear in Sysprof
#: src/backends/meta-profiler.c:79
#: src/backends/meta-profiler.c:82
msgid "Compositor"
msgstr "Compositor"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:533
#: src/compositor/compositor.c:510
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@@ -645,47 +632,47 @@ msgstr ""
msgid "Bell event"
msgstr "Klangereignis"
#: src/core/main.c:190
#: src/core/main.c:185
msgid "Disable connection to session manager"
msgstr "Verbindung zur Sitzungsverwaltung deaktivieren"
#: src/core/main.c:196
#: src/core/main.c:191
msgid "Replace the running window manager"
msgstr "Den aktuellen Fensterverwalter ersetzen"
#: src/core/main.c:202
#: src/core/main.c:197
msgid "Specify session management ID"
msgstr "Kennung der Sitzungsverwaltung angeben"
#: src/core/main.c:207
#: src/core/main.c:202
msgid "X Display to use"
msgstr "Zu verwendende X-Anzeige"
#: src/core/main.c:213
#: src/core/main.c:208
msgid "Initialize session from savefile"
msgstr "Sitzung anhand gespeicherter Datei starten"
#: src/core/main.c:219
#: src/core/main.c:214
msgid "Make X calls synchronous"
msgstr "X-Aufrufe abgleichen"
#: src/core/main.c:226
#: src/core/main.c:221
msgid "Run as a wayland compositor"
msgstr "Als Wayland-Compositor ausführen"
#: src/core/main.c:232
#: src/core/main.c:227
msgid "Run as a nested compositor"
msgstr "Als eingebetteten Compositor ausführen"
#: src/core/main.c:238
#: src/core/main.c:233
msgid "Run wayland compositor without starting Xwayland"
msgstr "Wayland-Compositor ausführen, ohne Xwayland zu starten"
#: src/core/main.c:246
#: src/core/main.c:241
msgid "Run as a full display server, rather than nested"
msgstr "Als vollwertigen Display-Server verwenden (nicht eingebettet)"
#: src/core/main.c:252
#: src/core/main.c:247
msgid "Run with X11 backend"
msgstr "Mit X11-Backend ausführen"
@@ -741,21 +728,21 @@ msgstr "Version ausgeben"
msgid "Mutter plugin to use"
msgstr "Zu benutzendes Mutter-Plugin"
#: src/core/prefs.c:1911
#: src/core/prefs.c:1849
#, c-format
msgid "Workspace %d"
msgstr "Arbeitsfläche %d"
#: src/core/util.c:122
#: src/core/util.c:121
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter wurde ohne Unterstützung für den redseligen Modus kompiliert\n"
#: src/wayland/meta-wayland-tablet-pad.c:568
#: src/wayland/meta-wayland-tablet-pad.c:567
#, c-format
msgid "Mode Switch: Mode %d"
msgstr "Moduswechsel: Modus %d"
#: src/x11/meta-x11-display.c:676
#: src/x11/meta-x11-display.c:671
#, c-format
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
@@ -764,21 +751,21 @@ msgstr ""
"Bildschirm »%s« hat bereits einen Fensterverwalter. Versuchen Sie die Option "
"»--replace«, um den aktuellen Fensterverwalter zu ersetzen."
#: src/x11/meta-x11-display.c:1089
#: src/x11/meta-x11-display.c:1032
msgid "Failed to initialize GDK\n"
msgstr "GDK konnte nicht initialisiert werden\n"
#: src/x11/meta-x11-display.c:1113
#: src/x11/meta-x11-display.c:1056
#, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n"
#: src/x11/meta-x11-display.c:1196
#: src/x11/meta-x11-display.c:1140
#, c-format
msgid "Screen %d on display “%s” is invalid\n"
msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n"
#: src/x11/meta-x11-selection-input-stream.c:460
#: src/x11/meta-x11-selection-input-stream.c:445
#, c-format
msgid "Format %s not supported"
msgstr "Format %s wird nicht unterstützt"

View File

@@ -49,7 +49,6 @@ typedef struct _MetaTileInfo MetaTileInfo;
typedef struct _MetaRenderer MetaRenderer;
typedef struct _MetaRendererView MetaRendererView;
typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
typedef struct _MetaScreenCast MetaScreenCast;
typedef struct _MetaScreenCastSession MetaScreenCastSession;
typedef struct _MetaScreenCastStream MetaScreenCastStream;

View File

@@ -552,12 +552,12 @@ meta_backend_real_post_init (MetaBackend *backend)
}
#ifdef HAVE_REMOTE_DESKTOP
priv->remote_access_controller =
g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL);
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
priv->screen_cast = meta_screen_cast_new (backend,
priv->dbus_session_watcher);
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
priv->remote_access_controller =
meta_remote_access_controller_new (priv->remote_desktop, priv->screen_cast);
#endif /* HAVE_REMOTE_DESKTOP */
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
@@ -809,6 +809,9 @@ static MetaMonitorManager *
meta_backend_create_monitor_manager (MetaBackend *backend,
GError **error)
{
if (g_getenv ("META_DUMMY_MONITORS"))
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
error);
}

View File

@@ -35,6 +35,7 @@ typedef struct _MetaMapperInputInfo MetaMapperInputInfo;
typedef struct _MetaMapperOutputInfo MetaMapperOutputInfo;
typedef struct _MappingHelper MappingHelper;
typedef struct _DeviceCandidates DeviceCandidates;
typedef struct _DeviceMatch DeviceMatch;
struct _MetaInputMapper
{
@@ -59,11 +60,11 @@ typedef enum
typedef enum
{
META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
META_MATCH_SIZE, /* Size from input device and output match */
META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
META_MATCH_EDID_PARTIAL, /* Partial EDID model match, eg. "Cintiq" */
META_MATCH_EDID_VENDOR, /* EDID vendor match, eg. "WAC" for Wacom */
META_MATCH_EDID_PARTIAL, /* Partial EDID model match, eg. "Cintiq" */
META_MATCH_EDID_FULL, /* Full EDID model match, eg. "Cintiq 12WX" */
META_MATCH_SIZE, /* Size from input device and output match */
META_MATCH_IS_BUILTIN, /* Output is builtin, applies mainly to system-integrated devices */
N_OUTPUT_MATCHES
} MetaOutputMatchType;
@@ -87,13 +88,19 @@ struct _MappingHelper
GArray *device_maps;
};
struct _DeviceMatch
{
MetaMonitor *monitor;
uint32_t score;
};
struct _DeviceCandidates
{
MetaMapperInputInfo *input;
MetaMonitor *candidates[N_OUTPUT_MATCHES];
GArray *matches; /* Array of DeviceMatch */;
MetaOutputMatchType best;
int best;
};
enum
@@ -305,52 +312,37 @@ input_device_get_physical_size (MetaInputMapper *mapper,
}
static gboolean
find_size_match (MetaMapperInputInfo *input,
GList *monitors,
MetaMonitor **matched_monitor)
match_size (MetaMapperInputInfo *input,
MetaMonitor *monitor)
{
double min_w_diff, min_h_diff;
double w_diff, h_diff;
int o_width, o_height;
double i_width, i_height;
gboolean found = FALSE;
GList *l;
min_w_diff = min_h_diff = MAX_SIZE_MATCH_DIFF;
if (!input_device_get_physical_size (input->mapper, input->device,
&i_width, &i_height))
return FALSE;
for (l = monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
double w_diff, h_diff;
int o_width, o_height;
meta_monitor_get_physical_dimensions (monitor, &o_width, &o_height);
w_diff = ABS (1 - ((double) o_width / i_width));
h_diff = ABS (1 - ((double) o_height / i_height));
meta_monitor_get_physical_dimensions (monitor, &o_width, &o_height);
w_diff = ABS (1 - ((double) o_width / i_width));
h_diff = ABS (1 - ((double) o_height / i_height));
if (w_diff >= min_w_diff || h_diff >= min_h_diff)
continue;
*matched_monitor = monitor;
min_w_diff = w_diff;
min_h_diff = h_diff;
found = TRUE;
}
return found;
return w_diff < MAX_SIZE_MATCH_DIFF && h_diff < MAX_SIZE_MATCH_DIFF;
}
static gboolean
find_builtin_output (MetaInputMapper *mapper,
MetaMonitor **matched_monitor)
match_builtin (MetaInputMapper *mapper,
MetaMonitor *monitor)
{
MetaMonitor *panel;
return monitor == meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
}
panel = meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
*matched_monitor = panel;
return panel != NULL;
static int
sort_by_score (DeviceMatch *match1,
DeviceMatch *match2)
{
return (int) match1->score - match2->score;
}
static void
@@ -358,36 +350,45 @@ guess_candidates (MetaInputMapper *mapper,
MetaMapperInputInfo *input,
DeviceCandidates *info)
{
MetaOutputMatchType best = N_OUTPUT_MATCHES;
GList *monitors, *l;
MetaMonitor *matched_monitor = NULL;
monitors = meta_monitor_manager_get_monitors (mapper->monitor_manager);
for (l = monitors; l; l = l->next)
{
MetaOutputMatchType edid_match;
DeviceMatch match = { l->data, 0 };
if (match_edid (input, l->data, &edid_match))
{
best = MIN (best, edid_match);
info->candidates[edid_match] = l->data;
}
match.score |= 1 << edid_match;
if (match_size (input, l->data))
match.score |= 1 << META_MATCH_SIZE;
if (input->builtin && match_builtin (mapper, l->data))
match.score |= 1 << META_MATCH_IS_BUILTIN;
if (match.score > 0)
g_array_append_val (info->matches, match);
}
if (find_size_match (input, monitors, &matched_monitor))
if (info->matches->len == 0)
{
best = MIN (best, META_MATCH_SIZE);
info->candidates[META_MATCH_SIZE] = matched_monitor;
}
DeviceMatch match = { 0 };
if (input->builtin || best == N_OUTPUT_MATCHES)
match.monitor =
meta_monitor_manager_get_laptop_panel (mapper->monitor_manager);
g_array_append_val (info->matches, match);
info->best = 0;
}
else
{
best = MIN (best, META_MATCH_IS_BUILTIN);
find_builtin_output (mapper, &info->candidates[META_MATCH_IS_BUILTIN]);
}
DeviceMatch *best;
info->best = best;
g_array_sort (info->matches, (GCompareFunc) sort_by_score);
best = &g_array_index (info->matches, DeviceMatch, 0);
info->best = best->score;
}
}
static void
@@ -399,6 +400,7 @@ mapping_helper_add (MappingHelper *helper,
guint i, pos = 0;
info.input = input;
info.matches = g_array_new (FALSE, TRUE, sizeof (DeviceMatch));
guess_candidates (mapper, input, &info);
@@ -408,7 +410,7 @@ mapping_helper_add (MappingHelper *helper,
elem = &g_array_index (helper->device_maps, DeviceCandidates, i);
if (elem->best < info.best)
if (elem->best > info.best)
pos = i;
}
@@ -422,26 +424,32 @@ static void
mapping_helper_apply (MappingHelper *helper,
MetaInputMapper *mapper)
{
guint i;
guint i, j;
/* Now, decide which input claims which output */
for (i = 0; i < helper->device_maps->len; i++)
{
MetaMapperOutputInfo *output;
DeviceCandidates *info;
MetaOutputMatchType j;
MetaMonitor *monitor;
info = &g_array_index (helper->device_maps, DeviceCandidates, i);
g_debug ("Applying mapping %d to input device '%s', capabilities %x", i,
clutter_input_device_get_device_name (info->input->device),
mapper_input_info_get_caps (info->input));
for (j = 0; j < N_OUTPUT_MATCHES; j++)
for (j = 0; j < info->matches->len; j++)
{
MetaLogicalMonitor *logical_monitor;
DeviceMatch *match;
if (!info->candidates[j])
continue;
match = &g_array_index (info->matches, DeviceMatch, j);
g_debug ("Output candidate '%s', score %x",
meta_monitor_get_display_name (match->monitor),
match->score);
logical_monitor =
meta_monitor_get_logical_monitor (info->candidates[j]);
monitor = match->monitor;
logical_monitor = meta_monitor_get_logical_monitor (monitor);
output = g_hash_table_lookup (mapper->output_devices,
logical_monitor);
@@ -451,8 +459,10 @@ mapping_helper_apply (MappingHelper *helper,
if (output->attached_caps & mapper_input_info_get_caps (info->input))
continue;
mapper_output_info_add_input (output, info->input,
info->candidates[j]);
g_debug ("Matched input '%s' with output '%s'",
clutter_input_device_get_device_name (info->input->device),
meta_monitor_get_display_name (match->monitor));
mapper_output_info_add_input (output, info->input, monitor);
break;
}
}

View File

@@ -172,7 +172,6 @@ assign_monitor_crtc (MetaMonitor *monitor,
MetaCrtc *crtc;
MetaMonitorTransform transform;
MetaMonitorTransform crtc_transform;
MetaMonitorTransform crtc_hw_transform;
int crtc_x, crtc_y;
float x_offset, y_offset;
float scale = 0.0;
@@ -201,12 +200,10 @@ assign_monitor_crtc (MetaMonitor *monitor,
transform = data->logical_monitor_config->transform;
crtc_transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
crtc_transform))
crtc_hw_transform = crtc_transform;
else
crtc_hw_transform = META_MONITOR_TRANSFORM_NORMAL;
if (!meta_monitor_manager_is_transform_handled (data->monitor_manager,
crtc,
crtc_transform))
crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
&crtc_x, &crtc_y);
@@ -247,7 +244,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
.crtc = crtc,
.mode = crtc_mode,
.layout = crtc_layout,
.transform = crtc_hw_transform,
.transform = crtc_transform,
.outputs = g_ptr_array_new ()
};
g_ptr_array_add (crtc_info->outputs, output);
@@ -446,35 +443,23 @@ MetaMonitorsConfigKey *
meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
{
MetaMonitorsConfigKey *config_key;
MetaMonitorSpec *laptop_monitor_spec;
GList *l;
GList *monitor_specs;
laptop_monitor_spec = NULL;
monitor_specs = NULL;
for (l = monitor_manager->monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
MetaMonitorSpec *monitor_spec;
if (meta_monitor_is_laptop_panel (monitor))
{
laptop_monitor_spec = meta_monitor_get_spec (monitor);
if (is_lid_closed (monitor_manager))
continue;
}
if (meta_monitor_is_laptop_panel (monitor) &&
is_lid_closed (monitor_manager))
continue;
monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor));
monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
}
if (!monitor_specs && laptop_monitor_spec)
{
monitor_specs =
g_list_prepend (NULL, meta_monitor_spec_clone (laptop_monitor_spec));
}
if (!monitor_specs)
return NULL;

View File

@@ -817,19 +817,19 @@ calculate_tile_coordinate (MetaMonitor *monitor,
case META_MONITOR_TRANSFORM_270:
case META_MONITOR_TRANSFORM_FLIPPED_270:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
case META_MONITOR_TRANSFORM_90:
case META_MONITOR_TRANSFORM_FLIPPED_90:
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
y += other_output->tile_info.tile_w;
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
x += other_output->tile_info.tile_h;
break;
}

View File

@@ -21,12 +21,8 @@
#ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
#define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
#include "backends/meta-backend-types.h"
#include "meta/meta-remote-access-controller.h"
MetaRemoteAccessController * meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
MetaScreenCast *screen_cast);
void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller,
MetaRemoteAccessHandle *handle);

View File

@@ -22,11 +22,6 @@
#include "backends/meta-remote-access-controller-private.h"
#ifdef HAVE_REMOTE_DESKTOP
#include "backends/meta-remote-desktop.h"
#include "backends/meta-screen-cast.h"
#endif
enum
{
HANDLE_STOPPED,
@@ -59,9 +54,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle,
struct _MetaRemoteAccessController
{
GObject parent;
MetaRemoteDesktop *remote_desktop;
MetaScreenCast *screen_cast;
};
G_DEFINE_TYPE (MetaRemoteAccessController,
@@ -130,53 +122,6 @@ meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *con
handle);
}
/**
* meta_remote_access_controller_inhibit_remote_access:
* @controller: a #MetaRemoteAccessController
*
* Inhibits remote access sessions from being created and running. Any active
* remote access session will be terminated.
*/
void
meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller)
{
#ifdef HAVE_REMOTE_DESKTOP
meta_remote_desktop_inhibit (controller->remote_desktop);
meta_screen_cast_inhibit (controller->screen_cast);
#endif
}
/**
* meta_remote_access_controller_uninhibit_remote_access:
* @controller: a #MetaRemoteAccessController
*
* Uninhibits remote access sessions from being created and running. If this was
* the last inhibitation that was inhibited, new remote access sessions can now
* be created.
*/
void
meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller)
{
#ifdef HAVE_REMOTE_DESKTOP
meta_screen_cast_uninhibit (controller->screen_cast);
meta_remote_desktop_uninhibit (controller->remote_desktop);
#endif
}
MetaRemoteAccessController *
meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
MetaScreenCast *screen_cast)
{
MetaRemoteAccessController *remote_access_controller;
remote_access_controller = g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER,
NULL);
remote_access_controller->remote_desktop = remote_desktop;
remote_access_controller->screen_cast = screen_cast;
return remote_access_controller;
}
static void
meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
{

View File

@@ -56,8 +56,6 @@ struct _MetaRemoteDesktop
int dbus_name_id;
int inhibit_count;
GHashTable *sessions;
MetaDbusSessionWatcher *session_watcher;
@@ -72,34 +70,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktop,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP,
meta_remote_desktop_init_iface));
void
meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop)
{
remote_desktop->inhibit_count++;
if (remote_desktop->inhibit_count == 1)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, remote_desktop->sessions);
while (g_hash_table_iter_next (&iter, &key, &value))
{
MetaRemoteDesktopSession *session = value;
g_hash_table_iter_steal (&iter);
meta_remote_desktop_session_close (session);
}
}
}
void
meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop)
{
g_return_if_fail (remote_desktop->inhibit_count > 0);
remote_desktop->inhibit_count--;
}
GDBusConnection *
meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop)
{
@@ -138,15 +108,6 @@ handle_create_session (MetaDBusRemoteDesktop *skeleton,
char *session_path;
const char *client_dbus_name;
if (remote_desktop->inhibit_count > 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Session creation inhibited");
return TRUE;
}
peer_name = g_dbus_method_invocation_get_sender (invocation);
session = meta_remote_desktop_session_new (remote_desktop,
peer_name,

View File

@@ -36,10 +36,6 @@ G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop,
META, REMOTE_DESKTOP,
MetaDBusRemoteDesktopSkeleton)
void meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop);
void meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop);
MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop,
const char *session_id);

View File

@@ -1,570 +0,0 @@
/*
* Copyright (C) 2020 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 "backends/meta-screen-cast-area-stream-src.h"
#include <spa/buffer/meta.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-screen-cast-area-stream.h"
#include "backends/meta-screen-cast-session.h"
#include "backends/meta-stage-private.h"
#include "clutter/clutter.h"
#include "clutter/clutter-mutter.h"
#include "core/boxes-private.h"
struct _MetaScreenCastAreaStreamSrc
{
MetaScreenCastStreamSrc parent;
gboolean cursor_bitmap_invalid;
gboolean hw_cursor_inhibited;
GList *watches;
gulong cursor_moved_handler_id;
gulong cursor_changed_handler_id;
guint maybe_record_idle_id;
};
static void
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaScreenCastAreaStreamSrc,
meta_screen_cast_area_stream_src,
META_TYPE_SCREEN_CAST_STREAM_SRC,
G_IMPLEMENT_INTERFACE (META_TYPE_HW_CURSOR_INHIBITOR,
hw_cursor_inhibitor_iface_init))
static ClutterStage *
get_stage (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src;
MetaScreenCastStream *stream;
MetaScreenCastAreaStream *area_stream;
src = META_SCREEN_CAST_STREAM_SRC (area_src);
stream = meta_screen_cast_stream_src_get_stream (src);
area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
return meta_screen_cast_area_stream_get_stage (area_stream);
}
static MetaBackend *
get_backend (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_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 MetaCursorRenderer *
get_cursor_renderer (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_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);
MetaBackend *backend = meta_screen_cast_get_backend (screen_cast);
return meta_backend_get_cursor_renderer (backend);
}
static void
meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
int *width,
int *height,
float *frame_rate)
{
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
MetaRectangle *area;
float scale;
area = meta_screen_cast_area_stream_get_area (area_stream);
scale = meta_screen_cast_area_stream_get_scale (area_stream);
*width = (int) roundf (area->width * scale);
*height = (int) roundf (area->height * scale);
*frame_rate = 60.0;
}
static gboolean
is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
MetaBackend *backend = get_backend (area_src);
MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (backend);
MetaRectangle *area;
graphene_rect_t area_rect;
MetaCursorSprite *cursor_sprite;
area = meta_screen_cast_area_stream_get_area (area_stream);
area_rect = meta_rectangle_to_graphene_rect (area);
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
if (cursor_sprite)
{
graphene_rect_t cursor_rect;
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
cursor_sprite);
return graphene_rect_intersection (&cursor_rect, &area_rect, NULL);
}
else
{
graphene_point_t cursor_position;
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
return graphene_rect_contains_point (&area_rect, &cursor_position);
}
}
static void
sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
ClutterStage *stage = get_stage (area_src);
if (!is_cursor_in_stream (area_src))
return;
if (clutter_stage_is_redraw_queued (stage))
return;
meta_screen_cast_stream_src_maybe_record_frame (src);
}
static void
cursor_moved (MetaCursorTracker *cursor_tracker,
float x,
float y,
MetaScreenCastAreaStreamSrc *area_src)
{
sync_cursor_state (area_src);
}
static void
cursor_changed (MetaCursorTracker *cursor_tracker,
MetaScreenCastAreaStreamSrc *area_src)
{
area_src->cursor_bitmap_invalid = TRUE;
sync_cursor_state (area_src);
}
static void
inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
{
MetaCursorRenderer *cursor_renderer;
MetaHwCursorInhibitor *inhibitor;
g_return_if_fail (!area_src->hw_cursor_inhibited);
cursor_renderer = get_cursor_renderer (area_src);
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor);
area_src->hw_cursor_inhibited = TRUE;
}
static void
uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
{
MetaCursorRenderer *cursor_renderer;
MetaHwCursorInhibitor *inhibitor;
g_return_if_fail (area_src->hw_cursor_inhibited);
cursor_renderer = get_cursor_renderer (area_src);
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor);
area_src->hw_cursor_inhibited = FALSE;
}
static gboolean
maybe_record_frame_on_idle (gpointer user_data)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
area_src->maybe_record_idle_id = 0;
meta_screen_cast_stream_src_maybe_record_frame (src);
return G_SOURCE_REMOVE;
}
static void
stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
gpointer user_data)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
const cairo_region_t *redraw_clip;
MetaRectangle *area;
if (area_src->maybe_record_idle_id)
return;
area = meta_screen_cast_area_stream_get_area (area_stream);
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
if (redraw_clip)
{
switch (cairo_region_contains_rectangle (redraw_clip, area))
{
case CAIRO_REGION_OVERLAP_IN:
case CAIRO_REGION_OVERLAP_PART:
break;
case CAIRO_REGION_OVERLAP_OUT:
return;
}
}
area_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, src);
}
static void
add_view_painted_watches (MetaScreenCastAreaStreamSrc *area_src,
MetaStageWatchPhase watch_phase)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
MetaBackend *backend = get_backend (area_src);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
ClutterStage *stage;
MetaStage *meta_stage;
MetaRectangle *area;
GList *l;
stage = get_stage (area_src);
meta_stage = META_STAGE (stage);
area = meta_screen_cast_area_stream_get_area (area_stream);
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
MetaRendererView *view = l->data;
MetaRectangle view_layout;
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
if (meta_rectangle_overlap (area, &view_layout))
{
MetaStageWatch *watch;
watch = meta_stage_watch_view (meta_stage,
CLUTTER_STAGE_VIEW (view),
watch_phase,
stage_painted,
area_src);
area_src->watches = g_list_prepend (area_src->watches, watch);
}
}
}
static void
meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaBackend *backend = get_backend (area_src);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterStage *stage;
MetaScreenCastStream *stream;
stream = meta_screen_cast_stream_src_get_stream (src);
stage = get_stage (area_src);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
area_src->cursor_moved_handler_id =
g_signal_connect_after (cursor_tracker, "cursor-moved",
G_CALLBACK (cursor_moved),
area_src);
area_src->cursor_changed_handler_id =
g_signal_connect_after (cursor_tracker, "cursor-changed",
G_CALLBACK (cursor_changed),
area_src);
G_GNUC_FALLTHROUGH;
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
add_view_painted_watches (area_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
inhibit_hw_cursor (area_src);
add_view_painted_watches (area_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
break;
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
static void
meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaBackend *backend = get_backend (area_src);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterStage *stage;
MetaStage *meta_stage;
GList *l;
stage = get_stage (area_src);
meta_stage = META_STAGE (stage);
for (l = area_src->watches; l; l = l->next)
{
MetaStageWatch *watch = l->data;
meta_stage_remove_watch (meta_stage, watch);
}
g_clear_pointer (&area_src->watches, g_list_free);
if (area_src->hw_cursor_inhibited)
uninhibit_hw_cursor (area_src);
g_clear_signal_handler (&area_src->cursor_moved_handler_id,
cursor_tracker);
g_clear_signal_handler (&area_src->cursor_changed_handler_id,
cursor_tracker);
g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
}
static gboolean
meta_screen_cast_area_stream_src_record_frame (MetaScreenCastStreamSrc *src,
uint8_t *data)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
ClutterStage *stage;
MetaRectangle *area;
float scale;
int stride;
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
g_autoptr (GError) error = NULL;
stage = get_stage (area_src);
area = meta_screen_cast_area_stream_get_area (area_stream);
scale = meta_screen_cast_area_stream_get_scale (area_stream);
stride = meta_screen_cast_stream_src_get_stride (src);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
break;
}
if (!clutter_stage_paint_to_buffer (stage, area, scale,
data,
stride,
CLUTTER_CAIRO_FORMAT_ARGB32,
paint_flags,
&error))
{
g_warning ("Failed to record area: %s", error->message);
return FALSE;
}
return TRUE;
}
static gboolean
meta_screen_cast_area_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
MetaBackend *backend = get_backend (area_src);
ClutterStage *stage;
MetaRectangle *area;
float scale;
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
area = meta_screen_cast_area_stream_get_area (area_stream);
scale = meta_screen_cast_area_stream_get_scale (area_stream);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
break;
}
clutter_stage_paint_to_framebuffer (stage, framebuffer,
area, scale,
paint_flags);
cogl_framebuffer_finish (framebuffer);
return TRUE;
}
static void
meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
MetaBackend *backend = get_backend (area_src);
MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (backend);
MetaCursorSprite *cursor_sprite;
MetaRectangle *area;
float scale;
graphene_point_t cursor_position;
int x, y;
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
if (!is_cursor_in_stream (area_src))
{
meta_screen_cast_stream_src_unset_cursor_metadata (src,
spa_meta_cursor);
return;
}
area = meta_screen_cast_area_stream_get_area (area_stream);
scale = meta_screen_cast_area_stream_get_scale (area_stream);
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
cursor_position.x -= area->x;
cursor_position.y -= area->y;
cursor_position.x *= scale;
cursor_position.y *= scale;
x = (int) roundf (cursor_position.x);
y = (int) roundf (cursor_position.y);
if (area_src->cursor_bitmap_invalid)
{
if (cursor_sprite)
{
float cursor_scale;
float metadata_scale;
cursor_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
metadata_scale = scale * cursor_scale;
meta_screen_cast_stream_src_set_cursor_sprite_metadata (src,
spa_meta_cursor,
cursor_sprite,
x, y,
metadata_scale);
}
else
{
meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src,
spa_meta_cursor,
x, y);
}
area_src->cursor_bitmap_invalid = FALSE;
}
else
{
meta_screen_cast_stream_src_set_cursor_position_metadata (src,
spa_meta_cursor,
x, y);
}
}
static gboolean
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor,
MetaCursorSprite *cursor_sprite)
{
MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor);
return is_cursor_in_stream (area_src);
}
static void
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
{
iface->is_cursor_sprite_inhibited =
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited;
}
MetaScreenCastAreaStreamSrc *
meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
GError **error)
{
return g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM_SRC, NULL, error,
"stream", area_stream,
NULL);
}
static void
meta_screen_cast_area_stream_src_init (MetaScreenCastAreaStreamSrc *area_src)
{
area_src->cursor_bitmap_invalid = TRUE;
}
static void
meta_screen_cast_area_stream_src_class_init (MetaScreenCastAreaStreamSrcClass *klass)
{
MetaScreenCastStreamSrcClass *src_class =
META_SCREEN_CAST_STREAM_SRC_CLASS (klass);
src_class->get_specs = meta_screen_cast_area_stream_src_get_specs;
src_class->enable = meta_screen_cast_area_stream_src_enable;
src_class->disable = meta_screen_cast_area_stream_src_disable;
src_class->record_frame = meta_screen_cast_area_stream_src_record_frame;
src_class->blit_to_framebuffer =
meta_screen_cast_area_stream_src_blit_to_framebuffer;
src_class->set_cursor_metadata =
meta_screen_cast_area_stream_src_set_cursor_metadata;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2020 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_SCREEN_CAST_AREA_STREAM_SRC_H
#define META_SCREEN_CAST_AREA_STREAM_SRC_H
#include "backends/meta-screen-cast-stream-src.h"
typedef struct _MetaScreenCastAreaStream MetaScreenCastAreaStream;
#define META_TYPE_SCREEN_CAST_AREA_STREAM_SRC (meta_screen_cast_area_stream_src_get_type ())
G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStreamSrc,
meta_screen_cast_area_stream_src,
META, SCREEN_CAST_AREA_STREAM_SRC,
MetaScreenCastStreamSrc)
MetaScreenCastAreaStreamSrc * meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
GError **error);
#endif /* META_SCREEN_CAST_AREA_STREAM_SRC_H */

View File

@@ -1,177 +0,0 @@
/*
* Copyright (C) 2020 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 "backends/meta-screen-cast-area-stream.h"
#include "backends/meta-screen-cast-area-stream-src.h"
struct _MetaScreenCastAreaStream
{
MetaScreenCastStream parent;
ClutterStage *stage;
MetaRectangle area;
float scale;
};
G_DEFINE_TYPE (MetaScreenCastAreaStream,
meta_screen_cast_area_stream,
META_TYPE_SCREEN_CAST_STREAM)
ClutterStage *
meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream)
{
return area_stream->stage;
}
MetaRectangle *
meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream)
{
return &area_stream->area;
}
float
meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream)
{
return area_stream->scale;
}
static gboolean
calculate_scale (ClutterStage *stage,
MetaRectangle *area,
float *out_scale)
{
GList *l;
float scale = 0.0;
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *stage_view = l->data;
MetaRectangle view_layout;
clutter_stage_view_get_layout (stage_view, &view_layout);
if (meta_rectangle_overlap (area, &view_layout))
scale = MAX (clutter_stage_view_get_scale (stage_view), scale);
}
if (scale == 0.0)
return FALSE;
*out_scale = scale;
return TRUE;
}
MetaScreenCastAreaStream *
meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
GDBusConnection *connection,
MetaRectangle *area,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
GError **error)
{
MetaScreenCastAreaStream *area_stream;
float scale;
if (!calculate_scale (stage, area, &scale))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Area is off-screen");
return NULL;
}
area_stream = g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM,
NULL,
error,
"session", session,
"connection", connection,
"cursor-mode", cursor_mode,
NULL);
if (!area_stream)
return NULL;
area_stream->area = *area;
area_stream->scale = scale;
area_stream->stage = stage;
return area_stream;
}
static MetaScreenCastStreamSrc *
meta_screen_cast_area_stream_create_src (MetaScreenCastStream *stream,
GError **error)
{
MetaScreenCastAreaStream *area_stream =
META_SCREEN_CAST_AREA_STREAM (stream);
MetaScreenCastAreaStreamSrc *area_stream_src;
area_stream_src = meta_screen_cast_area_stream_src_new (area_stream,
error);
if (!area_stream_src)
return NULL;
return META_SCREEN_CAST_STREAM_SRC (area_stream_src);
}
static void
meta_screen_cast_area_stream_set_parameters (MetaScreenCastStream *stream,
GVariantBuilder *parameters_builder)
{
MetaScreenCastAreaStream *area_stream =
META_SCREEN_CAST_AREA_STREAM (stream);
g_variant_builder_add (parameters_builder, "{sv}",
"size",
g_variant_new ("(ii)",
area_stream->area.width,
area_stream->area.height));
}
static void
meta_screen_cast_area_stream_transform_position (MetaScreenCastStream *stream,
double stream_x,
double stream_y,
double *x,
double *y)
{
MetaScreenCastAreaStream *area_stream =
META_SCREEN_CAST_AREA_STREAM (stream);
*x = area_stream->area.x + (int) roundf (stream_x / area_stream->scale);
*y = area_stream->area.y + (int) roundf (stream_y / area_stream->scale);
}
static void
meta_screen_cast_area_stream_init (MetaScreenCastAreaStream *area_stream)
{
}
static void
meta_screen_cast_area_stream_class_init (MetaScreenCastAreaStreamClass *klass)
{
MetaScreenCastStreamClass *stream_class =
META_SCREEN_CAST_STREAM_CLASS (klass);
stream_class->create_src = meta_screen_cast_area_stream_create_src;
stream_class->set_parameters = meta_screen_cast_area_stream_set_parameters;
stream_class->transform_position = meta_screen_cast_area_stream_transform_position;
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2020 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_SCREEN_CAST_AREA_STREAM_H
#define META_SCREEN_CAST_AREA_STREAM_H
#include <glib-object.h>
#include "backends/meta-screen-cast-stream.h"
#include "backends/meta-screen-cast.h"
#define META_TYPE_SCREEN_CAST_AREA_STREAM (meta_screen_cast_area_stream_get_type ())
G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStream,
meta_screen_cast_area_stream,
META, SCREEN_CAST_AREA_STREAM,
MetaScreenCastStream)
MetaScreenCastAreaStream * meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
GDBusConnection *connection,
MetaRectangle *area,
ClutterStage *stage,
MetaScreenCastCursorMode cursor_mode,
GError **error);
ClutterStage * meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream);
MetaRectangle * meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream);
float meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream);
#endif /* META_SCREEN_CAST_AREA_STREAM_H */

View File

@@ -115,10 +115,9 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
}
static void
stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
gpointer user_data)
stage_painted (MetaStage *stage,
ClutterStageView *view,
gpointer user_data)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);

View File

@@ -27,7 +27,6 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-dbus-session-watcher.h"
#include "backends/meta-remote-access-controller-private.h"
#include "backends/meta-screen-cast-area-stream.h"
#include "backends/meta-screen-cast-monitor-stream.h"
#include "backends/meta-screen-cast-stream.h"
#include "backends/meta-screen-cast-window-stream.h"
@@ -486,90 +485,6 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
return TRUE;
}
static gboolean
handle_record_area (MetaDBusScreenCastSession *skeleton,
GDBusMethodInvocation *invocation,
int x,
int y,
int width,
int height,
GVariant *properties_variant)
{
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
GDBusInterfaceSkeleton *interface_skeleton;
GDBusConnection *connection;
MetaBackend *backend;
ClutterStage *stage;
MetaScreenCastCursorMode cursor_mode;
g_autoptr (GError) error = NULL;
MetaRectangle rect;
MetaScreenCastAreaStream *area_stream;
MetaScreenCastStream *stream;
char *stream_path;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
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);
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
backend = meta_screen_cast_get_backend (session->screen_cast);
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
rect = (MetaRectangle) {
.x = x,
.y = y,
.width = width,
.height = height
};
area_stream = meta_screen_cast_area_stream_new (session,
connection,
&rect,
stage,
cursor_mode,
&error);
if (!area_stream)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"Failed to record area: %s",
error->message);
return TRUE;
}
stream = META_SCREEN_CAST_STREAM (area_stream);
stream_path = meta_screen_cast_stream_get_object_path (stream);
session->streams = g_list_append (session->streams, stream);
g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session);
meta_dbus_screen_cast_session_complete_record_area (skeleton,
invocation,
stream_path);
return TRUE;
}
static void
meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface)
{
@@ -577,7 +492,6 @@ meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface)
iface->handle_stop = handle_stop;
iface->handle_record_monitor = handle_record_monitor;
iface->handle_record_window = handle_record_window;
iface->handle_record_area = handle_record_area;
}
static void

View File

@@ -956,15 +956,6 @@ meta_screen_cast_stream_src_init_initable_iface (GInitableIface *iface)
iface->init = meta_screen_cast_stream_src_initable_init;
}
int
meta_screen_cast_stream_src_get_stride (MetaScreenCastStreamSrc *src)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
return priv->video_stride;
}
MetaScreenCastStream *
meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src)
{

View File

@@ -65,8 +65,6 @@ struct _MetaScreenCastStreamSrcClass
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
int meta_screen_cast_stream_src_get_stride (MetaScreenCastStreamSrc *src);
MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
gboolean meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc *src,

View File

@@ -40,8 +40,6 @@ struct _MetaScreenCast
int dbus_name_id;
int inhibit_count;
GList *sessions;
MetaDbusSessionWatcher *session_watcher;
@@ -56,29 +54,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCast, meta_screen_cast,
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST,
meta_screen_cast_init_iface))
void
meta_screen_cast_inhibit (MetaScreenCast *screen_cast)
{
screen_cast->inhibit_count++;
if (screen_cast->inhibit_count == 1)
{
while (screen_cast->sessions)
{
MetaScreenCastSession *session = screen_cast->sessions->data;
meta_screen_cast_session_close (session);
}
}
}
void
meta_screen_cast_uninhibit (MetaScreenCast *screen_cast)
{
g_return_if_fail (screen_cast->inhibit_count > 0);
screen_cast->inhibit_count--;
}
GDBusConnection *
meta_screen_cast_get_connection (MetaScreenCast *screen_cast)
{
@@ -144,15 +119,6 @@ handle_create_session (MetaDBusScreenCast *skeleton,
gboolean disable_animations;
MetaScreenCastSessionType session_type;
if (screen_cast->inhibit_count > 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Session creation inhibited");
return TRUE;
}
g_variant_lookup (properties, "remote-desktop-session-id", "s",
&remote_desktop_session_id);

View File

@@ -42,10 +42,6 @@ G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
META, SCREEN_CAST,
MetaDBusScreenCastSkeleton)
void meta_screen_cast_inhibit (MetaScreenCast *screen_cast);
void meta_screen_cast_uninhibit (MetaScreenCast *screen_cast);
GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);

View File

@@ -38,10 +38,9 @@ typedef enum
META_STAGE_WATCH_AFTER_PAINT,
} MetaStageWatchPhase;
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
gpointer user_data);
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
ClutterStageView *view,
gpointer user_data);
ClutterActor *meta_stage_new (MetaBackend *backend);

View File

@@ -65,6 +65,7 @@ struct _MetaStage
ClutterStage parent;
GPtrArray *watchers[N_WATCH_MODES];
ClutterStageView *current_view;
GList *overlays;
gboolean is_active;
@@ -168,7 +169,6 @@ meta_stage_finalize (GObject *object)
static void
notify_watchers_for_mode (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
MetaStageWatchPhase watch_phase)
{
GPtrArray *watchers;
@@ -183,7 +183,7 @@ notify_watchers_for_mode (MetaStage *stage,
if (watch->view && view != watch->view)
continue;
watch->callback (stage, view, paint_context, watch->user_data);
watch->callback (stage, view, watch->user_data);
}
}
@@ -192,32 +192,20 @@ meta_stage_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
MetaStage *stage = META_STAGE (actor);
ClutterStageView *view;
GList *l;
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
view = clutter_paint_context_get_stage_view (paint_context);
if (view)
{
notify_watchers_for_mode (stage, view, paint_context,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
}
notify_watchers_for_mode (stage, stage->current_view,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
if (!(clutter_paint_context_get_paint_flags (paint_context) &
CLUTTER_PAINT_FLAG_NO_CURSORS))
{
for (l = stage->overlays; l; l = l->next)
meta_overlay_paint (l->data, paint_context);
}
for (l = stage->overlays; l; l = l->next)
meta_overlay_paint (l->data, paint_context);
if (view)
{
notify_watchers_for_mode (stage, view, paint_context,
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
}
notify_watchers_for_mode (stage, stage->current_view,
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
}
static void
@@ -227,14 +215,13 @@ meta_stage_paint_view (ClutterStage *stage,
{
MetaStage *meta_stage = META_STAGE (stage);
notify_watchers_for_mode (meta_stage, view, NULL,
META_STAGE_WATCH_BEFORE_PAINT);
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT);
meta_stage->current_view = view;
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view,
redraw_clip);
notify_watchers_for_mode (meta_stage, view, NULL,
META_STAGE_WATCH_AFTER_PAINT);
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT);
}
static void

View File

@@ -407,14 +407,13 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
else
scale = 1.0;
transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
monitor_crtc_mode->output,
transform,
META_MONITOR_TRANSFORM_NORMAL,
&crtc_x, &crtc_y);
transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
if (meta_monitor_transform_is_rotated (transform))
{
crtc_width = monitor_crtc_mode->crtc_mode->height;

View File

@@ -44,12 +44,7 @@ struct _MetaDrmBufferGbm
uint32_t fb_id;
};
static void
cogl_scanout_iface_init (CoglScanoutInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER,
G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT,
cogl_scanout_iface_init))
G_DEFINE_TYPE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER)
struct gbm_bo *
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
@@ -58,12 +53,22 @@ meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
}
static gboolean
init_fb_id (MetaDrmBufferGbm *buffer_gbm,
struct gbm_bo *bo,
gboolean use_modifiers,
GError **error)
acquire_swapped_buffer (MetaDrmBufferGbm *buffer_gbm,
gboolean use_modifiers,
GError **error)
{
MetaGpuKmsFBArgs fb_args = { 0, };
struct gbm_bo *bo;
bo = gbm_surface_lock_front_buffer (buffer_gbm->surface);
if (!bo)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"gbm_surface_lock_front_buffer failed");
return FALSE;
}
if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1)
{
@@ -94,34 +99,21 @@ init_fb_id (MetaDrmBufferGbm *buffer_gbm,
use_modifiers,
&fb_args,
&buffer_gbm->fb_id, error))
return FALSE;
{
gbm_surface_release_buffer (buffer_gbm->surface, bo);
return FALSE;
}
buffer_gbm->bo = bo;
return TRUE;
}
static gboolean
lock_front_buffer (MetaDrmBufferGbm *buffer_gbm,
gboolean use_modifiers,
GError **error)
{
buffer_gbm->bo = gbm_surface_lock_front_buffer (buffer_gbm->surface);
if (!buffer_gbm->bo)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"gbm_surface_lock_front_buffer failed");
return FALSE;
}
return init_fb_id (buffer_gbm, buffer_gbm->bo, use_modifiers, error);
}
MetaDrmBufferGbm *
meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error)
meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error)
{
MetaDrmBufferGbm *buffer_gbm;
@@ -129,7 +121,7 @@ meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
buffer_gbm->gpu_kms = gpu_kms;
buffer_gbm->surface = gbm_surface;
if (!lock_front_buffer (buffer_gbm, use_modifiers, error))
if (!acquire_swapped_buffer (buffer_gbm, use_modifiers, error))
{
g_object_unref (buffer_gbm);
return NULL;
@@ -138,39 +130,12 @@ meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
return buffer_gbm;
}
MetaDrmBufferGbm *
meta_drm_buffer_gbm_new_take (MetaGpuKms *gpu_kms,
struct gbm_bo *bo,
gboolean use_modifiers,
GError **error)
{
MetaDrmBufferGbm *buffer_gbm;
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL);
buffer_gbm->gpu_kms = gpu_kms;
if (!init_fb_id (buffer_gbm, bo, use_modifiers, error))
{
g_object_unref (buffer_gbm);
return NULL;
}
buffer_gbm->bo = bo;
return buffer_gbm;
}
static uint32_t
meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_GBM (buffer)->fb_id;
}
static void
cogl_scanout_iface_init (CoglScanoutInterface *iface)
{
}
static void
meta_drm_buffer_gbm_finalize (GObject *object)
{
@@ -185,12 +150,7 @@ meta_drm_buffer_gbm_finalize (GObject *object)
}
if (buffer_gbm->bo)
{
if (buffer_gbm->surface)
gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo);
else
gbm_bo_destroy (buffer_gbm->bo);
}
gbm_surface_release_buffer (buffer_gbm->surface, buffer_gbm->bo);
G_OBJECT_CLASS (meta_drm_buffer_gbm_parent_class)->finalize (object);
}

View File

@@ -33,16 +33,10 @@ G_DECLARE_FINAL_TYPE (MetaDrmBufferGbm,
META, DRM_BUFFER_GBM,
MetaDrmBuffer)
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error);
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_take (MetaGpuKms *gpu_kms,
struct gbm_bo *gbm_bo,
gboolean use_modifiers,
GError **error);
MetaDrmBufferGbm * meta_drm_buffer_gbm_new (MetaGpuKms *gpu_kms,
struct gbm_surface *gbm_surface,
gboolean use_modifiers,
GError **error);
struct gbm_bo * meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Red Hat
* Copyright (C) 2019-2020 DisplayLink (UK) Ltd.
* Copyright (C) 2019 DisplayLink (UK) Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -660,9 +660,6 @@ process_page_flip (MetaKmsImpl *impl,
meta_kms_page_flip_data_ref (page_flip_data));
}
if (ret != 0)
meta_kms_page_flip_data_unref (page_flip_data);
if (ret == -EBUSY)
{
CachedModeSet *cached_mode_set;

View File

@@ -1,6 +1,5 @@
/*
* Copyright (C) 2018 Red Hat
* Copyright 2020 DisplayLink (UK) Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -384,7 +383,6 @@ meta_kms_add_source_in_impl (MetaKms *kms,
simple_impl_source->kms = kms;
g_source_set_callback (source, func, user_data, user_data_destroy);
g_source_set_ready_time (source, 0);
g_source_attach (source, g_main_context_get_thread_default ());
return source;

View File

@@ -313,12 +313,6 @@ meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms)
return renderer_gpu_data->gbm.device;
}
MetaGpuKms *
meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native)
{
return renderer_native->primary_gpu_kms;
}
static MetaRendererNativeGpuData *
meta_create_renderer_native_gpu_data (MetaGpuKms *gpu_kms)
{
@@ -1627,14 +1621,13 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
return;
}
buffer_gbm =
meta_drm_buffer_gbm_new_lock_front (secondary_gpu_state->gpu_kms,
buffer_gbm = meta_drm_buffer_gbm_new (secondary_gpu_state->gpu_kms,
secondary_gpu_state->gbm.surface,
renderer_native->use_modifiers,
&error);
if (!buffer_gbm)
{
g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s",
g_warning ("meta_drm_buffer_gbm_new failed: %s",
error->message);
g_error_free (error);
return;
@@ -2019,34 +2012,6 @@ retry:
}
}
static void
ensure_crtc_modes (CoglOnscreen *onscreen,
MetaKmsUpdate *kms_update)
{
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaPowerSave power_save_mode;
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
if (onscreen_native->pending_set_crtc &&
power_save_mode == META_POWER_SAVE_ON)
{
meta_onscreen_native_set_crtc_mode (onscreen,
renderer_gpu_data,
kms_update);
onscreen_native->pending_set_crtc = FALSE;
}
}
static void
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
const int *rectangles,
@@ -2060,6 +2025,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
@@ -2068,6 +2035,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglFrameInfo *frame_info;
gboolean egl_context_changed = FALSE;
MetaKmsUpdate *kms_update;
MetaPowerSave power_save_mode;
g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
@@ -2103,14 +2071,13 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
g_clear_object (&onscreen_native->gbm.next_fb);
buffer_gbm =
meta_drm_buffer_gbm_new_lock_front (render_gpu,
buffer_gbm = meta_drm_buffer_gbm_new (render_gpu,
onscreen_native->gbm.surface,
renderer_native->use_modifiers,
&error);
if (!buffer_gbm)
{
g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s",
g_warning ("meta_drm_buffer_gbm_new failed: %s",
error->message);
return;
}
@@ -2126,7 +2093,18 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed);
ensure_crtc_modes (onscreen, kms_update);
/* If this is the first framebuffer to be presented then we now setup the
* crtc modes, else we flip from the previous buffer */
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
if (onscreen_native->pending_set_crtc &&
power_save_mode == META_POWER_SAVE_ON)
{
meta_onscreen_native_set_crtc_mode (onscreen,
renderer_gpu_data,
kms_update);
onscreen_native->pending_set_crtc = FALSE;
}
onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter;
meta_onscreen_native_flip_crtcs (onscreen, kms_update);
@@ -2220,92 +2198,6 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
return NULL;
}
gboolean
meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
uint32_t drm_format,
uint64_t drm_modifier,
uint32_t stride)
{
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaDrmBuffer *fb;
struct gbm_bo *gbm_bo;
if (onscreen_native->crtc->config->transform != META_MONITOR_TRANSFORM_NORMAL)
return FALSE;
if (onscreen_native->secondary_gpu_state)
return FALSE;
if (!onscreen_native->gbm.surface)
return FALSE;
fb = onscreen_native->gbm.current_fb ? onscreen_native->gbm.current_fb
: onscreen_native->gbm.next_fb;
if (!fb)
return FALSE;
if (!META_IS_DRM_BUFFER_GBM (fb))
return FALSE;
gbm_bo = meta_drm_buffer_gbm_get_bo (META_DRM_BUFFER_GBM (fb));
if (gbm_bo_get_format (gbm_bo) != drm_format)
return FALSE;
if (gbm_bo_get_modifier (gbm_bo) != drm_modifier)
return FALSE;
if (gbm_bo_get_stride (gbm_bo) != stride)
return FALSE;
return TRUE;
}
static void
meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
CoglScanout *scanout)
{
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
CoglFrameInfo *frame_info;
MetaKmsUpdate *kms_update;
g_autoptr (GError) error = NULL;
kms_update = meta_kms_ensure_pending_update (kms);
wait_for_pending_flips (onscreen);
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
frame_info->global_frame_counter = renderer_native->frame_counter;
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
render_gpu);
g_return_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
g_warn_if_fail (!onscreen_native->gbm.next_fb);
g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout));
ensure_crtc_modes (onscreen, kms_update);
onscreen_native->pending_queue_swap_notify_frame_count =
renderer_native->frame_counter;
meta_onscreen_native_flip_crtcs (onscreen, kms_update);
meta_kms_post_pending_update_sync (kms);
}
static gboolean
meta_renderer_native_init_egl_context (CoglContext *cogl_context,
GError **error)
@@ -3029,7 +2921,6 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
vtable.onscreen_swap_region = NULL;
vtable.onscreen_swap_buffers_with_damage =
meta_onscreen_native_swap_buffers_with_damage;
vtable.onscreen_direct_scanout = meta_onscreen_native_direct_scanout;
vtable.context_get_clock_time = meta_renderer_native_get_clock_time;
@@ -3146,7 +3037,6 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
float scale;
int onscreen_width;
int onscreen_height;
MetaRectangle view_layout;
MetaRendererView *view;
GError *error = NULL;
@@ -3218,11 +3108,8 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
else
scale = 1.0;
meta_rectangle_from_graphene_rect (&crtc->config->layout,
META_ROUNDING_STRATEGY_ROUND,
&view_layout);
view = g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &view_layout,
"layout", &logical_monitor->rect,
"scale", scale,
"framebuffer", onscreen,
"offscreen", offscreen,

View File

@@ -51,15 +51,8 @@ MetaRendererNative * meta_renderer_native_new (MetaBackendNative *backend_nativ
struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms);
MetaGpuKms * meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native);
void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native);
int64_t meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native);
gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
uint32_t drm_format,
uint64_t drm_modifier,
uint32_t stride);
#endif /* META_RENDERER_NATIVE_H */

View File

@@ -14,14 +14,11 @@
/* Wait 2ms after vblank before starting to draw next frame */
#define META_SYNC_DELAY 2
typedef struct _MetaLaters MetaLaters;
struct _MetaCompositorClass
{
GObjectClass parent_class;
gboolean (* manage) (MetaCompositor *compositor,
GError **error);
void (* manage) (MetaCompositor *compositor);
void (* unmanage) (MetaCompositor *compositor);
void (* pre_paint) (MetaCompositor *compositor);
void (* post_paint) (MetaCompositor *compositor);
@@ -29,9 +26,6 @@ struct _MetaCompositorClass
MetaWindow *window);
};
gboolean meta_compositor_do_manage (MetaCompositor *compositor,
GError **error);
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
MetaWindowActor *window_actor);
@@ -73,6 +67,4 @@ ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
#endif /* META_COMPOSITOR_PRIVATE_H */

View File

@@ -62,8 +62,8 @@
#include "backends/x11/meta-stage-x11.h"
#include "clutter/clutter-mutter.h"
#include "cogl/cogl.h"
#include "compositor/meta-later-private.h"
#include "compositor/meta-window-actor-x11.h"
#include "compositor/meta-window-actor-wayland.h"
#include "compositor/meta-window-actor-private.h"
#include "compositor/meta-window-group-private.h"
#include "core/display-private.h"
@@ -82,7 +82,6 @@
#include "x11/meta-x11-display-private.h"
#ifdef HAVE_WAYLAND
#include "compositor/meta-window-actor-wayland.h"
#include "wayland/meta-wayland-private.h"
#endif
@@ -97,15 +96,6 @@ enum
static GParamSpec *obj_props[N_PROPS] = { NULL, };
enum
{
PRE_PAINT,
N_SIGNALS
};
static guint signals[N_SIGNALS];
typedef struct _MetaCompositorPrivate
{
GObject parent;
@@ -141,8 +131,6 @@ typedef struct _MetaCompositorPrivate
int switch_workspace_in_progress;
MetaPluginManager *plugin_mgr;
MetaLaters *laters;
} MetaCompositorPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor,
@@ -562,9 +550,8 @@ meta_compositor_redirect_x11_windows (MetaCompositor *compositor)
redirect_windows (display->x11_display);
}
gboolean
meta_compositor_do_manage (MetaCompositor *compositor,
GError **error)
void
meta_compositor_manage (MetaCompositor *compositor)
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
@@ -600,21 +587,9 @@ meta_compositor_do_manage (MetaCompositor *compositor,
clutter_actor_add_child (priv->stage, priv->top_window_group);
clutter_actor_add_child (priv->stage, priv->feedback_group);
if (!META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor, error))
return FALSE;
META_COMPOSITOR_GET_CLASS (compositor)->manage (compositor);
priv->plugin_mgr = meta_plugin_manager_new (compositor);
return TRUE;
}
void
meta_compositor_manage (MetaCompositor *compositor)
{
GError *error = NULL;
if (!meta_compositor_do_manage (compositor, &error))
g_error ("Compositor failed to manage display: %s", error->message);
}
void
@@ -1133,8 +1108,7 @@ meta_compositor_pre_paint (MetaCompositor *compositor)
{
COGL_TRACE_BEGIN_SCOPED (MetaCompositorPrePaint,
"Compositor (pre-paint)");
g_signal_emit (compositor, signals[PRE_PAINT], 0);
META_COMPOSITOR_GET_CLASS (compositor)->pre_paint (compositor);
}
static gboolean
@@ -1256,8 +1230,6 @@ meta_compositor_init (MetaCompositor *compositor)
meta_post_paint_func,
compositor,
NULL);
priv->laters = meta_laters_new (compositor);
}
static void
@@ -1267,8 +1239,6 @@ meta_compositor_dispose (GObject *object)
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
g_clear_pointer (&priv->laters, meta_laters_free);
g_clear_signal_handler (&priv->stage_after_paint_id, priv->stage);
g_clear_signal_handler (&priv->stage_presented_id, priv->stage);
@@ -1310,14 +1280,6 @@ meta_compositor_class_init (MetaCompositorClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
signals[PRE_PAINT] =
g_signal_new ("pre-paint",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MetaCompositorClass, pre_paint),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
/**
@@ -1635,12 +1597,3 @@ meta_compositor_is_switching_workspace (MetaCompositor *compositor)
return priv->switch_workspace_in_progress > 0;
}
MetaLaters *
meta_compositor_get_laters (MetaCompositor *compositor)
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
return priv->laters;
}

View File

@@ -1,148 +0,0 @@
/*
* Copyright (C) 2019 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 "compositor/meta-compositor-native.h"
#include "backends/meta-logical-monitor.h"
#include "compositor/meta-surface-actor-wayland.h"
struct _MetaCompositorNative
{
MetaCompositorServer parent;
};
G_DEFINE_TYPE (MetaCompositorNative, meta_compositor_native,
META_TYPE_COMPOSITOR_SERVER)
static MetaRendererView *
get_window_view (MetaRenderer *renderer,
MetaWindow *window)
{
GList *l;
MetaRendererView *view_found = NULL;
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
ClutterStageView *stage_view = l->data;
MetaRectangle view_layout;
clutter_stage_view_get_layout (stage_view, &view_layout);
if (meta_rectangle_equal (&window->buffer_rect,
&view_layout))
{
if (view_found)
return NULL;
view_found = META_RENDERER_VIEW (stage_view);
}
}
return view_found;
}
static void
maybe_assign_primary_plane (MetaCompositor *compositor)
{
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaWindowActor *window_actor;
MetaWindow *window;
MetaRendererView *view;
CoglFramebuffer *framebuffer;
CoglOnscreen *onscreen;
MetaSurfaceActor *surface_actor;
MetaSurfaceActorWayland *surface_actor_wayland;
g_autoptr (CoglScanout) scanout = NULL;
if (meta_compositor_is_unredirect_inhibited (compositor))
return;
window_actor = meta_compositor_get_top_window_actor (compositor);
if (!window_actor)
return;
if (meta_window_actor_effect_in_progress (window_actor))
return;
if (clutter_actor_has_transitions (CLUTTER_ACTOR (window_actor)))
return;
if (clutter_actor_get_n_children (CLUTTER_ACTOR (window_actor)) != 1)
return;
window = meta_window_actor_get_meta_window (window_actor);
if (!window)
return;
view = get_window_view (renderer, window);
if (!view)
return;
framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
if (!cogl_is_onscreen (framebuffer))
return;
surface_actor = meta_window_actor_get_surface (window_actor);
if (!META_IS_SURFACE_ACTOR_WAYLAND (surface_actor))
return;
surface_actor_wayland = META_SURFACE_ACTOR_WAYLAND (surface_actor);
onscreen = COGL_ONSCREEN (framebuffer);
scanout = meta_surface_actor_wayland_try_acquire_scanout (surface_actor_wayland,
onscreen);
if (!scanout)
return;
clutter_stage_view_assign_next_scanout (CLUTTER_STAGE_VIEW (view), scanout);
}
static void
meta_compositor_native_pre_paint (MetaCompositor *compositor)
{
MetaCompositorClass *parent_class;
maybe_assign_primary_plane (compositor);
parent_class = META_COMPOSITOR_CLASS (meta_compositor_native_parent_class);
parent_class->pre_paint (compositor);
}
MetaCompositorNative *
meta_compositor_native_new (MetaDisplay *display)
{
return g_object_new (META_TYPE_COMPOSITOR_NATIVE,
"display", display,
NULL);
}
static void
meta_compositor_native_init (MetaCompositorNative *compositor_native)
{
}
static void
meta_compositor_native_class_init (MetaCompositorNativeClass *klass)
{
MetaCompositorClass *compositor_class = META_COMPOSITOR_CLASS (klass);
compositor_class->pre_paint = meta_compositor_native_pre_paint;
}

View File

@@ -22,13 +22,16 @@
#include "compositor/meta-compositor-server.h"
struct _MetaCompositorServer
{
MetaCompositor parent;
};
G_DEFINE_TYPE (MetaCompositorServer, meta_compositor_server, META_TYPE_COMPOSITOR)
static gboolean
meta_compositor_server_manage (MetaCompositor *compositor,
GError **error)
static void
meta_compositor_server_manage (MetaCompositor *compositor)
{
return TRUE;
}
static void

View File

@@ -24,13 +24,8 @@
#include "compositor/compositor-private.h"
#define META_TYPE_COMPOSITOR_SERVER (meta_compositor_server_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaCompositorServer, meta_compositor_server,
META, COMPOSITOR_SERVER, MetaCompositor)
struct _MetaCompositorServerClass
{
MetaCompositorClass parent_class;
};
G_DECLARE_FINAL_TYPE (MetaCompositorServer, meta_compositor_server,
META, COMPOSITOR_SERVER, MetaCompositor)
MetaCompositorServer * meta_compositor_server_new (MetaDisplay *display);

View File

@@ -100,39 +100,15 @@ meta_compositor_x11_process_xevent (MetaCompositorX11 *compositor_x11,
meta_x11_handle_event (xevent);
}
static gboolean
meta_compositor_x11_manage (MetaCompositor *compositor,
GError **error)
static void
meta_compositor_x11_manage (MetaCompositor *compositor)
{
MetaCompositorX11 *compositor_x11 = META_COMPOSITOR_X11 (compositor);
MetaDisplay *display = meta_compositor_get_display (compositor);
MetaX11Display *x11_display = display->x11_display;
Display *xdisplay = meta_x11_display_get_xdisplay (x11_display);
int composite_version;
Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
MetaBackend *backend = meta_get_backend ();
Window xwindow;
if (!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ||
!META_X11_DISPLAY_HAS_DAMAGE (x11_display))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Missing required extension %s",
!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ?
"composite" : "damage");
return FALSE;
}
composite_version = ((x11_display->composite_major_version * 10) +
x11_display->composite_minor_version);
if (composite_version < 3)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"COMPOSITE extension 3.0 required (found %d.%d)",
x11_display->composite_major_version,
x11_display->composite_minor_version);
return FALSE;
}
meta_x11_display_set_cm_selection (display->x11_display);
compositor_x11->output = display->x11_display->composite_overlay_window;
@@ -163,8 +139,6 @@ meta_compositor_x11_manage (MetaCompositor *compositor,
compositor_x11->have_x11_sync_object = meta_sync_ring_init (xdisplay);
meta_compositor_redirect_x11_windows (META_COMPOSITOR (compositor));
return TRUE;
}
static void

View File

@@ -1,28 +0,0 @@
/*
* Copyright (C) 2020 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_LATER_PRIVATE_H
#define META_LATER_PRIVATE_H
typedef struct _MetaLaters MetaLaters;
typedef struct _MetaCompositor MetaCompositor;
MetaLaters * meta_laters_new (MetaCompositor *compositor);
void meta_laters_free (MetaLaters *laters);
#endif /* META_LATER_PRIVATE_H */

View File

@@ -1,349 +0,0 @@
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
* Copyright (C) 2020 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, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "compositor/meta-later-private.h"
#include "cogl/cogl.h"
#include "compositor/compositor-private.h"
#include "core/display-private.h"
#include "meta/meta-later.h"
typedef struct _MetaLater
{
unsigned int id;
unsigned int ref_count;
MetaLaterType when;
GSourceFunc func;
gpointer user_data;
GDestroyNotify destroy_notify;
guint source_id;
gboolean run_once;
} MetaLater;
#define META_LATER_N_TYPES (META_LATER_IDLE + 1)
struct _MetaLaters
{
MetaCompositor *compositor;
unsigned int last_later_id;
GSList *laters[META_LATER_N_TYPES];
ClutterTimeline *timeline;
gulong pre_paint_handler_id;
};
static MetaLater *
meta_later_ref (MetaLater *later)
{
later->ref_count++;
return later;
}
static void
meta_later_unref (MetaLater *later)
{
if (--later->ref_count == 0)
{
if (later->destroy_notify)
{
later->destroy_notify (later->user_data);
later->destroy_notify = NULL;
}
g_slice_free (MetaLater, later);
}
}
static void
meta_later_destroy (MetaLater *later)
{
g_clear_handle_id (&later->source_id, g_source_remove);
later->func = NULL;
meta_later_unref (later);
}
#ifdef COGL_HAS_TRACING
static const char *
later_type_to_string (MetaLaterType when)
{
switch (when)
{
case META_LATER_RESIZE:
return "Later (resize)";
case META_LATER_CALC_SHOWING:
return "Later (calc-showing)";
case META_LATER_CHECK_FULLSCREEN:
return "Later (check-fullscreen)";
case META_LATER_SYNC_STACK:
return "Later (sync-stack)";
case META_LATER_BEFORE_REDRAW:
return "Later (before-redraw)";
case META_LATER_IDLE:
return "Later (idle)";
}
return "unknown";
}
#endif
static gboolean
meta_later_invoke (MetaLater *later)
{
COGL_TRACE_BEGIN_SCOPED (later, later_type_to_string (later->when));
return later->func (later->user_data);
}
static gboolean
remove_later_from_list (unsigned int later_id,
GSList **laters_list)
{
GSList *l;
for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
if (later->id == later_id)
{
*laters_list = g_slist_delete_link (*laters_list, l);
meta_later_destroy (later);
return TRUE;
}
}
return FALSE;
}
static void
run_repaint_laters (GSList **laters_list)
{
g_autoptr (GSList) laters_copy = NULL;
GSList *l;
for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
if (!later->source_id ||
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
laters_copy = g_slist_prepend (laters_copy, meta_later_ref (later));
}
laters_copy = g_slist_reverse (laters_copy);
for (l = laters_copy; l; l = l->next)
{
MetaLater *later = l->data;
if (!later->func)
remove_later_from_list (later->id, laters_list);
else if (!meta_later_invoke (later))
remove_later_from_list (later->id, laters_list);
meta_later_unref (later);
}
}
static void
on_pre_paint (MetaCompositor *compositor,
MetaLaters *laters)
{
unsigned int i;
GSList *l;
gboolean keep_timeline_running = FALSE;
for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
run_repaint_laters (&laters->laters[i]);
for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
{
for (l = laters->laters[i]; l; l = l->next)
{
MetaLater *later = l->data;
if (!later->source_id)
keep_timeline_running = TRUE;
}
}
if (!keep_timeline_running)
clutter_timeline_stop (laters->timeline);
}
static void
ensure_timeline_running (MetaLaters *laters)
{
clutter_timeline_start (laters->timeline);
}
static gboolean
invoke_later_idle (gpointer data)
{
MetaLater *later = data;
if (!later->func (later->user_data))
{
meta_later_remove (later->id);
return FALSE;
}
else
{
later->run_once = TRUE;
return TRUE;
}
}
static unsigned int
meta_laters_add (MetaLaters *laters,
MetaLaterType when,
GSourceFunc func,
gpointer user_data,
GDestroyNotify notify)
{
MetaLater *later = g_slice_new0 (MetaLater);
later->id = ++laters->last_later_id;
later->ref_count = 1;
later->when = when;
later->func = func;
later->user_data = user_data;
later->destroy_notify = notify;
laters->laters[when] = g_slist_prepend (laters->laters[when], later);
switch (when)
{
case META_LATER_RESIZE:
later->source_id = g_idle_add_full (META_PRIORITY_RESIZE,
invoke_later_idle,
later, NULL);
g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
ensure_timeline_running (laters);
break;
case META_LATER_CALC_SHOWING:
case META_LATER_CHECK_FULLSCREEN:
case META_LATER_SYNC_STACK:
case META_LATER_BEFORE_REDRAW:
ensure_timeline_running (laters);
break;
case META_LATER_IDLE:
later->source_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
invoke_later_idle,
later, NULL);
g_source_set_name_by_id (later->source_id, "[mutter] invoke_later_idle");
break;
}
return later->id;
}
/**
* meta_later_add:
* @when: enumeration value determining the phase at which to run the callback
* @func: callback to run later
* @data: data to pass to the callback
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
*
* Sets up a callback to be called at some later time. @when determines the
* particular later occasion at which it is called. This is much like g_idle_add(),
* except that the functions interact properly with clutter event handling.
* If a "later" function is added from a clutter event handler, and is supposed
* to be run before the stage is redrawn, it will be run before that redraw
* of the stage, not the next one.
*
* Return value: an integer ID (guaranteed to be non-zero) that can be used
* to cancel the callback and prevent it from being run.
*/
unsigned int
meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
MetaDisplay *display = meta_get_display ();
MetaCompositor *compositor = display->compositor;
return meta_laters_add (meta_compositor_get_laters (compositor),
when, func, data, notify);
}
static void
meta_laters_remove (MetaLaters *laters,
unsigned int later_id)
{
unsigned int i;
for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
{
if (remove_later_from_list (later_id, &laters->laters[i]))
return;
}
}
/**
* meta_later_remove:
* @later_id: the integer ID returned from meta_later_add()
*
* Removes a callback added with meta_later_add()
*/
void
meta_later_remove (unsigned int later_id)
{
MetaDisplay *display = meta_get_display ();
MetaCompositor *compositor = display->compositor;
if (!compositor)
return;
meta_laters_remove (meta_compositor_get_laters (compositor), later_id);
}
MetaLaters *
meta_laters_new (MetaCompositor *compositor)
{
MetaLaters *laters;
laters = g_new0 (MetaLaters, 1);
laters->compositor = compositor;
laters->timeline = clutter_timeline_new (G_MAXUINT);
laters->pre_paint_handler_id = g_signal_connect (compositor, "pre-paint",
G_CALLBACK (on_pre_paint),
laters);
return laters;
}
void
meta_laters_free (MetaLaters *laters)
{
unsigned int i;
for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
g_slist_free_full (laters->laters[i], (GDestroyNotify) meta_later_unref);
g_clear_object (&laters->timeline);
g_clear_signal_handler (&laters->pre_paint_handler_id, laters->compositor);
g_free (laters);
}

View File

@@ -1270,9 +1270,7 @@ get_image_via_offscreen (MetaShapedTexture *stex,
root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR);
clutter_paint_node_set_static_name (root_node, "MetaShapedTexture.offscreen");
paint_context =
clutter_paint_context_new_for_framebuffer (fb, NULL,
CLUTTER_PAINT_FLAG_NONE);
paint_context = clutter_paint_context_new_for_framebuffer (fb);
do_paint_content (stex, root_node, paint_context,
stex->texture,

View File

@@ -79,40 +79,6 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
return meta_shaped_texture_is_opaque (stex);
}
static void
queue_frame_callbacks (MetaSurfaceActorWayland *self)
{
MetaWaylandCompositor *wayland_compositor;
if (!self->surface)
return;
if (meta_surface_actor_is_obscured (META_SURFACE_ACTOR (self)))
return;
wayland_compositor = self->surface->compositor;
wl_list_insert_list (&wayland_compositor->frame_callbacks,
&self->frame_callback_list);
wl_list_init (&self->frame_callback_list);
}
CoglScanout *
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
CoglOnscreen *onscreen)
{
MetaWaylandSurface *surface;
CoglScanout *scanout;
surface = meta_surface_actor_wayland_get_surface (self);
scanout = meta_wayland_surface_try_acquire_scanout (surface, onscreen);
if (!scanout)
return NULL;
queue_frame_callbacks (self);
return scanout;
}
void
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
struct wl_list *frame_callbacks)
@@ -126,7 +92,14 @@ meta_surface_actor_wayland_paint (ClutterActor *actor,
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
queue_frame_callbacks (self);
if (self->surface &&
!meta_surface_actor_is_obscured (META_SURFACE_ACTOR (actor)))
{
MetaWaylandCompositor *compositor = self->surface->compositor;
wl_list_insert_list (&compositor->frame_callbacks, &self->frame_callback_list);
wl_list_init (&self->frame_callback_list);
}
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
paint_context);

View File

@@ -52,9 +52,6 @@ void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *se
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
struct wl_list *frame_callbacks);
CoglScanout * meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
CoglOnscreen *onscreen);
G_END_DECLS
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */

View File

@@ -260,14 +260,33 @@ meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor)
gboolean
meta_surface_actor_x11_should_unredirect (MetaSurfaceActorX11 *self)
{
MetaWindow *window = self->window;
if (meta_window_requested_dont_bypass_compositor (window))
return FALSE;
if (window->opacity != 0xFF)
return FALSE;
if (window->shape_region != NULL)
return FALSE;
if (!meta_window_is_monitor_sized (window))
return FALSE;
if (meta_window_requested_bypass_compositor (window))
return TRUE;
if (!meta_surface_actor_x11_is_opaque (META_SURFACE_ACTOR (self)))
return FALSE;
if (!self->does_full_damage &&
!meta_window_is_override_redirect (self->window))
return FALSE;
if (meta_window_is_override_redirect (window))
return TRUE;
return TRUE;
if (self->does_full_damage)
return TRUE;
return FALSE;
}
static void

View File

@@ -39,7 +39,6 @@
#include "meta/meta-window-actor.h"
#include "meta/meta-x11-errors.h"
#include "meta/window.h"
#include "x11/window-x11.h"
#include "x11/meta-x11-display-private.h"
#include "x11/window-x11.h"
@@ -86,8 +85,6 @@ struct _MetaWindowActorX11
cairo_region_t *shape_region;
/* The region we should clip to when painting the shadow */
cairo_region_t *shadow_clip;
/* The frame region */
cairo_region_t *frame_bounds;
/* Extracted size-invariant shape used for shadows */
MetaWindowShape *shadow_shape;
@@ -543,18 +540,12 @@ has_shadow (MetaWindowActorX11 *actor_x11)
gboolean
meta_window_actor_x11_should_unredirect (MetaWindowActorX11 *actor_x11)
{
MetaWindow *window =
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
MetaSurfaceActor *surface;
MetaSurfaceActorX11 *surface_x11;
if (meta_window_actor_is_destroyed (META_WINDOW_ACTOR (actor_x11)))
return FALSE;
if (!meta_window_x11_can_unredirect (window_x11))
return FALSE;
surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11));
if (!surface)
return FALSE;
@@ -711,8 +702,11 @@ set_clip_region_beneath (MetaWindowActorX11 *actor_x11,
if (clip_shadow_under_window (actor_x11))
{
if (actor_x11->frame_bounds)
cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds);
cairo_region_t *frame_bounds;
frame_bounds = meta_window_get_frame_bounds (window);
if (frame_bounds)
cairo_region_subtract (actor_x11->shadow_clip, frame_bounds);
}
}
else
@@ -1132,17 +1126,6 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
cairo_region_destroy (opaque_region);
}
static void
update_frame_bounds (MetaWindowActorX11 *actor_x11)
{
MetaWindow *window =
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
actor_x11->frame_bounds =
cairo_region_copy (meta_window_get_frame_bounds (window));
}
static void
update_regions (MetaWindowActorX11 *actor_x11)
{
@@ -1214,7 +1197,6 @@ handle_updates (MetaWindowActorX11 *actor_x11)
if (!meta_surface_actor_is_visible (surface))
return;
update_frame_bounds (actor_x11);
check_needs_reshape (actor_x11);
check_needs_shadow (actor_x11);
}
@@ -1268,13 +1250,15 @@ meta_window_actor_x11_paint (ClutterActor *actor,
*/
if (!clip && clip_shadow_under_window (actor_x11))
{
cairo_region_t *frame_bounds;
cairo_rectangle_int_t bounds;
get_shadow_bounds (actor_x11, appears_focused, &bounds);
clip = cairo_region_create_rectangle (&bounds);
if (actor_x11->frame_bounds)
cairo_region_subtract (clip, actor_x11->frame_bounds);
frame_bounds = meta_window_get_frame_bounds (window);
if (frame_bounds)
cairo_region_subtract (clip, frame_bounds);
}
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
@@ -1561,7 +1545,6 @@ meta_window_actor_x11_dispose (GObject *object)
g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
g_clear_pointer (&actor_x11->shadow_class, g_free);
g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref);

View File

@@ -1321,9 +1321,7 @@ meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
cogl_framebuffer_translate (framebuffer, -x, -y, 0);
paint_context =
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
CLUTTER_PAINT_FLAG_NONE);
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
clutter_actor_paint (actor, paint_context);
clutter_paint_context_destroy (paint_context);
@@ -1481,9 +1479,7 @@ meta_window_actor_get_image (MetaWindowActor *self,
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
cogl_framebuffer_translate (framebuffer, -x, -y, 0);
paint_context =
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
CLUTTER_PAINT_FLAG_NONE);
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
clutter_actor_paint (actor, paint_context);
clutter_paint_context_destroy (paint_context);

View File

@@ -51,7 +51,6 @@
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-event-x11.h"
#include "backends/x11/cm/meta-backend-x11-cm.h"
#include "backends/x11/nested/meta-backend-x11-nested.h"
#include "clutter/x11/clutter-x11.h"
#include "compositor/compositor-private.h"
#include "compositor/meta-compositor-x11.h"
@@ -82,7 +81,6 @@
#include "x11/xprops.h"
#ifdef HAVE_WAYLAND
#include "compositor/meta-compositor-native.h"
#include "compositor/meta-compositor-server.h"
#include "wayland/meta-xwayland-private.h"
#include "wayland/meta-wayland-tablet-seat.h"
@@ -574,16 +572,44 @@ static MetaCompositor *
create_compositor (MetaDisplay *display)
{
#ifdef HAVE_WAYLAND
MetaBackend *backend = meta_get_backend ();
#ifdef HAVE_NATIVE_BACKEND
if (META_IS_BACKEND_NATIVE (backend))
return META_COMPOSITOR (meta_compositor_native_new (display));
#endif
if (META_IS_BACKEND_X11_NESTED (backend))
if (meta_is_wayland_compositor ())
return META_COMPOSITOR (meta_compositor_server_new (display));
else
#endif
return META_COMPOSITOR (meta_compositor_x11_new (display));
return META_COMPOSITOR (meta_compositor_x11_new (display));
}
static void
enable_compositor (MetaDisplay *display)
{
MetaX11Display *x11_display = display->x11_display;
if (x11_display)
{
if (!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ||
!META_X11_DISPLAY_HAS_DAMAGE (x11_display))
{
meta_fatal ("Missing %s extension required for compositing",
!META_X11_DISPLAY_HAS_COMPOSITE (x11_display) ?
"composite" : "damage");
return;
}
int version = (x11_display->composite_major_version * 10) +
x11_display->composite_minor_version;
if (version < 3)
{
meta_fatal ("Your version of COMPOSITE (%d.%d) is too old. Version 3.0 or later required.",
x11_display->composite_major_version,
x11_display->composite_minor_version);
return;
}
}
if (!display->compositor)
display->compositor = create_compositor (display);
meta_compositor_manage (display->compositor);
}
static void
@@ -859,8 +885,6 @@ meta_display_open (void)
g_signal_connect (settings, "ui-scaling-factor-changed",
G_CALLBACK (on_ui_scaling_factor_changed), display);
display->compositor = create_compositor (display);
meta_display_set_cursor (display, META_CURSOR_DEFAULT);
display->stack = meta_stack_new (display);
@@ -898,6 +922,7 @@ meta_display_open (void)
display->last_focus_time = timestamp;
display->last_user_time = timestamp;
display->compositor = NULL;
if (!meta_is_wayland_compositor ())
meta_prop_get_window (display->x11_display,
@@ -905,11 +930,7 @@ meta_display_open (void)
display->x11_display->atom__NET_ACTIVE_WINDOW,
&old_active_xwindow);
if (!meta_compositor_do_manage (display->compositor, &error))
{
g_error ("Compositor failed to manage display: %s",
error->message);
}
enable_compositor (display);
if (display->x11_display)
{

View File

@@ -2129,7 +2129,7 @@ process_special_modifier_key (MetaDisplay *display,
return TRUE;
}
else if (event->type == CLUTTER_KEY_PRESS &&
((event->modifier_state & ~(IGNORED_MODIFIERS)) & CLUTTER_MODIFIER_MASK) == 0 &&
(event->modifier_state & ~(IGNORED_MODIFIERS)) == 0 &&
resolved_key_combo_has_keycode (resolved_key_combo,
event->hardware_keycode))
{

View File

@@ -1,368 +0,0 @@
/*
* Copyright (C) 2020 Sebastian Wick
*
* 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.
*
* Author: Sebastian Wick <sebastian@sebastianwick.net>
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "core/meta-anonymous-file.h"
struct _MetaAnonymousFile
{
int fd;
size_t size;
};
#define READONLY_SEALS (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
static int
create_tmpfile_cloexec (char *tmpname)
{
int fd;
#if defined(HAVE_MKOSTEMP)
fd = mkostemp (tmpname, O_CLOEXEC);
if (fd >= 0)
unlink (tmpname);
#else
fd = mkstemp (tmpname);
if (fd >= 0)
{
long flags;
unlink (tmpname);
flags = fcntl (fd, F_GETFD);
if (flags == -1 ||
fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
{
close (fd);
return -1;
}
}
#endif
return fd;
}
/*
* Create a new, unique, anonymous file of the given size, and
* return the file descriptor for it. The file descriptor is set
* CLOEXEC. The file is immediately suitable for mmap()'ing
* the given size at offset zero.
*
* The file should not have a permanent backing store like a disk,
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
*
* The file name is deleted from the file system.
*
* The file is suitable for buffer sharing between processes by
* transmitting the file descriptor over Unix sockets using the
* SCM_RIGHTS methods.
*
* If the C library implements posix_fallocate(), it is used to
* guarantee that disk space is available for the file at the
* given size. If disk space is insufficient, errno is set to ENOSPC.
* If posix_fallocate() is not supported, program may receive
* SIGBUS on accessing mmap()'ed file contents instead.
*
* If the C library implements memfd_create(), it is used to create the
* file purely in memory, without any backing file name on the file
* system, and then sealing off the possibility of shrinking it. This
* can then be checked before accessing mmap()'ed file contents, to make
* sure SIGBUS can't happen. It also avoids requiring XDG_RUNTIME_DIR.
*/
static int
create_anonymous_file (off_t size)
{
int fd, ret;
#if defined(HAVE_MEMFD_CREATE)
fd = memfd_create ("mutter-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (fd >= 0)
{
/* We can add this seal before calling posix_fallocate(), as
* the file is currently zero-sized anyway.
*
* There is also no need to check for the return value, we
* couldn't do anything with it anyway.
*/
fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK);
}
else
#endif
{
static const char template[] = "/mutter-shared-XXXXXX";
const char *path;
char *name;
path = getenv ("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}
name = g_malloc (strlen (path) + sizeof (template));
if (!name)
return -1;
strcpy (name, path);
strcat (name, template);
fd = create_tmpfile_cloexec (name);
g_free (name);
if (fd < 0)
return -1;
}
#if defined(HAVE_POSIX_FALLOCATE)
do
{
ret = posix_fallocate (fd, 0, size);
}
while (ret == EINTR);
if (ret != 0)
{
close (fd);
errno = ret;
return -1;
}
#else
do
{
ret = ftruncate (fd, size);
}
while (ret < 0 && errno == EINTR);
if (ret < 0)
{
close (fd);
return -1;
}
#endif
return fd;
}
/**
* meta_anonymous_file_new: (skip)
* @size: The size of @data
* @data: The data of the file with the size @size
*
* Create a new anonymous read-only file of the given size and the given data
* The intended use-case is for sending mid-sized data from the compositor
* to clients.
*
* When done, free the data using meta_anonymous_file_free().
*
* If this function fails errno is set.
*
* Returns: The newly created #MetaAnonymousFile, or NULL on failure. Use
* meta_anonymous_file_free() to free the resources when done.
*/
MetaAnonymousFile *
meta_anonymous_file_new (size_t size,
const uint8_t *data)
{
MetaAnonymousFile *file;
void *map;
file = g_malloc0 (sizeof *file);
if (!file)
{
errno = ENOMEM;
return NULL;
}
file->size = size;
file->fd = create_anonymous_file (size);
if (file->fd == -1)
goto err_free;
map = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, file->fd, 0);
if (map == MAP_FAILED)
goto err_close;
memcpy (map, data, size);
munmap (map, size);
#if defined(HAVE_MEMFD_CREATE)
/* try to put seals on the file to make it read-only so that we can
* return the fd later directly when MAPMODE_SHARED is not set.
* meta_anonymous_file_open_fd can handle the fd even if it is not
* sealed read-only and will instead create a new anonymous file on
* each invocation.
*/
fcntl (file->fd, F_ADD_SEALS, READONLY_SEALS);
#endif
return file;
err_close:
close (file->fd);
err_free:
g_free (file);
return NULL;
}
/**
* meta_anonymous_file_free: (skip)
* @file: the #MetaAnonymousFile
*
* Free the resources used by an anonymous read-only file.
*/
void
meta_anonymous_file_free (MetaAnonymousFile *file)
{
close (file->fd);
g_free (file);
}
/**
* meta_anonymous_file_size: (skip)
* @file: the #MetaAnonymousFile
*
* Get the size of an anonymous read-only file.
*
* Returns: The size of the anonymous read-only file.
*/
size_t
meta_anonymous_file_size (MetaAnonymousFile *file)
{
return file->size;
}
/**
* meta_anonymous_file_open_fd: (skip)
* @file: the #MetaAnonymousFile to get a file descriptor for
* @mapmode: describes the ways in which the returned file descriptor can
* be used with mmap
*
* Returns a file descriptor for the given file, ready to be sent to a client.
* The returned file descriptor must not be shared between multiple clients.
* If @mapmode is %META_ANONYMOUS_FILE_MAPMODE_PRIVATE the file descriptor is
* only guaranteed to be mmapable with MAP_PRIVATE. If @mapmode is
* %META_ANONYMOUS_FILE_MAPMODE_SHARED the file descriptor can be mmaped with
* either MAP_PRIVATE or MAP_SHARED.
*
* In case %META_ANONYMOUS_FILE_MAPMODE_PRIVATE is used, it is important to
* only read the returned fd using mmap() since using read() will move the
* read cursor of the fd and thus may cause read() calls on other returned
* fds to fail.
*
* When done using the fd, it is required to call meta_anonymous_file_close_fd()
* instead of close().
*
* If this function fails errno is set.
*
* Returns: A file descriptor for the given file that can be sent to a client
* or -1 on failure. Use meta_anonymous_file_close_fd() to release the fd
* when done.
*/
int
meta_anonymous_file_open_fd (MetaAnonymousFile *file,
MetaAnonymousFileMapmode mapmode)
{
void *src, *dst;
int fd;
#if defined(HAVE_MEMFD_CREATE)
int seals;
seals = fcntl (file->fd, F_GET_SEALS);
/* file was sealed for read-only and we don't have to support MAP_SHARED
* so we can simply pass the memfd fd
*/
if (seals != -1 && mapmode == META_ANONYMOUS_FILE_MAPMODE_PRIVATE &&
(seals & READONLY_SEALS) == READONLY_SEALS)
return file->fd;
#endif
/* for all other cases we create a new anonymous file that can be mapped
* with MAP_SHARED and copy the contents to it and return that instead
*/
fd = create_anonymous_file (file->size);
if (fd == -1)
return fd;
src = mmap (NULL, file->size, PROT_READ, MAP_PRIVATE, file->fd, 0);
if (src == MAP_FAILED)
{
close (fd);
return -1;
}
dst = mmap (NULL, file->size, PROT_WRITE, MAP_SHARED, fd, 0);
if (dst == MAP_FAILED)
{
close (fd);
munmap (src, file->size);
return -1;
}
memcpy (dst, src, file->size);
munmap (src, file->size);
munmap (dst, file->size);
return fd;
}
/**
* meta_anonymous_file_close_fd: (skip)
* @fd: A file descriptor obtained using meta_anonymous_file_open_fd()
*
* Release a file descriptor returned by meta_anonymous_file_open_fd().
* This function must be called for every file descriptor created with
* meta_anonymous_file_open_fd() to not leak any resources.
*
* If this function fails errno is set.
*/
void
meta_anonymous_file_close_fd (int fd)
{
#if defined(HAVE_MEMFD_CREATE)
int seals;
seals = fcntl (fd, F_GET_SEALS);
if (seals == -1 && errno != EINVAL)
{
g_warning ("Reading seals of anonymous file %d failed", fd);
return;
}
/* The only case in which we do NOT have to close the file is when the file
* was sealed for read-only
*/
if (seals != -1 && (seals & READONLY_SEALS) == READONLY_SEALS)
return;
#endif
close (fd);
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2020 Sebastian Wick
*
* 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.
*
* Author: Sebastian Wick <sebastian@sebastianwick.net>
*/
#ifndef META_ANONYMOUS_FILE_H
#define META_ANONYMOUS_FILE_H
#include "meta/common.h"
#include "core/util-private.h"
typedef struct _MetaAnonymousFile MetaAnonymousFile;
typedef enum _MetaAnonymousFileMapmode
{
META_ANONYMOUS_FILE_MAPMODE_PRIVATE,
META_ANONYMOUS_FILE_MAPMODE_SHARED,
} MetaAnonymousFileMapmode;
META_EXPORT_TEST
MetaAnonymousFile * meta_anonymous_file_new (size_t size,
const uint8_t *data);
META_EXPORT_TEST
void meta_anonymous_file_free (MetaAnonymousFile *file);
META_EXPORT_TEST
size_t meta_anonymous_file_size (MetaAnonymousFile *file);
META_EXPORT_TEST
int meta_anonymous_file_open_fd (MetaAnonymousFile *file,
MetaAnonymousFileMapmode mapmode);
META_EXPORT_TEST
void meta_anonymous_file_close_fd (int fd);
#endif /* META_ANONYMOUS_FILE_H */

View File

@@ -51,9 +51,6 @@ static guint signals[N_SIGNALS] = { 0 };
G_DEFINE_TYPE (MetaSelection, meta_selection, G_TYPE_OBJECT)
static void read_selection_source_async (GTask *task,
TransferRequest *request);
static void
meta_selection_dispose (GObject *object)
{
@@ -220,7 +217,6 @@ write_cb (GOutputStream *stream,
GAsyncResult *result,
GTask *task)
{
TransferRequest *request;
GError *error = NULL;
g_output_stream_write_bytes_finish (stream, result, &error);
@@ -231,17 +227,8 @@ write_cb (GOutputStream *stream,
return;
}
request = g_task_get_task_data (task);
if (request->len > 0)
{
read_selection_source_async (task, request);
}
else
{
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
static void
@@ -260,26 +247,8 @@ read_cb (GInputStream *stream,
g_object_unref (task);
return;
}
else if (g_bytes_get_size (bytes) == 0)
{
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
request = g_task_get_task_data (task);
if (request->len < g_bytes_get_size (bytes))
{
GBytes *copy;
/* Trim content */
copy = g_bytes_new_from_bytes (bytes, 0, request->len);
g_bytes_unref (bytes);
bytes = copy;
}
request->len -= g_bytes_get_size (bytes);
g_output_stream_write_bytes_async (request->ostream,
bytes,
G_PRIORITY_DEFAULT,
@@ -289,18 +258,6 @@ read_cb (GInputStream *stream,
g_bytes_unref (bytes);
}
static void
read_selection_source_async (GTask *task,
TransferRequest *request)
{
g_input_stream_read_bytes_async (request->istream,
(gsize) request->len,
G_PRIORITY_DEFAULT,
g_task_get_cancellable (task),
(GAsyncReadyCallback) read_cb,
task);
}
static void
source_read_cb (MetaSelectionSource *source,
GAsyncResult *result,
@@ -334,7 +291,12 @@ source_read_cb (MetaSelectionSource *source,
}
else
{
read_selection_source_async (task, request);
g_input_stream_read_bytes_async (request->istream,
(gsize) request->len,
G_PRIORITY_DEFAULT,
g_task_get_cancellable (task),
(GAsyncReadyCallback) read_cb,
task);
}
}

View File

@@ -50,6 +50,9 @@ meta_topic_real_valist (MetaDebugTopic topic,
va_list args) G_GNUC_PRINTF(2, 0);
#endif
static gboolean
meta_later_remove_from_list (guint later_id, GSList **laters_list);
static gint verbose_topics = 0;
static gboolean is_debugging = FALSE;
static gboolean replace_current = FALSE;
@@ -712,6 +715,288 @@ meta_show_dialog (const char *type,
return child_pid;
}
/***************************************************************************
* Later functions: like idles but integrated with the Clutter repaint loop
***************************************************************************/
static guint last_later_id = 0;
typedef struct
{
guint id;
guint ref_count;
MetaLaterType when;
GSourceFunc func;
gpointer data;
GDestroyNotify notify;
int source;
gboolean run_once;
} MetaLater;
static GSList *laters[] = {
NULL, /* META_LATER_RESIZE */
NULL, /* META_LATER_CALC_SHOWING */
NULL, /* META_LATER_CHECK_FULLSCREEN */
NULL, /* META_LATER_SYNC_STACK */
NULL, /* META_LATER_BEFORE_REDRAW */
NULL, /* META_LATER_IDLE */
};
/* This is a dummy timeline used to get the Clutter master clock running */
static ClutterTimeline *later_timeline;
static guint later_repaint_func = 0;
static void ensure_later_repaint_func (void);
static void
unref_later (MetaLater *later)
{
if (--later->ref_count == 0)
{
if (later->notify)
{
later->notify (later->data);
later->notify = NULL;
}
g_slice_free (MetaLater, later);
}
}
static void
destroy_later (MetaLater *later)
{
g_clear_handle_id (&later->source, g_source_remove);
later->func = NULL;
unref_later (later);
}
#ifdef COGL_HAS_TRACING
static const char *
later_type_to_string (MetaLaterType when)
{
switch (when)
{
case META_LATER_RESIZE:
return "Later (resize)";
case META_LATER_CALC_SHOWING:
return "Later (calc-showing)";
case META_LATER_CHECK_FULLSCREEN:
return "Later (check-fullscreen)";
case META_LATER_SYNC_STACK:
return "Later (sync-stack)";
case META_LATER_BEFORE_REDRAW:
return "Later (before-redraw)";
case META_LATER_IDLE:
return "Later (idle)";
}
return "unknown";
}
#endif
static gboolean
call_later_func (MetaLater *later)
{
COGL_TRACE_BEGIN_SCOPED (later, later_type_to_string (later->when));
return later->func (later->data);
}
static void
run_repaint_laters (GSList **laters_list)
{
GSList *laters_copy;
GSList *l;
laters_copy = NULL;
for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
if (later->source == 0 ||
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
{
later->ref_count++;
laters_copy = g_slist_prepend (laters_copy, later);
}
}
laters_copy = g_slist_reverse (laters_copy);
for (l = laters_copy; l; l = l->next)
{
MetaLater *later = l->data;
if (!later->func || !call_later_func (later))
meta_later_remove_from_list (later->id, laters_list);
unref_later (later);
}
g_slist_free (laters_copy);
}
static gboolean
run_all_repaint_laters (gpointer data)
{
guint i;
GSList *l;
gboolean keep_timeline_running = FALSE;
for (i = 0; i < G_N_ELEMENTS (laters); i++)
{
run_repaint_laters (&laters[i]);
}
for (i = 0; i < G_N_ELEMENTS (laters); i++)
{
for (l = laters[i]; l; l = l->next)
{
MetaLater *later = l->data;
if (later->source == 0)
keep_timeline_running = TRUE;
}
}
if (!keep_timeline_running)
clutter_timeline_stop (later_timeline);
/* Just keep the repaint func around - it's cheap if the lists are empty */
return TRUE;
}
static void
ensure_later_repaint_func (void)
{
if (!later_timeline)
later_timeline = clutter_timeline_new (G_MAXUINT);
if (later_repaint_func == 0)
later_repaint_func = clutter_threads_add_repaint_func (run_all_repaint_laters,
NULL, NULL);
/* Make sure the repaint function gets run */
clutter_timeline_start (later_timeline);
}
static gboolean
call_idle_later (gpointer data)
{
MetaLater *later = data;
if (!later->func (later->data))
{
meta_later_remove (later->id);
return FALSE;
}
else
{
later->run_once = TRUE;
return TRUE;
}
}
/**
* meta_later_add:
* @when: enumeration value determining the phase at which to run the callback
* @func: callback to run later
* @data: data to pass to the callback
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
*
* Sets up a callback to be called at some later time. @when determines the
* particular later occasion at which it is called. This is much like g_idle_add(),
* except that the functions interact properly with clutter event handling.
* If a "later" function is added from a clutter event handler, and is supposed
* to be run before the stage is redrawn, it will be run before that redraw
* of the stage, not the next one.
*
* Return value: an integer ID (guaranteed to be non-zero) that can be used
* to cancel the callback and prevent it from being run.
*/
guint
meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
MetaLater *later = g_slice_new0 (MetaLater);
later->id = ++last_later_id;
later->ref_count = 1;
later->when = when;
later->func = func;
later->data = data;
later->notify = notify;
laters[when] = g_slist_prepend (laters[when], later);
switch (when)
{
case META_LATER_RESIZE:
/* We add this one two ways - as a high-priority idle and as a
* repaint func. If we are in a clutter event callback, the repaint
* handler will get hit first, and we'll take care of this function
* there so it gets called before the stage is redrawn, even if
* we haven't gotten back to the main loop. Otherwise, the idle
* handler will get hit first and we want to call this function
* there so it will happen before GTK+ repaints.
*/
later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL);
g_source_set_name_by_id (later->source, "[mutter] call_idle_later");
ensure_later_repaint_func ();
break;
case META_LATER_CALC_SHOWING:
case META_LATER_CHECK_FULLSCREEN:
case META_LATER_SYNC_STACK:
case META_LATER_BEFORE_REDRAW:
ensure_later_repaint_func ();
break;
case META_LATER_IDLE:
later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL);
g_source_set_name_by_id (later->source, "[mutter] call_idle_later");
break;
}
return later->id;
}
static gboolean
meta_later_remove_from_list (guint later_id, GSList **laters_list)
{
GSList *l;
for (l = *laters_list; l; l = l->next)
{
MetaLater *later = l->data;
if (later->id == later_id)
{
*laters_list = g_slist_delete_link (*laters_list, l);
/* If this was a "repaint func" later, we just let the
* repaint func run and get removed
*/
destroy_later (later);
return TRUE;
}
}
return FALSE;
}
/**
* meta_later_remove:
* @later_id: the integer ID returned from meta_later_add()
*
* Removes a callback added with meta_later_add()
*/
void
meta_later_remove (guint later_id)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (laters); i++)
{
if (meta_later_remove_from_list (later_id, &laters[i]))
return;
}
}
MetaLocaleDirection
meta_get_locale_direction (void)
{

View File

@@ -65,6 +65,13 @@ typedef enum
#define NUMBER_OF_QUEUES 3
typedef enum
{
_NET_WM_BYPASS_COMPOSITOR_HINT_AUTO = 0,
_NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1,
_NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2,
} MetaBypassCompositorHintValue;
typedef enum
{
META_MOVE_RESIZE_CONFIGURE_REQUEST = 1 << 0,
@@ -532,6 +539,9 @@ struct _MetaWindow
/* The currently complementary tiled window, if any */
MetaWindow *tile_match;
/* Bypass compositor hints */
guint bypass_compositor;
struct {
MetaPlacementRule *rule;
MetaPlacementState state;

View File

@@ -3018,6 +3018,30 @@ meta_window_is_on_primary_monitor (MetaWindow *window)
return window->monitor->is_primary;
}
/**
* meta_window_requested_bypass_compositor:
* @window: a #MetaWindow
*
* Return value: %TRUE if the window requested to bypass the compositor
*/
gboolean
meta_window_requested_bypass_compositor (MetaWindow *window)
{
return window->bypass_compositor == _NET_WM_BYPASS_COMPOSITOR_HINT_ON;
}
/**
* meta_window_requested_dont_bypass_compositor:
* @window: a #MetaWindow
*
* Return value: %TRUE if the window requested to opt out of unredirecting
*/
gboolean
meta_window_requested_dont_bypass_compositor (MetaWindow *window)
{
return window->bypass_compositor == _NET_WM_BYPASS_COMPOSITOR_HINT_OFF;
}
static void
meta_window_get_tile_fraction (MetaWindow *window,
MetaTileMode tile_mode,

View File

@@ -291,8 +291,6 @@ mutter_sources = [
'compositor/meta-background-group.c',
'compositor/meta-background-image.c',
'compositor/meta-background-private.h',
'compositor/meta-compositor-server.c',
'compositor/meta-compositor-server.h',
'compositor/meta-compositor-x11.c',
'compositor/meta-compositor-x11.h',
'compositor/meta-cullable.c',
@@ -302,7 +300,6 @@ mutter_sources = [
'compositor/meta-dnd.c',
'compositor/meta-feedback-actor.c',
'compositor/meta-feedback-actor-private.h',
'compositor/meta-later.c',
'compositor/meta-module.c',
'compositor/meta-module.h',
'compositor/meta-plugin.c',
@@ -349,8 +346,6 @@ mutter_sources = [
'core/main-private.h',
'core/meta-accel-parse.c',
'core/meta-accel-parse.h',
'core/meta-anonymous-file.c',
'core/meta-anonymous-file.h',
'core/meta-border.c',
'core/meta-border.h',
'core/meta-clipboard-manager.c',
@@ -458,10 +453,6 @@ if have_remote_desktop
'backends/meta-remote-desktop-session.h',
'backends/meta-screen-cast.c',
'backends/meta-screen-cast.h',
'backends/meta-screen-cast-area-stream.c',
'backends/meta-screen-cast-area-stream.h',
'backends/meta-screen-cast-area-stream-src.c',
'backends/meta-screen-cast-area-stream-src.h',
'backends/meta-screen-cast-monitor-stream.c',
'backends/meta-screen-cast-monitor-stream.h',
'backends/meta-screen-cast-monitor-stream-src.c',
@@ -485,6 +476,8 @@ if have_wayland
'compositor/meta-surface-actor-wayland.h',
'compositor/meta-window-actor-wayland.c',
'compositor/meta-window-actor-wayland.h',
'compositor/meta-compositor-server.c',
'compositor/meta-compositor-server.h',
'wayland/meta-cursor-sprite-wayland.c',
'wayland/meta-cursor-sprite-wayland.h',
'wayland/meta-pointer-confinement-wayland.c',
@@ -502,16 +495,7 @@ if have_wayland
'wayland/meta-wayland-cursor-surface.h',
'wayland/meta-wayland-data-device.c',
'wayland/meta-wayland-data-device.h',
'wayland/meta-wayland-data-device-primary.c',
'wayland/meta-wayland-data-device-primary.h',
'wayland/meta-wayland-data-offer.c',
'wayland/meta-wayland-data-offer.h',
'wayland/meta-wayland-data-offer-primary.c',
'wayland/meta-wayland-data-offer-primary.h',
'wayland/meta-wayland-data-source.c',
'wayland/meta-wayland-data-source.h',
'wayland/meta-wayland-data-source-primary.c',
'wayland/meta-wayland-data-source-primary.h',
'wayland/meta-wayland-data-device-private.h',
'wayland/meta-wayland-dma-buf.c',
'wayland/meta-wayland-dma-buf.h',
'wayland/meta-wayland-dnd-surface.c',
@@ -691,8 +675,6 @@ if have_native_backend
'backends/native/meta-virtual-input-device-native.h',
'backends/native/meta-xkb-utils.c',
'backends/native/meta-xkb-utils.h',
'compositor/meta-compositor-native.c',
'compositor/meta-compositor-native.h',
]
endif

View File

@@ -19,7 +19,6 @@ mutter_public_headers = [
'meta-idle-monitor.h',
'meta-inhibit-shortcuts-dialog.h',
'meta-launch-context.h',
'meta-later.h',
'meta-monitor-manager.h',
'meta-plugin.h',
'meta-remote-access-controller.h',

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
* Copyright (C) 2020 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_LATER_H
#define META_LATER_H
/**
* MetaLaterType:
* @META_LATER_RESIZE: call in a resize processing phase that is done
* before GTK+ repainting (including window borders) is done.
* @META_LATER_CALC_SHOWING: used by Mutter to compute which windows should be mapped
* @META_LATER_CHECK_FULLSCREEN: used by Mutter to see if there's a fullscreen window
* @META_LATER_SYNC_STACK: used by Mutter to send it's idea of the stacking order to the server
* @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
* @META_LATER_IDLE: call at a very low priority (can be blocked
* by running animations or redrawing applications)
**/
typedef enum
{
META_LATER_RESIZE,
META_LATER_CALC_SHOWING,
META_LATER_CHECK_FULLSCREEN,
META_LATER_SYNC_STACK,
META_LATER_BEFORE_REDRAW,
META_LATER_IDLE
} MetaLaterType;
META_EXPORT
guint meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify);
META_EXPORT
void meta_later_remove (guint later_id);
#endif /* META_LATER_H */

View File

@@ -54,10 +54,4 @@ G_DECLARE_FINAL_TYPE (MetaRemoteAccessController,
META, REMOTE_ACCESS_CONTROLLER,
GObject)
META_EXPORT
void meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller);
META_EXPORT
void meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller);
#endif /* META_REMOTE_ACCESS_CONTROLLER_H */

View File

@@ -27,7 +27,6 @@
#include <glib-object.h>
#include <meta/common.h>
#include <meta/meta-later.h>
META_EXPORT
gboolean meta_is_verbose (void);
@@ -186,6 +185,36 @@ GPid meta_show_dialog (const char *type,
#endif /* !WITH_VERBOSE_MODE */
/**
* MetaLaterType:
* @META_LATER_RESIZE: call in a resize processing phase that is done
* before GTK+ repainting (including window borders) is done.
* @META_LATER_CALC_SHOWING: used by Mutter to compute which windows should be mapped
* @META_LATER_CHECK_FULLSCREEN: used by Mutter to see if there's a fullscreen window
* @META_LATER_SYNC_STACK: used by Mutter to send it's idea of the stacking order to the server
* @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
* @META_LATER_IDLE: call at a very low priority (can be blocked
* by running animations or redrawing applications)
**/
typedef enum
{
META_LATER_RESIZE,
META_LATER_CALC_SHOWING,
META_LATER_CHECK_FULLSCREEN,
META_LATER_SYNC_STACK,
META_LATER_BEFORE_REDRAW,
META_LATER_IDLE
} MetaLaterType;
META_EXPORT
guint meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify);
META_EXPORT
void meta_later_remove (guint later_id);
typedef enum
{
META_LOCALE_DIRECTION_LTR,

View File

@@ -283,6 +283,12 @@ gboolean meta_window_is_monitor_sized (MetaWindow *window);
META_EXPORT
gboolean meta_window_is_on_primary_monitor (MetaWindow *window);
META_EXPORT
gboolean meta_window_requested_bypass_compositor (MetaWindow *window);
META_EXPORT
gboolean meta_window_requested_dont_bypass_compositor (MetaWindow *window);
META_EXPORT
gboolean meta_window_get_icon_geometry (MetaWindow *window,
MetaRectangle *rect);

View File

@@ -111,39 +111,6 @@
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
<!--
RecordArea:
@x: X position of the recorded area
@y: Y position of the recorded area
@width: width of the recorded area
@height: height of the recorded area
@properties: Properties
@stream_path: Path to the new stream object
Record an area of the stage. The coordinates are in stage coordinates.
The size of the stream does not necessarily match the size of the
recorded area, and will depend on DPI scale of the affected monitors.
Available @properties include:
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
Available since API version 2.
Available cursor mode values:
0: hidden - cursor is not included in the stream
1: embedded - cursor is included in the framebuffer
2: metadata - cursor is included as metadata in the PipeWire stream
-->
<method name="RecordArea">
<arg name="x" type="i" direction="in" />
<arg name="y" type="i" direction="in" />
<arg name="width" type="i" direction="in" />
<arg name="height" type="i" direction="in" />
<arg name="properties" type="a{sv}" direction="in" />
<arg name="stream_path" type="o" direction="out" />
</method>
</interface>
<!--

View File

@@ -1,23 +0,0 @@
<monitors version="2">
<configuration>
<logicalmonitor>
<x>0</x>
<y>0</y>
<primary>yes</primary>
<scale>2</scale>
<monitor>
<monitorspec>
<connector>eDP-1</connector>
<vendor>MetaProduct's Inc.</vendor>
<product>MetaMonitor</product>
<serial>0x123456</serial>
</monitorspec>
<mode>
<width>1920</width>
<height>1080</height>
<rate>60.000495910644531</rate>
</mode>
</monitor>
</logicalmonitor>
</configuration>
</monitors>

View File

@@ -2868,116 +2868,6 @@ meta_test_monitor_lid_closed_with_hotplugged_external (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_lid_scaled_closed_opened (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 1920,
.height = 1080,
.refresh_rate = 60.000495910644531
}
},
.n_modes = 1,
.outputs = {
{
.crtc = 0,
.modes = { 0 },
.n_modes = 1,
.preferred_mode = 0,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.is_laptop_panel = TRUE
},
},
.n_outputs = 1,
.crtcs = {
{
.current_mode = 0
},
},
.n_crtcs = 1
},
.expect = {
.monitors = {
{
.outputs = { 0 },
.n_outputs = 1,
.modes = {
{
.width = 1920,
.height = 1080,
.refresh_rate = 60.000495910644531,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 0
}
}
}
},
.n_modes = 1,
.current_mode = 0,
.width_mm = 222,
.height_mm = 125,
}
},
.n_monitors = 1,
.logical_monitors = {
{
.monitors = { 0 },
.n_monitors = 1,
.layout = { .x = 0, .y = 0, .width = 960, .height = 540 },
.scale = 2
}
},
.n_logical_monitors = 1,
.primary_logical_monitor = 0,
.n_outputs = 1,
.crtcs = {
{
.current_mode = 0,
}
},
.n_crtcs = 1,
.n_tiled_monitors = 0,
.screen_width = 960,
.screen_height = 540
}
};
MetaMonitorTestSetup *test_setup;
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
if (!meta_is_stage_views_enabled ())
{
g_test_skip ("Not using stage views");
return;
}
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NONE);
set_custom_monitor_config ("lid-scale.xml");
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE);
meta_monitor_manager_lid_is_closed_changed (monitor_manager);
check_monitor_configuration (&test_case);
meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE);
meta_monitor_manager_lid_is_closed_changed (monitor_manager);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_no_outputs (void)
{
@@ -4938,13 +4828,12 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
.y = 0,
.y = 400,
},
{
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
.y = 400,
}
},
.n_crtcs = 3,
@@ -4970,198 +4859,6 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_custom_second_rotated_nonnative_tiled_config (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 1024,
.height = 768,
.refresh_rate = 60.000495910644531
},
{
.width = 400,
.height = 600,
.refresh_rate = 60.000495910644531
}
},
.n_modes = 2,
.outputs = {
{
.crtc = 0,
.modes = { 0 },
.n_modes = 1,
.preferred_mode = 0,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
},
{
.crtc = -1,
.modes = { 1 },
.n_modes = 1,
.preferred_mode = 1,
.possible_crtcs = { 1, 2 },
.n_possible_crtcs = 2,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 0,
.loc_v_tile = 0,
.tile_w = 400,
.tile_h = 600
}
},
{
.crtc = -1,
.modes = { 1 },
.n_modes = 1,
.preferred_mode = 1,
.possible_crtcs = { 1, 2 },
.n_possible_crtcs = 2,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 1,
.loc_v_tile = 0,
.tile_w = 400,
.tile_h = 600
}
}
},
.n_outputs = 3,
.crtcs = {
{
.current_mode = -1
},
{
.current_mode = -1
},
{
.current_mode = -1
}
},
.n_crtcs = 3
},
.expect = {
.monitors = {
{
.outputs = { 0 },
.n_outputs = 1,
.modes = {
{
.width = 1024,
.height = 768,
.refresh_rate = 60.000495910644531,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 0
}
}
}
},
.n_modes = 1,
.current_mode = 0,
.width_mm = 222,
.height_mm = 125,
},
{
.outputs = { 1, 2 },
.n_outputs = 2,
.modes = {
{
.width = 800,
.height = 600,
.refresh_rate = 60.000495910644531,
.crtc_modes = {
{
.output = 1,
.crtc_mode = 1,
},
{
.output = 2,
.crtc_mode = 1,
}
}
}
},
.n_modes = 1,
.current_mode = 0,
.width_mm = 222,
.height_mm = 125,
}
},
.n_monitors = 2,
.logical_monitors = {
{
.monitors = { 0 },
.n_monitors = 1,
.layout = { .x = 0, .y = 256, .width = 1024, .height = 768 },
.scale = 1
},
{
.monitors = { 1 },
.n_monitors = 1,
.layout = { .x = 1024, .y = 0, .width = 600, .height = 800 },
.scale = 1,
.transform = META_MONITOR_TRANSFORM_90
}
},
.n_logical_monitors = 2,
.primary_logical_monitor = 0,
.n_outputs = 3,
.crtcs = {
{
.current_mode = 0,
.y = 256,
},
{
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_NORMAL,
.x = 1024,
.y = 0,
},
{
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_NORMAL,
.x = 1024,
.y = 400,
}
},
.n_crtcs = 3,
.n_tiled_monitors = 1,
.screen_width = 1024 + 600,
.screen_height = 1024
}
};
MetaMonitorTestSetup *test_setup;
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerTest *monitor_manager_test =
META_MONITOR_MANAGER_TEST (monitor_manager);
meta_monitor_manager_test_set_handles_transforms (monitor_manager_test,
FALSE);
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NONE);
set_custom_monitor_config ("second-rotated-tiled.xml");
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_custom_second_rotated_nonnative_config (void)
{
@@ -6361,8 +6058,6 @@ init_monitor_tests (void)
meta_test_monitor_lid_closed_no_external);
add_monitor_test ("/backends/monitor/lid-closed-with-hotplugged-external",
meta_test_monitor_lid_closed_with_hotplugged_external);
add_monitor_test ("/backends/monitor/lid-scaled-closed-opened",
meta_test_monitor_lid_scaled_closed_opened);
add_monitor_test ("/backends/monitor/no-outputs",
meta_test_monitor_no_outputs);
add_monitor_test ("/backends/monitor/underscanning-config",
@@ -6398,8 +6093,6 @@ init_monitor_tests (void)
meta_test_monitor_custom_second_rotated_config);
add_monitor_test ("/backends/monitor/custom/second-rotated-tiled-config",
meta_test_monitor_custom_second_rotated_tiled_config);
add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-tiled-config",
meta_test_monitor_custom_second_rotated_nonnative_tiled_config);
add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-config",
meta_test_monitor_custom_second_rotated_nonnative_config);
add_monitor_test ("/backends/monitor/custom/interlaced-config",

View File

@@ -59,19 +59,3 @@ executable('subsurface-remap-toplevel',
install: have_installed_tests,
install_dir: wayland_test_client_installed_tests_libexecdir,
)
executable('meta-anonymous-file',
sources: [
'meta-anonymous-file.c',
common_sources,
],
include_directories: tests_includepath,
c_args: tests_c_args,
dependencies: [
glib_dep,
wayland_client_dep,
libmutter_dep,
],
install: have_installed_tests,
install_dir: wayland_test_client_installed_tests_libexecdir,
)

View File

@@ -1,278 +0,0 @@
/*
* Copyright (C) 2020 Jonas Dreßler.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib.h>
#include <sys/resource.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <core/meta-anonymous-file.h>
#include "wayland-test-client-utils.h"
#define READONLY_SEALS (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
static const char *teststring = "test string 1234567890";
static int
test_read_fd_mmap (int fd,
const char *expected_string)
{
void *mem;
int string_size;
string_size = strlen (expected_string) + 1;
mem = mmap (NULL, string_size, PROT_READ, MAP_PRIVATE, fd, 0);
g_assert (mem != MAP_FAILED);
if (strcmp (expected_string, mem) != 0)
{
munmap (mem, string_size);
return FALSE;
}
munmap (mem, string_size);
return TRUE;
}
static int
test_write_fd (int fd,
const char *string)
{
int written_size, string_size;
string_size = strlen (string) + 1;
written_size = write (fd, string, string_size);
if (written_size != string_size)
return FALSE;
return TRUE;
}
static int
test_readonly_seals (int fd)
{
unsigned int seals;
seals = fcntl (fd, F_GET_SEALS);
if (seals == -1)
return FALSE;
if (seals != READONLY_SEALS)
return FALSE;
return TRUE;
}
static int
test_write_read (int fd)
{
g_autofree char *new_string = g_uuid_string_random ();
if (!test_write_fd (fd, new_string))
return FALSE;
if (!test_read_fd_mmap (fd, new_string))
return FALSE;
return TRUE;
}
#if defined(HAVE_MEMFD_CREATE)
static int
test_open_write_read (const char *path)
{
int fd;
fd = open (path, O_RDWR);
g_assert (fd != -1);
if (!test_write_read (fd))
{
close (fd);
return FALSE;
}
close (fd);
return TRUE;
}
#endif
int
main (int argc,
char **argv)
{
MetaAnonymousFile *file;
int fd = -1, other_fd = -1;
g_autofree char *fd_path = NULL;
file = meta_anonymous_file_new (strlen (teststring) + 1,
(const uint8_t *) teststring);
if (!file)
{
g_critical ("%s: Creating file failed", __func__);
return EXIT_FAILURE;
}
#if defined(HAVE_MEMFD_CREATE)
fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
g_assert (fd != -1);
other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
g_assert (other_fd != -1);
/* When MAPMODE_PRIVATE was used, meta_anonymous_file_open_fd() should always
* return the same fd. */
if (other_fd != fd)
goto fail;
/* If memfd_create was used and we request a MAPMODE_PRIVATE file, all the
* readonly seals should be set. */
if (!test_readonly_seals (fd))
goto fail;
if (!test_read_fd_mmap (fd, teststring))
goto fail;
/* Writing and reading the written data should fail */
if (test_write_read (fd))
goto fail;
/* Instead we should still be reading the teststring */
if (!test_read_fd_mmap (fd, teststring))
goto fail;
/* Opening the fd manually in RW mode and writing to it should fail */
fd_path = g_strdup_printf ("/proc/%d/fd/%d", getpid (), fd);
if (test_open_write_read (fd_path))
goto fail;
/* Instead we should still be reading the teststring */
if (!test_read_fd_mmap (fd, teststring))
goto fail;
/* Just to be sure test the other fd, too */
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
meta_anonymous_file_close_fd (fd);
meta_anonymous_file_close_fd (fd);
fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
g_assert (fd != -1);
other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
g_assert (other_fd != -1);
/* The MAPMODE_SHARED fd should not have readonly seals applied */
if (test_readonly_seals (fd))
goto fail;
if (!test_read_fd_mmap (fd, teststring))
goto fail;
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
/* Writing and reading the written data should succeed */
if (!test_write_read (fd))
goto fail;
/* The other fd should still read the teststring though */
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
meta_anonymous_file_close_fd (fd);
meta_anonymous_file_close_fd (other_fd);
/* Test an artificial out-of-space situation by setting the maximium file
* size this process may create to 2 bytes, if memfd_create with
* MAPMODE_PRIVATE is used, everything should still work (the existing FD
* should be used). */
struct rlimit limit = {2, 2};
if (setrlimit (RLIMIT_FSIZE, &limit) == -1)
goto fail;
fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
g_assert (fd != -1);
if (!test_read_fd_mmap (fd, teststring))
goto fail;
meta_anonymous_file_close_fd (fd);
#else
fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
g_assert (fd != -1);
other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_PRIVATE);
g_assert (other_fd != -1);
if (test_readonly_seals (fd))
goto fail;
/* Writing and reading the written data should succeed */
if (!test_write_read (fd))
goto fail;
/* The other fd should still read the teststring though */
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
meta_anonymous_file_close_fd (fd);
meta_anonymous_file_close_fd (other_fd);
fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
g_assert (fd != -1);
other_fd = meta_anonymous_file_open_fd (file, META_ANONYMOUS_FILE_MAPMODE_SHARED);
g_assert (other_fd != -1);
if (test_readonly_seals (fd))
goto fail;
if (!test_read_fd_mmap (fd, teststring))
goto fail;
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
/* Writing and reading the written data should succeed */
if (!test_write_read (fd))
goto fail;
/* The other fd should still read the teststring though */
if (!test_read_fd_mmap (other_fd, teststring))
goto fail;
meta_anonymous_file_close_fd (fd);
meta_anonymous_file_close_fd (other_fd);
#endif
meta_anonymous_file_free (file);
return EXIT_SUCCESS;
fail:
if (fd > 0)
meta_anonymous_file_close_fd (fd);
if (other_fd > 0)
meta_anonymous_file_close_fd (other_fd);
meta_anonymous_file_free (file);
return EXIT_FAILURE;
}

View File

@@ -417,7 +417,7 @@ meta_ui_frame_calc_geometry (MetaUIFrame *frame,
MetaFrameType type;
MetaButtonLayout button_layout;
MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window);
MetaRectangle client_rect;
MetaWindowX11Private *priv = window_x11->priv;
flags = meta_frame_get_flags (frame->meta_window->frame);
type = meta_window_get_frame_type (frame->meta_window);
@@ -426,15 +426,13 @@ meta_ui_frame_calc_geometry (MetaUIFrame *frame,
meta_prefs_get_button_layout (&button_layout);
client_rect = meta_window_x11_get_client_rect (window_x11);
meta_theme_calc_geometry (meta_theme_get_default (),
frame->style_info,
type,
frame->text_height,
flags,
client_rect.width,
client_rect.height,
priv->client_rect.width,
priv->client_rect.height,
&button_layout,
fgeom);
}
@@ -1522,7 +1520,7 @@ meta_ui_frame_paint (MetaUIFrame *frame,
int button_type = -1;
MetaButtonLayout button_layout;
MetaWindowX11 *window_x11 = META_WINDOW_X11 (frame->meta_window);
MetaRectangle client_rect;
MetaWindowX11Private *priv = window_x11->priv;
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
button_states[i] = META_BUTTON_STATE_NORMAL;
@@ -1560,15 +1558,13 @@ meta_ui_frame_paint (MetaUIFrame *frame,
meta_prefs_get_button_layout (&button_layout);
client_rect = meta_window_x11_get_client_rect (window_x11);
meta_theme_draw_frame (meta_theme_get_default (),
frame->style_info,
cr,
type,
flags,
client_rect.width,
client_rect.height,
priv->client_rect.width,
priv->client_rect.height,
frame->text_layout,
frame->text_height,
&button_layout,

View File

@@ -26,6 +26,7 @@
#include "meta/meta-selection-source.h"
#include "wayland/meta-wayland-data-device.h"
#include "wayland/meta-wayland-data-device-private.h"
#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ())

View File

@@ -156,7 +156,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
surface_actor = priv->actor;
stex = meta_surface_actor_get_texture (surface_actor);
buffer = surface->buffer_ref->buffer;
buffer = surface->buffer_ref.buffer;
if (buffer)
{
CoglSnippet *snippet;

View File

@@ -58,11 +58,6 @@
#include "meta/util.h"
#include "wayland/meta-wayland-dma-buf.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-drm-buffer-gbm.h"
#include "backends/native/meta-renderer-native.h"
#endif
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
@@ -582,93 +577,6 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
}
}
static CoglScanout *
try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen)
{
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
MetaGpuKms *gpu_kms;
struct gbm_device *gbm_device;
struct gbm_bo *gbm_bo;
uint32_t drm_format;
uint64_t drm_modifier;
uint32_t stride;
MetaDrmBufferGbm *fb;
g_autoptr (GError) error = NULL;
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
gbm_bo = gbm_bo_import (gbm_device,
GBM_BO_IMPORT_WL_BUFFER, buffer->resource,
GBM_BO_USE_SCANOUT);
if (!gbm_bo)
return NULL;
drm_format = gbm_bo_get_format (gbm_bo);
drm_modifier = gbm_bo_get_modifier (gbm_bo);
stride = gbm_bo_get_stride (gbm_bo);
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
drm_format,
drm_modifier,
stride))
{
gbm_bo_destroy (gbm_bo);
return NULL;
}
fb = meta_drm_buffer_gbm_new_take (gpu_kms, gbm_bo,
drm_modifier != DRM_FORMAT_MOD_INVALID,
&error);
if (!fb)
{
g_debug ("Failed to create scanout buffer: %s", error->message);
gbm_bo_destroy (gbm_bo);
return NULL;
}
return COGL_SCANOUT (fb);
#else
return NULL;
#endif
}
CoglScanout *
meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen)
{
switch (buffer->type)
{
case META_WAYLAND_BUFFER_TYPE_SHM:
return NULL;
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
return try_acquire_egl_image_scanout (buffer, onscreen);
#ifdef HAVE_WAYLAND_EGLSTREAM
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
return NULL;
#endif
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
{
MetaWaylandDmaBufBuffer *dma_buf;
dma_buf = meta_wayland_dma_buf_from_buffer (buffer);
if (!dma_buf)
return NULL;
return meta_wayland_dma_buf_try_acquire_scanout (dma_buf, onscreen);
}
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
g_warn_if_reached ();
return NULL;
}
g_assert_not_reached ();
return NULL;
}
static void
meta_wayland_buffer_finalize (GObject *object)
{

View File

@@ -88,7 +88,5 @@ gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuff
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
CoglTexture *texture,
cairo_region_t *region);
CoglScanout * meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen);
#endif /* META_WAYLAND_BUFFER_H */

View File

@@ -1,326 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/* The file is based on src/data-device.c from Weston */
#include "config.h"
#include "wayland/meta-wayland-data-device-primary.h"
#include "compositor/meta-dnd-actor-private.h"
#include "meta/meta-selection-source-memory.h"
#include "wayland/meta-selection-source-wayland-private.h"
#include "wayland/meta-wayland-data-offer-primary.h"
#include "wayland/meta-wayland-data-source-primary.h"
#include "wayland/meta-wayland-dnd-surface.h"
#include "wayland/meta-wayland-pointer.h"
#include "wayland/meta-wayland-private.h"
#include "wayland/meta-wayland-seat.h"
#include "gtk-primary-selection-server-protocol.h"
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
struct wl_resource *target);
static void
unbind_resource (struct wl_resource *resource)
{
wl_list_remove (wl_resource_get_link (resource));
}
static void
default_destructor (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}
static void
set_selection_source (MetaWaylandDataDevicePrimary *data_device,
MetaSelectionSource *selection_source)
{
MetaDisplay *display = meta_get_display ();
meta_selection_set_owner (meta_display_get_selection (display),
META_SELECTION_PRIMARY,
selection_source);
g_set_object (&data_device->owner, selection_source);
}
static void
unset_selection_source (MetaWaylandDataDevicePrimary *data_device)
{
MetaDisplay *display = meta_get_display ();
if (!data_device->owner)
return;
meta_selection_unset_owner (meta_display_get_selection (display),
META_SELECTION_PRIMARY,
data_device->owner);
g_clear_object (&data_device->owner);
}
static void
primary_source_destroyed (gpointer data,
GObject *object_was_here)
{
MetaWaylandDataDevicePrimary *data_device = data;
data_device->data_source = NULL;
unset_selection_source (data_device);
}
static void
meta_wayland_data_device_primary_set_selection (MetaWaylandDataDevicePrimary *data_device,
MetaWaylandDataSource *source,
uint32_t serial)
{
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
MetaSelectionSource *selection_source;
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source));
if (data_device->data_source &&
data_device->serial - serial < UINT32_MAX / 2)
return;
if (data_device->data_source)
{
g_object_weak_unref (G_OBJECT (data_device->data_source),
primary_source_destroyed,
data_device);
}
data_device->data_source = source;
data_device->serial = serial;
if (source)
{
meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source),
primary_source_destroyed,
data_device);
selection_source = meta_selection_source_wayland_new (source);
}
else
{
selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
}
set_selection_source (data_device, selection_source);
g_object_unref (selection_source);
}
static void
primary_device_set_selection (struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *source_resource,
uint32_t serial)
{
MetaWaylandDataDevicePrimary *data_device = wl_resource_get_user_data (resource);
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
MetaWaylandDataSource *source = NULL;
if (source_resource)
source = wl_resource_get_user_data (source_resource);
if (wl_resource_get_client (resource) !=
meta_wayland_keyboard_get_focus_client (seat->keyboard))
return;
meta_wayland_data_device_primary_set_selection (data_device, source, serial);
}
static const struct gtk_primary_selection_device_interface primary_device_interface = {
primary_device_set_selection,
default_destructor,
};
static void
owner_changed_cb (MetaSelection *selection,
MetaSelectionType selection_type,
MetaSelectionSource *new_owner,
MetaWaylandDataDevicePrimary *data_device)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaWaylandSeat *seat = compositor->seat;
struct wl_resource *data_device_resource;
struct wl_client *focus_client;
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
if (!focus_client)
return;
if (selection_type == META_SELECTION_PRIMARY)
{
data_device_resource =
wl_resource_find_for_client (&data_device->resource_list,
focus_client);
if (data_device_resource)
{
struct wl_resource *offer = NULL;
if (new_owner)
{
offer = create_and_send_primary_offer (data_device,
data_device_resource);
}
gtk_primary_selection_device_send_selection (data_device_resource,
offer);
}
}
}
static void
ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimary *data_device)
{
if (data_device->selection_owner_signal_id != 0)
return;
data_device->selection_owner_signal_id =
g_signal_connect (meta_display_get_selection (meta_get_display ()),
"owner-changed",
G_CALLBACK (owner_changed_cb), data_device);
}
static void
primary_device_manager_create_source (struct wl_client *client,
struct wl_resource *manager_resource,
guint32 id)
{
struct wl_resource *source_resource;
source_resource =
wl_resource_create (client, &gtk_primary_selection_source_interface,
wl_resource_get_version (manager_resource),
id);
meta_wayland_data_source_primary_new (source_resource);
}
static void
primary_device_manager_get_device (struct wl_client *client,
struct wl_resource *manager_resource,
guint32 id,
struct wl_resource *seat_resource)
{
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
struct wl_resource *cr;
cr = wl_resource_create (client, &gtk_primary_selection_device_interface,
wl_resource_get_version (manager_resource), id);
wl_resource_set_implementation (cr, &primary_device_interface,
&seat->primary_data_device, unbind_resource);
wl_list_insert (&seat->primary_data_device.resource_list, wl_resource_get_link (cr));
ensure_owners_changed_handler_connected (&seat->primary_data_device);
}
static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = {
primary_device_manager_create_source,
primary_device_manager_get_device,
default_destructor,
};
static void
bind_primary_manager (struct wl_client *client,
void *data,
uint32_t version,
uint32_t id)
{
struct wl_resource *resource;
resource = wl_resource_create (client, &gtk_primary_selection_device_manager_interface,
version, id);
wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
}
void
meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor)
{
if (wl_global_create (compositor->wayland_display,
&gtk_primary_selection_device_manager_interface,
1, NULL, bind_primary_manager) == NULL)
g_error ("Could not create data_device");
}
void
meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device)
{
wl_list_init (&data_device->resource_list);
}
static struct wl_resource *
create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
struct wl_resource *target)
{
MetaWaylandDataOffer *offer;
MetaDisplay *display = meta_get_display ();
struct wl_resource *resource;
GList *mimetypes, *l;
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
META_SELECTION_PRIMARY);
if (!mimetypes)
return NULL;
offer = meta_wayland_data_offer_primary_new (target);
resource = meta_wayland_data_offer_get_resource (offer);
gtk_primary_selection_device_send_data_offer (target, resource);
for (l = mimetypes; l; l = l->next)
gtk_primary_selection_offer_send_offer (resource, l->data);
g_list_free_full (mimetypes, g_free);
return resource;
}
void
meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device)
{
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
struct wl_client *focus_client;
struct wl_resource *data_device_resource;
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
if (focus_client == data_device->focus_client)
return;
data_device->focus_client = focus_client;
if (!focus_client)
return;
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
if (data_device_resource)
{
struct wl_resource *offer;
offer = create_and_send_primary_offer (data_device, data_device_resource);
gtk_primary_selection_device_send_selection (data_device_resource, offer);
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright © 2008 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_H
#define META_WAYLAND_DATA_DEVICE_PRIMARY_H
#include <glib-object.h>
#include <wayland-server.h>
#include "clutter/clutter.h"
#include "meta/meta-selection-source.h"
#include "wayland/meta-wayland-data-offer.h"
#include "wayland/meta-wayland-data-source.h"
#include "wayland/meta-wayland-types.h"
struct _MetaWaylandDataDevicePrimary
{
uint32_t serial;
MetaWaylandDataSource *data_source;
struct wl_list resource_list;
struct wl_client *focus_client;
guint selection_owner_signal_id;
MetaSelectionSource *owner;
};
void meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor);
void meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device);
void meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device);
#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_H */

View File

@@ -1,5 +1,7 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2019 Red Hat Inc.
* Copyright (C) 2015 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -16,17 +18,17 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#ifndef META_COMPOSITOR_NATIVE_H
#define META_COMPOSITOR_NATIVE_H
#ifndef META_WAYLAND_DATA_DEVICE_PRIVATE_H
#define META_WAYLAND_DATA_DEVICE_PRIVATE_H
#include "compositor/meta-compositor-server.h"
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
meta_wayland_data_source_primary,
META, WAYLAND_DATA_SOURCE_PRIMARY,
MetaWaylandDataSource);
#define META_TYPE_COMPOSITOR_NATIVE (meta_compositor_native_get_type ())
G_DECLARE_FINAL_TYPE (MetaCompositorNative, meta_compositor_native,
META, COMPOSITOR_NATIVE, MetaCompositor)
MetaCompositorNative * meta_compositor_native_new (MetaDisplay *display);
#endif /* META_COMPOSITOR_NATIVE_H */
#endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -28,19 +28,42 @@
#include "clutter/clutter.h"
#include "meta/meta-selection-source.h"
#include "wayland/meta-wayland-data-offer.h"
#include "wayland/meta-wayland-data-source.h"
#include "wayland/meta-wayland-types.h"
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource, meta_wayland_data_source,
META, WAYLAND_DATA_SOURCE, GObject);
struct _MetaWaylandDataSourceClass
{
GObjectClass parent_class;
void (* send) (MetaWaylandDataSource *source,
const gchar *mime_type,
gint fd);
void (* target) (MetaWaylandDataSource *source,
const gchar *mime_type);
void (* cancel) (MetaWaylandDataSource *source);
void (* action) (MetaWaylandDataSource *source,
uint32_t action);
void (* drop_performed) (MetaWaylandDataSource *source);
void (* drag_finished) (MetaWaylandDataSource *source);
};
struct _MetaWaylandDataDevice
{
uint32_t selection_serial;
uint32_t primary_serial;
MetaWaylandDataSource *selection_data_source;
MetaWaylandDataSource *dnd_data_source;
MetaWaylandDataSource *primary_data_source;
struct wl_listener selection_data_source_listener;
struct wl_list resource_list;
struct wl_list primary_resource_list;
MetaWaylandDragGrab *current_grab;
struct wl_client *focus_client;
@@ -66,7 +89,42 @@ void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_de
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
MetaWaylandDataSource *source,
guint32 serial);
void meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device);
void meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
MetaWaylandDataSource *source,
guint32 serial);
gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
const gchar *mime_type);
gboolean meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
const gchar *mime_type);
struct wl_array *
meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source);
gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source);
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
gboolean has_target);
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
void meta_wayland_data_source_send (MetaWaylandDataSource *source,
const gchar *mime_type,
gint fd);
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_actions (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
uint32_t meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
uint32_t dnd_actions);
void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
uint32_t action);
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
uint32_t action);
const MetaWaylandDragDestFuncs *
meta_wayland_data_device_get_drag_dest_funcs (void);

View File

@@ -1,138 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "config.h"
#include "meta-wayland-data-offer-primary.h"
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "core/display-private.h"
#include "gtk-primary-selection-server-protocol.h"
#include "wayland/meta-wayland-data-offer.h"
static void
transfer_cb (MetaSelection *selection,
GAsyncResult *res,
GOutputStream *stream)
{
GError *error = NULL;
if (!meta_selection_transfer_finish (selection, res, &error))
{
g_warning ("Could not fetch selection data: %s", error->message);
g_error_free (error);
}
g_output_stream_close (stream, NULL, NULL);
}
static void
primary_offer_receive (struct wl_client *client,
struct wl_resource *resource,
const char *mime_type,
int32_t fd)
{
MetaDisplay *display = meta_get_display ();
GOutputStream *stream;
GList *mime_types;
gboolean found;
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
META_SELECTION_PRIMARY);
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
g_list_free_full (mime_types, g_free);
if (!found)
{
close (fd);
return;
}
stream = g_unix_output_stream_new (fd, TRUE);
meta_selection_transfer_async (meta_display_get_selection (display),
META_SELECTION_PRIMARY,
mime_type,
-1,
stream,
NULL,
(GAsyncReadyCallback) transfer_cb,
stream);
}
static void
primary_offer_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}
static const struct gtk_primary_selection_offer_interface primary_offer_interface = {
primary_offer_receive,
primary_offer_destroy,
};
static void
destroy_primary_offer (struct wl_resource *resource)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
if (offer->source)
{
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
{
meta_wayland_data_source_cancel (offer->source);
meta_wayland_data_source_set_current_offer (offer->source, NULL);
}
g_object_remove_weak_pointer (G_OBJECT (offer->source),
(gpointer *)&offer->source);
offer->source = NULL;
}
meta_display_sync_wayland_input_focus (meta_get_display ());
g_slice_free (MetaWaylandDataOffer, offer);
}
MetaWaylandDataOffer *
meta_wayland_data_offer_primary_new (struct wl_resource *target)
{
MetaWaylandDataOffer *offer;
offer = g_slice_new0 (MetaWaylandDataOffer);
offer->selection_type = META_SELECTION_PRIMARY;
offer->resource = wl_resource_create (wl_resource_get_client (target),
&gtk_primary_selection_offer_interface,
wl_resource_get_version (target), 0);
wl_resource_set_implementation (offer->resource,
&primary_offer_interface,
offer,
destroy_primary_offer);
return offer;
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_H
#define META_WAYLAND_DATA_OFFER_PRIMARY_H
#include "meta-wayland-data-offer.h"
MetaWaylandDataOffer * meta_wayland_data_offer_primary_new (struct wl_resource *target);
#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_H */

View File

@@ -1,326 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "config.h"
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "meta/meta-selection.h"
#include "wayland/meta-wayland-data-device.h"
#include "wayland/meta-wayland-private.h"
#include "meta-wayland-data-offer.h"
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
static void
data_offer_accept (struct wl_client *client,
struct wl_resource *resource,
guint32 serial,
const char *mime_type)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
/* FIXME: Check that client is currently focused by the input
* device that is currently dragging this data source. Should
* this be a wl_data_device request? */
if (offer->source)
{
meta_wayland_data_source_target (offer->source, mime_type);
meta_wayland_data_source_set_has_target (offer->source,
mime_type != NULL);
}
offer->accepted = mime_type != NULL;
}
static void
transfer_cb (MetaSelection *selection,
GAsyncResult *res,
GOutputStream *stream)
{
GError *error = NULL;
if (!meta_selection_transfer_finish (selection, res, &error))
{
g_warning ("Could not fetch selection data: %s", error->message);
g_error_free (error);
}
g_output_stream_close (stream, NULL, NULL);
}
static void
data_offer_receive (struct wl_client *client, struct wl_resource *resource,
const char *mime_type, int32_t fd)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
MetaDisplay *display = meta_get_display ();
MetaSelectionType selection_type;
GList *mime_types;
gboolean found;
selection_type = offer->selection_type;
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
selection_type);
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
g_list_free_full (mime_types, g_free);
if (found)
{
GOutputStream *stream;
stream = g_unix_output_stream_new (fd, TRUE);
meta_selection_transfer_async (meta_display_get_selection (display),
selection_type,
mime_type,
-1,
stream,
NULL,
(GAsyncReadyCallback) transfer_cb,
stream);
}
else
{
close (fd);
}
}
static void
data_offer_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}
static void
data_offer_finish (struct wl_client *client,
struct wl_resource *resource)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
enum wl_data_device_manager_dnd_action current_action;
if (!offer->source ||
offer != meta_wayland_data_source_get_current_offer (offer->source))
return;
if (!offer->accepted || !offer->action_sent)
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_FINISH,
"premature finish request");
return;
}
current_action = meta_wayland_data_source_get_current_action (offer->source);
if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_OFFER,
"offer finished with an invalid action");
return;
}
meta_wayland_data_source_notify_finish (offer->source);
}
static void
data_offer_set_actions (struct wl_client *client,
struct wl_resource *resource,
uint32_t dnd_actions,
uint32_t preferred_action)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
if (dnd_actions & ~(ALL_ACTIONS))
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
"invalid actions mask %x", dnd_actions);
return;
}
if (preferred_action &&
(!(preferred_action & dnd_actions) ||
__builtin_popcount (preferred_action) > 1))
{
wl_resource_post_error (offer->resource,
WL_DATA_OFFER_ERROR_INVALID_ACTION,
"invalid action %x", preferred_action);
return;
}
offer->dnd_actions = dnd_actions;
offer->preferred_dnd_action = preferred_action;
meta_wayland_data_offer_update_action (offer);
}
static const struct wl_data_offer_interface data_offer_interface = {
data_offer_accept,
data_offer_receive,
data_offer_destroy,
data_offer_finish,
data_offer_set_actions,
};
static void
destroy_data_offer (struct wl_resource *resource)
{
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
MetaWaylandSeat *seat;
if (offer->source)
{
seat = meta_wayland_data_source_get_seat (offer->source);
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
{
if (seat->data_device.dnd_data_source == offer->source)
{
if (wl_resource_get_version (offer->resource) <
WL_DATA_OFFER_ACTION_SINCE_VERSION)
meta_wayland_data_source_notify_finish (offer->source);
else if (meta_wayland_data_source_get_drop_performed (offer->source))
meta_wayland_data_source_cancel (offer->source);
}
else
{
meta_wayland_data_source_set_current_offer (offer->source, NULL);
meta_wayland_data_source_set_has_target (offer->source, FALSE);
}
}
g_object_remove_weak_pointer (G_OBJECT (offer->source),
(gpointer *)&offer->source);
offer->source = NULL;
}
meta_display_sync_wayland_input_focus (meta_get_display ());
g_slice_free (MetaWaylandDataOffer, offer);
}
MetaWaylandDataOffer *
meta_wayland_data_offer_new (MetaSelectionType selection_type,
MetaWaylandDataSource *source,
struct wl_resource *target)
{
MetaWaylandDataOffer *offer;
offer = g_slice_new0 (MetaWaylandDataOffer);
offer->selection_type = selection_type;
offer->resource = wl_resource_create (wl_resource_get_client (target),
&wl_data_offer_interface,
wl_resource_get_version (target), 0);
wl_resource_set_implementation (offer->resource,
&data_offer_interface,
offer,
destroy_data_offer);
if (source)
{
offer->source = source;
g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
}
return offer;
}
static enum wl_data_device_manager_dnd_action
data_offer_choose_action (MetaWaylandDataOffer *offer)
{
MetaWaylandDataSource *source = offer->source;
uint32_t actions, user_action, available_actions;
if (wl_resource_get_version (offer->resource) <
WL_DATA_OFFER_ACTION_SINCE_VERSION)
return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
meta_wayland_data_source_get_actions (source, &actions);
user_action = meta_wayland_data_source_get_user_action (source);
available_actions = actions & offer->dnd_actions;
if (!available_actions)
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
/* If the user is forcing an action, go for it */
if ((user_action & available_actions) != 0)
return user_action;
/* If the dest side has a preferred DnD action, use it */
if ((offer->preferred_dnd_action & available_actions) != 0)
return offer->preferred_dnd_action;
/* Use the first found action, in bit order */
return 1 << (ffs (available_actions) - 1);
}
void
meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer)
{
enum wl_data_device_manager_dnd_action current_action, action;
MetaWaylandDataSource *source;
if (!offer->source)
return;
source = offer->source;
current_action = meta_wayland_data_source_get_current_action (source);
action = data_offer_choose_action (offer);
if (current_action == action)
return;
meta_wayland_data_source_set_current_action (source, action);
if (!meta_wayland_data_source_get_in_ask (source) &&
wl_resource_get_version (offer->resource) >=
WL_DATA_OFFER_ACTION_SINCE_VERSION)
{
wl_data_offer_send_action (offer->resource, action);
offer->action_sent = TRUE;
}
}
struct wl_resource *
meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer)
{
return offer->resource;
}
MetaWaylandDataSource *
meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer)
{
return offer->source;
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef META_WAYLAND_DATA_OFFER_H
#define META_WAYLAND_DATA_OFFER_H
#include "meta/meta-selection.h"
#include "wayland/meta-wayland-data-source.h"
struct _MetaWaylandDataOffer
{
struct wl_resource *resource;
MetaWaylandDataSource *source;
struct wl_listener source_destroy_listener;
gboolean accepted;
gboolean action_sent;
uint32_t dnd_actions;
enum wl_data_device_manager_dnd_action preferred_dnd_action;
MetaSelectionType selection_type;
};
MetaWaylandDataOffer * meta_wayland_data_offer_new (MetaSelectionType selection_type,
MetaWaylandDataSource *source,
struct wl_resource *resource);
void meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer);
struct wl_resource * meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer);
MetaWaylandDataSource * meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer);
#endif /* META_WAYLAND_DATA_OFFER_H */

View File

@@ -1,117 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "config.h"
#include <unistd.h>
#include "gtk-primary-selection-server-protocol.h"
#include "wayland/meta-wayland-data-source-primary.h"
typedef struct _MetaWaylandDataSourcePrimary
{
MetaWaylandDataSource parent;
} MetaWaylandDataSourcePrimary;
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
META_TYPE_WAYLAND_DATA_SOURCE);
static void
primary_source_offer (struct wl_client *client,
struct wl_resource *resource,
const char *type)
{
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
if (!meta_wayland_data_source_add_mime_type (source, type))
wl_resource_post_no_memory (resource);
}
static void
primary_source_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}
static struct gtk_primary_selection_source_interface primary_source_interface = {
primary_source_offer,
primary_source_destroy,
};
static void
destroy_primary_source (struct wl_resource *resource)
{
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
meta_wayland_data_source_set_resource (source, NULL);
g_object_unref (source);
}
static void
meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
const gchar *mime_type,
gint fd)
{
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
gtk_primary_selection_source_send_send (resource, mime_type, fd);
close (fd);
}
static void
meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source)
{
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
if (resource)
gtk_primary_selection_source_send_cancelled (resource);
}
static void
meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary)
{
}
static void
meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass)
{
MetaWaylandDataSourceClass *data_source_class =
META_WAYLAND_DATA_SOURCE_CLASS (klass);
data_source_class->send = meta_wayland_data_source_primary_send;
data_source_class->cancel = meta_wayland_data_source_primary_cancel;
}
MetaWaylandDataSource *
meta_wayland_data_source_primary_new (struct wl_resource *resource)
{
MetaWaylandDataSource *source_primary =
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL);
meta_wayland_data_source_set_resource (source_primary, resource);
wl_resource_set_implementation (resource, &primary_source_interface,
source_primary, destroy_primary_source);
return source_primary;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright © 2011 Kristian Høgsberg
* 2020 Red Hat Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
#define META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
#include "meta-wayland-data-source.h"
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
meta_wayland_data_source_primary,
META, WAYLAND_DATA_SOURCE_PRIMARY,
MetaWaylandDataSource);
MetaWaylandDataSource * meta_wayland_data_source_primary_new (struct wl_resource *resource);
#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H */

Some files were not shown because too many files have changed in this diff Show More