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;
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)) _bd = cw2->bd;
129 if ((_bd->client.icccm.name) && (_bd->client.icccm.class))
131 if ((!strcmp(_bd->client.icccm.name, "camera")) &&
132 (!strcmp(_bd->client.icccm.class, "camera")))
134 ELB(ELBT_COMP, "SKIP CAMERA", _bd->client.win);
137 else if (!strcmp(_bd->client.icccm.name, "video_play"))
139 ELB(ELBT_COMP, "SKIP VIDEO PLAYER", _bd->client.win);
142 if ((!strcmp(_bd->client.icccm.name, "LOCK_SCREEN")) &&
143 (!strcmp(_bd->client.icccm.class, "LOCK_SCREEN")))
145 ELB(ELBT_COMP, "SKIP LOCK_SCREEN", _bd->client.win);
153 ly = e_mod_comp_canvas_layer_get(zr->canvas, "effect");
156 /* TODO: check animation is running */
157 if (zr->trans_begin) elm_transit_del(zr->trans_begin);
158 if (zr->trans_end) elm_transit_del(zr->trans_end);
159 zr->trans_begin = NULL;
160 zr->trans_end = NULL;
162 zr->trans_begin = elm_transit_add();
164 zr->effect_begin = _effect_zone_rot_begin_new(ly);
165 if (!zr->effect_begin)
167 if (zr->trans_begin) elm_transit_del(zr->trans_begin);
168 zr->trans_begin = NULL;
169 zr->ready = EINA_FALSE;
172 elm_transit_object_add(zr->trans_begin, ly->layout);
173 elm_transit_smooth_set(zr->trans_begin, EINA_FALSE);
174 elm_transit_duration_set(zr->trans_begin, 0.4f);
175 elm_transit_effect_add(zr->trans_begin, _effect_zone_rot_begin_op, zr->effect_begin, _effect_zone_rot_begin_free);
176 elm_transit_tween_mode_set(zr->trans_begin, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
177 elm_transit_objects_final_state_keep_set(zr->trans_begin, EINA_FALSE);
179 e_mod_comp_layer_effect_set(ly, EINA_TRUE);
181 zr->ready = EINA_TRUE;
188 e_mod_comp_effect_zone_rotation_end(E_Comp_Effect_Zone_Rotation *zr)
191 E_Comp *c = e_mod_comp_util_get();
193 E_CHECK_RETURN(c->animatable, EINA_FALSE);
194 E_CHECK_RETURN(zr->ready, EINA_FALSE);
195 E_CHECK_RETURN(zr->trans_begin, EINA_FALSE);
197 zr->ready = EINA_FALSE;
199 ly = e_mod_comp_canvas_layer_get(zr->canvas, "comp");
202 if (zr->trans_end) elm_transit_del(zr->trans_end);
203 zr->trans_end = NULL;
205 zr->trans_end = elm_transit_add();
206 zr->effect_end = _effect_zone_rot_end_new(ly->layout, zr->canvas->zone);
207 elm_transit_object_add(zr->trans_end, ly->layout);
208 elm_transit_smooth_set(zr->trans_end, EINA_FALSE);
209 elm_transit_duration_set(zr->trans_end, 0.4f);
210 elm_transit_effect_add(zr->trans_end, _effect_zone_rot_end_op, zr->effect_end, _effect_zone_rot_end_free);
211 elm_transit_tween_mode_set(zr->trans_end, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
212 elm_transit_objects_final_state_keep_set(zr->trans_end, EINA_FALSE);
214 e_zone_rotation_block_set(zr->canvas->zone, "comp-tizen", EINA_TRUE);
223 e_mod_comp_effect_zone_rotation_cancel(E_Comp_Effect_Zone_Rotation *zr)
227 elm_transit_del(zr->trans_begin);
228 zr->trans_begin = NULL;
232 elm_transit_del(zr->trans_end);
233 zr->trans_end = NULL;
235 zr->ready = EINA_FALSE;
241 e_mod_comp_effect_zone_rotation_do(E_Comp_Effect_Zone_Rotation *zr)
243 E_Comp *c = e_mod_comp_util_get();
244 E_CHECK_RETURN(c->animatable, EINA_FALSE);
246 elm_transit_go(zr->trans_begin);
247 elm_transit_go(zr->trans_end);
252 /* local subsystem functions */
254 _angle_get(E_Comp_Win *cw,
258 E_CHECK_RETURN(cw->bd, 0);
259 E_CHECK_RETURN(req, 0);
260 E_CHECK_RETURN(curr, 0);
262 *req = cw->bd->client.e.state.rot.prev;
263 *curr = cw->bd->client.e.state.rot.curr;
268 static Elm_Transit_Effect *
269 _effect_zone_rot_begin_new(E_Comp_Layer *ly)
271 E_Comp_Zone_Rotation_Effect_Begin *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_Begin, 1);
272 E_CHECK_RETURN(ctx, NULL);
274 E_Zone *zone = ly->canvas->zone;
276 /* capture the screen */
277 Ecore_X_Window_Attributes att;
278 Ecore_X_Window root = ecore_x_window_root_first_get();
279 memset((&att), 0, sizeof(Ecore_X_Window_Attributes));
280 if (!ecore_x_window_attributes_get(root, &att))
286 ctx->xim = ecore_x_image_new(zone->w, zone->h, att.visual, att.depth);
293 unsigned int *pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
294 ELBF(ELBT_COMP, 0, 0, "%15.15s|root:0x%08x vis:%p depth:%d xim:%p pix:%p", "ZONE_ROT_B_NEW",
295 root, att.visual, att.depth, ctx->xim, pix);
297 ctx->img = evas_object_image_filled_add(evas_object_evas_get(ly->layout));
298 evas_object_image_colorspace_set(ctx->img, EVAS_COLORSPACE_ARGB8888);
299 evas_object_image_alpha_set(ctx->img, 0);
300 evas_object_image_size_set(ctx->img, zone->w, zone->h);
301 evas_object_image_smooth_scale_set(ctx->img, EINA_FALSE);
302 evas_object_image_data_set(ctx->img, pix);
303 evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
305 // why do we neeed these 2? this smells wrong
306 if (ecore_x_image_get(ctx->xim, root, 0, 0, 0, 0, zone->w, zone->h))
308 pix = ecore_x_image_data_get(ctx->xim, NULL, NULL, NULL);;
309 evas_object_image_data_set(ctx->img, pix);
310 evas_object_image_data_update_add(ctx->img, 0, 0, zone->w, zone->h);
312 evas_object_show(ctx->img);
314 e_mod_comp_layer_populate(ly, ctx->img);
315 e_layout_child_move(ctx->img, 0, 0);
316 e_layout_child_resize(ctx->img, zone->w, zone->h);
319 ctx->zone = ly->canvas->zone;
322 int diff = zone->rot.prev - zone->rot.curr;
323 if (diff == 270) diff = -90;
324 else if (diff == -270) diff = 90;
327 ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d pix:%p", "ZONE_ROT_B_NEW", zone->rot.prev, zone->rot.curr, pix);
331 static Elm_Transit_Effect *
332 _effect_zone_rot_end_new(Evas_Object *o,
335 E_Comp_Zone_Rotation_Effect_End *ctx= E_NEW(E_Comp_Zone_Rotation_Effect_End, 1);
336 E_CHECK_RETURN(ctx, NULL);
340 int diff = zone->rot.curr - zone->rot.prev;
341 if (diff == 270) diff = -90;
342 else if (diff == -270) diff = 90;
345 ELBF(ELBT_COMP, 0, 0, "%15.15s|%d->%d", "ZONE_ROTATION_EFFECT_END_NEW", zone->rot.prev, zone->rot.curr);
350 _effect_zone_rot_begin_free(Elm_Transit_Effect *effect,
351 Elm_Transit *transit)
353 E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
354 if (ctx->xim) ecore_x_image_free(ctx->xim);
357 evas_object_hide(ctx->img);
358 e_layout_unpack(ctx->img);
359 evas_object_del(ctx->img);
361 //evas_object_color_set(ctx->o, 255, 255, 255, 255);
363 e_mod_comp_layer_effect_set(ctx->ly, EINA_FALSE);
369 _effect_zone_rot_end_free(Elm_Transit_Effect *effect,
370 Elm_Transit *transit)
372 E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
373 e_zone_rotation_block_set(ctx->zone, "comp-tizen", EINA_FALSE);
374 evas_object_color_set(ctx->o, 255, 255, 255, 255);
375 ELBF(ELBT_COMP, 0, 0, "%15.15s|", "ZONE_ROTATION_EFFECT_END_FREE");
380 _effect_zone_rot_begin_op(Elm_Transit_Effect *effect,
381 Elm_Transit *transit,
384 E_Comp_Zone_Rotation_Effect_Begin *ctx = (E_Comp_Zone_Rotation_Effect_Begin *)effect;
385 double curr = (progress * ctx->target);
386 Evas_Coord x, y, w, h;
388 double col = 255 - (255 * progress * 1.3);
389 if (col <= 0) col = 0;
390 evas_object_color_set(ctx->o, col, col, col, col);
392 int diff = ctx->zone->h - ctx->zone->w;
393 Evas_Coord _x = -1.0 * (diff * progress) / 2;
394 Evas_Coord _y = (diff * progress) / 2;
395 Evas_Coord _w = ctx->zone->w + (diff * progress);
396 Evas_Coord _h = ctx->zone->h - (diff * progress);
397 evas_object_move(ctx->o, _x, _y);
398 evas_object_resize(ctx->o, _w, _h);
399 evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
401 Evas_Map *m = evas_map_new(4);
402 evas_map_util_points_populate_from_object(m, ctx->o);
403 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
404 evas_object_map_set(ctx->o, m);
405 evas_object_map_enable_set(ctx->o, EINA_TRUE);
411 _effect_zone_rot_end_op(Elm_Transit_Effect *effect,
412 Elm_Transit *transit,
415 E_Comp_Zone_Rotation_Effect_End *ctx = (E_Comp_Zone_Rotation_Effect_End *)effect;
416 double curr = ((-1.0f * progress * ctx->src) + ctx->src);
417 Evas_Coord x, y, w, h;
419 double col = 100 + 155 * progress;
420 evas_object_color_set(ctx->o, col, col, col, 255);
422 evas_object_geometry_get(ctx->o, &x, &y, &w, &h);
424 Evas_Map *m = evas_map_new(4);
425 evas_map_util_points_populate_from_object(m, ctx->o);
426 evas_map_util_rotate(m, curr, x + (w/2), y + (h/2));
427 evas_object_map_set(ctx->o, m);
428 evas_object_map_enable_set(ctx->o, EINA_TRUE);