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>
8 typedef struct _E_Comp_Zone_Rotation_Effect_Begin E_Comp_Zone_Rotation_Effect_Begin;
9 typedef struct _E_Comp_Zone_Rotation_Effect_End E_Comp_Zone_Rotation_Effect_End;
11 struct _E_Comp_Effect_Zone_Rotation
13 E_Comp_Canvas *canvas;
16 Elm_Transit *trans_begin;
17 Elm_Transit *trans_end;
18 Elm_Transit_Effect *effect_begin;
19 Elm_Transit_Effect *effect_end;
22 struct _E_Comp_Zone_Rotation_Effect_Begin
33 struct _E_Comp_Zone_Rotation_Effect_End
41 /* local subsystem functions */
42 static Eina_Bool _angle_get(E_Comp_Win *cw, int *req, int *curr);
43 static Elm_Transit_Effect *_effect_zone_rot_begin_new(E_Comp_Layer *ly);
44 static Elm_Transit_Effect *_effect_zone_rot_end_new(Evas_Object *o, E_Zone *zone);
45 static void _effect_zone_rot_begin_free(Elm_Transit_Effect *effect, Elm_Transit *transit);
46 static void _effect_zone_rot_end_free(Elm_Transit_Effect *effect, Elm_Transit *transit);
47 static void _effect_zone_rot_begin_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress);
48 static void _effect_zone_rot_end_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress);
50 /* externally accessible functions */
52 e_mod_comp_effect_win_angle_get(E_Comp_Win *cw)
54 E_Comp_Effect_Style st;
59 E_CHECK_RETURN(cw, 0);
61 win = e_mod_comp_util_client_xid_get(cw);
62 st = e_mod_comp_effect_style_get
64 E_COMP_EFFECT_KIND_ROTATION);
66 if (st == E_COMP_EFFECT_STYLE_NONE)
69 res = _angle_get(cw, &req_angle, &cur_angle);
73 cw->angle = cur_angle;
79 EINTERN E_Comp_Effect_Zone_Rotation *
80 e_mod_comp_effect_zone_rotation_new(E_Comp_Canvas *canvas)
82 E_Comp_Effect_Zone_Rotation *zr = NULL;
83 zr = E_NEW(E_Comp_Effect_Zone_Rotation, 1);
84 E_CHECK_RETURN(zr, NULL);
92 e_mod_comp_effect_zone_rotation_free(E_Comp_Effect_Zone_Rotation *zr)
98 e_mod_comp_effect_zone_rotation_begin(E_Comp_Effect_Zone_Rotation *zr)
101 E_Comp *c = e_mod_comp_util_get();
103 E_CHECK_RETURN(c->animatable, EINA_FALSE);
105 /* HACK: disabled xv app rotation and lock screen rotation
106 * look for full-screen window and then check class and name.
107 * if it is an app window which is using xv, rotation effect will be
110 E_Border *bd = e_border_focused_get();
111 E_Border *_bd = NULL;
112 E_Comp_Win *cw = NULL, *cw2 = NULL, *cw3 = NULL;
115 cw = e_mod_comp_win_find(bd->win);
116 if ((cw) && (!cw->invalid) && (!cw->input_only) && (cw->visible))
118 /* floating mode window can have focus */
119 if (!REGION_EQUAL_TO_ZONE(cw, bd->zone))
121 cw2 = e_mod_comp_util_win_normal_get(cw);
122 if ((cw2) && (cw2->bd))
136 if (TYPE_LOCKSCREEN_CHECK(cw3) ||
137 TYPE_HOME_CHECK(cw3))
139 ELB(ELBT_COMP, "SKIP ROT_EFFECT",
140 e_mod_comp_util_client_xid_get(cw3));
147 if ((_bd->client.icccm.name) && (_bd->client.icccm.class))
149 if ((!strcmp(_bd->client.icccm.name, "camera")) &&
150 (!strcmp(_bd->client.icccm.class, "camera")))
152 ELB(ELBT_COMP, "SKIP CAMERA", _bd->client.win);
155 else if (!strcmp(_bd->client.icccm.name, "video_play"))
157 ELB(ELBT_COMP, "SKIP VIDEO PLAYER", _bd->client.win);
165 ly = e_mod_comp_canvas_layer_get(zr->canvas, "effect");
168 /* TODO: check animation is running */
169 if (zr->trans_begin) elm_transit_del(zr->trans_begin);
170 if (zr->trans_end) elm_transit_del(zr->trans_end);
171 zr->trans_begin = NULL;
172 zr->trans_end = NULL;
174 zr->trans_begin = elm_transit_add();
176 zr->effect_begin = _effect_zone_rot_begin_new(ly);
177 if (!zr->effect_begin)
179 if (zr->trans_begin) elm_transit_del(zr->trans_begin);
180 zr->trans_begin = NULL;
181 zr->ready = EINA_FALSE;
184 elm_transit_object_add(zr->trans_begin, ly->layout);
185 elm_transit_smooth_set(zr->trans_begin, EINA_FALSE);
186 elm_transit_duration_set(zr->trans_begin, 0.4f);
187 elm_transit_effect_add(zr->trans_begin, _effect_zone_rot_begin_op, zr->effect_begin, _effect_zone_rot_begin_free);
188 elm_transit_tween_mode_set(zr->trans_begin, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
189 elm_transit_objects_final_state_keep_set(zr->trans_begin, EINA_FALSE);
191 e_mod_comp_layer_effect_set(ly, EINA_TRUE);
193 zr->ready = EINA_TRUE;
200 e_mod_comp_effect_zone_rotation_end(E_Comp_Effect_Zone_Rotation *zr)
203 E_Comp *c = e_mod_comp_util_get();
205 E_CHECK_RETURN(c->animatable, EINA_FALSE);
206 E_CHECK_RETURN(zr->ready, EINA_FALSE);
207 E_CHECK_RETURN(zr->trans_begin, EINA_FALSE);
209 zr->ready = EINA_FALSE;
211 ly = e_mod_comp_canvas_layer_get(zr->canvas, "comp");
214 if (zr->trans_end) elm_transit_del(zr->trans_end);
215 zr->trans_end = NULL;
217 zr->trans_end = elm_transit_add();
218 zr->effect_end = _effect_zone_rot_end_new(ly->layout, zr->canvas->zone);
219 elm_transit_object_add(zr->trans_end, ly->layout);
220 elm_transit_smooth_set(zr->trans_end, EINA_FALSE);
221 elm_transit_duration_set(zr->trans_end, 0.4f);
222 elm_transit_effect_add(zr->trans_end, _effect_zone_rot_end_op, zr->effect_end, _effect_zone_rot_end_free);
223 elm_transit_tween_mode_set(zr->trans_end, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
224 elm_transit_objects_final_state_keep_set(zr->trans_end, EINA_FALSE);
226 e_zone_rotation_block_set(zr->canvas->zone, "comp-tizen", EINA_TRUE);
235 e_mod_comp_effect_zone_rotation_cancel(E_Comp_Effect_Zone_Rotation *zr)
239 elm_transit_del(zr->trans_begin);
240 zr->trans_begin = NULL;
244 elm_transit_del(zr->trans_end);
245 zr->trans_end = NULL;
247 zr->ready = EINA_FALSE;
253 e_mod_comp_effect_zone_rotation_do(E_Comp_Effect_Zone_Rotation *zr)
255 E_Comp *c = e_mod_comp_util_get();
256 E_CHECK_RETURN(c->animatable, EINA_FALSE);
258 elm_transit_go(zr->trans_begin);
259 elm_transit_go(zr->trans_end);
264 /* local subsystem functions */
266 _angle_get(E_Comp_Win *cw,
270 E_CHECK_RETURN(cw->bd, 0);
271 E_CHECK_RETURN(req, 0);
272 E_CHECK_RETURN(curr, 0);
274 *req = cw->bd->client.e.state.rot.prev;
275 *curr = cw->bd->client.e.state.rot.curr;
280 static Elm_Transit_Effect *
281 _effect_zone_rot_begin_new(E_Comp_Layer *ly)
283 E_Comp_Zone_Rotation_Effect_Begin *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_Begin, 1);
284 E_CHECK_RETURN(ctx, NULL);
286 E_Zone *zone = ly->canvas->zone;
288 /* capture the screen */
289 Ecore_X_Window_Attributes att;
290 Ecore_X_Window root = ecore_x_window_root_first_get();
291 memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
292 if (!ecore_x_window_attributes_get(root, &att))
298 ctx->xim = ecore_x_image_new(zone->w, zone->h, att.visual, att.depth);
305 unsigned int *pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
306 ELBF(ELBT_COMP, 0, 0, "%15.15s|root:0x%08x vis:%p depth:%d xim:%p pix:%p", "ZONE_ROT_B_NEW",
307 root, att.visual, att.depth, ctx->xim, pix);
309 ctx->img = evas_object_image_filled_add(evas_object_evas_get(ly->layout));
310 evas_object_image_colorspace_set(ctx->img, EVAS_COLORSPACE_ARGB8888);
311 evas_object_image_alpha_set(ctx->img, 0);
312 evas_object_image_size_set(ctx->img, zone->w, zone->h);
313 evas_object_image_smooth_scale_set(ctx->img, EINA_FALSE);
314 evas_object_image_data_set(ctx->img, pix);
315 evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
317 // why do we neeed these 2? this smells wrong
318 if (ecore_x_image_get(ctx->xim, root, 0, 0, 0, 0, zone->w, zone->h))
320 pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
321 evas_object_image_data_set(ctx->img, pix);
322 evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
324 evas_object_show(ctx->img);
326 e_mod_comp_layer_populate(ly, ctx->img);
327 e_layout_child_move(ctx->img, 0, 0);
328 e_layout_child_resize(ctx->img, zone->w, zone->h);
331 ctx->zone = ly->canvas->zone;
334 int diff = zone->rot.prev - zone->rot.curr;
335 if (diff == 270) diff = -90;
336 else if (diff == -270) diff = 90;
339 ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d pix:%p", "ZONE_ROT_B_NEW", zone->rot.prev, zone->rot.curr, pix);
343 static Elm_Transit_Effect *
344 _effect_zone_rot_end_new(Evas_Object *o,
347 E_Comp_Zone_Rotation_Effect_End *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_End, 1);
348 E_CHECK_RETURN(ctx, NULL);
352 int diff = zone->rot.curr - zone->rot.prev;
353 if (diff == 270) diff = -90;
354 else if (diff == -270) diff = 90;
357 ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d", "ZONE_ROTATION_EFFECT_END_NEW", zone->rot.prev, zone->rot.curr);
362 _effect_zone_rot_begin_free(Elm_Transit_Effect *effect,
363 Elm_Transit *transit)
365 E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
366 if (ctx->xim) ecore_x_image_free(ctx->xim);
369 evas_object_hide(ctx->img);
370 e_layout_unpack(ctx->img);
371 evas_object_del(ctx->img);
373 //evas_object_color_set(ctx->o, 255, 255, 255, 255);
375 e_mod_comp_layer_effect_set(ctx->ly, EINA_FALSE);
381 _effect_zone_rot_end_free(Elm_Transit_Effect *effect,
382 Elm_Transit *transit)
384 E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
385 e_zone_rotation_block_set(ctx->zone, "comp-tizen", EINA_FALSE);
386 evas_object_color_set(ctx->o, 255, 255, 255, 255);
387 ELBF(ELBT_COMP, 0, 0, "%15.15s|", "ZONE_ROTATION_EFFECT_END_FREE");
392 _effect_zone_rot_begin_op(Elm_Transit_Effect *effect,
393 Elm_Transit *transit,
396 E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
397 double curr = (progress * ctx->target);
398 Evas_Coord x, y, w, h;
400 double col = 255 - (255 * progress * 1.3);
401 if (col <= 0) col = 0;
402 evas_object_color_set(ctx->o, col, col, col, col);
404 int diff = ctx->zone->h - ctx->zone->w;
405 Evas_Coord _x = -1.0 * (diff * progress) / 2;
406 Evas_Coord _y = (diff * progress) / 2;
407 Evas_Coord _w = ctx->zone->w + (diff * progress);
408 Evas_Coord _h = ctx->zone->h - (diff * progress);
409 evas_object_move(ctx->o, _x, _y);
410 evas_object_resize(ctx->o, _w, _h);
411 evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
413 Evas_Map *m = evas_map_new(4);
414 evas_map_util_points_populate_from_object(m, ctx->o);
415 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
416 evas_object_map_set(ctx->o, m);
417 evas_object_map_enable_set(ctx->o, EINA_TRUE);
423 _effect_zone_rot_end_op(Elm_Transit_Effect *effect,
424 Elm_Transit *transit,
427 E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
428 double curr = ((-1.0f * progress * ctx->src) + ctx->src);
429 Evas_Coord x, y, w, h;
431 double col = 100 + 155 * progress;
432 evas_object_color_set(ctx->o, col, col, col, 255);
434 evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
436 Evas_Map *m = evas_map_new(4);
437 evas_map_util_points_populate_from_object(m, ctx->o);
438 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
439 evas_object_map_set(ctx->o, m);
440 evas_object_map_enable_set(ctx->o, EINA_TRUE);