diff options
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_clip.c')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_clip.c | 321 |
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 | |||
4 | void | ||
5 | evas_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 | |||
17 | void | ||
18 | evas_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 | |||
31 | int | ||
32 | evas_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 | ||
78 | static void | ||
79 | evas_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 | |||
110 | void | ||
111 | evas_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 | |||
120 | void | ||
121 | evas_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 | ||
144 | void | ||
145 | evas_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 */ | ||
162 | extern const char *o_rect_type; | ||
163 | |||
164 | EAPI void | ||
165 | evas_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 | |||
257 | EAPI Evas_Object * | ||
258 | evas_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 | |||
266 | EAPI void | ||
267 | evas_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 | |||
314 | EAPI const Eina_List * | ||
315 | evas_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 | } | ||