1 /*
2 * Wayland Support
3 *
4 * Copyright (C) 2012,2013 Intel Corporation
5 * Copyright (C) 2013-2017 Red Hat, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include "config.h"
24
25 #include "wayland/meta-wayland-surface.h"
26
27 #include <gobject/gvaluecollector.h>
28 #include <wayland-server.h>
29
30 #include "backends/meta-cursor-tracker-private.h"
31 #include "clutter/clutter.h"
32 #include "cogl/cogl-wayland-server.h"
33 #include "cogl/cogl.h"
34 #include "compositor/meta-surface-actor-wayland.h"
35 #include "compositor/meta-surface-actor.h"
36 #include "compositor/meta-window-actor-private.h"
37 #include "compositor/region-utils.h"
38 #include "core/display-private.h"
39 #include "core/window-private.h"
40 #include "wayland/meta-wayland-actor-surface.h"
41 #include "wayland/meta-wayland-buffer.h"
42 #include "wayland/meta-wayland-data-device.h"
43 #include "wayland/meta-wayland-gtk-shell.h"
44 #include "wayland/meta-wayland-keyboard.h"
45 #include "wayland/meta-wayland-legacy-xdg-shell.h"
46 #include "wayland/meta-wayland-outputs.h"
47 #include "wayland/meta-wayland-pointer.h"
48 #include "wayland/meta-wayland-presentation-time-private.h"
49 #include "wayland/meta-wayland-private.h"
50 #include "wayland/meta-wayland-region.h"
51 #include "wayland/meta-wayland-seat.h"
52 #include "wayland/meta-wayland-subsurface.h"
53 #include "wayland/meta-wayland-viewporter.h"
54 #include "wayland/meta-wayland-wl-shell.h"
55 #include "wayland/meta-wayland-xdg-shell.h"
56 #include "wayland/meta-window-wayland.h"
57 #include "wayland/meta-xwayland-private.h"
58 #include "wayland/meta-xwayland-private.h"
59
60 enum
61 {
62 SURFACE_STATE_SIGNAL_APPLIED,
63
64 SURFACE_STATE_SIGNAL_N_SIGNALS
65 };
66
67 enum
68 {
69 SURFACE_ROLE_PROP_0,
70
71 SURFACE_ROLE_PROP_SURFACE,
72 };
73
74 static guint surface_state_signals[SURFACE_STATE_SIGNAL_N_SIGNALS];
75
76 typedef struct _MetaWaylandSurfaceRolePrivate
77 {
78 MetaWaylandSurface *surface;
79 } MetaWaylandSurfaceRolePrivate;
80
81 G_DEFINE_TYPE (MetaWaylandSurface, meta_wayland_surface, G_TYPE_OBJECT);
82
83 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRole,
84 meta_wayland_surface_role,
85 G_TYPE_OBJECT)
86
87 G_DEFINE_TYPE (MetaWaylandSurfaceState,
88 meta_wayland_surface_state,
89 G_TYPE_OBJECT)
90
91 enum
92 {
93 SURFACE_DESTROY,
94 SURFACE_UNMAPPED,
95 SURFACE_CONFIGURE,
96 SURFACE_SHORTCUTS_INHIBITED,
97 SURFACE_SHORTCUTS_RESTORED,
98 SURFACE_GEOMETRY_CHANGED,
99 SURFACE_PRE_STATE_APPLIED,
100 N_SURFACE_SIGNALS
101 };
102
103 guint surface_signals[N_SURFACE_SIGNALS] = { 0 };
104
105 static void
106 meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role);
107
108 static void
109 meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role,
110 MetaWaylandSurfaceState *pending);
111
112 static void
113 meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
114 MetaWaylandSurfaceState *pending);
115
116 static void
117 meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
118 MetaWaylandSurfaceState *pending);
119
120 static gboolean
121 meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
122 MetaLogicalMonitor *logical_monitor);
123
124 static MetaWaylandSurface *
125 meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role);
126
127 static void
128 set_surface_is_on_output (MetaWaylandSurface *surface,
129 MetaWaylandOutput *wayland_output,
130 gboolean is_on_output);
131
132 static MetaWaylandBufferRef *
meta_wayland_buffer_ref_new(void)133 meta_wayland_buffer_ref_new (void)
134 {
135 MetaWaylandBufferRef *buffer_ref;
136
137 buffer_ref = g_new0 (MetaWaylandBufferRef, 1);
138 g_ref_count_init (&buffer_ref->ref_count);
139
140 return buffer_ref;
141 }
142
143 static MetaWaylandBufferRef *
meta_wayland_buffer_ref_ref(MetaWaylandBufferRef * buffer_ref)144 meta_wayland_buffer_ref_ref (MetaWaylandBufferRef *buffer_ref)
145 {
146 g_ref_count_inc (&buffer_ref->ref_count);
147 return buffer_ref;
148 }
149
150 static void
meta_wayland_buffer_ref_unref(MetaWaylandBufferRef * buffer_ref)151 meta_wayland_buffer_ref_unref (MetaWaylandBufferRef *buffer_ref)
152 {
153 if (g_ref_count_dec (&buffer_ref->ref_count))
154 {
155 g_warn_if_fail (buffer_ref->use_count == 0);
156 g_clear_object (&buffer_ref->buffer);
157 g_free (buffer_ref);
158 }
159 }
160
161 static void
meta_wayland_buffer_ref_inc_use_count(MetaWaylandBufferRef * buffer_ref)162 meta_wayland_buffer_ref_inc_use_count (MetaWaylandBufferRef *buffer_ref)
163 {
164 g_return_if_fail (buffer_ref->buffer);
165 g_warn_if_fail (buffer_ref->buffer->resource);
166
167 buffer_ref->use_count++;
168 }
169
170 static void
meta_wayland_buffer_ref_dec_use_count(MetaWaylandBufferRef * buffer_ref)171 meta_wayland_buffer_ref_dec_use_count (MetaWaylandBufferRef *buffer_ref)
172 {
173 MetaWaylandBuffer *buffer = buffer_ref->buffer;
174
175 g_return_if_fail (buffer_ref->use_count > 0);
176 g_return_if_fail (buffer);
177
178 buffer_ref->use_count--;
179
180 if (buffer_ref->use_count == 0 && buffer->resource)
181 wl_buffer_send_release (buffer->resource);
182 }
183
184 static void
role_assignment_valist_to_properties(GType role_type,const char * first_property_name,va_list var_args,GArray * names,GArray * values)185 role_assignment_valist_to_properties (GType role_type,
186 const char *first_property_name,
187 va_list var_args,
188 GArray *names,
189 GArray *values)
190 {
191 GObjectClass *object_class;
192 const char *property_name = first_property_name;
193
194 object_class = g_type_class_ref (role_type);
195
196 while (property_name)
197 {
198 GValue value = G_VALUE_INIT;
199 GParamSpec *pspec;
200 GType ptype;
201 gchar *error = NULL;
202
203 pspec = g_object_class_find_property (object_class,
204 property_name);
205 g_assert (pspec);
206
207 ptype = G_PARAM_SPEC_VALUE_TYPE (pspec);
208 G_VALUE_COLLECT_INIT (&value, ptype, var_args, 0, &error);
209 g_assert (!error);
210
211 g_array_append_val (names, property_name);
212 g_array_append_val (values, value);
213
214 property_name = va_arg (var_args, const char *);
215 }
216
217 g_type_class_unref (object_class);
218 }
219
220 gboolean
meta_wayland_surface_assign_role(MetaWaylandSurface * surface,GType role_type,const char * first_property_name,...)221 meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
222 GType role_type,
223 const char *first_property_name,
224 ...)
225 {
226 va_list var_args;
227
228 if (!surface->role)
229 {
230 if (first_property_name)
231 {
232 GArray *names;
233 GArray *values;
234 const char *surface_prop_name;
235 GValue surface_value = G_VALUE_INIT;
236 GObject *role_object;
237
238 names = g_array_new (FALSE, FALSE, sizeof (const char *));
239 values = g_array_new (FALSE, FALSE, sizeof (GValue));
240 g_array_set_clear_func (values, (GDestroyNotify) g_value_unset);
241
242 va_start (var_args, first_property_name);
243 role_assignment_valist_to_properties (role_type,
244 first_property_name,
245 var_args,
246 names,
247 values);
248 va_end (var_args);
249
250 surface_prop_name = "surface";
251 g_value_init (&surface_value, META_TYPE_WAYLAND_SURFACE);
252 g_value_set_object (&surface_value, surface);
253 g_array_append_val (names, surface_prop_name);
254 g_array_append_val (values, surface_value);
255
256 role_object =
257 g_object_new_with_properties (role_type,
258 values->len,
259 (const char **) names->data,
260 (const GValue *) values->data);
261 surface->role = META_WAYLAND_SURFACE_ROLE (role_object);
262
263 g_array_free (names, TRUE);
264 g_array_free (values, TRUE);
265 }
266 else
267 {
268 surface->role = g_object_new (role_type, "surface", surface, NULL);
269 }
270
271 meta_wayland_surface_role_assigned (surface->role);
272
273 /* Release the use count held on behalf of the just assigned role. */
274 if (surface->unassigned.buffer)
275 {
276 meta_wayland_surface_unref_buffer_use_count (surface);
277 g_clear_object (&surface->unassigned.buffer);
278 }
279
280 return TRUE;
281 }
282 else if (G_OBJECT_TYPE (surface->role) != role_type)
283 {
284 return FALSE;
285 }
286 else
287 {
288 va_start (var_args, first_property_name);
289 g_object_set_valist (G_OBJECT (surface->role),
290 first_property_name, var_args);
291 va_end (var_args);
292
293 meta_wayland_surface_role_assigned (surface->role);
294
295 return TRUE;
296 }
297 }
298
299 static int
get_buffer_width(MetaWaylandSurface * surface)300 get_buffer_width (MetaWaylandSurface *surface)
301 {
302 MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
303
304 if (buffer)
305 return cogl_texture_get_width (surface->texture);
306 else
307 return 0;
308 }
309
310 static int
get_buffer_height(MetaWaylandSurface * surface)311 get_buffer_height (MetaWaylandSurface *surface)
312 {
313 MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
314
315 if (buffer)
316 return cogl_texture_get_height (surface->texture);
317 else
318 return 0;
319 }
320
321 static void
surface_process_damage(MetaWaylandSurface * surface,cairo_region_t * surface_region,cairo_region_t * buffer_region)322 surface_process_damage (MetaWaylandSurface *surface,
323 cairo_region_t *surface_region,
324 cairo_region_t *buffer_region)
325 {
326 MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
327 cairo_rectangle_int_t surface_rect;
328 cairo_rectangle_int_t buffer_rect;
329 cairo_region_t *scaled_region;
330 cairo_region_t *transformed_region;
331 cairo_region_t *viewport_region;
332 graphene_rect_t src_rect;
333 MetaSurfaceActor *actor;
334
335 /* If the client destroyed the buffer it attached before committing, but
336 * still posted damage, or posted damage without any buffer, don't try to
337 * process it on the non-existing buffer.
338 */
339 if (!buffer)
340 return;
341
342 buffer_rect = (cairo_rectangle_int_t) {
343 .width = get_buffer_width (surface),
344 .height = get_buffer_height (surface),
345 };
346
347 /* Intersect the damage region with the surface region before scaling in
348 * order to avoid integer overflow when scaling a damage region is too large
349 * (for example INT32_MAX which mesa passes). */
350 surface_rect = (cairo_rectangle_int_t) {
351 .width = meta_wayland_surface_get_width (surface),
352 .height = meta_wayland_surface_get_height (surface),
353 };
354 cairo_region_intersect_rectangle (surface_region, &surface_rect);
355
356 /* The damage region must be in the same coordinate space as the buffer,
357 * i.e. scaled with surface->scale. */
358 scaled_region = meta_region_scale (surface_region, surface->scale);
359 if (surface->viewport.has_src_rect)
360 {
361 src_rect = (graphene_rect_t) {
362 .origin.x = surface->viewport.src_rect.origin.x * surface->scale,
363 .origin.y = surface->viewport.src_rect.origin.y * surface->scale,
364 .size.width = surface->viewport.src_rect.size.width * surface->scale,
365 .size.height = surface->viewport.src_rect.size.height * surface->scale
366 };
367 }
368 else
369 {
370 src_rect = (graphene_rect_t) {
371 .size.width = surface_rect.width * surface->scale,
372 .size.height = surface_rect.height * surface->scale,
373 };
374 }
375 viewport_region = meta_region_crop_and_scale (scaled_region,
376 &src_rect,
377 surface_rect.width *
378 surface->scale,
379 surface_rect.height *
380 surface->scale);
381 transformed_region = meta_region_transform (viewport_region,
382 surface->buffer_transform,
383 buffer_rect.width,
384 buffer_rect.height);
385
386 /* Now add the scaled, cropped and transformed damage region to the
387 * buffer damage. Buffer damage is already in the correct coordinate space. */
388 cairo_region_union (buffer_region, transformed_region);
389
390 cairo_region_intersect_rectangle (buffer_region, &buffer_rect);
391
392 meta_wayland_buffer_process_damage (buffer, surface->texture, buffer_region);
393
394 actor = meta_wayland_surface_get_actor (surface);
395 if (actor)
396 {
397 int i, n_rectangles;
398
399 n_rectangles = cairo_region_num_rectangles (buffer_region);
400 for (i = 0; i < n_rectangles; i++)
401 {
402 cairo_rectangle_int_t rect;
403 cairo_region_get_rectangle (buffer_region, i, &rect);
404
405 meta_surface_actor_process_damage (actor,
406 rect.x, rect.y,
407 rect.width, rect.height);
408 }
409 }
410
411 cairo_region_destroy (viewport_region);
412 cairo_region_destroy (scaled_region);
413 cairo_region_destroy (transformed_region);
414 }
415
416 MetaWaylandBuffer *
meta_wayland_surface_get_buffer(MetaWaylandSurface * surface)417 meta_wayland_surface_get_buffer (MetaWaylandSurface *surface)
418 {
419 return surface->buffer_ref->buffer;
420 }
421
422 void
meta_wayland_surface_ref_buffer_use_count(MetaWaylandSurface * surface)423 meta_wayland_surface_ref_buffer_use_count (MetaWaylandSurface *surface)
424 {
425 meta_wayland_buffer_ref_inc_use_count (surface->buffer_ref);
426 }
427
428 void
meta_wayland_surface_unref_buffer_use_count(MetaWaylandSurface * surface)429 meta_wayland_surface_unref_buffer_use_count (MetaWaylandSurface *surface)
430 {
431 meta_wayland_buffer_ref_dec_use_count (surface->buffer_ref);
432 }
433
434 static void
pending_buffer_resource_destroyed(MetaWaylandBuffer * buffer,MetaWaylandSurfaceState * pending)435 pending_buffer_resource_destroyed (MetaWaylandBuffer *buffer,
436 MetaWaylandSurfaceState *pending)
437 {
438 g_clear_signal_handler (&pending->buffer_destroy_handler_id, buffer);
439 pending->buffer = NULL;
440 }
441
442 static void
meta_wayland_surface_state_set_default(MetaWaylandSurfaceState * state)443 meta_wayland_surface_state_set_default (MetaWaylandSurfaceState *state)
444 {
445 state->newly_attached = FALSE;
446 state->buffer = NULL;
447 state->buffer_destroy_handler_id = 0;
448 state->dx = 0;
449 state->dy = 0;
450 state->scale = 0;
451
452 state->input_region = NULL;
453 state->input_region_set = FALSE;
454 state->opaque_region = NULL;
455 state->opaque_region_set = FALSE;
456
457 state->surface_damage = cairo_region_create ();
458 state->buffer_damage = cairo_region_create ();
459 wl_list_init (&state->frame_callback_list);
460
461 state->has_new_geometry = FALSE;
462 state->has_acked_configure_serial = FALSE;
463 state->has_new_min_size = FALSE;
464 state->has_new_max_size = FALSE;
465
466 state->has_new_buffer_transform = FALSE;
467 state->has_new_viewport_src_rect = FALSE;
468 state->has_new_viewport_dst_size = FALSE;
469
470 state->subsurface_placement_ops = NULL;
471
472 wl_list_init (&state->presentation_feedback_list);
473 }
474
475 static void
meta_wayland_surface_state_discard_presentation_feedback(MetaWaylandSurfaceState * state)476 meta_wayland_surface_state_discard_presentation_feedback (MetaWaylandSurfaceState *state)
477 {
478 while (!wl_list_empty (&state->presentation_feedback_list))
479 {
480 MetaWaylandPresentationFeedback *feedback =
481 wl_container_of (state->presentation_feedback_list.next, feedback, link);
482
483 meta_wayland_presentation_feedback_discard (feedback);
484 }
485 }
486
487 static void
meta_wayland_surface_state_clear(MetaWaylandSurfaceState * state)488 meta_wayland_surface_state_clear (MetaWaylandSurfaceState *state)
489 {
490 MetaWaylandFrameCallback *cb, *next;
491
492 g_clear_pointer (&state->surface_damage, cairo_region_destroy);
493 g_clear_pointer (&state->buffer_damage, cairo_region_destroy);
494 g_clear_pointer (&state->input_region, cairo_region_destroy);
495 g_clear_pointer (&state->opaque_region, cairo_region_destroy);
496
497 if (state->buffer)
498 g_clear_signal_handler (&state->buffer_destroy_handler_id, state->buffer);
499
500 wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
501 wl_resource_destroy (cb->resource);
502
503 if (state->subsurface_placement_ops)
504 {
505 g_slist_free_full (
506 state->subsurface_placement_ops,
507 (GDestroyNotify) meta_wayland_subsurface_placement_op_free);
508 }
509
510 meta_wayland_surface_state_discard_presentation_feedback (state);
511 }
512
513 static void
meta_wayland_surface_state_reset(MetaWaylandSurfaceState * state)514 meta_wayland_surface_state_reset (MetaWaylandSurfaceState *state)
515 {
516 meta_wayland_surface_state_clear (state);
517 meta_wayland_surface_state_set_default (state);
518 }
519
520 static void
meta_wayland_surface_state_merge_into(MetaWaylandSurfaceState * from,MetaWaylandSurfaceState * to)521 meta_wayland_surface_state_merge_into (MetaWaylandSurfaceState *from,
522 MetaWaylandSurfaceState *to)
523 {
524 if (from->newly_attached)
525 {
526 if (to->buffer)
527 g_clear_signal_handler (&to->buffer_destroy_handler_id, to->buffer);
528
529 to->newly_attached = TRUE;
530 to->buffer = from->buffer;
531 to->dx = from->dx;
532 to->dy = from->dy;
533 }
534
535 wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list);
536 wl_list_init (&from->frame_callback_list);
537
538 cairo_region_union (to->surface_damage, from->surface_damage);
539 cairo_region_union (to->buffer_damage, from->buffer_damage);
540
541 if (from->input_region_set)
542 {
543 if (to->input_region)
544 cairo_region_union (to->input_region, from->input_region);
545 else
546 to->input_region = cairo_region_reference (from->input_region);
547
548 to->input_region_set = TRUE;
549 }
550
551 if (from->opaque_region_set)
552 {
553 if (to->opaque_region)
554 cairo_region_union (to->opaque_region, from->opaque_region);
555 else
556 to->opaque_region = cairo_region_reference (from->opaque_region);
557
558 to->opaque_region_set = TRUE;
559 }
560
561 if (from->has_new_geometry)
562 {
563 to->new_geometry = from->new_geometry;
564 to->has_new_geometry = TRUE;
565 }
566
567 if (from->has_acked_configure_serial)
568 {
569 to->acked_configure_serial = from->acked_configure_serial;
570 to->has_acked_configure_serial = TRUE;
571 }
572
573 if (from->has_new_min_size)
574 {
575 to->new_min_width = from->new_min_width;
576 to->new_min_height = from->new_min_height;
577 to->has_new_min_size = TRUE;
578 }
579
580 if (from->has_new_max_size)
581 {
582 to->new_max_width = from->new_max_width;
583 to->new_max_height = from->new_max_height;
584 to->has_new_max_size = TRUE;
585 }
586
587 if (from->scale > 0)
588 to->scale = from->scale;
589
590 if (from->has_new_buffer_transform)
591 {
592 to->buffer_transform = from->buffer_transform;
593 to->has_new_buffer_transform = TRUE;
594 }
595
596 if (from->has_new_viewport_src_rect)
597 {
598 to->viewport_src_rect.origin.x = from->viewport_src_rect.origin.x;
599 to->viewport_src_rect.origin.y = from->viewport_src_rect.origin.y;
600 to->viewport_src_rect.size.width = from->viewport_src_rect.size.width;
601 to->viewport_src_rect.size.height = from->viewport_src_rect.size.height;
602 to->has_new_viewport_src_rect = TRUE;
603 }
604
605 if (from->has_new_viewport_dst_size)
606 {
607 to->viewport_dst_width = from->viewport_dst_width;
608 to->viewport_dst_height = from->viewport_dst_height;
609 to->has_new_viewport_dst_size = TRUE;
610 }
611
612 if (to->buffer && to->buffer_destroy_handler_id == 0)
613 {
614 to->buffer_destroy_handler_id =
615 g_signal_connect (to->buffer, "resource-destroyed",
616 G_CALLBACK (pending_buffer_resource_destroyed),
617 to);
618 }
619
620 if (from->subsurface_placement_ops != NULL)
621 {
622 if (to->subsurface_placement_ops != NULL)
623 {
624 to->subsurface_placement_ops =
625 g_slist_concat (to->subsurface_placement_ops,
626 from->subsurface_placement_ops);
627 }
628 else
629 {
630 to->subsurface_placement_ops = from->subsurface_placement_ops;
631 }
632
633 from->subsurface_placement_ops = NULL;
634 }
635
636 wl_list_insert_list (&to->presentation_feedback_list,
637 &from->presentation_feedback_list);
638 wl_list_init (&from->presentation_feedback_list);
639
640 meta_wayland_surface_state_reset (from);
641 }
642
643 static void
meta_wayland_surface_state_finalize(GObject * object)644 meta_wayland_surface_state_finalize (GObject *object)
645 {
646 MetaWaylandSurfaceState *state = META_WAYLAND_SURFACE_STATE (object);
647
648 meta_wayland_surface_state_clear (state);
649
650 G_OBJECT_CLASS (meta_wayland_surface_state_parent_class)->finalize (object);
651 }
652
653 static void
meta_wayland_surface_state_init(MetaWaylandSurfaceState * state)654 meta_wayland_surface_state_init (MetaWaylandSurfaceState *state)
655 {
656 meta_wayland_surface_state_set_default (state);
657 }
658
659 static void
meta_wayland_surface_state_class_init(MetaWaylandSurfaceStateClass * klass)660 meta_wayland_surface_state_class_init (MetaWaylandSurfaceStateClass *klass)
661 {
662 GObjectClass *object_class = G_OBJECT_CLASS (klass);
663
664 object_class->finalize = meta_wayland_surface_state_finalize;
665
666 surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED] =
667 g_signal_new ("applied",
668 G_TYPE_FROM_CLASS (object_class),
669 G_SIGNAL_RUN_LAST,
670 0,
671 NULL, NULL, NULL,
672 G_TYPE_NONE, 0);
673 }
674
675 static void
meta_wayland_surface_discard_presentation_feedback(MetaWaylandSurface * surface)676 meta_wayland_surface_discard_presentation_feedback (MetaWaylandSurface *surface)
677 {
678 while (!wl_list_empty (&surface->presentation_time.feedback_list))
679 {
680 MetaWaylandPresentationFeedback *feedback =
681 wl_container_of (surface->presentation_time.feedback_list.next,
682 feedback, link);
683
684 meta_wayland_presentation_feedback_discard (feedback);
685 }
686 }
687
688 static void
meta_wayland_surface_apply_state(MetaWaylandSurface * surface,MetaWaylandSurfaceState * state)689 meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
690 MetaWaylandSurfaceState *state)
691 {
692 MetaWaylandSurface *subsurface_surface;
693 gboolean had_damage = FALSE;
694
695 g_signal_emit (surface, surface_signals[SURFACE_PRE_STATE_APPLIED], 0);
696
697 if (surface->role)
698 {
699 meta_wayland_surface_role_pre_apply_state (surface->role, state);
700 }
701 else
702 {
703 if (state->newly_attached && surface->unassigned.buffer)
704 {
705 meta_wayland_surface_unref_buffer_use_count (surface);
706 g_clear_object (&surface->unassigned.buffer);
707 }
708 }
709
710 if (state->newly_attached)
711 {
712 /* Always release any previously held buffer. If the buffer held is same
713 * as the newly attached buffer, we still need to release it here, because
714 * wl_surface.attach+commit and wl_buffer.release on the attached buffer
715 * is symmetric.
716 */
717 if (surface->buffer_held)
718 meta_wayland_surface_unref_buffer_use_count (surface);
719
720 if (surface->buffer_ref->use_count > 0)
721 {
722 meta_wayland_buffer_ref_unref (surface->buffer_ref);
723 surface->buffer_ref = meta_wayland_buffer_ref_new ();
724 }
725
726 g_set_object (&surface->buffer_ref->buffer, state->buffer);
727
728 if (state->buffer)
729 meta_wayland_surface_ref_buffer_use_count (surface);
730
731 if (state->buffer)
732 {
733 GError *error = NULL;
734
735 if (!meta_wayland_buffer_attach (state->buffer,
736 &surface->texture,
737 &error))
738 {
739 g_warning ("Could not import pending buffer: %s", error->message);
740 wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_NO_MEMORY,
741 "Failed to attach buffer to surface %i: %s",
742 wl_resource_get_id (surface->resource),
743 error->message);
744 g_error_free (error);
745 goto cleanup;
746 }
747 }
748 else
749 {
750 cogl_clear_object (&surface->texture);
751 }
752
753 /* If the newly attached buffer is going to be accessed directly without
754 * making a copy, such as an EGL buffer, mark it as in-use don't release
755 * it until is replaced by a subsequent wl_surface.commit or when the
756 * wl_surface is destroyed.
757 */
758 surface->buffer_held = (state->buffer &&
759 !wl_shm_buffer_get (state->buffer->resource));
760 }
761
762 if (state->scale > 0)
763 surface->scale = state->scale;
764
765 if (state->has_new_buffer_transform)
766 surface->buffer_transform = state->buffer_transform;
767
768 if (state->has_new_viewport_src_rect)
769 {
770 surface->viewport.src_rect.origin.x = state->viewport_src_rect.origin.x;
771 surface->viewport.src_rect.origin.y = state->viewport_src_rect.origin.y;
772 surface->viewport.src_rect.size.width = state->viewport_src_rect.size.width;
773 surface->viewport.src_rect.size.height = state->viewport_src_rect.size.height;
774 surface->viewport.has_src_rect = surface->viewport.src_rect.size.width > 0;
775 }
776
777 if (state->has_new_viewport_dst_size)
778 {
779 surface->viewport.dst_width = state->viewport_dst_width;
780 surface->viewport.dst_height = state->viewport_dst_height;
781 surface->viewport.has_dst_size = surface->viewport.dst_width > 0;
782 }
783
784 if (!cairo_region_is_empty (state->surface_damage) ||
785 !cairo_region_is_empty (state->buffer_damage))
786 {
787 surface_process_damage (surface,
788 state->surface_damage,
789 state->buffer_damage);
790 had_damage = TRUE;
791 }
792
793 surface->offset_x += state->dx;
794 surface->offset_y += state->dy;
795
796 if (state->opaque_region_set)
797 {
798 if (surface->opaque_region)
799 cairo_region_destroy (surface->opaque_region);
800 if (state->opaque_region)
801 surface->opaque_region = cairo_region_reference (state->opaque_region);
802 else
803 surface->opaque_region = NULL;
804 }
805
806 if (state->input_region_set)
807 {
808 if (surface->input_region)
809 cairo_region_destroy (surface->input_region);
810 if (state->input_region)
811 surface->input_region = cairo_region_reference (state->input_region);
812 else
813 surface->input_region = NULL;
814 }
815
816 /*
817 * A new commit indicates a new content update, so any previous
818 * content update did not go on screen and needs to be discarded.
819 */
820 meta_wayland_surface_discard_presentation_feedback (surface);
821
822 wl_list_insert_list (&surface->presentation_time.feedback_list,
823 &state->presentation_feedback_list);
824 wl_list_init (&state->presentation_feedback_list);
825
826 if (!wl_list_empty (&surface->presentation_time.feedback_list))
827 meta_wayland_compositor_add_presentation_feedback_surface (surface->compositor,
828 surface);
829
830 if (surface->role)
831 {
832 meta_wayland_surface_role_apply_state (surface->role, state);
833 g_assert (wl_list_empty (&state->frame_callback_list));
834 }
835 else
836 {
837 wl_list_insert_list (surface->unassigned.pending_frame_callback_list.prev,
838 &state->frame_callback_list);
839 wl_list_init (&state->frame_callback_list);
840
841 if (state->newly_attached)
842 {
843 /* The need to keep the wl_buffer from being released depends on what
844 * role the surface is given. That means we need to also keep a use
845 * count for wl_buffer's that are used by unassigned wl_surface's.
846 */
847 g_set_object (&surface->unassigned.buffer,
848 surface->buffer_ref->buffer);
849 if (surface->unassigned.buffer)
850 meta_wayland_surface_ref_buffer_use_count (surface);
851 }
852 }
853
854 if (state->subsurface_placement_ops)
855 {
856 GSList *l;
857
858 for (l = state->subsurface_placement_ops; l; l = l->next)
859 {
860 MetaWaylandSubsurfacePlacementOp *op = l->data;
861 GNode *sibling_node;
862
863 if (!op->surface || !op->sibling)
864 continue;
865
866 if (op->sibling == surface)
867 sibling_node = surface->subsurface_leaf_node;
868 else
869 sibling_node = op->sibling->subsurface_branch_node;
870
871 g_node_unlink (op->surface->subsurface_branch_node);
872
873 switch (op->placement)
874 {
875 case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
876 g_node_insert_after (surface->subsurface_branch_node,
877 sibling_node,
878 op->surface->subsurface_branch_node);
879 break;
880 case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
881 g_node_insert_before (surface->subsurface_branch_node,
882 sibling_node,
883 op->surface->subsurface_branch_node);
884 break;
885 }
886 }
887
888 meta_wayland_surface_notify_subsurface_state_changed (surface);
889 }
890
891 cleanup:
892 /* If we have a buffer that we are not using, decrease the use count so it may
893 * be released if no-one else has a use-reference to it.
894 */
895 if (state->newly_attached &&
896 !surface->buffer_held && surface->buffer_ref->buffer)
897 meta_wayland_surface_unref_buffer_use_count (surface);
898
899 g_signal_emit (state,
900 surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
901 0);
902
903 META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
904 {
905 MetaWaylandSubsurface *subsurface;
906
907 subsurface = META_WAYLAND_SUBSURFACE (subsurface_surface->role);
908 meta_wayland_subsurface_parent_state_applied (subsurface);
909 }
910
911 if (had_damage)
912 {
913 MetaWindow *toplevel_window;
914
915 toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
916 if (toplevel_window)
917 {
918 MetaWindowActor *toplevel_window_actor;
919
920 toplevel_window_actor =
921 meta_window_actor_from_window (toplevel_window);
922 if (toplevel_window_actor)
923 meta_window_actor_notify_damaged (toplevel_window_actor);
924 }
925 }
926
927 if (surface->role)
928 meta_wayland_surface_role_post_apply_state (surface->role, state);
929
930 meta_wayland_surface_state_reset (state);
931 }
932
933 void
meta_wayland_surface_apply_cached_state(MetaWaylandSurface * surface)934 meta_wayland_surface_apply_cached_state (MetaWaylandSurface *surface)
935 {
936 if (!surface->cached_state)
937 return;
938
939 meta_wayland_surface_apply_state (surface, surface->cached_state);
940 }
941
942 MetaWaylandSurfaceState *
meta_wayland_surface_get_pending_state(MetaWaylandSurface * surface)943 meta_wayland_surface_get_pending_state (MetaWaylandSurface *surface)
944 {
945 return surface->pending_state;
946 }
947
948 MetaWaylandSurfaceState *
meta_wayland_surface_ensure_cached_state(MetaWaylandSurface * surface)949 meta_wayland_surface_ensure_cached_state (MetaWaylandSurface *surface)
950 {
951 if (!surface->cached_state)
952 surface->cached_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE,
953 NULL);
954 return surface->cached_state;
955 }
956
957 static void
meta_wayland_surface_commit(MetaWaylandSurface * surface)958 meta_wayland_surface_commit (MetaWaylandSurface *surface)
959 {
960 MetaWaylandSurfaceState *pending = surface->pending_state;
961
962 COGL_TRACE_BEGIN_SCOPED (MetaWaylandSurfaceCommit,
963 "WaylandSurface (commit)");
964
965 if (pending->buffer &&
966 !meta_wayland_buffer_is_realized (pending->buffer))
967 meta_wayland_buffer_realize (pending->buffer);
968
969 /*
970 * If this is a sub-surface and it is in effective synchronous mode, only
971 * cache the pending surface state until either one of the following two
972 * scenarios happens:
973 * 1) Its parent surface gets its state applied.
974 * 2) Its mode changes from synchronized to desynchronized and its parent
975 * surface is in effective desynchronized mode.
976 */
977 if (meta_wayland_surface_should_cache_state (surface))
978 {
979 MetaWaylandSurfaceState *cached_state;
980
981 cached_state = meta_wayland_surface_ensure_cached_state (surface);
982
983 /*
984 * A new commit indicates a new content update, so any previous
985 * cached content update did not go on screen and needs to be discarded.
986 */
987 meta_wayland_surface_state_discard_presentation_feedback (cached_state);
988
989 meta_wayland_surface_state_merge_into (pending, cached_state);
990 }
991 else
992 {
993 meta_wayland_surface_apply_state (surface, surface->pending_state);
994 }
995 }
996
997 static void
wl_surface_destroy(struct wl_client * client,struct wl_resource * resource)998 wl_surface_destroy (struct wl_client *client,
999 struct wl_resource *resource)
1000 {
1001 wl_resource_destroy (resource);
1002 }
1003
1004 static void
wl_surface_attach(struct wl_client * client,struct wl_resource * surface_resource,struct wl_resource * buffer_resource,gint32 dx,gint32 dy)1005 wl_surface_attach (struct wl_client *client,
1006 struct wl_resource *surface_resource,
1007 struct wl_resource *buffer_resource,
1008 gint32 dx, gint32 dy)
1009 {
1010 MetaWaylandSurface *surface =
1011 wl_resource_get_user_data (surface_resource);
1012 MetaWaylandSurfaceState *pending = surface->pending_state;
1013 MetaWaylandBuffer *buffer;
1014
1015 /* X11 unmanaged window */
1016 if (!surface)
1017 return;
1018
1019 if (buffer_resource)
1020 buffer = meta_wayland_buffer_from_resource (buffer_resource);
1021 else
1022 buffer = NULL;
1023
1024 if (surface->pending_state->buffer)
1025 {
1026 g_clear_signal_handler (&pending->buffer_destroy_handler_id,
1027 pending->buffer);
1028 }
1029
1030 pending->newly_attached = TRUE;
1031 pending->buffer = buffer;
1032 pending->dx = dx;
1033 pending->dy = dy;
1034
1035 if (buffer)
1036 {
1037 pending->buffer_destroy_handler_id =
1038 g_signal_connect (buffer, "resource-destroyed",
1039 G_CALLBACK (pending_buffer_resource_destroyed),
1040 pending);
1041 }
1042 }
1043
1044 static void
wl_surface_damage(struct wl_client * client,struct wl_resource * surface_resource,int32_t x,int32_t y,int32_t width,int32_t height)1045 wl_surface_damage (struct wl_client *client,
1046 struct wl_resource *surface_resource,
1047 int32_t x,
1048 int32_t y,
1049 int32_t width,
1050 int32_t height)
1051 {
1052 MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
1053 MetaWaylandSurfaceState *pending = surface->pending_state;
1054 cairo_rectangle_int_t rectangle;
1055
1056 /* X11 unmanaged window */
1057 if (!surface)
1058 return;
1059
1060 rectangle = (cairo_rectangle_int_t) {
1061 .x = x,
1062 .y = y,
1063 .width = width,
1064 .height = height
1065 };
1066 cairo_region_union_rectangle (pending->surface_damage, &rectangle);
1067 }
1068
1069 static void
destroy_frame_callback(struct wl_resource * callback_resource)1070 destroy_frame_callback (struct wl_resource *callback_resource)
1071 {
1072 MetaWaylandFrameCallback *callback =
1073 wl_resource_get_user_data (callback_resource);
1074
1075 wl_list_remove (&callback->link);
1076 g_free (callback);
1077 }
1078
1079 static void
wl_surface_frame(struct wl_client * client,struct wl_resource * surface_resource,guint32 callback_id)1080 wl_surface_frame (struct wl_client *client,
1081 struct wl_resource *surface_resource,
1082 guint32 callback_id)
1083 {
1084 MetaWaylandFrameCallback *callback;
1085 MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
1086 MetaWaylandSurfaceState *pending = surface->pending_state;
1087
1088 /* X11 unmanaged window */
1089 if (!surface)
1090 return;
1091
1092 callback = g_new0 (MetaWaylandFrameCallback, 1);
1093 callback->surface = surface;
1094 callback->resource = wl_resource_create (client,
1095 &wl_callback_interface,
1096 META_WL_CALLBACK_VERSION,
1097 callback_id);
1098 wl_resource_set_implementation (callback->resource, NULL, callback,
1099 destroy_frame_callback);
1100
1101 wl_list_insert (pending->frame_callback_list.prev, &callback->link);
1102 }
1103
1104 static void
wl_surface_set_opaque_region(struct wl_client * client,struct wl_resource * surface_resource,struct wl_resource * region_resource)1105 wl_surface_set_opaque_region (struct wl_client *client,
1106 struct wl_resource *surface_resource,
1107 struct wl_resource *region_resource)
1108 {
1109 MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
1110 MetaWaylandSurfaceState *pending = surface->pending_state;
1111
1112 /* X11 unmanaged window */
1113 if (!surface)
1114 return;
1115
1116 g_clear_pointer (&pending->opaque_region, cairo_region_destroy);
1117 if (region_resource)
1118 {
1119 MetaWaylandRegion *region = wl_resource_get_user_data (region_resource);
1120 cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region);
1121 pending->opaque_region = cairo_region_copy (cr_region);
1122 }
1123 pending->opaque_region_set = TRUE;
1124 }
1125
1126 static void
wl_surface_set_input_region(struct wl_client * client,struct wl_resource * surface_resource,struct wl_resource * region_resource)1127 wl_surface_set_input_region (struct wl_client *client,
1128 struct wl_resource *surface_resource,
1129 struct wl_resource *region_resource)
1130 {
1131 MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
1132 MetaWaylandSurfaceState *pending = surface->pending_state;
1133
1134 /* X11 unmanaged window */
1135 if (!surface)
1136 return;
1137
1138 g_clear_pointer (&pending->input_region, cairo_region_destroy);
1139 if (region_resource)
1140 {
1141 MetaWaylandRegion *region = wl_resource_get_user_data (region_resource);
1142 cairo_region_t *cr_region = meta_wayland_region_peek_cairo_region (region);
1143 pending->input_region = cairo_region_copy (cr_region);
1144 }
1145 pending->input_region_set = TRUE;
1146 }
1147
1148 static void
wl_surface_commit(struct wl_client * client,struct wl_resource * resource)1149 wl_surface_commit (struct wl_client *client,
1150 struct wl_resource *resource)
1151 {
1152 MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
1153
1154 /* X11 unmanaged window */
1155 if (!surface)
1156 return;
1157
1158 meta_wayland_surface_commit (surface);
1159 }
1160
1161 static MetaMonitorTransform
transform_from_wl_output_transform(int32_t transform_value)1162 transform_from_wl_output_transform (int32_t transform_value)
1163 {
1164 enum wl_output_transform transform = transform_value;
1165
1166 switch (transform)
1167 {
1168 case WL_OUTPUT_TRANSFORM_NORMAL:
1169 return META_MONITOR_TRANSFORM_NORMAL;
1170 case WL_OUTPUT_TRANSFORM_90:
1171 return META_MONITOR_TRANSFORM_90;
1172 case WL_OUTPUT_TRANSFORM_180:
1173 return META_MONITOR_TRANSFORM_180;
1174 case WL_OUTPUT_TRANSFORM_270:
1175 return META_MONITOR_TRANSFORM_270;
1176 case WL_OUTPUT_TRANSFORM_FLIPPED:
1177 return META_MONITOR_TRANSFORM_FLIPPED;
1178 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1179 return META_MONITOR_TRANSFORM_FLIPPED_90;
1180 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
1181 return META_MONITOR_TRANSFORM_FLIPPED_180;
1182 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1183 return META_MONITOR_TRANSFORM_FLIPPED_270;
1184 default:
1185 return -1;
1186 }
1187 }
1188
1189 static void
wl_surface_set_buffer_transform(struct wl_client * client,struct wl_resource * resource,int32_t transform)1190 wl_surface_set_buffer_transform (struct wl_client *client,
1191 struct wl_resource *resource,
1192 int32_t transform)
1193 {
1194 MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
1195 MetaWaylandSurfaceState *pending = surface->pending_state;
1196 MetaMonitorTransform buffer_transform;
1197
1198 buffer_transform = transform_from_wl_output_transform (transform);
1199
1200 if (buffer_transform == -1)
1201 {
1202 wl_resource_post_error (resource,
1203 WL_SURFACE_ERROR_INVALID_TRANSFORM,
1204 "Trying to set invalid buffer_transform of %d",
1205 transform);
1206 return;
1207 }
1208
1209 pending->buffer_transform = buffer_transform;
1210 pending->has_new_buffer_transform = TRUE;
1211 }
1212
1213 static void
wl_surface_set_buffer_scale(struct wl_client * client,struct wl_resource * resource,int scale)1214 wl_surface_set_buffer_scale (struct wl_client *client,
1215 struct wl_resource *resource,
1216 int scale)
1217 {
1218 MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
1219 MetaWaylandSurfaceState *pending = surface->pending_state;
1220
1221 if (scale <= 0)
1222 {
1223 wl_resource_post_error (resource,
1224 WL_SURFACE_ERROR_INVALID_SCALE,
1225 "Trying to set invalid buffer_scale of %d",
1226 scale);
1227 return;
1228 }
1229
1230 pending->scale = scale;
1231 }
1232
1233 static void
wl_surface_damage_buffer(struct wl_client * client,struct wl_resource * surface_resource,int32_t x,int32_t y,int32_t width,int32_t height)1234 wl_surface_damage_buffer (struct wl_client *client,
1235 struct wl_resource *surface_resource,
1236 int32_t x,
1237 int32_t y,
1238 int32_t width,
1239 int32_t height)
1240 {
1241 MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
1242 MetaWaylandSurfaceState *pending = surface->pending_state;
1243 cairo_rectangle_int_t rectangle;
1244
1245 /* X11 unmanaged window */
1246 if (!surface)
1247 return;
1248
1249 rectangle = (cairo_rectangle_int_t) {
1250 .x = x,
1251 .y = y,
1252 .width = width,
1253 .height = height
1254 };
1255 cairo_region_union_rectangle (pending->buffer_damage, &rectangle);
1256 }
1257
1258 static const struct wl_surface_interface meta_wayland_wl_surface_interface = {
1259 wl_surface_destroy,
1260 wl_surface_attach,
1261 wl_surface_damage,
1262 wl_surface_frame,
1263 wl_surface_set_opaque_region,
1264 wl_surface_set_input_region,
1265 wl_surface_commit,
1266 wl_surface_set_buffer_transform,
1267 wl_surface_set_buffer_scale,
1268 wl_surface_damage_buffer,
1269 };
1270
1271 static void
handle_output_destroyed(MetaWaylandOutput * wayland_output,MetaWaylandSurface * surface)1272 handle_output_destroyed (MetaWaylandOutput *wayland_output,
1273 MetaWaylandSurface *surface)
1274 {
1275 set_surface_is_on_output (surface, wayland_output, FALSE);
1276 }
1277
1278 static void
handle_output_bound(MetaWaylandOutput * wayland_output,struct wl_resource * output_resource,MetaWaylandSurface * surface)1279 handle_output_bound (MetaWaylandOutput *wayland_output,
1280 struct wl_resource *output_resource,
1281 MetaWaylandSurface *surface)
1282 {
1283 if (wl_resource_get_client (output_resource) ==
1284 wl_resource_get_client (surface->resource))
1285 wl_surface_send_enter (surface->resource, output_resource);
1286 }
1287
1288 static void
surface_entered_output(MetaWaylandSurface * surface,MetaWaylandOutput * wayland_output)1289 surface_entered_output (MetaWaylandSurface *surface,
1290 MetaWaylandOutput *wayland_output)
1291 {
1292 const GList *l;
1293
1294 g_signal_connect (wayland_output, "output-destroyed",
1295 G_CALLBACK (handle_output_destroyed),
1296 surface);
1297
1298 for (l = meta_wayland_output_get_resources (wayland_output); l; l = l->next)
1299 {
1300 struct wl_resource *resource = l->data;
1301
1302 if (wl_resource_get_client (resource) !=
1303 wl_resource_get_client (surface->resource))
1304 continue;
1305
1306 wl_surface_send_enter (surface->resource, resource);
1307 }
1308
1309 g_signal_connect (wayland_output, "output-bound",
1310 G_CALLBACK (handle_output_bound),
1311 surface);
1312 }
1313
1314 static void
surface_left_output(MetaWaylandSurface * surface,MetaWaylandOutput * wayland_output)1315 surface_left_output (MetaWaylandSurface *surface,
1316 MetaWaylandOutput *wayland_output)
1317 {
1318 const GList *l;
1319
1320 g_signal_handlers_disconnect_by_func (wayland_output,
1321 G_CALLBACK (handle_output_destroyed),
1322 surface);
1323
1324 g_signal_handlers_disconnect_by_func (wayland_output,
1325 G_CALLBACK (handle_output_bound),
1326 surface);
1327
1328 for (l = meta_wayland_output_get_resources (wayland_output); l; l = l->next)
1329 {
1330 struct wl_resource *resource = l->data;
1331
1332 if (wl_resource_get_client (resource) !=
1333 wl_resource_get_client (surface->resource))
1334 continue;
1335
1336 wl_surface_send_leave (surface->resource, resource);
1337 }
1338 }
1339
1340 static void
set_surface_is_on_output(MetaWaylandSurface * surface,MetaWaylandOutput * wayland_output,gboolean is_on_output)1341 set_surface_is_on_output (MetaWaylandSurface *surface,
1342 MetaWaylandOutput *wayland_output,
1343 gboolean is_on_output)
1344 {
1345 gboolean was_on_output;
1346
1347 was_on_output = g_hash_table_contains (surface->outputs, wayland_output);
1348
1349 if (!was_on_output && is_on_output)
1350 {
1351 g_hash_table_add (surface->outputs, wayland_output);
1352 surface_entered_output (surface, wayland_output);
1353 }
1354 else if (was_on_output && !is_on_output)
1355 {
1356 g_hash_table_remove (surface->outputs, wayland_output);
1357 surface_left_output (surface, wayland_output);
1358 }
1359 }
1360
1361 static void
update_surface_output_state(gpointer key,gpointer value,gpointer user_data)1362 update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
1363 {
1364 MetaWaylandOutput *wayland_output = value;
1365 MetaWaylandSurface *surface = user_data;
1366 MetaLogicalMonitor *logical_monitor;
1367 gboolean is_on_logical_monitor;
1368
1369 g_assert (surface->role);
1370
1371 logical_monitor = meta_wayland_output_get_logical_monitor (wayland_output);
1372 if (!logical_monitor)
1373 {
1374 set_surface_is_on_output (surface, wayland_output, FALSE);
1375 return;
1376 }
1377
1378 is_on_logical_monitor =
1379 meta_wayland_surface_role_is_on_logical_monitor (surface->role,
1380 logical_monitor);
1381 set_surface_is_on_output (surface, wayland_output, is_on_logical_monitor);
1382 }
1383
1384 static void
surface_output_disconnect_signals(gpointer key,gpointer value,gpointer user_data)1385 surface_output_disconnect_signals (gpointer key,
1386 gpointer value,
1387 gpointer user_data)
1388 {
1389 MetaWaylandOutput *wayland_output = key;
1390 MetaWaylandSurface *surface = user_data;
1391
1392 g_signal_handlers_disconnect_by_func (wayland_output,
1393 G_CALLBACK (handle_output_destroyed),
1394 surface);
1395
1396 g_signal_handlers_disconnect_by_func (wayland_output,
1397 G_CALLBACK (handle_output_bound),
1398 surface);
1399 }
1400
1401 void
meta_wayland_surface_update_outputs(MetaWaylandSurface * surface)1402 meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
1403 {
1404 if (!surface->compositor)
1405 return;
1406
1407 g_hash_table_foreach (surface->compositor->outputs,
1408 update_surface_output_state,
1409 surface);
1410 }
1411
1412 void
meta_wayland_surface_notify_unmapped(MetaWaylandSurface * surface)1413 meta_wayland_surface_notify_unmapped (MetaWaylandSurface *surface)
1414 {
1415 g_signal_emit (surface, surface_signals[SURFACE_UNMAPPED], 0);
1416 }
1417
1418 static void
wl_surface_destructor(struct wl_resource * resource)1419 wl_surface_destructor (struct wl_resource *resource)
1420 {
1421 MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
1422 MetaWaylandCompositor *compositor = surface->compositor;
1423 MetaWaylandFrameCallback *cb, *next;
1424
1425 g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
1426
1427 g_clear_object (&surface->role);
1428
1429 if (surface->unassigned.buffer)
1430 {
1431 meta_wayland_surface_unref_buffer_use_count (surface);
1432 g_clear_object (&surface->unassigned.buffer);
1433 }
1434
1435 if (surface->buffer_held)
1436 meta_wayland_surface_unref_buffer_use_count (surface);
1437 g_clear_pointer (&surface->texture, cogl_object_unref);
1438 g_clear_pointer (&surface->buffer_ref, meta_wayland_buffer_ref_unref);
1439
1440 g_clear_object (&surface->cached_state);
1441 g_clear_object (&surface->pending_state);
1442
1443 if (surface->opaque_region)
1444 cairo_region_destroy (surface->opaque_region);
1445 if (surface->input_region)
1446 cairo_region_destroy (surface->input_region);
1447
1448 meta_wayland_compositor_remove_frame_callback_surface (compositor, surface);
1449 meta_wayland_compositor_remove_presentation_feedback_surface (compositor,
1450 surface);
1451
1452 g_hash_table_foreach (surface->outputs,
1453 surface_output_disconnect_signals,
1454 surface);
1455 g_hash_table_destroy (surface->outputs);
1456
1457 wl_list_for_each_safe (cb, next,
1458 &surface->unassigned.pending_frame_callback_list,
1459 link)
1460 wl_resource_destroy (cb->resource);
1461
1462 meta_wayland_surface_discard_presentation_feedback (surface);
1463
1464 if (surface->resource)
1465 wl_resource_set_user_data (surface->resource, NULL);
1466
1467 if (surface->wl_subsurface)
1468 wl_resource_destroy (surface->wl_subsurface);
1469
1470 g_clear_pointer (&surface->subsurface_branch_node, g_node_destroy);
1471
1472 g_hash_table_destroy (surface->shortcut_inhibited_seats);
1473
1474 g_object_unref (surface);
1475 }
1476
1477 MetaWaylandSurface *
meta_wayland_surface_create(MetaWaylandCompositor * compositor,struct wl_client * client,struct wl_resource * compositor_resource,guint32 id)1478 meta_wayland_surface_create (MetaWaylandCompositor *compositor,
1479 struct wl_client *client,
1480 struct wl_resource *compositor_resource,
1481 guint32 id)
1482 {
1483 MetaWaylandSurface *surface = g_object_new (META_TYPE_WAYLAND_SURFACE, NULL);
1484 int surface_version;
1485
1486 surface->compositor = compositor;
1487 surface->scale = 1;
1488
1489 surface_version = wl_resource_get_version (compositor_resource);
1490 surface->resource = wl_resource_create (client,
1491 &wl_surface_interface,
1492 surface_version,
1493 id);
1494 wl_resource_set_implementation (surface->resource,
1495 &meta_wayland_wl_surface_interface,
1496 surface,
1497 wl_surface_destructor);
1498
1499 wl_list_init (&surface->unassigned.pending_frame_callback_list);
1500
1501 surface->outputs = g_hash_table_new (NULL, NULL);
1502 surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
1503
1504 wl_list_init (&surface->presentation_time.feedback_list);
1505
1506 meta_wayland_compositor_notify_surface_id (compositor, id, surface);
1507
1508 return surface;
1509 }
1510
1511 gboolean
meta_wayland_surface_begin_grab_op(MetaWaylandSurface * surface,MetaWaylandSeat * seat,MetaGrabOp grab_op,gfloat x,gfloat y)1512 meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface,
1513 MetaWaylandSeat *seat,
1514 MetaGrabOp grab_op,
1515 gfloat x,
1516 gfloat y)
1517 {
1518 MetaWindow *window = meta_wayland_surface_get_window (surface);
1519
1520 if (grab_op == META_GRAB_OP_NONE)
1521 return FALSE;
1522
1523 /* This is an input driven operation so we set frame_action to
1524 constrain it in the same way as it would be if the window was
1525 being moved/resized via a SSD event. */
1526 return meta_display_begin_grab_op (window->display,
1527 window,
1528 grab_op,
1529 TRUE, /* pointer_already_grabbed */
1530 TRUE, /* frame_action */
1531 1, /* button. XXX? */
1532 0, /* modmask */
1533 meta_display_get_current_time_roundtrip (window->display),
1534 x, y);
1535 }
1536
1537 /**
1538 * meta_wayland_shell_init:
1539 * @compositor: The #MetaWaylandCompositor object
1540 *
1541 * Initializes the Wayland interfaces providing features that deal with
1542 * desktop-specific conundrums, like XDG shell, wl_shell (deprecated), etc.
1543 */
1544 void
meta_wayland_shell_init(MetaWaylandCompositor * compositor)1545 meta_wayland_shell_init (MetaWaylandCompositor *compositor)
1546 {
1547 meta_wayland_xdg_shell_init (compositor);
1548 meta_wayland_legacy_xdg_shell_init (compositor);
1549 meta_wayland_wl_shell_init (compositor);
1550 meta_wayland_init_gtk_shell (compositor);
1551 meta_wayland_init_viewporter (compositor);
1552 }
1553
1554 void
meta_wayland_surface_configure_notify(MetaWaylandSurface * surface,MetaWaylandWindowConfiguration * configuration)1555 meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
1556 MetaWaylandWindowConfiguration *configuration)
1557 {
1558 MetaWaylandShellSurface *shell_surface =
1559 META_WAYLAND_SHELL_SURFACE (surface->role);
1560
1561 g_signal_emit (surface, surface_signals[SURFACE_CONFIGURE], 0);
1562
1563 meta_wayland_shell_surface_configure (shell_surface, configuration);
1564 }
1565
1566 void
meta_wayland_surface_ping(MetaWaylandSurface * surface,guint32 serial)1567 meta_wayland_surface_ping (MetaWaylandSurface *surface,
1568 guint32 serial)
1569 {
1570 MetaWaylandShellSurface *shell_surface =
1571 META_WAYLAND_SHELL_SURFACE (surface->role);
1572
1573 meta_wayland_shell_surface_ping (shell_surface, serial);
1574 }
1575
1576 void
meta_wayland_surface_delete(MetaWaylandSurface * surface)1577 meta_wayland_surface_delete (MetaWaylandSurface *surface)
1578 {
1579 MetaWaylandShellSurface *shell_surface =
1580 META_WAYLAND_SHELL_SURFACE (surface->role);
1581
1582 meta_wayland_shell_surface_close (shell_surface);
1583 }
1584
1585 void
meta_wayland_surface_window_managed(MetaWaylandSurface * surface,MetaWindow * window)1586 meta_wayland_surface_window_managed (MetaWaylandSurface *surface,
1587 MetaWindow *window)
1588 {
1589 MetaWaylandShellSurface *shell_surface =
1590 META_WAYLAND_SHELL_SURFACE (surface->role);
1591
1592 meta_wayland_shell_surface_managed (shell_surface, window);
1593 }
1594
1595 void
meta_wayland_surface_drag_dest_focus_in(MetaWaylandSurface * surface,MetaWaylandDataOffer * offer)1596 meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface,
1597 MetaWaylandDataOffer *offer)
1598 {
1599 MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
1600 MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
1601
1602 surface->dnd.funcs->focus_in (data_device, surface, offer);
1603 }
1604
1605 void
meta_wayland_surface_drag_dest_motion(MetaWaylandSurface * surface,const ClutterEvent * event)1606 meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface,
1607 const ClutterEvent *event)
1608 {
1609 MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
1610 MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
1611
1612 surface->dnd.funcs->motion (data_device, surface, event);
1613 }
1614
1615 void
meta_wayland_surface_drag_dest_focus_out(MetaWaylandSurface * surface)1616 meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface)
1617 {
1618 MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
1619 MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
1620
1621 surface->dnd.funcs->focus_out (data_device, surface);
1622 }
1623
1624 void
meta_wayland_surface_drag_dest_drop(MetaWaylandSurface * surface)1625 meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface)
1626 {
1627 MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
1628 MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
1629
1630 surface->dnd.funcs->drop (data_device, surface);
1631 }
1632
1633 void
meta_wayland_surface_drag_dest_update(MetaWaylandSurface * surface)1634 meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface)
1635 {
1636 MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
1637 MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
1638
1639 surface->dnd.funcs->update (data_device, surface);
1640 }
1641
1642 MetaWaylandSurface *
meta_wayland_surface_get_toplevel(MetaWaylandSurface * surface)1643 meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface)
1644 {
1645 if (surface->role)
1646 return meta_wayland_surface_role_get_toplevel (surface->role);
1647 else
1648 return NULL;
1649 }
1650
1651 MetaWindow *
meta_wayland_surface_get_toplevel_window(MetaWaylandSurface * surface)1652 meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
1653 {
1654 MetaWaylandSurface *toplevel;
1655
1656 toplevel = meta_wayland_surface_get_toplevel (surface);
1657 if (toplevel)
1658 return meta_wayland_surface_get_window (toplevel);
1659 else
1660 return NULL;
1661 }
1662
1663 void
meta_wayland_surface_get_relative_coordinates(MetaWaylandSurface * surface,float abs_x,float abs_y,float * sx,float * sy)1664 meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface,
1665 float abs_x,
1666 float abs_y,
1667 float *sx,
1668 float *sy)
1669 {
1670 MetaWaylandSurfaceRoleClass *surface_role_class =
1671 META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role);
1672
1673 surface_role_class->get_relative_coordinates (surface->role,
1674 abs_x, abs_y,
1675 sx, sy);
1676 }
1677
1678 void
meta_wayland_surface_get_absolute_coordinates(MetaWaylandSurface * surface,float sx,float sy,float * x,float * y)1679 meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
1680 float sx,
1681 float sy,
1682 float *x,
1683 float *y)
1684 {
1685 ClutterActor *actor =
1686 CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
1687 graphene_point3d_t sv = {
1688 .x = sx,
1689 .y = sy,
1690 };
1691 graphene_point3d_t v = { 0 };
1692
1693 clutter_actor_apply_relative_transform_to_point (actor, NULL, &sv, &v);
1694
1695 *x = v.x;
1696 *y = v.y;
1697 }
1698
1699 static void
meta_wayland_surface_init(MetaWaylandSurface * surface)1700 meta_wayland_surface_init (MetaWaylandSurface *surface)
1701 {
1702 surface->pending_state = g_object_new (META_TYPE_WAYLAND_SURFACE_STATE, NULL);
1703
1704 surface->buffer_ref = meta_wayland_buffer_ref_new ();
1705
1706 surface->subsurface_branch_node = g_node_new (surface);
1707 surface->subsurface_leaf_node =
1708 g_node_prepend_data (surface->subsurface_branch_node, surface);
1709 }
1710
1711 static void
meta_wayland_surface_class_init(MetaWaylandSurfaceClass * klass)1712 meta_wayland_surface_class_init (MetaWaylandSurfaceClass *klass)
1713 {
1714 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1715
1716 surface_signals[SURFACE_DESTROY] =
1717 g_signal_new ("destroy",
1718 G_TYPE_FROM_CLASS (object_class),
1719 G_SIGNAL_RUN_LAST,
1720 0, NULL, NULL,
1721 g_cclosure_marshal_VOID__VOID,
1722 G_TYPE_NONE, 0);
1723
1724 surface_signals[SURFACE_UNMAPPED] =
1725 g_signal_new ("unmapped",
1726 G_TYPE_FROM_CLASS (object_class),
1727 G_SIGNAL_RUN_LAST,
1728 0, NULL, NULL,
1729 g_cclosure_marshal_VOID__VOID,
1730 G_TYPE_NONE, 0);
1731
1732 surface_signals[SURFACE_CONFIGURE] =
1733 g_signal_new ("configure",
1734 G_TYPE_FROM_CLASS (object_class),
1735 G_SIGNAL_RUN_LAST,
1736 0, NULL, NULL,
1737 g_cclosure_marshal_VOID__VOID,
1738 G_TYPE_NONE, 0);
1739
1740 surface_signals[SURFACE_SHORTCUTS_INHIBITED] =
1741 g_signal_new ("shortcuts-inhibited",
1742 G_TYPE_FROM_CLASS (object_class),
1743 G_SIGNAL_RUN_LAST,
1744 0, NULL, NULL,
1745 g_cclosure_marshal_VOID__VOID,
1746 G_TYPE_NONE, 0);
1747
1748 surface_signals[SURFACE_SHORTCUTS_RESTORED] =
1749 g_signal_new ("shortcuts-restored",
1750 G_TYPE_FROM_CLASS (object_class),
1751 G_SIGNAL_RUN_LAST,
1752 0, NULL, NULL,
1753 g_cclosure_marshal_VOID__VOID,
1754 G_TYPE_NONE, 0);
1755 surface_signals[SURFACE_GEOMETRY_CHANGED] =
1756 g_signal_new ("geometry-changed",
1757 G_TYPE_FROM_CLASS (object_class),
1758 G_SIGNAL_RUN_LAST,
1759 0, NULL, NULL,
1760 g_cclosure_marshal_VOID__VOID,
1761 G_TYPE_NONE, 0);
1762 surface_signals[SURFACE_PRE_STATE_APPLIED] =
1763 g_signal_new ("pre-state-applied",
1764 G_TYPE_FROM_CLASS (object_class),
1765 G_SIGNAL_RUN_LAST,
1766 0, NULL, NULL,
1767 g_cclosure_marshal_VOID__VOID,
1768 G_TYPE_NONE, 0);
1769 }
1770
1771 static void
meta_wayland_surface_role_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1772 meta_wayland_surface_role_set_property (GObject *object,
1773 guint prop_id,
1774 const GValue *value,
1775 GParamSpec *pspec)
1776 {
1777 MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (object);
1778 MetaWaylandSurfaceRolePrivate *priv =
1779 meta_wayland_surface_role_get_instance_private (surface_role);
1780
1781 switch (prop_id)
1782 {
1783 case SURFACE_ROLE_PROP_SURFACE:
1784 priv->surface = g_value_get_object (value);
1785 break;
1786
1787 default:
1788 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1789 }
1790 }
1791
1792 static void
meta_wayland_surface_role_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1793 meta_wayland_surface_role_get_property (GObject *object,
1794 guint prop_id,
1795 GValue *value,
1796 GParamSpec *pspec)
1797 {
1798 MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (object);
1799 MetaWaylandSurfaceRolePrivate *priv =
1800 meta_wayland_surface_role_get_instance_private (surface_role);
1801
1802 switch (prop_id)
1803 {
1804 case SURFACE_ROLE_PROP_SURFACE:
1805 g_value_set_object (value, priv->surface);
1806 break;
1807
1808 default:
1809 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1810 }
1811 }
1812
1813 static void
meta_wayland_surface_role_init(MetaWaylandSurfaceRole * role)1814 meta_wayland_surface_role_init (MetaWaylandSurfaceRole *role)
1815 {
1816 }
1817
1818 static void
meta_wayland_surface_role_class_init(MetaWaylandSurfaceRoleClass * klass)1819 meta_wayland_surface_role_class_init (MetaWaylandSurfaceRoleClass *klass)
1820 {
1821 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1822
1823 object_class->set_property = meta_wayland_surface_role_set_property;
1824 object_class->get_property = meta_wayland_surface_role_get_property;
1825
1826 g_object_class_install_property (object_class,
1827 SURFACE_ROLE_PROP_SURFACE,
1828 g_param_spec_object ("surface",
1829 "MetaWaylandSurface",
1830 "The MetaWaylandSurface instance",
1831 META_TYPE_WAYLAND_SURFACE,
1832 G_PARAM_READWRITE |
1833 G_PARAM_CONSTRUCT_ONLY |
1834 G_PARAM_STATIC_STRINGS));
1835 }
1836
1837 static void
meta_wayland_surface_role_assigned(MetaWaylandSurfaceRole * surface_role)1838 meta_wayland_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
1839 {
1840 META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->assigned (surface_role);
1841 }
1842
1843 static void
meta_wayland_surface_role_pre_apply_state(MetaWaylandSurfaceRole * surface_role,MetaWaylandSurfaceState * pending)1844 meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role,
1845 MetaWaylandSurfaceState *pending)
1846 {
1847 MetaWaylandSurfaceRoleClass *klass;
1848
1849 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1850 if (klass->pre_apply_state)
1851 klass->pre_apply_state (surface_role, pending);
1852 }
1853
1854 static void
meta_wayland_surface_role_post_apply_state(MetaWaylandSurfaceRole * surface_role,MetaWaylandSurfaceState * pending)1855 meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
1856 MetaWaylandSurfaceState *pending)
1857 {
1858 MetaWaylandSurfaceRoleClass *klass;
1859
1860 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1861 if (klass->post_apply_state)
1862 klass->post_apply_state (surface_role, pending);
1863 }
1864
1865 static void
meta_wayland_surface_role_apply_state(MetaWaylandSurfaceRole * surface_role,MetaWaylandSurfaceState * pending)1866 meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
1867 MetaWaylandSurfaceState *pending)
1868 {
1869 META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role)->apply_state (surface_role,
1870 pending);
1871 }
1872
1873 static gboolean
meta_wayland_surface_role_is_on_logical_monitor(MetaWaylandSurfaceRole * surface_role,MetaLogicalMonitor * logical_monitor)1874 meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
1875 MetaLogicalMonitor *logical_monitor)
1876 {
1877 MetaWaylandSurfaceRoleClass *klass;
1878
1879 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1880 if (klass->is_on_logical_monitor)
1881 return klass->is_on_logical_monitor (surface_role, logical_monitor);
1882 else
1883 return FALSE;
1884 }
1885
1886 static MetaWaylandSurface *
meta_wayland_surface_role_get_toplevel(MetaWaylandSurfaceRole * surface_role)1887 meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
1888 {
1889 MetaWaylandSurfaceRoleClass *klass;
1890
1891 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1892 if (klass->get_toplevel)
1893 return klass->get_toplevel (surface_role);
1894 else
1895 return NULL;
1896 }
1897
1898 static MetaWindow *
meta_wayland_surface_role_get_window(MetaWaylandSurfaceRole * surface_role)1899 meta_wayland_surface_role_get_window (MetaWaylandSurfaceRole *surface_role)
1900 {
1901 MetaWaylandSurfaceRoleClass *klass;
1902
1903 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1904
1905 if (klass->get_window)
1906 return klass->get_window (surface_role);
1907 else
1908 return NULL;
1909 }
1910
1911 MetaWindow *
meta_wayland_surface_get_window(MetaWaylandSurface * surface)1912 meta_wayland_surface_get_window (MetaWaylandSurface *surface)
1913 {
1914 if (!surface->role)
1915 return NULL;
1916
1917 return meta_wayland_surface_role_get_window (surface->role);
1918 }
1919
1920 static gboolean
meta_wayland_surface_role_should_cache_state(MetaWaylandSurfaceRole * surface_role)1921 meta_wayland_surface_role_should_cache_state (MetaWaylandSurfaceRole *surface_role)
1922 {
1923 MetaWaylandSurfaceRoleClass *klass;
1924
1925 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1926 if (klass->should_cache_state)
1927 return klass->should_cache_state (surface_role);
1928 else
1929 return FALSE;
1930 }
1931
1932 gboolean
meta_wayland_surface_should_cache_state(MetaWaylandSurface * surface)1933 meta_wayland_surface_should_cache_state (MetaWaylandSurface *surface)
1934 {
1935 if (!surface->role)
1936 return FALSE;
1937
1938 return meta_wayland_surface_role_should_cache_state (surface->role);
1939 }
1940
1941 static void
meta_wayland_surface_role_notify_subsurface_state_changed(MetaWaylandSurfaceRole * surface_role)1942 meta_wayland_surface_role_notify_subsurface_state_changed (MetaWaylandSurfaceRole *surface_role)
1943 {
1944 MetaWaylandSurfaceRoleClass *klass;
1945
1946 klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
1947 g_return_if_fail (klass->notify_subsurface_state_changed);
1948
1949 klass->notify_subsurface_state_changed (surface_role);
1950 }
1951
1952 void
meta_wayland_surface_notify_subsurface_state_changed(MetaWaylandSurface * surface)1953 meta_wayland_surface_notify_subsurface_state_changed (MetaWaylandSurface *surface)
1954 {
1955 if (surface->role)
1956 meta_wayland_surface_role_notify_subsurface_state_changed (surface->role);
1957 }
1958
1959 MetaWaylandSurface *
meta_wayland_surface_role_get_surface(MetaWaylandSurfaceRole * role)1960 meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
1961 {
1962 MetaWaylandSurfaceRolePrivate *priv =
1963 meta_wayland_surface_role_get_instance_private (role);
1964
1965 return priv->surface;
1966 }
1967
1968 cairo_region_t *
meta_wayland_surface_calculate_input_region(MetaWaylandSurface * surface)1969 meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface)
1970 {
1971 cairo_region_t *region;
1972 cairo_rectangle_int_t buffer_rect;
1973
1974 if (!surface->buffer_ref->buffer)
1975 return NULL;
1976
1977 buffer_rect = (cairo_rectangle_int_t) {
1978 .width = meta_wayland_surface_get_width (surface),
1979 .height = meta_wayland_surface_get_height (surface),
1980 };
1981 region = cairo_region_create_rectangle (&buffer_rect);
1982
1983 if (surface->input_region)
1984 cairo_region_intersect (region, surface->input_region);
1985
1986 return region;
1987 }
1988
1989 void
meta_wayland_surface_inhibit_shortcuts(MetaWaylandSurface * surface,MetaWaylandSeat * seat)1990 meta_wayland_surface_inhibit_shortcuts (MetaWaylandSurface *surface,
1991 MetaWaylandSeat *seat)
1992 {
1993 g_hash_table_add (surface->shortcut_inhibited_seats, seat);
1994 g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_INHIBITED], 0);
1995 }
1996
1997 void
meta_wayland_surface_restore_shortcuts(MetaWaylandSurface * surface,MetaWaylandSeat * seat)1998 meta_wayland_surface_restore_shortcuts (MetaWaylandSurface *surface,
1999 MetaWaylandSeat *seat)
2000 {
2001 g_signal_emit (surface, surface_signals[SURFACE_SHORTCUTS_RESTORED], 0);
2002 g_hash_table_remove (surface->shortcut_inhibited_seats, seat);
2003 }
2004
2005 gboolean
meta_wayland_surface_is_shortcuts_inhibited(MetaWaylandSurface * surface,MetaWaylandSeat * seat)2006 meta_wayland_surface_is_shortcuts_inhibited (MetaWaylandSurface *surface,
2007 MetaWaylandSeat *seat)
2008 {
2009 if (surface->shortcut_inhibited_seats == NULL)
2010 return FALSE;
2011
2012 return g_hash_table_contains (surface->shortcut_inhibited_seats, seat);
2013 }
2014
2015 CoglTexture *
meta_wayland_surface_get_texture(MetaWaylandSurface * surface)2016 meta_wayland_surface_get_texture (MetaWaylandSurface *surface)
2017 {
2018 return surface->texture;
2019 }
2020
2021 MetaSurfaceActor *
meta_wayland_surface_get_actor(MetaWaylandSurface * surface)2022 meta_wayland_surface_get_actor (MetaWaylandSurface *surface)
2023 {
2024 if (!surface->role || !META_IS_WAYLAND_ACTOR_SURFACE (surface->role))
2025 return NULL;
2026
2027 return meta_wayland_actor_surface_get_actor (META_WAYLAND_ACTOR_SURFACE (surface->role));
2028 }
2029
2030 void
meta_wayland_surface_notify_geometry_changed(MetaWaylandSurface * surface)2031 meta_wayland_surface_notify_geometry_changed (MetaWaylandSurface *surface)
2032 {
2033 g_signal_emit (surface, surface_signals[SURFACE_GEOMETRY_CHANGED], 0);
2034 }
2035
2036 int
meta_wayland_surface_get_width(MetaWaylandSurface * surface)2037 meta_wayland_surface_get_width (MetaWaylandSurface *surface)
2038 {
2039 if (surface->viewport.has_dst_size)
2040 {
2041 return surface->viewport.dst_width;
2042 }
2043 else if (surface->viewport.has_src_rect)
2044 {
2045 return ceilf (surface->viewport.src_rect.size.width);
2046 }
2047 else
2048 {
2049 int width;
2050
2051 if (meta_monitor_transform_is_rotated (surface->buffer_transform))
2052 width = get_buffer_height (surface);
2053 else
2054 width = get_buffer_width (surface);
2055
2056 return width / surface->scale;
2057 }
2058 }
2059
2060 int
meta_wayland_surface_get_height(MetaWaylandSurface * surface)2061 meta_wayland_surface_get_height (MetaWaylandSurface *surface)
2062 {
2063 if (surface->viewport.has_dst_size)
2064 {
2065 return surface->viewport.dst_height;
2066 }
2067 else if (surface->viewport.has_src_rect)
2068 {
2069 return ceilf (surface->viewport.src_rect.size.height);
2070 }
2071 else
2072 {
2073 int height;
2074
2075 if (meta_monitor_transform_is_rotated (surface->buffer_transform))
2076 height = get_buffer_width (surface);
2077 else
2078 height = get_buffer_height (surface);
2079
2080 return height / surface->scale;
2081 }
2082 }
2083
2084 static void
scanout_destroyed(gpointer data,GObject * where_the_object_was)2085 scanout_destroyed (gpointer data,
2086 GObject *where_the_object_was)
2087 {
2088 MetaWaylandBufferRef *buffer_ref = data;
2089
2090 meta_wayland_buffer_ref_dec_use_count (buffer_ref);
2091 meta_wayland_buffer_ref_unref (buffer_ref);
2092 }
2093
2094 CoglScanout *
meta_wayland_surface_try_acquire_scanout(MetaWaylandSurface * surface,CoglOnscreen * onscreen)2095 meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
2096 CoglOnscreen *onscreen)
2097 {
2098 CoglScanout *scanout;
2099 MetaWaylandBufferRef *buffer_ref;
2100
2101 if (!surface->buffer_ref->buffer)
2102 return NULL;
2103
2104 if (surface->buffer_ref->use_count == 0)
2105 return NULL;
2106
2107 scanout = meta_wayland_buffer_try_acquire_scanout (surface->buffer_ref->buffer,
2108 onscreen);
2109 if (!scanout)
2110 return NULL;
2111
2112 buffer_ref = meta_wayland_buffer_ref_ref (surface->buffer_ref);
2113 meta_wayland_buffer_ref_inc_use_count (buffer_ref);
2114 g_object_weak_ref (G_OBJECT (scanout), scanout_destroyed, buffer_ref);
2115
2116 return scanout;
2117 }
2118