1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include "ecore_wl2_private.h"
6 
7 void
_ecore_wl2_subsurf_unmap(Ecore_Wl2_Subsurface * subsurf)8 _ecore_wl2_subsurf_unmap(Ecore_Wl2_Subsurface *subsurf)
9 {
10    if (subsurf->wl.subsurface) wl_subsurface_destroy(subsurf->wl.subsurface);
11    if (subsurf->wl.surface) wl_surface_destroy(subsurf->wl.surface);
12    subsurf->wl.subsurface = NULL;
13    subsurf->wl.surface = NULL;
14 }
15 
16 void
_ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface * subsurf)17 _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf)
18 {
19    Ecore_Wl2_Window *parent;
20 
21    _ecore_wl2_subsurf_unmap(subsurf);
22 
23    parent = subsurf->parent;
24    if (parent)
25      {
26         parent->subsurfs =
27           eina_inlist_remove(parent->subsurfs, EINA_INLIST_GET(subsurf));
28      }
29 
30    free(subsurf);
31 }
32 
33 EAPI Ecore_Wl2_Subsurface *
ecore_wl2_subsurface_new(Ecore_Wl2_Window * window)34 ecore_wl2_subsurface_new(Ecore_Wl2_Window *window)
35 {
36    Ecore_Wl2_Display *display;
37    Ecore_Wl2_Subsurface *subsurf;
38 
39    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
40    EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL);
41 
42    display = window->display;
43 
44    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, NULL);
45    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, NULL);
46 
47    subsurf = calloc(1, sizeof(Ecore_Wl2_Subsurface));
48    if (!subsurf) return NULL;
49 
50    subsurf->parent = window;
51 
52    subsurf->wl.surface = wl_compositor_create_surface(display->wl.compositor);
53    if (!subsurf->wl.surface)
54      {
55         ERR("Failed to create surface");
56         goto surf_err;
57      }
58 
59    subsurf->wl.subsurface =
60      wl_subcompositor_get_subsurface(display->wl.subcompositor,
61                                      subsurf->wl.surface, window->surface);
62    if (!subsurf->wl.subsurface)
63      {
64         ERR("Could not create subsurface");
65         goto sub_surf_err;
66      }
67 
68    /* A sub-surface is initially in the synchronized mode. */
69    subsurf->sync = EINA_TRUE;
70 
71    window->subsurfs =
72      eina_inlist_append(window->subsurfs, EINA_INLIST_GET(subsurf));
73 
74    return subsurf;
75 
76 sub_surf_err:
77    wl_surface_destroy(subsurf->wl.surface);
78 
79 surf_err:
80    free(subsurf);
81    return NULL;
82 }
83 
84 EAPI void
ecore_wl2_subsurface_del(Ecore_Wl2_Subsurface * subsurface)85 ecore_wl2_subsurface_del(Ecore_Wl2_Subsurface *subsurface)
86 {
87    EINA_SAFETY_ON_NULL_RETURN(subsurface);
88 
89    _ecore_wl2_subsurf_free(subsurface);
90 }
91 
92 EAPI struct wl_surface *
ecore_wl2_subsurface_surface_get(Ecore_Wl2_Subsurface * subsurface)93 ecore_wl2_subsurface_surface_get(Ecore_Wl2_Subsurface *subsurface)
94 {
95    EINA_SAFETY_ON_NULL_RETURN_VAL(subsurface, NULL);
96 
97    return subsurface->wl.surface;
98 }
99 
100 EAPI void
ecore_wl2_subsurface_position_set(Ecore_Wl2_Subsurface * subsurface,int x,int y)101 ecore_wl2_subsurface_position_set(Ecore_Wl2_Subsurface *subsurface, int x, int y)
102 {
103    EINA_SAFETY_ON_NULL_RETURN(subsurface);
104    EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
105 
106    if ((subsurface->x == x) && (subsurface->y == y)) return;
107 
108    subsurface->x = x;
109    subsurface->y = y;
110 
111    wl_subsurface_set_position(subsurface->wl.subsurface, x, y);
112 }
113 
114 EAPI void
ecore_wl2_subsurface_position_get(Ecore_Wl2_Subsurface * subsurface,int * x,int * y)115 ecore_wl2_subsurface_position_get(Ecore_Wl2_Subsurface *subsurface, int *x, int *y)
116 {
117    EINA_SAFETY_ON_NULL_RETURN(subsurface);
118 
119    if (x) *x = subsurface->x;
120    if (y) *y = subsurface->y;
121 }
122 
123 EAPI void
ecore_wl2_subsurface_place_above(Ecore_Wl2_Subsurface * subsurface,struct wl_surface * surface)124 ecore_wl2_subsurface_place_above(Ecore_Wl2_Subsurface *subsurface, struct wl_surface *surface)
125 {
126    EINA_SAFETY_ON_NULL_RETURN(subsurface);
127    EINA_SAFETY_ON_NULL_RETURN(surface);
128 
129    wl_subsurface_place_above(subsurface->wl.subsurface, surface);
130 }
131 
132 EAPI void
ecore_wl2_subsurface_place_below(Ecore_Wl2_Subsurface * subsurface,struct wl_surface * surface)133 ecore_wl2_subsurface_place_below(Ecore_Wl2_Subsurface *subsurface, struct wl_surface *surface)
134 {
135    EINA_SAFETY_ON_NULL_RETURN(subsurface);
136    EINA_SAFETY_ON_NULL_RETURN(surface);
137 
138    wl_subsurface_place_below(subsurface->wl.subsurface, surface);
139 }
140 
141 EAPI void
ecore_wl2_subsurface_sync_set(Ecore_Wl2_Subsurface * subsurface,Eina_Bool sync)142 ecore_wl2_subsurface_sync_set(Ecore_Wl2_Subsurface *subsurface, Eina_Bool sync)
143 {
144    EINA_SAFETY_ON_NULL_RETURN(subsurface);
145    EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
146 
147    sync = !!sync;
148    if (subsurface->sync == sync) return;
149 
150    subsurface->sync = sync;
151 
152    if (subsurface->sync)
153      wl_subsurface_set_sync(subsurface->wl.subsurface);
154    else
155      wl_subsurface_set_desync(subsurface->wl.subsurface);
156 }
157 
158 EAPI void
ecore_wl2_subsurface_opaque_region_set(Ecore_Wl2_Subsurface * subsurface,int x,int y,int w,int h)159 ecore_wl2_subsurface_opaque_region_set(Ecore_Wl2_Subsurface *subsurface, int x, int y, int w, int h)
160 {
161    EINA_SAFETY_ON_NULL_RETURN(subsurface);
162    EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
163 
164    if ((w > 0) && (h > 0))
165      {
166         Ecore_Wl2_Window *parent;
167 
168         parent = subsurface->parent;
169         if (parent)
170           {
171              struct wl_region *region;
172 
173              region =
174                wl_compositor_create_region(parent->display->wl.compositor);
175              if (!region)
176                {
177                   ERR("Failed to create opaque region");
178                   return;
179                }
180 
181              wl_region_add(region, x, y, w, h);
182              wl_surface_set_opaque_region(subsurface->wl.surface, region);
183              wl_region_destroy(region);
184           }
185      }
186    else
187      wl_surface_set_opaque_region(subsurface->wl.surface, NULL);
188 }
189