Imported Upstream version 1.7.4
[platform/upstream/edje.git] / src / bin / edje_cc_handlers.c
1 /*
2     Concerning the EDC reference:
3
4     The formatting for blocks and properties has been implemented as a table
5     which is filled using ALIASES.
6     For maximum flexibility I implemented them in the \@code/\@encode style,
7     this means that missing one or changing the order most certainly cause
8     formatting errors.
9
10     \@block
11         block name
12     \@context
13         code sample of the block
14     \@description
15         the block's description
16     \@endblock
17
18     \@property
19         property name
20     \@parameters
21         property's parameter list
22     \@effect
23         the property description (lol)
24     \@endproperty
25 */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <sys/mman.h>
36 #include <unistd.h>
37
38 #include "edje_cc.h"
39
40 /**
41  * @page edcref Edje Data Collection reference
42  * An Edje Data Collection, it's a plain text file (normally identified with the
43  * .edc extension), consisting of instructions for the Edje Compiler.
44  *
45  * The syntax for the edje data collection files follows a simple structure of
46  * "blocks { .. }" that can contain "properties: ..", more blocks, or both.
47  *
48  * @anchor sec_quickaccess Quick access to block descriptions:
49  * <ul>
50  *    <li>@ref sec_toplevel "Top-Level"</li>
51  *    <li>@ref sec_group "Group"</li>
52  *    <li>@ref sec_description "State description"</li>
53  *    <ul>
54  *      <li>@ref sec_description_image "Image"</li>
55  *      <li>@ref sec_description_text "Text"</li>
56  *      <li>@ref sec_description_box "Box"</li>
57  *      <li>@ref sec_description_table "Table"</li>
58  *      <li>@ref sec_description_map "Map (3d/transformations)"</li>
59  *    </ul>
60  *    <li>@ref sec_program "Program block"</li>
61  * </ul>
62  *
63  * @author Andres Blanc (dresb) andresblanc@gmail.com
64  *
65  * <table class="edcref" border="0">
66  */
67
68 static Edje_Part_Collection_Directory_Entry *current_de = NULL;
69 static Edje_Part *current_part = NULL;
70 static Edje_Pack_Element *current_item = NULL;
71 static Edje_Part_Description_Common *current_desc = NULL;
72 static Edje_Part_Description_Common *parent_desc = NULL;
73 static Edje_Program *current_program = NULL;
74
75 static void st_externals_external(void);
76
77 static void st_images_image(void);
78 static void ob_images_set(void);
79 static void st_images_set_name(void);
80 static void ob_images_set_image(void);
81 static void st_images_set_image_image(void);
82 static void st_images_set_image_size(void);
83
84 static void st_fonts_font(void);
85
86 static void st_data_item(void);
87 static void st_data_file(void);
88
89 static void ob_styles_style(void);
90 static void st_styles_style_name(void);
91 static void st_styles_style_base(void);
92 static void st_styles_style_tag(void);
93
94 static void ob_color_class(void);
95 static void st_color_class_name(void);
96 static void st_color_class_color(void);
97 static void st_color_class_color2(void);
98 static void st_color_class_color3(void);
99
100 static void ob_collections(void);
101
102 static void ob_collections_group(void);
103 static void st_collections_group_name(void);
104 static void st_collections_group_inherit(void);
105 static void st_collections_group_script_only(void);
106 static void st_collections_group_alias(void);
107 static void st_collections_group_min(void);
108 static void st_collections_group_max(void);
109 static void st_collections_group_broadcast_signal(void);
110 static void st_collections_group_data_item(void);
111 static void st_collections_group_orientation(void);
112
113 static void st_collections_group_limits_vertical(void);
114 static void st_collections_group_limits_horizontal(void);
115
116 static void ob_collections_group_script(void);
117 static void ob_collections_group_lua_script(void);
118
119 static void st_collections_group_parts_alias(void);
120
121 static void ob_collections_group_parts_part(void);
122 static void st_collections_group_parts_part_name(void);
123 static void st_collections_group_parts_part_type(void);
124 static void st_collections_group_parts_part_insert_before(void);
125 static void st_collections_group_parts_part_insert_after(void);
126 static void st_collections_group_parts_part_effect(void);
127 static void st_collections_group_parts_part_mouse_events(void);
128 static void st_collections_group_parts_part_repeat_events(void);
129 static void st_collections_group_parts_part_ignore_flags(void);
130 static void st_collections_group_parts_part_scale(void);
131 static void st_collections_group_parts_part_pointer_mode(void);
132 static void st_collections_group_parts_part_precise_is_inside(void);
133 static void st_collections_group_parts_part_use_alternate_font_metrics(void);
134 static void st_collections_group_parts_part_clip_to_id(void);
135 static void st_collections_group_parts_part_source(void);
136 static void st_collections_group_parts_part_source2(void);
137 static void st_collections_group_parts_part_source3(void);
138 static void st_collections_group_parts_part_source4(void);
139 static void st_collections_group_parts_part_source5(void);
140 static void st_collections_group_parts_part_source6(void);
141 static void st_collections_group_parts_part_entry_mode(void);
142 static void st_collections_group_parts_part_select_mode(void);
143 static void st_collections_group_parts_part_cursor_mode(void);
144 static void st_collections_group_parts_part_multiline(void);
145 static void st_collections_group_parts_part_access(void);
146 static void st_collections_group_parts_part_dragable_x(void);
147 static void st_collections_group_parts_part_dragable_y(void);
148 static void st_collections_group_parts_part_dragable_confine(void);
149 static void st_collections_group_parts_part_dragable_events(void);
150
151 /* box and table items share these */
152 static void ob_collections_group_parts_part_box_items_item(void);
153 static void st_collections_group_parts_part_box_items_item_type(void);
154 static void st_collections_group_parts_part_box_items_item_name(void);
155 static void st_collections_group_parts_part_box_items_item_source(void);
156 static void st_collections_group_parts_part_box_items_item_min(void);
157 static void st_collections_group_parts_part_box_items_item_prefer(void);
158 static void st_collections_group_parts_part_box_items_item_max(void);
159 static void st_collections_group_parts_part_box_items_item_padding(void);
160 static void st_collections_group_parts_part_box_items_item_align(void);
161 static void st_collections_group_parts_part_box_items_item_weight(void);
162 static void st_collections_group_parts_part_box_items_item_aspect(void);
163 static void st_collections_group_parts_part_box_items_item_aspect_mode(void);
164 static void st_collections_group_parts_part_box_items_item_options(void);
165 /* but these are only for table */
166 static void st_collections_group_parts_part_table_items_item_position(void);
167 static void st_collections_group_parts_part_table_items_item_span(void);
168
169 static void ob_collections_group_parts_part_description(void);
170 static void st_collections_group_parts_part_description_inherit(void);
171 static void st_collections_group_parts_part_description_source(void);
172 static void st_collections_group_parts_part_description_state(void);
173 static void st_collections_group_parts_part_description_visible(void);
174 static void st_collections_group_parts_part_description_limit(void);
175 static void st_collections_group_parts_part_description_align(void);
176 static void st_collections_group_parts_part_description_fixed(void);
177 static void st_collections_group_parts_part_description_min(void);
178 static void st_collections_group_parts_part_description_minmul(void);
179 static void st_collections_group_parts_part_description_max(void);
180 static void st_collections_group_parts_part_description_step(void);
181 static void st_collections_group_parts_part_description_aspect(void);
182 static void st_collections_group_parts_part_description_aspect_preference(void);
183 static void st_collections_group_parts_part_description_rel1_relative(void);
184 static void st_collections_group_parts_part_description_rel1_offset(void);
185 static void st_collections_group_parts_part_description_rel1_to(void);
186 static void st_collections_group_parts_part_description_rel1_to_x(void);
187 static void st_collections_group_parts_part_description_rel1_to_y(void);
188 static void st_collections_group_parts_part_description_rel2_relative(void);
189 static void st_collections_group_parts_part_description_rel2_offset(void);
190 static void st_collections_group_parts_part_description_rel2_to(void);
191 static void st_collections_group_parts_part_description_rel2_to_x(void);
192 static void st_collections_group_parts_part_description_rel2_to_y(void);
193 static void st_collections_group_parts_part_description_image_normal(void);
194 static void st_collections_group_parts_part_description_image_tween(void);
195 static void st_collections_group_parts_part_description_image_border(void);
196 static void st_collections_group_parts_part_description_image_middle(void);
197 static void st_collections_group_parts_part_description_image_border_scale(void);
198 static void st_collections_group_parts_part_description_image_border_scale_by(void);
199 static void st_collections_group_parts_part_description_image_scale_hint(void);
200 static void st_collections_group_parts_part_description_fill_smooth(void);
201 static void st_collections_group_parts_part_description_fill_origin_relative(void);
202 static void st_collections_group_parts_part_description_fill_origin_offset(void);
203 static void st_collections_group_parts_part_description_fill_size_relative(void);
204 static void st_collections_group_parts_part_description_fill_size_offset(void);
205 static void st_collections_group_parts_part_description_fill_spread(void);
206 static void st_collections_group_parts_part_description_fill_type(void);
207 static void st_collections_group_parts_part_description_color_class(void);
208 static void st_collections_group_parts_part_description_color(void);
209 static void st_collections_group_parts_part_description_color2(void);
210 static void st_collections_group_parts_part_description_color3(void);
211 static void st_collections_group_parts_part_description_text_text(void);
212 static void st_collections_group_parts_part_description_text_text_class(void);
213 static void st_collections_group_parts_part_description_text_font(void);
214 static void st_collections_group_parts_part_description_text_style(void);
215 static void st_collections_group_parts_part_description_text_repch(void);
216 static void st_collections_group_parts_part_description_text_size(void);
217 static void st_collections_group_parts_part_description_text_size_range(void);
218 static void st_collections_group_parts_part_description_text_fit(void);
219 static void st_collections_group_parts_part_description_text_min(void);
220 static void st_collections_group_parts_part_description_text_max(void);
221 static void st_collections_group_parts_part_description_text_align(void);
222 static void st_collections_group_parts_part_description_text_source(void);
223 static void st_collections_group_parts_part_description_text_text_source(void);
224 static void st_collections_group_parts_part_description_text_elipsis(void);
225 static void st_collections_group_parts_part_description_box_layout(void);
226 static void st_collections_group_parts_part_description_box_align(void);
227 static void st_collections_group_parts_part_description_box_padding(void);
228 static void st_collections_group_parts_part_description_box_min(void);
229 static void st_collections_group_parts_part_description_table_homogeneous(void);
230 static void st_collections_group_parts_part_description_table_align(void);
231 static void st_collections_group_parts_part_description_table_padding(void);
232 static void st_collections_group_parts_part_description_table_min(void);
233 static void st_collections_group_parts_part_description_map_perspective(void);
234 static void st_collections_group_parts_part_description_map_light(void);
235 static void st_collections_group_parts_part_description_map_rotation_center(void);
236 static void st_collections_group_parts_part_description_map_rotation_x(void);
237 static void st_collections_group_parts_part_description_map_rotation_y(void);
238 static void st_collections_group_parts_part_description_map_rotation_z(void);
239 static void st_collections_group_parts_part_description_map_on(void);
240 static void st_collections_group_parts_part_description_map_smooth(void);
241 static void st_collections_group_parts_part_description_map_alpha(void);
242 static void st_collections_group_parts_part_description_map_backface_cull(void);
243 static void st_collections_group_parts_part_description_map_perspective_on(void);
244 static void st_collections_group_parts_part_description_perspective_zplane(void);
245 static void st_collections_group_parts_part_description_perspective_focal(void);
246 static void st_collections_group_parts_part_api(void);
247
248 /* external part parameters */
249 static void st_collections_group_parts_part_description_params_int(void);
250 static void ob_collections_group_programs_program(void);
251 static void st_collections_group_parts_part_description_params_double(void);
252
253 static void st_collections_group_programs_program_name(void);
254 static void st_collections_group_parts_part_description_params_string(void);
255 static void st_collections_group_parts_part_description_params_bool(void);
256 static void st_collections_group_parts_part_description_params_choice(void);
257 static void st_collections_group_programs_program_signal(void);
258 static void st_collections_group_programs_program_source(void);
259 static void st_collections_group_programs_program_filter(void);
260 static void st_collections_group_programs_program_in(void);
261 static void st_collections_group_programs_program_action(void);
262 static void st_collections_group_programs_program_transition(void);
263 static void st_collections_group_programs_program_target(void);
264 static void st_collections_group_programs_program_after(void);
265 static void st_collections_group_programs_program_api(void);
266
267 static void ob_collections_group_programs_program_script(void);
268 static void st_collections_group_sound_sample_name(void);
269 static void st_collections_group_sound_sample_source(void);
270 static void st_collections_group_sound_tone(void);
271
272 /*****/
273
274 New_Statement_Handler statement_handlers[] =
275 {
276      {"externals.external", st_externals_external},
277      {"images.image", st_images_image},
278      {"images.set.name", st_images_set_name},
279      {"images.set.image.image", st_images_set_image_image},
280      {"images.set.image.size", st_images_set_image_size},
281      {"fonts.font", st_fonts_font},
282      {"data.item", st_data_item},
283      {"data.file", st_data_file},
284      {"styles.style.name", st_styles_style_name},
285      {"styles.style.base", st_styles_style_base},
286      {"styles.style.tag", st_styles_style_tag},
287      {"color_classes.color_class.name", st_color_class_name},
288      {"color_classes.color_class.color", st_color_class_color},
289      {"color_classes.color_class.color2", st_color_class_color2},
290      {"color_classes.color_class.color3", st_color_class_color3},
291      {"collections.externals.external", st_externals_external}, /* dup */
292      {"collections.image", st_images_image}, /* dup */
293      {"collections.set.name", st_images_set_name}, /* dup */
294      {"collections.set.image.image", st_images_set_image_image}, /* dup */
295      {"collections.set.image.size", st_images_set_image_size}, /* dup */
296      {"collections.images.image", st_images_image}, /* dup */
297      {"collections.images.set.name", st_images_set_name}, /* dup */
298      {"collections.images.set.image.image", st_images_set_image_image}, /* dup */
299      {"collections.images.set.image.size", st_images_set_image_size}, /* dup */
300      {"collections.font", st_fonts_font}, /* dup */
301      {"collections.fonts.font", st_fonts_font}, /* dup */
302      {"collections.styles.style.name", st_styles_style_name}, /* dup */
303      {"collections.styles.style.base", st_styles_style_base}, /* dup */
304      {"collections.styles.style.tag", st_styles_style_tag}, /* dup */
305      {"collections.color_classes.color_class.name", st_color_class_name}, /* dup */
306      {"collections.color_classes.color_class.color", st_color_class_color}, /* dup */
307      {"collections.color_classes.color_class.color2", st_color_class_color2}, /* dup */
308      {"collections.color_classes.color_class.color3", st_color_class_color3}, /* dup */
309
310      {"collections.sounds.sample.name", st_collections_group_sound_sample_name},
311      {"collections.sounds.sample.source", st_collections_group_sound_sample_source},
312      {"collections.group.sounds.sample.name", st_collections_group_sound_sample_name}, /* dup */
313      {"collections.group.sounds.sample.source", st_collections_group_sound_sample_source}, /* dup */
314      {"collections.sounds.tone", st_collections_group_sound_tone},
315      {"collections.group.sounds.tone", st_collections_group_sound_tone}, /* dup */
316      {"collections.group.name", st_collections_group_name},
317      {"collections.group.inherit", st_collections_group_inherit},
318      {"collections.group.script_only", st_collections_group_script_only},
319      {"collections.group.lua_script_only", st_collections_group_script_only},
320      {"collections.group.alias", st_collections_group_alias},
321      {"collections.group.min", st_collections_group_min},
322      {"collections.group.max", st_collections_group_max},
323      {"collections.group.broadcast_signal", st_collections_group_broadcast_signal},
324      {"collections.group.orientation", st_collections_group_orientation},
325      {"collections.group.data.item", st_collections_group_data_item},
326      {"collections.group.limits.horizontal", st_collections_group_limits_horizontal},
327      {"collections.group.limits.vertical", st_collections_group_limits_vertical},
328      {"collections.group.externals.external", st_externals_external}, /* dup */
329      {"collections.group.image", st_images_image}, /* dup */
330      {"collections.group.set.name", st_images_set_name},
331      {"collections.group.set.image.image", st_images_set_image_image},
332      {"collections.group.set.image.size", st_images_set_image_size},
333      {"collections.group.images.image", st_images_image}, /* dup */
334      {"collections.group.images.set.name", st_images_set_name},
335      {"collections.group.images.set.image.image", st_images_set_image_image},
336      {"collections.group.images.set.image.size", st_images_set_image_size},
337      {"collections.group.font", st_fonts_font}, /* dup */
338      {"collections.group.fonts.font", st_fonts_font}, /* dup */
339      {"collections.group.styles.style.name", st_styles_style_name}, /* dup */
340      {"collections.group.styles.style.base", st_styles_style_base}, /* dup */
341      {"collections.group.styles.style.tag", st_styles_style_tag}, /* dup */
342      {"collections.group.color_classes.color_class.name", st_color_class_name}, /* dup */
343      {"collections.group.color_classes.color_class.color", st_color_class_color}, /* dup */
344      {"collections.group.color_classes.color_class.color2", st_color_class_color2}, /* dup */
345      {"collections.group.color_classes.color_class.color3", st_color_class_color3}, /* dup */
346      {"collections.group.parts.alias", st_collections_group_parts_alias },
347      {"collections.group.parts.image", st_images_image}, /* dup */
348      {"collections.group.parts.set.name", st_images_set_name},
349      {"collections.group.parts.set.image.image", st_images_set_image_image},
350      {"collections.group.parts.set.image.size", st_images_set_image_size},
351      {"collections.group.parts.images.image", st_images_image}, /* dup */
352      {"collections.group.parts.images.set.name", st_images_set_name},
353      {"collections.group.parts.images.set.image.image", st_images_set_image_image},
354      {"collections.group.parts.images.set.image.size", st_images_set_image_size},
355      {"collections.group.parts.font", st_fonts_font}, /* dup */
356      {"collections.group.parts.fonts.font", st_fonts_font}, /* dup */
357      {"collections.group.parts.styles.style.name", st_styles_style_name}, /* dup */
358      {"collections.group.parts.styles.style.base", st_styles_style_base}, /* dup */
359      {"collections.group.parts.styles.style.tag", st_styles_style_tag}, /* dup */
360      {"collections.group.parts.color_classes.color_class.name", st_color_class_name}, /* dup */
361      {"collections.group.parts.color_classes.color_class.color", st_color_class_color}, /* dup */
362      {"collections.group.parts.color_classes.color_class.color2", st_color_class_color2}, /* dup */
363      {"collections.group.parts.color_classes.color_class.color3", st_color_class_color3}, /* dup */
364      {"collections.group.parts.part.name", st_collections_group_parts_part_name},
365      {"collections.group.parts.part.api", st_collections_group_parts_part_api},
366      {"collections.group.parts.part.type", st_collections_group_parts_part_type},
367      {"collections.group.parts.part.insert_before", st_collections_group_parts_part_insert_before},
368      {"collections.group.parts.part.insert_after", st_collections_group_parts_part_insert_after},
369      {"collections.group.parts.part.effect", st_collections_group_parts_part_effect},
370      {"collections.group.parts.part.mouse_events", st_collections_group_parts_part_mouse_events},
371      {"collections.group.parts.part.repeat_events", st_collections_group_parts_part_repeat_events},
372      {"collections.group.parts.part.ignore_flags", st_collections_group_parts_part_ignore_flags},
373      {"collections.group.parts.part.scale", st_collections_group_parts_part_scale},
374      {"collections.group.parts.part.pointer_mode", st_collections_group_parts_part_pointer_mode},
375      {"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside},
376      {"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics},
377      {"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id},
378      {"collections.group.parts.part.source", st_collections_group_parts_part_source},
379      {"collections.group.parts.part.source2", st_collections_group_parts_part_source2},
380      {"collections.group.parts.part.source3", st_collections_group_parts_part_source3},
381      {"collections.group.parts.part.source4", st_collections_group_parts_part_source4},
382      {"collections.group.parts.part.source5", st_collections_group_parts_part_source5},
383      {"collections.group.parts.part.source6", st_collections_group_parts_part_source6},
384      {"collections.group.parts.part.dragable.x", st_collections_group_parts_part_dragable_x},
385      {"collections.group.parts.part.dragable.y", st_collections_group_parts_part_dragable_y},
386      {"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine},
387      {"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events},
388      {"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode},
389      {"collections.group.parts.part.select_mode", st_collections_group_parts_part_select_mode},
390      {"collections.group.parts.part.cursor_mode", st_collections_group_parts_part_cursor_mode},
391      {"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline},
392      {"collections.group.parts.part.access", st_collections_group_parts_part_access},
393      {"collections.group.parts.part.image", st_images_image}, /* dup */
394      {"collections.group.parts.part.set.name", st_images_set_name},
395      {"collections.group.parts.part.set.image.image", st_images_set_image_image},
396      {"collections.group.parts.part.set.image.size", st_images_set_image_size},
397      {"collections.group.parts.part.images.image", st_images_image}, /* dup */
398      {"collections.group.parts.part.images.set.name", st_images_set_name},
399      {"collections.group.parts.part.images.set.image.image", st_images_set_image_image},
400      {"collections.group.parts.part.images.set.image.size", st_images_set_image_size},
401      {"collections.group.parts.part.font", st_fonts_font}, /* dup */
402      {"collections.group.parts.part.fonts.font", st_fonts_font}, /* dup */
403      {"collections.group.parts.part.styles.style.name", st_styles_style_name}, /* dup */
404      {"collections.group.parts.part.styles.style.base", st_styles_style_base}, /* dup */
405      {"collections.group.parts.part.styles.style.tag", st_styles_style_tag}, /* dup */
406      {"collections.group.parts.part.color_classes.color_class.name", st_color_class_name}, /* dup */
407      {"collections.group.parts.part.color_classes.color_class.color", st_color_class_color}, /* dup */
408      {"collections.group.parts.part.color_classes.color_class.color2", st_color_class_color2}, /* dup */
409      {"collections.group.parts.part.color_classes.color_class.color3", st_color_class_color3}, /* dup */
410      {"collections.group.parts.part.box.items.item.type", st_collections_group_parts_part_box_items_item_type},
411      {"collections.group.parts.part.box.items.item.name", st_collections_group_parts_part_box_items_item_name},
412      {"collections.group.parts.part.box.items.item.source", st_collections_group_parts_part_box_items_item_source},
413      {"collections.group.parts.part.box.items.item.min", st_collections_group_parts_part_box_items_item_min},
414      {"collections.group.parts.part.box.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer},
415      {"collections.group.parts.part.box.items.item.max", st_collections_group_parts_part_box_items_item_max},
416      {"collections.group.parts.part.box.items.item.padding", st_collections_group_parts_part_box_items_item_padding},
417      {"collections.group.parts.part.box.items.item.align", st_collections_group_parts_part_box_items_item_align},
418      {"collections.group.parts.part.box.items.item.weight", st_collections_group_parts_part_box_items_item_weight},
419      {"collections.group.parts.part.box.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect},
420      {"collections.group.parts.part.box.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode},
421      {"collections.group.parts.part.box.items.item.options", st_collections_group_parts_part_box_items_item_options},
422      {"collections.group.parts.part.table.items.item.type", st_collections_group_parts_part_box_items_item_type}, /* dup */
423      {"collections.group.parts.part.table.items.item.name", st_collections_group_parts_part_box_items_item_name}, /* dup */
424      {"collections.group.parts.part.table.items.item.source", st_collections_group_parts_part_box_items_item_source}, /* dup */
425      {"collections.group.parts.part.table.items.item.min", st_collections_group_parts_part_box_items_item_min}, /* dup */
426      {"collections.group.parts.part.table.items.item.prefer", st_collections_group_parts_part_box_items_item_prefer}, /* dup */
427      {"collections.group.parts.part.table.items.item.max", st_collections_group_parts_part_box_items_item_max}, /* dup */
428      {"collections.group.parts.part.table.items.item.padding", st_collections_group_parts_part_box_items_item_padding}, /* dup */
429      {"collections.group.parts.part.table.items.item.align", st_collections_group_parts_part_box_items_item_align}, /* dup */
430      {"collections.group.parts.part.table.items.item.weight", st_collections_group_parts_part_box_items_item_weight}, /* dup */
431      {"collections.group.parts.part.table.items.item.aspect", st_collections_group_parts_part_box_items_item_aspect}, /* dup */
432      {"collections.group.parts.part.table.items.item.aspect_mode", st_collections_group_parts_part_box_items_item_aspect_mode}, /* dup */
433      {"collections.group.parts.part.table.items.item.options", st_collections_group_parts_part_box_items_item_options}, /* dup */
434      {"collections.group.parts.part.table.items.item.position", st_collections_group_parts_part_table_items_item_position},
435      {"collections.group.parts.part.table.items.item.span", st_collections_group_parts_part_table_items_item_span},
436      {"collections.group.parts.part.description.inherit", st_collections_group_parts_part_description_inherit},
437      {"collections.group.parts.part.description.source", st_collections_group_parts_part_description_source},
438      {"collections.group.parts.part.description.state", st_collections_group_parts_part_description_state},
439      {"collections.group.parts.part.description.visible", st_collections_group_parts_part_description_visible},
440      {"collections.group.parts.part.description.limit", st_collections_group_parts_part_description_limit},
441      {"collections.group.parts.part.description.align", st_collections_group_parts_part_description_align},
442      {"collections.group.parts.part.description.fixed", st_collections_group_parts_part_description_fixed},
443      {"collections.group.parts.part.description.min", st_collections_group_parts_part_description_min},
444      {"collections.group.parts.part.description.minmul", st_collections_group_parts_part_description_minmul},
445      {"collections.group.parts.part.description.max", st_collections_group_parts_part_description_max},
446      {"collections.group.parts.part.description.step", st_collections_group_parts_part_description_step},
447      {"collections.group.parts.part.description.aspect", st_collections_group_parts_part_description_aspect},
448      {"collections.group.parts.part.description.aspect_preference", st_collections_group_parts_part_description_aspect_preference},
449      {"collections.group.parts.part.description.rel1.relative", st_collections_group_parts_part_description_rel1_relative},
450      {"collections.group.parts.part.description.rel1.offset", st_collections_group_parts_part_description_rel1_offset},
451      {"collections.group.parts.part.description.rel1.to", st_collections_group_parts_part_description_rel1_to},
452      {"collections.group.parts.part.description.rel1.to_x", st_collections_group_parts_part_description_rel1_to_x},
453      {"collections.group.parts.part.description.rel1.to_y", st_collections_group_parts_part_description_rel1_to_y},
454      {"collections.group.parts.part.description.rel2.relative", st_collections_group_parts_part_description_rel2_relative},
455      {"collections.group.parts.part.description.rel2.offset", st_collections_group_parts_part_description_rel2_offset},
456      {"collections.group.parts.part.description.rel2.to", st_collections_group_parts_part_description_rel2_to},
457      {"collections.group.parts.part.description.rel2.to_x", st_collections_group_parts_part_description_rel2_to_x},
458      {"collections.group.parts.part.description.rel2.to_y", st_collections_group_parts_part_description_rel2_to_y},
459      {"collections.group.parts.part.description.image.normal", st_collections_group_parts_part_description_image_normal},
460      {"collections.group.parts.part.description.image.tween", st_collections_group_parts_part_description_image_tween},
461      {"collections.group.parts.part.description.image.image", st_images_image}, /* dup */
462      {"collections.group.parts.part.description.image.set.name", st_images_set_name},
463      {"collections.group.parts.part.description.image.set.image.image", st_images_set_image_image},
464      {"collections.group.parts.part.description.image.set.image.size", st_images_set_image_size},
465      {"collections.group.parts.part.description.image.images.image", st_images_image}, /* dup */
466      {"collections.group.parts.part.description.image.images.set.name", st_images_set_name},
467      {"collections.group.parts.part.description.image.images.set.image.image", st_images_set_image_image},
468      {"collections.group.parts.part.description.image.images.set.image.size", st_images_set_image_size},
469      {"collections.group.parts.part.description.image.border", st_collections_group_parts_part_description_image_border},
470      {"collections.group.parts.part.description.image.middle", st_collections_group_parts_part_description_image_middle},
471      {"collections.group.parts.part.description.image.border_scale", st_collections_group_parts_part_description_image_border_scale},
472      {"collections.group.parts.part.description.image.border_scale_by", st_collections_group_parts_part_description_image_border_scale_by},
473      {"collections.group.parts.part.description.image.scale_hint", st_collections_group_parts_part_description_image_scale_hint},
474      {"collections.group.parts.part.description.fill.smooth", st_collections_group_parts_part_description_fill_smooth},
475      {"collections.group.parts.part.description.fill.origin.relative", st_collections_group_parts_part_description_fill_origin_relative},
476      {"collections.group.parts.part.description.fill.origin.offset", st_collections_group_parts_part_description_fill_origin_offset},
477      {"collections.group.parts.part.description.fill.size.relative", st_collections_group_parts_part_description_fill_size_relative},
478      {"collections.group.parts.part.description.fill.size.offset", st_collections_group_parts_part_description_fill_size_offset},
479      {"collections.group.parts.part.description.fill.spread", st_collections_group_parts_part_description_fill_spread},
480      {"collections.group.parts.part.description.fill.type", st_collections_group_parts_part_description_fill_type},
481      {"collections.group.parts.part.description.color_class", st_collections_group_parts_part_description_color_class},
482      {"collections.group.parts.part.description.color", st_collections_group_parts_part_description_color},
483      {"collections.group.parts.part.description.color2", st_collections_group_parts_part_description_color2},
484      {"collections.group.parts.part.description.color3", st_collections_group_parts_part_description_color3},
485      {"collections.group.parts.part.description.text.text", st_collections_group_parts_part_description_text_text},
486      {"collections.group.parts.part.description.text.text_class", st_collections_group_parts_part_description_text_text_class},
487      {"collections.group.parts.part.description.text.font", st_collections_group_parts_part_description_text_font},
488      {"collections.group.parts.part.description.text.style", st_collections_group_parts_part_description_text_style},
489      {"collections.group.parts.part.description.text.repch", st_collections_group_parts_part_description_text_repch},
490      {"collections.group.parts.part.description.text.size", st_collections_group_parts_part_description_text_size},
491      {"collections.group.parts.part.description.text.size_range", st_collections_group_parts_part_description_text_size_range},
492      {"collections.group.parts.part.description.text.fit", st_collections_group_parts_part_description_text_fit},
493      {"collections.group.parts.part.description.text.min", st_collections_group_parts_part_description_text_min},
494      {"collections.group.parts.part.description.text.max", st_collections_group_parts_part_description_text_max},
495      {"collections.group.parts.part.description.text.align", st_collections_group_parts_part_description_text_align},
496      {"collections.group.parts.part.description.text.source", st_collections_group_parts_part_description_text_source},
497      {"collections.group.parts.part.description.text.text_source", st_collections_group_parts_part_description_text_text_source},
498      {"collections.group.parts.part.description.text.font", st_fonts_font}, /* dup */
499      {"collections.group.parts.part.description.text.fonts.font", st_fonts_font}, /* dup */
500      {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_elipsis},
501      {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_elipsis},
502      {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout},
503      {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align},
504      {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding},
505      {"collections.group.parts.part.description.box.min", st_collections_group_parts_part_description_box_min},
506      {"collections.group.parts.part.description.table.homogeneous", st_collections_group_parts_part_description_table_homogeneous},
507      {"collections.group.parts.part.description.table.align", st_collections_group_parts_part_description_table_align},
508      {"collections.group.parts.part.description.table.padding", st_collections_group_parts_part_description_table_padding},
509      {"collections.group.parts.part.description.table.min", st_collections_group_parts_part_description_table_min},
510      {"collections.group.parts.part.description.map.perspective", st_collections_group_parts_part_description_map_perspective},
511      {"collections.group.parts.part.description.map.light", st_collections_group_parts_part_description_map_light},
512      {"collections.group.parts.part.description.map.rotation.center", st_collections_group_parts_part_description_map_rotation_center},
513      {"collections.group.parts.part.description.map.rotation.x", st_collections_group_parts_part_description_map_rotation_x},
514      {"collections.group.parts.part.description.map.rotation.y", st_collections_group_parts_part_description_map_rotation_y},
515      {"collections.group.parts.part.description.map.rotation.z", st_collections_group_parts_part_description_map_rotation_z},
516      {"collections.group.parts.part.description.map.on", st_collections_group_parts_part_description_map_on},
517      {"collections.group.parts.part.description.map.smooth", st_collections_group_parts_part_description_map_smooth},
518      {"collections.group.parts.part.description.map.alpha", st_collections_group_parts_part_description_map_alpha},
519      {"collections.group.parts.part.description.map.backface_cull", st_collections_group_parts_part_description_map_backface_cull},
520      {"collections.group.parts.part.description.map.perspective_on", st_collections_group_parts_part_description_map_perspective_on},
521      {"collections.group.parts.part.description.perspective.zplane", st_collections_group_parts_part_description_perspective_zplane},
522      {"collections.group.parts.part.description.perspective.focal", st_collections_group_parts_part_description_perspective_focal},
523      {"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int},
524      {"collections.group.parts.part.description.params.double", st_collections_group_parts_part_description_params_double},
525      {"collections.group.parts.part.description.params.string", st_collections_group_parts_part_description_params_string},
526      {"collections.group.parts.part.description.params.bool", st_collections_group_parts_part_description_params_bool},
527      {"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice},
528      {"collections.group.parts.part.description.images.image", st_images_image}, /* dup */
529      {"collections.group.parts.part.description.images.set.name", st_images_set_name},
530      {"collections.group.parts.part.description.images.set.image.image", st_images_set_image_image},
531      {"collections.group.parts.part.description.images.set.image.size", st_images_set_image_size},
532      {"collections.group.parts.part.description.font", st_fonts_font}, /* dup */
533      {"collections.group.parts.part.description.fonts.font", st_fonts_font}, /* dup */
534      {"collections.group.parts.part.description.styles.style.name", st_styles_style_name}, /* dup */
535      {"collections.group.parts.part.description.styles.style.base", st_styles_style_base}, /* dup */
536      {"collections.group.parts.part.description.styles.style.tag", st_styles_style_tag}, /* dup */
537      {"collections.group.parts.part.description.color_classes.color_class.name", st_color_class_name}, /* dup */
538      {"collections.group.parts.part.description.color_classes.color_class.color", st_color_class_color}, /* dup */
539      {"collections.group.parts.part.description.color_classes.color_class.color2", st_color_class_color2}, /* dup */
540      {"collections.group.parts.part.description.color_classes.color_class.color3", st_color_class_color3}, /* dup */
541      {"collections.group.parts.part.description.programs.image", st_images_image}, /* dup */
542      {"collections.group.parts.part.description.programs.set.name", st_images_set_name},
543      {"collections.group.parts.part.description.programs.set.image.image", st_images_set_image_image},
544      {"collections.group.parts.part.description.programs.set.image.size", st_images_set_image_size},
545      {"collections.group.parts.part.description.programs.images.image", st_images_image}, /* dup */
546      {"collections.group.parts.part.description.programs.images.set.name", st_images_set_name},
547      {"collections.group.parts.part.description.programs.images.set.image.image", st_images_set_image_image},
548      {"collections.group.parts.part.description.programs.images.set.image.size", st_images_set_image_size},
549      {"collections.group.parts.part.description.programs.font", st_fonts_font}, /* dup */
550      {"collections.group.parts.part.description.programs.fonts.font", st_fonts_font}, /* dup */
551      {"collections.group.parts.part.description.programs.program.name", st_collections_group_programs_program_name}, /* dup */
552      {"collections.group.parts.part.description.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
553      {"collections.group.parts.part.description.programs.program.source", st_collections_group_programs_program_source}, /* dup */
554      {"collections.group.parts.part.description.programs.program.in", st_collections_group_programs_program_in}, /* dup */
555      {"collections.group.parts.part.description.programs.program.action", st_collections_group_programs_program_action}, /* dup */
556      {"collections.group.parts.part.description.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
557      {"collections.group.parts.part.description.programs.program.target", st_collections_group_programs_program_target}, /* dup */
558      {"collections.group.parts.part.description.programs.program.after", st_collections_group_programs_program_after}, /* dup */
559      {"collections.group.parts.part.description.programs.program.api", st_collections_group_programs_program_api}, /* dup */
560      {"collections.group.parts.part.description.program.name", st_collections_group_programs_program_name}, /* dup */
561      {"collections.group.parts.part.description.program.signal", st_collections_group_programs_program_signal}, /* dup */
562      {"collections.group.parts.part.description.program.source", st_collections_group_programs_program_source}, /* dup */
563      {"collections.group.parts.part.description.program.in", st_collections_group_programs_program_in}, /* dup */
564      {"collections.group.parts.part.description.program.action", st_collections_group_programs_program_action}, /* dup */
565      {"collections.group.parts.part.description.program.transition", st_collections_group_programs_program_transition}, /* dup */
566      {"collections.group.parts.part.description.program.target", st_collections_group_programs_program_target}, /* dup */
567      {"collections.group.parts.part.description.program.after", st_collections_group_programs_program_after}, /* dup */
568      {"collections.group.parts.part.description.program.api", st_collections_group_programs_program_api}, /* dup */
569      {"collections.group.parts.part.programs.image", st_images_image}, /* dup */
570      {"collections.group.parts.part.programs.set.name", st_images_set_name},
571      {"collections.group.parts.part.programs.set.image.image", st_images_set_image_image},
572      {"collections.group.parts.part.programs.set.image.size", st_images_set_image_size},
573      {"collections.group.parts.part.programs.images.image", st_images_image}, /* dup */
574      {"collections.group.parts.part.programs.images.set.name", st_images_set_name},
575      {"collections.group.parts.part.programs.images.set.image.image", st_images_set_image_image},
576      {"collections.group.parts.part.programs.images.set.image.size", st_images_set_image_size},
577      {"collections.group.parts.part.programs.font", st_fonts_font}, /* dup */
578      {"collections.group.parts.part.programs.fonts.font", st_fonts_font}, /* dup */
579      {"collections.group.parts.part.programs.program.name", st_collections_group_programs_program_name}, /* dup */
580      {"collections.group.parts.part.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
581      {"collections.group.parts.part.programs.program.source", st_collections_group_programs_program_source}, /* dup */
582      {"collections.group.parts.part.programs.program.in", st_collections_group_programs_program_in}, /* dup */
583      {"collections.group.parts.part.programs.program.action", st_collections_group_programs_program_action}, /* dup */
584      {"collections.group.parts.part.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
585      {"collections.group.parts.part.programs.program.target", st_collections_group_programs_program_target}, /* dup */
586      {"collections.group.parts.part.programs.program.after", st_collections_group_programs_program_after}, /* dup */
587      {"collections.group.parts.part.programs.program.api", st_collections_group_programs_program_api}, /* dup */
588      {"collections.group.parts.part.program.name", st_collections_group_programs_program_name}, /* dup */
589      {"collections.group.parts.part.program.signal", st_collections_group_programs_program_signal}, /* dup */
590      {"collections.group.parts.part.program.source", st_collections_group_programs_program_source}, /* dup */
591      {"collections.group.parts.part.program.in", st_collections_group_programs_program_in}, /* dup */
592      {"collections.group.parts.part.program.action", st_collections_group_programs_program_action}, /* dup */
593      {"collections.group.parts.part.program.transition", st_collections_group_programs_program_transition}, /* dup */
594      {"collections.group.parts.part.program.target", st_collections_group_programs_program_target}, /* dup */
595      {"collections.group.parts.part.program.after", st_collections_group_programs_program_after}, /* dup */
596      {"collections.group.parts.part.program.api", st_collections_group_programs_program_api}, /* dup */
597      {"collections.group.parts.programs.image", st_images_image}, /* dup */
598      {"collections.group.parts.programs.set.name", st_images_set_name},
599      {"collections.group.parts.programs.set.image.image", st_images_set_image_image},
600      {"collections.group.parts.programs.set.image.size", st_images_set_image_size},
601      {"collections.group.parts.programs.images.image", st_images_image}, /* dup */
602      {"collections.group.parts.programs.images.set.name", st_images_set_name},
603      {"collections.group.parts.programs.images.set.image.image", st_images_set_image_image},
604      {"collections.group.parts.programs.images.set.image.size", st_images_set_image_size},
605      {"collections.group.parts.programs.font", st_fonts_font}, /* dup */
606      {"collections.group.parts.programs.fonts.font", st_fonts_font}, /* dup */
607      {"collections.group.parts.programs.program.name", st_collections_group_programs_program_name}, /* dup */
608      {"collections.group.parts.programs.program.signal", st_collections_group_programs_program_signal}, /* dup */
609      {"collections.group.parts.programs.program.source", st_collections_group_programs_program_source}, /* dup */
610      {"collections.group.parts.programs.program.filter", st_collections_group_programs_program_filter}, /* dup */
611      {"collections.group.parts.programs.program.in", st_collections_group_programs_program_in}, /* dup */
612      {"collections.group.parts.programs.program.action", st_collections_group_programs_program_action}, /* dup */
613      {"collections.group.parts.programs.program.transition", st_collections_group_programs_program_transition}, /* dup */
614      {"collections.group.parts.programs.program.target", st_collections_group_programs_program_target}, /* dup */
615      {"collections.group.parts.programs.program.after", st_collections_group_programs_program_after},
616      {"collections.group.parts.programs.program.api", st_collections_group_programs_program_api},
617      {"collections.group.parts.program.name", st_collections_group_programs_program_name}, /* dup */
618      {"collections.group.parts.program.signal", st_collections_group_programs_program_signal}, /* dup */
619      {"collections.group.parts.program.source", st_collections_group_programs_program_source}, /* dup */
620      {"collections.group.parts.program.filter", st_collections_group_programs_program_filter}, /* dup */
621      {"collections.group.parts.program.in", st_collections_group_programs_program_in}, /* dup */
622      {"collections.group.parts.program.action", st_collections_group_programs_program_action}, /* dup */
623      {"collections.group.parts.program.transition", st_collections_group_programs_program_transition}, /* dup */
624      {"collections.group.parts.program.target", st_collections_group_programs_program_target}, /* dup */
625      {"collections.group.parts.program.after", st_collections_group_programs_program_after}, /* dup */
626      {"collections.group.parts.program.api", st_collections_group_programs_program_api}, /* dup */
627      {"collections.group.program.name", st_collections_group_programs_program_name}, /* dup */
628      {"collections.group.program.signal", st_collections_group_programs_program_signal}, /* dup */
629      {"collections.group.program.source", st_collections_group_programs_program_source}, /* dup */
630      {"collections.group.program.filter", st_collections_group_programs_program_filter}, /* dup */
631      {"collections.group.program.in", st_collections_group_programs_program_in}, /* dup */
632      {"collections.group.program.action", st_collections_group_programs_program_action}, /* dup */
633      {"collections.group.program.transition", st_collections_group_programs_program_transition}, /* dup */
634      {"collections.group.program.target", st_collections_group_programs_program_target}, /* dup */
635      {"collections.group.program.after", st_collections_group_programs_program_after}, /* dup */
636      {"collections.group.program.api", st_collections_group_programs_program_api}, /* dup */
637      {"collections.group.programs.program.name", st_collections_group_programs_program_name},
638      {"collections.group.programs.program.signal", st_collections_group_programs_program_signal},
639      {"collections.group.programs.program.source", st_collections_group_programs_program_source},
640      {"collections.group.programs.program.filter", st_collections_group_programs_program_filter}, /* dup */
641      {"collections.group.programs.program.in", st_collections_group_programs_program_in},
642      {"collections.group.programs.program.action", st_collections_group_programs_program_action},
643      {"collections.group.programs.program.transition", st_collections_group_programs_program_transition},
644      {"collections.group.programs.program.target", st_collections_group_programs_program_target},
645      {"collections.group.programs.program.after", st_collections_group_programs_program_after},
646      {"collections.group.programs.program.api", st_collections_group_programs_program_api},
647      {"collections.group.programs.image", st_images_image}, /* dup */
648      {"collections.group.programs.set.name", st_images_set_name},
649      {"collections.group.programs.set.image.image", st_images_set_image_image},
650      {"collections.group.programs.set.image.size", st_images_set_image_size},
651      {"collections.group.programs.images.image", st_images_image}, /* dup */
652      {"collections.group.programs.images.set.name", st_images_set_name},
653      {"collections.group.programs.images.set.image.image", st_images_set_image_image},
654      {"collections.group.programs.images.set.image.size", st_images_set_image_size},
655      {"collections.group.programs.font", st_fonts_font}, /* dup */
656      {"collections.group.programs.fonts.font", st_fonts_font} /* dup */
657 };
658
659 New_Object_Handler object_handlers[] =
660 {
661      {"externals", NULL},
662      {"images", NULL},
663      {"images.set", ob_images_set},
664      {"images.set.image", ob_images_set_image},
665      {"fonts", NULL},
666      {"data", NULL},
667      {"styles", NULL},
668      {"styles.style", ob_styles_style},
669      {"color_classes", NULL},
670      {"color_classes.color_class", ob_color_class},
671      {"spectra", NULL},
672      {"collections", ob_collections},
673      {"collections.externals", NULL}, /* dup */
674      {"collections.set", ob_images_set}, /* dup */
675      {"collections.set.image", ob_images_set_image}, /* dup */
676      {"collections.images", NULL}, /* dup */
677      {"collections.images.set", ob_images_set}, /* dup */
678      {"collections.images.set.image", ob_images_set_image}, /* dup */
679      {"collections.fonts", NULL}, /* dup */
680      {"collections.styles", NULL}, /* dup */
681      {"collections.styles.style", ob_styles_style}, /* dup */
682      {"collections.color_classes", NULL}, /* dup */
683      {"collections.color_classes.color_class", ob_color_class}, /* dup */
684      {"collections.sounds", NULL},
685      {"collections.group.sounds", NULL}, /* dup */
686      {"collections.sounds.sample", NULL},
687      {"collections.group.sounds.sample", NULL}, /* dup */
688      {"collections.group", ob_collections_group},
689      {"collections.group.data", NULL},
690      {"collections.group.limits", NULL},
691      {"collections.group.script", ob_collections_group_script},
692      {"collections.group.lua_script", ob_collections_group_lua_script},
693      {"collections.group.externals", NULL}, /* dup */
694      {"collections.group.set", ob_images_set}, /* dup */
695      {"collections.group.set.image", ob_images_set_image}, /* dup */
696      {"collections.group.images", NULL}, /* dup */
697      {"collections.group.images.set", ob_images_set}, /* dup */
698      {"collections.group.images.set.image", ob_images_set_image}, /* dup */
699      {"collections.group.fonts", NULL}, /* dup */
700      {"collections.group.styles", NULL}, /* dup */
701      {"collections.group.styles.style", ob_styles_style}, /* dup */
702      {"collections.group.color_classes", NULL}, /* dup */
703      {"collections.group.color_classes.color_class", ob_color_class}, /* dup */
704      {"collections.group.parts", NULL},
705      {"collections.group.parts.set", ob_images_set}, /* dup */
706      {"collections.group.parts.set.image", ob_images_set_image}, /* dup */
707      {"collections.group.parts.images", NULL}, /* dup */
708      {"collections.group.parts.images.set", ob_images_set}, /* dup */
709      {"collections.group.parts.images.set.image", ob_images_set_image}, /* dup */
710      {"collections.group.parts.fonts", NULL}, /* dup */
711      {"collections.group.parts.styles", NULL}, /* dup */
712      {"collections.group.parts.styles.style", ob_styles_style}, /* dup */
713      {"collections.group.parts.color_classes", NULL}, /* dup */
714      {"collections.group.parts.color_classes.color_class", ob_color_class}, /* dup */
715      {"collections.group.parts.part", ob_collections_group_parts_part},
716      {"collections.group.parts.part.dragable", NULL},
717      {"collections.group.parts.part.set", ob_images_set}, /* dup */
718      {"collections.group.parts.part.set.image", ob_images_set_image}, /* dup */
719      {"collections.group.parts.part.images", NULL}, /* dup */
720      {"collections.group.parts.part.images.set", ob_images_set}, /* dup */
721      {"collections.group.parts.part.images.set.image", ob_images_set_image}, /* dup */
722      {"collections.group.parts.part.fonts", NULL}, /* dup */
723      {"collections.group.parts.part.styles", NULL}, /* dup */
724      {"collections.group.parts.part.styles.style", ob_styles_style}, /* dup */
725      {"collections.group.parts.part.color_classes", NULL}, /* dup */
726      {"collections.group.parts.part.color_classes.color_class", ob_color_class}, /* dup */
727      {"collections.group.parts.part.box", NULL},
728      {"collections.group.parts.part.box.items", NULL},
729      {"collections.group.parts.part.box.items.item", ob_collections_group_parts_part_box_items_item},
730      {"collections.group.parts.part.table", NULL},
731      {"collections.group.parts.part.table.items", NULL},
732      {"collections.group.parts.part.table.items.item", ob_collections_group_parts_part_box_items_item}, /* dup */
733      {"collections.group.parts.part.description", ob_collections_group_parts_part_description},
734      {"collections.group.parts.part.description.rel1", NULL},
735      {"collections.group.parts.part.description.rel2", NULL},
736      {"collections.group.parts.part.description.image", NULL}, /* dup */
737      {"collections.group.parts.part.description.image.set", ob_images_set}, /* dup */
738      {"collections.group.parts.part.description.image.set.image", ob_images_set_image}, /* dup */
739      {"collections.group.parts.part.description.image.images", NULL}, /* dup */
740      {"collections.group.parts.part.description.image.images.set", ob_images_set}, /* dup */
741      {"collections.group.parts.part.description.image.images.set.image", ob_images_set_image}, /* dup */
742      {"collections.group.parts.part.description.fill", NULL},
743      {"collections.group.parts.part.description.fill.origin", NULL},
744      {"collections.group.parts.part.description.fill.size", NULL},
745      {"collections.group.parts.part.description.text", NULL},
746      {"collections.group.parts.part.description.text.fonts", NULL}, /* dup */
747      {"collections.group.parts.part.description.images", NULL}, /* dup */
748      {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */
749      {"collections.group.parts.part.description.images.set.image", ob_images_set_image}, /* dup */
750      {"collections.group.parts.part.description.fonts", NULL}, /* dup */
751      {"collections.group.parts.part.description.styles", NULL}, /* dup */
752      {"collections.group.parts.part.description.styles.style", ob_styles_style}, /* dup */
753      {"collections.group.parts.part.description.box", NULL},
754      {"collections.group.parts.part.description.table", NULL},
755      {"collections.group.parts.part.description.map", NULL},
756      {"collections.group.parts.part.description.map.rotation", NULL},
757      {"collections.group.parts.part.description.perspective", NULL},
758      {"collections.group.parts.part.description.params", NULL},
759      {"collections.group.parts.part.description.color_classes", NULL}, /* dup */
760      {"collections.group.parts.part.description.color_classes.color_class", ob_color_class}, /* dup */
761      {"collections.group.parts.part.description.program", ob_collections_group_programs_program}, /* dup */
762      {"collections.group.parts.part.description.program.script", ob_collections_group_programs_program_script}, /* dup */
763      {"collections.group.parts.part.description.programs", NULL}, /* dup */
764      {"collections.group.parts.part.description.programs.set", ob_images_set}, /* dup */
765      {"collections.group.parts.part.description.programs.set.image", ob_images_set_image}, /* dup */
766      {"collections.group.parts.part.description.programs.images", NULL}, /* dup */
767      {"collections.group.parts.part.description.programs.images.set", ob_images_set},
768      {"collections.group.parts.part.description.programs.images.set.image", ob_images_set_image}, /* dup */
769      {"collections.group.parts.part.description.programs.fonts", NULL}, /* dup */
770      {"collections.group.parts.part.description.programs.program", ob_collections_group_programs_program}, /* dup */
771      {"collections.group.parts.part.description.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
772      {"collections.group.parts.part.description.script", ob_collections_group_script}, /* dup */
773      {"collections.group.parts.part.program", ob_collections_group_programs_program}, /* dup */
774      {"collections.group.parts.part.program.script", ob_collections_group_programs_program_script}, /* dup */
775      {"collections.group.parts.part.programs", NULL}, /* dup */
776      {"collections.group.parts.part.programs.set", ob_images_set}, /* dup */
777      {"collections.group.parts.part.programs.set.image", ob_images_set_image}, /* dup */
778      {"collections.group.parts.part.programs.images", NULL}, /* dup */
779      {"collections.group.parts.part.programs.images.set", ob_images_set}, /* dup */
780      {"collections.group.parts.part.programs.images.set.image", ob_images_set_image}, /* dup */
781      {"collections.group.parts.part.programs.fonts", NULL}, /* dup */
782      {"collections.group.parts.part.programs.program", ob_collections_group_programs_program}, /* dup */
783      {"collections.group.parts.part.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
784      {"collections.group.parts.part.script", ob_collections_group_script}, /* dup */
785      {"collections.group.parts.program", ob_collections_group_programs_program}, /* dup */
786      {"collections.group.parts.program.script", ob_collections_group_programs_program_script}, /* dup */
787      {"collections.group.parts.programs", NULL}, /* dup */
788      {"collections.group.parts.programs.set", ob_images_set}, /* dup */
789      {"collections.group.parts.programs.set.image", ob_images_set_image}, /* dup */
790      {"collections.group.parts.programs.images", NULL}, /* dup */
791      {"collections.group.parts.programs.images.set", ob_images_set}, /* dup */
792      {"collections.group.parts.programs.images.set.image", ob_images_set_image}, /* dup */
793      {"collections.group.parts.programs.fonts", NULL}, /* dup */
794      {"collections.group.parts.programs.program", ob_collections_group_programs_program}, /* dup */
795      {"collections.group.parts.programs.program.script", ob_collections_group_programs_program_script}, /* dup */
796      {"collections.group.parts.script", ob_collections_group_script}, /* dup */
797      {"collections.group.program", ob_collections_group_programs_program}, /* dup */
798      {"collections.group.program.script", ob_collections_group_programs_program_script}, /* dup */
799      {"collections.group.programs", NULL},
800      {"collections.group.programs.set", ob_images_set}, /* dup */
801      {"collections.group.programs.set.image", ob_images_set_image}, /* dup */
802      {"collections.group.programs.images", NULL}, /* dup */
803      {"collections.group.programs.images.set", ob_images_set}, /* dup */
804      {"collections.group.programs.images.set.image", ob_images_set_image}, /* dup */
805      {"collections.group.programs.fonts", NULL}, /* dup */
806      {"collections.group.programs.program", ob_collections_group_programs_program},
807      {"collections.group.programs.program.script", ob_collections_group_programs_program_script},
808      {"collections.group.programs.script", ob_collections_group_script} /* dup */
809 };
810
811 /*****/
812
813 int
814 object_handler_num(void)
815 {
816    return sizeof(object_handlers) / sizeof (New_Object_Handler);
817 }
818
819 int
820 statement_handler_num(void)
821 {
822    return sizeof(statement_handlers) / sizeof (New_Object_Handler);
823 }
824
825 static void
826 _edje_part_description_fill(Edje_Part_Description_Spec_Fill *fill)
827 {
828    fill->smooth = 1;
829    fill->pos_rel_x = FROM_DOUBLE(0.0);
830    fill->pos_abs_x = 0;
831    fill->rel_x = FROM_DOUBLE(1.0);
832    fill->abs_x = 0;
833    fill->pos_rel_y = FROM_DOUBLE(0.0);
834    fill->pos_abs_y = 0;
835    fill->rel_y = FROM_DOUBLE(1.0);
836    fill->abs_y = 0;
837    fill->angle = 0;
838    fill->spread = 0;
839    fill->type = EDJE_FILL_TYPE_SCALE;
840 }
841
842 static void
843 _edje_part_description_image_remove(Edje_Part_Description_Image *ed)
844 {
845    unsigned int j;
846
847    if (!ed) return;
848
849    data_queue_image_remove(&(ed->image.id), &(ed->image.set));
850
851    for (j = 0; j < ed->image.tweens_count; ++j)
852      data_queue_image_remove(&(ed->image.tweens[j]->id),
853                              &(ed->image.tweens[j]->set));
854 }
855
856 void
857 part_description_image_cleanup(Edje_Part *ep)
858 {
859    Edje_Part_Description_Image *ed;
860    unsigned int j;
861
862    if (ep->type != EDJE_PART_TYPE_IMAGE)
863      return ;
864
865    ed = (Edje_Part_Description_Image*) ep->default_desc;
866    _edje_part_description_image_remove(ed);
867
868    for (j = 0; j < ep->other.desc_count; j++)
869      {
870         ed = (Edje_Part_Description_Image*) ep->other.desc[j];
871         _edje_part_description_image_remove(ed);
872      }
873 }
874
875 static Edje_Part_Description_Common *
876 _edje_part_description_alloc(unsigned char type, const char *collection, const char *part)
877 {
878    Edje_Part_Description_Common *result = NULL;
879
880    switch (type)
881      {
882       case EDJE_PART_TYPE_SPACER:
883       case EDJE_PART_TYPE_RECTANGLE:
884       case EDJE_PART_TYPE_SWALLOW:
885       case EDJE_PART_TYPE_GROUP:
886          result = mem_alloc(SZ(Edje_Part_Description_Common));
887          break;
888       case EDJE_PART_TYPE_TEXT:
889       case EDJE_PART_TYPE_TEXTBLOCK:
890         {
891            Edje_Part_Description_Text *ed;
892
893            ed = mem_alloc(SZ(Edje_Part_Description_Text));
894
895            ed->text.color3.r = 0;
896            ed->text.color3.g = 0;
897            ed->text.color3.b = 0;
898            ed->text.color3.a = 128;
899            ed->text.align.x = FROM_DOUBLE(0.5);
900            ed->text.align.y = FROM_DOUBLE(0.5);
901            ed->text.id_source = -1;
902            ed->text.id_text_source = -1;
903
904            result = &ed->common;
905            break;
906         }
907       case EDJE_PART_TYPE_IMAGE:
908         {
909            Edje_Part_Description_Image *ed;
910
911            ed = mem_alloc(SZ(Edje_Part_Description_Image));
912
913            ed->image.id = -1;
914
915            _edje_part_description_fill(&ed->image.fill);
916
917            result = &ed->common;
918            break;
919         }
920       case EDJE_PART_TYPE_PROXY:
921         {
922            Edje_Part_Description_Proxy *ed;
923
924            ed = mem_alloc(SZ(Edje_Part_Description_Proxy));
925
926            ed->proxy.id = -1;
927
928            _edje_part_description_fill(&ed->proxy.fill);
929
930            result = &ed->common;
931            break;
932         }
933       case EDJE_PART_TYPE_BOX:
934         {
935            Edje_Part_Description_Box *ed;
936
937            ed = mem_alloc(SZ(Edje_Part_Description_Box));
938
939            ed->box.layout = NULL;
940            ed->box.alt_layout = NULL;
941            ed->box.align.x = FROM_DOUBLE(0.5);
942            ed->box.align.y = FROM_DOUBLE(0.5);
943            ed->box.padding.x = 0;
944            ed->box.padding.y = 0;
945
946            result = &ed->common;
947            break;
948         }
949       case EDJE_PART_TYPE_TABLE:
950         {
951            Edje_Part_Description_Table *ed;
952
953            ed = mem_alloc(SZ(Edje_Part_Description_Table));
954
955            ed->table.homogeneous = EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE;
956            ed->table.align.x = FROM_DOUBLE(0.5);
957            ed->table.align.y = FROM_DOUBLE(0.5);
958            ed->table.padding.x = 0;
959            ed->table.padding.y = 0;
960
961            result = &ed->common;
962            break;
963         }
964       case EDJE_PART_TYPE_EXTERNAL:
965         {
966            Edje_Part_Description_External *ed;
967
968            ed = mem_alloc(SZ(Edje_Part_Description_External));
969
970            ed->external_params = NULL;
971
972            result = &ed->common;
973            break;
974         }
975      }
976
977    if (!result)
978      {
979         ERR("Unknown type %i of part %s in collection %s.",
980             type, part, collection);
981         exit(-1);
982      }
983
984    return result;
985 }
986
987 static void
988 _edje_program_check(const char *name, Edje_Program *me, Edje_Program **pgrms, unsigned int count)
989 {
990    Edje_Part_Collection *pc;
991    unsigned int i;
992    Edje_Program_Parser *epp;
993
994    pc = eina_list_data_get(eina_list_last(edje_collections));
995
996    for (i = 0; i < count; ++i)
997      if (pgrms[i]->name)
998        if (pgrms[i] != me && (!strcmp(name, pgrms[i]->name)))
999          {
1000             epp = (Edje_Program_Parser *)pgrms[i];
1001             if (!epp->can_override)
1002               {
1003                  ERR("parse error %s:%i. There is already a program of the name %s",
1004                      file_in, line - 1, name);
1005                  exit(-1);
1006               }
1007             else
1008               {
1009                  _edje_program_remove(pc, me);
1010                  current_program = pgrms[i];
1011                  epp->can_override = EINA_FALSE;
1012                  return;
1013               }
1014          }
1015 }
1016
1017 static void
1018 _edje_program_copy(Edje_Program *ep, Edje_Program *ep2)
1019 {
1020    Edje_Part_Collection *pc;
1021    Edje_Program_Target *et, *et2;
1022    Edje_Program_After *pa, *pa2;
1023    Edje_Program_Parser *epp;
1024    Eina_List *l;
1025    char *name;
1026    char *copy;
1027
1028    pc = eina_list_data_get(eina_list_last(edje_collections));
1029
1030    #define STRDUP(x) x ? strdup(x) : NULL
1031    ep->name = STRDUP(ep2->name);
1032
1033    _edje_program_remove(pc, current_program);
1034    ep->signal = STRDUP(ep2->signal);
1035    ep->source = STRDUP(ep2->source);
1036    _edje_program_insert(pc, current_program);
1037
1038    ep->filter.part = STRDUP(ep2->filter.part);
1039    ep->filter.state = STRDUP(ep2->filter.state);
1040    ep->in.from = ep2->in.from;
1041    ep->in.range = ep2->in.range;
1042    ep->action = ep2->action;
1043    ep->state = STRDUP(ep2->state);
1044    ep->state2 = STRDUP(ep2->state2);
1045    ep->value = ep2->value;
1046    ep->value2 = ep2->value2;
1047    ep->tween.mode = ep2->tween.mode;
1048    ep->tween.time = ep2->tween.time;
1049    ep->tween.v1 = ep2->tween.v1;
1050    ep->tween.v2 = ep2->tween.v2;
1051    ep->sample_name = STRDUP(ep2->sample_name);
1052    ep->tone_name = STRDUP(ep2->tone_name);
1053    ep->duration = ep2->duration;
1054    ep->speed = ep2->speed;
1055
1056    EINA_LIST_FOREACH(ep2->targets, l, et2)
1057      {
1058         name = (char*) (et2 + 1);
1059         et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
1060         ep->targets = eina_list_append(ep->targets, et);
1061         copy = (char*) (et + 1);
1062
1063         memcpy(copy, name, strlen(name) + 1);
1064
1065         if (ep2->action == EDJE_ACTION_TYPE_STATE_SET)
1066           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1067         else if (ep2->action == EDJE_ACTION_TYPE_ACTION_STOP)
1068           data_queue_copied_program_lookup(pc, &(et2->id), &(et->id));
1069         else if (ep2->action == EDJE_ACTION_TYPE_SCRIPT)
1070           data_queue_copied_program_lookup(pc, &(et2->id), &(et->id));
1071         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
1072           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1073         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
1074           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1075         else if (ep2->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
1076           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1077         else if (ep2->action == EDJE_ACTION_TYPE_FOCUS_SET)
1078
1079           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1080         else if (ep2->action == EDJE_ACTION_TYPE_FOCUS_OBJECT)
1081           data_queue_copied_part_lookup(pc, &(et2->id), &(et->id));
1082         else
1083           {
1084              ERR("parse error %s:%i. target may only be used after action",
1085                  file_in, line - 1);
1086              exit(-1);
1087           }
1088      }
1089
1090    EINA_LIST_FOREACH(ep2->after, l, pa2)
1091      {
1092         name = (char*) (pa2 + 1);
1093         pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
1094         ep->after = eina_list_append(ep->after, pa);
1095         copy = (char*) (pa + 1);
1096         memcpy(copy, name, strlen(name) + 1);
1097         data_queue_copied_program_lookup(pc, &(pa2->id), &(pa->id));
1098      }
1099
1100    ep->api.name = STRDUP(ep2->api.name);
1101    ep->api.description = STRDUP(ep2->api.description);
1102    data_queue_copied_part_lookup(pc, &(ep2->param.src), &(ep->param.src));
1103    data_queue_copied_part_lookup(pc, &(ep2->param.dst), &(ep->param.dst));
1104
1105    epp = (Edje_Program_Parser *)ep;
1106    epp->can_override = EINA_TRUE;
1107
1108    #undef STRDUP
1109 }
1110
1111 /*****/
1112
1113 /**
1114    @edcsection{toplevel,Top-Level blocks}
1115  */
1116
1117 /**
1118     @page edcref
1119
1120     @block
1121         externals
1122     @context
1123         externals {
1124            external: "name";
1125         }
1126     @description
1127         The "externals" block is used to list each external module file that will be used in others
1128         programs.
1129     @endblock
1130
1131     @property
1132         external
1133     @parameters
1134         [external filename]
1135     @effect
1136         Used to add a file to the externals list.
1137     @endproperty
1138  */
1139 static void
1140 st_externals_external(void)
1141 {
1142    External *ex;
1143
1144    check_arg_count(1);
1145
1146    if (!edje_file->external_dir)
1147      edje_file->external_dir = mem_alloc(SZ(Edje_External_Directory));
1148
1149    ex = mem_alloc(SZ(External));
1150    ex->name = parse_str(0);
1151      {
1152         Eina_List *l;
1153         External *lex;
1154
1155         EINA_LIST_FOREACH(externals, l, lex)
1156           {
1157              if (!strcmp(lex->name, ex->name))
1158                {
1159                   free(ex->name);
1160                   free(ex);
1161                   return;
1162                }
1163           }
1164      }
1165    externals = eina_list_append(externals, ex);
1166
1167    if (edje_file->external_dir)
1168      {
1169         edje_file->external_dir->entries_count++;
1170         edje_file->external_dir->entries = realloc(edje_file->external_dir->entries,
1171                                                    sizeof (Edje_External_Directory) * edje_file->external_dir->entries_count);
1172         memset(edje_file->external_dir->entries + edje_file->external_dir->entries_count - 1,
1173                0, sizeof (Edje_External_Directory));
1174         if (!edje_file->external_dir->entries)
1175           {
1176              ERR("not enough memory");
1177              exit(-1);
1178           }
1179
1180         edje_file->external_dir->entries[edje_file->external_dir->entries_count - 1].entry = mem_strdup(ex->name);
1181      }
1182 }
1183
1184 /**
1185     @page edcref
1186
1187     @block
1188         images
1189     @context
1190         images {
1191             image: "filename1.ext" COMP;
1192             image: "filename2.ext" LOSSY 99;
1193             set {
1194                name: "image_name_used";
1195                image {
1196                   image: "filename3.ext" LOSSY 90;
1197                   size: 201 201 500 500;
1198                }
1199                image {
1200                   image: "filename4.ext" COMP;
1201                   size: 51 51 200 200;
1202                }
1203                image {
1204                   image: "filename5.ext" COMP;
1205                   size: 11 11 50 50;
1206                }
1207                image {
1208                   image: "filename6.ext" RAW;
1209                   size: 0 0 10 10;
1210                }
1211             }
1212             ..
1213         }
1214     @description
1215         The "images" block is used to list each image file that will be used in
1216         the theme along with its compression method (if any).
1217         Besides the document's root, additional "images" blocks can be
1218         included inside other blocks, normally "collections", "group" and
1219         "part", easing maintenance of the file list when the theme is split
1220         among multiple files.
1221     @endblock
1222
1223     @property
1224         image
1225     @parameters
1226         [image file] [compression method] (compression level)
1227     @effect
1228         Used to include each image file. The full path to the directory holding
1229         the images can be defined later with edje_cc's "-id" option.
1230         Compression methods:
1231         @li RAW: Uncompressed.
1232         @li COMP: Lossless compression.
1233         @li LOSSY [0-100]: Lossy compression with quality from 0 to 100.
1234         @li USER: Do not embed the file, refer to the external file instead.
1235     @endproperty
1236  */
1237 static void
1238 st_images_image(void)
1239 {
1240    Edje_Image_Directory_Entry *img;
1241    const char *tmp;
1242    unsigned int i;
1243    int v;
1244
1245    if (!edje_file->image_dir)
1246      edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
1247
1248    tmp = parse_str(0);
1249
1250    for (i = 0; i < edje_file->image_dir->entries_count; ++i)
1251      if (!strcmp(edje_file->image_dir->entries[i].entry, tmp))
1252        {
1253           free((char*) tmp);
1254           return;
1255        }
1256
1257    edje_file->image_dir->entries_count++;
1258    edje_file->image_dir->entries = realloc(edje_file->image_dir->entries,
1259                                            sizeof (Edje_Image_Directory_Entry) * edje_file->image_dir->entries_count);
1260    memset(edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1,
1261           0, sizeof (Edje_Image_Directory_Entry));
1262    if (!edje_file->image_dir->entries)
1263      {
1264         ERR("No enough memory.");
1265         exit(-1);
1266      }
1267
1268    img = edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1;
1269
1270    img->entry = tmp;
1271    img->id = edje_file->image_dir->entries_count - 1;
1272    v = parse_enum(1,
1273                   "RAW", 0,
1274                   "COMP", 1,
1275                   "LOSSY", 2,
1276                   "USER", 3,
1277                   NULL);
1278    if (v == 0)
1279      {
1280         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
1281         img->source_param = 0;
1282      }
1283    else if (v == 1)
1284      {
1285         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT;
1286         img->source_param = 1;
1287      }
1288    else if (v == 2)
1289      {
1290         img->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY;
1291         img->source_param = 0;
1292      }
1293    else if (v == 3)
1294      {
1295         img->source_type = EDJE_IMAGE_SOURCE_TYPE_EXTERNAL;
1296         img->source_param = 0;
1297      }
1298    if (img->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY)
1299         check_arg_count(2);
1300    else
1301      {
1302         img->source_param = parse_int_range(2, 0, 100);
1303         check_arg_count(3);
1304      }
1305 }
1306
1307 /**
1308     @page edcref
1309
1310     @block
1311         set
1312     @context
1313     set {
1314        name: "image_name_used";
1315        image {
1316           image: "filename3.ext" LOSSY 90;
1317           size: 201 201 500 500;
1318        }
1319        image {
1320           image: "filename4.ext" COMP;
1321           size: 51 51 200 200;
1322        }
1323        image {
1324           image: "filename5.ext" COMP;
1325           size: 11 11 50 50;
1326        }
1327        image {
1328           image: "filename6.ext" RAW;
1329           size: 0 0 10 10;
1330        }
1331     }
1332     @description
1333         The "set" block is used to define an image with different content depending on their size.
1334         Besides the document's root, additional "set" blocks can be
1335         included inside other blocks, normally "collections", "group" and
1336         "part", easing maintenance of the file list when the theme is split
1337         among multiple files.
1338     @endblock
1339  */
1340 static void
1341 ob_images_set(void)
1342 {
1343    if (!edje_file->image_dir)
1344      edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory));
1345
1346    edje_file->image_dir->sets_count++;
1347    edje_file->image_dir->sets = realloc(edje_file->image_dir->sets,
1348                                         sizeof (Edje_Image_Directory_Set) * edje_file->image_dir->sets_count);
1349    memset(edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1,
1350           0, sizeof (Edje_Image_Directory_Set));
1351    if (!edje_file->image_dir->sets)
1352      {
1353         ERR("Not enough memory.");
1354         exit(-1);
1355      }
1356    edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].id = edje_file->image_dir->sets_count - 1;
1357 }
1358
1359 /**
1360     @page edcref
1361
1362     @property
1363         name
1364     @parameters
1365         [image name]
1366     @effect
1367         Define the name that refer to this image description.
1368     @endproperty
1369 */
1370 static void
1371 st_images_set_name(void)
1372 {
1373    check_arg_count(1);
1374
1375    edje_file->image_dir->sets[edje_file->image_dir->sets_count - 1].name = parse_str(0);
1376 }
1377
1378 /**
1379     @page edcref
1380
1381     @block
1382         image
1383     @description
1384         The "image" block inside a "set" block define the characteristic of an image.
1385         Every block will describe one image and the size rule to use it.
1386     @endblock
1387 **/
1388 static void
1389 ob_images_set_image(void)
1390 {
1391    Edje_Image_Directory_Set_Entry *entry;
1392    Edje_Image_Directory_Set *set;
1393
1394    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1395
1396    entry = mem_alloc(SZ(Edje_Image_Directory_Set_Entry));
1397
1398    set->entries = eina_list_append(set->entries, entry);
1399 }
1400
1401 /**
1402     @page edcref
1403
1404     @property
1405         image
1406     @parameters
1407         [image file] [compression method] (compression level)
1408     @effect
1409         Used to include each image file. The full path to the directory holding
1410         the images can be defined later with edje_cc's "-id" option.
1411         Compression methods:
1412         @li RAW: Uncompressed.
1413         @li COMP: Lossless compression.
1414         @li LOSSY [0-100]: Lossy compression with quality from 0 to 100.
1415         @li USER: Do not embed the file, refer to the external file instead.
1416     @endproperty
1417 **/
1418 static void
1419 st_images_set_image_image(void)
1420 {
1421    Edje_Image_Directory_Set_Entry *entry;
1422    Edje_Image_Directory_Set *set;
1423    unsigned int i;
1424
1425    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1426    entry = eina_list_data_get(eina_list_last(set->entries));
1427
1428    /* Add the image to the global pool with the same syntax. */
1429    st_images_image();
1430
1431    entry->name = parse_str(0);
1432
1433    for (i = 0; i < edje_file->image_dir->entries_count; ++i)
1434      if (!strcmp(edje_file->image_dir->entries[i].entry, entry->name))
1435        {
1436          entry->id = i;
1437          return;
1438        }
1439 }
1440
1441 /**
1442     @page edcref
1443
1444     @property
1445         size
1446     @parameters
1447         [minw minh maxw mawh]
1448     @effect
1449         Define the minimal and maximal size that will select the specified image.
1450     @endproperty
1451 */
1452 static void
1453 st_images_set_image_size(void)
1454 {
1455    Edje_Image_Directory_Set_Entry *entry;
1456    Edje_Image_Directory_Set *set;
1457
1458    set = edje_file->image_dir->sets + edje_file->image_dir->sets_count - 1;
1459    entry = eina_list_data_get(eina_list_last(set->entries));
1460
1461    entry->size.min.w = parse_int(0);
1462    entry->size.min.h = parse_int(1);
1463    entry->size.max.w = parse_int(2);
1464    entry->size.max.h = parse_int(3);
1465
1466    if (entry->size.min.w > entry->size.max.w
1467        || entry->size.min.h > entry->size.max.h)
1468      {
1469        ERR("parse error %s:%i. Image min and max size are not in the right order ([%i, %i] < [%i, %i])",
1470            file_in, line - 1,
1471            entry->size.min.w, entry->size.min.h,
1472            entry->size.max.w, entry->size.max.h);
1473        exit(-1);
1474      }
1475 }
1476
1477 /**
1478     @page edcref
1479
1480     @block
1481         fonts
1482     @context
1483         fonts {
1484             font: "filename1.ext" "fontname";
1485             font: "filename2.ext" "otherfontname";
1486             ..
1487         }
1488     @description
1489         The "fonts" block is used to list each font file with an alias used later
1490         in the theme. As with the "images" block, additional "fonts" blocks can
1491         be included inside other blocks.
1492     @endblock
1493
1494     @property
1495         font
1496     @parameters
1497         [font filename] [font alias]
1498     @effect
1499         Defines each font "file" and "alias", the full path to the directory
1500         holding the font files can be defined with edje_cc's "-fd" option.
1501     @endproperty
1502  */
1503 static void
1504 st_fonts_font(void)
1505 {
1506    Font *fn;
1507
1508    check_arg_count(2);
1509
1510    if (!edje_file->fonts)
1511      edje_file->fonts = eina_hash_string_small_new(free);
1512
1513    fn = mem_alloc(SZ(Font));
1514    fn->file = parse_str(0);
1515    fn->name = parse_str(1);
1516
1517    if (eina_hash_find(edje_file->fonts, fn->name))
1518      {
1519         free(fn->file);
1520         free(fn->name);
1521         free(fn);
1522         return;
1523      }
1524
1525    eina_hash_direct_add(edje_file->fonts, fn->name, fn);
1526 }
1527
1528 /**
1529     @page edcref
1530     @block
1531         data
1532     @context
1533         data {
1534             item: "key" "value";
1535             file: "otherkey" "filename.ext";
1536             ..
1537         }
1538     @description
1539         The "data" block is used to pass arbitrary parameters from the theme to
1540         the application. Unlike the "images" and "fonts" blocks, additional
1541         "data" blocks can only be included inside the "group" block.
1542     @endblock
1543
1544     @property
1545         item
1546     @parameters
1547         [parameter name] [parameter value]
1548     @effect
1549         Defines a new parameter, the value will be the string specified next to
1550         it.
1551     @endproperty
1552  */
1553 static void
1554 st_data_item(void)
1555 {
1556    Edje_String *es;
1557    char *key;
1558
1559    check_arg_count(2);
1560
1561    key = parse_str(0);
1562
1563    es = mem_alloc(SZ(Edje_String));
1564    es->str = parse_str(1);
1565
1566    if (!edje_file->data)
1567      edje_file->data = eina_hash_string_small_new(free);
1568
1569    /* FIXME: check if data already exist */
1570    eina_hash_direct_add(edje_file->data, key, es);
1571 }
1572
1573 /**
1574     @page edcref
1575     @property
1576         file
1577     @parameters
1578         [parameter name] [parameter filename]
1579     @effect
1580         Defines a new parameter, the value will be the contents of the
1581         specified file formated as a single string of text. This property only
1582         works with plain text files.
1583     @endproperty
1584  */
1585 static void
1586 st_data_file(void)
1587 {
1588    const char *data;
1589    const char *over;
1590    Edje_String *es;
1591    char *filename;
1592    char *value;
1593    char *key;
1594    int fd;
1595    int i;
1596    struct stat buf;
1597
1598    check_arg_count(2);
1599
1600    key = parse_str(0);
1601
1602    es = mem_alloc(SZ(Edje_String));
1603    filename = parse_str(1);
1604
1605    fd = open(filename, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
1606    if (fd < 0)
1607      {
1608         ERR("%s:%i when opening file \"%s\": \"%s\"",
1609             file_in, line, filename, strerror(errno));
1610         exit(-1);
1611      }
1612
1613    if (fstat(fd, &buf))
1614      {
1615         ERR("%s:%i when stating file \"%s\": \"%s\"",
1616             file_in, line, filename, strerror(errno));
1617         exit(-1);
1618      }
1619
1620    data = mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
1621    if (data == MAP_FAILED)
1622      {
1623         ERR("%s:%i when mapping file \"%s\": \"%s\"",
1624             file_in, line, filename, strerror(errno));
1625         exit(-1);
1626      }
1627
1628    over = data;
1629    for (i = 0; i < buf.st_size; ++i, ++over)
1630      if (*over == '\0')
1631        {
1632           ERR("%s:%i file \"%s\" is a binary file.", file_in, line, filename);
1633           exit(-1);
1634        }
1635
1636    value = malloc(sizeof (char) * buf.st_size + 1);
1637    snprintf(value, buf.st_size + 1, "%s", data);
1638
1639    munmap((void*)data, buf.st_size);
1640    close(fd);
1641
1642    es->str = value;
1643
1644    eina_hash_direct_add(edje_file->data, key, es);
1645
1646    free(filename);
1647 }
1648
1649 /**
1650     @page edcref
1651     @block
1652         color_classes
1653     @context
1654         color_classes {
1655             color_class {
1656                 name:  "colorclassname";
1657                 color:  [0-255] [0-255] [0-255] [0-255];
1658                 color2: [0-255] [0-255] [0-255] [0-255];
1659                 color3: [0-255] [0-255] [0-255] [0-255]
1660             }
1661             ..
1662         }
1663     @description
1664         The "color_classes" block contains a list of one or more "color_class"
1665         blocks. Each "color_class" allows the designer to name an arbitrary
1666         group of colors to be used in the theme, the application can use that
1667         name to alter the color values at runtime.
1668     @endblock
1669 */
1670 static void
1671 ob_color_class(void)
1672 {
1673    Edje_Color_Class *cc;
1674
1675    cc = mem_alloc(SZ(Edje_Color_Class));
1676    edje_file->color_classes = eina_list_append(edje_file->color_classes, cc);
1677
1678    cc->r = 0;
1679    cc->g = 0;
1680    cc->b = 0;
1681    cc->a = 0;
1682    cc->r2 = 0;
1683    cc->g2 = 0;
1684    cc->b2 = 0;
1685    cc->a2 = 0;
1686    cc->r3 = 0;
1687    cc->g3 = 0;
1688    cc->b3 = 0;
1689    cc->a3 = 0;
1690 }
1691
1692 /**
1693     @page edcref
1694
1695     @property
1696         name
1697     @parameters
1698         [color class name]
1699     @effect
1700         Sets the name for the color class, used as reference by both the theme
1701         and the application.
1702     @endproperty
1703 */
1704 static void
1705 st_color_class_name(void)
1706 {
1707    Edje_Color_Class *cc, *tcc;
1708    Eina_List *l;
1709
1710    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1711    cc->name = parse_str(0);
1712    EINA_LIST_FOREACH(edje_file->color_classes, l, tcc)
1713      {
1714         if ((cc != tcc) && (!strcmp(cc->name, tcc->name)))
1715           {
1716              ERR("parse error %s:%i. There is already a color class named \"%s\"",
1717                  file_in, line - 1, cc->name);
1718              exit(-1);
1719           }
1720      }
1721 }
1722
1723 /**
1724     @page edcref
1725     @property
1726         color
1727     @parameters
1728         [red] [green] [blue] [alpha]
1729     @effect
1730         The main color.
1731     @endproperty
1732 */
1733 static void
1734 st_color_class_color(void)
1735 {
1736    Edje_Color_Class *cc;
1737
1738    check_arg_count(4);
1739
1740    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1741    cc->r = parse_int_range(0, 0, 255);
1742    cc->g = parse_int_range(1, 0, 255);
1743    cc->b = parse_int_range(2, 0, 255);
1744    cc->a = parse_int_range(3, 0, 255);
1745 }
1746
1747 /**
1748     @page edcref
1749     @property
1750         color2
1751     @parameters
1752         [red] [green] [blue] [alpha]
1753     @effect
1754         Used as shadow in text and textblock parts.
1755     @endproperty
1756 */
1757 static void
1758 st_color_class_color2(void)
1759 {
1760    Edje_Color_Class *cc;
1761
1762    check_arg_count(4);
1763
1764    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1765    cc->r2 = parse_int_range(0, 0, 255);
1766    cc->g2 = parse_int_range(1, 0, 255);
1767    cc->b2 = parse_int_range(2, 0, 255);
1768    cc->a2 = parse_int_range(3, 0, 255);
1769 }
1770
1771 /**
1772     @page edcref
1773     @property
1774         color3
1775     @parameters
1776         [red] [green] [blue] [alpha]
1777     @effect
1778         Used as outline in text and textblock parts.
1779     @endproperty
1780 */
1781 static void
1782 st_color_class_color3(void)
1783 {
1784    Edje_Color_Class *cc;
1785
1786    check_arg_count(4);
1787
1788    cc = eina_list_data_get(eina_list_last(edje_file->color_classes));
1789    cc->r3 = parse_int_range(0, 0, 255);
1790    cc->g3 = parse_int_range(1, 0, 255);
1791    cc->b3 = parse_int_range(2, 0, 255);
1792    cc->a3 = parse_int_range(3, 0, 255);
1793 }
1794
1795 /**
1796     @page edcref
1797     @block
1798         styles
1799     @context
1800         styles {
1801             style {
1802                 name: "stylename";
1803                 base: "..default style properties..";
1804
1805                 tag:  "tagname" "..style properties..";
1806                 ..
1807             }
1808             ..
1809         }
1810     @description
1811         The "styles" block contains a list of one or more "style" blocks. A
1812         "style" block is used to create style \<tags\> for advanced TEXTBLOCK
1813         formatting.
1814     @endblock
1815 */
1816 static void
1817 ob_styles_style(void)
1818 {
1819    Edje_Style *stl;
1820
1821    stl = mem_alloc(SZ(Edje_Style));
1822    edje_file->styles = eina_list_append(edje_file->styles, stl);
1823 }
1824
1825 /**
1826     @page edcref
1827     @property
1828         name
1829     @parameters
1830         [style name]
1831     @effect
1832         The name of  the style to be used as reference later in the theme.
1833     @endproperty
1834 */
1835 static void
1836 st_styles_style_name(void)
1837 {
1838    Edje_Style *stl, *tstl;
1839    Eina_List *l;
1840
1841    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1842    stl->name = parse_str(0);
1843    EINA_LIST_FOREACH(edje_file->styles, l, tstl)
1844      {
1845         if (stl->name && tstl->name && (stl != tstl) && (!strcmp(stl->name, tstl->name)))
1846           {
1847              ERR("parse error %s:%i. There is already a style named \"%s\"",
1848                  file_in, line - 1, stl->name);
1849              exit(-1);
1850           }
1851      }
1852 }
1853
1854 /**
1855     @page edcref
1856     @property
1857         base
1858     @parameters
1859         [style properties string]
1860     @effect
1861         The default style properties that will be applied to the complete
1862         text.
1863     @endproperty
1864 */
1865 static void
1866 st_styles_style_base(void)
1867 {
1868    Edje_Style *stl;
1869    Edje_Style_Tag *tag;
1870
1871    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1872    if (stl->tags)
1873      {
1874         ERR("parse error %s:%i. There is already a basic format for the style",
1875             file_in, line - 1);
1876         exit(-1);
1877      }
1878    tag = mem_alloc(SZ(Edje_Style_Tag));
1879    tag->key = mem_strdup("DEFAULT");
1880    tag->value = parse_str(0);
1881    stl->tags = eina_list_append(stl->tags, tag);
1882 }
1883
1884 /**
1885     @page edcref
1886     @property
1887         tag
1888     @parameters
1889         [tag name] [style properties string]
1890     @effect
1891         Style to be applied only to text between style \<tags\>..\</tags\>.
1892         When creating "paired" tags, like \<bold\>\</bold\>, A '+' should be added at the start of the style properties of the first part (\<bold\>).
1893         If the second part (\</bold\>) is also defined, a '-' should be prepended to it's style properties.
1894         This only applies to paired tags; Single tags, like \<tab\>, must not include a starting '+'.
1895     @endproperty
1896 */
1897 static void
1898 st_styles_style_tag(void)
1899 {
1900    Edje_Style *stl;
1901    Edje_Style_Tag *tag;
1902
1903    stl = eina_list_data_get(eina_list_last(edje_file->styles));
1904    tag = mem_alloc(SZ(Edje_Style_Tag));
1905    tag->key = parse_str(0);
1906    tag->value = parse_str(1);
1907    stl->tags = eina_list_append(stl->tags, tag);
1908 }
1909
1910 /**
1911     @page edcref
1912     @block
1913         collections
1914     @context
1915         collections {
1916             ..
1917             group { }
1918             group { }
1919             sounds { }
1920             ..
1921         }
1922     @description
1923         The "collections" block is used to list the groups that compose the
1924         theme. Additional "collections" blocks do not prevent overriding group
1925         names. The "sounds" block comprises of all sound definitions.
1926     @endblock
1927 */
1928 static void
1929 ob_collections(void)
1930 {
1931    if (!edje_file->collection)
1932      edje_file->collection = eina_hash_string_small_new(NULL);
1933 }
1934
1935 /**
1936     @page edcref
1937     @block
1938         sounds
1939     @context
1940         sounds {
1941            sample {
1942               name: "sound_file1" COMP;
1943               source: "sound_file1.wav";
1944            }
1945            sample {
1946               name: "sound_file2" LOSSY 0.4;
1947               source: "sound_file2.wav";
1948            }
1949            tone: "tone-1"  2300;
1950         }
1951
1952     @description
1953         The "sounds" block contains a list of one or more sound sample and tones items.
1954     @endblock
1955     @block
1956         sample
1957     @context
1958        sample {
1959           name: "sound_file1" RAW;
1960           source: "sound_file1.wav";
1961        }
1962        sample {
1963           name: "sound_file2" LOSSY 0.5;
1964           source: "sound_file2.wav";
1965        }
1966        sample {
1967           name: "sound_file3" COMP;
1968           source: "sound_file3.wav";
1969        }
1970        sample {
1971           name: "sound_file4" AS_IS;
1972           source: "sound_file1.wav";
1973        }
1974     @description
1975         The sample block defines the sound sample.
1976     @endblock
1977     @property
1978         name
1979     @parameters
1980         [sample name] [compression type] [if lossy, then quality]
1981     @effect
1982         Used to include each sound file. The full path to the directory holding
1983         the sounds can be defined later with edje_cc's "-sd" option.
1984         @li RAW: Uncompressed.
1985         @li COMP: Lossless compression.
1986         @li LOSSY [-0.1  - 1.0]: Lossy compression with quality from 0 to 1.0.
1987         @li AS_IS: Check for re-encoding, no compression/encoding, just write the file information as it is.
1988     @endproperty
1989     @since 1.1.0
1990  */
1991 static void
1992 st_collections_group_sound_sample_name(void)
1993 {
1994    Edje_Sound_Sample *sample;
1995    const char *tmp;
1996    unsigned int i;
1997    
1998    if (!edje_file->sound_dir)
1999      edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
2000    
2001    tmp = parse_str(0);
2002    
2003    for (i = 0; i < edje_file->sound_dir->samples_count; i++)
2004      {
2005         if (!strcmp(edje_file->sound_dir->samples[i].name, tmp))
2006           {
2007              free((char *)tmp);
2008              return;
2009           }
2010      }
2011    
2012    edje_file->sound_dir->samples_count++;
2013    edje_file->sound_dir->samples = 
2014      realloc(edje_file->sound_dir->samples,
2015              sizeof(Edje_Sound_Sample) * 
2016              edje_file->sound_dir->samples_count);
2017
2018    if (!edje_file->sound_dir->samples)
2019      {
2020         ERR("No enough memory.");
2021         exit(-1);
2022      }
2023    
2024    sample =
2025      edje_file->sound_dir->samples +
2026      edje_file->sound_dir->samples_count - 1;
2027    memset(sample, 0, sizeof (Edje_Sound_Sample));
2028    
2029    sample->name = tmp;
2030    sample->id = edje_file->sound_dir->samples_count - 1;
2031    sample->compression = parse_enum(1,
2032                                     "RAW", EDJE_SOUND_SOURCE_TYPE_INLINE_RAW,
2033                                     "COMP", EDJE_SOUND_SOURCE_TYPE_INLINE_COMP,
2034                                     "LOSSY", EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY,
2035                                     "AS_IS", EDJE_SOUND_SOURCE_TYPE_INLINE_AS_IS,
2036                                     NULL);
2037    
2038    if (sample->compression == EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY)
2039      {
2040         sample->quality = parse_float_range(2, 45.0, 1000.0);
2041         check_arg_count(3);
2042      }
2043    else
2044      check_arg_count(2);
2045
2046 }
2047
2048 /**
2049     @page edcref
2050     @property
2051         source
2052     @parameters
2053         [sound file name]
2054     @effect
2055         The Sound source file name (Source can be mono/stereo WAV file.
2056         Only files with 44.1 KHz sample rate supported now)
2057     @endproperty
2058     @since 1.1.0
2059  */
2060 static void
2061 st_collections_group_sound_sample_source(void)
2062 {
2063    Edje_Sound_Sample *sample;
2064
2065    if (!edje_file->sound_dir->samples)
2066      {
2067         ERR("Invalid sound sample source definition.");
2068         exit(-1);
2069      }
2070    
2071    sample = 
2072      edje_file->sound_dir->samples +
2073      edje_file->sound_dir->samples_count - 1;
2074    
2075    if (!sample)
2076      {
2077         ERR("Invalid sound sample source definition.");
2078         exit(-1);
2079      }
2080    sample->snd_src = parse_str(0);
2081    check_arg_count(1);
2082 }
2083
2084 /**
2085     @page edcref
2086     @property
2087         tone
2088     @parameters
2089         [tone name] [frequency]
2090     @effect
2091         sound of specific frequency
2092     @endproperty
2093     @since 1.1.0
2094  */
2095 static void
2096 st_collections_group_sound_tone(void)
2097 {
2098    Edje_Sound_Tone *tone;
2099    const char *tmp;
2100    unsigned int i;
2101    int value;
2102
2103    check_arg_count(2);
2104    
2105    if (!edje_file->sound_dir)
2106      edje_file->sound_dir = mem_alloc(SZ(Edje_Sound_Directory));
2107    
2108    tmp = parse_str(0);
2109    /* Audible range 20 to 20KHz */
2110    value = parse_int_range(1, 20, 20000);
2111    
2112    /* Check for Tone duplication */
2113    for (i = 0; i < edje_file->sound_dir->tones_count; i++)
2114      {
2115         if (!strcmp(edje_file->sound_dir->tones[i].name, tmp))
2116           {
2117              ERR("Tone name: %s already exist.", tmp);
2118              free((char *)tmp);
2119              exit(-1);
2120           }
2121         if (edje_file->sound_dir->tones[i].value == value)
2122           {
2123              ERR("Tone name %s with same frequency %d exist.",
2124                  edje_file->sound_dir->tones[i].name, value);
2125              exit(-1);
2126           }
2127      }
2128    edje_file->sound_dir->tones_count++;
2129    edje_file->sound_dir->tones = 
2130      realloc(edje_file->sound_dir->tones,
2131              sizeof (Edje_Sound_Tone) * 
2132              edje_file->sound_dir->tones_count);
2133    
2134    if (!edje_file->sound_dir->tones)
2135      {
2136         ERR("No enough memory.");
2137         exit(-1);
2138      }
2139    
2140    tone = edje_file->sound_dir->tones + edje_file->sound_dir->tones_count - 1;
2141    memset(tone, 0, sizeof (Edje_Sound_Tone));
2142    
2143    tone->name = tmp;
2144    tone->value = value;
2145    tone->id = edje_file->sound_dir->tones_count - 1;
2146 }
2147
2148 /**
2149    @edcsection{group,Group sub blocks}
2150  */
2151
2152 /**
2153     @page edcref
2154     @block
2155         group
2156     @context
2157         collections {
2158             ..
2159             group {
2160                 name: "nameusedbytheapplication";
2161                 alias: "anothername";
2162                 min: width height;
2163                 max: width height;
2164
2165                 data { }
2166                 script { }
2167                 parts { }
2168                 programs { }
2169             }
2170             ..
2171         }
2172     @description
2173         A "group" block contains the list of parts and programs that compose a
2174         given Edje Object.
2175     @endblock
2176 */
2177 static void
2178 ob_collections_group(void)
2179 {
2180    Edje_Part_Collection *pc;
2181    Code *cd;
2182
2183    if (current_de && !current_de->entry)
2184      {
2185         ERR("A collection without a name was detected, that's not allowed.");
2186         exit(-1);
2187      }
2188
2189    current_de = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
2190    current_de->id = eina_list_count(edje_collections);
2191
2192    pc = mem_alloc(SZ(Edje_Part_Collection));
2193    edje_collections = eina_list_append(edje_collections, pc);
2194    pc->id = current_de->id;
2195    pc->broadcast_signal = EINA_TRUE; /* This was the behaviour by default in Edje 1.1 */
2196
2197    cd = mem_alloc(SZ(Code));
2198    codes = eina_list_append(codes, cd);
2199 }
2200
2201 /**
2202     @page edcref
2203     @property
2204         name
2205     @parameters
2206         [group name]
2207     @effect
2208         The name that will be used by the application to load the resulting
2209         Edje object and to identify the group to swallow in a GROUP part. If a
2210         group with the same name exists already it will be completely overriden
2211         by the new group.
2212     @endproperty
2213 */
2214 static void
2215 st_collections_group_name(void)
2216 {
2217    Edje_Part_Collection_Directory_Entry *alias;
2218    Edje_Part_Collection_Directory_Entry *older;
2219    Edje_Part_Collection *current_pc;
2220    Eina_List *l = NULL;
2221
2222    check_arg_count(1);
2223
2224    current_pc = eina_list_data_get(eina_list_last(edje_collections));
2225
2226    current_de->entry = parse_str(0);
2227    current_pc->part = current_de->entry;
2228
2229    older = eina_hash_find(edje_file->collection, current_de->entry);
2230    if (older) eina_hash_del(edje_file->collection, current_de->entry, older);
2231    eina_hash_direct_add(edje_file->collection, current_de->entry, current_de);
2232    if (!older) return;
2233
2234    EINA_LIST_FOREACH(aliases, l, alias)
2235      if (strcmp(alias->entry, current_de->entry) == 0)
2236        {
2237           Edje_Part_Collection *pc;
2238
2239           pc = eina_list_nth(edje_collections, older->id);
2240           INF("overriding alias ('%s' => '%s') by group '%s'",
2241               alias->entry, pc->part,
2242               current_de->entry);
2243           aliases = eina_list_remove_list(aliases, l);
2244           free(alias);
2245           break;
2246        }
2247
2248 }
2249
2250 typedef struct _Edje_List_Foreach_Data Edje_List_Foreach_Data;
2251 struct _Edje_List_Foreach_Data
2252 {
2253    Eina_List *list;
2254 };
2255
2256 static Eina_Bool
2257 _edje_data_item_list_foreach(const Eina_Hash *hash __UNUSED__, const void *key, void *data __UNUSED__, void *fdata)
2258 {
2259    Edje_List_Foreach_Data *fd;
2260
2261    fd = fdata;
2262    fd->list = eina_list_append(fd->list, strdup(key));
2263
2264    return EINA_TRUE;
2265 }
2266
2267 /**
2268     @page edcref
2269     @property
2270         inherit
2271     @parameters
2272         [parent group name]
2273     @effect
2274         Parent group name for inheritance.
2275         Group "inherit" is used to inherit any predefined group and change
2276         some property which belongs to "part", "description", "items" or "program".
2277         The child group has the same property as parent group. If you specify the
2278         type again in an inherited part, it will cause an error (unless you plan
2279         to fix that).
2280     @endproperty
2281     @since 1.1.0
2282 */
2283 static void
2284 st_collections_group_inherit(void)
2285 {
2286    Edje_Part_Collection *pc, *pc2;
2287    Edje_Part *ep, *ep2;
2288    Edje_Part_Parser *epp, *epp2;
2289    Edje_Pack_Element *item, *item2;
2290    Edje_Pack_Element_Parser *pitem;
2291    Edje_Part_Description_Common *ed, *ed2;
2292    Edje_List_Foreach_Data fdata;
2293    Eina_List *l;
2294    char *parent_name;
2295    unsigned int i, j;
2296
2297    check_arg_count(1);
2298
2299    pc = eina_list_data_get(eina_list_last(edje_collections));
2300
2301    parent_name = parse_str(0);
2302
2303    EINA_LIST_FOREACH(edje_collections, l, pc2)
2304      {
2305         if (!strcmp(parent_name, pc2->part))
2306           break;
2307      }
2308    if (!pc2)
2309      {
2310         ERR("parse error %s:%i. There isn't a group with the name %s",
2311             file_in, line - 1, parent_name);
2312         exit(-1);
2313      }
2314    if (pc2 == pc)
2315      {
2316         ERR("parse error %s:%i. You are trying to inherit '%s' from itself. That's not possible."
2317             "If there is another group of the same name, you want to inherit from that group and have the"
2318             "same name as that group, there is a trick ! Just put the inherit before the directive that set"
2319             "the name !", file_in, line - 1, parent_name);
2320         exit(-1);
2321      }
2322
2323    if (pc2->data)
2324      {
2325         char *key, *data;
2326
2327         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2328         eina_hash_foreach(pc2->data,
2329                      _edje_data_item_list_foreach, &fdata);
2330
2331         if (!pc->data) pc->data = eina_hash_string_small_new(free);
2332         EINA_LIST_FREE(fdata.list, key)
2333           {
2334              data = eina_hash_find(pc2->data, key);
2335              eina_hash_direct_add(pc->data, key, data);
2336           }
2337      }
2338
2339    if (pc2->alias)
2340      {
2341         char *key, *alias;
2342
2343         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2344         eina_hash_foreach(pc2->alias,
2345                      _edje_data_item_list_foreach, &fdata);
2346         if (!pc->alias) pc->alias = eina_hash_string_small_new(free);
2347         EINA_LIST_FREE(fdata.list, key)
2348           {
2349              alias = eina_hash_find(pc2->alias, key);
2350              eina_hash_direct_add(pc->alias, key, alias);
2351           }
2352      }
2353    if (pc2->aliased)
2354      {
2355         char *key, *aliased;
2356
2357         memset(&fdata, 0, sizeof(Edje_List_Foreach_Data));
2358         eina_hash_foreach(pc2->aliased,
2359                           _edje_data_item_list_foreach, &fdata);
2360         if (!pc->aliased) pc->aliased = eina_hash_string_small_new(free);
2361         EINA_LIST_FREE(fdata.list, key)
2362           {
2363              aliased = eina_hash_find(pc2->aliased, key);
2364              eina_hash_direct_add(pc->aliased, key, aliased);
2365           }
2366      }
2367
2368    pc->prop.min.w = pc2->prop.min.w;
2369    pc->prop.min.h = pc2->prop.min.h;
2370    pc->prop.orientation = pc2->prop.orientation;
2371
2372    pc->lua_script_only = pc2->lua_script_only;
2373
2374    #define STRDUP(x) x ? strdup(x) : NULL
2375    for (i = 0 ; i < pc2->parts_count ; i++)
2376      {
2377         // copy the part
2378         ob_collections_group_parts_part();
2379         ep = pc->parts[i];
2380         ep2 = pc2->parts[i];
2381         ep->name = STRDUP(ep2->name);
2382         ep->source = STRDUP(ep2->source);
2383         ep->source2 = STRDUP(ep2->source2);
2384         ep->source3 = STRDUP(ep2->source3);
2385         ep->source4 = STRDUP(ep2->source4);
2386         ep->source5 = STRDUP(ep2->source5);
2387         ep->source6 = STRDUP(ep2->source6);
2388
2389         data_queue_copied_part_lookup(pc, &(ep2->clip_to_id), &(ep->clip_to_id));
2390
2391         ep->type = ep2->type;
2392         ep->mouse_events = ep2->mouse_events;
2393         ep->repeat_events = ep2->repeat_events;
2394         ep->ignore_flags = ep2->ignore_flags;
2395         ep->scale = ep2->scale;
2396         ep->pointer_mode = ep2->pointer_mode;
2397         ep->precise_is_inside = ep2->precise_is_inside;
2398         ep->use_alternate_font_metrics = ep2->use_alternate_font_metrics;
2399         ep->effect = ep2->effect;
2400         ep->entry_mode = ep2->entry_mode;
2401         ep->select_mode = ep2->select_mode;
2402         ep->cursor_mode = ep2->cursor_mode;
2403         ep->multiline = ep2->multiline;
2404         ep->access = ep2->access;
2405         ep->dragable.x = ep2->dragable.x;
2406         ep->dragable.step_x = ep2->dragable.step_x;
2407         ep->dragable.count_x = ep2->dragable.count_x;
2408         ep->dragable.y = ep2->dragable.y;
2409         ep->dragable.step_y = ep2->dragable.step_y;
2410         ep->dragable.count_y = ep2->dragable.count_y;
2411
2412         data_queue_copied_part_lookup(pc, &(ep2->dragable.confine_id), &(ep->dragable.confine_id));
2413         data_queue_copied_part_lookup(pc, &(ep2->dragable.event_id), &(ep->dragable.event_id));
2414
2415         epp = (Edje_Part_Parser *)ep;
2416         epp2 = (Edje_Part_Parser *)ep2;
2417         epp->reorder.insert_before = STRDUP(epp2->reorder.insert_before);
2418         epp->reorder.insert_after = STRDUP(epp2->reorder.insert_after);
2419         epp->can_override = EINA_TRUE;
2420
2421         for (j = 0 ; j < ep2->items_count ; j++)
2422           {
2423              ob_collections_group_parts_part_box_items_item();
2424              item = ep->items[j];
2425              item2 = ep2->items[j];
2426              item->type = item2->type;
2427              item->name = STRDUP(item2->name);
2428              item->source = STRDUP(item2->source);
2429              item->min.w = item2->min.w;
2430              item->min.h = item2->min.h;
2431              item->prefer.w = item2->prefer.w;
2432              item->prefer.h = item2->prefer.h;
2433              item->max.w = item2->max.w;
2434              item->max.h = item2->max.h;
2435              item->padding.l = item2->padding.l;
2436              item->padding.r = item2->padding.r;
2437              item->padding.t = item2->padding.t;
2438              item->padding.b = item2->padding.b;
2439              item->align.x = item2->align.x;
2440              item->align.y = item2->align.y;
2441              item->weight.x = item2->weight.x;
2442              item->weight.y = item2->weight.y;
2443              item->aspect.w = item2->aspect.w;
2444              item->aspect.h = item2->aspect.h;
2445              item->aspect.mode = item2->aspect.mode;
2446              item->options = STRDUP(item2->options);
2447              item->col = item2->col;
2448              item->row = item2->row;
2449              item->colspan = item2->colspan;
2450              item->rowspan = item2->rowspan;
2451
2452              pitem = (Edje_Pack_Element_Parser *)item;
2453              pitem->can_override = EINA_TRUE;
2454           }
2455
2456         ep->api.name = STRDUP(ep2->api.name);
2457         if (ep2->api.description) ep->api.description = STRDUP(ep2->api.description);
2458
2459         // copy default description
2460         ob_collections_group_parts_part_description();
2461         ed = ep->default_desc;
2462         parent_desc = ed2 = ep2->default_desc;
2463         ed->state.name = STRDUP(ed2->state.name);
2464         ed->state.value = ed2->state.value;
2465         st_collections_group_parts_part_description_inherit();
2466         parent_desc = NULL;
2467
2468         // copy other description
2469         for (j = 0 ; j < ep2->other.desc_count ; j++)
2470           {
2471              ob_collections_group_parts_part_description();
2472              ed = ep->other.desc[j];
2473              parent_desc = ed2 = ep2->other.desc[j];
2474              ed->state.name = STRDUP(ed2->state.name);
2475              ed->state.value = ed2->state.value;
2476              st_collections_group_parts_part_description_inherit();
2477              parent_desc = NULL;
2478           }
2479      }
2480
2481    //copy programs
2482    for (j = 0 ; j < pc2->programs.fnmatch_count ; j++)
2483      {
2484         ob_collections_group_programs_program();
2485         _edje_program_copy(current_program, pc2->programs.fnmatch[j]);
2486      }
2487    for (j = 0 ; j < pc2->programs.strcmp_count ; j++)
2488      {
2489         ob_collections_group_programs_program();
2490         _edje_program_copy(current_program, pc2->programs.strcmp[j]);
2491      }
2492    for (j = 0 ; j < pc2->programs.strncmp_count ; j++)
2493      {
2494         ob_collections_group_programs_program();
2495         _edje_program_copy(current_program, pc2->programs.strncmp[j]);
2496      }
2497    for (j = 0 ; j < pc2->programs.strrncmp_count ; j++)
2498      {
2499         ob_collections_group_programs_program();
2500         _edje_program_copy(current_program, pc2->programs.strrncmp[j]);
2501      }
2502    for (j = 0 ; j < pc2->programs.nocmp_count ; j++)
2503      {
2504         ob_collections_group_programs_program();
2505         _edje_program_copy(current_program, pc2->programs.nocmp[j]);
2506      }
2507
2508    Code *cd, *cd2;
2509    Code_Program *cp, *cp2;
2510    Edje_Part_Collection_Directory_Entry *de;
2511
2512    de = eina_hash_find(edje_file->collection, pc2->part);
2513    cd2 = eina_list_nth(codes, de->id);
2514    cd = eina_list_data_get(eina_list_last(codes));
2515
2516    EINA_LIST_FOREACH(cd2->programs, l, cp2)
2517      {
2518         cp = mem_alloc(SZ(Code_Program));
2519
2520         cp->l1 = cp2->l1;
2521         cp->l2 = cp2->l2;
2522         cp->script = STRDUP(cp2->script);
2523         cd->is_lua = cd2->is_lua;
2524         cd->shared = cd2->shared;
2525         cd->programs = eina_list_append(cd->programs, cp);
2526         data_queue_copied_anonymous_lookup(pc, &(cp2->id), &(cp->id));
2527      }
2528
2529    free(parent_name);
2530    #undef STRDUP
2531 }
2532
2533 /**
2534     @page edcref
2535     @property
2536         script_only
2537     @parameters
2538         [on/off]
2539     @effect
2540         The flag (on/off) as to if this group is defined ONLY by script
2541         callbacks such as init(), resize() and shutdown()
2542     @endproperty
2543 */
2544 static void
2545 st_collections_group_script_only(void)
2546 {
2547    Edje_Part_Collection *pc;
2548
2549    check_arg_count(1);
2550
2551    pc = eina_list_data_get(eina_list_last(edje_collections));
2552    pc->lua_script_only = parse_bool(0);
2553 }
2554
2555 /**
2556     @page edcref
2557     @property
2558         alias
2559     @parameters
2560         [aditional group name]
2561     @effect
2562         Additional name to serve as identifier. Defining multiple aliases is
2563         supported.
2564     @endproperty
2565 */
2566 static void
2567 st_collections_group_alias(void)
2568 {
2569    Edje_Part_Collection_Directory_Entry *alias;
2570    Edje_Part_Collection_Directory_Entry *tmp;
2571    Eina_List *l;
2572
2573    check_arg_count(1);
2574
2575    alias = mem_alloc(SZ(Edje_Part_Collection_Directory_Entry));
2576    alias->id = current_de->id;
2577    alias->entry = parse_str(0);
2578
2579    EINA_LIST_FOREACH(aliases, l, tmp)
2580      if (strcmp(alias->entry, tmp->entry) == 0)
2581        {
2582           Edje_Part_Collection *pc;
2583
2584           pc = eina_list_nth(edje_collections, tmp->id);
2585           INF("overriding alias ('%s' => '%s') to ('%s' => '%s')",
2586               tmp->entry, pc->part,
2587               alias->entry, current_de->entry);
2588           aliases = eina_list_remove_list(aliases, l);
2589           free(tmp);
2590           break;
2591        }
2592
2593    aliases = eina_list_append(aliases, alias);
2594 }
2595
2596 /**
2597     @page edcref
2598     @property
2599         min
2600     @parameters
2601         [width] [height]
2602     @effect
2603         The minimum size for the container defined by the composition of the
2604         parts. It is not enforced.
2605     @endproperty
2606 */
2607 static void
2608 st_collections_group_min(void)
2609 {
2610    Edje_Part_Collection *pc;
2611
2612    check_arg_count(2);
2613
2614    pc = eina_list_data_get(eina_list_last(edje_collections));
2615    pc->prop.min.w = parse_int_range(0, 0, 0x7fffffff);
2616    pc->prop.min.h = parse_int_range(1, 0, 0x7fffffff);
2617 }
2618
2619 /**
2620     @page edcref
2621     @property
2622         max
2623     @parameters
2624         [width] [height]
2625     @effect
2626         The maximum size for the container defined by the totality of the
2627         parts. It is not enforced.
2628     @endproperty
2629 */
2630 static void
2631 st_collections_group_max(void)
2632 {
2633    Edje_Part_Collection *pc;
2634
2635    check_arg_count(2);
2636
2637    pc = eina_list_data_get(eina_list_last(edje_collections));
2638    pc->prop.max.w = parse_int_range(0, 0, 0x7fffffff);
2639    pc->prop.max.h = parse_int_range(1, 0, 0x7fffffff);
2640 }
2641
2642 /**
2643    @page edcref
2644    @property
2645        broadcast_signal
2646    @parameters
2647        [broadcast]
2648    @effect
2649        Signal got automatically broadcasted to all sub group part. Default to
2650        true since 1.1.
2651    @endproperty
2652 */
2653 static void
2654 st_collections_group_broadcast_signal(void)
2655 {
2656    Edje_Part_Collection *pc;
2657
2658    check_arg_count(1);
2659
2660    pc = eina_list_data_get(eina_list_last(edje_collections));
2661    pc->broadcast_signal = parse_bool(0);
2662 }
2663
2664 /**
2665     @page edcref
2666     @block
2667         script
2668     @context
2669         ..
2670         group {
2671             script {
2672                 //embryo script
2673             }
2674             ..
2675             program {
2676                 script {
2677                     //embryo script
2678                 }
2679             }
2680             ..
2681         }
2682         ..
2683     @description
2684         This block is used to "inject" embryo scripts to a given Edje theme and
2685         it functions in two modalities. When it's included inside a "program"
2686         block, the script will be executed every time the program is run, on
2687         the other hand, when included directly into a "group", "part" or
2688         "description" block, it will be executed once at load time, in the
2689         load order.
2690     @endblock
2691 */
2692 static void
2693 ob_collections_group_script(void)
2694 {
2695    Code *cd;
2696
2697    cd = eina_list_data_get(eina_list_last(codes));
2698
2699    if (!is_verbatim()) track_verbatim(1);
2700    else
2701      {
2702         char *s;
2703
2704         s = get_verbatim();
2705         if (s)
2706           {
2707              cd->l1 = get_verbatim_line1();
2708              cd->l2 = get_verbatim_line2();
2709              if (cd->shared)
2710                {
2711                   ERR("parse error %s:%i. There is already an existing script section for the group",
2712                       file_in, line - 1);
2713                   exit(-1);
2714                }
2715              cd->shared = s;
2716              cd->original = strdup(s);
2717              cd->is_lua = 0;
2718              set_verbatim(NULL, 0, 0);
2719           }
2720      }
2721 }
2722
2723 static void
2724 ob_collections_group_lua_script(void)
2725 {
2726    Code *cd;
2727
2728    cd = eina_list_data_get(eina_list_last(codes));
2729
2730    if (!is_verbatim()) track_verbatim(1);
2731    else
2732      {
2733         char *s;
2734
2735         s = get_verbatim();
2736         if (s)
2737           {
2738              cd->l1 = get_verbatim_line1();
2739              cd->l2 = get_verbatim_line2();
2740              if (cd->shared)
2741                {
2742                   ERR("parse error %s:%i. There is already an existing script section for the group",
2743                       file_in, line - 1);
2744                   exit(-1);
2745                }
2746              cd->shared = s;
2747              cd->is_lua = 1;
2748              set_verbatim(NULL, 0, 0);
2749           }
2750      }
2751 }
2752
2753 static void
2754 st_collections_group_data_item(void)
2755 {
2756    Edje_Part_Collection *pc;
2757    Edje_String *es;
2758    char *key;
2759
2760    check_arg_count(2);
2761
2762    pc = eina_list_data_get(eina_list_last(edje_collections));
2763
2764    if (!pc->data)
2765      pc->data = eina_hash_string_small_new(free);
2766
2767    key = parse_str(0);
2768
2769    es = mem_alloc(SZ(Edje_String));
2770    es->str = parse_str(1);
2771
2772    if (eina_hash_find(pc->data, key))
2773      eina_hash_modify(pc->data, key, es);
2774    else
2775      eina_hash_direct_add(pc->data, key, es);
2776 }
2777
2778 /**
2779     @page edcref
2780     @property
2781         orientation
2782     @parameters
2783     enum AUTO, LTR, RTL
2784     @effect
2785         This defines GROUP orientation.
2786         This is useful if you want match interface orientation with language.
2787         AUTO  - Follow system defs.
2788         LTR  - suitable for Left To Right Languages (latin)
2789         RTL - suitable for Right To Left Languages (Hebrew, Arabic interface)
2790     @endproperty
2791 */
2792 static void
2793 st_collections_group_orientation(void)
2794 {
2795    Edje_Part_Collection *pc;
2796
2797    check_arg_count(1);
2798
2799    pc = eina_list_data_get(eina_list_last(edje_collections));
2800    pc->prop.orientation = parse_enum(0,
2801          "AUTO", EDJE_ORIENTATION_AUTO,
2802          "LTR", EDJE_ORIENTATION_LTR,
2803          "RTL", EDJE_ORIENTATION_RTL,
2804          NULL);
2805 }
2806
2807 /**
2808     @page edcref
2809     @block
2810         limits
2811     @context
2812         group {
2813             limits {
2814                 vertical: "limit_name" height_barrier;
2815                 horizontal: "limit_name" width_barrier;
2816                 ..
2817             }
2818             ..
2819         }
2820         ..
2821     @description
2822         This block is used to trigger some signal when the Edje object is resized.
2823     @endblock
2824
2825     @page edcref
2826     @property
2827         vertical
2828     @parameters
2829         [name] [height barrier]
2830     @effect
2831         It will send a signal: "limit,name,over" when the object is resized and pass
2832         the limit by growing over it. And it will send: "limit,name,below" when
2833         it pass below that limit.
2834         This limit will be applied on the y absis and is expressed in pixels.
2835     @endproperty
2836 */
2837 static void
2838 st_collections_group_limits_vertical(void)
2839 {
2840    Edje_Part_Collection *pc;
2841    Edje_Limit *el;
2842
2843    check_arg_count(2);
2844
2845    el = mem_alloc(SZ(Edje_Limit));
2846
2847    pc = eina_list_data_get(eina_list_last(edje_collections));
2848    pc->limits.vertical_count++;
2849    pc->limits.vertical = realloc(pc->limits.vertical, pc->limits.vertical_count * sizeof (Edje_Limit *));
2850    if (!pc->limits.vertical || !el)
2851      {
2852         ERR("Not enough memory.");
2853         exit(-1);
2854      }
2855
2856    pc->limits.vertical[pc->limits.vertical_count - 1] = el;
2857
2858    el->name = parse_str(0);
2859    el->value = parse_int_range(1, 1, 0xffff);
2860 }
2861
2862 /**
2863     @page edcref
2864     @property
2865         horizontal
2866     @parameters
2867         [name] [width barrier]
2868     @effect
2869         It will send a signal: "limit,name,over" when the object is resized and pass
2870         the limit by growing over it. And it will send: "limit,name,below" when
2871         it pass below that limit.
2872         This limit will be applied on the x absis and is expressed in pixels.
2873     @endproperty
2874 */
2875 static void
2876 st_collections_group_limits_horizontal(void)
2877 {
2878    Edje_Part_Collection *pc;
2879    Edje_Limit *el;
2880
2881    check_arg_count(2);
2882
2883    el = mem_alloc(SZ(Edje_Limit));
2884
2885    pc = eina_list_data_get(eina_list_last(edje_collections));
2886    pc->limits.horizontal_count++;
2887    pc->limits.horizontal = realloc(pc->limits.horizontal, pc->limits.horizontal_count * sizeof (Edje_Limit *));
2888    if (!pc->limits.horizontal || !el)
2889      {
2890         ERR("Not enough memory.");
2891         exit(-1);
2892      }
2893
2894    pc->limits.horizontal[pc->limits.horizontal_count - 1] = el;
2895
2896    el->name = parse_str(0);
2897    el->value = parse_int_range(1, 1, 0xffff);
2898 }
2899
2900 /**
2901     @page edcref
2902     @block
2903         parts
2904     @context
2905         group {
2906             parts {
2907                 alias: "theme_part_path" "real_part_path";
2908                 ..
2909             }
2910         }
2911     @description
2912         Alias of part give a chance to let the designer put the real one
2913         in a box or reuse one from a GROUP or inside a BOX.
2914     @endblock
2915 */
2916 static void
2917 st_collections_group_parts_alias(void)
2918 {
2919    Edje_Part_Collection *pc;
2920    const char *alias;
2921    const char *aliased;
2922
2923    check_arg_count(2);
2924
2925    pc = eina_list_data_get(eina_list_last(edje_collections));
2926
2927    alias = parse_str(0);
2928    aliased = parse_str(1);
2929
2930    if (!pc->alias) pc->alias = eina_hash_string_small_new(NULL);
2931    eina_hash_add(pc->alias, alias, aliased);
2932
2933    if (!pc->aliased) pc->aliased = eina_hash_string_small_new(NULL);
2934    eina_hash_add(pc->aliased, aliased, alias);
2935 }
2936
2937
2938 /**
2939     @page edcref
2940     @block
2941         part
2942     @context
2943         group {
2944             parts {
2945                 ..
2946                 part {
2947                     name: "partname";
2948                     type: IMAGE;
2949                     mouse_events:  1;
2950                     repeat_events: 0;
2951                     ignore_flags: NONE;
2952                     clip_to: "anotherpart";
2953                     source:  "groupname";
2954                     pointer_mode: AUTOGRAB;
2955                     use_alternate_font_metrics: 0;
2956
2957                     description { }
2958                     dragable { }
2959                     items { }
2960                 }
2961                 ..
2962             }
2963         }
2964     @description
2965         Parts are used to represent the most basic design elements of the
2966         theme, for example, a part can represent a line in a border or a label
2967         on a button.
2968     @endblock
2969 */
2970 static void
2971 ob_collections_group_parts_part(void)
2972 {
2973    Edje_Part_Collection *pc;
2974    Edje_Part *ep;
2975    Edje_Part_Parser *epp;
2976
2977    ep = mem_alloc(SZ(Edje_Part_Parser));
2978
2979    pc = eina_list_data_get(eina_list_last(edje_collections));
2980    pc->parts_count++;
2981    pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
2982    if (!pc->parts)
2983      {
2984         ERR("Not enough memory.");
2985         exit(-1);
2986      }
2987    current_part = pc->parts[pc->parts_count - 1] = ep;
2988
2989    ep->id = pc->parts_count - 1;
2990    ep->type = EDJE_PART_TYPE_IMAGE;
2991    ep->mouse_events = 1;
2992    ep->repeat_events = 0;
2993    ep->ignore_flags = EVAS_EVENT_FLAG_NONE;
2994    ep->scale = 0;
2995    ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
2996    ep->precise_is_inside = 0;
2997    ep->use_alternate_font_metrics = 0;
2998    ep->access = 0;
2999    ep->clip_to_id = -1;
3000    ep->dragable.confine_id = -1;
3001    ep->dragable.event_id = -1;
3002    ep->items = NULL;
3003
3004    epp = (Edje_Part_Parser *)ep;
3005    epp->reorder.insert_before = NULL;
3006    epp->reorder.insert_after = NULL;
3007    epp->reorder.before = NULL;
3008    epp->reorder.after = NULL;
3009    epp->reorder.linked_prev = 0;
3010    epp->reorder.linked_next = 0;
3011    epp->reorder.done = EINA_FALSE;
3012    epp->can_override = EINA_FALSE;
3013 }
3014
3015 /**
3016     @page edcref
3017     @property
3018         name
3019     @parameters
3020         [part name]
3021     @effect
3022         The part's name will be used as reference in the theme's relative
3023         positioning system, by programs and in some cases by the application.
3024         It must be unique within the group.
3025     @endproperty
3026 */
3027 static void
3028 st_collections_group_parts_part_name(void)
3029 {
3030    Edje_Part_Collection *pc;
3031    Edje_Part *ep;
3032    Edje_Part_Parser *epp;
3033
3034    check_arg_count(1);
3035
3036    pc = eina_list_data_get(eina_list_last(edje_collections));
3037    ep = current_part;
3038    ep->name = parse_str(0);
3039
3040    if (ep->name)
3041      {
3042         unsigned int i;
3043
3044         for (i = 0; i < (pc->parts_count - 1); i++)
3045           {
3046              if (pc->parts[i]->name && (!strcmp(pc->parts[i]->name, ep->name)))
3047                {
3048                   epp = (Edje_Part_Parser *)pc->parts[i];
3049                   if (!epp->can_override)
3050                     {
3051                        ERR("parse error %s:%i. There is already a part of the name %s",
3052                            file_in, line - 1, ep->name);
3053                        exit(-1);
3054                     }
3055                   else
3056                     {
3057                        free(ep);
3058                        pc->parts_count--;
3059                        pc->parts = realloc(pc->parts, pc->parts_count * sizeof (Edje_Part *));
3060                        ep = current_part = pc->parts[i];
3061                        epp->can_override = EINA_FALSE;
3062                        break;
3063                     }
3064                }
3065           }
3066      }
3067 }
3068
3069 /**
3070     @page edcref
3071     @property
3072         type
3073     @parameters
3074         [TYPE]
3075     @effect
3076         Set the type (all caps) from among the available types, it's set to
3077         IMAGE by default. Valid types:
3078             @li RECT
3079             @li TEXT
3080             @li IMAGE
3081             @li SWALLOW
3082             @li TEXTBLOCK
3083             @li GROUP
3084             @li BOX
3085             @li TABLE
3086             @li EXTERNAL
3087             @li PROXY
3088             @li SPACER
3089     @endproperty
3090 */
3091 static void
3092 st_collections_group_parts_part_type(void)
3093 {
3094    unsigned int type;
3095
3096    check_arg_count(1);
3097
3098    type = parse_enum(0,
3099                      "NONE", EDJE_PART_TYPE_NONE,
3100                      "RECT", EDJE_PART_TYPE_RECTANGLE,
3101                      "TEXT", EDJE_PART_TYPE_TEXT,
3102                      "IMAGE", EDJE_PART_TYPE_IMAGE,
3103                      "SWALLOW", EDJE_PART_TYPE_SWALLOW,
3104                      "TEXTBLOCK", EDJE_PART_TYPE_TEXTBLOCK,
3105                      "GROUP", EDJE_PART_TYPE_GROUP,
3106                      "BOX", EDJE_PART_TYPE_BOX,
3107                      "TABLE", EDJE_PART_TYPE_TABLE,
3108                      "EXTERNAL", EDJE_PART_TYPE_EXTERNAL,
3109                      "PROXY", EDJE_PART_TYPE_PROXY,
3110                      "SPACER", EDJE_PART_TYPE_SPACER,
3111                      NULL);
3112
3113    /* handle type change of inherited part */
3114    if (type != current_part->type)
3115      {
3116         Edje_Part_Description_Common *new, *previous;
3117         Edje_Part_Collection *pc;
3118         Edje_Part *ep;
3119         unsigned int i;
3120
3121         /* we don't free old part as we don't remove all reference to them */
3122         part_description_image_cleanup(current_part);
3123
3124         pc = eina_list_data_get(eina_list_last(edje_collections));
3125         ep = current_part;
3126
3127         previous = ep->default_desc;
3128         if (previous)
3129           {
3130              new = _edje_part_description_alloc(type, pc->part, ep->name);
3131              memcpy(new, previous, sizeof (Edje_Part_Description_Common));
3132
3133              ep->default_desc = new;
3134           }
3135
3136         for (i = 0; i < ep->other.desc_count; i++)
3137           {
3138              previous = ep->other.desc[i];
3139              new = _edje_part_description_alloc(type, pc->part, ep->name);
3140              memcpy(new, previous, sizeof (Edje_Part_Description_Common));
3141              ep->other.desc[i] = new;
3142           }
3143      }
3144
3145    current_part->type = type;
3146 }
3147
3148 /**
3149     @page edcref
3150     @property
3151         insert_before
3152     @parameters
3153         [another part's name]
3154     @effect
3155         The part's name which this part is inserted before. One part cannot
3156         have both insert_before and insert_after. One part cannot refer
3157         more than one by insert_before.
3158     @endproperty
3159     @since 1.1.0
3160 */
3161 static void
3162 st_collections_group_parts_part_insert_before(void)
3163 {
3164    Edje_Part_Parser *epp;
3165    check_arg_count(1);
3166
3167    epp = (Edje_Part_Parser *)current_part;
3168    epp->reorder.insert_before = parse_str(0);
3169 }
3170
3171 /**
3172     @page edcref
3173     @property
3174         insert_after
3175     @parameters
3176         [another part's name]
3177     @effect
3178         The part's name which this part is inserted after. One part cannot
3179         have both insert_before and insert_after. One part cannot refer
3180         more than one by insert_after.
3181     @endproperty
3182     @since 1.1.0
3183 */
3184 static void
3185 st_collections_group_parts_part_insert_after(void)
3186 {
3187    Edje_Part_Parser *epp;
3188    check_arg_count(1);
3189
3190    epp = (Edje_Part_Parser *)current_part;
3191    epp->reorder.insert_after = parse_str(0);
3192 }
3193
3194 /**
3195     @page edcref
3196     @property
3197         mouse_events
3198     @parameters
3199         [1 or 0]
3200     @effect
3201         Specifies whether the part will emit signals, although it is named
3202         "mouse_events", disabling it (0) will prevent the part from emitting
3203         any type of signal at all. It's set to 1 by default.
3204     @endproperty
3205 */
3206 static void
3207 st_collections_group_parts_part_mouse_events(void)
3208 {
3209    check_arg_count(1);
3210
3211    current_part->mouse_events = parse_bool(0);
3212 }
3213
3214 /**
3215     @page edcref
3216     @property
3217         repeat_events
3218     @parameters
3219         [1 or 0]
3220     @effect
3221         Specifies whether a part echoes a mouse event to other parts below the
3222         pointer (1), or not (0). It's set to 0 by default.
3223     @endproperty
3224 */
3225 static void
3226 st_collections_group_parts_part_repeat_events(void)
3227 {
3228    check_arg_count(1);
3229
3230    current_part->repeat_events = parse_bool(0);
3231 }
3232
3233 /**
3234     @page edcref
3235     @property
3236         ignore_flags
3237     @parameters
3238         [FLAG] ...
3239     @effect
3240         Specifies whether events with the given flags should be ignored,
3241         i.e., will not have the signals emitted to the parts. Multiple flags
3242         must be separated by spaces, the effect will be ignoring all events
3243         with one of the flags specified. Possible flags:
3244             @li NONE (default value, no event will be ignored)
3245             @li ON_HOLD
3246     @endproperty
3247 */
3248 static void
3249 st_collections_group_parts_part_ignore_flags(void)
3250 {
3251    check_min_arg_count(1);
3252
3253    current_part->ignore_flags = parse_flags(0,
3254                                   "NONE", EVAS_EVENT_FLAG_NONE,
3255                                   "ON_HOLD", EVAS_EVENT_FLAG_ON_HOLD,
3256                                   NULL);
3257 }
3258
3259 /**
3260     @page edcref
3261     @property
3262         scale
3263     @parameters
3264         [1 or 0]
3265     @effect
3266         Specifies whether the part will scale its size with an edje scaling
3267         factor. By default scale is off (0) and the default scale factor is
3268         1.0 - that means no scaling. This would be used to scale properties
3269         such as font size, min/max size of the part, and possibly can be used
3270         to scale based on DPI of the target device. The reason to be selective
3271         is that some things work well being scaled, others do not, so the
3272         designer gets to choose what works best.
3273     @endproperty
3274 */
3275 static void
3276 st_collections_group_parts_part_scale(void)
3277 {
3278    check_arg_count(1);
3279
3280    current_part->scale = parse_bool(0);
3281 }
3282
3283 /**
3284     @page edcref
3285     @property
3286         pointer_mode
3287     @parameters
3288         [MODE]
3289     @effect
3290         Sets the mouse pointer behavior for a given part. The default value is
3291         AUTOGRAB. Aviable modes:
3292             @li AUTOGRAB, when the part is clicked and the button remains
3293                 pressed, the part will be the source of all future mouse
3294                 signals emitted, even outside the object, until the button is
3295                 released.
3296             @li NOGRAB, the effect will be limited to the part's container.
3297     @endproperty
3298 */
3299 static void
3300 st_collections_group_parts_part_pointer_mode(void)
3301 {
3302    check_arg_count(1);
3303
3304    current_part->pointer_mode = parse_enum(0,
3305                                  "AUTOGRAB", EVAS_OBJECT_POINTER_MODE_AUTOGRAB,
3306                                  "NOGRAB", EVAS_OBJECT_POINTER_MODE_NOGRAB,
3307                                  NULL);
3308 }
3309
3310 /**
3311     @page edcref
3312     @property
3313         precise_is_inside
3314     @parameters
3315         [1 or 0]
3316     @effect
3317         Enables precise point collision detection for the part, which is more
3318         resource intensive. Disabled by default.
3319     @endproperty
3320 */
3321 static void
3322 st_collections_group_parts_part_precise_is_inside(void)
3323 {
3324    check_arg_count(1);
3325
3326    current_part->precise_is_inside = parse_bool(0);
3327 }
3328
3329 /**
3330     @page edcref
3331     @property
3332         use_alternate_font_metrics
3333     @parameters
3334         [1 or 0]
3335     @effect
3336         Only affects text and textblock parts, when enabled Edje will use
3337         different size measurement functions. Disabled by default. (note from
3338         the author: I don't know what this is exactly useful for?)
3339     @endproperty
3340 */
3341 static void
3342 st_collections_group_parts_part_use_alternate_font_metrics(void)
3343 {
3344    check_arg_count(1);
3345
3346    current_part->use_alternate_font_metrics = parse_bool(0);
3347 }
3348
3349 /**
3350     @page edcref
3351     @property
3352         clip_to
3353     @parameters
3354         [another part's name]
3355     @effect
3356         Only renders the area of part that coincides with another part's
3357         container. Overflowing content will not be displayed. Note that
3358         the part being clipped to can only be a rectangle part.
3359     @endproperty
3360 */
3361 static void
3362 st_collections_group_parts_part_clip_to_id(void)
3363 {
3364    Edje_Part_Collection *pc;
3365
3366    check_arg_count(1);
3367
3368    pc = eina_list_data_get(eina_list_last(edje_collections));
3369      {
3370         char *name;
3371
3372         name = parse_str(0);
3373         data_queue_part_lookup(pc, name, &(current_part->clip_to_id));
3374         free(name);
3375      }
3376 }
3377
3378 /**
3379     @page edcref
3380     @property
3381         source
3382     @parameters
3383         [another group's name]
3384     @effect
3385         Only available to GROUP or TEXTBLOCK parts. Swallows the specified 
3386         group into the part's container if a GROUP. If TEXTBLOCK it is used
3387         for the group to be loaded and used for selection display UNDER the
3388         selected text. source2 is used for on top of the selected text, if
3389         source2 is specified.
3390     @endproperty
3391 */
3392 static void
3393 st_collections_group_parts_part_source(void)
3394 {
3395    check_arg_count(1);
3396
3397    //FIXME: validate this somehow (need to decide on the format also)
3398    current_part->source = parse_str(0);
3399    data_queue_group_lookup(current_part->source, current_part);
3400 }
3401
3402 /**
3403     @page edcref
3404     @property
3405         source2
3406     @parameters
3407         [another group's name]
3408     @effect
3409         Only available to TEXTBLOCK parts. It is used for the group to be 
3410         loaded and used for selection display OVER the selected text. source
3411         is used for under of the selected text, if source is specified.
3412     @endproperty
3413 */
3414 static void
3415 st_collections_group_parts_part_source2(void)
3416 {
3417    check_arg_count(1);
3418
3419    //FIXME: validate this somehow (need to decide on the format also)
3420    current_part->source2 = parse_str(0);
3421    data_queue_group_lookup(current_part->source2, current_part);
3422 }
3423
3424 /**
3425     @page edcref
3426     @property
3427         source3
3428     @parameters
3429         [another group's name]
3430     @effect
3431         Only available to TEXTBLOCK parts. It is used for the group to be 
3432         loaded and used for cursor display UNDER the cursor position. source4
3433         is used for over the cursor text, if source4 is specified.
3434     @endproperty
3435 */
3436 static void
3437 st_collections_group_parts_part_source3(void)
3438 {
3439    check_arg_count(1);
3440
3441    //FIXME: validate this somehow (need to decide on the format also)
3442    current_part->source3 = parse_str(0);
3443    data_queue_group_lookup(current_part->source3, current_part);
3444 }
3445
3446 /**
3447     @page edcref
3448     @property
3449         source4
3450     @parameters
3451         [another group's name]
3452     @effect
3453         Only available to TEXTBLOCK parts. It is used for the group to be 
3454         loaded and used for cursor display OVER the cursor position. source3
3455         is used for under the cursor text, if source4 is specified.
3456     @endproperty
3457 */
3458 static void
3459 st_collections_group_parts_part_source4(void)
3460 {
3461    check_arg_count(1);
3462
3463    //FIXME: validate this somehow (need to decide on the format also)
3464    current_part->source4 = parse_str(0);
3465    data_queue_group_lookup(current_part->source4, current_part);
3466 }
3467
3468 /**
3469     @page edcref
3470     @property
3471         source5
3472     @parameters
3473         [another group's name]
3474     @effect
3475         Only available to TEXTBLOCK parts. It is used for the group to be 
3476         loaded and used for anchors display UNDER the anchor position. source6
3477         is used for over the anchors text, if source6 is specified.
3478     @endproperty
3479 */
3480 static void
3481 st_collections_group_parts_part_source5(void)
3482 {
3483    check_arg_count(1);
3484
3485    //FIXME: validate this somehow (need to decide on the format also)
3486    current_part->source5 = parse_str(0);
3487    data_queue_group_lookup(current_part->source5, current_part);
3488 }
3489
3490 /**
3491     @page edcref
3492     @property
3493         source6
3494     @parameters
3495         [another group's name]
3496     @effect
3497         Only available to TEXTBLOCK parts. It is used for the group to be 
3498         loaded and used for anchor display OVER the anchor position. source5
3499         is used for under the anchor text, if source6 is specified.
3500     @endproperty
3501 */
3502 static void
3503 st_collections_group_parts_part_source6(void)
3504 {
3505    check_arg_count(1);
3506
3507    //FIXME: validate this somehow (need to decide on the format also)
3508    current_part->source6 = parse_str(0);
3509    data_queue_group_lookup(current_part->source6, current_part);
3510 }
3511
3512 /**
3513     @page edcref
3514
3515     @property
3516         effect
3517     @parameters
3518         [EFFECT]
3519         (optional) [SHADOW DIRECTION]
3520     @effect
3521         Causes Edje to draw the selected effect among:
3522         @li PLAIN
3523         @li OUTLINE
3524         @li SOFT_OUTLINE
3525         @li SHADOW
3526         @li SOFT_SHADOW
3527         @li OUTLINE_SHADOW
3528         @li OUTLINE_SOFT_SHADOW
3529         @li FAR_SHADOW
3530         @li FAR_SOFT_SHADOW
3531         @li GLOW
3532
3533         Shadow directions (default if not given is BOTTOM_RIGHT):
3534         @li BOTTOM_RIGHT
3535         @li BOTTOM
3536         @li BOTTOM_LEFT
3537         @li LEFT
3538         @li TOP_LEFT
3539         @li TOP
3540         @li TOP_RIGHT
3541         @li RIGHT
3542     @endproperty
3543 */
3544 static void
3545 st_collections_group_parts_part_effect(void)
3546 {
3547    check_min_arg_count(1);
3548
3549    current_part->effect = parse_enum(0,
3550                "NONE", EDJE_TEXT_EFFECT_NONE,
3551                "PLAIN", EDJE_TEXT_EFFECT_PLAIN,
3552                "OUTLINE", EDJE_TEXT_EFFECT_OUTLINE,
3553                "SOFT_OUTLINE", EDJE_TEXT_EFFECT_SOFT_OUTLINE,
3554                "SHADOW", EDJE_TEXT_EFFECT_SHADOW,
3555                "SOFT_SHADOW", EDJE_TEXT_EFFECT_SOFT_SHADOW,
3556                "OUTLINE_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SHADOW,
3557                "OUTLINE_SOFT_SHADOW", EDJE_TEXT_EFFECT_OUTLINE_SOFT_SHADOW,
3558                "FAR_SHADOW", EDJE_TEXT_EFFECT_FAR_SHADOW,
3559                "FAR_SOFT_SHADOW", EDJE_TEXT_EFFECT_FAR_SOFT_SHADOW,
3560                "GLOW", EDJE_TEXT_EFFECT_GLOW,
3561                NULL);
3562    if (get_arg_count() >= 2)
3563      {
3564         unsigned char shadow;
3565         
3566         shadow = parse_enum(1,
3567                "BOTTOM_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_RIGHT,
3568                "BOTTOM", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM,
3569                "BOTTOM_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_LEFT,
3570                "LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_LEFT,
3571                "TOP_LEFT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_LEFT,
3572                "TOP", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP,
3573                "TOP_RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_RIGHT,
3574                "RIGHT", EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT,
3575                NULL);
3576         EDJE_TEXT_EFFECT_SHADOW_DIRECTION_SET(current_part->effect, shadow);
3577      }
3578 }
3579
3580 /**
3581     @page edcref
3582     @property
3583         entry_mode
3584     @parameters
3585         [MODE]
3586     @effect
3587         Sets the edit mode for a textblock part to one of:
3588         @li NONE
3589         @li PLAIN
3590         @li EDITABLE
3591         @li PASSWORD
3592         It causes the part be editable if the edje object has the keyboard
3593         focus AND the part has the edje focus (or selectable always
3594         regardless of focus) and in the event of password mode, not
3595         selectable and all text chars replaced with *'s but editable and
3596         pastable.
3597     @endproperty
3598 */
3599 static void
3600 st_collections_group_parts_part_entry_mode(void)
3601 {
3602    check_arg_count(1);
3603
3604    current_part->entry_mode = parse_enum(0,
3605                                "NONE", EDJE_ENTRY_EDIT_MODE_NONE,
3606                                "PLAIN", EDJE_ENTRY_EDIT_MODE_SELECTABLE,
3607                                "EDITABLE", EDJE_ENTRY_EDIT_MODE_EDITABLE,
3608                                "PASSWORD", EDJE_ENTRY_EDIT_MODE_PASSWORD,
3609                                NULL);
3610 }
3611
3612 /**
3613     @page edcref
3614     @property
3615         select_mode
3616     @parameters
3617         [MODE]
3618     @effect
3619         Sets the selection mode for a textblock part to one of:
3620         @li DEFAULT selection mode is what you would expect on any desktop. Press
3621         mouse, drag and release to end.
3622         @li EXPLICIT mode requires the application
3623         controlling the edje object has to explicitly begin and end selection
3624         modes, and the selection itself is dragable at both ends.
3625         @li BLOCK_HANDLE mode is the same as DEFAULT, it is for backward-compatibility.
3626     @endproperty
3627 */
3628 static void
3629 st_collections_group_parts_part_select_mode(void)
3630 {
3631    check_arg_count(1);
3632
3633    current_part->select_mode = parse_enum(0,
3634                                 "DEFAULT", EDJE_ENTRY_SELECTION_MODE_DEFAULT,
3635                                 "EXPLICIT", EDJE_ENTRY_SELECTION_MODE_EXPLICIT,
3636                                 "BLOCK_HANDLE", EDJE_ENTRY_SELECTION_MODE_DEFAULT,
3637                                 NULL);
3638 }
3639
3640 /**
3641     @page edcref
3642     @property
3643         cursor_mode
3644     @parameters
3645         [MODE]
3646     @effect
3647         Sets the cursor mode for a textblock part to one of:
3648         @li UNDER cursor mode means the cursor will draw below the character pointed
3649         at. That's the default.
3650         @li BEFORE cursor mode means the cursor is drawn as a vertical line before
3651         the current character, just like many other GUI toolkits handle it.
3652     @endproperty
3653 */
3654 static void
3655 st_collections_group_parts_part_cursor_mode(void)
3656 {
3657    check_arg_count(1);
3658
3659    current_part->cursor_mode = parse_enum(0,
3660                                 "UNDER", EDJE_ENTRY_CURSOR_MODE_UNDER,
3661                                 "BEFORE", EDJE_ENTRY_CURSOR_MODE_BEFORE,
3662                                 NULL);
3663 }
3664
3665 /**
3666     @page edcref
3667     @property
3668         multiline
3669     @parameters
3670         [1 or 0]
3671     @effect
3672         It causes a textblock that is editable to allow multiple lines for
3673         editing.
3674     @endproperty
3675 */
3676 static void
3677 st_collections_group_parts_part_multiline(void)
3678 {
3679    check_arg_count(1);
3680
3681    current_part->multiline = parse_bool(0);
3682 }
3683
3684 /**
3685     @page edcref
3686     @property
3687         access 
3688     @parameters
3689         [1 or 0]
3690     @effect
3691         Specifies whether the part will use accessibility feature (1),
3692         or not (0). It's set to 0 by default.
3693     @endproperty
3694 */
3695 static void
3696 st_collections_group_parts_part_access(void)
3697 {
3698    check_arg_count(1);
3699
3700    current_part->access = parse_bool(0);
3701 }
3702
3703 /**
3704     @page edcref
3705     @block
3706         dragable
3707     @context
3708         part {
3709             ..
3710             dragable {
3711                 confine: "another part";
3712                 events:  "another dragable part";
3713                 x: 0 0 0;
3714                 y: 0 0 0;
3715             }
3716             ..
3717         }
3718     @description
3719         When this block is used the resulting part can be dragged around the
3720         interface, do not confuse with external drag & drop. By default Edje
3721         (and most applications) will attempt to use the minimal size possible
3722         for a dragable part. If the min property is not set in the description
3723         the part will be (most likely) set to 0px width and 0px height, thus
3724         invisible.
3725     @endblock
3726
3727     @property
3728         x
3729     @parameters
3730         [enable/disable] [step] [count]
3731     @effect
3732         Used to setup dragging events for the X axis. The first parameter is
3733         used to enable (1 or -1) and disable (0) dragging along the axis. When
3734         enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
3735         parameter takes any integer and will limit movement to values
3736         divisible by it, causing the part to jump from position to position.
3737         The third parameter, (question from the author: What is count for?).
3738     @endproperty
3739 */
3740 static void
3741 st_collections_group_parts_part_dragable_x(void)
3742 {
3743    check_arg_count(3);
3744
3745    current_part->dragable.x = parse_int_range(0, -1, 1);
3746    current_part->dragable.step_x = parse_int_range(1, 0, 0x7fffffff);
3747    current_part->dragable.count_x = parse_int_range(2, 0, 0x7fffffff);
3748 }
3749
3750 /**
3751     @page edcref
3752     @property
3753         y
3754     @parameters
3755         [enable/disable] [step] [count]
3756     @effect
3757         Used to setup dragging events for the Y axis. The first parameter is
3758         used to enable (1 or -1) and disable (0) dragging along the axis. When
3759         enabled, 1 will set the starting point at 0.0 and -1 at 1.0. The second
3760         parameter takes any integer and will limit movement to values
3761         divisibles by it, causing the part to jump from position to position.
3762         The third parameter, (question from the author: What is count for?).
3763     @endproperty
3764 */
3765 static void
3766 st_collections_group_parts_part_dragable_y(void)
3767 {
3768    check_arg_count(3);
3769
3770    current_part->dragable.y = parse_int_range(0, -1, 1);
3771    current_part->dragable.step_y = parse_int_range(1, 0, 0x7fffffff);
3772    current_part->dragable.count_y = parse_int_range(2, 0, 0x7fffffff);
3773 }
3774
3775 /**
3776     @page edcref
3777     @property
3778         confine
3779     @parameters
3780         [another part's name]
3781     @effect
3782         When set, limits the movement of the dragged part to another part's
3783         container. When you use confine don't forget to set a min size for the
3784         part, or the draggie will not show up.
3785     @endproperty
3786 */
3787 static void
3788 st_collections_group_parts_part_dragable_confine(void)
3789 {
3790    Edje_Part_Collection *pc;
3791
3792    check_arg_count(1);
3793
3794    pc = eina_list_data_get(eina_list_last(edje_collections));
3795      {
3796         char *name;
3797
3798         name = parse_str(0);
3799         data_queue_part_lookup(pc, name, &(current_part->dragable.confine_id));
3800         free(name);
3801      }
3802 }
3803
3804 /**
3805     @page edcref
3806     @property
3807         events
3808     @parameters
3809         [another dragable part's name]
3810     @effect
3811         It causes the part to forward the drag events to another part, thus
3812         ignoring them for itself.
3813     @endproperty
3814 */
3815 static void
3816 st_collections_group_parts_part_dragable_events(void)
3817 {
3818    Edje_Part_Collection *pc;
3819
3820    check_arg_count(1);
3821
3822    pc = eina_list_data_get(eina_list_last(edje_collections));
3823      {
3824         char *name;
3825
3826         name = parse_str(0);
3827         data_queue_part_lookup(pc, name, &(current_part->dragable.event_id));
3828         free(name);
3829      }
3830 }
3831
3832 /**
3833     @page edcref
3834     @block
3835         items
3836     @context
3837         part {
3838             ..
3839             box {
3840                 items {
3841                     item {
3842                         type: TYPE;
3843                         source: "some source";
3844                         min: 1 1;
3845                         max: 100 100;
3846                         padding: 1 1 2 2;
3847                     }
3848                     item {
3849                         type: TYPE;
3850                         source: "some other source";
3851                         name: "some name";
3852                         align: 1.0 0.5;
3853                     }
3854                     ..
3855                 }
3856             }
3857             ..
3858         }
3859     @description
3860         On a part of type BOX, this block can be used to set other groups
3861         as elements of the box. These can be mixed with external objects set
3862         by the application through the edje_object_part_box_* API.
3863     @endblock
3864 */
3865 static void ob_collections_group_parts_part_box_items_item(void)
3866 {
3867    Edje_Part *ep;
3868    Edje_Pack_Element *item;
3869    Edje_Pack_Element_Parser *pitem;
3870
3871    ep = current_part;
3872
3873    if ((ep->type != EDJE_PART_TYPE_BOX) && (ep->type != EDJE_PART_TYPE_TABLE))
3874      {
3875         ERR("parse error %s:%i. box attributes in non-BOX or TABLE part.",
3876             file_in, line - 1);
3877         exit(-1);
3878      }
3879
3880    ep->items_count++;
3881    ep->items = realloc(ep->items, sizeof (Edje_Pack_Element*) * ep->items_count);
3882    if (!ep->items)
3883      {
3884         ERR("Not enough memory.");
3885         exit(-1);
3886      }
3887
3888    item = mem_alloc(SZ(Edje_Pack_Element_Parser));
3889    current_item = ep->items[ep->items_count - 1] = item;
3890    item->type = EDJE_PART_TYPE_GROUP;
3891    item->name = NULL;
3892    item->source = NULL;
3893    item->min.w = 0;
3894    item->min.h = 0;
3895    item->prefer.w = 0;
3896    item->prefer.h = 0;
3897    item->max.w = -1;
3898    item->max.h = -1;
3899    item->padding.l = 0;
3900    item->padding.r = 0;
3901    item->padding.t = 0;
3902    item->padding.b = 0;
3903    item->align.x = FROM_DOUBLE(0.5);
3904    item->align.y = FROM_DOUBLE(0.5);
3905    item->weight.x = FROM_DOUBLE(0.0);
3906    item->weight.y = FROM_DOUBLE(0.0);
3907    item->aspect.w = 0;
3908    item->aspect.h = 0;
3909    item->aspect.mode = EDJE_ASPECT_CONTROL_NONE;
3910    item->options = NULL;
3911    item->col = -1;
3912    item->row = -1;
3913    item->colspan = 1;
3914    item->rowspan = 1;
3915    pitem = (Edje_Pack_Element_Parser *)item;
3916    pitem->can_override = EINA_FALSE;
3917 }
3918
3919 /**
3920     @page edcref
3921     @property
3922         type
3923     @parameters
3924         Only GROUP for now (defaults to it)
3925     @effect
3926         Sets the type of the object this item will hold.
3927     @endproperty
3928 */
3929 static void st_collections_group_parts_part_box_items_item_type(void)
3930 {
3931    check_arg_count(1);
3932
3933      {
3934         char *s;
3935
3936         s = parse_str(0);
3937         if (strcmp(s, "GROUP"))
3938           {
3939              ERR("parse error %s:%i. token %s not one of: GROUP.",
3940                  file_in, line - 1, s);
3941              exit(-1);
3942           }
3943         /* FIXME: handle the enum, once everything else is supported */
3944         current_item->type = EDJE_PART_TYPE_GROUP;
3945      }
3946 }
3947
3948 /**
3949     @page edcref
3950     @property
3951         name
3952     @parameters
3953         [name for the object]
3954     @effect
3955         Sets the name of the object via evas_object_name_set().
3956     @endproperty
3957 */
3958 static void st_collections_group_parts_part_box_items_item_name(void)
3959 {
3960    Edje_Part *ep;
3961    Edje_Pack_Element *item;
3962    Edje_Pack_Element_Parser *pitem;
3963
3964    check_arg_count(1);
3965
3966    ep = current_part;
3967    item = ep->items[ep->items_count - 1];
3968
3969    item->name = parse_str(0);
3970
3971      {
3972         unsigned int i;
3973
3974         for (i = 0; i < ep->items_count - 1; ++i)
3975           {
3976              if (ep->items[i]->name && (!strcmp(ep->items[i]->name, item->name)))
3977                {
3978                   pitem = (Edje_Pack_Element_Parser *)ep->items[i];
3979                   if (!pitem->can_override)
3980                     {
3981                        ERR("parse error %s:%i. There is already a item of the name %s",
3982                            file_in, line - 1, item->name);
3983                        exit(-1);
3984                     }
3985                   else
3986                     {
3987                        free(item);
3988                        ep->items_count--;
3989                        ep->items = realloc(ep->items, ep->items_count * sizeof (Edje_Pack_Element *));
3990                        current_item = ep->items[i];
3991                        pitem->can_override = EINA_FALSE;
3992                     }
3993                }
3994           }
3995      }
3996 }
3997
3998 /**
3999     @page edcref
4000     @property
4001         source
4002     @parameters
4003         [another group's name]
4004     @effect
4005         Sets the group this object will be made from.
4006     @endproperty
4007 */
4008 static void st_collections_group_parts_part_box_items_item_source(void)
4009 {
4010    check_arg_count(1);
4011
4012    current_item->source = parse_str(0);
4013    data_queue_group_lookup(current_item->source, current_part);
4014 }
4015
4016 /**
4017     @page edcref
4018     @property
4019         min
4020     @parameters
4021         [width] [height]
4022     @effect
4023         Sets the minimum size hints for this object.
4024     @endproperty
4025 */
4026 static void st_collections_group_parts_part_box_items_item_min(void)
4027 {
4028    check_arg_count(2);
4029
4030    current_item->min.w = parse_int_range(0, 0, 0x7ffffff);
4031    current_item->min.h = parse_int_range(1, 0, 0x7ffffff);
4032 }
4033
4034 /**
4035     @page edcref
4036     @property
4037         prefer
4038     @parameters
4039         [width] [height]
4040     @effect
4041         Sets the preferred size hints for this object.
4042     @endproperty
4043 */
4044 static void st_collections_group_parts_part_box_items_item_prefer(void)
4045 {
4046    check_arg_count(2);
4047
4048    current_item->prefer.w = parse_int_range(0, 0, 0x7ffffff);
4049    current_item->prefer.h = parse_int_range(1, 0, 0x7ffffff);
4050 }
4051 /**
4052     @page edcref
4053     @property
4054         max
4055     @parameters
4056         [width] [height]
4057     @effect
4058         Sets the maximum size hints for this object.
4059     @endproperty
4060 */
4061 static void st_collections_group_parts_part_box_items_item_max(void)
4062 {
4063    check_arg_count(2);
4064
4065    current_item->max.w = parse_int_range(0, 0, 0x7ffffff);
4066    current_item->max.h = parse_int_range(1, 0, 0x7ffffff);
4067 }
4068
4069 /**
4070     @page edcref
4071     @property
4072         padding
4073     @parameters
4074         [left] [right] [top] [bottom]
4075     @effect
4076         Sets the padding hints for this object.
4077     @endproperty
4078 */
4079 static void st_collections_group_parts_part_box_items_item_padding(void)
4080 {
4081    check_arg_count(4);
4082
4083    current_item->padding.l = parse_int_range(0, 0, 0x7ffffff);
4084    current_item->padding.r = parse_int_range(1, 0, 0x7ffffff);
4085    current_item->padding.t = parse_int_range(2, 0, 0x7ffffff);
4086    current_item->padding.b = parse_int_range(3, 0, 0x7ffffff);
4087 }
4088
4089 /**
4090     @page edcref
4091     @property
4092         align
4093     @parameters
4094         [x] [y]
4095     @effect
4096         Sets the alignment hints for this object.
4097     @endproperty
4098 */
4099 static void st_collections_group_parts_part_box_items_item_align(void)
4100 {
4101    check_arg_count(2);
4102
4103    current_item->align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
4104    current_item->align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
4105 }
4106
4107 /**
4108     @page edcref
4109     @property
4110         weight
4111     @parameters
4112         [x] [y]
4113     @effect
4114         Sets the weight hints for this object.
4115     @endproperty
4116 */
4117 static void st_collections_group_parts_part_box_items_item_weight(void)
4118 {
4119    check_arg_count(2);
4120
4121    current_item->weight.x = FROM_DOUBLE(parse_float_range(0, 0.0, 99999.99));
4122    current_item->weight.y = FROM_DOUBLE(parse_float_range(1, 0.0, 99999.99));
4123 }
4124
4125 /**
4126     @page edcref
4127     @property
4128         aspect
4129     @parameters
4130         [w] [h]
4131     @effect
4132         Sets the aspect width and height hints for this object.
4133     @endproperty
4134 */
4135 static void st_collections_group_parts_part_box_items_item_aspect(void)
4136 {
4137    check_arg_count(2);
4138
4139    current_item->aspect.w = parse_int_range(0, 0, 0x7fffffff);
4140    current_item->aspect.h = parse_int_range(1, 0, 0x7fffffff);
4141 }
4142
4143 /**
4144     @page edcref
4145     @property
4146         aspect_mode
4147     @parameters
4148         NONE, NEITHER, HORIZONTAL, VERTICAL, BOTH
4149     @effect
4150         Sets the aspect control hints for this object.
4151     @endproperty
4152 */
4153 static void st_collections_group_parts_part_box_items_item_aspect_mode(void)
4154 {
4155    check_arg_count(1);
4156
4157    current_item->aspect.mode = parse_enum(0,
4158                                   "NONE", EDJE_ASPECT_CONTROL_NONE,
4159                                   "NEITHER", EDJE_ASPECT_CONTROL_NEITHER,
4160                                   "HORIZONTAL", EDJE_ASPECT_CONTROL_HORIZONTAL,
4161                                   "VERTICAL", EDJE_ASPECT_CONTROL_VERTICAL,
4162                                   "BOTH", EDJE_ASPECT_CONTROL_BOTH,
4163                                   NULL);
4164 }
4165
4166 /**
4167     @page edcref
4168     @property
4169         options
4170     @parameters
4171         [extra options]
4172     @effect
4173         Sets extra options for the object. Unused for now.
4174     @endproperty
4175 */
4176 static void st_collections_group_parts_part_box_items_item_options(void)
4177 {
4178    check_arg_count(1);
4179
4180    current_item->options = parse_str(0);
4181 }
4182
4183 /**
4184     @page edcref
4185     @property
4186         position
4187     @parameters
4188         [col] [row]
4189     @effect
4190         Sets the position this item will have in the table.
4191         This is required for parts of type TABLE.
4192     @endproperty
4193 */
4194 static void st_collections_group_parts_part_table_items_item_position(void)
4195 {
4196    check_arg_count(2);
4197
4198    if (current_part->type != EDJE_PART_TYPE_TABLE)
4199      {
4200         ERR("parse error %s:%i. table attributes in non-TABLE part.",
4201             file_in, line - 1);
4202         exit(-1);
4203      }
4204
4205    current_item->col = parse_int_range(0, 0, 0xffff);
4206    current_item->row = parse_int_range(1, 0, 0xffff);
4207 }
4208
4209 /**
4210     @page edcref
4211     @property
4212         span
4213     @parameters
4214         [col] [row]
4215     @effect
4216         Sets how many columns/rows this item will use.
4217         Defaults to 1 1.
4218     @endproperty
4219 */
4220 static void st_collections_group_parts_part_table_items_item_span(void)
4221 {
4222    check_arg_count(2);
4223
4224    if (current_part->type != EDJE_PART_TYPE_TABLE)
4225      {
4226         ERR("parse error %s:%i. table attributes in non-TABLE part.",
4227             file_in, line - 1);
4228         exit(-1);
4229      }
4230
4231    current_item->colspan = parse_int_range(0, 1, 0xffff);
4232    current_item->rowspan = parse_int_range(1, 1, 0xffff);
4233 }
4234
4235 /**
4236    @edcsection{description,State description sub blocks}
4237  */
4238
4239 /**
4240     @page edcref
4241     @block
4242         description
4243     @context
4244         description {
4245             inherit: "another_description" INDEX;
4246             state: "description_name" INDEX;
4247             visible: 1;
4248             min: 0 0;
4249             max: -1 -1;
4250             align: 0.5 0.5;
4251             fixed: 0 0;
4252             step: 0 0;
4253             aspect: 1 1;
4254
4255             rel1 {
4256                 ..
4257             }
4258
4259             rel2 {
4260                 ..
4261             }
4262         }
4263     @description
4264         Every part can have one or more description blocks. Each description is
4265         used to define style and layout properties of a part in a given
4266         "state".
4267     @endblock
4268 */
4269 static void
4270 ob_collections_group_parts_part_description(void)
4271 {
4272    Edje_Part_Collection *pc;
4273    Edje_Part *ep;
4274    Edje_Part_Description_Common *ed;
4275
4276    pc = eina_list_data_get(eina_list_last(edje_collections));
4277    ep = current_part;
4278
4279    ed = _edje_part_description_alloc(ep->type, pc->part, ep->name);
4280
4281    if (!ep->default_desc)
4282      {
4283         current_desc = ep->default_desc = ed;
4284      }
4285    else
4286      {
4287         ep->other.desc_count++;
4288         ep->other.desc = realloc(ep->other.desc,
4289                                  sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4290         current_desc = ep->other.desc[ep->other.desc_count - 1] = ed;
4291      }
4292
4293    ed->visible = 1;
4294    ed->limit = 0;
4295    ed->align.x = FROM_DOUBLE(0.5);
4296    ed->align.y = FROM_DOUBLE(0.5);
4297    ed->min.w = 0;
4298    ed->min.h = 0;
4299    ed->fixed.w = 0;
4300    ed->fixed.h = 0;
4301    ed->max.w = -1;
4302    ed->max.h = -1;
4303    ed->rel1.relative_x = FROM_DOUBLE(0.0);
4304    ed->rel1.relative_y = FROM_DOUBLE(0.0);
4305    ed->rel1.offset_x = 0;
4306    ed->rel1.offset_y = 0;
4307    ed->rel1.id_x = -1;
4308    ed->rel1.id_y = -1;
4309    ed->rel2.relative_x = FROM_DOUBLE(1.0);
4310    ed->rel2.relative_y = FROM_DOUBLE(1.0);
4311    ed->rel2.offset_x = -1;
4312    ed->rel2.offset_y = -1;
4313    ed->rel2.id_x = -1;
4314    ed->rel2.id_y = -1;
4315    ed->color_class = NULL;
4316    ed->color.r = 255;
4317    ed->color.g = 255;
4318    ed->color.b = 255;
4319    ed->color.a = 255;
4320    ed->color2.r = 0;
4321    ed->color2.g = 0;
4322    ed->color2.b = 0;
4323    ed->color2.a = 255;
4324    ed->map.id_persp = -1;
4325    ed->map.id_light = -1;
4326    ed->map.rot.id_center = -1;
4327    ed->map.rot.x = FROM_DOUBLE(0.0);
4328    ed->map.rot.y = FROM_DOUBLE(0.0);
4329    ed->map.rot.z = FROM_DOUBLE(0.0);
4330    ed->map.on = 0;
4331    ed->map.smooth = 1;
4332    ed->map.alpha = 1;
4333    ed->map.backcull = 0;
4334    ed->map.persp_on = 0;
4335    ed->persp.zplane = 0;
4336    ed->persp.focal = 1000;
4337    ed->minmul.have = 1;
4338    ed->minmul.w = FROM_INT(1);
4339    ed->minmul.h = FROM_INT(1);
4340 }
4341
4342 /**
4343     @page edcref
4344     @property
4345         inherit
4346     @parameters
4347         [another description's name] [another description's index]
4348     @effect
4349         When set, the description will inherit all the properties from the
4350         named description. The properties defined in this part will override
4351         the inherited properties, reducing the amount of necessary code for
4352         simple state changes. Note: inheritance in Edje is single level only.
4353     @endproperty
4354 */
4355 static void
4356 st_collections_group_parts_part_description_inherit(void)
4357 {
4358    Edje_Part_Collection *pc;
4359    Edje_Part *ep;
4360    Edje_Part_Description_Common *ed, *parent = NULL;
4361    Edje_Part_Image_Id *iid;
4362    char *parent_name;
4363    const char *state_name;
4364    double parent_val, state_val;
4365
4366    pc = eina_list_data_get(eina_list_last(edje_collections));
4367    ep = current_part;
4368    ed = current_desc;
4369
4370    if (!ed->state.name)
4371      {
4372         ERR("parse error %s:%i. inherit may only be used after state",
4373             file_in, line - 1);
4374         exit(-1);
4375      }
4376
4377    parent = parent_desc;
4378    if (!parent)
4379      {
4380         check_min_arg_count(1);
4381
4382         /* inherit may not be used in the default description */
4383         if (!ep->other.desc_count)
4384           {
4385              ERR("parse error %s:%i. "
4386                  "inherit may not be used in the default description",
4387                  file_in, line - 1);
4388              exit(-1);
4389           }
4390
4391         /* find the description that we inherit from */
4392         parent_name = parse_str(0);
4393         if (get_arg_count() == 2)
4394           parent_val = parse_float_range(1, 0.0, 1.0);
4395         else
4396           parent_val = 0.0;
4397
4398         if (!strcmp (parent_name, "default") && parent_val == 0.0)
4399           parent = ep->default_desc;
4400         else
4401           {
4402              Edje_Part_Description_Common *d;
4403              double min_dst = 999.0;
4404              unsigned int i;
4405
4406              if (!strcmp(parent_name, "default"))
4407                {
4408                   parent = ep->default_desc;
4409                   min_dst = ABS(ep->default_desc->state.value - parent_val);
4410                }
4411
4412              for (i = 0; i < ep->other.desc_count; ++i)
4413                {
4414                   d = ep->other.desc[i];
4415
4416                   if (!strcmp (d->state.name, parent_name))
4417                     {
4418
4419                        double dst;
4420
4421                        dst = ABS(d->state.value - parent_val);
4422                        if (dst < min_dst)
4423                          {
4424                             parent = d;
4425                             min_dst = dst;
4426                          }
4427                     }
4428                }
4429           }
4430
4431         if (!parent)
4432           {
4433              ERR("parse error %s:%i. "
4434                  "cannot find referenced part %s state %s %lf",
4435                  file_in, line - 1, ep->name, parent_name, parent_val);
4436              exit(-1);
4437           }
4438
4439         free(parent_name);
4440      }
4441    /* now do a full copy, only state info will be kept */
4442    state_name = ed->state.name;
4443    state_val = ed->state.value;
4444
4445    *ed = *parent;
4446
4447    ed->state.name = state_name;
4448    ed->state.value = state_val;
4449
4450    data_queue_copied_part_lookup(pc, &parent->rel1.id_x, &ed->rel1.id_x);
4451    data_queue_copied_part_lookup(pc, &parent->rel1.id_y, &ed->rel1.id_y);
4452    data_queue_copied_part_lookup(pc, &parent->rel2.id_x, &ed->rel2.id_x);
4453    data_queue_copied_part_lookup(pc, &parent->rel2.id_y, &ed->rel2.id_y);
4454
4455    data_queue_copied_part_lookup(pc, &parent->map.id_persp, &ed->map.id_persp);
4456    data_queue_copied_part_lookup(pc, &parent->map.id_light, &ed->map.id_light);
4457    data_queue_copied_part_lookup(pc, &parent->map.rot.id_center, &ed->map.rot.id_center);
4458
4459    /* make sure all the allocated memory is getting copied, not just
4460     * referenced
4461     */
4462 #define STRDUP(x) x ? strdup(x) : NULL
4463
4464    ed->color_class = STRDUP(ed->color_class);
4465    switch (ep->type)
4466      {
4467       case EDJE_PART_TYPE_SPACER:
4468       case EDJE_PART_TYPE_RECTANGLE:
4469       case EDJE_PART_TYPE_SWALLOW:
4470       case EDJE_PART_TYPE_GROUP:
4471          /* Nothing todo, this part only have a common description. */
4472          break;
4473       case EDJE_PART_TYPE_TEXT:
4474       case EDJE_PART_TYPE_TEXTBLOCK:
4475            {
4476               Edje_Part_Description_Text *ted = (Edje_Part_Description_Text*) ed;
4477               Edje_Part_Description_Text *tparent = (Edje_Part_Description_Text*) parent;
4478
4479               ted->text = tparent->text;
4480
4481               ted->text.text.str = STRDUP(ted->text.text.str);
4482               ted->text.text_class = STRDUP(ted->text.text_class);
4483               ted->text.font.str = STRDUP(ted->text.font.str);
4484
4485               data_queue_copied_part_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source));
4486               data_queue_copied_part_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source));
4487
4488               break;
4489            }
4490       case EDJE_PART_TYPE_IMAGE:
4491            {
4492               Edje_Part_Description_Image *ied = (Edje_Part_Description_Image *) ed;
4493               Edje_Part_Description_Image *iparent = (Edje_Part_Description_Image *) parent;
4494               unsigned int i;
4495
4496               ied->image = iparent->image;
4497
4498               data_queue_image_remove(&ied->image.id, &ied->image.set);
4499               data_queue_copied_image_lookup(&iparent->image.id, &ied->image.id, &ied->image.set);
4500
4501               ied->image.tweens = calloc(iparent->image.tweens_count,
4502                                          sizeof (Edje_Part_Image_Id*));
4503               for (i = 0; i < iparent->image.tweens_count; i++)
4504                 {
4505                    Edje_Part_Image_Id *iid_new;
4506
4507                    iid = iparent->image.tweens[i];
4508
4509                    iid_new = mem_alloc(SZ(Edje_Part_Image_Id));
4510                    data_queue_image_remove(&ied->image.id, &ied->image.set);
4511                    data_queue_copied_image_lookup(&(iid->id), &(iid_new->id), &(iid_new->set));
4512                    ied->image.tweens[i] = iid_new;
4513                 }
4514
4515               break;
4516            }
4517       case EDJE_PART_TYPE_PROXY:
4518            {
4519               Edje_Part_Description_Proxy *ped = (Edje_Part_Description_Proxy*) ed;
4520               Edje_Part_Description_Proxy *pparent = (Edje_Part_Description_Proxy*) parent;
4521
4522               data_queue_copied_part_lookup(pc, &(pparent->proxy.id), &(ped->proxy.id));
4523
4524               break;
4525            }
4526       case EDJE_PART_TYPE_BOX:
4527            {
4528               Edje_Part_Description_Box *bed = (Edje_Part_Description_Box *) ed;
4529               Edje_Part_Description_Box *bparent = (Edje_Part_Description_Box *) parent;
4530
4531               bed->box = bparent->box;
4532
4533               break;
4534            }
4535       case EDJE_PART_TYPE_TABLE:
4536            {
4537               Edje_Part_Description_Table *ted = (Edje_Part_Description_Table *) ed;
4538               Edje_Part_Description_Table *tparent = (Edje_Part_Description_Table *) parent;
4539
4540               ted->table = tparent->table;
4541
4542               break;
4543            }
4544       case EDJE_PART_TYPE_EXTERNAL:
4545            {
4546               Edje_Part_Description_External *eed = (Edje_Part_Description_External *) ed;
4547               Edje_Part_Description_External *eparent = (Edje_Part_Description_External *) parent;
4548
4549               if (eparent->external_params)
4550                 {
4551                    Eina_List *l;
4552                    Edje_External_Param *param, *new_param;
4553
4554                    eed->external_params = NULL;
4555                    EINA_LIST_FOREACH(eparent->external_params, l, param)
4556                      {
4557                         new_param = mem_alloc(SZ(Edje_External_Param));
4558                         *new_param = *param;
4559                         eed->external_params = eina_list_append(eed->external_params, new_param);
4560                      }
4561                 }
4562               break;
4563            }
4564      }
4565
4566 #undef STRDUP
4567 }
4568
4569 /**
4570     @page edcref
4571
4572     @property
4573         source
4574     @parameters
4575         [another part's name]
4576     @effect
4577         Causes the part to use another part content as the content of this part.
4578         Only work with PROXY part.
4579     @endproperty
4580 */
4581 static void
4582 st_collections_group_parts_part_description_source(void)
4583 {
4584    Edje_Part_Collection *pc;
4585    Edje_Part_Description_Proxy *ed;
4586    char *name;
4587
4588    check_arg_count(1);
4589
4590    pc = eina_list_data_get(eina_list_last(edje_collections));
4591
4592    if (current_part->type != EDJE_PART_TYPE_PROXY)
4593      {
4594         ERR("parse error %s:%i. source attributes in non-PROXY part.",
4595             file_in, line - 1);
4596         exit(-1);
4597      }
4598
4599    ed = (Edje_Part_Description_Proxy*) current_desc;
4600
4601    name = parse_str(0);
4602
4603    data_queue_part_lookup(pc, name, &(ed->proxy.id));
4604    free(name);
4605 }
4606
4607 /**
4608     @page edcref
4609     @property
4610         state
4611     @parameters
4612         [a name for the description] [an index]
4613     @effect
4614         Sets a name used to identify a description inside a given part.
4615         Multiple descriptions are used to declare different states of the same
4616         part, like "clicked" or "invisible". All states declarations are also
4617         coupled with an index number between 0.0 and 1.0. All parts must have
4618         at least one description named "default 0.0".
4619     @endproperty
4620 */
4621 static void
4622 st_collections_group_parts_part_description_state(void)
4623 {
4624    Edje_Part *ep;
4625    Edje_Part_Description_Common *ed;
4626    char *s;
4627
4628    check_min_arg_count(1);
4629
4630    ep = current_part;
4631
4632    ed = ep->default_desc;
4633    if (ep->other.desc_count) ed = ep->other.desc[ep->other.desc_count - 1];
4634
4635    s = parse_str(0);
4636    if (!strcmp (s, "custom"))
4637      {
4638         ERR("parse error %s:%i. invalid state name: '%s'.",
4639             file_in, line - 1, s);
4640         exit(-1);
4641      }
4642
4643    ed->state.name = s;
4644    if (get_arg_count() == 1)
4645      ed->state.value = 0.0;
4646    else
4647      ed->state.value = parse_float_range(1, 0.0, 1.0);
4648
4649    if (ed != ep->default_desc)
4650      {
4651         if ((ep->default_desc->state.name && !strcmp(s, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) ||
4652             (!ep->default_desc->state.name && !strcmp(s, "default") && ed->state.value == ep->default_desc->state.value))
4653           {
4654              if (ep->type == EDJE_PART_TYPE_IMAGE)
4655                _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
4656
4657              free(ed);
4658              ep->other.desc_count--;
4659              ep->other.desc = realloc(ep->other.desc,
4660                                       sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4661              current_desc = ep->default_desc;
4662           }
4663         else if (ep->other.desc_count)
4664           {
4665              unsigned int i;
4666              for (i = 0; i < ep->other.desc_count - 1; ++i)
4667                {
4668                   if (!strcmp(s, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value)
4669                     {
4670                        if (ep->type == EDJE_PART_TYPE_IMAGE)
4671                          _edje_part_description_image_remove((Edje_Part_Description_Image*) ed);
4672
4673                        free(ed);
4674                        ep->other.desc_count--;
4675                        ep->other.desc = realloc(ep->other.desc,
4676                                                 sizeof (Edje_Part_Description_Common*) * ep->other.desc_count);
4677                        current_desc = ep->other.desc[i];
4678                        break;
4679                     }
4680                }
4681           }
4682      }
4683 }
4684
4685 /**
4686     @page edcref
4687     @property
4688         visible
4689     @parameters
4690         [0 or 1]
4691     @effect
4692         Takes a boolean value specifying whether part is visible (1) or not
4693         (0). Non-visible parts do not emit signals. The default value is 1.
4694     @endproperty
4695 */
4696 static void
4697 st_collections_group_parts_part_description_visible(void)
4698 {
4699    check_arg_count(1);
4700
4701    if (current_part->type == EDJE_PART_TYPE_SPACER)
4702      {
4703        ERR("parse error %s:%i. SPACER part can't have a visibility defined",
4704            file_in, line - 1);
4705        exit(-1);
4706      }
4707
4708    current_desc->visible = parse_bool(0);
4709 }
4710 /**
4711     @page edcref
4712     @property
4713         limit
4714     @parameters
4715         [NONE, WIDTH, HEIGHT or BOTH]
4716     @effect
4717         Emit a signal when the part size change from zero or to a zero size
4718         ('limit,width,over', 'limit,width,zero'). By default no signal are
4719         emitted.
4720     @endproperty
4721     @since 1.7.0
4722 */
4723 static void
4724 st_collections_group_parts_part_description_limit(void)
4725 {
4726    check_arg_count(1);
4727
4728    current_desc->limit = parse_enum(0,
4729                                     "NONE", 0,
4730                                     "WIDTH", 1,
4731                                     "HEIGHT", 2,
4732                                     "BOTH", 3);
4733
4734    if (current_desc->limit)
4735      {
4736         Edje_Part_Collection *pc;
4737         int count;
4738
4739         pc = eina_list_data_get(eina_list_last(edje_collections));
4740         count = pc->limits.parts_count++;
4741         pc->limits.parts = realloc(pc->limits.parts,
4742                                    pc->limits.parts_count * sizeof (Edje_Part_Limit));
4743         data_queue_part_lookup(pc, current_part->name,
4744                                &(pc->limits.parts[count].part));
4745      }
4746 }
4747
4748 /**
4749     @page edcref
4750     @property
4751         align
4752     @parameters
4753         [X axis] [Y axis]
4754     @effect
4755         When the displayed object's size is smaller than its container, this
4756         property moves it relatively along both axis inside its container. The
4757         default value is "0.5 0.5".
4758     @endproperty
4759 */
4760 static void
4761 st_collections_group_parts_part_description_align(void)
4762 {
4763    check_arg_count(2);
4764
4765    current_desc->align.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
4766    current_desc->align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
4767 }
4768
4769 /**
4770     @page edcref
4771     @property
4772         fixed
4773     @parameters
4774         [width, 0 or 1] [height, 0 or 1]
4775     @effect
4776         This affects the minimum size calculation. See
4777         edje_object_size_min_calc() and edje_object_size_min_restricted_calc().
4778         This tells the min size calculation routine that this part does not
4779         change size in width or height (1 for it doesn't, 0 for it does), so
4780         the routine should not try and expand or contract the part.
4781     @endproperty
4782 */
4783 static void
4784 st_collections_group_parts_part_description_fixed(void)
4785 {
4786    check_arg_count(2);
4787
4788    current_desc->fixed.w = parse_float_range(0, 0, 1);
4789    current_desc->fixed.h = parse_float_range(1, 0, 1);
4790 }
4791
4792 /**
4793     @page edcref
4794     @property
4795         min
4796     @parameters
4797         [width] [height] or SOURCE
4798     @effect
4799         The minimum size of the state.
4800
4801         When min is defined to SOURCE, it will look at the original
4802         image size and enforce it minimal size to match at least the
4803         original one. The part must be an IMAGE or a GROUP part.
4804     @endproperty
4805 */
4806 static void
4807 st_collections_group_parts_part_description_min(void)
4808 {
4809    check_min_arg_count(1);
4810
4811    if (is_param(1)) {
4812       current_desc->min.w = parse_float_range(0, 0, 0x7fffffff);
4813       current_desc->min.h = parse_float_range(1, 0, 0x7fffffff);
4814    } else {
4815       char *tmp;
4816
4817       tmp = parse_str(0);
4818       if ((current_part->type != EDJE_PART_TYPE_IMAGE && current_part->type != EDJE_PART_TYPE_GROUP) ||
4819           !tmp || strcmp(tmp, "SOURCE") != 0)
4820         {
4821            ERR("parse error %s:%i. "
4822                "Only IMAGE and GROUP part can have a min: SOURCE; defined",
4823                file_in, line - 1);
4824            exit(-1);
4825         }
4826
4827       current_desc->min.limit = EINA_TRUE;
4828    }
4829 }
4830
4831 /**
4832     @page edcref
4833     @property
4834         minmul
4835     @parameters
4836         [width multipler] [height multiplier]
4837     @effect
4838         A multiplier FORCIBLY applied to whatever minimum size is only during
4839         minimum size calculation.
4840     @endproperty
4841     @since 1.2
4842 */
4843 static void
4844 st_collections_group_parts_part_description_minmul(void)
4845 {
4846    check_arg_count(2);
4847
4848    current_desc->minmul.w = FROM_DOUBLE(parse_float_range(0, 0, 999999));
4849    current_desc->minmul.h = FROM_DOUBLE(parse_float_range(1, 0, 999999));
4850 }
4851
4852 /**
4853     @page edcref
4854     @property
4855         max
4856     @parameters
4857         [width] [height] or SOURCE
4858     @effect
4859         The maximum size of the state. A size of -1.0 means that it will be ignored in one direction.
4860
4861         When max is set to SOURCE, edje will enforce the part to be
4862         not more than the original image size. The part must be an
4863         IMAGE part.
4864     @endproperty
4865 */
4866 static void
4867 st_collections_group_parts_part_description_max(void)
4868 {
4869    check_min_arg_count(1);
4870
4871    if (is_param(1)) {
4872       current_desc->max.w = parse_float_range(0, -1.0, 0x7fffffff);
4873       current_desc->max.h = parse_float_range(1, -1.0, 0x7fffffff);
4874    } else {
4875       char *tmp;
4876
4877       tmp = parse_str(0);
4878       if (current_part->type != EDJE_PART_TYPE_IMAGE ||
4879           !tmp || strcmp(tmp, "SOURCE") != 0)
4880         {
4881            ERR("parse error %s:%i. "
4882                "Only IMAGE part can have a max: SOURCE; defined",
4883                file_in, line - 1);
4884            exit(-1);
4885         }
4886
4887       current_desc->max.limit = EINA_TRUE;
4888    }
4889 }
4890
4891 /**
4892     @page edcref
4893     @property
4894         step
4895     @parameters
4896         [width] [height]
4897     @effect
4898         Restricts resizing of each dimension to values divisibles by its value.
4899         This causes the part to jump from value to value while resizing. The
4900         default value is "0 0" disabling stepping.
4901     @endproperty
4902 */
4903 static void
4904 st_collections_group_parts_part_description_step(void)
4905 {
4906    check_arg_count(2);
4907
4908    current_desc->step.x = parse_float_range(0, 0, 0x7fffffff);
4909    current_desc->step.y = parse_float_range(1, 0, 0x7fffffff);
4910 }
4911
4912 /**
4913     @page edcref
4914     @property
4915         aspect
4916     @parameters
4917         [min] [max]
4918     @effect
4919         Normally width and height can be resized to any values independently.
4920         The aspect property forces the width to height ratio to be kept between
4921         the minimum and maximum set. For example, "1.0 1.0" will increase the
4922         width a pixel for every pixel added to height. The default value is
4923         "0.0 0.0" disabling aspect.
4924     @endproperty
4925 */
4926 static void
4927 st_collections_group_parts_part_description_aspect(void)
4928 {
4929    check_arg_count(2);
4930
4931    current_desc->aspect.min = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
4932    current_desc->aspect.max = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
4933 }
4934
4935 /**
4936     @page edcref
4937     @property
4938         aspect_preference
4939     @parameters
4940         [DIMENSION]
4941     @effect
4942         Sets the scope of the "aspect" property to a given dimension. Available
4943         options are BOTH, VERTICAL, HORIZONTAL, SOURCE and NONE
4944     @endproperty
4945 */
4946 static void
4947 st_collections_group_parts_part_description_aspect_preference(void)
4948 {
4949    check_arg_count(1);
4950
4951    current_desc->aspect.prefer =  parse_enum(0,
4952                                    "NONE", EDJE_ASPECT_PREFER_NONE,
4953                                    "VERTICAL", EDJE_ASPECT_PREFER_VERTICAL,
4954                                    "HORIZONTAL", EDJE_ASPECT_PREFER_HORIZONTAL,
4955                                    "BOTH", EDJE_ASPECT_PREFER_BOTH,
4956                                    "SOURCE", EDJE_ASPECT_PREFER_SOURCE,
4957                                    NULL);
4958 }
4959
4960 /**
4961     @page edcref
4962     @property
4963         color_class
4964     @parameters
4965         [color class name]
4966     @effect
4967         The part will use the color values of the named color_class, these
4968         values can be overrided by the "color", "color2" and "color3"
4969         properties set below.
4970     @endproperty
4971 */
4972 static void
4973 st_collections_group_parts_part_description_color_class(void)
4974 {
4975    check_arg_count(1);
4976
4977    if (current_part->type == EDJE_PART_TYPE_SPACER)
4978      {
4979        ERR("parse error %s:%i. SPACER part can't have a color defined",
4980            file_in, line - 1);
4981        exit(-1);
4982      }
4983
4984    current_desc->color_class = parse_str(0);
4985 }
4986
4987 /**
4988     @page edcref
4989     @property
4990         color
4991     @parameters
4992         [red] [green] [blue] [alpha]
4993     @effect
4994         Sets the main color to the specified values (between 0 and 255).
4995     @endproperty
4996 */
4997 static void
4998 st_collections_group_parts_part_description_color(void)
4999 {
5000    check_arg_count(4);
5001
5002    if (current_part->type == EDJE_PART_TYPE_SPACER)
5003      {
5004        ERR("parse error %s:%i. SPACER part can't have a color defined",
5005            file_in, line - 1);
5006        exit(-1);
5007      }
5008
5009    current_desc->color.r = parse_int_range(0, 0, 255);
5010    current_desc->color.g = parse_int_range(1, 0, 255);
5011    current_desc->color.b = parse_int_range(2, 0, 255);
5012    current_desc->color.a = parse_int_range(3, 0, 255);
5013 }
5014
5015 /**
5016     @page edcref
5017     @property
5018         color2
5019     @parameters
5020         [red] [green] [blue] [alpha]
5021     @effect
5022         Sets the text shadow color to the specified values (0 to 255).
5023     @endproperty
5024 */
5025 static void
5026 st_collections_group_parts_part_description_color2(void)
5027 {
5028    check_arg_count(4);
5029
5030    if (current_part->type == EDJE_PART_TYPE_SPACER)
5031      {
5032        ERR("parse error %s:%i. SPACER part can't have a color defined",
5033            file_in, line - 1);
5034        exit(-1);
5035      }
5036
5037    current_desc->color2.r = parse_int_range(0, 0, 255);
5038    current_desc->color2.g = parse_int_range(1, 0, 255);
5039    current_desc->color2.b = parse_int_range(2, 0, 255);
5040    current_desc->color2.a = parse_int_range(3, 0, 255);
5041 }
5042
5043 /**
5044     @page edcref
5045     @property
5046         color3
5047     @parameters
5048         [red] [green] [blue] [alpha]
5049     @effect
5050         Sets the text outline color to the specified values (0 to 255).
5051     @endproperty
5052 */
5053 static void
5054 st_collections_group_parts_part_description_color3(void)
5055 {
5056    Edje_Part_Collection *pc;
5057    Edje_Part_Description_Text *ed;
5058
5059    check_arg_count(4);
5060
5061    pc = eina_list_data_get(eina_list_last(edje_collections));
5062
5063    if (current_part->type != EDJE_PART_TYPE_TEXT
5064        && current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
5065      {
5066         ERR("Setting color3 in part %s from %s not of type TEXT or TEXTBLOCK.",
5067             current_part->name, pc->part);
5068         exit(-1);
5069      }
5070
5071    ed = (Edje_Part_Description_Text*)current_desc;
5072
5073    ed->text.color3.r = parse_int_range(0, 0, 255);
5074    ed->text.color3.g = parse_int_range(1, 0, 255);
5075    ed->text.color3.b = parse_int_range(2, 0, 255);
5076    ed->text.color3.a = parse_int_range(3, 0, 255);
5077 }
5078
5079 /**
5080     @page edcref
5081     @block
5082         rel1/rel2
5083     @context
5084         description {
5085             ..
5086             rel1 {
5087                 relative: 0.0 0.0;
5088                 offset:     0   0;
5089             }
5090             ..
5091             rel2 {
5092                 relative: 1.0 1.0;
5093                 offset:    -1  -1;
5094             }
5095             ..
5096         }
5097     @description
5098         The rel1 and rel2 blocks are used to define the position of each corner
5099         of the part's container. With rel1 being the left-up corner and rel2
5100         being the right-down corner.
5101     @endblock
5102
5103     @property
5104         relative
5105     @parameters
5106         [X axis] [Y axis]
5107     @effect
5108         Moves a corner to a relative position inside the container of the
5109         relative "to" part. Values from 0.0 (0%, beginning) to 1.0 (100%, end)
5110         of each axis.
5111     @endproperty
5112 */
5113 static void
5114 st_collections_group_parts_part_description_rel1_relative(void)
5115 {
5116    check_arg_count(2);
5117
5118    current_desc->rel1.relative_x = FROM_DOUBLE(parse_float(0));
5119    current_desc->rel1.relative_y = FROM_DOUBLE(parse_float(1));
5120 }
5121
5122 /**
5123     @page edcref
5124     @property
5125         offset
5126     @parameters
5127         [X axis] [Y axis]
5128     @effect
5129         Affects the corner position a fixed number of pixels along each axis.
5130     @endproperty
5131 */
5132 static void
5133 st_collections_group_parts_part_description_rel1_offset(void)
5134 {
5135    check_arg_count(2);
5136
5137    current_desc->rel1.offset_x = parse_int(0);
5138    current_desc->rel1.offset_y = parse_int(1);
5139 }
5140
5141 /**
5142     @page edcref
5143     @property
5144         to
5145     @parameters
5146         [another part's name]
5147     @effect
5148         Causes a corner to be positioned relatively to another part's
5149         container. Setting to "" will un-set this value for inherited
5150         parts.
5151     @endproperty
5152 */
5153 static void
5154 st_collections_group_parts_part_description_rel1_to(void)
5155 {
5156    Edje_Part_Collection *pc;
5157
5158    check_arg_count(1);
5159
5160    pc = eina_list_data_get(eina_list_last(edje_collections));
5161
5162    {
5163       char *name;
5164
5165       name = parse_str(0);
5166       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
5167       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
5168       free(name);
5169    }
5170 }
5171
5172 /**
5173     @page edcref
5174     @property
5175         to_x
5176     @parameters
5177         [another part's name]
5178     @effect
5179         Causes a corner to be positioned relatively to the X axis of another
5180         part's container. Simply put affects the first parameter of "relative".
5181         Setting to "" will un-set this value for inherited parts.
5182     @endproperty
5183 */
5184 static void
5185 st_collections_group_parts_part_description_rel1_to_x(void)
5186 {
5187    Edje_Part_Collection *pc;
5188
5189    check_arg_count(1);
5190
5191    pc = eina_list_data_get(eina_list_last(edje_collections));
5192
5193    {
5194       char *name;
5195
5196       name = parse_str(0);
5197       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_x));
5198       free(name);
5199    }
5200 }
5201
5202 /**
5203     @page edcref
5204     @property
5205         to_y
5206     @parameters
5207         [another part's name]
5208     @effect
5209         Causes a corner to be positioned relatively to the Y axis of another
5210         part's container. Simply put, affects the second parameter of
5211         "relative". Setting to "" will un-set this value for inherited parts.
5212     @endproperty
5213 */
5214 static void
5215 st_collections_group_parts_part_description_rel1_to_y(void)
5216 {
5217    Edje_Part_Collection *pc;
5218
5219    check_arg_count(1);
5220
5221    pc = eina_list_data_get(eina_list_last(edje_collections));
5222
5223    {
5224       char *name;
5225
5226       name = parse_str(0);
5227       data_queue_part_lookup(pc, name, &(current_desc->rel1.id_y));
5228       free(name);
5229    }
5230 }
5231
5232 static void
5233 st_collections_group_parts_part_description_rel2_relative(void)
5234 {
5235    check_arg_count(2);
5236
5237    current_desc->rel2.relative_x = FROM_DOUBLE(parse_float(0));
5238    current_desc->rel2.relative_y = FROM_DOUBLE(parse_float(1));
5239 }
5240
5241 static void
5242 st_collections_group_parts_part_description_rel2_offset(void)
5243 {
5244    check_arg_count(2);
5245
5246    current_desc->rel2.offset_x = parse_int(0);
5247    current_desc->rel2.offset_y = parse_int(1);
5248 }
5249
5250 static void
5251 st_collections_group_parts_part_description_rel2_to(void)
5252 {
5253    Edje_Part_Collection *pc;
5254
5255    check_arg_count(1);
5256
5257    pc = eina_list_data_get(eina_list_last(edje_collections));
5258
5259    {
5260       char *name;
5261
5262       name = parse_str(0);
5263       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
5264       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
5265       free(name);
5266    }
5267 }
5268
5269 static void
5270 st_collections_group_parts_part_description_rel2_to_x(void)
5271 {
5272    Edje_Part_Collection *pc;
5273
5274    check_arg_count(1);
5275
5276    pc = eina_list_data_get(eina_list_last(edje_collections));
5277
5278    {
5279       char *name;
5280
5281       name = parse_str(0);
5282       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_x));
5283       free(name);
5284    }
5285 }
5286
5287 static void
5288 st_collections_group_parts_part_description_rel2_to_y(void)
5289 {
5290    Edje_Part_Collection *pc;
5291
5292    check_arg_count(1);
5293
5294    pc = eina_list_data_get(eina_list_last(edje_collections));
5295
5296    {
5297       char *name;
5298
5299       name = parse_str(0);
5300       data_queue_part_lookup(pc, name, &(current_desc->rel2.id_y));
5301       free(name);
5302    }
5303 }
5304
5305 /**
5306    @edcsection{description_image,Image state description sub blocks}
5307  */
5308
5309 /**
5310     @page edcref
5311     @block
5312         image
5313     @context
5314         description {
5315             ..
5316             image {
5317                 normal: "filename.ext";
5318                 tween:  "filename2.ext";
5319                 ..
5320                 tween:  "filenameN.ext";
5321                 border:  left right top bottom;
5322                 middle:  0/1/NONE/DEFAULT/SOLID;
5323             }
5324             ..
5325         }
5326     @description
5327     @endblock
5328
5329     @property
5330         normal
5331     @parameters
5332         [image's filename]
5333     @effect
5334         Name of image to be used as previously declared in the  images block.
5335         In an animation, this is the first and last image displayed. It's
5336         required in any image part
5337     @endproperty
5338 */
5339 static void
5340 st_collections_group_parts_part_description_image_normal(void)
5341 {
5342    Edje_Part_Description_Image *ed;
5343
5344    check_arg_count(1);
5345
5346    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5347      {
5348         ERR("parse error %s:%i. "
5349             "image attributes in non-IMAGE part.",
5350             file_in, line - 1);
5351         exit(-1);
5352      }
5353
5354    ed = (Edje_Part_Description_Image*) current_desc;
5355
5356    {
5357       char *name;
5358
5359       name = parse_str(0);
5360       data_queue_image_remove(&(ed->image.id), &(ed->image.set));
5361       data_queue_image_lookup(name, &(ed->image.id), &(ed->image.set));
5362       free(name);
5363    }
5364 }
5365
5366 /**
5367     @page edcref
5368     @property
5369         tween
5370     @parameters
5371         [image's filename]
5372     @effect
5373         Name of an image to be used in an animation loop, an image block can
5374         have none, one or multiple tween declarations. Images are displayed in
5375         the order they are listed, during the transition to the state they are
5376         declared in; the "normal" image is the final state.
5377     @endproperty
5378 */
5379 static void
5380 st_collections_group_parts_part_description_image_tween(void)
5381 {
5382    Edje_Part_Description_Image *ed;
5383
5384    check_arg_count(1);
5385
5386    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5387      {
5388         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5389             file_in, line - 1);
5390         exit(-1);
5391      }
5392
5393    ed = (Edje_Part_Description_Image*) current_desc;
5394
5395    {
5396       char *name;
5397       Edje_Part_Image_Id *iid;
5398
5399       iid = mem_alloc(SZ(Edje_Part_Image_Id));
5400       ed->image.tweens_count++;
5401       ed->image.tweens = realloc(ed->image.tweens,
5402                                  sizeof (Edje_Part_Image_Id*) * ed->image.tweens_count);
5403       ed->image.tweens[ed->image.tweens_count - 1] = iid;
5404       name = parse_str(0);
5405       data_queue_image_remove(&(iid->id), &(iid->set));
5406       data_queue_image_lookup(name, &(iid->id), &(iid->set));
5407       free(name);
5408    }
5409 }
5410
5411 /**
5412     @page edcref
5413     @property
5414         border
5415     @parameters
5416         [left] [right] [top] [bottom]
5417     @effect
5418         If set, the area (in pixels) of each side of the image will be
5419         displayed as a fixed size border, from the side -> inwards, preventing
5420         the corners from being changed on a resize.
5421     @endproperty
5422 */
5423 static void
5424 st_collections_group_parts_part_description_image_border(void)
5425 {
5426    Edje_Part_Description_Image *ed;
5427
5428    check_arg_count(4);
5429
5430    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5431      {
5432         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5433             file_in, line - 1);
5434         exit(-1);
5435      }
5436
5437    ed = (Edje_Part_Description_Image*) current_desc;
5438
5439    ed->image.border.l = parse_int_range(0, 0, 0x7fffffff);
5440    ed->image.border.r = parse_int_range(1, 0, 0x7fffffff);
5441    ed->image.border.t = parse_int_range(2, 0, 0x7fffffff);
5442    ed->image.border.b = parse_int_range(3, 0, 0x7fffffff);
5443 }
5444
5445 /**
5446     @page edcref
5447     @property
5448         middle
5449     @parameters
5450         0, 1, NONE, DEFAULT, SOLID
5451     @effect
5452         If border is set, this value tells Edje if the rest of the
5453         image (not covered by the defined border) will be displayed or not
5454         or be assumed to be solid (without alpha). The default is 1/DEFAULT.
5455     @endproperty
5456 */
5457 static void
5458 st_collections_group_parts_part_description_image_middle(void)
5459 {
5460    Edje_Part_Description_Image *ed;
5461
5462    check_arg_count(1);
5463
5464    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5465      {
5466         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5467             file_in, line - 1);
5468         exit(-1);
5469      }
5470
5471    ed = (Edje_Part_Description_Image*) current_desc;
5472
5473    ed->image.border.no_fill =  parse_enum(0,
5474                                           "1", 0,
5475                                           "DEFAULT", 0,
5476                                           "0", 1,
5477                                           "NONE", 1,
5478                                           "SOLID", 2,
5479                                           NULL);
5480 }
5481
5482 /**
5483     @page edcref
5484     @property
5485         border_scale_by
5486     @parameters
5487         0.0 or bigger (0.0 or 1.0 to turn it off)
5488     @effect
5489         If border scaling is enabled then normally the OUTPUT border sizes
5490         (e.g. if 3 pixels on the left edge are set as a border, then normally
5491         at scale 1.0, those 3 columns will always be the exact 3 columns of
5492         output, or at scale 2.0 they will be 6 columns, or 0.33 they will merge
5493         into a single column). This property multiplies the input scale
5494         factor by this multiplier, allowing the creation of "supersampled"
5495         borders to make much higher resolution outputs possible by always using
5496         the highest resolution artwork and then runtime scaling it down.
5497     @endproperty
5498 */
5499 static void
5500 st_collections_group_parts_part_description_image_border_scale_by(void)
5501 {
5502    Edje_Part_Description_Image *ed;
5503
5504    check_arg_count(1);
5505
5506    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5507      {
5508         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5509             file_in, line - 1);
5510         exit(-1);
5511      }
5512
5513    ed = (Edje_Part_Description_Image*) current_desc;
5514
5515    ed->image.border.scale_by = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
5516 }
5517
5518 /**
5519     @page edcref
5520     @property
5521         border_scale
5522     @parameters
5523         0, 1
5524     @effect
5525         If border is set, this value tells Edje if the border should be scaled
5526         by the object/global edje scale factors
5527     @endproperty
5528 */
5529 static void
5530 st_collections_group_parts_part_description_image_border_scale(void)
5531 {
5532    Edje_Part_Description_Image *ed;
5533
5534    check_arg_count(1);
5535
5536    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5537      {
5538         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5539             file_in, line - 1);
5540         exit(-1);
5541      }
5542
5543    ed = (Edje_Part_Description_Image*) current_desc;
5544
5545    ed->image.border.scale =  parse_enum(0,
5546                                         "0", 0,
5547                                         "1", 1,
5548                                         NULL);
5549 }
5550
5551 /**
5552     @page edcref
5553     @property
5554         scale_hint
5555     @parameters
5556         0, NONE, DYNAMIC, STATIC
5557     @effect
5558         Sets the evas image scale hint letting the engine more effectively save
5559         cached copies of the scaled image if it makes sense
5560     @endproperty
5561 */
5562 static void
5563 st_collections_group_parts_part_description_image_scale_hint(void)
5564 {
5565    Edje_Part_Description_Image *ed;
5566
5567    check_arg_count(1);
5568
5569    if (current_part->type != EDJE_PART_TYPE_IMAGE)
5570      {
5571         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5572             file_in, line - 1);
5573         exit(-1);
5574      }
5575
5576    ed = (Edje_Part_Description_Image*) current_desc;
5577
5578    ed->image.scale_hint =  parse_enum(0,
5579                                       "NONE", EVAS_IMAGE_SCALE_HINT_NONE,
5580                                       "DYNAMIC", EVAS_IMAGE_SCALE_HINT_DYNAMIC,
5581                                       "STATIC", EVAS_IMAGE_SCALE_HINT_STATIC,
5582                                       "0", EVAS_IMAGE_SCALE_HINT_NONE,
5583                                       NULL);
5584 }
5585
5586 /**
5587     @page edcref
5588     @block
5589         fill
5590     @context
5591         description {
5592             ..
5593             fill {
5594                 smooth: 0-1;
5595                 origin {
5596                     relative: X-axis Y-axis;
5597                     offset:   X-axis Y-axis;
5598                 }
5599                 size {
5600                     relative: width  height;
5601                     offset:   width  height;
5602                 }
5603             }
5604             ..
5605         }
5606     @description
5607         The fill method is an optional block that defines the way an IMAGE part
5608         is going to be displayed inside its container.
5609         It can be used for tiling (repeating the image) or displaying only
5610         part of an image. See @ref evas_object_image_fill_set() documentation
5611         for more details.
5612     @endblock
5613
5614     @property
5615         smooth
5616     @parameters
5617         [0 or 1]
5618     @effect
5619         The smooth property takes a boolean value to decide if the image will
5620         be smoothed on scaling (1) or not (0). The default value is 1.
5621     @endproperty
5622 */
5623 static void
5624 st_collections_group_parts_part_description_fill_smooth(void)
5625 {
5626    Edje_Part_Description_Spec_Fill *fill;
5627
5628    check_arg_count(1);
5629
5630    switch (current_part->type)
5631      {
5632       case EDJE_PART_TYPE_IMAGE:
5633         {
5634            Edje_Part_Description_Image *ed;
5635
5636            ed = (Edje_Part_Description_Image*) current_desc;
5637
5638            fill = &ed->image.fill;
5639            break;
5640         }
5641       case EDJE_PART_TYPE_PROXY:
5642         {
5643            Edje_Part_Description_Proxy *ed;
5644
5645            ed = (Edje_Part_Description_Proxy*) current_desc;
5646
5647            fill = &ed->proxy.fill;
5648            break;
5649         }
5650       default:
5651         {
5652            ERR("parse error %s:%i. "
5653                "image and proxy attributes in non-IMAGE, non-PROXY `%s` part (%i).",
5654                file_in, line - 1, current_part->name, current_part->type);
5655            exit(-1);
5656         }
5657      }
5658
5659    fill->smooth = parse_bool(0);
5660 }
5661
5662 /**
5663     @page edcref
5664
5665     @property
5666         spread
5667     @parameters
5668         TODO
5669     @effect
5670         TODO
5671     @endproperty
5672 */
5673 static void
5674 st_collections_group_parts_part_description_fill_spread(void)
5675 {
5676 #if 0
5677    Edje_Part_Collection *pc;
5678    Edje_Part *ep;
5679    Edje_Part_Description_Image *ed;
5680 #endif
5681
5682    check_arg_count(1);
5683
5684    /* XXX this will need to include IMAGES when spread support is added to evas images */
5685    {
5686       ERR("parse error %s:%i. fill.spread not supported yet.",
5687           file_in, line - 1);
5688       exit(-1);
5689    }
5690
5691 #if 0
5692    pc = eina_list_data_get(eina_list_last(edje_collections));
5693
5694    ep = pc->parts[pc->parts_count - 1];
5695
5696    if (ep->type != EDJE_PART_TYPE_IMAGE)
5697      {
5698         ERR("parse error %s:%i. image attributes in non-IMAGE part.",
5699             file_in, line - 1);
5700         exit(-1);
5701      }
5702
5703    ed = (Edje_Part_Description_Image*) ep->default_desc;
5704    if (ep->other.desc_count) ed = (Edje_Part_Description_Image*)  ep->other.desc[ep->other.desc_count - 1];
5705
5706    ed->image.fill.spread = parse_int_range(0, 0, 1);
5707 #endif
5708 }
5709
5710 /**
5711     @page edcref
5712
5713     @property
5714         type
5715     @parameters
5716         TODO
5717     @effect
5718         TODO
5719     @endproperty
5720 */
5721 static void
5722 st_collections_group_parts_part_description_fill_type(void)
5723 {
5724    Edje_Part_Description_Spec_Fill *fill;
5725
5726    check_arg_count(1);
5727
5728    switch (current_part->type)
5729      {
5730       case EDJE_PART_TYPE_IMAGE:
5731         {
5732            Edje_Part_Description_Image *ed;
5733
5734            ed = (Edje_Part_Description_Image*) current_desc;
5735
5736            fill = &ed->image.fill;
5737            break;
5738         }
5739       case EDJE_PART_TYPE_PROXY:
5740         {
5741            Edje_Part_Description_Proxy *ed;
5742
5743            ed = (Edje_Part_Description_Proxy*) current_desc;
5744
5745            fill = &ed->proxy.fill;
5746            break;
5747         }
5748       default:
5749         {
5750            ERR("parse error %s:%i. "
5751                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5752                file_in, line - 1);
5753            exit(-1);
5754         }
5755      }
5756
5757    fill->type = parse_enum(0,
5758                            "SCALE", EDJE_FILL_TYPE_SCALE,
5759                            "TILE", EDJE_FILL_TYPE_TILE,
5760                            NULL);
5761 }
5762
5763 /**
5764     @page edcref
5765     @block
5766         origin
5767     @context
5768         description {
5769             ..
5770             fill {
5771                 ..
5772                 origin {
5773                     relative: 0.0 0.0;
5774                     offset:   0   0;
5775                 }
5776                 ..
5777             }
5778             ..
5779         }
5780     @description
5781         The origin block is used to place the starting point, inside the
5782         displayed element, that will be used to render the tile. By default,
5783         the origin is set at the element's left-up corner.
5784     @endblock
5785
5786     @property
5787         relative
5788     @parameters
5789         [X axis] [Y axis]
5790     @effect
5791         Sets the starting point relatively to displayed element's content.
5792     @endproperty
5793 */
5794 static void
5795 st_collections_group_parts_part_description_fill_origin_relative(void)
5796 {
5797    Edje_Part_Description_Spec_Fill *fill;
5798
5799    check_arg_count(2);
5800
5801    switch (current_part->type)
5802      {
5803       case EDJE_PART_TYPE_IMAGE:
5804         {
5805            Edje_Part_Description_Image *ed;
5806
5807            ed = (Edje_Part_Description_Image*) current_desc;
5808
5809            fill = &ed->image.fill;
5810            break;
5811         }
5812       case EDJE_PART_TYPE_PROXY:
5813         {
5814            Edje_Part_Description_Proxy *ed;
5815
5816            ed = (Edje_Part_Description_Proxy*) current_desc;
5817
5818            fill = &ed->proxy.fill;
5819            break;
5820         }
5821       default:
5822         {
5823            ERR("parse error %s:%i. "
5824                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5825                file_in, line - 1);
5826            exit(-1);
5827         }
5828      }
5829
5830    fill->pos_rel_x = FROM_DOUBLE(parse_float_range(0, -999999999.0, 999999999.0));
5831    fill->pos_rel_y = FROM_DOUBLE(parse_float_range(1, -999999999.0, 999999999.0));
5832 }
5833
5834 /**
5835     @page edcref
5836     @property
5837         offset
5838     @parameters
5839         [X axis] [Y axis]
5840     @effect
5841         Affects the starting point a fixed number of pixels along each axis.
5842     @endproperty
5843 */
5844 static void
5845 st_collections_group_parts_part_description_fill_origin_offset(void)
5846 {
5847    Edje_Part_Description_Spec_Fill *fill;
5848
5849    check_arg_count(2);
5850
5851    switch (current_part->type)
5852      {
5853       case EDJE_PART_TYPE_IMAGE:
5854         {
5855            Edje_Part_Description_Image *ed;
5856
5857            ed = (Edje_Part_Description_Image*) current_desc;
5858
5859            fill = &ed->image.fill;
5860            break;
5861         }
5862       case EDJE_PART_TYPE_PROXY:
5863         {
5864            Edje_Part_Description_Proxy *ed;
5865
5866            ed = (Edje_Part_Description_Proxy*) current_desc;
5867
5868            fill = &ed->proxy.fill;
5869            break;
5870         }
5871       default:
5872         {
5873            ERR("parse error %s:%i. "
5874                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5875                file_in, line - 1);
5876            exit(-1);
5877         }
5878      }
5879
5880    fill->pos_abs_x = parse_int(0);
5881    fill->pos_abs_y = parse_int(1);
5882 }
5883
5884 /**
5885     @page edcref
5886     @block
5887         size
5888     @context
5889         description {
5890             ..
5891             fill {
5892                 ..
5893                 size {
5894                     relative: 1.0 1.0;
5895                     offset:  -1  -1;
5896                 }
5897                 ..
5898             }
5899             ..
5900         }
5901     @description
5902         The size block defines the tile size of the content that will be
5903         displayed.
5904     @endblock
5905
5906     @property
5907         relative
5908     @parameters
5909         [width] [height]
5910     @effect
5911         Takes a pair of decimal values that represent the percentual value
5912         of the original size of the element. For example, "0.5 0.5" represents
5913         half the size, while "2.0 2.0" represents the double. The default
5914         value is "1.0 1.0".
5915     @endproperty
5916 */
5917 static void
5918 st_collections_group_parts_part_description_fill_size_relative(void)
5919 {
5920    Edje_Part_Description_Spec_Fill *fill;
5921
5922    check_arg_count(2);
5923
5924    switch (current_part->type)
5925      {
5926       case EDJE_PART_TYPE_IMAGE:
5927         {
5928            Edje_Part_Description_Image *ed;
5929
5930            ed = (Edje_Part_Description_Image*) current_desc;
5931
5932            fill = &ed->image.fill;
5933            break;
5934         }
5935       case EDJE_PART_TYPE_PROXY:
5936         {
5937            Edje_Part_Description_Proxy *ed;
5938
5939            ed = (Edje_Part_Description_Proxy*) current_desc;
5940
5941            fill = &ed->proxy.fill;
5942            break;
5943         }
5944       default:
5945         {
5946            ERR("parse error %s:%i. "
5947                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5948                file_in, line - 1);
5949            exit(-1);
5950         }
5951      }
5952
5953    fill->rel_x = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
5954    fill->rel_y = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
5955 }
5956
5957 /**
5958     @page edcref
5959     @property
5960         offset
5961     @parameters
5962         [X axis] [Y axis]
5963     @effect
5964         Affects the size of the tile a fixed number of pixels along each axis.
5965     @endproperty
5966 */
5967 static void
5968 st_collections_group_parts_part_description_fill_size_offset(void)
5969 {
5970    Edje_Part_Description_Spec_Fill *fill;
5971
5972    check_arg_count(2);
5973
5974    switch (current_part->type)
5975      {
5976       case EDJE_PART_TYPE_IMAGE:
5977         {
5978            Edje_Part_Description_Image *ed;
5979
5980            ed = (Edje_Part_Description_Image*) current_desc;
5981
5982            fill = &ed->image.fill;
5983            break;
5984         }
5985       case EDJE_PART_TYPE_PROXY:
5986         {
5987            Edje_Part_Description_Proxy *ed;
5988
5989            ed = (Edje_Part_Description_Proxy*) current_desc;
5990
5991            fill = &ed->proxy.fill;
5992            break;
5993         }
5994       default:
5995         {
5996            ERR("parse error %s:%i. "
5997                "image and proxy attributes in non-IMAGE, non-PROXY part.",
5998                file_in, line - 1);
5999            exit(-1);
6000         }
6001      }
6002
6003    fill->abs_x = parse_int(0);
6004    fill->abs_y = parse_int(1);
6005 }
6006
6007
6008 /**
6009    @edcsection{description_text,Text state description sub blocks}
6010  */
6011
6012 /**
6013     @page edcref
6014
6015     @block
6016         text
6017     @context
6018         part {
6019             description {
6020                 ..
6021                 text {
6022                     text:        "some string of text to display";
6023                     font:        "font_name";
6024                     size:         SIZE;
6025                     text_class:  "class_name";
6026                     fit:          horizontal vertical;
6027                     min:          horizontal vertical;
6028                     max:          horizontal vertical;
6029                     align:        X-axis     Y-axis;
6030                     source:      "part_name";
6031                     text_source: "text_part_name";
6032                     ellipsis:     0.0-1.0;
6033                     style:       "stylename";
6034                 }
6035                 ..
6036             }
6037         }
6038     @description
6039     @endblock
6040
6041     @property
6042         text
6043     @parameters
6044         [a string of text, or nothing]
6045     @effect
6046         Sets the default content of a text part, normally the application is
6047         the one changing its value.
6048     @endproperty
6049 */
6050 static void
6051 st_collections_group_parts_part_description_text_text(void)
6052 {
6053    Edje_Part_Description_Text *ed;
6054    char *str = NULL;
6055    int i;
6056
6057    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6058        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6059      {
6060         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6061             file_in, line - 1);
6062         exit(-1);
6063      }
6064
6065    ed = (Edje_Part_Description_Text*) current_desc;
6066
6067    for (i = 0; ;i++)
6068      {
6069         char *s;
6070
6071         if (!is_param(i)) break;
6072         s = parse_str(i);
6073         if (!str) str = s;
6074         else
6075           {
6076              str = realloc(str, strlen(str) + strlen(s) + 1);
6077              strcat(str, s);
6078              free(s);
6079           }
6080      }
6081    ed->text.text.str = str;
6082 }
6083
6084 /**
6085     @page edcref
6086
6087     @property
6088         text_class
6089     @parameters
6090         [text class name]
6091     @effect
6092         Similar to color_class, this is the name used by the application
6093         to alter the font family and size at runtime.
6094     @endproperty
6095 */
6096 static void
6097 st_collections_group_parts_part_description_text_text_class(void)
6098 {
6099    Edje_Part_Description_Text *ed;
6100
6101    check_arg_count(1);
6102
6103    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6104        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6105      {
6106         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6107             file_in, line - 1);
6108         exit(-1);
6109      }
6110
6111    ed = (Edje_Part_Description_Text*) current_desc;
6112
6113    ed->text.text_class = parse_str(0);
6114 }
6115
6116 /**
6117     @page edcref
6118
6119     @property
6120         font
6121     @parameters
6122         [font alias]
6123     @effect
6124         This sets the font family to one of the aliases set up in the "fonts"
6125         block. Can be overrided by the application.
6126     @endproperty
6127 */
6128 static void
6129 st_collections_group_parts_part_description_text_font(void)
6130 {
6131    Edje_Part_Description_Text *ed;
6132
6133    check_arg_count(1);
6134
6135    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6136        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6137      {
6138         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6139             file_in, line - 1);
6140         exit(-1);
6141      }
6142
6143    ed = (Edje_Part_Description_Text*) current_desc;
6144
6145    ed->text.font.str = parse_str(0);
6146 }
6147
6148 /**
6149     @page edcref
6150
6151     @property
6152         style
6153     @parameters
6154         [the style name]
6155     @effect
6156         Causes the part to use the default style and tags defined in the
6157         "style" block with the specified name.
6158     @endproperty
6159 */
6160 static void
6161 st_collections_group_parts_part_description_text_style(void)
6162 {
6163    Edje_Part_Description_Text *ed;
6164
6165    check_arg_count(1);
6166
6167    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6168        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6169      {
6170         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6171             file_in, line - 1);
6172         exit(-1);
6173      }
6174
6175    ed = (Edje_Part_Description_Text*) current_desc;
6176
6177    ed->text.style.str = parse_str(0);
6178 }
6179
6180 /**
6181     @page edcref
6182
6183     @property
6184         repch
6185     @parameters
6186         [the replacement character string]
6187     @effect
6188         If this is a textblock and is in PASSWORD mode this string is used
6189         to replace every character to hide the details of the entry. Normally
6190         you would use a "*", but you can use anything you like.
6191     @endproperty
6192 */
6193 static void
6194 st_collections_group_parts_part_description_text_repch(void)
6195 {
6196    Edje_Part_Description_Text *ed;
6197
6198    check_arg_count(1);
6199
6200    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6201        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6202      {
6203         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6204             file_in, line - 1);
6205         exit(-1);
6206      }
6207
6208    ed = (Edje_Part_Description_Text*) current_desc;
6209
6210    ed->text.repch.str = parse_str(0);
6211 }
6212
6213 /**
6214     @page edcref
6215
6216     @property
6217         size
6218     @parameters
6219         [font size in points (pt)]
6220     @effect
6221         Sets the default font size for the text part. Can be overrided by the
6222         application.
6223     @endproperty
6224 */
6225 static void
6226 st_collections_group_parts_part_description_text_size(void)
6227 {
6228    Edje_Part_Description_Text *ed;
6229
6230    check_arg_count(1);
6231
6232    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6233        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6234      {
6235         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6236             file_in, line - 1);
6237         exit(-1);
6238      }
6239
6240    ed = (Edje_Part_Description_Text*)current_desc;
6241
6242    ed->text.size = parse_int_range(0, 0, 255);
6243 }
6244
6245 /**
6246     @page edcref
6247
6248     @property
6249         size_range
6250     @parameters
6251         [font min size in points (pt)] [font max size in points (pt)]
6252     @effect
6253         Sets the allowed font size for the text part. Setting min and max to 0
6254         means we won't restrict the sizing (default).
6255     @endproperty
6256     @since 1.1.0
6257 */
6258 static void
6259 st_collections_group_parts_part_description_text_size_range(void)
6260 {
6261    Edje_Part_Description_Text *ed;
6262
6263    check_arg_count(2);
6264
6265    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6266        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6267      {
6268         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6269             file_in, line - 1);
6270         exit(-1);
6271      }
6272
6273    ed = (Edje_Part_Description_Text*) current_desc;
6274
6275    ed->text.size_range_min = parse_int_range(0, 0, 255);
6276    ed->text.size_range_max = parse_int_range(1, 0, 255);
6277    if (ed->text.size_range_min > ed->text.size_range_max)
6278      {
6279         ERR("parse error %s:%i. min size is bigger than max size.",
6280             file_in, line - 1);
6281         exit(-1);
6282      }
6283 }
6284
6285 /**
6286     @page edcref
6287
6288     @property
6289         fit
6290     @parameters
6291         [horizontal] [vertical]
6292     @effect
6293         When any of the parameters is set to 1 edje will resize the text for it
6294         to fit in it's container. Both are disabled by default.
6295     @endproperty
6296 */
6297 static void
6298 st_collections_group_parts_part_description_text_fit(void)
6299 {
6300    Edje_Part_Description_Text *ed;
6301
6302    check_arg_count(2);
6303
6304    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6305        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6306      {
6307         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6308             file_in, line - 1);
6309         exit(-1);
6310      }
6311
6312    ed = (Edje_Part_Description_Text*) current_desc;
6313
6314    ed->text.fit_x = parse_bool(0);
6315    ed->text.fit_y = parse_bool(1);
6316 }
6317
6318 /**
6319     @page edcref
6320
6321     @property
6322         min
6323     @parameters
6324         [horizontal] [vertical]
6325     @effect
6326         When any of the parameters is enabled (1) it forces the minimum size of
6327         the container to be equal to the minimum size of the text. The default
6328         value is "0 0".
6329     @endproperty
6330 */
6331 static void
6332 st_collections_group_parts_part_description_text_min(void)
6333 {
6334    Edje_Part_Description_Text *ed;
6335
6336    check_arg_count(2);
6337
6338    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6339        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6340      {
6341         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6342             file_in, line - 1);
6343         exit(-1);
6344      }
6345
6346    ed = (Edje_Part_Description_Text*)current_desc;
6347
6348    ed->text.min_x = parse_bool(0);
6349    ed->text.min_y = parse_bool(1);
6350 }
6351
6352 /**
6353     @page edcref
6354
6355     @property
6356         max
6357     @parameters
6358         [horizontal] [vertical]
6359     @effect
6360         When any of the parameters is enabled (1) it forces the maximum size of
6361         the container to be equal to the maximum size of the text. The default
6362         value is "0 0".
6363     @endproperty
6364 */
6365 static void
6366 st_collections_group_parts_part_description_text_max(void)
6367 {
6368    Edje_Part_Description_Text *ed;
6369
6370    check_arg_count(2);
6371
6372    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6373        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6374      {
6375         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6376             file_in, line - 1);
6377         exit(-1);
6378      }
6379
6380    ed = (Edje_Part_Description_Text*) current_desc;
6381
6382    ed->text.max_x = parse_bool(0);
6383    ed->text.max_y = parse_bool(1);
6384 }
6385
6386 /**
6387     @page edcref
6388
6389     @property
6390         align
6391     @parameters
6392         [horizontal] [vertical]
6393     @effect
6394         Change the position of the point of balance inside the container. The
6395         default value is 0.5 0.5.
6396     @endproperty
6397 */
6398 static void
6399 st_collections_group_parts_part_description_text_align(void)
6400 {
6401    Edje_Part_Description_Text *ed;
6402
6403    check_arg_count(2);
6404
6405    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6406        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6407      {
6408         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6409             file_in, line - 1);
6410         exit(-1);
6411      }
6412
6413    ed = (Edje_Part_Description_Text*) current_desc;
6414
6415    ed->text.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6416    ed->text.align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
6417 }
6418
6419 /**
6420     @page edcref
6421
6422     @property
6423         source
6424     @parameters
6425         [another TEXT part's name]
6426     @effect
6427         Causes the part to use the text properties (like font and size) of
6428         another part and update them as they change.
6429     @endproperty
6430 */
6431 static void
6432 st_collections_group_parts_part_description_text_source(void)
6433 {
6434    Edje_Part_Collection *pc;
6435    Edje_Part_Description_Text *ed;
6436
6437    check_arg_count(1);
6438
6439    pc = eina_list_data_get(eina_list_last(edje_collections));
6440
6441    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6442        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6443      {
6444         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6445             file_in, line - 1);
6446         exit(-1);
6447      }
6448
6449    ed = (Edje_Part_Description_Text*) current_desc;
6450
6451    {
6452       char *name;
6453
6454       name = parse_str(0);
6455       data_queue_part_lookup(pc, name, &(ed->text.id_source));
6456       free(name);
6457    }
6458 }
6459
6460 /**
6461     @page edcref
6462
6463     @property
6464         text_source
6465     @parameters
6466         [another TEXT part's name]
6467     @effect
6468         Causes the part to display the text content of another part and update
6469         them as they change.
6470     @endproperty
6471 */
6472 static void
6473 st_collections_group_parts_part_description_text_text_source(void)
6474 {
6475    Edje_Part_Collection *pc;
6476    Edje_Part_Description_Text *ed;
6477
6478    check_arg_count(1);
6479
6480    pc = eina_list_data_get(eina_list_last(edje_collections));
6481
6482    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6483        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6484      {
6485         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6486             file_in, line - 1);
6487         exit(-1);
6488      }
6489
6490    ed = (Edje_Part_Description_Text*) current_desc;
6491
6492    {
6493       char *name;
6494
6495       name = parse_str(0);
6496       data_queue_part_lookup(pc, name, &(ed->text.id_text_source));
6497       free(name);
6498    }
6499 }
6500
6501 /**
6502     @page edcref
6503
6504     @property
6505         ellipsis
6506     @parameters
6507         [point of balance]
6508     @effect
6509         Used to balance the text in a relative point from 0.0 to 1.0, this
6510         point is the last section of the string to be cut out in case of a
6511         resize that is smaller than the text itself. The default value is 0.0.
6512     @endproperty
6513 */
6514 static void
6515 st_collections_group_parts_part_description_text_elipsis(void)
6516 {
6517    Edje_Part_Description_Text *ed;
6518
6519    check_arg_count(1);
6520
6521    if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
6522        (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
6523      {
6524         ERR("parse error %s:%i. text attributes in non-TEXT part.",
6525             file_in, line - 1);
6526         exit(-1);
6527      }
6528
6529    ed = (Edje_Part_Description_Text*) current_desc;
6530
6531    ed->text.elipsis = parse_float_range(0, 0.0, 1.0);
6532 }
6533
6534
6535 /**
6536    @edcsection{description_box,Box state description sub blocks}
6537  */
6538
6539 /**
6540     @page edcref
6541
6542     @block
6543         box
6544     @context
6545         part {
6546             description {
6547                 ..
6548                 box {
6549                     layout: "vertical";
6550                     padding: 0 2;
6551                     align: 0.5 0.5;
6552                     min: 0 0;
6553                 }
6554                 ..
6555             }
6556         }
6557     @description
6558         A box block can contain other objects and display them in different
6559         layouts, any of the predefined set, or a custom one, set by the
6560         application.
6561     @endblock
6562
6563     @property
6564         layout
6565     @parameters
6566         [primary layout] [fallback layout]
6567     @effect
6568         Sets the layout for the box:
6569             @li horizontal (default)
6570             @li vertical
6571             @li horizontal_homogeneous
6572             @li vertical_homogeneous
6573             @li horizontal_max (homogeneous to the max sized child)
6574             @li vertical_max
6575             @li horizontal_flow
6576             @li vertical_flow
6577             @li stack
6578             @li some_other_custom_layout_set_by_the_application
6579         You could set a custom layout as fallback, it makes very
6580         very little sense though, and if that one fails, it will
6581         default to horizontal.
6582     @endproperty
6583
6584     @property
6585         align
6586     @parameters
6587         [horizontal] [vertical]
6588     @effect
6589         Change the position of the point of balance inside the container. The
6590         default value is 0.5 0.5.
6591     @endproperty
6592
6593     @property
6594         padding
6595     @parameters
6596         [horizontal] [vertical]
6597     @effect
6598         Sets the space between cells in pixels. Defaults to 0 0.
6599     @endproperty
6600
6601     @property
6602         min
6603     @parameters
6604         [horizontal] [vertical]
6605     @effect
6606         When any of the parameters is enabled (1) it forces the minimum size of
6607         the box to be equal to the minimum size of the items. The default
6608         value is "0 0".
6609     @endproperty
6610 */
6611 static void st_collections_group_parts_part_description_box_layout(void)
6612 {
6613    Edje_Part_Description_Box *ed;
6614
6615    check_min_arg_count(1);
6616
6617    if (current_part->type != EDJE_PART_TYPE_BOX)
6618      {
6619         ERR("parse error %s:%i. box attributes in non-BOX part.",
6620             file_in, line - 1);
6621         exit(-1);
6622      }
6623
6624    ed = (Edje_Part_Description_Box*) current_desc;
6625
6626    ed->box.layout = parse_str(0);
6627    if (is_param(1))
6628      ed->box.alt_layout = parse_str(1);
6629 }
6630
6631 static void st_collections_group_parts_part_description_box_align(void)
6632 {
6633    Edje_Part_Description_Box *ed;
6634
6635    check_arg_count(2);
6636
6637    if (current_part->type != EDJE_PART_TYPE_BOX)
6638      {
6639         ERR("parse error %s:%i. box attributes in non-BOX part.",
6640             file_in, line - 1);
6641         exit(-1);
6642      }
6643
6644    ed = (Edje_Part_Description_Box*) current_desc;
6645
6646    ed->box.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6647    ed->box.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
6648 }
6649
6650 static void st_collections_group_parts_part_description_box_padding(void)
6651 {
6652    Edje_Part_Description_Box *ed;
6653
6654    check_arg_count(2);
6655
6656    if (current_part->type != EDJE_PART_TYPE_BOX)
6657      {
6658         ERR("parse error %s:%i. box attributes in non-BOX part.",
6659             file_in, line - 1);
6660         exit(-1);
6661      }
6662
6663    ed = (Edje_Part_Description_Box*) current_desc;
6664
6665    ed->box.padding.x = parse_int_range(0, 0, 0x7fffffff);
6666    ed->box.padding.y = parse_int_range(1, 0, 0x7fffffff);
6667 }
6668
6669 static void
6670 st_collections_group_parts_part_description_box_min(void)
6671 {
6672    Edje_Part_Description_Box *ed;
6673
6674    check_arg_count(2);
6675
6676    if (current_part->type != EDJE_PART_TYPE_BOX)
6677      {
6678         ERR("parse error %s:%i. box attributes in non-BOX part.",
6679             file_in, line - 1);
6680         exit(-1);
6681      }
6682
6683    ed = (Edje_Part_Description_Box*) current_desc;
6684
6685    ed->box.min.h = parse_bool(0);
6686    ed->box.min.v = parse_bool(1);
6687 }
6688
6689
6690 /**
6691    @edcsection{description_table,Table state description sub blocks}
6692  */
6693
6694 /**
6695     @page edcref
6696
6697     @block
6698         table
6699     @context
6700         part {
6701             description {
6702                 ..
6703                 table {
6704                     homogeneous: TABLE;
6705                     padding: 0 2;
6706                     align: 0.5 0.5;
6707                     min: 0 0;
6708                 }
6709                 ..
6710             }
6711         }
6712     @description
6713         A table block can contain other objects packed in multiple columns
6714         and rows, and each item can span across more than one column and/or
6715         row.
6716     @endblock
6717
6718     @property
6719         homogeneous
6720     @parameters
6721         [homogeneous mode]
6722     @effect
6723         Sets the homogeneous mode for the table:
6724             @li NONE (default)
6725             @li TABLE
6726             @li ITEM
6727     @endproperty
6728
6729     @property
6730         align
6731     @parameters
6732         [horizontal] [vertical]
6733     @effect
6734         Change the position of the point of balance inside the container. The
6735         default value is 0.5 0.5.
6736     @endproperty
6737
6738     @property
6739         padding
6740     @parameters
6741         [horizontal] [vertical]
6742     @effect
6743         Sets the space between cells in pixels. Defaults to 0 0.
6744     @endproperty
6745
6746     @property
6747         min
6748     @parameters
6749         [horizontal] [vertical]
6750     @effect
6751         When any of the parameters is enabled (1) it forces the minimum size of
6752         the table to be equal to the minimum size of the items. The default
6753         value is "0 0".
6754     @endproperty
6755 */
6756 static void st_collections_group_parts_part_description_table_homogeneous(void)
6757 {
6758    Edje_Part_Description_Table *ed;
6759
6760    check_min_arg_count(1);
6761
6762    if (current_part->type != EDJE_PART_TYPE_TABLE)
6763      {
6764         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6765             file_in, line - 1);
6766         exit(-1);
6767      }
6768
6769    ed = (Edje_Part_Description_Table*) current_desc;
6770
6771    ed->table.homogeneous = parse_enum(0,
6772                                      "NONE", EDJE_OBJECT_TABLE_HOMOGENEOUS_NONE,
6773                                      "TABLE", EDJE_OBJECT_TABLE_HOMOGENEOUS_TABLE,
6774                                      "ITEM", EDJE_OBJECT_TABLE_HOMOGENEOUS_ITEM,
6775                                      NULL);
6776 }
6777
6778 static void st_collections_group_parts_part_description_table_align(void)
6779 {
6780    Edje_Part_Description_Table *ed;
6781
6782    check_arg_count(2);
6783
6784    if (current_part->type != EDJE_PART_TYPE_TABLE)
6785      {
6786         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6787             file_in, line - 1);
6788         exit(-1);
6789      }
6790
6791    ed = (Edje_Part_Description_Table*) current_desc;
6792
6793    ed->table.align.x = FROM_DOUBLE(parse_float_range(0, -1.0, 1.0));
6794    ed->table.align.y = FROM_DOUBLE(parse_float_range(1, -1.0, 1.0));
6795 }
6796
6797 static void st_collections_group_parts_part_description_table_padding(void)
6798 {
6799    Edje_Part_Description_Table *ed;
6800
6801    check_arg_count(2);
6802
6803    if (current_part->type != EDJE_PART_TYPE_TABLE)
6804      {
6805         ERR("parse error %s:%i. table attributes in non-TABLE part.",
6806             file_in, line - 1);
6807         exit(-1);
6808      }
6809
6810    ed = (Edje_Part_Description_Table*) current_desc;
6811
6812    ed->table.padding.x = parse_int_range(0, 0, 0x7fffffff);
6813    ed->table.padding.y = parse_int_range(1, 0, 0x7fffffff);
6814 }
6815
6816 static void
6817 st_collections_group_parts_part_description_table_min(void)
6818 {
6819    Edje_Part_Description_Table *ed;
6820
6821    check_arg_count(2);
6822
6823    if (current_part->type != EDJE_PART_TYPE_TABLE)
6824      {
6825         ERR("parse error %s:%i. box attributes in non-TABLE part.",
6826             file_in, line - 1);
6827         exit(-1);
6828      }
6829
6830    ed = (Edje_Part_Description_Table*) current_desc;
6831
6832    ed->table.min.h = parse_bool(0);
6833    ed->table.min.v = parse_bool(1);
6834 }
6835
6836 /**
6837    @edcsection{description_map,Map state description sub blocks}
6838  */
6839
6840 /**
6841     @page edcref
6842     @block
6843         map
6844     @context
6845     description {
6846         ..
6847         map {
6848             perspective: "name";
6849             light: "name";
6850             on: 1;
6851             smooth: 1;
6852             perspective_on: 1;
6853             backface_cull: 1;
6854             alpha: 1;
6855             
6856             rotation {
6857                 ..
6858             }
6859         }
6860         ..
6861     }
6862     
6863     @description
6864     @endblock
6865     
6866     @property
6867         perspective
6868     @parameters
6869         [another part's name]
6870     @effect
6871         This sets the part that is used as the "perspective point" for giving
6872         a part a "3d look". The perspective point should have a perspective
6873         section that provides zplane and focal properties. The center of this
6874         part will be used as the focal point, so size, color and visibility
6875         etc. are not relevant just center point, zplane and focal are used.
6876         This also implicitly enables perspective transforms (see the on
6877         parameter for the map section).
6878     @endproperty
6879 */
6880 static void
6881 st_collections_group_parts_part_description_map_perspective(void)
6882 {
6883    Edje_Part_Collection *pc;
6884
6885    check_arg_count(1);
6886
6887    pc = eina_list_data_get(eina_list_last(edje_collections));
6888
6889    {
6890       char *name;
6891
6892       name = parse_str(0);
6893       data_queue_part_lookup(pc, name, &(current_desc->map.id_persp));
6894       free(name);
6895    }
6896
6897    current_desc->map.persp_on = 1;
6898 }
6899
6900 /**
6901     @page edcref
6902     @property
6903         light
6904     @parameters
6905         [another part's name]
6906     @effect
6907         This sets the part that is used as the "light" for calculating the
6908         brightness (based on how directly the part's surface is facing the
6909         light source point). Like the perspective point part, the center point
6910         is used and zplane is used for the z position (0 being the zero-plane
6911         where all 2D objects normally live) and positive values being further
6912         away into the distance. The light part color is used as the light
6913         color (alpha not used for light color). The color2 color is used for
6914         the ambient lighting when calculating brightness (alpha also not
6915         used).
6916     @endproperty
6917 */
6918 static void
6919 st_collections_group_parts_part_description_map_light(void)
6920 {
6921    Edje_Part_Collection *pc;
6922
6923    check_arg_count(1);
6924
6925    pc = eina_list_data_get(eina_list_last(edje_collections));
6926
6927    {
6928       char *name;
6929
6930       name = parse_str(0);
6931       data_queue_part_lookup(pc, name, &(current_desc->map.id_light));
6932       free(name);
6933    }
6934 }
6935
6936 /**
6937     @page edcref
6938     @property
6939         on
6940     @parameters
6941         [1 or 0]
6942     @effect
6943         This enables mapping for the part. Default is 0.
6944     @endproperty
6945 */
6946 static void
6947 st_collections_group_parts_part_description_map_on(void)
6948 {
6949    check_arg_count(1);
6950
6951    current_desc->map.on = parse_bool(0);
6952 }
6953
6954 /**
6955     @page edcref
6956     @property
6957         smooth
6958     @parameters
6959         [1 or 0]
6960     @effect
6961         This enable smooth map rendering. This may be linear interpolation,
6962         anisotropic filtering or anything the engine decides is "smooth".
6963         This is a best-effort hint and may not produce precisely the same
6964         results in all engines and situations. Default is 1
6965     @endproperty
6966 */
6967 static void
6968 st_collections_group_parts_part_description_map_smooth(void)
6969 {
6970    check_arg_count(1);
6971
6972    current_desc->map.smooth = parse_bool(0);
6973 }
6974
6975 /**
6976     @page edcref
6977     @property
6978         alpha
6979     @parameters
6980         [1 or 0]
6981     @effect
6982         This enable alpha channel when map rendering. Default is 1.
6983     @endproperty
6984 */
6985 static void
6986 st_collections_group_parts_part_description_map_alpha(void)
6987 {
6988    check_arg_count(1);
6989
6990    current_desc->map.alpha = parse_bool(0);
6991 }
6992
6993 /**
6994     @page edcref
6995     @property
6996         backface_cull
6997     @parameters
6998         [1 or 0]
6999     @effect
7000         This enables backface culling (when the rotated part that normally
7001         faces the camera is facing away after being rotated etc.). This means
7002         that the object will be hidden when "backface culled".
7003     @endproperty
7004 */
7005 static void
7006 st_collections_group_parts_part_description_map_backface_cull(void)
7007 {
7008    check_arg_count(1);
7009
7010    current_desc->map.backcull = parse_bool(0);
7011 }
7012
7013 /**
7014     @page edcref
7015     @property
7016         perspective_on
7017     @parameters
7018        [1 or 0]
7019     @effect
7020         Enable perspective when rotating even without a perspective point object.
7021         This would use perspective set for the object itself or for the
7022         canvas as a whole as the global perspective with 
7023         edje_perspective_set() and edje_perspective_global_set().
7024     @endproperty
7025 */
7026 static void
7027 st_collections_group_parts_part_description_map_perspective_on(void)
7028 {
7029    check_arg_count(1);
7030
7031    current_desc->map.persp_on = parse_bool(0);
7032 }
7033 /**
7034     @page edcref
7035     @block
7036         rotation
7037     @context
7038     map {
7039         ..
7040         rotation {
7041             center: "name";
7042             x: 45.0;
7043             y: 45.0;
7044             z: 45.0;
7045         }
7046         ..
7047     }
7048     @description
7049         Rotates the part, optionally with the center on another part.
7050     @endblock
7051     
7052     @property
7053         center
7054     @parameters
7055         [another part's name]
7056     @effect
7057         This sets the part that is used as the center of rotation when
7058         rotating the part with this description. The part's center point
7059         is used as the rotation center when applying rotation around the
7060         x, y and z axes. If no center is given, the parts original center
7061         itself is used for the rotation center.
7062     @endproperty
7063 */
7064 static void
7065 st_collections_group_parts_part_description_map_rotation_center(void)
7066 {
7067    Edje_Part_Collection *pc;
7068
7069    check_arg_count(1);
7070
7071    pc = eina_list_data_get(eina_list_last(edje_collections));
7072
7073    {
7074       char *name;
7075
7076       name = parse_str(0);
7077       data_queue_part_lookup(pc, name, &(current_desc->map.rot.id_center));
7078       free(name);
7079    }
7080 }
7081
7082 /**
7083     @page edcref
7084     @property
7085         x
7086     @parameters
7087         [X degrees]
7088     @effect
7089         This sets the rotation around the x axis of the part considering
7090         the center set. In degrees.
7091     @endproperty
7092 */
7093 static void
7094 st_collections_group_parts_part_description_map_rotation_x(void)
7095 {
7096    check_arg_count(1);
7097
7098    current_desc->map.rot.x = FROM_DOUBLE(parse_float(0));
7099 }
7100
7101 /**
7102     @page edcref
7103     @property
7104         y
7105     @parameters
7106         [Y degrees]
7107     @effect
7108         This sets the rotation around the y axis of the part considering
7109         the center set. In degrees.
7110     @endproperty
7111 */
7112 static void
7113 st_collections_group_parts_part_description_map_rotation_y(void)
7114 {
7115    check_arg_count(1);
7116
7117    current_desc->map.rot.y = FROM_DOUBLE(parse_float(0));
7118 }
7119
7120 /**
7121     @page edcref
7122     @property
7123         z
7124     @parameters
7125         [Z degrees]
7126     @effect
7127         This sets the rotation around the z axis of the part considering
7128         the center set. In degrees.
7129     @endproperty
7130 */
7131 static void
7132 st_collections_group_parts_part_description_map_rotation_z(void)
7133 {
7134    check_arg_count(1);
7135
7136    current_desc->map.rot.z = FROM_DOUBLE(parse_float(0));
7137 }
7138
7139 /**
7140     @page edcref
7141     @block
7142         perspective
7143     @context
7144     description {
7145         ..
7146         perspective {
7147             zplane: 0;
7148             focal: 1000;
7149         }
7150         ..
7151     }
7152     @description
7153         Adds focal and plane perspective to the part. Active if perspective_on is true.
7154         Must be provided if the part is being used by other part as it's perspective target.
7155     @endblock
7156     
7157     @property
7158         zplane
7159     @parameters
7160         [unscaled Z value]
7161     @effect
7162         This sets the z value that will not be scaled. Normally this is 0 as
7163         that is the z distance that all objects are at normally.
7164     @endproperty
7165 */
7166 static void
7167 st_collections_group_parts_part_description_perspective_zplane(void)
7168 {
7169    check_arg_count(1);
7170
7171    current_desc->persp.zplane = parse_int(0);
7172 }
7173
7174
7175 /**
7176     @page edcref
7177     @property
7178         focal
7179     @parameters
7180         [distance]
7181     @effect
7182         This sets the distance from the focal z plane (zplane) and the
7183         camera - i.e. very much equating to focal length of the camera
7184     @endproperty
7185 */
7186 static void
7187 st_collections_group_parts_part_description_perspective_focal(void)
7188 {
7189    check_arg_count(1);
7190
7191    current_desc->persp.focal = parse_int_range(0, 1, 0x7fffffff);
7192 }
7193
7194
7195 /**
7196    @edcsection{description_params,Params state description sub blocks}
7197  */
7198
7199 /**
7200     @page edcref
7201     @block
7202         params
7203     @context
7204     description {
7205         ..
7206         params {
7207             int: "name" 0;
7208             double: "other_name" 0.0;
7209             string: "another_name" "some text";
7210             bool: "name" 1;
7211             choice: "some_name" "value";
7212         }
7213         ..
7214     }
7215     @description
7216         Set parameters for EXTERNAL parts. The value overwrites previous
7217         definitions with the same name.
7218     @endblock
7219 */
7220 static void
7221 _st_collections_group_parts_part_description_params(Edje_External_Param_Type type)
7222 {
7223    Edje_Part_Description_External *ed;
7224    Edje_External_Param *param;
7225    Eina_List *l;
7226    const char *name;
7227    int found = 0;
7228
7229    check_arg_count(2);
7230
7231    if (current_part->type != EDJE_PART_TYPE_EXTERNAL)
7232      {
7233         ERR("parse error %s:%i. params in non-EXTERNAL part.",
7234             file_in, line - 1);
7235         exit(-1);
7236      }
7237
7238    ed = (Edje_Part_Description_External*) current_desc;
7239
7240    name = parse_str(0);
7241
7242    /* if a param with this name already exists, overwrite it */
7243    EINA_LIST_FOREACH(ed->external_params, l, param)
7244      {
7245         if (!strcmp(param->name, name))
7246           {
7247              found = 1;
7248              break;
7249           }
7250      }
7251
7252    if (!found)
7253      {
7254         param = mem_alloc(SZ(Edje_External_Param));
7255         param->name = name;
7256      }
7257
7258    param->type = type;
7259    param->i = 0;
7260    param->d = 0;
7261    param->s = NULL;
7262
7263    switch (type)
7264      {
7265       case EDJE_EXTERNAL_PARAM_TYPE_BOOL:
7266       case EDJE_EXTERNAL_PARAM_TYPE_INT:
7267          param->i = parse_int(1);
7268          break;
7269       case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE:
7270          param->d = parse_float(1);
7271          break;
7272       case EDJE_EXTERNAL_PARAM_TYPE_CHOICE:
7273       case EDJE_EXTERNAL_PARAM_TYPE_STRING:
7274          param->s = parse_str(1);
7275          break;
7276       default:
7277          ERR("parse error %s:%i. Invalid param type.",
7278              file_in, line - 1);
7279          break;
7280      }
7281
7282    if (!found)
7283      ed->external_params = eina_list_append(ed->external_params, param);
7284 }
7285
7286 /**
7287     @page edcref
7288     @property
7289         int
7290     @parameters
7291         [param_name] [int_value]
7292     @effect
7293         Adds an integer parameter for an external object
7294     @endproperty
7295 */
7296 static void
7297 st_collections_group_parts_part_description_params_int(void)
7298 {
7299    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_INT);
7300 }
7301
7302 /**
7303     @page edcref
7304     @property
7305         double
7306     @parameters
7307         [param_name] [double_value]
7308     @effect
7309         Adds a double parameter for an external object
7310     @endproperty
7311 */
7312 static void
7313 st_collections_group_parts_part_description_params_double(void)
7314 {
7315    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_DOUBLE);
7316 }
7317
7318 /**
7319     @page edcref
7320     @property
7321         string
7322     @parameters
7323         [param_name] [string_value]
7324     @effect
7325         Adds a string parameter for an external object
7326     @endproperty
7327 */
7328 static void
7329 st_collections_group_parts_part_description_params_string(void)
7330 {
7331    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_STRING);
7332 }
7333
7334 /**
7335     @page edcref
7336     @property
7337         bool
7338     @parameters
7339         [param_name] [bool_value]
7340     @effect
7341         Adds an boolean parameter for an external object. Value must be 0 or 1.
7342     @endproperty
7343 */
7344 static void
7345 st_collections_group_parts_part_description_params_bool(void)
7346 {
7347    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_BOOL);
7348 }
7349
7350 /**
7351     @page edcref
7352     @property
7353         choice
7354     @parameters
7355         [param_name] [choice_string]
7356     @effect
7357         Adds a choice parameter for an external object. The possible
7358         choice values are defined by external type at their register time
7359         and will be validated at runtime.
7360     @endproperty
7361 */
7362 static void
7363 st_collections_group_parts_part_description_params_choice(void)
7364 {
7365    _st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_CHOICE);
7366 }
7367
7368
7369 /**
7370    @edcsection{program, Program block}
7371  */
7372
7373 /**
7374     @page edcref
7375     @block
7376         program
7377     @context
7378         group {
7379             programs {
7380                ..
7381                   program {
7382                      name: "programname";
7383                      signal: "signalname";
7384                      source: "partname";
7385                      filter: "partname" "statename";
7386                      in: 0.3 0.0;
7387                      action: STATE_SET "statename" state_value;
7388                      transition: LINEAR 0.5;
7389                      target: "partname";
7390                      target: "anotherpart";
7391                      after: "programname";
7392                      after: "anotherprogram";
7393                   }
7394                ..
7395             }
7396         }
7397     @description
7398         Programs define how your interface reacts to events.
7399         Programs can change the state of parts, react to events or trigger
7400         other events.
7401     @endblock
7402 */
7403 static void
7404 ob_collections_group_programs_program(void)
7405 {
7406    Edje_Part_Collection *pc;
7407    Edje_Program *ep;
7408    Edje_Program_Parser *epp;
7409
7410    pc = eina_list_data_get(eina_list_last(edje_collections));
7411
7412    ep = mem_alloc(SZ(Edje_Program_Parser));
7413    ep->id = -1;
7414    ep->tween.mode = EDJE_TWEEN_MODE_LINEAR;
7415    ep->after = NULL;
7416    epp = (Edje_Program_Parser *)ep;
7417    epp->can_override = EINA_FALSE;
7418
7419    _edje_program_insert(pc, ep);
7420
7421    current_program = ep;
7422 }
7423
7424 /**
7425     @page edcref
7426     @property
7427         name
7428     @parameters
7429         [program name]
7430     @effect
7431         Symbolic name of program as a unique identifier.
7432     @endproperty
7433 */
7434 static void
7435 st_collections_group_programs_program_name(void)
7436 {
7437    Edje_Part_Collection *pc;
7438
7439    check_arg_count(1);
7440
7441    pc = eina_list_data_get(eina_list_last(edje_collections));
7442    current_program->name = parse_str(0);
7443
7444    _edje_program_check(current_program->name, current_program, pc->programs.fnmatch, pc->programs.fnmatch_count);
7445    _edje_program_check(current_program->name, current_program, pc->programs.strcmp, pc->programs.strcmp_count);
7446    _edje_program_check(current_program->name, current_program, pc->programs.strncmp, pc->programs.strncmp_count);
7447    _edje_program_check(current_program->name, current_program, pc->programs.strrncmp, pc->programs.strrncmp_count);
7448    _edje_program_check(current_program->name, current_program, pc->programs.nocmp, pc->programs.nocmp_count);
7449 }
7450
7451 /**
7452     @page edcref
7453     @property
7454         signal
7455     @parameters
7456         [signal name]
7457     @effect
7458         Specifies signal(s) that should cause the program to run. The signal
7459         received must match the specified source to run.
7460         Signals may be globbed, but only one signal keyword per program
7461         may be used. ex: signal: "mouse,clicked,*"; (clicking any mouse button
7462         that matches source starts program).
7463     @endproperty
7464 */
7465 static void
7466 st_collections_group_programs_program_signal(void)
7467 {
7468    Edje_Part_Collection *pc;
7469
7470    check_arg_count(1);
7471
7472    pc = eina_list_data_get(eina_list_last(edje_collections));
7473
7474    _edje_program_remove(pc, current_program);
7475    current_program->signal = parse_str(0);
7476    _edje_program_insert(pc, current_program);
7477 }
7478
7479 /**
7480     @page edcref
7481     @property
7482         source
7483     @parameters
7484         [source name]
7485     @effect
7486         Source of accepted signal. Sources may be globbed, but only one source
7487         keyword per program may be used. ex:source: "button-*"; (Signals from
7488         any part or program named "button-*" are accepted).
7489     @endproperty
7490 */
7491 static void
7492 st_collections_group_programs_program_source(void)
7493 {
7494    Edje_Part_Collection *pc;
7495
7496    check_arg_count(1);
7497
7498    pc = eina_list_data_get(eina_list_last(edje_collections));
7499
7500    _edje_program_remove(pc, current_program);
7501    current_program->source = parse_str(0);
7502    _edje_program_insert(pc, current_program);
7503 }
7504
7505 /**
7506     @page edcref
7507     @property
7508         filter
7509     @parameters
7510         [part] [state]
7511     @effect
7512         Filter signals to be only accepted if the part [part] is in state named [state].
7513         Only one filter per program can be used. If [state] is not given, the source of
7514         the event will be used instead.
7515     @endproperty
7516 */
7517 static void
7518 st_collections_group_programs_program_filter(void)
7519 {
7520    check_min_arg_count(1);
7521
7522    if(is_param(1)) {
7523            current_program->filter.part = parse_str(0);
7524            current_program->filter.state = parse_str(1);
7525    } else {
7526            current_program->filter.state = parse_str(0);
7527    }
7528 }
7529
7530 /**
7531     @page edcref
7532     @property
7533         in
7534     @parameters
7535         [from] [range]
7536     @effect
7537         Wait 'from' seconds before executing the program. And add a random
7538         number of seconds (from 0 to 'range') to the total waiting time.
7539     @endproperty
7540 */
7541 static void
7542 st_collections_group_programs_program_in(void)
7543 {
7544    check_arg_count(2);
7545
7546    current_program->in.from = parse_float_range(0, 0.0, 999999999.0);
7547    current_program->in.range = parse_float_range(1, 0.0, 999999999.0);
7548 }
7549
7550 /**
7551     @page edcref
7552     @property
7553         action
7554     @parameters
7555         [type] [param1] [param2]
7556     @effect
7557         Action to be performed by the program. Valid actions are: STATE_SET,
7558         ACTION_STOP, SIGNAL_EMIT, DRAG_VAL_SET, DRAG_VAL_STEP, DRAG_VAL_PAGE,
7559         FOCUS_SET, PARAM_COPY, PARAM_SET, PLAY_SAMPLE, PLAY_TONE
7560         Only one action can be specified per program. Examples:\n
7561            action: STATE_SET "statename" 0.5;\n
7562            action: ACTION_STOP;\n
7563            action: SIGNAL_EMIT "signalname" "emitter";\n
7564            action: DRAG_VAL_SET 0.5 0.0;\n
7565            action: DRAG_VAL_STEP 1.0 0.0;\n
7566            action: DRAG_VAL_PAGE 0.0 0.0;\n
7567            action: FOCUS_SET;\n
7568            action: FOCUS_OBJECT;\n
7569            action: PARAM_COPY "src_part" "src_param" "dst_part" "dst_param";\n
7570            action: PARAM_SET "part" "param" "value";\n
7571            action: PLAY_SAMPLE "sample name";\n
7572            action: PLAY_TONE "tone name" duration in seconds ( Range 0.1 to 10.0 );\n
7573     @endproperty
7574 */
7575 static void
7576 st_collections_group_programs_program_action(void)
7577 {
7578    Edje_Part_Collection *pc;
7579    Edje_Program *ep;
7580    int i;
7581    
7582    pc = eina_list_data_get(eina_list_last(edje_collections));
7583    ep = current_program;
7584    ep->action = parse_enum(0,
7585                            "STATE_SET", EDJE_ACTION_TYPE_STATE_SET,
7586                            "ACTION_STOP", EDJE_ACTION_TYPE_ACTION_STOP,
7587                            "SIGNAL_EMIT", EDJE_ACTION_TYPE_SIGNAL_EMIT,
7588                            "DRAG_VAL_SET", EDJE_ACTION_TYPE_DRAG_VAL_SET,
7589                            "DRAG_VAL_STEP", EDJE_ACTION_TYPE_DRAG_VAL_STEP,
7590                            "DRAG_VAL_PAGE", EDJE_ACTION_TYPE_DRAG_VAL_PAGE,
7591                            "SCRIPT", EDJE_ACTION_TYPE_SCRIPT,
7592                            "FOCUS_SET", EDJE_ACTION_TYPE_FOCUS_SET,
7593                            "FOCUS_OBJECT", EDJE_ACTION_TYPE_FOCUS_OBJECT,
7594                            "PARAM_COPY", EDJE_ACTION_TYPE_PARAM_COPY,
7595                            "PARAM_SET", EDJE_ACTION_TYPE_PARAM_SET,
7596                            "PLAY_SAMPLE", EDJE_ACTION_TYPE_SOUND_SAMPLE,
7597                            "PLAY_TONE", EDJE_ACTION_TYPE_SOUND_TONE,
7598                            NULL);
7599    if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
7600      {
7601         ep->state = parse_str(1);
7602         if (get_arg_count() == 1)
7603           ep->value = 0.0;
7604         else
7605           ep->value = parse_float_range(2, 0.0, 1.0);
7606      }
7607    else if (ep->action == EDJE_ACTION_TYPE_SIGNAL_EMIT)
7608      {
7609         ep->state = parse_str(1);
7610         ep->state2 = parse_str(2);
7611      }
7612    else if (ep->action == EDJE_ACTION_TYPE_SOUND_SAMPLE)
7613      {
7614         ep->sample_name = parse_str(1);
7615         for (i = 0; i < (int)edje_file->sound_dir->samples_count; i++)
7616           {
7617              if (!strcmp(edje_file->sound_dir->samples[i].name, ep->sample_name))
7618                break;
7619              if (i == (int)(edje_file->sound_dir->samples_count - 1))
7620                {
7621                   ERR("No Sample name %s exist.", ep->sample_name);
7622                   exit(-1);
7623                }
7624           }
7625         ep->speed = parse_float_range(2, 0.0, 10.0);
7626      }
7627    else if (ep->action == EDJE_ACTION_TYPE_SOUND_TONE)
7628      {
7629         ep->tone_name = parse_str(1);
7630         for (i = 0; i < (int)edje_file->sound_dir->tones_count; i++)
7631           {
7632              if (!strcmp(edje_file->sound_dir->tones[i].name, ep->tone_name))
7633                break;
7634              if (i == (int)(edje_file->sound_dir->tones_count - 1))
7635                {
7636                   ERR("No Tone name %s exist.", ep->tone_name);
7637                   exit(-1);
7638                }
7639           }
7640         ep->duration = parse_float_range(2, 0.1, 10.0);
7641      }
7642    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
7643      {
7644         ep->value = parse_float(1);
7645         ep->value2 = parse_float(2);
7646      }
7647    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
7648      {
7649         ep->value = parse_float(1);
7650         ep->value2 = parse_float(2);
7651      }
7652    else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
7653      {
7654         ep->value = parse_float(1);
7655         ep->value2 = parse_float(2);
7656      }
7657    else if (ep->action == EDJE_ACTION_TYPE_PARAM_COPY)
7658      {
7659         char *src_part, *dst_part;
7660         
7661         src_part = parse_str(1);
7662         ep->state = parse_str(2);
7663         dst_part = parse_str(3);
7664         ep->state2 = parse_str(4);
7665         
7666         data_queue_part_lookup(pc, src_part, &(ep->param.src));
7667         data_queue_part_lookup(pc, dst_part, &(ep->param.dst));
7668         
7669         free(src_part);
7670         free(dst_part);
7671      }
7672    else if (ep->action == EDJE_ACTION_TYPE_PARAM_SET)
7673      {
7674         char *part;
7675         
7676         part = parse_str(1);
7677         ep->state = parse_str(2);
7678         ep->state2 = parse_str(3);
7679         
7680         data_queue_part_lookup(pc, part, &(ep->param.dst));
7681         free(part);
7682      }
7683    
7684    switch (ep->action)
7685      {
7686       case EDJE_ACTION_TYPE_ACTION_STOP:
7687         check_arg_count(1);
7688         break;
7689       case EDJE_ACTION_TYPE_SCRIPT:
7690         /* this is implicitly set by script {} so this is here just for
7691          * completeness */
7692         break;
7693       case EDJE_ACTION_TYPE_FOCUS_OBJECT:
7694       case EDJE_ACTION_TYPE_FOCUS_SET:
7695         check_arg_count(1);
7696         break;
7697       case EDJE_ACTION_TYPE_PARAM_COPY:
7698         check_arg_count(5);
7699         break;
7700       case EDJE_ACTION_TYPE_PARAM_SET:
7701         check_arg_count(4);
7702         break;
7703       case EDJE_ACTION_TYPE_SOUND_SAMPLE:
7704         check_arg_count(3);
7705         break;
7706       case EDJE_ACTION_TYPE_SOUND_TONE:
7707         check_arg_count(3);
7708         break;
7709       default:
7710         check_arg_count(3);
7711      }
7712 }
7713
7714 /**
7715     @page edcref
7716     @property
7717         transition
7718     @parameters
7719         [type] [length] [[interp val 1]] [[interp val 2]] [[option]]
7720     @effect
7721         Defines how transitions occur using STATE_SET action.\n
7722         Where 'type' is the style of the transition and 'length' is a double
7723         specifying the number of seconds in which to preform the transition.\n
7724         Valid types are: LIN or LINEAR, SIN or SINUSOIDAL, 
7725         ACCEL or ACCELERATE, DECEL or DECELERATE, 
7726         ACCEL_FAC or ACCELERATE_FACTOR, DECEL_FAC or DECELERATE_FACTOR,
7727         SIN_FAC or SINUSOIDAL_FACTOR, DIVIS or DIVISOR_INTERP,
7728         BOUNCE, SPRING.
7729         
7730         ACCEL_FAC, DECEL_FAC and SIN_FAC need the extra optional
7731         "interp val 1" to determine the "factor" of curviness. 1.0 is the same
7732         as their non-factor counterparts, where 0.0 is equal to linear.
7733         Numbers higher than one make the curve angles steeper with a more
7734         pronounced curve point.
7735         
7736         DIVIS, BOUNCE and SPRING also require "interp val 2" in addition
7737         to "interp val 1".
7738         
7739         DIVIS uses val 1 as the initial gradient start
7740         (0.0 is horizontal, 1.0 is diagonal (linear), 2.0 is twice the
7741         gradient of linear etc.). val 2 is interpreted as an integer factor
7742         defining how much the value swings "outside" the gradient only to come
7743         back to the final resting spot at the end. 0.0 for val 2 is equivalent
7744         to linear interpolation. Note that DIVIS can exceed 1.0
7745         
7746         BOUNCE uses val 2 as the number of bounces (so its rounded down to
7747         the nearest integer value), with val 1 determining how much the
7748         bounce decays, with 0.0 giving linear decay per bounce, and higher
7749         values giving much more decay.
7750
7751         SPRING is similar to bounce, where val 2 specifies the number of
7752         spring "swings" and val 1 specifies the decay, but it can exceed 1.0
7753         on the outer swings.
7754
7755         Valid option is CURRENT.
7756
7757         CURRENT is the option which causes the edje object to move from its current position.
7758         It can be used as the last parameter of any transition type. (@since 1.1.0)
7759
7760     @endproperty
7761 */
7762 static void
7763 st_collections_group_programs_program_transition(void)
7764 {
7765    check_min_arg_count(2);
7766
7767    current_program->tween.mode = parse_enum(0,
7768                                             // short names
7769                                             "LIN", EDJE_TWEEN_MODE_LINEAR,
7770                                             "SIN", EDJE_TWEEN_MODE_SINUSOIDAL,
7771                                             "ACCEL", EDJE_TWEEN_MODE_ACCELERATE,
7772                                             "DECEL", EDJE_TWEEN_MODE_DECELERATE,
7773                                             "ACCEL_FAC", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
7774                                             "DECEL_FAC", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
7775                                             "SIN_FAC", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
7776                                             "DIVIS", EDJE_TWEEN_MODE_DIVISOR_INTERP,
7777                                             
7778                                             // long/full names
7779                                             "LINEAR", EDJE_TWEEN_MODE_LINEAR,
7780                                             "SINUSOIDAL", EDJE_TWEEN_MODE_SINUSOIDAL,
7781                                             "ACCELERATE", EDJE_TWEEN_MODE_ACCELERATE,
7782                                             "DECELERATE", EDJE_TWEEN_MODE_DECELERATE,
7783                                             "ACCELERATE_FACTOR", EDJE_TWEEN_MODE_ACCELERATE_FACTOR,
7784                                             "DECELERATE_FACTOR", EDJE_TWEEN_MODE_DECELERATE_FACTOR,
7785                                             "SINUSOIDAL_FACTOR", EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR,
7786                                             "DIVISOR_INTERP", EDJE_TWEEN_MODE_DIVISOR_INTERP,
7787                                             
7788                                             // long/full is short enough
7789                                             "BOUNCE", EDJE_TWEEN_MODE_BOUNCE,
7790                                             "SPRING", EDJE_TWEEN_MODE_SPRING,
7791                                             NULL);
7792    current_program->tween.time = FROM_DOUBLE(parse_float_range(1, 0.0, 999999999.0));
7793    if ((current_program->tween.mode >= EDJE_TWEEN_MODE_LINEAR) &&
7794        (current_program->tween.mode <= EDJE_TWEEN_MODE_DECELERATE))
7795      {
7796         if ((get_arg_count() == 3) && (!strcmp(parse_str(2), "CURRENT")))
7797           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7798         else if (get_arg_count() != 2)
7799           {
7800              ERR("parse error %s:%i. Need 2rd parameter to set time",
7801                  file_in, line - 1);
7802              exit(-1);
7803           }
7804      }
7805    // the following need v1
7806    // EDJE_TWEEN_MODE_ACCELERATE_FACTOR
7807    // EDJE_TWEEN_MODE_DECELERATE_FACTOR
7808    // EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR
7809    // current_program->tween.v1
7810    else if ((current_program->tween.mode >= EDJE_TWEEN_MODE_ACCELERATE_FACTOR) &&
7811        (current_program->tween.mode <= EDJE_TWEEN_MODE_SINUSOIDAL_FACTOR))
7812      {
7813         if ((get_arg_count() == 4) && (!strcmp(parse_str(3), "CURRENT")))
7814           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7815         else if (get_arg_count() != 3)
7816           {
7817              ERR("parse error %s:%i. Need 3rd parameter to set factor",
7818                  file_in, line - 1);
7819              exit(-1);
7820           }
7821         current_program->tween.v1 = FROM_DOUBLE(parse_float_range(2, 0.0, 999999999.0));
7822      }
7823    // the followjng also need v2
7824    // EDJE_TWEEN_MODE_DIVISOR_INTERP
7825    // EDJE_TWEEN_MODE_BOUNCE
7826    // EDJE_TWEEN_MODE_SPRING
7827    // current_program->tween.v2
7828    else if ((current_program->tween.mode >= EDJE_TWEEN_MODE_DIVISOR_INTERP) &&
7829             (current_program->tween.mode <= EDJE_TWEEN_MODE_SPRING))
7830      {
7831         if ((get_arg_count() == 5) && (!strcmp(parse_str(4), "CURRENT")))
7832           current_program->tween.mode |= EDJE_TWEEN_MODE_OPT_FROM_CURRENT;
7833         else if (get_arg_count() != 4)
7834           {
7835              ERR("parse error %s:%i. "
7836                  "Need 3rd and 4th parameters to set factor and counts",
7837                  file_in, line - 1);
7838              exit(-1);
7839           }
7840         current_program->tween.v1 = FROM_DOUBLE(parse_float_range(2, 0.0, 999999999.0));
7841         current_program->tween.v2 = FROM_DOUBLE(parse_float_range(3, 0.0, 999999999.0));
7842      }
7843 }
7844
7845 /**
7846     @page edcref
7847     @property
7848         target
7849     @parameters
7850         [target]
7851     @effect
7852         Program or part on which the specified action acts. Multiple target
7853         keywords may be specified, one per target. SIGNAL_EMITs do not have
7854         targets.
7855     @endproperty
7856 */
7857 static void
7858 st_collections_group_programs_program_target(void)
7859 {
7860    Edje_Part_Collection *pc;
7861    Edje_Program *ep;
7862
7863    check_arg_count(1);
7864
7865    pc = eina_list_data_get(eina_list_last(edje_collections));
7866    ep = current_program;
7867      {
7868         Edje_Program_Target *et;
7869         Edje_Program_Target *etw;
7870         Eina_List *l;
7871         char *name;
7872         char *copy;
7873
7874         name = parse_str(0);
7875         
7876         EINA_LIST_FOREACH(ep->targets, l, etw)
7877           {
7878              if (!strcmp(name, (char*) (etw + 1)))
7879                {
7880                   free(name);
7881                   return;
7882                }
7883           }
7884
7885         et = mem_alloc(SZ(Edje_Program_Target) + strlen(name) + 1);
7886         ep->targets = eina_list_append(ep->targets, et);
7887         copy = (char*) (et + 1);
7888
7889         memcpy(copy, name, strlen(name) + 1);
7890
7891         if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
7892           data_queue_part_lookup(pc, name, &(et->id));
7893         else if (ep->action == EDJE_ACTION_TYPE_ACTION_STOP)
7894           data_queue_program_lookup(pc, name, &(et->id));
7895         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_SET)
7896           data_queue_part_lookup(pc, name, &(et->id));
7897         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_STEP)
7898           data_queue_part_lookup(pc, name, &(et->id));
7899         else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
7900           data_queue_part_lookup(pc, name, &(et->id));
7901         else if (ep->action == EDJE_ACTION_TYPE_FOCUS_SET)
7902           data_queue_part_lookup(pc, name, &(et->id));
7903         else if (ep->action == EDJE_ACTION_TYPE_FOCUS_OBJECT)
7904           data_queue_part_lookup(pc, name, &(et->id));
7905         else
7906           {
7907              ERR("parse error %s:%i. target may only be used after action",
7908                  file_in, line - 1);
7909              exit(-1);
7910           }
7911         free(name);
7912      }
7913 }
7914
7915 /**
7916     @page edcref
7917     @property
7918         after
7919     @parameters
7920         [after]
7921     @effect
7922         Specifies a program to run after the current program completes. The
7923         source and signal parameters of a program run as an "after" are ignored.
7924         Multiple "after" statements can be specified per program.
7925     @endproperty
7926 */
7927 static void
7928 st_collections_group_programs_program_after(void)
7929 {
7930    Edje_Part_Collection *pc;
7931    Edje_Program *ep;
7932
7933    check_arg_count(1);
7934
7935    pc = eina_list_data_get(eina_list_last(edje_collections));
7936    ep = current_program;
7937      {
7938         Edje_Program_After *pa;
7939         Edje_Program_After *pa2;
7940         Eina_List *l;
7941         char *name;
7942         char *copy;
7943
7944         name = parse_str(0);
7945
7946         EINA_LIST_FOREACH(ep->after, l, pa2)
7947           {
7948              if (!strcmp(name, (char*) (pa2 + 1)))
7949                {
7950                   free(name);
7951                   return;
7952                }
7953           }
7954
7955         pa = mem_alloc(SZ(Edje_Program_After) + strlen(name) + 1);
7956         pa->id = -1;
7957         ep->after = eina_list_append(ep->after, pa);
7958         copy = (char*)(pa + 1);
7959         memcpy(copy, name, strlen(name) + 1);
7960         data_queue_program_lookup(pc, name, &(pa->id));
7961         free(name);
7962      }
7963 }
7964
7965 /**
7966     @page edcref
7967     @property
7968         api
7969     @parameters
7970         [name] [description]
7971     @effect
7972         Specifies a hint to let applications (or IDE's) know how to bind
7973         things. The parameter name should contain the name of the function that
7974         the application should use, and description describes how it should
7975         be used.
7976     @endproperty
7977 */
7978 static void
7979 st_collections_group_programs_program_api(void)
7980 {
7981    check_min_arg_count(1);
7982
7983    current_program->api.name = parse_str(0);
7984
7985    if (is_param(1))
7986      {
7987        check_arg_count(2);
7988        current_program->api.description = parse_str(1);
7989      }
7990 }
7991
7992 static void
7993 st_collections_group_parts_part_api(void)
7994 {
7995    check_min_arg_count(1);
7996
7997    current_part->api.name = parse_str(0);
7998    if (is_param(1))
7999      {
8000        check_arg_count(2);
8001        current_part->api.description = parse_str(1);
8002      }
8003 }
8004
8005 static void
8006 ob_collections_group_programs_program_script(void)
8007 {
8008    Edje_Part_Collection *pc;
8009    Code *cd;
8010
8011    pc = eina_list_data_get(eina_list_last(edje_collections));
8012    cd = eina_list_data_get(eina_list_last(codes));
8013
8014    if (!is_verbatim()) track_verbatim(1);
8015    else
8016      {
8017         Eina_Bool empty = EINA_TRUE;
8018         char *s;
8019         int i, len;
8020
8021         s = get_verbatim();
8022         if (s)
8023           {
8024              Code_Program *cp;
8025
8026              /* FIXME: Need to store the script somewhere to be restored when using edje_edit API */
8027              cp = mem_alloc(SZ(Code_Program));
8028              cp->l1 = get_verbatim_line1();
8029              cp->l2 = get_verbatim_line2();
8030              cp->script = s;
8031              cp->original = strdup(s);
8032              if (cd->shared && cd->is_lua)
8033                {
8034                   ERR("parse error %s:%i. You're trying to mix Embryo and Lua scripting in the same group",
8035                       file_in, line - 1);
8036                   exit(-1);
8037                }
8038              cd->is_lua = 0;
8039
8040              len = strlen(cp->script);
8041              for (i = 0; i < len; i++)
8042                {
8043                   if (((cp->script[i] > 'a') && (cp->script[i] < 'z')) ||
8044                       ((cp->script[i] > 'A') && (cp->script[i] < 'Z')) ||
8045                       ((cp->script[i] > '0') && (cp->script[i] < '9')))
8046                     empty = EINA_FALSE;
8047                }
8048
8049              if (!empty)
8050                {
8051                   cd->programs = eina_list_append(cd->programs, cp);
8052                   data_queue_anonymous_lookup(pc, current_program, &(cp->id));
8053                   current_program->action = EDJE_ACTION_TYPE_SCRIPT;
8054                }
8055              else
8056                {
8057                   data_queue_anonymous_lookup(pc, current_program, NULL);
8058                   free(cp);
8059                   cp = NULL;
8060                }
8061
8062              set_verbatim(NULL, 0, 0);
8063           }
8064      }
8065 }
8066 /**
8067     @page edcref
8068     </table>
8069 */