aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_clip.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_clip.c')
-rw-r--r--libraries/evas/src/lib/canvas/evas_clip.c321
1 files changed, 0 insertions, 321 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_clip.c b/libraries/evas/src/lib/canvas/evas_clip.c
deleted file mode 100644
index 1ae2f73..0000000
--- a/libraries/evas/src/lib/canvas/evas_clip.c
+++ /dev/null
@@ -1,321 +0,0 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4void
5evas_object_clip_dirty(Evas_Object *obj)
6{
7 Eina_List *l;
8 Evas_Object *data;
9
10 if (obj->cur.cache.clip.dirty) return ;
11
12 obj->cur.cache.clip.dirty = 1;
13 EINA_LIST_FOREACH(obj->clip.clipees, l, data)
14 evas_object_clip_dirty(data);
15}
16
17void
18evas_object_recalc_clippees(Evas_Object *obj)
19{
20 Eina_List *l;
21 Evas_Object *data;
22
23 if (obj->cur.cache.clip.dirty)
24 {
25 evas_object_clip_recalc(obj);
26 EINA_LIST_FOREACH(obj->clip.clipees, l, data)
27 evas_object_recalc_clippees(data);
28 }
29}
30
31int
32evas_object_clippers_was_visible(Evas_Object *obj)
33{
34 if (obj->prev.visible)
35 {
36 if (obj->prev.clipper)
37 return evas_object_clippers_is_visible(obj->prev.clipper);
38 return 1;
39 }
40 return 0;
41}
42
43/* aaaaargh (pirate voice) ... notes!
44 *
45 * we have a big problem until now that's gone undetected... until yesterday.
46 * that problem involves clips and maps and smart objects. hooray! 3 of the
47 * more complex bits of evas - and maps and smart objects being one of the
48 * nastiest ones.
49 *
50 * what is the problem? when a clip crosses a map boundary. that is to say
51 * that when the clipper and clippee are not within the child tree of the
52 * mapped object. in this case "bad stuff" happens. basically as clips are
53 * then used to render objects, but they no longer apply as you'd expect as
54 * the map transfomr the objects to-be-clipped separately from the objects
55 * that clip them and this whole relationship is broken by maps. it somehow
56 * managed to not break with the advent of smart objects. lucky me... but
57 * maps killed it. now... what do we do? that is a good question. detect
58 * such a broken link and "turn off clipping" in that event - sure. but this
59 * isn't going to be cheap as ANY addition or deletion of a map to an object
60 * or any change in clipper of an object or any change in smart object
61 * membership needs to walk the obj tree both up and down from the changed
62 * object and probably walk entire object trees to find these and mark them.
63 * thats silly-expensive and i was about to fix it that way but it has since
64 * dawned on me that that is just going to kill performance in some critical
65 * areas like during object setup and manipulation, as well as teardown.
66 *
67 * aaaaagh! best for now is to document this as a "don't do it damnit!" thing
68 * and have the apps avoid it. but even then - how to do this? this is not
69 * easy. everywhere i turn so far i come up to either expensive operations,
70 * breaks in logic, or nasty re-work of apps or4 the whole concept of clipping,
71 * smart objects and maps... and that will have to wait for evas 2.0
72 *
73 * the below does clip fixups etc. in the even a clip spans a map boundary.
74 * not pretty, but necessary.
75 */
76
77#define MAP_ACROSS 1
78static void
79evas_object_child_map_across_mark(Evas_Object *obj, Evas_Object *map_obj, Eina_Bool force)
80{
81#ifdef MAP_ACROSS
82 if ((obj->cur.map_parent != map_obj) || force)
83 {
84 obj->cur.map_parent = map_obj;
85 obj->cur.cache.clip.dirty = 1;
86 evas_object_clip_recalc(obj);
87 if (obj->smart.smart)
88 {
89 Evas_Object *obj2;
90
91 EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2)
92 {
93 // if obj has its own map - skip it. already done
94 if ((obj2->cur.map) && (obj2->cur.usemap)) continue;
95 evas_object_child_map_across_mark(obj2, map_obj, force);
96 }
97 }
98 else if (obj->clip.clipees)
99 {
100 Eina_List *l;
101 Evas_Object *obj2;
102
103 EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
104 evas_object_child_map_across_mark(obj2, map_obj, force);
105 }
106 }
107#endif
108}
109
110void
111evas_object_clip_across_check(Evas_Object *obj)
112{
113#ifdef MAP_ACROSS
114 if (!obj->cur.clipper) return;
115 if (obj->cur.clipper->cur.map_parent != obj->cur.map_parent)
116 evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1);
117#endif
118}
119
120void
121evas_object_clip_across_clippees_check(Evas_Object *obj)
122{
123#ifdef MAP_ACROSS
124 Eina_List *l;
125 Evas_Object *obj2;
126
127 if (!obj->clip.clipees) return;
128// schloooooooooooow:
129// evas_object_child_map_across_mark(obj, obj->cur.map_parent, 1);
130// buggy:
131 evas_object_child_map_across_mark(obj, obj->cur.map_parent, 0);
132 if (obj->cur.cache.clip.dirty)
133 {
134 EINA_LIST_FOREACH(obj->clip.clipees, l, obj2)
135 evas_object_clip_across_clippees_check(obj2);
136 }
137#endif
138}
139
140// this function is called on an object when map is enabled or disabled on it
141// thus creating a "map boundary" at that point.
142//
143// FIXME: flip2 test broken in elm - might be show/hide of clips
144void
145evas_object_mapped_clip_across_mark(Evas_Object *obj)
146{
147#ifdef MAP_ACROSS
148 if ((obj->cur.map) && (obj->cur.usemap))
149 evas_object_child_map_across_mark(obj, obj, 0);
150 else
151 {
152 if (obj->smart.parent)
153 evas_object_child_map_across_mark
154 (obj, obj->smart.parent->cur.map_parent, 0);
155 else
156 evas_object_child_map_across_mark(obj, NULL, 0);
157 }
158#endif
159}
160
161/* public functions */
162extern const char *o_rect_type;
163
164EAPI void
165evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
166{
167 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
168 return;
169 MAGIC_CHECK_END();
170 if (!clip)
171 {
172 evas_object_clip_unset(obj);
173 return;
174 }
175 MAGIC_CHECK(clip, Evas_Object, MAGIC_OBJ);
176 return;
177 MAGIC_CHECK_END();
178 if (obj->cur.clipper == clip) return;
179 if (obj == clip) return;
180 if (evas_object_intercept_call_clip_set(obj, clip)) return;
181 // illegal to set anything but a rect as a clip
182 if (clip->type != o_rect_type)
183 {
184 ERR("For now a clip on other object than a rectangle is disabled");
185 return;
186 }
187 if (obj->smart.smart)
188 {
189 if (obj->smart.smart->smart_class->clip_set)
190 obj->smart.smart->smart_class->clip_set(obj, clip);
191 }
192 if (obj->cur.clipper)
193 {
194 /* unclip */
195 obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, obj);
196 if (!obj->cur.clipper->clip.clipees)
197 {
198 obj->cur.clipper->cur.have_clipees = 0;
199 if (obj->cur.clipper->cur.visible)
200 evas_damage_rectangle_add(obj->cur.clipper->layer->evas,
201 obj->cur.clipper->cur.geometry.x,
202 obj->cur.clipper->cur.geometry.y,
203 obj->cur.clipper->cur.geometry.w,
204 obj->cur.clipper->cur.geometry.h);
205 }
206 evas_object_change(obj->cur.clipper);
207 evas_object_change(obj);
208 obj->cur.clipper = NULL;
209 }
210 /* clip me */
211 if ((!clip->clip.clipees) && (clip->cur.visible))
212 {
213 /* Basically it just went invisible */
214 clip->changed = 1;
215 clip->layer->evas->changed = 1;
216 evas_damage_rectangle_add(clip->layer->evas,
217 clip->cur.geometry.x, clip->cur.geometry.y,
218 clip->cur.geometry.w, clip->cur.geometry.h);
219 }
220 obj->cur.clipper = clip;
221 clip->clip.clipees = eina_list_append(clip->clip.clipees, obj);
222 if (clip->clip.clipees) clip->cur.have_clipees = 1;
223
224 /* If it's NOT a rectangle set the mask bits too */
225 /* FIXME: Optmz ths chck */
226 if (strcmp(evas_object_type_get(clip),"rectangle") == 0)
227 obj->cur.mask = NULL;
228 else
229 {
230 void *engdata;
231 obj->cur.mask = clip;
232 engdata = clip->func->engine_data_get(clip);
233 /* FIXME: Images only */
234 clip->layer->evas->engine.func->image_mask_create(
235 clip->layer->evas->engine.data.output,
236 engdata);
237 }
238 evas_object_change(clip);
239 evas_object_change(obj);
240 evas_object_clip_dirty(obj);
241 evas_object_recalc_clippees(obj);
242 if ((!obj->smart.smart) &&
243 (!((obj->cur.map) && (obj->cur.usemap))))
244 {
245 if (evas_object_is_in_output_rect(obj,
246 obj->layer->evas->pointer.x,
247 obj->layer->evas->pointer.y, 1, 1))
248 evas_event_feed_mouse_move(obj->layer->evas,
249 obj->layer->evas->pointer.x,
250 obj->layer->evas->pointer.y,
251 obj->layer->evas->last_timestamp,
252 NULL);
253 }
254 evas_object_clip_across_check(obj);
255}
256
257EAPI Evas_Object *
258evas_object_clip_get(const Evas_Object *obj)
259{
260 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
261 return NULL;
262 MAGIC_CHECK_END();
263 return obj->cur.clipper;
264}
265
266EAPI void
267evas_object_clip_unset(Evas_Object *obj)
268{
269 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
270 return;
271 MAGIC_CHECK_END();
272 if (!obj->cur.clipper) return;
273 /* unclip */
274 if (evas_object_intercept_call_clip_unset(obj)) return;
275 if (obj->smart.smart)
276 {
277 if (obj->smart.smart->smart_class->clip_unset)
278 obj->smart.smart->smart_class->clip_unset(obj);
279 }
280 if (obj->cur.clipper)
281 {
282 obj->cur.clipper->clip.clipees = eina_list_remove(obj->cur.clipper->clip.clipees, obj);
283 if (!obj->cur.clipper->clip.clipees)
284 {
285 obj->cur.clipper->cur.have_clipees = 0;
286 if (obj->cur.clipper->cur.visible)
287 evas_damage_rectangle_add(obj->cur.clipper->layer->evas,
288 obj->cur.clipper->cur.geometry.x,
289 obj->cur.clipper->cur.geometry.y,
290 obj->cur.clipper->cur.geometry.w,
291 obj->cur.clipper->cur.geometry.h);
292 }
293 evas_object_change(obj->cur.clipper);
294 }
295 obj->cur.clipper = NULL;
296 evas_object_change(obj);
297 evas_object_clip_dirty(obj);
298 evas_object_recalc_clippees(obj);
299 if ((!obj->smart.smart) &&
300 (!((obj->cur.map) && (obj->cur.usemap))))
301 {
302 if (evas_object_is_in_output_rect(obj,
303 obj->layer->evas->pointer.x,
304 obj->layer->evas->pointer.y, 1, 1))
305 evas_event_feed_mouse_move(obj->layer->evas,
306 obj->layer->evas->pointer.x,
307 obj->layer->evas->pointer.y,
308 obj->layer->evas->last_timestamp,
309 NULL);
310 }
311 evas_object_clip_across_check(obj);
312}
313
314EAPI const Eina_List *
315evas_object_clipees_get(const Evas_Object *obj)
316{
317 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
318 return NULL;
319 MAGIC_CHECK_END();
320 return obj->clip.clipees;
321}