Sorry for the ugly log message, I forgot to modify it before commit ;-) This commit has been done to reduce memory usage. The Evas Smart legacy mechanism checks if an object is of a certain type by string comparing. To support it in Eo, we needed to implement a mechanism that stores every type of an object, so that when evas_object_smart_type_check (legacy function) is called, the Eo class is supported. This commit has improved the support of the legacy mechanism by using a global hash table instead of a eina_list per object.
By the way, if you need to check the type of a class fully supporting Eo, use eo_isa instead of evas_object_smart_type_check. On 02/10/2013 09:52 AM, Enlightenment SVN wrote: > Log: > Replace supported_types > > Signed-off-by: Daniel Zaoui <daniel.za...@samsung.com> > > Author: jackdanielz > Date: 2013-02-09 23:52:17 -0800 (Sat, 09 Feb 2013) > New Revision: 83802 > Trac: http://trac.enlightenment.org/e/changeset/83802 > > Modified: > trunk/efl/src/lib/edje/edje_smart.c trunk/efl/src/lib/evas/Evas.h > trunk/efl/src/lib/evas/canvas/evas_object_box.c > trunk/efl/src/lib/evas/canvas/evas_object_main.c > trunk/efl/src/lib/evas/canvas/evas_object_smart.c > trunk/efl/src/lib/evas/canvas/evas_object_smart_clipped.c > trunk/efl/src/lib/evas/canvas/evas_object_table.c > trunk/efl/src/lib/evas/include/evas_private.h > > Modified: trunk/efl/src/lib/edje/edje_smart.c > =================================================================== > --- trunk/efl/src/lib/edje/edje_smart.c 2013-02-10 06:21:47 UTC (rev > 83801) > +++ trunk/efl/src/lib/edje/edje_smart.c 2013-02-10 07:52:17 UTC (rev > 83802) > @@ -10,7 +10,7 @@ > > #define MY_CLASS EDJE_OBJ_CLASS > > -#define MY_CLASS_NAME "Edje_Smart" > +#define MY_CLASS_NAME "edje" > > Eina_List *_edje_edjes = NULL; > > @@ -32,7 +32,7 @@ > ed->base = eo_data_get(obj, EVAS_OBJ_SMART_CLIPPED_CLASS); > > eo_do_super(obj, eo_constructor()); > - eo_do(obj, evas_obj_type_set("edje")); > + eo_do(obj, evas_obj_type_set(MY_CLASS_NAME)); > _edje_lib_ref(); > } > > @@ -489,6 +489,8 @@ > }; > > eo_class_funcs_set(klass, func_desc); > + > + evas_smart_legacy_type_register(MY_CLASS_NAME, klass); > } > > static const Eo_Op_Description op_desc[] = { > > Modified: trunk/efl/src/lib/evas/Evas.h > =================================================================== > --- trunk/efl/src/lib/evas/Evas.h 2013-02-10 06:21:47 UTC (rev 83801) > +++ trunk/efl/src/lib/evas/Evas.h 2013-02-10 07:52:17 UTC (rev 83802) > @@ -13583,18 +13583,19 @@ > * type, @c EINA_FALSE otherwise > * > * If @p obj is not a smart object, this call will fail > - * immediately. Otherwise, make sure evas_smart_class_inherit() or its > - * sibling functions were used correctly when creating the smart > - * object's class, so it has a valid @b parent smart class pointer > - * set. > + * immediately. > * > + * This function supports Eo and legacy inheritance mechanisms. However, > + * it is recommended to use eo_isa instead if your object is using Eo from > + * top to bottom. > + * > * The checks use smart classes names and <b>string > * comparison</b>. There is a version of this same check using > * <b>pointer comparison</b>, since a smart class' name is a single > * string in Evas. > * > * @see evas_object_smart_type_check_ptr() > - * @see #EVAS_SMART_SUBCLASS_NEW > + * @see eo_isa > * > * @ingroup Evas_Smart_Object_Group > */ > @@ -13610,12 +13611,33 @@ > * type, @c EINA_FALSE otherwise > * > * @see evas_object_smart_type_check() for more details > + * @see eo_isa > * > * @ingroup Evas_Smart_Object_Group > */ > EAPI Eina_Bool evas_object_smart_type_check_ptr(const Evas_Object *obj, > const char *type) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2); > > /** > + * Registers an object type and its associated class. LEGACY MECHANISM > SUPPORT. > + * > + * This function is invoked in the class constructor of smart classes. It > will > + * add the type and the class into a hash table that will then be used to > check > + * the type of an object. > + * This function has been implemented to support legacy mechanism that checks > + * objects types by name. > + * USE IT ONLY FOR LEGACY SUPPORT. > + * Otherwise, it is HIGHLY recommended to use eo_isa. > + * > + * @param type The type (name string) to add. > + * @param klass The class to associate to the type. > + * > + * @see eo_isa > + * > + * @ingroup Evas_Smart_Object_Group > + */ > +EAPI void evas_smart_legacy_type_register(const char *type, const Eo_Class > *klass) EINA_ARG_NONNULL(1, 2); > + > +/** > * Get the #Evas_Smart from which @p obj smart object was created. > * > * @param obj a smart object > @@ -17434,7 +17456,6 @@ > EVAS_OBJ_SUB_ID_STACK_BELOW, > EVAS_OBJ_SUB_ID_ABOVE_GET, > EVAS_OBJ_SUB_ID_BELOW_GET, > - EVAS_OBJ_SUB_ID_TYPE_CHECK, > EVAS_OBJ_SUB_ID_LAST > }; > > @@ -18399,21 +18420,6 @@ > */ > #define evas_obj_below_get(ret) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_BELOW_GET), > EO_TYPECHECK(Evas_Object **, ret) > > -/** > - * @def evas_obj_type_check > - * @since 1.8 > - * > - * Checks whether a given object is of a given class. > - * > - * @param[in] type in > - * @param[out] type_check out > - * > - * This function has been implemented to support legacy smart inheritance > - * and needs to be removed when all the objects are Eo objects (inc. Edje > and ELM) > - * @see evas_object_smart_type_check > - */ > -#define evas_obj_type_check(type, type_check) > EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_TYPE_CHECK), EO_TYPECHECK(const char *, type), > EO_TYPECHECK(Eina_Bool *, type_check) > - > #define EVAS_OBJ_CLASS evas_object_class_get() > > const Eo_Class *evas_object_class_get(void) EINA_CONST; > > Modified: trunk/efl/src/lib/evas/canvas/evas_object_box.c > =================================================================== > --- trunk/efl/src/lib/evas/canvas/evas_object_box.c 2013-02-10 06:21:47 UTC > (rev 83801) > +++ trunk/efl/src/lib/evas/canvas/evas_object_box.c 2013-02-10 07:52:17 UTC > (rev 83802) > @@ -9,6 +9,8 @@ > > EAPI Eo_Op EVAS_OBJ_BOX_BASE_ID = EO_NOOP; > > +#define MY_CLASS_NAME "Evas_Object_Box" > + > #define MY_CLASS EVAS_OBJ_BOX_CLASS > > typedef struct _Evas_Object_Box_Iterator Evas_Object_Box_Iterator; > @@ -30,7 +32,6 @@ > const Evas_Object *box; > }; > > -#define _evas_object_box_type "Evas_Object_Box" > #define SIG_CHILD_ADDED "child,added" > #define SIG_CHILD_REMOVED "child,removed" > > @@ -503,23 +504,12 @@ > } > > static void > -_type_check(Eo *obj, void *_pd EINA_UNUSED, va_list *list) > -{ > - const char *type = va_arg(*list, const char *); > - Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - if (0 == strcmp(type, _evas_object_box_type)) > - *type_check = EINA_TRUE; > - else > - eo_do_super(obj, evas_obj_type_check(type, type_check)); > -} > - > -static void > _constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list > EINA_UNUSED) > { > eo_do_super(obj, eo_constructor()); > eo_do(obj, > evas_obj_smart_callbacks_descriptions_set(_signals, NULL), > - evas_obj_type_set(_evas_object_box_type)); > + evas_obj_type_set(MY_CLASS_NAME)); > } > > EAPI Evas_Object * > @@ -2308,7 +2298,6 @@ > const Eo_Op_Func_Description func_desc[] = { > EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), > > - EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_TYPE_CHECK), _type_check), > EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SMART_DATA_GET), > _smart_data_get), > > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_ADD), > _smart_add), > @@ -2359,6 +2348,8 @@ > }; > > eo_class_funcs_set(klass, func_desc); > + > + evas_smart_legacy_type_register(MY_CLASS_NAME, klass); > } > > static const Eo_Op_Description op_desc[] = { > @@ -2406,7 +2397,7 @@ > > static const Eo_Class_Description class_desc = { > EO_VERSION, > - "Evas_Object_Box", > + MY_CLASS_NAME, > EO_CLASS_TYPE_REGULAR, > EO_CLASS_DESCRIPTION_OPS(&EVAS_OBJ_BOX_BASE_ID, op_desc, > EVAS_OBJ_BOX_SUB_ID_LAST), > NULL, > > Modified: trunk/efl/src/lib/evas/canvas/evas_object_main.c > =================================================================== > --- trunk/efl/src/lib/evas/canvas/evas_object_main.c 2013-02-10 06:21:47 UTC > (rev 83801) > +++ trunk/efl/src/lib/evas/canvas/evas_object_main.c 2013-02-10 07:52:17 UTC > (rev 83802) > @@ -618,7 +618,6 @@ > obj->delete_me = 1; > evas_object_change(eo_obj, obj); > end: > - obj->supported_types = eina_list_free(obj->supported_types); > eo_do_super(eo_obj, eo_destructor()); > } > > @@ -2265,8 +2264,6 @@ > Evas_Object_Protected_Data *obj = _pd; > const char *type = va_arg(*list, const char *); > obj->type = type; // Store it as the top type of this class > - // Need to add this type to the list of all the types supported > - obj->supported_types = eina_list_append(obj->supported_types, type); > } > > EAPI void > @@ -2394,104 +2391,24 @@ > } > > static void > -_type_check(Eo *eo_obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) > +_smart_type_check(Eo *eo_obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list > *list) > { > - const char *type = va_arg(*list, const char *); > + va_arg(*list, const char *); > Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - if (0 == strcmp(type, "Evas_Object")) > - *type_check = EINA_TRUE; > - else > - *type_check = EINA_FALSE; > + *type_check = EINA_FALSE; > + return; > } > > static void > -_smart_type_check(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > +_smart_type_check_ptr(Eo *eo_obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list > *list) > { > - const char *type = va_arg(*list, const char *); > + va_arg(*list, const char *); > Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - > - const Evas_Smart_Class *sc; > - > - Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS); > - if (!obj) return; > - if (!obj->is_smart) > - { > - *type_check = EINA_FALSE; > - return; > - } > - > - if (obj->supported_types) > - { > - Eina_List *l; > - const char *type_in_list; > - EINA_LIST_FOREACH(obj->supported_types, l, type_in_list) > - if (!strcmp(type_in_list, type)) > - { > - *type_check = EINA_TRUE; > - return; > - } > - } > - > - eo_do((Eo *)eo_obj, evas_obj_type_check(type, type_check)); > - > - if (EINA_FALSE == *type_check) > - { > - if (obj->smart.smart) > - { > - sc = obj->smart.smart->smart_class; > - while (sc) > - { > - if (!strcmp(sc->name, type)) > - { > - *type_check = EINA_TRUE; > - return; > - } > - sc = sc->parent; > - } > - } > - } > - > *type_check = EINA_FALSE; > + return; > } > > static void > -_smart_type_check_ptr(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > -{ > - const Evas_Smart_Class *sc; > - const char* type = va_arg(*list, const char *); > - Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - > - Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS); > - if (!obj) return; > - if (!obj->is_smart) > - { > - if (type_check) *type_check = EINA_FALSE; > - return; > - } > - > - eo_do((Eo *)eo_obj, evas_obj_type_check(type, type_check)); > - > - if (EINA_FALSE == *type_check) > - { > - if (obj->smart.smart) > - { > - sc = obj->smart.smart->smart_class; > - while (sc) > - { > - if (sc->name == type) > - { > - if (type_check) *type_check = EINA_TRUE; > - return; > - } > - sc = sc->parent; > - } > - } > - } > - > - if (type_check) *type_check = EINA_FALSE; > -} > - > -static void > _class_constructor(Eo_Class *klass) > { > const Eo_Op_Func_Description func_desc[] = { > @@ -2574,7 +2491,6 @@ > EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_STACK_BELOW), _stack_below), > EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_ABOVE_GET), _above_get), > EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_BELOW_GET), _below_get), > - EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_TYPE_CHECK), _type_check), > EO_OP_FUNC_SENTINEL > }; > > @@ -2657,7 +2573,6 @@ > EO_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_STACK_BELOW, "Stack obj immediately > below below"), > EO_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_ABOVE_GET, "Get the Evas object > stacked right above obj"), > EO_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_BELOW_GET, "Get the Evas object > stacked right below obj"), > - EO_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_TYPE_CHECK, "description here"), > EO_OP_DESCRIPTION_SENTINEL > }; > > > Modified: trunk/efl/src/lib/evas/canvas/evas_object_smart.c > =================================================================== > --- trunk/efl/src/lib/evas/canvas/evas_object_smart.c 2013-02-10 06:21:47 UTC > (rev 83801) > +++ trunk/efl/src/lib/evas/canvas/evas_object_smart.c 2013-02-10 07:52:17 UTC > (rev 83802) > @@ -11,6 +11,8 @@ > > extern Eina_Hash* signals_hash_table; > > +static Eina_Hash *_evas_smart_class_names_hash_table = NULL; > + > typedef struct _Evas_Object_Smart Evas_Object_Smart; > typedef struct _Evas_Smart_Callback Evas_Smart_Callback; > > @@ -307,17 +309,6 @@ > return smart_parent; > } > > -static void > -_type_check(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > -{ > - const char *type = va_arg(*list, const char *); > - Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - if (0 == strcmp(type, "Evas_Object_Smart")) > - *type_check = EINA_TRUE; > - else > - eo_do_super(eo_obj, evas_obj_type_check(type, type_check)); > -} > - > EAPI Eina_Bool > evas_object_smart_type_check(const Evas_Object *eo_obj, const char *type) > { > @@ -329,6 +320,41 @@ > return type_check; > } > > +static void > +_smart_type_check(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > +{ > + const char *type = va_arg(*list, const char *); > + Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > + *type_check = EINA_FALSE; > + > + const Evas_Smart_Class *sc; > + Eo_Class *klass; > + > + Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS); > + if (!obj) return; > + > + klass = eina_hash_find(_evas_smart_class_names_hash_table, type); > + if (klass) *type_check = eo_isa(eo_obj, klass); > + > + /* Backward compatibility - walk over smart classes and compare type */ > + if (EINA_FALSE == *type_check) > + { > + if (obj->smart.smart) > + { > + sc = obj->smart.smart->smart_class; > + while (sc) > + { > + if (!strcmp(sc->name, type)) > + { > + *type_check = EINA_TRUE; > + return; > + } > + sc = sc->parent; > + } > + } > + } > +} > + > EAPI Eina_Bool > evas_object_smart_type_check_ptr(const Evas_Object *eo_obj, const char > *type) > { > @@ -340,6 +366,46 @@ > return type_check_ptr; > } > > +static void > +_smart_type_check_ptr(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > +{ > + Eo_Class *klass; > + const Evas_Smart_Class *sc; > + const char* type = va_arg(*list, const char *); > + Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > + *type_check = EINA_FALSE; > + > + Evas_Object_Protected_Data *obj = eo_data_get(eo_obj, EVAS_OBJ_CLASS); > + if (!obj) return; > + > + klass = eina_hash_find(_evas_smart_class_names_hash_table, type); > + if (klass) *type_check = eo_isa(eo_obj, klass); > + > + /* Backward compatibility - walk over smart classes and compare type */ > + if (EINA_FALSE == *type_check) > + { > + if (obj->smart.smart) > + { > + sc = obj->smart.smart->smart_class; > + while (sc) > + { > + if (sc->name == type) > + { > + if (type_check) *type_check = EINA_TRUE; > + return; > + } > + sc = sc->parent; > + } > + } > + } > +} > + > +EAPI void > +evas_smart_legacy_type_register(const char *type, const Eo_Class *klass) > +{ > + eina_hash_set(_evas_smart_class_names_hash_table, type, klass); > +} > + > EAPI Eina_List * > evas_object_smart_members_get(const Evas_Object *eo_obj) > { > @@ -1442,7 +1508,8 @@ > { > const Eo_Op_Func_Description func_desc[] = { > EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), > - EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_TYPE_CHECK), _type_check), > + EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SMART_TYPE_CHECK), > _smart_type_check), > + EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SMART_TYPE_CHECK_PTR), > _smart_type_check_ptr), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_DATA_SET), > _smart_data_set), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_SMART_GET), > _smart_smart_get), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MEMBER_ADD), > _smart_member_add), > @@ -1470,8 +1537,18 @@ > }; > > eo_class_funcs_set(klass, func_desc); > + > + _evas_smart_class_names_hash_table = eina_hash_string_small_new(NULL); > + > + evas_smart_legacy_type_register(MY_CLASS_NAME, klass); > } > > +static void > +_class_destructor(Eo_Class *klass EINA_UNUSED) > +{ > + eina_hash_free(_evas_smart_class_names_hash_table); > +} > + > static const Eo_Op_Description op_desc[] = { > EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_DATA_SET, "Store a pointer to > user data for a given smart object."), > EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_SMART_GET, "Get the > #Evas_Smart from which obj smart object was created."), > @@ -1506,7 +1583,7 @@ > NULL, > sizeof(Evas_Object_Smart), > _class_constructor, > - NULL > + _class_destructor > }; > > EO_DEFINE_CLASS(evas_object_smart_class_get, &class_desc, EVAS_OBJ_CLASS, > EVAS_SMART_SIGNAL_INTERFACE, NULL); > > Modified: trunk/efl/src/lib/evas/canvas/evas_object_smart_clipped.c > =================================================================== > --- trunk/efl/src/lib/evas/canvas/evas_object_smart_clipped.c 2013-02-10 > 06:21:47 UTC (rev 83801) > +++ trunk/efl/src/lib/evas/canvas/evas_object_smart_clipped.c 2013-02-10 > 07:52:17 UTC (rev 83802) > @@ -283,17 +283,6 @@ > } > > static void > -_type_check(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) > -{ > - const char *type = va_arg(*list, const char *); > - Eina_Bool *type_check = va_arg(*list, Eina_Bool *); > - if (0 == strcmp(type, "EvasObjectSmartClipped")) > - *type_check = EINA_TRUE; > - else > - eo_do_super(eo_obj, evas_obj_type_check(type, type_check)); > -} > - > -static void > _constructor(Eo *eo_obj, void *class_data EINA_UNUSED, va_list *list > EINA_UNUSED) > { > eo_do_super(eo_obj, eo_constructor()); > @@ -304,7 +293,6 @@ > { > const Eo_Op_Func_Description func_desc[] = { > EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), > - EO_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_TYPE_CHECK), _type_check), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_ADD), > _smart_add), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_DEL), > _smart_del), > EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MOVE), > _smart_move), > > Modified: trunk/efl/src/lib/evas/canvas/evas_object_table.c > =================================================================== > --- trunk/efl/src/lib/evas/canvas/evas_object_table.c 2013-02-10 06:21:47 UTC > (rev 83801) > +++ trunk/efl/src/lib/evas/canvas/evas_object_table.c 2013-02-10 07:52:17 UTC > (rev 83802) > @@ -1588,6 +1588,8 @@ > EO_OP_FUNC_SENTINEL > }; > eo_class_funcs_set(klass, func_desc); > + > + evas_smart_legacy_type_register(MY_CLASS_NAME, klass); > } > static const Eo_Op_Description op_desc[] = { > EO_OP_DESCRIPTION(EVAS_OBJ_TABLE_SUB_ID_ADD_TO, "Create a table that > is child of a given element parent."), > > Modified: trunk/efl/src/lib/evas/include/evas_private.h > =================================================================== > --- trunk/efl/src/lib/evas/include/evas_private.h 2013-02-10 06:21:47 UTC > (rev 83801) > +++ trunk/efl/src/lib/evas/include/evas_private.h 2013-02-10 07:52:17 UTC > (rev 83802) > @@ -614,7 +614,6 @@ > void **interface_privates; > > unsigned int ref; > - Eina_List *supported_types; > > unsigned char delete_me; > > > > ------------------------------------------------------------------------------ > Free Next-Gen Firewall Hardware Offer > Buy your Sophos next-gen firewall before the end March 2013 > and get the hardware for free! Learn more. > http://p.sf.net/sfu/sophos-d2d-feb > _______________________________________________ > enlightenment-svn mailing list > enlightenment-...@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/enlightenment-svn > ------------------------------------------------------------------------------ Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel