1 #include "e_blender_intern.h"
2 #include "e_client_intern.h"
3 #include "e_comp_object_intern.h"
5 #include <wtz-blender-server-protocol.h>
7 static E_Blender *_blender = NULL;
9 static void _e_blend_surface_set(E_Blend *blend, struct wl_resource *surface);
12 _e_blend_cb_destroy(struct wl_client *client,
13 struct wl_resource *resource)
15 wl_resource_destroy(resource);
19 _e_blend_cb_set_alpha(struct wl_client *client,
20 struct wl_resource *resource,
25 blend = wl_resource_get_user_data(resource);
27 if (!blend->surface) return;
28 if (blend->alpha == value) return;
31 blend->changed = EINA_TRUE;
33 ELOGF("E_BLENDER", "E_Blend:%p set alpha:%x",
34 e_client_from_surface_resource(blend->surface), blend, value);
38 _e_blend_cb_set_equation(struct wl_client *client,
39 struct wl_resource *resource,
44 blend = wl_resource_get_user_data(resource);
46 if (!blend->surface) return;
47 if (blend->equation == equation) return;
49 if ((equation != WTZ_BLEND_EQUATION_PREMULTIPLIED) &&
50 (equation != WTZ_BLEND_EQUATION_NONE))
52 wl_resource_post_error(resource, WTZ_BLEND_ERROR_INVALID_EQUATION,
57 blend->equation = equation;
58 blend->changed = EINA_TRUE;
60 ELOGF("E_BLENDER", "E_Blend:%p set equation:%d",
61 e_client_from_surface_resource(blend->surface), blend, equation);
64 static const struct wtz_blend_interface _e_blend_implementation = {
66 _e_blend_cb_set_alpha,
67 _e_blend_cb_set_equation,
71 _e_blend_free(E_Blend *blend)
73 ELOGF("E_BLENDER", "E_Blend:%p Free",
74 blend->surface ? e_client_from_surface_resource(blend->surface) : NULL,
77 _e_blend_surface_set(blend, NULL);
82 _e_blend_cb_surface_destroy(struct wl_listener *listener, void *data)
86 blend = container_of(listener, E_Blend, surface_destroy_listener);
89 _e_blend_surface_set(blend, NULL);
95 _e_blend_cb_surface_state_commit(struct wl_listener *listener, void *data)
101 blend = container_of(listener, E_Blend, surface_state_commit_listener);
102 if (!blend->changed) return;
104 ec = e_client_from_surface_resource(blend->surface);
107 if (!blend->resource)
109 e_comp_object_render_op_set(ec->frame, EVAS_RENDER_BLEND);
110 evas_object_color_set(ec->frame, 255, 255, 255, 255);
111 _e_blend_free(blend);
115 if (!ec->argb) return;
118 a = (int)((blend->alpha / (double)0xffffffff) * a);
119 evas_color_argb_premul(a, &r, &g, &b);
121 evas_object_color_set(ec->frame, r, g, b, a);
123 if (blend->equation == WTZ_BLEND_EQUATION_PREMULTIPLIED)
124 e_comp_object_render_op_set(ec->frame, EVAS_RENDER_BLEND);
125 else if (blend->equation == WTZ_BLEND_EQUATION_NONE)
126 e_comp_object_render_op_set(ec->frame, EVAS_RENDER_COPY);
128 blend->changed = EINA_FALSE;
132 _e_blend_surface_set(E_Blend *blend, struct wl_resource *surface)
135 E_Comp_Client_Data *cdata;
137 if (blend->surface == surface) return;
139 if (blend->surface_destroy_listener.notify)
141 wl_list_remove(&blend->surface_destroy_listener.link);
142 blend->surface_destroy_listener.notify = NULL;
145 if (blend->surface_state_commit_listener.notify)
147 wl_list_remove(&blend->surface_state_commit_listener.link);
148 blend->surface_state_commit_listener.notify = NULL;
151 blend->surface = NULL;
155 ec = e_client_from_surface_resource(surface);
156 EINA_SAFETY_ON_NULL_RETURN(ec);
158 cdata = e_client_cdata_get(ec);
159 EINA_SAFETY_ON_NULL_RETURN(cdata);
161 blend->surface = surface;
163 blend->surface_destroy_listener.notify = _e_blend_cb_surface_destroy;
164 wl_resource_add_destroy_listener(surface, &blend->surface_destroy_listener);
166 blend->surface_state_commit_listener.notify = _e_blend_cb_surface_state_commit;
167 wl_signal_add(&cdata->state_commit_signal, &blend->surface_state_commit_listener);
172 _e_blend_cb_resource_destroy(struct wl_resource *resource)
175 Evas_Render_Op render_op;
179 blend = wl_resource_get_user_data(resource);
184 ec = e_client_from_surface_resource(blend->surface);
187 e_comp_object_color_get(ec->frame, NULL, NULL, NULL, &a);
188 render_op = e_comp_object_render_op_get(ec->frame);
189 if ((a != 255) || (render_op != EVAS_RENDER_BLEND))
191 blend->resource = NULL;
192 blend->changed = EINA_TRUE;
198 _e_blend_free(blend);
202 _e_blender_cb_destroy(struct wl_client *client,
203 struct wl_resource *resource)
205 wl_resource_destroy(resource);
209 _e_blender_blend_get_from_surface(struct wl_resource *surface)
212 struct wl_listener *listener;
214 listener = wl_resource_get_destroy_listener(surface, _e_blend_cb_surface_destroy);
215 if (!listener) return NULL;
217 return wl_container_of(listener, blend, surface_destroy_listener);
221 _e_blender_cb_get_blend(struct wl_client *client, struct wl_resource *resource,
222 uint32_t id, struct wl_resource *surface)
225 E_Blend *blend = NULL;
226 E_Blender *blender = _blender;
230 ERR("blender is not initialized");
234 ec = e_client_from_surface_resource(surface);
235 if ((!ec) || (e_object_is_del(E_OBJECT(ec))))
237 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
238 "invalid wl_surface resource:%u",
239 (unsigned int)wl_resource_get_id(surface));
243 blend = _e_blender_blend_get_from_surface(surface);
248 wl_resource_post_error(resource, WTZ_BLENDER_ERROR_BLEND_EXISTS,
249 "blend object already exists");
254 _e_blend_free(blend);
258 blend = E_NEW(E_Blend, 1);
261 wl_client_post_no_memory(client);
265 blend->resource = wl_resource_create(client,
266 &wtz_blend_interface,
267 wl_resource_get_version(resource),
269 if (!blend->resource)
271 wl_client_post_no_memory(client);
275 wl_resource_set_implementation(blend->resource,
276 &_e_blend_implementation,
278 _e_blend_cb_resource_destroy);
280 blend->alpha = 0xffffffff;
281 _e_blend_surface_set(blend, surface);
283 ELOGF("E_BLENDER", "E_Blend:%p Create", ec, blend);
294 static const struct wtz_blender_interface _e_blender_implementation = {
295 _e_blender_cb_destroy,
296 _e_blender_cb_get_blend,
300 _e_blender_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
302 struct wl_resource *resource;
306 if (!blender) return;
308 resource = wl_resource_create(client, &wtz_blender_interface, version, id);
311 wl_client_post_no_memory(client);
315 wl_resource_set_implementation(resource, &_e_blender_implementation,
324 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
325 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->wl.disp, EINA_FALSE);
327 if (_blender) return EINA_TRUE;
329 blender = E_NEW(E_Blender, 1);
330 EINA_SAFETY_ON_NULL_RETURN_VAL(blender, EINA_FALSE);
332 blender->global = wl_global_create(e_comp_wl->wl.disp,
333 &wtz_blender_interface,
337 EINA_SAFETY_ON_NULL_GOTO(blender->global, fail);
345 wl_global_destroy(blender->global);
353 e_blender_shutdown(void)
358 if (!blender) return;
360 wl_global_destroy(blender->global);