1 #include "services/e_service_volume_intern.h"
2 #include "e_policy_private_data.h"
3 #include "e_client_intern.h"
5 #include <wayland-server.h>
6 #include <tzsh_server.h>
8 #define REGION_OBJS_FOREACH(l, o) \
9 EINA_LIST_FOREACH(_volume_region_objs[_volume_cur_angle_map], l, o)
11 #define REGION_OBJS_VISIBLE_CHANGE(V) \
15 EINA_LIST_FOREACH(_volume_region_objs[_volume_cur_angle_map], l, o) \
17 if (V) evas_object_show(o); \
18 else evas_object_hide(o); \
21 #define REGION_OBJS_SHOW() REGION_OBJS_VISIBLE_CHANGE(EINA_TRUE)
22 #define REGION_OBJS_HIDE() REGION_OBJS_VISIBLE_CHANGE(EINA_FALSE)
24 /* private data for volume */
25 static struct wl_resource *_volume_wl_touch = NULL;
26 static E_Client *_volume_ec = NULL;
27 static Eina_List *_volume_region_objs[E_POLICY_ANGLE_MAP_NUM];
28 static E_Policy_Angle_Map _volume_cur_angle_map = E_POLICY_ANGLE_MAP_0;
29 static Eina_Bool _volume_ec_ev_init = EINA_FALSE;
32 static Ecore_Event_Handler *_rot_handler = NULL;
33 static E_Client_Hook *_volume_del_hook = NULL;
36 e_service_volume_client_get(void)
42 _volume_region_obj_cb_mouse_move(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
44 Evas_Event_Mouse_Move *e = event;
46 wl_touch_send_motion(_volume_wl_touch, e->timestamp, 0, // id 0 for the 1st figner
47 wl_fixed_from_int(e->cur.canvas.x - _volume_ec->client.x),
48 wl_fixed_from_int(e->cur.canvas.y - _volume_ec->client.y));
52 _volume_region_obj_cb_mouse_down(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
54 Evas_Event_Mouse_Down *e = event;
56 E_Comp_Wl_Client_Data *volume_cdata = e_client_cdata_get(_volume_ec);
58 serial = wl_display_next_serial(e_comp_wl->wl.disp);
59 wl_touch_send_down(_volume_wl_touch, serial, e->timestamp,
60 volume_cdata->surface, 0,
61 wl_fixed_from_int(e->canvas.x - _volume_ec->client.x),
62 wl_fixed_from_int(e->canvas.y - _volume_ec->client.y));
66 _volume_region_obj_cb_mouse_up(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
68 Evas_Event_Mouse_Up *e = event;
71 serial = wl_display_next_serial(e_comp_wl->wl.disp);
72 wl_touch_send_up(_volume_wl_touch, serial, e->timestamp, 0);
76 _volume_region_obj_cb_multi_down(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
78 Evas_Event_Multi_Down *e = event;
80 E_Comp_Wl_Client_Data *volume_cdata = e_client_cdata_get(_volume_ec);
82 serial = wl_display_next_serial(e_comp_wl->wl.disp);
83 wl_touch_send_down(_volume_wl_touch, serial, e->timestamp,
84 volume_cdata->surface, e->device,
85 wl_fixed_from_int(e->canvas.x - _volume_ec->client.x),
86 wl_fixed_from_int(e->canvas.y - _volume_ec->client.y));
90 _volume_region_obj_cb_multi_up(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
92 Evas_Event_Multi_Up *e = event;
95 serial = wl_display_next_serial(e_comp_wl->wl.disp);
96 wl_touch_send_up(_volume_wl_touch, serial, e->timestamp, e->device);
100 _volume_region_obj_cb_multi_move(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
102 Evas_Event_Multi_Move *e = event;
104 wl_touch_send_motion(_volume_wl_touch, e->timestamp, e->device,
105 wl_fixed_from_int(e->cur.canvas.x - _volume_ec->client.x),
106 wl_fixed_from_int(e->cur.canvas.y - _volume_ec->client.y));
110 _volume_client_evas_cb_show(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
112 /* show region objects in current rotation */
117 _volume_client_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
119 /* hide region objects in current rotation */
124 _volume_client_evas_cb_move(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *volume_obj, void *event EINA_UNUSED)
128 Evas_Object *region_obj;
131 REGION_OBJS_FOREACH(l, region_obj)
133 r = evas_object_data_get(region_obj, "content_rect");
134 if (EINA_UNLIKELY(r == NULL))
137 evas_object_geometry_get(volume_obj, &x, &y, NULL, NULL);
138 evas_object_move(region_obj, x + r->x, y + r->y);
143 _volume_client_evas_cb_restack(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
146 Evas_Object *region_obj;
148 REGION_OBJS_FOREACH(l, region_obj)
149 evas_object_stack_above(region_obj, _volume_ec->frame);
153 _region_objs_is_empty(void)
157 for (i = E_POLICY_ANGLE_MAP_0; i < E_POLICY_ANGLE_MAP_NUM; i++)
159 if (_volume_region_objs[i])
167 _region_obj_del(Evas_Object *obj)
171 r = evas_object_data_get(obj, "content_rect");
172 E_FREE_FUNC(r, eina_rectangle_free);
173 evas_object_del(obj);
177 _region_objs_del(E_Policy_Angle_Map angle_map)
181 EINA_LIST_FREE(_volume_region_objs[angle_map], obj)
182 _region_obj_del(obj);
184 if ((_volume_ec_ev_init) &&
185 (_region_objs_is_empty()))
187 _volume_ec_ev_init = EINA_FALSE;
189 evas_object_event_callback_del(_volume_ec->frame, EVAS_CALLBACK_SHOW,
190 _volume_client_evas_cb_show);
191 evas_object_event_callback_del(_volume_ec->frame, EVAS_CALLBACK_HIDE,
192 _volume_client_evas_cb_hide);
193 evas_object_event_callback_del(_volume_ec->frame, EVAS_CALLBACK_MOVE,
194 _volume_client_evas_cb_move);
195 evas_object_event_callback_del(_volume_ec->frame, EVAS_CALLBACK_RESTACK,
196 _volume_client_evas_cb_restack);
201 _volume_client_unset(void)
205 for (i = E_POLICY_ANGLE_MAP_0; i < E_POLICY_ANGLE_MAP_NUM; i++)
208 E_FREE_FUNC(_rot_handler, ecore_event_handler_del);
209 E_FREE_FUNC(_volume_del_hook, e_client_hook_del);
211 _volume_wl_touch = NULL;
216 _volume_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
218 if (EINA_UNLIKELY(!ec)) return;
219 if (EINA_LIKELY(_volume_ec != ec)) return;
221 ELOGF("VOLUME","Del Client", ec);
223 _volume_client_unset();
227 _volume_client_cb_rot_done(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
229 E_Event_Client_Rotation_Change_End *e = event;
230 E_Policy_Angle_Map new_idx;
232 if (EINA_UNLIKELY(e == NULL))
235 new_idx = e_policy_angle_map(_volume_ec->e.state.rot.ang.curr);
236 if (EINA_UNLIKELY(new_idx == -1))
239 if (e->ec != _volume_ec)
242 /* is new rotation same with previous? */
243 if (_volume_cur_angle_map == new_idx)
246 /* hide region object in current rotation */
249 /* update current rotation */
250 _volume_cur_angle_map = new_idx;
252 /* show region object in current rotation */
256 return ECORE_CALLBACK_RENEW;
260 e_service_volume_client_set(E_Client *ec)
267 _volume_client_unset();
274 ERR("Volume client is already registered."
275 "Multi volume service is not supported.");
279 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
281 ELOGF("VOLUME","Set Client", ec);
284 _volume_cur_angle_map = e_policy_angle_map(ec->e.state.rot.ang.curr);
286 /* repeat events for volume client. */
287 evas_object_repeat_events_set(ec->frame, EINA_TRUE);
290 ecore_event_handler_add(E_EVENT_CLIENT_ROTATION_CHANGE_END,
291 (Ecore_Event_Handler_Cb)_volume_client_cb_rot_done,
294 e_client_hook_add(E_CLIENT_HOOK_DEL, _volume_hook_client_del, NULL);
296 #ifdef REFACTOR_DESK_AREA
298 layer = e_client_layer_get(ec);
301 layer = e_client_desk_area_original_layer_get(ec);
304 if (E_POLICY_VOLUME_LAYER != layer)
306 e_client_layer_set(ec, E_POLICY_VOLUME_LAYER);
310 ec->exp_iconify.skip_iconify = 1;
316 _volume_content_region_obj_new(void)
320 obj = evas_object_rectangle_add(evas_object_evas_get(_volume_ec->frame));
322 /* make it transparent */
323 evas_object_color_set(obj, 0, 0, 0, 0);
325 /* set stack of obj object on the volume object. */
326 evas_object_layer_set(obj, evas_object_layer_get(_volume_ec->frame));
327 evas_object_stack_above(obj, _volume_ec->frame);
329 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
330 _volume_region_obj_cb_mouse_move, NULL);
331 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
332 _volume_region_obj_cb_mouse_down, NULL);
333 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
334 _volume_region_obj_cb_mouse_up, NULL);
335 evas_object_event_callback_add(obj, EVAS_CALLBACK_MULTI_DOWN,
336 _volume_region_obj_cb_multi_down, NULL);
337 evas_object_event_callback_add(obj, EVAS_CALLBACK_MULTI_UP,
338 _volume_region_obj_cb_multi_up, NULL);
339 evas_object_event_callback_add(obj, EVAS_CALLBACK_MULTI_MOVE,
340 _volume_region_obj_cb_multi_move, NULL);
346 _region_objs_tile_set(E_Policy_Angle_Map angle_map, Eina_Tiler *tiler)
348 Eina_List *objs_list, *l, *ll;
350 Eina_Rectangle *r, *cr;
355 zone = e_comp_zone_find_by_ec(_volume_ec);
356 EINA_SAFETY_ON_NULL_RETURN(zone);
358 desk = e_desk_current_get(zone);
359 EINA_SAFETY_ON_NULL_RETURN(desk);
361 objs_list = _volume_region_objs[angle_map];
362 it = eina_tiler_iterator_new(tiler);
363 EINA_ITERATOR_FOREACH(it, r)
365 /* trying to reuse allocated object */
366 obj = eina_list_data_get(objs_list);
369 objs_list = eina_list_next(objs_list);
370 cr = evas_object_data_get(obj, "content_rect");
371 E_FREE_FUNC(cr, eina_rectangle_free);
375 obj = _volume_content_region_obj_new();
376 _volume_region_objs[angle_map] = eina_list_append(_volume_region_objs[angle_map], obj);
377 e_desk_smart_member_add(desk, obj);
380 INF("\t@@@@@ Region Set: %d %d %d %d", r->x, r->y, r->w, r->h);
381 /* set geometry of region object */
382 evas_object_move(obj, _volume_ec->client.x + r->x, _volume_ec->client.y + r->y);
383 evas_object_resize(obj, r->w, r->h);
385 /* store the value of reigon as a region object's data */
386 cr = eina_rectangle_new(r->x, r->y, r->w, r->h);
387 evas_object_data_set(obj, "content_rect", cr);
389 if (angle_map == _volume_cur_angle_map)
391 if (evas_object_visible_get(_volume_ec->frame))
392 evas_object_show(obj);
395 eina_iterator_free(it);
397 /* delete rest of objects after reusing */
398 EINA_LIST_FOREACH_SAFE(objs_list, l, ll, obj)
400 _region_obj_del(obj);
401 _volume_region_objs[angle_map] =
402 eina_list_remove_list(_volume_region_objs[angle_map], l);
407 _volume_content_region_set(E_Policy_Angle_Map angle_map, Eina_Tiler *tiler)
411 _region_objs_del(angle_map);
415 _region_objs_tile_set(angle_map, tiler);
418 static struct wl_resource *
419 _volume_wl_touch_resource_get(void)
422 struct wl_client *wc;
423 struct wl_resource *res;
424 E_Comp_Wl_Client_Data *volume_cdata = e_client_cdata_get(_volume_ec);
426 if (_volume_wl_touch) goto end;
428 wc = wl_resource_get_client(volume_cdata->surface);
429 EINA_LIST_FOREACH(e_comp_wl->touch.resources, l, res)
431 if (wl_resource_get_client(res) != wc) continue;
433 _volume_wl_touch = res;
438 return _volume_wl_touch;
442 e_service_volume_region_set(int type, int angle, Eina_Tiler *tiler)
444 E_Policy_Angle_Map angle_map;
446 if (EINA_UNLIKELY(!_volume_ec))
448 ERR("No registered volume client");
452 angle_map = e_policy_angle_map(angle);
453 if (EINA_UNLIKELY(angle_map == -1))
456 /* FIXME: use enum instead of constant */
457 if (EINA_UNLIKELY(type != 1))
459 ERR("Not supported region type %d", type);
463 if (EINA_UNLIKELY(_volume_wl_touch_resource_get() == NULL))
465 ERR("Could not found wl_touch resource for volume");
469 ELOGF("VOLUME","Content Region Set: angle %d, tiler %p",
472 _volume_content_region_set(angle_map, tiler);
474 if (!_volume_ec_ev_init)
476 _volume_ec_ev_init = EINA_TRUE;
478 evas_object_event_callback_add(_volume_ec->frame, EVAS_CALLBACK_SHOW,
479 _volume_client_evas_cb_show, NULL);
480 evas_object_event_callback_add(_volume_ec->frame, EVAS_CALLBACK_HIDE,
481 _volume_client_evas_cb_hide, NULL);
482 evas_object_event_callback_add(_volume_ec->frame, EVAS_CALLBACK_MOVE,
483 _volume_client_evas_cb_move, NULL);
484 evas_object_event_callback_add(_volume_ec->frame, EVAS_CALLBACK_RESTACK,
485 _volume_client_evas_cb_restack, NULL);