diff --git a/.ci/ci-configure.sh b/.ci/ci-configure.sh index b2a62b5736..4a2211ba09 100755 --- a/.ci/ci-configure.sh +++ b/.ci/ci-configure.sh @@ -7,7 +7,7 @@ set -e if [ "$BUILDSYSTEM" = "ninja" ] ; then if [ "$DISTRO" != "" ] ; then # Normal build test of all targets - OPTS=" -Decore-imf-loaders-disabler=scim,ibus -Davahi=false -Dmono=false -Dcxx=false" + OPTS=" -Decore-imf-loaders-disabler=scim,ibus -Davahi=false -Dbindings=luajit" WAYLAND_LINUX_COPTS=" -Dwl=true -Ddrm=true -Dopengl=es-egl" @@ -41,7 +41,7 @@ if [ "$BUILDSYSTEM" = "ninja" ] ; then export CFLAGS="-I/usr/local/opt/openssl/include -frewrite-includes $CFLAGS" export LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS" export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig" - mkdir build && meson build -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Dmono=false -Dcxx=false -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Demotion-loaders-disabler=gstreamer,gstreamer1,libvlc,xine + mkdir build && meson build -Decore-imf-loaders-disabler=scim,ibus -Dx11=false -Davahi=false -Dbindings=luajit -Deeze=false -Dsystemd=false -Dnls=false -Dcocoa=true -Demotion-loaders-disabler=gstreamer,gstreamer1,libvlc,xine fi else CI_BUILD_TYPE="$1" diff --git a/meson.build b/meson.build index cee0c1bc3b..0e2a50c2c9 100644 --- a/meson.build +++ b/meson.build @@ -228,6 +228,10 @@ config_h.set_quoted('MOD_SUFFIX', '.'+sys_mod_extension) config_h.set_quoted('EXE_SUFFIX', '.'+sys_exe_extension) config_h.set('EFL_BUILD', '1') +if get_option('tslib') == true + config_h.set('HAVE_TSLIB', '1') +endif + subdir('header_checks') subdir('po') @@ -406,12 +410,10 @@ subdir(join_paths('src', 'generic', 'evas')) subdir(join_paths('src', 'generic', 'emotion')) subdir('cmakeconfig') -bindings = ['luajit', 'cxx', 'mono'] +bindings = get_option('bindings') foreach binding : bindings - if get_option(binding) - subdir(join_paths('src', 'bindings', binding)) - endif + subdir(join_paths('src', 'bindings', binding)) endforeach subdir(join_paths('src', 'edje_external')) diff --git a/meson_options.txt b/meson_options.txt index 713ac1304f..af3b87aa41 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -97,7 +97,7 @@ option('build-examples', option('build-tests', type : 'boolean', value : true, - description : 'build examples' + description : 'build tests' ) option('crypto', @@ -310,22 +310,11 @@ option('nls', description: 'enable localization: (default=true)' ) -option('luajit', - type: 'boolean', - value: true, - description: 'Flag for handling lua bindings' -) - -option('cxx', - type: 'boolean', - value: true, - description: 'Flag for handling cxx bindings' -) - -option('mono', - type: 'boolean', - value: false, - description: 'Flag for handling c# bindings' +option('bindings', + type : 'array', + choices : ['luajit', 'cxx', 'mono'], + value : ['luajit', 'cxx'], + description : 'Add values here to enable the bindings', ) option('native-arch-optimization', @@ -346,3 +335,15 @@ option('windows-version', value : 'win7', description : 'When host_machine is windows, compile the efl with the specified version of Windows' ) + +option('dictionaries-hyphen-dir', + type : 'string', + value : '/usr/share/hyphen/', + description : 'Put the path to hyphen dictionaries directory' +) + +option('elementary-base-dir', + type : 'string', + value : '.elementary', + description : 'Put the name of a base directory for elementary data' +) diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am index 4c775b8085..b69f3b63b0 100644 --- a/src/Makefile_Efl.am +++ b/src/Makefile_Efl.am @@ -78,6 +78,7 @@ efl_eolian_files = \ lib/efl/interfaces/efl_gfx_text_class.eo \ lib/efl/interfaces/efl_gfx_size_class.eo \ lib/efl/interfaces/efl_interpolator.eo \ + lib/efl/interfaces/efl_cached_item.eo \ $(efl_eolian_legacy_files) \ $(NULL) @@ -114,7 +115,7 @@ lib_LTLIBRARIES += lib/efl/libefl.la lib_efl_libefl_la_SOURCES = \ lib/efl/interfaces/efl_interfaces_main.c \ -lib/efl/interfaces/efl_model_common.c \ +lib/efl/interfaces/efl_mvvm_common.c \ lib/efl/interfaces/efl_gfx_path.c \ lib/efl/interfaces/efl_gfx_shape.c \ lib/efl/interfaces/efl_input_device.c \ @@ -140,7 +141,7 @@ lib_efl_libefl_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ installed_eflheadersdir = $(includedir)/efl-@VMAJ@ dist_installed_eflheaders_DATA = \ lib/efl/Efl_Config.h \ - lib/efl/Efl_Model_Common.h \ + lib/efl/Efl_MVVM_Common.h \ lib/efl/Efl.h installed_eflinterfacesdir = $(includedir)/efl-@VMAJ@/interfaces diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am index 792a8dc6e8..73e9ded754 100644 --- a/src/Makefile_Efl_Mono.am +++ b/src/Makefile_Efl_Mono.am @@ -463,7 +463,9 @@ tests_efl_mono_efl_mono_SOURCES = \ tests/efl_mono/Strings.cs \ tests/efl_mono/Structs.cs \ tests/efl_mono/Value.cs \ - tests/efl_mono/ValueEolian.cs + tests/efl_mono/ValueEolian.cs \ + tests/efl_mono/EinaTestData.cs \ + tests/efl_mono/StructHelpers.cs tests/efl_mono/efl_mono$(EXEEXT): $(tests_efl_mono_efl_mono_SOURCES) tests/efl_mono/$(am__dirstamp) lib/efl_mono/libefl_mono.dll tests/efl_mono/libefl_mono_test.dll tests/efl_mono/efl_mono$(EXEEXT).config @rm -f $@ diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index fc4e3daf6a..ff247b7731 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -134,6 +134,7 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_tab_page_part_tab.eo \ lib/elementary/efl_ui_widget_focus_manager.eo \ lib/elementary/efl_ui_text_part.eo \ + lib/elementary/efl_ui_caching_factory.eo \ $(NULL) # More public files -- FIXME @@ -889,6 +890,7 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_tab_bar.c \ lib/elementary/efl_ui_tab_page.c \ lib/elementary/efl_ui_widget_focus_manager.c \ + lib/elementary/efl_ui_caching_factory.c \ $(NULL) diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am index 6d607ef950..5e1e2d01af 100644 --- a/src/Makefile_Eolian.am +++ b/src/Makefile_Eolian.am @@ -103,6 +103,8 @@ tests/eolian/data/typedef.eo \ tests/eolian/data/var.eo \ tests/eolian/data/function_types.eot \ tests/eolian/data/import_types.eot \ +tests/eolian/data/class_requires.eo \ +tests/eolian/data/mixins_require.eo \ tests/eolian/data_aux/aux_a.eo \ tests/eolian/data_aux/aux_b.eo \ tests/eolian/data_aux/aux_c.eo diff --git a/src/bin/eldbus/source_client.c b/src/bin/eldbus/source_client.c index 8d5fdd143b..8860f0665b 100644 --- a/src/bin/eldbus/source_client.c +++ b/src/bin/eldbus/source_client.c @@ -127,7 +127,7 @@ source_client_complex_method_call_generate(const DBus_Method *method, Eina_Strbu eina_strbuf_append_printf(c_code, " p = eldbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name); eina_strbuf_append_printf(c_code, " if (data)\n"); eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n"); - eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n"); + eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n"); eina_strbuf_append_printf(c_code, " return p;\n"); eina_strbuf_append_printf(c_code, "}\n"); @@ -210,7 +210,7 @@ source_client_simple_method_call_generate(const DBus_Method *method, Eina_Strbuf eina_strbuf_append_printf(c_code, " p = eldbus_proxy_send(proxy, msg, %s, cb, -1);\n", method->cb_name); eina_strbuf_append_printf(c_code, " if (data)\n"); eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n"); - eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n"); + eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n"); eina_strbuf_append_printf(c_code, " return p;\n"); eina_strbuf_append_printf(c_code, "}\n"); @@ -228,7 +228,7 @@ source_client_complex_method_callback_generate(const DBus_Method *method, Eina_S eina_strbuf_append_printf(c_code, " %s cb = data;\n", prefix_append(method->function_cb)); eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n"); eina_strbuf_append_printf(c_code, " Eina_Value *value;\n"); - eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n"); + eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n"); eina_strbuf_append_printf(c_code, " if (eldbus_message_error_get(msg, &error, &error_msg))\n"); eina_strbuf_append_printf(c_code, " {\n"); eina_strbuf_append_printf(c_code, " Eldbus_Error_Info error_info = {error, error_msg};\n"); @@ -256,7 +256,7 @@ source_client_simple_method_callback_generate(const DBus_Method *method, Eina_St eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n"); eina_strbuf_append_printf(c_code, " %s cb = data;\n", prefix_append(method->function_cb)); eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n"); - eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n"); + eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n"); EINA_INLIST_FOREACH(method->args, arg) { @@ -436,7 +436,7 @@ source_client_property_generate_get(const DBus_Property *prop, Eina_Strbuf *c_co eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n"); eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n"); eina_strbuf_append_printf(c_code, " %s cb = data;\n", prop_cb_get(prop)); - eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n"); + eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n"); eina_strbuf_append_printf(c_code, " Eldbus_Message_Iter *variant;\n"); if (prop->complex) eina_strbuf_append_printf(c_code, " Eina_Value *v, stack_value;\n"); @@ -485,7 +485,7 @@ source_client_property_generate_get(const DBus_Property *prop, Eina_Strbuf *c_co eina_strbuf_append_printf(c_code, " p = eldbus_proxy_property_get(proxy, \"%s\", %s, cb);\n", prop->name, prop->cb_name); eina_strbuf_append_printf(c_code, " if (data)\n"); eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n"); - eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n"); + eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n"); eina_strbuf_append_printf(c_code, " return p;\n"); eina_strbuf_append_printf(c_code, "}\n"); } @@ -497,7 +497,7 @@ source_client_property_generate_set(const DBus_Property *prop, Eina_Strbuf *c_co eina_strbuf_append_printf(c_code, "\nstatic void\n%s_set(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)\n{\n", prop->cb_name); eina_strbuf_append_printf(c_code, " const char *error, *error_msg;\n"); eina_strbuf_append_printf(c_code, " void *user_data = eldbus_pending_data_del(pending, \"__user_data\");\n"); - eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__proxy\");\n"); + eina_strbuf_append_printf(c_code, " Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, \"__user_proxy\");\n"); eina_strbuf_append_printf(c_code, " Eldbus_Codegen_Property_Set_Cb cb = data;\n"); eina_strbuf_append_printf(c_code, " if (eldbus_message_error_get(msg, &error, &error_msg))"); eina_strbuf_append_printf(c_code, " {\n"); @@ -517,7 +517,7 @@ source_client_property_generate_set(const DBus_Property *prop, Eina_Strbuf *c_co eina_strbuf_append_printf(c_code, " EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);\n"); eina_strbuf_append_printf(c_code, " p = eldbus_proxy_property_set(proxy, \"%s\", \"%s\", value, %s_set, cb);\n", prop->name, prop->type, prop->cb_name); eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_data\", data);\n"); - eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__proxy\", proxy);\n"); + eina_strbuf_append_printf(c_code, " eldbus_pending_data_set(p, \"__user_proxy\", proxy);\n"); eina_strbuf_append_printf(c_code, " return p;\n"); eina_strbuf_append_printf(c_code, "}\n"); } diff --git a/src/bin/elementary/meson.build b/src/bin/elementary/meson.build index f8ca71e9c8..008eab708f 100644 --- a/src/bin/elementary/meson.build +++ b/src/bin/elementary/meson.build @@ -157,7 +157,8 @@ elementary_test_src = [ ] if sys_windows == false - link_args = '-rdynamic' + link_args = ['-rdynamic', '-fPIC', '-pie'] + package_c_args = package_c_args + ['-fPIC'] else link_args = [] endif diff --git a/src/bin/eolian_mono/eolian/mono/alias_definition.hh b/src/bin/eolian_mono/eolian/mono/alias_definition.hh index 91659fb7bd..cf9d3495ce 100644 --- a/src/bin/eolian_mono/eolian/mono/alias_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/alias_definition.hh @@ -33,7 +33,7 @@ struct alias_definition_generator if (!name_helpers::open_namespaces(sink, alias.namespaces, context)) return false; - std::string const& alias_name = alias.eolian_name; + std::string const alias_name = utils::remove_all(alias.eolian_name, '_'); if (!as_generator( "public struct " << alias_name << " {\n" << scope_tab << "private " << type << " payload;\n" diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh index 684b842c24..fff61c7231 100644 --- a/src/bin/eolian_mono/eolian/mono/blacklist.hh +++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh @@ -45,6 +45,7 @@ inline bool is_function_blacklisted(std::string const& c_name) || c_name == "efl_ui_spin_button_loop_get" || c_name == "efl_ui_list_model_size_get" || c_name == "efl_ui_list_relayout_layout_do" + || c_name == "efl_event_callback_forwarder_priority_add" // Depends on constants support. ; } diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh index 6e02765366..22849a9fcb 100644 --- a/src/bin/eolian_mono/eolian/mono/events.hh +++ b/src/bin/eolian_mono/eolian/mono/events.hh @@ -25,10 +25,19 @@ struct unpack_event_args_visitor std::string const& arg = "evt.Info"; std::string arg_type = name_helpers::type_full_managed_name(regular); - // Structs are usually passed by pointer to events, like having a ptr<> modifier - if (type.is_ptr || regular.is_struct()) - return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))") + if (regular.is_struct()) + { + // Structs are usually passed by pointer to events, like having a ptr<> modifier + // Uses implicit conversion from IntPtr + return as_generator( + " evt.Info;" + ).generate(sink, attributes::unused, *context); + } + else if (type.is_ptr) + { + return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))") .generate(sink, attributes::unused, *context); + } using attributes::regular_type_def; struct match @@ -84,21 +93,15 @@ struct event_argument_wrapper_generator return true; std::string evt_name = name_helpers::managed_event_name(evt.name); - std::string arg_type; - if (!as_generator(type).generate(std::back_inserter(arg_type), *etype, efl::eolian::grammar::context_null())) - { - EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Failed to get argument type for event " << evt.name; - return false; - } return as_generator("///Event argument wrapper for event .\n" << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n" << scope_tab << "///Actual event payload.\n" - << scope_tab << "public " << arg_type << " arg { get; set; }\n" + << scope_tab << "public " << type << " arg { get; set; }\n" << "}\n" - ).generate(sink, attributes::unused, context); + ).generate(sink, *etype, context); } } const event_argument_wrapper {}; diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh index 05e1e4a7ac..801d721008 100644 --- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh @@ -194,7 +194,9 @@ inline std::string managed_method_name(attributes::function_def const& f) inline std::string alias_full_eolian_name(attributes::alias_def const& alias) { - return join_namespaces(alias.namespaces, '.') + alias.eolian_name; + + std::string eolian_name = utils::remove_all(alias.eolian_name, '_'); + return join_namespaces(alias.namespaces, '.') + eolian_name; } inline std::string managed_async_method_name(attributes::function_def const& f) @@ -368,7 +370,7 @@ inline std::string klass_full_native_inherit_name(T const& klass) template inline std::string klass_get_name(T const& clsname) { - return utils::to_lowercase(join_namespaces(clsname.namespaces, '_') + clsname.eolian_name + "_class_get"); + return clsname.klass_get_name; } inline std::string klass_get_full_name(attributes::klass_name const& clsname) diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index 70d22fb97e..416cacbe69 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -559,7 +559,7 @@ struct native_convert_in_variable_generator else if (helpers::need_struct_conversion(regular)) { return as_generator( - "var " << string << " = " << type << "_StructConversion.ToExternal(" << escape_keyword(param.param_name) << ");\n" + "var " << string << " = " << type << "_StructConversion.ToManaged(" << 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_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") @@ -898,7 +898,7 @@ struct convert_out_assign_generator else if (helpers::need_struct_conversion(regular)) { return as_generator( - string << " = " << type << "_StructConversion.ToExternal(" << out_variable_name(param.param_name) << ");\n" + string << " = " << type << "_StructConversion.ToManaged(" << out_variable_name(param.param_name) << ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context); } else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) @@ -1002,7 +1002,7 @@ struct convert_in_ptr_assign_generator if (param_should_use_in_var(param, true) && param.type.is_ptr && !param.type.has_own && helpers::need_struct_conversion(regular)) { return as_generator( - string << " = " << type << "_StructConversion.ToExternal(" << in_variable_name(param.param_name) << ");\n" + string << " = " << type << "_StructConversion.ToManaged(" << in_variable_name(param.param_name) << ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context); } @@ -1040,7 +1040,7 @@ struct convert_return_generator else if (helpers::need_struct_conversion(regular)) { return as_generator( - "return " << type << "_StructConversion.ToExternal(_ret_var);\n" + "return " << type << "_StructConversion.ToManaged(_ret_var);\n" ).generate(sink, ret_type, context); } else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *") diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 99347ed1dc..0eda387668 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -56,6 +56,8 @@ struct struct_definition_generator 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 @@ -68,7 +70,6 @@ struct struct_definition_generator else { // Constructor with default parameters for easy struct initialization - auto struct_name = binding_struct_name(struct_); if(!as_generator( scope_tab << "///Constructor for " << string << ".\n" << scope_tab << "public " << string << "(\n" @@ -81,6 +82,16 @@ struct struct_definition_generator return false; } + if(!as_generator( + "public static implicit operator " << struct_name << "(IntPtr ptr)\n" + << scope_tab << "{\n" + << scope_tab << scope_tab << "var tmp = (" << struct_name << "_StructInternal)Marshal.PtrToStructure(ptr, typeof(" << struct_name << "_StructInternal));\n" + << scope_tab << scope_tab << "return " << struct_name << "_StructConversion.ToManaged(tmp);\n" + << scope_tab << "}\n" + ).generate(sink, attributes::unused, context)) + return false; + + if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; return true; @@ -120,7 +131,8 @@ struct struct_internal_definition_generator .generate(sink, nullptr, context)) return false; } - else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n") + else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n" + << scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n") .generate(sink, std::make_tuple(field.type, field.type, field_name), context)) return false; } @@ -142,7 +154,7 @@ struct struct_internal_definition_generator scope_tab << "///Implicit conversion to the internal/marshalling representation.\n" << scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n" << scope_tab << "{\n" - << scope_tab << scope_tab << "return " << string << "_StructConversion.ToExternal(struct_);\n" + << scope_tab << scope_tab << "return " << string << "_StructConversion.ToManaged(struct_);\n" << scope_tab << "}\n" << scope_tab << "///Implicit conversion to the managed representation.\n" << scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n" @@ -315,7 +327,7 @@ struct to_external_field_convert_generator else if (helpers::need_struct_conversion(regular)) { if (!as_generator( - scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToExternal(_internal_struct." << string << ");\n") + scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToManaged(_internal_struct." << string << ");\n") .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) return false; } @@ -406,7 +418,7 @@ struct struct_binding_conversion_functions_generator // to external if (!as_generator ( - scope_tab << "internal static " << string << " ToExternal(" << string << " _internal_struct)\n" + scope_tab << "internal static " << string << " ToManaged(" << string << " _internal_struct)\n" << scope_tab << "{\n" << scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n" ) diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs index be84e4adff..6fae14b022 100644 --- a/src/bindings/mono/eina_mono/eina_value.cs +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -792,6 +792,83 @@ public class Value : IDisposable, IComparable, IEquatable this.Ownership = Ownership.Managed; } + /// Type-specific constructor, for convenience. + public Value(byte x) : this(ValueType.Byte) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(sbyte x) : this(ValueType.SByte) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(short x) : this(ValueType.Short) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(ushort x) : this(ValueType.UShort) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(int x) : this(ValueType.Int32) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(uint x) : this(ValueType.UInt32) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(long x) : this(ValueType.Long) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(ulong x) : this(ValueType.ULong) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(float x) : this(ValueType.Float) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(double x) : this(ValueType.Double) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + + /// Type-specific constructor, for convenience. + public Value(string x) : this(ValueType.String) + { + if (!Set(x)) + throw new InvalidOperationException("Couldn't set value."); + } + /// Implicit conversion from managed value to native struct representation. public static implicit operator ValueNative(Value v) { diff --git a/src/bindings/mono/eo_mono/workaround.cs b/src/bindings/mono/eo_mono/workaround.cs index 1fa3889d48..99fb53b7e4 100644 --- a/src/bindings/mono/eo_mono/workaround.cs +++ b/src/bindings/mono/eo_mono/workaround.cs @@ -134,19 +134,6 @@ public struct ActionData { public IntPtr func; } -public struct StateSet { - private ulong val; - - public static implicit operator StateSet(ulong x) - { - return new StateSet{val=x}; - } - public static implicit operator ulong(StateSet x) - { - return x.val; - } -} - } // namespace Access } // namespace Efl diff --git a/src/examples/ecore/meson.build b/src/examples/ecore/meson.build index 7233a83b82..c0b42959fa 100644 --- a/src/examples/ecore/meson.build +++ b/src/examples/ecore/meson.build @@ -7,7 +7,6 @@ examples = [ 'ecore_file_download_example', 'ecore_idler_example', 'ecore_job_example', - 'ecore_pipe_gstreamer_example', 'ecore_pipe_simple_example', 'ecore_poller_example', 'ecore_thread_example', @@ -22,9 +21,20 @@ examples += ['ecore_fd_handler_gnutls_example'] endif foreach example : examples - executable(example, example + '.c', dependencies: [eina, ecore, gstreamer, ecore_file, gnutls]) + executable(example, example + '.c', dependencies: [eina, ecore, ecore_file, gnutls]) endforeach +if get_option('gstreamer') == true + examples = [ + 'ecore_pipe_gstreamer_example', + ] + + foreach example : examples + executable(example, example + '.c', dependencies: [eina, ecore, gstreamer, ecore_file]) + endforeach +endif + + examples = [ # 'ecore_audio_custom', # 'ecore_audio_playback', diff --git a/src/examples/elementary/efl_ui_list_view_example_1.c b/src/examples/elementary/efl_ui_list_view_example_1.c index dc300264aa..e432fe1d66 100644 --- a/src/examples/elementary/efl_ui_list_view_example_1.c +++ b/src/examples/elementary/efl_ui_list_view_example_1.c @@ -87,7 +87,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) ); factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, win); - efl_ui_model_connect(factory, "signal/elm,state,%v", "odd_style"); + efl_ui_model_connect(factory, "signal/efl,state,%v", "odd_style"); efl_ui_model_connect(factory, "signal/efl,state,%{selected;unselected}", "selected"); efl_ui_model_connect(factory, "efl.text", "name"); efl_ui_layout_factory_theme_config(factory, "list_item", NULL, "default"); diff --git a/src/generic/evas/gst/meson.build b/src/generic/evas/gst/meson.build index 9689aee80a..aa10f7e513 100644 --- a/src/generic/evas/gst/meson.build +++ b/src/generic/evas/gst/meson.build @@ -10,5 +10,8 @@ generic_src = files([ 'main.c' ]) -generic_deps = [dependency('gstreamer-1.0')] +generic_deps = [] +if get_option('gstreamer') == true + generic_deps += dependency('gstreamer-1.0') +endif generic_support = ['264','3g2','3gp','3gp2','3gpp','3gpp2','3p2','asf','avi','bdm','bdmv','clpi','cpi','dv','fla','flv','m1v','m2t','m2v','m4v','mkv','mov','mp2','mp2ts','mp4','mpe','mpeg','mpg','mpl','mpls','mts','mxf','nut','nuv','ogg','ogm','ogv','qt','rm','rmj','rmm','rms','rmx','rmvb','rv','swf','ts','webm','weba','wmv'] \ No newline at end of file diff --git a/src/lib/ecore/Ecore_Common.h b/src/lib/ecore/Ecore_Common.h index c446fb3b05..cccb5b736c 100644 --- a/src/lib/ecore/Ecore_Common.h +++ b/src/lib/ecore/Ecore_Common.h @@ -1895,6 +1895,9 @@ EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); * @param thread The thread to wait on. * @param wait Maximum time to wait before exiting anyway. * @return EINA_TRUE if the thread execution is over. + * + * Note: This function should only be called in the main loop. + * */ EAPI Eina_Bool ecore_thread_wait(Ecore_Thread *thread, double wait); diff --git a/src/lib/ecore/efl_io_closer_fd.eo b/src/lib/ecore/efl_io_closer_fd.eo index 721e449f1d..e601f582ad 100644 --- a/src/lib/ecore/efl_io_closer_fd.eo +++ b/src/lib/ecore/efl_io_closer_fd.eo @@ -1,4 +1,4 @@ -mixin Efl.Io.Closer_Fd (Efl.Io.Closer, Efl.Object) { +mixin Efl.Io.Closer_Fd requires Efl.Object extends Efl.Io.Closer { [[Close fd using close(2). @since 1.19 diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c index ab6d198316..5a7166cb48 100644 --- a/src/lib/ecore/efl_loop.c +++ b/src/lib/ecore/efl_loop.c @@ -76,7 +76,6 @@ _efl_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block) return _ecore_main_loop_iterate_may_block(obj, pd, may_block); } -// FIXME: This should return an Eina_Value, but that doesn't work at the moment EOLIAN static Eina_Value * _efl_loop_begin(Eo *obj, Efl_Loop_Data *pd) { diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c index 35f1547cb6..6442669efd 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -380,26 +380,6 @@ _efl_task_flags_get(const Eo *obj EINA_UNUSED, Efl_Task_Data *pd) return pd->flags; } -EOLIAN static Eina_Future * -_efl_task_run(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED) -{ - // NOP - return NULL; -} - -EOLIAN static void -_efl_task_end(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED) -{ - // NOP -} - -EOLIAN static Efl_Object * -_efl_task_efl_object_constructor(Eo *obj, Efl_Task_Data *pd EINA_UNUSED) -{ - obj = efl_constructor(efl_super(obj, MY_CLASS)); - return obj; -} - EOLIAN static void _efl_task_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) { diff --git a/src/lib/ecore/efl_task.eo b/src/lib/ecore/efl_task.eo index 7fdb895f49..8670299de4 100644 --- a/src/lib/ecore/efl_task.eo +++ b/src/lib/ecore/efl_task.eo @@ -15,7 +15,7 @@ enum Efl.Task_Flags { no_exit_code_error = 4, } -class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) +abstract Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) { [[ ]] methods { @@ -138,11 +138,11 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) flags: Efl.Task_Flags; [[ ]] } } - run { + run @pure_virtual { [[ Actually run the task ]] return: future @owned; [[ A future triggered when task exits and is passed int exit code ]] } - end { + end @pure_virtual { [[ Request the task end (may send a signal or interrupt signal resulting in a terminate event being tiggered in the target task loop) ]] @@ -151,7 +151,6 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) events { } implements { - Efl.Object.constructor; Efl.Object.destructor; Efl.Object.parent { set; } } diff --git a/src/lib/ecore_con/efl_net_control_technology-connman.c b/src/lib/ecore_con/efl_net_control_technology-connman.c index a006923e61..2ccec1d983 100644 --- a/src/lib/ecore_con/efl_net_control_technology-connman.c +++ b/src/lib/ecore_con/efl_net_control_technology-connman.c @@ -371,22 +371,20 @@ _efl_net_control_technology_scan_cb(void *data, const Eldbus_Message *msg, Eldbu } static void -_efl_net_control_technology_scan_promise_del(void *data, Efl_Loop_Consumer *consumer, const Eina_Promise *dead_ptr) +_efl_net_control_technology_scan_promise_del(void *data EINA_UNUSED, Efl_Loop_Consumer *consumer EINA_UNUSED, const Eina_Promise *dead_ptr) { - Eldbus_Pending *p = consumer; + Eldbus_Pending *p; Efl_Net_Control_Technology_Data *pd; Eo *o; - if (!p) return ; + p = eina_promise_data_get(dead_ptr); + if (!p) return; /* already gone, nothing to do */ o = eldbus_pending_data_get(p, ".object"); pd = efl_data_scope_get(o, MY_CLASS); EINA_SAFETY_ON_NULL_RETURN(pd); - p = eina_promise_data_get(dead_ptr); - if (!p) return; /* already gone, nothing to do */ - pd->pending = eina_list_remove(pd->pending, p); DBG("cancel pending scan %p", p); eldbus_pending_cancel(p); diff --git a/src/lib/ecore_fb/meson.build b/src/lib/ecore_fb/meson.build index 0bcf11e3c8..a2eb5400c6 100644 --- a/src/lib/ecore_fb/meson.build +++ b/src/lib/ecore_fb/meson.build @@ -1,6 +1,10 @@ ecore_fb_deps = [ecore, ecore_input] ecore_fb_pub_deps = [eina] +if get_option('tslib') + ecore_fb_deps += dependency('tslib') +endif + ecore_fb_header_src = [ 'Ecore_Fb.h' ] diff --git a/src/lib/ecore_wl2/meson.build b/src/lib/ecore_wl2/meson.build index 96078fc344..b455ba586f 100644 --- a/src/lib/ecore_wl2/meson.build +++ b/src/lib/ecore_wl2/meson.build @@ -1,4 +1,7 @@ -ecore_wl2_deps = [dependency('wayland-client'), dependency('wayland-server'), dependency('xkbcommon'), wayland_protocol, dependency('wayland-client')] +ecore_wl2_deps = [ + dependency('wayland-client'), dependency('wayland-server'), dependency('xkbcommon'), + wayland_protocol, dl, m, ecore, ecore_input, libdrm, buildsystem +] ecore_wl2_pub_deps = [eina, ecore] ecore_wl2_header_src = [ @@ -20,7 +23,7 @@ ecore_wl2_src = [ ecore_wl2_lib = library('ecore_wl2', ecore_wl2_src, pub_eo_file_target, - dependencies: ecore_wl2_pub_deps + [dl, m, ecore, ecore_input, ecore_wl2_deps, libdrm, buildsystem], + dependencies: ecore_wl2_deps + ecore_wl2_pub_deps, include_directories : config_dir, install: true, version : meson.project_version() diff --git a/src/lib/ector/ector_renderer_gradient.eo b/src/lib/ector/ector_renderer_gradient.eo index f19aa83147..43b9c1d435 100644 --- a/src/lib/ector/ector_renderer_gradient.eo +++ b/src/lib/ector/ector_renderer_gradient.eo @@ -1,4 +1,4 @@ -mixin Ector.Renderer.Gradient (Efl.Gfx.Gradient, Efl.Object) +mixin Ector.Renderer.Gradient requires Efl.Object extends Efl.Gfx.Gradient { [[Ector gradient renderer mixin]] eo_prefix: ector_renderer_gradient; diff --git a/src/lib/ector/ector_renderer_shape.eo b/src/lib/ector/ector_renderer_shape.eo index 0206b1afcf..683b0072f2 100644 --- a/src/lib/ector/ector_renderer_shape.eo +++ b/src/lib/ector/ector_renderer_shape.eo @@ -1,6 +1,6 @@ import ector_renderer; -mixin Ector.Renderer.Shape (Efl.Gfx.Shape, Efl.Object) +mixin Ector.Renderer.Shape requires Efl.Object extends Efl.Gfx.Shape { [[Ector shape renderer mixin]] eo_prefix: ector_renderer_shape; diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 37810745d9..e08ec4edb8 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -2024,12 +2024,11 @@ _edje_file_del(Edje *ed) // fallthrough intentional case EDJE_PART_TYPE_GROUP: evas_object_del(rp->typedata.swallow->swallowed_object); - + rp->typedata.swallow->swallowed_object = NULL; default: break; } _edje_real_part_swallow_clear(ed, rp); - rp->typedata.swallow->swallowed_object = NULL; } free(rp->typedata.swallow); rp->typedata.swallow = NULL; diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index 1ff6767e6c..af6154b766 100644 --- a/src/lib/efl/Efl.h +++ b/src/lib/efl/Efl.h @@ -73,7 +73,7 @@ typedef struct _Efl_Text_Annotate_Annotation Efl_Text_Annotate_Annotation; #include "interfaces/efl_types.eot.h" -#include +#include /* Data types */ #include "interfaces/efl_gfx_types.eot.h" @@ -149,6 +149,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command; #include "interfaces/efl_ui_model_connect.eo.h" #include "interfaces/efl_ui_factory.eo.h" #include "interfaces/efl_ui_format.eo.h" +#include "interfaces/efl_cached_item.eo.h" /* Observable interface */ #include "interfaces/efl_observer.eo.h" diff --git a/src/lib/efl/Efl_Model_Common.h b/src/lib/efl/Efl_MVVM_Common.h similarity index 92% rename from src/lib/efl/Efl_Model_Common.h rename to src/lib/efl/Efl_MVVM_Common.h index 034d1170c1..954163b4cf 100644 --- a/src/lib/efl/Efl_Model_Common.h +++ b/src/lib/efl/Efl_MVVM_Common.h @@ -12,6 +12,8 @@ EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE; EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED; EAPI extern Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT; /**< @since 1.19 */ +EAPI extern Eina_Error EFL_FACTORY_ERROR_NOT_SUPPORTED; /**< Returned error when factory got a request that it can't fullfil due to a set of unsupported parameters @since 1.22 */ + #include "interfaces/efl_model.eo.h" EAPI int efl_model_init(void); diff --git a/src/lib/efl/interfaces/efl_cached_item.eo b/src/lib/efl/interfaces/efl_cached_item.eo new file mode 100644 index 0000000000..f3f82d6baf --- /dev/null +++ b/src/lib/efl/interfaces/efl_cached_item.eo @@ -0,0 +1,14 @@ +interface Efl.Cached.Item +{ + [[Efl Cached Item interface]] + methods { + @property memory_size { + get { + [[Get the memory size associated with an object.]] + } + values { + consumed: uint; [[Bytes of memory consumed by this object.]] + } + } + } +} diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c index 5133def96b..d1f9b80394 100644 --- a/src/lib/efl/interfaces/efl_interfaces_main.c +++ b/src/lib/efl/interfaces/efl_interfaces_main.c @@ -81,6 +81,8 @@ #include "interfaces/efl_ui_multi_selectable.eo.c" #include "interfaces/efl_ui_zoom.eo.c" +#include "interfaces/efl_cached_item.eo.c" + static void _noref_death(void *data EINA_UNUSED, const Efl_Event *event) { diff --git a/src/lib/efl/interfaces/efl_model_common.c b/src/lib/efl/interfaces/efl_mvvm_common.c similarity index 92% rename from src/lib/efl/interfaces/efl_model_common.c rename to src/lib/efl/interfaces/efl_mvvm_common.c index ecbbb59ecb..2c95c76eaa 100644 --- a/src/lib/efl/interfaces/efl_model_common.c +++ b/src/lib/efl/interfaces/efl_mvvm_common.c @@ -3,7 +3,7 @@ #endif #include "Efl.h" -#include "Efl_Model_Common.h" +#include "Efl_MVVM_Common.h" EAPI Eina_Error EFL_MODEL_ERROR_UNKNOWN = 0; EAPI Eina_Error EFL_MODEL_ERROR_NOT_SUPPORTED = 0; @@ -14,6 +14,8 @@ EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0; EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0; EAPI Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT = 0; +EAPI Eina_Error EFL_FACTORY_ERROR_NOT_SUPPORTED = 0; + static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error"; static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported"; static const char EFL_MODEL_ERROR_NOT_FOUND_STR[] = "Value not found"; @@ -23,11 +25,12 @@ static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied"; static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value"; static const char EFL_MODEL_ERROR_INVALID_OBJECT_STR[] = "Object is invalid"; -#define _ERROR(Name) EFL_MODEL_ERROR_##Name = eina_error_msg_static_register(EFL_MODEL_ERROR_##Name##_STR); +static const char EFL_FACTORY_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported"; EAPI int efl_model_init(void) { +#define _ERROR(Name) EFL_MODEL_ERROR_##Name = eina_error_msg_static_register(EFL_MODEL_ERROR_##Name##_STR); _ERROR(INCORRECT_VALUE); _ERROR(UNKNOWN); _ERROR(NOT_SUPPORTED); @@ -37,6 +40,10 @@ efl_model_init(void) _ERROR(PERMISSION_DENIED); _ERROR(INVALID_OBJECT); +#undef _ERROR +#define _ERROR(Name) EFL_FACTORY_ERROR_##Name = eina_error_msg_static_register(EFL_FACTORY_ERROR_##Name##_STR); + _ERROR(NOT_SUPPORTED); + return EINA_TRUE; } diff --git a/src/lib/efl/interfaces/meson.build b/src/lib/efl/interfaces/meson.build index c263b05b70..13f71e4408 100644 --- a/src/lib/efl/interfaces/meson.build +++ b/src/lib/efl/interfaces/meson.build @@ -104,6 +104,7 @@ pub_eo_files = [ 'efl_gfx_color_class.eo', 'efl_gfx_text_class.eo', 'efl_gfx_size_class.eo', + 'efl_cached_item.eo', ] foreach eo_file : pub_eo_files @@ -155,7 +156,7 @@ pub_eo_types_files = [] efl_src += files([ 'efl_interfaces_main.c', - 'efl_model_common.c', + 'efl_mvvm_common.c', 'efl_gfx_path.c', 'efl_gfx_shape.c', 'efl_gfx_color.c', diff --git a/src/lib/efl/meson.build b/src/lib/efl/meson.build index cadf14bdab..d5805be9b3 100644 --- a/src/lib/efl/meson.build +++ b/src/lib/efl/meson.build @@ -3,7 +3,7 @@ efl_pub_deps = [eo] efl_header_src = [ 'Efl.h', - 'Efl_Model_Common.h' + 'Efl_MVVM_Common.h' ] efl_src = [] diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h index f4219975b8..d2e2297091 100644 --- a/src/lib/elementary/Efl_Ui.h +++ b/src/lib/elementary/Efl_Ui.h @@ -207,6 +207,8 @@ typedef Eo Efl_Ui_Focus_Manager; # include # include +# include "efl_ui_caching_factory.eo.h" + /* FIXME: Multibuttonentry must not use elm_widget_item */ # warning Efl.Ui.Multibutton is not available yet without Elementary.h # if 0 diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 75348188c2..9574c31c90 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -348,6 +348,7 @@ typedef Eo Efl_Ui_Focus_Manager; # include # include # include +# include # include # include # include diff --git a/src/lib/elementary/efl_access_object.eo b/src/lib/elementary/efl_access_object.eo index ad82be2357..e20f50dc60 100644 --- a/src/lib/elementary/efl_access_object.eo +++ b/src/lib/elementary/efl_access_object.eo @@ -239,7 +239,7 @@ struct Efl.Access.Relation objects: list; [[List with relation objects]] } -mixin Efl.Access.Object (Efl.Interface, Efl.Object) +mixin Efl.Access.Object requires Efl.Object { [[Accessibility accessible mixin]] eo_prefix: efl_access_object; diff --git a/src/lib/elementary/efl_ui_caching_factory.c b/src/lib/elementary/efl_ui_caching_factory.c new file mode 100644 index 0000000000..b25d6ba829 --- /dev/null +++ b/src/lib/elementary/efl_ui_caching_factory.c @@ -0,0 +1,218 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "elm_priv.h" + +typedef struct _Efl_Ui_Caching_Factory_Data Efl_Ui_Caching_Factory_Data; +struct _Efl_Ui_Caching_Factory_Data +{ + const Efl_Class *klass; + + // Simple list of ready-to-use objects. They are all equal so it does not matter from which + // end of the list objects are added and removed. + Eina_List *cache; + + struct { + unsigned int memory; + unsigned int items; + } limit, current; +}; + +// Clear the cache until it meet the constraint +static void +_efl_ui_caching_factory_remove(Efl_Ui_Caching_Factory_Data *pd, Eina_List *l, Efl_Gfx_Entity *entity) +{ + pd->cache = eina_list_remove_list(pd->cache, l); + pd->current.items--; + + pd->current.memory -= efl_class_memory_size_get(entity); + if (efl_isa(entity, EFL_CACHED_ITEM_INTERFACE)) + pd->current.memory -= efl_cached_item_memory_size_get(entity); +} + +static void +_efl_ui_caching_factory_flush(Efl_Ui_Caching_Factory_Data *pd) +{ + while (pd->limit.items != 0 && + pd->current.items > pd->limit.items) + { + Efl_Gfx_Entity *entity; + + entity = eina_list_data_get(eina_list_last(pd->cache)); + + _efl_ui_caching_factory_remove(pd, eina_list_last(pd->cache), entity); + + efl_del(entity); + } + + while (pd->limit.memory != 0 && + pd->current.memory > pd->limit.memory) + { + Efl_Gfx_Entity *entity; + + entity = eina_list_data_get(eina_list_last(pd->cache)); + + _efl_ui_caching_factory_remove(pd, eina_list_last(pd->cache), entity); + + efl_del(entity); + } +} + +static Eina_Future * +_efl_ui_caching_factory_efl_ui_factory_create(Eo *obj, + Efl_Ui_Caching_Factory_Data *pd, + Efl_Model *model, Efl_Gfx_Entity *parent) +{ + Efl_Gfx_Entity *r; + + if (pd->cache) + { + r = eina_list_data_get(pd->cache); + + _efl_ui_caching_factory_remove(pd, pd->cache, r); + + efl_parent_set(r, parent); + } + else + { + r = efl_add(pd->klass, parent); + } + + efl_ui_view_model_set(r, model); + + return efl_loop_future_resolved(obj, eina_value_object_init(r)); +} + +static void +_efl_ui_caching_factory_item_class_set(Eo *obj, + Efl_Ui_Caching_Factory_Data *pd, + const Efl_Object *klass) +{ + if (!efl_isa(klass, EFL_GFX_ENTITY_INTERFACE) || + !efl_isa(klass, EFL_UI_VIEW_INTERFACE)) + { + ERR("Provided class '%s' for factory '%s' doesn't implement '%s' and '%s' interfaces.", + efl_class_name_get(klass), + efl_class_name_get(obj), + efl_class_name_get(EFL_GFX_ENTITY_INTERFACE), + efl_class_name_get(EFL_UI_VIEW_INTERFACE)); + return ; + } + pd->klass = klass; +} + +static const Efl_Object * +_efl_ui_caching_factory_item_class_get(const Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd) +{ + return pd->klass; +} + +static void +_efl_ui_caching_factory_memory_limit_set(Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd, + unsigned int limit) +{ + pd->limit.memory = limit; + + _efl_ui_caching_factory_flush(pd); +} + +static unsigned int +_efl_ui_caching_factory_memory_limit_get(const Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd) +{ + return pd->limit.memory; +} + +static void +_efl_ui_caching_factory_items_limit_set(Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd, + unsigned int limit) +{ + pd->limit.items = limit; + + _efl_ui_caching_factory_flush(pd); +} + +static unsigned int +_efl_ui_caching_factory_items_limit_get(const Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd) +{ + return pd->limit.items; +} + +static void +_efl_ui_caching_factory_efl_ui_factory_release(Eo *obj, + Efl_Ui_Caching_Factory_Data *pd, + Efl_Gfx_Entity *ui_view) +{ + // Change parent, disconnect the object and make it invisible + efl_parent_set(ui_view, obj); + efl_gfx_entity_visible_set(ui_view, EINA_FALSE); + efl_ui_view_model_set(ui_view, NULL); + + // Add to the cache + pd->cache = eina_list_prepend(pd->cache, ui_view); + pd->current.items++; + pd->current.memory += efl_class_memory_size_get(ui_view); + if (efl_isa(ui_view, EFL_CACHED_ITEM_INTERFACE)) + pd->current.memory += efl_cached_item_memory_size_get(ui_view); + + // And check if the cache need some triming + _efl_ui_caching_factory_flush(pd); +} + +static void +_efl_ui_caching_factory_efl_object_invalidate(Eo *obj EINA_UNUSED, + Efl_Ui_Caching_Factory_Data *pd) +{ + // As all the objects in the cache have the factory as parent, there's no need to unparent them + pd->cache = eina_list_free(pd->cache); +} + +static Efl_App * +_efl_ui_caching_factory_app_get(Eo *obj) +{ + Efl_Object *p; + + p = efl_parent_get(obj); + if (!p) return NULL; + + // It is acceptable to just have a loop as parent and not an app + return efl_provider_find(obj, EFL_APP_CLASS); +} + +static void +_efl_ui_caching_factory_pause(void *data, const Efl_Event *event EINA_UNUSED) +{ + Efl_Ui_Caching_Factory_Data *pd = data; + Efl_Gfx_Entity *entity; + + // Application is going into background, let's free ressource + // Possible improvement would be to delay that by a few second. + EINA_LIST_FREE(pd->cache, entity) + efl_del(entity); + + pd->current.items = 0; + pd->current.memory = 0; +} + +static void +_efl_ui_caching_factory_efl_object_parent_set(Eo *obj, Efl_Ui_Caching_Factory_Data *pd, Efl_Object *parent) +{ + Efl_App *a; + + a = _efl_ui_caching_factory_app_get(obj); + if (a) efl_event_callback_del(a, EFL_APP_EVENT_PAUSE, _efl_ui_caching_factory_pause, pd); + + efl_parent_set(efl_super(obj, EFL_UI_CACHING_FACTORY_CLASS), parent); + + // We are fetching the parent again, just in case the update was denied + a = _efl_ui_caching_factory_app_get(obj); + if (a) efl_event_callback_add(a, EFL_APP_EVENT_PAUSE, _efl_ui_caching_factory_pause, pd); +} + +#include "efl_ui_caching_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_caching_factory.eo b/src/lib/elementary/efl_ui_caching_factory.eo new file mode 100644 index 0000000000..c894e2cf22 --- /dev/null +++ b/src/lib/elementary/efl_ui_caching_factory.eo @@ -0,0 +1,48 @@ +class Efl.Ui.Caching_Factory (Efl.Loop_Consumer, Efl.Ui.Factory) +{ + [[Efl Ui Factory that provides object caching. + + This factory handles caching of one type of object and automatically empties the cache + when the application goes into pause. + + Creating objects is costly and time consuming, keeping a few on hand for when you next will need them helps a lot. + This is what this factory caching infrastructure provides. It will create the object from the class defined on it and + set the parent and the model as needed for all created items. The View has to release the Item using the + release function of the Factory interface for all of this to work properly. + + The cache might decide to flush itself when the application event pause is triggered. + ]] + methods { + @property item_class { + [[Define the class of the item returned by this factory.]] + get {} + set {} + values { + klass: const(Efl.Class); [[The class identifier to create item from.]] + } + } + @property memory_limit { + [[Define the maxium size in Bytes that all the object waiting on standby in the cache take. They must provide the @Efl.Cached.Item interface for an accurate accounting.]] + get {} + set {} + values { + limit: uint; [[When set to zero, there is no limit on the amount of memory the cache will use.]] + } + } + @property items_limit { + [[Define how many maximum number of items are waiting on standby in the cache.]] + get {} + set {} + values { + limit: uint; [[When set to zero, there is no limit to the amount of items stored in the cache.]] + } + } + } + + implements { + Efl.Ui.Factory.create; + Efl.Ui.Factory.release; + Efl.Object.invalidate; + Efl.Object.parent { set; } + } +} diff --git a/src/lib/elementary/efl_ui_dnd.c b/src/lib/elementary/efl_ui_dnd.c index 4f491cea39..c368beb0d1 100644 --- a/src/lib/elementary/efl_ui_dnd.c +++ b/src/lib/elementary/efl_ui_dnd.c @@ -20,6 +20,9 @@ struct _Efl_Ui_Dnd_Container_Data }; extern int _wl_default_seat_id_get(Evas_Object *obj); +#ifdef HAVE_ELEMENTARY_WL2 +Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj); +#endif Eo* _efl_ui_selection_manager_get(Eo *obj) @@ -339,7 +342,7 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data, sl.mem = data; sl.len = strlen(data); #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif ic->icon_data = icon_create_data; @@ -366,7 +369,7 @@ elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action) int seatid = 1; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif efl_ui_selection_manager_drag_action_set(sel_man, obj, (Efl_Ui_Selection_Action)action, seatid); @@ -380,7 +383,7 @@ elm_drag_cancel(Evas_Object *obj) int seatid = 1; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif efl_ui_selection_manager_drag_cancel(sel_man, obj, seatid); @@ -433,7 +436,7 @@ elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format, drop = calloc(1, sizeof(Dnd_Drop)); if (!enter || !leave || !pos || !drop) goto on_error; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif enter->state_cb = enter_cb; enter->state_data = enter_data; @@ -489,7 +492,7 @@ elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format, Dnd_Drop *drop; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif drop_list = efl_key_data_get(obj, "__drop_list"); @@ -650,7 +653,7 @@ elm_drop_item_container_add(Evas_Object *obj, drop = calloc(1, sizeof(Dnd_Cont_Drop)); if (!enter || !leave || !pos || !drop) goto on_error; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif enter->state_cb = enter_cb; @@ -703,7 +706,7 @@ elm_drop_item_container_del(Evas_Object *obj) int seatid = 1; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif _cont_drop_free_data(obj); @@ -806,7 +809,7 @@ elm_drag_item_container_add(Evas_Object *obj, double anim_tm, double tm_to_drag, Item_Container_Drag_Info *di; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif di = calloc(1, sizeof(Item_Container_Drag_Info)); @@ -833,7 +836,7 @@ elm_drag_item_container_del(Evas_Object *obj) int seatid = 1; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif _cont_drag_free_data(obj); diff --git a/src/lib/elementary/efl_ui_focus_composition.eo b/src/lib/elementary/efl_ui_focus_composition.eo index 2befe106b0..120867e53a 100644 --- a/src/lib/elementary/efl_ui_focus_composition.eo +++ b/src/lib/elementary/efl_ui_focus_composition.eo @@ -1,4 +1,4 @@ -mixin Efl.Ui.Focus.Composition (Efl.Interface, Efl.Ui.Widget) { +mixin Efl.Ui.Focus.Composition requires Efl.Ui.Widget { [[This defines the inheriting widget as Composition widget. A composition widget is a widget that's the logical parent of another set of widgets which can be used for interaction. diff --git a/src/lib/elementary/efl_ui_focus_layer.eo b/src/lib/elementary/efl_ui_focus_layer.eo index a5a3564168..92145ae29c 100644 --- a/src/lib/elementary/efl_ui_focus_layer.eo +++ b/src/lib/elementary/efl_ui_focus_layer.eo @@ -1,4 +1,4 @@ -mixin Efl.Ui.Focus.Layer (Efl.Interface, Efl.Ui.Widget, Efl.Ui.Widget_Focus_Manager) { +mixin Efl.Ui.Focus.Layer requires Efl.Ui.Widget extends Efl.Ui.Widget_Focus_Manager { [[This defines the inheriting widget as focus layer A focus layer is the uppermost one which received input and handles all focus related events for as long as it exists and is visible. It's NOT possible to escape this layer with focus movement. diff --git a/src/lib/elementary/efl_ui_focus_manager_sub.eo b/src/lib/elementary/efl_ui_focus_manager_sub.eo index 40b81fc630..a2414d43eb 100644 --- a/src/lib/elementary/efl_ui_focus_manager_sub.eo +++ b/src/lib/elementary/efl_ui_focus_manager_sub.eo @@ -1,4 +1,4 @@ -mixin Efl.Ui.Focus.Manager_Sub (Efl.Interface, Efl.Ui.Focus.Manager, Efl.Object) +mixin Efl.Ui.Focus.Manager_Sub requires Efl.Object extends Efl.Ui.Focus.Manager { [[A class that automatically registers its border elements in the parent manager diff --git a/src/lib/elementary/efl_ui_image_factory.c b/src/lib/elementary/efl_ui_image_factory.c index 998c43f70d..ce4d892dfa 100644 --- a/src/lib/elementary/efl_ui_image_factory.c +++ b/src/lib/elementary/efl_ui_image_factory.c @@ -17,6 +17,7 @@ EOLIAN static Eo * _efl_ui_image_factory_efl_object_constructor(Eo *obj, Efl_Ui_Image_Factory_Data *pd) { obj = efl_constructor(efl_super(obj, MY_CLASS)); + efl_ui_caching_factory_item_class_set(obj, EFL_UI_IMAGE_CLASS); pd->property = NULL; @@ -32,27 +33,33 @@ _efl_ui_image_factory_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Image_Fa efl_destructor(efl_super(obj, MY_CLASS)); } +static Eina_Value +_efl_ui_image_factory_connect(Eo *obj EINA_UNUSED, void *data, const Eina_Value value) +{ + Efl_Gfx_Entity *entity = NULL; + Efl_Ui_Image_Factory_Data *pd = data; + + eina_value_pget(&value, &entity); + + efl_ui_model_connect(entity, "filename", pd->property); + + return value; +} + EOLIAN static Eina_Future * _efl_ui_image_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model, Efl_Gfx_Entity *parent) { - Efl_Gfx_Entity *ui_view; - Eina_Value r; + Eina_Future *f; - EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL); - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - ui_view = efl_add(EFL_UI_IMAGE_CLASS, parent); - efl_ui_view_model_set(ui_view, model); - efl_ui_model_connect(ui_view, "filename", pd->property); + if (!parent) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED); + if (!pd->property) return efl_loop_future_rejected(obj, EFL_FACTORY_ERROR_NOT_SUPPORTED); - r = eina_value_object_init(ui_view); + f = efl_ui_factory_create(efl_super(obj, EFL_UI_IMAGE_FACTORY_CLASS), model, parent); - return eina_future_resolved(efl_loop_future_scheduler_get(obj), r); -} - -EOLIAN static void -_efl_ui_image_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd EINA_UNUSED, Efl_Gfx_Entity *ui_view) -{ - efl_parent_set(ui_view, NULL); + return efl_future_then(obj, f, + .success_type = EINA_VALUE_TYPE_OBJECT, + .success = _efl_ui_image_factory_connect, + .data = pd); } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_image_factory.eo b/src/lib/elementary/efl_ui_image_factory.eo index a966d23ec2..66abdf4d23 100644 --- a/src/lib/elementary/efl_ui_image_factory.eo +++ b/src/lib/elementary/efl_ui_image_factory.eo @@ -1,11 +1,10 @@ -class Efl.Ui.Image_Factory (Efl.Object, Efl.Ui.Factory) +class Efl.Ui.Image_Factory (Efl.Ui.Caching_Factory) { [[Efl UI image factory class]] implements { Efl.Object.constructor; Efl.Object.destructor; Efl.Ui.Factory.create; - Efl.Ui.Factory.release; Efl.Ui.Model.Connect.connect; } } diff --git a/src/lib/elementary/efl_ui_layout_factory.c b/src/lib/elementary/efl_ui_layout_factory.c index 36bf8ddb5f..150fd67aa0 100644 --- a/src/lib/elementary/efl_ui_layout_factory.c +++ b/src/lib/elementary/efl_ui_layout_factory.c @@ -45,6 +45,8 @@ _efl_ui_layout_factory_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Factory_Dat { obj = efl_constructor(efl_super(obj, MY_CLASS)); + efl_ui_caching_factory_item_class_set(obj, EFL_UI_LAYOUT_CLASS); + pd->connects = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del)); pd->factory_connects = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref)); @@ -64,17 +66,15 @@ _efl_ui_layout_factory_efl_object_destructor(Eo *obj, Efl_Ui_Layout_Factory_Data efl_destructor(efl_super(obj, MY_CLASS)); } -EOLIAN static Eina_Future * -_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data *pd, - Efl_Model *model, Efl_Gfx_Entity *parent) +static Eina_Value +_efl_ui_layout_factory_connect(Eo *obj EINA_UNUSED, void *data, const Eina_Value value) { - Eina_Value r; + Efl_Ui_Layout_Factory_Data *pd = data; Efl_Gfx_Entity *layout; - EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); - layout = efl_add(EFL_UI_LAYOUT_CLASS, parent, - efl_ui_view_model_set(efl_added, model), - efl_ui_layout_theme_set(efl_added, pd->klass, pd->group, pd->style)); + eina_value_pget(&value, &layout); + + efl_ui_layout_theme_set(layout, pd->klass, pd->group, pd->style); eina_hash_foreach(pd->connects, _model_connect, layout); eina_hash_foreach(pd->factory_connects, _factory_model_connect, layout); @@ -82,16 +82,21 @@ _efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0); evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); - r = eina_value_object_init(layout); - - return eina_future_resolved(efl_loop_future_scheduler_get(obj), r); + return value; } -EOLIAN static void -_efl_ui_layout_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd EINA_UNUSED, Efl_Gfx_Entity *layout) +EOLIAN static Eina_Future * +_efl_ui_layout_factory_efl_ui_factory_create(Eo *obj, Efl_Ui_Layout_Factory_Data *pd, + Efl_Model *model, Efl_Gfx_Entity *parent) { - efl_ui_view_model_set(layout, NULL); - efl_del(layout); + Eina_Future *f; + + f = efl_ui_factory_create(efl_super(obj, EFL_UI_LAYOUT_FACTORY_CLASS), model, parent); + + return efl_future_then(obj, f, + .success_type = EINA_VALUE_TYPE_OBJECT, + .success = _efl_ui_layout_factory_connect, + .data = pd); } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_layout_factory.eo b/src/lib/elementary/efl_ui_layout_factory.eo index 334a4c4478..8b9c06bd87 100644 --- a/src/lib/elementary/efl_ui_layout_factory.eo +++ b/src/lib/elementary/efl_ui_layout_factory.eo @@ -1,4 +1,4 @@ -class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory) +class Efl.Ui.Layout_Factory (Efl.Ui.Caching_Factory) { [[Efl Ui Layout Factory class]] methods { @@ -16,7 +16,6 @@ class Efl.Ui.Layout_Factory (Efl.Object, Efl.Ui.Factory) Efl.Object.constructor; Efl.Object.destructor; Efl.Ui.Factory.create; - Efl.Ui.Factory.release; Efl.Ui.Factory.model_connect; Efl.Ui.Model.Connect.connect; } diff --git a/src/lib/elementary/efl_ui_list_view.c b/src/lib/elementary/efl_ui_list_view.c index fc85818fc0..ee26515822 100644 --- a/src/lib/elementary/efl_ui_list_view.c +++ b/src/lib/elementary/efl_ui_list_view.c @@ -32,7 +32,6 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { void _efl_ui_list_view_custom_layout(Efl_Ui_List_View *); void _efl_ui_list_view_item_select_set(Efl_Ui_List_View_Layout_Item*, Eina_Bool); -static void _layout(Efl_Ui_List_View_Data* pd); static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); static Eina_Bool _key_action_select(Evas_Object *obj, const char *params); @@ -166,7 +165,7 @@ _on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; v = efl_model_property_get(item->children, SELECTED_PROP); - if (!eina_value_get(v, &select)) + if (!eina_value_get(v, &select)) { WRN("Could not get the select value"); eina_value_free(v); @@ -239,7 +238,11 @@ _efl_ui_list_view_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_List_View_Data *pd, Ei EOLIAN static void _efl_ui_list_view_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data *pd) { - _layout(pd); + if (!pd->model) + return; + + efl_ui_list_view_relayout_layout_do(pd->relayout, pd->obj, pd->seg_array_first, pd->seg_array); + } EOLIAN static void @@ -841,15 +844,6 @@ _efl_ui_list_view_relayout_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data return pd->relayout; } -static void -_layout(Efl_Ui_List_View_Data *pd) -{ - if (!pd->model) - return; - - efl_ui_list_view_relayout_layout_do(pd->relayout, pd->obj, pd->seg_array_first, pd->seg_array); -} - static Eina_Value _children_slice_then(void * data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED) { @@ -941,8 +935,11 @@ _content_created(Eo *obj, void *data, const Eina_Value value) evt.layout = item->layout; evt.index = efl_ui_list_view_item_index_get(item); efl_event_callback_call(obj, EFL_UI_LIST_VIEW_EVENT_ITEM_REALIZED, &evt); - efl_ui_focus_composition_dirty(obj); + tracking->item->layout_request = NULL; + efl_ui_list_view_relayout_content_created(tracking->pd->relayout, item); + + efl_ui_focus_composition_dirty(obj); evas_object_show(item->layout); return value; diff --git a/src/lib/elementary/efl_ui_list_view_precise_layouter.c b/src/lib/elementary/efl_ui_list_view_precise_layouter.c index 9b6ba9f0ad..156662caa5 100644 --- a/src/lib/elementary/efl_ui_list_view_precise_layouter.c +++ b/src/lib/elementary/efl_ui_list_view_precise_layouter.c @@ -22,7 +22,6 @@ typedef struct _Efl_Ui_List_View_Precise_Layouter_Data unsigned int calc_progress; - int first; int count_total; Eina_Bool initialized : 1; @@ -118,21 +117,26 @@ _item_size_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Lay } } -static void -_item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item - , Eina_Size2D min, Efl_Ui_List_View_Seg_Array_Node *itemnode) +static Eina_Size2D +_item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item* item) { - Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = itemnode->layout_data; + Efl_Ui_List_View_Seg_Array_Node *itemnode = item->tree_node; + Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata; Efl_Ui_List_View_Layout_Item *layout_item; int i, pad[4]; - efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]); + Eina_Size2D min = efl_gfx_size_hint_combined_min_get(item->layout); + efl_gfx_size_hint_margin_get(item->layout, &pad[0], &pad[1], &pad[2], &pad[3]); min.w += pad[0] + pad[1]; min.h += pad[2] + pad[3]; if (item->min.h == min.h && item->min.w == min.w) - return; + return min; + + EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode, min); + EINA_SAFETY_ON_NULL_RETURN_VAL(itemnode->layout_data, min); + nodedata = itemnode->layout_data; pd->min.h += min.h - item->min.h; nodedata->min.h += min.h - item->min.h; @@ -175,13 +179,12 @@ _item_min_calc(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layo item->min.w = min.w; item->min.h = min.h; - - _item_size_calc(pd, item); + return item->min; } static void _on_item_size_hint_change(void *data, Evas *e EINA_UNUSED, - Evas_Object *obj, void *event_info EINA_UNUSED) + Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data = data; Efl_Ui_List_View_Precise_Layouter_Data *pd = cb_data->pd; @@ -189,8 +192,7 @@ _on_item_size_hint_change(void *data, Evas *e EINA_UNUSED, Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node; Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data; - Eina_Size2D min = efl_gfx_size_hint_combined_min_get(obj); - _item_min_calc(pd, item, min, node); + _item_min_calc(pd, item); if (!nodedata->realized) { free(evas_object_event_callback_del(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change)); @@ -273,17 +275,17 @@ _child_removed_cb(void *data, const Efl_Event *event) nodedata->min.w = 0; for (i = 0; i != itemnode->length; ++i) - { - layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i]; - if (nodedata->min.w < layout_item->min.w) - nodedata->min.w = layout_item->min.w; + { + layout_item = (Efl_Ui_List_View_Layout_Item *)itemnode->pointers[i]; + if (nodedata->min.w < layout_item->min.w) + nodedata->min.w = layout_item->min.w; - if (litem->min.w == layout_item->min.w) - { - nodedata->min.w = layout_item->min.w; - break; - } - } + if (litem->min.w == layout_item->min.w) + { + nodedata->min.w = layout_item->min.w; + break; + } + } if (pd->min.w == litem->min.w) { @@ -300,9 +302,8 @@ _child_removed_cb(void *data, const Efl_Event *event) if (litem->min.w == nodedata2->min.w) break; } - eina_accessor_free(nodes); + eina_accessor_free(nodes); } - efl_ui_list_view_model_unrealize(pd->modeler, litem); free(litem); @@ -391,7 +392,6 @@ static void _node_realize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_Array_Node *node) { Efl_Ui_List_View_Layout_Item* layout_item; - Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data; Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data; int i; @@ -405,15 +405,6 @@ _node_realize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg_A { layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i]; efl_ui_list_view_model_realize(pd->modeler, layout_item); - - if (layout_item->layout) - { - cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data)); - cb_data->pd = pd; - cb_data->item = layout_item; - evas_object_event_callback_add(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data); - _item_size_calc(pd, layout_item); - } } } @@ -438,8 +429,8 @@ _node_unrealize(Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Seg { cb_data = evas_object_event_callback_del(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change); free(cb_data); + efl_ui_list_view_model_unrealize(pd->modeler, layout_item); } - efl_ui_list_view_model_unrealize(pd->modeler, layout_item); } } @@ -485,8 +476,8 @@ _calc_size_job(void *data) Efl_Ui_List_View_Precise_Layouter_Data *pd; Efl_Ui_List_View_Seg_Array_Node *node; Efl_Ui_List_View_Layout_Item *layout_item; + Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata; Eo *obj = data; - Eina_Size2D min; int i; double start_time = ecore_time_get(); @@ -501,52 +492,36 @@ _calc_size_job(void *data) if (!node->layout_data) node->layout_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Node_Data)); + nodedata = node->layout_data; + if (pd->calc_progress == 1) + nodedata->realized = EINA_TRUE; + for (i = 0; i != node->length; ++i) { layout_item = (Efl_Ui_List_View_Layout_Item *)node->pointers[i]; EINA_SAFETY_ON_NULL_RETURN(layout_item); // cache size of new items - if ((layout_item->min.w == 0) && (layout_item->min.h == 0)) - { - if (!layout_item->layout) - { - efl_ui_list_view_model_realize(pd->modeler, layout_item); - } - - min = efl_gfx_size_hint_combined_min_get(layout_item->layout); - if (min.w && min.h) - { - _item_min_calc(pd, layout_item, min, node); - efl_ui_list_view_model_unrealize(pd->modeler, layout_item); - } - else - { - Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data)); - cb_data->pd = pd; - cb_data->item = layout_item; - evas_object_event_callback_add(layout_item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data); - } - } + if ((layout_item->min.w == 0) && (layout_item->min.h == 0) && (!layout_item->layout)) + efl_ui_list_view_model_realize(pd->modeler, layout_item); } + if ( (ecore_time_get() - start_time ) > 0.01 ) { ecore_job_del(pd->calc_job); pd->calc_job = ecore_job_add(_calc_size_job, obj); eina_accessor_free(nodes); return; - } + } } eina_accessor_free(nodes); pd->calc_progress = 0; pd->calc_job = NULL; pd->recalc = EINA_FALSE; - - evas_object_smart_changed(pd->modeler); } EOLIAN static Efl_Object * -_efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd) +_efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd) { obj = efl_constructor(efl_super(obj, MY_CLASS)); pd->initialized = EINA_FALSE; @@ -554,6 +529,31 @@ _efl_ui_list_view_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, E return obj; } +EOLIAN static void +_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_content_created(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Ui_List_View_Layout_Item *item) +{ + Efl_Ui_List_View_Precise_Layouter_Callback_Data *cb_data; + EINA_SAFETY_ON_NULL_RETURN(item); + EINA_SAFETY_ON_NULL_RETURN(item->layout); + Efl_Ui_List_View_Seg_Array_Node *node = item->tree_node; + Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = node->layout_data; + + Eina_Size2D min = _item_min_calc(pd, item); + + if (min.w && min.h && !nodedata->realized) + { + efl_ui_list_view_model_unrealize(pd->modeler, item); + return; + } + + cb_data = calloc(1, sizeof(Efl_Ui_List_View_Precise_Layouter_Callback_Data)); + cb_data->pd = pd; + cb_data->item = item; + evas_object_event_callback_add(item->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_item_size_hint_change, cb_data); + + _item_size_calc(pd, item); +} + EOLIAN static Eina_List * _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd) { @@ -569,7 +569,7 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const if (!nodedata || !nodedata->realized) continue; - for(j = 0; j != items_node->length;++j) + for (j = 0; j != items_node->length;++j) { layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j]; if (layout_item->layout) @@ -582,7 +582,7 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const } EOLIAN static void -_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_model_set(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Model *model) +_efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_model_set(Eo *obj, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_Model *model) { _finalize(obj, pd); @@ -607,11 +607,11 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd) Efl_Ui_List_View_Layout_Item* layout_item; Efl_Ui_List_View_Seg_Array_Node *items_node; int i, j = 0; + int boxx, boxy, boxw, boxh, extra = 0, rounding = 0; + int boxl = 0, boxr = 0, boxt = 0, boxb = 0; _calc_range(pd); - int boxx, boxy, boxw, boxh, extra = 0, rounding = 0; - int boxl = 0, boxr = 0, boxt = 0, boxb = 0; evas_object_geometry_get(pd->modeler, &boxx, &boxy, &boxw, &boxh); efl_gfx_size_hint_margin_get(pd->modeler, &boxl, &boxr, &boxt, &boxb); @@ -621,13 +621,6 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd) boxx += boxl; boxy += boxt; - //padding can not be squeezed (note: could make it an option) -// int pad; -// double scale; -// scale = evas_object_scale_get(pd->modeler); -// pad = 0;//pd->pad.scalable ? (pd->pad.v * scale) : pd->pad.v; -// length -= pad * (pd->count_total - 1); - // available space. if <0 we overflow extra = boxh - pd->min.h; if (extra < 0) extra = 0; @@ -641,46 +634,50 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd) EINA_ACCESSOR_FOREACH(nodes, i, items_node) { Efl_Ui_List_View_Precise_Layouter_Node_Data *nodedata = items_node->layout_data; - if (!nodedata) - { - continue; - } + if (!items_node->layout_data) + continue; - if (nodedata->realized) - { - for(j = 0; j != items_node->length;++j) - { - layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j]; - double x, y, w, h; - double weight_x, weight_y; - - if (layout_item->min.w && layout_item->min.h) - { - assert(layout_item->layout != NULL); - if (pd->resize) - _item_size_calc(pd, layout_item); - - efl_gfx_size_hint_weight_get(layout_item->layout, &weight_x, &weight_y); - // extra rounding up (compensate cumulative error) - if ((i == (pd->count_total - 1)) && (cur_pos - floor(cur_pos) >= 0.5)) - rounding = 1; - - x = layout_item->pos.x; - y = layout_item->pos.y + cur_pos; - w = layout_item->size.w; - h = layout_item->size.h + rounding + weight_y * extra; - cur_pos += h; - - if (w < pd->min.w) w = pd->min.w; - if (w > vgmt.w) w = vgmt.w; - - evas_object_geometry_set(layout_item->layout, (x + 0 - spos.x), (y + 0 - spos.y), w, h); - } - } - } - else + if (!nodedata->realized) { cur_pos += nodedata->min.h; + continue; + } + + for (j = 0; j != items_node->length;++j) + { + layout_item = (Efl_Ui_List_View_Layout_Item *)items_node->pointers[j]; + double x, y, w, h; + double weight_x, weight_y; + if (!(layout_item->min.w && layout_item->min.h)) + continue; + + // extra rounding up (compensate cumulative error) + if ((i == (pd->count_total - 1)) && (cur_pos - floor(cur_pos) >= 0.5)) + rounding = 1; + + if (layout_item->layout) + { + if (pd->resize) + _item_size_calc(pd, layout_item); + + efl_gfx_size_hint_weight_get(layout_item->layout, &weight_x, &weight_y); + } + else + { + cur_pos += layout_item->size.h; + continue; + } + + x = layout_item->pos.x; + y = layout_item->pos.y + cur_pos; + w = layout_item->size.w; + h = layout_item->size.h + rounding + weight_y * extra; + cur_pos += h; + + if (w < pd->min.w) w = pd->min.w; + if (w > vgmt.w) w = vgmt.w; + + evas_object_geometry_set(layout_item->layout, (x + 0 - spos.x), (y + 0 - spos.y), w, h); } } eina_accessor_free(nodes); @@ -691,18 +688,15 @@ _efl_ui_list_view_relayout_layout_do(Efl_Ui_List_View_Precise_Layouter_Data *pd) EOLIAN static void _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_layout_do (Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd - , Efl_Ui_List_View_Model *modeler, int first, Efl_Ui_List_View_Seg_Array *seg_array) + , Efl_Ui_List_View_Model *modeler, int first EINA_UNUSED, Efl_Ui_List_View_Seg_Array *seg_array) { if (!_initilize(obj, pd, modeler, seg_array) || !pd->seg_array) return; - pd->first = first; - - if (pd->recalc && efl_ui_list_view_seg_array_count(seg_array) > 0) + if (!pd->calc_job && pd->recalc && efl_ui_list_view_seg_array_count(seg_array) > 0) { // cache size of new items pd->calc_progress = 0; - ecore_job_del(pd->calc_job); pd->calc_job = ecore_job_add(_calc_size_job, obj); return; } diff --git a/src/lib/elementary/efl_ui_list_view_precise_layouter.eo b/src/lib/elementary/efl_ui_list_view_precise_layouter.eo index 9f953aa91c..9100f6967b 100644 --- a/src/lib/elementary/efl_ui_list_view_precise_layouter.eo +++ b/src/lib/elementary/efl_ui_list_view_precise_layouter.eo @@ -3,6 +3,7 @@ class Efl.Ui.List_View_Precise_Layouter (Efl.Object, Efl.Ui.List_View_Relayout) implements { Efl.Object.constructor; Efl.Ui.List_View_Relayout.layout_do; + Efl.Ui.List_View_Relayout.content_created; Efl.Ui.List_View_Relayout.model { set; } Efl.Ui.List_View_Relayout.elements { get; } } diff --git a/src/lib/elementary/efl_ui_list_view_relayout.eo b/src/lib/elementary/efl_ui_list_view_relayout.eo index ac6cd788bc..e5359b79d5 100644 --- a/src/lib/elementary/efl_ui_list_view_relayout.eo +++ b/src/lib/elementary/efl_ui_list_view_relayout.eo @@ -8,6 +8,11 @@ interface Efl.Ui.List_View_Relayout (Efl.Interface) children: Efl.Ui.List_View_Seg_Array; } } + content_created { + params { + item: ptr(Efl.Ui.List_View_Layout_Item); + } + } @property model { [[Model that is/will be ]] set {} diff --git a/src/lib/elementary/efl_ui_selection.c b/src/lib/elementary/efl_ui_selection.c index cb5f0a5c32..2fd60c4a38 100644 --- a/src/lib/elementary/efl_ui_selection.c +++ b/src/lib/elementary/efl_ui_selection.c @@ -10,6 +10,10 @@ #define MY_CLASS EFL_UI_SELECTION_MIXIN #define MY_CLASS_NAME "Efl.Ui.Selection" +#ifdef HAVE_ELEMENTARY_WL2 +Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj); +#endif + EOLIAN static void _efl_ui_selection_selection_get(Eo *obj, void *pd EINA_UNUSED, Efl_Ui_Selection_Type type, Efl_Ui_Selection_Format format, void *data_func_data, Efl_Ui_Selection_Data_Ready data_func, Eina_Free_Cb data_func_free_cb, unsigned int seat) @@ -72,34 +76,6 @@ _wl_is_wl(const Evas_Object *obj) return NULL; } -static Ecore_Wl2_Window * -_wl_window_get(const Evas_Object *obj) -{ - Evas_Object *top; - Ecore_Wl2_Window *win = NULL; - - if (elm_widget_is(obj)) - { - top = elm_widget_top_get(obj); - if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj)); - if (top && (efl_isa(top, EFL_UI_WIN_CLASS))) - win = elm_win_wl_window_get(top); - } - if (!win) - { - Ecore_Evas *ee = _wl_is_wl(obj); - - if (ee) - { - /* In case the engine is not a buffer, we want to check once. */ - win = ecore_evas_wayland2_window_get(ee); - if (!win) return NULL; - } - } - - return win; -} - int _wl_default_seat_id_get(Evas_Object *obj) { @@ -212,8 +188,7 @@ elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type type, if (!wdata) return EINA_FALSE; #ifdef HAVE_ELEMENTARY_WL2 - - seatid = _wl_default_seat_id_get((Evas_Object *)obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get((Evas_Object *)obj); #endif wdata->udata = udata; wdata->datacb = datacb; @@ -238,7 +213,7 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type type, data.mem = selbuf; data.len = buflen; #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif f = efl_ui_selection_manager_selection_set(sel_man, obj, (Efl_Ui_Selection_Type)type, (Efl_Ui_Selection_Format)format, data, seatid); @@ -257,7 +232,7 @@ elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type type) Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj); #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif efl_ui_selection_manager_selection_clear(sel_man, obj, (Efl_Ui_Selection_Type)type, seatid); @@ -289,7 +264,7 @@ elm_selection_selection_has_owner(Evas_Object *obj) Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj); #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif return efl_ui_selection_manager_selection_has_owner(sel_man, obj, @@ -303,7 +278,7 @@ elm_cnp_clipboard_selection_has_owner(Evas_Object *obj) Eo *sel_man = _efl_ui_selection_manager_get((Evas_Object *)obj); #ifdef HAVE_ELEMENTARY_WL2 - seatid = _wl_default_seat_id_get(obj); + if (_wl_window_get(obj)) seatid = _wl_default_seat_id_get(obj); #endif return efl_ui_selection_manager_selection_has_owner(sel_man, obj, EFL_UI_SELECTION_TYPE_CLIPBOARD, seatid); diff --git a/src/lib/elementary/efl_ui_selection_manager.c b/src/lib/elementary/efl_ui_selection_manager.c index 4391dfcd5a..0f1bfc71ec 100644 --- a/src/lib/elementary/efl_ui_selection_manager.c +++ b/src/lib/elementary/efl_ui_selection_manager.c @@ -37,7 +37,7 @@ static Ecore_X_Window _x11_xwin_get(const Evas_Object *obj); #endif #ifdef HAVE_ELEMENTARY_WL2 -static Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj); +Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj); static Ecore_Wl2_Input *_wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id); #endif @@ -738,14 +738,16 @@ _x11_data_preparer_uri(Sel_Manager_Seat_Selection *seat_sel, Ecore_X_Event_Selec return EINA_FALSE; } free(seat_sel->saved_types->imgfile); +#if 0 // this seems to be broken - we should be handling uri lists as text if (seat_sel->saved_types->textreq) { seat_sel->saved_types->textreq = 0; seat_sel->saved_types->imgfile = stripstr; } else +#endif { - ddata->format = EFL_UI_SELECTION_FORMAT_IMAGE; + ddata->format = EFL_UI_SELECTION_FORMAT_TEXT; ddata->content.mem = stripstr; ddata->content.len = strlen(stripstr); seat_sel->saved_types->imgfile = NULL; @@ -944,7 +946,7 @@ _efl_sel_manager_x11_selection_notify(void *udata, int type EINA_UNUSED, void *e { if (pd->atom_list[i].x_data_preparer) { - Efl_Ui_Selection_Data ddata; + Efl_Ui_Selection_Data ddata = { 0 }; Tmp_Info *tmp_info = NULL; Eina_Bool success; sel_debug("Found something: %s", pd->atom_list[i].name); @@ -1960,11 +1962,9 @@ _x11_dnd_drop(void *data, int etype EINA_UNUSED, void *ev) Efl_Ui_Selection_Manager_Data *pd = seat_sel->pd; Ecore_X_Event_Xdnd_Drop *drop; Sel_Manager_Dropable *dropable = NULL; - Efl_Ui_Selection_Data ddata; Evas_Coord x = 0, y = 0; Efl_Ui_Selection_Action act = EFL_UI_SELECTION_ACTION_UNKNOWN; Eina_List *l; - Eina_Inlist *itr; Sel_Manager_Selection *sel; drop = ev; @@ -2000,6 +2000,10 @@ found: dropable->last.in = EINA_FALSE; sel_debug("Last type: %s - Last format: %X\n", dropable->last.type, dropable->last.format); +#if 0 // this seems to be broken and causes dnd to stop working e.g. to/from + // rage even though iut used to work fine. + Efl_Ui_Selection_Data ddata; + Eina_Inlist *itr; if ((!strcmp(dropable->last.type, pd->text_uri))) { sel_debug("We found a URI... (%scached) %s\n", @@ -2061,7 +2065,7 @@ found: return EINA_TRUE; } } - +#endif sel = seat_sel->sel_list + EFL_UI_SELECTION_TYPE_DND; sel_debug("doing a request then: %s\n", dropable->last.type); sel->xwin = drop->win; @@ -2069,6 +2073,7 @@ found: sel->request_format = dropable->last.format; sel->active = EINA_TRUE; sel->action = act; + sel->asked++; ecore_x_selection_xdnd_request(drop->win, dropable->last.type); return EINA_TRUE; @@ -2806,7 +2811,7 @@ _wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id) evas_device_seat_id_get(seat)); } -static Ecore_Wl2_Window * +Ecore_Wl2_Window * _wl_window_get(const Evas_Object *obj) { Evas_Object *top; @@ -5269,7 +5274,7 @@ _efl_ui_selection_manager_efl_object_constructor(Eo *obj, Efl_Ui_Selection_Manag #endif pd->atom_list[SELECTION_ATOM_TEXT_URILIST].name = "text/uri-list"; - pd->atom_list[SELECTION_ATOM_TEXT_URILIST].format = EFL_UI_SELECTION_FORMAT_IMAGE; + pd->atom_list[SELECTION_ATOM_TEXT_URILIST].format = EFL_UI_SELECTION_FORMAT_TEXT; #ifdef HAVE_ELEMENTARY_X pd->atom_list[SELECTION_ATOM_TEXT_URILIST].x_converter = _x11_general_converter; pd->atom_list[SELECTION_ATOM_TEXT_URILIST].x_data_preparer = _x11_data_preparer_uri; diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index b3761e0a3a..000ba0e3bb 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -2168,7 +2168,6 @@ _efl_ui_text_efl_object_finalize(Eo *obj, //efl_text_font_set(sd->text_obj, "Sans", 12); sd->single_line = !efl_text_multiline_get(sd->text_obj); - efl_text_set(sd->text_obj, ""); efl_pack_table(sd->text_table, sd->text_obj, 0, 0, 1, 1); efl_pack_table(sd->text_table, sd->text_guide_obj, 0, 0, 1, 1); diff --git a/src/lib/elementary/efl_ui_widget_focus_manager.eo b/src/lib/elementary/efl_ui_widget_focus_manager.eo index c7c3af9037..2c4fe32244 100644 --- a/src/lib/elementary/efl_ui_widget_focus_manager.eo +++ b/src/lib/elementary/efl_ui_widget_focus_manager.eo @@ -1,4 +1,4 @@ -mixin Efl.Ui.Widget_Focus_Manager (Efl.Interface, Efl.Ui.Widget, Efl.Ui.Focus.Manager) +mixin Efl.Ui.Widget_Focus_Manager requires Efl.Ui.Widget extends Efl.Ui.Focus.Manager { methods { focus_manager_create @protected @pure_virtual { diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index 64a78514df..aeafaf8db4 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -3564,7 +3564,7 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize) double wx, wy; evas_object_size_hint_combined_min_get(sd->legacy.edje, &minw, &minh); - if ((!minw) && (!minh)) return; + if ((!minw) && (!minh) && (!sd->deferred_resize_job)) return; // If content has a weight, make resizable efl_gfx_size_hint_weight_get(sd->legacy.edje, &wx, &wy); @@ -3610,6 +3610,12 @@ _elm_win_resize_objects_eval(Evas_Object *obj, Eina_Bool force_resize) sd->tmp_updating_hints = 0; _elm_win_size_hints_update(obj, sd); + if (sd->deferred_resize_job) + _elm_win_resize_job(sd->obj); + + /* do not need to go below. if you go, ee could become 0. */ + if ((!minw) && (!minh)) return; + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); w = ow; h = oh; diff --git a/src/lib/elementary/elm_interface_scrollable.eo b/src/lib/elementary/elm_interface_scrollable.eo index f95ce04806..3d81d15d3f 100644 --- a/src/lib/elementary/elm_interface_scrollable.eo +++ b/src/lib/elementary/elm_interface_scrollable.eo @@ -27,7 +27,7 @@ enum Elm.Scroller.Single_Direction last [[Sentinel value to indicate last enum field during iteration]] } -mixin Elm.Interface_Scrollable(Efl.Ui.Scrollable, Efl.Ui.Focus.Manager_Sub, Efl.Ui.Widget, Efl.Ui.Widget_Focus_Manager) +mixin Elm.Interface_Scrollable requires Efl.Ui.Widget extends Efl.Ui.Scrollable, Efl.Ui.Focus.Manager_Sub, Efl.Ui.Widget_Focus_Manager { [[Elm scrollable mixin]] eo_prefix: elm_interface_scrollable; diff --git a/src/lib/elementary/elm_map.c b/src/lib/elementary/elm_map.c index 6685a1979f..fa64e2ce82 100644 --- a/src/lib/elementary/elm_map.c +++ b/src/lib/elementary/elm_map.c @@ -1607,6 +1607,8 @@ _overlay_default_content_update(Overlay_Default *ovl, if (ovl->content == content) return; evas_object_del(ovl->content); ovl->content = content; + evas_object_smart_member_add(ovl->content, ovl->wsd->pan_obj); + evas_object_stack_above(ovl->content, ovl->wsd->sep_maps_overlays); if (ovl->content) evas_object_event_callback_add(ovl->content, EVAS_CALLBACK_MOUSE_DOWN, diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build index 89c1a5eb89..cfc41555a7 100644 --- a/src/lib/elementary/meson.build +++ b/src/lib/elementary/meson.build @@ -281,7 +281,8 @@ pub_eo_files = [ 'elm_view_form.eo', 'elm_web.eo', 'elm_widget_item.eo', - 'efl_ui_text_part.eo' + 'efl_ui_text_part.eo', + 'efl_ui_caching_factory.eo', ] foreach eo_file : pub_eo_files @@ -908,7 +909,8 @@ elementary_src = [ 'efl_ui_tab_pager.c', 'efl_ui_tab_bar.c', 'efl_ui_tab_page.c', - 'efl_ui_widget_focus_manager.c' + 'efl_ui_widget_focus_manager.c', + 'efl_ui_caching_factory.c' ] elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl] @@ -919,7 +921,7 @@ elm_options = configuration_data() config_h.set_quoted('ELM_TOP_BUILD_DIR', meson.build_root()) config_h.set_quoted('MODULES_PATH', join_paths(dir_lib, 'modules')) -config_h.set_quoted('ELEMENTARY_BASE_DIR', '.elementary') +config_h.set_quoted('ELEMENTARY_BASE_DIR', get_option('elementary-base-dir')) config_h.set_quoted('ICON_DIR', join_paths(dir_lib, 'icons')) if sys_windows == false diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 62210443a1..21a4bf25d2 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -918,13 +918,22 @@ EAPI Eina_Bool efl_isa(const Eo *obj, const Efl_Class *klass); /** * @brief Gets the name of the passed class. - * @param klass the class to work on. + * @param[in] klass The class (or object) to work on. * @return The class' name. * * @see efl_class_get() */ EAPI const char *efl_class_name_get(const Efl_Class *klass); +/** + * @brief Gets the amount of memory this class object would use. + * @param[in] klass The class (or object) to work on. + * @return The amount of memory in Bytes. + * + * @see efl_class_get() + */ +EAPI size_t efl_class_memory_size_get(const Efl_Class *klass); + /** * @brief Gets a debug name for this object * @param obj_id The object (or class) @@ -2008,7 +2017,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_ /** * @def efl_event_callback_add(obj, desc, cb, data) * Add a callback for an event. - * @param[in] desc The description of the event to listen to. + * @param[in] desc An #Efl_Event_Description of the event to listen to. * @param[in] cb the callback to call. * @param[in] data additional data to pass to the callback. * @@ -2024,6 +2033,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_ * @def efl_event_callback_array_add(obj, desc, cb, data) * Add an array of callbacks for an event. * + * @param[in] obj The object. * @param[in] array an #Efl_Callback_Array_Item of events to listen to. * @param[in] data additional data to pass to the callback. * @@ -2044,7 +2054,7 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_ * @brief Add an event callback forwarder for an event and an object. * * @param[in] obj The object. - * @param[in] desc The description of the event to listen to + * @param[in] desc An #Efl_Event_Description of the event to forward to. * @param[in] new_obj The object to emit events from * * @ingroup Efl_Object diff --git a/src/lib/eo/efl_object.eo b/src/lib/eo/efl_object.eo index 49a836c8e3..6049ceb29a 100644 --- a/src/lib/eo/efl_object.eo +++ b/src/lib/eo/efl_object.eo @@ -13,6 +13,10 @@ type Efl.Callback_Priority : short; [[ Callback priority. Range is -32k - 32k. The lower the number, the higher the priority. + This is used to insert an event handler relative to the existing stack of sorted event + handlers according to that priority. All event handlers always have a priority. If not + specified @Efl.Callback_Priority_Default is to be assumed. + See @Efl.Callback_Priority_Before @Efl.Callback_Priority_Default @Efl.Callback_Priority_After ]] @@ -166,7 +170,7 @@ abstract Efl.Object If this is not done the class cannot be found up in the object tree. ]] params { - klass : const(Efl.Object); [[The class identifier to search for]] + klass : const(Efl.Class); [[The class identifier to search for]] } return : Efl.Object; [[Object from the provider list]] } @@ -245,15 +249,31 @@ abstract Efl.Object ]] } event_callback_forwarder_priority_add { - [[Add an event callback forwarder for an event and an object.]] + [[Add an event callback forwarder that will make this object emit an event whenever another + object ($source) emits it. The event is said to be forwarded from $source to this object. + + The event is unaffected on $source and behave like any other event being propagated on + any object and will trigger all the handler registered on $source like nothing special + happened. + + This allow object that hide internally another object to easily be able to propagate an event + without the need to add custom handler. + + Note: The priority is used to make sure that you are intercepting the event when you expect + by inserting a handler at the right position in the stack of event handler on the object that + emit the event.]] params { @cref desc: Efl.Event_Description; [[The description of the event to listen to]] - @in priority: short; [[The priority at which to insert the callback handler.]] - @in new_obj: Efl.Object @nonull; [[The object to emit events from]] + @in priority: Efl.Callback_Priority; [[The priority at which to insert the event forwarder handler + in the existing list of handler on the source of event object. The lower the number, the higher + the priority. As a shortcut @Efl.Callback_Priority_Before, + @Efl.Callback_Priority_Default and @Efl.Callback_Priority_After can be used. See + @Efl.Callback_Priority for more details.]] + @in source: Efl.Object @nonull; [[The object which emits the initial event]] } } event_callback_forwarder_del { - [[Remove an event callback forwarder for an event and an object.]] + [[Remove an event callback forwarder for a specified event and object.]] params { @cref desc: Efl.Event_Description; [[The description of the event to listen to]] @in new_obj: Efl.Object @nonull; [[The object to emit events from]] diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 3fb7fd6639..82299fe622 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1150,6 +1150,31 @@ err_obj: return NULL; } +EAPI size_t +efl_class_memory_size_get(const Efl_Class *eo_id) +{ + const _Efl_Class *klass; + + if (_eo_is_a_class(eo_id)) + { + EO_CLASS_POINTER_GOTO(eo_id, _klass, err_klass); + klass = _klass; + } + else + { + EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj); + klass = obj->klass; + EO_OBJ_DONE(eo_id); + } + return klass->obj_size; + +err_klass: + _EO_POINTER_ERR(eo_id, "Class (%p) is an invalid ref.", eo_id); +err_obj: + return 0; +} + + static void _vtable_init(Eo_Vtable *vtable, size_t size) { diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index a96e389010..09004c81c4 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -508,6 +508,12 @@ _get_impl_class(const Eolian_Class *cl, const char *cln) if (fcl) return fcl; } + EINA_LIST_FOREACH(cl->requires, l, icl) + { + const Eolian_Class *fcl = _get_impl_class(icl, cln); + if (fcl) + return fcl; + } EINA_LIST_FOREACH(cl->extends, l, icl) { const Eolian_Class *fcl = _get_impl_class(icl, cln); @@ -743,9 +749,10 @@ _db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash) if (eina_hash_find(cl->base.unit->state->main.unit.classes, cl->base.name)) return EINA_TRUE; - Eina_List *il = cl->extends; + Eina_List *il = cl->extends, *rl = cl->requires; Eina_Stringshare *inn = NULL; cl->extends = NULL; + cl->requires = NULL; Eina_Bool succ = EINA_TRUE; if (cl->parent_name) @@ -771,6 +778,30 @@ _db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash) succ = _db_fill_inherits(out_cl, fhash); } + if (succ && cl->type == EOLIAN_CLASS_MIXIN) + { + EINA_LIST_FREE(rl, inn) + { + Eolian_Class *out_cl = NULL; + succ = _db_swap_inherit(cl, succ, inn, &out_cl); + if (succ && !(out_cl->type == EOLIAN_CLASS_REGULAR || out_cl->type == EOLIAN_CLASS_ABSTRACT)) + { + char buf[PATH_MAX]; + snprintf(buf, sizeof(buf), "requires only allows regulars or abstracts"); + _obj_error(&cl->base, buf); + succ = EINA_FALSE; + } + if (succ) + { + _db_fill_inherits(out_cl, fhash); + } + if (!succ) + continue; + if (!eina_list_data_find(cl->requires, out_cl)) + cl->requires = eina_list_append(cl->requires, out_cl); + } + } + /* failed on the way, no point in filling further * the failed stuff will get dropped so it's ok if it's inconsistent */ @@ -805,6 +836,24 @@ _validate_implement(Eolian_Implement *impl) return _validate(&impl->base); } +static Eina_List* +_required_classes(Eolian_Class *mixin) +{ + Eina_List *result = NULL, *n; + Eolian_Class *extension; + + + result = eina_list_clone(mixin->requires); + + if (mixin->parent) + result = eina_list_merge(result, _required_classes(mixin->parent)); + + EINA_LIST_FOREACH(mixin->extends, n, extension) + result = eina_list_merge(result, _required_classes(extension)); + + return result; +} + static Eina_Bool _validate_class(Validate_State *vals, Eolian_Class *cl, Eina_Hash *nhash, Eina_Hash *ehash, Eina_Hash *chash) @@ -815,6 +864,7 @@ _validate_class(Validate_State *vals, Eolian_Class *cl, Eolian_Part *part; Eolian_Implement *impl; Eolian_Class *icl; + Eina_List *required_classes = NULL; if (!cl) return EINA_FALSE; /* if this happens something is very wrong though */ @@ -849,6 +899,17 @@ _validate_class(Validate_State *vals, Eolian_Class *cl, EINA_LIST_FOREACH(cl->extends, l, icl) { + if (icl->type == EOLIAN_CLASS_MIXIN) + { + Eina_List *res = _required_classes(icl); + Eolian_Class *required_class; + Eina_List *n; + EINA_LIST_FOREACH(res, n, required_class) + { + if (!eina_list_data_find(required_classes, required_class)) + required_classes = eina_list_append(required_classes, required_class); + } + } if (!valid && vals->ext_regular) switch (icl->type) { case EOLIAN_CLASS_REGULAR: @@ -869,6 +930,35 @@ _validate_class(Validate_State *vals, Eolian_Class *cl, if (!_validate_class(vals, icl, nhash, ehash, chash)) return EINA_FALSE; } + if (cl->type == EOLIAN_CLASS_ABSTRACT || cl->type == EOLIAN_CLASS_REGULAR) + { + //walk up the parent list and remove all classes from there + icl = cl; + while (icl) + { + required_classes = eina_list_remove(required_classes, icl); + icl = icl->parent; + } + //if there are a few left, drop, and error + if (required_classes) + { + Eina_Strbuf *classes = eina_strbuf_new(); + Eolian_Class *required_class; + Eina_List *n; + EINA_LIST_FOREACH(required_classes, n, required_class) + { + eina_strbuf_append(classes, required_class->base.name); + eina_strbuf_append_char(classes, ' '); + } + char buf[PATH_MAX]; + snprintf(buf, sizeof(buf), "required classes %sare not in the inherit chain of %s", + eina_strbuf_string_get(classes), cl->base.name); + eina_strbuf_free(classes); + _obj_error(&cl->base, buf); + return EINA_FALSE; + } + } + EINA_LIST_FOREACH(cl->properties, l, func) if (!_validate_function(vals, func, nhash)) diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index d80535723d..522cc41271 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -28,7 +28,7 @@ enum Tokens KW(destructor), KW(eo), KW(eo_prefix), KW(event_prefix), KW(events), \ KW(extends), KW(free), KW(get), KW(implements), KW(import), KW(interface), \ KW(keys), KW(legacy), KW(legacy_prefix), KW(methods), KW(mixin), KW(params), \ - KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), \ + KW(parse), KW(parts), KW(ptr), KW(set), KW(type), KW(values), KW(var), KW(requires), \ \ KWAT(auto), KWAT(beta), KWAT(class), KWAT(const), KWAT(cref), KWAT(empty), \ KWAT(extern), KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), KWAT(nonull), \ diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 37bed0ac1f..a06b69b6fb 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -2009,6 +2009,24 @@ inherit_dup: eo_lexer_syntax_error(ls, ebuf); } +static void +_requires_add(Eo_Lexer *ls, Eina_Strbuf *buf) +{ + const char *required; + char *fnm; + + eo_lexer_context_push(ls); + parse_name(ls, buf); + required = eina_strbuf_string_get(buf); + fnm = database_class_to_filename(required); + + ls->klass->requires = eina_list_append(ls->klass->requires, eina_stringshare_add(required)); + database_defer(ls->state, fnm, EINA_TRUE); + eo_lexer_context_pop(ls); + + free(fnm); +} + static void parse_class(Eo_Lexer *ls, Eolian_Class_Type type) { @@ -2052,6 +2070,20 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type) Eina_Strbuf *ibuf = eina_strbuf_new(); eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf); /* new inherits syntax, keep alongside old for now */ + if (ls->t.kw == KW_requires) + { + if (type != EOLIAN_CLASS_MIXIN) + { + eo_lexer_syntax_error(ls, "\"requires\" keyword is only needed for mixin classes"); + } + eo_lexer_get(ls); + do + _requires_add(ls, ibuf); + while (test_next(ls, ',')); + if (ls->t.token == '{') + goto inherit_done; + } + if (ls->t.kw == KW_extends || (is_reg && (ls->t.kw == KW_implements))) { Eina_Bool ext = (ls->t.kw == KW_extends); diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 9804449bda..fdaee09d11 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -191,6 +191,7 @@ struct _Eolian_Class Eina_List *constructors; /* Eolian_Constructor */ Eina_List *events; /* Eolian_Event */ Eina_List *parts; /* Eolian_Part */ + Eina_List *requires; /* a list of required other classes only used internally */ Eina_Bool class_ctor_enable:1; Eina_Bool class_dtor_enable:1; }; diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index 23303a0202..f69fca29d3 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -106,18 +106,20 @@ struct klass_name std::string eolian_name; qualifier_def base_qualifier; class_type type; + std::string klass_get_name; klass_name() { } klass_name(std::vector namespaces , std::string eolian_name, qualifier_def base_qualifier - , class_type type) + , class_type type, std::string klass_get_name) : namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier) - , type(type) {} + , type(type), klass_get_name(klass_get_name) {} klass_name(Eolian_Class const* klass, qualifier_def base_qualifier) : eolian_name( ::eolian_class_short_name_get(klass)) , base_qualifier(base_qualifier) + , klass_get_name( ::eolian_class_c_get_function_name_get(klass)) { for(efl::eina::iterator namespace_iterator ( ::eolian_class_namespaces_get(klass)) , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) @@ -1003,6 +1005,7 @@ struct klass_def std::set immediate_inherits; eina::optional parent; std::set extensions; + std::string klass_get_name; std::set parts; Eolian_Unit const* unit; @@ -1018,7 +1021,8 @@ struct klass_def && lhs.inherits == rhs.inherits && lhs.type == rhs.type && lhs.events == rhs.events - && lhs.parts == rhs.parts; + && lhs.parts == rhs.parts + && lhs.klass_get_name == rhs.klass_get_name; } friend inline bool operator!=(klass_def const& lhs, klass_def const& rhs) { @@ -1039,24 +1043,29 @@ struct klass_def , std::vector properties , std::set inherits , class_type type - , std::set immediate_inherits) + , std::set immediate_inherits + , std::string klass_get_name) : eolian_name(eolian_name), cxx_name(cxx_name), filename(filename) , documentation(documentation) , namespaces(namespaces) , functions(functions), properties(properties), inherits(inherits), type(type) , immediate_inherits(immediate_inherits) + , klass_get_name(klass_get_name) {} klass_def(std::string _eolian_name, std::string _cxx_name , std::vector _namespaces , std::vector _functions , std::vector _properties , std::set _inherits - , class_type _type, Eolian_Unit const* unit) + , class_type _type, Eolian_Unit const* unit + , std::string klass_get_name) : eolian_name(_eolian_name), cxx_name(_cxx_name) , namespaces(_namespaces) , functions(_functions), properties(_properties), inherits(_inherits), type(_type), unit(unit) + , klass_get_name(klass_get_name) {} klass_def(Eolian_Class const* klass, Eolian_Unit const* unit) : unit(unit) + , klass_get_name( ::eolian_class_c_get_function_name_get(klass)) { for(efl::eina::iterator namespace_iterator( ::eolian_class_namespaces_get(klass)) , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) @@ -1349,7 +1358,7 @@ struct struct_def inline klass_name get_klass_name(klass_def const& klass) { - return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type}; + return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type, klass.klass_get_name}; } inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit) diff --git a/src/lib/evas/canvas/efl_canvas_filter_internal.eo b/src/lib/evas/canvas/efl_canvas_filter_internal.eo index e25eba1584..c13d8bd5b3 100644 --- a/src/lib/evas/canvas/efl_canvas_filter_internal.eo +++ b/src/lib/evas/canvas/efl_canvas_filter_internal.eo @@ -41,7 +41,7 @@ struct Efl.Canvas.Filter.State pos: double; [[Position]] } -mixin Efl.Canvas.Filter.Internal (Efl.Gfx.Filter, Efl.Object) +mixin Efl.Canvas.Filter.Internal requires Efl.Object extends Efl.Gfx.Filter { [[Evas internal implementation of filters.]] diff --git a/src/lib/evas/canvas/efl_gfx_map.eo b/src/lib/evas/canvas/efl_gfx_map.eo index c581ba1093..9dc5b3246a 100644 --- a/src/lib/evas/canvas/efl_gfx_map.eo +++ b/src/lib/evas/canvas/efl_gfx_map.eo @@ -1,4 +1,4 @@ -mixin Efl.Gfx.Map (Efl.Interface, Efl.Object) +mixin Efl.Gfx.Map requires Efl.Object { [[Texture UV mapping for all objects (rotation, perspective, 3d, ...). diff --git a/src/lib/evas/canvas/efl_input_event.eo b/src/lib/evas/canvas/efl_input_event.eo index 48bef437ef..14b9b38e31 100644 --- a/src/lib/evas/canvas/efl_input_event.eo +++ b/src/lib/evas/canvas/efl_input_event.eo @@ -1,6 +1,6 @@ import efl_input_types; -mixin Efl.Input.Event (Efl.Interface, Efl.Object, Efl.Duplicate) +mixin Efl.Input.Event requires Efl.Object extends Efl.Duplicate { [[Represents a generic event data. diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 339d153f83..37932a1d62 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -2842,7 +2842,8 @@ _format_dup(Evas_Object *eo_obj, const Evas_Object_Textblock_Format *fmt) fmt2->gfx_filter = malloc(sizeof(*fmt2->gfx_filter)); memcpy(fmt2->gfx_filter, fmt->gfx_filter, sizeof(*fmt->gfx_filter)); fmt2->gfx_filter->name = eina_stringshare_ref(fmt->gfx_filter->name); - fmt2->gfx_filter->dc = ENFN->context_dup(ENC, fmt->gfx_filter->dc); + if (fmt->gfx_filter->dc) + fmt2->gfx_filter->dc = ENFN->context_dup(ENC, fmt->gfx_filter->dc); } return fmt2; @@ -6787,6 +6788,8 @@ _relayout_if_needed(const Evas_Object *eo_obj, Efl_Canvas_Text_Data *o) ASYNC_BLOCK; Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + if (obj->delete_me) return EINA_TRUE; + /* XXX const */ evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data); if (o->formatted.valid) @@ -14855,7 +14858,11 @@ evas_object_textblock_render_pre(Evas_Object *eo_obj, if ((obj->cur->color.r != obj->prev->color.r) || (obj->cur->color.g != obj->prev->color.g) || (obj->cur->color.b != obj->prev->color.b) || - (obj->cur->color.a != obj->prev->color.a)) + (obj->cur->color.a != obj->prev->color.a) || + (obj->cur->cache.clip.r != obj->prev->cache.clip.r) || + (obj->cur->cache.clip.g != obj->prev->cache.clip.g) || + (obj->cur->cache.clip.b != obj->prev->cache.clip.b) || + (obj->cur->cache.clip.a != obj->prev->cache.clip.a)) { evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj); diff --git a/src/lib/evas/meson.build b/src/lib/evas/meson.build index 10b6fcd920..1b306c363e 100644 --- a/src/lib/evas/meson.build +++ b/src/lib/evas/meson.build @@ -139,7 +139,7 @@ if (get_option('hyphen')) evas_deps += cc.find_library('hyphen') endif evas_deps += hyphen - config_h.set_quoted('EVAS_DICTS_HYPHEN_DIR', '/usr/share/hyphen') + config_h.set_quoted('EVAS_DICTS_HYPHEN_DIR', get_option('dictionaries-hyphen-dir')) endif subdir('include') diff --git a/src/modules/ecore_buffer/meson.build b/src/modules/ecore_buffer/meson.build index 00f393fdb4..1982c7bcd7 100644 --- a/src/modules/ecore_buffer/meson.build +++ b/src/modules/ecore_buffer/meson.build @@ -4,22 +4,19 @@ subdir('shm') #common dri packages libtbm = dependency('libtbm', required: false) -libdrm = dependency('libdrm', required: false) -if libtbm.found() == true and libdrm.found() == true +if libtbm.found() == true libdri2 = dependency('libdri2', required: false) if libdri2.found() subdir('x11_dri2') endif -endif -if libtbm.found() == true and libdrm.found() == true xshmfence = dependency('xshmfence', required: false) xcb = dependency('xcb', required: false) x11_xcb = dependency('x11_xcb', required: false) xcb_sync = dependency('xcb_sync', required: false) xcb_dri3 = dependency('xkb_dri3', required: false) if xshmfence.found() == true and xcb.found() == true and x11_xcb.found() and xcb_sync.found() and xkb_dri3.found() - subdir('x11_dri3') + subdir('x11_dri3') endif endif diff --git a/src/modules/evas/engines/gl_common/evas_gl_font.c b/src/modules/evas/engines/gl_common/evas_gl_font.c index 2e2c5263a9..3d5d436448 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_font.c +++ b/src/modules/evas/engines/gl_common/evas_gl_font.c @@ -5,7 +5,7 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg) { Evas_Engine_GL_Context *gc = context; Evas_GL_Texture *tex; - int w, h, j, nw, fh, x, y; + int w, h, j, nw, fh, y; DATA8 *ndata, *data, *p1, *p2; if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :( @@ -22,19 +22,21 @@ evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg) // expand to 32bit (4 byte) aligned rows for texture upload nw = ((w + 3) / 4) * 4; - ndata = alloca(nw *h); - if (!ndata) return NULL; - for (y = 0; y < h; y++) - { + // if image already (4 byte) aligned rows then assign old image data to new data(ndata) to + if(nw == w){ + ndata = data; + } else { + ndata = alloca(nw *h); + if (!ndata) return NULL; + // else copy row by row + for (y = 0; y < h; y++) + { p1 = data + (j * y); p2 = ndata + (nw * y); - for (x = 0; x < w; x++) - { - *p2 = *p1; - p1++; - p2++; - } - } + memcpy(p2,p1,w); + } + } + fh = fg->fi->max_h; tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh); if (!tex) goto done; diff --git a/src/tests/ecore/efl_app_test_promise.c b/src/tests/ecore/efl_app_test_promise.c index 6f71881df3..610851045c 100644 --- a/src/tests/ecore/efl_app_test_promise.c +++ b/src/tests/ecore/efl_app_test_promise.c @@ -1341,7 +1341,7 @@ test_got_int(Eo *o EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value value) } static Eina_Value -test_error_not_reached(Eo *o EINA_UNUSED, void *data EINA_UNUSED, Eina_Error error) +test_error_not_reached(Eo *o EINA_UNUSED, void *data EINA_UNUSED, Eina_Error error EINA_UNUSED) { abort(); diff --git a/src/tests/efl/efl_test_model_view.c b/src/tests/efl/efl_test_model_view.c index 94d05d5331..fead57cae7 100644 --- a/src/tests/efl/efl_test_model_view.c +++ b/src/tests/efl/efl_test_model_view.c @@ -214,7 +214,7 @@ _efl_test_model_view_child_get(Eo *obj EINA_UNUSED, static Eina_Value _efl_test_model_view_child_fetch(Eo *mv, void *data EINA_UNUSED, - const Eina_Value v) + const Eina_Value v EINA_UNUSED) { Eina_Future *r; diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs index 119659b923..db42b23d7f 100644 --- a/src/tests/efl_mono/Eina.cs +++ b/src/tests/efl_mono/Eina.cs @@ -7,283 +7,6 @@ using System.Runtime.CompilerServices; using EinaTestData; using static EinaTestData.BaseData; -namespace EinaTestData -{ - -class BaseSequence -{ - public static byte[] Values() - { - return new byte[3]{0x0,0x2A,0x42}; - } -} - -public static class BaseData -{ - public static readonly int[] base_seq_int = {0x0,0x2A,0x42}; - public static readonly int[] append_seq_int = {42,43,33}; - public static readonly int[] modified_seq_int = {0x0,0x2A,0x42,42,43,33}; - - public static readonly string[] base_seq_str = {"0x0","0x2A","0x42"}; - public static readonly string[] append_seq_str = {"42","43","33"}; - public static readonly string[] modified_seq_str = {"0x0","0x2A","0x42","42","43","33"}; - - public static Dummy.Numberwrapper NW(int n) - { - var nw = new Dummy.Numberwrapper(); - nw.SetNumber(n); - return nw; - } - - public static Dummy.Numberwrapper[] BaseSeqObj() - { - var a = new Dummy.Numberwrapper(); - var b = new Dummy.Numberwrapper(); - var c = new Dummy.Numberwrapper(); - a.SetNumber(0x0); - b.SetNumber(0x2A); - c.SetNumber(0x42); - return new Dummy.Numberwrapper[]{a,b,c}; - } - - public static Dummy.Numberwrapper[] AppendSeqObj() - { - var a = new Dummy.Numberwrapper(); - var b = new Dummy.Numberwrapper(); - var c = new Dummy.Numberwrapper(); - a.SetNumber(42); - b.SetNumber(43); - c.SetNumber(33); - return new Dummy.Numberwrapper[]{a,b,c}; - } - - public static Dummy.Numberwrapper[] ModifiedSeqObj() - { - var a = new Dummy.Numberwrapper(); - var b = new Dummy.Numberwrapper(); - var c = new Dummy.Numberwrapper(); - var d = new Dummy.Numberwrapper(); - var e = new Dummy.Numberwrapper(); - var f = new Dummy.Numberwrapper(); - a.SetNumber(0x0); - b.SetNumber(0x2A); - c.SetNumber(0x42); - d.SetNumber(42); - e.SetNumber(43); - f.SetNumber(33); - return new Dummy.Numberwrapper[]{a,b,c,d,e,f}; - } - - public static void NumberwrapperSequenceAssertEqual( - Dummy.Numberwrapper[] a - , Dummy.Numberwrapper[] b - , [CallerLineNumber] int line = 0 - , [CallerFilePath] string file = null - , [CallerMemberName] string member = null) - { - Test.Assert(a.Length == b.Length, "Different lenght", line, file, member); - for (int i = 0; i < a.Length; ++i) - { - int av = a[i].GetNumber(); - int bv = b[i].GetNumber(); - Test.Assert(av == bv, $"Different values for element [{i}]: {av} == {bv}", line, file, member); - } - } -} - -class NativeInheritImpl : Dummy.TestObject -{ - public NativeInheritImpl(Efl.Object parent = null) : base(parent) {} - - public bool slice_in_flag = false; - public bool rw_slice_in_flag = false; - public bool slice_out_flag = false; - public bool rw_slice_out_flag = false; - public bool binbuf_in_flag = false; - public bool binbuf_in_own_flag = false; - public bool binbuf_out_flag = false; - public bool binbuf_out_own_flag = false; - public bool binbuf_return_flag = false; - public bool binbuf_return_own_flag = false; - - override public bool EinaSliceIn(Eina.Slice slice) - { - slice_in_flag = true; - return slice.GetBytes().SequenceEqual(BaseSequence.Values()); - } - - override public bool EinaRwSliceIn(Eina.RwSlice slice) - { - rw_slice_in_flag = true; - return slice.GetBytes().SequenceEqual(BaseSequence.Values()); - } - - private byte[] slice_out_seq = null; - private GCHandle slice_out_pinned; - override public bool EinaSliceOut(ref Eina.Slice slice) - { - slice_out_flag = true; - - slice_out_seq = (byte[]) BaseSequence.Values(); - slice_out_pinned = GCHandle.Alloc(slice_out_seq, GCHandleType.Pinned); - IntPtr ptr = slice_out_pinned.AddrOfPinnedObject(); - - slice.Mem = ptr; - slice.Len = (UIntPtr) slice_out_seq.Length; - - return true; - } - - private byte[] rw_slice_out_seq = null; - private GCHandle rw_slice_out_pinned; - override public bool EinaRwSliceOut(ref Eina.RwSlice slice) - { - rw_slice_out_flag = true; - - rw_slice_out_seq = (byte[]) BaseSequence.Values(); - rw_slice_out_pinned = GCHandle.Alloc(rw_slice_out_seq, GCHandleType.Pinned); - IntPtr ptr = rw_slice_out_pinned.AddrOfPinnedObject(); - - slice.Mem = ptr; - slice.Len = (UIntPtr) rw_slice_out_seq.Length; - - return true; - } - - // // - // - override public bool EinaBinbufIn(Eina.Binbuf binbuf) - { - binbuf_in_flag = true; - - bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); - r = r && !binbuf.Own; - - binbuf.Insert(42, 0); - binbuf.Insert(43, 0); - binbuf.Append(33); - - binbuf.Dispose(); - - return r; - } - - private Eina.Binbuf binbuf_in_own_binbuf = null; - override public bool EinaBinbufInOwn(Eina.Binbuf binbuf) - { - binbuf_in_own_flag = true; - - bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); - r = r && binbuf.Own; - - binbuf.Insert(42, 0); - binbuf.Insert(43, 0); - binbuf.Append(33); - - binbuf_in_own_binbuf = binbuf; - - return r; - } - public bool binbuf_in_own_still_usable() - { - bool r = binbuf_in_own_binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33}); - r = r && binbuf_in_own_binbuf.Own; - - binbuf_in_own_binbuf.Dispose(); - binbuf_in_own_binbuf = null; - - return r; - } - - private Eina.Binbuf binbuf_out_binbuf = null; - override public bool EinaBinbufOut(out Eina.Binbuf binbuf) - { - binbuf_out_flag = true; - - binbuf = new Eina.Binbuf(); - binbuf.Append(33); - - binbuf_out_binbuf = binbuf; - - return true; - } - public bool binbuf_out_still_usable() - { - bool r = binbuf_out_binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); - r = r && binbuf_out_binbuf.Own; - - binbuf_out_binbuf.Dispose(); - binbuf_out_binbuf = null; - - return r; - } - - private Eina.Binbuf binbuf_out_own_binbuf = null; - override public bool EinaBinbufOutOwn(out Eina.Binbuf binbuf) - { - binbuf_out_own_flag = true; - - binbuf = new Eina.Binbuf(); - binbuf.Append(33); - - binbuf_out_own_binbuf = binbuf; - - return true; - } - public bool binbuf_out_own_no_longer_own() - { - bool r = !binbuf_out_own_binbuf.Own; - binbuf_out_own_binbuf.Dispose(); - binbuf_out_own_binbuf = null; - return r; - } - - private Eina.Binbuf binbuf_return_binbuf = null; - override public Eina.Binbuf EinaBinbufReturn() - { - binbuf_return_flag = true; - - var binbuf = new Eina.Binbuf(); - binbuf.Append(33); - - binbuf_return_binbuf = binbuf; - - return binbuf; - } - public bool binbuf_return_still_usable() - { - bool r = binbuf_return_binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); - r = r && binbuf_return_binbuf.Own; - - binbuf_return_binbuf.Dispose(); - binbuf_return_binbuf = null; - - return r; - } - - private Eina.Binbuf binbuf_return_own_binbuf = null; - override public Eina.Binbuf EinaBinbufReturnOwn() - { - binbuf_return_own_flag = true; - - var binbuf = new Eina.Binbuf(); - binbuf.Append(33); - - binbuf_return_own_binbuf = binbuf; - - return binbuf; - } - public bool binbuf_return_own_no_longer_own() - { - bool r = !binbuf_return_own_binbuf.Own; - binbuf_return_own_binbuf.Dispose(); - binbuf_return_own_binbuf = null; - return r; - } -} - -} // EinaTestData - namespace TestSuite { diff --git a/src/tests/efl_mono/EinaTestData.cs b/src/tests/efl_mono/EinaTestData.cs new file mode 100644 index 0000000000..c4272a8ca2 --- /dev/null +++ b/src/tests/efl_mono/EinaTestData.cs @@ -0,0 +1,283 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +namespace EinaTestData +{ + +class BaseSequence +{ + public static byte[] Values() + { + return new byte[3]{0x0,0x2A,0x42}; + } +} + +public static class BaseData +{ + public static readonly int[] base_seq_int = {0x0,0x2A,0x42}; + public static readonly int[] append_seq_int = {42,43,33}; + public static readonly int[] modified_seq_int = {0x0,0x2A,0x42,42,43,33}; + + public static readonly string[] base_seq_str = {"0x0","0x2A","0x42"}; + public static readonly string[] append_seq_str = {"42","43","33"}; + public static readonly string[] modified_seq_str = {"0x0","0x2A","0x42","42","43","33"}; + + public static Dummy.Numberwrapper NW(int n) + { + var nw = new Dummy.Numberwrapper(); + nw.SetNumber(n); + return nw; + } + + public static Dummy.Numberwrapper[] BaseSeqObj() + { + var a = new Dummy.Numberwrapper(); + var b = new Dummy.Numberwrapper(); + var c = new Dummy.Numberwrapper(); + a.SetNumber(0x0); + b.SetNumber(0x2A); + c.SetNumber(0x42); + return new Dummy.Numberwrapper[]{a,b,c}; + } + + public static Dummy.Numberwrapper[] AppendSeqObj() + { + var a = new Dummy.Numberwrapper(); + var b = new Dummy.Numberwrapper(); + var c = new Dummy.Numberwrapper(); + a.SetNumber(42); + b.SetNumber(43); + c.SetNumber(33); + return new Dummy.Numberwrapper[]{a,b,c}; + } + + public static Dummy.Numberwrapper[] ModifiedSeqObj() + { + var a = new Dummy.Numberwrapper(); + var b = new Dummy.Numberwrapper(); + var c = new Dummy.Numberwrapper(); + var d = new Dummy.Numberwrapper(); + var e = new Dummy.Numberwrapper(); + var f = new Dummy.Numberwrapper(); + a.SetNumber(0x0); + b.SetNumber(0x2A); + c.SetNumber(0x42); + d.SetNumber(42); + e.SetNumber(43); + f.SetNumber(33); + return new Dummy.Numberwrapper[]{a,b,c,d,e,f}; + } + + public static void NumberwrapperSequenceAssertEqual( + Dummy.Numberwrapper[] a + , Dummy.Numberwrapper[] b + , [CallerLineNumber] int line = 0 + , [CallerFilePath] string file = null + , [CallerMemberName] string member = null) + { + Test.Assert(a.Length == b.Length, "Different lenght", line, file, member); + for (int i = 0; i < a.Length; ++i) + { + int av = a[i].GetNumber(); + int bv = b[i].GetNumber(); + Test.Assert(av == bv, $"Different values for element [{i}]: {av} == {bv}", line, file, member); + } + } +} + +class NativeInheritImpl : Dummy.TestObject +{ + public NativeInheritImpl(Efl.Object parent = null) : base(parent) {} + + public bool slice_in_flag = false; + public bool rw_slice_in_flag = false; + public bool slice_out_flag = false; + public bool rw_slice_out_flag = false; + public bool binbuf_in_flag = false; + public bool binbuf_in_own_flag = false; + public bool binbuf_out_flag = false; + public bool binbuf_out_own_flag = false; + public bool binbuf_return_flag = false; + public bool binbuf_return_own_flag = false; + + override public bool EinaSliceIn(Eina.Slice slice) + { + slice_in_flag = true; + return slice.GetBytes().SequenceEqual(BaseSequence.Values()); + } + + override public bool EinaRwSliceIn(Eina.RwSlice slice) + { + rw_slice_in_flag = true; + return slice.GetBytes().SequenceEqual(BaseSequence.Values()); + } + + private byte[] slice_out_seq = null; + private GCHandle slice_out_pinned; + override public bool EinaSliceOut(ref Eina.Slice slice) + { + slice_out_flag = true; + + slice_out_seq = (byte[]) BaseSequence.Values(); + slice_out_pinned = GCHandle.Alloc(slice_out_seq, GCHandleType.Pinned); + IntPtr ptr = slice_out_pinned.AddrOfPinnedObject(); + + slice.Mem = ptr; + slice.Len = (UIntPtr) slice_out_seq.Length; + + return true; + } + + private byte[] rw_slice_out_seq = null; + private GCHandle rw_slice_out_pinned; + override public bool EinaRwSliceOut(ref Eina.RwSlice slice) + { + rw_slice_out_flag = true; + + rw_slice_out_seq = (byte[]) BaseSequence.Values(); + rw_slice_out_pinned = GCHandle.Alloc(rw_slice_out_seq, GCHandleType.Pinned); + IntPtr ptr = rw_slice_out_pinned.AddrOfPinnedObject(); + + slice.Mem = ptr; + slice.Len = (UIntPtr) rw_slice_out_seq.Length; + + return true; + } + + // // + // + override public bool EinaBinbufIn(Eina.Binbuf binbuf) + { + binbuf_in_flag = true; + + bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); + r = r && !binbuf.Own; + + binbuf.Insert(42, 0); + binbuf.Insert(43, 0); + binbuf.Append(33); + + binbuf.Dispose(); + + return r; + } + + private Eina.Binbuf binbuf_in_own_binbuf = null; + override public bool EinaBinbufInOwn(Eina.Binbuf binbuf) + { + binbuf_in_own_flag = true; + + bool r = binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); + r = r && binbuf.Own; + + binbuf.Insert(42, 0); + binbuf.Insert(43, 0); + binbuf.Append(33); + + binbuf_in_own_binbuf = binbuf; + + return r; + } + public bool binbuf_in_own_still_usable() + { + bool r = binbuf_in_own_binbuf.GetBytes().SequenceEqual(new byte[]{43,42,0x0,0x2A,0x42,33}); + r = r && binbuf_in_own_binbuf.Own; + + binbuf_in_own_binbuf.Dispose(); + binbuf_in_own_binbuf = null; + + return r; + } + + private Eina.Binbuf binbuf_out_binbuf = null; + override public bool EinaBinbufOut(out Eina.Binbuf binbuf) + { + binbuf_out_flag = true; + + binbuf = new Eina.Binbuf(); + binbuf.Append(33); + + binbuf_out_binbuf = binbuf; + + return true; + } + public bool binbuf_out_still_usable() + { + bool r = binbuf_out_binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); + r = r && binbuf_out_binbuf.Own; + + binbuf_out_binbuf.Dispose(); + binbuf_out_binbuf = null; + + return r; + } + + private Eina.Binbuf binbuf_out_own_binbuf = null; + override public bool EinaBinbufOutOwn(out Eina.Binbuf binbuf) + { + binbuf_out_own_flag = true; + + binbuf = new Eina.Binbuf(); + binbuf.Append(33); + + binbuf_out_own_binbuf = binbuf; + + return true; + } + public bool binbuf_out_own_no_longer_own() + { + bool r = !binbuf_out_own_binbuf.Own; + binbuf_out_own_binbuf.Dispose(); + binbuf_out_own_binbuf = null; + return r; + } + + private Eina.Binbuf binbuf_return_binbuf = null; + override public Eina.Binbuf EinaBinbufReturn() + { + binbuf_return_flag = true; + + var binbuf = new Eina.Binbuf(); + binbuf.Append(33); + + binbuf_return_binbuf = binbuf; + + return binbuf; + } + public bool binbuf_return_still_usable() + { + bool r = binbuf_return_binbuf.GetBytes().SequenceEqual(BaseSequence.Values()); + r = r && binbuf_return_binbuf.Own; + + binbuf_return_binbuf.Dispose(); + binbuf_return_binbuf = null; + + return r; + } + + private Eina.Binbuf binbuf_return_own_binbuf = null; + override public Eina.Binbuf EinaBinbufReturnOwn() + { + binbuf_return_own_flag = true; + + var binbuf = new Eina.Binbuf(); + binbuf.Append(33); + + binbuf_return_own_binbuf = binbuf; + + return binbuf; + } + public bool binbuf_return_own_no_longer_own() + { + bool r = !binbuf_return_own_binbuf.Own; + binbuf_return_own_binbuf.Dispose(); + binbuf_return_own_binbuf = null; + return r; + } +} + +} // EinaTestData + + diff --git a/src/tests/efl_mono/Events.cs b/src/tests/efl_mono/Events.cs index 7387c1e1b4..84918b9ca8 100644 --- a/src/tests/efl_mono/Events.cs +++ b/src/tests/efl_mono/Events.cs @@ -148,6 +148,22 @@ class TestEoEvents Test.AssertEquals(sent_struct.Fstring, received_struct.Fstring); } + public static void event_with_struct_complex_payload() + { + var obj = new Dummy.TestObject(); + Dummy.StructComplex received_struct = default(Dummy.StructComplex); + + obj.EvtWithStructComplexEvt += (object sender, Dummy.TestObjectEvtWithStructComplexEvt_Args e) => { + received_struct = e.arg; + }; + + Dummy.StructComplex sent_struct = StructHelpers.structComplexWithValues(); + + obj.EmitEventWithStructComplex(sent_struct); + + Test.AssertEquals(sent_struct.Fobj, received_struct.Fobj); + } + public static void event_in_init_callback() { int received = 0; diff --git a/src/tests/efl_mono/StructHelpers.cs b/src/tests/efl_mono/StructHelpers.cs new file mode 100644 index 0000000000..1b05a072fc --- /dev/null +++ b/src/tests/efl_mono/StructHelpers.cs @@ -0,0 +1,235 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; + +using static EinaTestData.BaseData; + +namespace TestSuite +{ + +internal class StructHelpers +{ + // Auxiliary function // + + internal static Dummy.StructSimple structSimpleWithValues() + { + var simple = new Dummy.StructSimple(); + + simple.Fbyte = (sbyte)-126; + simple.Fubyte = (byte) 254u; + simple.Fchar = '~'; + simple.Fshort = (short) -32766; + simple.Fushort = (ushort) 65534u; + simple.Fint = -32766; + simple.Fuint = 65534u; + simple.Flong = -2147483646; + simple.Fulong = 4294967294u; + simple.Fllong = -9223372036854775806; + simple.Fullong = 18446744073709551614u; + simple.Fint8 = (sbyte) -126; + simple.Fuint8 = (byte) 254u; + simple.Fint16 = (short) -32766; + simple.Fuint16 = (ushort) 65534u; + simple.Fint32 = -2147483646; + simple.Fuint32 = 4294967294u; + simple.Fint64 = -9223372036854775806; + simple.Fuint64 = 18446744073709551614u; + simple.Fssize = -2147483646; + simple.Fsize = 4294967294u; + simple.Fintptr = (IntPtr) 0xFE; + simple.Fptrdiff = -2147483646; + simple.Ffloat = -16777216.0f; + simple.Fdouble = -9007199254740992.0; + simple.Fbool = true; + simple.Fvoid_ptr = (IntPtr) 0xFE; + simple.Fenum = Dummy.SampleEnum.V2; + simple.Fstring = "test/string"; + simple.Fmstring = "test/mstring"; + simple.Fstringshare = "test/stringshare"; + + return simple; + } + + internal static void checkStructSimple(Dummy.StructSimple simple) + { + Test.Assert(simple.Fbyte == (sbyte) -126); + Test.Assert(simple.Fubyte == (byte) 254u); + Test.Assert(simple.Fchar == '~'); + Test.Assert(simple.Fshort == (short) -32766); + Test.Assert(simple.Fushort == (ushort) 65534u); + Test.Assert(simple.Fint == -32766); + Test.Assert(simple.Fuint == 65534u); + Test.Assert(simple.Flong == -2147483646); + Test.Assert(simple.Fulong == 4294967294u); + Test.Assert(simple.Fllong == -9223372036854775806); + Test.Assert(simple.Fullong == 18446744073709551614u); + Test.Assert(simple.Fint8 == (sbyte) -126); + Test.Assert(simple.Fuint8 == (byte) 254u); + Test.Assert(simple.Fint16 == (short) -32766); + Test.Assert(simple.Fuint16 == (ushort) 65534u); + Test.Assert(simple.Fint32 == -2147483646); + Test.Assert(simple.Fuint32 == 4294967294u); + Test.Assert(simple.Fint64 == -9223372036854775806); + Test.Assert(simple.Fuint64 == 18446744073709551614u); + Test.Assert(simple.Fssize == -2147483646); + Test.Assert(simple.Fsize == 4294967294u); + Test.Assert(simple.Fintptr == (IntPtr) 0xFE); + Test.Assert(simple.Fptrdiff == -2147483646); + Test.Assert(simple.Ffloat == -16777216.0f); + Test.Assert(simple.Fdouble == -9007199254740992.0); + Test.Assert(simple.Fbool == true); + Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE); + Test.Assert(simple.Fenum == Dummy.SampleEnum.V2); + Test.Assert(simple.Fstring == "test/string"); + Test.Assert(simple.Fmstring == "test/mstring"); + Test.Assert(simple.Fstringshare == "test/stringshare"); + } + + internal static void checkZeroedStructSimple(Dummy.StructSimple simple) + { + Test.Assert(simple.Fbyte == 0); + Test.Assert(simple.Fubyte == 0); + Test.Assert(simple.Fchar == '\0'); + Test.Assert(simple.Fshort == 0); + Test.Assert(simple.Fushort == 0); + Test.Assert(simple.Fint == 0); + Test.Assert(simple.Fuint == 0); + Test.Assert(simple.Flong == 0); + Test.Assert(simple.Fulong == 0); + Test.Assert(simple.Fllong == 0); + Test.Assert(simple.Fullong == 0); + Test.Assert(simple.Fint8 == 0); + Test.Assert(simple.Fuint8 == 0); + Test.Assert(simple.Fint16 == 0); + Test.Assert(simple.Fuint16 == 0); + Test.Assert(simple.Fint32 == 0); + Test.Assert(simple.Fuint32 == 0); + Test.Assert(simple.Fint64 == 0); + Test.Assert(simple.Fuint64 == 0); + Test.Assert(simple.Fssize == 0); + Test.Assert(simple.Fsize == 0); + Test.Assert(simple.Fintptr == IntPtr.Zero); + Test.Assert(simple.Fptrdiff == 0); + Test.Assert(simple.Ffloat == 0); + Test.Assert(simple.Fdouble == 0); + Test.Assert(simple.Fbool == false); + Test.Assert(simple.Fvoid_ptr == IntPtr.Zero); + Test.Assert(simple.Fenum == Dummy.SampleEnum.V0); + Test.Assert(simple.Fstring == null); + Test.Assert(simple.Fmstring == null); + Test.Assert(simple.Fstringshare == null); + } + + internal static Dummy.StructComplex structComplexWithValues() + { + var complex = new Dummy.StructComplex(); + + complex.Farray = new Eina.Array(); + complex.Farray.Push(0x0); + complex.Farray.Push(0x2A); + complex.Farray.Push(0x42); + + complex.Finarray = new Eina.Inarray(); + complex.Finarray.Push(0x0); + complex.Finarray.Push(0x2A); + complex.Finarray.Push(0x42); + + + complex.Flist = new Eina.List(); + complex.Flist.Append("0x0"); + complex.Flist.Append("0x2A"); + complex.Flist.Append("0x42"); + + complex.Finlist = new Eina.Inlist(); + complex.Finlist.Append(0x0); + complex.Finlist.Append(0x2A); + complex.Finlist.Append(0x42); + + complex.Fhash = new Eina.Hash(); + complex.Fhash["aa"] = "aaa"; + complex.Fhash["bb"] = "bbb"; + complex.Fhash["cc"] = "ccc"; + + complex.Fiterator = complex.Farray.GetIterator(); + + complex.Fany_value = new Eina.Value(Eina.ValueType.Double); + complex.Fany_value.Set(-9007199254740992.0); + + complex.Fany_value_ptr = new Eina.Value(Eina.ValueType.String); + complex.Fany_value_ptr.Set("abc"); + + complex.Fbinbuf = new Eina.Binbuf(); + complex.Fbinbuf.Append(126); + + complex.Fslice.Length = 1; + complex.Fslice.Mem = Eina.MemoryNative.Alloc(1); + Marshal.WriteByte(complex.Fslice.Mem, 125); + + complex.Fobj = new Dummy.Numberwrapper(); + complex.Fobj.SetNumber(42); + + return complex; + } + + internal static void checkStructComplex(Dummy.StructComplex complex) + { + Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int)); + + Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int)); + + Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str)); + + Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int)); + + Test.Assert(complex.Fhash["aa"] == "aaa"); + Test.Assert(complex.Fhash["bb"] == "bbb"); + Test.Assert(complex.Fhash["cc"] == "ccc"); + + int idx = 0; + foreach (int e in complex.Fiterator) + { + Test.Assert(e == base_seq_int[idx]); + ++idx; + } + + double double_val = 0; + Test.Assert(complex.Fany_value.Get(out double_val)); + Test.Assert(double_val == -9007199254740992.0); + + string str_val = null; + Test.Assert(complex.Fany_value_ptr.Get(out str_val)); + Test.Assert(str_val == "abc"); + + Test.Assert(complex.Fbinbuf.Length == 1); + Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126); + + Test.Assert(complex.Fslice.Length == 1); + Test.Assert(complex.Fslice.GetBytes()[0] == 125); + + Test.Assert(complex.Fobj != null); + Test.Assert(complex.Fobj.GetNumber() == 42); + } + + + internal static void checkZeroedStructComplex(Dummy.StructComplex complex) + { + Test.Assert(complex.Farray == null); + Test.Assert(complex.Finarray == null); + Test.Assert(complex.Flist == null); + Test.Assert(complex.Finlist == null); + Test.Assert(complex.Fhash == null); + Test.Assert(complex.Fiterator == null); + Test.Assert(complex.Fany_value == null); + Test.Assert(complex.Fany_value_ptr == null); + Test.Assert(complex.Fbinbuf == null); + + Test.Assert(complex.Fslice.Length == 0); + Test.Assert(complex.Fslice.Mem == IntPtr.Zero); + + Test.Assert(complex.Fobj == null); + } + + +} + +} diff --git a/src/tests/efl_mono/Structs.cs b/src/tests/efl_mono/Structs.cs index d2bb464c85..71246b3198 100644 --- a/src/tests/efl_mono/Structs.cs +++ b/src/tests/efl_mono/Structs.cs @@ -3,232 +3,13 @@ using System.Runtime.InteropServices; using System.Linq; using static EinaTestData.BaseData; +using static TestSuite.StructHelpers; namespace TestSuite { -class TestStructs +internal class TestStructs { - // Auxiliary function // - - private static Dummy.StructSimple structSimpleWithValues() - { - var simple = new Dummy.StructSimple(); - - simple.Fbyte = (sbyte)-126; - simple.Fubyte = (byte) 254u; - simple.Fchar = '~'; - simple.Fshort = (short) -32766; - simple.Fushort = (ushort) 65534u; - simple.Fint = -32766; - simple.Fuint = 65534u; - simple.Flong = -2147483646; - simple.Fulong = 4294967294u; - simple.Fllong = -9223372036854775806; - simple.Fullong = 18446744073709551614u; - simple.Fint8 = (sbyte) -126; - simple.Fuint8 = (byte) 254u; - simple.Fint16 = (short) -32766; - simple.Fuint16 = (ushort) 65534u; - simple.Fint32 = -2147483646; - simple.Fuint32 = 4294967294u; - simple.Fint64 = -9223372036854775806; - simple.Fuint64 = 18446744073709551614u; - simple.Fssize = -2147483646; - simple.Fsize = 4294967294u; - simple.Fintptr = (IntPtr) 0xFE; - simple.Fptrdiff = -2147483646; - simple.Ffloat = -16777216.0f; - simple.Fdouble = -9007199254740992.0; - simple.Fbool = true; - simple.Fvoid_ptr = (IntPtr) 0xFE; - simple.Fenum = Dummy.SampleEnum.V2; - simple.Fstring = "test/string"; - simple.Fmstring = "test/mstring"; - simple.Fstringshare = "test/stringshare"; - - return simple; - } - - private static void checkStructSimple(Dummy.StructSimple simple) - { - Test.Assert(simple.Fbyte == (sbyte) -126); - Test.Assert(simple.Fubyte == (byte) 254u); - Test.Assert(simple.Fchar == '~'); - Test.Assert(simple.Fshort == (short) -32766); - Test.Assert(simple.Fushort == (ushort) 65534u); - Test.Assert(simple.Fint == -32766); - Test.Assert(simple.Fuint == 65534u); - Test.Assert(simple.Flong == -2147483646); - Test.Assert(simple.Fulong == 4294967294u); - Test.Assert(simple.Fllong == -9223372036854775806); - Test.Assert(simple.Fullong == 18446744073709551614u); - Test.Assert(simple.Fint8 == (sbyte) -126); - Test.Assert(simple.Fuint8 == (byte) 254u); - Test.Assert(simple.Fint16 == (short) -32766); - Test.Assert(simple.Fuint16 == (ushort) 65534u); - Test.Assert(simple.Fint32 == -2147483646); - Test.Assert(simple.Fuint32 == 4294967294u); - Test.Assert(simple.Fint64 == -9223372036854775806); - Test.Assert(simple.Fuint64 == 18446744073709551614u); - Test.Assert(simple.Fssize == -2147483646); - Test.Assert(simple.Fsize == 4294967294u); - Test.Assert(simple.Fintptr == (IntPtr) 0xFE); - Test.Assert(simple.Fptrdiff == -2147483646); - Test.Assert(simple.Ffloat == -16777216.0f); - Test.Assert(simple.Fdouble == -9007199254740992.0); - Test.Assert(simple.Fbool == true); - Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE); - Test.Assert(simple.Fenum == Dummy.SampleEnum.V2); - Test.Assert(simple.Fstring == "test/string"); - Test.Assert(simple.Fmstring == "test/mstring"); - Test.Assert(simple.Fstringshare == "test/stringshare"); - } - - private static void checkZeroedStructSimple(Dummy.StructSimple simple) - { - Test.Assert(simple.Fbyte == 0); - Test.Assert(simple.Fubyte == 0); - Test.Assert(simple.Fchar == '\0'); - Test.Assert(simple.Fshort == 0); - Test.Assert(simple.Fushort == 0); - Test.Assert(simple.Fint == 0); - Test.Assert(simple.Fuint == 0); - Test.Assert(simple.Flong == 0); - Test.Assert(simple.Fulong == 0); - Test.Assert(simple.Fllong == 0); - Test.Assert(simple.Fullong == 0); - Test.Assert(simple.Fint8 == 0); - Test.Assert(simple.Fuint8 == 0); - Test.Assert(simple.Fint16 == 0); - Test.Assert(simple.Fuint16 == 0); - Test.Assert(simple.Fint32 == 0); - Test.Assert(simple.Fuint32 == 0); - Test.Assert(simple.Fint64 == 0); - Test.Assert(simple.Fuint64 == 0); - Test.Assert(simple.Fssize == 0); - Test.Assert(simple.Fsize == 0); - Test.Assert(simple.Fintptr == IntPtr.Zero); - Test.Assert(simple.Fptrdiff == 0); - Test.Assert(simple.Ffloat == 0); - Test.Assert(simple.Fdouble == 0); - Test.Assert(simple.Fbool == false); - Test.Assert(simple.Fvoid_ptr == IntPtr.Zero); - Test.Assert(simple.Fenum == Dummy.SampleEnum.V0); - Test.Assert(simple.Fstring == null); - Test.Assert(simple.Fmstring == null); - Test.Assert(simple.Fstringshare == null); - } - - private static Dummy.StructComplex structComplexWithValues() - { - var complex = new Dummy.StructComplex(); - - complex.Farray = new Eina.Array(); - complex.Farray.Push(0x0); - complex.Farray.Push(0x2A); - complex.Farray.Push(0x42); - - complex.Finarray = new Eina.Inarray(); - complex.Finarray.Push(0x0); - complex.Finarray.Push(0x2A); - complex.Finarray.Push(0x42); - - - complex.Flist = new Eina.List(); - complex.Flist.Append("0x0"); - complex.Flist.Append("0x2A"); - complex.Flist.Append("0x42"); - - complex.Finlist = new Eina.Inlist(); - complex.Finlist.Append(0x0); - complex.Finlist.Append(0x2A); - complex.Finlist.Append(0x42); - - complex.Fhash = new Eina.Hash(); - complex.Fhash["aa"] = "aaa"; - complex.Fhash["bb"] = "bbb"; - complex.Fhash["cc"] = "ccc"; - - complex.Fiterator = complex.Farray.GetIterator(); - - complex.Fany_value = new Eina.Value(Eina.ValueType.Double); - complex.Fany_value.Set(-9007199254740992.0); - - complex.Fany_value_ptr = new Eina.Value(Eina.ValueType.String); - complex.Fany_value_ptr.Set("abc"); - - complex.Fbinbuf = new Eina.Binbuf(); - complex.Fbinbuf.Append(126); - - complex.Fslice.Length = 1; - complex.Fslice.Mem = Eina.MemoryNative.Alloc(1); - Marshal.WriteByte(complex.Fslice.Mem, 125); - - complex.Fobj = new Dummy.Numberwrapper(); - complex.Fobj.SetNumber(42); - - return complex; - } - - private static void checkStructComplex(Dummy.StructComplex complex) - { - Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int)); - - Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int)); - - Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str)); - - Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int)); - - Test.Assert(complex.Fhash["aa"] == "aaa"); - Test.Assert(complex.Fhash["bb"] == "bbb"); - Test.Assert(complex.Fhash["cc"] == "ccc"); - - int idx = 0; - foreach (int e in complex.Fiterator) - { - Test.Assert(e == base_seq_int[idx]); - ++idx; - } - - double double_val = 0; - Test.Assert(complex.Fany_value.Get(out double_val)); - Test.Assert(double_val == -9007199254740992.0); - - string str_val = null; - Test.Assert(complex.Fany_value_ptr.Get(out str_val)); - Test.Assert(str_val == "abc"); - - Test.Assert(complex.Fbinbuf.Length == 1); - Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126); - - Test.Assert(complex.Fslice.Length == 1); - Test.Assert(complex.Fslice.GetBytes()[0] == 125); - - Test.Assert(complex.Fobj != null); - Test.Assert(complex.Fobj.GetNumber() == 42); - } - - - private static void checkZeroedStructComplex(Dummy.StructComplex complex) - { - Test.Assert(complex.Farray == null); - Test.Assert(complex.Finarray == null); - Test.Assert(complex.Flist == null); - Test.Assert(complex.Finlist == null); - Test.Assert(complex.Fhash == null); - Test.Assert(complex.Fiterator == null); - Test.Assert(complex.Fany_value == null); - Test.Assert(complex.Fany_value_ptr == null); - Test.Assert(complex.Fbinbuf == null); - - Test.Assert(complex.Fslice.Length == 0); - Test.Assert(complex.Fslice.Mem == IntPtr.Zero); - - Test.Assert(complex.Fobj == null); - } - // Test cases // // Default initialization (C# side) diff --git a/src/tests/efl_mono/ValueEolian.cs b/src/tests/efl_mono/ValueEolian.cs index 4d33dfacde..ea178d4ac9 100644 --- a/src/tests/efl_mono/ValueEolian.cs +++ b/src/tests/efl_mono/ValueEolian.cs @@ -151,7 +151,14 @@ public static class TestEinaValueEolian { Test.AssertEquals(expected, received); Test.AssertEquals(Eina.ValueType.Double, received.GetValueType()); - + // Check for 0 + // This is a special value, since C# can silently convert it to an enum + // leading to collisions with Eina.ValueType + expected = new Eina.Value(0); + obj.SetValue(0); + obj.OutValue(out received); + Test.AssertEquals(expected, received); + Test.AssertEquals(Eina.ValueType.Int32, received.GetValueType()); } } #pragma warning restore 1591 diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo index e37616c979..4a6ea5fcc6 100644 --- a/src/tests/efl_mono/dummy_test_object.eo +++ b/src/tests/efl_mono/dummy_test_object.eo @@ -1577,6 +1577,12 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface } } + emit_event_with_struct_complex { + params { + @in data: Dummy.StructComplex; + } + } + append_to_strbuf { params { @in buf: strbuf; @@ -1671,5 +1677,6 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface evt,with,obj @hot: Dummy.Test_Object; evt,with,error @hot: Eina.Error; evt,with,struct @hot: Dummy.StructSimple; + evt,with,struct,complex @hot: Dummy.StructComplex; } } diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c index a861f7ba48..576690bb86 100644 --- a/src/tests/efl_mono/libefl_mono_native_test.c +++ b/src/tests/efl_mono/libefl_mono_native_test.c @@ -3754,6 +3754,10 @@ void _dummy_test_object_emit_event_with_struct(Eo *obj, EINA_UNUSED Dummy_Test_O efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT, &data); } +void _dummy_test_object_emit_event_with_struct_complex(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Dummy_StructComplex data) +{ + efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT_COMPLEX, &data); +} Efl_Object *_dummy_test_object_efl_part_part_get(EINA_UNUSED const Eo *obj, Dummy_Test_Object_Data *pd, const char *name) { diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build index f901152b54..25541996e1 100644 --- a/src/tests/efl_mono/meson.build +++ b/src/tests/efl_mono/meson.build @@ -39,6 +39,8 @@ efl_mono_test = library('efl_mono_test', efl_mono_src = [ 'Main.cs', 'TestUtils.cs', + 'EinaTestData.cs', + 'StructHelpers.cs', 'BasicDirection.cs', 'Eina.cs', 'Eldbus.cs', diff --git a/src/tests/eio/eio_model_test_monitor_add.c b/src/tests/eio/eio_model_test_monitor_add.c index b93ee1c7ad..fb1edbdd01 100644 --- a/src/tests/eio/eio_model_test_monitor_add.c +++ b/src/tests/eio/eio_model_test_monitor_add.c @@ -95,7 +95,6 @@ _children_added_cb(void *d EINA_UNUSED, const Efl_Event* event) EFL_START_TEST(eio_model_test_test_monitor_add) { Eo *filemodel = NULL; - Eina_Future* future; tmpdir = eina_environment_tmp_get(); diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index 603b14e836..889bfdd294 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -1788,6 +1788,14 @@ EFL_START_TEST(efl_object_auto_unref_test) } EFL_END_TEST +EFL_START_TEST(efl_object_size) +{ + // This test is checking that we are not increasing the size of our object over time + // Update this number only if you modified the class size on purpose + ck_assert_int_le(efl_class_memory_size_get(SIMPLE_CLASS), 148); +} +EFL_END_TEST + void eo_test_general(TCase *tc) { tcase_add_test(tc, eo_simple); @@ -1815,4 +1823,5 @@ void eo_test_general(TCase *tc) tcase_add_test(tc, efl_cast_test); tcase_add_test(tc, efl_object_destruct_test); tcase_add_test(tc, efl_object_auto_unref_test); + tcase_add_test(tc, efl_object_size); } diff --git a/src/tests/eolian/data/class_requires.eo b/src/tests/eolian/data/class_requires.eo new file mode 100644 index 0000000000..173c660b39 --- /dev/null +++ b/src/tests/eolian/data/class_requires.eo @@ -0,0 +1,8 @@ +import base; +import mixins_require; + +class Class.Requires (Base, Mixins.Require) { + methods { + + } +} diff --git a/src/tests/eolian/data/mixins_require.eo b/src/tests/eolian/data/mixins_require.eo new file mode 100644 index 0000000000..474e1a3af1 --- /dev/null +++ b/src/tests/eolian/data/mixins_require.eo @@ -0,0 +1,13 @@ +import base; +import class_simple; + +mixin Mixins.Require requires Base { + methods { + test { + + } + } + implements { + Base.constructor; + } +} diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index 6df473f24d..d93906bc56 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -1552,6 +1552,66 @@ EFL_START_TEST(eolian_parts) } EFL_END_TEST +EFL_START_TEST(eolian_mixins_require) +{ + const Eolian_Unit *unit; + const Eolian_Class *cl; + const Eolian_Class *base; + + Eolian_State *eos = eolian_state_new(); + + fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data")); + + fail_if(!(unit = eolian_state_file_parse(eos, TESTS_SRC_DIR"/data/mixins_require.eo"))); + + fail_if (!(cl = eolian_state_class_by_name_get(eos, "Mixins.Require"))); + fail_if (!(base = eolian_state_class_by_name_get(eos, "Base"))); + + ck_assert_ptr_eq(eolian_class_parent_get(cl), NULL); + + //Check that implements is empty + { + Eolian_Class *extc; + Eina_Iterator *ext = eolian_class_extensions_get (cl); + + EINA_ITERATOR_FOREACH(ext, extc) + { + ck_abort_msg("Iterator should be empty"); + } + eina_iterator_free(ext); + } + //check that implements contains this one class + { + Eolian_Implement *impl; + Eina_Iterator *i = eolian_class_extensions_get (cl); + + EINA_ITERATOR_FOREACH(i, impl) + { + ck_assert_ptr_eq(eolian_implement_class_get(impl), base); + } + eina_iterator_free(i); + } + eolian_state_free(eos); +} +EFL_END_TEST + +EFL_START_TEST(eolian_class_requires_classes) +{ + const Eolian_Unit *unit; + const Eolian_Class *cl; + + Eolian_State *eos = eolian_state_new(); + + fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data")); + + fail_if(!(unit = eolian_state_file_parse(eos, TESTS_SRC_DIR"/data/class_requires.eo"))); + + fail_if (!(cl = eolian_state_class_by_name_get(eos, "Class.Requires"))); + + eolian_state_free(eos); +} +EFL_END_TEST + void eolian_parsing_test(TCase *tc) { tcase_add_test(tc, eolian_simple_parsing); @@ -1575,4 +1635,6 @@ void eolian_parsing_test(TCase *tc) tcase_add_test(tc, eolian_function_types); tcase_add_test(tc, eolian_function_as_arguments); tcase_add_test(tc, eolian_parts); + tcase_add_test(tc, eolian_mixins_require); + tcase_add_test(tc, eolian_class_requires_classes); } diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc index 936687a288..2215312f18 100644 --- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc +++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc @@ -309,6 +309,19 @@ EFL_START_TEST(eolian_cxx_test_parent_extensions) } EFL_END_TEST +EFL_START_TEST(eolian_cxx_test_cls_get) +{ + efl::eolian::eolian_init eolian_init; + efl::eolian::eolian_state eolian_state; + + klass_def cls = init_test_data("generic.eo", "Generic", eolian_state); + ck_assert_str_eq("generic_class_get", cls.klass_get_name.c_str()); + + klass_def iface = init_test_data("generic_interface.eo", "Generic_Interface", eolian_state); + ck_assert_str_eq("generic_interface_interface_get", iface.klass_get_name.c_str()); +} +EFL_END_TEST + void eolian_cxx_test_binding(TCase* tc) { @@ -321,4 +334,5 @@ eolian_cxx_test_binding(TCase* tc) tcase_add_test(tc, eolian_cxx_test_type_callback); tcase_add_test(tc, eolian_cxx_test_properties); tcase_add_test(tc, eolian_cxx_test_parent_extensions); + tcase_add_test(tc, eolian_cxx_test_cls_get); }