1 #include "e_mod_effect_rotation.h"
3 #include <tbm_bufmgr.h>
4 #include <tbm_surface.h>
5 #include <tbm_surface_internal.h>
6 #include <tdm_helper.h>
7 #include <wayland-tbm-server.h>
10 #define e_util_size_debug_set(x, y)
13 typedef struct _Rotation_Effect_Object
18 struct wl_shm_pool *data_pool;
20 } Rotation_Effect_Object;
22 typedef struct _Rotation_Effect_Begin_Context
29 } Rotation_Effect_Begin_Context;
31 typedef struct _Rotation_Effect_End_Context
38 } Rotation_Effect_End_Context;
40 typedef struct _Rotation_Effect
46 Eina_List *waiting_list;
48 Rotation_Effect_Begin_Context *ctx_begin;
49 Rotation_Effect_End_Context *ctx_end;
51 Ecore_Animator *animator;
54 Eina_Bool wait_for_buffer;
58 typedef struct _Rotation_Zone
61 Eina_List *event_hdlrs;
63 Rotation_Effect *effect;
69 static Rotation_Zone *_rotation_zone = NULL;
72 _rotation_effect_ready_send(E_Zone *zone)
74 E_Event_Zone_Rotation_Effect_Ready *ev;
76 ev = E_NEW(E_Event_Zone_Rotation_Effect_Ready, 1);
80 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_READY, ev, NULL, NULL);
82 EFFINF("Rotation Effect Event Ready", NULL, NULL);
86 _rotation_effect_cancel_send(E_Zone *zone)
88 E_Event_Zone_Rotation_Effect_Cancel *ev;
90 ev = E_NEW(E_Event_Zone_Rotation_Effect_Cancel, 1);
94 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_CANCEL, ev, NULL, NULL);
96 EFFINF("Rotation Effect Event Cancel", NULL, NULL);
100 _rotation_effect_done_send(E_Zone *zone)
102 E_Event_Zone_Rotation_Effect_Done *ev;
104 ev = E_NEW(E_Event_Zone_Rotation_Effect_Done, 1);
108 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_DONE, ev, NULL, NULL);
110 EFFINF("Rotation Effect Event Done", NULL, NULL);
114 _rotation_effect_available(const E_Client *ec, int ang)
116 Eina_Bool ret = EINA_FALSE;
119 if (ang < 0) return EINA_FALSE;
120 if (!ec->e.state.rot.support)
123 if (ec->e.state.rot.preferred_rot == -1)
125 if (ec->e.state.rot.available_rots &&
126 ec->e.state.rot.count)
128 for (i = 0; i < ec->e.state.rot.count; i++)
130 if (ec->e.state.rot.available_rots[i] == ang)
140 else if (ec->e.state.rot.preferred_rot == ang)
149 _rotation_effect_targets_get(Rotation_Effect *effect, E_Desk *desk)
159 if (!effect) return NULL;
161 if (effect->zone->display_state == E_ZONE_DISPLAY_STATE_OFF)
166 t = eina_tiler_new(effect->zone->w + edge, effect->zone->h + edge);
167 eina_tiler_tile_size_set(t, 1, 1);
169 EINA_RECTANGLE_SET(&r, effect->zone->x, effect->zone->y, effect->zone->w, effect->zone->h);
170 eina_tiler_rect_add(t, &r);
172 o = evas_object_top_get(e_comp->evas);
173 for (; o; o = evas_object_below_get(o))
175 if (!evas_object_visible_get(o)) continue;
176 if (o == effect->zone->over) continue;
177 if (o == effect->bg) continue;
178 if (evas_object_layer_get(o) > E_LAYER_EFFECT) continue;
179 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) continue;
181 evas_object_geometry_get(o, &x, &y, &w, &h);
182 ec = evas_object_data_get(o, "E_Client");
185 if (ec->desk != desk) continue;
186 if (e_object_is_del(E_OBJECT(ec))) continue;
187 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h))
189 if ((ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) &&
193 if ((!ec->animatable) ||
194 (e_client_video_client_has(ec)) ||
195 (!_rotation_effect_available(ec, effect->zone->rot.curr)) ||
196 (ec->e.state.rot.ang.curr == effect->zone->rot.curr))
198 if (l) eina_list_free(l);
204 l = eina_list_append(l, o);
206 if ((ec) && (ec->argb))
208 if (ec->visibility.opaque <= 0) continue;
211 if (ec->parent) continue;
215 EINA_RECTANGLE_SET(&r, x, y, w + edge, h + edge);
216 eina_tiler_rect_del(t, &r);
218 if (eina_tiler_empty(t)) break;
226 _rotation_effect_object_free(Rotation_Effect_Object *eobj)
232 evas_object_image_data_set(eobj->img, NULL);
235 if (eobj->img) evas_object_del(eobj->img);
236 if (eobj->data_pool) wl_shm_pool_unref(eobj->data_pool);
241 static Rotation_Effect_Object *
242 _rotation_effect_object_create(Evas_Object *o)
244 Rotation_Effect_Object *eobj;
245 E_Comp_Wl_Buffer *buffer = NULL;
246 Evas_Object *img = NULL;
250 void *data = NULL, *pix = NULL;
252 if (!evas_object_visible_get(o)) return NULL;
254 ec = evas_object_data_get(o, "E_Client");
257 if (e_object_is_del(E_OBJECT(ec))) return NULL;
259 eobj = E_NEW(Rotation_Effect_Object, 1);
260 if (!eobj) goto fail;
264 buffer = e_pixmap_resource_get(ec->pixmap);
265 if (!buffer) goto fail;
267 img = evas_object_image_filled_add(e_comp->evas);
268 e_util_size_debug_set(img, 1);
269 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
270 evas_object_image_smooth_scale_set(img, e_comp_config_get()->smooth_windows);
272 if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
274 if (!buffer->shm_buffer) goto fail;
279 pix = wl_shm_buffer_get_data(buffer->shm_buffer);
283 wl_shm_pool_unref(eobj->data_pool);
284 eobj->data_pool = wl_shm_buffer_ref_pool(buffer->shm_buffer);
286 else if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
288 tbm_surface_info_s surface_info;
289 tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
290 memset(&surface_info, 0, sizeof(tbm_surface_info_s));
291 tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
293 data = surface_info.planes[0].ptr;
294 if (!data) goto fail;
296 w = surface_info.width;
297 h = surface_info.height;
299 pix = eobj->data = malloc(w * h * 4);
300 for (i = 0; i < h; i++)
302 memcpy(pix, data, surface_info.width * 4);
303 pix += surface_info.width * 4;
304 data += surface_info.planes[0].stride;
308 tbm_surface_unmap(tbm_surface);
310 else if (buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
312 tbm_surface_info_s surface_info;
313 tbm_surface_h tbm_surface = buffer->tbm_surface;
315 memset(&surface_info, 0, sizeof(tbm_surface_info_s));
316 tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
318 data = surface_info.planes[0].ptr;
319 if (!data) goto fail;
321 w = surface_info.width;
322 h = surface_info.height;
324 pix = eobj->data = malloc(w * h * 4);
325 for (i = 0; i < h; i++)
327 memcpy(pix, data, surface_info.width * 4);
328 pix += surface_info.width * 4;
329 data += surface_info.planes[0].stride;
333 tbm_surface_unmap(tbm_surface);
340 evas_object_image_alpha_set(img, 1);
341 evas_object_image_size_set(img, w, h);
342 evas_object_image_data_set(img, pix);
343 evas_object_image_data_update_add(img, 0, 0, w, h);
345 evas_object_name_set(img, "rotation-effect-image");
346 evas_object_move(img, ec->x, ec->y);
347 evas_object_resize(img, ec->w, ec->h);
352 EFFINF("Rotation EFFECT Object Created E_Client:%p",
360 eobj = E_NEW(Rotation_Effect_Object, 1);
361 if (!eobj) return NULL;
365 evas_object_geometry_get(o, &x, &y, &w, &h);
367 img = evas_object_image_filled_add(e_comp->evas);
368 e_util_size_debug_set(img, 1);
370 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
371 evas_object_image_smooth_scale_set(img, e_comp_config_get()->smooth_windows);
372 evas_object_image_alpha_set(img, 1);
373 evas_object_image_size_set(img, w, h);
374 evas_object_image_source_set(img, o);
376 evas_object_name_set(img, "rotation-effect-image");
377 evas_object_move(img, x, y);
378 evas_object_resize(img, w, h);
382 EFFINF("Rotation EFFECT Object Created Object:%p",
391 evas_object_image_data_set(img, NULL);
392 evas_object_del(img);
398 wl_shm_pool_unref(eobj->data_pool);
406 static Rotation_Effect_Begin_Context *
407 _rotation_effect_begin_create(Rotation_Effect *effect, Eina_List *targets, E_Desk *desk)
409 Rotation_Effect_Begin_Context *ctx_begin = NULL;
410 Rotation_Effect_Object *eobj = NULL;
415 ctx_begin = E_NEW(Rotation_Effect_Begin_Context, 1);
416 if (!ctx_begin) return NULL;
418 ctx_begin->layout = e_layout_add(e_comp->evas);
419 e_util_size_debug_set(ctx_begin->layout, 1);
420 evas_object_name_set(ctx_begin->layout, "rotation-begin-effect-layout");
421 e_layout_virtual_size_set(ctx_begin->layout, effect->zone->w, effect->zone->h);
422 evas_object_move(ctx_begin->layout, effect->zone->x, effect->zone->y);
423 evas_object_resize(ctx_begin->layout, effect->zone->w, effect->zone->h);
424 evas_object_layer_set(ctx_begin->layout, E_LAYER_EFFECT);
426 EINA_LIST_REVERSE_FOREACH(targets, l, target)
428 eobj = _rotation_effect_object_create(target);
431 ctx_begin->objects = eina_list_append(ctx_begin->objects, eobj);
433 effect->waiting_list = eina_list_append(effect->waiting_list, eobj->ec);
435 evas_object_geometry_get(target, &x, &y, &w, &h);
437 e_layout_pack(ctx_begin->layout, eobj->img);
438 e_layout_child_move(eobj->img, x, y);
439 e_layout_child_resize(eobj->img, w, h);
440 e_layout_child_raise(eobj->img);
441 evas_object_show(eobj->img);
444 if (!ctx_begin->objects)
446 evas_object_del(ctx_begin->layout);
451 e_desk_smart_member_add(desk, ctx_begin->layout);
453 EFFINF("Rotation Begin Created", NULL, NULL);
455 int diff = effect->zone->rot.prev - effect->zone->rot.curr;
456 if (diff == 270) diff = - 90;
457 else if (diff == -270) diff = 90;
458 ctx_begin->src = 0.0;
459 ctx_begin->dest = diff;
465 static Rotation_Effect_End_Context *
466 _rotation_effect_end_create(Rotation_Effect *effect, Eina_List *targets, E_Desk *desk)
468 Rotation_Effect_End_Context *ctx_end = NULL;
469 Rotation_Effect_Object *eobj = NULL;
474 ctx_end = E_NEW(Rotation_Effect_End_Context, 1);
475 if (!ctx_end) return NULL;
477 ctx_end->layout = e_layout_add(e_comp->evas);
478 e_util_size_debug_set(ctx_end->layout, 1);
479 evas_object_name_set(ctx_end->layout, "rotation-end-effect-layout");
480 e_layout_virtual_size_set(ctx_end->layout, effect->zone->w, effect->zone->h);
481 evas_object_move(ctx_end->layout, effect->zone->x, effect->zone->y);
482 evas_object_resize(ctx_end->layout, effect->zone->w, effect->zone->h);
483 evas_object_layer_set(ctx_end->layout, E_LAYER_EFFECT);
485 EINA_LIST_REVERSE_FOREACH(targets, l, target)
487 eobj = _rotation_effect_object_create(target);
490 evas_object_geometry_get(target, &x, &y, &w, &h);
492 ctx_end->objects = eina_list_append(ctx_end->objects, eobj);
494 e_layout_pack(ctx_end->layout, eobj->img);
495 e_layout_child_move(eobj->img, x, y);
496 e_layout_child_resize(eobj->img, w, h);
497 e_layout_child_raise(eobj->img);
498 evas_object_show(eobj->img);
501 if (!ctx_end->objects)
503 evas_object_del(ctx_end->layout);
508 e_desk_smart_member_add(desk, ctx_end->layout);
510 EFFINF("Rotation End Created", NULL, NULL);
512 int diff = _rotation_zone->curr_angle - _rotation_zone->prev_angle;
513 if (diff == 270) diff = - 90;
514 else if (diff == -270) diff = 90;
522 _rotation_effect_animator_begin_context_free(Rotation_Effect_Begin_Context *ctx_begin)
524 Rotation_Effect_Object *eobj;
526 if (!ctx_begin) return;
528 EFFINF("Rotation Begin Free", NULL, NULL);
530 if (ctx_begin->layout)
531 evas_object_hide(ctx_begin->layout);
533 EINA_LIST_FREE(ctx_begin->objects, eobj)
535 e_layout_unpack(eobj->img);
536 _rotation_effect_object_free(eobj);
539 if (ctx_begin->layout)
540 evas_object_del(ctx_begin->layout);
546 _rotation_effect_animator_end_context_free(Rotation_Effect_End_Context *ctx_end)
548 Rotation_Effect_Object *eobj;
550 if (!ctx_end) return;
552 EFFINF("Rotation End Free", NULL, NULL);
555 evas_object_hide(ctx_end->layout);
557 EINA_LIST_FREE(ctx_end->objects, eobj)
559 e_layout_unpack(eobj->img);
560 _rotation_effect_object_free(eobj);
564 evas_object_del(ctx_end->layout);
570 _rotation_effect_clear(Rotation_Effect *effect)
574 EFFINF("Rotation Effect Clear", NULL, NULL);
576 effect->targets = eina_list_free(effect->targets);
577 effect->waiting_list = eina_list_free(effect->waiting_list);
579 if (effect->animator)
580 ecore_animator_del(effect->animator);
582 evas_object_hide(effect->bg);
584 if (effect->ctx_begin)
586 _rotation_effect_animator_begin_context_free(effect->ctx_begin);
587 e_comp_override_del();
592 _rotation_effect_animator_end_context_free(effect->ctx_end);
593 _rotation_effect_done_send(effect->zone);
596 effect->running = EINA_FALSE;
597 effect->wait_for_buffer = EINA_FALSE;
598 effect->animator = NULL;
599 effect->ctx_begin = NULL;
600 effect->ctx_end = NULL;
604 _rotation_effect_animator_cb_update(void *data, double pos)
606 Rotation_Effect *effect;
607 Rotation_Effect_Begin_Context *ctx_begin;
608 Rotation_Effect_End_Context *ctx_end;
610 double curr, col, progress;
611 Evas_Coord x, y, w, h;
613 effect = (Rotation_Effect *)data;
614 ctx_begin = effect->ctx_begin;
615 ctx_end = effect->ctx_end;
619 ecore_animator_del(effect->animator);
620 effect->animator = NULL;
622 _rotation_effect_animator_begin_context_free(effect->ctx_begin);
623 effect->ctx_begin = NULL;
625 _rotation_effect_animator_end_context_free(effect->ctx_end);
626 effect->ctx_end = NULL;
628 effect->wait_for_buffer = EINA_FALSE;
629 effect->running = EINA_FALSE;
630 evas_object_hide(effect->bg);
632 e_comp_override_del();
633 _rotation_effect_done_send(effect->zone);
635 return ECORE_CALLBACK_CANCEL;
638 progress = ecore_animator_pos_map(pos, ECORE_POS_MAP_DECELERATE, 0, 0);
640 if (progress < 0.0) progress = 0.0;
643 curr = (progress * ctx_begin->dest);
644 col = 255 - (255 * progress);
646 evas_object_geometry_get(ctx_begin->layout, &x, &y, &w, &h);
648 Evas_Map *m = evas_map_new(4);
649 evas_map_util_points_populate_from_object(m, ctx_begin->layout);
650 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
651 evas_map_alpha_set(m, EINA_TRUE);
652 evas_map_util_points_color_set(m, col, col, col, col);
653 evas_object_map_set(ctx_begin->layout, m);
654 evas_object_map_enable_set(ctx_begin->layout, EINA_TRUE);
658 curr = ((-1.0f * progress * ctx_end->src) + ctx_end->src);
660 evas_object_geometry_get(ctx_end->layout, &x, &y, &w, &h);
663 evas_map_util_points_populate_from_object(m, ctx_end->layout);
664 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
665 evas_object_map_set(ctx_end->layout, m);
666 evas_object_map_enable_set(ctx_end->layout, EINA_TRUE);
669 return ECORE_CALLBACK_RENEW;
673 _rotation_effect_start(Rotation_Effect *effect)
675 if ((!effect->ctx_begin) || (!effect->ctx_end)) return;
676 if (effect->running) return;
678 /* now, we're going to start rotation effect.
679 * so, unblock updating canvas (compositing mode)
681 if (effect->norender)
683 e_comp_canvas_norender_pop();
684 effect->norender = EINA_FALSE;
687 EFFINF("Rotation Effect Start", NULL, NULL);
689 effect->running = EINA_TRUE;
691 evas_object_raise(effect->ctx_begin->layout);
692 evas_object_show(effect->ctx_begin->layout);
693 evas_object_show(effect->ctx_end->layout);
695 evas_object_move(effect->bg, 0, 0);
696 evas_object_resize(effect->bg, effect->zone->w, effect->zone->h);
697 evas_object_lower(effect->bg);
698 evas_object_show(effect->bg);
700 effect->animator = ecore_animator_timeline_add(0.3f,
701 _rotation_effect_animator_cb_update,
706 _rotation_effect_animator_begin_prepare(Rotation_Effect *effect, E_Desk *desk)
710 _rotation_effect_clear(effect);
712 effect->targets = _rotation_effect_targets_get(effect, desk);
713 if (!effect->targets) return;
715 effect->ctx_begin = _rotation_effect_begin_create(effect, effect->targets, desk);
716 if (!effect->ctx_begin)
718 _rotation_effect_clear(effect);
722 EFFINF("Rotation Begin Prepared", NULL, NULL);
724 /* add hwc override */
725 e_comp_override_add();
727 /* block updating canvas (compositing mode) to avoid showing rotated window that
728 * could be outputted to the screen before starting rotation effect.
729 * it will be unset when the rotation effect starts.
731 if (!effect->norender)
733 e_comp_canvas_norender_push();
734 effect->norender = EINA_TRUE;
739 _rotation_effect_animator_end_prepare(Rotation_Effect *effect, E_Desk *desk)
742 if (!effect->targets) return;
743 if (!effect->ctx_begin) return;
745 /* clear previous context */
747 _rotation_effect_animator_end_context_free(effect->ctx_end);
748 effect->ctx_end = NULL;
750 effect->ctx_end = _rotation_effect_end_create(effect, effect->targets, desk);
751 if (!effect->ctx_end) return;
753 EFFINF("Rotation End Prepared", NULL, NULL);
755 effect->targets = eina_list_free(effect->targets);
759 _rotation_effect_cb_zone_rotation_begin(void *data, int type, void *event)
761 Rotation_Effect *effect;
762 E_Event_Zone_Rotation_Change_Begin *ev = event;
766 effect = (Rotation_Effect *)data;
767 if (!effect) return ECORE_CALLBACK_PASS_ON;
770 if (!zone) return ECORE_CALLBACK_PASS_ON;
772 EFFINF("Zone rotation begin zone(prev:%d cur:%d)",
774 zone->rot.prev, zone->rot.curr);
776 if (zone->rot.prev == zone->rot.curr) return ECORE_CALLBACK_PASS_ON;
778 _rotation_zone->curr_angle = zone->rot.curr;
779 _rotation_zone->prev_angle = zone->rot.prev;
781 desk = e_desk_current_get(zone);
782 _rotation_effect_animator_begin_prepare(effect, desk);
785 _rotation_effect_ready_send(zone);
787 return ECORE_CALLBACK_PASS_ON;
791 _rotation_effect_cb_zone_rotation_end(void *data, int type, void *event)
793 Rotation_Effect *effect;
794 E_Event_Zone_Rotation_Change_End *ev = event;
798 effect = (Rotation_Effect *)data;
799 if (!effect) return ECORE_CALLBACK_PASS_ON;
802 if (!zone) return ECORE_CALLBACK_PASS_ON;
804 EFFINF("Zone rotation end angle(prev:%d cur:%d)", NULL, NULL,
805 zone->rot.prev, zone->rot.curr);
807 if (effect->running) return ECORE_CALLBACK_PASS_ON;
808 if (effect->waiting_list)
810 effect->wait_for_buffer = EINA_TRUE;
811 return ECORE_CALLBACK_PASS_ON;
814 if (!effect->ctx_end)
816 desk = e_desk_current_get(zone);
817 _rotation_effect_animator_end_prepare(effect, desk);
819 if (!effect->ctx_end)
820 _rotation_effect_clear(effect);
822 if (effect->ctx_end) _rotation_effect_start(effect);
824 return ECORE_CALLBACK_PASS_ON;
828 _rotation_effect_cb_zone_rotation_cancel(void *data, int type, void *event)
830 E_Event_Zone_Rotation_Change_Cancel *ev = event;
831 Rotation_Effect *effect;
835 if (!zone) return ECORE_CALLBACK_PASS_ON;
837 effect = (Rotation_Effect *)data;
838 if (!effect) return ECORE_CALLBACK_PASS_ON;
840 EFFINF("Zone Rotation Cancelled", NULL, NULL);
842 if (effect->running) return ECORE_CALLBACK_PASS_ON;
843 if (effect->targets) _rotation_effect_cancel_send(zone);
845 if (effect->norender)
847 e_comp_canvas_norender_pop();
848 effect->norender = EINA_FALSE;
851 _rotation_effect_clear(effect);
853 return ECORE_CALLBACK_PASS_ON;
857 _rotation_effect_cb_buffer_change(void *data, int ev_type, void *event)
859 E_Event_Client *ev = event;
862 Rotation_Effect *effect;
865 if (!ec) return ECORE_CALLBACK_PASS_ON;
867 effect = (Rotation_Effect *)data;
868 if (!effect) return ECORE_CALLBACK_PASS_ON;
869 if (!effect->ctx_begin) return ECORE_CALLBACK_PASS_ON;
870 if (!effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
872 effect->waiting_list = eina_list_remove(effect->waiting_list, ec);
873 if (effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
875 if (!effect->wait_for_buffer) return ECORE_CALLBACK_PASS_ON;
877 if (!effect->ctx_end)
879 desk = e_desk_current_get(ec->zone);
880 _rotation_effect_animator_end_prepare(effect, desk);
882 if (effect->ctx_end) _rotation_effect_start(effect);
884 return ECORE_CALLBACK_PASS_ON;
888 _rotation_effect_cb_client_hide(void *data, int ev_type, void *event)
890 E_Event_Client *ev = event;
892 Rotation_Effect *effect;
896 if (!ec) return ECORE_CALLBACK_PASS_ON;
898 effect = (Rotation_Effect *)data;
899 if (!effect) return ECORE_CALLBACK_PASS_ON;
900 if (!effect->ctx_begin) return ECORE_CALLBACK_PASS_ON;
901 if (!effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
903 effect->waiting_list = eina_list_remove(effect->waiting_list, ec);
904 if (effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
906 if (!effect->wait_for_buffer) return ECORE_CALLBACK_PASS_ON;
908 if (!effect->ctx_end)
910 desk = e_desk_current_get(ec->zone);
911 _rotation_effect_animator_end_prepare(effect, desk);
913 if (effect->ctx_end) _rotation_effect_start(effect);
915 return ECORE_CALLBACK_PASS_ON;
919 _rotation_effect_cb_client_remove(void *data, int ev_type, void *event)
921 E_Event_Client *ev = event;
923 Rotation_Effect *effect;
924 Rotation_Effect_Object *eobj;
926 Eina_Bool clear = EINA_FALSE;
929 if (!ec) return ECORE_CALLBACK_PASS_ON;
931 effect = (Rotation_Effect *)data;
932 if (!effect) return ECORE_CALLBACK_PASS_ON;
933 if (effect->ctx_begin)
935 EINA_LIST_FOREACH(effect->ctx_begin->objects, l, eobj)
945 _rotation_effect_clear(effect);
948 return ECORE_CALLBACK_PASS_ON;
952 _rotation_effect_free(Rotation_Effect *effect)
956 _rotation_effect_clear(effect);
957 evas_object_del(effect->bg);
961 static Rotation_Effect *
962 _rotation_effect_create(E_Zone *zone)
964 Rotation_Effect *rotation_effect;
966 rotation_effect = E_NEW(Rotation_Effect, 1);
967 if (!rotation_effect) return NULL;
969 rotation_effect->zone = zone;
971 rotation_effect->bg = evas_object_rectangle_add(e_comp->evas);
972 e_util_size_debug_set(rotation_effect->bg, 1);
973 evas_object_color_set(rotation_effect->bg, 0, 0, 0, 255);
974 evas_object_layer_set(rotation_effect->bg, E_LAYER_EFFECT);
975 evas_object_name_set(rotation_effect->bg, "rotation-bg");
977 return rotation_effect;
981 _rotation_zone_free(Rotation_Zone *rotation_zone)
983 if (!rotation_zone) return;
985 E_FREE_LIST(rotation_zone->event_hdlrs, ecore_event_handler_del);
987 _rotation_effect_free(rotation_zone->effect);
989 E_FREE(rotation_zone);
994 static Rotation_Zone *
995 _rotation_zone_create(E_Zone *zone)
997 Rotation_Zone *rotation_zone = NULL;
999 if (!zone) return NULL;
1000 if ((zone->w == 0) || (zone->h == 0)) return NULL;
1002 rotation_zone = E_NEW(Rotation_Zone, 1);
1003 if (!rotation_zone) return NULL;
1005 /* create rotation effect data */
1006 rotation_zone->effect = _rotation_effect_create(zone);
1007 if (!rotation_zone->effect)
1009 E_FREE(rotation_zone);
1013 rotation_zone->zone = zone;
1014 rotation_zone->curr_angle = zone->rot.curr;
1015 rotation_zone->prev_angle = zone->rot.prev;
1017 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1018 E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
1019 _rotation_effect_cb_zone_rotation_begin, rotation_zone->effect);
1021 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1022 E_EVENT_ZONE_ROTATION_CHANGE_END,
1023 _rotation_effect_cb_zone_rotation_end, rotation_zone->effect);
1025 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1026 E_EVENT_ZONE_ROTATION_CHANGE_CANCEL,
1027 _rotation_effect_cb_zone_rotation_cancel, rotation_zone->effect);
1029 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1030 E_EVENT_CLIENT_BUFFER_CHANGE,
1031 _rotation_effect_cb_buffer_change, rotation_zone->effect);
1033 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1034 E_EVENT_CLIENT_HIDE,
1035 _rotation_effect_cb_client_hide, rotation_zone->effect);
1037 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
1038 E_EVENT_CLIENT_REMOVE,
1039 _rotation_effect_cb_client_remove, rotation_zone->effect);
1041 return rotation_zone;
1045 e_mod_effect_rotation_init(void)
1047 _rotation_zone = _rotation_zone_create(e_zone_current_get());
1048 if (!_rotation_zone) return EINA_FALSE;
1054 e_mod_effect_rotation_shutdown(void)
1057 _rotation_zone_free(_rotation_zone);
1059 _rotation_zone = NULL;