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