tizen 2.4 release
[framework/uifw/e17-mod-tizen-comp.git] / src / effect / effect_win_rotation.c
1 #include "e_mod_comp_shared_types.h"
2 #include "e_mod_comp.h"
3 #include "e_mod_comp_atoms.h"
4 #include "e_mod_comp_debug.h"
5 #include "e_mod_comp_effect_win_rotation.h"
6 #include <Elementary.h>
7
8 #include "effect.h"
9 #include "effect_image_launch.h"
10 #include "effect_win_rotation.h"
11
12 /* local subsystem functions */
13 static void                _on_trans_begin_end(void *data, Elm_Transit *transit __UNUSED__);
14 static void                _on_trans_end_end(void *data, Elm_Transit *transit __UNUSED__);
15 static Eina_Bool           _angle_get(E_Comp_Win *cw, int *req, int *curr);
16 static Eina_Bool           _effect_zone_rot_bd_check(E_Border *bd);
17 static Elm_Transit_Effect *_effect_zone_rot_begin_new(E_Comp_Layer *ly, Eina_Bool xv_use);
18 static Elm_Transit_Effect *_effect_zone_rot_end_new(E_Comp_Layer *ly, E_Zone *zone, Eina_Bool xv_use);
19 static void                _effect_zone_rot_begin_free(Elm_Transit_Effect *effect, Elm_Transit *transit);
20 static void                _effect_zone_rot_end_free(Elm_Transit_Effect *effect, Elm_Transit *transit);
21 static void                _effect_zone_rot_begin_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress);
22 static void                _effect_zone_rot_end_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress);
23 static Eina_Bool           _effect_zone_rot_clear(E_Comp_Effect_Zone_Rotation *zr);
24
25 /* externally accessible functions */
26 Eina_Bool
27 _effect_mod_win_angle_get(E_Comp_Win *cw)
28 {
29    E_Comp_Effect_Style st;
30    int req_angle = -1;
31    int cur_angle = -1;
32    Eina_Bool res;
33    Ecore_X_Window win;
34    E_CHECK_RETURN(cw, 0);
35
36    win = e_mod_comp_util_client_xid_get(cw);
37    st = _effect_mod_style_get
38       (cw->eff_type,
39        E_COMP_EFFECT_KIND_ROTATION);
40
41    if (st == E_COMP_EFFECT_STYLE_NONE)
42      return EINA_FALSE;
43
44    res = _angle_get(cw, &req_angle, &cur_angle);
45    if (!res)
46      return EINA_FALSE;
47
48    cw->angle = cur_angle;
49    cw->angle %= 360;
50
51    return EINA_TRUE;
52 }
53
54 E_Comp_Effect_Zone_Rotation *
55 _effect_mod_zone_rotation_new(E_Comp_Canvas *canvas)
56 {
57    E_Comp_Effect_Zone_Rotation *zr = NULL;
58    zr = E_NEW(E_Comp_Effect_Zone_Rotation, 1);
59    E_CHECK_RETURN(zr, NULL);
60
61    zr->canvas = canvas;
62    memset(canvas->xv_ready, 0, sizeof(canvas->xv_ready));
63
64    return zr;
65 }
66
67 void
68 _effect_mod_zone_rotation_free(E_Comp_Effect_Zone_Rotation *zr)
69 {
70    E_FREE(zr);
71 }
72
73 Eina_Bool
74 _effect_mod_zone_rotation_begin(E_Comp_Effect_Zone_Rotation *zr)
75 {
76    E_Comp_Layer *ly;
77    E_Comp *c = e_mod_comp_util_get();
78
79    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.zone.rotation.begin");
80
81    E_CHECK_GOTO(c->animatable, finish);
82
83    E_Comp_Win *cw = NULL, *nocomp_cw = NULL;
84    E_Zone *zone = NULL;
85    E_Comp_Canvas *canvas = NULL;
86
87    Eina_Bool res = EINA_FALSE;
88
89    Ecore_X_Window root = c->man->root;
90    int xv_prop_res = -1;
91    unsigned int xv_use = 0;
92
93    canvas = zr->canvas;
94
95    zone = zr->canvas->zone;
96    E_CHECK_GOTO(zone, finish);
97
98    /* find nocomp window first because nocomp window doesn't have pixmap */
99    nocomp_cw = e_mod_comp_util_win_nocomp_get(c, zone);
100
101    /* Check whether or not it will do xv rotation effect. */
102    xv_prop_res =  ecore_x_window_prop_card32_get(root, ATOM_XV_USE, &xv_use, 1);
103    if ((xv_prop_res == -1 ) || (!xv_use))
104      {
105         zr->xv_use = EINA_FALSE;
106         canvas->xv_ready[0] = EINA_FALSE;
107      }
108    else
109      {
110         if (!_comp_mod->conf->xv_rotation_effect)
111           {
112              zr->xv_use = EINA_FALSE;
113              canvas->xv_ready[0] = EINA_FALSE;
114              goto finish;
115           }
116      }
117
118    /* if it is first entering to effect begin route and xv is running,
119     * rotation effect is canceled at first and waits until xv pass pixmap0.
120     */
121    if ((!zr->xv_use) && (xv_prop_res >= 0) && (xv_use))
122      {
123         Ecore_X_Pixmap pix0 = 0, pix1 = 0;
124         zr->xv_use = EINA_TRUE;
125         zr->canvas->xv_ready[0] = EINA_TRUE;
126
127         pix0 = ecore_x_pixmap_new(root, zone->w, zone->h, 24);
128         ecore_x_window_prop_xid_set(root, ATOM_XV_PIXMAP0, ECORE_X_ATOM_PIXMAP, &pix0, 1);
129
130         pix1 = ecore_x_pixmap_new(root, zone->w, zone->h, 24);
131         ecore_x_window_prop_xid_set(root, ATOM_XV_PIXMAP1, ECORE_X_ATOM_PIXMAP, &pix1, 1);
132
133         ecore_x_client_message32_send(root,
134                                       ATOM_XV_BYPASS_TO_PIXMAP0,
135                                       ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
136                                       root, 0, 0, 0, 0);
137
138         ecore_x_client_message32_send(root,
139                                       ATOM_XV_BYPASS_TO_PIXMAP1,
140                                       ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
141                                       root, 0, 0, 0, 0);
142
143         goto finish;
144      }
145
146    if (_effect_mod_image_launch_running_check(c->eff_img))
147      goto finish;
148
149    /* look for visible normal window except for given window */
150    EINA_INLIST_REVERSE_FOREACH(c->wins, cw)
151      {
152         if ((cw->invalid) || (cw->input_only)) continue;
153         if (!cw->bd) continue;
154         if (!cw->bd->zone) continue;
155         if (cw->bd->zone != zone) continue;
156         if (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
157                           cw->x, cw->y, cw->w, cw->h))
158           continue;
159
160         /* return nocomp window */
161         if ((nocomp_cw) && (nocomp_cw == cw))
162           {
163              if (TYPE_LOCKSCREEN_CHECK(cw))
164                {
165                   ELB(ELBT_COMP, "SKIP LOCKSCREEN", e_mod_comp_util_client_xid_get(cw));
166                   goto finish;
167                }
168              else
169                {
170                   if (cw->bd)
171                     {
172                        res = _effect_zone_rot_bd_check(cw->bd);
173                        E_CHECK_GOTO(res, finish);
174                     }
175
176                   Eina_Bool animatable = EINA_FALSE;
177                   animatable = _effect_mod_state_get(cw->eff_type);
178                   E_CHECK_GOTO(animatable, finish);
179                   break; /* do rotation effect */
180                }
181           }
182
183         /* check pixmap and compare size with zone */
184         if (!((cw->pixmap) && (cw->pw > 0) && (cw->ph > 0) &&
185               (cw->dmg_updates >= 1)))
186           continue;
187
188         if (REGION_EQUAL_TO_ZONE(cw, zone))
189           {
190              if (cw->argb)
191                {
192                   /* except the lock screen window */
193                   if (TYPE_LOCKSCREEN_CHECK(cw))
194                     {
195                        ELB(ELBT_COMP, "SKIP LOCKSCREEN", e_mod_comp_util_client_xid_get(cw));
196                        goto finish;
197                     }
198                   else
199                     {
200                        if (cw->bd)
201                          {
202                             res = _effect_zone_rot_bd_check(cw->bd);
203                             E_CHECK_GOTO(res, finish);
204                          }
205                        else
206                          continue;
207                     }
208                }
209              else
210                {
211                   if (cw->bd)
212                     {
213                        res = _effect_zone_rot_bd_check(cw->bd);
214                        E_CHECK_GOTO(res, finish);
215                     }
216
217                   Eina_Bool animatable = EINA_FALSE;
218                   animatable = _effect_mod_state_get(cw->eff_type);
219                   E_CHECK_GOTO(animatable, finish);
220                   break; /* do rotation effect */
221                }
222           }
223         else
224           {
225              /* block effect of desk layout */
226              if ((cw->bd) &&
227                  (cw->bd->client.e.state.ly.support) &&
228                  (cw->bd->client.e.state.ly.curr_ly))
229                {
230                   goto finish;
231                }
232           }
233      }
234
235    ly = e_mod_comp_canvas_layer_get(zr->canvas, "effect");
236    if (ly)
237      {
238         /* TODO: check animation is running */
239         if (zr->trans_begin)
240           {
241              elm_transit_del_cb_set(zr->trans_begin, NULL, NULL);
242              elm_transit_del(zr->trans_begin);
243           }
244         if (zr->trans_end)
245           {
246              elm_transit_del_cb_set(zr->trans_end, NULL, NULL);
247              elm_transit_del(zr->trans_end);
248           }
249         zr->trans_begin = NULL;
250         zr->trans_end = NULL;
251         zr->trans_begin = elm_transit_add();
252         elm_transit_del_cb_set(zr->trans_begin, _on_trans_begin_end, zr);
253
254         zr->effect_begin = _effect_zone_rot_begin_new(ly, zr->xv_use);
255         if (!zr->effect_begin)
256           {
257              if (zr->trans_begin)
258                {
259                   elm_transit_del_cb_set(zr->trans_begin, NULL, NULL);
260                   elm_transit_del(zr->trans_begin);
261                }
262              zr->trans_begin = NULL;
263              zr->ready = EINA_FALSE;
264              zr->xv_use = EINA_FALSE;
265              goto finish;
266           }
267         elm_transit_object_add(zr->trans_begin, ly->layout);
268         elm_transit_smooth_set(zr->trans_begin, EINA_FALSE);
269         elm_transit_duration_set(zr->trans_begin, 0.2f);
270         elm_transit_effect_add(zr->trans_begin, _effect_zone_rot_begin_op, zr->effect_begin, _effect_zone_rot_begin_free);
271         elm_transit_tween_mode_set(zr->trans_begin, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
272         elm_transit_objects_final_state_keep_set(zr->trans_begin, EINA_FALSE);
273
274         e_mod_comp_layer_effect_set(ly, EINA_TRUE);
275
276         if (_comp_mod->conf->use_hwc)
277           {
278              if (canvas->comp->hwcomp_funcs.set_full_composite)
279                 canvas->comp->hwcomp_funcs.set_full_composite(canvas->hwcomp);
280              if (canvas->comp->hwcomp_funcs.update_null_set_drawables)
281                 canvas->comp->hwcomp_funcs.update_null_set_drawables(canvas->hwcomp);
282           }
283
284         zr->ready = EINA_TRUE;
285      }
286
287    return EINA_TRUE;
288
289 finish:
290    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.effect.rotation.cancel");
291    return EINA_FALSE;
292 }
293
294 Eina_Bool
295 _effect_mod_zone_rotation_end(E_Comp_Effect_Zone_Rotation *zr)
296 {
297    E_Comp_Layer *ly;
298    E_Comp *c = e_mod_comp_util_get();
299    Eina_Bool xv_use = EINA_FALSE;
300
301    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.zone.rotation.end");
302
303    E_CHECK_RETURN(c->animatable, EINA_FALSE);
304
305    if ((!zr->ready) || (!zr->trans_begin))
306      {
307         zr->canvas->xv_ready[0] = EINA_FALSE;
308         return EINA_FALSE;
309      }
310
311    if ((zr->canvas->xv_ready[0]) && (!((zr->canvas->xv_ready[1]) && (zr->canvas->xv_ready[2]))))
312      return EINA_FALSE;
313
314    zr->ready = EINA_FALSE;
315    xv_use = zr->xv_use;
316    zr->xv_use = EINA_FALSE;
317    memset(zr->canvas->xv_ready, 0, sizeof(zr->canvas->xv_ready));
318
319    ly = e_mod_comp_canvas_layer_get(zr->canvas, "comp");
320    if (ly)
321      {
322         if (zr->trans_end)
323           {
324              elm_transit_del_cb_set(zr->trans_end, NULL, NULL);
325              elm_transit_del(zr->trans_end);
326           }
327         zr->trans_end = NULL;
328         zr->trans_end = elm_transit_add();
329         elm_transit_del_cb_set(zr->trans_end, _on_trans_end_end, zr);
330         zr->effect_end = _effect_zone_rot_end_new(ly, zr->canvas->zone, xv_use);
331         elm_transit_object_add(zr->trans_end, ly->layout);
332         elm_transit_smooth_set(zr->trans_end, EINA_FALSE);
333         elm_transit_duration_set(zr->trans_end, 0.2f);
334         elm_transit_effect_add(zr->trans_end, _effect_zone_rot_end_op, zr->effect_end, _effect_zone_rot_end_free);
335         elm_transit_tween_mode_set(zr->trans_end, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
336         elm_transit_objects_final_state_keep_set(zr->trans_end, EINA_FALSE);
337
338         e_zone_rotation_block_set(zr->canvas->zone, "comp-tizen", EINA_TRUE);
339
340         return EINA_TRUE;
341      }
342
343    return EINA_FALSE;
344 }
345
346 Eina_Bool
347 _effect_mod_zone_rotation_cancel(E_Comp_Effect_Zone_Rotation *zr)
348 {
349    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.zone.rotation.cancel");
350    return _effect_zone_rot_clear(zr);
351 }
352
353 Eina_Bool
354 _effect_mod_zone_rotation_do(E_Comp_Effect_Zone_Rotation *zr)
355 {
356    E_Comp *c = e_mod_comp_util_get();
357    E_CHECK_RETURN(c->animatable, EINA_FALSE);
358
359    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.effect.rotation.start");
360
361    elm_transit_go(zr->trans_begin);
362    elm_transit_go(zr->trans_end);
363
364    return EINA_TRUE;
365 }
366
367 Eina_Bool
368 _effect_mod_zone_rotation_clear(E_Comp_Effect_Zone_Rotation *zr)
369 {
370    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.effect.rotation.cancel");
371    return _effect_zone_rot_clear(zr);
372 }
373
374 static Eina_Bool
375 _effect_zone_rot_clear(E_Comp_Effect_Zone_Rotation *zr)
376 {
377    if (zr->trans_begin)
378      {
379         elm_transit_del_cb_set(zr->trans_begin, NULL, NULL);
380         elm_transit_del(zr->trans_begin);
381         zr->trans_begin = NULL;
382      }
383    if (zr->trans_end)
384      {
385         elm_transit_del_cb_set(zr->trans_end, NULL, NULL);
386         elm_transit_del(zr->trans_end);
387         zr->trans_end = NULL;
388      }
389    zr->ready = EINA_FALSE;
390    zr->xv_use = EINA_FALSE;
391
392    return EINA_TRUE;
393 }
394
395 static void
396 _on_trans_begin_end(void *data,
397                         Elm_Transit *transit __UNUSED__)
398 {
399    E_Comp_Effect_Zone_Rotation *zr = data;
400    zr->trans_begin = NULL;
401    if (zr->trans_begin)
402      {
403         elm_transit_del_cb_set(zr->trans_begin, NULL, NULL);
404         zr->trans_begin = NULL;
405      }
406 }
407
408 static void
409 _on_trans_end_end(void *data,
410                         Elm_Transit *transit __UNUSED__)
411 {
412    E_Comp_Effect_Zone_Rotation *zr = data;
413    if (zr->trans_end)
414      {
415         elm_transit_del_cb_set(zr->trans_end, NULL, NULL);
416         zr->trans_end = NULL;
417      }
418 }
419
420 /* local subsystem functions */
421 static Eina_Bool
422 _angle_get(E_Comp_Win *cw,
423            int        *req,
424            int        *curr)
425 {
426    E_CHECK_RETURN(cw->bd, 0);
427    E_CHECK_RETURN(req, 0);
428    E_CHECK_RETURN(curr, 0);
429
430    *req  = e_border_rotation_prev_angle_get(cw->bd);
431    *curr = e_border_rotation_curr_angle_get(cw->bd);
432
433    return EINA_TRUE;
434 }
435
436 /* check before running rotation effect for given normal window.
437  * exceptional windows: lock, setup wizard
438  * otherwise: do rotation effect
439  */
440 static Eina_Bool
441 _effect_zone_rot_bd_check(E_Border *bd)
442 {
443    /* except window which does not use the wm rotation */
444    if (!bd->client.e.state.rot.app_set)
445      {
446         ELB(ELBT_COMP, "SKIP ROT_EFFECT app_set:0", bd->client.win);
447         return EINA_FALSE;
448      }
449    /* except window which has the value of preferred rotation */
450    else if (bd->client.e.state.rot.preferred_rot != -1)
451      {
452         ELB(ELBT_COMP, "SKIP ROT_EFFECT preferred_rot", bd->client.win);
453         return EINA_FALSE;
454      }
455
456    return EINA_TRUE;
457 }
458
459
460 static Elm_Transit_Effect *
461 _effect_zone_rot_begin_new(E_Comp_Layer *ly,
462                            Eina_Bool xv_use)
463 {
464    E_Comp_Zone_Rotation_Effect_Begin *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_Begin, 1);
465    E_CHECK_RETURN(ctx, NULL);
466
467    Evas_Native_Surface ns;
468
469    E_Zone *zone = ly->canvas->zone;
470
471    /* capture the screen */
472    Ecore_X_Window_Attributes att;
473    Ecore_X_Window root = ecore_x_window_root_first_get();
474    memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
475    if (!ecore_x_window_attributes_get(root, &att))
476      {
477         E_FREE(ctx);
478         return NULL;
479      }
480
481    ctx->xim = ecore_x_image_new(zone->w, zone->h, att.visual, att.depth);
482    if (!ctx->xim)
483      {
484         E_FREE(ctx);
485         return NULL;
486      }
487
488    unsigned int *pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
489    ELBF(ELBT_COMP, 0, 0, "%15.15s|root:0x%08x vis:%p depth:%d xim:%p pix:%p", "ZONE_ROT_B_NEW",
490         root, att.visual, att.depth, ctx->xim, pix);
491
492    ctx->img = evas_object_image_filled_add(evas_object_evas_get(ly->layout));
493    evas_object_image_colorspace_set(ctx->img, EVAS_COLORSPACE_ARGB8888);
494    evas_object_image_alpha_set(ctx->img, 1);
495    evas_object_render_op_set(ctx->img, EVAS_RENDER_COPY);
496    evas_object_image_size_set(ctx->img, zone->w, zone->h);
497    evas_object_image_smooth_scale_set(ctx->img, EINA_FALSE);
498    evas_object_image_data_set(ctx->img, pix);
499    evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
500
501    // why do we neeed these 2? this smells wrong
502    if (ecore_x_image_get(ctx->xim, root, 0, 0, 0, 0, zone->w, zone->h))
503      {
504         pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
505         evas_object_image_data_set(ctx->img, pix);
506         evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
507      }
508
509    if (xv_use)
510      {
511         int ret = -1;
512         int pw = 0, ph = 0;
513         ctx->xv_pix = 0;
514
515         ret = ecore_x_window_prop_xid_get(root, ATOM_XV_PIXMAP0, ECORE_X_ATOM_PIXMAP, &ctx->xv_pix, 1);
516
517         if (ret < 0)
518           ctx->xv_pix = ecore_x_pixmap_new(root, zone->w, zone->h, 32);
519
520         ecore_x_pixmap_geometry_get(ctx->xv_pix, NULL, NULL, &pw, &ph);
521
522         ns.version = EVAS_NATIVE_SURFACE_VERSION;
523         ns.type = EVAS_NATIVE_SURFACE_X11;
524         ns.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
525         ns.data.x11.pixmap = ctx->xv_pix;
526
527         ctx->xv_img = evas_object_image_filled_add(ly->canvas->evas);
528         evas_object_image_size_set(ctx->xv_img, pw, ph);
529         evas_object_image_smooth_scale_set(ctx->xv_img, EINA_FALSE);
530         evas_object_image_native_surface_set(ctx->xv_img, &ns);
531         evas_object_image_data_update_add(ctx->xv_img, 0, 0, zone->w, zone->h);
532
533         evas_object_show(ctx->xv_img);
534
535         e_layout_pack(ly->layout, ctx->xv_img);
536         e_layout_child_move(ctx->xv_img, 0, 0);
537         e_layout_child_resize(ctx->xv_img, zone->w, zone->h);
538      }
539
540    evas_object_show(ctx->img);
541
542    e_mod_comp_layer_populate(ly, ctx->img);
543    e_layout_child_move(ctx->img, 0, 0);
544    e_layout_child_resize(ctx->img, zone->w, zone->h);
545
546    ctx->o = ly->layout;
547    ctx->zone = ly->canvas->zone;
548    ctx->ly = ly;
549
550    int diff = zone->rot.prev - zone->rot.curr;
551    if (diff == 270) diff = -90;
552    else if (diff == -270) diff = 90;
553    ctx->src = 0.0;
554    ctx->target = diff;
555    ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d pix:%p", "ZONE_ROT_B_NEW", zone->rot.prev, zone->rot.curr, pix);
556    return ctx;
557 }
558
559 static Elm_Transit_Effect *
560 _effect_zone_rot_end_new(E_Comp_Layer *ly,
561                          E_Zone       *zone,
562                          Eina_Bool     xv_use)
563 {
564    E_Comp_Zone_Rotation_Effect_End *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_End, 1);
565    E_CHECK_RETURN(ctx, NULL);
566
567    Evas_Native_Surface ns;
568
569    Ecore_X_Window root = ecore_x_window_root_first_get();
570
571    if (xv_use)
572      {
573         int ret = -1;
574         ctx->xv_pix = 0;
575
576         ret = ecore_x_window_prop_xid_get(root, ATOM_XV_PIXMAP1, ECORE_X_ATOM_PIXMAP, &ctx->xv_pix, 1);
577
578         if (ret < 0)
579           ctx->xv_pix = ecore_x_pixmap_new(root, zone->w, zone->h, 24);
580
581         ns.version = EVAS_NATIVE_SURFACE_VERSION;
582         ns.type = EVAS_NATIVE_SURFACE_X11;
583         ns.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
584         ns.data.x11.pixmap = ctx->xv_pix;
585
586         ctx->xv_img = evas_object_image_filled_add(evas_object_evas_get(ly->layout));
587         evas_object_image_size_set(ctx->xv_img, zone->w, zone->h);
588         evas_object_image_smooth_scale_set(ctx->xv_img, EINA_FALSE);
589         evas_object_image_native_surface_set(ctx->xv_img, &ns);
590         evas_object_image_data_update_add(ctx->xv_img, 0, 0, zone->w, zone->h);
591
592 //        evas_object_show(ctx->xv_img);
593
594         e_layout_pack(ly->layout, ctx->xv_img);
595         e_layout_child_move(ctx->xv_img, 0, 0);
596         e_layout_child_resize(ctx->xv_img, zone->w, zone->h);
597
598         ctx->send_msg = EINA_TRUE;
599      }
600
601    ctx->o = ly->layout;
602    ctx->zone = zone;
603    int diff = zone->rot.curr - zone->rot.prev;
604    if (diff == 270) diff = -90;
605    else if (diff == -270) diff = 90;
606    ctx->src = diff;
607    ctx->target = 0.0;
608    ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d", "ZONE_ROTATION_EFFECT_END_NEW", zone->rot.prev, zone->rot.curr);
609    return ctx;
610 }
611
612 static void
613 _effect_zone_rot_begin_free(Elm_Transit_Effect *effect,
614                             Elm_Transit        *transit)
615 {
616    E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
617    if (ctx->xim) ecore_x_image_free(ctx->xim);
618    if (ctx->xv_img)
619      {
620         evas_object_image_native_surface_set(ctx->xv_img, NULL);
621         evas_object_image_size_set(ctx->xv_img, 1, 1);
622         evas_object_image_data_set(ctx->xv_img, NULL);
623
624         if (ctx->xv_pix)
625           {
626              ecore_x_pixmap_free(ctx->xv_pix);
627              ctx->xv_pix = 0;
628           }
629
630         evas_object_hide(ctx->xv_img);
631         e_layout_unpack(ctx->xv_img);
632         evas_object_del(ctx->xv_img);
633         ctx->xv_img = NULL;
634      }
635    if (ctx->img)
636      {
637         evas_object_hide(ctx->img);
638         e_layout_unpack(ctx->img);
639         evas_object_del(ctx->img);
640         ctx->img = NULL;
641      }
642
643    //evas_object_color_set(ctx->o, 255, 255, 255, 255);
644
645    e_mod_comp_layer_effect_set(ctx->ly, EINA_FALSE);
646
647    E_FREE(ctx);
648 }
649
650 static void
651 _effect_zone_rot_end_free(Elm_Transit_Effect *effect,
652                           Elm_Transit        *transit)
653 {
654    E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
655    e_zone_rotation_block_set(ctx->zone, "comp-tizen", EINA_FALSE);
656    evas_object_color_set(ctx->o, 255, 255, 255, 255);
657
658    if (ctx->xv_img)
659      {
660         evas_object_image_native_surface_set(ctx->xv_img, NULL);
661         evas_object_image_size_set(ctx->xv_img, 1, 1);
662         evas_object_image_data_set(ctx->xv_img, NULL);
663
664         if (ctx->xv_pix)
665           {
666              ecore_x_pixmap_free(ctx->xv_pix);
667              ctx->xv_pix = 0;
668           }
669
670         evas_object_hide(ctx->xv_img);
671         e_layout_unpack(ctx->xv_img);
672         evas_object_del(ctx->xv_img);
673         ctx->xv_img = NULL;
674      }
675
676    if (ctx->send_msg)
677      {
678         ecore_x_client_message32_send(ecore_x_window_root_first_get(),
679                                       ATOM_XV_ROT_EFFECT_DONE,
680                                       ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
681                                       ecore_x_window_root_first_get(), 0, 0, 0, 0);
682      }
683
684    e_mod_comp_util_rr_prop_set(ATOM_RR_WM_STATE, "wm.effect.rotation.finish");
685
686    ELBF(ELBT_COMP, 0, 0, "%15.15s|", "ZONE_ROTATION_EFFECT_END_FREE");
687    E_FREE(ctx);
688 }
689
690 static void
691 _effect_zone_rot_begin_op(Elm_Transit_Effect *effect,
692                           Elm_Transit        *transit,
693                           double              progress)
694 {
695    E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
696    if (progress < 0.0) progress = 0.0;
697    double curr = (progress * ctx->target);
698    Evas_Coord x, y, w, h;
699
700    double col = 255 - (255 * progress);
701    if (col <= 0) col = 0;
702
703    evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
704
705    Evas_Map *m = evas_map_new(4);
706    evas_map_util_points_populate_from_object(m, ctx->o);
707    evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
708    evas_map_alpha_set(m, EINA_TRUE);
709    evas_map_util_points_color_set(m, col, col, col, col);
710    evas_object_map_set(ctx->o, m);
711    evas_object_map_enable_set(ctx->o, EINA_TRUE);
712    evas_map_free(m);
713
714    /* to notify beginning of xv rotation effect */
715    if ((ctx->xv_img) && (!ctx->init) && (progress >= 0.1))
716      {
717         E_Comp *c = e_mod_comp_util_get();
718         ecore_x_client_message32_send(c->man->root,
719                                       ATOM_XV_ROT_EFFECT_BEGIN,
720                                       ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
721                                       c->man->root, 0, 0, 0, 0);
722         ctx->init = EINA_TRUE;
723      }
724
725
726 }
727
728 static void
729 _effect_zone_rot_end_op(Elm_Transit_Effect *effect,
730                         Elm_Transit        *transit,
731                         double              progress)
732 {
733    E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
734    if (progress < 0.0) progress = 0.0;
735    double curr = ((-1.0f * progress * ctx->src) + ctx->src);
736    Evas_Coord x, y, w, h;
737
738    evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
739
740    Evas_Map *m = evas_map_new(4);
741    evas_map_util_points_populate_from_object(m, ctx->o);
742    evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
743    evas_object_map_set(ctx->o, m);
744    evas_object_map_enable_set(ctx->o, EINA_TRUE);
745    evas_map_free(m);
746
747    /* to avoid exposing "comp" layer before rotation effect running */
748    if ((ctx->xv_img) && (!ctx->init) && (progress >= 0.1))
749      {
750         evas_object_show(ctx->xv_img);
751         ctx->init = EINA_TRUE;
752      }
753 }