summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/ecore_buffer/meson.build2
-rw-r--r--src/bin/ecore_evas/ecore_evas_convert.c4
-rw-r--r--src/bin/ecore_evas/eetpack.c4
-rw-r--r--src/bin/edje/edje_cc.c9
-rw-r--r--src/bin/edje/edje_cc.h6
-rw-r--r--src/bin/edje/edje_cc_handlers.c1869
-rw-r--r--src/bin/edje/edje_cc_out.c333
-rw-r--r--src/bin/edje/edje_cc_parse.c12
-rw-r--r--src/bin/edje/edje_external_inspector.c7
-rw-r--r--src/bin/edje/edje_multisense_convert.c1
-rw-r--r--src/bin/edje/edje_player.c230
-rw-r--r--src/bin/edje/meson.build14
-rw-r--r--src/bin/eet/eet_main.c22
-rw-r--r--src/bin/eeze/eeze_mount/eeze_mount.c2
-rw-r--r--src/bin/efl/efl_debug.c2
-rw-r--r--src/bin/efl/efl_debugd.c3
-rw-r--r--src/bin/efl_canvas_wl/efl_canvas_wl_test.c (renamed from src/bin/efl_wl/efl_wl_test.c)21
-rw-r--r--src/bin/efl_canvas_wl/efl_canvas_wl_test_stack.c (renamed from src/bin/efl_wl/efl_wl_test_stack.c)10
-rw-r--r--src/bin/efl_canvas_wl/meson.build13
-rw-r--r--src/bin/efl_wl/meson.build13
-rw-r--r--src/bin/efreet/efreet_icon_cache_create.c208
-rw-r--r--src/bin/efreet/efreetd.c10
-rw-r--r--src/bin/efreet/efreetd_cache.c35
-rw-r--r--src/bin/efreet/efreetd_ipc.c41
-rw-r--r--src/bin/efreet/meson.build3
-rw-r--r--src/bin/elementary/config.c166
-rw-r--r--src/bin/elementary/elm_prefs_cc_parse.c4
-rw-r--r--src/bin/elementary/meson.build37
-rw-r--r--src/bin/elementary/perf_test_01.c4
-rw-r--r--src/bin/elementary/perf_test_02.c4
-rw-r--r--src/bin/elementary/perf_test_03.c4
-rw-r--r--src/bin/elementary/perf_test_04.c4
-rw-r--r--src/bin/elementary/perf_test_05.c4
-rw-r--r--src/bin/elementary/perf_test_06.c4
-rw-r--r--src/bin/elementary/test.c33
-rw-r--r--src/bin/elementary/test_combobox.c40
-rw-r--r--src/bin/elementary/test_dnd.c6
-rw-r--r--src/bin/elementary/test_efl_anim_alpha.c4
-rw-r--r--src/bin/elementary/test_efl_anim_group_parallel.c8
-rw-r--r--src/bin/elementary/test_efl_anim_group_sequential.c8
-rw-r--r--src/bin/elementary/test_efl_anim_interpolator.c2
-rw-r--r--src/bin/elementary/test_efl_anim_pause.c4
-rw-r--r--src/bin/elementary/test_efl_anim_repeat.c4
-rw-r--r--src/bin/elementary/test_efl_anim_rotate.c12
-rw-r--r--src/bin/elementary/test_efl_anim_scale.c12
-rw-r--r--src/bin/elementary/test_efl_anim_start_delay.c4
-rw-r--r--src/bin/elementary/test_efl_anim_translate.c8
-rw-r--r--src/bin/elementary/test_efl_gfx_vg_value_provider.c298
-rw-r--r--src/bin/elementary/test_efl_ui_text.c15
-rw-r--r--src/bin/elementary/test_efl_ui_vg_animation.c (renamed from src/bin/elementary/test_efl_ui_animation_view.c)140
-rw-r--r--src/bin/elementary/test_factory.c2
-rw-r--r--src/bin/elementary/test_gengrid.c1
-rw-r--r--src/bin/elementary/test_genlist.c48
-rw-r--r--src/bin/elementary/test_gesture_framework.c176
-rw-r--r--src/bin/elementary/test_gesture_layer3.c6
-rw-r--r--src/bin/elementary/test_glview_manygears.c2
-rw-r--r--src/bin/elementary/test_icon_animated.c3
-rw-r--r--src/bin/elementary/test_label.c120
-rw-r--r--src/bin/elementary/test_map.c4
-rw-r--r--src/bin/elementary/test_naviframe.c43
-rw-r--r--src/bin/elementary/test_part_shadow.c24
-rw-r--r--src/bin/elementary/test_photocam.c9
-rw-r--r--src/bin/elementary/test_tooltip.c2
-rw-r--r--src/bin/elementary/test_ui_clock.c90
-rw-r--r--src/bin/elementary/test_ui_pager.c2
-rw-r--r--src/bin/elementary/test_ui_pager_scroll.c2
-rw-r--r--src/bin/elementary/test_ui_progressbar.c2
-rw-r--r--src/bin/elementary/test_ui_separator.c26
-rw-r--r--src/bin/elementary/test_ui_spotlight.c123
-rw-r--r--src/bin/elementary/test_ui_tab_pager.c24
-rw-r--r--src/bin/elementary/test_ui_textpath.c20
-rw-r--r--src/bin/elementary/test_ui_timepicker.c6
-rw-r--r--src/bin/elementary/test_win_state.c38
-rw-r--r--src/bin/elua/main.c9
-rw-r--r--src/bin/embryo/embryo_cc_sc1.c20
-rw-r--r--src/bin/embryo/embryo_cc_sc2.c12
-rw-r--r--src/bin/eolian/docs.c2
-rw-r--r--src/bin/eolian/headers.c16
-rw-r--r--src/bin/eolian/main.c13
-rw-r--r--src/bin/eolian/sources.c42
-rw-r--r--src/bin/eolian/types.c24
-rw-r--r--src/bin/eolian_mono/eolian/mono/async_function_definition.hh37
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh32
-rw-r--r--src/bin/eolian_mono/eolian/mono/documentation.hh288
-rw-r--r--src/bin/eolian_mono/eolian/mono/enum_definition.hh14
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh140
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_declaration.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh706
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_helpers.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh20
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh215
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh327
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh21
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh113
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh206
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh24
-rw-r--r--src/bin/eolian_mono/eolian/mono/property_definition.hh390
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh268
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_fields.hh127
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/utils.hh22
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc6
-rw-r--r--src/bin/ethumb_client/ethumbd.c11
-rw-r--r--src/bin/ethumb_client/ethumbd_client.c2
-rw-r--r--src/bin/ethumb_client/ethumbd_slave.c13
-rw-r--r--src/bin/exactness/.gitignore5
-rw-r--r--src/bin/exactness/common.c436
-rw-r--r--src/bin/exactness/common.h269
-rw-r--r--src/bin/exactness/exactness.c707
-rw-r--r--src/bin/exactness/exactness_play.in101
-rw-r--r--src/bin/exactness/exactness_record.in76
-rw-r--r--src/bin/exactness/injector.c393
-rw-r--r--src/bin/exactness/inspect.c1615
-rw-r--r--src/bin/exactness/meson.build66
-rw-r--r--src/bin/exactness/player.c1149
-rw-r--r--src/bin/exactness/player_entry.edc932
-rw-r--r--src/bin/exactness/recorder.c397
118 files changed, 9679 insertions, 4077 deletions
diff --git a/src/bin/ecore_buffer/meson.build b/src/bin/ecore_buffer/meson.build
index 5e1a9d9381..b2df51b4f7 100644
--- a/src/bin/ecore_buffer/meson.build
+++ b/src/bin/ecore_buffer/meson.build
@@ -1,6 +1,6 @@
executable('bqmgr',
['bq_mgr_protocol.c', 'bq_mgr.c'],
- dependencies: [ecore, ecore_buffer, ecore_buffer_deps],
+ dependencies: [ecore, ecore_buffer, ecore_buffer_deps, ecore_buffer_ext_deps],
install: true,
install_dir: join_paths(dir_lib, 'ecore_buffer', 'bin')
)
diff --git a/src/bin/ecore_evas/ecore_evas_convert.c b/src/bin/ecore_evas/ecore_evas_convert.c
index 8b4f19ab2f..cefc16cc84 100644
--- a/src/bin/ecore_evas/ecore_evas_convert.c
+++ b/src/bin/ecore_evas/ecore_evas_convert.c
@@ -128,7 +128,6 @@ main(int argc, char *argv[])
eina_init();
_log_dom = eina_log_domain_register(argv[0], EINA_COLOR_CYAN);
- ecore_init();
ecore_evas_init();
arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
@@ -211,7 +210,8 @@ main(int argc, char *argv[])
end:
if (flags) eina_strbuf_free(flags);
ecore_evas_shutdown();
- ecore_shutdown();
+ eina_log_domain_unregister(_log_dom);
+ eina_shutdown();
return r;
}
diff --git a/src/bin/ecore_evas/eetpack.c b/src/bin/ecore_evas/eetpack.c
index 6e7616d189..9be4c2f77a 100644
--- a/src/bin/ecore_evas/eetpack.c
+++ b/src/bin/ecore_evas/eetpack.c
@@ -274,9 +274,7 @@ main(int argc, char **argv)
return -1;
}
- eina_init();
eet_init();
- evas_init();
ecore_evas_init();
scratch_canvas_init();
@@ -285,8 +283,6 @@ main(int argc, char **argv)
if (ef) eet_close(ef);
ecore_evas_shutdown();
- evas_shutdown();
eet_shutdown();
- eina_shutdown();
return 0;
}
diff --git a/src/bin/edje/edje_cc.c b/src/bin/edje/edje_cc.c
index 1963dae341..dff3fd7a3e 100644
--- a/src/bin/edje/edje_cc.c
+++ b/src/bin/edje/edje_cc.c
@@ -25,7 +25,6 @@ Eina_List *snd_dirs = NULL;
Eina_List *mo_dirs = NULL;
Eina_List *vibration_dirs = NULL;
Eina_List *img_dirs = NULL;
-Eina_List *model_dirs = NULL;
Eina_List *fnt_dirs = NULL;
Eina_List *data_dirs = NULL;
Eina_List *defines = NULL;
@@ -174,8 +173,6 @@ main(int argc, char **argv)
img_dirs = eina_list_append(img_dirs, ".");
- model_dirs = eina_list_append(model_dirs, ".");
-
/* add defines to epp so edc files can detect edje_cc version */
defines = eina_list_append(defines, mem_strdup("-DEDJE_VERSION_12=12"));
@@ -224,11 +221,6 @@ main(int argc, char **argv)
i++;
img_dirs = eina_list_append(img_dirs, argv[i]);
}
- else if ((!strcmp(argv[i], "-mod") || !strcmp(argv[i], "--model_dir")) && (i < (argc - 1)))
- {
- i++;
- model_dirs = eina_list_append(model_dirs, argv[i]);
- }
else if ((!strcmp(argv[i], "-fd") || !strcmp(argv[i], "--font_dir")) && (i < (argc - 1)))
{
i++;
@@ -458,6 +450,7 @@ main(int argc, char **argv)
eina_prefix_free(pfx);
pfx = NULL;
+ ecore_evas_shutdown();
edje_shutdown();
eina_log_domain_unregister(_edje_cc_log_dom);
eina_shutdown();
diff --git a/src/bin/edje/edje_cc.h b/src/bin/edje/edje_cc.h
index afb7a99c03..580c44fe6d 100644
--- a/src/bin/edje/edje_cc.h
+++ b/src/bin/edje/edje_cc.h
@@ -230,13 +230,8 @@ void copied_program_anonymous_lookup_delete(Edje_Part_Collection *pc, int *de
void data_queue_anonymous_lookup(Edje_Part_Collection *pc, Edje_Program *ep, int *dest);
void data_queue_copied_anonymous_lookup(Edje_Part_Collection *pc, int *src, int *dest);
void data_queue_image_lookup(char *name, int *dest, Eina_Bool *set);
-void data_queue_model_lookup(char *name, int *dest, Eina_Bool *set);
void data_queue_copied_image_lookup(int *src, int *dest, Eina_Bool *set);
void data_queue_image_remove(int *dest, Eina_Bool *set);
-void data_queue_copied_model_lookup(int *src, int *dest, Eina_Bool *set);
-void data_queue_model_remove(int *dest, Eina_Bool *set);
-void data_queue_spectrum_lookup(char *name, int *dest);
-void data_queue_spectrum_slave_lookup(int *master, int *slave);
void data_process_lookups(void);
void data_process_scripts(void);
void data_process_script_lookups(void);
@@ -308,7 +303,6 @@ void script_rewrite(Code *code);
/* global vars */
extern Eina_List *ext_dirs;
extern Eina_List *img_dirs;
-extern Eina_List *model_dirs;
extern Eina_List *fnt_dirs;
extern Eina_List *snd_dirs;
extern Eina_List *mo_dirs;
diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 8353d260a3..0ced3e3308 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -220,8 +220,6 @@ static void st_images_set_image_size(void);
static void st_images_set_image_border(void);
static void st_images_set_image_border_scale_by(void);
-static void st_models_model(void);
-
static void st_fonts_font(void);
static void st_data_item(void);
@@ -272,7 +270,6 @@ static void st_collections_group_script_recursion(void);
static void st_collections_group_alias(void);
static void st_collections_group_min(void);
static void st_collections_group_max(void);
-static void st_collections_group_scene_size(void);
static void st_collections_group_broadcast_signal(void);
static void st_collections_group_data_item(void);
static void st_collections_group_orientation(void);
@@ -437,34 +434,7 @@ static void st_collections_group_parts_part_description_table_padding(void
static void st_collections_group_parts_part_description_table_min(void);
static void st_collections_group_parts_part_description_proxy_source_visible(void);
static void st_collections_group_parts_part_description_proxy_source_clip(void);
-static void st_collections_group_parts_part_description_position_point(void);
-static void st_collections_group_parts_part_description_position_space(void);
-static void st_collections_group_parts_part_description_camera_properties(void);
-static void st_collections_group_parts_part_description_properties_ambient(void);
-static void st_collections_group_parts_part_description_properties_diffuse(void);
-static void st_collections_group_parts_part_description_properties_specular(void);
-static void st_collections_group_parts_part_description_properties_material(void);
-static void st_collections_group_parts_part_description_properties_normal(void);
-static void st_collections_group_parts_part_description_properties_shininess(void);
-static void st_collections_group_parts_part_description_properties_shade(void);
-static void st_collections_group_parts_part_description_orientation_angle_axis(void);
-static void st_collections_group_parts_part_description_orientation_look1(void);
-static void st_collections_group_parts_part_description_orientation_look2(void);
-static void st_collections_group_parts_part_description_orientation_look_to(void);
-static void st_collections_group_parts_part_description_orientation_angle_axis(void);
-static void st_collections_group_parts_part_description_orientation_quaternion(void);
-static void st_collections_group_parts_part_description_scale(void);
static void st_collections_group_parts_part_description_offset_scale(void);
-static void st_collections_group_parts_part_description_mesh_primitive(void);
-static void ob_collections_group_parts_part_description_texture(void);
-static void st_collections_group_parts_part_description_texture_image(void);
-static void st_collections_group_parts_part_description_texture_wrap1(void);
-static void st_collections_group_parts_part_description_texture_wrap2(void);
-static void st_collections_group_parts_part_description_texture_filter1(void);
-static void st_collections_group_parts_part_description_texture_filter2(void);
-static void st_collections_group_parts_part_description_mesh_assembly(void);
-static void st_collections_group_parts_part_description_mesh_geometry(void);
-static void st_collections_group_parts_part_description_mesh_frame(void);
static void st_collections_group_parts_part_description_filter_code(void);
static void st_collections_group_parts_part_description_filter_source(void);
static void st_collections_group_parts_part_description_filter_data(void);
@@ -516,6 +486,9 @@ static void st_collections_group_parts_part_description_params_bool(void);
static void st_collections_group_parts_part_description_params_choice(void);
static void st_collections_group_parts_part_description_params_smart(void);
+/* vector part parameter */
+static void st_collections_group_parts_part_description_vector_frame(void);
+
static void ob_collections_group_programs_program(void);
static void st_collections_group_programs_program_name(void);
static void st_collections_group_programs_program_signal(void);
@@ -641,70 +614,6 @@ static void _handle_vector_image(void);
PROGRAM_BASE(PREFIX) \
PROGRAM_BASE(PREFIX ".programs")
-#define SET_LOOK1(Type, type_node) \
- Edje_Part_Description_##Type * ed; \
- ed = (Edje_Part_Description_##Type *)current_desc; \
- \
- if (ed->type_node.orientation.type <= EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT) \
- { \
- ed->type_node.orientation.data[0] = FROM_DOUBLE(parse_float(0)); \
- ed->type_node.orientation.data[1] = FROM_DOUBLE(parse_float(1)); \
- ed->type_node.orientation.data[2] = FROM_DOUBLE(parse_float(2)); \
- ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT; \
- }
-
-#define SET_LOOK2(Type, type_node) \
- Edje_Part_Description_##Type * ed; \
- ed = (Edje_Part_Description_##Type *)current_desc; \
- \
- if (ed->type_node.orientation.type <= EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT) \
- { \
- ed->type_node.orientation.data[3] = FROM_DOUBLE(parse_float(0)); \
- ed->type_node.orientation.data[4] = FROM_DOUBLE(parse_float(1)); \
- ed->type_node.orientation.data[5] = FROM_DOUBLE(parse_float(2)); \
- ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT; \
- }
-
-#define SET_LOOK_TO(list, Type, type_node) \
- Edje_Part_Description_##Type * ed; \
- char *name; \
- \
- ed = (Edje_Part_Description_##Type *)current_desc; \
- \
- if (ed->type_node.orientation.type <= EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO) \
- { \
- name = parse_str(0); \
- data_queue_part_lookup(list, name, &(ed->type_node.orientation.look_to)); \
- free(name); \
- ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO; \
- }
-
-#define SET_ANGLE_AXIS(Type, type_node) \
- Edje_Part_Description_##Type * ed; \
- ed = (Edje_Part_Description_##Type *)current_desc; \
- \
- if (ed->type_node.orientation.type <= EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS) \
- { \
- ed->type_node.orientation.data[0] = FROM_DOUBLE(parse_float(0)); \
- ed->type_node.orientation.data[1] = FROM_DOUBLE(parse_float(1)); \
- ed->type_node.orientation.data[2] = FROM_DOUBLE(parse_float(2)); \
- ed->type_node.orientation.data[3] = FROM_DOUBLE(parse_float(3)); \
- ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS; \
- }
-
-#define SET_QUATERNION(Type, type_node) \
- Edje_Part_Description_##Type * ed; \
- ed = (Edje_Part_Description_##Type *)current_desc; \
- \
- if (ed->type_node.orientation.type <= EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION) \
- { \
- ed->type_node.orientation.data[1] = FROM_DOUBLE(parse_float(0)); \
- ed->type_node.orientation.data[2] = FROM_DOUBLE(parse_float(1)); \
- ed->type_node.orientation.data[3] = FROM_DOUBLE(parse_float(2)); \
- ed->type_node.orientation.data[0] = FROM_DOUBLE(parse_float(3)); \
- ed->type_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION; \
- }
-
#define FILTERS_STATEMENTS(PREFIX) \
{PREFIX "filters.filter.file", st_filters_filter_file}, \
{PREFIX "filters.filter.name", st_filters_filter_name},
@@ -770,7 +679,6 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.alias", st_collections_group_alias},
{"collections.group.min", st_collections_group_min},
{"collections.group.max", st_collections_group_max},
- {"collections.group.scene_size", st_collections_group_scene_size},
{"collections.group.broadcast_signal", st_collections_group_broadcast_signal},
{"collections.group.orientation", st_collections_group_orientation},
{"collections.group.mouse_events", st_collections_group_mouse_events},
@@ -782,9 +690,6 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.programs.target_group", st_collections_group_target_group}, /* dup */
IMAGE_SET_STATEMENTS("collections.group")
IMAGE_STATEMENTS("collections.group.")
- {
- "collections.group.models.model", st_models_model
- },
{"collections.group.font", st_fonts_font}, /* dup */
FONT_STYLE_CC_STATEMENTS("collections.group.")
TEXT_CLASS_STATEMENTS("collections.group.")
@@ -976,31 +881,6 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.description.table.min", st_collections_group_parts_part_description_table_min},
{"collections.group.parts.part.description.proxy.source_visible", st_collections_group_parts_part_description_proxy_source_visible},
{"collections.group.parts.part.description.proxy.source_clip", st_collections_group_parts_part_description_proxy_source_clip},
- {"collections.group.parts.part.description.position.point", st_collections_group_parts_part_description_position_point},
- {"collections.group.parts.part.description.position.space", st_collections_group_parts_part_description_position_space},
- {"collections.group.parts.part.description.properties.perspective", st_collections_group_parts_part_description_camera_properties},
- {"collections.group.parts.part.description.properties.ambient", st_collections_group_parts_part_description_properties_ambient},
- {"collections.group.parts.part.description.properties.diffuse", st_collections_group_parts_part_description_properties_diffuse},
- {"collections.group.parts.part.description.properties.specular", st_collections_group_parts_part_description_properties_specular},
- {"collections.group.parts.part.description.properties.material", st_collections_group_parts_part_description_properties_material},
- {"collections.group.parts.part.description.properties.normal", st_collections_group_parts_part_description_properties_normal},
- {"collections.group.parts.part.description.properties.shininess", st_collections_group_parts_part_description_properties_shininess},
- {"collections.group.parts.part.description.properties.shade", st_collections_group_parts_part_description_properties_shade},
- {"collections.group.parts.part.description.mesh.primitive", st_collections_group_parts_part_description_mesh_primitive},
- {"collections.group.parts.part.description.orientation.look1", st_collections_group_parts_part_description_orientation_look1},
- {"collections.group.parts.part.description.orientation.look2", st_collections_group_parts_part_description_orientation_look2},
- {"collections.group.parts.part.description.orientation.look_to", st_collections_group_parts_part_description_orientation_look_to},
- {"collections.group.parts.part.description.orientation.angle_axis", st_collections_group_parts_part_description_orientation_angle_axis},
- {"collections.group.parts.part.description.orientation.quaternion", st_collections_group_parts_part_description_orientation_quaternion},
- {"collections.group.parts.part.description.scale", st_collections_group_parts_part_description_scale},
- {"collections.group.parts.part.description.texture.image", st_collections_group_parts_part_description_texture_image},
- {"collections.group.parts.part.description.texture.wrap1", st_collections_group_parts_part_description_texture_wrap1},
- {"collections.group.parts.part.description.texture.wrap2", st_collections_group_parts_part_description_texture_wrap2},
- {"collections.group.parts.part.description.texture.filter1", st_collections_group_parts_part_description_texture_filter1},
- {"collections.group.parts.part.description.texture.filter2", st_collections_group_parts_part_description_texture_filter2},
- {"collections.group.parts.part.description.mesh.assembly", st_collections_group_parts_part_description_mesh_assembly},
- {"collections.group.parts.part.description.mesh.geometry", st_collections_group_parts_part_description_mesh_geometry},
- {"collections.group.parts.part.description.mesh.frame", st_collections_group_parts_part_description_mesh_frame},
{"collections.group.parts.part.description.filter.code", st_collections_group_parts_part_description_filter_code},
{"collections.group.parts.part.description.filter.source", st_collections_group_parts_part_description_filter_source},
{"collections.group.parts.part.description.filter.data", st_collections_group_parts_part_description_filter_data},
@@ -1047,6 +927,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.description.params.bool", st_collections_group_parts_part_description_params_bool},
{"collections.group.parts.part.description.params.choice", st_collections_group_parts_part_description_params_choice},
{"collections.group.parts.part.description.params.*", st_collections_group_parts_part_description_params_smart},
+ {"collections.group.parts.part.description.vector.frame", st_collections_group_parts_part_description_vector_frame},
IMAGE_STATEMENTS("collections.group.parts.part.description.")
{
"collections.group.parts.part.description.font", st_fonts_font
@@ -1495,7 +1376,6 @@ New_Object_Handler object_handlers[] =
{"collections.group.set", ob_images_set}, /* dup */
{"collections.group.set.image", ob_images_set_image}, /* dup */
{"collections.group.images", NULL}, /* dup */
- {"collections.group.models", NULL}, /* dup */
{"collections.group.images.set", ob_images_set}, /* dup */
{"collections.group.images.set.image", ob_images_set_image}, /* dup */
{"collections.group.fonts", NULL}, /* dup */
@@ -1572,11 +1452,6 @@ New_Object_Handler object_handlers[] =
{"collections.group.parts.part.description.styles.style", ob_styles_style}, /* dup */
{"collections.group.parts.part.description.box", NULL},
{"collections.group.parts.part.description.table", NULL},
- {"collections.group.parts.part.description.position", NULL},
- {"collections.group.parts.part.description.properties", NULL},
- {"collections.group.parts.part.description.orientation", NULL},
- {"collections.group.parts.part.description.texture", ob_collections_group_parts_part_description_texture},
- {"collections.group.parts.part.description.mesh", NULL},
{"collections.group.parts.part.description.filter", NULL},
{"collections.group.parts.part.description.proxy", NULL},
#ifdef HAVE_EPHYSICS
@@ -1590,6 +1465,7 @@ New_Object_Handler object_handlers[] =
{"collections.group.parts.part.description.map.zoom", NULL},
{"collections.group.parts.part.description.perspective", NULL},
{"collections.group.parts.part.description.params", NULL},
+ {"collections.group.parts.part.description.vector", NULL},
{"collections.group.parts.part.description.color_classes", NULL}, /* dup */
{"collections.group.parts.part.description.color_classes.color_class", ob_color_class}, /* dup */
{"collections.group.parts.part.description.text_classes", NULL}, /* dup */
@@ -1888,160 +1764,6 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c
break;
}
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = mem_alloc(SZ(Edje_Part_Description_Mesh_Node));
-
- ed->mesh_node.mesh.id = -1;
- ed->mesh_node.mesh.primitive = 0;
- ed->mesh_node.mesh.assembly = 1;
- ed->mesh_node.mesh.frame = 0;
-
- ed->mesh_node.texture.id = -1;
- ed->mesh_node.texture.wrap1 = 0;
- ed->mesh_node.texture.wrap2 = 0;
- ed->mesh_node.texture.filter1 = 0;
- ed->mesh_node.texture.filter2 = 0;
-
- ed->mesh_node.properties.shade = EVAS_CANVAS3D_SHADER_MODE_VERTEX_COLOR;
- ed->mesh_node.properties.ambient.r = 50;
- ed->mesh_node.properties.ambient.g = 50;
- ed->mesh_node.properties.ambient.b = 50;
- ed->mesh_node.properties.ambient.a = 255;
- ed->mesh_node.properties.diffuse.r = 255;
- ed->mesh_node.properties.diffuse.g = 255;
- ed->mesh_node.properties.diffuse.b = 255;
- ed->mesh_node.properties.diffuse.a = 255;
- ed->mesh_node.properties.specular.r = 255;
- ed->mesh_node.properties.specular.g = 255;
- ed->mesh_node.properties.specular.b = 255;
- ed->mesh_node.properties.specular.a = 255;
-
- ed->mesh_node.properties.material_attrib = 1;
- ed->mesh_node.properties.normal = 1;
- ed->mesh_node.properties.shininess = 50;
-
- ed->mesh_node.aabb1.relative.x = -1.0;
- ed->mesh_node.aabb1.relative.y = -1.0;
- ed->mesh_node.aabb1.relative.z = -1.0;
- ed->mesh_node.aabb1.offset.x = 0;
- ed->mesh_node.aabb1.offset.y = 0;
- ed->mesh_node.aabb1.offset.z = 0;
- ed->mesh_node.aabb1.rel_to = -1;
- ed->mesh_node.aabb2.relative.x = 1.0;
- ed->mesh_node.aabb2.relative.y = 1.0;
- ed->mesh_node.aabb2.relative.z = 1.0;
- ed->mesh_node.aabb2.offset.x = 0;
- ed->mesh_node.aabb2.offset.y = 0;
- ed->mesh_node.aabb2.offset.z = 0;
- ed->mesh_node.aabb2.rel_to = -1;
-
- ed->mesh_node.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE;
- /* x1 is angle for angle_axis and cosine of half angle for quternion,
- x2, x3, x4 define axis for angle_axis and quaternion,
- x1, x2, x3 are coordinates of point to look at for look_at,
- x4, x5, x6 define a vector that indicates the angle at which
- the subject is looking at the target for look_at and look_to */
- ed->mesh_node.orientation.data[0] = 1.0;
- ed->mesh_node.orientation.data[1] = 0.0;
- ed->mesh_node.orientation.data[2] = 0.0;
- ed->mesh_node.orientation.data[3] = 0.0;
- ed->mesh_node.orientation.data[4] = 1.0;
- ed->mesh_node.orientation.data[5] = 0.0;
- ed->mesh_node.orientation.look_to = -1;
-
- ed->mesh_node.scale_3d.x = 1.0;
- ed->mesh_node.scale_3d.y = 1.0;
- ed->mesh_node.scale_3d.z = 1.0;
-
- ed->mesh_node.position.point.x = 0.0;
- ed->mesh_node.position.point.y = 0.0;
- ed->mesh_node.position.point.z = 0.0;
- ed->mesh_node.position.space = EVAS_CANVAS3D_SPACE_PARENT;
-
- result = &ed->common;
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = mem_alloc(SZ(Edje_Part_Description_Light));
-
- ed->light.properties.ambient.r = 50;
- ed->light.properties.ambient.g = 50;
- ed->light.properties.ambient.b = 50;
- ed->light.properties.ambient.a = 255;
- ed->light.properties.diffuse.r = 255;
- ed->light.properties.diffuse.g = 255;
- ed->light.properties.diffuse.b = 255;
- ed->light.properties.diffuse.a = 255;
- ed->light.properties.specular.r = 255;
- ed->light.properties.specular.g = 255;
- ed->light.properties.specular.b = 255;
- ed->light.properties.specular.a = 255;
-
- ed->light.position.point.x = 0.0;
- ed->light.position.point.y = 0.0;
- ed->light.position.point.z = 1.0;
- ed->light.position.space = EVAS_CANVAS3D_SPACE_PARENT;
-
- ed->light.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE;
- /* x1 is angle for angle_axis and cosine of half angle for quternion,
- x2, x3, x4 define axis for angle_axis and quaternion,
- x1, x2, x3 are coordinates of point to look at for look_at,
- x4, x5, x6 define a vector that indicates the angle at which
- the subject is looking at the target for look_at and look_to */
- ed->light.orientation.data[0] = 1.0;
- ed->light.orientation.data[1] = 0.0;
- ed->light.orientation.data[2] = 0.0;
- ed->light.orientation.data[3] = 0.0;
- ed->light.orientation.data[4] = 1.0;
- ed->light.orientation.data[5] = 0.0;
- ed->light.orientation.look_to = -1;
-
- result = &ed->common;
- break;
- }
-
- case EDJE_PART_TYPE_CAMERA:
- {
- Edje_Part_Description_Camera *ed;
-
- ed = mem_alloc(SZ(Edje_Part_Description_Camera));
-
- ed->camera.camera.fovy = 60.0;
- ed->camera.camera.aspect = 1.0;
- ed->camera.camera.frustum_near = 2.0;
- ed->camera.camera.frustum_far = 50.0;
-
- ed->camera.position.point.x = 0.0;
- ed->camera.position.point.y = 0.0;
- ed->camera.position.point.z = 5.0;
-
- ed->camera.position.space = EVAS_CANVAS3D_SPACE_PARENT;
-
- ed->camera.orientation.type = EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE;
- /* x1 is angle for angle_axis and cosine of half angle for quternion,
- x2, x3, x4 define axis for angle_axis and quaternion,
- x1, x2, x3 are coordinates of point to look at for look_at,
- x4, x5, x6 define a vector that indicates the angle at which
- the subject is looking at the target for look_at and look_to */
- ed->camera.orientation.data[0] = 1.0;
- ed->camera.orientation.data[1] = 0.0;
- ed->camera.orientation.data[2] = 0.0;
- ed->camera.orientation.data[3] = 0.0;
- ed->camera.orientation.data[4] = 1.0;
- ed->camera.orientation.data[5] = 0.0;
- ed->camera.orientation.look_to = -1;
-
- result = &ed->common;
- break;
- }
-
case EDJE_PART_TYPE_VECTOR:
{
Edje_Part_Description_Vector *ed;
@@ -2545,6 +2267,7 @@ _handle_vector_image(void)
{
ed->vg.set = EINA_TRUE;
ed->vg.id = edje_file->image_dir->vectors[i].id;
+ ed->vg.type = edje_file->image_dir->vectors[i].type;
break;
}
}
@@ -2555,7 +2278,7 @@ _handle_vector_image(void)
free(name);
}
-/** @edcsubsection{toplevel_images,
+/** @edcsubsection{toplevel_images2,
* Images} */
/**
@@ -2587,6 +2310,7 @@ st_images_vector(void)
Edje_Vector_Directory_Entry *vector;
const char *tmp;
unsigned int i;
+ size_t entry_len;
check_min_arg_count(1);
@@ -2618,74 +2342,16 @@ st_images_vector(void)
vector->entry = tmp;
vector->id = edje_file->image_dir->vectors_count - 1;
-}
-
-/**
- @edcsubsection{toplevel_models,model}
- */
-
-/**
- @page edcref
-
- @block
- models
- @context
- models {
- model: "filename1.ext";
- model: "filename2.ext";
- model: "filename2.ext" 50;
- ..
- }
- @description
- The "models" block is used to list each model file that will be used in
- the theme.
- @endblock
-
- @property
- model
- @parameters
- [model file]
- @effect
- Used to include each model file.
- @endproperty
- */
-static void
-st_models_model(void)
-{
- Edje_Model_Directory_Entry *mdl;
- const char *tmp;
- unsigned int i;
-
- check_min_arg_count(1);
-
- if (!edje_file->model_dir)
- edje_file->model_dir = mem_alloc(SZ(Edje_Model_Directory));
-
- tmp = parse_str(0);
- for (i = 0; i < edje_file->model_dir->entries_count; ++i)
- if (!strcmp(edje_file->model_dir->entries[i].entry, tmp))
- {
- free((char *)tmp);
- return;
- }
-
- edje_file->model_dir->entries_count++;
- mdl = realloc(edje_file->model_dir->entries,
- sizeof (Edje_Model_Directory_Entry) * edje_file->model_dir->entries_count);
- if (!mdl)
+ entry_len = strlen(vector->entry);
+ if ((entry_len > 5) && !strncmp(vector->entry + entry_len - 5, ".json", 5))
{
- ERR("No enough memory.");
- exit(-1);
+ vector->type = EDJE_VECTOR_FILE_TYPE_LOTTIE;
+ }
+ else
+ {
+ vector->type = EDJE_VECTOR_FILE_TYPE_SVG;
}
- edje_file->model_dir->entries = mdl;
- memset(edje_file->model_dir->entries + edje_file->model_dir->entries_count - 1,
- 0, sizeof (Edje_Model_Directory_Entry));
-
- mdl = edje_file->model_dir->entries + edje_file->model_dir->entries_count - 1;
-
- mdl->entry = tmp;
- mdl->id = edje_file->model_dir->entries_count - 1;
}
/** @edcsubsection{toplevel_images_set,
@@ -3831,7 +3497,7 @@ st_size_class_max(void)
/** @edcsection{collections,Collections Blocks} */
-/** @edcsubsection{collections,
+/** @edcsubsection{sub_collections,
* Collections} */
/**
@@ -3888,7 +3554,7 @@ st_collections_base_scale(void)
check_min_arg_count(1);
edje_file->base_scale = FROM_DOUBLE(parse_float_range(0, 0.0, 999999999.0));
- if (edje_file->base_scale == ZERO)
+ if (EQ(edje_file->base_scale, ZERO))
{
ERR("The base_scale is 0.0. The value should be bigger than 0.0.");
exit(-1);
@@ -4349,12 +4015,12 @@ _link_combine(void)
EINA_LIST_FOREACH_SAFE(tup->data, l, ll, ell)
{
if (ell->pr->tween.mode != el->pr->tween.mode) continue;
- if (fabs(ell->pr->tween.time - el->pr->tween.time) > DBL_EPSILON) continue;
- if (fabs(ell->pr->tween.v1 - el->pr->tween.v1) > DBL_EPSILON) continue;
- if (fabs(ell->pr->tween.v2 - el->pr->tween.v2) > DBL_EPSILON) continue;
- if (fabs(ell->pr->tween.v3 - el->pr->tween.v3) > DBL_EPSILON) continue;
- if (fabs(ell->pr->tween.v4 - el->pr->tween.v4) > DBL_EPSILON) continue;
- if (fabs(ell->ed->state.value - el->ed->state.value) > DBL_EPSILON) continue;
+ if (!EQ(ell->pr->tween.time, el->pr->tween.time)) continue;
+ if (!EQ(ell->pr->tween.v1, el->pr->tween.v1)) continue;
+ if (!EQ(ell->pr->tween.v2, el->pr->tween.v2)) continue;
+ if (!EQ(ell->pr->tween.v3, el->pr->tween.v3)) continue;
+ if (!EQ(ell->pr->tween.v4, el->pr->tween.v4)) continue;
+ if (!EQ(ell->ed->state.value, el->ed->state.value)) continue;
if ((!!ell->ed->state.name) != (!!el->ed->state.name))
{
if (((!!ell->ed->state.name) && strcmp(ell->ed->state.name, "default")) ||
@@ -4458,9 +4124,6 @@ ob_collections_group(void)
pcp->default_mouse_events = 1;
pcp->inherit_script = EINA_FALSE;
- pc->scene_size.width = 0;
- pc->scene_size.height = 0;
-
#ifdef HAVE_EPHYSICS
pc->physics.world.gravity.x = 0;
pc->physics.world.gravity.y = 294;
@@ -4545,7 +4208,7 @@ st_collections_group_name(void)
This property can be inherited.
Defaults: 0
- @warning Your edc file should always wrap this keyword with #ifdef HAVE_SKIP_NAMESPACE_VALIDATION
+ @warning Your edc file should always wrap this keyword with <tt>\#ifdef HAVE_SKIP_NAMESPACE_VALIDATION</tt>
@since 1.21
@endproperty
*/
@@ -4649,18 +4312,6 @@ _parts_count_update(unsigned int type, int inc)
current_de->count.PROXY += inc;
break;
- case EDJE_PART_TYPE_MESH_NODE:
- current_de->count.MESH_NODE += inc;
- break;
-
- case EDJE_PART_TYPE_LIGHT:
- current_de->count.LIGHT += inc;
- break;
-
- case EDJE_PART_TYPE_CAMERA:
- current_de->count.CAMERA += inc;
- break;
-
case EDJE_PART_TYPE_SPACER:
current_de->count.SPACER += inc;
break;
@@ -5515,30 +5166,6 @@ st_collections_group_max(void)
}
/**
- @page edcref
- @property
- scene_size
- @parameters
- [width] [height]
- @effect
- Size of scene.
-
- Defaults: 0.0 0.0
- @endproperty
- */
-static void
-st_collections_group_scene_size(void)
-{
- Edje_Part_Collection *pc;
-
- check_arg_count(2);
-
- pc = eina_list_data_get(eina_list_last(edje_collections));
- pc->scene_size.width = parse_float(0);
- pc->scene_size.height = parse_float(1);
-}
-
-/**
@page edcref
@property
broadcast_signal
@@ -6856,9 +6483,6 @@ st_collections_group_parts_part_name(void)
@li BOX
@li TABLE
@li EXTERNAL
- @li MESH_NODE
- @li CAMERA
- @li LIGHT
@li PROXY
@li SPACER
@li SNAPSHOT
@@ -6870,9 +6494,6 @@ static void
st_collections_group_parts_part_type(void)
{
unsigned int type;
- unsigned int i = 0;
-
- Edje_Part_Collection *pc;
check_arg_count(1);
@@ -6888,29 +6509,11 @@ st_collections_group_parts_part_type(void)
"TABLE", EDJE_PART_TYPE_TABLE,
"EXTERNAL", EDJE_PART_TYPE_EXTERNAL,
"PROXY", EDJE_PART_TYPE_PROXY,
- "MESH_NODE", EDJE_PART_TYPE_MESH_NODE,
- "LIGHT", EDJE_PART_TYPE_LIGHT,
- "CAMERA", EDJE_PART_TYPE_CAMERA,
"SPACER", EDJE_PART_TYPE_SPACER,
"SNAPSHOT", EDJE_PART_TYPE_SNAPSHOT,
"VECTOR", EDJE_PART_TYPE_VECTOR,
NULL);
- pc = eina_list_data_get(eina_list_last(edje_collections));
-
- if (type == EDJE_PART_TYPE_CAMERA)
- {
- for (i = 0; i < (pc->parts_count - 1); i++)
- {
- if (pc->parts[i]->type == EDJE_PART_TYPE_CAMERA)
- {
- WRN("parse error %s:%i. more then one part of type CAMERA in scene.",
- file_in, line - 1);
- exit(-1);
- }
- }
- }
-
_part_type_set(type);
}
@@ -8628,9 +8231,6 @@ ob_collections_group_parts_part_description(void)
ed->minmul.have = 1;
ed->minmul.w = FROM_DOUBLE(1.0);
ed->minmul.h = FROM_DOUBLE(1.0);
- ed->align_3d.x = FROM_DOUBLE(0.5);
- ed->align_3d.y = FROM_DOUBLE(0.5);
- ed->align_3d.z = FROM_DOUBLE(0.5);
}
static void
@@ -8704,7 +8304,7 @@ st_collections_group_parts_part_description_inherit(void)
exit(-1);
}
- if (!strcmp(parent_name, "default") && parent_val == 0.0)
+ if (!strcmp(parent_name, "default") && EINA_DBL_EQ(parent_val, 0.0))
parent = ep->default_desc;
else
{
@@ -8735,7 +8335,7 @@ st_collections_group_parts_part_description_inherit(void)
}
}
- if (min_dst)
+ if (EINA_DBL_NONZERO(min_dst))
{
WRN("%s:%i: couldn't find an exact match in part '%s' when looking for '%s' %lf. Falling back to nearest one '%s' %lf.",
file_in, line - 1, ep->name, parent_name, parent_val, parent ? parent->state.name : NULL, parent ? parent->state.value : 0);
@@ -8912,54 +8512,14 @@ st_collections_group_parts_part_description_inherit(void)
break;
}
- case EDJE_PART_TYPE_CAMERA:
- {
- Edje_Part_Description_Camera *ced = (Edje_Part_Description_Camera *)ed;
- Edje_Part_Description_Camera *cparent = (Edje_Part_Description_Camera *)parent;
-
- ced->camera = cparent->camera;
-
- data_queue_copied_part_lookup(pc, &(cparent->camera.orientation.look_to), &(ced->camera.orientation.look_to));
-
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *led = (Edje_Part_Description_Light *)ed;
- Edje_Part_Description_Light *lparent = (Edje_Part_Description_Light *)parent;
-
- led->light = lparent->light;
-
- data_queue_copied_part_lookup(pc, &(lparent->light.orientation.look_to), &(led->light.orientation.look_to));
-
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *med = (Edje_Part_Description_Mesh_Node *)ed;
- Edje_Part_Description_Mesh_Node *mparent = (Edje_Part_Description_Mesh_Node *)parent;
-
- med->mesh_node = mparent->mesh_node;
-
- data_queue_model_remove(&med->mesh_node.mesh.id, &med->mesh_node.mesh.set);
- data_queue_copied_model_lookup(&mparent->mesh_node.mesh.id, &med->mesh_node.mesh.id, &med->mesh_node.mesh.set);
-
- data_queue_image_remove(&med->mesh_node.texture.id, &med->mesh_node.texture.set);
- data_queue_copied_model_lookup(&mparent->mesh_node.texture.id, &med->mesh_node.texture.id, &med->mesh_node.texture.set);
-
- data_queue_copied_part_lookup(pc, &(mparent->mesh_node.orientation.look_to), &(med->mesh_node.orientation.look_to));
-
- break;
- }
-
case EDJE_PART_TYPE_VECTOR:
{
Edje_Part_Description_Vector *ied = (Edje_Part_Description_Vector *)ed;
Edje_Part_Description_Vector *iparent = (Edje_Part_Description_Vector *)parent;
ied->vg.set = iparent->vg.set;
ied->vg.id = iparent->vg.id;
+ ied->vg.type = iparent->vg.type;
+ ied->vg.frame = iparent->vg.frame;
break;
}
}
@@ -9009,8 +8569,8 @@ _part_description_state_update(Edje_Part_Description_Common *ed)
Edje_Part *ep = current_part;
if (ed == ep->default_desc) return;
- if ((ep->default_desc->state.name && !strcmp(ed->state.name, ep->default_desc->state.name) && ed->state.value == ep->default_desc->state.value) ||
- (!ep->default_desc->state.name && !strcmp(ed->state.name, "default") && ed->state.value == ep->default_desc->state.value))
+ if ((ep->default_desc->state.name && !strcmp(ed->state.name, ep->default_desc->state.name) && EINA_DBL_EQ(ed->state.value, ep->default_desc->state.value)) ||
+ (!ep->default_desc->state.name && !strcmp(ed->state.name, "default") && EINA_DBL_EQ(ed->state.value, ep->default_desc->state.value)))
{
if (ep->type == EDJE_PART_TYPE_IMAGE)
_edje_part_description_image_remove((Edje_Part_Description_Image *)ed);
@@ -9026,7 +8586,7 @@ _part_description_state_update(Edje_Part_Description_Common *ed)
unsigned int i;
for (i = 0; i < ep->other.desc_count - 1; ++i)
{
- if (!strcmp(ed->state.name, ep->other.desc[i]->state.name) && ed->state.value == ep->other.desc[i]->state.value)
+ if (!strcmp(ed->state.name, ep->other.desc[i]->state.name) && EINA_DBL_EQ(ed->state.value, ep->other.desc[i]->state.value))
{
if (ep->type == EDJE_PART_TYPE_IMAGE)
_edje_part_description_image_remove((Edje_Part_Description_Image *)ed);
@@ -9085,7 +8645,7 @@ st_collections_group_parts_part_description_state(void)
val = parse_float_range(1, 0.0, 1.0);
/* if only default desc exists and current desc is not default, commence paddling */
- if ((!ep->other.desc_count) && (val || (!eina_streq(s, "default"))))
+ if ((!ep->other.desc_count) && (EINA_DBL_NONZERO(val) || (!eina_streq(s, "default"))))
{
ERR("parse error %s:%i. invalid state name: '%s'. \"default\" state must always be first.",
file_in, line - 1, s);
@@ -9238,7 +8798,7 @@ st_collections_group_parts_part_description_limit(void)
@property
align
@parameters
- [X axis] [Y axis] ([Z axis])
+ [X axis] [Y axis]
@effect
When the displayed object's size is smaller (or bigger) than
its container, this property moves it relatively along both
@@ -9246,27 +8806,18 @@ st_collections_group_parts_part_description_limit(void)
the object touching container's respective ones, while @c
"1.0" stands for right/bottom edges of the object (on
horizontal/vertical axis, respectively).
- There is one more parameter for Z axis in case of MESH_NODE.
- Defaults: 0.5 0.5 (0.5)
+ Defaults: 0.5 0.5
@endproperty
*/
static void
st_collections_group_parts_part_description_align(void)
{
check_has_anchors();
+ check_arg_count(2);
- if (get_arg_count() == 2)
- {
- current_desc->align.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
- current_desc->align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
- }
- else if (get_arg_count() == 3)
- {
- current_desc->align_3d.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
- current_desc->align_3d.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
- current_desc->align_3d.z = FROM_DOUBLE(parse_float_range(2, 0.0, 1.0));
- }
+ current_desc->align.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1.0));
+ current_desc->align.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1.0));
}
/**
@@ -9279,8 +8830,8 @@ st_collections_group_parts_part_description_align(void)
This affects the minimum size calculation. See
edje_object_size_min_calc() and edje_object_size_min_restricted_calc().
This tells the min size calculation routine that this part does not
- change size in width or height (1 for it doesn't, 0 for it does), so
- the routine should not try and expand or contract the part.
+ change group size in width or height (1 for it doesn't, 0 for it does),
+ so the routine should not try and expand or contract the group.
Defaults: 0 0
@endproperty
@@ -9293,6 +8844,8 @@ st_collections_group_parts_part_description_fixed(void)
current_desc->fixed.w = parse_bool(0);
current_desc->fixed.h = parse_bool(1);
+
+ current_desc->user_set.fixed = EINA_TRUE;
}
/**
@@ -10926,7 +10479,7 @@ st_collections_group_parts_part_description_image_scale_hint(void)
The fill method is an optional block that defines the way an IMAGE or
PROXY part is going to be displayed inside its container.
It can be used for tiling (repeating the image) or displaying only
- part of an image. See @ref evas_object_image_fill_set() documentation
+ part of an image. See evas_object_image_fill_set() documentation
for more details.
@endblock
@@ -11730,7 +11283,7 @@ st_collections_group_parts_part_description_text_fit_size_array(void)
for (n = 0, argc = get_arg_count(); n < argc; n++)
{
unsigned int *value = malloc(sizeof(unsigned int));
- *value = (unsigned int) parse_int(n);
+ if (value) *value = (unsigned int) parse_int(n);
ed->text.fit_size_array = eina_list_append(ed->text.fit_size_array, value);
}
}
@@ -12379,1302 +11932,6 @@ st_collections_group_parts_part_description_proxy_source_visible(void)
ed->proxy.source_visible = parse_bool(0);
}
-/**
- @edcsubsection{collections_group_parts_description_position,
- Group.Parts.Part.Description.Position}
- */
-
-/**
- @page edcref
-
- @block
- position
- @context
- part {
- description {
- ..
- position {
- point: x y z;
- space: LOCAL/PARENT/WORLD;
- }
- ..
- }
- }
- @description
- A position block defines position of CAMERA,
- LIGHT or MESH_NODE at the scene.
- @endblock
-
- @property
- point
- @parameters
- [x] [y] [z]
- @effect
- Sets the point of CAMERA, LIGHT or MESH_NODE centre.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_position_point(void)
-{
- check_arg_count(3);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_CAMERA:
- {
- Edje_Part_Description_Camera *ed;
-
- ed = (Edje_Part_Description_Camera *)current_desc;
-
- ed->camera.position.point.x = FROM_DOUBLE(parse_float(0));
- ed->camera.position.point.y = FROM_DOUBLE(parse_float(1));
- ed->camera.position.point.z = FROM_DOUBLE(parse_float(2));
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- ed->light.position.point.x = FROM_DOUBLE(parse_float(0));
- ed->light.position.point.y = FROM_DOUBLE(parse_float(1));
- ed->light.position.point.z = FROM_DOUBLE(parse_float(2));
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.position.point.x = FROM_DOUBLE(parse_float(0));
- ed->mesh_node.position.point.y = FROM_DOUBLE(parse_float(1));
- ed->mesh_node.position.point.z = FROM_DOUBLE(parse_float(2));
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. camera and light attributes in non-CAMERA, non-LIGHT, and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
-
- @property
- space
- @parameters
- [SPACE]
- @effect
- Explains in which relative coordinates the location of LIGHT
- or CAMERA considers. Valid space types:
- @li LOCAL
- @li PARENT
- @li WORLD
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_position_space(void)
-{
- unsigned int space;
-
- check_arg_count(1);
-
- space = parse_enum(0,
- "LOCAL", EVAS_CANVAS3D_SPACE_LOCAL,
- "PARENT", EVAS_CANVAS3D_SPACE_PARENT,
- "WORLD", EVAS_CANVAS3D_SPACE_WORLD,
- NULL);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_CAMERA:
- {
- Edje_Part_Description_Camera *ed;
-
- ed = (Edje_Part_Description_Camera *)current_desc;
-
- ed->camera.position.space = space;
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- ed->light.position.space = space;
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.position.space = space;
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. camera and light attributes in non-CAMERA, non-LIGHT, and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @edcsubsection{collections_group_parts_description_camera,
- Group.Parts.Part.Description.Properties}
- */
-
-/**
- @page edcref
-
- @block
- properties
- @context
- part { type: CAMERA;
- description {
- ..
- properties {
- perspective: fovy aspect near far;
- }
- ..
- }
- }
- @description
- @endblock
-
- @property
- properties
- @parameters
- [fovy] [aspect] [near] [far]
- @effect
- Specifies the basic attributes of the camera.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_camera_properties(void)
-{
- check_arg_count(4);
-
- if (current_part->type == EDJE_PART_TYPE_CAMERA)
- {
- Edje_Part_Description_Camera *ed;
-
- ed = (Edje_Part_Description_Camera *)current_desc;
-
- ed->camera.camera.fovy = FROM_DOUBLE(parse_float(0));
- ed->camera.camera.aspect = FROM_DOUBLE(parse_float(1));
- ed->camera.camera.frustum_near = FROM_DOUBLE(parse_float(2));
- ed->camera.camera.frustum_far = FROM_DOUBLE(parse_float(3));
- }
- else if (current_part->type == EDJE_PART_TYPE_LIGHT)
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- ed->light.light.fovy = FROM_DOUBLE(parse_float(0));
- ed->light.light.aspect = FROM_DOUBLE(parse_float(1));
- ed->light.light.frustum_near = FROM_DOUBLE(parse_float(2));
- ed->light.light.frustum_far = FROM_DOUBLE(parse_float(3));
- }
- else
- {
- ERR("parse error %s:%i. camera attributes in non-CAMERA and non-LIGHT part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @edcsubsection{collections_group_parts_description_properties,
- Group.Parts.Part.Description.Properties}
- */
-
-/**
- @page edcref
-
- @block
- properties
- @context
- part { type: [LIGHT or MESH_NODE];
- description {
- ..
- properties {
- ambient: red green blue alpha;
- diffuse: red green blue alpha;
- specular: red green blue alpha;
- shade: PHONG;
- material: AMBIENT;
- normal: 1;
- shininess: 50.0;
- }
- ..
- }
- }
- @description
- A properties block defines main lighting attributes of LIGHT and MESH_NODE.
- @endblock
-
- @property
- ambient
- @parameters
- [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
- @effect
- Sets the components of the ambient color.
-
- Format:
- @li [red] [green] [blue] [alpha]: one integer [0-255] for each
- RGBA channel, i.e. 255 0 0 255
- @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
- i.e "#FF0000FF" or "#FF0000"
- @li "#[R][G][B](A)": string with one hex value per RGBA channel,
- i.e "#F00F" or "#F00".\n
- In string format you can omit alpha channel and it will be set to FF.
-
- Defaults: 50 50 50 255
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_ambient(void)
-{
- check_arg_count(4);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- parse_color(0, &(ed->light.properties.ambient));
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- parse_color(0, &(ed->mesh_node.properties.ambient));
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. light and mesh_node attributes in non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- diffuse
- @parameters
- [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
- @effect
- Sets the components of the diffuse color.
-
- Format:
- @li [red] [green] [blue] [alpha]: one integer [0-255] for each
- RGBA channel, i.e. 255 0 0 255
- @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
- i.e "#FF0000FF" or "#FF0000"
- @li "#[R][G][B](A)": string with one hex value per RGBA channel,
- i.e "#F00F" or "#F00".\n
- In string format you can omit alpha channel and it will be set to FF.
-
- Defaults: 255 255 255 255
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_diffuse(void)
-{
- check_arg_count(4);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- parse_color(0, &(ed->light.properties.diffuse));
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- parse_color(0, &(ed->mesh_node.properties.diffuse));
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. light and mesh_node attributes in non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- specular
- @parameters
- [red] [green] [blue] [alpha] or "#[RR][GG][BB](AA)" or "#[R][G][B](A)"
- @effect
- Sets the components of the specular color.
-
- Format:
- @li [red] [green] [blue] [alpha]: one integer [0-255] for each
- RGBA channel, i.e. 255 0 0 255
- @li "#[RR][GG][BB](AA)": string with two hex values per RGBA channel,
- i.e "#FF0000FF" or "#FF0000"
- @li "#[R][G][B](A)": string with one hex value per RGBA channel,
- i.e "#F00F" or "#F00".\n
- In string format you can omit alpha channel and it will be set to FF.
-
- Defaults: 255 255 255 255
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_specular(void)
-{
- check_arg_count(4);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_LIGHT:
- {
- Edje_Part_Description_Light *ed;
-
- ed = (Edje_Part_Description_Light *)current_desc;
-
- parse_color(0, &(ed->light.properties.specular));
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- parse_color(0, &(ed->mesh_node.properties.specular));
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. light and mesh_node attributes in non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- material
- @parameters
- [MATERIAL]
- @effect
- Sets the color mode for the lighting. Valid color modes:
- @li AMBIENT
- @li DIFFUSE
- @li SPECULAR
- @li EMISSION
- @li NORMAL
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_material(void)
-{
- unsigned int material_attrib;
-
- check_arg_count(1);
-
- material_attrib = parse_enum(0,
- "AMBIENT", EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT,
- "DIFFUSE", EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE,
- "SPECULAR", EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR,
- "EMISSION", EVAS_CANVAS3D_MATERIAL_ATTRIB_EMISSION,
- "NORMAL", EVAS_CANVAS3D_MATERIAL_ATTRIB_NORMAL,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.properties.material_attrib = material_attrib;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- normal
- @parameters
- [0 or 1]
- @effect
- Sets the material attribute enable flag of the given material.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_normal(void)
-{
- check_arg_count(1);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.properties.normal = parse_bool(0);
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- shininess
- @parameters
- [shininess]
- @effect
- Sets the shininess of the given material.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_properties_shininess(void)
-{
- check_arg_count(1);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.properties.shininess = FROM_DOUBLE(parse_float(0));
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- shade
- @parameters
- [SHADE]
- @effect
- Sets the shade mode for MESH_NODE. Valid shade modes:
- @li COLOR
- @li DIFFUSE
- @li FLAT
- @li PHONG
- @li MAP
- @li RENDER
- @endproperty
- */
-
-static void
-st_collections_group_parts_part_description_properties_shade(void)
-{
- unsigned int shade;
-
- check_arg_count(1);
-
- shade = parse_enum(0,
- "VERTEX_COLOR", EVAS_CANVAS3D_SHADER_MODE_VERTEX_COLOR,
- "PARENT", EVAS_CANVAS3D_SHADER_MODE_DIFFUSE,
- "WORLD", EVAS_CANVAS3D_SHADER_MODE_FLAT,
- "PHONG", EVAS_CANVAS3D_SHADER_MODE_PHONG,
- "NORMAL_MAP", EVAS_CANVAS3D_SHADER_MODE_NORMAL_MAP,
- "RENDER", EVAS_CANVAS3D_SHADER_MODE_SHADOW_MAP_RENDER,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.properties.shade = shade;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @edcsubsection{collections_group_parts_description_orientation,
- Group.Parts.Part.Description.Orientation}
- */
-
-/**
- @page edcref
-
- @block
- orientation
- @context
- part { type: [CAMERA or MESH_NODE or LIGHT];
- description {
- ..
- orientation {
- look1: [x] [y] [z];
- look2: [x] [y] [z];
- look_to: [another part's name];
- angle_axis: [w] [x] [y] [z];
- quaternion: [x] [y] [z] [w];
- }
- ..
- }
- }
- @description
- The orientation block defines an orientation of CAMERA, LIGHT or MESH_NODE in the scene.
- @endblock
-
- @property
- look1
- @parameters
- [x] [y] [z]
- @effect
- Indicates a target point for CAMERA and MESH_NODE or for LIGHT to see or
- to illuminate.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_orientation_look1(void)
-{
- check_arg_count(3);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_CAMERA:
- {
- SET_LOOK1(Camera, camera);
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- SET_LOOK1(Light, light);
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- SET_LOOK1(Mesh_Node, mesh_node);
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. camera, light and mesh_node attributes in non-CAMERA, non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- look2
- @parameters
- [x] [y] [z]
- @effect
- Specifies the angle at which the target point will be caught.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_orientation_look2(void)
-{
- check_arg_count(3);
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_CAMERA:
- {
- SET_LOOK2(Camera, camera);
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- SET_LOOK2(Light, light);
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- SET_LOOK2(Mesh_Node, mesh_node);
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. camera, light and mesh_node attributes in non-CAMERA, non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- look_to
- @parameters
- [another part's name]
- @effect
- Indicates another part to make target of CAMERA, LIGHT or MESH_NODE
- or LIGHT.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_orientation_look_to(void)
-{
- Edje_Part_Collection *pc;
-
- check_arg_count(1);
-
- pc = eina_list_data_get(eina_list_last(edje_collections));
-
- switch (current_part->type)
- {
- case EDJE_PART_TYPE_CAMERA:
- {
- SET_LOOK_TO(pc, Camera, camera);
- break;
- }
-
- case EDJE_PART_TYPE_LIGHT:
- {
- SET_LOOK_TO(pc, Light, light);
- break;
- }
-
- case EDJE_PART_TYPE_MESH_NODE:
- {
- SET_LOOK_TO(pc, Mesh_Node, mesh_node);
- break;
- }
-
- default:
- {
- ERR("parse error %s:%i. camera, light and mesh_node attributes in non-CAMERA, non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
- }
-}
-
-/**
- @page edcref
- @property
- angle_axis
- @parameters
- [x] [y] [z] [w]
- @effect
- Specifies the angle and indicates what proportions the MESH_NODE rotates in.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_orientation_angle_axis(void)
-{
- check_arg_count(4);
-
- if (current_part->type == EDJE_PART_TYPE_CAMERA)
- {
- SET_ANGLE_AXIS(Camera, camera)
- }
- else if (current_part->type == EDJE_PART_TYPE_LIGHT)
- {
- SET_ANGLE_AXIS(Light, light)
- }
- else if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- SET_ANGLE_AXIS(Mesh_Node, mesh_node)
- }
- else
- {
- ERR("parse error %s:%i. camera, light and mesh_node attributes in non-CAMERA, non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- quaternion
- @parameters
- [x] [y] [z] [w]
- @effect
- Specifies the axis and arccosinus of half angle to rotate on the MESH_NODE, CAMERA or LIGHT.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_orientation_quaternion(void)
-{
- check_arg_count(4);
-
- if (current_part->type == EDJE_PART_TYPE_CAMERA)
- {
- SET_QUATERNION(Camera, camera)
- }
- else if (current_part->type == EDJE_PART_TYPE_LIGHT)
- {
- SET_QUATERNION(Light, light)
- }
- else if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- SET_QUATERNION(Mesh_Node, mesh_node)
- }
- else
- {
- ERR("parse error %s:%i. camera, light and mesh_node attributes in non-CAMERA, non-LIGHT and non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- scale
- @parameters
- [scale_x] [scale_y] [scale_z]
- @effect
- Specifies the scale parameter for MESH_NODE.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_scale(void)
-{
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.scale_3d.x = FROM_DOUBLE(parse_float_range(0, 0.0, 1000.0));
- ed->mesh_node.scale_3d.y = FROM_DOUBLE(parse_float_range(1, 0.0, 1000.0));
- ed->mesh_node.scale_3d.z = FROM_DOUBLE(parse_float_range(2, 0.0, 1000.0));
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @edcsubsection{collections_group_parts_description_texture,
- Group.Parts.Part.Description.Texture}
- */
-
-/**
- @page edcref
-
- @block
- texture
- @context
- part {
- description {
- ..
- texture {
- image: "file_name";
- wrap1: REPEAT;
- wrap2: REPEAT;
- filter1: NEAREST;
- filter2: NEAREST;
- }
- ..
- }
- }
- @description
- A texture block is used to set texture, this texture will be imposed on
- MESH_NODE model.
- @endblock
- */
-
-static void
-ob_collections_group_parts_part_description_texture(void)
-{
- Edje_Part_Description_Mesh_Node *ed;
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.need_texture = EINA_TRUE;
- }
- else
- {
- ERR("parse error %s:%i. "
- "mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- shade
- image
- @parameters
- [SHADE]
- [texture's filename]
- @effect
- Sets the shade mode for MESH_NODE. Valid shade modes:
- @li COLOR
- @li DIFFUSE
- @li FLAT
- @li PHONG
- @li MAP
- @li RENDER
- Name of image to be used as previously declared in the image block.
- It's required in any mesh_node part.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_texture_image(void)
-{
- Edje_Part_Description_Mesh_Node *ed;
-
- check_arg_count(1);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- char *name;
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.textured = EINA_TRUE;
-
- name = parse_str(0);
- data_queue_image_remove(&(ed->mesh_node.texture.id), &(ed->mesh_node.texture.set));
- data_queue_image_lookup(name, &(ed->mesh_node.texture.id), &(ed->mesh_node.texture.set));
- free(name);
- }
- else
- {
- ERR("parse error %s:%i. "
- "mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- wrap1
- @parameters
- [WRAP]
- @effect
- Sets the wrap mode for S-axis. Valid wrap modes:
- @li CLAMP
- @li REPEAT
- @li REFLECT
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_texture_wrap1(void)
-{
- unsigned int wrap1;
-
- check_arg_count(1);
-
- wrap1 = parse_enum(0,
- "CLAMP", EVAS_CANVAS3D_WRAP_MODE_CLAMP,
- "REPEAT", EVAS_CANVAS3D_WRAP_MODE_REPEAT,
- "REFLECT", EVAS_CANVAS3D_WRAP_MODE_REFLECT,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.wrap1 = wrap1;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- wrap2
- @parameters
- [SHADE]
- @effect
- Sets the wrap mode for T-axis. Valid wrap modes:
- @li CLAMP
- @li REPEAT
- @li REFLECT
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_texture_wrap2(void)
-{
- unsigned int wrap2;
-
- check_arg_count(1);
-
- wrap2 = parse_enum(0,
- "CLAMP", EVAS_CANVAS3D_WRAP_MODE_CLAMP,
- "REPEAT", EVAS_CANVAS3D_WRAP_MODE_REPEAT,
- "REFLECT", EVAS_CANVAS3D_WRAP_MODE_REFLECT,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.wrap2 = wrap2;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- filter1
- @parameters
- [FILTER]
- @effect
- Sets the minification filter used when down-scrolling. Valid filter types:
- @li NEAREST
- @li LINEAR
- @li NEAREST_MIPMAP_NEAREST
- @li LINEAR_MIPMAP_NEAREST
- @li NEAREST_MIPMAP_LINEAR
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_texture_filter1(void)
-{
- unsigned int filter1;
-
- check_arg_count(1);
-
- filter1 = parse_enum(0,
- "NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST,
- "LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR,
- "NEAREST_NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST,
- "LINEAR_NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST,
- "NEAREST_LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR,
- "LINEAR_LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.filter1 = filter1;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- filter2
- @parameters
- [FILTER]
- @effect
- Sets the magnification filter used when down-scrolling. Valid filter types:
- @li NEAREST
- @li LINEAR
- @li NEAREST_MIPMAP_NEAREST
- @li LINEAR_MIPMAP_NEAREST
- @li NEAREST_MIPMAP_LINEAR
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_texture_filter2(void)
-{
- unsigned int filter2;
-
- check_arg_count(1);
-
- filter2 = parse_enum(0,
- "NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST,
- "LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR,
- "NEAREST_NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST,
- "LINEAR_NEAREST", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST,
- "NEAREST_LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR,
- "LINEAR_LINEAR", EVAS_CANVAS3D_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.texture.filter2 = filter2;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @edcsubsection{collections_group_parts_description_mesh,Mesh}
- */
-
-/**
- @page edcref
-
- @block
- mesh
- @context
- part {
- description {
- ..
- mesh {
- geometry: "file_name";
- primitive: CUBE;
- assembly: LINEAR;
- }
- ..
- }
- }
- @description
- @endblock
-
- @property
- primitive
- @parameters
- [PRIMITIVE]
- @effect
- Specifies the type of primitive model to be used.
- Valid primitives:
- @li NONE
- @li CUBE
- @li SPHERE
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_mesh_primitive(void)
-{
- unsigned int primitive;
-
- check_arg_count(1);
-
- primitive = parse_enum(0,
- "NONE", EVAS_CANVAS3D_MESH_PRIMITIVE_NONE,
- "CUBE", EVAS_CANVAS3D_MESH_PRIMITIVE_CUBE,
- "SPHERE", EVAS_CANVAS3D_MESH_PRIMITIVE_SPHERE,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.mesh.primitive = primitive;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- assembly
- @parameters
- [ASSEMBLY]
- @effect
- Sets the vertex assembly of the mesh. Valid assemblies:
- @li POINTS
- @li LINES
- @li LINE_STRIP
- @li LINE_LOOP
- @li TRIANGLES
- @li TRIANGLE_STRIP
- @li TRIANGLE_FAN
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_mesh_assembly(void)
-{
- unsigned int assembly;
-
- check_arg_count(1);
-
- assembly = parse_enum(0,
- "POINTS", EVAS_CANVAS3D_VERTEX_ASSEMBLY_POINTS,
- "LINES", EVAS_CANVAS3D_VERTEX_ASSEMBLY_LINES,
- "LINE_STRIP", EVAS_CANVAS3D_VERTEX_ASSEMBLY_LINE_STRIP,
- "LINE_LOOP", EVAS_CANVAS3D_VERTEX_ASSEMBLY_LINE_LOOP,
- "TRIANGLES", EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLES,
- "TRIANGLE_STRIP", EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLE_STRIP,
- "TRIANGLE_FAN", EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLE_FAN,
- NULL);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.mesh.assembly = assembly;
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-/**
- @page edcref
- @property
- geometry
- @parameters
- [model's filename]
- @effect
- Name of model to be used as previously declared in the model block.
- It's required in any mesh_node part.
- @endproperty
- */
-static void
-st_collections_group_parts_part_description_mesh_geometry(void)
-{
- Edje_Part_Description_Mesh_Node *ed;
-
- check_arg_count(1);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- char *name;
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- name = parse_str(0);
- if (!ecore_file_exists(name))
- {
- ERR("Unable to load model \"%s\". Check if path to file is correct (both directory and file name).",
- name);
- exit(-1);
- }
- data_queue_model_remove(&(ed->mesh_node.mesh.id), &(ed->mesh_node.mesh.set));
- data_queue_model_lookup(name, &(ed->mesh_node.mesh.id), &(ed->mesh_node.mesh.set));
- free(name);
- }
- else
- {
- ERR("parse error %s:%i. "
- "image attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
-
-static void
-st_collections_group_parts_part_description_mesh_frame(void)
-{
- check_arg_count(1);
-
- if (current_part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- Edje_Part_Description_Mesh_Node *ed;
-
- ed = (Edje_Part_Description_Mesh_Node *)current_desc;
-
- ed->mesh_node.mesh.frame = parse_int(0);
- }
- else
- {
- ERR("parse error %s:%i. mesh_node attributes in non-MESH_NODE part.",
- file_in, line - 1);
- exit(-1);
- }
-}
/** @edcsubsection{collections_group_parts_description_physics,
* Group.Parts.Part.Description.Physics} */
@@ -15235,6 +13492,25 @@ st_collections_group_parts_part_description_params_choice(void)
_st_collections_group_parts_part_description_params(EDJE_EXTERNAL_PARAM_TYPE_CHOICE);
}
+static void
+st_collections_group_parts_part_description_vector_frame(void)
+{
+ Edje_Part_Description_Vector *ed;
+
+ check_arg_count(1);
+
+ if (current_part->type != EDJE_PART_TYPE_VECTOR)
+ {
+ ERR("parse error %s:%i. vector attributes in non-VECTOR part.",
+ file_in, line - 1);
+ exit(-1);
+ }
+
+ ed = (Edje_Part_Description_Vector *)current_desc;
+
+ ed->vg.frame = parse_float_range(0, 0.0, 1.0);
+}
+
/** @edcsubsection{collections_group_parts_description_links,
* Group.Parts.Part.Description.Links} */
@@ -15475,7 +13751,6 @@ ob_collections_group_programs_program(void)
ep = mem_alloc(SZ(Edje_Program_Parser));
ep->id = -1;
- ep->source_3d_id = -1;
ep->tween.mode = EDJE_TWEEN_MODE_LINEAR;
ep->tween.use_duration_factor = EINA_FALSE;
ep->after = NULL;
@@ -15747,6 +14022,12 @@ st_collections_group_programs_program_action(void)
"PHYSICS_STOP", EDJE_ACTION_TYPE_PHYSICS_STOP,
"PHYSICS_ROT_SET", EDJE_ACTION_TYPE_PHYSICS_ROT_SET,
"PLAY_VIBRATION", EDJE_ACTION_TYPE_VIBRATION_SAMPLE,
+ "VG_ANIM_STOP", EDJE_ACTION_TYPE_VG_ANIM_STOP,
+ "VG_ANIM_PAUSE", EDJE_ACTION_TYPE_VG_ANIM_PAUSE,
+ "VG_ANIM_RESUME", EDJE_ACTION_TYPE_VG_ANIM_RESUME,
+ "VG_ANIM_PLAY", EDJE_ACTION_TYPE_VG_ANIM_PLAY,
+ "VG_ANIM_REWIND", EDJE_ACTION_TYPE_VG_ANIM_REWIND,
+ "VG_ANIM_LOOP", EDJE_ACTION_TYPE_VG_ANIM_LOOP,
NULL);
if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
{
@@ -15908,6 +14189,12 @@ st_collections_group_programs_program_action(void)
case EDJE_ACTION_TYPE_ACTION_STOP:
case EDJE_ACTION_TYPE_PHYSICS_FORCES_CLEAR:
case EDJE_ACTION_TYPE_PHYSICS_STOP:
+ case EDJE_ACTION_TYPE_VG_ANIM_STOP:
+ case EDJE_ACTION_TYPE_VG_ANIM_PAUSE:
+ case EDJE_ACTION_TYPE_VG_ANIM_RESUME:
+ case EDJE_ACTION_TYPE_VG_ANIM_PLAY:
+ case EDJE_ACTION_TYPE_VG_ANIM_REWIND:
+ case EDJE_ACTION_TYPE_VG_ANIM_LOOP:
check_arg_count(1);
break;
@@ -16187,6 +14474,12 @@ _program_target_add(char *name)
case EDJE_ACTION_TYPE_PHYSICS_STOP:
case EDJE_ACTION_TYPE_PHYSICS_ROT_SET:
#endif
+ case EDJE_ACTION_TYPE_VG_ANIM_STOP:
+ case EDJE_ACTION_TYPE_VG_ANIM_PAUSE:
+ case EDJE_ACTION_TYPE_VG_ANIM_RESUME:
+ case EDJE_ACTION_TYPE_VG_ANIM_PLAY:
+ case EDJE_ACTION_TYPE_VG_ANIM_REWIND:
+ case EDJE_ACTION_TYPE_VG_ANIM_LOOP:
data_queue_part_lookup(pc, name, &(et->id));
break;
@@ -16842,7 +15135,7 @@ edje_cc_handlers_wildcard(void)
if (((!!ed->state.name) != (!!current_desc->state.name)) ||
(ed->state.name && strcmp(ed->state.name, current_desc->state.name)) ||
- (fabs(ed->state.value - st) > DBL_EPSILON)) continue;
+ (!EINA_DBL_EQ(ed->state.value, st))) continue;
current_desc = ed;
break;
}
diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c
index f932eac9e9..57cb438c07 100644
--- a/src/bin/edje/edje_cc_out.c
+++ b/src/bin/edje/edje_cc_out.c
@@ -232,7 +232,6 @@ static Eina_List *program_lookups = NULL;
static Eina_List *group_lookups = NULL;
static Eina_List *face_group_lookups = NULL;
static Eina_List *image_lookups = NULL;
-static Eina_List *model_lookups = NULL;
static Eina_Hash *part_dest_lookup = NULL;
static Eina_Hash *part_pc_dest_lookup = NULL;
@@ -716,13 +715,6 @@ check_program(Edje_Part_Collection *pc, Edje_Program *ep, Eet_File *ef)
Edje_Program_Target *et;
Eina_List *l;
unsigned int i = 0;
- int camera_id = -1;
-
- for (i = 0; (i < pc->parts_count) && (camera_id < 0); i++)
- {
- if (pc->parts[i]->type == EDJE_PART_TYPE_CAMERA)
- camera_id = i;
- }
if ((!ep->targets) && (ep->action == EDJE_ACTION_TYPE_SIGNAL_EMIT))
{
@@ -744,7 +736,8 @@ check_program(Edje_Part_Collection *pc, Edje_Program *ep, Eet_File *ef)
if (et->id >= (int) pc->parts_count)
{
- ERR("Target id '%d' greater than possible index '%d'.", et->id, (int) pc->parts_count - 1);
+ ERR("In group '%s' program '%s', target id '%d' greater than possible index '%d'.",
+ pc->part ? pc->part : "", ep->name ? ep->name : "", et->id, (int) pc->parts_count - 1);
exit(-1);
}
@@ -774,19 +767,6 @@ check_program(Edje_Part_Collection *pc, Edje_Program *ep, Eet_File *ef)
}
}
}
- if (((ep->action == EDJE_ACTION_TYPE_STATE_SET) ||
- (ep->action == EDJE_ACTION_TYPE_SIGNAL_EMIT)) &&
- (et->id < (int)pc->parts_count) &&
- (part->type == EDJE_PART_TYPE_MESH_NODE) &&
- (strstr(ep->signal, "mouse")))
- {
- for (i = 0; (i < pc->parts_count) && (ep->source_3d_id < 0); i++)
- {
- if (!strcmp(pc->parts[i]->name, ep->source))
- ep->source_3d_id = i;
- }
- ep->source = mem_strdup(pc->parts[camera_id]->name);
- }
}
}
@@ -806,9 +786,6 @@ _alias_clean(Edje_Part_Collection_Directory_Entry *ce)
ce->count.TABLE = 0;
ce->count.EXTERNAL = 0;
ce->count.PROXY = 0;
- ce->count.MESH_NODE = 0;
- ce->count.LIGHT = 0;
- ce->count.CAMERA = 0;
ce->count.SPACER = 0;
ce->count.VECTOR = 0;
ce->count.part = 0;
@@ -1416,31 +1393,54 @@ data_write_vectors(Eet_File *ef, int *vector_num)
buf = eina_strbuf_new();
for (i = 0; i < edje_file->image_dir->vectors_count; i++)
{
- if (!beta)
- error_and_abort(ef, "Vector part are currently a beta feature, please enable them by running edje_cc with -beta.");
-
vector = &edje_file->image_dir->vectors[i];
EINA_LIST_FOREACH(img_dirs, ll, s)
{
eina_strbuf_reset(buf);
eina_strbuf_append_printf(buf, "%s" EINA_PATH_SEP_S "%s", s, vector->entry);
- f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
- if (!f) continue;
- eina_file_close(f);
- if (efl_file_set(vg, eina_strbuf_string_get(buf)))
- error_and_abort(ef, "Failed to parse svg : %s", vector->entry);
- if (efl_file_load(vg))
- error_and_abort(ef, "Failed to parse svg : %s", vector->entry);
+ if (vector->type == EDJE_VECTOR_FILE_TYPE_LOTTIE)
+ {
+ char *lottie_data = NULL;
+ int lottie_data_len = 0;
- eina_strbuf_reset(buf);
- eina_strbuf_append_printf(buf, "edje/vectors/%i", vector->id);
- if (!efl_file_save(vg, eet_file_get(ef), eina_strbuf_string_get(buf), NULL))
- error_and_abort(ef, "Failed to write data in Eet for svg :%s", vector->entry);
+ f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
+ if (!f) continue;
- *vector_num += 1;
- found = EINA_TRUE;
- break;
+ lottie_data_len = (int) eina_file_size_get(f);
+ lottie_data = eina_file_map_all(f, EINA_FILE_POPULATE);
+
+ eina_strbuf_reset(buf);
+ eina_strbuf_append_printf(buf, "edje/vectors/%i", vector->id);
+ eet_write(ef, eina_strbuf_string_get(buf), lottie_data, lottie_data_len, EET_COMPRESSION_NONE);
+
+ eina_file_map_free(f, lottie_data);
+ eina_file_close(f);
+
+ *vector_num += 1;
+ found = EINA_TRUE;
+ break;
+ }
+ else
+ {
+ f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
+ if (!f) continue;
+ eina_file_close(f);
+
+ if (efl_file_set(vg, eina_strbuf_string_get(buf)))
+ error_and_abort(ef, "Failed to parse svg : %s", vector->entry);
+ if (efl_file_load(vg))
+ error_and_abort(ef, "Failed to parse svg : %s", vector->entry);
+
+ eina_strbuf_reset(buf);
+ eina_strbuf_append_printf(buf, "edje/vectors/%i", vector->id);
+ if (!efl_file_save(vg, eet_file_get(ef), eina_strbuf_string_get(buf), NULL))
+ error_and_abort(ef, "Failed to write data in Eet for svg :%s", vector->entry);
+
+ *vector_num += 1;
+ found = EINA_TRUE;
+ break;
+ }
}
if (!found)
error_and_abort(ef, "Unable to find the svg :%s", vector->entry);
@@ -1588,39 +1588,6 @@ data_write_images(void)
}
static void
-data_check_models(Eet_File *ef EINA_UNUSED, int *model_num EINA_UNUSED)
-{
- int i;
-
- if (!((edje_file) && (edje_file->model_dir))) return;
-
- for (i = 0; i < (int)edje_file->model_dir->entries_count; i++)
- {
- Edje_Model_Directory_Entry *model;
- Eina_List *ll;
- char *s;
- Eina_Bool file_exist = EINA_FALSE;
-
- model = &edje_file->model_dir->entries[i];
-
- EINA_LIST_FOREACH(model_dirs, ll, s)
- {
- char buf[PATH_MAX];
-
- snprintf(buf, sizeof(buf), "%s/%s", s, model->entry);
-
- file_exist = file_exist || ecore_file_exists(buf);
- }
- if (!file_exist)
- {
- ERR("Unable to load model \"%s\". Check if path to file is correct (both directory and file name).",
- model->entry);
- exit(-1);
- }
- }
-}
-
-static void
data_thread_sounds(void *data, Ecore_Thread *thread EINA_UNUSED)
{
Sound_Write *sw = data;
@@ -1747,7 +1714,7 @@ data_thread_mo(void *data, Ecore_Thread *thread EINA_UNUSED)
Eina_List *ll;
char *dir_path = NULL;
- char mo_path[PATH_MAX];
+ char mo_path[PATH_MAX] = {0};
char moid_str[50];
Eina_File *f = NULL;
void *m = NULL;
@@ -2806,7 +2773,6 @@ data_write(void)
{
Eet_File *ef;
Eet_Error err;
- int model_num = 0;
int sound_num = 0;
int mo_num = 0;
int vibration_num = 0;
@@ -2893,8 +2859,6 @@ data_write(void)
INF("fontmap: %3.5f", ecore_time_get() - t); t = ecore_time_get();
data_write_vectors(ef, &vector_num);
INF("vectors: %3.5f", ecore_time_get() - t); t = ecore_time_get();
- data_check_models(ef, &model_num);
- INF("models: %3.5f", ecore_time_get() - t); t = ecore_time_get();
data_write_fonts(ef, &font_num);
INF("fonts: %3.5f", ecore_time_get() - t); t = ecore_time_get();
data_write_sounds(ef, &sound_num);
@@ -3486,49 +3450,6 @@ data_queue_image_remove(int *dest, Eina_Bool *set)
}
void
-data_queue_model_lookup(char *name, int *dest, Eina_Bool *set)
-{
- Image_Lookup *il;
-
- il = mem_alloc(SZ(Image_Lookup));
- model_lookups = eina_list_append(model_lookups, il);
- il->name = mem_strdup(name);
- il->dest = dest;
- il->set = set;
-}
-
-void
-data_queue_model_remove(int *dest, Eina_Bool *set)
-{
- Eina_List *l;
- Image_Lookup *il;
-
- EINA_LIST_FOREACH(model_lookups, l, il)
- {
- if (il->dest == dest && il->set == set)
- {
- model_lookups = eina_list_remove_list(model_lookups, l);
- free(il->name);
- free(il);
- return;
- }
- }
-}
-
-void
-data_queue_copied_model_lookup(int *src, int *dest, Eina_Bool *set)
-{
- Eina_List *l;
- Image_Lookup *il;
-
- EINA_LIST_FOREACH(model_lookups, l, il)
- {
- if (il->dest == src)
- data_queue_model_lookup(il->name, dest, set);
- }
-}
-
-void
data_queue_copied_image_lookup(int *src, int *dest, Eina_Bool *set)
{
Eina_List *l;
@@ -3582,7 +3503,7 @@ _data_image_h_size_compare_cb(const void *data1, const void *data2)
}
static void
-_data_image_sets_size_set()
+_data_image_sets_size_set(void)
{
Evas *evas;
Edje_Image_Directory_Set *set;
@@ -3689,7 +3610,6 @@ _data_image_id_update(Eina_List *images_unused_list)
Edje_Part_Collection *pc;
Edje_Part *part;
Edje_Part_Description_Image *part_desc_image;
- Edje_Part_Description_Mesh_Node *part_desc_mesh_node;
Edje_Part_Image_Id *tween_id;
unsigned int i, j, desc_it;
Eina_List *l, *l2, *l3;
@@ -3716,15 +3636,6 @@ _data_image_id_update(Eina_List *images_unused_list)
} \
}
-#define PART_DESC_PROXY_ID_UPDATE \
- EINA_LIST_FOREACH(images_unused_list, l3, iui) \
- { \
- if ((iui) && (part_desc_mesh_node->mesh_node.texture.id == iui->old_id)) \
- { \
- part_desc_mesh_node->mesh_node.texture.id = iui->new_id; \
- break; \
- } \
- }
EINA_LIST_FOREACH_SAFE(edje_collections, l, l2, pc)
{
for (i = 0; i < pc->parts_count; i++)
@@ -3741,17 +3652,6 @@ _data_image_id_update(Eina_List *images_unused_list)
PART_DESC_IMAGE_ID_UPDATE
}
}
- else if (part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- part_desc_mesh_node = (Edje_Part_Description_Mesh_Node *)part->default_desc;
- if (!part_desc_mesh_node) continue;
- PART_DESC_PROXY_ID_UPDATE
- for (j = 0; j < part->other.desc_count; j++)
- {
- part_desc_mesh_node = (Edje_Part_Description_Mesh_Node *)part->other.desc[j];
- PART_DESC_PROXY_ID_UPDATE
- }
- }
}
}
for (i = 0; i < edje_file->image_dir->sets_count; i++)
@@ -3774,46 +3674,6 @@ _data_image_id_update(Eina_List *images_unused_list)
}
}
-static void
-_data_model_id_update(Eina_List *models_unused_list)
-{
- Image_Unused_Ids *iui;
- Edje_Part_Collection *pc;
- Edje_Part *part;
- Edje_Part_Description_Mesh_Node *part_desc_mesh_node;
- unsigned int i, j;
- Eina_List *l, *l2, *l3;
-
-#define PART_DESC_MODEL_ID_UPDATE \
- EINA_LIST_FOREACH(models_unused_list, l3, iui) \
- { \
- if ((iui) && (part_desc_mesh_node->mesh_node.mesh.id == iui->old_id)) \
- { \
- part_desc_mesh_node->mesh_node.mesh.id = iui->new_id; \
- break; \
- } \
- } \
-
- EINA_LIST_FOREACH_SAFE(edje_collections, l, l2, pc)
- {
- for (i = 0; i < pc->parts_count; i++)
- {
- part = pc->parts[i];
- if (part->type == EDJE_PART_TYPE_MESH_NODE)
- {
- part_desc_mesh_node = (Edje_Part_Description_Mesh_Node *)part->default_desc;
- if (!part_desc_mesh_node) continue;
- PART_DESC_MODEL_ID_UPDATE
- for (j = 0; j < part->other.desc_count; j++)
- {
- part_desc_mesh_node = (Edje_Part_Description_Mesh_Node *)part->other.desc[j];
- PART_DESC_MODEL_ID_UPDATE
- }
- }
- }
- }
-}
-
void
data_process_lookups(void)
{
@@ -3823,11 +3683,9 @@ data_process_lookups(void)
Program_Lookup *program;
Group_Lookup *group;
Image_Lookup *image;
- Image_Lookup *model;
Eina_List *l2;
Eina_List *l;
Eina_Hash *images_in_use;
- Eina_Hash *models_in_use;
char *group_name;
Eina_Bool is_lua = EINA_FALSE;
Image_Unused_Ids *iui;
@@ -4153,7 +4011,7 @@ free_group:
if (edje_file->image_dir && !is_lua)
{
Edje_Image_Directory_Entry *de, *de_last, *img;
- Edje_Image_Directory_Set *set, *set_last, *set_realloc;
+ Edje_Image_Directory_Set *set;
Edje_Image_Directory_Set_Entry *set_e;
Eina_List *images_unused_list = NULL;
unsigned int i;
@@ -4165,11 +4023,12 @@ free_group:
if (de->entry && eina_hash_find(images_in_use, de->entry))
continue;
+ printf("Warning: Image '%s' not used\n", de->entry);
INF("Image '%s' in resource 'edje/image/%i' will not be included as it is unused.",
de->entry, de->id);
- /* so as not to write the unused images, moved last image in the
- list to unused image position and check it */
+ // so as not to write the unused images, moved last image in the
+ // list to unused image position and check it
free((void *)de->entry);
de->entry = NULL;
de_last = edje_file->image_dir->entries + edje_file->image_dir->entries_count - 1;
@@ -4178,8 +4037,8 @@ free_group:
images_unused_list = eina_list_append(images_unused_list, iui);
iui->new_id = i;
de_last->id = i;
- memcpy(de, de_last, sizeof (Edje_Image_Directory_Entry));
- --i; /* need to check a moved image on this index */
+ memcpy(de, de_last, sizeof(Edje_Image_Directory_Entry));
+ --i; // need to check a moved image on this index
edje_file->image_dir->entries_count--;
img = realloc(edje_file->image_dir->entries,
sizeof (Edje_Image_Directory_Entry) * edje_file->image_dir->entries_count);
@@ -4193,6 +4052,17 @@ free_group:
if (set->name && eina_hash_find(images_in_use, set->name))
continue;
+ printf("Warning: Image set '%s' not used\n", set->name);
+ EINA_LIST_FOREACH(set->entries, l, set_e)
+ {
+ printf(" Contains '%s' size %ix%i -> %ix%i\n",
+ set_e->name,
+ set_e->size.min.w, set_e->size.min.h,
+ set_e->size.max.w, set_e->size.max.h);
+ }
+/* No need to redo id's - we will warn of unused images - fix in src
+ * Also .. this is broken and messes up id's ... so easyer - complain
+ * to develoepr to clean up the theme...
INF("Set '%s' will not be included as it is unused.", set->name);
free((void *)set->name);
@@ -4214,6 +4084,7 @@ free_group:
set_realloc = realloc(edje_file->image_dir->sets,
sizeof(Edje_Image_Directory_Set) * edje_file->image_dir->sets_count);
edje_file->image_dir->sets = set_realloc;
+ */
}
/* update image id in parts */
@@ -4225,86 +4096,6 @@ free_group:
}
eina_hash_free(images_in_use);
-
- models_in_use = eina_hash_string_superfast_new(NULL);
-
- EINA_LIST_FREE(model_lookups, model)
- {
- Eina_Bool find = EINA_FALSE;
-
- if (edje_file->model_dir)
- {
- Edje_Model_Directory_Entry *de;
- unsigned int i;
-
- for (i = 0; i < edje_file->model_dir->entries_count; ++i)
- {
- de = edje_file->model_dir->entries + i;
-
- if ((de->entry) && (!strcmp(de->entry, model->name)))
- {
- *(model->dest) = de->id;
- *(model->set) = EINA_FALSE;
- find = EINA_TRUE;
-
- if (!eina_hash_find(models_in_use, model->name))
- eina_hash_direct_add(models_in_use, de->entry, de);
- break;
- }
- }
- }
-
- if (!find)
- {
- ERR("Unable to find model name \"%s\".", model->name);
- exit(-1);
- }
-
- free(model->name);
- free(model);
- }
-
- if (edje_file->model_dir && !is_lua)
- {
- Edje_Model_Directory_Entry *de, *de_last, *mdl;
- Eina_List *models_unused_list = NULL;
- unsigned int i;
-
- for (i = 0; i < edje_file->model_dir->entries_count; ++i)
- {
- de = edje_file->model_dir->entries + i;
-
- if (de->entry && eina_hash_find(models_in_use, de->entry))
- continue;
-
- INF("Model '%s' in resource 'edje/model/%i' will not be included as it is unused.",
- de->entry, de->id);
-
- /* so as not to write the unused models, moved last model in the
- list to unused model position and check it */
- free((void *)de->entry);
- de->entry = NULL;
- de_last = edje_file->model_dir->entries + edje_file->model_dir->entries_count - 1;
- iui = mem_alloc(SZ(Image_Unused_Ids));
- iui->old_id = de_last->id;
- models_unused_list = eina_list_append(models_unused_list, iui);
- iui->new_id = i;
- de_last->id = i;
- memcpy(de, de_last, sizeof (Edje_Model_Directory_Entry));
- --i; /* need to check a moved model on this index */
- edje_file->model_dir->entries_count--;
- mdl = realloc(edje_file->model_dir->entries,
- sizeof (Edje_Model_Directory_Entry) * edje_file->model_dir->entries_count);
- edje_file->model_dir->entries = mdl;
- }
-
- /* update model id in parts */
- if (models_unused_list) _data_model_id_update(models_unused_list);
- EINA_LIST_FREE(models_unused_list, iui)
- free(iui);
- }
-
- eina_hash_free(models_in_use);
}
static void
diff --git a/src/bin/edje/edje_cc_parse.c b/src/bin/edje/edje_cc_parse.c
index ad1a2c95ac..32d06350e3 100644
--- a/src/bin/edje/edje_cc_parse.c
+++ b/src/bin/edje/edje_cc_parse.c
@@ -30,6 +30,9 @@
#define EDJE_1_21_SUPPORTED " -DEFL_VERSION_1_21=1 "
#define EDJE_1_22_SUPPORTED " -DEFL_VERSION_1_22=1 "
#define EDJE_1_23_SUPPORTED " -DEFL_VERSION_1_23=1 "
+#define EDJE_1_24_SUPPORTED " -DEFL_VERSION_1_24=1 "
+#define EDJE_1_25_SUPPORTED " -DEFL_VERSION_1_25=1 "
+#define EDJE_1_26_SUPPORTED " -DEFL_VERSION_1_26=1 "
#define EDJE_CC_EFL_VERSION_SUPPORTED \
EDJE_1_18_SUPPORTED \
@@ -37,7 +40,10 @@
EDJE_1_20_SUPPORTED \
EDJE_1_21_SUPPORTED \
EDJE_1_22_SUPPORTED \
- EDJE_1_23_SUPPORTED
+ EDJE_1_23_SUPPORTED \
+ EDJE_1_24_SUPPORTED \
+ EDJE_1_25_SUPPORTED \
+ EDJE_1_26_SUPPORTED
static void new_object(void);
static void new_statement(void);
@@ -1944,7 +1950,7 @@ _calcf(char op, double a, double b)
return a;
case '/':
- if (b != 0) a /= b;
+ if (EINA_DBL_NONZERO(b)) a /= b;
else
ERR("%s:%i divide by zero", file_in, line - 1);
return a;
@@ -1954,7 +1960,7 @@ _calcf(char op, double a, double b)
return a;
case '%':
- if (0 != b) a = (double)((int)a % (int)b);
+ if (EINA_DBL_NONZERO(b)) a = (double)((int)a % (int)b);
else
ERR("%s:%i modula by zero", file_in, line - 1);
return a;
diff --git a/src/bin/edje/edje_external_inspector.c b/src/bin/edje/edje_external_inspector.c
index 3a4f937b06..718c02fc74 100644
--- a/src/bin/edje/edje_external_inspector.c
+++ b/src/bin/edje/edje_external_inspector.c
@@ -614,9 +614,7 @@ main(int argc, char **argv)
ecore_app_no_system_modules();
- ecore_init();
eina_init();
- edje_init();
_log_dom = eina_log_domain_register
("edje_external_inspector", EINA_COLOR_YELLOW);
@@ -628,6 +626,8 @@ main(int argc, char **argv)
goto error_log;
}
+ edje_init();
+
arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
if (arg_index < 0)
{
@@ -670,10 +670,9 @@ main(int argc, char **argv)
free(module_patterns_str);
error_getopt:
+ edje_shutdown();
eina_log_domain_unregister(_log_dom);
error_log:
- edje_shutdown();
- ecore_shutdown();
eina_shutdown();
return ret;
diff --git a/src/bin/edje/edje_multisense_convert.c b/src/bin/edje/edje_multisense_convert.c
index 50576efab2..3c8046037b 100644
--- a/src/bin/edje/edje_multisense_convert.c
+++ b/src/bin/edje/edje_multisense_convert.c
@@ -256,7 +256,6 @@ _edje_multisense_encode_to_ogg_vorbis(char *snd_path, double quality, SF_INFO sf
vorbis_analysis_init(&vd, &vi);
vorbis_block_init(&vd, &vb);
- srand(time(NULL));
ogg_stream_init(&os, rand());
ogg_packet header;
diff --git a/src/bin/edje/edje_player.c b/src/bin/edje/edje_player.c
index cacfdf2974..7d79ec0d7a 100644
--- a/src/bin/edje/edje_player.c
+++ b/src/bin/edje/edje_player.c
@@ -31,12 +31,16 @@ struct opts
Eina_Bool print;
Eina_Bool slave_mode;
double scale;
+ int pad;
char *title;
};
static Eina_Bool _edje_load_or_show_error(Evas_Object *edje, const char *file, const char *group);
static Ecore_Evas *win;
+static Evas *evas;
+static Evas_Object *bg, *bg2 = NULL, *edje;
+static struct opts opts;
static void
_win_title_set(const char *group, const char *file)
@@ -754,71 +758,37 @@ _print_message(void *data EINA_UNUSED, Evas_Object *edje EINA_UNUSED, Edje_Messa
}
static void
-_reset_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *stack, void *event_info EINA_UNUSED)
-{
- Evas_Coord minw, minh;
- Evas_Object *edje = data;
-
- edje_object_size_min_get(edje, &minw, &minh);
- if ((minw <= 0) && (minh <= 0))
- edje_object_size_min_calc(edje, &minw, &minh);
-
- evas_object_size_hint_min_set(stack, minw, minh);
-}
-
-static void
-_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *stack EINA_UNUSED, void *event_info)
+_key_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Evas_Event_Key_Down *ev = event_info;
- struct opts *opts = data;
if ((!strcmp(ev->keyname, "equal")) ||
(!strcmp(ev->keyname, "plus")))
- opts->scale += 0.1;
+ opts.scale += 0.1;
else if ((!strcmp(ev->keyname, "minus")) ||
(!strcmp(ev->keyname, "underscore")))
- opts->scale -= 0.1;
+ opts.scale -= 0.1;
else if ((!strcmp(ev->keyname, "0")))
- opts->scale = 1.0;
- if (opts->scale < 0.1) opts->scale = 0.1;
- else if (opts->scale > 10.0)
- opts->scale = 1.0;
- edje_scale_set(opts->scale);
-}
-
-static Evas_Object *
-_create_stack(Evas *evas, const struct opts *opts)
-{
- Evas_Object *stack = evas_object_box_add(evas);
- if (!stack)
- {
- fputs("ERROR: could not create object stack (box).\n", stderr);
- return NULL;
- }
- evas_object_box_layout_set(stack, evas_object_box_layout_stack, NULL, NULL);
- evas_object_resize(stack, opts->size.w, opts->size.h);
- evas_object_size_hint_weight_set(stack, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(stack, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(stack);
- return stack;
+ opts.scale = 1.0;
+ if (opts.scale < 0.1) opts.scale = 0.1;
+ else if (opts.scale > 10.0)
+ opts.scale = 10.0;
+ edje_scale_set(opts.scale);
}
static Evas_Object *
-_create_bg(Evas *evas, const struct opts *opts)
+_create_bg(void)
{
- const unsigned char *color = opts->color;
- Evas_Object *bg = evas_object_rectangle_add(evas);
- if (!bg)
+ const unsigned char *color = opts.color;
+ Evas_Object *o = evas_object_rectangle_add(evas);
+ if (!o)
{
fputs("ERROR: could not create background.\n", stderr);
return NULL;
}
- evas_object_resize(bg, opts->size.w, opts->size.h);
- evas_object_color_set(bg, color[0], color[1], color[2], 255);
- evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(bg);
- return bg;
+ evas_object_color_set(o, color[0], color[1], color[2], 255);
+ evas_object_show(o);
+ return o;
}
static void
@@ -827,7 +797,6 @@ _edje_reload(void *data EINA_UNUSED, Evas_Object *obj, const char *emission EINA
const char *file;
const char *group;
edje_object_signal_callback_del(obj, "edje,change,file", "edje", _edje_reload);
-
edje_object_file_get(obj, &file, &group);
_edje_load_or_show_error(obj, file, group);
}
@@ -862,32 +831,14 @@ _edje_load_or_show_error(Evas_Object *edje, const char *file, const char *group)
Eina_File *f = NULL;
const char *errmsg;
int err;
- Evas_Canvas3D_Scene *scene = NULL;
- Evas_Canvas3D_Node *root_node = NULL;
f = eina_file_open(file, EINA_FALSE);
- if (!(edje_mmap_3d_has(f, group)))
+ if (edje_object_file_set(edje, file, group))
{
- if (edje_object_file_set(edje, file, group))
- {
- edje_object_signal_callback_add(edje, "edje,change,file", "edje", _edje_reload, NULL);
- evas_object_focus_set(edje, EINA_TRUE);
- eina_file_close(f);
- return EINA_TRUE;
- }
- }
- else
- {
- if (edje_object_file_set(edje, file, group))
- {
- if (edje_3d_object_add(edje, &root_node, scene))
- {
- edje_object_signal_callback_add(edje, "edje,change,file", "edje", _edje_reload, NULL);
- evas_object_focus_set(edje, EINA_TRUE);
- eina_file_close(f);
- return EINA_TRUE;
- }
- }
+ edje_object_signal_callback_add(edje, "edje,change,file", "edje", _edje_reload, NULL);
+ evas_object_focus_set(edje, EINA_TRUE);
+ eina_file_close(f);
+ return EINA_TRUE;
}
err = edje_object_load_error_get(edje);
@@ -899,73 +850,73 @@ _edje_load_or_show_error(Evas_Object *edje, const char *file, const char *group)
}
static Evas_Object *
-_create_edje(Evas *evas, const struct opts *opts)
+_create_edje(void)
{
Evas_Coord minw, minh, maxw, maxh;
- Evas_Object *edje = edje_object_add(evas);
- if (!edje)
+ Evas_Object *o = edje_object_add(evas);
+ if (!o)
{
fputs("ERROR: could not create edje.\n", stderr);
return NULL;
}
- if (opts->group)
+ if (opts.group)
{
- if (!_edje_load_or_show_error(edje, opts->file, opts->group))
+ if (!_edje_load_or_show_error(o, opts.file, opts.group))
{
evas_object_del(edje);
return NULL;
}
- if (!opts->title) _win_title_set(opts->group, opts->file);
+ if (!opts.title) _win_title_set(opts.group, opts.file);
}
else
{
- if (edje_file_group_exists(opts->file, "main"))
+ if (edje_file_group_exists(opts.file, "main"))
{
- if (!_edje_load_or_show_error(edje, opts->file, "main"))
+ if (!_edje_load_or_show_error(o, opts.file, "main"))
{
evas_object_del(edje);
return NULL;
}
- if (!opts->title) _win_title_set("main", opts->file);
+ if (!opts.title) _win_title_set("main", opts.file);
}
else
{
- Eina_List *groups = edje_file_collection_list(opts->file);
+ Eina_List *groups = edje_file_collection_list(opts.file);
const char *group;
if (!groups)
{
fprintf(stderr, "ERROR: file '%s' has no groups!\n",
- opts->file);
+ opts.file);
evas_object_del(edje);
return NULL;
}
group = groups->data;
- if (!_edje_load_or_show_error(edje, opts->file, group))
+ if (!_edje_load_or_show_error(o, opts.file, group))
{
edje_file_collection_list_free(groups);
evas_object_del(edje);
return NULL;
}
- if (!opts->title) _win_title_set(group, opts->file);
+ if (!opts.title) _win_title_set(group, opts.file);
edje_file_collection_list_free(groups);
}
}
- evas_object_smart_callback_add(edje, "circular,dependency", _edje_circul, opts->group);
+ evas_object_smart_callback_add(o, "circular,dependency", _edje_circul, opts.group);
- edje_object_size_max_get(edje, &maxw, &maxh);
- edje_object_size_min_get(edje, &minw, &minh);
+ edje_object_size_max_get(o, &maxw, &maxh);
+ edje_object_size_min_get(o, &minw, &minh);
if ((minw <= 0) && (minh <= 0))
- edje_object_size_min_calc(edje, &minw, &minh);
+ edje_object_size_min_calc(o, &minw, &minh);
- evas_object_size_hint_max_set(edje, maxw, maxh);
- evas_object_size_hint_min_set(edje, minw, minh);
+ ecore_evas_size_max_set(win,
+ maxw > 0 ? (maxw + opts.pad * 2) : 0,
+ maxh > 0 ? (maxh + opts.pad * 2) : 0);
+ ecore_evas_size_min_set(win, (minw + opts.pad * 2), (minh + opts.pad * 2));
- evas_object_size_hint_weight_set(edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(edje);
+ evas_object_show(o);
- return edje;
+ return o;
}
static unsigned char
@@ -988,6 +939,18 @@ _cb_delete(EINA_UNUSED Ecore_Evas *ee)
ecore_main_loop_quit();
}
+static void
+_cb_resize(Ecore_Evas *ee)
+{
+ int w, h;
+ ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+ evas_object_move(edje, opts.pad, opts.pad);
+ evas_object_resize(edje, w - (opts.pad * 2), h - (opts.pad * 2));
+ evas_object_move(bg, opts.pad, opts.pad);
+ evas_object_resize(bg, w - (opts.pad * 2), h - (opts.pad * 2));
+ if (bg2) evas_object_resize(bg2, w, h);
+}
+
const Ecore_Getopt optdesc = {
"edje_player",
"%prog [options] <filename.edj>",
@@ -1010,8 +973,8 @@ const Ecore_Getopt optdesc = {
('Z', "size", "size to use in wxh form.", "WxH",
ecore_getopt_callback_size_parse, NULL),
ECORE_GETOPT_CALLBACK_ARGS
- ('c', "bg-color", "Color of the background (if not shaped or alpha)",
- "RRGGBB", _parse_color, NULL),
+ ('c', "bg-color", "Color of the background (if not shaped or alpha) e.g. 255,150,50",
+ "R,G,B", _parse_color, NULL),
ECORE_GETOPT_STORE_TRUE
('b', "borderless", "Display window without border."),
ECORE_GETOPT_STORE_TRUE
@@ -1029,6 +992,8 @@ const Ecore_Getopt optdesc = {
('S', "slave-mode", "Listen for commands on stdin"),
ECORE_GETOPT_STORE_DOUBLE
('z', "scale", "Set scale factor"),
+ ECORE_GETOPT_STORE_INT
+ ('P', "pad", "Set pixel padding around object"),
ECORE_GETOPT_LICENSE('L', "license"),
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
ECORE_GETOPT_VERSION('V', "version"),
@@ -1040,13 +1005,9 @@ const Ecore_Getopt optdesc = {
int
main(int argc, char **argv)
{
- Evas *evas;
- Evas_Object *stack, *edje;
- struct opts opts;
Eina_Bool quit_option = EINA_FALSE;
int args;
Eina_List *groups;
- Eina_File *f = NULL;
const char *group;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_STR(opts.group),
@@ -1063,6 +1024,7 @@ main(int argc, char **argv)
ECORE_GETOPT_VALUE_BOOL(opts.print),
ECORE_GETOPT_VALUE_BOOL(opts.slave_mode),
ECORE_GETOPT_VALUE_DOUBLE(opts.scale),
+ ECORE_GETOPT_VALUE_INT(opts.pad),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
ECORE_GETOPT_VALUE_BOOL(quit_option),
@@ -1119,33 +1081,6 @@ main(int argc, char **argv)
goto end;
}
- group = eina_list_data_get(eina_list_last(groups));
-
- f = eina_file_open(opts.file, EINA_FALSE);
- if (edje_mmap_3d_has(f, group))
- {
- Eina_List *engine_list, *n;
- Eina_Bool opengl_x11_has = EINA_FALSE, wayland_egl_has = EINA_FALSE;
- const char *engine;
- engine_list = ecore_evas_engines_get();
- EINA_LIST_FOREACH(engine_list, n, engine)
- {
- if (!strcmp(engine, "wayland_egl"))
- {
- wayland_egl_has = EINA_TRUE;
- break;
- }
- else if (!strcmp(engine, "opengl_x11"))
- opengl_x11_has = EINA_TRUE;
- }
- if (wayland_egl_has)
- opts.engine = "wayland_egl";
- else if (opengl_x11_has)
- opts.engine = "opengl_x11";
- }
- eina_file_close(f);
- edje_file_collection_list_free(groups);
-
if (opts.size.w <= 0) opts.size.w = 320;
if (opts.size.h <= 0) opts.size.h = 240;
win = ecore_evas_new(opts.engine, 0, 0, opts.size.w, opts.size.h, NULL);
@@ -1160,37 +1095,32 @@ main(int argc, char **argv)
ecore_evas_callback_delete_request_set(win, _cb_delete);
evas = ecore_evas_get(win);
- stack = _create_stack(evas, &opts);
- if (!stack)
- {
- goto free_ecore_evas;
- }
-
- ecore_evas_object_associate(win, stack, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
if (opts.alpha)
ecore_evas_alpha_set(win, EINA_TRUE);
else if (opts.shaped)
ecore_evas_shaped_set(win, EINA_TRUE);
- else
- {
- Evas_Object *bg = _create_bg(evas, &opts);
- if (bg) evas_object_box_append(stack, bg);
- }
- edje = _create_edje(evas, &opts);
- if (edje)
- evas_object_box_append(stack, edje);
- else
+ if (opts.pad > 0)
{
- goto free_ecore_evas;
+ bg2 = evas_object_rectangle_add(evas);
+ evas_object_resize(bg2, opts.size.w, opts.size.h);
+ if (opts.alpha)
+ evas_object_color_set(bg2, 0, 0, 0, 64);
+ else
+ evas_object_color_set(bg2, 64, 64, 64, 255);
+ evas_object_show(bg2);
}
+ bg = _create_bg();
+
+ edje = _create_edje();
+ if (!edje) goto free_ecore_evas;
- evas_object_focus_set(stack, EINA_TRUE);
- evas_object_event_callback_add(stack, EVAS_CALLBACK_KEY_DOWN,
+ ecore_evas_callback_resize_set(win, _cb_resize);
+ _cb_resize(win);
+ evas_object_focus_set(bg, EINA_TRUE);
+ evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN,
_key_down, &opts);
- evas_object_event_callback_add(stack, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
- _reset_size_hints, edje);
if (opts.print)
{
diff --git a/src/bin/edje/meson.build b/src/bin/edje/meson.build
index 0fff2cd6dc..e715571852 100644
--- a/src/bin/edje/meson.build
+++ b/src/bin/edje/meson.build
@@ -6,7 +6,8 @@ edje_bin_deps = [
ecore_file, ecore_input,
ecore_imf, ecore_imf_evas,
embryo, efreet, eio,
- edje, ecore_evas
+ edje, ecore_evas,
+ intl,
]
edje_cc_src = [
@@ -30,6 +31,11 @@ edje_cc = executable('edje_cc',
link_args : bin_linker_args
)
+asan_option =[]
+if get_option('b_sanitize') == 'address'
+ asan_option= 'ASAN_OPTIONS=detect_leaks=0'
+endif
+
if meson.is_cross_build()
_edje_cc = find_program('edje_cc', native: true)
edje_cc_path = _edje_cc.path()
@@ -39,8 +45,7 @@ else
if sys_windows == true
edje_cc_exe = [edje_cc.full_path()]
else
- env = find_program('env', native: true)
- edje_cc_exe = [env, 'EFL_RUN_IN_TREE=1', edje_cc.full_path()]
+ edje_cc_exe = [env, asan_option, 'EFL_RUN_IN_TREE=1', edje_cc.full_path()]
endif
edje_depends = [edje_cc, epp, evas_engine_buffer_mod, embryo_cc]
endif
@@ -92,8 +97,7 @@ if meson.is_cross_build()
edje_codegen_path = _edje_codegen.path()
edje_codegen_exe = [_edje_codegen]
else
- env = find_program('env', native: true)
- edje_codegen_exe = [env, 'EFL_RUN_IN_TREE=1', edje_codegen.full_path()]
+ edje_codegen_exe = [env, asan_option, 'EFL_RUN_IN_TREE=1', edje_codegen.full_path()]
endif
edje_pick = executable('edje_pick',
diff --git a/src/bin/eet/eet_main.c b/src/bin/eet/eet_main.c
index 7da5cfd4d3..8061dd956e 100644
--- a/src/bin/eet/eet_main.c
+++ b/src/bin/eet/eet_main.c
@@ -440,17 +440,6 @@ int
main(int argc,
char **argv)
{
- if (!eet_init())
- return -1;
-
- _eet_main_log_dom = eina_log_domain_register("eet_main", EINA_COLOR_CYAN);
- if(_eet_main_log_dom < -1)
- {
- EINA_LOG_ERR("Impossible to create a log domain for eet_main.");
- eet_shutdown();
- return -1;
- }
-
if (argc < 2)
{
help:
@@ -468,6 +457,17 @@ help:
" eet -h print out this help message\n"
" eet -V [--version] show program version\n"
);
+
+ return -1;
+ }
+
+ if (!eet_init())
+ return -1;
+
+ _eet_main_log_dom = eina_log_domain_register("eet_main", EINA_COLOR_CYAN);
+ if(_eet_main_log_dom < -1)
+ {
+ EINA_LOG_ERR("Impossible to create a log domain for eet_main.");
eet_shutdown();
return -1;
}
diff --git a/src/bin/eeze/eeze_mount/eeze_mount.c b/src/bin/eeze/eeze_mount/eeze_mount.c
index 04c644f4ef..9e9dd16cdd 100644
--- a/src/bin/eeze/eeze_mount/eeze_mount.c
+++ b/src/bin/eeze/eeze_mount/eeze_mount.c
@@ -109,7 +109,7 @@ main(int argc, char *argv[])
if (argc - args > 1)
{
eeze_disk_mount_point_set(disk, mount_point);
- if (eina_str_has_extension(dev, "iso"))
+ if (eina_str_has_extension(dev, ".iso"))
{
int f;
f = eeze_disk_mountopts_get(disk);
diff --git a/src/bin/efl/efl_debug.c b/src/bin/efl/efl_debug.c
index f7829c6545..7cf9768115 100644
--- a/src/bin/efl/efl_debug.c
+++ b/src/bin/efl/efl_debug.c
@@ -254,7 +254,6 @@ EINA_DEBUG_OPCODES_ARRAY_DEFINE(ops,
int
main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
- eina_init();
ecore_init();
my_argc = argc;
@@ -271,7 +270,6 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
ecore_main_loop_begin();
ecore_shutdown();
- eina_shutdown();
return 0;
}
diff --git a/src/bin/efl/efl_debugd.c b/src/bin/efl/efl_debugd.c
index b23db7544c..84f789254b 100644
--- a/src/bin/efl/efl_debugd.c
+++ b/src/bin/efl/efl_debugd.c
@@ -663,11 +663,11 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
ecore_app_no_system_modules();
eina_init();
+ _log_dom = eina_log_domain_register("efl_debugd", EINA_COLOR_CYAN);
ecore_init();
ecore_con_init();
_retval = EXIT_SUCCESS;
- _log_dom = eina_log_domain_register("efl_debugd", EINA_COLOR_CYAN);
_string_to_opcode_hash = eina_hash_string_superfast_new(NULL);
_opcode_register("Daemon/opcode_register", EINA_DEBUG_OPCODE_REGISTER, _opcode_register_cb);
@@ -683,6 +683,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
ecore_con_shutdown();
ecore_shutdown();
+ eina_log_domain_unregister(_log_dom);
eina_shutdown();
return _retval;
diff --git a/src/bin/efl_wl/efl_wl_test.c b/src/bin/efl_canvas_wl/efl_canvas_wl_test.c
index bf5b2ad4d1..6bedb9ce47 100644
--- a/src/bin/efl_wl/efl_wl_test.c
+++ b/src/bin/efl_canvas_wl/efl_canvas_wl_test.c
@@ -1,18 +1,17 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include "Efl_Wl.h"
+#include "Efl_Canvas_Wl.h"
#include "Elementary.h"
static Evas_Object *win;
static Eina_Strbuf *buf;
-static Ecore_Exe *exe;
+static Eo *exe;
-static Eina_Bool
-del_handler(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Del *ev)
+static void
+del_handler(void *d EINA_UNUSED, const Efl_Event *ev)
{
- if (ev->exe == exe) ecore_main_loop_quit();
- return ECORE_CALLBACK_RENEW;
+ if (ev->object == exe) ecore_main_loop_quit();
}
static void
@@ -24,8 +23,8 @@ focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev
static Eina_Bool
dostuff(void *data)
{
- exe = efl_wl_run(data, eina_strbuf_string_get(buf));
- ecore_event_handler_add(ECORE_EXE_EVENT_DEL, (Ecore_Event_Handler_Cb)del_handler, NULL);
+ exe = efl_canvas_wl_run(data, eina_strbuf_string_get(buf));
+ efl_event_callback_add(exe, EFL_TASK_EVENT_EXIT, del_handler, NULL);
evas_object_focus_set(data, 1);
return EINA_FALSE;
}
@@ -63,9 +62,9 @@ main(int argc, char *argv[])
elm_win_autodel_set(win, 1);
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
- o = efl_wl_add(evas_object_evas_get(win));
- efl_wl_aspect_set(o, 1);
- efl_wl_minmax_set(o, 1);
+ o = efl_add(EFL_CANVAS_WL_CLASS, win);
+ efl_canvas_wl_aspect_propagate_set(o, 1);
+ efl_canvas_wl_minmax_propagate_set(o, 1);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_event_callback_add(o, EVAS_CALLBACK_CHANGED_SIZE_HINTS, hints_changed, win);
diff --git a/src/bin/efl_wl/efl_wl_test_stack.c b/src/bin/efl_canvas_wl/efl_canvas_wl_test_stack.c
index 51cd598984..49849e07e8 100644
--- a/src/bin/efl_wl/efl_wl_test_stack.c
+++ b/src/bin/efl_canvas_wl/efl_canvas_wl_test_stack.c
@@ -1,7 +1,7 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include "Efl_Wl.h"
+#include "Efl_Canvas_Wl.h"
#include "Elementary.h"
static Evas_Object *win;
@@ -18,7 +18,7 @@ static unsigned int n;
static Eina_Bool
dostuff(void *data)
{
- efl_wl_run(data, cmds[n++]);
+ efl_canvas_wl_run(data, cmds[n++]);
evas_object_focus_set(data, 1);
return n != num_cmds;
}
@@ -26,13 +26,13 @@ dostuff(void *data)
static void
prev_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
- efl_wl_prev(data);
+ efl_canvas_wl_surface_prev(data);
}
static void
next_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
- efl_wl_next(data);
+ efl_canvas_wl_surface_next(data);
}
int
@@ -69,7 +69,7 @@ main(int argc, char *argv[])
evas_object_show(next);
elm_table_pack(o, next, 1, 0, 1, 1);
- comp = efl_wl_add(evas_object_evas_get(win));
+ comp = efl_add(EFL_CANVAS_WL_CLASS, win);
evas_object_size_hint_min_set(comp, 640, 480);
elm_table_pack(o, comp, 0, 1, 2, 1);
evas_object_size_hint_align_set(comp, EVAS_HINT_FILL, EVAS_HINT_FILL);
diff --git a/src/bin/efl_canvas_wl/meson.build b/src/bin/efl_canvas_wl/meson.build
new file mode 100644
index 0000000000..278a2c58db
--- /dev/null
+++ b/src/bin/efl_canvas_wl/meson.build
@@ -0,0 +1,13 @@
+executable('efl_canvas_wl_test',
+ 'efl_canvas_wl_test.c',
+ include_directories : config_dir,
+ dependencies: [efl_canvas_wl, efl_canvas_wl_deps, efl_canvas_wl_pub_deps, elementary],
+ install: true,
+)
+
+executable('efl_canvas_wl_test_stack',
+ 'efl_canvas_wl_test_stack.c',
+ include_directories : config_dir,
+ dependencies: [efl_canvas_wl, efl_canvas_wl_deps, efl_canvas_wl_pub_deps, elementary],
+ install: true,
+)
diff --git a/src/bin/efl_wl/meson.build b/src/bin/efl_wl/meson.build
deleted file mode 100644
index c95cd0e767..0000000000
--- a/src/bin/efl_wl/meson.build
+++ /dev/null
@@ -1,13 +0,0 @@
-executable('efl_wl_test',
- 'efl_wl_test.c',
- include_directories : config_dir,
- dependencies: [efl_wl, elementary],
- install: true,
-)
-
-executable('efl_wl_test_stack',
- 'efl_wl_test_stack.c',
- include_directories : config_dir,
- dependencies: [efl_wl, elementary],
- install: true,
-)
diff --git a/src/bin/efreet/efreet_icon_cache_create.c b/src/bin/efreet/efreet_icon_cache_create.c
index 9f3141b8f9..44d6097b1b 100644
--- a/src/bin/efreet/efreet_icon_cache_create.c
+++ b/src/bin/efreet/efreet_icon_cache_create.c
@@ -38,38 +38,36 @@ static Eina_Hash *icon_themes = NULL;
static Eina_Bool
cache_directory_modified(Eina_Hash *dirs, const char *dir)
{
- Efreet_Cache_Directory *dcache;
- long long time;
-
- if (!dirs) return EINA_TRUE;
-
- time = ecore_file_mod_time(dir);
- if (!time)
- return EINA_FALSE;
- dcache = eina_hash_find(dirs, dir);
- if (!dcache)
- {
+ Efreet_Cache_Directory *dcache;
+ Efreet_Cache_Check check;
+
+ if (!dirs) return EINA_TRUE;
+ if (!efreet_file_cache_fill(dir, &check)) return EINA_FALSE;
+ dcache = eina_hash_find(dirs, dir);
+ if (!dcache)
+ {
dcache = malloc(sizeof (Efreet_Cache_Directory));
if (!dcache) return EINA_TRUE;
-
- dcache->modified_time = time;
+ dcache->check = check;
eina_hash_add(dirs, dir, dcache);
- }
- else if (dcache->modified_time == time) return EINA_FALSE;
- dcache->modified_time = time;
-
- return EINA_TRUE;
+ }
+ else if (efreet_file_cache_check(&check, &dcache->check))
+ return EINA_FALSE;
+ else
+ dcache->check = check;
+ return EINA_TRUE;
}
static Eina_Bool
cache_extension_lookup(const char *ext)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < exts->count; ++i)
- if (!strcmp(exts->data[i], ext))
- return EINA_TRUE;
- return EINA_FALSE;
+ for (i = 0; i < exts->count; ++i)
+ {
+ if (!strcmp(exts->data[i], ext)) return EINA_TRUE;
+ }
+ return EINA_FALSE;
}
static Eina_Bool
@@ -164,6 +162,7 @@ cache_fallback_scan(Eina_Hash *icons, Eina_Hash *dirs)
}
#endif
+ cache_fallback_scan_dir(icons, dirs, "/usr/local/share/pixmaps");
cache_fallback_scan_dir(icons, dirs, "/usr/share/pixmaps");
return EINA_TRUE;
@@ -217,10 +216,42 @@ check_fallback_changed(Efreet_Cache_Icon_Theme *theme)
}
#endif
+ if (cache_directory_modified(theme->dirs, "/usr/local/share/pixmaps")) return EINA_TRUE;
if (cache_directory_modified(theme->dirs, "/usr/share/pixmaps")) return EINA_TRUE;
return EINA_FALSE;
}
+typedef struct
+{
+ char *path;
+ int name_start;
+} Scanned_Entry;
+
+static Eina_Hash *already_scanned_path = NULL;
+
+static void
+cache_theme_change_verify(Efreet_Cache_Icon_Theme *theme)
+{
+ Eina_Bool changed = EINA_FALSE;
+ Eina_List *l;
+ Efreet_Icon_Theme_Directory *d;
+ char buf[PATH_MAX], *tdir, *sep;
+
+ tdir = strdup(theme->path);
+ sep = strrchr(tdir, '/');
+ if (sep) *sep = 0;
+ EINA_LIST_FOREACH(theme->theme.directories, l, d)
+ {
+ snprintf(buf, sizeof(buf), "%s/%s", tdir, d->name);
+ if (cache_directory_modified(theme->dirs, buf))
+ {
+ changed = EINA_TRUE;
+ }
+ }
+ free(tdir);
+ if (changed) theme->changed = changed;
+}
+
static Eina_Bool
cache_scan_path_dir(Efreet_Icon_Theme *theme,
const char *path,
@@ -230,29 +261,64 @@ cache_scan_path_dir(Efreet_Icon_Theme *theme,
Eina_Iterator *it;
char buf[PATH_MAX];
Eina_File_Direct_Info *entry;
+ Eina_List *dirs = NULL;
+ Eina_List *l;
+ char *ext;
+ Scanned_Entry *scentry;
snprintf(buf, sizeof(buf), "%s/%s", path, dir->name);
+ // we wont ever free this - no point
+ if (!already_scanned_path)
+ already_scanned_path = eina_hash_string_superfast_new(NULL);
+ dirs = eina_hash_find(already_scanned_path, buf);
+ if ((intptr_t)dirs == (intptr_t)(-1L)) return EINA_TRUE;
+ else if (!dirs)
+ {
+ it = eina_file_stat_ls(buf);
+ if (!it)
+ {
+ eina_hash_add(already_scanned_path, buf, (void *)(intptr_t)(-1L));
+ return EINA_TRUE;
+ }
+
+ EINA_ITERATOR_FOREACH(it, entry)
+ {
+ if (entry->type == EINA_FILE_DIR) continue;
+ ext = strrchr(entry->path + entry->name_start, '.');
+ if (!ext || !cache_extension_lookup(ext)) continue;
+ scentry = malloc(sizeof(Scanned_Entry));
+ if (!scentry)
+ {
+ ERR("Out of memory");
+ exit(1);
+ }
+ scentry->name_start = entry->name_start;
+ scentry->path = strdup(entry->path);
+ if (!scentry->path)
+ {
+ ERR("Out of memory");
+ exit(1);
+ }
+ dirs = eina_list_append(dirs, scentry);
+ }
+ eina_iterator_free(it);
+ if (dirs)
+ eina_hash_add(already_scanned_path, buf, dirs);
+ else
+ eina_hash_add(already_scanned_path, buf, (void *)(intptr_t)(-1L));
+ }
- it = eina_file_stat_ls(buf);
- if (!it) return EINA_TRUE;
-
- EINA_ITERATOR_FOREACH(it, entry)
+ EINA_LIST_FOREACH(dirs, l, scentry)
{
Efreet_Cache_Icon *icon;
char *name;
- char *ext;
const char **tmp;
unsigned int i;
- if (entry->type == EINA_FILE_DIR)
- continue;
-
- ext = strrchr(entry->path + entry->name_start, '.');
- if (!ext || !cache_extension_lookup(ext))
- continue;
-
+ ext = strrchr(scentry->path + scentry->name_start, '.');
+ if (!ext) continue;
/* icon with known extension */
- name = entry->path + entry->name_start;
+ name = scentry->path + scentry->name_start;
*ext = '\0';
icon = eina_hash_find(icons, name);
@@ -282,7 +348,7 @@ cache_scan_path_dir(Efreet_Icon_Theme *theme,
/* check if the path already exist */
for (j = 0; j < icon->icons[i]->paths_count; ++j)
- if (!strcmp(icon->icons[i]->paths[j], entry->path))
+ if (!strcmp(icon->icons[i]->paths[j], scentry->path))
break;
if (j != icon->icons[i]->paths_count)
@@ -346,12 +412,9 @@ cache_scan_path_dir(Efreet_Icon_Theme *theme,
exit(1);
}
icon->icons[i]->paths = tmp;
- icon->icons[i]->paths[icon->icons[i]->paths_count] = eina_stringshare_add(entry->path);
+ icon->icons[i]->paths[icon->icons[i]->paths_count] = eina_stringshare_add(scentry->path);
eina_array_push(strs, icon->icons[i]->paths[icon->icons[i]->paths_count++]);
}
-
- eina_iterator_free(it);
-
return EINA_TRUE;
}
@@ -362,7 +425,9 @@ cache_scan_path(Efreet_Icon_Theme *theme, Eina_Hash *icons, const char *path)
Efreet_Icon_Theme_Directory *dir;
EINA_LIST_FOREACH(theme->directories, l, dir)
+ {
if (!cache_scan_path_dir(theme, path, dir, icons)) return EINA_FALSE;
+ }
return EINA_TRUE;
}
@@ -509,13 +574,13 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
Efreet_Ini *ini;
Efreet_Icon_Theme_Directory *dir;
const char *tmp;
- long long time;
+ Efreet_Cache_Check check;
if (!theme || !path) return EINA_FALSE;
- time = ecore_file_mod_time(path);
- if (!time) return EINA_FALSE;
- if (theme->path && !strcmp(theme->path, path) && theme->last_cache_check >= time)
+ if (!efreet_file_cache_fill(path, &check)) return EINA_FALSE;
+ if (theme->path && !strcmp(theme->path, path) &&
+ efreet_file_cache_check(&check, &(theme->check)))
{
/* no change */
theme->valid = 1;
@@ -526,8 +591,7 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
theme->path = eina_stringshare_add(path);
eina_array_push(strs, theme->path);
}
- if (time > theme->last_cache_check)
- theme->last_cache_check = time;
+ theme->check = check;
theme->changed = 1;
ini = efreet_ini_new(path);
@@ -642,10 +706,10 @@ cache_theme_scan(const char *dir)
Efreet_Cache_Icon_Theme *theme;
const char *name;
const char *path;
- long long time;
+ Efreet_Cache_Check check;
+ Efreet_Cache_Directory *d;
- time = ecore_file_mod_time(entry->path);
- if (!time) continue;
+ if (!efreet_file_cache_fill(entry->path, &check)) continue;
if ((entry->type != EINA_FILE_DIR) &&
(entry->type != EINA_FILE_LNK))
@@ -667,10 +731,26 @@ cache_theme_scan(const char *dir)
(void *)theme->theme.name.internal, theme);
theme->changed = 1;
}
- if (time > theme->last_cache_check)
- {
- theme->last_cache_check = time;
+
+ d = NULL;
+ if (theme->dirs)
+ d = eina_hash_find(theme->dirs, entry->path);
+ if (!d)
+ {
+ if (!theme->dirs)
+ theme->dirs = eina_hash_string_superfast_new(NULL);
theme->changed = 1;
+ d = NEW(Efreet_Cache_Directory, 1);
+ d->check = check;
+ eina_hash_add(theme->dirs, entry->path, d);
+ }
+ else
+ {
+ if (!efreet_file_cache_check(&check, &(d->check)))
+ {
+ d->check = check;
+ theme->changed = 1;
+ }
}
/* TODO: We need to handle change in order of included paths */
@@ -730,8 +810,7 @@ icon_theme_free(Efreet_Cache_Icon_Theme *theme)
eina_list_free(theme->theme.paths);
eina_list_free(theme->theme.inherits);
- EINA_LIST_FREE(theme->theme.directories, data)
- free(data);
+ EINA_LIST_FREE(theme->theme.directories, data) free(data);
if (theme->dirs) efreet_hash_free(theme->dirs, free);
free(theme);
}
@@ -912,6 +991,7 @@ main(int argc, char **argv)
}
#endif
+ cache_theme_scan("/usr/local/share/pixmaps");
cache_theme_scan("/usr/share/pixmaps");
/* scan icons */
@@ -923,7 +1003,7 @@ main(int argc, char **argv)
if (!theme->theme.name.name) continue;
#endif
INF("scan theme %s", theme->theme.name.name);
-
+ cache_theme_change_verify(theme);
theme->changed = check_changed(theme);
if (flush)
theme->changed = EINA_TRUE;
@@ -978,18 +1058,18 @@ main(int argc, char **argv)
icons_it = eina_hash_iterator_tuple_new(icons);
EINA_ITERATOR_FOREACH(icons_it, tuple)
- eet_data_write(icon_ef, icon_edd, tuple->key, tuple->data, 1);
+ eet_data_write(icon_ef, icon_edd, tuple->key, tuple->data, EET_COMPRESSION_SUPERFAST);
eina_iterator_free(icons_it);
- INF("theme change: %s %lld", theme->theme.name.internal, theme->last_cache_check);
- eet_data_write(theme_ef, theme_edd, theme->theme.name.internal, theme, 1);
+ INF("theme change: %s %lld", theme->theme.name.internal, theme->check.mtime);
+ eet_data_write(theme_ef, theme_edd, theme->theme.name.internal, theme, EET_COMPRESSION_SUPERFAST);
}
eina_hash_free(themes);
eina_hash_free(icons);
changed = EINA_TRUE;
}
- eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, 1);
+ eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, EET_COMPRESSION_SUPERFAST);
eet_close(icon_ef);
efreet_setowner(efreet_icon_cache_file(theme->theme.name.internal));
free(icon_version);
@@ -1061,17 +1141,17 @@ main(int argc, char **argv)
icons_it = eina_hash_iterator_tuple_new(icons);
EINA_ITERATOR_FOREACH(icons_it, tuple)
- eet_data_write(icon_ef, fallback_edd, tuple->key, tuple->data, 1);
+ eet_data_write(icon_ef, fallback_edd, tuple->key, tuple->data, EET_COMPRESSION_SUPERFAST);
eina_iterator_free(icons_it);
}
eina_hash_free(icons);
- eet_data_write(theme_ef, theme_edd, EFREET_CACHE_ICON_FALLBACK, theme, 1);
+ eet_data_write(theme_ef, theme_edd, EFREET_CACHE_ICON_FALLBACK, theme, EET_COMPRESSION_SUPERFAST);
}
icon_theme_free(theme);
- eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, 1);
+ eet_data_write(icon_ef, efreet_version_edd(), EFREET_CACHE_VERSION, icon_version, EET_COMPRESSION_SUPERFAST);
eet_close(icon_ef);
efreet_setowner(efreet_icon_cache_file(EFREET_CACHE_ICON_FALLBACK));
free(icon_version);
@@ -1079,7 +1159,7 @@ main(int argc, char **argv)
eina_hash_free(icon_themes);
/* save data */
- eet_data_write(theme_ef, efreet_version_edd(), EFREET_CACHE_VERSION, theme_version, 1);
+ eet_data_write(theme_ef, efreet_version_edd(), EFREET_CACHE_VERSION, theme_version, EET_COMPRESSION_SUPERFAST);
eet_close(theme_ef);
theme_ef = NULL;
diff --git a/src/bin/efreet/efreetd.c b/src/bin/efreet/efreetd.c
index 1ef7d339c2..fbff09b58f 100644
--- a/src/bin/efreet/efreetd.c
+++ b/src/bin/efreet/efreetd.c
@@ -21,6 +21,7 @@
int efreetd_log_dom = -1;
Eina_Mempool *efreetd_mp_stat = NULL;
+FILE *efreetd_log_file = NULL;
void
quit(void)
@@ -32,7 +33,7 @@ int
main(int argc, char *argv[])
{
char path[PATH_MAX + 128], buf[PATH_MAX];
- FILE *log;
+ FILE *logf;
int fd;
const char *log_file_dir = NULL;
const char *hostname_str = NULL;
@@ -69,9 +70,10 @@ main(int argc, char *argv[])
ERR("Can't create log file '%s'\b", path);
goto tmp_error;
}
- log = fdopen(fd, "wb");
- if (!log) goto tmp_error;
- eina_log_print_cb_set(eina_log_print_cb_file, log);
+ logf = fdopen(fd, "wb");
+ if (!logf) goto tmp_error;
+ eina_log_print_cb_set(eina_log_print_cb_file, logf);
+ efreetd_log_file = logf;
efreetd_log_dom = eina_log_domain_register("efreetd", EFREETD_DEFAULT_LOG_COLOR);
if (efreetd_log_dom < 0)
{
diff --git a/src/bin/efreet/efreetd_cache.c b/src/bin/efreet/efreetd_cache.c
index 4b801a8fc0..d7a7f2539f 100644
--- a/src/bin/efreet/efreetd_cache.c
+++ b/src/bin/efreet/efreetd_cache.c
@@ -19,6 +19,8 @@
#include <sys/stat.h>
#include <unistd.h>
+extern FILE *efreetd_log_file;
+
static Eina_Hash *icon_change_monitors = NULL;
static Eina_Hash *icon_change_monitors_mon = NULL;
static Eina_Hash *desktop_change_monitors = NULL;
@@ -376,10 +378,13 @@ icon_cache_update_cache_cb(void *data EINA_UNUSED)
if (icon_flush)
eina_strbuf_append(file, " -f");
icon_flush = EINA_FALSE;
- icon_cache_exe =
- ecore_exe_pipe_run(eina_strbuf_string_get(file), ECORE_EXE_PIPE_READ |
- ECORE_EXE_PIPE_READ_LINE_BUFFERED,
- NULL);
+ fprintf(efreetd_log_file, "[%09.3f] Run:\n %s\n", ecore_time_get(),
+ eina_strbuf_string_get(file));
+ fflush(efreetd_log_file);
+ icon_cache_exe = ecore_exe_pipe_run
+ (eina_strbuf_string_get(file),
+ ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_READ_LINE_BUFFERED,
+ NULL);
eina_strbuf_free(file);
@@ -424,10 +429,13 @@ desktop_cache_update_cache_cb(void *data EINA_UNUSED)
}
}
INF("Run desktop cache creation: %s", eina_strbuf_string_get(file));
+ fprintf(efreetd_log_file, "[%09.3f] Run:\n %s\n", ecore_time_get(),
+ eina_strbuf_string_get(file));
+ fflush(efreetd_log_file);
desktop_cache_exe = ecore_exe_pipe_run
- (eina_strbuf_string_get(file), ECORE_EXE_PIPE_READ |
- ECORE_EXE_PIPE_READ_LINE_BUFFERED,
- NULL);
+ (eina_strbuf_string_get(file),
+ ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_READ_LINE_BUFFERED,
+ NULL);
eina_strbuf_free(file);
@@ -698,6 +706,7 @@ icon_changes_listen(void)
}
#endif
eina_inarray_flush(stack);
+ icon_changes_listen_recursive(stack, "/usr/local/share/pixmaps", EINA_TRUE);
icon_changes_listen_recursive(stack, "/usr/share/pixmaps", EINA_TRUE);
eina_inarray_free(stack);
eina_strbuf_free(buf);
@@ -801,6 +810,8 @@ cache_exe_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Eina_Bool update = EINA_FALSE;
+ fprintf(efreetd_log_file, "[%09.3f] Data desktop_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
if (!desktop_exists)
send_signal_desktop_cache_build();
@@ -811,11 +822,15 @@ cache_exe_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Eina_Bool update = EINA_FALSE;
+ fprintf(efreetd_log_file, "[%09.3f] Data icon_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
send_signal_icon_cache_update(update);
}
else if (ev->exe == mime_cache_exe)
{
+ fprintf(efreetd_log_file, "[%09.3f] Data mime_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
// XXX: ZZZ: handle stdout here from cache updater... if needed
}
return ECORE_CALLBACK_RENEW;
@@ -828,16 +843,22 @@ cache_exe_del_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
if (ev->exe == desktop_cache_exe)
{
+ fprintf(efreetd_log_file, "[%09.3f] Exit desktop_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
desktop_cache_exe = NULL;
if (desktop_queue) cache_desktop_update();
}
else if (ev->exe == icon_cache_exe)
{
+ fprintf(efreetd_log_file, "[%09.3f] Exit icon_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
icon_cache_exe = NULL;
if (icon_queue) cache_icon_update(EINA_FALSE);
}
else if (ev->exe == mime_cache_exe)
{
+ fprintf(efreetd_log_file, "[%09.3f] Exit mime_cache_create\n", ecore_time_get());
+ fflush(efreetd_log_file);
mime_cache_exe = NULL;
send_signal_mime_cache_build();
}
diff --git a/src/bin/efreet/efreetd_ipc.c b/src/bin/efreet/efreetd_ipc.c
index 933abfca9c..129f886f34 100644
--- a/src/bin/efreet/efreetd_ipc.c
+++ b/src/bin/efreet/efreetd_ipc.c
@@ -12,12 +12,15 @@
#include "efreetd.h"
#include "efreetd_cache.h"
+extern FILE *efreetd_log_file;
+
static int init = 0;
static Ecore_Ipc_Server *ipc = NULL;
static Ecore_Event_Handler *hnd_add = NULL;
static Ecore_Event_Handler *hnd_del = NULL;
static Ecore_Event_Handler *hnd_data = NULL;
static int clients = 0;
+static Ecore_Timer *quit_timer_start = NULL;
static Ecore_Timer *quit_timer = NULL;
static Eina_Bool
@@ -28,6 +31,15 @@ _cb_quit_timer(void *data EINA_UNUSED)
return EINA_FALSE;
}
+static Eina_Bool
+_cb_quit_timer_start(void *data EINA_UNUSED)
+{
+ quit_timer_start = NULL;
+ if (quit_timer) ecore_timer_del(quit_timer);
+ quit_timer = ecore_timer_add(10.0, _cb_quit_timer, NULL);
+ return EINA_FALSE;
+}
+
static void
_broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size)
{
@@ -37,6 +49,8 @@ _broadcast(Ecore_Ipc_Server *svr, int major, int minor, void *data, int size)
EINA_LIST_FOREACH(ipc_clients, l, cl)
{
+ fprintf(efreetd_log_file, "[%09.3f] Client broadcast %i.%i\n", ecore_time_get(), major, minor);
+ fflush(efreetd_log_file);
ecore_ipc_client_send(cl, major, minor, 0, 0, 0, data, size);
}
}
@@ -101,7 +115,15 @@ _cb_client_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
ecore_timer_del(quit_timer);
quit_timer = NULL;
}
+ if (quit_timer_start)
+ {
+ ecore_timer_del(quit_timer_start);
+ quit_timer_start = NULL;
+ }
clients++;
+ fprintf(efreetd_log_file, "[%09.3f] Add client (count=%i)\n", ecore_time_get(),
+ clients);
+ fflush(efreetd_log_file);
return ECORE_CALLBACK_DONE;
}
@@ -110,6 +132,9 @@ _cb_client_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
IPC_HEAD(Del);
clients--;
+ fprintf(efreetd_log_file, "[%09.3f] Del client (count=%i)\n", ecore_time_get(),
+ clients);
+ fflush(efreetd_log_file);
if (clients == 0)
{
if (quit_timer) ecore_timer_del(quit_timer);
@@ -126,6 +151,8 @@ _cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
IPC_HEAD(Data);
if (e->major == 1) // register lang
{ // input: str -> lang
+ fprintf(efreetd_log_file, "[%09.3f] Client register lang\n", ecore_time_get());
+ fflush(efreetd_log_file);
if ((s = _parse_str(e->data, e->size)))
{
setenv("LANG", s, 1);
@@ -137,6 +164,8 @@ _cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
}
else if (e->major == 2) // add desktop dirs
{ // input: array of str -> dirs
+ fprintf(efreetd_log_file, "[%09.3f] Client add desktop dirs\n", ecore_time_get());
+ fflush(efreetd_log_file);
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
@@ -146,6 +175,8 @@ _cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
}
else if (e->major == 3) // build desktop cache
{ // input: str -> lang
+ fprintf(efreetd_log_file, "[%09.3f] Client update desktop cache\n", ecore_time_get());
+ fflush(efreetd_log_file);
if ((s = _parse_str(e->data, e->size)))
{
setenv("LANG", s, 1);
@@ -155,6 +186,8 @@ _cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
}
else if (e->major == 4) // add icon dirs
{ // input: array of str -> dirs
+ fprintf(efreetd_log_file, "[%09.3f] Client add icon dirs\n", ecore_time_get());
+ fflush(efreetd_log_file);
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
@@ -164,6 +197,8 @@ _cb_client_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
}
else if (e->major == 5) // add icon exts
{ // input: array of str -> exts
+ fprintf(efreetd_log_file, "[%09.3f] Client add icon exts\n", ecore_time_get());
+ fflush(efreetd_log_file);
strs = _parse_strs(e->data, e->size);
EINA_LIST_FREE(strs, s)
{
@@ -211,7 +246,7 @@ ipc_init(void)
ecore_ipc_shutdown();
return EINA_FALSE;
}
- quit_timer = ecore_timer_add(2.0, _cb_quit_timer, NULL);
+ quit_timer_start = ecore_timer_add(10.0, _cb_quit_timer_start, NULL);
hnd_add = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
_cb_client_add, NULL);
hnd_del = ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
@@ -228,6 +263,10 @@ ipc_shutdown(void)
if (init <= 0) return EINA_TRUE;
init--;
if (init > 0) return EINA_TRUE;
+ if (quit_timer) ecore_timer_del(quit_timer);
+ if (quit_timer_start) ecore_timer_del(quit_timer_start);
+ quit_timer = NULL;
+ quit_timer_start = NULL;
ecore_ipc_server_del(ipc);
ecore_event_handler_del(hnd_add);
ecore_event_handler_del(hnd_del);
diff --git a/src/bin/efreet/meson.build b/src/bin/efreet/meson.build
index 27f0e396e6..baf945d5de 100644
--- a/src/bin/efreet/meson.build
+++ b/src/bin/efreet/meson.build
@@ -7,7 +7,8 @@ efreetd_src = [
'efreetd_cache.c'
]
-config_h.set('STRICT_SPEC', '1')
+# disable strict as this causes efreet to be less functional for people
+#config_h.set('STRICT_SPEC', '1')
efreetd = executable('efreetd',
efreetd_src,
diff --git a/src/bin/elementary/config.c b/src/bin/elementary/config.c
index 71309ecf2a..1131437849 100644
--- a/src/bin/elementary/config.c
+++ b/src/bin/elementary/config.c
@@ -213,7 +213,7 @@ bf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -224,7 +224,7 @@ bf_change(void *data EINA_UNUSED,
double bf = elm_config_scroll_bounce_friction_get();
double val = elm_slider_value_get(obj);
- if (bf == val) return;
+ if (EINA_DBL_EQ(bf, val)) return;
elm_config_scroll_bounce_friction_set(val);
elm_config_all_flush();
}
@@ -238,7 +238,7 @@ ps_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -249,7 +249,7 @@ ps_change(void *data EINA_UNUSED,
double ps = elm_config_scroll_page_scroll_friction_get();
double val = elm_slider_value_get(obj);
- if (ps == val) return;
+ if (EINA_DBL_EQ(ps, val)) return;
elm_config_scroll_page_scroll_friction_set(val);
elm_config_all_flush();
}
@@ -263,7 +263,7 @@ bis_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -274,7 +274,7 @@ bis_change(void *data EINA_UNUSED,
double bis = elm_config_scroll_bring_in_scroll_friction_get();
double val = elm_slider_value_get(obj);
- if (bis == val) return;
+ if (EINA_DBL_EQ(bis, val)) return;
elm_config_scroll_bring_in_scroll_friction_set(val);
elm_config_all_flush();
}
@@ -288,7 +288,7 @@ zf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -299,7 +299,7 @@ zf_change(void *data EINA_UNUSED,
double zf = elm_config_scroll_zoom_friction_get();
double val = elm_slider_value_get(obj);
- if (zf == val) return;
+ if (EINA_DBL_EQ(zf, val)) return;
elm_config_scroll_zoom_friction_set(val);
elm_config_all_flush();
}
@@ -313,7 +313,7 @@ smooth_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 100.0))) / 100.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -324,7 +324,7 @@ smooth_change(void *data EINA_UNUSED,
double zf = elm_config_scroll_thumbscroll_smooth_amount_get();
double val = elm_slider_value_get(obj);
- if (zf == val) return;
+ if (EINA_DBL_EQ(zf, val)) return;
elm_config_scroll_thumbscroll_smooth_amount_set(val);
elm_config_all_flush();
}
@@ -338,7 +338,7 @@ smooth_win_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 100.0))) / 100.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -349,7 +349,7 @@ smooth_win_change(void *data EINA_UNUSED,
double zf = elm_config_scroll_thumbscroll_smooth_time_window_get();
double val = elm_slider_value_get(obj);
- if (zf == val) return;
+ if (EINA_DBL_EQ(zf, val)) return;
elm_config_scroll_thumbscroll_smooth_time_window_set(val);
elm_config_all_flush();
}
@@ -378,7 +378,7 @@ tst_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -389,7 +389,7 @@ tst_change(void *data EINA_UNUSED,
double tst = elm_config_scroll_thumbscroll_threshold_get();
double val = elm_slider_value_get(obj);
- if (tst == val) return;
+ if (EINA_DBL_EQ(tst, val)) return;
elm_config_scroll_thumbscroll_threshold_set(val);
elm_config_all_flush();
}
@@ -403,7 +403,7 @@ tsht_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -414,7 +414,7 @@ tsht_change(void *data EINA_UNUSED,
double tst = elm_config_scroll_thumbscroll_hold_threshold_get();
double val = elm_slider_value_get(obj);
- if (tst == val) return;
+ if (EINA_DBL_EQ(tst, val)) return;
elm_config_scroll_thumbscroll_hold_threshold_set(val);
elm_config_all_flush();
}
@@ -428,7 +428,7 @@ tsmt_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -439,7 +439,7 @@ tsmt_change(void *data EINA_UNUSED,
double tsmt = elm_config_scroll_thumbscroll_momentum_threshold_get();
double val = elm_slider_value_get(obj);
- if (tsmt == val) return;
+ if (EINA_DBL_EQ(tsmt, val)) return;
elm_config_scroll_thumbscroll_momentum_threshold_set(val);
elm_config_all_flush();
}
@@ -453,7 +453,7 @@ tsfdt_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -464,7 +464,7 @@ tsfdt_change(void *data EINA_UNUSED,
double tsfdt = elm_config_scroll_thumbscroll_flick_distance_tolerance_get();
double val = elm_slider_value_get(obj);
- if (tsfdt == val) return;
+ if (EINA_DBL_EQ(tsfdt, val)) return;
elm_config_scroll_thumbscroll_flick_distance_tolerance_set(val);
elm_config_all_flush();
}
@@ -478,7 +478,7 @@ tsf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -489,7 +489,7 @@ tsf_change(void *data EINA_UNUSED,
double tsf = elm_config_scroll_thumbscroll_friction_get();
double val = elm_slider_value_get(obj);
- if (tsf == val) return;
+ if (EINA_DBL_EQ(tsf, val)) return;
elm_config_scroll_thumbscroll_friction_set(val);
elm_config_all_flush();
}
@@ -503,7 +503,7 @@ tsmf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -514,7 +514,7 @@ tsmf_change(void *data EINA_UNUSED,
double tsmf = elm_config_scroll_thumbscroll_min_friction_get();
double val = elm_slider_value_get(obj);
- if (tsmf == val) return;
+ if (EINA_DBL_EQ(tsmf, val)) return;
elm_config_scroll_thumbscroll_min_friction_set(val);
elm_config_all_flush();
}
@@ -528,7 +528,7 @@ tsfs_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -539,7 +539,7 @@ tsfs_change(void *data EINA_UNUSED,
double tsfs = elm_config_scroll_thumbscroll_friction_standard_get();
double val = elm_slider_value_get(obj);
- if (tsfs == val) return;
+ if (EINA_DBL_EQ(tsfs, val)) return;
elm_config_scroll_thumbscroll_friction_standard_set(val);
elm_config_all_flush();
}
@@ -553,7 +553,7 @@ tsbf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -564,7 +564,7 @@ tsbf_change(void *data EINA_UNUSED,
double tsbf = elm_config_scroll_thumbscroll_border_friction_get();
double val = elm_slider_value_get(obj);
- if (tsbf == val) return;
+ if (EINA_DBL_EQ(tsbf, val)) return;
elm_config_scroll_thumbscroll_border_friction_set(val);
elm_config_all_flush();
}
@@ -578,7 +578,7 @@ tssf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 20.0))) / 20.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -589,7 +589,7 @@ tssf_change(void *data EINA_UNUSED,
double tssf = elm_config_scroll_thumbscroll_sensitivity_friction_get();
double val = elm_slider_value_get(obj);
- if (tssf == val) return;
+ if (EINA_DBL_EQ(tssf, val)) return;
elm_config_scroll_thumbscroll_sensitivity_friction_set(val);
elm_config_all_flush();
}
@@ -603,7 +603,7 @@ tsat_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -614,7 +614,7 @@ tsat_change(void *data EINA_UNUSED,
double tsat = elm_config_scroll_thumbscroll_acceleration_threshold_get();
double val = elm_slider_value_get(obj);
- if (tsat == val) return;
+ if (EINA_DBL_EQ(tsat, val)) return;
elm_config_scroll_thumbscroll_acceleration_threshold_set(val);
elm_config_all_flush();
}
@@ -628,7 +628,7 @@ tsatl_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -639,7 +639,7 @@ tsatl_change(void *data EINA_UNUSED,
double tsatl = elm_config_scroll_thumbscroll_acceleration_time_limit_get();
double val = elm_slider_value_get(obj);
- if (tsatl == val) return;
+ if (EINA_DBL_EQ(tsatl, val)) return;
elm_config_scroll_thumbscroll_acceleration_time_limit_set(val);
elm_config_all_flush();
}
@@ -653,7 +653,7 @@ tsaw_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -664,7 +664,7 @@ tsaw_change(void *data EINA_UNUSED,
double tsaw = elm_config_scroll_thumbscroll_acceleration_weight_get();
double val = elm_slider_value_get(obj);
- if (tsaw == val) return;
+ if (EINA_DBL_EQ(tsaw, val)) return;
elm_config_scroll_thumbscroll_acceleration_weight_set(val);
elm_config_all_flush();
}
@@ -692,7 +692,7 @@ cf_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 5.0))) / 5.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -703,7 +703,7 @@ cf_change(void *data EINA_UNUSED,
double cf = elm_config_cache_flush_interval_get();
double val = elm_slider_value_get(obj);
- if (cf == val) return;
+ if (EINA_DBL_EQ(cf, val)) return;
elm_config_cache_flush_interval_set(val);
elm_config_all_flush();
}
@@ -717,7 +717,7 @@ fc_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -728,7 +728,7 @@ fc_change(void *data EINA_UNUSED,
double font_cache = elm_config_cache_font_cache_size_get();
double val = elm_slider_value_get(obj);
- if (font_cache == val) return;
+ if (EINA_DBL_EQ(font_cache, val)) return;
elm_config_cache_font_cache_size_set(val * 1024);
elm_config_all_flush();
}
@@ -742,7 +742,7 @@ ic_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -753,7 +753,7 @@ ic_change(void *data EINA_UNUSED,
double image_cache = elm_config_cache_image_cache_size_get();
double val = elm_slider_value_get(obj);
- if (image_cache == val) return;
+ if (EINA_DBL_EQ(image_cache, val)) return;
elm_config_cache_image_cache_size_set(val * 1024);
elm_config_all_flush();
}
@@ -767,7 +767,7 @@ sc_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 10.0))) / 10.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -778,7 +778,7 @@ sc_change(void *data EINA_UNUSED,
double scale = elm_config_scale_get();
double val = elm_slider_value_get(obj);
- if (scale == val) return;
+ if (EINA_DBL_EQ(scale, val)) return;
elm_config_scale_set(val);
elm_config_all_flush();
}
@@ -792,7 +792,7 @@ fs_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 5.0))) / 5.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -803,7 +803,7 @@ fs_change(void *data EINA_UNUSED,
double fs = elm_config_finger_size_get();
double val = elm_slider_value_get(obj);
- if (fs == val) return;
+ if (EINA_DBL_EQ(fs, val)) return;
elm_config_finger_size_set(val);
elm_config_all_flush();
}
@@ -817,7 +817,7 @@ efc_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 5.0))) / 5.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -828,7 +828,7 @@ efc_change(void *data EINA_UNUSED,
double efc = elm_config_cache_edje_file_cache_size_get();
double val = elm_slider_value_get(obj);
- if (efc == val) return;
+ if (EINA_DBL_EQ(efc, val)) return;
elm_config_cache_edje_file_cache_size_set(val);
elm_config_all_flush();
}
@@ -842,7 +842,7 @@ ecc_round(void *data EINA_UNUSED,
double v;
v = ((double)((int)(val * 5.0))) / 5.0;
- if (v != val) elm_slider_value_set(obj, v);
+ if (!EINA_DBL_EQ(v, val)) elm_slider_value_set(obj, v);
}
static void
@@ -853,7 +853,7 @@ ecc_change(void *data EINA_UNUSED,
double ecc = elm_config_cache_edje_collection_cache_size_get();
double val = elm_slider_value_get(obj);
- if (ecc == val) return;
+ if (EINA_DBL_EQ(ecc, val)) return;
elm_config_cache_edje_collection_cache_size_set(val);
elm_config_all_flush();
}
@@ -942,14 +942,28 @@ transition_duration_change(void *data EINA_UNUSED,
void *event_info EINA_UNUSED)
{
double val = elm_slider_value_get(obj);
- Eina_Bool scale = elm_config_transition_duration_factor_get();
+ double scale = elm_config_transition_duration_factor_get();
- if (scale == val) return;
+ if (EINA_DBL_EQ(scale, val)) return;
elm_config_transition_duration_factor_set(val);
elm_config_all_flush();
}
static void
+tooltip_delay_change(void *data EINA_UNUSED,
+ Evas_Object *obj,
+ void *event_info EINA_UNUSED)
+{
+ double val = elm_slider_value_get(obj);
+ double delay = elm_config_tooltip_delay_get();
+
+ if (EINA_DBL_EQ(delay, val)) return;
+ elm_config_tooltip_delay_set(val);
+ elm_config_all_flush();
+}
+
+
+static void
_status_basic(Evas_Object *win,
Evas_Object *bx0)
{
@@ -1307,7 +1321,7 @@ _config_display_update(Evas_Object *win)
ts_sensitivity_friction, ts_acceleration_threshold,
ts_acceleration_time_limit, ts_acceleration_weight, page_friction,
bring_in_friction, zoom_friction, transition_duration,
- smooth_amount, smooth_time_window;
+ smooth_amount, smooth_time_window, tooltip_delay;
const char *curr_theme;
Eina_Bool s_bounce, ts, smooth_start;
Elm_Theme *th;
@@ -1319,6 +1333,7 @@ _config_display_update(Evas_Object *win)
font_c = elm_config_cache_font_cache_size_get();
image_c = elm_config_cache_image_cache_size_get();
transition_duration = elm_config_transition_duration_factor_get();
+ tooltip_delay = elm_config_tooltip_delay_get();
edje_file_c = elm_config_cache_edje_file_cache_size_get();
edje_col_c = elm_config_cache_edje_collection_cache_size_get();
@@ -1423,6 +1438,7 @@ _config_display_update(Evas_Object *win)
elm_object_theme_set(evas_object_data_get(win, "theme_preview"), th);
elm_theme_free(th);
elm_config_transition_duration_factor_set(transition_duration);
+ elm_config_tooltip_delay_set(tooltip_delay);
eina_stringshare_del(curr_theme);
}
@@ -1575,7 +1591,9 @@ _icon_preview_icon_add(const char *icon, const char *theme)
elm_box_pack_end(icon_preview_frame, ic);
evas_object_show(ic);
- if (strcmp(theme, ELM_CONFIG_ICON_THEME_ELEMENTARY))
+ if (!strcmp(theme, ELM_CONFIG_ICON_THEME_ELEMENTARY))
+ elm_icon_standard_set(ic, icon);
+ else
elm_image_file_set(ic, efreet_icon_path_find(theme, icon, 48), NULL);
}
@@ -1586,9 +1604,9 @@ _icon_preview_update(Evas_Object *win)
const char **example_icon, *example_icons[] =
{
"folder",
- "user-home",
- "text-x-generic",
- "system-run",
+ "video-display",
+ "mail-unread",
+ "start-here",
"preferences-system",
NULL,
};
@@ -2023,6 +2041,32 @@ _status_config_etc(Evas_Object *win,
CHECK_ADD("Enable ATSPI support", "Set atspi mode", atspi_change, NULL);
elm_check_state_set(ck, elm_config_atspi_mode_get());
+ // tooltip delay
+ fr = elm_frame_add(bx);
+ elm_object_text_set(fr, "Tooltip delay");
+ evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, 0.5);
+ elm_box_pack_end(bx, fr);
+ evas_object_show(fr);
+
+ bx2 = elm_box_add(fr);
+ elm_object_content_set(fr, bx2);
+ evas_object_show(bx2);
+
+ sl = elm_slider_add(bx2);
+ evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
+ elm_slider_span_size_set(sl, 120);
+ elm_slider_unit_format_set(sl, "%1.1f");
+ elm_slider_indicator_format_set(sl, "%1.1f");
+ elm_slider_min_max_set(sl, 0, 20.0);
+ elm_slider_value_set(sl, elm_config_tooltip_delay_get());
+ elm_box_pack_end(bx2, sl);
+ evas_object_show(sl);
+ evas_object_smart_callback_add(sl, "changed", sc_round, NULL);
+ evas_object_smart_callback_add(sl, "delay,changed", tooltip_delay_change, NULL);
+
+
// transition duration in edje
fr = elm_frame_add(bx);
elm_object_text_set(fr, "Edje Transition Duration Factor");
@@ -4372,25 +4416,25 @@ efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
else if ((!strcmp(arg, "-t")) && (i < eina_array_count(arge->argv)))
{
i++;
- theme_set = arg;
+ theme_set = eina_array_data_get(arge->argv, i);
interactive = 0;
}
else if ((!strcmp(arg, "-f")) && (i < eina_array_count(arge->argv)))
{
i++;
- finger_size_set = arg;
+ finger_size_set = eina_array_data_get(arge->argv, i);
interactive = 0;
}
else if ((!strcmp(arg, "-s")) && (i < eina_array_count(arge->argv)))
{
i++;
- scale_set = arg;
+ scale_set = eina_array_data_get(arge->argv, i);
interactive = 0;
}
else if ((!strcmp(arg, "-w")) && (i < eina_array_count(arge->argv)))
{
i++;
- web_backend = arg;
+ web_backend = eina_array_data_get(arge->argv, i);
interactive = 0;
}
}
diff --git a/src/bin/elementary/elm_prefs_cc_parse.c b/src/bin/elementary/elm_prefs_cc_parse.c
index 11415e1d86..fa960ac326 100644
--- a/src/bin/elementary/elm_prefs_cc_parse.c
+++ b/src/bin/elementary/elm_prefs_cc_parse.c
@@ -1345,7 +1345,7 @@ _calcf(char op, double a, double b)
return a;
case '/':
- if (b != 0) a /= b;
+ if (EINA_DBL_NONZERO(b)) a /= b;
else
ERR("%s:%i divide by zero", file_in, line - 1);
return a;
@@ -1355,7 +1355,7 @@ _calcf(char op, double a, double b)
return a;
case '%':
- if (0 != b) a = (double)((int)a % (int)b);
+ if (EINA_DBL_NONZERO(b)) a = (double)((int)a % (int)b);
else
ERR("%s:%i modula by zero", file_in, line - 1);
return a;
diff --git a/src/bin/elementary/meson.build b/src/bin/elementary/meson.build
index 27dabe6d3d..1d7aa75057 100644
--- a/src/bin/elementary/meson.build
+++ b/src/bin/elementary/meson.build
@@ -161,20 +161,24 @@ elementary_test_src = [
'test_ui_collection_view.c',
'test_ui_items.c',
'test_ui_frame.c',
- 'test_efl_ui_animation_view.c',
+ 'test_ui_separator.c',
+ 'test_efl_ui_vg_animation.c',
'test_efl_gfx_vg_value_provider.c',
'test.h'
]
+link_args = []
if sys_windows == false
- link_args = ['-rdynamic', '-fPIC', '-pie']
+ link_args += ['-rdynamic', '-fPIC']
package_c_args = package_c_args + ['-fPIC']
-else
- link_args = []
endif
+if sys_windows == false and sys_sun == false
+ link_args += ['-pie']
+endif
+
elementary_test = executable('elementary_test',
elementary_test_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args + [
'-Delementary_test_BIN_DIR="'+dir_bin+'"',
@@ -190,7 +194,7 @@ elementary_config_src = [
elementary_config = executable('elementary_config',
elementary_config_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args,
link_args: link_args
@@ -203,7 +207,7 @@ if sys_windows == false
elementary_quicklaunch = executable('elementary_quicklaunch',
elementary_quicklaunch_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args,
link_args: link_args
@@ -216,17 +220,21 @@ elementary_codegen_src = [
elementary_codegen = executable('elementary_codegen',
elementary_codegen_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args,
link_args: link_args
)
+asan_option =[]
+if get_option('b_sanitize') == 'address'
+ asan_option= 'ASAN_OPTIONS=detect_leaks=0'
+endif
+
if meson.is_cross_build()
elementary_codegen_exe = [find_program('elementary_codegen', native: true)]
else
- env = find_program('env', native: true)
- elementary_codegen_exe = [env, 'EFL_RUN_IN_TREE=1', elementary_codegen.full_path()]
+ elementary_codegen_exe = [env, asan_option, 'EFL_RUN_IN_TREE=1', elementary_codegen.full_path()]
endif
elm_prefs_cc_src = [
@@ -240,7 +248,7 @@ elm_prefs_cc_src = [
elm_prefs_cc = executable('elm_prefs_cc',
elm_prefs_cc_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args,
link_args: link_args
@@ -251,8 +259,7 @@ if meson.is_cross_build()
elm_prefs_cc_path = _elm_prefs_cc.path()
elm_prefs_cc_exe = [_elm_prefs_cc]
else
- env = find_program('env', native: true)
- elm_prefs_cc_exe = [env, 'EFL_RUN_IN_TREE=1', elm_prefs_cc.full_path()]
+ elm_prefs_cc_exe = [env, asan_option, 'EFL_RUN_IN_TREE=1', elm_prefs_cc.full_path()]
endif
if sys_windows == false
@@ -262,7 +269,7 @@ if sys_windows == false
elementary_run = executable('elementary_run',
elementary_run_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args,
link_args: link_args
@@ -282,7 +289,7 @@ elementary_perf_src = [
elementary_perf = executable('elementary_perf',
elementary_perf_src,
- dependencies: [elementary] + elementary_deps + elementary_pub_deps,
+ dependencies: [elementary, intl] + elementary_deps + elementary_pub_deps,
install: true,
c_args : package_c_args + [
'-Delementary_test_BIN_DIR="'+dir_bin+'"',
diff --git a/src/bin/elementary/perf_test_01.c b/src/bin/elementary/perf_test_01.c
index d29f84813b..ef7f32d112 100644
--- a/src/bin/elementary/perf_test_01.c
+++ b/src/bin/elementary/perf_test_01.c
@@ -36,9 +36,9 @@ TST(01, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2));
+ x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0));
y = (win_h / 2) - (h / 2);
- y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2));
+ y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0));
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/perf_test_02.c b/src/bin/elementary/perf_test_02.c
index ac381c732a..e5f10f1549 100644
--- a/src/bin/elementary/perf_test_02.c
+++ b/src/bin/elementary/perf_test_02.c
@@ -36,9 +36,9 @@ TST(02, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2));
+ x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0));
y = (win_h / 2) - (h / 2);
- y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2));
+ y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0));
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/perf_test_03.c b/src/bin/elementary/perf_test_03.c
index 6737bedac5..ab35044538 100644
--- a/src/bin/elementary/perf_test_03.c
+++ b/src/bin/elementary/perf_test_03.c
@@ -36,9 +36,9 @@ TST(03, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2));
+ x += (Evas_Coord)(sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0));
y = (win_h / 2) - (h / 2);
- y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2));
+ y += (Evas_Coord)(cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0));
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/perf_test_04.c b/src/bin/elementary/perf_test_04.c
index 17aae98342..d593096f32 100644
--- a/src/bin/elementary/perf_test_04.c
+++ b/src/bin/elementary/perf_test_04.c
@@ -36,9 +36,9 @@ TST(04, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
+ x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0);
y = (win_h / 2) - (h / 2);
- y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
+ y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0);
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/perf_test_05.c b/src/bin/elementary/perf_test_05.c
index 64618ae608..1016952875 100644
--- a/src/bin/elementary/perf_test_05.c
+++ b/src/bin/elementary/perf_test_05.c
@@ -36,9 +36,9 @@ TST(05, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
+ x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0);
y = (win_h / 2) - (h / 2);
- y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
+ y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0);
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/perf_test_06.c b/src/bin/elementary/perf_test_06.c
index 952a4bced2..d227d65557 100644
--- a/src/bin/elementary/perf_test_06.c
+++ b/src/bin/elementary/perf_test_06.c
@@ -36,9 +36,9 @@ TST(06, tick) (Evas *e EINA_UNUSED, double f, Evas_Coord win_w, Evas_Coord win_h
w = 5 + ((1.0 + cos((double)((f * 30.0) + (i * 10)))) * w0 * 2);
h = 5 + ((1.0 + sin((double)((f * 40.0) + (i * 19)))) * h0 * 2);
x = (win_w / 2) - (w / 2);
- x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2);
+ x += sin((double)((f * 50.0) + (i * 13))) * (w0 / 2.0);
y = (win_h / 2) - (h / 2);
- y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2);
+ y += cos((double)((f * 45.0) + (i * 28))) * (h0 / 2.0);
evas_object_geometry_set(o, x, y, w, h);
}
}
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index 4150ab20ea..d0d374ece4 100644
--- a/src/bin/elementary/test.c
+++ b/src/bin/elementary/test.c
@@ -241,6 +241,7 @@ void test_label(void *data, Evas_Object *obj, void *event_info);
void test_label_slide(void *data, Evas_Object *obj, void *event_info);
void test_label_wrap(void *data, Evas_Object *obj, void *event_info);
void test_textblock_fit(void *data, Evas_Object *obj, void *event_info);
+void test_text_memory(void *data, Evas_Object *obj, void *event_info);
void test_label_ellipsis(void *data, Evas_Object *obj, void *event_info);
void test_label_colors(void *data, Evas_Object *obj, void *event_info);
void test_label_emoji(void *data, Evas_Object *obj, void *event_info);
@@ -398,7 +399,7 @@ void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_stack(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_plain(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_scroll(void *data, Evas_Object *obj, void *event_info);
-
+void test_ui_spotlight_animation(void *data, Evas_Object *obj, void *event_info);
void test_ui_relative_container(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_radio(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_collection_list(void *data, Evas_Object *obj, void *event_info);
@@ -407,8 +408,9 @@ void test_efl_ui_collection_view(void *data, Evas_Object *obj, void *event_info)
void test_efl_ui_item(void *data, Evas_Object *obj, void *event_info);
void test_ui_frame(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
-void test_efl_ui_animation_view(void *data, Evas_Object *obj, void *event_info);
+void test_efl_ui_vg_animation(void *data, Evas_Object *obj, void *event_info);
void test_efl_gfx_vg_value_provider(void *data, Evas_Object *obj, void *event_info);
+void test_ui_separator(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, void *event_info EINA_UNUSED);
static void _list_udpate(void);
@@ -680,14 +682,23 @@ _my_win_key_up(void *d EINA_UNUSED, int type EINA_UNUSED, Ecore_Event_Key *ev)
return ECORE_CALLBACK_RENEW;
}
+static Eina_Bool
+_auto_close(void *data EINA_UNUSED)
+{
+ elm_exit();
+ return EINA_FALSE;
+}
+
static void
-my_win_main(const char *autorun, Eina_Bool test_win_only)
+my_win_main(const char *autorun, Eina_Bool test_win_only, Eina_Bool autoclose)
{
Evas_Object *bg = NULL, *bx0 = NULL, *bx1 = NULL, *lb = NULL, *chk = NULL;
Evas_Object *fr = NULL, *tg = NULL, *sc = NULL, *en = NULL;
Eina_List *l = NULL;
struct elm_test *t = NULL;
+ if (autoclose) ecore_timer_add(2, _auto_close, win);
+
if (test_win_only) goto add_tests;
/* Create an elm window - It returns an evas object. This is a little
* special as the object lives in the canvas that is inside the window
@@ -1151,7 +1162,7 @@ add_tests:
// FIXME: add frame test
ADD_TEST(NULL, "Boundaries", "Bubble", test_bubble);
ADD_TEST(NULL, "Boundaries", "Separator", test_separator);
-
+ ADD_TEST_EO(NULL, "Boundaries", "Separator", test_ui_separator);
//------------------------------//
ADD_TEST(NULL, "Range Values", "Spinner", test_spinner);
ADD_TEST_EO(NULL, "Range Values", "Efl.Ui.Spin", test_ui_spin);
@@ -1172,6 +1183,7 @@ add_tests:
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Plain", test_ui_spotlight_plain);
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Scroll", test_ui_spotlight_scroll);
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Stack", test_ui_spotlight_stack);
+ ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Custom animation", test_ui_spotlight_animation);
ADD_TEST_EO(NULL, "Spotlight", "Navigation stack", test_ui_stack);
//------------------------------//
ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);
@@ -1209,10 +1221,11 @@ add_tests:
ADD_TEST(NULL, "Text", "Label Slide", test_label_slide);
ADD_TEST(NULL, "Text", "Label Wrap", test_label_wrap);
ADD_TEST(NULL, "Text", "Textblock Fit", test_textblock_fit);
+ ADD_TEST(NULL, "Text", "Text Memory", test_text_memory);
ADD_TEST(NULL, "Text", "Label Ellipsis", test_label_ellipsis);
ADD_TEST(NULL, "Text", "Label Colors", test_label_colors);
ADD_TEST(NULL, "Text", "Label Emoji", test_label_emoji);
- ADD_TEST(NULL, "Text", "Label Variation Sequnece", test_label_variation_sequence);
+ ADD_TEST(NULL, "Text", "Label Variation Sequence", test_label_variation_sequence);
ADD_TEST_EO(NULL, "Text", "Efl.Ui.Textpath", test_ui_textpath);
ADD_TEST_EO(NULL, "Text", "Efl.Canvas.Textblock style", test_canvas_textblock);
@@ -1305,7 +1318,7 @@ add_tests:
ADD_TEST_EO(NULL, "Widgets Part", "Part Shadow", test_part_shadow);
//------------------------------//
- ADD_TEST_EO(NULL, "Vector Animation", "Animation View", test_efl_ui_animation_view);
+ ADD_TEST_EO(NULL, "Vector Animation", "Vector Graphics Animation", test_efl_ui_vg_animation);
ADD_TEST_EO(NULL, "Vector Animation", "Value Provider", test_efl_gfx_vg_value_provider);
#undef ADD_TEST
@@ -1361,7 +1374,7 @@ add_tests:
}
/* set an initial window size */
- evas_object_resize(win, 480 * elm_config_scale_get(), 480 * elm_config_scale_get());
+ evas_object_resize(win, 480 * elm_config_scale_get(), 490 * elm_config_scale_get());
evas_object_show(win);
}
@@ -1412,6 +1425,7 @@ efl_main(void *data EINA_UNUSED,
{
Efl_Loop_Arguments *arge = ev->info;
Eina_Bool test_win_only = EINA_FALSE;
+ Eina_Bool autoclose = EINA_FALSE;
char *autorun = NULL;
if (arge->initialization)
@@ -1452,6 +1466,7 @@ efl_main(void *data EINA_UNUSED,
"$ elementary_test\n"
"$ elementary_test --test-win-only [TEST_NAME]\n"
"$ elementary_test -to [TEST_NAME]\n\n"
+ "$ elementary_test --autoclose\n\n"
"Examples:\n"
"$ elementary_test -to Button\n\n"));
return ;
@@ -1465,6 +1480,8 @@ efl_main(void *data EINA_UNUSED,
}
else if (eina_streq(arg, "--all") || eina_streq(arg, "-a"))
all_tests = EINA_TRUE;
+ else if (eina_streq(arg, "--autoclose"))
+ autoclose = EINA_TRUE;
else if ((i == eina_array_count(arge->argv) - 1) && (arg[0] != '-'))
autorun = arg;
@@ -1474,7 +1491,7 @@ efl_main(void *data EINA_UNUSED,
{
}
- my_win_main(autorun, test_win_only); /* create main window */
+ my_win_main(autorun, test_win_only, autoclose); /* create main window */
/* FIXME: Hum, no exit code anywhere anymore ? */
}
diff --git a/src/bin/elementary/test_combobox.c b/src/bin/elementary/test_combobox.c
index ee68a3bdaf..62d21d0913 100644
--- a/src/bin/elementary/test_combobox.c
+++ b/src/bin/elementary/test_combobox.c
@@ -111,7 +111,7 @@ void
test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- Evas_Object *win, *bx, *combobox;
+ Evas_Object *win, *bx, *combobox, *fr;
Elm_Genlist_Item_Class *itc;
win = elm_win_util_standard_add("combobox", "Combobox");
elm_win_autodel_set(win, EINA_TRUE);
@@ -129,6 +129,26 @@ test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
itc->func.filter_get = gl_filter_get;
itc->func.del = NULL;
+ fr = elm_frame_add(win);
+ elm_object_style_set(fr, "pad_huge");
+ evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(bx, fr);
+ evas_object_show(fr);
+
+ combobox = elm_combobox_add(win);
+ evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
+ elm_object_part_text_set(combobox, "guide", "Short List");
+ evas_object_smart_callback_add(combobox, "expanded",
+ _combobox_expanded_cb, NULL);
+ for (int i = 0; i < 5; i++)
+ elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
+ NULL, ELM_GENLIST_ITEM_NONE, NULL,
+ (void*)(uintptr_t)(i * 10));
+ elm_object_content_set(fr, combobox);
+ evas_object_show(combobox);
+
combobox = elm_combobox_add(win);
evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
@@ -178,6 +198,24 @@ test_combobox(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
elm_box_pack_end(bx, combobox);
evas_object_show(combobox);
+ fr = elm_frame_add(win);
+ elm_object_style_set(fr, "pad_huge");
+ evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(bx, fr);
+ evas_object_show(fr);
+
+ combobox = elm_combobox_add(win);
+ evas_object_size_hint_weight_set(combobox, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(combobox, EVAS_HINT_FILL, 0);
+ elm_object_part_text_set(combobox, "guide", "Short List");
+ for (int i = 0; i < 5; i++)
+ elm_genlist_item_append(combobox, itc, (void *)(uintptr_t)i,
+ NULL, ELM_GENLIST_ITEM_NONE, NULL,
+ (void*)(uintptr_t)(i * 10));
+ elm_object_content_set(fr, combobox);
+ evas_object_show(combobox);
+
evas_object_resize(win, 320, 500);
evas_object_show(win);
diff --git a/src/bin/elementary/test_dnd.c b/src/bin/elementary/test_dnd.c
index be0738e122..604f73f33f 100644
--- a/src/bin/elementary/test_dnd.c
+++ b/src/bin/elementary/test_dnd.c
@@ -635,7 +635,7 @@ _gl_dnd_default_anim_data_getcb(Evas_Object *obj, /* The genlist object */
/* Now, collect data to send for drop from ALL selected items */
/* Save list pointer to remove items after drop and free list on done */
info->data = _gl_get_drag_data(obj, it, (Eina_List **) &info->donecbdata);
- printf("%s - data = %s\n", __FUNCTION__, info->data);
+ printf("%s - data = %s\n", __func__, info->data);
info->acceptdata = info->donecbdata;
if (info->data)
@@ -740,7 +740,7 @@ _grid_data_getcb(Evas_Object *obj, /* The genlist object */
/* Now, collect data to send for drop from ALL selected items */
/* Save list pointer to remove items after drop and free list on done */
info->data = _grid_get_drag_data(obj, it, (Eina_List **) &info->donecbdata);
- printf("%s %d- data = %s\n", __FUNCTION__, __LINE__, info->data);
+ printf("%s %d- data = %s\n", __func__, __LINE__, info->data);
info->acceptdata = info->donecbdata;
if (info->data)
@@ -1005,7 +1005,7 @@ static Eina_Bool _drop_box_button_new_cb(void *data, Evas_Object *obj, Elm_Selec
void _enter_but_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
{
- printf("Entered %s - drop it here and I will never print this line anymore.\n", __FUNCTION__);
+ printf("Entered %s - drop it here and I will never print this line anymore.\n", __func__);
}
static Eina_Bool _drop_but_icon_change_cb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
diff --git a/src/bin/elementary/test_efl_anim_alpha.c b/src/bin/elementary/test_efl_anim_alpha.c
index b364319279..3c5f62ca64 100644
--- a/src/bin/elementary/test_efl_anim_alpha.c
+++ b/src/bin/elementary/test_efl_anim_alpha.c
@@ -90,13 +90,13 @@ test_efl_anim_alpha(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Show Animation
- Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(show_anim, 0.0, 1.0);
efl_animation_duration_set(show_anim, 1.0);
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
efl_animation_duration_set(hide_anim, 1.0);
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_group_parallel.c b/src/bin/elementary/test_efl_anim_group_parallel.c
index 728c54ea4e..d560023f2c 100644
--- a/src/bin/elementary/test_efl_anim_group_parallel.c
+++ b/src/bin/elementary/test_efl_anim_group_parallel.c
@@ -88,19 +88,19 @@ test_efl_anim_group_parallel(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
//Rotate from 0 to 45 degrees Animation
- Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(cw_45_degrees_anim, 0.0, 45.0, NULL, EINA_VECTOR2(0.5, 0.5));
//Scale Animation to zoom in
- Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_double_anim, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(2.0, 2.0), NULL, EINA_VECTOR2(0.5, 0.5));
//Hide Parallel Group Animation
- Efl_Canvas_Animation *parallel_hide_anim = efl_add(EFL_CANVAS_ANIMATION_GROUP_PARALLEL_CLASS, win);
+ Efl_Canvas_Animation *parallel_hide_anim = efl_add(EFL_CANVAS_PARALLEL_GROUP_ANIMATION_CLASS, win);
efl_animation_duration_set(parallel_hide_anim, 1.0);
efl_animation_final_state_keep_set(parallel_hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_group_sequential.c b/src/bin/elementary/test_efl_anim_group_sequential.c
index 60b3a836a1..62b00a669e 100644
--- a/src/bin/elementary/test_efl_anim_group_sequential.c
+++ b/src/bin/elementary/test_efl_anim_group_sequential.c
@@ -89,19 +89,19 @@ test_efl_anim_group_sequential(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
/* Animations to hide button */
//Rotate from 0 to 45 degrees Animation
- Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(cw_45_degrees_anim, 0.0, 45.0, NULL, EINA_VECTOR2(0.5, 0.5));
//Scale Animation to zoom in
- Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_double_anim, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(2.0, 2.0), NULL, EINA_VECTOR2(0.5, 0.5));
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
//Hide Sequential Group Animation
- Efl_Canvas_Animation *sequential_hide_anim = efl_add(EFL_CANVAS_ANIMATION_GROUP_SEQUENTIAL_CLASS, win);
+ Efl_Canvas_Animation *sequential_hide_anim = efl_add(EFL_CANVAS_SEQUENTIAL_GROUP_ANIMATION_CLASS, win);
efl_animation_duration_set(sequential_hide_anim, 1.0);
efl_animation_final_state_keep_set(sequential_hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_interpolator.c b/src/bin/elementary/test_efl_anim_interpolator.c
index c5a828ff22..e6c42b711c 100644
--- a/src/bin/elementary/test_efl_anim_interpolator.c
+++ b/src/bin/elementary/test_efl_anim_interpolator.c
@@ -202,7 +202,7 @@ test_efl_anim_interpolator(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
ad->btn[i] = btn;
Efl_Canvas_Animation *anim =
- efl_add(EFL_CANVAS_ANIMATION_TRANSLATE_CLASS, win);
+ efl_add(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS, win);
efl_animation_translate_set(anim, EINA_POSITION2D(0, 0), EINA_POSITION2D((WIN_W - BTN_W), 0));
efl_animation_duration_set(anim, 2.0);
efl_animation_final_state_keep_set(anim, EINA_FALSE);
diff --git a/src/bin/elementary/test_efl_anim_pause.c b/src/bin/elementary/test_efl_anim_pause.c
index 92d4b3e308..8585b38fac 100644
--- a/src/bin/elementary/test_efl_anim_pause.c
+++ b/src/bin/elementary/test_efl_anim_pause.c
@@ -115,13 +115,13 @@ test_efl_anim_pause(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Show Animation
- Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(show_anim, 0.0, 1.0);
efl_animation_duration_set(show_anim, 2.0);
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
efl_animation_duration_set(hide_anim, 2.0);
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_repeat.c b/src/bin/elementary/test_efl_anim_repeat.c
index b3dddcd0e3..26e3d3f00f 100644
--- a/src/bin/elementary/test_efl_anim_repeat.c
+++ b/src/bin/elementary/test_efl_anim_repeat.c
@@ -137,13 +137,13 @@ test_efl_anim_repeat(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Show Animation
- Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(show_anim, 0.0, 1.0);
efl_animation_duration_set(show_anim, 1.0);
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
efl_animation_duration_set(hide_anim, 1.0);
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_rotate.c b/src/bin/elementary/test_efl_anim_rotate.c
index 437d015d75..4e3434cf41 100644
--- a/src/bin/elementary/test_efl_anim_rotate.c
+++ b/src/bin/elementary/test_efl_anim_rotate.c
@@ -88,13 +88,13 @@ test_efl_anim_rotate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Rotate from 0 to 45 degrees Animation
- Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(cw_45_degrees_anim, 0.0, 45.0, NULL, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(cw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(cw_45_degrees_anim, EINA_TRUE);
//Rotate from 45 to 0 degrees Animation
- Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(ccw_45_degrees_anim, 45.0, 0.0, NULL, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(ccw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(ccw_45_degrees_anim, EINA_TRUE);
@@ -147,13 +147,13 @@ test_efl_anim_rotate_relative(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUS
evas_object_show(pivot);
//Rotate from 0 to 45 degrees Animation
- Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(cw_45_degrees_anim, 0.0, 45.0, pivot, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(cw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(cw_45_degrees_anim, EINA_TRUE);
//Rotate from 45 to 0 degrees Animation
- Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_set(ccw_45_degrees_anim, 45.0, 0.0, pivot, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(ccw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(ccw_45_degrees_anim, EINA_TRUE);
@@ -206,13 +206,13 @@ test_efl_anim_rotate_absolute(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUS
evas_object_show(abs_center);
//Rotate from 0 to 45 degrees Animation
- Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *cw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_absolute_set(cw_45_degrees_anim, 0.0, 45.0, EINA_POSITION2D(0, 0));
efl_animation_duration_set(cw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(cw_45_degrees_anim, EINA_TRUE);
//Rotate from 45 to 0 degrees Animation
- Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ANIMATION_ROTATE_CLASS, win);
+ Efl_Canvas_Animation *ccw_45_degrees_anim = efl_add(EFL_CANVAS_ROTATE_ANIMATION_CLASS, win);
efl_animation_rotate_absolute_set(ccw_45_degrees_anim, 45.0, 0.0, EINA_POSITION2D(0, 0));
efl_animation_duration_set(ccw_45_degrees_anim, 1.0);
efl_animation_final_state_keep_set(ccw_45_degrees_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_scale.c b/src/bin/elementary/test_efl_anim_scale.c
index 93ac1f7270..6653772299 100644
--- a/src/bin/elementary/test_efl_anim_scale.c
+++ b/src/bin/elementary/test_efl_anim_scale.c
@@ -88,13 +88,13 @@ test_efl_anim_scale(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Scale Animation to zoom in
- Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_double_anim, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(2.0, 2.0), NULL, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(scale_double_anim, 1.0);
efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE);
//Scale Animation to zoom out
- Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_half_anim, EINA_VECTOR2(2.0, 2.0), EINA_VECTOR2(1.0, 1.0), NULL, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(scale_half_anim, 1.0);
efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE);
@@ -147,13 +147,13 @@ test_efl_anim_scale_relative(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
evas_object_show(pivot);
//Scale Animation to zoom in
- Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_double_anim, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(2.0, 2.0), pivot, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(scale_double_anim, 1.0);
efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE);
//Scale Animation to zoom out
- Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_set(scale_half_anim, EINA_VECTOR2(2.0, 2.0), EINA_VECTOR2(1.0, 1.0), pivot, EINA_VECTOR2(0.5, 0.5));
efl_animation_duration_set(scale_half_anim, 1.0);
efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE);
@@ -206,13 +206,13 @@ test_efl_anim_scale_absolute(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
evas_object_show(abs_center);
//Scale Animation to zoom in
- Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_double_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_absolute_set(scale_double_anim, EINA_VECTOR2(1.0, 1.0), EINA_VECTOR2(2.0, 2.0), EINA_POSITION2D(0, 0));
efl_animation_duration_set(scale_double_anim, 1.0);
efl_animation_final_state_keep_set(scale_double_anim, EINA_TRUE);
//Scale Animation to zoom out
- Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_ANIMATION_SCALE_CLASS, win);
+ Efl_Canvas_Animation *scale_half_anim = efl_add(EFL_CANVAS_SCALE_ANIMATION_CLASS, win);
efl_animation_scale_absolute_set(scale_half_anim, EINA_VECTOR2(2.0, 2.0), EINA_VECTOR2(1.0, 1.0), EINA_POSITION2D(0, 0));
efl_animation_duration_set(scale_half_anim, 1.0);
efl_animation_final_state_keep_set(scale_half_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_start_delay.c b/src/bin/elementary/test_efl_anim_start_delay.c
index 6ef663b33a..ae41fc7f30 100644
--- a/src/bin/elementary/test_efl_anim_start_delay.c
+++ b/src/bin/elementary/test_efl_anim_start_delay.c
@@ -102,13 +102,13 @@ test_efl_anim_start_delay(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Show Animation
- Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *show_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(show_anim, 0.0, 1.0);
efl_animation_duration_set(show_anim, 1.0);
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
//Hide Animation
- Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, win);
+ Efl_Canvas_Animation *hide_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, win);
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
efl_animation_duration_set(hide_anim, 1.0);
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_anim_translate.c b/src/bin/elementary/test_efl_anim_translate.c
index 7617be87d1..c1a3165d45 100644
--- a/src/bin/elementary/test_efl_anim_translate.c
+++ b/src/bin/elementary/test_efl_anim_translate.c
@@ -88,13 +88,13 @@ test_efl_anim_translate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, vo
efl_event_callback_array_add(btn, animation_stats_cb(), ad);
//Translate Animation to right bottom relatively
- Efl_Canvas_Animation *translate_rb_anim = efl_add(EFL_CANVAS_ANIMATION_TRANSLATE_CLASS, win);
+ Efl_Canvas_Animation *translate_rb_anim = efl_add(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS, win);
efl_animation_translate_set(translate_rb_anim, EINA_POSITION2D(0, 0), EINA_POSITION2D(100, 100));
efl_animation_duration_set(translate_rb_anim, 1.0);
efl_animation_final_state_keep_set(translate_rb_anim, EINA_TRUE);
//Translate Animation to left top relatively
- Efl_Canvas_Animation *translate_lt_anim = efl_add(EFL_CANVAS_ANIMATION_TRANSLATE_CLASS, win);
+ Efl_Canvas_Animation *translate_lt_anim = efl_add(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS, win);
efl_animation_translate_set(translate_lt_anim, EINA_POSITION2D(100, 100), EINA_POSITION2D(0, 0));
efl_animation_duration_set(translate_lt_anim, 1.0);
efl_animation_final_state_keep_set(translate_lt_anim, EINA_TRUE);
@@ -147,13 +147,13 @@ test_efl_anim_translate_absolute(void *data EINA_UNUSED, Evas_Object *obj EINA_U
evas_object_show(abs_center);
//Translate Animation to right bottom absolutely
- Efl_Canvas_Animation *translate_rb_anim = efl_add(EFL_CANVAS_ANIMATION_TRANSLATE_CLASS, win);
+ Efl_Canvas_Animation *translate_rb_anim = efl_add(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS, win);
efl_animation_translate_absolute_set(translate_rb_anim, EINA_POSITION2D(0, 0), EINA_POSITION2D(100, 100));
efl_animation_duration_set(translate_rb_anim, 1.0);
efl_animation_final_state_keep_set(translate_rb_anim, EINA_TRUE);
//Translate Animation to left top absolutely
- Efl_Canvas_Animation *translate_lt_anim = efl_add(EFL_CANVAS_ANIMATION_TRANSLATE_CLASS, win);
+ Efl_Canvas_Animation *translate_lt_anim = efl_add(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS, win);
efl_animation_translate_absolute_set(translate_lt_anim, EINA_POSITION2D(100, 100), EINA_POSITION2D(0, 0));
efl_animation_duration_set(translate_lt_anim, 1.0);
efl_animation_final_state_keep_set(translate_lt_anim, EINA_TRUE);
diff --git a/src/bin/elementary/test_efl_gfx_vg_value_provider.c b/src/bin/elementary/test_efl_gfx_vg_value_provider.c
index 9982652464..991c5c4e9d 100644
--- a/src/bin/elementary/test_efl_gfx_vg_value_provider.c
+++ b/src/bin/elementary/test_efl_gfx_vg_value_provider.c
@@ -15,6 +15,12 @@
#ifdef BUILD_VG_LOADER_JSON
+typedef struct _App_Data
+{
+ Eo *label;
+ Eo *slider;
+} App_Data;
+
Evas_Object *values[4], *anim_view;
Evas_Object *path_entry, *type_hoversel;
@@ -49,9 +55,7 @@ add_value_provider(char* new_path, char* new_type, char* new_values)
efl_gfx_vg_value_provider_stroke_color_set(vp, color[0], color[1], color[2], color[3]);
sprintf(new_type, "StrokeColor");
}
-
-
- efl_ui_animation_view_value_provider_override(anim_view, vp);
+ efl_ui_vg_animation_value_provider_override(anim_view, vp);
}
if (!strcmp(type, "StrokeWidth"))
{
@@ -61,12 +65,54 @@ add_value_provider(char* new_path, char* new_type, char* new_values)
char* v = (char*)efl_text_get(values[0]);
if (v) width = strtod(v, NULL);
efl_gfx_vg_value_provider_stroke_width_set(vp, width);
- efl_ui_animation_view_value_provider_override(anim_view, vp);
- evas_object_show(anim_view);
+ efl_ui_vg_animation_value_provider_override(anim_view, vp);
sprintf(new_path, "%s", path);
sprintf(new_type, "StrokeWidth");
sprintf(new_values, "%f", width);
}
+ if (strstr(type, "Tr"))
+ {
+ double value[2], value_cnt;
+ Eina_Matrix4 m;
+ Eo *vp = efl_add(EFL_GFX_VG_VALUE_PROVIDER_CLASS, anim_view);
+
+ efl_gfx_vg_value_provider_keypath_set(vp, (char*)path);
+
+ value_cnt = strstr(type, "Rotation") ? 1 : 2;
+ for( int i = 0; i < value_cnt; i++)
+ {
+ char* v = (char*)efl_text_get(values[i]);
+ if (v) value[i] = atof(v);
+ }
+
+ eina_matrix4_identity(&m);
+ if (!strcmp(type, "TrPosition"))
+ {
+ // Z projection
+ eina_matrix4_translate(&m, value[0], value[1], 0);
+ sprintf(new_type, "TrPosition");
+ sprintf(new_values, "%f %f",value[0], value[1]);
+
+ }
+ else if (!strcmp(type, "TrScale"))
+ {
+ // Z projection
+ eina_matrix4_scale(&m, value[0], value[1], 1);
+ sprintf(new_type, "TrScale");
+ sprintf(new_values, "%f %f",value[0], value[1]);
+ }
+ else if (!strcmp(type, "TrRotation"))
+ {
+ // Z projection
+ eina_matrix4_rotate(&m, value[0] * (M_PI / 180), EINA_MATRIX_AXIS_Z); //degree to radian
+ sprintf(new_values, "%f",value[0]);
+ sprintf(new_type, "TrRotation");
+ }
+
+ sprintf(new_path, "%s", path);
+ efl_gfx_vg_value_provider_transform_set(vp, &m);
+ efl_ui_vg_animation_value_provider_override(anim_view, vp);
+ }
return EINA_TRUE;
}
@@ -78,15 +124,23 @@ btn_clicked_cb(void *data , const Efl_Event *ev )
if (!text) return;
if (!strcmp("Play", text))
- efl_ui_animation_view_play((Evas_Object*)data);
+ {
+ double speed = efl_player_playback_speed_get(anim_view);
+ efl_player_playback_speed_set(anim_view, speed < 0 ? speed * -1 : speed);
+ efl_player_playing_set(anim_view, EINA_TRUE);
+ }
else if (!strcmp("Pause", text))
- efl_ui_animation_view_pause((Evas_Object*)data);
+ efl_player_paused_set((Evas_Object*)data, EINA_TRUE);
else if (!strcmp("Resume", text))
- efl_ui_animation_view_resume((Evas_Object*)data);
- else if (!strcmp("Play Back", text))
- efl_ui_animation_view_play_back((Evas_Object*)data);
+ efl_player_paused_set((Evas_Object*)data, EINA_FALSE);
+ else if (!strcmp("Play Backwards", text))
+ {
+ double speed = efl_player_playback_speed_get(anim_view);
+ efl_player_playback_speed_set(anim_view, speed > 0 ? speed * -1 : speed);
+ efl_player_playing_set(anim_view, EINA_TRUE);
+ }
else if (!strcmp("Stop", text))
- efl_ui_animation_view_stop((Evas_Object*)data);
+ efl_player_playing_set((Evas_Object*)data, EINA_FALSE);
else if (!strcmp("ADD", text))
{
Evas_Object *list = (Evas_Object*)data;
@@ -94,9 +148,9 @@ btn_clicked_cb(void *data , const Efl_Event *ev )
char new_path[255], new_type[255], new_values[255];
if (add_value_provider(new_path, new_type, new_values))
{
- char buf[255];
+ char buf[765];
//TODO: Even if there is the same path as the existing item, it is added without updating.
- // In efl_ui_animation_view, duplicate paths are managed.
+ // In efl_ui_vg_animation, duplicate paths are managed.
// However, animator (lottie) does not have an implementation that manages overridden values.
/*Eina_List *items = (Eina_List*)elm_list_items_get(list);
Eina_List *l;
@@ -115,7 +169,7 @@ btn_clicked_cb(void *data , const Efl_Event *ev )
}
}
}*/
- sprintf(buf, "%s/%s/%s", new_path, new_type, new_values);
+ snprintf(buf, sizeof(buf), "%s/%s/%s", new_path, new_type, new_values);
list_it = elm_list_item_append(list, buf, NULL, NULL, NULL, NULL);
elm_list_item_bring_in(list_it);
elm_list_go(list);
@@ -145,7 +199,7 @@ static void
check_changed_cb(void *data, const Efl_Event *event)
{
Evas_Object *anim_view = data;
- efl_ui_animation_view_auto_repeat_set(anim_view, efl_ui_selectable_selected_get(event->object));
+ efl_player_playback_loop_set(anim_view, efl_ui_selectable_selected_get(event->object));
}
static void
@@ -154,92 +208,34 @@ speed_changed_cb(void *data, const Efl_Event *event)
Evas_Object *anim_view = data;
double speed = 1;
if (efl_ui_selectable_selected_get(event->object)) speed = 0.25;
- efl_ui_animation_view_speed_set(anim_view, speed);
+ efl_player_playback_speed_set(anim_view, speed);
}
static void
limit_frame_cb(void *data, const Efl_Event *event)
{
Evas_Object *anim_view = data;
- int frame_count = efl_ui_animation_view_frame_count_get(anim_view);
+ int frame_count = efl_ui_vg_animation_frame_count_get(anim_view);
printf("Total Frame Count : %d\n", frame_count);
if (efl_ui_selectable_selected_get(event->object))
{
- efl_ui_animation_view_min_frame_set(anim_view, 5);
- efl_ui_animation_view_max_frame_set(anim_view, 10);
+ efl_ui_vg_animation_min_frame_set(anim_view, 5);
+ efl_ui_vg_animation_max_frame_set(anim_view, 10);
printf("Frames to show 5-10 only\n");
}
else
{
- efl_ui_animation_view_min_frame_set(anim_view, 0);
- efl_ui_animation_view_max_frame_set(anim_view, frame_count);
+ efl_ui_vg_animation_min_frame_set(anim_view, 0);
+ efl_ui_vg_animation_max_frame_set(anim_view, frame_count);
printf("Showing all frames now\n");
}
}
static void
-update_anim_view_state(Evas_Object *anim_view, Evas_Object *label)
-{
- Efl_Ui_Animation_View_State state = efl_ui_animation_view_state_get(anim_view);
-
- switch (state)
- {
- case EFL_UI_ANIMATION_VIEW_STATE_NOT_READY:
- efl_text_set(label, "State = Not Ready");
- break;
- case EFL_UI_ANIMATION_VIEW_STATE_PLAY:
- efl_text_set(label, "State = Playing");
- break;
- case EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK:
- efl_text_set(label, "State = Playing Back");
- break;
- case EFL_UI_ANIMATION_VIEW_STATE_PAUSE:
- efl_text_set(label, "State = Paused");
- break;
- case EFL_UI_ANIMATION_VIEW_STATE_STOP:
- efl_text_set(label, "State = Stopped");
- break;
- }
-}
-
-static void
-_play_updated(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
-{
- Evas_Object *slider = data;
- efl_ui_range_value_set(slider, efl_ui_animation_view_progress_get(obj));
-}
-
-static void
-_state_update(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
-{
- Evas_Object *label = data;
- update_anim_view_state(obj, label);
-}
-
-static void
-_play_done(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
-{
- printf("done!\n");
-}
-
-static void
-_play_repeated(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
-{
- printf("repeated!\n");
-}
-
-static void
_slider_changed_cb(void *data, const Efl_Event *ev)
{
Evas_Object *anim_view = data;
- efl_ui_animation_view_progress_set(anim_view, efl_ui_range_value_get(ev->object));
-}
-
-static void
-_slider_reset(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
-{
- Evas_Object *slider = data;
- efl_ui_range_value_set(slider, 0);
+ efl_player_playback_progress_set(anim_view, efl_ui_range_value_get(ev->object));
}
void values_input(Eo* box, const char* type)
@@ -279,6 +275,37 @@ void values_input(Eo* box, const char* type)
efl_gfx_hint_size_min_set(values[0], EINA_SIZE2D(50, 10));
efl_text_set(efl_part(values[0], "efl.text_guide"), "Width(double type)");
}
+ else if (strstr(type, "Tr"))
+ {
+ char text[2][2];
+ if (!strcmp(type, "TrPosition"))
+ {
+ snprintf(text[0], sizeof(text[0]), "X");
+ snprintf(text[1], sizeof(text[1]), "Y");
+ }
+ else if (!strcmp(type, "TrScale"))
+ {
+ snprintf(text[0], sizeof(text[0]), "W");
+ snprintf(text[1], sizeof(text[1]), "H");
+ }
+ else if (!strcmp(type, "TrRotation"))
+ {
+ snprintf(text[0], sizeof(text[0]), "R");
+ }
+
+ int value_cnt = strstr(type, "Rotation") ? 1 : 2;
+ for( int i = 0; i < value_cnt; i++)
+ {
+ values[i] = efl_add(EFL_UI_TEXTBOX_CLASS, box,
+ efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
+ efl_gfx_hint_fill_set(efl_added, EINA_FALSE, EINA_FALSE),
+ efl_gfx_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL),
+ efl_text_interactive_editable_set(efl_added, EINA_TRUE),
+ efl_pack(box, efl_added));
+ efl_gfx_hint_size_min_set(values[i], EINA_SIZE2D(50, 10));
+ efl_text_set(efl_part(values[i], "efl.text_guide"), text[i]);
+ }
+ }
}
static void
@@ -291,18 +318,102 @@ _hover_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
values_input(box, selected);
}
+static void
+update_anim_view_state(Evas_Object *anim_view, Evas_Object *label)
+{
+ Efl_Ui_Vg_Animation_State state = efl_ui_vg_animation_state_get(anim_view);
+
+ switch (state)
+ {
+ case EFL_UI_VG_ANIMATION_STATE_NOT_READY:
+ efl_text_set(label, "State = Not Ready");
+ break;
+ case EFL_UI_VG_ANIMATION_STATE_PLAYING:
+ efl_text_set(label, "State = Playing");
+ break;
+ case EFL_UI_VG_ANIMATION_STATE_PLAYING_BACKWARDS:
+ efl_text_set(label, "State = Playing Backwards");
+
+ break;
+ case EFL_UI_VG_ANIMATION_STATE_PAUSED:
+ efl_text_set(label, "State = Paused");
+ break;
+ case EFL_UI_VG_ANIMATION_STATE_STOPPED:
+ efl_text_set(label, "State = Stopped");
+ break;
+ }
+}
+
+static void
+_animation_playing_changed_cb(void *data, const Efl_Event *event)
+{
+ Eina_Bool playing = *(Eina_Bool*)event->info;
+ App_Data *ad = data;
+ update_anim_view_state(event->object, ad->label);
+ //Stopped
+ if (!playing)
+ efl_ui_range_value_set(ad->slider, 0);
+}
+
+static void
+_animation_paused_changed_cb(void *data, const Efl_Event *event)
+{
+ App_Data *ad = data;
+ update_anim_view_state(event->object, ad->label);
+}
+
+static void
+_animation_playback_progress_changed_cb(void *data, const Efl_Event *event)
+{
+ double progress = *(double*)event->info;
+ App_Data *ad = data;
+ efl_ui_range_value_set(ad->slider, progress);
+}
+
+static void
+_animation_playback_repeated_changed_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ int repeated_times = *(int*)event->info;
+ printf("repeated! (times: %d)\n", repeated_times);
+}
+
+static void
+_animation_playback_finished_changed_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
+{
+ printf("done!\n");
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(animation_stats_cb,
+ {EFL_PLAYER_EVENT_PLAYING_CHANGED, _animation_playing_changed_cb },
+ {EFL_PLAYER_EVENT_PAUSED_CHANGED, _animation_paused_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_PROGRESS_CHANGED, _animation_playback_progress_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_REPEATED, _animation_playback_repeated_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_FINISHED, _animation_playback_finished_changed_cb },
+)
+
+static void
+_win_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ App_Data *ad = data;
+ free(ad);
+}
+
void
test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *box, *box_sub, *label, *check, *slider, *list;
char buf[255];
+ App_Data *ad = calloc(1, sizeof(App_Data));
+ if (!ad) return;
+
// This line must to need.
setenv("ELM_ACCEL", "gl", 1);
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
- efl_text_set(efl_added, "Efl_Ui_Animation_View demo"),
- efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+ efl_text_set(efl_added, "Efl_Ui_Vg_Animation demo"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL, _win_del_cb, ad));
// Create a box in Canvas
box = efl_add(EFL_UI_BOX_CLASS, win,
@@ -317,7 +428,7 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
//Create Animation View to play animation directly from JSON file
snprintf(buf, sizeof(buf), "%s/images/three_box.json", elm_app_data_dir_get());
- anim_view = efl_add(EFL_UI_ANIMATION_VIEW_CLASS, win,
+ anim_view = efl_add(EFL_UI_VG_ANIMATION_CLASS, win,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND),
efl_gfx_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL),
efl_gfx_entity_size_set(efl_added, EINA_SIZE2D(600, 600)),
@@ -394,6 +505,9 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
elm_hoversel_item_add(type_hoversel, "FillColor", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
elm_hoversel_item_add(type_hoversel, "StrokeColor", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
elm_hoversel_item_add(type_hoversel, "StrokeWidth", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
+ elm_hoversel_item_add(type_hoversel, "TrPosition", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
+ elm_hoversel_item_add(type_hoversel, "TrScale", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
+ elm_hoversel_item_add(type_hoversel, "TrRotation", NULL, ELM_ICON_NONE, _hover_item_selected_cb, box_sub);
evas_object_show(type_hoversel);
elm_object_focus_set(type_hoversel, EINA_TRUE);
efl_pack(box_sub, type_hoversel);
@@ -478,7 +592,7 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
//Duration Text
- snprintf(buf, sizeof(buf), "Duration: %1.2fs", efl_ui_animation_view_duration_time_get(anim_view));
+ snprintf(buf, sizeof(buf), "Duration(Length): %1.2fs", efl_playable_length_get(anim_view));
efl_add(EFL_UI_TEXTBOX_CLASS, box_sub,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
efl_gfx_hint_fill_set(efl_added, EINA_FALSE, EINA_FALSE),
@@ -514,7 +628,7 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
efl_add(EFL_UI_BUTTON_CLASS, box_sub,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
efl_gfx_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL),
- efl_text_set(efl_added, "Play Back"),
+ efl_text_set(efl_added, "Play Backwards"),
efl_pack(box_sub, efl_added),
efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, btn_clicked_cb, anim_view));
@@ -549,16 +663,10 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
efl_pack(box_sub, efl_added),
efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, btn_clicked_cb, anim_view));
- evas_object_smart_callback_add(anim_view, "play,start", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,stop", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,pause", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,resume", _state_update, label);
-
- evas_object_smart_callback_add(anim_view, "play,repeat", _play_repeated, label);
- evas_object_smart_callback_add(anim_view, "play,done", _play_done, label);
+ efl_event_callback_array_add(anim_view, animation_stats_cb(), ad);
- evas_object_smart_callback_add(anim_view, "play,update", _play_updated, slider);
- evas_object_smart_callback_add(anim_view, "play,stop", _slider_reset, slider);
+ ad->label = label;
+ ad->slider = slider;
update_anim_view_state(anim_view, label);
@@ -575,7 +683,7 @@ test_efl_gfx_vg_value_provider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNU
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
- efl_text_set(efl_added, "Efl_Ui_Animation_View demo"),
+ efl_text_set(efl_added, "Efl_Ui_Vg_Animation demo"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
// Create a box
diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c
index dc1748bd07..49cfff589f 100644
--- a/src/bin/elementary/test_efl_ui_text.c
+++ b/src/bin/elementary/test_efl_ui_text.c
@@ -8,13 +8,13 @@
static void
_apply_style(Eo *obj, size_t start_pos, size_t end_pos, const char *style)
{
- Efl_Text_Cursor *start, *end;
+ Efl_Text_Cursor_Object *start, *end;
start = efl_ui_textbox_cursor_create(obj);
end = efl_ui_textbox_cursor_create(obj);
- efl_text_cursor_position_set(start, start_pos);
- efl_text_cursor_position_set(end, end_pos);
+ efl_text_cursor_object_position_set(start, start_pos);
+ efl_text_cursor_object_position_set(end, end_pos);
efl_text_formatter_attribute_insert(start, end, style);
@@ -101,15 +101,15 @@ typedef struct
static void
_on_bt3_clicked(void *data, const Efl_Event *event EINA_UNUSED)
{
- Efl_Text_Cursor *sel_start, *sel_end;
+ Efl_Text_Cursor_Object *sel_start, *sel_end;
Eo *en = data;
efl_text_interactive_selection_cursors_get(en, &sel_start, &sel_end);
- const char *s = efl_text_cursor_range_text_get(sel_start, sel_end);
+ const char *s = efl_text_cursor_object_range_text_get(sel_start, sel_end);
printf("SELECTION REGION: %d - %d\n",
- efl_text_cursor_position_get( sel_start),
- efl_text_cursor_position_get(sel_end));
+ efl_text_cursor_object_position_get( sel_start),
+ efl_text_cursor_object_position_get(sel_end));
printf("SELECTION:\n");
if (s) printf("%s\n", s);
}
@@ -234,7 +234,6 @@ test_efl_ui_text_inputfield(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED
efl_text_multiline_set(en, EINA_TRUE);
efl_ui_textbox_scrollable_set(en, EINA_TRUE);
evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0.5);
- efl_pack(bx, en);
efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 200));
diff --git a/src/bin/elementary/test_efl_ui_animation_view.c b/src/bin/elementary/test_efl_ui_vg_animation.c
index f5a73df745..a54a816bf1 100644
--- a/src/bin/elementary/test_efl_ui_animation_view.c
+++ b/src/bin/elementary/test_efl_ui_vg_animation.c
@@ -14,6 +14,12 @@
#ifdef BUILD_VG_LOADER_JSON
+typedef struct _App_Data
+{
+ Eo *label;
+ Eo *slider;
+} App_Data;
+
static void
btn_clicked_cb(void *data , const Efl_Event *ev )
{
@@ -23,22 +29,30 @@ btn_clicked_cb(void *data , const Efl_Event *ev )
if (!text) return;
if (!strcmp("Play", text))
- efl_ui_animation_view_play(anim_view);
+ {
+ double speed = efl_player_playback_speed_get(anim_view);
+ efl_player_playback_speed_set(anim_view, speed < 0 ? speed * -1 : speed);
+ efl_player_playing_set(anim_view, EINA_TRUE);
+ }
else if (!strcmp("Pause", text))
- efl_ui_animation_view_pause(anim_view);
+ efl_player_paused_set(anim_view, EINA_TRUE);
else if (!strcmp("Resume", text))
- efl_ui_animation_view_resume(anim_view);
- else if (!strcmp("Play Back", text))
- efl_ui_animation_view_play_back(anim_view);
+ efl_player_paused_set(anim_view, EINA_FALSE);
+ else if (!strcmp("Play Backwards", text))
+ {
+ double speed = efl_player_playback_speed_get(anim_view);
+ efl_player_playback_speed_set(anim_view, speed > 0 ? speed * -1 : speed);
+ efl_player_playing_set(anim_view, EINA_TRUE);
+ }
else if (!strcmp("Stop", text))
- efl_ui_animation_view_stop(anim_view);
+ efl_player_playing_set(anim_view, EINA_FALSE);
}
static void
check_changed_cb(void *data, const Efl_Event *event)
{
Evas_Object *anim_view = data;
- efl_ui_animation_view_auto_repeat_set(anim_view, efl_ui_selectable_selected_get(event->object));
+ efl_player_playback_loop_set(anim_view, efl_ui_selectable_selected_get(event->object));
}
static void
@@ -47,103 +61,127 @@ speed_changed_cb(void *data, const Efl_Event *event)
Evas_Object *anim_view = data;
double speed = 1;
if (efl_ui_selectable_selected_get(event->object)) speed = 0.25;
- efl_ui_animation_view_speed_set(anim_view, speed);
+ efl_player_playback_speed_set(anim_view, speed);
}
static void
limit_frame_cb(void *data, const Efl_Event *event)
{
Evas_Object *anim_view = data;
- int frame_count = efl_ui_animation_view_frame_count_get(anim_view);
+ int frame_count = efl_ui_vg_animation_frame_count_get(anim_view);
printf("Total Frame Count : %d\n", frame_count);
if (efl_ui_selectable_selected_get(event->object))
{
- efl_ui_animation_view_min_frame_set(anim_view, 5);
- efl_ui_animation_view_max_frame_set(anim_view, 10);
+ efl_ui_vg_animation_min_frame_set(anim_view, 5);
+ efl_ui_vg_animation_max_frame_set(anim_view, 10);
printf("Frames to show 5-10 only\n");
}
else
{
- efl_ui_animation_view_min_frame_set(anim_view, 0);
- efl_ui_animation_view_max_frame_set(anim_view, frame_count);
+ efl_ui_vg_animation_min_frame_set(anim_view, 0);
+ efl_ui_vg_animation_max_frame_set(anim_view, frame_count);
printf("Showing all frames now\n");
}
}
static void
+_slider_changed_cb(void *data, const Efl_Event *ev)
+{
+ Evas_Object *anim_view = data;
+ efl_player_playback_progress_set(anim_view, efl_ui_range_value_get(ev->object));
+}
+
+static void
update_anim_view_state(Evas_Object *anim_view, Evas_Object *label)
{
- Efl_Ui_Animation_View_State state = efl_ui_animation_view_state_get(anim_view);
+ Efl_Ui_Vg_Animation_State state = efl_ui_vg_animation_state_get(anim_view);
switch (state)
{
- case EFL_UI_ANIMATION_VIEW_STATE_NOT_READY:
+ case EFL_UI_VG_ANIMATION_STATE_NOT_READY:
efl_text_set(label, "State = Not Ready");
break;
- case EFL_UI_ANIMATION_VIEW_STATE_PLAY:
+ case EFL_UI_VG_ANIMATION_STATE_PLAYING:
efl_text_set(label, "State = Playing");
break;
- case EFL_UI_ANIMATION_VIEW_STATE_PLAY_BACK:
- efl_text_set(label, "State = Playing Back");
+ case EFL_UI_VG_ANIMATION_STATE_PLAYING_BACKWARDS:
+ efl_text_set(label, "State = Playing Backwards");
break;
- case EFL_UI_ANIMATION_VIEW_STATE_PAUSE:
+ case EFL_UI_VG_ANIMATION_STATE_PAUSED:
efl_text_set(label, "State = Paused");
break;
- case EFL_UI_ANIMATION_VIEW_STATE_STOP:
+ case EFL_UI_VG_ANIMATION_STATE_STOPPED:
efl_text_set(label, "State = Stopped");
break;
}
}
static void
-_play_updated(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
+_animation_playing_changed_cb(void *data, const Efl_Event *event)
{
- Evas_Object *slider = data;
- efl_ui_range_value_set(slider, efl_ui_animation_view_progress_get(obj));
+ Eina_Bool playing = *(Eina_Bool*)event->info;
+ App_Data *ad = data;
+ update_anim_view_state(event->object, ad->label);
+ //Stopped
+ if (!playing)
+ efl_ui_range_value_set(ad->slider, 0);
}
static void
-_state_update(void *data, Evas_Object *obj, void *ev EINA_UNUSED)
+_animation_paused_changed_cb(void *data, const Efl_Event *event)
{
- Evas_Object *label = data;
- update_anim_view_state(obj, label);
+ App_Data *ad = data;
+ update_anim_view_state(event->object, ad->label);
}
static void
-_play_done(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
+_animation_playback_progress_changed_cb(void *data, const Efl_Event *event)
{
- printf("done!\n");
+ double progress = *(double*)event->info;
+ App_Data *ad = data;
+ efl_ui_range_value_set(ad->slider, progress);
}
static void
-_play_repeated(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
+_animation_playback_repeated_changed_cb(void *data EINA_UNUSED, const Efl_Event *event)
{
- printf("repeated!\n");
+ int repeated_times = *(int*)event->info;
+ printf("repeated! (times: %d)\n", repeated_times);
}
static void
-_slider_changed_cb(void *data, const Efl_Event *ev)
+_animation_playback_finished_changed_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
{
- Evas_Object *anim_view = data;
- efl_ui_animation_view_progress_set(anim_view, efl_ui_range_value_get(ev->object));
+ printf("done!\n");
}
+EFL_CALLBACKS_ARRAY_DEFINE(animation_stats_cb,
+ {EFL_PLAYER_EVENT_PLAYING_CHANGED, _animation_playing_changed_cb },
+ {EFL_PLAYER_EVENT_PAUSED_CHANGED, _animation_paused_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_PROGRESS_CHANGED, _animation_playback_progress_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_REPEATED, _animation_playback_repeated_changed_cb },
+ {EFL_PLAYER_EVENT_PLAYBACK_FINISHED, _animation_playback_finished_changed_cb },
+)
+
static void
-_slider_reset(void *data, Evas_Object *obj EINA_UNUSED, void *ev EINA_UNUSED)
+_win_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Evas_Object *slider = data;
- efl_ui_range_value_set(slider, 0);
+ App_Data *ad = data;
+ free(ad);
}
void
-test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+test_efl_ui_vg_animation(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *box, *box2, *box3, *box4, *label, *anim_view, *check, *slider;
char buf[255];
+ App_Data *ad = calloc(1, sizeof(App_Data));
+ if (!ad) return;
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
- efl_text_set(efl_added, "Efl_Ui_Animation_View demo"),
- efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+ efl_text_set(efl_added, "Efl_Ui_Vg_Animation demo"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_EVENT_DEL, _win_del_cb, ad));
// Create a box in Canvas
box = efl_add(EFL_UI_BOX_CLASS, win,
@@ -158,7 +196,7 @@ test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
//Create Animation View to play animation directly from JSON file
snprintf(buf, sizeof(buf), "%s/images/emoji_wink.json", elm_app_data_dir_get());
- anim_view = efl_add(EFL_UI_ANIMATION_VIEW_CLASS, win,
+ anim_view = efl_add(EFL_UI_VG_ANIMATION_CLASS, win,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND),
efl_gfx_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL),
efl_gfx_entity_size_set(efl_added, EINA_SIZE2D(600, 600)),
@@ -200,7 +238,7 @@ test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
//Duration Text
- snprintf(buf, sizeof(buf), "Duration: %1.2fs", efl_ui_animation_view_duration_time_get(anim_view));
+ snprintf(buf, sizeof(buf), "Duration(Length): %1.2fs", efl_playable_length_get(anim_view));
efl_add(EFL_UI_TEXTBOX_CLASS, box2,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
efl_gfx_hint_fill_set(efl_added, EINA_FALSE, EINA_FALSE),
@@ -236,7 +274,7 @@ test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
efl_add(EFL_UI_BUTTON_CLASS, box3,
efl_gfx_hint_weight_set(efl_added, EFL_GFX_HINT_EXPAND, 0),
efl_gfx_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL),
- efl_text_set(efl_added, "Play Back"),
+ efl_text_set(efl_added, "Play Backwards"),
efl_pack(box3, efl_added),
efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, btn_clicked_cb, anim_view));
@@ -271,32 +309,26 @@ test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
efl_pack(box4, efl_added),
efl_event_callback_add(efl_added, EFL_INPUT_EVENT_CLICKED, btn_clicked_cb, anim_view));
- evas_object_smart_callback_add(anim_view, "play,start", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,stop", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,pause", _state_update, label);
- evas_object_smart_callback_add(anim_view, "play,resume", _state_update, label);
-
- evas_object_smart_callback_add(anim_view, "play,repeat", _play_repeated, label);
- evas_object_smart_callback_add(anim_view, "play,done", _play_done, label);
-
- evas_object_smart_callback_add(anim_view, "play,update", _play_updated, slider);
- evas_object_smart_callback_add(anim_view, "play,stop", _slider_reset, slider);
+ efl_event_callback_array_add(anim_view, animation_stats_cb(), ad);
update_anim_view_state(anim_view, label);
+ ad->label = label;
+ ad->slider = slider;
+
efl_gfx_entity_size_set(win, EINA_SIZE2D(600, 730));
}
#else
void
-test_efl_ui_animation_view(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+test_efl_ui_vg_animation(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *box;
char buf[255];
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
- efl_text_set(efl_added, "Efl_Ui_Animation_View demo"),
+ efl_text_set(efl_added, "Efl_Ui_Vg_Animation demo"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
// Create a box
diff --git a/src/bin/elementary/test_factory.c b/src/bin/elementary/test_factory.c
index daae81b63d..71ca204023 100644
--- a/src/bin/elementary/test_factory.c
+++ b/src/bin/elementary/test_factory.c
@@ -5,7 +5,7 @@
// 16 ^ 4 = 65k
#define BLOK 16
-// homogenous layout
+// homogeneous layout
//#define HOMOG 1
// aligned to top of box
#define ZEROALIGN 1
diff --git a/src/bin/elementary/test_gengrid.c b/src/bin/elementary/test_gengrid.c
index e2009e0db6..83f2dd9262 100644
--- a/src/bin/elementary/test_gengrid.c
+++ b/src/bin/elementary/test_gengrid.c
@@ -2160,6 +2160,7 @@ test_gengrid_update(void *data EINA_UNUSED,
win = elm_win_util_standard_add("gengrid-update", "Gengrid Update");
elm_win_autodel_set(win, EINA_TRUE);
+ evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, api);
api->box = bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
diff --git a/src/bin/elementary/test_genlist.c b/src/bin/elementary/test_genlist.c
index 749d04fe63..41ff4a3903 100644
--- a/src/bin/elementary/test_genlist.c
+++ b/src/bin/elementary/test_genlist.c
@@ -292,6 +292,24 @@ _gl_selected(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i
}
static void
+_gl_unselected(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ printf("unselected: %p\n", event_info);
+}
+
+static void
+_gl_highlighted(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ printf("highlighted: %p\n", event_info);
+}
+
+static void
+_gl_unhighlighted(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ printf("unhighlighted: %p\n", event_info);
+}
+
+static void
_gl_double_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
printf("double clicked: %p\n", event_info);
@@ -445,6 +463,9 @@ test_genlist(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i
gl = elm_genlist_add(win);
evas_object_smart_callback_add(gl, "selected", _gl_selected, NULL);
+ evas_object_smart_callback_add(gl, "unselected", _gl_unselected, NULL);
+ evas_object_smart_callback_add(gl, "highlighted", _gl_highlighted, NULL);
+ evas_object_smart_callback_add(gl, "unhighlighted", _gl_unhighlighted, NULL);
evas_object_smart_callback_add(gl, "clicked,double", _gl_double_clicked, NULL);
evas_object_smart_callback_add(gl, "clicked,right", _gl_right_clicked, NULL);
evas_object_smart_callback_add(gl, "longpressed", _gl_longpress, NULL);
@@ -5528,20 +5549,21 @@ test_genlist_show_item(void *data,
api->itc1->func.state_get = NULL;
api->itc1->func.del = NULL;
- g_data->gl = gl;
- g_data->itc1 = api->itc1;
-
- max = g_data->max_items;
- for (i = 0; i <= max; i++)
- elm_genlist_item_append(gl, api->itc1, (void*)(uintptr_t)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
-
if (g_data)
- gli = elm_genlist_nth_item_get(gl, g_data->show_item);
- if (!gli) gli = elm_genlist_last_item_get(gl);
- elm_genlist_item_show(gli, g_data->type);
-
- //prepends item while queue processing is happening
- ecore_timer_add(0.1, _late_item_prepender, g_data);
+ {
+ g_data->gl = gl;
+ g_data->itc1 = api->itc1;
+
+ max = g_data->max_items;
+ for (i = 0; i <= max; i++)
+ elm_genlist_item_append(gl, api->itc1, (void*)(uintptr_t)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+
+ gli = elm_genlist_nth_item_get(gl, g_data->show_item);
+ if (!gli) gli = elm_genlist_last_item_get(gl);
+ elm_genlist_item_show(gli, g_data->type);
+ //prepends item while queue processing is happening
+ ecore_timer_add(0.1, _late_item_prepender, g_data);
+ }
evas_object_resize(win, 480, 400);
explode_win_enable(win);
diff --git a/src/bin/elementary/test_gesture_framework.c b/src/bin/elementary/test_gesture_framework.c
index 5e2e935e49..4675604fa3 100644
--- a/src/bin/elementary/test_gesture_framework.c
+++ b/src/bin/elementary/test_gesture_framework.c
@@ -6,7 +6,7 @@
#define TAP_NAME "tap"
#define DOUBLE_TAP_NAME "double_tap"
#define TRIPLE_TAP_NAME "triple_tap"
-#define LONG_TAP_NAME "long_tap"
+#define LONG_PRESS_NAME "long_press"
#define FLICK_NAME "flick"
#define LINE_NAME "line"
#define MOMENTUM_NAME "momentum"
@@ -17,7 +17,7 @@
#define MAX_DOUBLE_TAP 5
#define MAX_FLICK 5
#define MAX_LINE 5
-#define MAX_LONG_TAP 5
+#define MAX_LONG_PRESS 5
#define MAX_MOMENTUM 5
#define MAX_ROTATE 1
#define MAX_TAP 5
@@ -59,7 +59,7 @@ struct _infra_data
icon_properties *icons;
Ecore_Timer *colortimer;
char buf[1024];
- int long_tap_count;
+ int long_press_count;
};
typedef struct _infra_data infra_data;
@@ -224,6 +224,60 @@ finger_flick_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
}
static void
+finger_rotate_start(void *data , Efl_Canvas_Gesture *tap)
+{
+ Eina_Position2D pos = efl_gesture_hotspot_get(tap);
+
+ _color_and_icon_set(data, ROTATE_NAME, 1, MAX_TAP, START_COLOR);
+ printf("Rotate Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
+}
+
+static void
+finger_rotate_end(void *data , Efl_Canvas_Gesture *tap)
+{
+ Eina_Position2D pos = efl_gesture_hotspot_get(tap);
+ double angle = efl_gesture_rotate_angle_get(tap);
+ double radius = efl_gesture_rotate_radius_get(tap);
+
+ _color_and_icon_set(data, ROTATE_NAME, 1, MAX_TAP, END_COLOR);
+ printf("Rotate Gesture ended x,y=<%d,%d> angle=<%g> radius=<%f>\n", pos.x, pos.y, angle, radius);
+}
+
+static void
+finger_rotate_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
+{
+ _color_and_icon_set(data, ROTATE_NAME, 1, MAX_TAP, ABORT_COLOR);
+ printf("Rotate Aborted\n");
+}
+
+static void
+finger_zoom_start(void *data , Efl_Canvas_Gesture *tap)
+{
+ Eina_Position2D pos = efl_gesture_hotspot_get(tap);
+
+ _color_and_icon_set(data, ZOOM_NAME, 1, MAX_TAP, START_COLOR);
+ printf("Zoom Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
+}
+
+static void
+finger_zoom_end(void *data , Efl_Canvas_Gesture *tap)
+{
+ Eina_Position2D pos = efl_gesture_hotspot_get(tap);
+ double zoom = efl_gesture_zoom_get(tap);
+ double radius = efl_gesture_zoom_radius_get(tap);
+
+ _color_and_icon_set(data, ZOOM_NAME, 1, MAX_TAP, END_COLOR);
+ printf("Zoom Gesture ended x,y=<%d,%d> zoom=<%g> radius=<%f>\n", pos.x, pos.y, zoom, radius);
+}
+
+static void
+finger_zoom_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
+{
+ _color_and_icon_set(data, ZOOM_NAME, 1, MAX_TAP, ABORT_COLOR);
+ printf("Zoom Aborted\n");
+}
+
+static void
finger_momentum_start(void *data , Efl_Canvas_Gesture *tap)
{
Eina_Position2D pos = efl_gesture_hotspot_get(tap);
@@ -333,34 +387,34 @@ finger_double_tap_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
}
static void
-finger_long_tap_start(void *data , Efl_Canvas_Gesture *tap)
+finger_long_press_start(void *data , Efl_Canvas_Gesture *tap)
{
Eina_Position2D pos = efl_gesture_hotspot_get(tap);
- _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, START_COLOR);
+ _color_and_icon_set(data, LONG_PRESS_NAME, 1, MAX_TAP, START_COLOR);
printf("Long Tap Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
}
static void
-finger_long_tap_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
+finger_long_press_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
{
- _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, UPDATE_COLOR);
+ _color_and_icon_set(data, LONG_PRESS_NAME, 1, MAX_TAP, UPDATE_COLOR);
printf("Long Tap Gesture updated\n");
}
static void
-finger_long_tap_end(void *data , Efl_Canvas_Gesture *tap)
+finger_long_press_end(void *data , Efl_Canvas_Gesture *tap)
{
Eina_Position2D pos = efl_gesture_hotspot_get(tap);
- _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, END_COLOR);
+ _color_and_icon_set(data, LONG_PRESS_NAME, 1, MAX_TAP, END_COLOR);
printf("Long Tap Gesture ended x,y=<%d,%d> \n",pos.x, pos.y);
}
static void
-finger_long_tap_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
+finger_long_press_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
{
- _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, ABORT_COLOR);
+ _color_and_icon_set(data, LONG_PRESS_NAME, 1, MAX_TAP, ABORT_COLOR);
printf("Long Tap Aborted\n");
}
@@ -370,13 +424,13 @@ tap_gesture_cb(void *data , const Efl_Event *ev)
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
+ case EFL_GESTURE_STATE_STARTED:
finger_tap_start(data, g);
break;
- case EFL_GESTURE_CANCELED:
+ case EFL_GESTURE_STATE_CANCELED:
finger_tap_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
+ case EFL_GESTURE_STATE_FINISHED:
finger_tap_end(data, g);
break;
default:
@@ -390,13 +444,13 @@ flick_gesture_cb(void *data , const Efl_Event *ev)
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
+ case EFL_GESTURE_STATE_STARTED:
finger_flick_start(data, g);
break;
- case EFL_GESTURE_CANCELED:
+ case EFL_GESTURE_STATE_CANCELED:
finger_flick_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
+ case EFL_GESTURE_STATE_FINISHED:
finger_flick_end(data, g);
break;
default:
@@ -405,21 +459,61 @@ flick_gesture_cb(void *data , const Efl_Event *ev)
}
static void
+rotate_gesture_cb(void *data , const Efl_Event *ev)
+{
+ Efl_Canvas_Gesture *g = ev->info;
+ switch(efl_gesture_state_get(g))
+ {
+ case EFL_GESTURE_STATE_STARTED:
+ finger_rotate_start(data, g);
+ break;
+ case EFL_GESTURE_STATE_CANCELED:
+ finger_rotate_abort(data, g);
+ break;
+ case EFL_GESTURE_STATE_FINISHED:
+ finger_rotate_end(data, g);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+zoom_gesture_cb(void *data , const Efl_Event *ev)
+{
+ Efl_Canvas_Gesture *g = ev->info;
+ switch(efl_gesture_state_get(g))
+ {
+ case EFL_GESTURE_STATE_STARTED:
+ finger_zoom_start(data, g);
+ break;
+ case EFL_GESTURE_STATE_CANCELED:
+ finger_zoom_abort(data, g);
+ break;
+ case EFL_GESTURE_STATE_FINISHED:
+ finger_zoom_end(data, g);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
momentum_gesture_cb(void *data , const Efl_Event *ev)
{
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
+ case EFL_GESTURE_STATE_STARTED:
finger_momentum_start(data, g);
break;
- case EFL_GESTURE_UPDATED:
+ case EFL_GESTURE_STATE_UPDATED:
finger_momentum_update(data, g);
break;
- case EFL_GESTURE_CANCELED:
+ case EFL_GESTURE_STATE_CANCELED:
finger_momentum_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
+ case EFL_GESTURE_STATE_FINISHED:
finger_momentum_end(data, g);
break;
default:
@@ -433,16 +527,16 @@ triple_tap_gesture_cb(void *data , const Efl_Event *ev)
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
+ case EFL_GESTURE_STATE_STARTED:
finger_triple_tap_start(data, g);
break;
- case EFL_GESTURE_UPDATED:
+ case EFL_GESTURE_STATE_UPDATED:
finger_triple_tap_update(data, g);
break;
- case EFL_GESTURE_CANCELED:
+ case EFL_GESTURE_STATE_CANCELED:
finger_triple_tap_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
+ case EFL_GESTURE_STATE_FINISHED:
finger_triple_tap_end(data, g);
break;
default:
@@ -456,16 +550,16 @@ double_tap_gesture_cb(void *data , const Efl_Event *ev)
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
+ case EFL_GESTURE_STATE_STARTED:
finger_double_tap_start(data, g);
break;
- case EFL_GESTURE_UPDATED:
+ case EFL_GESTURE_STATE_UPDATED:
finger_double_tap_update(data, g);
break;
- case EFL_GESTURE_CANCELED:
+ case EFL_GESTURE_STATE_CANCELED:
finger_double_tap_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
+ case EFL_GESTURE_STATE_FINISHED:
finger_double_tap_end(data, g);
break;
default:
@@ -474,22 +568,22 @@ double_tap_gesture_cb(void *data , const Efl_Event *ev)
}
static void
-long_tap_gesture_cb(void *data , const Efl_Event *ev)
+long_press_gesture_cb(void *data , const Efl_Event *ev)
{
Efl_Canvas_Gesture *g = ev->info;
switch(efl_gesture_state_get(g))
{
- case EFL_GESTURE_STARTED:
- finger_long_tap_start(data, g);
+ case EFL_GESTURE_STATE_STARTED:
+ finger_long_press_start(data, g);
break;
- case EFL_GESTURE_UPDATED:
- finger_long_tap_update(data, g);
+ case EFL_GESTURE_STATE_UPDATED:
+ finger_long_press_update(data, g);
break;
- case EFL_GESTURE_CANCELED:
- finger_long_tap_abort(data, g);
+ case EFL_GESTURE_STATE_CANCELED:
+ finger_long_press_abort(data, g);
break;
- case EFL_GESTURE_FINISHED:
- finger_long_tap_end(data, g);
+ case EFL_GESTURE_STATE_FINISHED:
+ finger_long_press_end(data, g);
break;
default:
break;
@@ -578,7 +672,7 @@ test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
elm_table_pack(tb, bx, 2, 0, 1, 1);
/* Box of Long Tap icon and label */
- bx = create_gesture_box(win, infra->icons, 3, LONG_TAP_NAME, "Long Tap");
+ bx = create_gesture_box(win, infra->icons, 3, LONG_PRESS_NAME, "Long Tap");
elm_table_pack(tb, bx, 3, 0, 1, 1);
/* Box of Momentum icon and label */
@@ -689,11 +783,13 @@ test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
// LISTEN FOR GESTURES
efl_event_callback_add(target, EFL_EVENT_GESTURE_TAP, tap_gesture_cb, infra);
- efl_event_callback_add(target, EFL_EVENT_GESTURE_LONG_TAP, long_tap_gesture_cb, infra);
+ efl_event_callback_add(target, EFL_EVENT_GESTURE_LONG_PRESS, long_press_gesture_cb, infra);
efl_event_callback_add(target, EFL_EVENT_GESTURE_DOUBLE_TAP, double_tap_gesture_cb, infra);
efl_event_callback_add(target, EFL_EVENT_GESTURE_TRIPLE_TAP, triple_tap_gesture_cb, infra);
efl_event_callback_add(target, EFL_EVENT_GESTURE_MOMENTUM, momentum_gesture_cb, infra);
efl_event_callback_add(target, EFL_EVENT_GESTURE_FLICK, flick_gesture_cb, infra);
+ efl_event_callback_add(target, EFL_EVENT_GESTURE_ROTATE, rotate_gesture_cb, infra);
+ efl_event_callback_add(target, EFL_EVENT_GESTURE_ZOOM, zoom_gesture_cb, infra);
/* Update color state 20 times a second */
infra->colortimer = ecore_timer_add(0.05, _icon_color_set_cb, infra->icons);
diff --git a/src/bin/elementary/test_gesture_layer3.c b/src/bin/elementary/test_gesture_layer3.c
index 1029087d44..7e5007aed1 100644
--- a/src/bin/elementary/test_gesture_layer3.c
+++ b/src/bin/elementary/test_gesture_layer3.c
@@ -272,7 +272,7 @@ rotate_end(void *_po, void *event_info)
po->rot_tot_time = fabs(r_info->momentum) / ROTATE_MOMENTUM_FRICTION;
po->rot_momentum = r_info->momentum;
po->rot_progress = 0.0;
- if (po->rot_momentum)
+ if (EINA_DBL_NONZERO(po->rot_momentum))
{
po->rot_timer = ecore_animator_add(rotate_momentum_animation_operation, po);
}
@@ -334,7 +334,7 @@ zoom_end(void *_po, void *event_info)
po->zoom_mom_time = tot_time;
po->zoom_mom = p->momentum;
po->base_zoom = po->zoom;
- if (po->zoom_mom)
+ if (EINA_DBL_NONZERO(po->zoom_mom))
{
po->zoom_momentum = elm_transit_add();
elm_transit_duration_set(po->zoom_momentum,
@@ -425,7 +425,7 @@ momentum_end(void *_po, void *event_info)
po->mom_tot_time = sqrt((p->mx * p->mx) + (p->my * p->my))
/ MOMENTUM_FRICTION;
- if (po->mom_tot_time)
+ if (EINA_DBL_NONZERO(po->mom_tot_time))
{ /* Compute acceleration for both compenents, and launch timer */
po->mom_x_acc = (p->mx) / po->mom_tot_time; /* a = (v-v0) / t */
po->mom_y_acc = (p->my) / po->mom_tot_time; /* a = (v-v0) / t */
diff --git a/src/bin/elementary/test_glview_manygears.c b/src/bin/elementary/test_glview_manygears.c
index 31084b78ec..fbf404bf4f 100644
--- a/src/bin/elementary/test_glview_manygears.c
+++ b/src/bin/elementary/test_glview_manygears.c
@@ -405,7 +405,7 @@ perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFa
sine = sin(radians);
cosine = cos(radians);
- if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
+ if (EINA_DBL_EQ(deltaZ, 0) || EINA_DBL_EQ(sine, 0) || EINA_DBL_EQ(aspect, 0))
return;
cotangent = cosine / sine;
diff --git a/src/bin/elementary/test_icon_animated.c b/src/bin/elementary/test_icon_animated.c
index 3ecfa26950..301f9a9385 100644
--- a/src/bin/elementary/test_icon_animated.c
+++ b/src/bin/elementary/test_icon_animated.c
@@ -22,8 +22,7 @@ test_icon_animated(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
- win = elm_win_add(NULL, "icon-animated-gif", ELM_WIN_BASIC);
- elm_win_title_set(win, "Icon Animated Gif");
+ win = elm_win_util_standard_add("icon-animated-gif", "Icon Animated Gif");
elm_win_autodel_set(win, EINA_TRUE);
bx = elm_box_add(win);
diff --git a/src/bin/elementary/test_label.c b/src/bin/elementary/test_label.c
index 5b3e5e8265..de7c2bcf32 100644
--- a/src/bin/elementary/test_label.c
+++ b/src/bin/elementary/test_label.c
@@ -492,6 +492,8 @@ test_textblock_fit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e
evas_textblock_style_set(style,styles[0]);
evas_object_textblock_style_set(app->txtblock,style);
evas_object_textblock_text_markup_set(app->txtblock,contents[0]);
+ evas_textblock_style_free(style);
+ style = NULL;
elm_box_horizontal_set(app->boxHor, EINA_TRUE);
elm_box_horizontal_set(app->boxHor2, EINA_TRUE);
@@ -541,6 +543,124 @@ test_textblock_fit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e
evas_object_show(app->win);
}
+/*** Text Memory Configuration **************************************************************/
+enum BUTTON_MEM{
+ BUTTON_MEM_SET_TEXT = 0,
+ BUTTON_MEM_APPLY_MEM = 1,
+ BUTTON_MEM_APPLY_FONT_SIZE = 2,
+ BUTTON_MEM_ALL = BUTTON_MEM_APPLY_FONT_SIZE+1,
+};
+
+char* BUTTON_MEM_STR[BUTTON_MEM_ALL] ={
+ "Load Emojis Text",
+ "Memory Limit(MB)",
+ "Font Size"
+};
+
+char *content = "<align=center>😀😁😂🤣😃😄😅😆😉😊😋😎😍😘😗😙😚☺🙂🤗🤔😐😑😶🙄😏😣😥😮🤐😯😪😫😴😌🤓😛😜😝🤤😒😓😔😕🙃🤑😲☹🙁😖😞😟😤😢😭😦😧😨😩😬😰😱😳😵😡😠😇🤠🤡🤥😷🤒🤕🤢🤧☻😈👿👹👺💀☠👻👽👾🤖💩😺😸😹😻😼😽🙀😿😾🙈🙉🙊👦👧👨👩👵👶👼👨‍⚕️👩‍⚕️👨‍🎓👩‍🎓👨‍🏫👩‍🏫👨‍⚖👩‍⚖👨‍🌾👩‍🌾👨‍🍳👩‍🍳👨‍🔧👩‍🔧👨‍🏭👩‍🏭👨‍💼👩‍💼👨‍🔬👩‍🔬👨‍💻👩‍💻👨‍🎤👩‍🎤👨‍🎨👩‍🎨👨‍✈️👩‍✈️👨‍🚀👩‍🚀👨‍🚒👩‍🚒👮‍♂️👮‍♀️🕵️‍♂️🕵️‍♀️💂‍♂️💂‍♀️👷‍♂️👷‍♀️👳‍♂️👳‍♀️👱‍♂️👱‍♀️🎅🤶👸🤴👰🤵🤰👲🙍‍♂️🙍‍♀️🙎‍♂️🙎‍♀️🙅‍♂️🙅‍♀️🙆‍♂️🙆‍♀️💁‍♂️💁‍♀️🙋‍♂️🙋‍♀️🙇‍♂️🙇‍♀️🤦‍♂️🤦‍♀️🤷‍♂️🤷‍♀️💆‍♂️💆‍♀️💇‍♂️💇‍♀️🚶‍♂️🚶‍♀️🏃‍♂️🏃‍♀️💃🕺👯‍♂️👯‍♀️🕴🗣👤👥👫👬👭💏💑👪👨‍👩‍👧👨‍👩‍👧‍👦👨‍👩‍👦‍👦👨‍👩‍👧‍👧👨‍👦👨‍👦‍👦👨‍👧👨‍👧‍👦👨‍👧‍👧👩‍👦👩‍👦‍👦👩‍👧👩‍👧‍👦👩‍👧‍👧💪🤳👈👉☝️👆🖕👇✌🤞🖖🤘👊🖐✋👌👍👎✊👊🤛🤜🤚👋👏✍👐🙌🙏🤝💅👂👃👣👀👁👅👄💋💘❤💓💔💕💖💗💙💚💛💜🖤💝💞💟❣💌💤💢💣💥💦💨💫💬🗨🗯💭🕳👓🕶👔👕👖👗👘👙👚👛👜👝🛍🎒👞👟👠👡👢👑👒🎩🎓⛑📿💄💍💎🐵🐒🦍🐶🐕🐩🐺🦊🐱🐈🦁🐯🐅🐆🐴🐎🦌🦄🐮🐂🐃🐄🐷🐖🐗🐽🐏🐑🐐🐪🐫🐘🦏🐭🐁🐀🐹🐰🐇🐿🦇🐻🐨🐼🐾🦃🐔🐓🐣🐤🐥🐦🐧🕊🦅🦆🦉🐸🐊🐢🦎🐍🐲🐉🐳🐋🐬🐟🐠🐡🦈🐙🐚🦀🦐🦑🦋🐌🐛🐜🐝🐞🕷🕸🦂💐🌸💮🏵🌹🥀🌺🌻🌼🌷⚘🌱🌲🌳🌴🌵🌾🌿☘🍀🍁🍂🍃🍇🍈🍉🍊🍋🍌🍍🍎🍏🍐🍑🍒🍓🍅🥝🥑🍆🥔🥕🌽🌶🥒🍄🥜🌰🍞🥐🥖🥞🧀🍖🍗🥓🍔🍟🍕🌭🌮🌯🥙🥚🍳🥘🍲🥗🍿🍱🍘🍙🍚🍛🍜🍝🍠🍢🍣🍤🍥🍡🍦🍧🍨🍩🍪🎂🍰🍫🍬🍭🍮🍯🍼🥛☕🍵🍶🍾🍷🍸🍹🍺🍻🥂🍽🍴🥄🔪🏺🎃🎄🎆🎇✨🎈🎉🎊🎋🎍🎎🎏🎐🎑🎀🎁🎗🎟🎫🎖🏆🏅🥇🥈🥉⚽️⚾️🏀🏐🏈🏉🎾🎱🎳🏏🏑🏒🏓🏸🥊🥋🥅🎯⛳🏌️‍♂️🏌️‍♀️⛸🎣🎽🎿⛷🏂🏄‍♂️🏄‍♀️🏇🏊‍♂️🏊‍♀️⛹️‍♂️⛹️‍♀️🏋️‍♂️🏋️‍♀️🚴‍♂️🚴‍♀️🚵‍♂️🚵‍♀️🏎🏍🤸‍♂️🤸‍♀️🤼‍♂️🤼‍♀️🤽‍♂️🤽‍♀️🤾‍♂️🤾‍♀️🤺🤹‍♂️🤹‍♀️🎮🕹🎲♠️♥️♦️♣️🃏🀄🎴🌍🌎🌏🌐🗺🏔⛰🌋🗻🏕🏖🏜🏝🏞🏟🏛🏗🏘🏙🏚🏠🏡🏢🏣🏤🏥🏦🏨🏩🏪🏫🏬🏭🏯🏰💒🗼🗽⛪🕌🕍⛩🕋⛲⛺🌁🌃🌄🌅🌆🌇🌉⛼♨️🌌🎠🎡🎢💈🎪🎭🖼🎨🎰🚂🚃🚄🚅🚆🚇🚈🚉🚊🚝🚞🚋🚌🚍🚎🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛⛟🚜🚲🛴🛵🚏🛣🛤⛽🚨🚥🚦🚧🛑⚓⛵🚣‍♂️🚣‍♀️🛶🚤🛳⛴🛥🚢✈🛩🛫🛬💺🚁🚟🚠🚡🚀🛰🛎🚪🛌🛏🛋🚽🚿🛀🛁⌛⏳⌚⏰⏱⏲🕰🕛🕧🕐🕜🕑🕝🕒🕞🕓🕟🕔🕠🕕🕡🕖🕢🕗🕣🕘🕤🕙🕥🕚🕦🌑🌒🌓🌔🌕🌖🌗🌘🌙🌚🌛🌜🌡☀️🌝🌞⭐🌟🌠☁️⛅⛈🌤🌥🌦🌧🌨🌩🌪🌫🌬🌀🌈🌂☂️☔⛱⚡❄☃️⛄☄🔥💧🌊🔇🔈🔉🔊📢📣📯🔔🔕🎼🎵🎶🎙🎚🎛🎤🎧📻🎷🎸🎹🎺🎻🥁📱📲☎️📞📟📠🔋🔌💻🖥🖨⌨🖱🖲💽💾💿📀🎥🎞📽🎬📺📷📸📹📼🔍🔎🔬🔭📡🕯💡🔦🏮📔📕📖📗📘📙📚📓📒📃📜📄📰🗞📑🔖🏷💰💴💵💶💷💸💳💱💲✉📧📨📩📤📥📦📫📪📬📭📮🗳✏✒🖋🖊🖌🖍📝💼📁📂🗂📅📆🗒🗓📇📈📉📊📋📌📍📎🖇📏📐✂️🗃🗄🗑🔒🔓🔏🔐🔑🗝🔨⛏⚒🛠🗡⚔🔫🏹🛡🔧🔩⚙🗜⚗⚖🔗⛓💉💊🚬⚰⚱🗿🛢🔮🔮🏧🚮🚰♿🚹🚺🚻🚼🚾🛂🛃🛄🛅⚠️🚸⛔🚫🚳🚭🚯🚱🚷📵🔞☢☣⬆️↗️➡️↘️⬇️↙️⬅️↖️↕️↔️↩↪⤴️⤵️🔃🔄🔙🔚🔛🔜🔝🛐⚛🕉✡☸☯️☦☮🕎🔯♈♉♊♋♌♍♎♏♐♑♒♓⛎🔀🔁🔂▶️⏩⏭⏯◀️⏪⏮🔼⏫🔽⏬⏸⏹⏺⏏🎦🔅🔆📶📳📴♻️📛⚜🔰🔱⭕✅☑✔✖❌❎➕♀️♂️⚕➖➗➰➿〽✳✴❇⁉️❓❔❕❗〰🔟💯🔠🔡🔢🔣🔤🅰️🆎️🅱️🆑️🆒️🆓️ℹ🆔️Ⓜ️🆕️🆖️🅾️🆗️🅿️🆘️🆙️🆚️🈁🈂🈷🈶🈯🉐🈹🈚🈲🉑🈸🈴🈳㊗㊙🈺🈵▫️◻◼◽◾⬛⬜🔶️🔷️🔸️🔹️🔺️🔻💠🔘🔲🔳⚪⚫🔴🔵🏁🚩🏴🏳🏳️‍🌈⚀⚁⚂⚃⚄⚅⛾♾🇦🇨🇦🇩🇦🇪🇦🇫🇦🇬🇦🇮🇦🇱🇦🇲🇦🇴🇦🇶🇦🇷🇦🇸🇦🇹🇦🇺🇦🇼🇦🇽🇦🇿🇧🇦🇧🇧🇧🇩🇧🇪🇧🇫🇧🇬🇧🇭🇧🇮🇧🇯🇧🇱🇧🇲🇧🇳🇧🇴🇧🇶🇧🇷🇧🇸🇧🇹🇧🇼🇧🇾🇧🇿🇨🇦🇨🇨🇨🇩🇨🇫🇨🇬🇨🇭🇨🇮🇨🇰🇨🇱🇨🇲🇨🇳🇨🇴🇨🇷🇨🇺🇨🇻🇨🇼🇨🇽🇨🇾🇨🇿🇩🇪🇩🇯🇩🇰🇩🇲🇩🇴🇩🇿🇪🇨🇪🇪🇪🇬🇪🇭🇪🇷🇪🇸🇪🇹🇪🇺🇫🇮🇫🇯🇫🇰🇫🇲🇫🇴🇫🇷🇬🇦🇬🇧🇬🇩🇬🇪🇬🇫🇬🇬🇬🇭🇬🇮🇬🇱🇬🇲🇬🇳🇬🇵🇬🇶🇬🇷🇬🇸🇬🇹🇬🇺🇬🇼🇬🇾🇭🇰🇭🇲🇭🇳🇭🇷🇭🇹🇭🇺🇮🇨🇮🇩🇮🇪🇮🇱🇮🇲🇮🇳🇮🇴🇮🇶🇮🇷🇮🇸🇮🇹🇯🇪🇯🇲🇯🇴🇯🇵🇰🇪🇰🇬🇰🇭🇰🇮🇰🇲🇰🇳🇰🇵🇰🇷🇰🇼🇰🇾🇰🇿🇱🇦🇱🇧🇱🇨🇱🇮🇱🇰🇱🇷🇱🇸🇱🇹🇱🇺🇱🇻🇱🇾🇲🇦🇲🇨🇲🇩🇲🇪🇲🇬🇲🇭🇲🇰🇲🇱🇲🇲🇲🇳🇲🇴🇲🇵🇲🇶🇲🇷🇲🇸🇲🇹🇲🇺🇲🇻🇲🇼🇲🇽🇲🇾🇲🇿🇳🇦🇳🇨🇳🇪🇳🇫🇳🇬🇳🇮🇳🇱🇳🇴🇳🇵🇳🇷🇳🇺🇳🇿🇴🇲🇵🇦🇵🇪🇵🇫🇵🇬🇵🇭🇵🇰🇵🇱🇵🇲🇵🇳🇵🇷🇵🇸🇵🇹🇵🇼🇵🇾🇶🇦🇷🇪🇷🇴🇷🇸🇷🇺🇷🇼🇸🇦🇸🇧🇸🇨🇸🇩🇸🇪🇸🇬🇸🇭🇸🇮🇸🇰🇸🇱🇸🇲🇸🇳🇸🇴🇸🇷🇸🇸🇸🇹🇸🇻🇸🇽🇸🇾🇸🇿🇹🇦🇹🇨🇹🇩🇹🇫🇹🇬🇹🇭🇹🇯🇹🇰🇹🇱🇹🇲🇹🇳🇹🇴🇹🇷🇹🇹🇹🇻🇹🇼🇹🇿🇺🇦🇺🇬🇺🇳🇺🇸🇺🇾🇺🇿🇻🇦🇻🇨🇻🇪🇻🇬🇻🇮🇻🇳🇻🇺🇼🇫🇼🇸🇽🇰🇾🇪🇾🇹🇿🇦🇿🇲🇿🇼</align>";
+
+typedef struct _APP_MEM
+{
+ Evas_Object *win, *box, *main_entry;
+ Eo *btn[BUTTON_MEM_ALL];
+ Eo *entry[BUTTON_MEM_ALL];
+} APP_MEM;
+APP_MEM *app_mem;
+
+static void _btn_clicked_mem(void *data EINA_UNUSED, Eo *obj, void *eventInfo EINA_UNUSED){
+ if (obj == app_mem->btn[BUTTON_MEM_SET_TEXT])
+ {
+ elm_object_text_set(app_mem->main_entry, content);
+ }
+ else if (obj == app_mem->btn[BUTTON_MEM_APPLY_MEM])
+ {
+ int size = atoi(elm_object_text_get(app_mem->entry[BUTTON_MEM_APPLY_MEM]));
+ if (size > 0 && size < 4000)
+ {
+ evas_font_data_cache_set(EVAS_FONT_DATA_CACHE_TEXTURE, size * 1024 * 1024);
+ }
+ else
+ {
+ elm_object_text_set(app_mem->entry[BUTTON_MEM_APPLY_MEM], "NAN");
+ }
+ }
+ else if (obj == app_mem->btn[BUTTON_MEM_APPLY_FONT_SIZE])
+ {
+ int font_size = atoi(elm_object_text_get(app_mem->entry[BUTTON_MEM_APPLY_FONT_SIZE]));
+ if (font_size > 0 && font_size < 1000)
+ {
+ char sfont_size[256] = {0};
+ sprintf(sfont_size,"DEFAULT='font_size=%i'", font_size);
+ elm_entry_text_style_user_push(app_mem->main_entry, sfont_size);
+ }
+ else
+ {
+ elm_object_text_set(app_mem->entry[BUTTON_MEM_APPLY_FONT_SIZE], "NAN");
+ }
+ }
+}
+
+void
+test_text_memory(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ app_mem = calloc(sizeof(APP_MEM), 1);
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+ app_mem->win = elm_win_util_standard_add("Main", "App");
+ elm_win_autodel_set(app_mem->win, EINA_TRUE);
+
+ app_mem->box = elm_box_add(app_mem->win);
+ app_mem->main_entry = elm_entry_add(app_mem->box);
+
+ evas_object_size_hint_weight_set(app_mem->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(app_mem->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ app_mem->btn[BUTTON_MEM_SET_TEXT] = elm_button_add(app_mem->box);
+ evas_object_smart_callback_add(app_mem->btn[BUTTON_MEM_SET_TEXT], "clicked", _btn_clicked_mem, NULL);
+ elm_object_text_set(app_mem->btn[BUTTON_MEM_SET_TEXT], BUTTON_MEM_STR[BUTTON_MEM_SET_TEXT]);
+ evas_object_size_hint_align_set(app_mem->btn[BUTTON_MEM_SET_TEXT], EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_box_pack_end(app_mem->box, app_mem->btn[BUTTON_MEM_SET_TEXT]);
+ evas_object_show(app_mem->btn[BUTTON_MEM_SET_TEXT]);
+
+ elm_entry_scrollable_set(app_mem->main_entry, EINA_TRUE);
+ evas_object_show(app_mem->main_entry);
+ evas_object_show(app_mem->box);
+
+ elm_box_pack_end(app_mem->box, app_mem->main_entry);
+ evas_object_smart_callback_add(app_mem->btn[BUTTON_MEM_SET_TEXT], "clicked", _btn_clicked_mem, NULL);
+ evas_object_show(app_mem->btn[BUTTON_MEM_SET_TEXT]);
+
+ elm_win_resize_object_add(app_mem->win, app_mem->box);
+ evas_object_resize(app_mem->win, 320, 320);
+
+ elm_entry_text_style_user_push(app_mem->main_entry, "DEFAULT='font_size=20'");
+
+ for(int i = BUTTON_MEM_APPLY_MEM ; i < BUTTON_MEM_ALL ; i++)
+ {
+ app_mem->btn[i] = elm_button_add(app_mem->box);
+ app_mem->entry[i] = elm_entry_add(app_mem->box);
+ evas_object_smart_callback_add(app_mem->btn[i], "clicked", _btn_clicked_mem, NULL);
+ elm_object_text_set(app_mem->btn[i], BUTTON_MEM_STR[i]);
+ elm_box_pack_end(app_mem->box, app_mem->btn[i]);
+ elm_box_pack_end(app_mem->box, app_mem->entry[i]);
+
+ evas_object_size_hint_align_set(app_mem->btn[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_align_set(app_mem->entry[i], EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ evas_object_show(app_mem->btn[i]);
+ evas_object_show(app_mem->entry[i]);
+ }
+
+ elm_object_text_set(app_mem->entry[BUTTON_MEM_APPLY_MEM],"Texture limit in MB");
+ elm_object_text_set(app_mem->entry[BUTTON_MEM_APPLY_FONT_SIZE],"20");
+
+ evas_object_size_hint_weight_set(app_mem->main_entry, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(app_mem->main_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ evas_object_show(app_mem->win);
+}
+
/*** Label Wrap **************************************************************/
void
test_label_wrap(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
diff --git a/src/bin/elementary/test_map.c b/src/bin/elementary/test_map.c
index 3fe55b9be7..b87f3d6521 100644
--- a/src/bin/elementary/test_map.c
+++ b/src/bin/elementary/test_map.c
@@ -448,7 +448,7 @@ _map_name_loaded(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA
if (addr)
{
printf("name of [lon = %lf, lat = %lf] is %s\n", lon, lat, addr);
- if ((lon != 0.0) && (lat !=0.0))
+ if (EINA_DBL_NONZERO(lon) && EINA_DBL_NONZERO(lat))
{
Eina_Bool b = elm_map_paused_get(data);
elm_map_paused_set(data, EINA_TRUE);
@@ -1096,8 +1096,6 @@ test_map(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info
evas_object_event_callback_add(map, EVAS_CALLBACK_DEL, _del_map, NULL);
- srand(time(NULL));
-
tile_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_TILE);
route_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_ROUTE);
name_srcs = elm_map_sources_get(map, ELM_MAP_SOURCE_TYPE_NAME);
diff --git a/src/bin/elementary/test_naviframe.c b/src/bin/elementary/test_naviframe.c
index 81696148ba..36e4bdb332 100644
--- a/src/bin/elementary/test_naviframe.c
+++ b/src/bin/elementary/test_naviframe.c
@@ -65,6 +65,43 @@ _promote(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
elm_naviframe_item_promote(data);
}
+Eina_Bool
+_pop_cb(void *data EINA_UNUSED, Elm_Object_Item *it)
+{
+ elm_object_item_del(it);
+
+ /* If EINA_TRUE is returned, pop transition effect happens and then the item
+ * is automatically deleted.
+ * If EINA_FALSE is returned, pop transition effect does not happen and the
+ * item is not automatically deleted.
+ */
+ return EINA_FALSE;
+}
+
+void
+_page9(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ Evas_Object *bt, *bt2, *nf = data;
+ Elm_Object_Item *it;
+
+ bt = elm_button_add(nf);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ BUTTON_TEXT_SET(bt, "Page 8");
+
+ bt2 = elm_button_add(nf);
+ evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ BUTTON_TEXT_SET(bt2, "Page 1");
+ evas_object_smart_callback_add(bt2, "clicked", _promote,
+ evas_object_data_get(nf, "page1"));
+
+ it = elm_naviframe_item_push(nf, "Page 9", bt, bt2, NULL, NULL);
+ elm_object_item_part_text_set(it, "subtitle", "Callback for naviframe item pop is set");
+
+ elm_naviframe_item_pop_cb_set(it, _pop_cb, NULL);
+
+ evas_object_smart_callback_add(bt, "clicked", _navi_pop, nf);
+}
+
void
_page8(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -78,9 +115,9 @@ _page8(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
bt2 = elm_button_add(nf);
evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
- BUTTON_TEXT_SET(bt2, "Page 1");
- evas_object_smart_callback_add(bt2, "clicked", _promote,
- evas_object_data_get(nf, "page1"));
+ BUTTON_TEXT_SET(bt2, "Page 9");
+ evas_object_smart_callback_add(bt2, "clicked", _page9, nf);
+
content = _content_new(nf, img6);
it = elm_naviframe_item_push(nf, "Page 8", bt, bt2, content, NULL);
elm_object_item_part_text_set(it, "subtitle", "Overlap style!");
diff --git a/src/bin/elementary/test_part_shadow.c b/src/bin/elementary/test_part_shadow.c
index c8e0f18591..12b202c86e 100644
--- a/src/bin/elementary/test_part_shadow.c
+++ b/src/bin/elementary/test_part_shadow.c
@@ -37,11 +37,11 @@ pulse_start(void *data, const Efl_Event *ev EINA_UNUSED)
{
Test_Data *td = data;
- efl_ui_progressbar_pulse_set(td->pb1, EINA_TRUE);
- efl_ui_progressbar_pulse_set(td->pb2, EINA_TRUE);
- efl_ui_progressbar_pulse_set(td->pb3, EINA_TRUE);
- efl_ui_progressbar_pulse_set(td->pb4, EINA_TRUE);
- efl_ui_progressbar_pulse_set(td->pb5, EINA_TRUE);
+ efl_ui_progressbar_infinite_mode_set(td->pb1, EINA_TRUE);
+ efl_ui_progressbar_infinite_mode_set(td->pb2, EINA_TRUE);
+ efl_ui_progressbar_infinite_mode_set(td->pb3, EINA_TRUE);
+ efl_ui_progressbar_infinite_mode_set(td->pb4, EINA_TRUE);
+ efl_ui_progressbar_infinite_mode_set(td->pb5, EINA_TRUE);
efl_ui_widget_disabled_set(td->btn_start, EINA_TRUE);
efl_ui_widget_disabled_set(td->btn_stop, EINA_FALSE);
@@ -54,11 +54,11 @@ pulse_stop(void *data, const Efl_Event *ev EINA_UNUSED)
{
Test_Data *td = data;
- efl_ui_progressbar_pulse_set(td->pb1, EINA_FALSE);
- efl_ui_progressbar_pulse_set(td->pb2, EINA_FALSE);
- efl_ui_progressbar_pulse_set(td->pb3, EINA_FALSE);
- efl_ui_progressbar_pulse_set(td->pb4, EINA_FALSE);
- efl_ui_progressbar_pulse_set(td->pb5, EINA_FALSE);
+ efl_ui_progressbar_infinite_mode_set(td->pb1, EINA_FALSE);
+ efl_ui_progressbar_infinite_mode_set(td->pb2, EINA_FALSE);
+ efl_ui_progressbar_infinite_mode_set(td->pb3, EINA_FALSE);
+ efl_ui_progressbar_infinite_mode_set(td->pb4, EINA_FALSE);
+ efl_ui_progressbar_infinite_mode_set(td->pb5, EINA_FALSE);
efl_ui_widget_disabled_set(td->btn_start, EINA_FALSE);
efl_ui_widget_disabled_set(td->btn_stop, EINA_TRUE);
@@ -96,7 +96,6 @@ test_part_shadow(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
pb = efl_add(EFL_UI_PROGRESSBAR_CLASS, win);
efl_gfx_hint_weight_set(pb, EFL_GFX_HINT_EXPAND, 0);
- efl_ui_progressbar_pulse_mode_set(pb, EINA_TRUE);
efl_pack(bx, pb);
td->pb1 = pb;
@@ -122,7 +121,6 @@ test_part_shadow(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
efl_unref(shadow);
pb = efl_add(EFL_UI_PROGRESSBAR_CLASS, win);
- efl_ui_progressbar_pulse_mode_set(pb, EINA_TRUE);
efl_gfx_hint_weight_set(pb, EFL_GFX_HINT_EXPAND, 0);
efl_pack(bx, pb);
td->pb4 = pb;
@@ -150,7 +148,6 @@ test_part_shadow(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
// FIXME: Needs wheel progressbar class
pb = efl_add(EFL_UI_PROGRESSBAR_CLASS, win,
efl_ui_widget_style_set(efl_added, "wheel"));
- efl_ui_progressbar_pulse_mode_set(pb, EINA_TRUE);
efl_pack(hbx, pb);
td->pb2 = pb;
@@ -163,7 +160,6 @@ test_part_shadow(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
pb = efl_add(EFL_UI_PROGRESSBAR_CLASS, win,
efl_ui_widget_style_set(efl_added, "wheel"));
- efl_ui_progressbar_pulse_mode_set(pb, EINA_TRUE);
efl_pack(hbx, pb);
td->pb3 = pb;
diff --git a/src/bin/elementary/test_photocam.c b/src/bin/elementary/test_photocam.c
index de7b827a84..687033b0f1 100644
--- a/src/bin/elementary/test_photocam.c
+++ b/src/bin/elementary/test_photocam.c
@@ -150,10 +150,6 @@ my_bt_open(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
eina_list_free(grps);
}
-
- if (file && eina_str_has_extension(file, ".gif")
- && efl_playable_get(ph))
- efl_player_playing_set(ph, EINA_TRUE);
}
static void
@@ -179,7 +175,7 @@ my_bt_zoom_in(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UN
zoom -= 0.5;
else if ((zoom > 1.0) && (zoom <= 1.5))
zoom = 1.0;
- else if (zoom == 1.0)
+ else if (EINA_DBL_EQ(zoom, 1.0))
zoom = 0.8;
else
zoom = zoom * zoom;
@@ -834,7 +830,8 @@ test_image_zoomable_animated(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
if (efl_playable_get(zoomable))
{
printf("animation is available for this image.\n");
- efl_player_playing_set(zoomable, EINA_TRUE);
+ efl_player_autoplay_set(zoomable, EINA_TRUE);
+ efl_player_playback_loop_set(zoomable, EINA_TRUE);
}
rect = efl_add(EFL_CANVAS_RECTANGLE_CLASS, win,
diff --git a/src/bin/elementary/test_tooltip.c b/src/bin/elementary/test_tooltip.c
index eb4ce890c1..3615886478 100644
--- a/src/bin/elementary/test_tooltip.c
+++ b/src/bin/elementary/test_tooltip.c
@@ -157,7 +157,7 @@ _tt_item_icon3(void *data EINA_UNUSED,
sc = ((float)sw * 0.8) / (float)w;
else if ((float)h / (float)sh >= 0.8)
sc = ((float)sh * 0.8) / (float)h;
- if (sc) elm_object_scale_set(ic, sc);
+ if (EINA_FLT_NONZERO(sc)) elm_object_scale_set(ic, sc);
}
return ic;
}
diff --git a/src/bin/elementary/test_ui_clock.c b/src/bin/elementary/test_ui_clock.c
index 79e9074ead..9973b25cd3 100644
--- a/src/bin/elementary/test_ui_clock.c
+++ b/src/bin/elementary/test_ui_clock.c
@@ -6,7 +6,7 @@
/* A simple test, just displaying clock in its default format */
-Evas_Object *dt1, *dt2, *dt3, *dt4;
+Evas_Object *uicdt1, *uicdt2, *uicdt3, *uicdt4;
static void
_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
@@ -28,19 +28,19 @@ _bt_clicked(void *data EINA_UNUSED, const Efl_Event *ev)
new_time.tm_mday = 26;
new_time.tm_hour = 9;
new_time.tm_min = 0;
- efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_HOUR, EINA_TRUE);
- efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_MINUTE, EINA_TRUE);
- efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_AMPM, EINA_TRUE);
- efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_SECOND, EINA_TRUE);
- efl_ui_clock_field_visible_set(dt1, EFL_UI_CLOCK_TYPE_DAY, EINA_TRUE);
- efl_ui_clock_time_set(dt1, new_time);
-
- elm_object_disabled_set(dt1, EINA_TRUE);
+ efl_ui_clock_field_visible_set(uicdt1, EFL_UI_CLOCK_TYPE_HOUR, EINA_TRUE);
+ efl_ui_clock_field_visible_set(uicdt1, EFL_UI_CLOCK_TYPE_MINUTE, EINA_TRUE);
+ efl_ui_clock_field_visible_set(uicdt1, EFL_UI_CLOCK_TYPE_AMPM, EINA_TRUE);
+ efl_ui_clock_field_visible_set(uicdt1, EFL_UI_CLOCK_TYPE_SECOND, EINA_TRUE);
+ efl_ui_clock_field_visible_set(uicdt1, EFL_UI_CLOCK_TYPE_DAY, EINA_TRUE);
+ efl_ui_clock_time_set(uicdt1, new_time);
+
+ elm_object_disabled_set(uicdt1, EINA_TRUE);
elm_object_disabled_set(ev->object, EINA_TRUE);
- efl_del(dt2);
- efl_del(dt3);
- dt2 = dt3 = NULL;
+ efl_del(uicdt2);
+ efl_del(uicdt3);
+ uicdt2 = uicdt3 = NULL;
}
void
@@ -56,33 +56,33 @@ test_ui_clock(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_
efl_content_set(win, efl_added),
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(360, 240)));
- dt1 = efl_add(EFL_UI_CLOCK_CLASS, bx,
- efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
- efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_HOUR, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_MINUTE, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_AMPM, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_DAY, EINA_FALSE),
- efl_ui_clock_pause_set(efl_added, EINA_TRUE),
- efl_event_callback_add(efl_added, EFL_UI_CLOCK_EVENT_CHANGED, _changed_cb, NULL),
- efl_pack(bx, efl_added));
-
- dt2 = efl_add(EFL_UI_CLOCK_CLASS, bx,
- efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
- efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_YEAR, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_MONTH, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_DATE, EINA_FALSE),
- efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE),
- efl_ui_clock_pause_set(efl_added, EINA_TRUE),
- efl_pack(bx, efl_added));
- elm_object_disabled_set(dt2, EINA_TRUE);
-
- dt3 = efl_add(EFL_UI_CLOCK_CLASS, bx,
- efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
- efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
- efl_pack(bx, efl_added));
+ uicdt1 = efl_add(EFL_UI_CLOCK_CLASS, bx,
+ efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
+ efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_HOUR, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_MINUTE, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_AMPM, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_DAY, EINA_FALSE),
+ efl_ui_clock_pause_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_CLOCK_EVENT_CHANGED, _changed_cb, NULL),
+ efl_pack(bx, efl_added));
+
+ uicdt2 = efl_add(EFL_UI_CLOCK_CLASS, bx,
+ efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
+ efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_YEAR, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_MONTH, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_DATE, EINA_FALSE),
+ efl_ui_clock_field_visible_set(efl_added, EFL_UI_CLOCK_TYPE_SECOND, EINA_FALSE),
+ efl_ui_clock_pause_set(efl_added, EINA_TRUE),
+ efl_pack(bx, efl_added));
+ elm_object_disabled_set(uicdt2, EINA_TRUE);
+
+ uicdt3 = efl_add(EFL_UI_CLOCK_CLASS, bx,
+ efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
+ efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
+ efl_pack(bx, efl_added));
efl_add(EFL_UI_TEXTBOX_CLASS, bx,
efl_text_set(efl_added, "Editable Clock:"),
@@ -92,12 +92,12 @@ test_ui_clock(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 25)),
efl_pack(bx, efl_added));
- dt4 = efl_add(EFL_UI_CLOCK_CLASS, bx,
- efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
- efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
- efl_ui_clock_edit_mode_set(efl_added, EINA_TRUE),
- efl_ui_clock_pause_set(efl_added, EINA_TRUE),
- efl_pack(bx, efl_added));
+ uicdt4 = efl_add(EFL_UI_CLOCK_CLASS, bx,
+ efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
+ efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
+ efl_ui_clock_edit_mode_set(efl_added, EINA_TRUE),
+ efl_ui_clock_pause_set(efl_added, EINA_TRUE),
+ efl_pack(bx, efl_added));
efl_add(EFL_UI_BUTTON_CLASS, win,
efl_text_set(efl_added, "Back to the future..."),
diff --git a/src/bin/elementary/test_ui_pager.c b/src/bin/elementary/test_ui_pager.c
index 34792f3832..c9ec2d6222 100644
--- a/src/bin/elementary/test_ui_pager.c
+++ b/src/bin/elementary/test_ui_pager.c
@@ -316,7 +316,7 @@ static void indicator_icon_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Params *params = data;
- params->indicator = efl_add(EFL_PAGE_INDICATOR_ICON_CLASS, params->pager);
+ params->indicator = efl_add(EFL_PAGE_ICON_INDICATOR_CLASS, params->pager);
efl_ui_pager_indicator_set(params->pager, params->indicator);
}
diff --git a/src/bin/elementary/test_ui_pager_scroll.c b/src/bin/elementary/test_ui_pager_scroll.c
index c60ac486b2..7c1211e31b 100644
--- a/src/bin/elementary/test_ui_pager_scroll.c
+++ b/src/bin/elementary/test_ui_pager_scroll.c
@@ -369,7 +369,7 @@ static void indicator_icon_btn_cb(void *data,
{
Params *params = data;
- params->indicator = efl_add(EFL_PAGE_INDICATOR_ICON_CLASS, params->pager);
+ params->indicator = efl_add(EFL_PAGE_ICON_INDICATOR_CLASS, params->pager);
efl_ui_pager_indicator_set(params->pager, params->indicator);
}
diff --git a/src/bin/elementary/test_ui_progressbar.c b/src/bin/elementary/test_ui_progressbar.c
index a9ca9a86f8..faea211629 100644
--- a/src/bin/elementary/test_ui_progressbar.c
+++ b/src/bin/elementary/test_ui_progressbar.c
@@ -179,7 +179,7 @@ test_ui_progressbar(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, void *event_inf
pd->pb2 = efl_add(EFL_UI_PROGRESSBAR_CLASS, bx,
efl_pack(bx, efl_added),
efl_text_set(efl_added, "10-100"),
- efl_ui_progressbar_pulse_set(efl_added, EINA_TRUE),
+ efl_ui_progressbar_infinite_mode_set(efl_added, EINA_TRUE),
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(250, 20)),
efl_ui_range_limits_set(efl_added, 10, 100),
efl_ui_range_value_set(efl_added, 10)
diff --git a/src/bin/elementary/test_ui_separator.c b/src/bin/elementary/test_ui_separator.c
new file mode 100644
index 0000000000..d30afd3a12
--- /dev/null
+++ b/src/bin/elementary/test_ui_separator.c
@@ -0,0 +1,26 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Efl_Ui.h>
+
+void
+test_ui_separator(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ Eo *win, *table, *sep;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_text_set(efl_added, "Efl.Ui.Separator"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ table = efl_add(EFL_UI_TABLE_CLASS, win);
+ efl_content_set(win, table);
+
+ sep = efl_add(EFL_UI_SEPARATOR_CLASS, win);
+ efl_pack_table(table, sep, 0, 0, 2, 1);
+
+ sep = efl_add(EFL_UI_SEPARATOR_CLASS, win,
+ efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL));
+ efl_pack_table(table, sep, 0, 0, 2, 1);
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(100, 120));
+}
diff --git a/src/bin/elementary/test_ui_spotlight.c b/src/bin/elementary/test_ui_spotlight.c
index f38dfca754..a5c8d141e3 100644
--- a/src/bin/elementary/test_ui_spotlight.c
+++ b/src/bin/elementary/test_ui_spotlight.c
@@ -396,7 +396,7 @@ indicator_icon_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Params *params = data;
- params->indicator = efl_new(EFL_UI_SPOTLIGHT_INDICATOR_ICON_CLASS);
+ params->indicator = efl_new(EFL_UI_SPOTLIGHT_ICON_INDICATOR_CLASS);
efl_ui_spotlight_indicator_set(params->spotlight, params->indicator);
}
@@ -849,7 +849,7 @@ test_ui_spotlight_stack(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- Eo *win, *panes, *navi, *list, *layout, *spotlight, *view;
+ Eo *win, *panes, *navi, *list, *layout, *spotlight, *view = NULL;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@@ -945,7 +945,7 @@ test_ui_spotlight_plain(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- Eo *win, *panes, *navi, *list, *layout, *spotlight, *view;
+ Eo *win, *panes, *navi, *list, *layout, *spotlight, *view = NULL;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@@ -1039,7 +1039,7 @@ test_ui_spotlight_scroll(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
- Eo *win, *panes, *navi, *list, *layout, *spotlight, *view;
+ Eo *win, *panes, *navi, *list, *layout, *spotlight, *view = NULL;
Params *params = NULL;
char buf[PATH_MAX];
int i;
@@ -1129,3 +1129,118 @@ test_ui_spotlight_scroll(void *data EINA_UNUSED,
efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
}
+
+void
+test_ui_spotlight_animation(void *data EINA_UNUSED,
+ Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ Eo *win, *panes, *navi, *list, *layout, *spotlight, *view, *custom_animation_manager;
+ Efl_Canvas_Animation *jump_animation, *push_animation, *pop_animation;
+ Params *params = NULL;
+ char buf[PATH_MAX];
+ int i;
+
+ win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
+ efl_text_set(efl_added, "Efl.Ui.Spotlight Scroll"),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+
+ panes = efl_add(EFL_UI_PANES_CLASS, win,
+ efl_gfx_hint_weight_set(efl_added, 1, 1),
+ efl_ui_panes_split_ratio_set(efl_added, 0.3),
+ efl_content_set(win, efl_added));
+
+ navi = elm_naviframe_add(panes);
+ evas_object_show(navi);
+ efl_content_set(efl_part(panes, "first"), navi);
+
+ list = elm_list_add(navi);
+ elm_list_horizontal_set(list, EINA_FALSE);
+ elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
+ elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
+ evas_object_show(list);
+
+ snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
+ elm_app_data_dir_get());
+ layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
+ efl_file_set(efl_added, buf),
+ efl_file_key_set(efl_added, "pager"),
+ efl_file_load(efl_added),
+ efl_content_set(efl_part(panes, "second"), efl_added));
+
+
+ jump_animation = efl_new(EFL_CANVAS_ALPHA_ANIMATION_CLASS);
+ efl_animation_alpha_set(jump_animation, 0.0, 1.0);
+ efl_animation_duration_set(jump_animation, 0.5);
+
+ push_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
+ efl_animation_translate_set(push_animation, EINA_POSITION2D(0, 100), EINA_POSITION2D(0, 0));
+ efl_animation_duration_set(push_animation, 0.5);
+
+ pop_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
+ efl_animation_translate_set(pop_animation, EINA_POSITION2D(0, -100), EINA_POSITION2D(0, 0));
+ efl_animation_duration_set(pop_animation, 0.5);
+
+ custom_animation_manager = efl_new(EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS,
+ efl_ui_spotlight_manager_animation_push_setup_set(efl_added, push_animation, jump_animation),
+ efl_ui_spotlight_manager_animation_pop_setup_set(efl_added, jump_animation, pop_animation),
+ efl_ui_spotlight_manager_animation_jump_setup_set(efl_added, jump_animation, jump_animation));
+
+ spotlight = efl_add(EFL_UI_SPOTLIGHT_CONTAINER_CLASS, layout,
+ efl_ui_spotlight_manager_set(efl_added, custom_animation_manager),
+ efl_content_set(efl_part(layout, "pager"), efl_added),
+ efl_ui_spotlight_size_set(efl_added, EINA_SIZE2D(200, 300)));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Pop"),
+ efl_event_callback_add(efl_added,
+ EFL_INPUT_EVENT_CLICKED, pop_btn_cb, spotlight),
+ efl_content_set(efl_part(layout, "prev_btn"), efl_added));
+
+ efl_add(EFL_UI_BUTTON_CLASS, layout,
+ efl_text_set(efl_added, "Push"),
+ efl_event_callback_add(efl_added,
+ EFL_INPUT_EVENT_CLICKED, push_btn_cb, spotlight),
+ efl_content_set(efl_part(layout, "next_btn"), efl_added));
+
+ params = calloc(1, sizeof(Params));
+ if (!params) return;
+
+ params->navi = navi;
+ params->spotlight = spotlight;
+ params->indicator = NULL;
+ params->w = 200;
+ params->h = 300;
+ params->wfill = EINA_FALSE;
+ params->hfill = EINA_FALSE;
+
+ elm_list_item_append(list, "View Size", NULL, NULL, spotlight_size, params);
+ elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
+ elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
+ elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
+ elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
+ elm_list_item_append(list, "Scroll Block", NULL, NULL, scroll_block_cb, params);
+ elm_list_go(list);
+
+ efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
+
+ for (i = 0; i < PAGE_NUM; i++) {
+ switch (i % 3)
+ {
+ case 0:
+ view = view_add(LAYOUT, spotlight);
+ break;
+
+ case 1:
+ view = view_add(LIST, spotlight);
+ break;
+
+ case 2:
+ view = view_add(BUTTON, spotlight);
+ break;
+ }
+ efl_pack_end(spotlight, view);
+ }
+
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
+}
diff --git a/src/bin/elementary/test_ui_tab_pager.c b/src/bin/elementary/test_ui_tab_pager.c
index 62e4e7df09..2c948dcaac 100644
--- a/src/bin/elementary/test_ui_tab_pager.c
+++ b/src/bin/elementary/test_ui_tab_pager.c
@@ -139,7 +139,7 @@ test_ui_tab_pager(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev
page = tab_page_add(tp);
efl_pack_end(tp, page);
if (i == 0)
- efl_ui_spotlight_active_element_set(tp, page);
+ efl_ui_selectable_selected_set(efl_ui_tab_page_tab_bar_item_get(page), EINA_TRUE);
}
ad = (App_Data*)calloc(1, sizeof(App_Data));
@@ -174,7 +174,9 @@ static void
_tab_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Tab_Set_Data *tsd = data;
- efl_ui_spotlight_active_element_set(tsd->tab_pager, efl_pack_content_get(tsd->tab_pager, elm_spinner_value_get(tsd->spinner)));
+ Efl_Ui_Tab_Page *page = efl_pack_content_get(tsd->tab_pager, elm_spinner_value_get(tsd->spinner));
+
+ efl_ui_selectable_selected_set(efl_ui_tab_page_tab_bar_item_get(page), EINA_TRUE);
}
static void
@@ -246,7 +248,7 @@ _pack_before_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *tab_pager = data;
Eo *tab_page, *cur_tab_page;
- cur_tab_page = efl_ui_spotlight_active_element_get(tab_pager);
+ cur_tab_page = efl_ui_selectable_last_selected_get(tab_pager);
tab_page = tab_page_add(tab_pager);
@@ -259,7 +261,7 @@ _pack_after_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
Eo *tab_pager = data;
Eo *tab_page, *cur_tab_page;
- cur_tab_page = efl_ui_spotlight_active_element_get(tab_pager);
+ cur_tab_page = efl_ui_selectable_last_selected_get(tab_pager);
tab_page = tab_page_add(tab_pager);
@@ -361,7 +363,7 @@ _unpack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *tab_pager = data;
- Eo *tab_page = efl_ui_spotlight_active_element_get(tab_pager);
+ Eo *tab_page = efl_ui_selectable_last_selected_get(tab_pager);
efl_pack_unpack(tab_pager, tab_page);
efl_del(tab_page);
@@ -460,7 +462,7 @@ _change_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
char *label = NULL;
char *icon = NULL;
- tab_page = efl_ui_spotlight_active_element_get(tcd->tab_pager);
+ tab_page = efl_ui_selectable_last_selected_get(tcd->tab_pager);
if (efl_ui_selectable_selected_get(tcd->label_check))
{
@@ -527,21 +529,21 @@ _tab_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
static void
_tran_set_btn_scroll_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Efl_Ui_Spotlight_Manager_Scroll *scroll = efl_new(EFL_UI_SPOTLIGHT_MANAGER_SCROLL_CLASS);
- efl_ui_spotlight_manager_set(data, scroll);
+ Efl_Ui_Spotlight_Scroll_Manager *scroll = efl_new(EFL_UI_SPOTLIGHT_SCROLL_MANAGER_CLASS);
+ efl_ui_tab_pager_spotlight_manager_set(data, scroll);
}
static void
_tran_set_btn_stack_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
- Efl_Ui_Spotlight_Manager_Scroll *stack = efl_new(EFL_UI_SPOTLIGHT_MANAGER_STACK_CLASS);
- efl_ui_spotlight_manager_set(data, stack);
+ Efl_Ui_Spotlight_Scroll_Manager *stack = efl_new(EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS);
+ efl_ui_tab_pager_spotlight_manager_set(data, stack);
}
static void
_tran_unset_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
- efl_ui_spotlight_manager_set(data, NULL);
+ efl_ui_tab_pager_spotlight_manager_set(data, NULL);
}
static void
diff --git a/src/bin/elementary/test_ui_textpath.c b/src/bin/elementary/test_ui_textpath.c
index 40317a9627..41783386b1 100644
--- a/src/bin/elementary/test_ui_textpath.c
+++ b/src/bin/elementary/test_ui_textpath.c
@@ -56,6 +56,20 @@ _short_text_changed_cb(void *data, const Efl_Event *event)
efl_text_set(txtpath, TEST_UI_TEXTPATH_LONG_TEXT);
}
+static char *user_style = "DEFAULT='font_size=16 color=#F00 underline=on underline_color=#00ffff'";
+
+static void
+_user_style_changed_cb(void *data, const Efl_Event *event)
+{
+ Evas_Object *txtpath = data;
+ Eina_Bool val = elm_check_selected_get(event->object);
+
+ if (val)
+ elm_textpath_text_user_style_set(txtpath, user_style);
+ else
+ elm_textpath_text_user_style_set(txtpath, NULL);
+}
+
static void
_change_shape_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -138,6 +152,12 @@ test_ui_textpath(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
elm_box_pack_end(hbox, chk);
efl_gfx_entity_visible_set(chk, EINA_TRUE);
+ chk = efl_add(EFL_UI_CHECK_CLASS, win);
+ efl_text_set(chk, "User style");
+ efl_event_callback_add(chk, EFL_UI_EVENT_SELECTED_CHANGED, _user_style_changed_cb, txtpath);
+ elm_box_pack_end(hbox, chk);
+ efl_gfx_entity_visible_set(chk, EINA_TRUE);
+
hbox = elm_box_add(win);
elm_box_horizontal_set(hbox, EINA_TRUE);
efl_gfx_hint_weight_set(hbox, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND);
diff --git a/src/bin/elementary/test_ui_timepicker.c b/src/bin/elementary/test_ui_timepicker.c
index 3249699bc8..f7b5d7d676 100644
--- a/src/bin/elementary/test_ui_timepicker.c
+++ b/src/bin/elementary/test_ui_timepicker.c
@@ -32,5 +32,11 @@ test_ui_timepicker(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *e
efl_event_callback_add(efl_added, EFL_UI_TIMEPICKER_EVENT_TIME_CHANGED,_time_changed_cb, NULL),
efl_pack(bx, efl_added));
+ efl_add(EFL_UI_TIMEPICKER_CLASS, bx,
+ efl_ui_timepicker_time_set(efl_added, 11, 35),
+ efl_ui_timepicker_is_24hour_set(efl_added, EINA_TRUE),
+ efl_event_callback_add(efl_added, EFL_UI_TIMEPICKER_EVENT_TIME_CHANGED,_time_changed_cb, NULL),
+ efl_pack(bx, efl_added));
+
efl_gfx_entity_size_set(win, EINA_SIZE2D(150, 170));
}
diff --git a/src/bin/elementary/test_win_state.c b/src/bin/elementary/test_win_state.c
index f1b9af34cc..1b75d3d835 100644
--- a/src/bin/elementary/test_win_state.c
+++ b/src/bin/elementary/test_win_state.c
@@ -227,6 +227,22 @@ _bt_win_center_cb(void *data, Evas_Object *obj EINA_UNUSED,
}
static void
+_bt_win_maximize(void *data, Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ printf("Maximize\n");
+ elm_win_maximized_set(data, EINA_TRUE);
+}
+
+static void
+_bt_win_unmaximize(void *data, Evas_Object *obj EINA_UNUSED,
+ void *event_info EINA_UNUSED)
+{
+ printf("Unmaximize\n");
+ elm_win_maximized_set(data, EINA_FALSE);
+}
+
+static void
_win_state_print_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
printf("WIN: %s\n", (char *)data);
@@ -414,7 +430,7 @@ test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
evas_object_show(bt);
bt = elm_button_add(win);
- elm_object_text_set(bt, "Iconify and Activate");
+ elm_object_text_set(bt, "Iconify + Act");
evas_object_smart_callback_add(bt, "clicked",
_bt_win_iconify_and_activate, win);
evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -423,7 +439,7 @@ test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
evas_object_show(bt);
bt = elm_button_add(bx2);
- elm_object_text_set(bt, "Iconify and Deiconify");
+ elm_object_text_set(bt, "Iconify + De");
evas_object_smart_callback_add(bt, "clicked",
_bt_win_iconify_and_deiconify, win);
evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -431,6 +447,24 @@ test_win_state(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
elm_box_pack_end(bx2, bt);
evas_object_show(bt);
+ bt = elm_button_add(bx2);
+ elm_object_text_set(bt, "Maximize");
+ evas_object_smart_callback_add(bt, "clicked",
+ _bt_win_maximize, win);
+ evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ bt = elm_button_add(bx2);
+ elm_object_text_set(bt, "Unmaximize");
+ evas_object_smart_callback_add(bt, "clicked",
+ _bt_win_unmaximize, win);
+ evas_object_size_hint_fill_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
bt = elm_button_add(win);
elm_object_text_set(bt, "Center");
evas_object_smart_callback_add(bt, "clicked",
diff --git a/src/bin/elua/main.c b/src/bin/elua/main.c
index ed1b4074a4..0c228b68f0 100644
--- a/src/bin/elua/main.c
+++ b/src/bin/elua/main.c
@@ -138,6 +138,13 @@ elua_bin_shutdown(Elua_State *es, int c)
exit(c);
}
+#if LUA_VERSION_NUM < 502
+# define elua_cpcall(L, f, u) lua_cpcall(L, f, u)
+#else
+# define elua_cpcall(L, f, u) \
+ (lua_pushcfunction(L, f), lua_pushlightuserdata(L, u), lua_pcall(L, 1, 0, 0))
+#endif
+
int
main(int argc, char **argv)
{
@@ -175,7 +182,7 @@ main(int argc, char **argv)
m.argv = argv;
m.status = 0;
- elua_bin_shutdown(es, !!(lua_cpcall(elua_state_lua_state_get(es), elua_main, &m) || m.status));
+ elua_bin_shutdown(es, !!(elua_cpcall(elua_state_lua_state_get(es), elua_main, &m) || m.status));
return 0; /* never gets here */
}
diff --git a/src/bin/embryo/embryo_cc_sc1.c b/src/bin/embryo/embryo_cc_sc1.c
index bb9486de6b..8f25be75b5 100644
--- a/src/bin/embryo/embryo_cc_sc1.c
+++ b/src/bin/embryo/embryo_cc_sc1.c
@@ -266,7 +266,7 @@ sc_compile(int argc, char *argv[])
void *inpfmark;
char lcl_ctrlchar;
int lcl_packstr, lcl_needsemicolon, lcl_tabsize;
- Eina_Tmpstr *outfname;
+ Eina_Tmpstr *outfname = NULL;
/* set global variables to their initial value */
binf = NULL;
@@ -398,8 +398,11 @@ sc_compile(int argc, char *argv[])
} /* if */
if (outf)
sc_closeasm(outf);
- unlink(outfname);
- eina_tmpstr_del(outfname);
+ if (outfname)
+ {
+ unlink(outfname);
+ eina_tmpstr_del(outfname);
+ }
if (binf)
sc_closebin(binf, errnum != 0);
@@ -1203,10 +1206,8 @@ declloc(int fstatic)
if (numdim > 0 && dim[numdim - 1] == 0)
error(52); /* only last dimension may be variable length */
size = needsub(&idxtag[numdim]); /* get size; size==0 for "var[]" */
-#if INT_MAX < CELL_MAX
- if (size > INT_MAX)
+ if ((unsigned long long)size * sizeof(cell) > MIN(INT_MAX, CELL_MAX))
error(105); /* overflow, exceeding capacity */
-#endif
dim[numdim++] = (int)size;
} /* while */
if (ident == iARRAY || fstatic)
@@ -1237,6 +1238,9 @@ declloc(int fstatic)
}
else
{
+ if (((unsigned long long)declared + (unsigned long long)size) * sizeof(cell) >
+ MIN(INT_MAX, CELL_MAX))
+ error(105);
declared += (int)size; /* variables are put on stack,
* adjust "declared" */
sym =
@@ -3491,11 +3495,11 @@ static void
doif(void)
{
int flab1, flab2;
-#if 0
+#if 0
int ifindent;
ifindent = stmtindent; /* save the indent of the "if" instruction */
-#endif
+#endif
flab1 = getlabel(); /* get label number for false branch */
test(flab1, TRUE, FALSE); /*get expression, branch to flab1 if false */
statement(NULL, FALSE); /* if true, do a statement */
diff --git a/src/bin/embryo/embryo_cc_sc2.c b/src/bin/embryo/embryo_cc_sc2.c
index 2bd34b8f71..7a7f5ebd14 100644
--- a/src/bin/embryo/embryo_cc_sc2.c
+++ b/src/bin/embryo/embryo_cc_sc2.c
@@ -101,7 +101,7 @@ plungequalifiedfile(char *name)
} /* if */
ext_idx++;
}
- while ((!fp) &&
+ while ((!fp) &&
(ext_idx < (int)(sizeof extensions / sizeof extensions[0])));
if (!fp)
{
@@ -1004,8 +1004,8 @@ command(void)
{
int i;
- for (i = 0;
- (i < (int)(sizeof(name)) - 1) &&
+ for (i = 0;
+ (i < (int)(sizeof(name)) - 1) &&
(alphanum(*lptr));
i++, lptr++)
name[i] = *lptr;
@@ -1041,7 +1041,7 @@ command(void)
/* first gather all information, start with the tag name */
while ((*lptr <= ' ') && (*lptr != '\0'))
lptr++;
- for (i = 0;
+ for (i = 0;
(i < (int)(sizeof(name)) - 1) &&
(alphanum(*lptr));
i++, lptr++)
@@ -1105,8 +1105,8 @@ command(void)
/* get the name */
while ((*lptr <= ' ') && (*lptr != '\0'))
lptr++;
- for (i = 0;
- (i < (int)(sizeof(name)) - 1) &&
+ for (i = 0;
+ (i < (int)(sizeof(name)) - 1) &&
(sc_isalpha(*lptr));
i++, lptr++)
name[i] = *lptr;
diff --git a/src/bin/eolian/docs.c b/src/bin/eolian/docs.c
index c01508dab6..2f27a107b2 100644
--- a/src/bin/eolian/docs.c
+++ b/src/bin/eolian/docs.c
@@ -462,7 +462,7 @@ eo_gen_docs_func_gen(const Eolian_State *state, const Eolian_Function *fid,
int curl = 0;
- const char *group = eolian_class_name_get(eolian_function_class_get(fid));
+ const char *group = eolian_class_c_name_get(eolian_function_class_get(fid));
const Eolian_Implement *fimp = eolian_function_implement_get(fid);
if (ftype == EOLIAN_METHOD)
diff --git a/src/bin/eolian/headers.c b/src/bin/eolian/headers.c
index ead40d8f75..ebca0c9b75 100644
--- a/src/bin/eolian/headers.c
+++ b/src/bin/eolian/headers.c
@@ -1,6 +1,8 @@
#include "main.h"
#include "docs.h"
+extern char* _eolian_api_symbol;
+
static const char *
_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Direction pdir)
{
@@ -118,7 +120,7 @@ _gen_func(const Eolian_State *state, const Eolian_Function *fid,
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(dbuf);
}
- eina_strbuf_append(buf, "EOAPI ");
+ eina_strbuf_append_printf(buf, "%s %s_WEAK ", _eolian_api_symbol, _eolian_api_symbol);
if (rtp)
{
if (!rtps)
@@ -211,7 +213,7 @@ eo_gen_header_gen(const Eolian_State *state, const Eolian_Class *cl,
if (doc)
{
Eina_Strbuf *cdoc = eo_gen_docs_full_gen(state, doc,
- eolian_class_name_get(cl), 0);
+ eolian_class_c_name_get(cl), 0);
if (cdoc)
{
eina_strbuf_append(buf, eina_strbuf_string_get(cdoc));
@@ -225,7 +227,8 @@ eo_gen_header_gen(const Eolian_State *state, const Eolian_Class *cl,
eina_strbuf_append_printf(buf, "#define %s %s()\n\n", mname, gname);
eina_stringshare_del(mname);
- eina_strbuf_append_printf(buf, "EWAPI const Efl_Class *%s(void);\n", gname);
+ eina_strbuf_append_printf(buf, "%s %s_WEAK const Efl_Class *%s(void) EINA_CONST;\n",
+ _eolian_api_symbol, _eolian_api_symbol, gname);
eina_stringshare_del(gname);
/* method section */
@@ -283,11 +286,12 @@ events:
if (!eolian_event_is_beta(ev) && evs == EOLIAN_SCOPE_PUBLIC)
eina_strbuf_append_char(buf, '\n');
- eina_strbuf_append_printf(buf, "EWAPI extern const "
- "Efl_Event_Description _%s;\n\n", evn);
+ eina_strbuf_append_printf(buf, "%s %s_WEAK extern const "
+ "Efl_Event_Description _%s;\n\n",
+ _eolian_api_symbol, _eolian_api_symbol, evn);
Eina_Strbuf *evdbuf = eo_gen_docs_event_gen(state, ev,
- eolian_class_name_get(cl));
+ eolian_class_c_name_get(cl));
eina_strbuf_append(buf, eina_strbuf_string_get(evdbuf));
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(evdbuf);
diff --git a/src/bin/eolian/main.c b/src/bin/eolian/main.c
index 114f989ac4..b2167ef62d 100644
--- a/src/bin/eolian/main.c
+++ b/src/bin/eolian/main.c
@@ -7,6 +7,7 @@
#include "sources.h"
int _eolian_gen_log_dom = -1;
+char* _eolian_api_symbol;
enum
{
@@ -44,6 +45,7 @@ _print_usage(const char *progn, FILE *outf)
" -o type:name specify a particular output filename\n"
" -h print this message and exit\n"
" -v print version and exit\n"
+ " -e api symbol string to be used for import/export symbol"
"\n"
"Available types:\n"
" h: C header file (.eo.h/.eot.h)\n"
@@ -288,7 +290,7 @@ void eo_gen_class_names_get(const Eolian_Class *cl, char **cname,
char **cnameu, char **cnamel)
{
char *cn = NULL, *cnu = NULL, *cnl = NULL;
- cn = eo_gen_c_full_name_get(eolian_class_name_get(cl));
+ cn = eo_gen_c_full_name_get(eolian_class_c_name_get(cl));
if (!cn)
abort();
if (cname)
@@ -494,6 +496,7 @@ main(int argc, char **argv)
NULL, NULL, NULL, NULL, NULL, NULL
};
char *basen = NULL;
+ _eolian_api_symbol = strdup("EAPI");
Eina_List *includes = NULL;
eina_init();
@@ -514,7 +517,7 @@ main(int argc, char **argv)
int gen_what = 0;
Eina_Bool scan_system = EINA_TRUE;
- for (int opt; (opt = getopt(argc, argv, "SI:g:o:hv")) != -1;)
+ for (int opt; (opt = getopt(argc, argv, "SI:g:o:hve:")) != -1;)
switch (opt)
{
case 0:
@@ -526,6 +529,10 @@ main(int argc, char **argv)
/* just a pointer to argv contents, so it persists */
includes = eina_list_append(includes, optarg);
break;
+ case 'e':
+ free(_eolian_api_symbol);
+ _eolian_api_symbol = strdup(optarg);
+ break;
case 'g':
for (const char *wstr = optarg; *wstr; ++wstr)
switch (*wstr)
@@ -665,6 +672,8 @@ end:
free(outs[i]);
free(basen);
+ free(_eolian_api_symbol);
+
eolian_state_free(eos);
eolian_shutdown();
eina_shutdown();
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 26e031f4c7..543d7c8f51 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -7,6 +7,7 @@
*/
static Eina_Hash *_funcs_params_init_get = NULL;
static Eina_Hash *_funcs_params_init_set = NULL;
+extern char* _eolian_api_symbol;
static const char *
_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Direction pdir)
@@ -320,6 +321,13 @@ _gen_function_param_fallback(Eina_Iterator *itr, Eina_Strbuf *fallback_free_owne
if (!eolian_parameter_is_move(pr) || eolian_parameter_direction_get(pr) == EOLIAN_PARAMETER_OUT)
{
eina_strbuf_append_printf(fallback_free_ownership, " (void)%s;\n", eolian_parameter_name_get(pr));
+ /* FIXME: quick hack to avoid warnings, but should be rewritten properly */
+ if (eolian_type_typedecl_get(type) &&
+ eolian_typedecl_type_get(eolian_type_typedecl_get(type)) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
+ {
+ eina_strbuf_append_printf(fallback_free_ownership, " (void)%s_data;\n", eolian_parameter_name_get(pr));
+ eina_strbuf_append_printf(fallback_free_ownership, " (void)%s_free_cb;\n", eolian_parameter_name_get(pr));
+ }
continue;
}
@@ -465,10 +473,11 @@ _gen_reflect_set(Eina_Strbuf *buf, const char *cnamel,
}
static void
-_emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const char *rtpn, Eina_Strbuf *params_full,
+_emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const Eolian_Function_Type ftype, const Eolian_Type *rtp, const char *rtpn, Eina_Strbuf *params_full,
const char *ocnamel, const char *func_suffix, Eina_Strbuf *params, const char *function_name)
{
- eina_strbuf_append(buf, "EOAPI ");
+ eina_strbuf_append_printf(buf, "%s %s_WEAK", _eolian_api_symbol, _eolian_api_symbol);
+ eina_strbuf_append(buf, " ");
eina_strbuf_append(buf, rtpn);
eina_strbuf_append(buf, " ");
eina_strbuf_append(buf, function_name);
@@ -479,11 +488,22 @@ _emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const char *r
eina_strbuf_append_buffer(buf, params_full);
eina_strbuf_append(buf, ")\n");
eina_strbuf_append(buf, "{\n");
- eina_strbuf_append_printf(buf, " %s();\n", eolian_class_c_get_function_name_get(eolian_function_class_get(fid)));
- if (strcmp(rtpn, "void"))
- eina_strbuf_append(buf, " return ");
+ eina_strbuf_append_printf(buf, " const Efl_Class *klass = %s();\n", eolian_class_c_get_function_name_get(eolian_function_class_get(fid)));
+ if (!!strcmp(rtpn, "void") && rtp)
+ {
+ const Eolian_Expression *default_value_expression = eolian_function_return_default_value_get(fid, ftype);
+
+ eina_strbuf_append_printf(buf, " EINA_SAFETY_ON_NULL_RETURN_VAL(klass,");
+ _append_defval(buf, default_value_expression, rtp, rtpn);
+ eina_strbuf_append_printf(buf, ");\n");
+
+ eina_strbuf_append(buf, " return ");
+ }
else
- eina_strbuf_append(buf, " ");
+ {
+ eina_strbuf_append(buf, " EINA_SAFETY_ON_NULL_RETURN(klass);\n");
+ eina_strbuf_append(buf, " ");
+ }
eina_strbuf_append_printf(buf, "_%s", ocnamel);
eina_strbuf_append_char(buf, '_');
eina_strbuf_append(buf, eolian_function_name_get(fid));
@@ -675,7 +695,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
eina_strbuf_append_char(params_full_imp, ' ');
eina_strbuf_append(params_full_imp, add_star);
eina_strbuf_append(params_full_imp, prn);
- if (!dfv && is_empty)
+ if ((!dfv || ftype == EOLIAN_PROP_SET) && is_empty)
eina_strbuf_append(params_full_imp, " EINA_UNUSED");
eina_strbuf_append(params, prn);
@@ -876,7 +896,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
eina_strbuf_append_printf(buf, "}\n\n");
}
- eina_strbuf_append(buf, "EOAPI EFL_");
+ eina_strbuf_append_printf(buf, "%s %s_WEAK", _eolian_api_symbol, _eolian_api_symbol);
+ eina_strbuf_append(buf, " EFL_");
if (!strcmp(rtpn, "void"))
eina_strbuf_append(buf, "VOID_");
eina_strbuf_append(buf, "FUNC_BODY");
@@ -918,7 +939,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
eina_stringshare_del(eofn);
}
if (impl_same_class && eolian_function_is_static(fid))
- _emit_class_function(buf, fid, rtpn, params_full, ocnamel, func_suffix, params, eolian_function_full_c_name_get(fid, ftype));
+ _emit_class_function(buf, fid, ftype, rtp, rtpn, params_full, ocnamel, func_suffix, params, eolian_function_full_c_name_get(fid, ftype));
free(cname);
free(cnamel);
@@ -1107,7 +1128,8 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
EINA_ITERATOR_FOREACH(itr, ev)
{
Eina_Stringshare *evn = eolian_event_c_macro_get(ev);
- eina_strbuf_append(buf, "EWAPI const Efl_Event_Description _");
+ eina_strbuf_append_printf(buf, "%s %s_WEAK", _eolian_api_symbol, _eolian_api_symbol);
+ eina_strbuf_append(buf, " const Efl_Event_Description _");
eina_strbuf_append(buf, evn);
eina_strbuf_append(buf, " =\n EFL_EVENT_DESCRIPTION");
if (eolian_event_is_hot(ev))
diff --git a/src/bin/eolian/types.c b/src/bin/eolian/types.c
index 96232833cd..897da96e36 100644
--- a/src/bin/eolian/types.c
+++ b/src/bin/eolian/types.c
@@ -4,11 +4,13 @@
#include "headers.h"
#include "docs.h"
+extern char* _eolian_api_symbol;
+
static Eina_Strbuf *
_type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
Eina_Bool full)
{
- char *grp = strdup(eolian_typedecl_name_get(tp));
+ char *grp = strdup(eolian_typedecl_c_name_get(tp));
char *p = strrchr(grp, '.');
if (p) *p = '\0';
Eina_Strbuf *buf = eo_gen_docs_full_gen(state, eolian_typedecl_documentation_get(tp),
@@ -30,7 +32,7 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
case EOLIAN_TYPEDECL_STRUCT_OPAQUE:
{
const Eolian_Struct_Type_Field *memb;
- char *fn = eo_gen_c_full_name_get(eolian_typedecl_name_get(tp));
+ char *fn = eo_gen_c_full_name_get(eolian_typedecl_c_name_get(tp));
if (tpt == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full)
{
eina_strbuf_append_printf(buf, "typedef struct _%s %s", fn, fn);
@@ -119,7 +121,7 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
eina_strbuf_append(buf, "\n");
}
eina_iterator_free(membs);
- char *fn = eo_gen_c_full_name_get(eolian_typedecl_name_get(tp));
+ char *fn = eo_gen_c_full_name_get(eolian_typedecl_c_name_get(tp));
eina_strbuf_append_printf(buf, "} %s", fn);
free(fn);
break;
@@ -142,7 +144,7 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
}
/* Function name */
- char *fn = eo_gen_c_full_name_get(eolian_typedecl_name_get(tp));
+ char *fn = eo_gen_c_full_name_get(eolian_typedecl_c_name_get(tp));
eina_strbuf_append_printf(buf, "(*%s)", fn);
free(fn);
@@ -170,7 +172,7 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
static Eina_Strbuf *
_const_generate(const Eolian_State *state, const Eolian_Constant *vr)
{
- char *fn = strdup(eolian_constant_name_get(vr));
+ char *fn = strdup(eolian_constant_c_name_get(vr));
char *p = strrchr(fn, '.');
if (p) *p = '\0';
Eina_Strbuf *buf = eo_gen_docs_full_gen(state, eolian_constant_documentation_get(vr),
@@ -211,7 +213,7 @@ _const_generate(const Eolian_State *state, const Eolian_Constant *vr)
static Eina_Strbuf *
_err_generate(const Eolian_State *state, const Eolian_Error *err)
{
- char *fn = strdup(eolian_error_name_get(err));
+ char *fn = strdup(eolian_error_c_name_get(err));
char *p = strrchr(fn, '.');
if (p) *p = '\0';
Eina_Strbuf *buf = eo_gen_docs_full_gen(state, eolian_error_documentation_get(err),
@@ -226,7 +228,8 @@ _err_generate(const Eolian_State *state, const Eolian_Error *err)
if (!buf) buf = eina_strbuf_new();
else eina_strbuf_append_char(buf, '\n');
- eina_strbuf_prepend_printf(buf, "EWAPI Eina_Error %s_get(void);\n\n", fn);
+ eina_strbuf_prepend_printf(buf, "%s %s_WEAK Eina_Error %s_get(void);\n\n",
+ _eolian_api_symbol, _eolian_api_symbol, fn);
char *ufn = strdup(fn);
eina_str_toupper(&ufn);
@@ -319,12 +322,13 @@ _source_gen_error(Eina_Strbuf *buf, const Eolian_Error *err)
if (eolian_error_is_extern(err))
return;
- char *fn = strdup(eolian_error_name_get(err));
+ char *fn = strdup(eolian_error_c_name_get(err));
for (char *p = strchr(fn, '.'); p; p = strchr(p, '.'))
*p = '_';
eina_str_tolower(&fn);
- eina_strbuf_append_printf(buf, "EWAPI Eina_Error %s_get(void)\n{\n", fn);
+ eina_strbuf_append_printf(buf, "%s %s_WEAK Eina_Error %s_get(void)\n{\n",
+ _eolian_api_symbol, _eolian_api_symbol, fn);
free(fn);
const char *msg = eolian_error_message_get(err);
@@ -385,7 +389,7 @@ Eina_Strbuf *eo_gen_class_typedef_gen(const Eolian_State *eos, const char *eof)
const Eolian_Class *cl = eolian_state_class_by_file_get(eos, eof);
if (!cl)
return NULL;
- char *clfn = eo_gen_c_full_name_get(eolian_class_name_get(cl));
+ char *clfn = eo_gen_c_full_name_get(eolian_class_c_name_get(cl));
if (!clfn)
return NULL;
Eina_Strbuf *ret = eina_strbuf_new();
diff --git a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
index bf00ddadba..3fddb03780 100644
--- a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
@@ -36,6 +36,7 @@
#include "using_decl.hh"
#include "generation_contexts.hh"
#include "blacklist.hh"
+#include "documentation.hh"
namespace eolian_mono {
@@ -71,31 +72,33 @@ struct async_function_declaration_generator
if(f.scope != attributes::member_scope::scope_public)
return true;
+ auto ref = documentation_generator::function_conversion (f, context);
+
if (!as_generator(
- scope_tab << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n"
+ scope_tab(2) << "/// <summary>Async wrapper for <see cref=\"" << ref << "\" />.\n"
).generate(sink, attributes::unused, context))
return false;
if (!f.documentation.since.empty())
if (!as_generator
- (scope_tab << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
+ (scope_tab(2) << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
.generate (sink, attributes::unused, context))
return false;
if (!as_generator(
- scope_tab << "/// </summary>\n"
+ scope_tab(2) << "/// </summary>\n"
).generate(sink, attributes::unused, context))
return false;
// generate_parameter is not a proper as_generator-compatible generator, so we had to do an old fashioned loop
for (auto&& param : f.parameters)
- if (!documentation(1).generate_parameter(sink, param, context))
+ if (!documentation(2).generate_parameter(sink, param, context))
return false;
if (!as_generator(
- scope_tab << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
- << scope_tab << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
- << scope_tab << "System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") <<
+ scope_tab(2) << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
+ << scope_tab(2) << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
+ << scope_tab(2) << "System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") <<
" System.Threading.CancellationToken token = default(System.Threading.CancellationToken));\n\n"
).generate(sink, f.parameters, context))
return false;
@@ -130,18 +133,18 @@ struct async_function_definition_generator
std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding);
if (!as_generator(
- scope_tab << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n"
+ scope_tab(2) << "/// <summary>Async wrapper for <see cref=\"" << name_helpers::managed_method_name(f) << "\" />.\n"
).generate(sink, attributes::unused, context))
return false;
if (!f.documentation.since.empty())
if (!as_generator
- (scope_tab << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
+ (scope_tab(2) << "/// <para>Since EFL " + f.documentation.since + ".</para>\n")
.generate (sink, attributes::unused, context))
return false;
if (!as_generator(
- scope_tab << "/// </summary>\n"
+ scope_tab(2) << "/// </summary>\n"
).generate(sink, attributes::unused, context))
return false;
@@ -151,13 +154,13 @@ struct async_function_definition_generator
return false;
if(!as_generator(
- scope_tab << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
- << scope_tab << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
- << scope_tab << "public System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") << " System.Threading.CancellationToken token = default(System.Threading.CancellationToken))\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "Eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ", ") << ");\n"
- << scope_tab << scope_tab << "return Efl.Eo.Globals.WrapAsync(future, token);\n"
- << scope_tab << "}\n\n"
+ scope_tab(2) << "/// <param name=\"token\">Token to notify the async operation of external request to cancel.</param>\n"
+ << scope_tab(2) << "/// <returns>An async task wrapping the result of the operation.</returns>\n"
+ << scope_tab(2) << "public System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ", ") << " System.Threading.CancellationToken token = default(System.Threading.CancellationToken))\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "Eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ", ") << ");\n"
+ << scope_tab(2) << scope_tab << "return Efl.Eo.Globals.WrapAsync(future, token);\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, std::make_tuple(f.parameters, param_forwarding), context))
return false;
return true;
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index 70bc34a038..683095f1dd 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -32,7 +32,6 @@ inline bool is_function_blacklisted(std::string const& c_name)
return
c_name == "efl_event_callback_array_priority_add"
|| c_name == "efl_constructor"
- || c_name == "efl_player_playback_position_get"
|| c_name == "efl_ui_widget_focus_set"
|| c_name == "efl_ui_widget_focus_get"
|| c_name == "efl_ui_text_password_get"
@@ -70,6 +69,8 @@ inline bool is_function_blacklisted(std::string const& c_name)
|| c_name == "efl_access_object_event_handler_add"
|| c_name == "efl_access_object_event_handler_del"
|| c_name == "efl_access_object_event_emit"
+ || c_name == "efl_access_widget_action_elm_actions_get"
+ || c_name == "efl_access_action_actions_get"
;
}
@@ -150,34 +151,9 @@ inline bool is_alias_blacklisted(attributes::alias_def const& alias, Context con
return name_helpers::alias_full_eolian_name(alias) == "Eina.Error";
}
-inline bool is_property_blacklisted(std::string const& name)
+inline bool is_property_blacklisted(std::string const&)
{
- auto properties = std::vector<std::string>{
- // These properties encode (void* arr, int len) arrays
- "Efl.Gfx.IGradient.Stop"
- , "Efl.Gfx.GradientConcrete.Stop"
- , "Efl.Gfx.IShape.StrokeDash"
- , "Efl.Gfx.ShapeConcrete.StrokeDash"
- , "Efl.Gfx.Vg.ValueProvider.Transform"
- , "Efl.Canvas.Vg.Node.Transformation"
- // Will be bound manually
- , "Efl.Core.Env.Env"
- // Setter returns a future
- , "Efl.IModel.Property"
- // Protected
- , "Efl.Access.IAction.ActionName"
- , "Efl.Access.IAction.ActionLocalizedName"
- , "Efl.Access.IComponent.Extents"
- , "Efl.Access.IText.AccessSelection"
- , "Efl.Access.IText.AccessText"
- , "Efl.Access.IText.BoundedRanges"
- , "Efl.Access.IText.Character"
- , "Efl.Access.IText.OffsetAtPoint"
- , "Efl.Access.IText.String"
- , "Efl.Access.IText.TextAttributes"
- };
-
- return std::find(std::begin(properties), std::end(properties), name) != std::end(properties);
+ return false;
}
template<typename Context>
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh
index db00ba8a0f..eac5e1a179 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -21,9 +21,9 @@
#include "grammar/html_escaped_string.hpp"
#include "using_decl.hh"
#include "name_helpers.hh"
-#include "helpers.hh"
#include "generation_contexts.hh"
#include "blacklist.hh"
+#include "property_definition.hh"
#include <Eina.h>
@@ -77,11 +77,8 @@ struct documentation_generator
// The name_tail parameter is the last 4 chars of the original string, which
// could be ".set" or ".get" and in this case they are ignored by Eolian.
// We want them to know what the documentation intended to reference.
- template<typename Context>
- static std::string function_conversion(const ::Eolian_Object *klass
- , const ::Eolian_Function *function
- , std::string name_tail
- , Context const& context)
+ template <typename Context>
+ static std::string function_conversion(const ::Eolian_Object *klass, const ::Eolian_Function *function, std::string name_tail, Context const& context)
{
::Eolian_Function_Type ftype = ::eolian_function_type_get(function);
const char* eo_name = ::eolian_function_name_get(function);
@@ -118,40 +115,65 @@ struct documentation_generator
name += name_helpers::managed_method_name({function, ftype, NULL, eolian_object_unit_get(EOLIAN_OBJECT(function))});
break;
case ::EOLIAN_PROP_SET:
- name += ".Set";
- name += name_helpers::property_managed_name(klass_d, eo_name);
- break;
case ::EOLIAN_PROP_GET:
- name += ".Get";
- name += name_helpers::property_managed_name(klass_d, eo_name);
- break;
case ::EOLIAN_PROPERTY:
- {
- std::string short_name = name_helpers::property_managed_name(klass_d, eo_name);
+ {
+ efl::eina::optional<attributes::function_def> getter_func;
+ efl::eina::optional<attributes::function_def> setter_func;
+ auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
+ if (ftype == ::EOLIAN_PROPERTY || ftype == ::EOLIAN_PROP_GET)
+ getter_func = attributes::function_def{function, ::EOLIAN_PROP_GET, nullptr, unit};
+ if (ftype == ::EOLIAN_PROPERTY || ftype == ::EOLIAN_PROP_SET)
+ setter_func = attributes::function_def{function, ::EOLIAN_PROP_SET, nullptr, unit};
+ attributes::property_def property{function, getter_func, setter_func, unit};
+
+ std::string short_name = name_helpers::property_managed_name(klass_d, eo_name);
+ class_context::wrapper_kind klass_kind;
+ if (helpers::is_managed_interface(klass_d))
+ klass_kind = class_context::interface;
+ else
+ klass_kind = class_context::inherit;
+ auto my_context = grammar::context_replace_tag(class_context{klass_kind}, context);
- // We need to replace the current class context with the context
- // from the class that originated this property.
- class_context::wrapper_kind klass_kind;
- if (helpers::is_managed_interface(klass_d))
- klass_kind = class_context::interface;
+ if (name_tail == ".get")
+ {
+ if (property_generate_wrapper_getter (property, my_context))
+ {
+ name += "." + short_name;
+ }
else
- klass_kind = class_context::inherit;
-
- auto my_context = grammar::context_replace_tag(class_context{klass_kind}, context);
-
- auto unit = eolian_object_unit_get((const Eolian_Object*)function);
- attributes::function_def getter_func{function, ::EOLIAN_PROP_GET, nullptr, unit};
- attributes::function_def setter_func{function, ::EOLIAN_PROP_SET, nullptr, unit};
- attributes::property_def prop{function, getter_func, setter_func, unit};
-
- auto has_wrapper = helpers::has_property_wrapper(prop, &klass_d, my_context);
-
- if (has_wrapper == helpers::has_property_wrapper_bit::has_none)
+ {
name += ".Get" + short_name;
- else if (name_tail == ".get") name += ".Get" + short_name;
- else if (name_tail == ".set") name += ".Set" + short_name;
- else name += "." + short_name;
+ }
}
+ else if (name_tail == ".set")
+ {
+ if (property_generate_wrapper_setter (property, my_context))
+ {
+ name += "." + short_name;
+ }
+ else
+ {
+ name += ".Set" + short_name;
+ }
+ }
+ else
+ {
+ switch (ftype)
+ {
+ case ::EOLIAN_PROPERTY:
+ case ::EOLIAN_PROP_GET:
+ if (property_generate_wrapper_getter (property, my_context))
+ name += "." + short_name;
+ else
+ name += ".Get" + short_name;
+ break;
+ default:
+ name += ".Set" + short_name;
+ break;
+ }
+ }
+ }
break;
default:
break;
@@ -159,38 +181,90 @@ struct documentation_generator
return name;
}
- static std::string function_conversion(attributes::function_def const& func)
+ template <typename Context>
+ static std::string function_conversion(attributes::function_def const& func, Context const& context)
{
// This function is called only from the constructor reference conversion, so it does not
// need to check whether this function non-public in a interface returning an empty reference (yet).
std::string name = name_helpers::klass_full_concrete_or_interface_name(func.klass);
switch (func.type)
{
- // managed_method_name takes care of reordering the function name so the get/set goes first
- // for properties
- case attributes::function_type::method:
- case attributes::function_type::prop_set:
- case attributes::function_type::prop_get:
- if (blacklist::is_function_blacklisted(func.c_name))return "";
- if (!name.empty()) name += ".";
- name += name_helpers::managed_method_name(func);
- break;
- default:
- // No need to deal with property as function_defs are converted to get/set when building a given klass_def.
- break;
+ // managed_method_name takes care of reordering the function name so the get/set goes first
+ // for properties
+ case attributes::function_type::method:
+ if (blacklist::is_function_blacklisted(func.c_name))return "";
+ if (!name.empty()) name += ".";
+ name += name_helpers::managed_method_name(func);
+ break;
+ case attributes::function_type::prop_set:
+ case attributes::function_type::prop_get:
+ case attributes::function_type::property:
+ {
+ auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state;
+ auto klass = get_klass(func.klass, unit);
+ attributes::klass_def klass_d(klass, unit);
+
+ auto eo_name = func.name;
+ auto prop_name = eo_name;
+ if (prop_name.size () > 4
+ &&
+ ( prop_name.substr(prop_name.size() - 4) == "_set"
+ || prop_name.substr(prop_name.size() - 4) == "_get"))
+ {
+ prop_name = prop_name.substr(0, prop_name.size() - 4);
+ }
+ std::string short_name = name_helpers::property_managed_name(klass_d, prop_name);
+ assert (prop_name.size() <= 4 ||
+ (prop_name.substr(prop_name.size() - 4) != "_set"
+ && prop_name.substr(prop_name.size() - 4) != "_get"));
+ assert (short_name.size() <= 3 ||
+ (short_name.substr(short_name.size() - 3) != "Set"
+ && short_name.substr(short_name.size() - 3) != "Get"));
+
+ // We need to replace the current class context with the context
+ // from the class that originated this property.
+ class_context::wrapper_kind klass_kind;
+ if (helpers::is_managed_interface(klass_d))
+ klass_kind = class_context::interface;
+ else
+ klass_kind = class_context::inherit;
+
+ auto my_context = grammar::context_replace_tag(class_context{klass_kind}, context);
+
+ auto function = eolian_class_function_by_name_get (klass, prop_name.c_str(), EOLIAN_PROPERTY);
+ attributes::function_def getter_func{function, ::EOLIAN_PROP_GET, nullptr, unit};
+ attributes::function_def setter_func{function, ::EOLIAN_PROP_SET, nullptr, unit};
+ attributes::property_def prop{function, getter_func, setter_func, unit};
+
+ if (func.type == attributes::function_type::prop_get || func.type == attributes::function_type::property)
+ {
+ if (property_generate_wrapper_getter (prop, my_context))
+ name += "." + short_name;
+ else
+ name += ".Get" + short_name;
+ }
+ else if (func.type == attributes::function_type::prop_set)
+ {
+ if (property_generate_wrapper_setter (prop, my_context))
+ name += "." + short_name;
+ else
+ name += ".Set" + short_name;
+ }
+ }
+ break;
+ default:
+ // No need to deal with property as function_defs are converted to get/set when building a given klass_def.
+ break;
}
return name;
}
// Turns an Eolian reference like @Efl.Input.Pointer.tool into a <see> tag
- template<typename Context>
- static std::string ref_conversion(const ::Eolian_Doc_Token *token
- , const Eolian_State *state
- , std::string name_tail
- , Context const& context)
+ template <typename Context>
+ static std::string ref_conversion(const ::Eolian_Doc_Token *token, const Eolian_State *state, std::string name_tail,
+ bool want_beta, Context const& context)
{
- bool want_beta = context_want_beta(context);
const Eolian_Object *data, *data2;
::Eolian_Object_Type type =
::eolian_doc_token_ref_resolve(token, state, &data, &data2);
@@ -249,9 +323,9 @@ struct documentation_generator
return ref;
}
- // Turns EO documentation syntax into C# triple-slash XML comment syntax
- template<typename Context>
- static std::string syntax_conversion(std::string text, const Eolian_State *state, Context const& context)
+ // Turns EO documentation syntax into C# triple-slash XML comment syntax
+ template <typename Context>
+ static std::string syntax_conversion(std::string text, const Eolian_State *state, bool want_beta, Context const& context)
{
std::string new_text, ref;
::Eolian_Doc_Token_Type previous_token_type = ::EOLIAN_DOC_TOKEN_UNKNOWN;
@@ -290,7 +364,7 @@ struct documentation_generator
new_text += token_text;
break;
case ::EOLIAN_DOC_TOKEN_REF:
- ref = ref_conversion(&token, state, name_tail, context);
+ ref = ref_conversion(&token, state, name_tail, want_beta, context);
if (ref != "")
{
if (utils::ends_with(ref, BETA_REF_SUFFIX))
@@ -339,7 +413,9 @@ struct documentation_generator
template<typename OutputIterator, typename Context>
bool generate_opening_tag(OutputIterator sink, std::string const& tag, Context const& context, std::string tag_params = "") const
{
- return as_generator("<" << tag << tag_params << ">").generate(sink, attributes::unused, context);
+ auto tag_separator = tag_params.empty() ? "" : " ";
+
+ return as_generator("<" << tag << tag_separator << tag_params << ">").generate(sink, attributes::unused, context);
}
template<typename OutputIterator, typename Context>
@@ -355,7 +431,7 @@ struct documentation_generator
if (!as_generator(html_escaped_string).generate(std::back_inserter(new_text), text, context))
return false;
auto options = context_find_tag<options_context>(context);
- new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, context);
+ new_text = syntax_conversion( new_text, context_find_tag<eolian_state_context>(context).state, options.want_beta, context);
std::string tabs;
as_generator(scope_tab(scope_size) << "/// ").generate (std::back_inserter(tabs), attributes::unused, context);
@@ -485,6 +561,69 @@ struct documentation_generator
return generate_tag_example(sink, klass_name, context);
}
+ /*! Generates documentation for tuple-value properties.
+ *
+ * Example:
+ *
+ * A tuple containing the following information:
+ * <list type="bullet">
+ * <item><description><c>a</c>: Parameter a.</description></item>
+ * <item><description><c>b</c>: Parameter b.</description></item>
+ * </list>
+ *
+ * \param index_names If true, tuple items are referenced by their index. If
+ * false, they are referenced by their names instead.
+ */
+ template<typename OutputIterator, typename Context>
+ bool generate_tuple_parameters_doc(OutputIterator sink,
+ std::vector<attributes::parameter_def> const& parameters,
+ Context const& context,
+ bool numbered_refs = false) const
+ {
+ if (!(as_generator(scope_tab(scope_size) << "/// ")
+ .generate(sink, attributes::unused, context)
+ && as_generator(
+ "A tuple containing the following information:\n"
+ << scope_tab(scope_size) << "/// "
+ ).generate(sink, attributes::unused, context)
+ && generate_opening_tag(sink, "list", context, "type=\"bullet\"")
+ && as_generator("\n" << scope_tab(scope_size) << "/// ")
+ .generate(sink, attributes::unused, context)))
+ return false;
+
+ auto i = 0u;
+ for (auto const& param: parameters)
+ {
+ auto name = param.param_name;
+ if (!(generate_opening_tag(sink, "item", context)
+ && generate_opening_tag(sink, "description", context)
+ && generate_opening_tag(sink, "c", context)
+ && as_generator(name).generate(sink, attributes::unused, context)
+ && generate_closing_tag(sink, "c", context)))
+ return false;
+
+ if (numbered_refs && !(
+ as_generator(" (").generate(sink, attributes::unused, context)
+ && generate_opening_tag(sink, "c", context)
+ && as_generator("Item" + std::to_string(i)).generate(sink, attributes::unused, context)
+ && generate_closing_tag(sink, "c", context)
+ && as_generator(")").generate(sink, attributes::unused, context)))
+ return false;
+
+ if (!(generate_escaped_content(sink, ": " + param.documentation.full_text, context)
+ && generate_closing_tag(sink, "description", context)
+ && generate_closing_tag(sink, "item", context)
+ && as_generator("\n" << scope_tab(scope_size) << "/// ")
+ .generate(sink, attributes::unused, context)))
+ return false;
+ ++i;
+ }
+
+ return generate_closing_tag(sink, "list", context)
+ && as_generator("\n")
+ .generate(sink, attributes::unused, context);
+ }
+
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::property_def const& prop, Context const& context) const
{
@@ -507,12 +646,35 @@ struct documentation_generator
text = "";
if (prop.setter.is_engaged())
- text = prop.setter->parameters[0].documentation.full_text;
+ {
+ if (prop.setter.is_engaged() && prop.setter->values.size() > 1u)
+ {
+ if (!(
+ as_generator(scope_tab(scope_size) << "/// ")
+ .generate(sink, attributes::unused, context)
+ && generate_opening_tag(sink, "value", context)
+ && as_generator("\n")
+ .generate(sink, attributes::unused, context)
+ && generate_tuple_parameters_doc(sink, prop.setter->parameters, context, true)
+ && as_generator(scope_tab(scope_size) << "/// ")
+ .generate(sink, attributes::unused, context)
+ && generate_closing_tag(sink, "value", context)
+ && as_generator("\n")
+ .generate(sink, attributes::unused, context)
+ ))
+ return false;
+ }
+ else
+ text = prop.setter->parameters[0].documentation.full_text;
+ }
else if (prop.getter.is_engaged())
text = prop.getter->return_documentation.full_text;
// If there are no docs at all, do not generate <value> tag
if (!text.empty())
- if (!generate_tag_value(sink, text, context)) return false;
+ if (!generate_tag_value(
+ sink,
+ text,
+ context)) return false;
return generate_all_tag_examples(sink,
name_helpers::klass_full_concrete_or_interface_name(prop.klass),
@@ -634,7 +796,7 @@ struct documentation_generator
for (auto &&param : ctor.function.parameters)
{
- auto ref = function_conversion(func);
+ auto ref = function_conversion(func, context);
if (!context_find_tag<options_context>(context).want_beta && func.is_beta)
{
@@ -677,7 +839,7 @@ struct documentation_string_generator
auto options = context_find_tag<options_context>(context);
auto state = context_find_tag<eolian_state_context>(context).state;
- if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, context), context))
+ if (!as_generator(string).generate(sink, documentation_generator::syntax_conversion(escaped, state, options.want_beta, context), context))
return false;
return true;
diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
index 2c304fcd0f..4b07652275 100644
--- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
@@ -49,10 +49,11 @@ struct enum_definition_generator
if(!as_generator
(
- documentation
- << flags_attribute
- << "[Efl.Eo.BindingEntity]\n"
- "public enum " << enum_name << "\n{\n"
+ documentation(1)
+ << scope_tab << flags_attribute << "\n"
+ << scope_tab << "[Efl.Eo.BindingEntity]\n"
+ << scope_tab << "public enum " << enum_name << "\n"
+ << scope_tab << "{\n"
)
.generate(sink, enum_, context))
return false;
@@ -65,13 +66,14 @@ struct enum_definition_generator
auto literal = (*first).value.literal;
if (!as_generator
(
- documentation << string << " = " << string << ",\n"
+ documentation(2)
+ << scope_tab(2) << string << " = " << string << ",\n"
)
.generate(sink, std::make_tuple(*first, name, literal), context))
return false;
}
- if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
+ if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, context)) return false;
if(!name_helpers::close_namespaces(sink, enum_.namespaces, context))
return false;
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index a77f6d7d9c..2040a2ef04 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -131,7 +131,7 @@ struct unpack_event_args_visitor
}
bool operator()(grammar::attributes::klass_name const& cls) const
{
- return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context);
+ return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_interface_name(cls) + ")").generate(sink, attributes::unused, *context);
}
bool operator()(attributes::complex_type_def const& types) const
{
@@ -139,6 +139,10 @@ struct unpack_event_args_visitor
return as_generator("Efl.Eo.Globals.IteratorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
else if (types.outer.base_type == "accessor")
return as_generator("Efl.Eo.Globals.AccessorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
+ else if (types.outer.base_type == "array")
+ return as_generator("Efl.Eo.Globals.NativeArrayTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
+ else if (types.outer.base_type == "list")
+ return as_generator("Efl.Eo.Globals.NativeListTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
else
return as_generator("new " << eolian_mono::type << "(info, false, false)").generate(sink, type, *context);
}
@@ -165,8 +169,9 @@ struct pack_event_info_and_call_visitor
if (regular.is_struct())
{
return as_generator(
- indent << "IntPtr info = Marshal.AllocHGlobal(Marshal.SizeOf(e.arg));\n"
- << indent << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
+ indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+ << indent.inc() << "IntPtr info = Marshal.AllocHGlobal(Marshal.SizeOf(e.Arg));\n"
+ << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
).generate(sink, attributes::unused, *context);
}
@@ -185,15 +190,16 @@ struct pack_event_info_and_call_visitor
match const str_table[] =
{
- {"string", [] { return "e.arg"; }}
- , {"stringshare", [] { return "e.arg"; }}
+ {"string", [] { return "e.Arg"; }}
+ , {"stringshare", [] { return "e.Arg"; }}
};
auto str_accept_func = [&](std::string const& conversion)
{
return as_generator(
- indent << "IntPtr info = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(" << conversion << ");\n"
- << indent << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Eina.MemoryNative.Free(p));\n"
+ indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+ << indent.inc() << "IntPtr info = Eina.StringConversion.ManagedStringToNativeUtf8Alloc(" << conversion << ");\n"
+ << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Eina.MemoryNative.Free(p));\n"
).generate(sink, attributes::unused, *context);
};
@@ -202,39 +208,53 @@ struct pack_event_info_and_call_visitor
match const value_table [] =
{
- {"bool", [] { return "e.arg ? (byte) 1 : (byte) 0"; }}
- , {"Eina.Error", [] { return "(int)e.arg"; }}
- , {nullptr, [] { return "e.arg"; }}
+ {"bool", [] { return "e.Arg ? (byte) 1 : (byte) 0"; }}
+ , {"Eina.Error", [] { return "(int)e.Arg"; }}
+ , {nullptr, [] { return "e.Arg"; }}
};
auto value_accept_func = [&](std::string const& conversion)
{
return as_generator(
- indent << "IntPtr info = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << conversion << ");\n"
- << indent << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
+ indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+ << indent.inc() << "IntPtr info = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << conversion << ");\n"
+ << indent.inc() << "CallNativeEventCallback(" + library_name + ", \"_" + evt_c_name + "\", info, " << "(p) => Marshal.FreeHGlobal(p));\n"
).generate(sink, attributes::unused, *context);
};
if (eina::optional<bool> b = type_match::get_match(value_table, filter_func, value_accept_func))
return *b;
- return value_accept_func("e.args");
+ return value_accept_func("e.Args");
}
bool operator()(grammar::attributes::klass_name const&) const
{
auto const& indent = current_indentation(*context);
- return as_generator(indent << "IntPtr info = e.arg.NativeHandle;\n"
- << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", IntPtr.Zero, null);\n"
+ return as_generator(
+ indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+ << indent.inc() << "IntPtr info = e.Arg.NativeHandle;\n"
+ << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
).generate(sink, attributes::unused, *context);
}
bool operator()(attributes::complex_type_def const& type) const
{
auto const& indent = current_indentation(*context);
- if ((type.outer.base_type == "iterator") || (type.outer.base_type == "accessor"))
- return true;
-
- return as_generator(indent << "IntPtr info = e.arg.Handle;\n"
- << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", IntPtr.Zero, null);\n"
+ bool is_own = type.outer.base_qualifier & attributes::qualifier_info::is_own;
+ std::string info_variable;
+
+ if (type.outer.base_type == "iterator")
+ info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToIterator(e.Arg, ") + (is_own ? "true" : "false") + ");\n";
+ else if (type.outer.base_type == "accessor")
+ info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToAccessor(e.Arg, ") + (is_own ? "true" : "false") + ");\n";
+ else if (type.outer.base_type == "array")
+ info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeArray(e.Arg, ") + (is_own ? "true" : "false") + ");\n";
+ else if (type.outer.base_type == "list")
+ info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeList(e.Arg, ") + (is_own ? "true" : "false") + ");\n";
+ else
+ info_variable = "IntPtr info = e.Arg.Handle;\n";
+ return as_generator(indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+ << indent.inc() << info_variable
+ << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
).generate(sink, attributes::unused, *context);
}
};
@@ -256,7 +276,7 @@ struct event_argument_wrapper_generator
std::string evt_name = name_helpers::managed_event_name(evt.name);
- if (!as_generator("/// <summary>Event argument wrapper for event <see cref=\""
+ if (!as_generator(scope_tab << "/// <summary>Event argument wrapper for event <see cref=\""
<< join_namespaces(evt.klass.namespaces, '.', managed_namespace)
<< klass_interface_name(evt.klass) << "." << evt_name << "\"/>.\n"
).generate(sink, nullptr, context))
@@ -279,7 +299,7 @@ struct event_argument_wrapper_generator
{
if (!as_generator(
- lit("/// <para>Since EFL ") << evt.documentation.since << ".</para>\n"
+ scope_tab << lit("/// <para>Since EFL ") << evt.documentation.since << ".</para>\n"
).generate(sink, nullptr, context))
return false;
}
@@ -291,23 +311,23 @@ struct event_argument_wrapper_generator
}
}
- if (!as_generator(lit("/// </summary>\n")
- << "[Efl.Eo.BindingEntity]\n"
- << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
- << scope_tab << "/// <summary>Actual event payload.\n"
+ if (!as_generator(scope_tab << lit("/// </summary>\n")
+ << scope_tab << "[Efl.Eo.BindingEntity]\n"
+ << scope_tab << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
+ << scope_tab(2) << "/// <summary>Actual event payload.\n"
).generate(sink, nullptr, context))
return false;
if (since != "")
{
- if (!as_generator(scope_tab << "/// <para>Since EFL " << since << ".</para>\n").generate(sink, nullptr, context))
+ if (!as_generator(scope_tab(2) << "/// <para>Since EFL " << since << ".</para>\n").generate(sink, nullptr, context))
return false;
}
- if (!as_generator(scope_tab << "/// </summary>\n"
- << scope_tab << "/// <value>" << documentation_string << "</value>\n"
- << scope_tab << "public " << type << " arg { get; set; }\n"
- << "}\n\n"
+ if (!as_generator(scope_tab(2) << "/// </summary>\n"
+ << scope_tab(2) << "/// <value>" << documentation_string << "</value>\n"
+ << scope_tab(2) << "public " << type << " Arg { get; set; }\n"
+ << scope_tab << "}\n\n"
).generate(sink, std::make_tuple(evt.documentation.summary, *etype), context))
return false;
@@ -334,14 +354,14 @@ struct event_declaration_generator
if (evt.type.is_engaged())
wrapper_args_type = "<" + name_helpers::managed_event_args_name(evt) + ">";
- if (!as_generator(documentation(1))
+ if (!as_generator(documentation(2))
.generate(sink, evt, context)) return false;
if (evt.type.is_engaged())
if (!as_generator(
- scope_tab << "/// <value><see cref=\"" << name_helpers::managed_event_args_name(evt) << "\"/></value>\n"
+ scope_tab(2) << "/// <value><see cref=\"" << name_helpers::managed_event_args_name(evt) << "\"/></value>\n"
).generate(sink, evt, context)) return false;
if (!as_generator(
- scope_tab << "event EventHandler" << wrapper_args_type << " " << evt_name << ";\n"
+ scope_tab(2) << "event EventHandler" << wrapper_args_type << " " << evt_name << ";\n"
).generate(sink, evt, context))
return false;
@@ -391,7 +411,7 @@ struct event_definition_generator
if (!etype.is_engaged())
{
auto event_call_site_sink = std::back_inserter(event_native_call);
- if (!as_generator(indent.inc().inc() << "CallNativeEventCallback(" << library_name << ", \"_" << utils::to_uppercase(evt.c_name) << "\", IntPtr.Zero, null);\n")
+ if (!as_generator(indent.inc().inc().inc() << "CallNativeEventCallback(" << library_name << ", \"_" << utils::to_uppercase(evt.c_name) << "\", IntPtr.Zero, null);\n")
.generate(event_call_site_sink, attributes::unused, context))
return false;
}
@@ -407,7 +427,7 @@ struct event_definition_generator
auto sub_context = change_indentation(indent.inc().inc(), context);
if (!as_generator(", info => new " << wrapper_args_type << "{ "
- << "arg = ").generate(arg_initializer_sink, attributes::unused, context))
+ << "Arg = ").generate(arg_initializer_sink, attributes::unused, context))
return false;
if (!(*etype).original_type.visit(unpack_event_args_visitor<decltype(arg_initializer_sink), decltype(sub_context)>{arg_initializer_sink, &sub_context, *etype}))
return false;
@@ -420,11 +440,11 @@ struct event_definition_generator
event_args = arg_initializer;
}
- if(!as_generator(documentation(1)).generate(sink, evt, context))
+ if(!as_generator(documentation(2)).generate(sink, evt, context))
return false;
if (etype.is_engaged())
if (!as_generator(
- scope_tab << "/// <value><see cref=\"" << wrapper_args_type << "\"/></value>\n"
+ scope_tab(2) << "/// <value><see cref=\"" << wrapper_args_type << "\"/></value>\n"
).generate(sink, evt, context)) return false;
// Visible event declaration. Either a regular class member or an explicit interface implementation.
@@ -432,7 +452,7 @@ struct event_definition_generator
{
// Public event implementation.
if (!as_generator(
- scope_tab << (!use_explicit_impl ? "public " : " ") << "event EventHandler" << wrapper_args_template << " " << (use_explicit_impl ? (klass_name + ".") : "") << managed_evt_name << "\n"
+ scope_tab(2) << (!use_explicit_impl ? "public " : " ") << "event EventHandler" << wrapper_args_template << " " << (use_explicit_impl ? (klass_name + ".") : "") << managed_evt_name << "\n"
).generate(sink, attributes::unused, context))
return false;
}
@@ -445,7 +465,7 @@ struct event_definition_generator
visibility += "new ";
if (!as_generator(
- scope_tab << visibility << "event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << "\n"
+ scope_tab(2) << visibility << "event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << "\n"
).generate(sink, attributes::unused, context))
return false;
}
@@ -472,7 +492,7 @@ struct event_definition_generator
bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
if (!as_generator(
- scope_tab << "/// <summary>Method to raise event "<< event_name << ".\n"
+ scope_tab(2) << "/// <summary>Method to raise event "<< event_name << ".\n"
).generate(sink, nullptr, context))
return false;
@@ -491,7 +511,7 @@ struct event_definition_generator
{
if (!as_generator(
- scope_tab << "/// <para>Since EFL " << evt.documentation.since << ".</para>\n"
+ scope_tab(2) << "/// <para>Since EFL " << evt.documentation.since << ".</para>\n"
).generate(sink, nullptr, context))
return false;
}
@@ -504,21 +524,21 @@ struct event_definition_generator
}
// Close summary
- if (!as_generator(scope_tab << "/// </summary>\n").generate(sink, nullptr, context))
+ if (!as_generator(scope_tab(2) << "/// </summary>\n").generate(sink, nullptr, context))
return false;
if (evt.type.is_engaged())
{
- if (!as_generator(scope_tab << "/// <param name=\"e\">Event to raise.</param>\n"
+ if (!as_generator(scope_tab(2) << "/// <param name=\"e\">Event to raise.</param>\n"
).generate(sink, nullptr, context))
return false;
}
if (!as_generator(
- scope_tab << (is_concrete ? "public" : "protected virtual") << " void On" << event_name << "(" << (!evt.type.is_engaged() ? "" : event_args_type + " e") << ")\n"
- << scope_tab << "{\n"
+ scope_tab(2) << (is_concrete ? "public" : "protected virtual") << " void On" << event_name << "(" << (!evt.type.is_engaged() ? "" : event_args_type + " e") << ")\n"
+ << scope_tab(2) << "{\n"
<< event_native_call
- << scope_tab << "}\n\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, nullptr, context))
return false;
@@ -536,20 +556,20 @@ struct event_definition_generator
attributes::klass_def klass(get_klass(evt.klass, unit), unit);
auto library_name = context_find_tag<library_context>(context).actual_library_name(klass.filename);
return as_generator(
- scope_tab << "{\n"
- << scope_tab << scope_tab << "add\n"
- << scope_tab << scope_tab << "{\n"//evt.type.is_engaged()
- << scope_tab << scope_tab << scope_tab << "Efl.EventCb callerCb = GetInternalEventCallback(value"
+ scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "add\n"
+ << scope_tab(2) << scope_tab << "{\n"//evt.type.is_engaged()
+ << scope_tab(2) << scope_tab << scope_tab << "Efl.EventCb callerCb = GetInternalEventCallback(value"
<< (evt.type.is_engaged() ? event_args : "") << ");\n"
- << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
- << scope_tab << scope_tab << scope_tab << "AddNativeEventHandler(" << library_name << ", key, callerCb, value);\n"
- << scope_tab << scope_tab << "}\n\n"
- << scope_tab << scope_tab << "remove\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
- << scope_tab << scope_tab << scope_tab << "RemoveNativeEventHandler(" << library_name << ", key, value);\n"
- << scope_tab << scope_tab << "}\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
+ << scope_tab(2) << scope_tab << scope_tab << "AddNativeEventHandler(" << library_name << ", key, callerCb, value);\n"
+ << scope_tab(2) << scope_tab << "}\n\n"
+ << scope_tab(2) << scope_tab << "remove\n"
+ << scope_tab(2) << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
+ << scope_tab(2) << scope_tab << scope_tab << "RemoveNativeEventHandler(" << library_name << ", key, value);\n"
+ << scope_tab(2) << scope_tab << "}\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, attributes::unused, context);
}
};
diff --git a/src/bin/eolian_mono/eolian/mono/function_declaration.hh b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
index b71ffb121c..d209f06da1 100644
--- a/src/bin/eolian_mono/eolian/mono/function_declaration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
@@ -42,11 +42,11 @@ struct function_declaration_generator
if(f.scope != attributes::member_scope::scope_public)
return true;
- if(!as_generator(documentation(1)).generate(sink, f, context))
+ if(!as_generator(documentation(2)).generate(sink, f, context))
return false;
return as_generator
- (scope_tab << eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n\n")
+ (scope_tab(2) << eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n\n")
.generate(sink, std::make_tuple(f.return_type, name_helpers::managed_method_name(f), f.parameters), context);
}
};
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 86eb2db192..975335f4eb 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -26,8 +26,8 @@
#include "grammar/list.hpp"
#include "grammar/alternative.hpp"
#include "grammar/attribute_reorder.hpp"
-#include "grammar/eps.hpp"
#include "grammar/counter.hpp"
+#include "property_definition.hh"
#include "logging.hh"
#include "type.hh"
#include "name_helpers.hh"
@@ -39,12 +39,14 @@
#include "using_decl.hh"
#include "generation_contexts.hh"
#include "blacklist.hh"
+#include "grammar/eps.hpp"
namespace eolian_mono {
struct native_function_definition_generator
{
attributes::klass_def const* klass;
+ std::vector<attributes::property_def> properties;
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
@@ -53,6 +55,24 @@ struct native_function_definition_generator
if(blacklist::is_function_blacklisted(f, context))
return true;
+ auto it = std::find_if (properties.begin(), properties.end()
+ , [&] (attributes::property_def const& prop)
+ {
+ return (prop.getter && *prop.getter == f)
+ || (prop.setter && *prop.setter == f);
+ });
+ if (it != properties.end())
+ {
+ if (it->getter && *it->getter == f)
+ {
+ if (property_generate_wrapper_getter (*it, context))
+ return true;
+ }
+ else
+ if (property_generate_wrapper_setter (*it, context))
+ return true;
+ }
+
auto const& indent = current_indentation(context);
// Delegate for the C# method we will export to EO as a method implementation.
@@ -70,7 +90,9 @@ struct native_function_definition_generator
(marshall_annotation << " " << marshall_parameter)
) % ", ")
<< ");\n\n")
- .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
+ .generate(sink,
+ std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters),
+ context_add_tag(direction_context{direction_context::native_to_managed}, context)))
return false;
// API delegate is the wrapper for the Eo methods exported from C that we will use from C#.
@@ -166,7 +188,7 @@ struct native_function_definition_generator
, f.c_name
, f.parameters
)
- , context))
+ , context_add_tag(direction_context{direction_context::native_to_managed}, context)))
return false;
// Static functions do not need to be called from C
@@ -176,7 +198,9 @@ struct native_function_definition_generator
// This is the delegate that will be passed to Eo to be called from C.
if(!as_generator(
indent << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n\n"
- ).generate(sink, attributes::unused, context))
+ ).generate(sink,
+ attributes::unused,
+ context_add_tag(direction_context{direction_context::native_to_managed}, context)))
return false;
return true;
@@ -185,10 +209,6 @@ struct native_function_definition_generator
struct function_definition_generator
{
- function_definition_generator(bool do_super = false)
- : do_super(do_super)
- {}
-
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
{
@@ -198,6 +218,25 @@ struct function_definition_generator
if(blacklist::is_function_blacklisted(f, context))
return true;
+ auto function_scope = eolian_mono::function_scope_get(f);
+ auto it = std::find_if (properties.begin(), properties.end()
+ , [&] (attributes::property_def const& prop)
+ {
+ return (prop.getter && *prop.getter == f)
+ || (prop.setter && *prop.setter == f);
+ });
+ if (it != properties.end())
+ {
+ if (it->getter && *it->getter == f)
+ {
+ if (property_generate_wrapper_getter (*it, context))
+ function_scope = "internal ";
+ }
+ else
+ if (property_generate_wrapper_setter (*it, context))
+ function_scope = "internal ";
+ }
+
// Do not generate static function for concrete class
if (is_concrete && f.is_static)
return true;
@@ -207,7 +246,7 @@ struct function_definition_generator
return false;
if(!as_generator
- (documentation(1)).generate(sink, f, context))
+ (documentation(2)).generate(sink, f, context))
return false;
std::string self = "this.NativeHandle";
@@ -220,15 +259,15 @@ struct function_definition_generator
self = "";
if(!as_generator
- (scope_tab << eolian_mono::function_scope_get(f) << ((do_super && !f.is_static) ? "virtual " : "") << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
+ (scope_tab(2) << function_scope << ((do_super && !f.is_static) ? "virtual " : "") << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
<< ") {\n"
- << scope_tab(2) << eolian_mono::function_definition_preamble()
+ << scope_tab(3) << eolian_mono::function_definition_preamble()
<< klass_full_native_inherit_name(f.klass) << "." << string << "_ptr.Value.Delegate("
<< self
<< ((!f.is_static && (f.parameters.size() > 0)) ? ", " : "")
<< (argument_invocation % ", ") << ");\n"
- << scope_tab(2) << eolian_mono::function_definition_epilogue()
- << scope_tab(1) << "}\n\n")
+ << scope_tab(3) << eolian_mono::function_definition_epilogue()
+ << scope_tab(2) << "}\n\n")
.generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.parameters, f, f.c_name, f.parameters, f), context))
return false;
@@ -236,24 +275,29 @@ struct function_definition_generator
}
bool do_super;
+ std::vector<attributes::property_def> properties;
};
struct function_definition_parameterized
{
- function_definition_generator operator()(bool do_super) const
+ function_definition_generator operator()(bool do_super, std::vector<attributes::property_def> properties) const
{
- return {do_super};
+ return {do_super, properties};
+ }
+ function_definition_generator operator()(std::vector<attributes::property_def> properties) const
+ {
+ return {false, properties};
}
} const function_definition;
-function_definition_generator as_generator(function_definition_parameterized)
-{
- return {};
-}
+// function_definition_generator as_generator(function_definition_parameterized)
+// {
+// return {};
+// }
struct native_function_definition_parameterized
{
- native_function_definition_generator operator()(attributes::klass_def const& klass) const
+ native_function_definition_generator operator()(attributes::klass_def const& klass, std::vector<attributes::property_def> properties) const
{
- return {&klass};
+ return {&klass, properties};
}
} const native_function_definition;
@@ -285,11 +329,11 @@ struct property_extension_method_definition_generator
if (property.setter.is_engaged())
{
attributes::type_def prop_type = property.setter->parameters[0].type;
- if (!as_generator(scope_tab << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
+ if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
<< name_helpers::klass_full_concrete_or_interface_name(cls)
<< ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n"
- << scope_tab << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(\"" << property.name << "\", fac);\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(\"" << property.name << "\", fac);\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, std::make_tuple(prop_type, prop_type), context))
return false;
}
@@ -302,11 +346,12 @@ struct property_extension_method_definition_generator
if (property.setter.is_engaged())
{
attributes::type_def prop_type = property.setter->parameters[0].type;
- if (!as_generator(scope_tab << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.BindablePart<T> part, Efl.Csharp.ExtensionTag<"
+ if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "<T>(this Efl.BindablePart<T> part, Efl.Csharp.ExtensionTag<"
<< name_helpers::klass_full_concrete_or_interface_name(cls)
<< ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n"
- << scope_tab << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(part.PartName, \"" << property.name << "\", part.Binder);\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << scope_tab << "Contract.Requires(part != null, nameof(part));\n"
+ << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(part.PartName, \"" << property.name << "\", part.Binder);\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, std::make_tuple(prop_type, prop_type), context))
return false;
}
@@ -324,328 +369,109 @@ property_extension_method_definition_generator property_extension_method_definit
struct property_wrapper_definition_generator
{
- template <typename OutputIterator, typename Context>
- bool generate_get_indexer(OutputIterator sink, attributes::property_def const& property, Context const& context
- , std::string get_scope
- , bool is_interface) const
- {
- if (is_interface)
- {
- if (!as_generator(scope_tab << scope_tab << get_scope << "get;\n"
- ).generate(sink, attributes::unused, context))
- return false;
- }
- else
- {
- if (!as_generator(scope_tab << scope_tab << get_scope << "get\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab(2) << "var i = new "
- << name_helpers::property_concrete_indexer_name(property) << "();\n"
- << scope_tab << scope_tab(2) << "i.Self = this;\n"
- << scope_tab << scope_tab(2) << "return i;\n"
- << scope_tab << scope_tab << "}\n"
- ).generate(sink, attributes::unused, context))
- return false;
- }
-
- return true;
- }
-
- template <typename OutputIterator, typename Context, typename C1, typename C2>
- bool generate_indexer(OutputIterator sink
- , attributes::property_def const& property
- , Context const& context
- , std::string scope, std::string get_scope, std::string set_scope
- , std::string class_name
- , C1 keys, C2 values
- , bool is_interface
- , bool is_concrete_for_interface
- , bool has_setter) const
- {
- if (is_interface)
- return true;
-
- auto size_not_one = [] (std::vector<attributes::parameter_def> k) { return k.size() != 1; };
- auto type_or_tuple
- =
- (
- (
- attribute_conditional(size_not_one)["("]
- << (type(false) % ", ")
- << ")"
- )
- | *type(false)
- )
- ;
-
- std::string parentship = "\n";
-
- bool is_self_property = *implementing_klass == *klass_from_property;
-
- if (!(is_self_property && !is_concrete_for_interface))
- parentship = " : " + name_helpers::property_interface_indexer_name(property, *klass_from_property) + "\n";
-
- if (!as_generator
- (
- scope_tab << scope << "class " << name_helpers::property_concrete_indexer_name(property) << parentship
- << scope_tab << "{\n"
- << scope_tab(2) << "public " << class_name << " Self {get; set;}\n"
- << scope_tab(2) << "public "
- << type_or_tuple << " this[" << type_or_tuple <<" i]\n"
- << scope_tab(2) << "{\n"
- ).generate(sink, make_tuple(values, values, keys, keys), context))
- return false;
-
- assert (!keys.empty());
- std::vector<std::string> get_keys;
- if(keys.size() != 1)
- {
- unsigned int i = 0;
- for (auto&& key : keys)
- {
- static_cast<void>(key);
- ++i;
- get_keys.push_back("i.Item" + std::to_string(i));
- }
- }
- else
- {
- get_keys.push_back ("i");
- }
- assert (!get_keys.empty());
-
- generate_get(sink, property, context, get_scope, get_keys, values, is_interface, "Self.");
- if (has_setter)
- generate_set(sink, property, context, set_scope, get_keys, values, is_interface, "Self.");
-
- if (!as_generator
- (
- scope_tab(2) << "}\n"
- << scope_tab << "};\n"
- ).generate(sink, attributes::unused, context))
- return false;
- return true;
- }
- template <typename OutputIterator, typename Context, typename CK, typename CV>
- bool generate_set(OutputIterator sink, attributes::property_def const& property, Context const& context
- , std::string set_scope
- , CK keys, CV values
- , bool is_interface
- , std::string name_prefix = "") const
- {
- using efl::eolian::grammar::counter;
- if (is_interface)
- {
- if (!as_generator(scope_tab << scope_tab << set_scope << "set;\n"
- ).generate(sink, attributes::unused, context))
- return false;
- }
- else if (values.size() == 1)
- {
- if (!as_generator(scope_tab << scope_tab << set_scope << "set " << "{ " << name_prefix << name_helpers::managed_method_name(*property.setter) + "(" << *(string << ",") << "value); }\n"
- ).generate(sink, keys, context))
- return false;
- }
- else if (values.size() > 1)
- {
- if (!as_generator(
- scope_tab << scope_tab << set_scope << "set "
- << ("{ " << name_prefix << name_helpers::managed_method_name(*property.setter) + "(")
- << *(string << ",") << ((" value.Item" << counter(1)) % ", ")
- << "); }\n"
- ).generate(sink, std::make_tuple(keys, values), context))
- return false;
- }
- return true;
- }
- template <typename OutputIterator, typename Context, typename CK, typename CV>
- bool generate_get(OutputIterator sink, attributes::property_def const& property, Context const& context
- , std::string get_scope
- , CK keys, CV values
- , bool is_interface
- , std::string name_prefix = "") const
- {
- using efl::eolian::grammar::attribute_reorder;
- using efl::eolian::grammar::attributes::parameter_direction;
- using efl::eolian::grammar::attributes::parameter_def;
-
- if (is_interface) // only declaration
- {
- if (!as_generator(scope_tab << scope_tab << get_scope << "get;\n"
- ).generate(sink, attributes::unused, context))
- return false;
- }
- else
- if (/*has_getter && */values.size() == 1)
- {
- if (!as_generator
- (scope_tab << scope_tab << get_scope
- << "get " << "{ return " << name_prefix << name_helpers::managed_method_name(*property.getter)
- << "(" << (string % ",") << "); }\n"
- ).generate(sink, keys, context))
- return false;
- }
- else if (/*has_getter && */values.size() > 1)
- {
- if (!as_generator
- (scope_tab << scope_tab << get_scope << "get "
- << "{\n"
- << *attribute_reorder<1, -1, 1>
- (scope_tab(3) << type(true) << " _out_"
- << argument(false) << " = default(" << type(true) << ");\n"
- )
- << scope_tab(3) << name_prefix << name_helpers::managed_method_name(*property.getter)
- << "(" << *(string << ",") << (("out _out_" << argument(false)) % ", ") << ");\n"
- << scope_tab(3) << "return (" << (("_out_"<< argument(false)) % ", ") << ");\n"
- << scope_tab(2) << "}" << "\n"
- ).generate(sink, std::make_tuple(values, keys, values, values), context))
- return false;
- }
- // else if (values.size() == 1)
- // {
- // if (!as_generator
- // (scope_tab << scope_tab << get_scope << "get "
- // << "{\n"
- // << *attribute_reorder<1, -1, 1>(scope_tab(3) << type(true) << " _out_" << argument(false) << " = default(" << type(true) << ");\n")
- // << scope_tab(3) << name_prefix << name_helpers::managed_method_name(*property.getter)
- // << "(" << *(string << ",") << (("out _out_" << argument(false)) % ",") << ");\n"
- // << scope_tab(3) << "return " << (("_out_"<< argument(false)) % ",") << ";\n"
- // << scope_tab(2) << "}" << "\n"
- // ).generate(sink, std::make_tuple(values, keys, values, values), context))
- // return false;
- // }
- return true;
- }
-
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
{
using efl::eolian::grammar::attribute_reorder;
using efl::eolian::grammar::counter;
+ using efl::eolian::grammar::eps;
using efl::eolian::grammar::attributes::parameter_direction;
using efl::eolian::grammar::attributes::parameter_def;
- /// C(k) = keys count, C(v) = values count
- /// /------------\ /------\.
- /// |blacklisted?|---yes-----| skip |--------------\.
- /// \------------/ \------/ |
- /// | | |
- /// no yes |
- /// | | |
- /// /---------\ /------------\ |
- /// |is-static|----yes-----|is-interface| |
- /// \---------/ \------------/ |
- /// | | |
- /// no no |
- /// | | |
- /// /--------\ /-----------\ |
- /// |has-get?|---no-conc---|is-concrete|-----yes---/
- /// \--------/ \-----------/
- /// / \.
- /// no yes
- /// / \.
- /// /----\ /--------------------------------------\.
- /// |skip|-yes-|explicit return != Eina.Error or void |
- /// \----/ \--------------------------------------/
- /// |
- /// no
- /// |
- /// /--------\.
- /// |has-set?|
- /// \--------/
- /// / \.
- /// no yes
- /// / \.
- /// /------\ /--------------------------------------\.
- /// /------------------|no-set| |explicit return != Eina.Error or void |---- yes --\.
- /// | \------/ \--------------------------------------/ |
- /// | \------------|----------------------------------------------/
- /// | no
- /// | |
- /// | /--------\.
- /// | |has-both|
- /// | \--------/
- /// | |
- /// | /-------------------\.
- /// | |set-keys = get-keys|
- /// | \-------------------/
- /// | / |
- /// | no |
- /// | / |
- /// | /----\ /-----------------------\.
- /// | |skip|--no---|set-values = get-values|
- /// | \----/ \-----------------------/
- /// | /
- /// | yes
- /// | /
- /// | /--------\.
- /// \-------------------------| keys |
- /// \--------/
- /// / \.
- /// 0 >0
- /// / \.
- /// /----------\ /----------\.
- /// |no-indexer| | keys > 1 |
- /// \----------/ \----------/
- /// | / |
- /// | no yes
- /// | / |
- /// | / |
- /// | /---------\ /-------------------\.
- /// | | indexer | | indexer tuple key |
- /// | \---------/ \-------------------/
- /// | / |
- /// /--------\ |
- /// | values |----------/
- /// \--------/
- /// / \.
- /// 1 >1
- /// / \.
- /// /----------------\ /-------------\.
- /// | no tuple value | | tuple value |
- /// \----------------/ \-------------/
- ///
-
- auto has_wrapper = helpers::has_property_wrapper (property, implementing_klass, context);
- bool has_getter = has_wrapper & helpers::has_property_wrapper_bit::has_getter;
- if (!has_getter) return true;
- bool has_setter = has_wrapper & helpers::has_property_wrapper_bit::has_setter;
- bool has_indexer = has_wrapper & helpers::has_property_wrapper_bit::has_indexer;
+ if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
+ return true;
bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
bool is_static = (property.getter.is_engaged() && property.getter->is_static)
|| (property.setter.is_engaged() && property.setter->is_static);
bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
- bool is_concrete_for_interface = is_concrete
- && (implementing_klass->type == attributes::class_type::interface_
- || implementing_klass->type == attributes::class_type::mixin);
- //if (name_helpers::klass_concrete_or_interface_name (*implementing_klass) == "IMapping")
- if (false)
+
+ if ((is_concrete || is_interface) && is_static)
+ return true;
+
+ auto get_params = property.getter.is_engaged() ? property.getter->parameters.size() : 0;
+ //auto set_params = property.setter.is_engaged() ? property.setter->parameters.size() : 0;
+
+ // C# properties must have a single value.
+ //
+ // Single values in getters are automatically converted to return_type,
+ // meaning they should have 0 parameters.
+ //
+ // For setters, we ignore the return type - usually boolean.
+ // if (get_params > 0 || set_params > 1)
+ // return true;
+
+ if (property.getter && !property.getter->keys.empty())
+ return true;
+ if (property.setter && !property.setter->keys.empty())
+ return true;
+
+ if (property.getter && property.setter)
{
- if (!as_generator(grammar::lit("/// is interface ") << (int)is_interface
- << " is static " << (int)is_static
- << " is concrete " << (int)is_concrete
- << " is concrete_for_interface " << (int)is_concrete_for_interface
- << " klass_from_property->type " << (int)klass_from_property->type
- << " has_setter " << (int)has_setter
- << " property.setter->explicit_return_type != attributes::void_ " << (property.setter && property.setter->explicit_return_type != attributes::void_)
- << " property.setter->keys != property.getter->keys " << (property.setter && property.setter->keys != property.getter->keys)
- << " property.setter->values != property.getter->values " << (property.setter && property.setter->values != property.getter->values)
- << " has_setter && property.setter->scope != attributes::member_scope::scope_public " << (property.setter && property.setter->scope != attributes::member_scope::scope_public)
- << "\n")
- .generate (sink, attributes::unused, context))
- return false;
+ if (property.setter->values.size() != property.getter->values.size())
+ {
+ if (!std::equal(property.setter->values.begin(), property.setter->values.end()
+ , property.getter->values.begin()))
+ return true;
+ }
}
- if (blacklist::is_property_blacklisted(property, context))
- return true;
+ std::vector<attributes::parameter_def> parameters;
+
+ if (property.setter.is_engaged())
+ {
+ std::transform (property.setter->parameters.begin(), property.setter->parameters.end()
+ , std::back_inserter(parameters)
+ , [] (parameter_def p) -> parameter_def
+ {
+ //p.direction = efl::eolian::attributes::parameter_direction::in;
+ return p;
+ });
+ }
+ else if (property.getter.is_engaged())
+ {
+ // if getter has parameters, then we ignore return type, otherwise
+ // we use the return type.
+ if (get_params == 0)
+ parameters.push_back({parameter_direction::in
+ , property.getter->return_type, "propertyResult", {}
+ , property.getter->unit});
+ else
+ std::transform (property.getter->parameters.begin(), property.getter->parameters.end()
+ , std::back_inserter(parameters)
+ , [] (parameter_def p) -> parameter_def
+ {
+ p.direction = parameter_direction::in;
+ return p;
+ });
+ }
+ else
+ {
+ EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Property must have either a getter or a setter." << std::endl;
+ return false;
+ }
+
+ std::string dir_mod;
+ if (property.setter.is_engaged())
+ dir_mod = direction_modifier(property.setter->parameters[0]);
std::string managed_name = name_helpers::property_managed_name(property);
std::string scope = "public ";
- std::string get_scope = eolian_mono::function_scope_get(*property.getter);
- std::string set_scope = has_setter ? eolian_mono::function_scope_get(*property.setter) : "";
+ std::string get_scope = property.getter.is_engaged() ? eolian_mono::function_scope_get(*property.getter) : "";
+ bool is_get_public = get_scope == "public ";
+ std::string set_scope = property.setter.is_engaged() ? eolian_mono::function_scope_get(*property.setter) : "";
+ bool is_set_public = set_scope == "public ";
+ bool get_has_return_error = false, set_has_return_error = false;
+
+ // No need to generate this wrapper as no accessor is public.
+ if (is_interface && (!is_get_public && !is_set_public))
+ return true;
+
+ // Do not generate set-only proeprty
+ if (property.setter.is_engaged() && !property.getter.is_engaged())
+ return true;
// C# interface members are declared automatically as public
if (is_interface)
@@ -660,104 +486,146 @@ struct property_wrapper_definition_generator
get_scope = "";
set_scope = "";
}
- else if (!has_setter || (get_scope == scope))
+ else if (!property.setter.is_engaged() || (get_scope == scope))
{
scope = get_scope;
get_scope = "";
}
-
- std::string virtual_mod = (is_static || is_interface || is_concrete) ? "" : "virtual ";
-
- auto keys = property.getter->keys;
- auto values = property.getter->values;
- auto generated_values = values;
- auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
-
- if (has_indexer)
- {
- assert (!!implementing_klass);
- generate_indexer (sink, property, context, scope, get_scope, set_scope
- , klass_name, keys, values
- , is_interface, is_concrete_for_interface, has_setter);
-
- generated_values.clear();
- if (!is_interface && *implementing_klass == *klass_from_property
- && !is_concrete_for_interface)
- {
- generated_values.push_back
- (attributes::parameter_def
- {parameter_direction::in
- , attributes::type_def
- {
- attributes::regular_type_def{name_helpers::property_concrete_indexer_name(property), {attributes::qualifier_info::is_none, ""}, {}}
- , name_helpers::property_concrete_indexer_name(property)
- , false, false, false, ""
- }
- , "indexer", {}, nullptr
- });
- }
- else
+ else if (!property.getter.is_engaged() || (set_scope == scope))
{
- generated_values.push_back
- (attributes::parameter_def
- {parameter_direction::in
- , attributes::type_def
- {
- attributes::regular_type_def{name_helpers::klass_full_concrete_or_interface_name (*klass_from_property) + managed_name + "Indexer", {attributes::qualifier_info::is_none, ""}, {}}
- , name_helpers::property_interface_indexer_name(property, *klass_from_property)
- , false, false, false, ""
- }
- , "indexer", {}, nullptr
- });
+ scope = set_scope;
+ set_scope = "";
}
- }
- if (generated_values.size() == 1)
+ if (property.getter && property.getter->explicit_return_type.c_type == "Eina_Success_Flag")
+ get_has_return_error = true;
+
+ if (property.setter && property.setter->explicit_return_type.c_type == "Eina_Success_Flag")
+ set_has_return_error = true;
+
+ if (parameters.size() == 1)
{
if (!as_generator(
- documentation(1)
- << scope_tab << scope << (is_static ? "static " : virtual_mod) << type(true) << " " << managed_name << " {\n"
- ).generate(sink, std::make_tuple(property, generated_values[0].type), context))
+ documentation(2)
+ << scope_tab(2) << scope << (is_static ? "static " : "") << type(true) << " " << managed_name << " {\n"
+ ).generate(sink, std::make_tuple(property, parameters[0].type), context))
return false;
}
else
{
if (!as_generator
(
- documentation(1)
- << scope_tab << scope << (is_static ? "static (" : "(")
+ documentation(2)
+ << scope_tab(2) << scope << (is_static ? "static (" : "(")
<< (attribute_reorder<1, -1>(type(true) /*<< " " << argument*/) % ", ") << ") "
<< managed_name << " {\n"
- ).generate(sink, std::make_tuple(property, generated_values), context))
+ ).generate(sink, std::make_tuple(property, parameters), context))
return false;
}
- if (has_indexer)
+ if (property.getter)
{
- generate_get_indexer (sink, property, context, get_scope, is_interface);
+ auto managed_getter_name = name_helpers::managed_method_name(*property.getter);
+ if (is_interface)
+ {
+ if (is_get_public)
+ {
+ if (!as_generator(scope_tab(2) << scope_tab << set_scope << "get;\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+ }
+ }
+ else if (get_params == 0)
+ {
+ if (!as_generator
+ (scope_tab(2) << scope_tab << get_scope
+ << "get " << "{ return " + managed_getter_name + "(); }\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+ }
+ else if (parameters.size() >= 1)
+ {
+ if (!as_generator
+ (scope_tab(2) << scope_tab << get_scope << "get "
+ << "{\n"
+ << *attribute_reorder<1, -1, 1>
+ (scope_tab(4) << type(true) << " _out_"
+ << argument(false) << " = default(" << type(true) << ");\n"
+ )
+ << scope_tab(4) << (get_has_return_error ? "var s = " : "")
+ << name_helpers::managed_method_name(*property.getter)
+ << "(" << (("out _out_" << argument(false)) % ", ") << ");\n"
+ << ((eps(get_has_return_error) << scope_tab(4)
+ << "if (s == '\\0') throw new Efl.EflException("
+ << "\"Call of native function for " << managed_getter_name << " returned an error.\""
+ << ");\n")
+ | eps)
+ << scope_tab(4) << "return (" << (("_out_"<< argument(false)) % ", ") << ");\n"
+ << scope_tab(3) << "}" << "\n"
+ ).generate(sink, std::make_tuple(parameters, parameters, parameters), context))
+ return false;
+ }
}
- else
- {
- std::vector<std::string> empty_keys;
- generate_get(sink, property, context, get_scope, empty_keys, values, is_interface);
- if (has_setter)
- generate_set (sink, property, context, set_scope, empty_keys, values, is_interface);
+ if (property.setter)
+ {
+ auto managed_setter_name = name_helpers::managed_method_name(*property.setter);
+ if (is_interface)
+ {
+ if (is_set_public)
+ {
+ if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set;\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+ }
+ }
+ else if (parameters.size() == 1)
+ {
+ if (!as_generator(scope_tab(2) << scope_tab << set_scope << "set "
+ << "{ "
+ << ((eps (set_has_return_error) << "\n" << scope_tab(4) << "var s = ") | eps)
+ << managed_setter_name
+ << "(" << dir_mod << "value);"
+ << ((eps(set_has_return_error) << "\n" << scope_tab(4)
+ << "if (s == '\\0') throw new Efl.EflException("
+ << "\"Call of native function for " << managed_setter_name << " returned an error.\""
+ << ");\n" << scope_tab(3))
+ | eps)
+ << " }\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+ }
+ else if (parameters.size() > 1)
+ {
+ if (!as_generator(scope_tab(2) << scope_tab
+ << set_scope << "set "
+ << "{ "
+ << ((eps (set_has_return_error) << "\n" << scope_tab(4) << "var s = ") | eps)
+ << name_helpers::managed_method_name(*property.setter)
+ << "(" << dir_mod << ((" value.Item" << counter(1)) % ", ") << ");"
+ << ((eps(set_has_return_error) << "\n" << scope_tab(4)
+ << "if (s == '\\0') throw new Efl.EflException("
+ << "\"Call of native function for " << managed_setter_name << " returned an error.\""
+ << ");\n" << scope_tab(3))
+ | eps)
+ << " }" << "\n"
+ ).generate(sink, parameters, context))
+ return false;
+ }
}
- if (!as_generator(scope_tab << "}\n\n").generate(sink, attributes::unused, context))
+ if (!as_generator(scope_tab(2) << "}\n\n").generate(sink, attributes::unused, context))
return false;
return true;
}
- attributes::klass_def const* implementing_klass, *klass_from_property;
+ attributes::klass_def const* implementing_klass;
};
struct property_wrapper_definition_parameterized
{
- property_wrapper_definition_generator operator()(attributes::klass_def const& klass
- , attributes::klass_def const& prop_from_klass) const
+ property_wrapper_definition_generator operator()(attributes::klass_def const& klass) const
{
- return {&klass, &prop_from_klass};
+ return {&klass};
}
} const property_wrapper_definition;
property_wrapper_definition_generator as_generator(property_wrapper_definition_parameterized)
@@ -765,45 +633,6 @@ property_wrapper_definition_generator as_generator(property_wrapper_definition_p
return {};
}
-struct interface_property_indexer_definition_generator
-{
- template<typename OutputIterator, typename Context>
- bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
- {
- using efl::eolian::grammar::attribute_reorder;
- using efl::eolian::grammar::counter;
- using efl::eolian::grammar::attributes::parameter_direction;
- using efl::eolian::grammar::attributes::parameter_def;
-
- bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
-
- assert (is_interface);
- auto klass_name = name_helpers::klass_concrete_or_interface_name (*implementing_klass);
- std::string managed_name = name_helpers::property_managed_name(property);
-
- if (!as_generator
- ("public interface " << name_helpers::property_interface_indexer_short_name(property, *implementing_klass) << "\n"
- << "{\n"
- << "}\n"
- ).generate (sink, attributes::unused, context))
- return false;
-
- return true;
- }
- attributes::klass_def const* implementing_klass;
-};
-struct interface_property_indexer_definition_parameterized
-{
- interface_property_indexer_definition_generator operator()(attributes::klass_def const& klass) const
- {
- return {&klass};
- }
-} const interface_property_indexer_definition;
-interface_property_indexer_definition_generator as_generator(interface_property_indexer_definition_parameterized)
-{
- return {};
-}
-
}
namespace efl { namespace eolian { namespace grammar {
@@ -819,10 +648,6 @@ struct is_eager_generator< ::eolian_mono::property_wrapper_definition_generator>
template <>
struct is_eager_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
template <>
-struct is_eager_generator< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::true_type {};
-template <>
-struct is_eager_generator< ::eolian_mono::interface_property_indexer_definition_generator> : std::true_type {};
-template <>
struct is_generator< ::eolian_mono::function_definition_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_function_definition_generator> : std::true_type {};
@@ -834,10 +659,6 @@ template <>
struct is_generator< ::eolian_mono::property_wrapper_definition_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::property_wrapper_definition_parameterized> : std::true_type {};
-template <>
-struct is_generator< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::true_type {};
-template <>
-struct is_generator< ::eolian_mono::interface_property_indexer_definition_generator> : std::true_type {};
namespace type_traits {
template <>
@@ -856,11 +677,6 @@ template <>
struct attributes_needed< ::eolian_mono::property_wrapper_definition_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::property_wrapper_definition_parameterized> : std::integral_constant<int, 1> {};
-
-template <>
-struct attributes_needed< ::eolian_mono::interface_property_indexer_definition_parameterized> : std::integral_constant<int, 1> {};
-template <>
-struct attributes_needed< ::eolian_mono::interface_property_indexer_definition_generator> : std::integral_constant<int, 1> {};
}
} } }
diff --git a/src/bin/eolian_mono/eolian/mono/function_helpers.hh b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
index 4b9447f324..a70df9683a 100644
--- a/src/bin/eolian_mono/eolian/mono/function_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
@@ -117,7 +117,7 @@ struct function_definition_epilogue_generator
"Eina.Error.RaiseIfUnhandledException();\n"
<< *(convert_out_assign)
<< *(convert_in_ptr_assign)
- << scope_tab(2) << convert_return << "\n"
+ << scope_tab(3) << convert_return << "\n"
).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context))
return false;
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index 2ac16b0f61..6cbdb19a36 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -26,7 +26,6 @@ namespace eolian_mono {
struct class_context
{
enum wrapper_kind {
- none,
interface,
concrete,
inherit,
@@ -51,6 +50,19 @@ struct class_context
{}
};
+struct direction_context
+{
+ enum direction {
+ native_to_managed,
+ managed_to_native,
+ };
+ direction current_direction;
+
+ direction_context(direction current_direction)
+ : current_direction(current_direction)
+ {}
+};
+
struct indentation_context
{
constexpr indentation_context(indentation_context const& other) = default;
@@ -110,12 +122,6 @@ struct options_context {
std::string examples_dir;
};
-template<typename Context>
-bool context_want_beta(Context const& context)
-{
- return efl::eolian::grammar::context_find_tag<options_context>(context).want_beta;
-}
-
}
#endif
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 049f263d80..a13c26a1e8 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -17,7 +17,6 @@
#define EOLIAN_MONO_HELPERS_HH
#include "grammar/klass_def.hpp"
-#include "grammar/context.hpp"
#include "blacklist.hh"
#include "generation_contexts.hh"
#include "name_helpers.hh"
@@ -249,6 +248,67 @@ std::vector<attributes::function_def> get_all_implementable_methods(attributes::
return ret;
}
+/*
+ * Gets all properties that this class should implement (i.e. that come from an unimplemented interface/mixin and the class itself)
+ */
+template<typename Context>
+std::vector<attributes::property_def> get_all_implementable_properties(attributes::klass_def const& cls, Context const& context)
+{
+ bool want_beta = efl::eolian::grammar::context_find_tag<options_context>(context).want_beta;
+ std::vector<attributes::property_def> ret;
+ auto filter_beta = [&want_beta](attributes::property_def const& prop) {
+ if (!want_beta)
+ return prop.getter && !prop.setter ? !prop.getter->is_beta
+ : prop.getter && prop.setter ? !prop.getter->is_beta || !prop.setter->is_beta
+ : true
+ ;
+ else
+ return true;
+ };
+
+ std::copy_if(cls.properties.begin(), cls.properties.end(), std::back_inserter(ret), filter_beta);
+
+ // Non implemented interfaces
+ std::set<attributes::klass_name, attributes::compare_klass_name_by_name> implemented_interfaces;
+ std::set<attributes::klass_name, attributes::compare_klass_name_by_name> interfaces;
+ std::function<void(attributes::klass_name const&, bool)> inherit_algo =
+ [&] (attributes::klass_name const &klass, bool is_implemented)
+ {
+ attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
+ for (auto&& inherit: c.immediate_inherits)
+ {
+ switch(inherit.type)
+ {
+ case attributes::class_type::mixin:
+ case attributes::class_type::interface_:
+ interfaces.insert(inherit);
+ if (is_implemented)
+ implemented_interfaces.insert(inherit);
+ inherit_algo(inherit, is_implemented);
+ break;
+ case attributes::class_type::abstract_:
+ case attributes::class_type::regular:
+ inherit_algo(inherit, true);
+ default:
+ break;
+ }
+ }
+ };
+
+ inherit_algo(attributes::get_klass_name(cls), false);
+
+ for (auto&& inherit : implemented_interfaces)
+ interfaces.erase(inherit);
+
+ for (auto&& inherit : interfaces)
+ {
+ attributes::klass_def klass(get_klass(inherit, cls.unit), cls.unit);
+ std::copy_if(klass.properties.cbegin(), klass.properties.cend(), std::back_inserter(ret), filter_beta);
+ }
+
+ return ret;
+}
+
template<typename Klass>
inline bool is_managed_interface(Klass const& klass)
{
@@ -285,6 +345,51 @@ std::vector<attributes::function_def> get_all_registerable_methods(attributes::k
return ret;
}
+bool is_function_registerable (attributes::function_def func, attributes::klass_def const& cls)
+{
+ if (cls == func.klass)
+ return true;
+
+ if (is_managed_interface(func.klass) && func.is_static)
+ return true;
+
+ if (!is_managed_interface(func.klass) || func.scope != attributes::member_scope::scope_public)
+ return true;
+ return false;
+}
+
+// /*
+// * Gets all methods that this class should register (i.e. that comes from it and non-public interface methods
+// * that this class is the first one implementing)
+// */
+// template<typename Context>
+// std::vector<attributes::property_def> get_all_registerable_properties(attributes::klass_def const& cls, Context const& context)
+// {
+// std::vector<attributes::property_def> ret;
+
+// auto implementable_properties = get_all_implementable_properties(cls, context);
+
+// std::copy_if(implementable_properties.cbegin(), implementable_properties.cend(), std::back_inserter(ret)
+// , [&cls](attributes::property_def const & property) {
+// auto klass = property.getter ? property.getter->klass
+// : property.setter->klass;
+
+// if (cls == klass)
+// return true;
+
+// if (is_managed_interface(klass) && ((property.getter && property.getter->is_static)
+// || (property.setter && property.setter->is_static)))
+// return true;
+
+// if (!is_managed_interface(klass) || ((property.getter && property.getter->scope != attributes::member_scope::scope_public)
+// || (property.setter && property.setter->scope != attributes::member_scope::scope_public)))
+// return true;
+// return false;
+// });
+
+// return ret;
+// }
+
/*
* Checks whether the given is unique going up the inheritance tree from leaf_klass
*/
@@ -302,110 +407,18 @@ inline bool is_unique_event(attributes::event_def const& evt
inline std::vector<attributes::constructor_def> reorder_constructors(std::vector<attributes::constructor_def> constructors)
{
auto is_required = [](attributes::constructor_def const& ctr) { return !ctr.is_optional; };
+ auto is_object_parent = [](attributes::constructor_def const& ctr)
+ {
+ return (ctr.klass.namespaces.size() == 1
+ && ctr.klass.namespaces[0] == "Efl"
+ && ctr.klass.eolian_name == "Object"
+ && ctr.name == "Efl.Object.parent");
+ };
std::stable_partition(constructors.begin(), constructors.end(), is_required);
+ constructors.erase (std::remove_if (constructors.begin(), constructors.end(), is_object_parent), constructors.end());
return constructors;
}
-enum class has_property_wrapper_bit
-{
- has_none = 0
- , has_getter = 1 << 0
- , has_setter = 1 << 1
- , has_indexer = 1 << 2
- , has_key_tuple = 1 << 3
- , has_value_tuple = 1 << 4
- , has_set_error_check = 1 << 5
- , has_get_error_check = 1 << 6
-};
-
-has_property_wrapper_bit& operator|=(has_property_wrapper_bit& self, has_property_wrapper_bit bit)
-{
- self = static_cast<has_property_wrapper_bit>(static_cast<int>(self) | static_cast<int>(bit));
- return self;
-}
-
-bool operator&(has_property_wrapper_bit self, has_property_wrapper_bit bit)
-{
- return static_cast<int>(self) & static_cast<int>(bit);
-}
-
-template <typename Context>
-has_property_wrapper_bit has_property_wrapper(attributes::property_def const& property, attributes::klass_def const* implementing_klass
- , Context const& context)
-{
- using efl::eolian::grammar::context_find_tag;
- has_property_wrapper_bit r = has_property_wrapper_bit::has_none;
-
- if (blacklist::is_property_blacklisted(property, *implementing_klass, context))
- return r;
-
- bool has_getter = property.getter.is_engaged();
- bool has_setter = property.setter.is_engaged();
-
- bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
- bool is_static = (property.getter.is_engaged() && property.getter->is_static)
- || (has_setter && property.setter->is_static);
- bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
-
- if (is_static)
- {
- if (is_interface) return r;
- else if (is_concrete) return r;
- }
-
- // EINA_LOG_ERR("Generating property %s", name_helpers::property_managed_name(property).c_str());
- // C# interface can have only
- if (is_interface)
- {
- has_getter = has_getter && property.getter->scope == attributes::member_scope:: scope_public;
- }
-
- if (!has_getter)
- {
- return r;
- }
-
- if (property.getter->explicit_return_type != attributes::void_)
- {
- return r;
- }
- else if (has_setter)
- {
- if (property.setter->explicit_return_type != attributes::void_)
- has_setter = false; // do not generate setter
- else if (property.setter->keys != property.getter->keys)
- has_setter = false;
- else if (property.setter->values != property.getter->values)
- has_setter = false;
- }
-
- if (is_interface)
- {
- if (property.getter->scope != attributes::member_scope::scope_public)
- return r;
- else if (has_setter && property.setter->scope != attributes::member_scope::scope_public)
- has_setter = false;
- }
-
- if (has_getter)
- r |= has_property_wrapper_bit::has_getter;
- if (has_setter)
- r |= has_property_wrapper_bit::has_setter;
-
- if (property.getter->keys.size() == 1)
- r |= has_property_wrapper_bit::has_indexer;
- else if (property.getter->keys.size() > 1)
- {
- r |= has_property_wrapper_bit::has_indexer;
- r |= has_property_wrapper_bit::has_key_tuple;
- }
-
- if (property.getter->values.size() > 1)
- r |= has_property_wrapper_bit::has_value_tuple;
-
- return r;
-}
-
} // namespace helpers
} // namespace eolian_mono
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 478c6a9c80..9a494ef4c2 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -29,6 +29,7 @@
#include "name_helpers.hh"
#include "async_function_definition.hh"
#include "function_definition.hh"
+#include "property_definition.hh"
#include "function_registration.hh"
#include "function_declaration.hh"
#include "documentation.hh"
@@ -106,25 +107,21 @@ struct klass
name_helpers::klass_full_concrete_or_interface_name(cls)},
context);
- // Property wrappers
- if (!as_generator(*(interface_property_indexer_definition(cls))).generate(sink, cls.properties, iface_cxt))
- return false;
-
- if(!as_generator(documentation).generate(sink, cls, iface_cxt))
+ if(!as_generator(documentation(1)).generate(sink, cls, iface_cxt))
return false;
// Mark the interface with the proper native Efl_Class* getter
- if(!as_generator(lit("[") << name_helpers::klass_full_native_inherit_name(cls) << "]\n")
+ if(!as_generator(scope_tab << lit("[") << name_helpers::klass_full_native_inherit_name(cls) << "]\n")
.generate(sink, attributes::unused, iface_cxt))
return false;
- if(!as_generator("[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
+ if(!as_generator(scope_tab << "[Efl.Eo.BindingEntity]\n").generate(sink, attributes::unused, iface_cxt))
return false;
using efl::eolian::grammar::lit;
if(!as_generator
(
- lit("public ") << (is_partial ? "partial ":"")
+ scope_tab << lit("public ") << (is_partial ? "partial ":"")
/*<< class_type*/ << "interface" /*<<*/ " " << string << " : "
)
.generate(sink, name_helpers::klass_interface_name(cls), iface_cxt))
@@ -140,13 +137,33 @@ struct klass
return false;
}
- if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt))
+ if(!as_generator("\n" << scope_tab(2) << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt))
return false;
- if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt))
+ if(!as_generator("\n" << scope_tab << "{\n").generate(sink, attributes::unused, iface_cxt))
return false;
- if(!as_generator(*(function_declaration)).generate(sink, cls.functions, iface_cxt))
+ auto properties = cls.properties;
+ auto functions = cls.functions;
+ functions.erase (std::remove_if (functions.begin(), functions.end()
+ , [&] (attributes::function_def const& f)
+ {
+ auto it = std::find_if (properties.begin(), properties.end()
+ , [&f] (attributes::property_def const& prop)
+ {
+ return (prop.getter && *prop.getter == f)
+ || (prop.setter && *prop.setter == f);
+ });
+ if (it != properties.end())
+ {
+ if (it->getter && *it->getter == f)
+ return property_generate_wrapper_getter (*it, iface_cxt);
+ else if (it->setter && *it->setter == f)
+ return property_generate_wrapper_setter (*it, iface_cxt);
+ }
+ return false;
+ }), functions.end());
+ if(!as_generator(*(function_declaration)).generate(sink, functions, iface_cxt))
return false;
if(!as_generator(*(async_function_declaration)).generate(sink, cls.functions, iface_cxt))
@@ -157,16 +174,19 @@ struct klass
for (auto &&p : cls.parts)
if (!as_generator(
- documentation(1)
+ documentation(2)
<< name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n"
).generate(sink, p, iface_cxt))
return false;
- if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, iface_cxt))
+ properties.erase(std::remove_if (properties.begin(), properties.end()
+ , [&] (attributes::property_def const& prop)
+ { return !property_generate_wrapper_getter (prop, iface_cxt); }), properties.end());
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, properties, iface_cxt))
return false;
// End of interface declaration
- if(!as_generator("}\n\n").generate(sink, attributes::unused, iface_cxt)) return false;
+ if(!as_generator(scope_tab << "}\n\n").generate(sink, attributes::unused, iface_cxt)) return false;
}
// Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events.
@@ -197,98 +217,9 @@ struct klass
auto concrete_cxt = context_add_tag(class_context{class_context::concrete,
name_helpers::klass_full_concrete_or_interface_name(cls)},
context);
- auto concrete_name = name_helpers::klass_concrete_name(cls);
- auto interface_name = name_helpers::klass_interface_name(cls);
-
- // We can't make these internal yet as they have methods that are used by
- // other classes that implement the interface.
- if(!as_generator
- (
- documentation
- << "public sealed " << (is_partial ? "partial ":"") << "class " << concrete_name << " :\n"
- << scope_tab << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "")
- << ",\n" << scope_tab << interface_name
- << *(",\n" << scope_tab << name_helpers::klass_full_concrete_or_interface_name) << "\n"
- << "{\n"
- ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt))
- return false;
-
- if (!generate_fields(sink, cls, concrete_cxt))
- return false;
-
- if (!as_generator
- (
- scope_tab << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
- << scope_tab << "/// Do not call this constructor directly.</summary>\n"
- << scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
- << scope_tab << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n"
- << scope_tab << "{\n"
- << scope_tab << "}\n\n"
- )
- .generate(sink, attributes::unused, concrete_cxt))
- return false;
-
- if (!as_generator
- (
- scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
- << ")] internal static extern System.IntPtr\n"
- << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
- << scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << interface_name << "\"/> class.\n"
- << scope_tab << "/// Internal usage: This is used when interacting with C code and should not be used directly.</summary>\n"
- << scope_tab << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
- << scope_tab << "private " << concrete_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
- << scope_tab << "{\n"
- << scope_tab << "}\n\n"
- )
- .generate(sink, attributes::unused, concrete_cxt))
- return false;
- if (!generate_events(sink, cls, concrete_cxt))
- return false;
-
- if (!as_generator(lit("#pragma warning disable CS0628\n")).generate(sink, attributes::unused, concrete_cxt))
- return false;
-
- // Parts
- if(!as_generator(*(part_definition))
- .generate(sink, cls.parts, concrete_cxt)) return false;
-
- // Concrete function definitions
- auto implemented_methods = helpers::get_all_implementable_methods(cls, concrete_cxt);
- if(!as_generator(*(function_definition))
- .generate(sink, implemented_methods, concrete_cxt)) return false;
-
- // Async wrappers
- if(!as_generator(*(async_function_definition)).generate(sink, implemented_methods, concrete_cxt))
- return false;
-
- // Property wrappers
- if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, concrete_cxt))
- return false;
-
- for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt))
- {
- attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
- if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, concrete_cxt))
- return false;
- }
-
- if (!as_generator(lit("#pragma warning restore CS0628\n")).generate(sink, attributes::unused, concrete_cxt))
- return false;
-
- // Copied from nativeinherit class, used when setting up providers.
- if(!as_generator(
- scope_tab << "private static IntPtr GetEflClassStatic()\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
- << scope_tab << "}\n\n"
- ).generate(sink, attributes::unused, concrete_cxt))
- return false;
-
- if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt)))
+ if(!generate_native_inherit_class(sink, cls, change_indentation(indent, concrete_cxt)))
return true;
-
- if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
}
// Inheritable class
@@ -301,11 +232,11 @@ struct klass
// Class header
if(!as_generator
(
- documentation
- << "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
- << "[Efl.Eo.BindingEntity]\n"
- << "[SuppressMessage(\"Microsoft.Naming\", \"CA1724:TypeNamesShouldNotMatchNamespaces\")]\n"
- << "public "
+ documentation(1)
+ << scope_tab << "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
+ << scope_tab << "[Efl.Eo.BindingEntity]\n"
+ << scope_tab << "[SuppressMessage(\"Microsoft.Naming\", \"CA1724:TypeNamesShouldNotMatchNamespaces\")]\n"
+ << scope_tab<< "public "
<< (is_partial
? class_type == "class"
? "partial class"
@@ -317,7 +248,7 @@ struct klass
<< (root ? "Efl.Eo.EoWrapper" : "") // ... or root
<< (inherit_interfaces.empty() ? "" : ", ")
<< (klass_full_concrete_or_interface_name % ", ") // interfaces
- << "\n{\n"
+ << "\n" << scope_tab << "{\n"
)
.generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), inherit_cxt))
return false;
@@ -339,7 +270,7 @@ struct klass
// Inherit function definitions
auto implemented_methods = helpers::get_all_implementable_methods(cls, inherit_cxt);
- if(!as_generator(*(function_definition(true)))
+ if(!as_generator(*(function_definition(true, helpers::get_all_implementable_properties(cls, inherit_cxt))))
.generate(sink, implemented_methods, inherit_cxt)) return false;
// Async wrappers
@@ -347,29 +278,29 @@ struct klass
return false;
// Property wrappers
- if (!as_generator(*(property_wrapper_definition(cls, cls))).generate(sink, cls.properties, inherit_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, inherit_cxt))
return false;
for (auto&& klass : helpers::non_implemented_interfaces(cls, inherit_cxt))
{
attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
- if (!as_generator(*(property_wrapper_definition(cls, c))).generate(sink, c.properties, inherit_cxt))
+ if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, inherit_cxt))
return false;
}
// Copied from nativeinherit class, used when setting up providers.
if(!as_generator(
- scope_tab << "private static IntPtr GetEflClassStatic()\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
- << scope_tab << "}\n\n"
+ scope_tab(2) << "private static IntPtr GetEflClassStatic()\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, attributes::unused, inherit_cxt))
return false;
if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), inherit_cxt)))
return true;
- if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
+ if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
}
@@ -397,18 +328,24 @@ struct klass
if (extension_method_stream.tellp() <= 0)
return true;
+ if (!name_helpers::open_namespaces(sink, cls.namespaces, context))
+ return false;
+
if(!as_generator
(lit("#if EFL_BETA\n")
<< "#pragma warning disable CS1591\n" // Disabling warnings as DocFx will hide these classes
- <<"public static class " << (string % "_") << name_helpers::klass_inherit_name(cls)
- << "_ExtensionMethods {\n"
+ << scope_tab << "public static class " << name_helpers::klass_concrete_name(cls)
+ << "Extensions {\n"
<< extension_method_stream.str()
- << "}\n"
+ << scope_tab << "}\n"
<< "#pragma warning restore CS1591\n"
<< "#endif\n")
.generate(sink, cls.namespaces, context))
return false;
+ if (!name_helpers::close_namespaces(sink, cls.namespaces, context))
+ return false;
+
return true;
}
@@ -424,8 +361,10 @@ struct klass
auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
auto inherit_name = name_helpers::klass_inherit_name(cls);
auto implementable_methods = helpers::get_all_registerable_methods(cls, context);
+ auto implementable_properties = helpers::get_all_implementable_properties(cls, context);
bool root = !helpers::has_regular_ancestor(cls);
- auto const& indent = current_indentation(inative_cxt);
+ bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
+ auto const& indent = current_indentation(inative_cxt).inc();
std::string klass_since;
if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, indent, context))
@@ -445,16 +384,29 @@ struct klass
<< klass_since
<< indent << "/// </summary>\n"
<< indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n"
- << indent << "internal new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n"
+ << indent << "internal " << (is_concrete ? "" : "new ") << "class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n"
<< indent << "{\n"
).generate(sink, attributes::unused, inative_cxt))
return false;
- if(implementable_methods.size() >= 1)
+ if(is_concrete)
+ {
+ if (!as_generator
+ (
+ scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
+ << ")] internal static extern System.IntPtr\n"
+ << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
+ )
+ .generate(sink, attributes::unused, inative_cxt))
+ return false;
+ }
+
+ if(!implementable_methods.empty())
{
if(!as_generator(
indent << scope_tab << "private static Efl.Eo.NativeModule Module = new Efl.Eo.NativeModule("
- << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ");\n\n"
+ << context_find_tag<library_context>(context).actual_library_name(cls.filename) << "); // " << implementable_methods.size()
+ << " " << implementable_properties.size() << "\n\n"
).generate(sink, attributes::unused, inative_cxt))
return false;
}
@@ -500,7 +452,7 @@ struct klass
).generate(sink, attributes::unused, inative_cxt))
return false;
- if (!root || context_find_tag<class_context>(context).current_wrapper_kind != class_context::concrete)
+ if (!root || !is_concrete)
if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type, false));\n").generate(sink, attributes::unused, inative_cxt))
return false;
@@ -511,7 +463,7 @@ struct klass
return false;
if (!klass_since.empty())
- klass_since = static_cast<std::string>(scope_tab) + klass_since;
+ klass_since = static_cast<std::string>(scope_tab(2)) + klass_since;
// Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces)
if(!as_generator(
@@ -529,11 +481,18 @@ struct klass
// Native method definitions
if(!as_generator(
indent << scope_tab << "#pragma warning disable CA1707, CS1591, SA1300, SA1600\n\n"
- << *(native_function_definition(cls))
+ << *(native_function_definition(cls, implementable_properties))
<< indent << scope_tab << "#pragma warning restore CA1707, CS1591, SA1300, SA1600\n\n")
.generate(sink, implementable_methods, change_indentation(indent.inc(), inative_cxt))) return false;
- if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false;
+ if(!as_generator(
+ indent << scope_tab << "#pragma warning disable CA1707, CS1591, SA1300, SA1600\n\n"
+ << *(native_property_function_definition(cls, cls))
+ << indent << scope_tab << "#pragma warning restore CA1707, CS1591, SA1300, SA1600\n\n")
+ .generate(sink, implementable_properties
+ , change_indentation(indent.inc(), inative_cxt))) return false;
+
+ if(!as_generator(indent << "}\n").generate(sink, attributes::unused, inative_cxt)) return false;
}
return true;
}
@@ -548,21 +507,21 @@ struct klass
auto inherit_name = name_helpers::klass_concrete_name(cls);
if(!as_generator(
- scope_tab << "/// <summary>Pointer to the native class description.</summary>\n"
- << scope_tab << "public override System.IntPtr NativeClass\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "get\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n"
- << scope_tab << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "return GetEflClassStatic();\n"
- << scope_tab << scope_tab << scope_tab << "}\n"
- << scope_tab << scope_tab << scope_tab << "else\n"
- << scope_tab << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];\n"
- << scope_tab << scope_tab << scope_tab << "}\n"
- << scope_tab << scope_tab << "}\n"
- << scope_tab << "}\n\n"
+ scope_tab(2) << "/// <summary>Pointer to the native class description.</summary>\n"
+ << scope_tab(2) << "public override System.IntPtr NativeClass\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "get\n"
+ << scope_tab(2) << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n"
+ << scope_tab(2) << scope_tab << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << scope_tab << "return GetEflClassStatic();\n"
+ << scope_tab(2) << scope_tab << scope_tab << "}\n"
+ << scope_tab(2) << scope_tab << scope_tab << "else\n"
+ << scope_tab(2) << scope_tab << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << scope_tab << "return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];\n"
+ << scope_tab(2) << scope_tab << scope_tab << "}\n"
+ << scope_tab(2) << scope_tab << "}\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, attributes::unused, context))
return false;
@@ -575,9 +534,9 @@ struct klass
auto inherit_name = name_helpers::klass_concrete_name(cls);
if(!as_generator(
- scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
+ scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
<< ")] internal static extern System.IntPtr\n"
- << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
+ << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n"
).generate(sink, attributes::unused, context))
return false;
@@ -589,40 +548,40 @@ struct klass
});
std::string klass_since;
- if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, scope_tab, context))
+ if (!documentation_helpers::generate_since_tag_line(std::back_inserter(klass_since), cls.documentation, scope_tab(2), context))
return false;
// Public (API) constructors
if (!as_generator(
- scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
+ scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
<< klass_since
- << scope_tab << "/// </summary>\n"
- << scope_tab << "/// <param name=\"parent\">Parent instance.</param>\n"
- << *(documentation)
+ << scope_tab(2) << "/// </summary>\n"
+ << scope_tab(2) << "/// <param name=\"parent\">Parent instance.</param>\n"
+ << *(documentation(1))
// For constructors with arguments, the parent is also required, as optional parameters can't come before non-optional paramenters.
- << scope_tab << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null")
+ << scope_tab(2) << "public " << inherit_name << "(Efl.Object parent" << ((constructors.size() > 0) ? "" : "= null")
<< *(", " << constructor_param ) << ") : "
<< "base(" << name_helpers::klass_get_name(cls) << "(), parent)\n"
- << scope_tab << "{\n"
+ << scope_tab(2) << "{\n"
<< (*(scope_tab << scope_tab << constructor_invocation << "\n"))
- << scope_tab << scope_tab << "FinishInstantiation();\n"
- << scope_tab << "}\n\n"
- << scope_tab << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
- << scope_tab << "/// Do not call this constructor directly.\n"
+ << scope_tab(2) << scope_tab << "FinishInstantiation();\n"
+ << scope_tab(2) << "}\n\n"
+ << scope_tab(2) << "/// <summary>Subclasses should override this constructor if they are expected to be instantiated from native code.\n"
+ << scope_tab(2) << "/// Do not call this constructor directly.\n"
<< klass_since
- << scope_tab << "/// </summary>\n"
- << scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
- << scope_tab << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n"
- << scope_tab << "{\n"
- << scope_tab << "}\n\n"
- << scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
- << scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n"
+ << scope_tab(2) << "/// </summary>\n"
+ << scope_tab(2) << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
+ << scope_tab(2) << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << "}\n\n"
+ << scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
+ << scope_tab(2) << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n"
<< klass_since
- << scope_tab << "/// </summary>\n"
- << scope_tab << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
- << scope_tab << "internal " << inherit_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
- << scope_tab << "{\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << "/// </summary>\n"
+ << scope_tab(2) << "/// <param name=\"wh\">The native pointer to be wrapped.</param>\n"
+ << scope_tab(2) << "internal " << inherit_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
return false;
@@ -632,27 +591,27 @@ struct klass
if (cls.type == attributes::class_type::abstract_)
{
if (!as_generator(
- scope_tab << "[Efl.Eo.PrivateNativeClass]\n"
- << scope_tab << "private class " << inherit_name << "Realized : " << inherit_name << "\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "private " << inherit_name << "Realized(Efl.Eo.WrappingHandle wh) : base(wh)\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << "}\n"
- << scope_tab << "}\n"
+ scope_tab(2) << "[Efl.Eo.PrivateNativeClass]\n"
+ << scope_tab(2) << "private class " << inherit_name << "Realized : " << inherit_name << "\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "private " << inherit_name << "Realized(Efl.Eo.WrappingHandle wh) : base(wh)\n"
+ << scope_tab(2) << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << "}\n"
+ << scope_tab(2) << "}\n"
).generate(sink, attributes::unused, context))
return false;
}
return as_generator(
- scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
- << scope_tab << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.\n"
+ scope_tab(2) << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
+ << scope_tab(2) << "/// Internal usage: Constructor to forward the wrapper initialization to the root class that interfaces with native code. Should not be used directly.\n"
<< klass_since
- << scope_tab << "/// </summary>\n"
- << scope_tab << "/// <param name=\"baseKlass\">The pointer to the base native Eo class.</param>\n"
- << scope_tab << "/// <param name=\"parent\">The Efl.Object parent of this instance.</param>\n"
- << scope_tab << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n"
- << scope_tab << "{\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << "/// </summary>\n"
+ << scope_tab(2) << "/// <param name=\"baseKlass\">The pointer to the base native Eo class.</param>\n"
+ << scope_tab(2) << "/// <param name=\"parent\">The Efl.Object parent of this instance.</param>\n"
+ << scope_tab(2) << "protected " << inherit_name << "(IntPtr baseKlass, Efl.Object parent) : base(baseKlass, parent)\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, attributes::unused, context);
}
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index a9fc45d7da..527771959f 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -28,8 +28,9 @@ namespace eolian_mono {
namespace eina = efl::eina;
namespace detail {
-
+
template <typename OutputIterator, typename Context>
+
struct marshall_annotation_visitor_generate
{
mutable OutputIterator sink;
@@ -41,7 +42,7 @@ struct marshall_annotation_visitor_generate
typedef marshall_type_visitor_generate<OutputIterator, Context> visitor_type;
typedef bool result_type;
-
+
bool operator()(attributes::regular_type_def const& regular) const
{
using attributes::regular_type_def;
@@ -60,7 +61,13 @@ struct marshall_annotation_visitor_generate
{"string", true, [] {
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
}},
- {"string", false, [] {
+ {"string", false, [this] {
+ auto is_native_to_managed = false;
+ if constexpr (efl::eolian::grammar::tag_check<direction_context, Context>::value)
+ is_native_to_managed = context_find_tag<direction_context>(*context).current_direction == direction_context::native_to_managed;
+
+ if((is_out || is_return) && is_native_to_managed)
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutMarshaler))";
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
}},
{"mstring", true, [] {
@@ -98,7 +105,13 @@ struct marshall_annotation_visitor_generate
{"string", true, [] {
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))";
}},
- {"string", false, [] {
+ {"string", false, [this] {
+ auto is_native_to_managed = false;
+ if constexpr (efl::eolian::grammar::tag_check<direction_context, Context>::value)
+ is_native_to_managed = context_find_tag<direction_context>(*context).current_direction == direction_context::native_to_managed;
+
+ if((is_out || is_return) && is_native_to_managed)
+ return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringOutMarshaler))";
return "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))";
}},
{"mstring", true, [] {
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
index 4d1e188997..60b495ea39 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -129,7 +129,7 @@ struct marshall_type_visitor_generate
, {"event", nullptr, [&]
{
regular_type_def r = regular;
- r.base_type = "Efl.Event.NativeStruct";
+ r.base_type = "Efl.Event";
r.namespaces.clear();
return r;
}}
@@ -190,7 +190,7 @@ struct marshall_type_visitor_generate
{
if ((is_out || is_return) && is_ptr)
return as_generator("System.IntPtr").generate(sink, attributes::unused, *context);
- return as_generator(string << ".NativeStruct")
+ return as_generator(string)
.generate(sink, name_helpers::type_full_managed_name(regular), *context);
}
else if (eina::optional<bool> b = type_match::get_match
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index bf0abb7863..bc3f278c91 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -71,6 +71,7 @@ inline std::string escape_keyword(std::string const& name)
|| is_equal(name, "lock")
|| is_equal(name, "event")
|| is_equal(name, "in")
+ || is_equal(name, "out")
|| is_equal(name, "object")
|| is_equal(name, "interface")
|| is_equal(name, "string")
@@ -229,6 +230,12 @@ inline std::string managed_namespace(std::string const& ns)
return escape_keyword(utils::remove_all(ns, '_'));
}
+inline std::string managed_name(std::string const& name, char separator='_')
+{
+ auto tokens = utils::split(name, separator);
+ return utils::to_pascal_case(tokens);
+}
+
inline std::string managed_method_name(attributes::function_def const& f)
{
std::vector<std::string> names = utils::split(f.name, '_');
@@ -244,18 +251,12 @@ inline std::string managed_method_name(attributes::function_def const& f)
// Avoid clashing with System.Object.GetType
if (candidate == "GetType" || candidate == "SetType")
{
- candidate.insert(3, f.klass.eolian_name);
+ candidate.insert(3, managed_name(f.klass.eolian_name));
}
return candidate;
}
-inline std::string managed_name(std::string const& name, char separator='_')
-{
- auto tokens = utils::split(name, separator);
- return utils::to_pascal_case(tokens);
-}
-
inline std::string full_managed_name(std::string const& name)
{
std::stringstream ss;
@@ -331,7 +332,30 @@ inline std::string enum_field_managed_name(std::string name)
inline std::string to_field_name(std::string const& in)
{
- return utils::capitalize(in);
+ std::vector<std::string> names = utils::split(in, '_');
+ return utils::to_camel_case(names);
+}
+
+
+
+template<typename T>
+inline std::string property_managed_name(T const& klass, std::string const& name)
+{
+ auto names = utils::split(name, '_');
+ // No need to escape keyword here as it will be capitalized and already
+ // namespaced inside the owner class.
+ auto managed_name = utils::to_pascal_case(names);
+ auto managed_klass_name = klass_concrete_or_interface_name(klass);
+
+ if (managed_name == "Type")
+ managed_name = managed_klass_name + managed_name;
+
+ return managed_name;
+}
+
+inline std::string property_managed_name(attributes::property_def const& property)
+{
+ return property_managed_name(property.klass, property.name);
}
inline std::string managed_part_name(attributes::part_def const& part)
@@ -377,9 +401,7 @@ struct klass_full_interface_name_generator
template<typename T>
inline std::string klass_concrete_name(T const& klass)
{
- return utils::remove_all(klass.eolian_name, '_') + ((klass.type == attributes::class_type::mixin
- || klass.type == attributes::class_type::interface_)
- ? "Concrete" : "");
+ return utils::remove_all(klass.eolian_name, '_');
}
template<typename T>
@@ -445,14 +467,19 @@ inline std::string klass_inherit_name(T const& klass)
}
template<typename T>
-inline std::string klass_native_inherit_name(EINA_UNUSED T const& klass)
+inline std::string klass_native_inherit_name(T const& klass)
{
- return "NativeMethods";
+ return ((klass.type == attributes::class_type::mixin
+ || klass.type == attributes::class_type::interface_) ? klass_interface_name(klass) : "") + "NativeMethods";
}
template<typename T>
inline std::string klass_full_native_inherit_name(T const& klass)
{
+ if(klass.type == attributes::class_type::mixin
+ || klass.type == attributes::class_type::interface_)
+ return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_native_inherit_name(klass);
+
return klass_full_concrete_name(klass) + "." + klass_native_inherit_name(klass);
}
@@ -465,6 +492,10 @@ inline std::string klass_get_name(T const& clsname)
template<typename T>
inline std::string klass_get_full_name(T const& clsname)
{
+ if(clsname.type == attributes::class_type::mixin
+ || clsname.type == attributes::class_type::interface_)
+ return klass_get_name(clsname);
+
return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname);
}
@@ -490,45 +521,6 @@ inline std::string translate_inherited_event_name(const attributes::event_def &e
return join_namespaces(klass.namespaces, '_') + klass_interface_name(klass) + "_" + managed_event_name(evt.name);
}
-// Properties
-
-template<typename T>
-inline std::string property_managed_name(T const& klass, std::string const& name)
-{
- auto names = utils::split(name, '_');
- // No need to escape keyword here as it will be capitalized and already
- // namespaced inside the owner class.
- auto managed_name = utils::to_pascal_case(names);
- auto managed_klass_name = klass_concrete_or_interface_name(klass);
-
- if (managed_name == "Type")
- managed_name = managed_klass_name + managed_name;
-
- return managed_name;
-}
-
-inline std::string property_managed_name(attributes::property_def const& property)
-{
- return property_managed_name(property.klass, property.name);
-}
-
-inline std::string property_concrete_indexer_name(attributes::property_def const& property)
-{
- return property_managed_name(property) + "Indexer";
-}
-
-template<typename T>
-inline std::string property_interface_indexer_name(attributes::property_def const& property, T const& current_klass)
-{
- return name_helpers::klass_full_interface_name(current_klass) + property_concrete_indexer_name(property);
-}
-
-template<typename T>
-inline std::string property_interface_indexer_short_name(attributes::property_def const& property, T const& current_klass)
-{
- return name_helpers::klass_interface_name(current_klass) + property_concrete_indexer_name(property);
-}
-
// Open/close namespaces
template<typename OutputIterator, typename Context>
bool open_namespaces(OutputIterator sink, std::vector<std::string> namespaces, Context const& context)
@@ -593,6 +585,16 @@ struct struct_field_name_generator
}
} const struct_field_name {};
+// Property names //
+struct struct_property_name_generator
+{
+ template <typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
+ {
+ return as_generator(string).generate(sink, name_helpers::managed_name(field.name), context);
+ }
+} const struct_property_name {};
+
} // namespace name_helpers
} // namespace eolian_mono
@@ -625,12 +627,19 @@ struct is_eager_generator<eolian_mono::name_helpers::struct_field_name_generator
template <>
struct is_generator< ::eolian_mono::name_helpers::struct_field_name_generator> : std::true_type {};
+template <>
+struct is_eager_generator<eolian_mono::name_helpers::struct_property_name_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::name_helpers::struct_property_name_generator> : std::true_type {};
+
namespace type_traits {
template <>
struct attributes_needed<struct ::eolian_mono::name_helpers::klass_full_concrete_or_interface_name_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::name_helpers::struct_field_name_generator> : std::integral_constant<int, 1> {};
+template <>
+struct attributes_needed< ::eolian_mono::name_helpers::struct_property_name_generator> : std::integral_constant<int, 1> {};
}
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index 4af5fe2aef..59faa0d493 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -34,6 +34,7 @@ namespace eolian_mono {
struct argument_generator;
struct argument_invocation_generator;
struct native_argument_invocation_generator;
+ struct native_tuple_argument_invocation_generator;
struct native_convert_in_variable_generator;
struct convert_in_variable_generator;
struct native_convert_out_variable_generator;
@@ -65,7 +66,7 @@ struct is_generator< ::eolian_mono::parameter_generator> : std::true_type {};
namespace type_traits {
template <>
-struct attributes_needed< ::eolian_mono::parameter_generator> : std::integral_constant<int, 1> {};
+struct attributes_needed< ::eolian_mono::parameter_generator> : std::integral_constant<int, 1> {};
}
template <>
@@ -75,9 +76,9 @@ struct is_generator< ::eolian_mono::marshall_parameter_generator> : std::true_ty
namespace type_traits {
template <>
-struct attributes_needed< ::eolian_mono::marshall_parameter_generator> : std::integral_constant<int, 1> {};
+struct attributes_needed< ::eolian_mono::marshall_parameter_generator> : std::integral_constant<int, 1> {};
}
-
+
template <>
struct is_eager_generator< ::eolian_mono::argument_generator> : std::true_type {};
template <>
@@ -85,9 +86,9 @@ struct is_generator< ::eolian_mono::argument_generator> : std::true_type {};
namespace type_traits {
template <>
-struct attributes_needed< ::eolian_mono::argument_generator> : std::integral_constant<int, 1> {};
+struct attributes_needed< ::eolian_mono::argument_generator> : std::integral_constant<int, 1> {};
}
-
+
template <>
struct is_eager_generator< ::eolian_mono::argument_invocation_generator> : std::true_type {};
template <>
@@ -109,6 +110,16 @@ struct attributes_needed< ::eolian_mono::native_argument_invocation_generator> :
}
template <>
+struct is_eager_generator< ::eolian_mono::native_tuple_argument_invocation_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::native_tuple_argument_invocation_generator> : std::true_type {};
+
+namespace type_traits {
+template <>
+struct attributes_needed< ::eolian_mono::native_tuple_argument_invocation_generator> : std::integral_constant<int, 1> {};
+}
+
+template <>
struct is_eager_generator< ::eolian_mono::native_convert_in_variable_generator> : std::true_type {};
template <>
struct is_generator< ::eolian_mono::native_convert_in_variable_generator> : std::true_type {};
@@ -552,6 +563,28 @@ struct native_argument_invocation_generator
}
} const native_argument_invocation {};
+struct native_tuple_argument_invocation_generator
+{
+ template <typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
+ {
+ std::string arg;// = direction_modifier(param);
+
+ if (param_should_use_out_var(param, true))
+ arg += out_variable_name(param.param_name);
+ else if (param_should_use_in_var(param, true))
+ arg += in_variable_name(param.param_name);
+ else if (param.type.original_type.visit(is_fp_visitor{}))
+ {
+ arg += escape_keyword(param.param_name) + "_wrapper.ManagedCb";
+ }
+ else // FIXME Wrap data and C function pointers into some kind of structure.
+ arg += escape_keyword(param.param_name);
+
+ return as_generator(arg).generate(sink, attributes::unused, context);
+ }
+} const native_tuple_argument_invocation {};
+
// Generates the correct parameter name when invoking a function
struct argument_invocation_generator
{
@@ -625,20 +658,27 @@ struct native_convert_in_variable_generator
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
- else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
- || param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
- )
+ else if (param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
- "var " << string << " = new " << type << "(" << escape_keyword(param.param_name)
- << ", " << (param.type.has_own ? "true" : "false")
- << ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
+ "var " << string << " = Efl.Eo.Globals.NativeListTo" << type << "(" << escape_keyword(param.param_name)
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
+ else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *")
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
+ if (!complex)
+ return false;
+ return as_generator(
+ "var " << string << " = Efl.Eo.Globals.NativeArrayTo" << type << "(" << escape_keyword(param.param_name)
+ << ");\n"
+ ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
+ }
+
else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
@@ -693,10 +733,10 @@ struct convert_in_variable_generator
}
else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
{
- auto var_name = in_variable_name(param.param_name);
if (!as_generator(
- "var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
- ).generate(sink, var_name, context))
+ "Contract.Requires(" << string << " != null, nameof(" << string << "));\n"
+ << scope_tab(2) << "var " << string << " = " << string << ".Handle;\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), escape_keyword(param.param_name), in_variable_name(param.param_name), escape_keyword(param.param_name)), context))
return false;
if (param.type.has_own)
{
@@ -710,10 +750,10 @@ struct convert_in_variable_generator
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex || complex->subtypes.size() != 2)
return false;
- auto var_name = in_variable_name(param.param_name);
if (!as_generator(
- "var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
- ).generate(sink, var_name, context))
+ "Contract.Requires(" << string << " != null, nameof(" << string << "));\n"
+ << scope_tab(2) << "var " << string << " = " << string << ".Handle;\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), escape_keyword(param.param_name), in_variable_name(param.param_name), escape_keyword(param.param_name)), context))
return false;
if (param.type.has_own && !as_generator(
escape_keyword(param.param_name) << ".SetOwn(false);\n"
@@ -729,27 +769,25 @@ struct convert_in_variable_generator
).generate(sink, attributes::unused, context))
return false;
}
- else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
- || param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
- )
+ else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
- auto var_name = in_variable_name(param.param_name);
if (!as_generator(
- "var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
- ).generate(sink, var_name, context))
+ "var " << string << " = " << "Efl.Eo.Globals.IListToNativeArray(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
+ ).generate(sink, in_variable_name(param.param_name), context))
return false;
- if (param.type.has_own && !as_generator(
- escape_keyword(param.param_name) << ".Own = false;\n"
- ).generate(sink, attributes::unused, context))
+ }
+ else if (param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *")
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
+ if (!complex)
return false;
-
- if ((param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own))
- && !as_generator(
- escape_keyword(param.param_name) << ".OwnContent = false;\n"
- ).generate(sink, attributes::unused, context))
+ auto var_name = in_variable_name(param.param_name);
+ if (!as_generator(
+ "var " << string << " = " << "Efl.Eo.Globals.IListToNativeList(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
+ ).generate(sink, var_name, context))
return false;
}
else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *")
@@ -777,8 +815,9 @@ struct convert_in_variable_generator
else if (param.type.c_type == "Eina_Value")
{
return as_generator(
- "var " << string << " = " << string << ".GetNative();\n"
- ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.param_name), context);
+ "Contract.Requires(" << string << " != null, nameof(" << string << "));\n"
+ "var " << string << " = " << string << ".GetNative();\n"
+ ).generate(sink, std::make_tuple(param.param_name, param.param_name, in_variable_name(param.param_name), param.param_name), context);
}
return true;
}
@@ -996,7 +1035,17 @@ struct convert_out_assign_generator
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
+ )
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
+ if (!complex)
+ return false;
+ return as_generator(
+ string << " = Efl.Eo.Globals.NativeArrayTo" << type << "(" << string
+ << ");\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
+ }
+ else if (param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
@@ -1006,9 +1055,7 @@ struct convert_out_assign_generator
if (!complex)
return false;
return as_generator(
- string << " = new " << type << "(" << string
- << ", " << (param.type.has_own ? "true" : "false")
- << ", " << (param.type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
+ string << " = Efl.Eo.Globals.NativeListTo" << type << "(" << string
<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
@@ -1081,6 +1128,17 @@ struct convert_in_ptr_assign_generator
string << " = " << in_variable_name(param.param_name) << ";\n"
).generate(sink, escape_keyword(param.param_name), context);
}
+ else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, !WANT_OUT)
+ || param_is_acceptable(param, "Eina_Array *", !WANT_OWN, !WANT_OUT)
+ || param_is_acceptable(param, "const Eina_Array *", WANT_OWN, !WANT_OUT)
+ || param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, !WANT_OUT)
+ )
+ {
+ return as_generator(
+ scope_tab(2) << lit("Efl.Eo.Globals.UpdateListFromNativeArray(") << escape_keyword(param.param_name) << ", " << in_variable_name(param.param_name) << ");\n"
+ ).generate(sink, attributes::unused, context);
+ }
+
return true;
}
@@ -1138,17 +1196,23 @@ struct convert_return_generator
.generate(sink, ret_type, context))
return false;
}
- else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
- || ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
- )
+ else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
- if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
- << ", " << (ret_type.has_own && (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own) ? "true" : "false")
- << ");\n")
- .generate(sink, ret_type, context))
+
+ if (!as_generator("return Efl.Eo.Globals.NativeArrayTo" << type << "(_ret_var);")
+ .generate(sink, ret_type, context))
+ return false;
+ }
+ else if (ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *")
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
+ if (!complex)
+ return false;
+ if (!as_generator("return Efl.Eo.Globals.NativeListTo" << type << "(_ret_var);")
+ .generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *")
@@ -1271,30 +1335,30 @@ struct native_convert_out_assign_generator
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
- || param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
- )
+ || param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT))
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
auto outvar = out_variable_name(param.param_name);
if (!as_generator(
- string << " = " << string << ".Handle;\n"
+ string << " = Efl.Eo.Globals.IListToNativeArray(" << string << ", " << (param.type.has_own ? "true" : "false")<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
- if (param.type.has_own && !as_generator(
- string << ".Own = false;\n"
- ).generate(sink, outvar, context))
+ }
+ else if (param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
+ || param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
+ || param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
+ || param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT))
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
+ if (!complex)
return false;
- if ((param.type.has_own && (complex->subtypes.front().is_value_type && complex->subtypes.front().has_own))
- && !as_generator(
- string << ".OwnContent = false;\n"
- ).generate(sink, outvar, context))
+ auto outvar = out_variable_name(param.param_name);
+ if (!as_generator(
+ string << " = Efl.Eo.Globals.IListToNativeList(" << string << ", " << (param.type.has_own ? "true" : "false")<<");\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
}
else if (param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
@@ -1436,18 +1500,22 @@ struct native_convert_return_generator
return as_generator("return _ret_var.Handle;")
.generate(sink, attributes::unused, context);
}
- else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
- || ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
- )
+ else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
- if (ret_type.has_own && !as_generator("_ret_var.Own = false; ")
- .generate(sink, attributes::unused, context))
+
+ return as_generator(lit("return Efl.Eo.Globals.IListToNativeArray(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");")
+ .generate(sink, attributes::unused, context);
+ }
+ else if (ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *")
+ {
+ attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
+ if (!complex)
return false;
- return as_generator("return _ret_var.Handle;")
+ return as_generator(lit("return Efl.Eo.Globals.IListToNativeList(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *")
@@ -1553,7 +1621,7 @@ struct native_convert_function_pointer_generator
struct constructor_parameter_name_generator
{
-
+
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
@@ -1609,11 +1677,11 @@ struct constructor_invocation_generator
{
auto params = ctor.function.parameters;
if (!as_generator(
- "if (" <<
+ scope_tab << "if (" <<
(efl::eolian::grammar::attribute_reorder<-1>
("Efl.Eo.Globals.ParamHelperCheck(" << constructor_parameter_name(ctor) << ")") % " || ") << ")\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << name_helpers::managed_method_name(ctor.function) << "("
+ << scope_tab(2) << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << name_helpers::managed_method_name(ctor.function) << "("
).generate(sink, params, context))
return false;
@@ -1630,7 +1698,7 @@ struct constructor_invocation_generator
if (!as_generator(
");\n"
- << scope_tab << scope_tab << "}\n").generate(sink, attributes::unused, context))
+ << scope_tab(2) << scope_tab << "}\n").generate(sink, attributes::unused, context))
return false;
return true;
}
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
index 0b8dece50c..4facf27209 100644
--- a/src/bin/eolian_mono/eolian/mono/part_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -37,14 +37,14 @@ struct part_definition_generator
return true;
auto part_klass_name = name_helpers::klass_full_concrete_or_interface_name(part.klass);
- return as_generator(documentation(1)
- << scope_tab << "public " << part_klass_name << " " << name_helpers::managed_part_name(part) << "\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "get\n"
- << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << "return GetPart(\"" << part.name << "\") as " << part_klass_name << ";\n"
- << scope_tab << scope_tab << "}\n"
- << scope_tab << "}\n"
+ return as_generator(documentation(2)
+ << scope_tab(2) << "public " << part_klass_name << " " << name_helpers::managed_part_name(part) << "\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "get\n"
+ << scope_tab(2) << scope_tab << "{\n"
+ << scope_tab(2) << scope_tab << scope_tab << "return GetPart(\"" << part.name << "\") as " << part_klass_name << ";\n"
+ << scope_tab(2) << scope_tab << "}\n"
+ << scope_tab(2) << "}\n"
).generate(sink, part.documentation, context);
}
@@ -70,12 +70,12 @@ struct part_extension_method_definition_generator
bindableClass = "Efl.BindableFactoryPart";
if (!as_generator(
- scope_tab << "public static " << bindableClass << "<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
+ scope_tab(2) << "public static " << bindableClass << "<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
<< name_helpers::klass_full_concrete_or_interface_name(cls)
<< ", T> x=null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << "\n"
- << scope_tab << "{\n"
- << scope_tab << scope_tab << "return new " << bindableClass << "<" << part_klass_name << ">(\"" << part.name << "\", fac);\n"
- << scope_tab << "}\n\n"
+ << scope_tab(2) << "{\n"
+ << scope_tab(2) << scope_tab << "return new " << bindableClass << "<" << part_klass_name << ">(\"" << part.name << "\", fac);\n"
+ << scope_tab(2) << "}\n\n"
).generate(sink, attributes::unused, context))
return false;
diff --git a/src/bin/eolian_mono/eolian/mono/property_definition.hh b/src/bin/eolian_mono/eolian/mono/property_definition.hh
new file mode 100644
index 0000000000..827454fd10
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/property_definition.hh
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2019 by its authors. See AUTHORS.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef EOLIAN_MONO_PROPERTY_DEFINITION_HH
+#define EOLIAN_MONO_PROPERTY_DEFINITION_HH
+
+#include "grammar/generator.hpp"
+#include "grammar/klass_def.hpp"
+
+#include "grammar/indentation.hpp"
+#include "grammar/list.hpp"
+#include "grammar/alternative.hpp"
+#include "type.hh"
+#include "parameter.hh"
+#include "name_helpers.hh"
+#include "using_decl.hh"
+#include "blacklist.hh"
+
+#include <eina_variant.hh>
+
+namespace eolian_mono {
+
+struct compare_get_and_set_value_type
+{
+ inline bool operator () (attributes::parameter_def const& get, attributes::parameter_def const& set) const;
+ inline bool operator () (attributes::type_def const& get, attributes::type_def const& set) const;
+};
+
+struct compare_get_and_set_value_type_overload
+{
+ template <typename T, typename U>
+ bool operator()(T const& /*left*/, U const& /*right*/) const
+ {
+ return false;
+ }
+ bool operator()(attributes::regular_type_def const& left, attributes::regular_type_def const& right) const
+ {
+ return left.base_type == right.base_type
+ && left.namespaces == right.namespaces;
+ }
+ bool operator()(attributes::complex_type_def const& left, attributes::complex_type_def const& right) const
+ {
+ return (*this)(left.outer, right.outer)
+ && std::equal (left.subtypes.begin(), left.subtypes.end(), right.subtypes.begin()
+ , compare_get_and_set_value_type{});
+ }
+ bool operator()(attributes::klass_name const& left, attributes::klass_name const& right) const
+ {
+ return left.namespaces == right.namespaces
+ && left.eolian_name == right.eolian_name;
+ }
+
+ typedef bool result_type;
+};
+
+inline bool compare_get_and_set_value_type::operator () (attributes::parameter_def const& get, attributes::parameter_def const& set) const
+{
+ return efl::eina::visit(compare_get_and_set_value_type_overload{}, get.type.original_type, set.type.original_type);
+}
+inline bool compare_get_and_set_value_type::operator () (attributes::type_def const& get, attributes::type_def const& set) const
+{
+ return efl::eina::visit(compare_get_and_set_value_type_overload{}, get.original_type, set.original_type);
+}
+
+template <typename Context>
+bool property_generate_wrapper_both_check(attributes::property_def const& property, Context const& context)
+{
+ if (blacklist::is_property_blacklisted(property, context))
+ return false;
+
+ bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
+ bool is_static = (property.getter.is_engaged() && property.getter->is_static)
+ || (property.setter.is_engaged() && property.setter->is_static);
+ bool is_concrete = context_find_tag<class_context>(context).current_wrapper_kind == class_context::concrete;
+
+ if ((is_concrete || is_interface) && is_static)
+ return false;
+
+ if (!property.getter)
+ return false;
+
+ if (property.setter)
+ {
+ if (property.getter->values.size() == property.setter->values.size())
+ {
+ if (!std::equal (property.getter->values.begin(), property.getter->values.end(), property.setter->values.begin()
+ , compare_get_and_set_value_type{}))
+ return false;
+ }
+ else
+ return false;
+ }
+
+ return true;
+}
+
+template <typename Context>
+bool property_generate_wrapper_getter(attributes::property_def const& property, Context const& context)
+{
+ if (!property_generate_wrapper_both_check (property, context))
+ return false;
+
+ if (!property.getter->keys.empty())
+ return false;
+
+ if (property.getter->explicit_return_type != attributes::void_
+ && property.getter->explicit_return_type.c_type != "Eina_Success_Flag")
+ {
+ return false;
+ }
+
+ assert (!!property.getter.is_engaged());
+
+ bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
+ if (is_interface)
+ {
+ std::string get_scope = property.getter.is_engaged() ? eolian_mono::function_scope_get(*property.getter) : "";
+ bool is_get_public = get_scope == "public ";
+ if (!is_get_public)
+ return false;
+ }
+ return true;
+}
+
+template <typename Context>
+bool property_generate_wrapper_setter (attributes::property_def const& property, Context const& context)
+{
+ if (!property_generate_wrapper_both_check (property, context))
+ return false;
+ if (!property.setter)
+ return false;
+
+ if (property.setter->explicit_return_type != attributes::void_)
+ return false;
+
+ if (!property.setter->keys.empty())
+ return false;
+
+ bool is_interface = context_find_tag<class_context>(context).current_wrapper_kind == class_context::interface;
+ if (property.setter.is_engaged() && is_interface)
+ {
+ std::string set_scope = property.setter.is_engaged() ? eolian_mono::function_scope_get(*property.setter) : "";
+ bool is_set_public = set_scope == "public ";
+ if (!is_set_public)
+ return false;
+ }
+
+ return true;
+}
+
+struct native_property_function_definition_generator
+{
+ template <typename OutputIterator, typename Context>
+ bool generate(OutputIterator sink, attributes::property_def const& property, Context const& context) const
+ {
+ EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_property_function_definition_generator: " << property.name << std::endl;
+
+ if(blacklist::is_property_blacklisted(property, context))
+ return true;
+
+ auto const& indent = current_indentation(context);
+
+ bool has_wrapper_getter = property_generate_wrapper_getter (property, context);
+ bool has_wrapper_setter = property_generate_wrapper_setter (property, context);
+
+ auto gen = [&] (attributes::function_def const& f, bool is_set)
+ {
+ // Delegate for the C# method we will export to EO as a method implementation.
+ if(!as_generator
+ (
+ indent << eolian_mono::marshall_annotation(true) << "\n"
+ << indent << "private delegate "
+ << eolian_mono::marshall_type(true)
+ << " "
+ << string
+ << "_delegate(" << (f.is_static ? "" : "System.IntPtr obj, System.IntPtr pd")
+ << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
+ << (grammar::attribute_reorder<-1, -1>
+ (
+ (marshall_annotation << " " << marshall_parameter)
+ ) % ", ")
+ << ");\n\n")
+ .generate(sink,
+ std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters),
+ context_add_tag(direction_context{direction_context::native_to_managed}, context)))
+ return false;
+
+ // API delegate is the wrapper for the Eo methods exported from C that we will use from C#.
+ if(!as_generator
+ (
+ indent << eolian_mono::marshall_annotation(true) << "\n"
+ << indent << "internal delegate "
+ << eolian_mono::marshall_type(true)
+ << " "
+ << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj")
+ << ((!f.is_static && f.parameters.size() > 0) ? ", " : "")
+ << (grammar::attribute_reorder<-1, -1>
+ (
+ (marshall_annotation << " " << marshall_parameter)
+ ) % ", ")
+ << ");\n\n")
+ .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
+ return false;
+
+ // Delegate holder (so it can't be collected).
+ if(!as_generator
+ (indent << "internal static readonly Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<"
+ << string << "_api_delegate>(Module, \"" << string << "\");\n\n")
+ .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context))
+ return false;
+
+ // We do not generate the wrapper to be called from C for non public interface member directly.
+ if (blacklist::is_non_public_interface_member(f, *implementing_klass))
+ return true;
+
+ // Do not generate static method in interface
+ if (((implementing_klass->type == attributes::class_type::interface_) ||
+ (implementing_klass->type == attributes::class_type::mixin)) && f.is_static)
+ return true;
+
+ // Actual method implementation to be called from C.
+ std::string return_type;
+ if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
+ return false;
+
+ std::string klass_cast_name;
+ if ((implementing_klass->type == attributes::class_type::interface_) ||
+ ((implementing_klass->type == attributes::class_type::mixin) && !f.is_static))
+ klass_cast_name = name_helpers::klass_interface_name(*implementing_klass);
+ else
+ klass_cast_name = name_helpers::klass_inherit_name(*implementing_klass);
+
+ std::string self = "Efl.Eo.Globals.Super(obj, Efl.Eo.Globals.GetClass(obj))";
+
+ if (f.is_static)
+ self = "";
+
+ if(!as_generator
+ (indent << "[SuppressMessage(\"Microsoft.Reliability\", \"CA2000:DisposeObjectsBeforeLosingScope\", Justification = \"The instantiated objects can be stored in the called Managed API method.\")]\n"
+ << indent << "private static "
+ << eolian_mono::marshall_type(true) << " "
+ << string
+ << "(System.IntPtr obj, System.IntPtr pd"
+ << *(", " << marshall_parameter)
+ << ")\n"
+ << indent << "{\n"
+ << indent << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n"
+ << indent << scope_tab << "var ws = Efl.Eo.Globals.GetWrapperSupervisor(obj);\n"
+ << indent << scope_tab << "if (ws != null)\n"
+ << indent << scope_tab << "{\n"
+ << indent << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() << "\n"
+ << indent << scope_tab << scope_tab << "try\n"
+ << indent << scope_tab << scope_tab << "{\n"
+ )
+ .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters
+ , /***/f.c_name/***/
+ , f
+ ), context))
+ return false;
+ if (is_set/* && has_wrapper_setter*/)
+ {
+ if(!as_generator
+ (
+ indent << scope_tab << scope_tab << scope_tab << (return_type != "void" ? "_ret_var = " : "")
+ << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")ws.Target).") << string
+ )
+ .generate(sink, std::make_tuple(name_helpers::property_managed_name(property), f.parameters), context))
+ return false;
+
+ if(!f.keys.empty() && !as_generator(lit("[(") << (native_argument_invocation % ", ") << ")]").generate (sink, f.keys, context))
+ return false;
+
+ if(!as_generator
+ (" = ("
+ << (native_tuple_argument_invocation % ", ") << ");\n"
+ )
+ .generate(sink, f.values, context))
+ return false;
+ }
+ else if (!is_set/* && has_wrapper_getter*/)
+ {
+ if(!as_generator
+ (
+ indent << scope_tab << scope_tab << scope_tab << "var ret = "
+ << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")ws.Target).")
+ << string
+
+ )
+ .generate(sink, std::make_tuple(name_helpers::property_managed_name(property)), context))
+ return false;
+
+ if(!f.keys.empty() && !as_generator(lit("[(") << (native_argument_invocation % ", ") << ")]").generate (sink, f.keys, context))
+ return false;
+
+ if (!as_generator(";\n").generate (sink, attributes::unused, context))
+ return false;
+
+ }
+ // else if (!as_generator
+ // (indent << scope_tab << scope_tab << scope_tab << (return_type != "void" ? "_ret_var = " : "")
+ // << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")ws.Target).") << string
+ // << "(" << (native_argument_invocation % ", ") << ");\n"
+ // ).generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.parameters), context))
+ // return false;
+
+ if(!as_generator
+ (
+ indent << scope_tab << scope_tab << "}\n"
+ << indent << scope_tab << scope_tab << "catch (Exception e)\n"
+ << indent << scope_tab << scope_tab << "{\n"
+ << indent << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
+ << indent << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);\n"
+ << indent << scope_tab << scope_tab << "}\n\n"
+ << indent << eolian_mono::native_function_definition_epilogue(*implementing_klass) << "\n"
+ << indent << scope_tab << "}\n"
+ << indent << scope_tab << "else\n"
+ << indent << scope_tab << "{\n"
+ << indent << scope_tab << scope_tab << (return_type != "void" ? "return " : "") << string
+ << "_ptr.Value.Delegate(" << self << ((!f.is_static && f.parameters.size() > 0) ? ", " : "") << (argument % ", ") << ");\n"
+ << indent << scope_tab << "}\n"
+ << indent << "}\n\n"
+ )
+ .generate(sink, std::make_tuple(f, f.c_name, f.parameters), context))
+ return false;
+
+ // Static functions do not need to be called from C
+ if (f.is_static)
+ return true;
+
+ // This is the delegate that will be passed to Eo to be called from C.
+ if(!as_generator(
+ indent << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n\n"
+ ).generate(sink,
+ attributes::unused,
+ context_add_tag(direction_context{direction_context::native_to_managed}, context)))
+ return false;
+ return true;
+ };
+
+ bool r = true;
+ if(r && property.getter && has_wrapper_getter
+ && helpers::is_function_registerable (*property.getter, *implementing_klass))
+ r &= gen (*property.getter, false);
+ if(r && property.setter && has_wrapper_setter
+ && helpers::is_function_registerable (*property.setter, *implementing_klass))
+ r &= gen (*property.setter, true);
+ return r;
+ }
+
+ attributes::klass_def const* implementing_klass, *klass_from_property;
+};
+
+struct native_property_function_definition_parameterized
+{
+ native_property_function_definition_generator operator()(attributes::klass_def const& klass
+ , attributes::klass_def const& prop_from_klass) const
+ {
+ return {&klass, &prop_from_klass};
+ }
+} const native_property_function_definition;
+
+}
+
+namespace efl { namespace eolian { namespace grammar {
+
+template <>
+struct is_eager_generator< ::eolian_mono::native_property_function_definition_generator> : std::true_type {};
+template <>
+struct is_generator< ::eolian_mono::native_property_function_definition_generator> : std::true_type {};
+
+namespace type_traits {
+
+template <>
+struct attributes_needed< ::eolian_mono::native_property_function_definition_generator> : std::integral_constant<int, 1> {};
+
+} } } }
+
+#endif
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 7a3019ec45..038ab1d0fd 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -69,6 +69,20 @@ struct to_internal_field_convert_generator
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
+ else if ((complex && (complex->outer.base_type == "array")))
+ {
+ if (!as_generator(
+ indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IListToNativeArray(_external_struct." << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "list")))
+ {
+ if (!as_generator(
+ indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IListToNativeList(_external_struct." << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
else if ((complex && (complex->outer.base_type == "iterator")))
{
if (!as_generator(
@@ -76,9 +90,14 @@ struct to_internal_field_convert_generator
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
- else if ((complex && (complex->outer.base_type == "array"
- || complex->outer.base_type == "list"
- || complex->outer.base_type == "hash"))
+ else if ((complex && (complex->outer.base_type == "accessor")))
+ {
+ if (!as_generator(
+ indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IEnumerableToAccessor(_external_struct." << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "hash"))
|| field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
{
// Always assumes pointer
@@ -160,6 +179,7 @@ struct to_internal_field_convert_generator
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
+
return true;
}
} const to_internal_field_convert {};
@@ -169,7 +189,6 @@ struct to_external_field_convert_generator
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
{
- auto const& indent = current_indentation(context);
auto field_name = name_helpers::to_field_name(field.name);
auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
@@ -178,108 +197,116 @@ struct to_external_field_convert_generator
if (klass)
{
auto interface_name = name_helpers::klass_full_interface_name(*klass);
- auto concrete_name = name_helpers::klass_full_concrete_name(*klass);
if (!as_generator(
- "\n"
- << indent << scope_tab << scope_tab << "_external_struct." << string
- << " = (" << concrete_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n"
+ "(" << interface_name << ") Efl.Eo.Globals.CreateWrapperFor(" << string << ");"
).generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false);\n")
- .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ "new " << type << "(" << string << ", false);")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
return false;
}
- else if (complex && (complex->outer.base_type == "array"
- || complex->outer.base_type == "list"))
+ else if (complex && (complex->outer.base_type == "array"))
{
// Always assumes pointer
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
- .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ "Efl.Eo.Globals.NativeArrayTo" << type << "(" << string << ");")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
+ return false;
+ }
+ else if (complex && (complex->outer.base_type == "list"))
+ {
+ // Always assumes pointer
+ if (!as_generator(
+ "Efl.Eo.Globals.NativeListTo" << type << "(" << string << ");")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
return false;
}
else if (complex && complex->outer.base_type == "hash")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false, false);\n")
- .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ "new " << type << "(" << string << ", false, false, false);")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
return false;
}
else if (complex && complex->outer.base_type == "iterator")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = Efl.Eo.Globals.IteratorTo" << type << "(_internal_struct." << string << ");\n")
- .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ "Efl.Eo.Globals.IteratorTo" << type << "(" << string << ");")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
+ return false;
+ }
+ else if (complex && complex->outer.base_type == "accessor")
+ {
+ if (!as_generator(
+ "Efl.Eo.Globals.AccessorTo" << type << "(" << string << ");")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
return false;
}
else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n")
- .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ "Eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << string << ");")
+ .generate(sink, std::make_tuple(field.type, field_name), context))
return false;
}
else if (helpers::need_struct_conversion(regular))
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << ";\n")
- .generate(sink, std::make_tuple(field_name, field_name), context))
+ string << ";")
+ .generate(sink, field_name, context))
return false;
}
else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare"))
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = Eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n")
+ "Eina.StringConversion.NativeUtf8ToManagedString(" << string << ");")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
|| field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
{
- if (!as_generator(
- "\n" <<
- indent << scope_tab << scope_tab << "_external_struct." << field_name << ".Len = _internal_struct." << field_name << ".Len;\n" <<
- indent << scope_tab << scope_tab << "_external_struct." << field_name << ".Mem = _internal_struct." << field_name << ".Mem;\n")
+ if (!as_generator(field_name << ";")
.generate(sink, attributes::unused, context))
return false;
}
else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = new Eina.Value(_internal_struct." << string << ");\n"
- ).generate(sink, std::make_tuple(field_name, field_name), context))
+ "new Eina.Value(" << string << ");"
+ ).generate(sink, std::make_tuple(field_name), context))
return false;
}
else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = new Eina.Value(_internal_struct." << string << ", Eina.Ownership.Unmanaged);\n"
- ).generate(sink, std::make_tuple(field_name, field_name), context))
+ "new Eina.Value(" << string << ", Eina.Ownership.Unmanaged);"
+ ).generate(sink, std::make_tuple(field_name), context))
return false;
}
else if (!field.type.is_ptr && regular && regular->base_type == "bool")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << " != 0;\n"
- ).generate(sink, std::make_tuple(field_name, field_name), context))
+ string << " != 0;"
+ ).generate(sink, std::make_tuple(field_name), context))
return false;
}
else if (!field.type.is_ptr && regular && regular->base_type == "char")
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = (char)_internal_struct." << string << ";\n"
- ).generate(sink, std::make_tuple(field_name, field_name), context))
+ "(char)" << string << ";"
+ ).generate(sink, std::make_tuple(field_name), context))
return false;
}
else // primitives and enums
{
if (!as_generator(
- indent << scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << ";\n")
- .generate(sink, std::make_tuple(field_name, field_name), context))
+ field_name << ";"
+ ).generate(sink, attributes::unused, context))
return false;
}
return true;
@@ -288,22 +315,12 @@ struct to_external_field_convert_generator
// Internal Struct //
-struct struct_internal_definition_generator
+struct struct_private_property_generator
{
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
auto const& indent = current_indentation(context);
- if (!as_generator
- (
- indent << "#pragma warning disable CS1591\n\n"
- << indent << "/// <summary>Internal wrapper for struct " << string << ".</summary>\n"
- << indent << "[StructLayout(LayoutKind.Sequential)]\n"
- << indent << "internal struct " << string << "\n"
- << indent << "{\n"
- )
- .generate(sink, std::make_tuple<>(binding_struct_name(struct_), struct_internal_decl_name()), context))
- return false;
// iterate struct fields
for (auto const& field : struct_.fields)
@@ -319,7 +336,7 @@ struct struct_internal_definition_generator
|| regular->base_type == "any_value_ref")))
{
if (!as_generator(indent << scope_tab << "/// <summary>Internal wrapper for field " << field_name << "</summary>\n"
- << indent << scope_tab << "public System.IntPtr " << field_name << ";\n")
+ << indent << scope_tab << "private System.IntPtr " << field_name << ";\n")
.generate(sink, nullptr, context))
return false;
}
@@ -327,7 +344,7 @@ struct struct_internal_definition_generator
&& regular->base_type == "bool")
{
if (!as_generator(indent << scope_tab << "/// <summary>Internal wrapper for field " << field_name << "</summary>\n"
- << indent << scope_tab << "public System.Byte " << field_name << ";\n")
+ << indent << scope_tab << "private System.Byte " << field_name << ";\n")
.generate(sink, nullptr, context))
return false;
}
@@ -335,12 +352,12 @@ struct struct_internal_definition_generator
&& regular->base_type == "char")
{
if (!as_generator(indent << scope_tab << "/// <summary>Internal wrapper for field " << field_name << "</summary>\n"
- << indent << scope_tab << "public System.Byte " << field_name << ";\n")
+ << indent << scope_tab << "private System.Byte " << field_name << ";\n")
.generate(sink, nullptr, context))
return false;
}
else if (!as_generator(indent << scope_tab << eolian_mono::marshall_annotation(false) << "\n"
- << indent << scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
+ << indent << scope_tab << "private " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
return false;
}
@@ -351,59 +368,18 @@ struct struct_internal_definition_generator
// those 'mini-amd64.c condition fields not met' crashes.
if (struct_.fields.size() == 0)
{
- if (!as_generator(indent << scope_tab << "internal IntPtr field;\n").generate(sink, nullptr, context))
+ if (!as_generator(indent << scope_tab << "/// <summary>Placeholder field</summary>\n"
+ << indent << scope_tab << "private IntPtr field;\n").generate(sink, nullptr, context))
return false;
}
- auto external_name = binding_struct_name(struct_);
- auto internal_name = binding_struct_internal_name(struct_);
-
- // to internal
- if (!as_generator(
- indent << scope_tab << "/// <summary>Implicit conversion to the internal/marshalling representation.</summary>\n"
- << indent << scope_tab << "public static implicit operator " << string << "(" << string << " _external_struct)\n"
- << indent << scope_tab << "{\n"
- << indent << scope_tab << scope_tab << "var _internal_struct = new " << string << "();\n"
- ).generate(sink, std::make_tuple(internal_name, external_name, internal_name), context))
- return false;
-
- for (auto const& field : struct_.fields)
- {
- if (!to_internal_field_convert.generate(sink, field, context))
- return false;
- }
-
- if (!as_generator(indent << scope_tab << scope_tab << "return _internal_struct;\n"
- << indent << scope_tab << "}\n\n").generate(sink, nullptr, context))
- return false;
-
- // to managed
- if (!as_generator(
- indent << scope_tab << "/// <summary>Implicit conversion to the managed representation.</summary>\n"
- << indent << scope_tab << "public static implicit operator " << string << "(" << string << " _internal_struct)\n"
- << indent << scope_tab << "{\n"
- << indent << scope_tab << scope_tab << "var _external_struct = new " << string << "();\n"
- ).generate(sink, std::make_tuple(external_name, internal_name, external_name), context))
- return false;
-
- for (auto const& field : struct_.fields)
- {
- if (!to_external_field_convert.generate(sink, field, context))
- return false;
- }
-
- if (!as_generator(indent << scope_tab << scope_tab << "return _external_struct;\n"
- << indent << scope_tab << "}\n").generate(sink, nullptr, context))
+ if(!as_generator("\n")
+ .generate(sink, attributes::unused, context))
return false;
- // close internal class
- if(!as_generator(indent << "}\n"
- << indent << "#pragma warning restore CS1591\n"
- ).generate(sink, attributes::unused, context)) return false;
-
return true;
}
-} const struct_internal_definition {};
+} const struct_private_property {};
// Managed Struct //
@@ -426,7 +402,7 @@ struct struct_definition_generator
return true;
auto struct_name = binding_struct_name(struct_);
- auto const& indent = current_indentation(context);
+ auto const& indent = current_indentation(context).inc();
if (!as_generator(
indent << scope_tab << "/// <summary>Packs tuple into " << struct_name << " object.\n"
@@ -436,34 +412,22 @@ struct struct_definition_generator
return false;
if (!as_generator(
- indent << scope_tab << "public static implicit operator " << struct_name << "(\n"
- << indent << scope_tab << scope_tab << "(\n"
- << ((indent << scope_tab << scope_tab << " " << field_argument_decl) % ",\n") << "\n"
- << indent << scope_tab << scope_tab << ") tuple)\n"
- << indent << scope_tab << "{\n"
+ indent << scope_tab << "public static implicit operator " << struct_name << "(("
+ << (field_argument_decl % ", ")
+ << ") tuple)\n"
).generate(sink, struct_.fields, context))
return false;
// object constructor
if (!as_generator(
- indent << scope_tab << scope_tab << "return new " << struct_name << "{\n"
+ indent << scope_tab << scope_tab << "=> new " << struct_name << "("
).generate(sink, attributes::unused, context))
return false;
- for (const auto& field: struct_.fields)
- {
- auto field_name = name_helpers::to_field_name(field.name);
-
- if (!as_generator(
- indent << scope_tab << scope_tab << scope_tab << field_name << " = tuple." << field_name << ",\n"
- ).generate(sink, attributes::unused, context))
- return false;
- }
-
if (!as_generator(
- indent << scope_tab << scope_tab << "};\n"
- << indent << scope_tab << "}\n"
- ).generate(sink, attributes::unused, context))
+ (("tuple." << struct_field_name) % ", ")
+ << ");\n\n"
+ ).generate(sink, struct_.fields, context))
return false;
return true;
@@ -472,7 +436,7 @@ struct struct_definition_generator
template <typename OutputIterator, typename Context>
bool generate_deconstruct_method(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
- auto const& indent = current_indentation(context);
+ auto const& indent = current_indentation(context).inc();
auto struct_name = binding_struct_name(struct_);
if (!as_generator(
@@ -510,10 +474,11 @@ struct struct_definition_generator
// assigments
for (auto const& field : struct_.fields)
{
- auto field_name = name_helpers::to_field_name(field.name);
+ auto field_name = name_helpers::managed_name(field.name);
+ auto param_name = name_helpers::to_field_name(field.name);
if (!as_generator(
- indent << scope_tab << scope_tab << field_name << " = this." << field_name << ";\n"
+ indent << scope_tab << scope_tab << param_name << " = this." << field_name << ";\n"
).generate(sink, attributes::unused, context))
return false;
}
@@ -528,50 +493,44 @@ struct struct_definition_generator
bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
{
EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "struct_definition_generator: " << struct_.cxx_name << std::endl;
- auto const& indent = current_indentation(context);
- if(!as_generator(documentation).generate(sink, struct_, context))
+ auto const& indent = current_indentation(context).inc();
+ if(!as_generator(documentation(1)).generate(sink, struct_, context))
return false;
auto struct_managed_name = binding_struct_name(struct_);
if(!as_generator
(
indent << "[StructLayout(LayoutKind.Sequential)]\n"
<< indent << "[Efl.Eo.BindingEntity]\n"
- << "[SuppressMessage(\"Microsoft.Naming\", \"CA1724:TypeNamesShouldNotMatchNamespaces\")]\n"
+ << indent << "[SuppressMessage(\"Microsoft.Naming\", \"CA1724:TypeNamesShouldNotMatchNamespaces\")]\n"
<< indent << "public struct " << struct_managed_name << " : IEquatable<" << struct_managed_name << ">\n"
<< indent << "{\n"
)
.generate(sink, attributes::unused, context))
return false;
+ if (!struct_private_property.generate(sink, struct_, change_indentation(indent, context)))
+ return false;
+
// iterate struct fields
for (auto const& field : struct_.fields)
{
- if (!as_generator(documentation(indent.n + 1)).generate(sink, field, context))
+ auto docs = documentation(indent.n + 1);
+ if (!as_generator(docs).generate(sink, field, context))
return false;
if (!field.type.doc_summary.empty())
{
- if (!as_generator(indent << scope_tab << "/// <value>" << field.type.doc_summary << "</value>\n").generate(sink, attributes::unused, context))
+ if (!docs.generate_tag_value(sink, field.type.doc_summary, context))
return false;
}
- if (!as_generator(indent << scope_tab << "public " << type << " " << name_helpers::to_field_name(field.name) << ";\n").generate(sink, field.type, context))
+ if (!as_generator(indent << scope_tab << "public " << type << " " << name_helpers::managed_name(field.name) << " { get => " << to_external_field_convert << " }\n").generate(sink, std::make_tuple(field.type, field), context))
return false;
}
auto struct_name = binding_struct_name(struct_);
- // Check whether this is an extern struct without declared fields in .eo file and generate a
- // placeholder field if positive.
- // Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
- // those 'mini-amd64.c condition fields not met' crashes.
- if (struct_.fields.size() == 0)
- {
- if (!as_generator(indent << scope_tab << "/// <summary>Placeholder field</summary>\n"
- << indent << scope_tab << "public IntPtr field;\n").generate(sink, nullptr, context))
- return false;
- }
- else
+ if (struct_.fields.size() != 0)
{
// Constructor with default parameters for easy struct initialization
if(!as_generator(
@@ -589,9 +548,9 @@ struct struct_definition_generator
<< *(indent << scope_tab << field_argument_docs << "\n")
<< indent << scope_tab << "public " << string << "(\n"
<< ((indent << scope_tab << scope_tab << field_argument_default) % ",\n")
- << indent << scope_tab << ")\n"
+ << ")\n"
<< indent << scope_tab << "{\n"
- << *(indent << scope_tab << scope_tab << field_argument_assignment << ";\n")
+ << *(indent << scope_tab << scope_tab << field_argument_assignment)
<< indent << scope_tab << "}\n\n")
.generate(sink, std::make_tuple(struct_.fields, struct_name, struct_.fields, struct_.fields), context))
return false;
@@ -619,7 +578,14 @@ struct struct_definition_generator
).generate(sink, attributes::unused, context))
return false;
- if (struct_.fields.size() != 0 )
+ if (struct_.fields.size() == 1 )
+ {
+ if (!as_generator(
+ indent << scope_tab << scope_tab << "return " << name_helpers::managed_name(struct_.fields[0].name) << ".GetHashCode();\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+ }
+ else if (struct_.fields.size() != 0 )
{
// int hash = 17;
// hash = 23 * fieldA.GetHashCode();
@@ -628,7 +594,7 @@ struct struct_definition_generator
// return hash
if (!as_generator(
indent << scope_tab << scope_tab << "int hash = 17;\n"
- << *(grammar::attribute_reorder<-1, -1>(indent << scope_tab << scope_tab << "hash = hash * 23 + " << name_helpers::struct_field_name << ".GetHashCode(" << culture_info << ");\n"))
+ << *(grammar::attribute_reorder<-1, -1>(indent << scope_tab << scope_tab << "hash = hash * 23 + " << name_helpers::struct_property_name << ".GetHashCode(" << culture_info << ");\n"))
<< indent << scope_tab << scope_tab << "return hash;\n"
).generate(sink, struct_.fields, context))
return false;
@@ -637,7 +603,7 @@ struct struct_definition_generator
{
// Just compare the place holder pointers
if (!as_generator(
- "return field.GetHashCode();\n"
+ indent << scope_tab << scope_tab << "return field.GetHashCode();\n"
).generate(sink, attributes::unused, context))
return false;
}
@@ -661,7 +627,7 @@ struct struct_definition_generator
if (struct_.fields.size() != 0 )
{
if (!as_generator(
- grammar::attribute_reorder<-1, -1>((name_helpers::struct_field_name << " == other." << name_helpers::struct_field_name)) % " && "
+ grammar::attribute_reorder<-1, -1>((name_helpers::struct_property_name << " == other." << name_helpers::struct_property_name)) % " && "
).generate(sink, struct_.fields, context))
return false;
}
@@ -676,7 +642,7 @@ struct struct_definition_generator
if (!as_generator(
- indent << scope_tab << scope_tab << ";\n"
+ ";\n"
<< indent << scope_tab << "}\n"
).generate(sink, attributes::unused, context))
return false;
@@ -726,8 +692,7 @@ struct struct_definition_generator
<< indent << scope_tab << "/// <param name=\"ptr\">Native pointer to be converted.</param>\n"
<< indent << scope_tab << "public static implicit operator " << struct_name << "(IntPtr ptr)\n"
<< indent << scope_tab << "{\n"
- << indent << scope_tab << scope_tab << "var tmp = (" << struct_name << ".NativeStruct)Marshal.PtrToStructure(ptr, typeof(" << struct_name << ".NativeStruct));\n"
- << indent << scope_tab << scope_tab << "return tmp;\n"
+ << indent << scope_tab << scope_tab << "return (" << struct_name << ")Marshal.PtrToStructure(ptr, typeof(" << struct_name << "));\n"
<< indent << scope_tab << "}\n\n"
).generate(sink, attributes::unused, context))
return false;
@@ -752,9 +717,6 @@ struct struct_definition_generator
).generate(sink, attributes::unused, context))
return false;
- if (!struct_internal_definition.generate(sink, struct_, change_indentation(indent.inc(), context)))
- return false;
-
if(!as_generator(indent << "}\n\n").generate(sink, attributes::unused, context)) return false;
return true;
@@ -790,9 +752,9 @@ template <>
struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {};
template <>
-struct is_eager_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
+struct is_eager_generator< ::eolian_mono::struct_private_property_generator> : std::true_type {};
template <>
-struct is_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
+struct is_generator< ::eolian_mono::struct_private_property_generator> : std::true_type {};
template <>
struct is_eager_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
@@ -814,7 +776,7 @@ template <>
struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {};
template <>
-struct attributes_needed< ::eolian_mono::struct_internal_definition_generator> : std::integral_constant<int, 1> {};
+struct attributes_needed< ::eolian_mono::struct_private_property_generator> : std::integral_constant<int, 1> {};
template <>
struct attributes_needed< ::eolian_mono::to_internal_field_convert_generator> : std::integral_constant<int, 1> {};
diff --git a/src/bin/eolian_mono/eolian/mono/struct_fields.hh b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
index 76e0f64138..9d861a0b65 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_fields.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
@@ -69,11 +69,128 @@ struct field_argument_assignment_generator
template<typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
{
- auto field_name = name_helpers::to_field_name(field.name);
- if (!as_generator("this." << field_name << " = " << field_name)
- .generate(sink, attributes::unused, context))
- return false;
- return true;
+ auto field_name = to_field_name(field.name);
+ // FIXME Replace need_struct_conversion(regular) with need_struct_conversion(type)
+ auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
+ auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
+ auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
+
+ if (klass)
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << "?.NativeHandle ?? System.IntPtr.Zero;\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "array")))
+ {
+ if (!as_generator(
+ "this." << string << " = Efl.Eo.Globals.IListToNativeArray(" << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "list")))
+ {
+ if (!as_generator(
+ "this." << string << " = Efl.Eo.Globals.IListToNativeList(" << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "iterator")))
+ {
+ if (!as_generator(
+ "this." << string << " = Efl.Eo.Globals.IEnumerableToIterator(" << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "accessor")))
+ {
+ if (!as_generator(
+ "this." << string << " = Efl.Eo.Globals.IEnumerableToAccessor(" << string << ", " << (field.type.has_own ? "true" : "false") << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if ((complex && (complex->outer.base_type == "hash"))
+ || field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
+ {
+ // Always assumes pointer
+ if (!as_generator(
+ "this." << string << " = " << string << ".Handle;\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
+ {
+ if (!as_generator(
+ "this." << string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (helpers::need_struct_conversion(regular))
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << ";\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (regular && (regular->base_type == "string" || regular->base_type == "mstring"))
+ {
+ if (!as_generator(
+ "this." << string << " = Eina.MemoryNative.StrDup(" << string << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (regular && regular->base_type == "stringshare")
+ {
+ if (!as_generator(
+ "this." << string << " = Eina.MemoryNative.AddStringshare(" << string << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
+ || field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << ";\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << ".GetNative();\n"
+ ).generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << "?.NativeHandle ?? System.IntPtr.Zero;\n"
+ ).generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (!field.type.is_ptr && regular && regular->base_type == "bool")
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << " ? (byte)1 : (byte)0;\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else if (!field.type.is_ptr && regular && regular->base_type == "char")
+ {
+ if (!as_generator(
+ "this." << string << " = (byte)" << string << ";\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ else // primitives and enums
+ {
+ if (!as_generator(
+ "this." << string << " = " << string << ";\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
+ return true;
}
} const field_argument_assignment {};
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index f365a0d5a8..4475844e2d 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -368,13 +368,13 @@ struct visitor_generate
{"list", nullptr, nullptr, [&]
{
complex_type_def c = complex;
- c.outer.base_type = "Eina.List";
+ c.outer.base_type = "IList";
return c;
}}
, {"array", nullptr, nullptr, [&]
{
complex_type_def c = complex;
- c.outer.base_type = "Eina.Array";
+ c.outer.base_type = "IList";
return c;
}}
, {"hash", nullptr, nullptr
diff --git a/src/bin/eolian_mono/eolian/mono/utils.hh b/src/bin/eolian_mono/eolian/mono/utils.hh
index d942903aba..7905790b4c 100644
--- a/src/bin/eolian_mono/eolian/mono/utils.hh
+++ b/src/bin/eolian_mono/eolian/mono/utils.hh
@@ -90,6 +90,28 @@ namespace eolian_mono { namespace utils {
return ret;
}
+ std::string to_camel_case(const std::vector<std::string> &names, std::string const& delim="")
+ {
+ std::vector<std::string> outv(names.size());
+ std::stringstream osstream;
+
+ std::transform(names.begin(), names.end(), outv.begin(),
+ [](std::string name) {
+ name[0] = std::toupper(name[0]);
+ return name;
+ });
+
+ std::copy(outv.begin(), outv.end(), std::ostream_iterator<std::string>(osstream, delim.c_str()));
+
+ std::string ret = osstream.str();
+
+ if (delim != "")
+ ret.pop_back(); // We could implement an infix_iterator but this pop is enough for now.
+
+ ret[0] = std::tolower(ret[0]);
+ return ret;
+ }
+
inline std::string remove_all(std::string name, char target)
{
name.erase(std::remove(name.begin(), name.end(), target), name.end());
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index b6d2b6f1a0..1a96aaa826 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -172,7 +172,8 @@ run(options_type const& opts)
"using System.Linq;\n"
"using System.Threading;\n"
"using System.ComponentModel;\n"
- "using System.Diagnostics.CodeAnalysis;\n")
+ "using System.Diagnostics.CodeAnalysis;\n"
+ "using System.Diagnostics.Contracts;\n")
.generate(iterator, efl::eolian::grammar::attributes::unused, efl::eolian::grammar::context_null()))
{
throw std::runtime_error("Failed to generate file preamble");
@@ -182,14 +183,13 @@ run(options_type const& opts)
auto context = context_add_tag(eolian_mono::indentation_context{0},
context_add_tag(eolian_mono::eolian_state_context{opts.state},
- context_add_tag(eolian_mono::class_context{eolian_mono::class_context::none},
context_add_tag(eolian_mono::options_context{opts.want_beta,
opts.examples_dir},
context_add_tag(eolian_mono::library_context{opts.dllimport,
opts.v_major,
opts.v_minor,
opts.references_map},
- efl::eolian::grammar::context_null())))));
+ efl::eolian::grammar::context_null()))));
EINA_ITERATOR_FOREACH(aliases, tp)
{
diff --git a/src/bin/ethumb_client/ethumbd.c b/src/bin/ethumb_client/ethumbd.c
index 476ecd4b52..a1790c7be3 100644
--- a/src/bin/ethumb_client/ethumbd.c
+++ b/src/bin/ethumb_client/ethumbd.c
@@ -249,7 +249,7 @@ static Eina_Bool
_ethumbd_timeout_cb(void *data)
{
Ethumbd *ed = data;
-
+
ecore_main_loop_quit();
ed->timeout_timer = NULL;
return EINA_FALSE;
@@ -282,7 +282,7 @@ static Eina_Bool
_ethumbd_hang_cb(void *data)
{
Ethumbd *ed = data;
-
+
ed->hang_timer = NULL;
if (ed->processing)
{
@@ -296,7 +296,7 @@ static void
_ethumbd_hang_start(Ethumbd *ed)
{
double tim = ed->timeout;
-
+
if (tim < 0) tim = 10.0;
else
{
@@ -1752,11 +1752,9 @@ main(int argc, char *argv[])
#elif _WIN32
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
#endif
-
+
memset(&ed, 0, sizeof(ed));
ecore_init();
- eina_init();
-
ethumb_init();
if (_log_domain < 0)
@@ -1861,7 +1859,6 @@ main(int argc, char *argv[])
if (_pfx) eina_prefix_free(_pfx);
ethumb_shutdown();
- eina_shutdown();
ecore_shutdown();
return exit_value;
}
diff --git a/src/bin/ethumb_client/ethumbd_client.c b/src/bin/ethumb_client/ethumbd_client.c
index e81fc2e9a7..d833296f8c 100644
--- a/src/bin/ethumb_client/ethumbd_client.c
+++ b/src/bin/ethumb_client/ethumbd_client.c
@@ -246,7 +246,6 @@ main(int argc, char *argv[])
int i, ret = 0;
ethumb_client_init();
- ecore_init();
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_PTR_CAST(opts.geometry),
@@ -323,7 +322,6 @@ main(int argc, char *argv[])
eina_stringshare_del(opts.frame.group);
eina_stringshare_del(opts.frame.swallow);
}
- ecore_shutdown();
ethumb_client_shutdown();
return ret;
diff --git a/src/bin/ethumb_client/ethumbd_slave.c b/src/bin/ethumb_client/ethumbd_slave.c
index d7b7ff6680..1b805a4bd3 100644
--- a/src/bin/ethumb_client/ethumbd_slave.c
+++ b/src/bin/ethumb_client/ethumbd_slave.c
@@ -119,6 +119,11 @@ _ec_pipe_str_read(struct _Ethumbd_Child *ec EINA_UNUSED, char **str)
*str = NULL;
return 0;
}
+ if ((size < 0) || (size >= PATH_MAX))
+ {
+ *str = NULL;
+ return 0;
+ }
if (!size)
{
@@ -178,6 +183,8 @@ _ec_op_new(struct _Ethumbd_Child *ec)
r = _ec_read_safe(stdin, &idx, sizeof(idx));
if (!r)
return 0;
+ if ((idx < 0) || (idx >= NETHUMBS))
+ return 0;
DBG("ethumbd new(). idx = %d", idx);
@@ -194,6 +201,8 @@ _ec_op_del(struct _Ethumbd_Child *ec)
r = _ec_read_safe(stdin, &idx, sizeof(idx));
if (!r)
return 0;
+ if ((idx < 0) || (idx >= NETHUMBS))
+ return 0;
DBG("ethumbd del(). idx = %d", idx);
@@ -245,6 +254,8 @@ _ec_op_generate(struct _Ethumbd_Child *ec)
r = _ec_read_safe(stdin, &idx, sizeof(idx));
if (!r)
return 0;
+ if ((idx < 0) || (idx >= NETHUMBS))
+ return 0;
r = _ec_pipe_str_read(ec, &path);
if (!r)
@@ -667,6 +678,8 @@ _ec_op_setup(struct _Ethumbd_Child *ec)
r = _ec_read_safe(stdin, &idx, sizeof(idx));
if (!r)
return 0;
+ if ((idx < 0) || (idx >= NETHUMBS))
+ return 0;
r = _ec_read_safe(stdin, &type, sizeof(type));
if (!r)
diff --git a/src/bin/exactness/.gitignore b/src/bin/exactness/.gitignore
new file mode 100644
index 0000000000..2760101039
--- /dev/null
+++ b/src/bin/exactness/.gitignore
@@ -0,0 +1,5 @@
+/exactness
+/exactness_inject
+/exactness_inspect
+/exactness_play
+/exactness_record
diff --git a/src/bin/exactness/common.c b/src/bin/exactness/common.c
new file mode 100644
index 0000000000..d62d8fd519
--- /dev/null
+++ b/src/bin/exactness/common.c
@@ -0,0 +1,436 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "common.h"
+
+Eina_Bool
+ex_is_original_app(void)
+{
+ const char *original_pid_env = getenv("EXACTNESS_ORIGINAL_PID");
+ if (original_pid_env)
+ {
+ pid_t original_pid = atoi(original_pid_env);
+ if (original_pid == getpid())
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+void
+ex_set_original_envvar(void)
+{
+ const char *original_pid_env = getenv("EXACTNESS_ORIGINAL_PID");
+ if (!original_pid_env)
+ {
+ char pid[30];
+ snprintf(pid, sizeof(pid), "%d", getpid());
+ setenv("EXACTNESS_ORIGINAL_PID", pid, 0);
+ }
+}
+
+void
+ex_prepare_elm_overlay(void)
+{
+ elm_theme_overlay_add(NULL, DATA_DIR"/exactness_play.edj");
+}
+
+typedef struct _Dummy
+{
+} _Dummy;
+
+static Eet_Data_Descriptor *
+_mouse_wheel_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Mouse_Wheel);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Mouse_Wheel, "direction", direction, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Mouse_Wheel, "z", z, EET_T_INT);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_key_down_up_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Key_Down_Up);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "keyname", keyname, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "key", key, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "string", string, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "compose", compose, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Key_Down_Up, "keycode", keycode, EET_T_INT);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_multi_event_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Multi_Event);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "d", d, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "b", b, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "x", x, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "y", y, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "rad", rad, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "radx", radx, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "rady", rady, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "pres", pres, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "ang", ang, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "fx", fx, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "fy", fy, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Event, "flags", flags, EET_T_INT);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_multi_move_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Multi_Move);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "d", d, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "x", x, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "y", y, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "rad", rad, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "radx", radx, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "rady", rady, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "pres", pres, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "ang", ang, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "fx", fx, EET_T_DOUBLE);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Multi_Move, "fy", fy, EET_T_DOUBLE);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_efl_event_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Efl_Event);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Efl_Event, "wdg_name", wdg_name, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Efl_Event, "event_name", event_name, EET_T_STRING);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_click_on_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action_Click_On);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_d, Exactness_Action_Click_On, "wdg_name", wdg_name, EET_T_STRING);
+
+ return _d;
+}
+
+static Eet_Data_Descriptor *
+_dummy_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ Eet_Data_Descriptor *_d;
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, _Dummy);
+ _d = eet_data_descriptor_stream_new(&eddc);
+
+ return _d;
+}
+
+/* !!! SAME ORDER AS Exactness_Action_Type */
+static const char *_mapping[] =
+{
+ "",
+ "exactness_action_mouse_in",
+ "exactness_action_mouse_out",
+ "exactness_action_mouse_wheel",
+ "exactness_action_multi_down",
+ "exactness_action_multi_up",
+ "exactness_action_multi_move",
+ "exactness_action_key_down",
+ "exactness_action_key_up",
+ "exactness_action_take_shot",
+ "exactness_action_efl_event",
+ "exactness_action_click_on",
+ "exactness_action_stabilize"
+};
+
+const char *
+_exactness_action_type_to_string_get(Exactness_Action_Type type)
+{
+ if (type <= EXACTNESS_ACTION_LAST) return _mapping[type];
+ return NULL;
+}
+
+static const char *
+_variant_type_get(const void *data, Eina_Bool *unknow)
+{
+ const Exactness_Action *act = data;
+
+ if (unknow) *unknow = EINA_FALSE;
+ if (act->type <= EXACTNESS_ACTION_LAST) return _mapping[act->type];
+
+ return NULL;
+}
+
+static Eina_Bool
+_variant_type_set(const char *type,
+ void *data,
+ Eina_Bool unknow EINA_UNUSED)
+{
+ int i;
+ Exactness_Action *act = data;
+ for (i = 0; i <= EXACTNESS_ACTION_LAST; i++)
+ {
+ if (!strcmp(_mapping[i], type)) act->type = i;
+ }
+ return EINA_TRUE;
+}
+
+static Eet_Data_Descriptor *
+_unit_desc_make(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+ static Eet_Data_Descriptor *unit_d = NULL;
+ static Eet_Data_Descriptor *action_d = NULL, *action_variant_d = NULL;
+ static Eet_Data_Descriptor *objs_d = NULL;
+ static Eet_Data_Descriptor *obj_d = NULL;
+ if (!obj_d)
+ {
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Object);
+ obj_d = eet_data_descriptor_stream_new(&eddc);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "kl_name", kl_name, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "id", id, EET_T_ULONG_LONG);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "parent_id", parent_id, EET_T_ULONG_LONG);
+ /* Evas stuff */
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "x", x, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "y", y, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "w", w, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(obj_d, Exactness_Object, "h", h, EET_T_INT);
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Objects);
+ objs_d = eet_data_descriptor_stream_new(&eddc);
+ EET_DATA_DESCRIPTOR_ADD_LIST(objs_d, Exactness_Objects, "objs", objs, obj_d);
+ }
+ if (!unit_d)
+ {
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Action);
+ action_d = eet_data_descriptor_stream_new(&eddc);
+
+ eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
+ eddc.func.type_get = _variant_type_get;
+ eddc.func.type_set = _variant_type_set;
+ action_variant_d = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MOUSE_IN], _dummy_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MOUSE_OUT], _dummy_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MOUSE_WHEEL], _mouse_wheel_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MULTI_DOWN], _multi_event_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MULTI_UP], _multi_event_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_MULTI_MOVE], _multi_move_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_KEY_DOWN], _key_down_up_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_KEY_UP], _key_down_up_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_TAKE_SHOT], _dummy_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_EFL_EVENT], _efl_event_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_CLICK_ON], _click_on_desc_make());
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(action_variant_d,
+ _mapping[EXACTNESS_ACTION_STABILIZE], _dummy_desc_make());
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(action_d, Exactness_Action, "n_evas", n_evas, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(action_d, Exactness_Action, "delay_ms", delay_ms, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_VARIANT(action_d, Exactness_Action, "data", data, type, action_variant_d);
+
+ /* Exactness_Unit */
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Exactness_Unit);
+ unit_d = eet_data_descriptor_stream_new(&eddc);
+ EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "actions", actions, action_d);
+ EET_DATA_DESCRIPTOR_ADD_LIST(unit_d, Exactness_Unit, "objs", objs, objs_d);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "fonts_path", fonts_path, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(unit_d, Exactness_Unit, "nb_shots", nb_shots, EET_T_UINT);
+ }
+
+ return unit_d;
+}
+/* END Event struct descriptors */
+
+Exactness_Unit *
+exactness_unit_file_read(const char *filename)
+{
+ int i;
+ Eina_List *itr, *itr2;
+ Exactness_Objects *e_objs;
+ Exactness_Object *e_obj, *e_parent;
+ Exactness_Unit *unit = NULL;
+ Eet_File *file;
+ eet_init();
+ file = eet_open(filename, EET_FILE_MODE_READ);
+ if (!file)
+ {
+ fprintf(stderr, "Impossible to extract EET from %s\n", filename);
+ return NULL;
+ }
+ unit = eet_data_read(file, _unit_desc_make(), "cache");
+ for (i = 0; i < unit->nb_shots; i++)
+ {
+ char entry[32];
+ Exactness_Image *ex_img = malloc(sizeof(*ex_img));
+ sprintf(entry, "images/%d", i + 1);
+ ex_img->pixels = eet_data_image_read(file, entry,
+ &ex_img->w, &ex_img->h, NULL,
+ NULL, NULL, NULL);
+ unit->imgs = eina_list_append(unit->imgs, ex_img);
+ }
+ EINA_LIST_FOREACH(unit->objs, itr, e_objs)
+ {
+ Eina_Hash *hash = eina_hash_pointer_new(NULL);
+ EINA_LIST_FOREACH(e_objs->objs, itr2, e_obj)
+ {
+ eina_hash_set(hash, &(e_obj->id), e_obj);
+ }
+ EINA_LIST_FOREACH(e_objs->objs, itr2, e_obj)
+ {
+ if (!e_obj->parent_id)
+ e_objs->main_objs = eina_list_append(e_objs->main_objs, e_obj);
+ else
+ {
+ e_parent = eina_hash_find(hash, &(e_obj->parent_id));
+ if (e_parent) e_parent->children = eina_list_append(e_parent->children, e_obj);
+ }
+ }
+ eina_hash_free(hash);
+ }
+ eet_close(file);
+ eet_shutdown();
+ return unit;
+}
+
+Eina_Bool
+exactness_unit_file_write(Exactness_Unit *unit, const char *filename)
+{
+ Eina_List *itr;
+ Exactness_Image *ex_img;
+ Eet_File *file;
+ int i = 1;
+ int bytes;
+ Eina_Bool ret = EINA_TRUE;
+
+ eet_init();
+ file = eet_open(filename, EET_FILE_MODE_WRITE);
+ eet_data_write(file, _unit_desc_make(), "cache", unit, EINA_TRUE);
+ EINA_LIST_FOREACH(unit->imgs, itr, ex_img)
+ {
+ char entry[32];
+ sprintf(entry, "images/%d", i++);
+ bytes = eet_data_image_write(file, entry, ex_img->pixels, ex_img->w, ex_img->h, 0xFF,
+ 0, 100, EET_IMAGE_LOSSLESS);
+ if (bytes == 0)
+ {
+ ret = EINA_FALSE;
+ break;
+ }
+ }
+ eet_close(file);
+ eet_shutdown();
+ return ret;
+}
+
+Eina_Bool
+exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **imgO)
+{
+ unsigned int w, h;
+ int *pxs1, *pxs2, *pxsO = NULL;
+ unsigned int w1 = img1 ? img1->w : 0, h1 = img1 ? img1->h : 0;
+ unsigned int w2 = img2 ? img2->w : 0, h2 = img2 ? img2->h : 0;
+ unsigned int wO = MAX(w1, w2);
+ unsigned int hO = MAX(h1, h2);
+ Eina_Bool ret = EINA_FALSE;
+ if (imgO) *imgO = NULL;
+ if (!wO || !hO) return EINA_FALSE;
+
+ pxs1 = img1 ? img1->pixels : NULL;
+ pxs2 = img2 ? img2->pixels : NULL;
+ if (imgO) pxsO = malloc(wO * hO * 4);
+
+ for (w = 0; w < wO; w++)
+ {
+ for (h = 0; h < hO; h++)
+ {
+ Eina_Bool valid1 = img1 ? w < w1 && h < h1 : EINA_FALSE;
+ Eina_Bool valid2 = img2 ? w < w2 && h < h2 : EINA_FALSE;
+ int px1 = valid1 ? pxs1[h * w1 + w] : 0;
+ int px2 = valid2 ? pxs2[h * w2 + w] : 0;
+ int r1 = (px1 & 0x00FF0000) >> 16;
+ int r2 = (px2 & 0x00FF0000) >> 16;
+ int g1 = (px1 & 0x0000FF00) >> 8;
+ int g2 = (px2 & 0x0000FF00) >> 8;
+ int b1 = (px1 & 0x000000FF);
+ int b2 = (px2 & 0x000000FF);
+ int new_r, new_g, new_b;
+ if (valid1 || valid2)
+ {
+ if (px1 != px2)
+ {
+ new_r = 0xFF;
+ new_g = ((g1 + g2) >> 1) >> 2;
+ new_b = ((b1 + b2) >> 1) >> 2;
+ ret = EINA_TRUE;
+ }
+ else
+ {
+ new_r = (((r1 + r2) >> 1) >> 2) + 0xC0;
+ new_g = (((g1 + g2) >> 1) >> 2) + 0xC0;
+ new_b = (((b1 + b2) >> 1) >> 2) + 0xC0;
+ }
+ }
+ else
+ {
+ new_r = new_g = new_b = 0x0;
+ }
+ if (pxsO) pxsO[h * wO + w] = 0xFF000000 | new_r << 16 | new_g << 8 | new_b;
+ }
+ }
+ if (imgO)
+ {
+ Exactness_Image *imgR = calloc(1, sizeof(Exactness_Image));
+ *imgO = imgR;
+ imgR->w = wO;
+ imgR->h = hO;
+ imgR->pixels = pxsO;
+ }
+ return ret;
+}
+
+void exactness_image_free(Exactness_Image *img)
+{
+ if (!img) return;
+ free(img->pixels);
+ free(img);
+}
diff --git a/src/bin/exactness/common.h b/src/bin/exactness/common.h
new file mode 100644
index 0000000000..8654fb9449
--- /dev/null
+++ b/src/bin/exactness/common.h
@@ -0,0 +1,269 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Eet.h>
+#include <Evas.h>
+#include <Elementary.h>
+
+typedef struct
+{
+ Eina_Debug_Session *session;
+ int srcid;
+ void *buffer;
+ unsigned int size;
+} _Main_Loop_Info;
+
+#define WRAPPER_TO_XFER_MAIN_LOOP(foo) \
+static void \
+_intern_main_loop ## foo(void *data) \
+{ \
+ _Main_Loop_Info *info = data; \
+ _main_loop ## foo(info->session, info->srcid, info->buffer, info->size); \
+ free(info->buffer); \
+ free(info); \
+} \
+static Eina_Bool \
+foo(Eina_Debug_Session *session, int srcid, void *buffer, int size) \
+{ \
+ _Main_Loop_Info *info = calloc(1, sizeof(*info)); \
+ info->session = session; \
+ info->srcid = srcid; \
+ info->size = size; \
+ if (info->size) \
+ { \
+ info->buffer = malloc(info->size); \
+ memcpy(info->buffer, buffer, info->size); \
+ } \
+ ecore_main_loop_thread_safe_call_async(_intern_main_loop ## foo, info); \
+ return EINA_TRUE; \
+}
+
+#ifndef WORDS_BIGENDIAN
+#define SWAP_64(x) x
+#define SWAP_32(x) x
+#define SWAP_16(x) x
+#define SWAP_DBL(x) x
+#else
+#define SWAP_64(x) eina_swap64(x)
+#define SWAP_32(x) eina_swap32(x)
+#define SWAP_16(x) eina_swap16(x)
+#define SWAP_DBL(x) SWAP_64(x)
+#endif
+
+#define EXTRACT_INT(_buf) \
+({ \
+ int __i; \
+ memcpy(&__i, _buf, sizeof(int)); \
+ _buf += sizeof(int); \
+ SWAP_32(__i); \
+})
+
+#define EXTRACT_DOUBLE(_buf) \
+({ \
+ double __d; \
+ memcpy(&__d, _buf, sizeof(double)); \
+ _buf += sizeof(double); \
+ SWAP_DBL(__d); \
+})
+
+#define EXTRACT_STRING(_buf) \
+({ \
+ char *__s = _buf ? strdup(_buf) : NULL; \
+ int __len = (__s ? strlen(__s) : 0) + 1; \
+ _buf += __len; \
+ __s; \
+})
+
+#define STORE_INT(_buf, __i) \
+({ \
+ int __si = SWAP_32(__i); \
+ memcpy(_buf, &__si, sizeof(int)); \
+ _buf += sizeof(int); \
+})
+
+#define STORE_DOUBLE(_buf, __d) \
+{ \
+ double __d2 = SWAP_DBL(__d); \
+ memcpy(_buf, &__d2, sizeof(double)); \
+ _buf += sizeof(double); \
+}
+
+#define STORE_STRING(_buf, __s) \
+{ \
+ int __len = (__s ? strlen(__s) : 0) + 1; \
+ if (__s) memcpy(_buf, __s, __len); \
+ else *_buf = '\0'; \
+ _buf += __len; \
+}
+
+#define SHOT_DELIMITER '+'
+
+/**
+ * The type values for an Exactness action.
+ */
+typedef enum
+{
+ EXACTNESS_ACTION_UNKNOWN = 0,
+ EXACTNESS_ACTION_MOUSE_IN,
+ EXACTNESS_ACTION_MOUSE_OUT,
+ EXACTNESS_ACTION_MOUSE_WHEEL,
+ EXACTNESS_ACTION_MULTI_DOWN,
+ EXACTNESS_ACTION_MULTI_UP,
+ EXACTNESS_ACTION_MULTI_MOVE,
+ EXACTNESS_ACTION_KEY_DOWN,
+ EXACTNESS_ACTION_KEY_UP,
+ EXACTNESS_ACTION_TAKE_SHOT,
+ EXACTNESS_ACTION_EFL_EVENT,
+ EXACTNESS_ACTION_CLICK_ON,
+ EXACTNESS_ACTION_STABILIZE,
+ EXACTNESS_ACTION_LAST = EXACTNESS_ACTION_STABILIZE
+ /* Add any supported actions here and update _LAST */
+} Exactness_Action_Type;
+
+/**
+ * The type for the Exactness Mouse Wheel action.
+ */
+typedef struct
+{
+ int direction;
+ int z;
+} Exactness_Action_Mouse_Wheel;
+
+/**
+ * The type for the Exactness Key Down Up action.
+ */
+typedef struct
+{
+ const char *keyname;
+ const char *key;
+ const char *string;
+ const char *compose;
+ unsigned int keycode;
+} Exactness_Action_Key_Down_Up;
+
+/**
+ * The type for the Exactness Multi Event action.
+ */
+typedef struct
+{
+ int d;
+ int b; /* In case of simple mouse down/up, corresponds to the button */
+ int x;
+ int y;
+ double rad;
+ double radx;
+ double rady;
+ double pres;
+ double ang;
+ double fx;
+ double fy;
+ Evas_Button_Flags flags;
+} Exactness_Action_Multi_Event;
+
+/**
+ * The type for the Exactness Multi Move action.
+ */
+typedef struct
+{
+ int d;
+ int x;
+ int y;
+ double rad;
+ double radx;
+ double rady;
+ double pres;
+ double ang;
+ double fx;
+ double fy;
+} Exactness_Action_Multi_Move;
+
+/**
+ * The type for the Exactness EFL Event action.
+ */
+typedef struct
+{
+ char *wdg_name; /**< Name of the widget */
+ char *event_name; /**< Name of the event */
+} Exactness_Action_Efl_Event;
+
+/**
+ * The type for the Exactness Click on (widget) action.
+ */
+typedef struct
+{
+ char *wdg_name; /**< Name of the widget */
+} Exactness_Action_Click_On;
+
+/**
+ * The type for the Exactness action.
+ */
+typedef struct
+{
+ Exactness_Action_Type type; /**< The action type */
+ unsigned int n_evas; /**< The evas number on which the action has to be applied */
+ unsigned int delay_ms; /**< The delay (in ms) to wait for this action */
+ void *data; /**< The specific action data */
+} Exactness_Action;
+
+/**
+ * The type for the Exactness object.
+ */
+typedef struct
+{
+ long long id; /**< The Eo pointer */
+ long long parent_id; /**< The Eo parent pointer */
+ const char *kl_name; /**< The class name */
+
+ Eina_List *children; /* NOT EET */
+
+ /* Evas stuff */
+ int x; /**< The X coordinate */
+ int y; /**< The Y coordinate */
+ int w; /**< The object width */
+ int h; /**< The object height */
+} Exactness_Object;
+
+/**
+ * The type for the Exactness objects list.
+ */
+typedef struct
+{
+ Eina_List *objs; /**< List of all the objects */
+ /* main_objs not in EET */
+ Eina_List *main_objs; /**< List of the main objects */
+} Exactness_Objects;
+
+/**
+ * The type for the Exactness Image.
+ */
+typedef struct
+{
+ unsigned int w; /**< Width of the image */
+ unsigned int h; /**< Height of the image */
+ void *pixels; /**< Pixels of the image */
+} Exactness_Image;
+
+/**
+ * An Exactness test unit, including the list of tested actions and produced images.
+ */
+typedef struct
+{
+ Eina_List *actions; /**< List of Exactness_Action */
+ /* imgs not in EET */
+ Eina_List *imgs; /**< List of Exactness_Image */
+ Eina_List *objs; /**< List of Exactness_Objects */
+ const char *fonts_path; /**< Path to the fonts to use, relative to the fonts dir given in parameter to the player/recorder */
+ int nb_shots; /**< The number of shots present in the unit */
+} Exactness_Unit;
+
+const char *_exactness_action_type_to_string_get(Exactness_Action_Type type);
+
+Eina_Bool ex_is_original_app(void);
+void ex_set_original_envvar(void);
+Eina_Bool exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **diff_img);
+Exactness_Unit *exactness_unit_file_read(const char *filename);
+Eina_Bool exactness_unit_file_write(Exactness_Unit *unit, const char *filename);
+void exactness_image_free(Exactness_Image *img);
+
+void ex_prepare_elm_overlay(void);
diff --git a/src/bin/exactness/exactness.c b/src/bin/exactness/exactness.c
new file mode 100644
index 0000000000..ee62cbd33f
--- /dev/null
+++ b/src/bin/exactness/exactness.c
@@ -0,0 +1,707 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <Ecore_Evas.h>
+#include <Ecore_File.h>
+
+#include "common.h"
+
+#ifdef _WIN32
+# include <evil_private.h> /* mkdir */
+#endif
+
+#define SCHEDULER_CMD_SIZE 1024
+
+#define ORIG_SUBDIR "orig"
+#define CURRENT_SUBDIR "current"
+
+#define BUF_SIZE 1024
+
+#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__)
+#define CRI(...) EINA_LOG_DOM_CRIT(_log_domain, __VA_ARGS__)
+
+static int _log_domain = -1;
+
+typedef struct
+{
+ EINA_INLIST;
+ char *name;
+ const char *command;
+ double start_time;
+} List_Entry;
+
+typedef enum
+{
+ RUN_SIMULATION,
+ RUN_PLAY,
+ RUN_INIT
+} Run_Mode;
+
+static unsigned short _running_jobs = 0, _max_jobs = 1;
+static Eina_List *_base_dirs = NULL;
+static char *_dest_dir;
+static char *_wrap_command = NULL, *_fonts_dir = NULL;
+static int _verbose = 0;
+static Eina_Bool _scan_objs = EINA_FALSE, _disable_screenshots = EINA_FALSE, _stabilize_shots = EINA_FALSE;
+
+static Run_Mode _mode;
+static List_Entry *_next_test_to_run = NULL;
+static unsigned int _tests_executed = 0;
+
+static Eina_List *_errors;
+static Eina_List *_compare_errors;
+
+static Eina_Bool _job_consume();
+
+static Exactness_Image *
+_image_load(const char *filename)
+{
+ int w, h;
+ Evas_Load_Error err;
+ Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
+ Eo *e = ecore_evas_get(ee);
+
+ Eo *img = evas_object_image_add(e);
+ evas_object_image_file_set(img, filename, NULL);
+ err = evas_object_image_load_error_get(img);
+ if (err != EVAS_LOAD_ERROR_NONE)
+ {
+ CRI("Failed to load image");
+ return NULL;
+ }
+
+ Exactness_Image *ex_img = malloc(sizeof(*ex_img));
+ int len;
+ evas_object_image_size_get(img, &w, &h);
+ ex_img->w = w;
+ ex_img->h = h;
+ len = w * h * 4;
+ ex_img->pixels = malloc(len);
+ memcpy(ex_img->pixels, evas_object_image_data_get(img, EINA_FALSE), len);
+
+ ecore_evas_free(ee);
+ return ex_img;
+}
+
+static Eina_Bool
+_image_save(Exactness_Image *ex_img, const char *output)
+{
+ Ecore_Evas *ee;
+ Eo *e, *img;
+ Eina_Bool ret = EINA_TRUE;
+ ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
+ e = ecore_evas_get(ee);
+ img = evas_object_image_add(e);
+ evas_object_image_size_set(img, ex_img->w, ex_img->h);
+ evas_object_image_data_set(img, ex_img->pixels);
+ if (!evas_object_image_save(img, output, NULL, NULL))
+ ret = EINA_FALSE;
+ ecore_evas_free(ee);
+ return ret;
+}
+
+static Eina_Bool
+_file_compare(const char *orig_dir, const char *ent_name)
+{
+ Eina_Bool result = EINA_FALSE;
+ Exactness_Image *img1, *img2, *imgO = NULL;
+ char *filename1 = alloca(strlen(orig_dir) + strlen(ent_name) + 20);
+ char *filename2 = alloca(strlen(_dest_dir) + strlen(ent_name) + 20);
+ sprintf(filename1, "%s/%s", orig_dir, ent_name);
+ sprintf(filename2, "%s/%s/%s", _dest_dir, CURRENT_SUBDIR, ent_name);
+
+ img1 = _image_load(filename1);
+ img2 = _image_load(filename2);
+
+ if (exactness_image_compare(img1, img2, &imgO))
+ {
+ char *buf = alloca(strlen(_dest_dir) + strlen(ent_name));
+ sprintf(buf, "%s/%s/comp_%s", _dest_dir, CURRENT_SUBDIR, ent_name);
+ if (!_image_save(imgO, buf))
+ goto cleanup;
+ _compare_errors = eina_list_append(_compare_errors, strdup(ent_name));
+ result = EINA_TRUE;
+ }
+cleanup:
+ exactness_image_free(img1);
+ exactness_image_free(img2);
+ exactness_image_free(imgO);
+ return result;
+}
+
+static void
+_exu_imgs_unpack(const char *exu_path, const char *dir, const char *ent_name)
+{
+ Exactness_Unit *unit = exactness_unit_file_read(exu_path);
+ Exactness_Image *img;
+ Eina_List *itr;
+ Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
+ Eo *e = ecore_evas_get(ee);
+ int n = 1;
+ if (!unit) return;
+ EINA_LIST_FOREACH(unit->imgs, itr, img)
+ {
+ Eo *o = evas_object_image_add(e);
+ char *filename = alloca(strlen(dir) + strlen(ent_name) + 20);
+ snprintf(filename, PATH_MAX, "%s/%s%c%.3d.png",
+ dir, ent_name, SHOT_DELIMITER, n++);
+ evas_object_image_size_set(o, img->w, img->h);
+ evas_object_image_data_set(o, img->pixels);
+ if (!evas_object_image_save(o, filename, NULL, NULL))
+ {
+ printf("Cannot save widget to <%s>\n", filename);
+ }
+ efl_del(o);
+ }
+ ecore_evas_free(ee);
+}
+
+static void
+_run_test_compare(const List_Entry *ent)
+{
+ char *path = alloca(PATH_MAX);
+ char *origdir = alloca(strlen(_dest_dir) + 20);
+ const char *base_dir;
+ Eina_List *itr;
+ int n = 1, nb_fails = 0;
+ printf("STATUS %s: COMPARE\n", ent->name);
+ EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
+ {
+ sprintf(path, "%s/%s.exu", base_dir, ent->name);
+ if (ecore_file_exists(path))
+ {
+ char *currentdir;
+ sprintf(origdir, "%s/%s/%s", _dest_dir, CURRENT_SUBDIR, ORIG_SUBDIR);
+ if (!ecore_file_exists(origdir))
+ {
+ if (mkdir(origdir, 0744) < 0)
+ {
+ CRI("Failed to create dir %s\n", origdir);
+ return;
+ }
+ }
+ _exu_imgs_unpack(path, origdir, ent->name);
+ sprintf(path, "%s/%s/%s.exu", _dest_dir, CURRENT_SUBDIR, ent->name);
+ currentdir = alloca(strlen(_dest_dir) + 20);
+ sprintf(currentdir, "%s/%s", _dest_dir, CURRENT_SUBDIR);
+ _exu_imgs_unpack(path, currentdir, ent->name);
+ goto found;
+ }
+ }
+found:
+ do
+ {
+ sprintf(path, "%s/%s%c%.3d.png", origdir, ent->name, SHOT_DELIMITER, n);
+ if (ecore_file_exists(path))
+ {
+ sprintf(path, "%s%c%.3d.png", ent->name, SHOT_DELIMITER, n);
+ if (_file_compare(origdir, path)) nb_fails++;
+ }
+ else break;
+ n++;
+ } while (EINA_TRUE);
+ if (!nb_fails)
+ {
+ double runtime = ecore_time_get() - ent->start_time;
+ printf("STATUS %s: END - SUCCESS (time: %.2fs)\n", ent->name, runtime);
+ }
+ else
+ printf("STATUS %s: END - FAIL (%d/%d)\n", ent->name, nb_fails, n - 1);
+}
+
+#define CONFIG "ELM_SCALE=1 ELM_FINGER_SIZE=10 "
+static Eina_Bool
+_run_command_prepare(List_Entry *ent, char *buf)
+{
+ char scn_path[PATH_MAX];
+ Eina_Strbuf *sbuf;
+ const char *base_dir;
+ Eina_List *itr;
+ EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
+ {
+ sprintf(scn_path, "%s/%s.exu", base_dir, ent->name);
+ if (ecore_file_exists(scn_path)) goto ok;
+ }
+ CRI("Test %s not found in the provided base directories\n", ent->name);
+ return EINA_FALSE;
+ok:
+ sbuf = eina_strbuf_new();
+ printf("STATUS %s: START\n", ent->name);
+ ent->start_time = ecore_time_get();
+ eina_strbuf_append_printf(sbuf,
+ "%s exactness_play %s %s%s %s%.*s %s%s%s-t '%s' ",
+ _wrap_command ? _wrap_command : "",
+ _mode == RUN_SIMULATION ? "-s" : "",
+ _fonts_dir ? "-f " : "", _fonts_dir ? _fonts_dir : "",
+ _verbose ? "-" : "", _verbose, "vvvvvvvvvv",
+ _scan_objs ? "--scan-objects " : "",
+ _disable_screenshots ? "--disable-screenshots " : "",
+ _stabilize_shots ? "--stabilize-shots " : "",
+ scn_path
+ );
+
+ if (_mode == RUN_PLAY)
+ eina_strbuf_append_printf(sbuf, "-o '%s/%s/%s.exu' ", _dest_dir, CURRENT_SUBDIR, ent->name);
+ if (_mode == RUN_INIT)
+ eina_strbuf_append_printf(sbuf, "-o '%s' ", scn_path);
+
+ if (ent->command)
+ {
+ eina_strbuf_append(sbuf, "-- ");
+ eina_strbuf_append(sbuf, CONFIG);
+ eina_strbuf_append(sbuf, ent->command);
+ }
+ strncpy(buf, eina_strbuf_string_get(sbuf), SCHEDULER_CMD_SIZE-1);
+ eina_strbuf_free(sbuf);
+ printf("Command: %s\n", buf);
+ return EINA_TRUE;
+}
+
+static void
+_job_compare(void *data)
+{
+ _run_test_compare(data);
+
+ _running_jobs--;
+ _job_consume();
+ /* If all jobs are done. */
+ if (!_running_jobs) ecore_main_loop_quit();
+}
+
+static Eina_Bool
+_job_deleted_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_Exe_Event_Del *msg = (Ecore_Exe_Event_Del *) event;
+ List_Entry *ent = ecore_exe_data_get(msg->exe);
+
+ if ((msg->exit_code != 0) || (msg->exit_signal != 0))
+ {
+ _errors = eina_list_append(_errors, ent);
+ }
+
+ if (_mode == RUN_PLAY)
+ {
+ ecore_job_add(_job_compare, ent);
+ }
+ else
+ {
+ _running_jobs--;
+ _job_consume();
+ if (!_running_jobs) ecore_main_loop_quit();
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_job_consume()
+{
+ static Ecore_Event_Handler *job_del_callback_handler = NULL;
+ char buf[SCHEDULER_CMD_SIZE];
+ List_Entry *ent = _next_test_to_run;
+
+ if (_running_jobs == _max_jobs) return EINA_FALSE;
+ if (!ent) return EINA_FALSE;
+
+ if (_run_command_prepare(ent, buf))
+ {
+ _running_jobs++;
+ _tests_executed++;
+
+ if (!job_del_callback_handler)
+ {
+ job_del_callback_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+ _job_deleted_cb, NULL);
+ }
+
+ if (!ecore_exe_pipe_run(buf, ECORE_EXE_TERM_WITH_PARENT, ent))
+ {
+ CRI("Failed executing test '%s'\n", ent->name);
+ }
+ }
+ _next_test_to_run = EINA_INLIST_CONTAINER_GET(
+ EINA_INLIST_GET(ent)->next, List_Entry);
+
+
+ return EINA_TRUE;
+}
+
+static void
+_scheduler_run()
+{
+ while (_job_consume());
+}
+
+static List_Entry *
+_list_file_load(const char *filename)
+{
+ List_Entry *ret = NULL;
+ char buf[BUF_SIZE] = "";
+ FILE *file;
+ file = fopen(filename, "r");
+ if (!file)
+ {
+ perror("Failed opening list file");
+ return NULL;
+ }
+
+ while (fgets(buf, BUF_SIZE, file))
+ {
+ /* Skip comment/empty lines. */
+ if ((*buf == '#') || (*buf == '\n') || (!*buf))
+ continue;
+
+ char *tmp;
+ List_Entry *cur = calloc(1, sizeof(*cur));
+ cur->name = strdup(buf);
+
+ /* Set the command to the second half and put a \0 in between. */
+ tmp = strchr(cur->name, ' ');
+ if (tmp)
+ {
+ *tmp = '\0';
+ cur->command = tmp + 1;
+ }
+ else
+ {
+ /* FIXME: error. */
+ cur->command = "";
+ }
+
+ /* Replace the newline char with a \0. */
+ tmp = strchr(cur->command, '\n');
+ if (tmp)
+ {
+ *tmp = '\0';
+ }
+
+ ret = EINA_INLIST_CONTAINER_GET(
+ eina_inlist_append(EINA_INLIST_GET(ret), EINA_INLIST_GET(cur)),
+ List_Entry);
+ }
+
+ fclose(file);
+ return ret;
+}
+
+static void
+_list_file_free(List_Entry *list)
+{
+ while (list)
+ {
+ List_Entry *ent = list;
+ list = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(list)->next,
+ List_Entry);
+
+ free(ent->name);
+ free(ent);
+ /* we don't free ent->command because it's allocated together. */
+ }
+}
+
+static int
+_errors_sort_cb(List_Entry *a, List_Entry *b)
+{
+ return strcmp(a->name, b->name);
+}
+
+static const Ecore_Getopt optdesc = {
+ "exactness",
+ "%prog [options] <-p|-i|-s> <test list file>",
+ PACKAGE_VERSION,
+ "(C) 2013-2020 Enlightenment",
+ "BSD",
+ "A pixel-perfect test suite for EFL-based applications.\n"
+ "\n"
+ "This binary allows running the individual tools `exactness_record` and\n"
+ "`exactness_play` in batch for a set of tests specified in a test list file.\n"
+ "\n"
+ "To obtain the reference templates (the \"golden\" files):\n"
+ "1.For each tested application, run `exactness_record` to launch the\n"
+ " application and record actions like keystrokes and mouse clicks.\n"
+ " This produces a test file with `.exu` extension.\n"
+ "2.Run `exactness` in init mode (-i) to execute the stored actions in all\n"
+ " the tests in the test list file and obtain screenshots.\n"
+ " The screenshots are embedded into the test `.exu` file.\n"
+ "\n"
+ "To check if the application currently matches the reference templates:\n"
+ "1.Run `exactness` in play mode (-p) to execute the stored actions in all\n"
+ " the tests in the test list file and compare the obtained screenshots\n"
+ " with the stored versions (the reference templates).\n"
+ " If mismatches are detected an error report is produced, including\n"
+ " a graphical diff of the screenshots.\n"
+ "\n"
+ "The test list file contains one line per test. Each line starts with the\n"
+ "test file name (without the `.exu` extension), a space and then the command\n"
+ "to execute, including parameters if any. # indicates a comment.\n"
+ "Example:\n"
+ "separator elementary_test -to Separator",
+ 0,
+ {
+ ECORE_GETOPT_APPEND('b', "base-dir", "The location of the exu files. Defaults to `./recordings/`.",
+ ECORE_GETOPT_TYPE_STR),
+ ECORE_GETOPT_STORE_STR('o', "output", "The location of the images. Defaults to `./`."),
+ ECORE_GETOPT_STORE_STR('w', "wrap", "Use a custom command to launch the tests (e.g valgrind)."),
+ ECORE_GETOPT_STORE_USHORT('j', "jobs", "The number of jobs to run in parallel. Defaults to 1."),
+ ECORE_GETOPT_STORE_TRUE('p', "play", "Run in play mode. Actions are executed and obtained "
+ "screenshots are compared to the stored version (golden templates)."),
+ ECORE_GETOPT_STORE_TRUE('i', "init", "Run in init mode. Actions are executed and obtained "
+ "screenshots are stored to be used as golden templates in the future."),
+ ECORE_GETOPT_STORE_TRUE('s', "simulation", "Run in simulation mode. Actions are executed and "
+ "displayed but no screenshot is obtained. Useful for debugging."),
+ ECORE_GETOPT_STORE_TRUE(0, "scan-objects", "Extract information of all the objects at every shot (UNUSED)."),
+ ECORE_GETOPT_STORE_TRUE(0, "disable-screenshots", "Disable screenshots. Only checks that actions "
+ "can be performed and the application does not crash."),
+ ECORE_GETOPT_STORE_STR('f', "fonts-dir", "Specify a directory of the fonts that should be used."),
+ ECORE_GETOPT_STORE_TRUE(0, "stabilize-shots", "Wait for the frames to be stable before taking the shots."),
+ ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
+
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_HELP('h', "help"),
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
+int
+main(int argc, char *argv[])
+{
+ int ret = 0;
+ List_Entry *test_list;
+ int args = 0;
+ const char *list_file;
+ Eina_List *itr;
+ const char *base_dir;
+ char tmp[PATH_MAX];
+ Eina_Bool mode_play = EINA_FALSE, mode_init = EINA_FALSE, mode_simulation = EINA_FALSE;
+ Eina_Bool want_quit = EINA_FALSE, scan_objs = EINA_FALSE;
+ Ecore_Getopt_Value values[] = {
+ ECORE_GETOPT_VALUE_LIST(_base_dirs),
+ ECORE_GETOPT_VALUE_STR(_dest_dir),
+ ECORE_GETOPT_VALUE_STR(_wrap_command),
+ ECORE_GETOPT_VALUE_USHORT(_max_jobs),
+ ECORE_GETOPT_VALUE_BOOL(mode_play),
+ ECORE_GETOPT_VALUE_BOOL(mode_init),
+ ECORE_GETOPT_VALUE_BOOL(mode_simulation),
+ ECORE_GETOPT_VALUE_BOOL(scan_objs),
+ ECORE_GETOPT_VALUE_BOOL(_disable_screenshots),
+ ECORE_GETOPT_VALUE_STR(_fonts_dir),
+ ECORE_GETOPT_VALUE_BOOL(_stabilize_shots),
+ ECORE_GETOPT_VALUE_INT(_verbose),
+
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_NONE
+ };
+
+ if (!ecore_evas_init())
+ return EXIT_FAILURE;
+
+ _log_domain = eina_log_domain_register("exactness", "red");
+ _dest_dir = "./";
+ _scan_objs = scan_objs;
+
+ eina_log_abort_on_critical_set(EINA_TRUE);
+ eina_log_abort_on_critical_level_set(EINA_LOG_LEVEL_ERR);
+
+ args = ecore_getopt_parse(&optdesc, values, argc, argv);
+ if (args < 0)
+ {
+ fprintf(stderr, "Failed parsing arguments.\n");
+ ret = 1;
+ goto end;
+ }
+ else if (want_quit)
+ {
+ ret = 1;
+ goto end;
+ }
+ else if (args == argc)
+ {
+ fprintf(stderr, "Expected test list file as the last argument..\n");
+ ecore_getopt_help(stderr, &optdesc);
+ ret = 1;
+ goto end;
+ }
+ else if (mode_play + mode_init + mode_simulation != 1)
+ {
+ fprintf(stderr, "Exactly one running mode must be set.\n");
+ ecore_getopt_help(stderr, &optdesc);
+ ret = 1;
+ goto end;
+ }
+
+ if (!_base_dirs) _base_dirs = eina_list_append(NULL, "./recordings");
+
+ list_file = argv[args];
+
+ /* Load the list file and start iterating over the records. */
+ test_list = _list_file_load(list_file);
+ _next_test_to_run = test_list;
+
+ if (!test_list)
+ {
+ fprintf(stderr, "No matching tests found in list file '%s'\n", list_file);
+ ret = 1;
+ goto end;
+ }
+
+ /* Pre-run summary */
+ fprintf(stderr, "Running with settings:\n");
+ fprintf(stderr, "\tConcurrent jobs: %d\n", _max_jobs);
+ fprintf(stderr, "\tTest list file: %s\n", list_file);
+ fprintf(stderr, "\tBase dirs:\n");
+ EINA_LIST_FOREACH(_base_dirs, itr, base_dir)
+ fprintf(stderr, "\t\t%s\n", base_dir);
+ fprintf(stderr, "\tDest dir: %s\n", _dest_dir);
+
+ if (mode_play)
+ {
+ _mode = RUN_PLAY;
+ if (snprintf(tmp, PATH_MAX, "%s/%s", _dest_dir, CURRENT_SUBDIR)
+ >= PATH_MAX)
+ {
+ fprintf(stderr, "Path too long: %s", tmp);
+ ret = 1;
+ goto end;
+ }
+ if (!ecore_file_exists(tmp))
+ {
+ if (mkdir(tmp, 0744) < 0)
+ {
+ fprintf(stderr, "Failed to create dir %s", tmp);
+ ret = 1;
+ goto end;
+ }
+ }
+ }
+ else if (mode_init)
+ {
+ _mode = RUN_INIT;
+ if (snprintf(tmp, PATH_MAX, "%s/%s", _dest_dir, ORIG_SUBDIR)
+ >= PATH_MAX)
+ {
+ fprintf(stderr, "Path too long: %s", tmp);
+ ret = 1;
+ goto end;
+ }
+ if (!ecore_file_exists(tmp))
+ {
+ if (mkdir(tmp, 0744) < 0)
+ {
+ fprintf(stderr, "Failed to create dir %s", tmp);
+ ret = 1;
+ goto end;
+ }
+ }
+ }
+ else if (mode_simulation)
+ {
+ _mode = RUN_SIMULATION;
+ }
+ _scheduler_run();
+
+
+ ecore_main_loop_begin();
+
+ /* Results */
+ printf("*******************************************************\n");
+ if (mode_play && EINA_FALSE)
+ {
+ List_Entry *list_itr;
+
+ EINA_INLIST_FOREACH(test_list, list_itr)
+ {
+ _run_test_compare(list_itr);
+ }
+ }
+
+ printf("Finished executing %u out of %u tests.\n",
+ _tests_executed,
+ eina_inlist_count(EINA_INLIST_GET(test_list)));
+ printf("%u tests executed\n", _tests_executed);
+ printf("%u tests had execution errors\n", eina_list_count(_errors));
+ printf("%u screenshots failed comparison\n", eina_list_count(_compare_errors));
+
+ /* Sort the errors and the compare_errors. */
+ _errors = eina_list_sort(_errors, 0, (Eina_Compare_Cb) _errors_sort_cb);
+ _compare_errors = eina_list_sort(_compare_errors, 0, (Eina_Compare_Cb) strcmp);
+
+ if (_errors || _compare_errors)
+ {
+ FILE *report_file;
+ char report_filename[PATH_MAX] = "";
+ /* Generate the filename. */
+ snprintf(report_filename, PATH_MAX,
+ "%s/%s/errors.html",
+ _dest_dir, mode_init ? ORIG_SUBDIR : CURRENT_SUBDIR);
+ report_file = fopen(report_filename, "w+");
+ if (report_file)
+ {
+ fprintf(report_file,
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>Exactness report</title></head><body>");
+
+ if (_errors)
+ {
+ fprintf(report_file,
+ "<h1>Tests that failed execution:</h1><ul>");
+ List_Entry *ent;
+ printf("List of tests that failed execution:\n");
+ EINA_LIST_FOREACH(_errors, itr, ent)
+ {
+ printf("\t* %s\n", ent->name);
+
+ fprintf(report_file, "<li>%s</li>", ent->name);
+ }
+ fprintf(report_file, "</ul>");
+ }
+
+ if (_compare_errors)
+ {
+ fprintf(report_file,
+ "<h1>Images that failed comparison: (Original, Current, Diff)</h1><ul>");
+ char *test_name;
+ printf("List of images that failed comparison:\n");
+ EINA_LIST_FREE(_compare_errors, test_name)
+ {
+ Eina_Bool is_from_exu;
+ char origpath[PATH_MAX];
+ snprintf(origpath, PATH_MAX, "%s/%s/orig/%s",
+ _dest_dir, CURRENT_SUBDIR, test_name);
+ is_from_exu = ecore_file_exists(origpath);
+ printf("\t* %s\n", test_name);
+
+ fprintf(report_file, "<li><h2>%s</h2> <img src='%sorig/%s' alt='Original' /> <img src='%s' alt='Current' /> <img src='comp_%s' alt='Diff' /></li>",
+ test_name, is_from_exu ? "" : "../",
+ test_name, test_name, test_name);
+ free(test_name);
+ }
+ fprintf(report_file, "</ul>");
+ }
+ fprintf(report_file,
+ "</body></html>");
+
+ printf("Report html: %s\n", report_filename);
+ ret = 1;
+ }
+ else
+ {
+ perror("Failed opening report file");
+ }
+ }
+
+ _list_file_free(test_list);
+end:
+ ecore_evas_shutdown();
+
+ return ret;
+}
diff --git a/src/bin/exactness/exactness_play.in b/src/bin/exactness/exactness_play.in
new file mode 100644
index 0000000000..38200d9ba1
--- /dev/null
+++ b/src/bin/exactness/exactness_play.in
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+
+import argparse
+import subprocess
+import os
+
+parser = argparse.ArgumentParser(description='A recorded scenario player for EFL-based applications.\n\n'
+ 'Actions recorded with `exactness_record` can be played back with this\n'
+ 'application and screenshots obtained. It is typically more convenient to\n'
+ 'use the `exactness` wrapper in "play" mode to process files in batches.',
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog='Example:\n'
+ 'exactness_play -s -t my_app.exu -- my_app --app --arguments')
+parser.add_argument('app', metavar='app', help='The app to run. You can also pass environment variables here. '
+ 'Use a -- if you need to provide arguments to the app.',
+ type=str, nargs='*')
+parser.add_argument('-o', '--output', metavar='output', help="Destination for the shots. "
+ "If a `.exu` file is given, the shots are stored in the file. "
+ "Otherwise the given path is considered as a directory "
+ "where shots will be stored. "
+ "If omitted, the output type (exu or dir) is determined "
+ "by the given test extension (resp. exu or rec).", type=str)
+parser.add_argument('-t', '--tests', metavar='tests', help='Name of the file where to store the test.', type=str)
+parser.add_argument('-s', '--show-on-screen', help='Show on screen', action='store_true', default=False)
+parser.add_argument('--scan-objects', help='Extract information of all the objects at every shot.', action='store_true')
+parser.add_argument('--external-injection', help='Expect events injection via Eina debug channel.', action='store_true')
+parser.add_argument('--disable-screenshots', help='Disable screenshots.', action='store_true')
+parser.add_argument('-f', '--fontsdir', metavar='fontsdir', help='Specify a directory of the fonts that should be used.', type=str)
+parser.add_argument('--stabilize-shots', help='Wait for the frames to be stable before taking the shots.', action='store_true')
+parser.add_argument('--speed', metavar='speed', help='Set the speed used to play the given test (default 1.0).', type=float, default=1.0)
+parser.add_argument('-v', '--verbose', help='Turn verbose messages on', action='store_true')
+parser.add_argument('-L', '--license', help='Print license information and exit.', action='store_true')
+parser.add_argument('-C', '--copyright', help='Print copyright information and exit.', action='store_true')
+parser.add_argument('-V', '--version', help='Print version information and exit.', action='store_true')
+
+G = parser.parse_args()
+
+if G.license:
+ print("BSD.")
+ exit(0)
+
+if G.copyright:
+ print("(C) 2017-2020 Enlightenment.")
+ exit(0)
+
+if G.version:
+ print(@VERSION@)
+ exit(0)
+
+spawn_env = os.environ.copy()
+spawn_env["LD_PRELOAD"] = @EXACTNESS_PLAY_PRELOAD_PATH@
+
+if G.tests == None and G.external_injection == True:
+ print("no test file specified")
+ exit(-1)
+if G.tests != None and G.external_injection == True:
+ print("Cannot inject events from a source file and from outside simultaneously")
+ exit(-1)
+if G.scan_objects == True and G.tests.endswith(".exu"):
+ printf("Scan objects options is available only if the destination is a EXU file")
+ exit(-1)
+
+if G.output != None:
+ spawn_env["EXACTNESS_DEST"] = G.output;
+if G.external_injection:
+ spawn_env["EXACTNESS_EXTERNAL_INJECTION"] = "Yes"
+if G.tests != None:
+ spawn_env["EXACTNESS_SRC"] = G.tests
+if G.fontsdir != None:
+ spawn_env["EXACTNESS_FONTS_DIR"] = G.fontsdir
+if G.speed != 1.0:
+ spawn_env["EXACTNESS_SPEED"] = G.speed
+if G.scan_objects:
+ spawn_env["EXACTNESS_SCAN_OBJECTS"] = "Yes"
+if G.disable_screenshots:
+ spawn_env["EXACTNESS_DISABLE_SHOTS"] = "Yes"
+if G.stabilize_shots:
+ spawn_env["EXACTNESS_STABILIZE_SHOTS"] = "Yes"
+if G.verbose:
+ spawn_env["EXACTNESS_VERBOSE"] = "Yes"
+if G.show_on_screen == False:
+ spawn_env["ELM_DISPLAY"] = "buffer"
+
+passed_all_the_env_vars = False
+app = []
+
+for argument in G.app:
+ if '=' not in argument:
+ passed_all_the_env_vars = True
+ else:
+ if passed_all_the_env_vars:
+ print("Error, env vars can only be specified at the beginning of the app call line")
+ exit(-1)
+ split_env_var = argument.split('=')
+ spawn_env[split_env_var[0]] = split_env_var[1]
+
+ if passed_all_the_env_vars:
+ app.append(argument)
+
+recorder = subprocess.Popen(app, env=spawn_env)
+recorder.wait()
diff --git a/src/bin/exactness/exactness_record.in b/src/bin/exactness/exactness_record.in
new file mode 100644
index 0000000000..377d465199
--- /dev/null
+++ b/src/bin/exactness/exactness_record.in
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+import argparse
+import subprocess
+import os
+
+parser = argparse.ArgumentParser(description='A scenario recorder for EFL-based applications.\n\n'
+ 'This records all actions the user performs on an EFL application (like keystrokes\n'
+ 'and mouse clicks) and stores them on a file.\n'
+ 'Later on, the `exactness` or `exactness_play` commands can be used to play\n'
+ 'back these actions and obtain screenshots.\n'
+ '\n'
+ 'While running this application, use the following keys to control the process:\n'
+ '\tF1 - Request stabilization.\n'
+ '\tF2 - Request screenshot.\n'
+ '\tF3 - Request to save the scenario.\n'
+ '\n'
+ 'Note: If you don\'t press F3 at least once, no output file will be generated.',
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog='Example:\n'
+ 'exactness_record -t my_app.exu -- my_app --app --arguments')
+parser.add_argument('app', metavar='app', help='The app to run. You can also pass environment variables here. '
+ 'Use a -- if you need to provide arguments to the app.',
+ type=str, nargs='*')
+parser.add_argument('-t', '--tests', metavar='tests', help='Name of the file where to store the test. '
+ 'It is recommended to use the `.exu` extension.', type=str)
+parser.add_argument('-f', '--fontsdir', metavar='fontsdir', help='Directory of the fonts that should be used.',
+ type=str)
+parser.add_argument('-L', '--license', help='Print license information and exit.', action='store_true')
+parser.add_argument('-C', '--copyright', help='Print copyright information and exit.', action='store_true')
+parser.add_argument('-V', '--version', help='Print version information and exit.', action='store_true')
+
+G = parser.parse_args()
+
+if G.license:
+ print("BSD.")
+ exit(0)
+
+if G.copyright:
+ print("(C) 2017-2020 Enlightenment.")
+ exit(0)
+
+if G.version:
+ print(@VERSION@)
+ exit(0)
+
+spawn_env = os.environ.copy()
+spawn_env["LD_PRELOAD"] = @EXACTNESS_RECORD_PRELOAD_PATH@
+
+if G.tests != None:
+ spawn_env["EXACTNESS_DEST"] = G.tests
+else:
+ print("Tests dir must be passed!")
+ exit(-1)
+
+if G.fontsdir != None:
+ spawn_env["EXACTNESS_FONTS_DIR"] = G.fontsdir
+
+passed_all_the_env_vars = False
+app = []
+
+for argument in G.app:
+ if '=' not in argument:
+ passed_all_the_env_vars = True
+ else:
+ if passed_all_the_env_vars:
+ print("Error, env vars can only be specified at the beginning of the app call line")
+ exit(-1)
+ split_env_var = argument.split('=')
+ spawn_env[split_env_var[0]] = split_env_var[1]
+
+ if passed_all_the_env_vars:
+ app.append(argument)
+
+recorder = subprocess.Popen(app, env=spawn_env)
+recorder.wait()
diff --git a/src/bin/exactness/injector.c b/src/bin/exactness/injector.c
new file mode 100644
index 0000000000..183a5112eb
--- /dev/null
+++ b/src/bin/exactness/injector.c
@@ -0,0 +1,393 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include <Eina.h>
+#include <Eet.h>
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <Elementary.h>
+
+#include "common.h"
+
+#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
+
+static int _log_domain = -1;
+
+static Eina_Stringshare *_src_filename = NULL;
+static Exactness_Unit *_src_unit = NULL;
+static int _verbose = 0;
+
+static Eina_Debug_Session *_session = NULL;
+static int _cid = -1, _pid = -1;
+static Eina_List *_cur_event_list = NULL;
+
+static int _all_apps_get_op = EINA_DEBUG_OPCODE_INVALID;
+static int _mouse_in_op = EINA_DEBUG_OPCODE_INVALID;
+static int _mouse_out_op = EINA_DEBUG_OPCODE_INVALID;
+static int _mouse_wheel_op = EINA_DEBUG_OPCODE_INVALID;
+static int _multi_down_op = EINA_DEBUG_OPCODE_INVALID;
+static int _multi_up_op = EINA_DEBUG_OPCODE_INVALID;
+static int _multi_move_op = EINA_DEBUG_OPCODE_INVALID;
+static int _key_down_op = EINA_DEBUG_OPCODE_INVALID;
+static int _key_up_op = EINA_DEBUG_OPCODE_INVALID;
+static int _take_shot_op = EINA_DEBUG_OPCODE_INVALID;
+static int _efl_event_op = EINA_DEBUG_OPCODE_INVALID;
+static int _click_on_op = EINA_DEBUG_OPCODE_INVALID;
+static int _stabilize_op = EINA_DEBUG_OPCODE_INVALID;
+static int _finish_op = EINA_DEBUG_OPCODE_INVALID;
+
+static Eina_Bool _all_apps_get_cb(Eina_Debug_Session *, int , void *, int);
+
+EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
+ {"Daemon/Client/register_observer", &_all_apps_get_op, NULL},
+ {"Daemon/Client/added", NULL, &_all_apps_get_cb},
+ {"Exactness/Actions/Mouse In", &_mouse_in_op, NULL},
+ {"Exactness/Actions/Mouse Out", &_mouse_out_op, NULL},
+ {"Exactness/Actions/Mouse Wheel", &_mouse_wheel_op, NULL},
+ {"Exactness/Actions/Multi Down", &_multi_down_op, NULL},
+ {"Exactness/Actions/Multi Up", &_multi_up_op, NULL},
+ {"Exactness/Actions/Multi Move", &_multi_move_op, NULL},
+ {"Exactness/Actions/Key Down", &_key_down_op, NULL},
+ {"Exactness/Actions/Key Up", &_key_up_op, NULL},
+ {"Exactness/Actions/Take Shot", &_take_shot_op, NULL},
+ {"Exactness/Actions/EFL Event", &_efl_event_op, NULL},
+ {"Exactness/Actions/Click On", &_click_on_op, NULL},
+ {"Exactness/Actions/Stabilize", &_stabilize_op, NULL},
+ {"Exactness/Actions/Finish", &_finish_op, NULL},
+ {NULL, NULL, NULL}
+ );
+
+static void
+_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data)
+{
+ switch (type)
+ {
+ case EXACTNESS_ACTION_MOUSE_IN:
+ {
+ INF("Mouse in\n");
+ DBG("%s evas_event_feed_mouse_in n_evas=<%d>\n", __func__, n_evas);
+ eina_debug_session_send(_session, _cid, _mouse_in_op, &n_evas, sizeof(int));
+ break;
+ }
+ case EXACTNESS_ACTION_MOUSE_OUT:
+ {
+ INF("Mouse out\n");
+ DBG("%s evas_event_feed_mouse_out n_evas=<%d>\n", __func__, n_evas);
+ eina_debug_session_send(_session, _cid, _mouse_out_op, &n_evas, sizeof(int));
+ break;
+ }
+ case EXACTNESS_ACTION_MOUSE_WHEEL:
+ {
+ Exactness_Action_Mouse_Wheel *t = data;
+ int len = 3*sizeof(int);
+ char *buf = malloc(len), *tmp = buf;
+ INF("Mouse wheel\n");
+ DBG("%s evas_event_feed_mouse_wheel n_evas=<%d>\n", __func__, n_evas);
+ STORE_INT(tmp, n_evas);
+ STORE_INT(tmp, t->direction);
+ STORE_INT(tmp, t->z);
+ eina_debug_session_send(_session, _cid, _mouse_wheel_op, buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_DOWN:
+ case EXACTNESS_ACTION_MULTI_UP:
+ {
+ Exactness_Action_Multi_Event *t = data;
+ int len = 5*sizeof(int)+7*sizeof(double)+sizeof(int);
+ char *buf = malloc(len), *tmp = buf;
+ DBG("%s %s n_evas=<%d>\n", __func__,
+ type == EXACTNESS_ACTION_MULTI_DOWN ? "evas_event_feed_multi_down" :
+ "evas_event_feed_multi_up", n_evas);
+ STORE_INT(tmp, n_evas);
+ STORE_INT(tmp, t->d);
+ STORE_INT(tmp, t->b);
+ STORE_INT(tmp, t->x);
+ STORE_INT(tmp, t->y);
+ STORE_DOUBLE(tmp, t->rad);
+ STORE_DOUBLE(tmp, t->radx);
+ STORE_DOUBLE(tmp, t->rady);
+ STORE_DOUBLE(tmp, t->pres);
+ STORE_DOUBLE(tmp, t->ang);
+ STORE_DOUBLE(tmp, t->fx);
+ STORE_DOUBLE(tmp, t->fy);
+ STORE_INT(tmp, t->flags);
+ eina_debug_session_send(_session, _cid,
+ type == EXACTNESS_ACTION_MULTI_DOWN ? _multi_down_op : _multi_up_op,
+ buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_MOVE:
+ {
+ Exactness_Action_Multi_Move *t = data;
+ int len = 4*sizeof(int)+7*sizeof(double);
+ char *buf = malloc(len), *tmp = buf;
+ DBG("%s evas_event_feed_multi_move n_evas=<%d>\n", __func__, n_evas);
+ STORE_INT(tmp, n_evas);
+ STORE_INT(tmp, t->d);
+ STORE_INT(tmp, t->x);
+ STORE_INT(tmp, t->y);
+ STORE_DOUBLE(tmp, t->rad);
+ STORE_DOUBLE(tmp, t->radx);
+ STORE_DOUBLE(tmp, t->rady);
+ STORE_DOUBLE(tmp, t->pres);
+ STORE_DOUBLE(tmp, t->ang);
+ STORE_DOUBLE(tmp, t->fx);
+ STORE_DOUBLE(tmp, t->fy);
+ eina_debug_session_send(_session, _cid, _multi_move_op, buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_KEY_DOWN:
+ case EXACTNESS_ACTION_KEY_UP:
+ {
+ Exactness_Action_Key_Down_Up *t = data;
+ int len = 2*sizeof(int) + 4 + 1;
+ len += t->keyname ? strlen(t->keyname) : 0;
+ len += t->key ? strlen(t->key) : 0;
+ len += t->string ? strlen(t->string) : 0;
+ len += t->compose ? strlen(t->compose) : 0;
+ char *buf = malloc(len), *tmp = buf;
+ DBG("%s %s n_evas=<%d>\n", __func__,
+ type == EXACTNESS_ACTION_KEY_DOWN ? "evas_event_feed_key_down " :
+ "evas_event_feed_key_up", n_evas);
+ STORE_INT(tmp, n_evas);
+ STORE_STRING(tmp, t->keyname);
+ STORE_STRING(tmp, t->key);
+ STORE_STRING(tmp, t->string);
+ STORE_STRING(tmp, t->compose);
+ STORE_INT(tmp, t->keycode);
+ eina_debug_session_send(_session, _cid,
+ type == EXACTNESS_ACTION_KEY_DOWN ? _key_down_op : _key_up_op,
+ buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_TAKE_SHOT:
+ {
+ DBG("%s take shot n_evas=<%d>\n", __func__, n_evas);
+ eina_debug_session_send(_session, _cid, _take_shot_op, &n_evas, sizeof(int));
+ break;
+ }
+ case EXACTNESS_ACTION_EFL_EVENT:
+ {
+ Exactness_Action_Efl_Event *t = data;
+ int len = 2;
+ len += t->wdg_name ? strlen(t->wdg_name) : 0;
+ len += t->event_name ? strlen(t->event_name) : 0;
+ char *buf = malloc(len), *tmp = buf;
+ DBG("%s %s\n", __func__, "EFL event");
+ STORE_STRING(tmp, t->wdg_name);
+ STORE_STRING(tmp, t->event_name);
+ eina_debug_session_send(_session, _cid, _efl_event_op, buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_CLICK_ON:
+ {
+ Exactness_Action_Click_On *t = data;
+ int len = 1;
+ len += t->wdg_name ? strlen(t->wdg_name) : 0;
+ char *buf = malloc(len), *tmp = buf;
+ DBG("%s %s\n", __func__, "Click On");
+ STORE_STRING(tmp, t->wdg_name);
+ eina_debug_session_send(_session, _cid, _click_on_op, buf, len);
+ free(buf);
+ break;
+ }
+ case EXACTNESS_ACTION_STABILIZE:
+ {
+ DBG("%s stabilize\n", __func__);
+ eina_debug_session_send(_session, _cid, _stabilize_op, NULL, 0);
+ break;
+ }
+ default: /* All non-input events are not handeled */
+ break;
+ }
+}
+
+static Eina_Bool
+_feed_event_timer_cb(void *data EINA_UNUSED)
+{
+ Exactness_Action *act = eina_list_data_get(_cur_event_list);
+ _feed_event(act->type, act->n_evas, act->data);
+
+ _cur_event_list = eina_list_next(_cur_event_list);
+
+ if (!_cur_event_list)
+ { /* Finished reading all events */
+ eina_debug_session_send(_session, _cid, _finish_op, NULL, 0);
+ ecore_main_loop_quit();
+ }
+ else
+ {
+ Exactness_Action *cur_act = eina_list_data_get(_cur_event_list);
+ ecore_timer_add(cur_act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_src_open()
+{
+ double diff_time = 0; /* Time to wait before feeding the first event */
+
+ DBG("<%s> Source file is <%s>\n", __func__, _src_filename);
+ if (!strcmp(_src_filename + strlen(_src_filename) - 4,".exu"))
+ {
+ _src_unit = exactness_unit_file_read(_src_filename);
+ }
+ if (!_src_unit) return EINA_FALSE;
+ _cur_event_list = _src_unit->actions;
+ Exactness_Action *act = eina_list_data_get(_cur_event_list);
+
+ if (act->delay_ms)
+ {
+ DBG(" Waiting <%f>\n", diff_time);
+ ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
+ }
+ else
+ {
+ _feed_event_timer_cb(NULL);
+ }
+ return EINA_TRUE;
+}
+
+static void
+_main_loop_all_apps_get_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ int chosen_cid = -1;
+ if (_cid != -1) return;
+ while (size > 0)
+ {
+ int cid, pid, len;
+ cid = EXTRACT_INT(buf);
+ pid = EXTRACT_INT(buf);
+ if (_pid != -1)
+ {
+ if (_pid == pid)
+ {
+ _cid = cid;
+ _src_open();
+ return;
+ }
+ }
+ else
+ {
+ if (!strcmp(buf, "exactness_play"))
+ {
+ if (chosen_cid != -1)
+ {
+ fprintf(stderr, "Need to specify a PID - too much choice\n");
+ return;
+ }
+ chosen_cid = cid;
+ }
+ }
+ len = strlen(buf) + 1;
+ buf += len;
+ size -= (2 * sizeof(int) + len);
+ }
+ if (chosen_cid != -1)
+ {
+ _cid = chosen_cid;
+ _src_open();
+ }
+}
+
+WRAPPER_TO_XFER_MAIN_LOOP(_all_apps_get_cb)
+
+static void
+_ops_ready_cb(void *data EINA_UNUSED, Eina_Bool status)
+{
+ if (status)
+ eina_debug_session_send(_session, 0, _all_apps_get_op, NULL, 0);
+}
+
+static const Ecore_Getopt optdesc = {
+ "exactness_inject",
+ "%prog [options] <-v|-p|-t|-h> command",
+ PACKAGE_VERSION,
+ "(C) 2018 Enlightenment",
+ "BSD",
+ "A scenario events injector for EFL based applications.",
+ 1,
+ {
+ ECORE_GETOPT_STORE_STR('t', "test", "Test to run on the given application"),
+ ECORE_GETOPT_STORE_INT('p', "pid", "PID of the application to connect to"),
+ ECORE_GETOPT_STORE_INT('r', "remote-port", "Port to connect remotely to the daemon. Local connection if not specified"),
+ ECORE_GETOPT_COUNT('v', "verbose", "Turn verbose messages on."),
+
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_HELP('h', "help"),
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
+int main(int argc, char **argv)
+{
+ int opt_args = 0, real__ = 1, port = -1;
+ char *src = NULL;
+ Eina_Value *ret__;
+ Eina_Bool want_quit = EINA_FALSE;
+
+ Ecore_Getopt_Value values[] = {
+ ECORE_GETOPT_VALUE_STR(src),
+ ECORE_GETOPT_VALUE_INT(_pid),
+ ECORE_GETOPT_VALUE_INT(port),
+ ECORE_GETOPT_VALUE_INT(_verbose),
+
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_NONE
+ };
+
+ _log_domain = eina_log_domain_register("exactness_injector", NULL);
+
+ if (!ecore_evas_init())
+ return EXIT_FAILURE;
+
+ opt_args = ecore_getopt_parse(&optdesc, values, argc, argv);
+ if (opt_args < 0)
+ {
+ fprintf(stderr, "Failed parsing arguments.\n");
+ goto end;
+ }
+ if (want_quit) goto end;
+
+ if (!src)
+ {
+ fprintf(stderr, "no test file specified\n");
+ goto end;
+ }
+ _src_filename = eina_stringshare_add(src);
+
+ if (port == -1)
+ _session = eina_debug_local_connect(EINA_TRUE);
+ else
+ _session = eina_debug_remote_connect(port);
+ eina_debug_opcodes_register(_session, _debug_ops(), _ops_ready_cb, NULL);
+
+ elm_init(argc, argv);
+ ret__ = efl_loop_begin(efl_main_loop_get());
+ real__ = efl_loop_exit_code_process(ret__);
+ elm_shutdown();
+end:
+ ecore_evas_shutdown();
+ eina_log_domain_unregister(_log_domain);
+ _log_domain = -1;
+ return real__;
+}
diff --git a/src/bin/exactness/inspect.c b/src/bin/exactness/inspect.c
new file mode 100644
index 0000000000..4e2e301536
--- /dev/null
+++ b/src/bin/exactness/inspect.c
@@ -0,0 +1,1615 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <Ecore_Evas.h>
+#include <Elementary.h>
+#include <Efl_Ui.h>
+
+#include "common.h"
+
+#define LDIFF(x) "<b><color=#F0F>"#x"</color></b>"
+#define RDIFF(x) "<b><color=#0FF>"#x"</color></b>"
+
+typedef enum
+{
+ EX_FONTS_DIR,
+ EX_SCENARIO,
+ EX_IMAGE,
+ EX_OBJ_INFO
+} _Data_Type;
+
+typedef struct
+{
+ void *p1;
+ void *p2;
+ _Data_Type dt;
+} _Compare_Item_Data;
+
+typedef struct
+{
+ void *ex_parent;
+ Eo *gl_item;
+} _Item_Info;
+
+static Eo *_main_box = NULL;
+static Eina_List *_gls = NULL;
+static Eina_List *_units = NULL;
+static Eo *_comp_selected_item = NULL;
+
+static Elm_Genlist_Item_Class *_grp_itc = NULL, *_scn_itc = NULL, *_img_itc = NULL;
+static Elm_Genlist_Item_Class *_objs_itc = NULL, *_obj_itc = NULL;
+
+static Eina_Hash *_item_infos_hash = NULL;
+
+static Eina_Bool _show_only_diffs = EINA_FALSE;
+static Eina_List *_comp_vvs = NULL;
+
+static Eina_List *_modified_units = NULL;
+
+static const char *
+_action_name_get(Exactness_Action *act)
+{
+ if (!act) return NULL;
+ switch(act->type)
+ {
+ case EXACTNESS_ACTION_MOUSE_IN: return "Mouse In";
+ case EXACTNESS_ACTION_MOUSE_OUT: return "Mouse Out";
+ case EXACTNESS_ACTION_MOUSE_WHEEL: return "Mouse Wheel";
+ case EXACTNESS_ACTION_MULTI_DOWN: return "Multi Down";
+ case EXACTNESS_ACTION_MULTI_UP: return "Multi Up";
+ case EXACTNESS_ACTION_MULTI_MOVE: return "Multi Move";
+ case EXACTNESS_ACTION_KEY_DOWN: return "Key Down";
+ case EXACTNESS_ACTION_KEY_UP: return "Key Up";
+ case EXACTNESS_ACTION_TAKE_SHOT: return "Take shot";
+ case EXACTNESS_ACTION_EFL_EVENT: return "EFL Event";
+ case EXACTNESS_ACTION_CLICK_ON: return "Click On";
+ case EXACTNESS_ACTION_STABILIZE: return "Stabilize";
+ default: return NULL;
+ }
+}
+
+static int
+_event_struct_len_get(Exactness_Action_Type type)
+{
+ switch(type)
+ {
+ case EXACTNESS_ACTION_MOUSE_WHEEL:
+ return sizeof(Exactness_Action_Mouse_Wheel);
+ case EXACTNESS_ACTION_MULTI_DOWN:
+ case EXACTNESS_ACTION_MULTI_UP:
+ return sizeof(Exactness_Action_Multi_Event);
+ case EXACTNESS_ACTION_MULTI_MOVE:
+ return sizeof(Exactness_Action_Multi_Move);
+ case EXACTNESS_ACTION_KEY_DOWN:
+ case EXACTNESS_ACTION_KEY_UP:
+ return sizeof(Exactness_Action_Key_Down_Up);
+ case EXACTNESS_ACTION_EFL_EVENT:
+ return sizeof(Exactness_Action_Efl_Event);
+ case EXACTNESS_ACTION_CLICK_ON:
+ return sizeof(Exactness_Action_Click_On);
+ default: return 0;
+ }
+}
+
+static void
+_action_specific_info_get(const Exactness_Action *act, char output[1024])
+{
+ switch(act->type)
+ {
+ case EXACTNESS_ACTION_MOUSE_WHEEL:
+ {
+ Exactness_Action_Mouse_Wheel *t = act->data;
+ sprintf(output, "Direction %d Z %d", t->direction, t->z);
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_UP:
+ case EXACTNESS_ACTION_MULTI_DOWN:
+ {
+ Exactness_Action_Multi_Event *t = act->data;
+ if (!t->d)
+ sprintf(output, "Button %d Flags %d", t->b, t->flags);
+ else
+ sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f Flags %d",
+ t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy, t->flags);
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_MOVE:
+ {
+ Exactness_Action_Multi_Move *t = act->data;
+ if (!t->d)
+ sprintf(output, "X %d Y %d", t->x, t->y);
+ else
+ sprintf(output, "D %d X %d Y %d Rad %f RadX %f RadY %f Pres %f Ang %f FX %f FY %f",
+ t->d, t->x, t->y, t->rad, t->radx, t->rady, t->pres, t->ang, t->fx, t->fy);
+ break;
+ }
+ case EXACTNESS_ACTION_KEY_UP:
+ case EXACTNESS_ACTION_KEY_DOWN:
+ {
+ Exactness_Action_Key_Down_Up *t = act->data;
+ sprintf(output, "Keyname %s Key %s String %s Compose %s Keycode %d",
+ t->keyname, t->key, t->string, t->compose, t->keycode);
+ break;
+ }
+ case EXACTNESS_ACTION_EFL_EVENT:
+ {
+ Exactness_Action_Efl_Event *t = act->data;
+ sprintf(output, "Widget %s Event %s", t->wdg_name, t->event_name);
+ break;
+ }
+ case EXACTNESS_ACTION_CLICK_ON:
+ {
+ Exactness_Action_Click_On *t = act->data;
+ sprintf(output, "Widget %s", t->wdg_name);
+ break;
+ }
+ default:
+ {
+ output[0] = '\0';
+ break;
+ }
+ }
+}
+
+static Eina_Bool
+_is_hook_duplicate(const Exactness_Action *cur_act, const Exactness_Action *prev_act)
+{
+ if (!prev_act) return EINA_FALSE;
+ if (cur_act->type == prev_act->type)
+ {
+ int len = _event_struct_len_get(cur_act->type);
+ return (!len || !memcmp(cur_act->data, prev_act->data, len));
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_are_scenario_entries_different(Exactness_Action *act1, Exactness_Action *act2)
+{
+ if (!act1 || !act2) return EINA_TRUE;
+ if (act1->type != act2->type) return EINA_TRUE;
+ switch(act1->type)
+ {
+ case EXACTNESS_ACTION_MOUSE_WHEEL:
+ return !!memcmp(act1->data, act2->data, sizeof(Exactness_Action_Mouse_Wheel));
+ case EXACTNESS_ACTION_MULTI_DOWN:
+ case EXACTNESS_ACTION_MULTI_UP:
+ return !!memcmp(act1->data, act2->data, sizeof(Exactness_Action_Multi_Event));
+ case EXACTNESS_ACTION_MULTI_MOVE:
+ return !!memcmp(act1->data, act2->data, sizeof(Exactness_Action_Multi_Move));
+ case EXACTNESS_ACTION_KEY_UP:
+ case EXACTNESS_ACTION_KEY_DOWN:
+ return !!memcmp(act1->data, act2->data, sizeof(Exactness_Action_Key_Down_Up));
+ case EXACTNESS_ACTION_EFL_EVENT:
+ {
+ Exactness_Action_Efl_Event *e1 = act1->data;
+ Exactness_Action_Efl_Event *e2 = act2->data;
+ return (!!strcmp(e1->wdg_name, e2->wdg_name) ||
+ !!strcmp(e1->event_name, e2->event_name));
+ }
+ case EXACTNESS_ACTION_CLICK_ON:
+ {
+ Exactness_Action_Click_On *e1 = act1->data;
+ Exactness_Action_Click_On *e2 = act2->data;
+ return (!!strcmp(e1->wdg_name, e2->wdg_name));
+ }
+ default:
+ return EINA_FALSE;
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_are_images_different(Exactness_Image *e_img1, Exactness_Image *e_img2)
+{
+ unsigned int w, h;
+ int *pxs1 = NULL;
+ int *pxs2 = NULL;
+ if (!e_img1 || !e_img2) return EINA_TRUE;
+ if (e_img1->w != e_img2->w) return EINA_TRUE;
+ if (e_img1->h != e_img2->h) return EINA_TRUE;
+ pxs1 = e_img1->pixels;
+ pxs2 = e_img2->pixels;
+ for (w = 0; w < e_img1->w; w++)
+ {
+ for (h = 0; h < e_img1->h; h++)
+ {
+ if (pxs1[h * e_img1->w + w] != pxs2[h * e_img1->w + w])
+ return EINA_TRUE;
+ }
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_are_objs_different(Exactness_Object *e_obj1, Exactness_Object *e_obj2, Eina_Bool check_objs)
+{
+ if (!e_obj1 || !e_obj2) return EINA_TRUE;
+ Eina_List *itr1 = e_obj1->children;
+ Eina_List *itr2 = e_obj2->children;
+ if (check_objs &&
+ (strcmp(e_obj1->kl_name, e_obj2->kl_name) ||
+ e_obj1->x != e_obj2->x || e_obj1->y != e_obj2->y ||
+ e_obj1->w != e_obj2->w || e_obj1->h != e_obj2->h)) return EINA_TRUE;
+ while (itr1 || itr2)
+ {
+ if ((!itr1) ^ (!itr2)) return EINA_TRUE;
+ e_obj1 = eina_list_data_get(itr1);
+ e_obj2 = eina_list_data_get(itr2);
+
+ if (_are_objs_different(e_obj1, e_obj2, EINA_TRUE)) return EINA_TRUE;
+
+ itr1 = eina_list_next(itr1);
+ itr2 = eina_list_next(itr2);
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_are_objs_trees_different(Exactness_Objects *e_objs1, Exactness_Objects *e_objs2)
+{
+ if (!e_objs1 || !e_objs2) return EINA_TRUE;
+ Eina_List *itr1 = e_objs1->objs;
+ Eina_List *itr2 = e_objs2->objs;
+ Exactness_Object *e_obj1, *e_obj2;
+ while (itr1 || itr2)
+ {
+ if ((!itr1) ^ (!itr2)) return EINA_TRUE;
+ e_obj1 = eina_list_data_get(itr1);
+ e_obj2 = eina_list_data_get(itr2);
+
+ if (_are_objs_different(e_obj1, e_obj2, EINA_TRUE)) return EINA_TRUE;
+
+ itr1 = eina_list_next(itr1);
+ itr2 = eina_list_next(itr2);
+ }
+ return EINA_FALSE;
+}
+
+static void
+_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ efl_exit(0); /* exit the program's main loop that runs in elm_run() */
+}
+
+static void
+_gui_win_create()
+{
+ Eo *win, *bg;
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ win = elm_win_add(NULL, "Window", ELM_WIN_BASIC);
+ evas_object_smart_callback_add(win, "delete,request", _win_del, NULL);
+ elm_win_maximized_set(win, EINA_TRUE);
+ elm_win_autodel_set(win, EINA_TRUE);
+ elm_win_title_set(win, "Exactness Inspector");
+ efl_gfx_entity_size_set(win, EINA_SIZE2D(1000, 800));
+
+ bg = elm_bg_add(win);
+ evas_object_size_hint_weight_set(bg, 1.000000, 1.000000);
+ efl_gfx_entity_visible_set(bg, EINA_TRUE);
+ elm_win_resize_object_add(win, bg);
+
+ _main_box = elm_box_add(win);
+ elm_box_horizontal_set(_main_box, EINA_TRUE);
+ elm_box_homogeneous_set(_main_box, EINA_TRUE);
+ evas_object_size_hint_weight_set(_main_box, 1.000000, 1.000000);
+ efl_gfx_entity_visible_set(_main_box, EINA_TRUE);
+ elm_win_resize_object_add(win, _main_box);
+
+ efl_gfx_entity_visible_set(win, EINA_TRUE);
+}
+
+static char *
+_grp_text_get(void *data, Evas_Object *gl, const char *part EINA_UNUSED)
+{
+ char buf[256];
+ const char *str = NULL;
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ _Data_Type dt = (_Data_Type) data;
+ switch (dt)
+ {
+ case EX_FONTS_DIR:
+ {
+ char buf2[256];
+ if (!compare)
+ {
+ Exactness_Unit *unit = efl_key_data_get(gl, "unit");
+ snprintf(buf2, sizeof(buf2), "Fonts directory: %s", unit->fonts_path ? unit->fonts_path : "None");
+ }
+ else
+ {
+ Eo *gl1 = eina_list_nth(_gls, 0);
+ Eo *gl2 = eina_list_nth(_gls, 1);
+ Exactness_Unit *unit1 = efl_key_data_get(gl1, "unit");
+ Exactness_Unit *unit2 = efl_key_data_get(gl2, "unit");
+ snprintf(buf2, sizeof(buf2), "Fonts directory comparison: "LDIFF(%s)"/"RDIFF(%s),
+ unit1 ? unit1->fonts_path : "(NULL)", unit2 ? unit2->fonts_path : "(NULL)");
+ }
+ return strdup(buf2);
+ }
+ case EX_SCENARIO: { str = "Scenario"; break; }
+ case EX_IMAGE: { str = "Images"; break; }
+ case EX_OBJ_INFO: { str = "Objects"; break; }
+ default: { str = "Unknown"; break; }
+ }
+ sprintf(buf, "%s%s", str, compare ? " comparison" : "");
+ return strdup(buf);
+}
+
+static char *
+_scn_text_get(void *data, Evas_Object *gl, const char *part EINA_UNUSED)
+{
+ Eina_Strbuf *buf = eina_strbuf_new();
+ char *ret = NULL;
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ _Compare_Item_Data *vv = data;
+ Exactness_Action *a1 = vv->p1;
+ Exactness_Action *a2 = vv->p2;
+
+ if (!a1 || !a2)
+ {
+ eina_strbuf_free(buf);
+ return strdup("XXXXX");
+ }
+
+ if (a1->delay_ms != a2->delay_ms) eina_strbuf_append_printf(buf, "[+"LDIFF(%.3f)"/+"RDIFF(%.3f)"]: ", a1->delay_ms/1000.0, a2->delay_ms/1000.0);
+ else eina_strbuf_append_printf(buf, "+%.3f: ", a1->delay_ms / 1000.0);
+
+ if (a1->type != a2->type)
+ eina_strbuf_append_printf(buf, "["LDIFF(%s)"/"RDIFF(%s)"] - XXXXXX", _action_name_get(a1), _action_name_get(a2));
+ else
+ {
+ char params1[1024];
+ char params2[2024];
+ _action_specific_info_get(a1, params1);
+ _action_specific_info_get(a2, params2);
+
+ eina_strbuf_append_printf(buf, "%s", _action_name_get(a1));
+ if (*params1 || *params2)
+ {
+ if (strcmp(params1, params2))
+ eina_strbuf_append_printf(buf, " - ["LDIFF(%s)"/"RDIFF(%s)"]", params1, params2);
+ else
+ eina_strbuf_append_printf(buf, " - %s", params1);
+ }
+ }
+ }
+ else
+ {
+ Exactness_Action *act = data;
+ char specific_output[1024];
+ if (act)
+ {
+ eina_strbuf_append_printf(buf, "+%.3f: ", act->delay_ms / 1000.0);
+ eina_strbuf_append_printf(buf, "%s", _action_name_get(act));
+ _action_specific_info_get(act, specific_output);
+ if (*specific_output) eina_strbuf_append_printf(buf, " - %s", specific_output);
+ }
+ else
+ eina_strbuf_append(buf, "XXXXX");
+ }
+
+ ret = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ return ret;
+}
+
+static int
+_unit_shot_no_get(Exactness_Unit *unit, Exactness_Action *act_ref)
+{
+ Eina_List *itr;
+ Exactness_Action *act;
+ int ret = 0;
+ if (!unit) return -1;
+ EINA_LIST_FOREACH(unit->actions, itr, act)
+ {
+ if (act->type == EXACTNESS_ACTION_TAKE_SHOT)
+ {
+ if (act == act_ref) return ret;
+ ret++;
+ }
+ }
+ return -1;
+}
+
+static void
+_goto_shot(void *data EINA_UNUSED, Evas_Object *bt, void *event_info EINA_UNUSED)
+{
+ Eo *gl = efl_key_data_get(bt, "gl");
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ _Compare_Item_Data *vv;
+ Eina_List *itr;
+ Eo *gl1 = eina_list_nth(_gls, 0);
+ Eo *gl2 = eina_list_nth(_gls, 1);
+ Exactness_Unit *unit1 = efl_key_data_get(gl1, "unit");
+ Exactness_Unit *unit2 = efl_key_data_get(gl2, "unit");
+ int shot1_no = (intptr_t)efl_key_data_get(bt, "shot1_no");
+ int shot2_no = (intptr_t)efl_key_data_get(bt, "shot2_no");
+ Exactness_Image *ex_img1 = shot1_no != -1 ? eina_list_nth(unit1->imgs, shot1_no) : NULL;
+ Exactness_Image *ex_img2 = shot2_no != -1 ? eina_list_nth(unit2->imgs, shot2_no) : NULL;
+ EINA_LIST_FOREACH(_comp_vvs, itr, vv)
+ {
+ if (vv->p1 == ex_img1 && vv->p2 == ex_img2)
+ {
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &vv);
+ if (ii && ii->gl_item)
+ elm_genlist_item_show(ii->gl_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+ }
+ }
+ }
+ else
+ {
+ Exactness_Unit *unit = efl_key_data_get(gl, "unit");
+ int shot_no = (intptr_t)efl_key_data_get(bt, "shot_no");
+ Exactness_Image *ex_img = shot_no != -1 ? eina_list_nth(unit->imgs, shot_no) : NULL;
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &ex_img);
+ if (ii && ii->gl_item)
+ elm_genlist_item_show(ii->gl_item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
+ }
+}
+
+static Evas_Object *
+_scn_content_get(void *data, Evas_Object *gl, const char *part)
+{
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ if (!strcmp(part, "elm.swallow.end"))
+ {
+ _Compare_Item_Data *vv = data;
+ Exactness_Action *v1 = vv->p1;
+ Exactness_Action *v2 = vv->p2;
+ if (v1 && v2 && v1->type == EXACTNESS_ACTION_TAKE_SHOT &&
+ v2->type == EXACTNESS_ACTION_TAKE_SHOT)
+ {
+ Eo *gl1 = eina_list_nth(_gls, 0);
+ Eo *gl2 = eina_list_nth(_gls, 1);
+ Exactness_Unit *unit1 = efl_key_data_get(gl1, "unit");
+ Exactness_Unit *unit2 = efl_key_data_get(gl2, "unit");
+ int shot1_no = _unit_shot_no_get(unit1, v1);
+ int shot2_no = _unit_shot_no_get(unit2, v2);
+ Exactness_Image *ex_img1 = shot1_no != -1 ? eina_list_nth(unit1->imgs, shot1_no) : NULL;
+ Exactness_Image *ex_img2 = shot2_no != -1 ? eina_list_nth(unit2->imgs, shot2_no) : NULL;
+ Exactness_Image *ex_imgO = NULL;
+ exactness_image_compare(ex_img1, ex_img2, &ex_imgO);
+
+ if (ex_imgO)
+ {
+ Eo *bt, *ic, *evas_img;
+
+ bt = elm_button_add(gl);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(bt);
+ efl_key_data_set(bt, "gl", gl);
+ efl_key_data_set(bt, "shot1_no", (void *)(intptr_t)shot1_no);
+ efl_key_data_set(bt, "shot2_no", (void *)(intptr_t)shot2_no);
+ evas_object_smart_callback_add(bt, "clicked", _goto_shot, NULL);
+
+ ic = elm_icon_add(bt);
+ evas_img = elm_image_object_get(ic);
+ evas_object_image_size_set(evas_img, ex_imgO->w, ex_imgO->h);
+ evas_object_image_data_set(evas_img, ex_imgO->pixels);
+ evas_object_show(ic);
+ elm_object_part_content_set(bt, "icon", ic);
+ exactness_image_free(ex_imgO);
+ return bt;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!strcmp(part, "elm.swallow.end"))
+ {
+ Exactness_Action *v = data;
+ Exactness_Unit *unit = efl_key_data_get(gl, "unit");
+ int shot_no = _unit_shot_no_get(unit, v);
+ Exactness_Image *ex_img = shot_no != -1 ? eina_list_nth(unit->imgs, shot_no) : NULL;
+
+ if (ex_img)
+ {
+ Eo *bt, *ic, *evas_img;
+
+ bt = elm_button_add(gl);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(bt);
+ efl_key_data_set(bt, "gl", gl);
+ efl_key_data_set(bt, "shot_no", (void *)(intptr_t)shot_no);
+ evas_object_smart_callback_add(bt, "clicked", _goto_shot, NULL);
+
+ ic = elm_icon_add(bt);
+ evas_img = elm_image_object_get(ic);
+ evas_object_image_size_set(evas_img, ex_img->w, ex_img->h);
+ evas_object_image_data_set(evas_img, ex_img->pixels);
+ evas_object_show(ic);
+ elm_object_part_content_set(bt, "icon", ic);
+
+ return bt;
+ }
+ }
+ }
+ return NULL;
+}
+
+static Evas_Object *
+_img_content_get(void *data, Evas_Object *gl, const char *part)
+{
+ if (strcmp(part, "elm.swallow.content")) return NULL;
+ Eo *img = elm_image_add(gl);
+ Eo *evas_img = elm_image_object_get(img);
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ _Compare_Item_Data *vv = data;
+ Exactness_Image *ex_img1 = vv->p1;
+ Exactness_Image *ex_img2 = vv->p2;
+ Exactness_Image *ex_imgO = NULL;
+ exactness_image_compare(ex_img1, ex_img2, &ex_imgO);
+
+ evas_object_image_size_set(evas_img, ex_imgO->w, ex_imgO->h);
+ evas_object_image_data_set(evas_img, ex_imgO->pixels);
+ evas_object_size_hint_min_set(img, ELM_SCALE_SIZE(300), ELM_SCALE_SIZE(300));
+ exactness_image_free(ex_imgO);
+ }
+ else
+ {
+ if (!data)
+ {
+ efl_del(img);
+ return NULL;
+ }
+ Exactness_Image *ex_img = data;
+ evas_object_image_size_set(evas_img, ex_img->w, ex_img->h);
+ evas_object_image_data_set(evas_img, ex_img->pixels);
+ evas_object_size_hint_min_set(img, ELM_SCALE_SIZE(300), ELM_SCALE_SIZE(300));
+ }
+ return img;
+}
+
+static char *
+_objs_text_get(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
+{
+ return strdup("Shot");
+}
+
+#define SAFE_PRINT(field, format, fallback) \
+ eina_strbuf_append_printf(buf, LDIFF(format)"/"RDIFF(format), \
+ e_obj1 ? e_obj1->field : fallback, \
+ e_obj2 ? e_obj2->field : fallback); \
+
+
+static char *
+_obj_text_get(void *data, Evas_Object *gl, const char *part EINA_UNUSED)
+{
+ Eina_Strbuf *buf = eina_strbuf_new();
+ char *ret = NULL;
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ _Compare_Item_Data *vv = data;
+ Exactness_Object *e_obj1 = vv->p1;
+ Exactness_Object *e_obj2 = vv->p2;
+ eina_strbuf_append(buf, "(");
+ SAFE_PRINT(kl_name, %s, "(NULL)")
+ eina_strbuf_append(buf, ")");
+
+ eina_strbuf_append(buf, " x = ");
+ SAFE_PRINT(x, %d, -1)
+
+ eina_strbuf_append(buf, " y = ");
+ SAFE_PRINT(y, %d, -1)
+
+ eina_strbuf_append(buf, " w = ");
+ SAFE_PRINT(w, %d, -1)
+
+ eina_strbuf_append(buf, " h = ");
+ SAFE_PRINT(h, %d, -1)
+
+ if (e_obj1 && e_obj2 && _are_objs_different(e_obj1, e_obj2, EINA_FALSE))
+ eina_strbuf_append(buf, " - DIFF INSIDE");
+ }
+ else
+ {
+ Exactness_Object *e_obj = data;
+ eina_strbuf_append_printf(buf,
+ "%s: x = %d y = %d w = %d h = %d",
+ e_obj->kl_name,
+ e_obj->x, e_obj->y, e_obj->w, e_obj->h);
+ }
+
+ ret = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
+ return ret;
+}
+
+static void
+_itc_init()
+{
+ if (!_grp_itc)
+ {
+ _grp_itc = elm_genlist_item_class_new();
+ _grp_itc->item_style = "group_index";
+ _grp_itc->func.text_get = _grp_text_get;
+ }
+
+ if (!_scn_itc)
+ {
+ _scn_itc = elm_genlist_item_class_new();
+ _scn_itc->item_style = "default_style";
+ _scn_itc->func.text_get = _scn_text_get;
+ _scn_itc->func.content_get = _scn_content_get;
+ }
+
+ if (!_img_itc)
+ {
+ _img_itc = elm_genlist_item_class_new();
+ _img_itc->item_style = "full";
+ _img_itc->func.content_get = _img_content_get;
+ }
+
+ if (!_objs_itc)
+ {
+ _objs_itc = elm_genlist_item_class_new();
+ _objs_itc->item_style = "default_style";
+ _objs_itc->func.text_get = _objs_text_get;
+ }
+
+ if (!_obj_itc)
+ {
+ _obj_itc = elm_genlist_item_class_new();
+ _obj_itc->item_style = "default_style";
+ _obj_itc->func.text_get = _obj_text_get;
+ }
+}
+
+static void
+_comp_gl_dragged_cb(Evas_Object *obj, void *data EINA_UNUSED)
+{
+ int x = 0, y = 0;
+ Eo *gl;
+ Eina_List *itr;
+ elm_interface_scrollable_content_pos_get(obj, &x, &y);
+ EINA_LIST_FOREACH(_gls, itr, gl)
+ {
+ if (gl != obj)
+ elm_interface_scrollable_content_pos_set(gl, x, y, EINA_FALSE);
+ }
+}
+
+static void
+_obj_item_realize(Exactness_Object *ex_obj)
+{
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &ex_obj);
+ if (!ii) return;
+ if (ii->gl_item) return;
+ _obj_item_realize(ii->ex_parent);
+ _Item_Info *iip = eina_hash_find(_item_infos_hash, &(ii->ex_parent));
+ if (iip->gl_item) elm_genlist_item_expanded_set(iip->gl_item, EINA_TRUE);
+}
+
+static void
+_gl_expand_request_cb(void *data EINA_UNUSED, Evas_Object *gl, void *event_info)
+{
+ Elm_Object_Item *glit = event_info;
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ const Elm_Genlist_Item_Class *itc = elm_genlist_item_item_class_get(glit);
+ if (itc == _objs_itc)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (ii) elm_genlist_item_expanded_set(ii->gl_item, EINA_TRUE);
+ ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (ii) elm_genlist_item_expanded_set(ii->gl_item, EINA_TRUE);
+ }
+ else if (itc == _obj_itc)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (!ii || !ii->gl_item) _obj_item_realize(vv->p1);
+ if (!ii) ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (ii && ii->gl_item) elm_genlist_item_expanded_set(ii->gl_item, EINA_TRUE);
+
+ ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (!ii || !ii->gl_item) _obj_item_realize(vv->p2);
+ if (!ii) ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (ii && ii->gl_item) elm_genlist_item_expanded_set(ii->gl_item, EINA_TRUE);
+ }
+ }
+ elm_genlist_item_expanded_set(glit, EINA_TRUE);
+}
+
+static void
+_gl_contract_request_cb(void *data EINA_UNUSED, Evas_Object *gl EINA_UNUSED, void *event_info)
+{
+ Elm_Object_Item *glit = event_info;
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (compare)
+ {
+ const Elm_Genlist_Item_Class *itc = elm_genlist_item_item_class_get(glit);
+ if (itc == _objs_itc)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (ii) elm_genlist_item_expanded_set(ii->gl_item, EINA_FALSE);
+ ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (ii) elm_genlist_item_expanded_set(ii->gl_item, EINA_FALSE);
+ }
+ else if (itc == _obj_itc)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (ii && ii->gl_item) elm_genlist_item_expanded_set(ii->gl_item, EINA_FALSE);
+
+ ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (ii && ii->gl_item) elm_genlist_item_expanded_set(ii->gl_item, EINA_FALSE);
+ }
+ }
+ elm_genlist_item_expanded_set(glit, EINA_FALSE);
+}
+
+static void
+_gl_expanded_cb(void *_data EINA_UNUSED, Evas_Object *gl EINA_UNUSED, void *event_info)
+{
+ Elm_Object_Item *glit = event_info;
+ const Elm_Genlist_Item_Class *itc = elm_genlist_item_item_class_get(glit);
+ Eina_Bool compare = !!efl_key_data_get(gl, "_exactness_gl_compare");
+ if (itc == _objs_itc)
+ {
+ if (compare)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ Exactness_Objects *e_objs1 = vv->p1;
+ Exactness_Objects *e_objs2 = vv->p2;
+ Eina_List *itr1 = e_objs1->main_objs, *itr2 = e_objs2->main_objs;
+
+ while (itr1 || itr2)
+ {
+ Exactness_Object *e_obj1 = eina_list_data_get(itr1);
+ Exactness_Object *e_obj2 = eina_list_data_get(itr2);
+ vv = calloc(1, sizeof(*vv));
+ vv->p1 = e_obj1;
+ vv->p2 = e_obj2;
+ vv->dt = EX_OBJ_INFO;
+ elm_genlist_item_append(gl, _obj_itc, vv, glit,
+ e_obj1->children || e_obj2->children ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE,
+ NULL, NULL);
+ itr1 = eina_list_next(itr1);
+ itr2 = eina_list_next(itr2);
+ }
+ }
+ else
+ {
+ Exactness_Objects *e_objs = elm_object_item_data_get(glit);
+ Eina_List *itr;
+ Exactness_Object *e_obj;
+ EINA_LIST_FOREACH(e_objs->main_objs, itr, e_obj)
+ {
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &e_obj);
+ if (!ii)
+ {
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &e_obj, ii);
+ }
+ ii->ex_parent = e_objs;
+ ii->gl_item = elm_genlist_item_append(gl, _obj_itc, e_obj, glit,
+ e_obj->children ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE,
+ NULL, NULL);
+ efl_wref_add(ii->gl_item, &(ii->gl_item));
+ }
+ }
+ }
+ else if (itc == _obj_itc)
+ {
+ if (compare)
+ {
+ _Compare_Item_Data *vv = elm_object_item_data_get(glit);
+ Exactness_Object *e_obj1 = vv->p1;
+ Exactness_Object *e_obj2 = vv->p2;
+ Eina_List *itr1 = e_obj1->children, *itr2 = e_obj2->children;
+
+ while (itr1 || itr2)
+ {
+ e_obj1 = eina_list_data_get(itr1);
+ e_obj2 = eina_list_data_get(itr2);
+ vv = calloc(1, sizeof(*vv));
+ vv->p1 = e_obj1;
+ vv->p2 = e_obj2;
+ vv->dt = EX_OBJ_INFO;
+ elm_genlist_item_append(gl, _obj_itc, vv, glit,
+ (e_obj1 && e_obj1->children) || (e_obj2 && e_obj2->children) ?
+ ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE,
+ NULL, NULL);
+ itr1 = eina_list_next(itr1);
+ itr2 = eina_list_next(itr2);
+ }
+ }
+ else
+ {
+ Exactness_Object *e_obj = elm_object_item_data_get(glit), *e_obj2;
+ Eina_List *itr;
+
+ EINA_LIST_FOREACH(e_obj->children, itr, e_obj2)
+ {
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &e_obj2);
+ if (!ii)
+ {
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &e_obj2, ii);
+ }
+ ii->ex_parent = e_obj;
+ ii->gl_item = elm_genlist_item_append(gl, _obj_itc, e_obj2, glit,
+ e_obj2->children ? ELM_GENLIST_ITEM_TREE : ELM_GENLIST_ITEM_NONE,
+ NULL, NULL);
+ efl_wref_add(ii->gl_item, &(ii->gl_item));
+ }
+ }
+ }
+}
+
+static void
+_gl_contracted_cb(void *data EINA_UNUSED, Evas_Object *gl EINA_UNUSED, void *event_info)
+{
+ Elm_Object_Item *glit = event_info;
+ elm_genlist_item_subitems_clear(glit);
+}
+
+static void
+_comp_gl_selected_cb(void *data EINA_UNUSED, Evas_Object *gl EINA_UNUSED, void *event_info)
+{
+ _comp_selected_item = event_info;
+ _Compare_Item_Data *vv = elm_object_item_data_get(_comp_selected_item);
+ if (vv->p1)
+ {
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p1));
+ if (!ii || !ii->gl_item)
+ _obj_item_realize(vv->p1);
+ else
+ elm_genlist_item_selected_set(ii->gl_item, EINA_TRUE);
+ }
+
+ if (vv->p2)
+ {
+ _Item_Info *ii = eina_hash_find(_item_infos_hash, &(vv->p2));
+ if (!ii || !ii->gl_item)
+ _obj_item_realize(vv->p2);
+ else
+ elm_genlist_item_selected_set(ii->gl_item, EINA_TRUE);
+ }
+}
+
+static void
+_scn_item_remove(void *data, Evas_Object *menu EINA_UNUSED, void *item EINA_UNUSED)
+{
+ Eo *glit = data;
+ Exactness_Unit *unit = efl_key_data_get(efl_parent_get(glit), "unit");
+ Exactness_Action *act = elm_object_item_data_get(glit);
+ unit->actions = eina_list_remove(unit->actions, act);
+ if (!eina_list_data_find(_modified_units, unit))
+ _modified_units = eina_list_append(_modified_units, unit);
+ efl_del(glit);
+}
+
+static void
+_gl_clicked_right_cb(void *data, Evas_Object *gl, void *event_info)
+{
+ int x = 0, y = 0;
+ Eo *win = data, *menu;
+ Elm_Object_Item *glit = event_info;
+
+ if (elm_genlist_item_item_class_get(glit) == _scn_itc)
+ {
+ elm_genlist_item_selected_set(glit, EINA_TRUE);
+ evas_pointer_canvas_xy_get(evas_object_evas_get(gl), &x, &y);
+
+ menu = elm_menu_add(win);
+ elm_menu_move(menu, x, y);
+ elm_menu_item_add(menu, NULL, NULL, "Remove", _scn_item_remove, glit);
+ efl_gfx_entity_visible_set(menu, EINA_TRUE);
+ }
+}
+
+static void
+_gl_img_show(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ static Eo *_img_win = NULL;
+ Exactness_Image *ex_img = data;
+ if (_img_win) efl_del(_img_win);
+ _img_win = efl_add(EFL_UI_WIN_CLASS, elm_win_get(obj),
+ efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_DIALOG_BASIC),
+ efl_ui_win_autodel_set(efl_added, EINA_TRUE));
+ efl_wref_add(_img_win, &_img_win);
+
+ Evas_Object *image = elm_image_add(_img_win);
+ Eo *evas_img = elm_image_object_get(image);
+ evas_object_image_size_set(evas_img, ex_img->w, ex_img->h);
+ evas_object_image_data_set(evas_img, ex_img->pixels);
+ efl_content_set(_img_win, image);
+
+ efl_gfx_entity_size_set(_img_win, EINA_SIZE2D(550, 500));
+}
+
+static void
+_gui_unit_display(Exactness_Unit *unit1, Exactness_Unit *unit2)
+{
+ Eina_List *itr1, *itr2;
+ Eo *gl1, *gl2 = NULL, *glc = NULL;
+
+ gl1 = elm_genlist_add(_main_box);
+ elm_genlist_homogeneous_set(gl1, EINA_TRUE);
+ evas_object_size_hint_weight_set(gl1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(gl1, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ efl_gfx_entity_visible_set(gl1, EINA_TRUE);
+ _gls = eina_list_append(_gls, gl1);
+ elm_box_pack_end(_main_box, gl1);
+
+ efl_key_data_set(gl1, "unit", unit1);
+ evas_object_smart_callback_add(gl1, "expand,request", _gl_expand_request_cb, NULL);
+ evas_object_smart_callback_add(gl1, "contract,request", _gl_contract_request_cb, NULL);
+ evas_object_smart_callback_add(gl1, "expanded", _gl_expanded_cb, NULL);
+ evas_object_smart_callback_add(gl1, "contracted", _gl_contracted_cb, NULL);
+ if (!unit2)
+ evas_object_smart_callback_add(gl1, "clicked,right", _gl_clicked_right_cb, elm_win_get(_main_box));
+
+ if (unit2)
+ {
+ glc = elm_genlist_add(_main_box);
+ elm_genlist_homogeneous_set(glc, EINA_TRUE);
+ evas_object_size_hint_weight_set(glc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(glc, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ efl_gfx_entity_visible_set(glc, EINA_TRUE);
+ elm_box_pack_end(_main_box, glc);
+
+ evas_object_smart_callback_add(glc, "expand,request", _gl_expand_request_cb, NULL);
+ evas_object_smart_callback_add(glc, "contract,request", _gl_contract_request_cb, NULL);
+ evas_object_smart_callback_add(glc, "expanded", _gl_expanded_cb, NULL);
+ evas_object_smart_callback_add(glc, "contracted", _gl_contracted_cb, NULL);
+
+ efl_key_data_set(glc, "_exactness_gl_compare", glc);
+ elm_interface_scrollable_scroll_down_cb_set(glc, _comp_gl_dragged_cb);
+ elm_interface_scrollable_scroll_up_cb_set(glc, _comp_gl_dragged_cb);
+ evas_object_smart_callback_add(glc, "selected", _comp_gl_selected_cb, NULL);
+
+ gl2 = elm_genlist_add(_main_box);
+ elm_genlist_homogeneous_set(gl2, EINA_TRUE);
+ evas_object_size_hint_weight_set(gl2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(gl2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ efl_gfx_entity_visible_set(gl2, EINA_TRUE);
+ _gls = eina_list_append(_gls, gl2);
+ elm_box_pack_end(_main_box, gl2);
+
+ efl_key_data_set(gl2, "unit", unit2);
+ evas_object_smart_callback_add(gl2, "expand,request", _gl_expand_request_cb, NULL);
+ evas_object_smart_callback_add(gl2, "contract,request", _gl_contract_request_cb, NULL);
+ evas_object_smart_callback_add(gl2, "expanded", _gl_expanded_cb, NULL);
+ evas_object_smart_callback_add(gl2, "contracted", _gl_contracted_cb, NULL);
+ }
+ _itc_init();
+
+ if ((unit1->fonts_path) || (unit2 && unit2->fonts_path))
+ {
+ if (!_show_only_diffs || !unit2 ||
+ !unit1->fonts_path || !unit2->fonts_path ||
+ strcmp(unit1->fonts_path, unit2->fonts_path))
+ {
+ elm_genlist_item_append(gl1, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(gl2, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(glc, _grp_itc, (void *)EX_FONTS_DIR, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ }
+ }
+ itr1 = unit1->actions;
+ itr2 = unit2 ? unit2->actions : NULL;
+
+ if (itr1 || itr2)
+ {
+ elm_genlist_item_append(gl1, _grp_itc, (void *)EX_SCENARIO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(gl2, _grp_itc, (void *)EX_SCENARIO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(glc, _grp_itc, (void *)EX_SCENARIO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ }
+ while (itr1 || itr2)
+ {
+ Exactness_Action *v1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Action *v2 = itr2 ? eina_list_data_get(itr2) : NULL;
+ if (!_show_only_diffs || _are_scenario_entries_different(v1, v2))
+ {
+ _Item_Info *ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &v1, ii);
+ ii->gl_item = elm_genlist_item_append(gl1, _scn_itc, v1, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ if (unit2)
+ {
+ _Compare_Item_Data *vv = calloc(1, sizeof(*vv));
+ vv->p1 = v1;
+ vv->p2 = v2;
+ vv->dt = EX_SCENARIO;
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &v2, ii);
+ ii->gl_item = elm_genlist_item_append(gl2, _scn_itc, v2, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ elm_genlist_item_append(glc, _scn_itc, vv, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ }
+ }
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+
+ itr1 = unit1->imgs;
+ itr2 = unit2 ? unit2->imgs : NULL;
+
+ if (itr1 || itr2)
+ {
+ elm_genlist_item_append(gl1, _grp_itc, (void *)EX_IMAGE, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(gl2, _grp_itc, (void *)EX_IMAGE, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(glc, _grp_itc, (void *)EX_IMAGE, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ }
+ while (itr1 || itr2)
+ {
+ Exactness_Image *img1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Image *img2 = itr2 ? eina_list_data_get(itr2) : NULL;
+ if (!_show_only_diffs || _are_images_different(img1, img2))
+ {
+ _Item_Info *ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &img1, ii);
+ ii->gl_item = elm_genlist_item_append(gl1, _img_itc, img1, NULL, ELM_GENLIST_ITEM_NONE, _gl_img_show, img1);
+ if (unit2)
+ {
+ _Compare_Item_Data *vv = calloc(1, sizeof(*vv));
+ vv->p1 = img1;
+ vv->p2 = img2;
+ vv->dt = EX_IMAGE;
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &img2, ii);
+ ii->gl_item = elm_genlist_item_append(gl2, _img_itc, img2, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ /* This item info is needed to go to images from scenario shot entry */
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &vv, ii);
+ ii->gl_item = elm_genlist_item_append(glc, _img_itc, vv, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ _comp_vvs = eina_list_append(_comp_vvs, vv);
+ }
+ }
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+
+ itr1 = unit1->objs;
+ itr2 = unit2 ? unit2->objs : NULL;
+
+ if (itr1 || itr2)
+ {
+ elm_genlist_item_append(gl1, _grp_itc, (void *)EX_OBJ_INFO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(gl2, _grp_itc, (void *)EX_OBJ_INFO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ elm_genlist_item_append(glc, _grp_itc, (void *)EX_OBJ_INFO, NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
+ }
+ while (itr1 || itr2)
+ {
+ Exactness_Objects *objs1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Objects *objs2 = itr2 ? eina_list_data_get(itr2) : NULL;
+ if (!_show_only_diffs || _are_objs_trees_different(objs1, objs2))
+ {
+ _Item_Info *ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &objs1, ii);
+ ii->gl_item = elm_genlist_item_append(gl1, _objs_itc, objs1, NULL,
+ ELM_GENLIST_ITEM_TREE, NULL, NULL);
+ efl_wref_add(ii->gl_item, &(ii->gl_item));
+ if (unit2)
+ {
+ _Compare_Item_Data *vv = calloc(1, sizeof(*vv));
+ vv->p1 = objs1;
+ vv->p2 = objs2;
+ vv->dt = EX_OBJ_INFO;
+ ii = calloc(1, sizeof(*ii));
+ eina_hash_set(_item_infos_hash, &objs2, ii);
+ ii->gl_item = elm_genlist_item_append(gl2, _objs_itc, objs2, NULL,
+ ELM_GENLIST_ITEM_TREE, NULL, NULL);
+ efl_wref_add(ii->gl_item, &(ii->gl_item));
+ elm_genlist_item_append(glc, _objs_itc, vv, NULL, ELM_GENLIST_ITEM_TREE, NULL, NULL);
+ }
+ }
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+}
+
+static void
+_diff_result_print(Exactness_Unit *unit1, Exactness_Unit *unit2)
+{
+ Eina_List *itr1, *itr2;
+
+ int nb_scenario = 0, nb_diff_scenario = 0;
+ int nb_image = 0, nb_diff_image = 0;
+ int nb_objtree= 0, nb_diff_objtree = 0;
+
+ itr1 = unit1 ? unit1->actions : NULL;
+ itr2 = unit2 ? unit2->actions : NULL;
+
+ while (itr1 || itr2)
+ {
+ Exactness_Action *v1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Action *v2 = itr2 ? eina_list_data_get(itr2) : NULL;
+
+ nb_scenario++;
+ if (_are_scenario_entries_different(v1, v2))
+ nb_diff_scenario++;
+
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+
+ itr1 = unit1 ? unit1->imgs : NULL;
+ itr2 = unit2 ? unit2->imgs : NULL;
+
+ while (itr1 || itr2)
+ {
+ Exactness_Image *img1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Image *img2 = itr2 ? eina_list_data_get(itr2) : NULL;
+
+ nb_image++;
+ if (_are_images_different(img1, img2))
+ nb_diff_image++;
+
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+
+ itr1 = unit1 ? unit1->objs : NULL;
+ itr2 = unit2 ? unit2->objs : NULL;
+
+ while (itr1 || itr2)
+ {
+ Exactness_Objects *objs1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Objects *objs2 = itr2 ? eina_list_data_get(itr2) : NULL;
+
+ nb_objtree++;
+ if (_are_objs_trees_different(objs1, objs2))
+ nb_diff_objtree++;
+
+ if (itr1) itr1 = eina_list_next(itr1);
+ if (itr2) itr2 = eina_list_next(itr2);
+ }
+
+ printf("%s\nscenario (%d/%d)\nimage (%d/%d)\nobjs_tree (%d/%d)\n",
+ nb_diff_scenario || nb_diff_image || nb_diff_objtree ?
+ "Failure" : "Success",
+ nb_scenario - nb_diff_scenario, nb_scenario,
+ nb_image - nb_diff_image, nb_image,
+ nb_objtree - nb_diff_objtree, nb_objtree);
+}
+
+static Exactness_Image *
+_image_read(const char *filename)
+{
+ int w, h;
+ Evas_Load_Error err;
+ Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
+
+ /* the canvas pointer, de facto */
+ Eo *e = ecore_evas_get(ee);
+
+ Eo *img = evas_object_image_add(e);
+ evas_object_image_file_set(img, filename, NULL);
+ err = evas_object_image_load_error_get(img);
+ if (err != EVAS_LOAD_ERROR_NONE)
+ {
+ fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n",
+ filename, evas_load_error_str(err));
+ return NULL;
+ }
+
+ Exactness_Image *ex_img = malloc(sizeof(*ex_img));
+ int len;
+ evas_object_image_size_get(img, &w, &h);
+ ex_img->w = w;
+ ex_img->h = h;
+ len = w * h * 4;
+ ex_img->pixels = malloc(len);
+ memcpy(ex_img->pixels, evas_object_image_data_get(img, EINA_FALSE), len);
+
+ ecore_evas_free(ee);
+ return ex_img;
+}
+
+static const Ecore_Getopt optdesc = {
+ "exactness_inspect",
+ "%prog [options] [<exu file> | <file1 file2>]",
+ NULL,
+ "(C) 2016-2020 Enlightenment",
+ "BSD",
+ "Inspector for Exactness\n"
+ "\n"
+ "Dumps the contents of `.exu` files obtained with `exactness_record` or"
+ "`exactness -i` in an easy-to-examine way.",
+ 0,
+ {
+ ECORE_GETOPT_STORE_USHORT('d', "delay", "Delay the given recording by a given time (in milliseconds)."),
+ ECORE_GETOPT_STORE_TRUE('c', "clean", "Clean the given recording from wrong actions."),
+ ECORE_GETOPT_STORE_TRUE('l', "list", "List the actions of the given recording."),
+ ECORE_GETOPT_STORE_TRUE('C', "compare", "Compare given files (images files or objects eet files)."),
+ ECORE_GETOPT_STORE_TRUE(0, "show-only-diffs", "Show only differences during comparison."),
+ ECORE_GETOPT_STORE_TRUE(0, "stabilize", "Stabilize after the given shot number in --shot."),
+ ECORE_GETOPT_STORE_TRUE(0, "pack", "Pack the given input files (scenario and images) into the given output."),
+ ECORE_GETOPT_STORE_STR('o', "output", "Output."),
+ ECORE_GETOPT_STORE_USHORT('s', "shot", "Select a specific shot (1 = 1st shot...)."),
+
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_HELP('h', "help"),
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
+int
+main(int argc, char *argv[])
+{
+ Eina_List *units_filenames = NULL;
+ const char *ext = NULL;
+ char *output = NULL;
+ Exactness_Unit *unit = NULL;
+ int ret = 1, args = 0;
+ unsigned short delay = 0, shot = 0;
+ Eina_Bool write_file = EINA_FALSE;
+ Eina_Bool want_quit, clean = EINA_FALSE, list_get = EINA_FALSE, compare_files = EINA_FALSE;
+ Eina_Bool stabilize = EINA_FALSE, show_only_diffs = EINA_FALSE, gui_needed = EINA_TRUE;
+ Eina_Bool pack = EINA_FALSE;
+
+ Ecore_Getopt_Value values[] = {
+ ECORE_GETOPT_VALUE_USHORT(delay),
+ ECORE_GETOPT_VALUE_BOOL(clean),
+ ECORE_GETOPT_VALUE_BOOL(list_get),
+ ECORE_GETOPT_VALUE_BOOL(compare_files),
+ ECORE_GETOPT_VALUE_BOOL(show_only_diffs),
+ ECORE_GETOPT_VALUE_BOOL(stabilize),
+ ECORE_GETOPT_VALUE_BOOL(pack),
+ ECORE_GETOPT_VALUE_STR(output),
+ ECORE_GETOPT_VALUE_USHORT(shot),
+
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_BOOL(want_quit),
+ ECORE_GETOPT_VALUE_NONE
+ };
+
+ elm_init(0, NULL);
+ want_quit = EINA_FALSE;
+
+ args = ecore_getopt_parse(&optdesc, values, argc, argv);
+ if (args < 0)
+ {
+ fprintf(stderr, "Failed parsing arguments.\n");
+ goto end;
+ }
+ if (want_quit)
+ {
+ goto end;
+ }
+ if ((clean || delay || shot || list_get || stabilize || pack) && args == argc)
+ {
+ fprintf(stderr, "Expected scenario (.exu) as the last argument.\n");
+ ecore_getopt_help(stderr, &optdesc);
+ goto end;
+ }
+ if (shot && (!delay && !stabilize))
+ {
+ fprintf(stderr, "shot option can only be used with delay or stabilize option.\n");
+ goto end;
+ }
+ if (delay && !shot)
+ {
+ fprintf(stderr, "delay option can only be used with shot option.\n");
+ goto end;
+ }
+ if (stabilize && !shot)
+ {
+ fprintf(stderr, "stabilize option can only be used with shot option.\n");
+ goto end;
+ }
+ if (compare_files && argc - args < 2)
+ {
+ fprintf(stderr, "Expected at least two files to compare as last arguments.\n");
+ ecore_getopt_help(stderr, &optdesc);
+ goto end;
+ }
+ if (show_only_diffs && !compare_files)
+ {
+ fprintf(stderr, "--show-only-diffs is available with --compare only\n");
+ goto end;
+ }
+ if (show_only_diffs && output)
+ {
+ fprintf(stderr, "--show-only-diffs works in GUI only\n");
+ goto end;
+ }
+ _show_only_diffs = show_only_diffs;
+
+ if (clean || delay || list_get || stabilize || pack)
+ {
+ int arg;
+ Eina_List *images = NULL;
+ gui_needed = EINA_FALSE;
+ for (arg = args; arg < argc; arg++)
+ {
+ const char *src_file = argv[arg];
+ ext = strrchr(src_file, '.');
+ if (!ext)
+ {
+ fprintf(stderr, "Extension required\n");
+ goto end;
+ }
+ if (!strcmp(ext, ".exu"))
+ {
+ if (!unit) unit = exactness_unit_file_read(src_file);
+ else
+ {
+ fprintf(stderr, "%s - scenario already provided\n", src_file);
+ goto end;
+ }
+ }
+ else if (!strcmp(ext, ".png"))
+ {
+ Exactness_Image *ex_img = _image_read(src_file);
+ if (!ex_img)
+ {
+ fprintf(stderr, "Issue while reading %s\n", src_file);
+ goto end;
+ }
+ images = eina_list_append(images, ex_img);
+ }
+ else
+ {
+ fprintf(stderr, "Correct extension (.exu/.png) required\n");
+ goto end;
+ }
+ }
+ if (unit)
+ {
+ Exactness_Image *ex_img;
+ EINA_LIST_FREE(images, ex_img)
+ {
+ unit->imgs = eina_list_append(unit->imgs, ex_img);
+ unit->nb_shots++;
+ }
+ }
+ }
+ else
+ {
+ int arg;
+ if (output) gui_needed = EINA_FALSE;
+ for (arg = args; arg < argc; arg++)
+ {
+ ext = strrchr(argv[arg], '.');
+ if (!ext)
+ {
+ fprintf(stderr, "Extension required\n");
+ goto end;
+ }
+ if (!strcmp(ext, ".exu"))
+ {
+ Exactness_Unit *ex_unit = exactness_unit_file_read(argv[arg]);
+ units_filenames = eina_list_append(units_filenames, argv[arg]);
+ _units = eina_list_append(_units, ex_unit);
+ }
+ else if (!strcmp(ext, ".png"))
+ {
+ Exactness_Unit *ex_unit = calloc(1, sizeof(*ex_unit));
+ Exactness_Image *ex_img = _image_read(argv[arg]);
+ if (!ex_img)
+ {
+ fprintf(stderr, "Issue while reading %s\n", argv[arg]);
+ goto end;
+ }
+ ex_unit->imgs = eina_list_append(ex_unit->imgs, ex_img);
+ ex_unit->nb_shots++;
+ _units = eina_list_append(_units, ex_unit);
+ }
+ }
+ }
+
+ if (clean)
+ {
+ Exactness_Action *act;
+ Eina_List *itr, *itr2;
+ EINA_LIST_FOREACH_SAFE(unit->actions, itr, itr2, act)
+ {
+ Exactness_Action *prev_act = eina_list_data_get(eina_list_prev(itr));
+ if (_is_hook_duplicate(act, prev_act))
+ {
+ prev_act->delay_ms += act->delay_ms;
+ unit->actions = eina_list_remove_list(unit->actions, itr);
+ }
+ }
+ EINA_LIST_REVERSE_FOREACH_SAFE(unit->actions, itr, itr2, act)
+ {
+ if (act->type == EXACTNESS_ACTION_TAKE_SHOT) break;
+ unit->actions = eina_list_remove(unit->actions, act);
+ }
+ write_file = EINA_TRUE;
+ }
+
+ if (delay || stabilize)
+ {
+ Exactness_Action *act;
+ Eina_List *itr;
+ unsigned int cur_shot = 0;
+ EINA_LIST_FOREACH(unit->actions, itr, act)
+ {
+ if (act->type == EXACTNESS_ACTION_TAKE_SHOT)
+ {
+ cur_shot++;
+ if (cur_shot == shot)
+ {
+ if (delay) act->delay_ms = delay;
+ if (stabilize)
+ {
+ Exactness_Action *s_act = malloc(sizeof(*s_act));
+ s_act->type = EXACTNESS_ACTION_STABILIZE;
+ s_act->delay_ms = act->delay_ms;
+ s_act->n_evas = act->n_evas;
+ s_act->data = NULL;
+ act->delay_ms = 0; /* Shot right after stabilization */
+ unit->actions = eina_list_prepend_relative(unit->actions, s_act, act);
+ }
+ write_file = EINA_TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if (pack) write_file = EINA_TRUE;
+
+ if (list_get)
+ {
+ Exactness_Action *act;
+ Eina_List *itr;
+ if (unit->fonts_path) printf("Fonts dir: %s\n", unit->fonts_path);
+ EINA_LIST_FOREACH(unit->actions, itr, act)
+ {
+ char specific_output[1024];
+ printf("+%.3f: %s", act->delay_ms / 1000.0, _action_name_get(act));
+ _action_specific_info_get(act, specific_output);
+ if (*specific_output) printf(" - %s", specific_output);
+ printf("\n");
+ }
+ }
+
+ if (compare_files && output)
+ {
+ const char *out_ext = strrchr(output, '.');
+ Exactness_Unit *unit1 = NULL, *unit2 = NULL, *unitO = NULL;
+ int nb_diffs = 0;
+ Eina_List *itr1, *itr2;
+ EINA_LIST_FOREACH(_units, itr1, unit)
+ {
+ if (!unit1) unit1 = unit;
+ else if (!unit2) unit2 = unit;
+ else
+ {
+ fprintf(stderr, "Too much files to compare (only 2).\n");
+ goto end;
+ }
+ }
+
+ if (!strcmp(out_ext, ".png"))
+ {
+ if (unit1->nb_shots != 1 || unit2->nb_shots != 1)
+ {
+ fprintf(stderr, "Comparison output can be png only if the number of shots to compare is 1.\n");
+ goto end;
+ }
+ }
+
+ itr1 = unit1 ? unit1->imgs : NULL;
+ itr2 = unit2 ? unit2->imgs : NULL;
+
+ while (itr1 || itr2)
+ {
+ Exactness_Image *ex_img1 = itr1 ? eina_list_data_get(itr1) : NULL;
+ Exactness_Image *ex_img2 = itr2 ? eina_list_data_get(itr2) : NULL;
+ Exactness_Image *ex_imgO = NULL;
+ Eina_Bool has_diff = exactness_image_compare(ex_img1, ex_img2, &ex_imgO);
+ if (has_diff || !strcmp(out_ext, ".exu"))
+ {
+ if (has_diff) nb_diffs++;
+ if (!unitO) unitO = calloc(1, sizeof(*unitO));
+ unitO->imgs = eina_list_append(unitO->imgs, ex_imgO);
+ unitO->nb_shots++;
+ }
+ itr1 = eina_list_next(itr1);
+ itr2 = eina_list_next(itr2);
+ }
+ if (!strcmp(out_ext, ".png"))
+ {
+ Ecore_Evas *ee;
+ Eo *e, *img;
+ if (unitO->nb_shots == 1)
+ {
+ Exactness_Image *ex_imgO = eina_list_data_get(unitO->imgs);
+ ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL);
+ e = ecore_evas_get(ee);
+ img = evas_object_image_add(e);
+ evas_object_image_size_set(img, ex_imgO->w, ex_imgO->h);
+ evas_object_image_data_set(img, ex_imgO->pixels);
+ evas_object_image_save(img, output, NULL, NULL);
+ ecore_evas_free(ee);
+ goto end;
+ }
+ ret = 0;
+ }
+ else if (!strcmp(out_ext, ".exu"))
+ {
+ _diff_result_print(unit1, unit2);
+ if (nb_diffs) exactness_unit_file_write(unitO, output);
+ else ret = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Correct output extension (.exu/.png) required\n");
+ }
+ goto end;
+ }
+
+ ret = 0;
+ if (write_file)
+ {
+ if (!output)
+ {
+ fprintf(stderr, "An output file is required to write the modifications.\n");
+ }
+ else
+ {
+ const char *out_ext = strrchr(output, '.');
+ if (!out_ext || strcmp(out_ext, ".exu"))
+ {
+ fprintf(stderr, "Only exu extension is supported as output.\n");
+ goto end;
+ }
+ exactness_unit_file_write(unit, output);
+ }
+ goto end;
+ }
+
+ if (gui_needed)
+ {
+ Eina_List *itr;
+ Exactness_Unit *unit1 = NULL, *unit2 = NULL;
+ Eina_Bool need_compare = compare_files && eina_list_count(_units) == 2;
+ _item_infos_hash = eina_hash_pointer_new(NULL);
+ _gui_win_create();
+ EINA_LIST_FOREACH(_units, itr, unit)
+ {
+ if (need_compare)
+ {
+ if (!unit1) unit1 = unit;
+ else unit2 = unit;
+ }
+ else _gui_unit_display(unit, NULL);
+ }
+ if (need_compare) _gui_unit_display(unit1, unit2);
+ elm_run();
+ EINA_LIST_FREE(_modified_units, unit)
+ {
+ int i = 0;
+ EINA_LIST_FOREACH(_units, itr, unit2)
+ {
+ if (unit2 == unit) break;
+ i++;
+ }
+ exactness_unit_file_write(unit, eina_list_nth(units_filenames, i));
+ }
+ }
+
+end:
+ elm_shutdown();
+
+ return ret;
+}
diff --git a/src/bin/exactness/meson.build b/src/bin/exactness/meson.build
new file mode 100644
index 0000000000..4d048f18c9
--- /dev/null
+++ b/src/bin/exactness/meson.build
@@ -0,0 +1,66 @@
+exactness_bin = executable('exactness',
+ [ 'exactness.c', 'common.c', 'common.h' ],
+ dependencies: [ ecore, ecore_evas, ecore_file, elementary],
+ c_args: '-DDATA_DIR="'+join_paths(dir_data, 'exactness')+'"',
+ install: true,
+ )
+
+exactness_inject_bin = executable('exactness_inject',
+ [ 'injector.c', 'common.c', 'common.h' ],
+ dependencies: [ elementary ],
+ c_args: '-DDATA_DIR="'+join_paths(dir_data, 'exactness')+'"',
+ install: true,
+ )
+
+exactness_inspect_bin = executable('exactness_inspect',
+ [ 'inspect.c', 'common.c', 'common.h' ],
+ dependencies: [ elementary ],
+ c_args: '-DDATA_DIR="'+join_paths(dir_data, 'exactness')+'"',
+ install: true,
+ )
+
+edjs = custom_target('player_entry',
+ input : 'player_entry.edc',
+ output : 'player_entry.edj',
+ install : true,
+ install_dir : 'share/exactness',
+ command : edje_cc_exe + [
+ '-id', join_paths(meson.source_root(), 'data', 'elementary', 'themes', 'img'),
+ '-sd', join_paths(meson.source_root(), 'data', 'elementary', 'themes', 'snd'),
+ '@INPUT@', '@OUTPUT@'],
+ depends : edje_depends)
+
+exactness_play_bin = library('exactness_play',
+ [ 'player.c', 'common.c', 'common.h', edjs ],
+ dependencies: [ elementary, dl],
+ c_args: '-DDATA_DIR="'+join_paths(dir_data, 'exactness')+'"',
+ install: true,
+ version : meson.project_version()
+)
+
+exactness_record_bin = library('exactness_record',
+ [ 'recorder.c', 'common.c', 'common.h' ],
+ dependencies: [ elementary, dl],
+ c_args: '-DDATA_DIR="'+join_paths(dir_data, 'exactness')+'"',
+ install: true,
+ version : meson.project_version()
+)
+
+exactness_env = configuration_data()
+exactness_env.set_quoted('EXACTNESS_PLAY_PRELOAD_PATH', exactness_play_bin.full_path())
+exactness_env.set_quoted('EXACTNESS_RECORD_PRELOAD_PATH', exactness_record_bin.full_path())
+exactness_env.set_quoted('VERSION', meson.project_version())
+
+configure_file(
+ input: 'exactness_record.in',
+ output: 'exactness_record',
+ configuration: exactness_env,
+ install_dir: get_option('bindir'),
+ install_mode: 'rwxr-xr-x')
+
+configure_file(
+ input: 'exactness_play.in',
+ output: 'exactness_play',
+ configuration: exactness_env,
+ install_dir: get_option('bindir'),
+ install_mode: 'rwxr-xr-x')
diff --git a/src/bin/exactness/player.c b/src/bin/exactness/player.c
new file mode 100644
index 0000000000..44b3f36303
--- /dev/null
+++ b/src/bin/exactness/player.c
@@ -0,0 +1,1149 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>
+#endif
+
+#ifdef HAVE_FORK
+# ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+# endif
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# ifdef HAVE_SYS_SYSINFO_H
+# include <sys/sysinfo.h>
+# endif
+#endif
+
+#include <Eina.h>
+#include <Eo.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <Ecore_File.h>
+#include <Ecore_Con.h>
+#include <Elementary.h>
+
+#include "common.h"
+
+#define CMD_LINE_MAX 256
+#define IMAGE_FILENAME_EXT ".png"
+#define PAUSE_KEY_STR "F2"
+
+#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
+
+static int _log_domain = -1;
+
+typedef enum
+{
+ FTYPE_UNKNOWN,
+ FTYPE_DIR,
+ FTYPE_REC = FTYPE_DIR,
+ FTYPE_EXU,
+ FTYPE_REMOTE
+} File_Type;
+
+static File_Type _dest_type = FTYPE_UNKNOWN;
+static Eina_Stringshare *_dest = NULL;
+static Exactness_Unit *_dest_unit = NULL;
+
+static File_Type _src_type = FTYPE_UNKNOWN;
+static Eina_Stringshare *_src_filename = NULL;
+static Exactness_Unit *_src_unit = NULL;
+
+static const char *_test_name = NULL;
+static int _verbose = 0;
+
+static Eina_List *_evas_list = NULL;
+
+static Eina_List *_cur_event_list = NULL;
+
+static int _cur_shot_id = 0;
+static Eina_Bool _shot_needed = EINA_FALSE;
+static Eina_Bool _scan_objects = EINA_FALSE, _disable_shots = EINA_FALSE, _stabilize_shots = EINA_FALSE;
+
+static Eina_Debug_Session *_last_debug_session = NULL;
+static int _last_debug_src_cid = 0;
+static int _take_shot_op = EINA_DEBUG_OPCODE_INVALID;
+
+static Eina_Bool _stabilization_timer_cb(void *);
+static double _speed = 1.0;
+
+static Eina_Bool _exit_required = EINA_FALSE;
+static Eina_Bool _pause_request = EINA_FALSE;
+static Eina_Bool _playing_status = EINA_FALSE;
+static Eina_Bool _ready_to_write = EINA_FALSE;
+
+static Exactness_Image *
+_snapshot_shot_get(Evas *e)
+{
+ Exactness_Image *ex_img;
+ Evas_Object *snapshot;
+ void *pixels;
+ int w, h, nb_bytes;
+
+ if (!e) return NULL;
+
+ evas_output_size_get(e, &w, &h);
+ if ((w < 1) || (h < 1)) return NULL;
+
+ snapshot = efl_key_data_get(e, "_snapshot");
+ if (!snapshot)
+ {
+ snapshot = evas_object_image_filled_add(e);
+ if (snapshot)
+ {
+ evas_object_image_snapshot_set(snapshot, EINA_TRUE);
+ evas_object_geometry_set(snapshot, 0, 0, w, h);
+ efl_gfx_entity_visible_set(snapshot, EINA_TRUE);
+ efl_key_data_set(e, "_snapshot", snapshot);
+ }
+ return NULL;
+ }
+
+ pixels = evas_object_image_data_get(snapshot, EINA_FALSE);
+ if (!pixels) return NULL;
+
+ ex_img = malloc(sizeof(*ex_img));
+ nb_bytes = w * h * 4;
+ ex_img->w = w;
+ ex_img->h = h;
+ ex_img->pixels = malloc(nb_bytes);
+ memcpy(ex_img->pixels, pixels, nb_bytes);
+ return ex_img;
+}
+
+static void
+_evas_render_post_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ if (_shot_needed)
+ {
+ Evas_Event_Render_Post *post = event->info;
+ void *e_data = efl_key_data_get(event->object, "_shot");
+
+ // Nothing was updated, so let's not bother sending nothingness
+ if (post && !post->updated_area) return;
+ Exactness_Image *ex_shot = efl_key_data_get(event->object, "_last_shot");
+ if (!ex_shot) ex_shot = _snapshot_shot_get(event->object);
+ if (!ex_shot) return;
+
+ efl_key_data_set(event->object, "_last_shot", NULL);
+
+ if (e_data)
+ {
+ if (_dest_type == FTYPE_DIR)
+ {
+ char *filename = e_data;
+ Eo *o = evas_object_image_add(event->object);
+ evas_object_image_size_set(o, ex_shot->w, ex_shot->h);
+ evas_object_image_data_set(o, ex_shot->pixels);
+ INF("Shot taken (%s).\n", filename);
+ if (!evas_object_image_save(o, filename, NULL, NULL))
+ {
+ printf("Cannot save widget to <%s>\n", filename);
+ }
+ free(filename);
+ }
+ else if (_dest_type == FTYPE_EXU)
+ {
+ Exactness_Image *ex_img = e_data;
+ memcpy(ex_img, ex_shot, sizeof(Exactness_Image));
+ ex_shot->pixels = NULL;
+ INF("Shot taken (in %s).\n", _dest);
+ }
+ else if (_dest_type == FTYPE_REMOTE)
+ {
+ int len = sizeof(int) + sizeof(int) + ex_shot->w * ex_shot->h * 4;
+ char *buf = alloca(len);
+ char *tmp = buf;
+ STORE_INT(tmp, ex_shot->w);
+ STORE_INT(tmp, ex_shot->h);
+ memcpy(tmp, ex_shot->pixels, ex_shot->w * ex_shot->h * 4);
+ eina_debug_session_send(_last_debug_session, _last_debug_src_cid, _take_shot_op, buf, len);
+ }
+ }
+ exactness_image_free(ex_shot);
+ efl_key_data_set(event->object, "_shot", NULL);
+ evas_object_del(efl_key_data_get(event->object, "_snapshot"));
+ efl_key_data_set(event->object, "_snapshot", NULL);
+ /* This part is needed when the shot is needed at the end of the scenario.
+ * As it is async, we need to wait for the shot termination. */
+ _shot_needed = EINA_FALSE;
+ if (_exit_required) ecore_main_loop_quit();
+ }
+}
+
+static void
+_shot_do(Evas *e)
+{
+ void *e_data = NULL;
+ if (!e) return;
+
+ if (!_disable_shots)
+ {
+ if (_dest_type == FTYPE_DIR)
+ {
+ int dir_name_len;
+ char *filename;
+
+ dir_name_len = strlen(_dest) + 1; /* includes space of a '/' */
+ filename = malloc(strlen(_test_name) + strlen(IMAGE_FILENAME_EXT) +
+ dir_name_len + 8); /* also space for serial */
+
+ sprintf(filename, "%s/%s%c%03d%s", _dest, _test_name,
+ SHOT_DELIMITER, _cur_shot_id, IMAGE_FILENAME_EXT);
+ e_data = filename;
+ }
+ else if (_dest_type == FTYPE_EXU)
+ {
+ Exactness_Image *ex_img = malloc(sizeof(*ex_img));
+ _dest_unit->imgs = eina_list_append(_dest_unit->imgs, ex_img);
+ _dest_unit->nb_shots++;
+ e_data = ex_img;
+ }
+ else if (_dest_type == FTYPE_REMOTE)
+ {
+ e_data = e;
+ }
+ }
+ efl_key_data_set(e, "_shot", e_data);
+ _shot_needed = EINA_TRUE;
+ Efl_Event ev;
+ ev.info = NULL;
+ ev.object = e;
+ _evas_render_post_cb(NULL, &ev);
+
+ if (_scan_objects && _dest_type == FTYPE_EXU)
+ {
+ Eina_Iterator *iter;
+ Eo *obj;
+ Exactness_Objects *e_objs = calloc(1, sizeof(*e_objs));
+ iter = eo_objects_iterator_new();
+ EINA_ITERATOR_FOREACH(iter, obj)
+ {
+ if (!efl_isa(obj, EFL_CANVAS_OBJECT_CLASS) &&
+ !efl_isa(obj, EFL_CANVAS_SCENE_INTERFACE)) continue;
+ Exactness_Object *e_obj = calloc(1, sizeof(*e_obj));
+ Eo *parent = efl_parent_get(obj);
+ e_obj->id = (long long) obj;
+ if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS) ||
+ efl_isa(parent, EFL_CANVAS_SCENE_INTERFACE))
+ {
+ e_obj->parent_id = (long long) efl_parent_get(obj);
+ }
+ else
+ {
+ e_obj->parent_id = 0;
+ }
+ e_obj->kl_name = eina_stringshare_add(efl_class_name_get(obj));
+ if (efl_isa(obj, EFL_CANVAS_OBJECT_CLASS))
+ {
+ Eina_Size2D sz = efl_gfx_entity_size_get(obj);
+ e_obj->w = sz.w;
+ e_obj->h = sz.h;
+ Eina_Position2D pos = efl_gfx_entity_position_get(obj);
+ e_obj->x = pos.x;
+ e_obj->y = pos.y;
+ }
+ e_objs->objs = eina_list_append(e_objs->objs, e_obj);
+ }
+ eina_iterator_free(iter);
+ _dest_unit->objs = eina_list_append(_dest_unit->objs, e_objs);
+ }
+}
+
+static void
+_feed_event(Exactness_Action_Type type, unsigned int n_evas, void *data)
+{
+ static Evas_Object *rect = NULL;
+ static unsigned int rect_evas;
+
+ Eo *e = eina_list_nth(_evas_list, n_evas);
+
+ if (rect && rect_evas != n_evas)
+ {
+ efl_del(rect);
+ rect = NULL;
+ }
+ if (_verbose && !rect)
+ {
+ rect = evas_object_rectangle_add(e);
+ evas_object_repeat_events_set(rect, EINA_TRUE);
+ evas_object_color_set(rect, 255, 0, 0, 255);
+ evas_object_resize(rect, 15, 15);
+ evas_object_layer_set(rect, 100);
+ evas_object_show(rect);
+ rect_evas = n_evas;
+ }
+
+ switch (type)
+ {
+ case EXACTNESS_ACTION_MOUSE_IN:
+ {
+ INF("Mouse in\n");
+ DBG("%s evas_event_feed_mouse_in n_evas=<%d>\n", __func__, n_evas);
+ if (e) evas_event_feed_mouse_in(e, time(NULL), NULL);
+ break;
+ }
+ case EXACTNESS_ACTION_MOUSE_OUT:
+ {
+ INF("Mouse out\n");
+ DBG("%s evas_event_feed_mouse_out n_evas=<%d>\n", __func__, n_evas);
+ if (e) evas_event_feed_mouse_out(e, time(NULL), NULL);
+ break;
+ }
+ case EXACTNESS_ACTION_MOUSE_WHEEL:
+ {
+ Exactness_Action_Mouse_Wheel *t = data;
+ INF("Mouse wheel\n");
+ DBG("%s evas_event_feed_mouse_wheel n_evas=<%d>\n", __func__, n_evas);
+ if (e) evas_event_feed_mouse_wheel(e, t->direction, t->z, time(NULL), NULL);
+
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_DOWN:
+ {
+ Exactness_Action_Multi_Event *t = data;
+ DBG("%s evas_event_feed_multi_down n_evas=<%d>\n", __func__, n_evas);
+ if (!t->d)
+ {
+ if (e) evas_event_feed_mouse_down(e, t->b, t->flags, time(NULL), NULL);
+ if (rect) evas_object_color_set(rect, 255, 255, 0, 255);
+ }
+ else
+ {
+ if (e) evas_event_feed_multi_down(e,
+ t->d, t->x, t->y, t->rad,
+ t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
+ t->flags, time(NULL), NULL);
+ }
+
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_UP:
+ {
+ Exactness_Action_Multi_Event *t = data;
+ DBG("%s evas_event_feed_multi_up n_evas=<%d>\n", __func__, n_evas);
+ if (!t->d)
+ {
+ if (e) evas_event_feed_mouse_up(e, t->b, t->flags, time(NULL), NULL);
+ if (rect) evas_object_color_set(rect, 255, 0, 0, 255);
+ }
+ else
+ {
+ if (e) evas_event_feed_multi_up(e,
+ t->d, t->x, t->y, t->rad,
+ t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
+ t->flags, time(NULL), NULL);
+ }
+
+ break;
+ }
+ case EXACTNESS_ACTION_MULTI_MOVE:
+ {
+ Exactness_Action_Multi_Move *t = data;
+ DBG("%s evas_event_feed_multi_move n_evas=<%d>\n", __func__, n_evas);
+ if (!t->d)
+ {
+ if (e) evas_event_feed_mouse_move(e, t->x, t->y, time(NULL), NULL);
+ if (rect)
+ {
+ evas_object_move(rect, t->x, t->y);
+ evas_object_color_set(rect, 255, 0, 0, 255);
+ }
+ }
+ else
+ {
+ if (e) evas_event_feed_multi_move(e,
+ t->d, t->x, t->y, t->rad,
+ t->radx, t->rady, t->pres, t->ang, t->fx, t->fy,
+ time(NULL), NULL);
+ }
+
+ break;
+ }
+ case EXACTNESS_ACTION_KEY_DOWN:
+ {
+ Exactness_Action_Key_Down_Up *t = data;
+ DBG("%s evas_event_feed_key_down n_evas=<%d>\n", __func__, n_evas);
+ if (e)
+ evas_event_feed_key_down_with_keycode(e,
+ t->keyname, t->key, t->string,
+ t->compose, time(NULL), NULL, t->keycode);
+ break;
+ }
+ case EXACTNESS_ACTION_KEY_UP:
+ {
+ Exactness_Action_Key_Down_Up *t = data;
+ DBG("%s evas_event_feed_key_up n_evas=<%d>\n", __func__, n_evas);
+ if (e) evas_event_feed_key_up_with_keycode(e,
+ t->keyname, t->key, t->string,
+ t->compose, time(NULL), NULL, t->keycode);
+
+ break;
+ }
+ case EXACTNESS_ACTION_TAKE_SHOT:
+ {
+ DBG("%s take shot n_evas=<%d>\n", __func__, n_evas);
+ if (rect) evas_object_color_set(rect, 0, 0, 255, 255);
+ _cur_shot_id++;
+ if (_dest_type != FTYPE_UNKNOWN && e) _shot_do(e);
+ break;
+ }
+ case EXACTNESS_ACTION_EFL_EVENT:
+ {
+ Exactness_Action_Efl_Event *t = data;
+ Eina_Bool found = EINA_FALSE;
+ Eina_List *itr;
+ EINA_LIST_FOREACH(_evas_list, itr, e)
+ {
+ Eo *o = efl_name_find(e, t->wdg_name);
+ if (o)
+ {
+ DBG("%s EFL event invoke %s on %s\n",
+ __func__, t->event_name, t->wdg_name);
+ Efl_Event_Description d;
+ found = EINA_TRUE;
+ memset(&d, 0, sizeof(d));
+ d.name = t->event_name;
+ d.legacy_is = EINA_TRUE;
+ efl_event_callback_legacy_call(o, &d, NULL);
+ }
+ }
+ if (!found) fprintf(stderr, "Failed finding %s.\n", t->wdg_name);
+ break;
+ }
+ case EXACTNESS_ACTION_CLICK_ON:
+ {
+ Exactness_Action_Click_On *t = data;
+ Eina_List *itr;
+ Eo *o;
+ n_evas = 0;
+ EINA_LIST_FOREACH(_evas_list, itr, e)
+ {
+ o = efl_name_find(e, t->wdg_name);
+ if (o) goto wdg_found;
+ n_evas++;
+ }
+ o = NULL;
+wdg_found:
+ if (o)
+ {
+ Eina_Size2D sz = efl_gfx_entity_size_get(o);
+ Eina_Position2D pos = efl_gfx_entity_position_get(o);
+ int x = pos.x + (sz.w / 2);
+ int y = pos.y + (sz.h / 2);
+ Exactness_Action_Multi_Move *d_move = calloc(1, sizeof(*d_move));
+ Exactness_Action_Multi_Event *d_event = calloc(1, sizeof(*d_event));
+ Exactness_Action *act, *prev_act = eina_list_data_get(_cur_event_list);
+
+ DBG("%s click on %s\n", __func__, t->wdg_name);
+ act = calloc(1, sizeof(*act));
+ act->type = EXACTNESS_ACTION_MULTI_MOVE;
+ act->delay_ms = 100;
+ act->n_evas = n_evas;
+ act->data = d_move;
+ d_move->x = x;
+ d_move->y = y;
+ _cur_event_list = eina_list_append_relative(_cur_event_list,
+ act, prev_act);
+ prev_act = act;
+
+ act = calloc(1, sizeof(*act));
+ act->type = EXACTNESS_ACTION_MULTI_DOWN;
+ act->delay_ms = 100;
+ act->n_evas = n_evas;
+ act->data = d_event;
+ d_event->b = 1;
+ _cur_event_list = eina_list_append_relative(_cur_event_list,
+ act, prev_act);
+ prev_act = act;
+
+ act = calloc(1, sizeof(*act));
+ act->type = EXACTNESS_ACTION_MULTI_UP;
+ act->delay_ms = 100;
+ act->n_evas = n_evas;
+ d_event = calloc(1, sizeof(*d_event));
+ act->data = d_event;
+ d_event->b = 1;
+ _cur_event_list = eina_list_append_relative(_cur_event_list,
+ act, prev_act);
+ }
+ else fprintf(stderr, "Failed finding %s.\n", t->wdg_name);
+ break;
+ }
+ case EXACTNESS_ACTION_STABILIZE:
+ {
+ DBG("%s stabilize\n", __func__);
+ if (rect) evas_object_color_set(rect, 255, 165, 0, 255);
+ ecore_timer_add(0.1, _stabilization_timer_cb, NULL);
+ break;
+ }
+ default: /* All non-input events are not handeled */
+ break;
+ }
+}
+
+static Eina_Bool
+_feed_event_timer_cb(void *data EINA_UNUSED)
+{
+ if (_pause_request) return ECORE_CALLBACK_CANCEL;
+ Exactness_Action *act = eina_list_data_get(_cur_event_list);
+ if (act) _feed_event(act->type, act->n_evas, act->data);
+
+ _cur_event_list = eina_list_next(_cur_event_list);
+ if (!_cur_event_list)
+ { /* Finished reading all events */
+ _exit_required = EINA_TRUE;
+ if (!_shot_needed) ecore_main_loop_quit();
+ }
+ else
+ {
+ if (act && act->type != EXACTNESS_ACTION_STABILIZE)
+ {
+ act = eina_list_data_get(_cur_event_list);
+ if (act)
+ {
+ DBG(" %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0);
+ ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
+ }
+ }
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_stabilization_timer_cb(void *data EINA_UNUSED)
+{
+ Eina_List *itr;
+ Evas *e;
+#define STAB_MAX 5
+ static int need_more = STAB_MAX;
+ DBG("Not stable yet!\n");
+ EINA_LIST_FOREACH(_evas_list, itr, e)
+ {
+ if (!e) continue;
+ Exactness_Image *last_img = efl_key_data_get(e, "_last_stab_shot");
+ Exactness_Image *cur_img = _snapshot_shot_get(e);
+ if (!last_img || exactness_image_compare(last_img, cur_img, NULL)) need_more = STAB_MAX;
+ exactness_image_free(last_img);
+ efl_key_data_set(e, "_last_stab_shot", cur_img);
+ }
+ EINA_LIST_FOREACH(_evas_list, itr, e)
+ {
+ if (!need_more)
+ {
+ evas_object_del(efl_key_data_get(e, "_snapshot"));
+ efl_key_data_set(e, "_snapshot", NULL);
+ }
+ }
+ if (!need_more)
+ {
+ _playing_status = EINA_FALSE;
+ if (_src_type != FTYPE_REMOTE && !_pause_request)
+ {
+ Exactness_Action *act = eina_list_data_get(_cur_event_list);
+ if (act)
+ {
+ DBG(" %s timer_time=<%f>\n", __func__, act->delay_ms / 1000.0);
+ ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
+ }
+ }
+ need_more = STAB_MAX;
+ return ECORE_CALLBACK_CANCEL;
+ }
+ need_more--;
+ return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_main_loop_mouse_in_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ int n_evas = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_MOUSE_IN, n_evas, NULL);
+}
+
+static void
+_main_loop_mouse_out_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ int n_evas = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_MOUSE_OUT, n_evas, NULL);
+}
+
+static void
+_main_loop_mouse_wheel_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Mouse_Wheel t;
+ int n_evas = EXTRACT_INT(buf);
+ t.direction = EXTRACT_INT(buf);
+ t.z = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_MOUSE_WHEEL, n_evas, &t);
+}
+
+static void
+_main_loop_multi_down_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Multi_Event t;
+ int n_evas = EXTRACT_INT(buf);
+ t.d = EXTRACT_INT(buf);
+ t.b = EXTRACT_INT(buf);
+ t.x = EXTRACT_INT(buf);
+ t.y = EXTRACT_INT(buf);
+ t.rad = EXTRACT_DOUBLE(buf);
+ t.radx = EXTRACT_DOUBLE(buf);
+ t.rady = EXTRACT_DOUBLE(buf);
+ t.pres = EXTRACT_DOUBLE(buf);
+ t.ang = EXTRACT_DOUBLE(buf);
+ t.fx = EXTRACT_DOUBLE(buf);
+ t.fy = EXTRACT_DOUBLE(buf);
+ t.flags = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_MULTI_DOWN, n_evas, &t);
+}
+
+static void
+_main_loop_multi_up_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Multi_Event t;
+ int n_evas = EXTRACT_INT(buf);
+ t.d = EXTRACT_INT(buf);
+ t.b = EXTRACT_INT(buf);
+ t.x = EXTRACT_INT(buf);
+ t.y = EXTRACT_INT(buf);
+ t.rad = EXTRACT_DOUBLE(buf);
+ t.radx = EXTRACT_DOUBLE(buf);
+ t.rady = EXTRACT_DOUBLE(buf);
+ t.pres = EXTRACT_DOUBLE(buf);
+ t.ang = EXTRACT_DOUBLE(buf);
+ t.fx = EXTRACT_DOUBLE(buf);
+ t.fy = EXTRACT_DOUBLE(buf);
+ t.flags = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_MULTI_UP, n_evas, &t);
+}
+
+static void
+_main_loop_multi_move_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Multi_Move t;
+ int n_evas = EXTRACT_INT(buf);
+ t.d = EXTRACT_INT(buf);
+ t.x = EXTRACT_INT(buf);
+ t.y = EXTRACT_INT(buf);
+ t.rad = EXTRACT_DOUBLE(buf);
+ t.radx = EXTRACT_DOUBLE(buf);
+ t.rady = EXTRACT_DOUBLE(buf);
+ t.pres = EXTRACT_DOUBLE(buf);
+ t.ang = EXTRACT_DOUBLE(buf);
+ t.fx = EXTRACT_DOUBLE(buf);
+ t.fy = EXTRACT_DOUBLE(buf);
+ _feed_event(EXACTNESS_ACTION_MULTI_MOVE, n_evas, &t);
+}
+
+static void
+_main_loop_key_down_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Key_Down_Up t;
+ int n_evas = EXTRACT_INT(buf);
+ t.keyname = EXTRACT_STRING(buf);
+ t.key = EXTRACT_STRING(buf);
+ t.string = EXTRACT_STRING(buf);
+ t.compose = EXTRACT_STRING(buf);
+ t.keycode = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_KEY_DOWN, n_evas, &t);
+}
+
+static void
+_main_loop_key_up_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Key_Down_Up t;
+ int n_evas = EXTRACT_INT(buf);
+ t.keyname = EXTRACT_STRING(buf);
+ t.key = EXTRACT_STRING(buf);
+ t.string = EXTRACT_STRING(buf);
+ t.compose = EXTRACT_STRING(buf);
+ t.keycode = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_KEY_UP, n_evas, &t);
+}
+
+static void
+_main_loop_take_shot_cb(Eina_Debug_Session *session, int srcid, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ int n_evas = EXTRACT_INT(buf);
+ _feed_event(EXACTNESS_ACTION_TAKE_SHOT, n_evas, NULL);
+ _last_debug_session = session;
+ _last_debug_src_cid = srcid;
+}
+
+static void
+_main_loop_efl_event_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Efl_Event t;
+ t.wdg_name = EXTRACT_STRING(buf);
+ t.event_name = EXTRACT_STRING(buf);
+ _feed_event(EXACTNESS_ACTION_EFL_EVENT, 0, &t);
+}
+
+static void
+_main_loop_click_on_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer, int size EINA_UNUSED)
+{
+ char *buf = buffer;
+ Exactness_Action_Click_On t;
+ t.wdg_name = EXTRACT_STRING(buf);
+ _feed_event(EXACTNESS_ACTION_CLICK_ON, 0, &t);
+}
+
+static void
+_main_loop_stabilize_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
+{
+ _feed_event(EXACTNESS_ACTION_STABILIZE, 0, NULL);
+}
+
+static void
+_main_loop_finish_cb(Eina_Debug_Session *session EINA_UNUSED, int srcid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
+{
+ ecore_main_loop_quit();
+}
+
+WRAPPER_TO_XFER_MAIN_LOOP(_mouse_in_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_mouse_out_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_mouse_wheel_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_multi_down_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_multi_up_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_multi_move_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_key_down_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_key_up_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_take_shot_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_efl_event_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_click_on_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_stabilize_cb)
+WRAPPER_TO_XFER_MAIN_LOOP(_finish_cb)
+
+EINA_DEBUG_OPCODES_ARRAY_DEFINE(_debug_ops,
+ {"Exactness/Actions/Mouse In", NULL, &_mouse_in_cb},
+ {"Exactness/Actions/Mouse Out", NULL, &_mouse_out_cb},
+ {"Exactness/Actions/Mouse Wheel", NULL, &_mouse_wheel_cb},
+ {"Exactness/Actions/Multi Down", NULL, &_multi_down_cb},
+ {"Exactness/Actions/Multi Up", NULL, &_multi_up_cb},
+ {"Exactness/Actions/Multi Move", NULL, &_multi_move_cb},
+ {"Exactness/Actions/Key Down", NULL, &_key_down_cb},
+ {"Exactness/Actions/Key Up", NULL, &_key_up_cb},
+ {"Exactness/Actions/Take Shot", &_take_shot_op, &_take_shot_cb},
+ {"Exactness/Actions/EFL Event", NULL, &_efl_event_cb},
+ {"Exactness/Actions/Click On", NULL, &_click_on_cb},
+ {"Exactness/Actions/Stabilize", NULL, &_stabilize_cb},
+ {"Exactness/Actions/Finish", NULL, &_finish_cb},
+ {NULL, NULL, NULL}
+);
+
+static Eina_Bool
+_src_feed(void *data EINA_UNUSED)
+{
+ if (!_evas_list) return EINA_TRUE;
+ _cur_event_list = _src_unit->actions;
+ Exactness_Action *act = eina_list_data_get(_cur_event_list);
+
+ if (act && act->delay_ms)
+ {
+ DBG(" Waiting <%f>\n", act->delay_ms / 1000.0);
+ ecore_timer_add(act->delay_ms / 1000.0, _feed_event_timer_cb, NULL);
+ }
+ else
+ {
+ _feed_event_timer_cb(NULL);
+ }
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_src_open()
+{
+ if (_src_type != FTYPE_REMOTE)
+ {
+ Eina_List *itr, *itr2;
+ Exactness_Action *act;
+ DBG("<%s> Source file is <%s>\n", __func__, _src_filename);
+ if (_src_type == FTYPE_EXU)
+ {
+ _src_unit = exactness_unit_file_read(_src_filename);
+ _ready_to_write = EINA_TRUE;
+ }
+ if (!_src_unit) return EINA_FALSE;
+ if (_stabilize_shots)
+ {
+ Exactness_Action_Type last_action_type = EXACTNESS_ACTION_UNKNOWN;
+ EINA_LIST_FOREACH_SAFE(_src_unit->actions, itr, itr2, act)
+ {
+ if (act->type == EXACTNESS_ACTION_TAKE_SHOT &&
+ last_action_type != EXACTNESS_ACTION_STABILIZE)
+ {
+ Exactness_Action *act2 = calloc(1, sizeof(*act2));
+ act2->type = EXACTNESS_ACTION_STABILIZE;
+ _src_unit->actions = eina_list_prepend_relative(_src_unit->actions, act2, act);
+ }
+ last_action_type = act->type;
+ }
+ }
+ if (EINA_DBL_NONZERO(_speed) && (!EINA_DBL_EQ(_speed, 1)))
+ {
+ EINA_LIST_FOREACH(_src_unit->actions, itr, act)
+ act->delay_ms /= _speed;
+ }
+ }
+ else
+ {
+ eina_debug_opcodes_register(NULL, _debug_ops(), NULL, NULL);
+ }
+ return EINA_TRUE;
+}
+
+static void
+_old_shots_rm_cb(const char *name, const char *path, void *data)
+{
+ const char *prefix = data;
+ unsigned int len = strlen(prefix);
+ if (!strncmp(name, prefix, len) && (strlen(name) > len) && (name[len] == SHOT_DELIMITER))
+ {
+ unsigned int length = strlen(path) + strlen(name) + 2;
+ char *buf = alloca(length);
+ snprintf(buf, length, "%s/%s", path, name);
+ if (unlink(buf))
+ {
+ printf("Failed deleting '%s/%s': ", path, name);
+ perror("");
+ }
+ }
+}
+
+static void
+_evas_del_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Eina_List *p = eina_list_data_find_list(_evas_list, event->object);
+ eina_list_data_set(p, NULL);
+}
+
+static void
+_event_key_cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Efl_Input_Key *evk = event->info;
+ if (!evk) return;
+ const char *key = efl_input_key_name_get(evk);
+
+ if (!strcmp(key, PAUSE_KEY_STR) && efl_input_key_pressed_get(evk))
+ {
+ _pause_request = !_pause_request;
+ if (_pause_request) INF("Pausing scenario\n");
+ else
+ {
+ INF("Playing scenario\n");
+ if (!_playing_status)
+ _feed_event_timer_cb(NULL);
+ }
+ }
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(_evas_callbacks,
+ { EFL_EVENT_DEL, _evas_del_cb },
+ { EFL_CANVAS_SCENE_EVENT_RENDER_POST, _evas_render_post_cb },
+ { EFL_EVENT_KEY_DOWN, _event_key_cb },
+ { EFL_EVENT_KEY_UP, _event_key_cb }
+ )
+
+static Evas *
+_my_evas_new(int w EINA_UNUSED, int h EINA_UNUSED)
+{
+ Evas *e;
+ e = evas_new();
+ if (e)
+ {
+ INF("New Evas\n");
+ _evas_list = eina_list_append(_evas_list, e);
+ efl_event_callback_array_add(e, _evas_callbacks(), NULL);
+ }
+ return e;
+}
+
+static Eina_Bool
+_setup_dest_type(const char *dest, Eina_Bool external_injection)
+{
+ if (dest)
+ {
+ _dest = eina_stringshare_add(dest);
+ if (!strcmp(_dest + strlen(_dest) - 4,".exu"))
+ {
+ _dest_type = FTYPE_EXU;
+ char *path = ecore_file_dir_get(dest);
+
+ if (!ecore_file_mkpath(path))
+ {
+ fprintf(stderr, "Path for %s cannot be created\n", _dest);
+ free(path);
+ return EINA_FALSE;
+ }
+ free(path);
+ }
+ else
+ {
+ _dest_type = FTYPE_DIR;
+ if (!ecore_file_mkpath(_dest))
+ {
+ fprintf(stderr, "Directory %s cannot be created\n", _dest);
+ return EINA_FALSE;
+ }
+ }
+ }
+ if (external_injection)
+ {
+ _src_type = FTYPE_REMOTE;
+ if (_dest_type == FTYPE_UNKNOWN) _dest_type = FTYPE_REMOTE;
+ }
+ return EINA_TRUE;
+}
+
+static void
+_setup_names(const char *src)
+{
+ if (src)
+ {
+ _src_filename = eina_stringshare_add(src);
+ if (!strcmp(_src_filename + strlen(_src_filename) - 4,".exu"))
+ {
+ _src_type = FTYPE_EXU;
+ if (_dest_type == FTYPE_UNKNOWN)
+ {
+ _dest_type = FTYPE_EXU;
+ _dest = "./output.exu";
+ }
+ }
+ char *slash = strrchr(_src_filename, '/');
+ if (slash) _test_name = strdup(slash + 1);
+ else _test_name = strdup(_src_filename);
+ char *dot = strrchr(_test_name, '.');
+ if (dot) *dot = '\0';
+ }
+}
+
+static void
+_setup_dest_unit(void)
+{
+ if (_dest_type == FTYPE_EXU) _dest_unit = calloc(1, sizeof(*_dest_unit));
+
+}
+
+static void
+_remove_old_shots(void)
+{
+ if (_dest_type == FTYPE_DIR && _test_name)
+ eina_file_dir_list(_dest, 0, _old_shots_rm_cb, (void *)_test_name);
+}
+
+static Eina_Bool
+_setup_font_settings(const char *fonts_dir)
+{
+ const char *chosen_fonts = NULL;
+ if (_src_unit && _src_unit->fonts_path)
+ {
+ char buf[PATH_MAX];
+ if (!fonts_dir) fonts_dir = "./fonts";
+ snprintf(buf, PATH_MAX, "%s/%s", fonts_dir, _src_unit->fonts_path);
+ if (!ecore_file_exists(buf))
+ {
+ fprintf(stderr, "Unable to use the fonts path '%s' provided in %s\n",
+ _src_unit->fonts_path, _src_filename);
+ return EINA_FALSE;
+ }
+ chosen_fonts = _src_unit->fonts_path;
+ }
+ if (fonts_dir)
+ {
+ Eina_Tmpstr *fonts_conf_name = NULL;
+ if (!ecore_file_exists(fonts_dir))
+ {
+ fprintf(stderr, "Unable to find fonts directory %s\n", fonts_dir);
+ return EINA_FALSE;
+ }
+ if (!chosen_fonts)
+ {
+ Eina_List *dated_fonts = ecore_file_ls(fonts_dir);
+ char *date_dir;
+ chosen_fonts = eina_stringshare_add(eina_list_last_data_get(dated_fonts));
+ EINA_LIST_FREE(dated_fonts, date_dir) free(date_dir);
+ }
+ if (chosen_fonts)
+ {
+ int tmp_fd = eina_file_mkstemp("/tmp/fonts_XXXXXX.conf", &fonts_conf_name);
+ if (tmp_fd < 0) return EINA_FALSE;
+ FILE *tmp_f = fdopen(tmp_fd, "wb");
+ fprintf(tmp_f,
+ "<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig>\n"
+ "<dir prefix=\"default\">%s/%s</dir>\n</fontconfig>\n",
+ fonts_dir, chosen_fonts);
+ fclose(tmp_f);
+ close(tmp_fd);
+
+ setenv("FONTCONFIG_FILE", fonts_conf_name, 1);
+ }
+ }
+ return EINA_TRUE;
+}
+
+static void
+_setup_ee_creation(void)
+{
+ ecore_evas_callback_new_set(_my_evas_new);
+ if (_src_type != FTYPE_REMOTE)
+ ecore_idler_add(_src_feed, NULL);
+}
+
+static void
+_write_unit_file(void)
+{
+ if (_dest && _dest_unit && _ready_to_write)
+ {
+ Exactness_Unit *tmp = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN(_src_unit);
+ if (_src_type == FTYPE_EXU)
+ {
+ tmp = exactness_unit_file_read(_src_filename);
+ _dest_unit->actions = tmp->actions;
+ }
+ exactness_unit_file_write(_dest_unit, _dest);
+ }
+}
+#ifdef HAVE_DLSYM
+# define ORIGINAL_CALL_T(t, name, ...) \
+ t (*_original_init_cb)(); \
+ _original_init_cb = dlsym(RTLD_NEXT, name); \
+ original_return = _original_init_cb(__VA_ARGS__);
+#else
+# define ORIGINAL_CALL_T(t, name, ...) \
+ printf("THIS IS NOT SUPPORTED ON WINDOWS\n"); \
+ abort();
+#endif
+
+#define ORIGINAL_CALL(name, ...) \
+ ORIGINAL_CALL_T(int, name, __VA_ARGS__)
+
+EAPI int
+eina_init(void)
+{
+ int original_return;
+
+ ORIGINAL_CALL("eina_init");
+
+ ex_set_original_envvar();
+
+ if (original_return == 1)
+ {
+ const char *dest = getenv("EXACTNESS_DEST");
+ const char *external_injection = getenv("EXACTNESS_EXTERNAL_INJECTION");
+ const char *src = getenv("EXACTNESS_SRC");
+ const char *fonts_dir = getenv("EXACTNESS_FONTS_DIR");
+ const char *speed = getenv("EXACTNESS_SPEED");
+
+ _scan_objects = !!getenv("EXACTNESS_SCAN_OBJECTS");
+ _disable_shots = !!getenv("EXACTNESS_DISABLE_SHOTS");
+ _stabilize_shots = !!getenv("EXACTNESS_STABILIZE_SHOTS");
+ _verbose = !!getenv("EXACTNESS_VERBOSE");
+ if (speed)
+ _speed = atof(speed);
+
+ _log_domain = eina_log_domain_register("exactness_player", NULL);
+ if (!_setup_dest_type(dest, !!external_injection))
+ return 0;
+ _setup_names(src);
+ _setup_dest_unit();
+ _remove_old_shots();
+
+ if (!_src_open())
+ {
+ fprintf(stderr, "Unable to read source file\n");
+ return 0;
+ }
+ if (!_setup_font_settings(fonts_dir))
+ return 0;
+ }
+
+ return original_return;
+}
+
+EAPI int
+ecore_evas_init(void)
+{
+ int original_return;
+
+ ORIGINAL_CALL("ecore_evas_init")
+
+ if (ex_is_original_app() && original_return == 1)
+ {
+ _setup_ee_creation();
+ }
+
+ return original_return;
+}
+
+//hook, to hook in our theme
+EAPI int
+elm_init(int argc, char **argv)
+{
+ int original_return;
+ ORIGINAL_CALL("elm_init", argc, argv)
+
+ if (ex_is_original_app() && original_return == 1)
+ ex_prepare_elm_overlay();
+
+ return original_return;
+}
+
+EAPI void
+ecore_main_loop_begin(void)
+{
+ int original_return;
+ ORIGINAL_CALL("ecore_main_loop_begin")
+ if (ex_is_original_app())
+ _write_unit_file();
+ (void)original_return;
+}
+
+EAPI Eina_Value*
+efl_loop_begin(Eo *obj)
+{
+ Eina_Value *original_return;
+ ORIGINAL_CALL_T(Eina_Value*, "efl_loop_begin", obj);
+ if (ex_is_original_app())
+ _write_unit_file();
+ return original_return;
+}
+
+EAPI int
+eina_shutdown(void)
+{
+ int original_return;
+ static Eina_Bool output_written = EINA_FALSE;
+ ORIGINAL_CALL("eina_shutdown")
+ if (ex_is_original_app() &&original_return == 1 && !output_written)
+ {
+ output_written = EINA_TRUE;
+ _write_unit_file();
+ }
+
+ return original_return;
+}
diff --git a/src/bin/exactness/player_entry.edc b/src/bin/exactness/player_entry.edc
new file mode 100644
index 0000000000..0c1b907c10
--- /dev/null
+++ b/src/bin/exactness/player_entry.edc
@@ -0,0 +1,932 @@
+collections {
+ #include "../../../data/elementary/themes/fonts.edc"
+ group { name: "elm/entry/cursor/default";
+ min: 1 0;
+ images.image: "white_bar_vert_glow.png" COMP;
+ parts {
+ part { name: "cursor"; mouse_events: 0;
+ clip_to: "clipper";
+ description { state: "default" 0.0;
+ rel1.offset: -4 -4;
+ rel2.offset: 3 3;
+ image.normal: "white_bar_vert_glow.png";
+ image.border: 4 4 4 4;
+ fill.smooth: 0;
+ color: 255 255 255 0;
+ color_class: "entry_cursor";
+ min: 9 10;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part { name: "clipper"; type: RECT;
+ description { state: "default" 0.0;
+ rel1.to: "cursor";
+ rel2.to: "cursor";
+ fixed: 1 1;
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "selection,changed"; source: "elm.text";
+ action: STATE_SET "hidden" 0.0;
+ target: "clipper";
+ }
+ program {
+ signal: "selection,cleared"; source: "elm.text";
+ action: STATE_SET "default" 0.0;
+ target: "clipper";
+ }
+ program {
+ signal: "selection,reset"; source: "elm.text";
+ action: STATE_SET "default" 0.0;
+ target: "clipper";
+ }
+ program {
+ signal: "elm,action,focus"; source: "elm";
+ action: ACTION_STOP;
+ target: "cursor_show";
+ target: "cursor_hide";
+ target: "cursor_show_timer";
+ target: "cursor_hide_timer";
+ after: "cursor_show";
+ }
+ program {
+ signal: "elm,action,unfocus"; source: "elm";
+ action: ACTION_STOP;
+ target: "cursor_show";
+ target: "cursor_hide";
+ target: "cursor_show_timer";
+ target: "cursor_hide_timer";
+ after: "cursor_hide_stop";
+ }
+ program {
+ signal: "elm,action,show,cursor"; source: "elm";
+ action: ACTION_STOP;
+ target: "cursor_show";
+ target: "cursor_hide";
+ target: "cursor_show_timer";
+ target: "cursor_hide_timer";
+ after: "cursor_show";
+ }
+ program { name: "cursor_hide_stop";
+ action: STATE_SET "default" 0.0;
+ target: "cursor";
+ }
+ program { name: "cursor_show";
+ action: STATE_SET "default" 0.0;
+ target: "cursor";
+ after: "cursor_show_timer";
+ }
+ program { name: "cursor_hide";
+ action: STATE_SET "default" 0.0;
+ target: "cursor";
+ transition: SINUSOIDAL 0.2;
+ after: "cursor_hide_timer";
+ }
+ program { name: "cursor_show_timer";
+ in: 0.5 0.0;
+ after: "cursor_hide";
+ }
+ program { name: "cursor_hide_timer";
+ in: 0.2 0.0;
+ after: "cursor_show";
+ }
+ }
+ }
+
+ group { name: "elm/entry/selection/default";
+ parts {
+ part { name: "base"; type: RECT;
+ description { state: "default" 0.0;
+ color: 51 153 255 255;
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/anchor/default";
+ images.image: "horizontal_separated_bar_small_glow.png" COMP;
+ parts {
+ part { name: "bar";
+ description { state: "default" 0.0;
+ image.normal: "horizontal_separated_bar_small_glow.png";
+ image.border: 4 4 4 4;
+ fill.smooth: 0;
+ fixed: 0 1;
+ rel1.relative: 0.0 1.0;
+ rel1.offset: -3 -5;
+ rel2.offset: 2 4;
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base/default";
+ sounds {
+ sample { name: "key-tap1" LOSSY 64;
+ source: "kbd-tap.wav";
+ }
+ sample { name: "key-tap2" LOSSY 64;
+ source: "kbd-tap2.wav";
+ }
+ sample { name: "key-tap3" LOSSY 64;
+ source: "kbd-tap3.wav";
+ }
+ sample { name: "key-tap4" LOSSY 64;
+ source: "kbd-tap4.wav";
+ }
+ sample { name: "key-tap5" LOSSY 64;
+ source: "kbd-tap5.wav";
+ }
+ }
+
+ styles {
+ style { name: "entry_style";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=word text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_nowrap_style";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_disabled_style";
+ base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=word text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_nowrap_disabled_style";
+ base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_guide_style";
+ base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=word text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ }
+ // data.item: "context_menu_orientation" "horizontal";
+ parts {
+ part { name: "elm.swallow.background"; type: SWALLOW;
+ description { state: "default" 0.0;
+ rel1.offset: 1 1;
+ rel2.offset: -2 -2;
+ }
+ }
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_guide_style";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text"; type: TEXTBLOCK;
+ scale: 1;
+ entry_mode: EDITABLE;
+ select_mode: DEFAULT;
+ // select_mode: EXPLICIT;
+ cursor_mode: BEFORE;
+ multiline: 1;
+ source: "elm/entry/selection/default"; // selection under
+ // source2: "X"; // selection over
+ // source3: "X"; // cursor under
+ source4: "elm/entry/cursor/default"; // cursorover
+ // source5: "elm/entry/anchor/default"; // anchor under
+ source6: "elm/entry/anchor/default"; // anchor over
+ description { state: "default" 0.0;
+ /* we gotta use 0 0 here, because of scrolled entries */
+ fixed: 0 0;
+ rel1.offset: 2 2;
+ rel2.offset: -3 -3;
+ text { style: "entry_style";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style";
+ min: 0 1;
+ }
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "load"; source: "";
+ action: FOCUS_SET;
+ target: "elm.text";
+ }
+ program {
+ signal: "elm,state,disabled"; source: "elm";
+ action: STATE_SET "disabled" 0.0;
+ target: "elm.text";
+ }
+ program {
+ signal: "elm,state,enabled"; source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "elm.text";
+ }
+ program {
+ signal: "elm,guide,disabled"; source: "elm";
+ action: STATE_SET "hidden" 0.0;
+ target: "elm.guide";
+ }
+ program {
+ signal: "elm,guide,enabled"; source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "elm.guide";
+ }
+ program { name: "key-down";
+ signal: "entry,keydown"; source: "elm.text";
+ script {
+ new buf[32];
+ snprintf(buf, 31, "key-down%i", (rand() % 5) + 1);
+ run_program(get_program_id(buf));
+ }
+ }
+ program { name: "key-down1";
+ action: PLAY_SAMPLE "key-tap1" 1.0 INPUT;
+ }
+ program { name: "key-down2";
+ action: PLAY_SAMPLE "key-tap2" 1.0 INPUT;
+ }
+ program { name: "key-down3";
+ action: PLAY_SAMPLE "key-tap3" 1.0 INPUT;
+ }
+ program { name: "key-down4";
+ action: PLAY_SAMPLE "key-tap4" 1.0 INPUT;
+ }
+ program { name: "key-down5";
+ action: PLAY_SAMPLE "key-tap5" 1.0 INPUT;
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-mixedwrap/default";
+ inherit: "elm/entry/base/default";
+ styles {
+ style { name: "entry_style_mixedwrap";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=mixed text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_disabled_style_mixedwrap";
+ base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=mixed text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_guide_style_mixedwrap";
+ base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=mixed text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ }
+ parts {
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_guide_style_mixedwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text";
+ description { state: "default" 0.0;
+ fixed: 1 0;
+ text { style: "entry_style_mixedwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style_mixedwrap";
+ min: 0 1;
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-charwrap/default";
+ inherit: "elm/entry/base/default";
+ styles {
+ style { name: "entry_style_charwrap";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=char text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_disabled_style_charwrap";
+ base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=char text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_guide_style_charwrap";
+ base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=char text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ }
+ parts {
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_guide_style_charwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text";
+ description { state: "default" 0.0;
+ fixed: 1 1;
+ text { style: "entry_style_charwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style_charwrap";
+ min: 0 1;
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-nowrap/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_guide_style";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text";
+ description { state: "default" 0.0;
+ text { style: "entry_nowrap_style";
+ min: 1 1;
+ ellipsis: -1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_nowrap_disabled_style";
+ min: 0 1;
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-single/default";
+ inherit: "elm/entry/base/default";
+ styles {
+ style { name: "entry_single_style";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 wrap=none text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_single_disabled_style";
+ base: "font="FN" font_size=10 color=#151515 style=shadow,bottom shadow_color=#ffffff19 wrap=none text_class=entry_text_disabled color_class=entry_text_disabled left_margin=2 right_margin=2";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ style { name: "entry_single_guide_style";
+ base: "font="FN" font_size=10 color=#000000 style=shadow,bottom shadow_color=#ffffff19 wrap=none text_class=entry_guide_text color_class=entry_guide_text left_margin=2 right_margin=2 ellipsis=0.0";
+ DISABLED_TEXTBLOCK_TAGS
+ }
+ }
+ parts {
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_single_guide_style";
+ min: 0 1;
+ align: 0.0 0.5;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text";
+ multiline: 0;
+ description { state: "default" 0.0;
+ text { style: "entry_single_style";
+ min: 1 1;
+ ellipsis: -1;
+ max: 0 0;
+ align: 0.0 0.5;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_single_disabled_style";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-single/spinner/default";
+ alias: "elm/entry/base-single/spinner/vertical";
+ inherit: "elm/entry/base-single/default";
+ styles {
+ style { name: "entry_single_spinner_style";
+ base: "font="FN" font_size=10 color=#ffffff style=shadow,bottom shadow_color=#00000080 align=center wrap=none text_class=entry_text color_class=entry_text left_margin=2 right_margin=2";
+ ENABLED_TEXTBLOCK_TAGS
+ }
+ }
+ parts {
+ part { name: "elm.text";
+ description { state: "default" 0.0;
+ text.style: "entry_single_spinner_style";
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-single-noedit/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.text";
+ entry_mode: PLAIN;
+ multiline: 0;
+ source: "elm/entry/selection/default"; // selection under
+ source4: ""; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor over
+ description { state: "default" 0.0;
+ text { style: "entry_single_style";
+ min: 1 1;
+ ellipsis: -1;
+ max: 0 0;
+ align: 0.0 0.5;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_single_disabled_style";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-noedit/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.text";
+ entry_mode: PLAIN;
+ source: "elm/entry/selection/default"; // selection under
+ source4: ""; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor over
+ description { state: "default" 0.0;
+ fixed: 1 0;
+ text { style: "entry_style";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-noedit-mixedwrap/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.text";
+ entry_mode: PLAIN;
+ source: "elm/entry/selection/default"; // selection under
+ source4: ""; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor over
+ description { state: "default" 0.0;
+ fixed: 1 0;
+ text { style: "entry_style_mixedwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style_mixedwrap";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-noedit-charwrap/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.text";
+ entry_mode: PLAIN;
+ source: "elm/entry/selection/default"; // selection under
+ source4: ""; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor under
+ description { state: "default" 0.0;
+ fixed: 1 0;
+ text { style: "entry_style_charwrap";
+ min: 0 1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style_charwrap";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-nowrap-noedit/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.text";
+ entry_mode: PLAIN;
+ source: "elm/entry/selection/default"; // selection under
+ source4: ""; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor under
+ description { state: "default" 0.0;
+ text { style: "entry_style";
+ min: 1 1;
+ ellipsis: -1;
+ align: 0.0 0.0;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_disabled_style";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/base-password/default";
+ inherit: "elm/entry/base/default";
+ parts {
+ part { name: "elm.guide"; type: TEXTBLOCK; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ rel1.to: "elm.text";
+ rel2.to: "elm.text";
+ text { style: "entry_single_guide_style";
+ min: 0 1;
+ align: 0.0 0.5;
+ }
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.text";
+ entry_mode: PASSWORD;
+ multiline: 0;
+ source: "elm/entry/selection/default"; // selection under
+ source4: "elm/entry/cursor/default"; // cursorover
+ source6: "elm/entry/anchor/default"; // anchor under
+ description { state: "default" 0.0;
+ text { style: "entry_single_style";
+ repch: "*";
+ min: 1 1;
+ ellipsis: -1;
+ max: 0 0;
+ align: 0.0 0.5;
+ }
+ }
+ description { state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ text { style: "entry_single_disabled_style";
+ }
+ }
+ }
+ }
+ }
+
+ group { name: "elm/entry/magnifier/default";
+ images.image: "frame_rounded.png" COMP;
+ parts {
+ part { name: "bg"; type: RECT; mouse_events: 0;
+ description { state: "default" 0.0;
+ rel1.offset: 10 10;
+ rel1.to: "over";
+ rel2.offset: -11 -11;
+ rel2.to: "over";
+ color: 48 48 48 255;
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "elm.swallow.content"; type: SWALLOW; mouse_events: 0;
+ description { state: "default" 0.0;
+ rel1.offset: 10 10;
+ rel1.to: "over";
+ rel2.offset: -11 -11;
+ rel2.to: "over";
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ part { name: "over"; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 128 64;
+ align: 0 0;
+ image.normal: "frame_rounded.png";
+ image.border: 14 14 14 14;
+ image.middle: 0;
+ fill.smooth: 0;
+ }
+ description { state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+ }
+ programs {
+ program { name: "magnifier_show";
+ signal: "elm,action,show,magnifier"; source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "elm.swallow.content";
+ target: "bg";
+ target: "over";
+ }
+ program { name: "magnifier_hide";
+ signal: "elm,action,hide,magnifier"; source: "elm";
+ action: STATE_SET "hidden" 0.0;
+ target: "elm.swallow.content";
+ target: "bg";
+ target: "over";
+ }
+ }
+ }
+
+ group { name: "elm/entry/handler/start/default";
+ images.image: "handle_pick_up_left.png" COMP;
+ parts {
+ part { name: "base"; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 21 27; // 42 54
+ image.normal: "handle_pick_up_left.png";
+ align: (29/42) (11/54);
+ color_class: "entry_selection_handler";
+ visible: 0;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+ part { name: "event"; type: RECT;
+ scale: 1;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.to: "base";
+ rel2.to: "base";
+ min: 32 32;
+ visible: 0;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "elm,handler,show"; source: "elm";
+ action: STATE_SET "visible" 0.0;
+ target: "base";
+ target: "event";
+ }
+ program {
+ signal: "elm,handler,hide"; source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "base";
+ target: "event";
+ }
+ }
+ }
+
+ group { name: "elm/entry/handler/end/default";
+ images.image: "handle_pick_up_right.png" COMP;
+ parts {
+ part { name: "base"; mouse_events: 0;
+ scale: 1;
+ description { state: "default" 0.0;
+ min: 21 27; // 42 54
+ image.normal: "handle_pick_up_right.png";
+ align: (12/42) (11/54);
+ color_class: "entry_selection_handler";
+ visible: 0;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+ part { name: "event"; type: RECT;
+ scale: 1;
+ description { state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.to: "base";
+ rel2.to: "base";
+ min: 32 32;
+ visible: 0;
+ }
+ description { state: "visible" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+ }
+ programs {
+ program {
+ signal: "elm,handler,show"; source: "elm";
+ action: STATE_SET "visible" 0.0;
+ target: "base";
+ target: "event";
+ }
+ program {
+ signal: "elm,handler,hide"; source: "elm";
+ action: STATE_SET "default" 0.0;
+ target: "base";
+ target: "event";
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // emoticon images from:
+ // Tanya - Latvia
+ // http://lazycrazy.deviantart.com/
+ // http://lazycrazy.deviantart.com/art/Very-Emotional-Emoticons-144461621
+ group { name: "elm/entry/emoticon/angry/default"; images.image:
+ "emo-angry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-angry.png"; } } } }
+ group { name: "elm/entry/emoticon/angry-shout/default"; images.image:
+ "emo-angry-shout.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-angry-shout.png"; } } } }
+ group { name: "elm/entry/emoticon/crazy-laugh/default"; images.image:
+ "emo-crazy-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-crazy-laugh.png"; } } } }
+ group { name: "elm/entry/emoticon/evil-laugh/default"; images.image:
+ "emo-evil-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-evil-laugh.png"; } } } }
+ group { name: "elm/entry/emoticon/evil/default"; images.image:
+ "emo-evil.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-evil.png"; } } } }
+ group { name: "elm/entry/emoticon/goggle-smile/default"; images.image:
+ "emo-goggle-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-goggle-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/grumpy/default"; images.image:
+ "emo-grumpy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-grumpy.png"; } } } }
+ group { name: "elm/entry/emoticon/grumpy-smile/default"; images.image:
+ "emo-grumpy-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-grumpy-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/guilty/default"; images.image:
+ "emo-guilty.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-guilty.png"; } } } }
+ group { name: "elm/entry/emoticon/guilty-smile/default"; images.image:
+ "emo-guilty-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-guilty-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/haha/default"; images.image:
+ "emo-haha.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-haha.png"; } } } }
+ group { name: "elm/entry/emoticon/half-smile/default"; images.image:
+ "emo-half-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-half-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/happy-panting/default"; images.image:
+ "emo-happy-panting.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-happy-panting.png"; } } } }
+ group { name: "elm/entry/emoticon/happy/default"; images.image:
+ "emo-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-happy.png"; } } } }
+ group { name: "elm/entry/emoticon/indifferent/default"; images.image:
+ "emo-indifferent.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-indifferent.png"; } } } }
+ group { name: "elm/entry/emoticon/kiss/default"; images.image:
+ "emo-kiss.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-kiss.png"; } } } }
+ group { name: "elm/entry/emoticon/knowing-grin/default"; images.image:
+ "emo-knowing-grin.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-knowing-grin.png"; } } } }
+ group { name: "elm/entry/emoticon/laugh/default"; images.image:
+ "emo-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-laugh.png"; } } } }
+ group { name: "elm/entry/emoticon/little-bit-sorry/default"; images.image:
+ "emo-little-bit-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-little-bit-sorry.png"; } } } }
+ group { name: "elm/entry/emoticon/love-lots/default"; images.image:
+ "emo-love-lots.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-love-lots.png"; } } } }
+ group { name: "elm/entry/emoticon/love/default"; images.image:
+ "emo-love.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-love.png"; } } } }
+ group { name: "elm/entry/emoticon/minimal-smile/default"; images.image:
+ "emo-minimal-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-minimal-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/not-happy/default"; images.image:
+ "emo-not-happy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-not-happy.png"; } } } }
+ group { name: "elm/entry/emoticon/not-impressed/default"; images.image:
+ "emo-not-impressed.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-not-impressed.png"; } } } }
+ group { name: "elm/entry/emoticon/omg/default"; images.image:
+ "emo-omg.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-omg.png"; } } } }
+ group { name: "elm/entry/emoticon/opensmile/default"; images.image:
+ "emo-opensmile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-opensmile.png"; } } } }
+ group { name: "elm/entry/emoticon/smile/default"; images.image:
+ "emo-smile.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-smile.png"; } } } }
+ group { name: "elm/entry/emoticon/sorry/default"; images.image:
+ "emo-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-sorry.png"; } } } }
+ group { name: "elm/entry/emoticon/squint-laugh/default"; images.image:
+ "emo-squint-laugh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-squint-laugh.png"; } } } }
+ group { name: "elm/entry/emoticon/surprised/default"; images.image:
+ "emo-surprised.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-surprised.png"; } } } }
+ group { name: "elm/entry/emoticon/suspicious/default"; images.image:
+ "emo-suspicious.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-suspicious.png"; } } } }
+ group { name: "elm/entry/emoticon/tongue-dangling/default"; images.image:
+ "emo-tongue-dangling.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-tongue-dangling.png"; } } } }
+ group { name: "elm/entry/emoticon/tongue-poke/default"; images.image:
+ "emo-tongue-poke.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-tongue-poke.png"; } } } }
+ group { name: "elm/entry/emoticon/uh/default"; images.image:
+ "emo-uh.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-uh.png"; } } } }
+ group { name: "elm/entry/emoticon/unhappy/default"; images.image:
+ "emo-unhappy.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-unhappy.png"; } } } }
+ group { name: "elm/entry/emoticon/very-sorry/default"; images.image:
+ "emo-very-sorry.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-very-sorry.png"; } } } }
+ group { name: "elm/entry/emoticon/what/default"; images.image:
+ "emo-what.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-what.png"; } } } }
+ group { name: "elm/entry/emoticon/wink/default"; images.image:
+ "emo-wink.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-wink.png"; } } } }
+ group { name: "elm/entry/emoticon/worried/default"; images.image:
+ "emo-worried.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-worried.png"; } } } }
+ group { name: "elm/entry/emoticon/wtf/default"; images.image:
+ "emo-wtf.png" COMP; parts { part { name: "icon"; mouse_events: 0; description { state: "default" 0.0; max: 64 64; image.normal:
+ "emo-wtf.png"; } } } }
+ //------------------------------------------------------------
+}
diff --git a/src/bin/exactness/recorder.c b/src/bin/exactness/recorder.c
new file mode 100644
index 0000000000..6936521d7a
--- /dev/null
+++ b/src/bin/exactness/recorder.c
@@ -0,0 +1,397 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#ifdef HAVE_DLSYM
+# include <dlfcn.h>
+#endif
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_SYSINFO_H
+# include <sys/sysinfo.h>
+#endif
+
+#include <Eina.h>
+#include <Eo.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <Ecore_File.h>
+#include <Ecore_Getopt.h>
+#include <Ecore_Con.h>
+#include <Elementary.h>
+
+#include "common.h"
+
+#define STABILIZE_KEY_STR "F1"
+#define SHOT_KEY_STR "F2"
+#define SAVE_KEY_STR "F3"
+
+#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
+
+static int _log_domain = -1;
+
+static const char *_out_filename = NULL;
+
+static Eina_List *_evas_list = NULL;
+static unsigned int _last_evas_id = 0;
+
+static Exactness_Unit *_unit = NULL;
+
+static char *_shot_key = NULL;
+static unsigned int _last_timestamp = 0.0;
+
+static Exactness_Action_Type
+_event_pointer_type_get(Efl_Pointer_Action t)
+{
+ switch(t)
+ {
+ case EFL_POINTER_ACTION_IN: return EXACTNESS_ACTION_MOUSE_IN;
+ case EFL_POINTER_ACTION_OUT: return EXACTNESS_ACTION_MOUSE_OUT;
+ case EFL_POINTER_ACTION_DOWN: return EXACTNESS_ACTION_MULTI_DOWN;
+ case EFL_POINTER_ACTION_UP: return EXACTNESS_ACTION_MULTI_UP;
+ case EFL_POINTER_ACTION_MOVE: return EXACTNESS_ACTION_MULTI_MOVE;
+ case EFL_POINTER_ACTION_WHEEL: return EXACTNESS_ACTION_MOUSE_WHEEL;
+ default: return EXACTNESS_ACTION_UNKNOWN;
+ }
+}
+
+static void
+_output_write()
+{
+ if (_unit) exactness_unit_file_write(_unit, _out_filename);
+}
+
+static void
+_add_to_list(Exactness_Action_Type type, unsigned int n_evas, unsigned int timestamp, void *data, int len)
+{
+ if (_unit)
+ {
+ const Exactness_Action *prev_v = eina_list_last_data_get(_unit->actions);
+ if (prev_v)
+ {
+ if (prev_v->type == type &&
+ timestamp == _last_timestamp &&
+ prev_v->n_evas == n_evas &&
+ (!len || !memcmp(prev_v->data, data, len))) return;
+ }
+ INF("Recording %s\n", _exactness_action_type_to_string_get(type));
+ Exactness_Action *act = malloc(sizeof(*act));
+ act->type = type;
+ act->n_evas = n_evas;
+ act->delay_ms = timestamp - _last_timestamp;
+ _last_timestamp = timestamp;
+ if (len)
+ {
+ act->data = malloc(len);
+ memcpy(act->data, data, len);
+ }
+ _unit->actions = eina_list_append(_unit->actions, act);
+ }
+}
+
+static int
+_evas_id_get(Evas *e)
+{
+ return (intptr_t)efl_key_data_get(e, "__evas_id");
+}
+
+static void
+_event_pointer_cb(void *data, const Efl_Event *event)
+{
+ Eo *eo_e = data;
+ Eo *evp = event->info;
+ if (!evp) return;
+
+ int timestamp = efl_input_timestamp_get(evp);
+ int n_evas = _evas_id_get(eo_e);
+ Efl_Pointer_Action action = efl_input_pointer_action_get(evp);
+ Exactness_Action_Type evt = _event_pointer_type_get(action);
+
+ if (!timestamp) return;
+
+ DBG("Calling \"%s\" timestamp=<%u>\n", _exactness_action_type_to_string_get(evt), timestamp);
+
+ switch (action)
+ {
+ case EFL_POINTER_ACTION_MOVE:
+ {
+ double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0;
+ int tool = efl_input_pointer_touch_id_get(evp);
+ Eina_Position2D pos = efl_input_pointer_position_get(evp);
+ Exactness_Action_Multi_Move t = { tool, pos.x, pos.y, rad, radx, rady, pres, ang, fx, fy };
+ if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(t));
+ break;
+ }
+ case EFL_POINTER_ACTION_DOWN:
+ case EFL_POINTER_ACTION_UP:
+ {
+ double rad = 0, radx = 0, rady = 0, pres = 0, ang = 0, fx = 0, fy = 0;
+ int b = efl_input_pointer_button_get(evp);
+ int tool = efl_input_pointer_touch_id_get(evp);
+ Eina_Position2D pos = efl_input_pointer_position_get(evp);
+ Efl_Pointer_Flags flags = efl_input_pointer_button_flags_get(evp);
+ Exactness_Action_Multi_Event t = { tool, b, pos.x, pos.y, rad, radx, rady, pres, ang,
+ fx, fy, (Evas_Button_Flags)flags };
+ if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(t));
+ break;
+ }
+ case EFL_POINTER_ACTION_IN:
+ case EFL_POINTER_ACTION_OUT:
+ {
+ if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, NULL, 0);
+ break;
+ }
+ case EFL_POINTER_ACTION_WHEEL:
+ {
+ Eina_Bool horiz = efl_input_pointer_wheel_horizontal_get(evp);
+ int z = efl_input_pointer_wheel_delta_get(evp);
+ Exactness_Action_Mouse_Wheel t = { horiz, z };
+ if (n_evas >= 0) _add_to_list(evt, n_evas, timestamp, &t, sizeof(t));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+_event_key_cb(void *data, const Efl_Event *event)
+{
+ Efl_Input_Key *evk = event->info;
+ Eo *eo_e = data;
+ if (!evk) return;
+ const char *key = efl_input_key_name_get(evk);
+ int timestamp = efl_input_timestamp_get(evk);
+ unsigned int n_evas = _evas_id_get(eo_e);
+ Exactness_Action_Type evt = EXACTNESS_ACTION_KEY_UP;
+
+ if (efl_input_key_pressed_get(evk))
+ {
+ if (!strcmp(key, _shot_key))
+ {
+ DBG("Take Screenshot: %s timestamp=<%u>\n", __func__, timestamp);
+ _add_to_list(EXACTNESS_ACTION_TAKE_SHOT, n_evas, timestamp, NULL, 0);
+ return;
+ }
+ if (!strcmp(key, STABILIZE_KEY_STR))
+ {
+ DBG("Stabilize: %s timestamp=<%u>\n", __func__, timestamp);
+ _add_to_list(EXACTNESS_ACTION_STABILIZE, n_evas, timestamp, NULL, 0);
+ return;
+ }
+ if (!strcmp(key, SAVE_KEY_STR))
+ {
+ _output_write();
+ DBG("Save events: %s timestamp=<%u>\n", __func__, timestamp);
+ return;
+ }
+ evt = EXACTNESS_ACTION_KEY_DOWN;
+ }
+ else
+ {
+ if (!strcmp(key, _shot_key) || !strcmp(key, SAVE_KEY_STR) || !strcmp(key, STABILIZE_KEY_STR)) return;
+ }
+ if (_unit)
+ { /* Construct duplicate strings, free them when list if freed */
+ Exactness_Action_Key_Down_Up t;
+ t.keyname = eina_stringshare_add(key);
+ t.key = eina_stringshare_add(efl_input_key_sym_get(evk));
+ t.string = eina_stringshare_add(efl_input_key_string_get(evk));
+ t.compose = eina_stringshare_add(efl_input_key_compose_string_get(evk));
+ t.keycode = efl_input_key_code_get(evk);
+ _add_to_list(evt, n_evas, timestamp, &t, sizeof(t));
+ }
+}
+
+// note: "hold" event comes from above (elm), not below (ecore)
+EFL_CALLBACKS_ARRAY_DEFINE(_event_pointer_callbacks,
+ { EFL_EVENT_POINTER_MOVE, _event_pointer_cb },
+ { EFL_EVENT_POINTER_DOWN, _event_pointer_cb },
+ { EFL_EVENT_POINTER_UP, _event_pointer_cb },
+ { EFL_EVENT_POINTER_IN, _event_pointer_cb },
+ { EFL_EVENT_POINTER_OUT, _event_pointer_cb },
+ { EFL_EVENT_POINTER_WHEEL, _event_pointer_cb },
+ { EFL_EVENT_FINGER_MOVE, _event_pointer_cb },
+ { EFL_EVENT_FINGER_DOWN, _event_pointer_cb },
+ { EFL_EVENT_FINGER_UP, _event_pointer_cb },
+ { EFL_EVENT_KEY_DOWN, _event_key_cb },
+ { EFL_EVENT_KEY_UP, _event_key_cb }
+ )
+
+static Evas *
+_my_evas_new(int w EINA_UNUSED, int h EINA_UNUSED)
+{
+ Evas *e;
+ e = evas_new();
+ if (e)
+ {
+ INF("New Evas\n");
+ _evas_list = eina_list_append(_evas_list, e);
+ efl_key_data_set(e, "__evas_id", (void *)(intptr_t)_last_evas_id++);
+ efl_event_callback_array_add(e, _event_pointer_callbacks(), e);
+ }
+ return e;
+}
+
+static void
+_setup_unit(void)
+{
+ if (_unit) return;
+
+ _unit = calloc(1, sizeof(*_unit));
+}
+
+static Eina_Bool
+_setup_fonts_dir(const char *fonts_dir)
+{
+ if (fonts_dir)
+ {
+ Eina_Tmpstr *fonts_conf_name = NULL;
+ if (!ecore_file_exists(fonts_dir))
+ {
+ fprintf(stderr, "Unable to find fonts directory %s\n", fonts_dir);
+ return EINA_FALSE;
+ }
+ Eina_List *dated_fonts = ecore_file_ls(fonts_dir);
+ char *date_dir;
+ _unit->fonts_path = strdup(eina_list_last_data_get(dated_fonts));
+ EINA_LIST_FREE(dated_fonts, date_dir) free(date_dir);
+ if (_unit->fonts_path)
+ {
+ int tmp_fd = eina_file_mkstemp("/tmp/fonts_XXXXXX.conf", &fonts_conf_name);
+ if (tmp_fd < 0) return EINA_FALSE;
+ FILE *tmp_f = fdopen(tmp_fd, "wb");
+ fprintf(tmp_f,
+ "<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig>\n"
+ "<dir prefix=\"default\">%s/%s</dir>\n</fontconfig>\n",
+ fonts_dir, _unit->fonts_path);
+ fclose(tmp_f);
+ close(tmp_fd);
+
+ setenv("FONTCONFIG_FILE", fonts_conf_name, 1);
+ }
+ }
+ return EINA_TRUE;
+}
+
+static void
+_setup_shot_key(void)
+{
+ if (!_shot_key) _shot_key = getenv("SHOT_KEY");
+ if (!_shot_key) _shot_key = SHOT_KEY_STR;
+}
+
+static void
+_setup_ee_creation(void)
+{
+ ecore_evas_callback_new_set(_my_evas_new);
+ _last_timestamp = ecore_time_get() * 1000;
+}
+
+#ifdef HAVE_DLSYM
+# define ORIGINAL_CALL_T(t, name, ...) \
+ t (*_original_init_cb)(); \
+ _original_init_cb = dlsym(RTLD_NEXT, name); \
+ original_return = _original_init_cb(__VA_ARGS__);
+#else
+# define ORIGINAL_CALL_T(t, name, ...) \
+ printf("THIS IS NOT SUPPORTED ON WINDOWS\n"); \
+ abort();
+#endif
+
+#define ORIGINAL_CALL(name, ...) \
+ ORIGINAL_CALL_T(int, name, __VA_ARGS__)
+
+EAPI int
+eina_init(void)
+{
+ int original_return;
+
+ ORIGINAL_CALL("eina_init");
+
+ ex_set_original_envvar();
+
+ if (ex_is_original_app() && original_return == 1)
+ {
+ _log_domain = eina_log_domain_register("exactness_recorder", NULL);
+
+ _out_filename = getenv("EXACTNESS_DEST");
+ _setup_unit();
+ if (!_setup_fonts_dir(getenv("EXACTNESS_FONTS_DIR")))
+ return -1;
+
+ _setup_shot_key();
+ }
+
+ return original_return;
+}
+
+EAPI int
+ecore_evas_init(void)
+{
+ int original_return;
+
+ ORIGINAL_CALL("ecore_evas_init")
+
+ if (ex_is_original_app() && original_return == 1)
+ {
+ _setup_ee_creation();
+
+ }
+
+ return original_return;
+}
+
+//hook, to hook in our theme
+EAPI int
+elm_init(int argc, char **argv)
+{
+ int original_return;
+ ORIGINAL_CALL("elm_init", argc, argv)
+
+ if (ex_is_original_app() && original_return == 1)
+ ex_prepare_elm_overlay();
+
+ return original_return;
+}
+
+EAPI void
+ecore_main_loop_begin(void)
+{
+ int original_return;
+ ORIGINAL_CALL("ecore_main_loop_begin")
+ if (ex_is_original_app())
+ _output_write();
+ (void)original_return;
+}
+
+EAPI Eina_Value*
+efl_loop_begin(Eo *obj)
+{
+ Eina_Value *original_return;
+ ORIGINAL_CALL_T(Eina_Value*, "efl_loop_begin", obj);
+ if (ex_is_original_app())
+ _output_write();
+ return original_return;
+}
+
+EAPI int
+eina_shutdown(void)
+{
+ int original_return;
+ static Eina_Bool output_written = EINA_FALSE;
+ ORIGINAL_CALL("eina_shutdown")
+ if (ex_is_original_app() && original_return == 1 && !output_written)
+ {
+ output_written = EINA_TRUE;
+ _output_write();
+ }
+
+ return original_return;
+}