1 #include "e_mod_comp_shared_types.h"
2 #include "e_mod_comp_debug.h"
5 // input shape geometry (used on Move Module,
6 // Compositor receives input evevnt from this region.)
7 struct _E_Comp_Win_Shape_Input
12 struct _E_Comp_Shape_Input
20 /* local subsystem functions */
22 _e_mod_comp_shape_input_new_id_get(E_Comp *c)
25 E_Comp_Shape_Input *shape_input = NULL;
27 Eina_Bool create_id = EINA_FALSE;
31 while (new_id < INT_MAX)
33 create_id = EINA_TRUE;
35 EINA_LIST_FOREACH(c->shape_inputs, l, shape_input)
37 if (shape_input->id == new_id)
40 create_id = EINA_FALSE;
48 if (create_id) return new_id;
52 /* externally accessible functions */
54 e_mod_comp_shape_input_new(E_Comp *c)
57 E_Comp_Shape_Input *shape_input;
60 id = _e_mod_comp_shape_input_new_id_get(c);
63 shape_input = E_NEW(E_Comp_Shape_Input, 1);
64 E_CHECK_RETURN(shape_input, 0);
67 c->shape_inputs = eina_list_append(c->shape_inputs, shape_input);
73 e_mod_comp_shape_input_set(E_Comp *c,
80 Eina_Bool found = EINA_FALSE;
81 E_Comp_Shape_Input *shape_input = NULL;
84 E_CHECK_RETURN(c, EINA_FALSE);
85 if ( id <= 0 ) return EINA_FALSE;
87 EINA_LIST_FOREACH(c->shape_inputs, l, shape_input)
89 if (shape_input->id == id)
104 e_mod_comp_shape_input_del(E_Comp *c,
107 E_Comp_Shape_Input *shape_input = NULL;
108 E_Comp_Shape_Input *find_shape_input = NULL;
110 Eina_Bool found = EINA_FALSE;
112 E_CHECK_RETURN(c, EINA_FALSE);
113 if ( id <= 0 ) return EINA_FALSE;
115 EINA_LIST_FOREACH(c->shape_inputs, l, shape_input)
117 if (shape_input->id == id)
119 find_shape_input = shape_input;
125 if (find_shape_input)
127 c->shape_inputs = eina_list_remove(c->shape_inputs, find_shape_input);
128 memset(find_shape_input, 0, sizeof(E_Comp_Shape_Input));
129 E_FREE(find_shape_input);
136 e_mod_comp_win_shape_input_update(E_Comp *c)
138 E_Comp_Win *_cw = NULL;
140 E_Comp_Canvas *canvas = NULL;
141 E_Comp_Shape_Input *shape_input = NULL;
143 pixman_region32_t vis_part;
144 pixman_region32_t win_part;
145 pixman_region32_t cur_part;
146 pixman_region32_t res_part;
148 pixman_region32_t input_part;
149 pixman_region32_t cur_input_part;
150 pixman_region32_t res_input_part;
151 pixman_region32_t sum_input_part;
152 pixman_region32_t comp_input_part;
154 pixman_box32_t *input_rects;
156 Ecore_X_Rectangle *input_shape_rects = NULL;
159 int num_input_rects = 0;
162 pixman_box32_t screen_rect;
163 pixman_box32_t window_rect;
164 pixman_box32_t input_rect;
166 E_CHECK_RETURN(c, EINA_FALSE);
169 Eina_Bool res = c->effect_funcs.image_launch_running_check(c->eff_img);
170 E_CHECK_RETURN(!res, EINA_FALSE);
174 E_CHECK_RETURN(c->need_shape_merge, EINA_FALSE);
179 screen_rect.x2 = c->man->w;
180 screen_rect.y2 = c->man->h;
182 pixman_region32_init_rects(&vis_part, &screen_rect, 1);
183 pixman_region32_init_rect(&sum_input_part, 0, 0, 0, 0);
185 EINA_INLIST_REVERSE_FOREACH(c->wins, _cw)
187 if ((!_cw->visible) || (_cw->defer_hide) ||
189 (!E_INTERSECTS(0, 0, c->man->w, c->man->h,
190 _cw->x, _cw->y, _cw->w, _cw->h)))
194 if (TYPE_DEBUGGING_INFO_CHECK(_cw)) continue;
198 window_rect.x1 = _cw->x;
199 window_rect.y1 = _cw->y;
200 window_rect.x2 = window_rect.x1 + _cw->w;
201 window_rect.y2 = window_rect.y1 + _cw->h;
203 if (_cw->shape_input)
205 input_rect.x1 = window_rect.x1 + _cw->shape_input->x;
206 input_rect.y1 = window_rect.y1 + _cw->shape_input->y;
207 input_rect.x2 = input_rect.x1 + _cw->shape_input->w;
208 input_rect.y2 = input_rect.y1 + _cw->shape_input->h;
212 input_rect.x1 = window_rect.x1;
213 input_rect.y1 = window_rect.y1;
214 input_rect.x2 = input_rect.x1;
215 input_rect.y2 = input_rect.y1;
218 pixman_region32_init_rects(&input_part, &input_rect, 1);
219 pixman_region32_init_rect(&cur_input_part, 0, 0, 0, 0);
220 pixman_region32_init_rect(&res_input_part, 0, 0, 0, 0);
221 pixman_region32_init_rect(&cur_part, 0, 0, 0, 0);
222 pixman_region32_init_rects(&win_part, &window_rect, 1);
223 pixman_region32_init_rects(&res_part, &screen_rect, 1);
225 // current_visible_window = window (intersect) screen visible part
226 pixman_region32_intersect(&cur_part, &win_part, &vis_part);
228 // current_input = current_visible_window (intersect) input
229 pixman_region32_intersect(&cur_input_part, &cur_part, &input_part);
231 // result_input = sum_input
232 // sum_input = result_input + current_input
233 pixman_region32_copy(&res_input_part, &sum_input_part);
234 pixman_region32_union(&sum_input_part, &res_input_part, &cur_input_part);
236 // result = visible - window
237 pixman_region32_subtract(&res_part, &vis_part, &win_part);
238 pixman_region32_rectangles(&res_part, &num_rects);
240 pixman_region32_fini(&input_part);
241 pixman_region32_fini(&cur_input_part);
242 pixman_region32_fini(&res_input_part);
243 pixman_region32_fini(&cur_part);
244 pixman_region32_fini(&win_part);
248 pixman_region32_fini(&res_part);
252 pixman_region32_copy(&vis_part, &res_part);
253 pixman_region32_fini(&res_part);
256 e_mod_comp_shape_input_manage(c);
258 EINA_LIST_FOREACH(c->shape_inputs, l, shape_input)
260 if ((shape_input->managed) && (shape_input->skip))
262 if (E_INTERSECTS(0, 0, c->man->w, c->man->h,
263 shape_input->x, shape_input->y,
264 shape_input->w, shape_input->h))
266 pixman_region32_init_rect(&comp_input_part,
271 pixman_region32_init_rect(&res_input_part, 0, 0, 0, 0);
273 pixman_region32_copy(&res_input_part, &sum_input_part);
274 pixman_region32_union(&sum_input_part, &res_input_part, &comp_input_part);
276 pixman_region32_fini(&res_input_part);
277 pixman_region32_fini(&comp_input_part);
281 input_rects = pixman_region32_rectangles(&sum_input_part, &num_input_rects);
285 input_shape_rects = E_NEW(Ecore_X_Rectangle, num_input_rects);
286 if (input_shape_rects)
288 for (i = 0; i < num_input_rects; i++)
290 input_shape_rects[i].x = input_rects[i].x1;
291 input_shape_rects[i].y = input_rects[i].y1;
292 input_shape_rects[i].width = input_rects[i].x2 - input_rects[i].x1;
293 input_shape_rects[i].height = input_rects[i].y2 - input_rects[i].y1;
297 if (_comp_mod->conf->nocomp_fs)
299 /* set shape before setting shape input */
300 EINA_LIST_FOREACH(c->canvases, l, canvas)
303 (canvas->nocomp.mode == E_NOCOMP_MODE_RUN))
305 ecore_x_window_shape_rectangles_set
306 (c->win, input_shape_rects, num_input_rects);
311 /* FIXME: this code causes compositor couldn't update center region during composite state and software backend.
313 we have to ask someone who wrote this code what purpose of this code,
314 so that we can fix it appropriately. */
317 if ((input_shape_rects) && (num_input_rects == 1))
319 canvas = (E_Comp_Canvas *)eina_list_nth(c->canvases, 0);
321 (input_shape_rects[0].x == canvas->x) &&
322 (input_shape_rects[0].y == canvas->y) &&
323 (input_shape_rects[0].width == canvas->w) &&
324 (input_shape_rects[0].height == canvas->h))
326 ecore_x_window_shape_rectangle_subtract(c->win,
327 (canvas->w / 2) - 16,
328 (canvas->h / 2) - 16,
335 ecore_x_window_shape_input_rectangles_set(c->win,
338 if (input_shape_rects) E_FREE(input_shape_rects);
342 ecore_x_window_shape_input_rectangle_set(c->win, -1, -1, 1, 1);
345 pixman_region32_fini(&vis_part);
346 pixman_region32_fini(&sum_input_part);
348 c->need_shape_merge = EINA_FALSE;
352 EAPI E_Comp_Win_Shape_Input *
353 e_mod_comp_win_shape_input_new(E_Comp_Win *cw)
358 E_CHECK_RETURN(cw, 0);
360 EINA_LIST_FOREACH(cw->objs, l, co)
362 if (!co->img) return NULL;
363 if (!co->shadow) return NULL;
366 EINA_LIST_FOREACH(cw->objs, l, co)
368 evas_object_pass_events_set(co->img, EINA_FALSE);
369 evas_object_pass_events_set(co->shadow, EINA_FALSE);
372 return E_NEW(E_Comp_Win_Shape_Input, 1);
376 e_mod_comp_win_shape_input_free(E_Comp_Win_Shape_Input *input)
383 e_mod_comp_win_shape_input_rect_set(E_Comp_Win_Shape_Input *input,
389 E_CHECK_RETURN(input, EINA_FALSE);
391 if (((input->x == x) && (input->y == y) &&
392 (input->w == w) && (input->h == h)))
406 e_mod_comp_win_shape_input_invalid_set(E_Comp *c,
409 E_CHECK_RETURN(c, EINA_FALSE);
410 c->need_shape_merge = set;
415 e_mod_comp_shape_input_manage(E_Comp *c)
417 E_Comp_Shape_Input *shape_input;
418 Eina_List *l, *ll, *lm;
419 Evas_Object *o, *oo, *layout;
420 E_Comp_Layer *comp_ly, *ctrl_ly;
421 E_Comp_Canvas *canvas;
422 Eina_Bool hidden = EINA_FALSE;
423 int x = 0, y = 0, w = 0, h = 0;
424 int _x = 0, _y = 0, _w = 0, _h = 0;
427 pixman_region32_t target_part;
428 pixman_region32_t cur_part;
429 pixman_region32_t res_part;
430 pixman_box32_t *rects = NULL;
432 canvas = eina_list_nth(c->canvases, 0);
433 comp_ly = e_mod_comp_canvas_layer_get(canvas, "comp");
436 ctrl_ly = e_mod_comp_canvas_layer_get(canvas, "ly-ctrl");
439 EINA_LIST_FOREACH(c->shape_inputs_mo, l, o)
441 if (!evas_object_visible_get(o)) continue;
445 /*TODO: find layout of objects */
446 layout = ctrl_ly->layout;
448 evas_object_geometry_get(o, &x, &y, &w, &h);
450 pixman_region32_init_rect(&target_part, x, y, w, h);
451 pixman_region32_init_rect(&res_part, x, y, w, h);
456 lm = evas_object_smart_members_get(comp_ly->layout);
457 EINA_LIST_REVERSE_FOREACH(lm, ll, oo)
459 if (!evas_object_visible_get(oo)) continue;
460 if ((oo == o) || ((oo == layout)))
463 evas_object_geometry_get(oo, &_x, &_y, &_w, &_h);
466 if (_x == -100001) continue;
467 if (!E_INTERSECTS(x, y, w, h, _x, _y, _w, _h)) continue;
469 pixman_region32_copy(&target_part, &res_part);
470 pixman_region32_init_rect(&cur_part, _x, _y, _w, _h);
471 pixman_region32_subtract(&res_part, &target_part, &cur_part);
472 pixman_region32_fini(&cur_part);
474 rects = pixman_region32_rectangles(&res_part, &num_rects);
482 if (lm) eina_list_free(lm);
484 if ((rects) && (num_rects == 1))
486 if (((rects[0].x2 - rects[0].x1) >= w/2) &&
487 ((rects[0].y2 - rects[0].y1) >= h/2))
491 w = rects[0].x2 - rects[0].x1;
492 h = rects[0].y2 - rects[0].y1;
499 else if ((rects) && (num_rects >=2))
501 if ((((rects[0].x2 - rects[0].x1) >= w/2) &&
502 ((rects[0].y2 - rects[0].y1) >= h/2)) ||
503 (((rects[1].x2 - rects[1].x1) >= w/2) &&
504 ((rects[1].y2 - rects[1].y1) >= h/2)))
510 shape_input = evas_object_data_get(o, "e_shape_input_managed_data");
515 shape_input->skip = EINA_TRUE;
523 shape_input->skip = EINA_FALSE;
530 pixman_region32_fini(&target_part);
531 pixman_region32_fini(&res_part);
536 e_mod_comp_shape_input_managed_set(E_Comp *c,
541 Eina_Bool found = EINA_FALSE;
542 E_Comp_Shape_Input *shape_input = NULL;
543 E_Comp_Shape_Input *find_shape_input = NULL;
546 E_CHECK_RETURN(c, EINA_FALSE);
547 if (id <= 0) return EINA_FALSE;
549 EINA_LIST_FOREACH(c->shape_inputs, l, shape_input)
551 if (shape_input->id == id)
554 find_shape_input = shape_input;
559 if (find_shape_input)
561 find_shape_input->managed = set;
564 evas_object_data_set(obj, "e_shape_input_managed_data", find_shape_input);
565 c->shape_inputs_mo = eina_list_append(c->shape_inputs_mo, obj);
569 evas_object_data_del(obj, "e_shape_input_managed_data");
570 c->shape_inputs_mo = eina_list_remove(c->shape_inputs_mo, obj);