summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Antognolli <rafael.antognolli@intel.com>2013-10-10 15:21:06 -0300
committerRafael Antognolli <rafael.antognolli@intel.com>2013-10-10 15:21:06 -0300
commitf7a43e9dbc276881f24ece012fe5c4ce4f9927db (patch)
tree2621c4071b2f5b556a09e564947a20aafa89f3e6
parent2c1c6b9335e38c6e52b06829a95d9b58d780c99e (diff)
parentf2d1a211472e2779969ead8d6331fd3d13230946 (diff)
Merge branch 'subsurfaces'
-rw-r--r--configure.ac1
-rw-r--r--data/ecore/ecore_wayland/protocol/subsurface.xml244
-rw-r--r--src/Makefile_Ecore_Wayland.am20
-rw-r--r--src/lib/ecore_wayland/.gitignore2
-rw-r--r--src/lib/ecore_wayland/Ecore_Wayland.h92
-rw-r--r--src/lib/ecore_wayland/ecore_wl.c8
-rw-r--r--src/lib/ecore_wayland/ecore_wl_private.h2
-rw-r--r--src/lib/ecore_wayland/ecore_wl_subsurf.c191
-rw-r--r--src/lib/ecore_wayland/ecore_wl_window.c2
9 files changed, 562 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index d5a359e39c..e9efd1fb99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1007,6 +1007,7 @@ AC_ARG_ENABLE([wayland],
1007 1007
1008if test "${want_wayland}" = "yes"; then 1008if test "${want_wayland}" = "yes"; then
1009 EFL_PKG_CHECK_STRICT([wayland-client]) 1009 EFL_PKG_CHECK_STRICT([wayland-client])
1010 AC_PATH_PROG([wayland_scanner], [wayland-scanner], [AC_MSG_ERROR("wayland-scanner is needed to compile ecore_wayland protocol")])
1010fi 1011fi
1011 1012
1012# Fb 1013# Fb
diff --git a/data/ecore/ecore_wayland/protocol/subsurface.xml b/data/ecore/ecore_wayland/protocol/subsurface.xml
new file mode 100644
index 0000000000..9e4a658d6e
--- /dev/null
+++ b/data/ecore/ecore_wayland/protocol/subsurface.xml
@@ -0,0 +1,244 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<protocol name="subsurface">
3
4 <copyright>
5 Copyright © 2012-2013 Collabora, Ltd.
6
7 Permission to use, copy, modify, distribute, and sell this
8 software and its documentation for any purpose is hereby granted
9 without fee, provided that the above copyright notice appear in
10 all copies and that both that copyright notice and this permission
11 notice appear in supporting documentation, and that the name of
12 the copyright holders not be used in advertising or publicity
13 pertaining to distribution of the software without specific,
14 written prior permission. The copyright holders make no
15 representations about the suitability of this software for any
16 purpose. It is provided "as is" without express or implied
17 warranty.
18
19 THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
20 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
24 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
26 THIS SOFTWARE.
27 </copyright>
28
29 <interface name="wl_subcompositor" version="1">
30 <description summary="sub-surface compositing">
31 The global interface exposing sub-surface compositing capabilities.
32 A wl_surface, that has sub-surfaces associated, is called the
33 parent surface. Sub-surfaces can be arbitrarily nested and create
34 a tree of sub-surfaces.
35
36 The root surface in a tree of sub-surfaces is the main
37 surface. The main surface cannot be a sub-surface, because
38 sub-surfaces must always have a parent.
39
40 A main surface with its sub-surfaces forms a (compound) window.
41 For window management purposes, this set of wl_surface objects is
42 to be considered as a single window, and it should also behave as
43 such.
44
45 The aim of sub-surfaces is to offload some of the compositing work
46 within a window from clients to the compositor. A prime example is
47 a video player with decorations and video in separate wl_surface
48 objects. This should allow the compositor to pass YUV video buffer
49 processing to dedicated overlay hardware when possible.
50 </description>
51
52 <request name="destroy" type="destructor">
53 <description summary="unbind from the subcompositor interface">
54 Informs the server that the client will not be using this
55 protocol object anymore. This does not affect any other
56 objects, wl_subsurface objects included.
57 </description>
58 </request>
59
60 <enum name="error">
61 <entry name="bad_surface" value="0"
62 summary="the to-be sub-surface is invalid"/>
63 </enum>
64
65 <request name="get_subsurface">
66 <description summary="give a surface the role sub-surface">
67 Create a sub-surface interface for the given surface, and
68 associate it with the given parent surface. This turns a
69 plain wl_surface into a sub-surface.
70
71 The to-be sub-surface must not already have a dedicated
72 purpose, like any shell surface type, cursor image, drag icon,
73 or sub-surface. Otherwise a protocol error is raised.
74 </description>
75
76 <arg name="id" type="new_id" interface="wl_subsurface"
77 summary="the new subsurface object id"/>
78 <arg name="surface" type="object" interface="wl_surface"
79 summary="the surface to be turned into a sub-surface"/>
80 <arg name="parent" type="object" interface="wl_surface"
81 summary="the parent surface"/>
82 </request>
83 </interface>
84
85 <interface name="wl_subsurface" version="1">
86 <description summary="sub-surface interface to a wl_surface">
87 An additional interface to a wl_surface object, which has been
88 made a sub-surface. A sub-surface has one parent surface. A
89 sub-surface's size and position are not limited to that of the parent.
90 Particularly, a sub-surface is not automatically clipped to its
91 parent's area.
92
93 A sub-surface becomes mapped, when a non-NULL wl_buffer is applied
94 and the parent surface is mapped. The order of which one happens
95 first is irrelevant. A sub-surface is hidden if the parent becomes
96 hidden, or if a NULL wl_buffer is applied. These rules apply
97 recursively through the tree of surfaces.
98
99 The behaviour of wl_surface.commit request on a sub-surface
100 depends on the sub-surface's mode. The possible modes are
101 synchronized and desynchronized, see methods
102 wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized
103 mode caches the wl_surface state to be applied when the parent's
104 state gets applied, and desynchronized mode applies the pending
105 wl_surface state directly. A sub-surface is initially in the
106 synchronized mode.
107
108 Sub-surfaces have also other kind of state, which is managed by
109 wl_subsurface requests, as opposed to wl_surface requests. This
110 state includes the sub-surface position relative to the parent
111 surface (wl_subsurface.set_position), and the stacking order of
112 the parent and its sub-surfaces (wl_subsurface.place_above and
113 .place_below). This state is applied when the parent surface's
114 wl_surface state is applied, regardless of the sub-surface's mode.
115 As the exception, set_sync and set_desync are effective immediately.
116
117 The main surface can be thought to be always in desynchronized mode,
118 since it does not have a parent in the sub-surfaces sense.
119
120 Even if a sub-surface is in desynchronized mode, it will behave as
121 in synchronized mode, if its parent surface behaves as in
122 synchronized mode. This rule is applied recursively throughout the
123 tree of surfaces. This means, that one can set a sub-surface into
124 synchronized mode, and then assume that all its child and grand-child
125 sub-surfaces are synchronized, too, without explicitly setting them.
126
127 If the wl_surface associated with the wl_subsurface is destroyed, the
128 wl_subsurface object becomes inert. Note, that destroying either object
129 takes effect immediately. If you need to synchronize the removal
130 of a sub-surface to the parent surface update, unmap the sub-surface
131 first by attaching a NULL wl_buffer, update parent, and then destroy
132 the sub-surface.
133
134 If the parent wl_surface object is destroyed, the sub-surface is
135 unmapped.
136 </description>
137
138 <request name="destroy" type="destructor">
139 <description summary="remove sub-surface interface">
140 The sub-surface interface is removed from the wl_surface object
141 that was turned into a sub-surface with
142 wl_subcompositor.get_subsurface request. The wl_surface's association
143 to the parent is deleted, and the wl_surface loses its role as
144 a sub-surface. The wl_surface is unmapped.
145 </description>
146 </request>
147
148 <enum name="error">
149 <entry name="bad_surface" value="0"
150 summary="wl_surface is not a sibling or the parent"/>
151 </enum>
152
153 <request name="set_position">
154 <description summary="reposition the sub-surface">
155 This schedules a sub-surface position change.
156 The sub-surface will be moved so, that its origin (top-left
157 corner pixel) will be at the location x, y of the parent surface
158 coordinate system. The coordinates are not restricted to the parent
159 surface area. Negative values are allowed.
160
161 The next wl_surface.commit on the parent surface will reset
162 the sub-surface's position to the scheduled coordinates.
163
164 The initial position is 0, 0.
165 </description>
166
167 <arg name="x" type="int" summary="coordinate in the parent surface"/>
168 <arg name="y" type="int" summary="coordinate in the parent surface"/>
169 </request>
170
171 <request name="place_above">
172 <description summary="restack the sub-surface">
173 This sub-surface is taken from the stack, and put back just
174 above the reference surface, changing the z-order of the sub-surfaces.
175 The reference surface must be one of the sibling surfaces, or the
176 parent surface. Using any other surface, including this sub-surface,
177 will cause a protocol error.
178
179 The z-order is double-buffered state, and will be applied on the
180 next commit of the parent surface.
181 See wl_surface.commit and wl_subcompositor.get_subsurface.
182
183 A new sub-surface is initially added as the top-most in the stack
184 of its siblings and parent.
185 </description>
186
187 <arg name="sibling" type="object" interface="wl_surface"
188 summary="the reference surface"/>
189 </request>
190
191 <request name="place_below">
192 <description summary="restack the sub-surface">
193 The sub-surface is placed just below of the reference surface.
194 See wl_subsurface.place_above.
195 </description>
196
197 <arg name="sibling" type="object" interface="wl_surface"
198 summary="the reference surface"/>
199 </request>
200
201 <request name="set_sync">
202 <description summary="set sub-surface to synchronized mode">
203 Change the commit behaviour of the sub-surface to synchronized
204 mode, also described as the parent dependant mode.
205
206 In synchronized mode, wl_surface.commit on a sub-surface will
207 accumulate the committed state in a cache, but the state will
208 not be applied and hence will not change the compositor output.
209 The cached state is applied to the sub-surface immediately after
210 the parent surface's state is applied. This ensures atomic
211 updates of the parent and all its synchronized sub-surfaces.
212 Applying the cached state will invalidate the cache, so further
213 parent surface commits do not (re-)apply old state.
214
215 See wl_subsurface for the recursive effect of this mode.
216 </description>
217 </request>
218
219 <request name="set_desync">
220 <description summary="set sub-surface to desynchronized mode">
221 Change the commit behaviour of the sub-surface to desynchronized
222 mode, also described as independent or freely running mode.
223
224 In desynchronized mode, wl_surface.commit on a sub-surface will
225 apply the pending state directly, without caching, as happens
226 normally with a wl_surface. Calling wl_surface.commit on the
227 parent surface has no effect on the sub-surface's wl_surface
228 state. This mode allows a sub-surface to be updated on its own.
229
230 If cached state exists when wl_surface.commit is called in
231 desynchronized mode, the pending state is added to the cached
232 state, and applied as whole. This invalidates the cache.
233
234 Note: even if a sub-surface is set to desynchronized, a parent
235 sub-surface may override it to behave as synchronized. For details,
236 see wl_subsurface.
237
238 If a surface's parent surface behaves as desynchronized, then
239 the cached state is applied on set_desync.
240 </description>
241 </request>
242
243 </interface>
244</protocol>
diff --git a/src/Makefile_Ecore_Wayland.am b/src/Makefile_Ecore_Wayland.am
index aaf08f50f0..b2c66a19cb 100644
--- a/src/Makefile_Ecore_Wayland.am
+++ b/src/Makefile_Ecore_Wayland.am
@@ -14,10 +14,30 @@ lib/ecore_wayland/ecore_wl_dnd.c \
14lib/ecore_wayland/ecore_wl_input.c \ 14lib/ecore_wayland/ecore_wl_input.c \
15lib/ecore_wayland/ecore_wl_output.c \ 15lib/ecore_wayland/ecore_wl_output.c \
16lib/ecore_wayland/ecore_wl_window.c \ 16lib/ecore_wayland/ecore_wl_window.c \
17lib/ecore_wayland/ecore_wl_subsurf.c \
17lib/ecore_wayland/ecore_wl_private.h 18lib/ecore_wayland/ecore_wl_private.h
18 19
20lib_ecore_wayland_libecore_wayland_la_BUILT_SOURCES = \
21lib/ecore_wayland/subsurface-protocol.c \
22lib/ecore_wayland/subsurface-client-protocol.h
23
24CLEANFILES += $(lib_ecore_wayland_libecore_wayland_la_BUILT_SOURCES)
25
26lib_ecore_wayland_libecore_wayland_la_SOURCES += $(lib_ecore_wayland_libecore_wayland_la_BUILT_SOURCES)
27
28BUILT_SOURCES += $(lib_ecore_wayland_libecore_wayland_la_BUILT_SOURCES)
29
19lib_ecore_wayland_libecore_wayland_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WAYLAND_CFLAGS@ 30lib_ecore_wayland_libecore_wayland_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WAYLAND_CFLAGS@
20lib_ecore_wayland_libecore_wayland_la_LIBADD = @ECORE_WAYLAND_LIBS@ 31lib_ecore_wayland_libecore_wayland_la_LIBADD = @ECORE_WAYLAND_LIBS@
21lib_ecore_wayland_libecore_wayland_la_DEPENDENCIES = @ECORE_WAYLAND_INTERNAL_LIBS@ 32lib_ecore_wayland_libecore_wayland_la_DEPENDENCIES = @ECORE_WAYLAND_INTERNAL_LIBS@
22lib_ecore_wayland_libecore_wayland_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ 33lib_ecore_wayland_libecore_wayland_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
34
35wayland_protocoldir = $(top_srcdir)/data/ecore/ecore_wayland/protocol
36
37lib/ecore_wayland/subsurface-protocol.c: $(wayland_protocoldir)/subsurface.xml
38 $(AM_V_GEN)$(wayland_scanner) code < $< > $@
39
40lib/ecore_wayland/subsurface-client-protocol.h: $(wayland_protocoldir)/subsurface.xml
41 $(AM_V_GEN)$(wayland_scanner) client-header < $< > $@
42
23endif 43endif
diff --git a/src/lib/ecore_wayland/.gitignore b/src/lib/ecore_wayland/.gitignore
new file mode 100644
index 0000000000..ce73befd85
--- /dev/null
+++ b/src/lib/ecore_wayland/.gitignore
@@ -0,0 +1,2 @@
1subsurface-protocol.c
2subsurface-client-protocol.h
diff --git a/src/lib/ecore_wayland/Ecore_Wayland.h b/src/lib/ecore_wayland/Ecore_Wayland.h
index 05ceb00daf..30545b7343 100644
--- a/src/lib/ecore_wayland/Ecore_Wayland.h
+++ b/src/lib/ecore_wayland/Ecore_Wayland.h
@@ -35,6 +35,7 @@ typedef struct _Ecore_Wl_Display Ecore_Wl_Display;
35typedef struct _Ecore_Wl_Output Ecore_Wl_Output; 35typedef struct _Ecore_Wl_Output Ecore_Wl_Output;
36typedef struct _Ecore_Wl_Input Ecore_Wl_Input; 36typedef struct _Ecore_Wl_Input Ecore_Wl_Input;
37typedef struct _Ecore_Wl_Global Ecore_Wl_Global; /** @since 1.7.6 */ 37typedef struct _Ecore_Wl_Global Ecore_Wl_Global; /** @since 1.7.6 */
38typedef struct _Ecore_Wl_Subsurf Ecore_Wl_Subsurf; /** @since 1.8 */
38 39
39# ifndef _ECORE_WAYLAND_WINDOW_PREDEF 40# ifndef _ECORE_WAYLAND_WINDOW_PREDEF
40typedef struct _Ecore_Wl_Window Ecore_Wl_Window; 41typedef struct _Ecore_Wl_Window Ecore_Wl_Window;
@@ -101,6 +102,7 @@ struct _Ecore_Wl_Display
101 struct wl_display *display; 102 struct wl_display *display;
102 struct wl_registry *registry; 103 struct wl_registry *registry;
103 struct wl_compositor *compositor; 104 struct wl_compositor *compositor;
105 struct wl_subcompositor *subcompositor;
104 struct wl_shell *shell; 106 struct wl_shell *shell;
105 struct wl_shell *desktop_shell; 107 struct wl_shell *desktop_shell;
106 struct wl_shm *shm; 108 struct wl_shm *shm;
@@ -251,6 +253,8 @@ struct _Ecore_Wl_Window
251 /* FIXME: Ideally we should record the cursor name for this window 253 /* FIXME: Ideally we should record the cursor name for this window
252 * so we can compare and avoid unnecessary cursor set calls to wayland */ 254 * so we can compare and avoid unnecessary cursor set calls to wayland */
253 255
256 Ecore_Wl_Subsurf *subsurfs;
257
254 void *data; 258 void *data;
255}; 259};
256 260
@@ -381,6 +385,7 @@ struct _Ecore_Wl_Event_Interfaces_Bound
381 * @li @ref Ecore_Wl_Window_Group 385 * @li @ref Ecore_Wl_Window_Group
382 * @li @ref Ecore_Wl_Input_Group 386 * @li @ref Ecore_Wl_Input_Group
383 * @li @ref Ecore_Wl_Dnd_Group 387 * @li @ref Ecore_Wl_Dnd_Group
388 * @li @ref Ecore_Wl_Subsurf
384 */ 389 */
385 390
386EAPI extern int ECORE_WL_EVENT_MOUSE_IN; 391EAPI extern int ECORE_WL_EVENT_MOUSE_IN;
@@ -864,6 +869,93 @@ EAPI struct wl_array *ecore_wl_dnd_drag_types_get(Ecore_Wl_Input *input);
864 869
865EAPI void ecore_wl_server_mode_set(Eina_Bool on); 870EAPI void ecore_wl_server_mode_set(Eina_Bool on);
866 871
872/**
873 * @defgroup Ecore_Wl_Subsurf Functions to manipulate subsurfaces.
874 * @ingroup Ecore_Wl_Group
875 *
876 * Functions to manipulate wayland subsurfaces, using Ecore_Wl_Subsurf.
877 *
878 * This API is intended to expose Wayland subsurface functionality, although it
879 * should not be necessary for most applications to use it, as soon as we have
880 * means to make Evas automatically switch Evas images to use subsurfaces.
881 *
882 * It can/should be used, for instance, when subsurfaces are needed to be not
883 * in sync with the main window surface.
884 */
885
886/**
887 * Create and return a new subsurface.
888 *
889 * Create a new surface (and subsurface interface), with the parent surface
890 * being the one associated with the given @param win.
891 *
892 * The @param win must be visible, otherwise there will be no surface created
893 * for it yet.
894 *
895 * @ingroup Ecore_Wl_Subsurf
896 * @since 1.8
897 */
898EAPI Ecore_Wl_Subsurf *ecore_wl_subsurf_create(Ecore_Wl_Window *win);
899
900/**
901 * Destroy the given subsurface, as well as the surface associated with it.
902 *
903 * @ingroup Ecore_Wl_Subsurf
904 * @since 1.8
905 */
906EAPI void ecore_wl_subsurf_del(Ecore_Wl_Subsurf *ess);
907
908/**
909 * Return the wl_surface associated with this subsurface.
910 *
911 * @ingroup Ecore_Wl_Subsurf
912 * @since 1.8
913 */
914EAPI struct wl_surface *ecore_wl_subsurf_surface_get(Ecore_Wl_Subsurf *ess);
915
916/**
917 * Set the position of this subsurface, relative to its parent surface.
918 *
919 * @ingroup Ecore_Wl_Subsurf
920 * @since 1.8
921 */
922EAPI void ecore_wl_subsurf_position_set(Ecore_Wl_Subsurf *ess, int x, int y);
923
924/**
925 * Get the position of this subsurface, relative to its parent surface.
926 *
927 * @ingroup Ecore_Wl_Subsurf
928 * @since 1.8
929 */
930EAPI void ecore_wl_subsurf_position_get(Ecore_Wl_Subsurf *ess, int *x, int *y);
931
932/**
933 * @ingroup Ecore_Wl_Subsurf
934 * @since 1.8
935 */
936EAPI void ecore_wl_subsurf_place_above(Ecore_Wl_Subsurf *ess, struct wl_surface *surface);
937
938/**
939 * @ingroup Ecore_Wl_Subsurf
940 * @since 1.8
941 */
942EAPI void ecore_wl_subsurf_place_below(Ecore_Wl_Subsurf *ess, struct wl_surface *surface);
943
944/**
945 * @ingroup Ecore_Wl_Subsurf
946 * @since 1.8
947 */
948EAPI void ecore_wl_subsurf_sync_set(Ecore_Wl_Subsurf *ess, Eina_Bool val);
949
950/**
951 * Set an opaque region for the given subsurface.
952 *
953 * Use a 0x0 region size to unset the opaque region.
954 *
955 * @ingroup Ecore_Wl_Subsurf
956 * @since 1.8
957 */
958EAPI void ecore_wl_subsurf_opaque_region_set(Ecore_Wl_Subsurf *ess, int x, int y, int w, int h);
867#ifdef __cplusplus 959#ifdef __cplusplus
868} 960}
869#endif 961#endif
diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c
index acce7282fb..ee614e0e4b 100644
--- a/src/lib/ecore_wayland/ecore_wl.c
+++ b/src/lib/ecore_wayland/ecore_wl.c
@@ -4,6 +4,7 @@
4 4
5#include <fcntl.h> 5#include <fcntl.h>
6#include "ecore_wl_private.h" 6#include "ecore_wl_private.h"
7#include <subsurface-client-protocol.h>
7 8
8/* local function prototypes */ 9/* local function prototypes */
9static Eina_Bool _ecore_wl_shutdown(Eina_Bool close); 10static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
@@ -397,6 +398,8 @@ _ecore_wl_shutdown(Eina_Bool close)
397 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager); 398 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
398 if (_ecore_wl_disp->wl.compositor) 399 if (_ecore_wl_disp->wl.compositor)
399 wl_compositor_destroy(_ecore_wl_disp->wl.compositor); 400 wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
401 if (_ecore_wl_disp->wl.subcompositor)
402 wl_subcompositor_destroy(_ecore_wl_disp->wl.subcompositor);
400 if (_ecore_wl_disp->wl.display) 403 if (_ecore_wl_disp->wl.display)
401 { 404 {
402 wl_registry_destroy(_ecore_wl_disp->wl.registry); 405 wl_registry_destroy(_ecore_wl_disp->wl.registry);
@@ -515,6 +518,11 @@ _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned in
515 ewd->wl.compositor = 518 ewd->wl.compositor =
516 wl_registry_bind(registry, id, &wl_compositor_interface, 3); 519 wl_registry_bind(registry, id, &wl_compositor_interface, 3);
517 } 520 }
521 else if (!strcmp(interface, "wl_subcompositor"))
522 {
523 ewd->wl.subcompositor =
524 wl_registry_bind(registry, id, &wl_subcompositor_interface, 1);
525 }
518 else if (!strcmp(interface, "wl_output")) 526 else if (!strcmp(interface, "wl_output"))
519 _ecore_wl_output_add(ewd, id); 527 _ecore_wl_output_add(ewd, id);
520 else if (!strcmp(interface, "wl_seat")) 528 else if (!strcmp(interface, "wl_seat"))
diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h
index dc034af8d8..b83aae38eb 100644
--- a/src/lib/ecore_wayland/ecore_wl_private.h
+++ b/src/lib/ecore_wayland/ecore_wl_private.h
@@ -95,4 +95,6 @@ void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source);
95void _ecore_wl_events_init(void); 95void _ecore_wl_events_init(void);
96void _ecore_wl_events_shutdown(void); 96void _ecore_wl_events_shutdown(void);
97 97
98void _ecore_wl_subsurfs_del_all(Ecore_Wl_Window *win);
99
98#endif 100#endif
diff --git a/src/lib/ecore_wayland/ecore_wl_subsurf.c b/src/lib/ecore_wayland/ecore_wl_subsurf.c
new file mode 100644
index 0000000000..4e144fa084
--- /dev/null
+++ b/src/lib/ecore_wayland/ecore_wl_subsurf.c
@@ -0,0 +1,191 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecore_wl_private.h"
6#include <subsurface-client-protocol.h>
7
8struct _Ecore_Wl_Subsurf
9{
10 EINA_INLIST;
11 Ecore_Wl_Window *parent_win;
12 struct wl_surface *surface;
13 struct wl_subsurface *subsurface;
14
15 int x, y;
16
17 Eina_Bool sync : 1;
18};
19
20EAPI Ecore_Wl_Subsurf *
21ecore_wl_subsurf_create(Ecore_Wl_Window *win)
22{
23 struct wl_subsurface *subsurface;
24 struct wl_surface *surface;
25 Ecore_Wl_Subsurf *ess;
26
27 LOGFN(__FILE__, __LINE__, __FUNCTION__);
28
29 if (!win) return NULL;
30 if (!win->surface) return NULL;
31 if (!_ecore_wl_disp->wl.subcompositor) return NULL;
32
33 surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor);
34 if (!surface)
35 return NULL;
36
37 subsurface = wl_subcompositor_get_subsurface
38 (_ecore_wl_disp->wl.subcompositor, surface, win->surface);
39 if (!subsurface)
40 {
41 wl_surface_destroy(surface);
42 return NULL;
43 }
44
45 ess = calloc(1, sizeof(*ess));
46 ess->surface = surface;
47 ess->subsurface = subsurface;
48 ess->parent_win = win;
49
50 win->subsurfs = (Ecore_Wl_Subsurf *)eina_inlist_append
51 (EINA_INLIST_GET(win->subsurfs), EINA_INLIST_GET(ess));
52
53 return ess;
54}
55
56static void
57_ecore_wl_subsurf_destroy(Ecore_Wl_Subsurf *ess)
58{
59 Ecore_Wl_Window *parent;
60
61 wl_subsurface_destroy(ess->subsurface);
62 wl_surface_destroy(ess->surface);
63
64 parent = ess->parent_win;
65 parent->subsurfs = (Ecore_Wl_Subsurf *)eina_inlist_remove
66 (EINA_INLIST_GET(parent->subsurfs), EINA_INLIST_GET(ess));
67
68 free(ess);
69}
70
71EAPI void
72ecore_wl_subsurf_del(Ecore_Wl_Subsurf *ess)
73{
74 LOGFN(__FILE__, __LINE__, __FUNCTION__);
75
76 if (!ess) return;
77
78 _ecore_wl_subsurf_destroy(ess);
79}
80
81void
82_ecore_wl_subsurfs_del_all(Ecore_Wl_Window *win)
83{
84 Ecore_Wl_Subsurf *ess;
85
86 if (!win) return;
87
88 EINA_INLIST_FREE(win->subsurfs, ess)
89 {
90 _ecore_wl_subsurf_destroy(ess);
91 }
92}
93
94EAPI struct wl_surface *
95ecore_wl_subsurf_surface_get(Ecore_Wl_Subsurf *ess)
96{
97 LOGFN(__FILE__, __LINE__, __FUNCTION__);
98
99 if (!ess) return NULL;
100
101 return ess->surface;
102}
103
104EAPI void
105ecore_wl_subsurf_position_set(Ecore_Wl_Subsurf *ess, int x, int y)
106{
107 LOGFN(__FILE__, __LINE__, __FUNCTION__);
108
109 if (!ess) return;
110
111 if ((x == ess->x) && (y == ess->y))
112 return;
113
114 ess->x = x;
115 ess->y = y;
116
117 wl_subsurface_set_position(ess->subsurface, x, y);
118}
119
120EAPI void
121ecore_wl_subsurf_position_get(Ecore_Wl_Subsurf *ess, int *x, int *y)
122{
123 LOGFN(__FILE__, __LINE__, __FUNCTION__);
124
125 if (!ess) return;
126
127 if (x) *x = ess->x;
128 if (y) *y = ess->y;
129}
130
131EAPI void
132ecore_wl_subsurf_place_above(Ecore_Wl_Subsurf *ess, struct wl_surface *surface)
133{
134 LOGFN(__FILE__, __LINE__, __FUNCTION__);
135
136 if (!ess) return;
137 if (!surface) return;
138
139 wl_subsurface_place_above(ess->subsurface, surface);
140}
141
142EAPI void
143ecore_wl_subsurf_place_below(Ecore_Wl_Subsurf *ess, struct wl_surface *surface)
144{
145 LOGFN(__FILE__, __LINE__, __FUNCTION__);
146
147 if (!ess) return;
148 if (!surface) return;
149
150 wl_subsurface_place_below(ess->subsurface, surface);
151}
152
153EAPI void
154ecore_wl_subsurf_sync_set(Ecore_Wl_Subsurf *ess, Eina_Bool val)
155{
156 LOGFN(__FILE__, __LINE__, __FUNCTION__);
157
158 if (!ess) return;
159
160 val = !!val;
161 if (val == ess->sync) return;
162
163 ess->sync = val;
164
165 if (ess->sync)
166 wl_subsurface_set_sync(ess->subsurface);
167 else
168 wl_subsurface_set_desync(ess->subsurface);
169}
170
171EAPI void
172ecore_wl_subsurf_opaque_region_set(Ecore_Wl_Subsurf *ess, int x, int y, int w, int h)
173{
174 Ecore_Wl_Window *parent;
175 struct wl_region *region = NULL;
176
177 LOGFN(__FILE__, __LINE__, __FUNCTION__);
178
179 if (!ess) return;
180
181 if ((w > 0) && (h > 0))
182 {
183 parent = ess->parent_win;
184 region = wl_compositor_create_region(parent->display->wl.compositor);
185 wl_region_add(region, x, y, w, h);
186 wl_surface_set_opaque_region(ess->surface, region);
187 wl_region_destroy(region);
188 }
189 else
190 wl_surface_set_opaque_region(ess->surface, NULL);
191}
diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c
index cd5aabe7ad..4ec78c8460 100644
--- a/src/lib/ecore_wayland/ecore_wl_window.c
+++ b/src/lib/ecore_wayland/ecore_wl_window.c
@@ -114,6 +114,8 @@ ecore_wl_window_free(Ecore_Wl_Window *win)
114 if (win->anim_callback) wl_callback_destroy(win->anim_callback); 114 if (win->anim_callback) wl_callback_destroy(win->anim_callback);
115 win->anim_callback = NULL; 115 win->anim_callback = NULL;
116 116
117 if (win->subsurfs) _ecore_wl_subsurfs_del_all(win);
118
117 if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); 119 if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface);
118 win->shell_surface = NULL; 120 win->shell_surface = NULL;
119 if (win->surface) wl_surface_destroy(win->surface); 121 if (win->surface) wl_surface_destroy(win->surface);