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;
57 typedef struct _Rotation_Zone
60 Eina_List *event_hdlrs;
62 Rotation_Effect *effect;
68 static Rotation_Zone *_rotation_zone = NULL;
71 _rotation_effect_ready_send(E_Zone *zone)
73 E_Event_Zone_Rotation_Effect_Ready *ev;
75 ev = E_NEW(E_Event_Zone_Rotation_Effect_Ready, 1);
79 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_READY, ev, NULL, NULL);
81 EFFINF("Rotation Effect Event Ready", NULL, NULL);
85 _rotation_effect_cancel_send(E_Zone *zone)
87 E_Event_Zone_Rotation_Effect_Cancel *ev;
89 ev = E_NEW(E_Event_Zone_Rotation_Effect_Cancel, 1);
93 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_CANCEL, ev, NULL, NULL);
95 EFFINF("Rotation Effect Event Cancel", NULL, NULL);
99 _rotation_effect_done_send(E_Zone *zone)
101 E_Event_Zone_Rotation_Effect_Done *ev;
103 ev = E_NEW(E_Event_Zone_Rotation_Effect_Done, 1);
107 ecore_event_add(E_EVENT_ZONE_ROTATION_EFFECT_DONE, ev, NULL, NULL);
109 EFFINF("Rotation Effect Event Done", NULL, NULL);
113 _rotation_effect_available(const E_Client *ec, int ang)
115 Eina_Bool ret = EINA_FALSE;
118 if (ang < 0) return EINA_FALSE;
119 if (!ec->e.state.rot.support)
122 if (ec->e.state.rot.preferred_rot == -1)
124 if (ec->e.state.rot.available_rots &&
125 ec->e.state.rot.count)
127 for (i = 0; i < ec->e.state.rot.count; i++)
129 if (ec->e.state.rot.available_rots[i] == ang)
139 else if (ec->e.state.rot.preferred_rot == ang)
148 _rotation_effect_targets_get(Rotation_Effect *effect)
158 if (!effect) return NULL;
160 if (effect->zone->display_state == E_ZONE_DISPLAY_STATE_OFF)
165 t = eina_tiler_new(effect->zone->w + edge, effect->zone->h + edge);
166 eina_tiler_tile_size_set(t, 1, 1);
168 EINA_RECTANGLE_SET(&r, effect->zone->x, effect->zone->y, effect->zone->w, effect->zone->h);
169 eina_tiler_rect_add(t, &r);
171 o = evas_object_top_get(e_comp->evas);
172 for (; o; o = evas_object_below_get(o))
174 if (!evas_object_visible_get(o)) continue;
175 if (o == effect->zone->over) continue;
176 if (o == effect->bg) continue;
177 if (evas_object_layer_get(o) > E_LAYER_EFFECT) continue;
178 if (!e_util_strcmp(evas_object_name_get(o), "layer_obj")) continue;
180 evas_object_geometry_get(o, &x, &y, &w, &h);
181 ec = evas_object_data_get(o, "E_Client");
184 if (e_object_is_del(E_OBJECT(ec))) continue;
185 if (!E_INTERSECTS(ec->x, ec->y, ec->w, ec->h, ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h))
187 if ((ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) &&
191 if ((!ec->animatable) ||
192 (e_client_video_client_has(ec)) ||
193 (!_rotation_effect_available(ec, effect->zone->rot.curr)) ||
194 (ec->e.state.rot.ang.curr == effect->zone->rot.curr))
196 if (l) eina_list_free(l);
202 l = eina_list_append(l, o);
204 if ((ec) && (ec->argb))
206 if (ec->visibility.opaque <= 0) continue;
209 if (ec->parent) continue;
213 EINA_RECTANGLE_SET(&r, x, y, w + edge, h + edge);
214 eina_tiler_rect_del(t, &r);
216 if (eina_tiler_empty(t)) break;
224 _rotation_effect_object_free(Rotation_Effect_Object *eobj)
230 evas_object_image_data_set(eobj->img, NULL);
233 if (eobj->img) evas_object_del(eobj->img);
234 if (eobj->data_pool) wl_shm_pool_unref(eobj->data_pool);
239 static Rotation_Effect_Object *
240 _rotation_effect_object_create(Evas_Object *o)
242 Rotation_Effect_Object *eobj;
243 E_Comp_Wl_Buffer *buffer = NULL;
244 Evas_Object *img = NULL;
248 void *data = NULL, *pix = NULL;
250 if (!evas_object_visible_get(o)) return NULL;
252 ec = evas_object_data_get(o, "E_Client");
255 if (e_object_is_del(E_OBJECT(ec))) return NULL;
257 eobj = E_NEW(Rotation_Effect_Object, 1);
258 if (!eobj) goto fail;
262 buffer = e_pixmap_resource_get(ec->pixmap);
263 if (!buffer) goto fail;
265 img = evas_object_image_filled_add(e_comp->evas);
266 e_util_size_debug_set(img, 1);
267 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
268 evas_object_image_smooth_scale_set(img, e_comp_config_get()->smooth_windows);
270 if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
272 if (!buffer->shm_buffer) goto fail;
277 pix = wl_shm_buffer_get_data(buffer->shm_buffer);
281 wl_shm_pool_unref(eobj->data_pool);
282 eobj->data_pool = wl_shm_buffer_ref_pool(buffer->shm_buffer);
284 else if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
286 tbm_surface_info_s surface_info;
287 tbm_surface_h tbm_surface = wayland_tbm_server_get_surface(NULL, buffer->resource);
288 memset(&surface_info, 0, sizeof(tbm_surface_info_s));
289 tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
291 data = surface_info.planes[0].ptr;
292 if (!data) goto fail;
294 w = surface_info.width;
295 h = surface_info.height;
297 pix = eobj->data = malloc(w * h * 4);
298 for (i = 0; i < h; i++)
300 memcpy(pix, data, surface_info.width * 4);
301 pix += surface_info.width * 4;
302 data += surface_info.planes[0].stride;
306 tbm_surface_unmap(tbm_surface);
308 else if (buffer->type == E_COMP_WL_BUFFER_TYPE_TBM)
310 tbm_surface_info_s surface_info;
311 tbm_surface_h tbm_surface = buffer->tbm_surface;
313 memset(&surface_info, 0, sizeof(tbm_surface_info_s));
314 tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &surface_info);
316 data = surface_info.planes[0].ptr;
317 if (!data) goto fail;
319 w = surface_info.width;
320 h = surface_info.height;
322 pix = eobj->data = malloc(w * h * 4);
323 for (i = 0; i < h; i++)
325 memcpy(pix, data, surface_info.width * 4);
326 pix += surface_info.width * 4;
327 data += surface_info.planes[0].stride;
331 tbm_surface_unmap(tbm_surface);
338 evas_object_image_alpha_set(img, 1);
339 evas_object_image_size_set(img, w, h);
340 evas_object_image_data_set(img, pix);
341 evas_object_image_data_update_add(img, 0, 0, w, h);
343 evas_object_name_set(img, "rotation-effect-image");
344 evas_object_move(img, ec->x, ec->y);
345 evas_object_resize(img, ec->w, ec->h);
350 EFFINF("Rotation EFFECT Object Created E_Client:%p",
358 eobj = E_NEW(Rotation_Effect_Object, 1);
359 if (!eobj) return NULL;
363 evas_object_geometry_get(o, &x, &y, &w, &h);
365 img = evas_object_image_filled_add(e_comp->evas);
366 e_util_size_debug_set(img, 1);
368 evas_object_image_colorspace_set(img, EVAS_COLORSPACE_ARGB8888);
369 evas_object_image_smooth_scale_set(img, e_comp_config_get()->smooth_windows);
370 evas_object_image_alpha_set(img, 1);
371 evas_object_image_size_set(img, w, h);
372 evas_object_image_source_set(img, o);
374 evas_object_name_set(img, "rotation-effect-image");
375 evas_object_move(img, x, y);
376 evas_object_resize(img, w, h);
380 EFFINF("Rotation EFFECT Object Created Object:%p",
389 evas_object_image_data_set(img, NULL);
390 evas_object_del(img);
396 wl_shm_pool_unref(eobj->data_pool);
404 static Rotation_Effect_Begin_Context *
405 _rotation_effect_begin_create(Rotation_Effect *effect, Eina_List *targets)
407 Rotation_Effect_Begin_Context *ctx_begin = NULL;
408 Rotation_Effect_Object *eobj = NULL;
413 ctx_begin = E_NEW(Rotation_Effect_Begin_Context, 1);
414 if (!ctx_begin) return NULL;
416 ctx_begin->layout = e_layout_add(e_comp->evas);
417 e_util_size_debug_set(ctx_begin->layout, 1);
418 evas_object_name_set(ctx_begin->layout, "rotation-begin-effect-layout");
419 e_layout_virtual_size_set(ctx_begin->layout, effect->zone->w, effect->zone->h);
420 evas_object_move(ctx_begin->layout, effect->zone->x, effect->zone->y);
421 evas_object_resize(ctx_begin->layout, effect->zone->w, effect->zone->h);
422 evas_object_layer_set(ctx_begin->layout, E_LAYER_EFFECT);
424 EINA_LIST_REVERSE_FOREACH(targets, l, target)
426 eobj = _rotation_effect_object_create(target);
429 ctx_begin->objects = eina_list_append(ctx_begin->objects, eobj);
431 effect->waiting_list = eina_list_append(effect->waiting_list, eobj->ec);
433 evas_object_geometry_get(target, &x, &y, &w, &h);
435 e_layout_pack(ctx_begin->layout, eobj->img);
436 e_layout_child_move(eobj->img, x, y);
437 e_layout_child_resize(eobj->img, w, h);
438 e_layout_child_raise(eobj->img);
439 evas_object_show(eobj->img);
442 if (!ctx_begin->objects)
444 evas_object_del(ctx_begin->layout);
449 EFFINF("Rotation Begin Created", NULL, NULL);
451 int diff = effect->zone->rot.prev - effect->zone->rot.curr;
452 if (diff == 270) diff = - 90;
453 else if (diff == -270) diff = 90;
454 ctx_begin->src = 0.0;
455 ctx_begin->dest = diff;
461 static Rotation_Effect_End_Context *
462 _rotation_effect_end_create(Rotation_Effect *effect, Eina_List *targets)
464 Rotation_Effect_End_Context *ctx_end = NULL;
465 Rotation_Effect_Object *eobj = NULL;
470 ctx_end = E_NEW(Rotation_Effect_End_Context, 1);
471 if (!ctx_end) return NULL;
473 ctx_end->layout = e_layout_add(e_comp->evas);
474 e_util_size_debug_set(ctx_end->layout, 1);
475 evas_object_name_set(ctx_end->layout, "rotation-end-effect-layout");
476 e_layout_virtual_size_set(ctx_end->layout, effect->zone->w, effect->zone->h);
477 evas_object_move(ctx_end->layout, effect->zone->x, effect->zone->y);
478 evas_object_resize(ctx_end->layout, effect->zone->w, effect->zone->h);
479 evas_object_layer_set(ctx_end->layout, E_LAYER_EFFECT);
481 EINA_LIST_REVERSE_FOREACH(targets, l, target)
483 eobj = _rotation_effect_object_create(target);
486 evas_object_geometry_get(target, &x, &y, &w, &h);
488 ctx_end->objects = eina_list_append(ctx_end->objects, eobj);
490 e_layout_pack(ctx_end->layout, eobj->img);
491 e_layout_child_move(eobj->img, x, y);
492 e_layout_child_resize(eobj->img, w, h);
493 e_layout_child_raise(eobj->img);
494 evas_object_show(eobj->img);
497 if (!ctx_end->objects)
499 evas_object_del(ctx_end->layout);
504 EFFINF("Rotation End Created", NULL, NULL);
506 int diff = _rotation_zone->curr_angle - _rotation_zone->prev_angle;
507 if (diff == 270) diff = - 90;
508 else if (diff == -270) diff = 90;
516 _rotation_effect_animator_begin_context_free(Rotation_Effect_Begin_Context *ctx_begin)
518 Rotation_Effect_Object *eobj;
520 if (!ctx_begin) return;
522 EFFINF("Rotation Begin Free", NULL, NULL);
524 if (ctx_begin->layout)
525 evas_object_hide(ctx_begin->layout);
527 EINA_LIST_FREE(ctx_begin->objects, eobj)
529 e_layout_unpack(eobj->img);
530 _rotation_effect_object_free(eobj);
533 if (ctx_begin->layout)
534 evas_object_del(ctx_begin->layout);
540 _rotation_effect_animator_end_context_free(Rotation_Effect_End_Context *ctx_end)
542 Rotation_Effect_Object *eobj;
544 if (!ctx_end) return;
546 EFFINF("Rotation End Free", NULL, NULL);
549 evas_object_hide(ctx_end->layout);
551 EINA_LIST_FREE(ctx_end->objects, eobj)
553 e_layout_unpack(eobj->img);
554 _rotation_effect_object_free(eobj);
558 evas_object_del(ctx_end->layout);
564 _rotation_effect_clear(Rotation_Effect *effect)
568 EFFINF("Rotation Effect Clear", NULL, NULL);
570 effect->targets = eina_list_free(effect->targets);
571 effect->waiting_list = eina_list_free(effect->waiting_list);
573 if (effect->animator)
574 ecore_animator_del(effect->animator);
576 evas_object_hide(effect->bg);
578 if (effect->ctx_begin)
580 _rotation_effect_animator_begin_context_free(effect->ctx_begin);
581 e_comp_override_del();
586 _rotation_effect_animator_end_context_free(effect->ctx_end);
587 _rotation_effect_done_send(effect->zone);
590 effect->running = EINA_FALSE;
591 effect->wait_for_buffer = EINA_FALSE;
592 effect->animator = NULL;
593 effect->ctx_begin = NULL;
594 effect->ctx_end = NULL;
598 _rotation_effect_animator_cb_update(void *data, double pos)
600 Rotation_Effect *effect;
601 Rotation_Effect_Begin_Context *ctx_begin;
602 Rotation_Effect_End_Context *ctx_end;
604 double curr, col, progress;
605 Evas_Coord x, y, w, h;
607 effect = (Rotation_Effect *)data;
608 ctx_begin = effect->ctx_begin;
609 ctx_end = effect->ctx_end;
613 ecore_animator_del(effect->animator);
614 effect->animator = NULL;
616 _rotation_effect_animator_begin_context_free(effect->ctx_begin);
617 effect->ctx_begin = NULL;
619 _rotation_effect_animator_end_context_free(effect->ctx_end);
620 effect->ctx_end = NULL;
622 effect->wait_for_buffer = EINA_FALSE;
623 effect->running = EINA_FALSE;
624 evas_object_hide(effect->bg);
626 e_comp_override_del();
627 _rotation_effect_done_send(effect->zone);
629 return ECORE_CALLBACK_CANCEL;
632 progress = ecore_animator_pos_map(pos, ECORE_POS_MAP_DECELERATE, 0, 0);
634 if (progress < 0.0) progress = 0.0;
637 curr = (progress * ctx_begin->dest);
638 col = 255 - (255 * progress);
640 evas_object_geometry_get(ctx_begin->layout, &x, &y, &w, &h);
642 Evas_Map *m = evas_map_new(4);
643 evas_map_util_points_populate_from_object(m, ctx_begin->layout);
644 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
645 evas_map_alpha_set(m, EINA_TRUE);
646 evas_map_util_points_color_set(m, col, col, col, col);
647 evas_object_map_set(ctx_begin->layout, m);
648 evas_object_map_enable_set(ctx_begin->layout, EINA_TRUE);
652 curr = ((-1.0f * progress * ctx_end->src) + ctx_end->src);
654 evas_object_geometry_get(ctx_end->layout, &x, &y, &w, &h);
657 evas_map_util_points_populate_from_object(m, ctx_end->layout);
658 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
659 evas_object_map_set(ctx_end->layout, m);
660 evas_object_map_enable_set(ctx_end->layout, EINA_TRUE);
663 return ECORE_CALLBACK_RENEW;
667 _rotation_effect_start(Rotation_Effect *effect)
669 if ((!effect->ctx_begin) || (!effect->ctx_end)) return;
670 if (effect->running) return;
672 EFFINF("Rotation Effect Start", NULL, NULL);
674 effect->running = EINA_TRUE;
676 evas_object_raise(effect->ctx_begin->layout);
677 evas_object_show(effect->ctx_begin->layout);
678 evas_object_show(effect->ctx_end->layout);
680 evas_object_move(effect->bg, 0, 0);
681 evas_object_resize(effect->bg, effect->zone->w, effect->zone->h);
682 evas_object_lower(effect->bg);
683 evas_object_show(effect->bg);
685 effect->animator = ecore_animator_timeline_add(0.3f,
686 _rotation_effect_animator_cb_update,
691 _rotation_effect_animator_begin_prepare(Rotation_Effect *effect)
695 _rotation_effect_clear(effect);
697 effect->targets = _rotation_effect_targets_get(effect);
698 if (!effect->targets) return;
700 effect->ctx_begin = _rotation_effect_begin_create(effect, effect->targets);
701 if (!effect->ctx_begin)
703 _rotation_effect_clear(effect);
707 EFFINF("Rotation Begin Prepared", NULL, NULL);
709 /* add hwc override */
710 e_comp_override_add();
714 _rotation_effect_animator_end_prepare(Rotation_Effect *effect)
717 if (!effect->targets) return;
718 if (!effect->ctx_begin) return;
720 /* clear previous context */
722 _rotation_effect_animator_end_context_free(effect->ctx_end);
723 effect->ctx_end = NULL;
725 effect->ctx_end = _rotation_effect_end_create(effect, effect->targets);
726 if (!effect->ctx_end) return;
728 EFFINF("Rotation End Prepared", NULL, NULL);
730 effect->targets = eina_list_free(effect->targets);
734 _rotation_effect_cb_zone_rotation_begin(void *data, int type, void *event)
736 Rotation_Effect *effect;
737 E_Event_Zone_Rotation_Change_Begin *ev = event;
740 effect = (Rotation_Effect *)data;
741 if (!effect) return ECORE_CALLBACK_PASS_ON;
744 if (!zone) return ECORE_CALLBACK_PASS_ON;
746 EFFINF("Zone rotation begin zone(prev:%d cur:%d)",
748 zone->rot.prev, zone->rot.curr);
750 if (zone->rot.prev == zone->rot.curr) return ECORE_CALLBACK_PASS_ON;
752 _rotation_zone->curr_angle = zone->rot.curr;
753 _rotation_zone->prev_angle = zone->rot.prev;
755 _rotation_effect_animator_begin_prepare(effect);
758 _rotation_effect_ready_send(zone);
760 return ECORE_CALLBACK_PASS_ON;
764 _rotation_effect_cb_zone_rotation_end(void *data, int type, void *event)
766 Rotation_Effect *effect;
767 E_Event_Zone_Rotation_Change_End *ev = event;
770 effect = (Rotation_Effect *)data;
771 if (!effect) return ECORE_CALLBACK_PASS_ON;
774 if (!zone) return ECORE_CALLBACK_PASS_ON;
776 EFFINF("Zone rotation end angle(prev:%d cur:%d)", NULL, NULL,
777 zone->rot.prev, zone->rot.curr);
779 if (effect->running) return ECORE_CALLBACK_PASS_ON;
780 if (effect->waiting_list)
782 effect->wait_for_buffer = EINA_TRUE;
783 return ECORE_CALLBACK_PASS_ON;
786 if (!effect->ctx_end)
788 _rotation_effect_animator_end_prepare(effect);
790 if (!effect->ctx_end)
791 _rotation_effect_clear(effect);
793 if (effect->ctx_end) _rotation_effect_start(effect);
795 return ECORE_CALLBACK_PASS_ON;
799 _rotation_effect_cb_zone_rotation_cancel(void *data, int type, void *event)
801 E_Event_Zone_Rotation_Change_Cancel *ev = event;
802 Rotation_Effect *effect;
806 if (!zone) return ECORE_CALLBACK_PASS_ON;
808 effect = (Rotation_Effect *)data;
809 if (!effect) return ECORE_CALLBACK_PASS_ON;
811 EFFINF("Zone Rotation Cancelled", NULL, NULL);
813 if (effect->running) return ECORE_CALLBACK_PASS_ON;
814 if (effect->targets) _rotation_effect_cancel_send(zone);
815 _rotation_effect_clear(effect);
817 return ECORE_CALLBACK_PASS_ON;
821 _rotation_effect_cb_buffer_change(void *data, int ev_type, void *event)
823 E_Event_Client *ev = event;
825 Rotation_Effect *effect;
828 if (!ec) return ECORE_CALLBACK_PASS_ON;
830 effect = (Rotation_Effect *)data;
831 if (!effect) return ECORE_CALLBACK_PASS_ON;
832 if (!effect->ctx_begin) return ECORE_CALLBACK_PASS_ON;
833 if (!effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
835 effect->waiting_list = eina_list_remove(effect->waiting_list, ec);
836 if (effect->waiting_list) return ECORE_CALLBACK_PASS_ON;
838 if (!effect->wait_for_buffer) return ECORE_CALLBACK_PASS_ON;
840 if (!effect->ctx_end) _rotation_effect_animator_end_prepare(effect);
841 if (effect->ctx_end) _rotation_effect_start(effect);
843 return ECORE_CALLBACK_PASS_ON;
847 _rotation_effect_cb_client_remove(void *data, int ev_type, void *event)
849 E_Event_Client *ev = event;
851 Rotation_Effect *effect;
852 Rotation_Effect_Object *eobj;
854 Eina_Bool clear = EINA_FALSE;
857 if (!ec) return ECORE_CALLBACK_PASS_ON;
859 effect = (Rotation_Effect *)data;
860 if (!effect) return ECORE_CALLBACK_PASS_ON;
861 if (effect->ctx_begin)
863 EINA_LIST_FOREACH(effect->ctx_begin->objects, l, eobj)
873 _rotation_effect_clear(effect);
876 return ECORE_CALLBACK_PASS_ON;
880 _rotation_effect_free(Rotation_Effect *effect)
884 _rotation_effect_clear(effect);
885 evas_object_del(effect->bg);
889 static Rotation_Effect *
890 _rotation_effect_create(E_Zone *zone)
892 Rotation_Effect *rotation_effect;
894 rotation_effect = E_NEW(Rotation_Effect, 1);
895 if (!rotation_effect) return NULL;
897 rotation_effect->zone = zone;
899 rotation_effect->bg = evas_object_rectangle_add(e_comp->evas);
900 e_util_size_debug_set(rotation_effect->bg, 1);
901 evas_object_color_set(rotation_effect->bg, 0, 0, 0, 255);
902 evas_object_layer_set(rotation_effect->bg, E_LAYER_EFFECT);
903 evas_object_name_set(rotation_effect->bg, "rotation-bg");
905 return rotation_effect;
909 _rotation_zone_free(Rotation_Zone *rotation_zone)
911 if (!rotation_zone) return;
913 E_FREE_LIST(rotation_zone->event_hdlrs, ecore_event_handler_del);
915 _rotation_effect_free(rotation_zone->effect);
917 E_FREE(rotation_zone);
922 static Rotation_Zone *
923 _rotation_zone_create(E_Zone *zone)
925 Rotation_Zone *rotation_zone = NULL;
927 if (!zone) return NULL;
928 if ((zone->w == 0) || (zone->h == 0)) return NULL;
930 rotation_zone = E_NEW(Rotation_Zone, 1);
931 if (!rotation_zone) return NULL;
933 /* create rotation effect data */
934 rotation_zone->effect = _rotation_effect_create(zone);
935 if (!rotation_zone->effect)
937 E_FREE(rotation_zone);
941 rotation_zone->zone = zone;
942 rotation_zone->curr_angle = zone->rot.curr;
943 rotation_zone->prev_angle = zone->rot.prev;
945 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
946 E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
947 _rotation_effect_cb_zone_rotation_begin, rotation_zone->effect);
949 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
950 E_EVENT_ZONE_ROTATION_CHANGE_END,
951 _rotation_effect_cb_zone_rotation_end, rotation_zone->effect);
953 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
954 E_EVENT_ZONE_ROTATION_CHANGE_CANCEL,
955 _rotation_effect_cb_zone_rotation_cancel, rotation_zone->effect);
957 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
958 E_EVENT_CLIENT_BUFFER_CHANGE,
959 _rotation_effect_cb_buffer_change, rotation_zone->effect);
961 E_LIST_HANDLER_APPEND(rotation_zone->event_hdlrs,
962 E_EVENT_CLIENT_REMOVE,
963 _rotation_effect_cb_client_remove, rotation_zone->effect);
965 return rotation_zone;
969 e_mod_effect_rotation_init(void)
971 _rotation_zone = _rotation_zone_create(e_zone_current_get());
972 if (!_rotation_zone) return EINA_FALSE;
978 e_mod_effect_rotation_shutdown(void)
981 _rotation_zone_free(_rotation_zone);
983 _rotation_zone = NULL;