[Merge with upstream] core files are merged
authorWooHyun Jung <wh0705.jung@samsung.com>
Tue, 4 Jan 2011 04:32:00 +0000 (13:32 +0900)
committerWooHyun Jung <wh0705.jung@samsung.com>
Tue, 4 Jan 2011 04:32:00 +0000 (13:32 +0900)
30 files changed:
config/default/base.src
configure.ac
src/lib/Elementary.h.in
src/lib/Elementary_Cursor.h [new file with mode: 0644]
src/lib/Makefile.am
src/lib/elm_carousel.c
src/lib/elm_config.c
src/lib/elm_diskcontroller.c
src/lib/elm_entry.c
src/lib/elm_font.c [new file with mode: 0644]
src/lib/elm_gengrid.c
src/lib/elm_genlist.c
src/lib/elm_hor_scroller.c
src/lib/elm_main.c
src/lib/elm_map.c
src/lib/elm_module.c
src/lib/elm_panel.c
src/lib/elm_priv.h
src/lib/elm_scroller.c
src/lib/elm_slideshow.c
src/lib/elm_theme.c
src/lib/elm_thumb.c
src/lib/elm_toolbar.c
src/lib/elm_widget.c
src/lib/elm_widget.h [new file with mode: 0644]
src/lib/elm_win.c
src/lib/els_cursor.c [new file with mode: 0644]
src/lib/els_hor_scroller.c
src/lib/els_scroller.c
src/lib/els_tooltip.c [new file with mode: 0644]

index b1e59cc..5bc2be3 100644 (file)
@@ -1,24 +1,37 @@
 group "Elm_Config" struct {
-  value "config_version" int: 65537;
-  value "engine" int: 0;
-  value "thumbscroll_enable" int: 1;
-  value "thumbscroll_threshhold" int: 24;
-  value "thumbscroll_momentum_threshhold" double: 100.0;
+  value "config_version" int: 65539;
+  value "engine" string: "software_x11";
+  value "thumbscroll_enable" uchar: 1;
+  value "thumbscroll_threshold" int: 24;
+  value "thumbscroll_momentum_threshold" double: 100.0;
   value "thumbscroll_friction" double: 1.0;
   value "thumbscroll_bounce_friction" double: 0.5;
+  value "thumbscroll_bounce_enable" uchar: 1;
   value "page_scroll_friction" double: 0.5;
   value "bring_in_scroll_friction" double: 0.5;
   value "zoom_friction" double: 0.5;
-  value "thumbscroll_bounce_enable" int: 1;
+  value "thumbscroll_border_friction" double: 0.5;
   value "scale" double: 1.0;
   value "bgpixmap" int: 0;
   value "compositing" int: 1;
   value "font_hinting" int: 2;
+  value "cache_flush_poll_interval" int: 512;
+  value "cache_flush_enable" uchar: 1;
   value "image_cache" int: 4096;
   value "font_cache" int: 512;
+  value "edje_cache" int: 32;
+  value "edje_collection_cache" int: 64;
   value "finger_size" int: 40;
   value "fps" double: 60.0;
   value "theme" string: "default";
   value "modules" string: "";
+  value "tooltip_delay" double: 1.0;
+  value "cursor_engine_only" uchar: 1;
+  value "focus_highlight_enable" uchar: 0;
+  value "focus_highlight_animate" uchar: 0;
+  value "toolbar_shrink_mode" int: 3;
+  value "fileselector_expand_enable" uchar: 0;
+  value "inwin_dialogs_enable" uchar: 1;
+  value "icon_size" int: 32;
   value "longpress_timeout" double: 1.0;
 }
index 8ce4ecb..b86a6be 100755 (executable)
@@ -30,6 +30,8 @@ AM_INIT_AUTOMAKE([1.6 dist-bzip2])
 AM_CONFIG_HEADER([elementary_config.h])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
+AC_GNU_SOURCE
+
 AC_C_BIGENDIAN
 AC_ISC_POSIX
 AC_PROG_CC
@@ -465,6 +467,18 @@ if test "x$want_elementary_libxml2" = "xyes" -a "x$have_elementary_libxml2" = "x
 fi
 AC_SUBST(ELM_LIBXML2_DEF)
 
+ELM_DEBUG_DEF="#undef"
+want_elementary_debug="no"
+AC_ARG_ENABLE([debug],
+   [AC_HELP_STRING([--enable-debug], [enable elementary debug support. @<:@default=disabled@:>@])],
+   [want_elementary_debug=$enableval], [])
+
+if test "x$want_elementary_debug" = "xyes"; then
+        AC_DEFINE(HAVE_ELEMENTARY_DEBUG, 1, [Elementary debug.])
+        ELM_DEBUG_DEF="#define"
+fi
+AC_SUBST(ELM_DEBUG_DEF)
+
 ELM_ALLOCA_H_DEF="#undef"
 AC_CHECK_HEADER(alloca.h, [ELM_ALLOCA_H_DEF="#define"])
 AC_SUBST(ELM_ALLOCA_H_DEF)
index 0f27dff..a4a9736 100644 (file)
@@ -17,6 +17,7 @@
 @ELM_EDBUS_DEF@ ELM_EDBUS
 @ELM_EFREET_DEF@ ELM_EFREET
 @ELM_ETHUMB_DEF@ ELM_ETHUMB
+@ELM_DEBUG_DEF@ ELM_DEBUG
 @ELM_ALLOCA_H_DEF@ ELM_ALLOCA_H
 @ELM_LIBINTL_H_DEF@ ELM_LIBINTL_H
 
@@ -135,93 +136,86 @@ extern "C" {
 #define ELM_RECTS_INTERSECT(x, y, w, h, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && (((x) + (w)) > (xx)) && (((y) + (h)) > (yy)))
 #define ELM_PI 3.14159265358979323846
 
+  /**
+   * Defines couple of standard Evas_Object layers to be used
+   * with evas_object_layer_set().
+   *
+   * @note whenever extending with new values, try to keep some padding
+   *       to siblings so there is room for further extensions.
+   */
+  typedef enum _Elm_Object_Layer
+    {
+       ELM_OBJECT_LAYER_BACKGROUND = EVAS_LAYER_MIN + 64, /**< where to place backgrounds */
+       ELM_OBJECT_LAYER_DEFAULT = 0, /**< Evas_Object default layer (and thus for Elementary) */
+       ELM_OBJECT_LAYER_FOCUS = EVAS_LAYER_MAX - 128, /**< where focus object visualization is */
+       ELM_OBJECT_LAYER_TOOLTIP = EVAS_LAYER_MAX - 64, /**< where to show tooltips */
+       ELM_OBJECT_LAYER_CURSOR = EVAS_LAYER_MAX - 32, /**< where to show cursors */
+       ELM_OBJECT_LAYER_LAST /**< last layer known by Elementary */
+    } Elm_Object_Layer;
+
 /**************************************************************************/
    EAPI extern int ELM_ECORE_EVENT_ETHUMB_CONNECT;
 
    /* Objects */
-   typedef enum _Elm_Win_Type
+     /**
+    * Emitted when policy value changed.
+    */
+   EAPI extern int ELM_EVENT_POLICY_CHANGED;
+   typedef struct _Elm_Event_Policy_Changed
      {
-        ELM_WIN_BASIC,
-        ELM_WIN_DIALOG_BASIC,
-        ELM_WIN_DESKTOP,
-        ELM_WIN_DOCK,
-        ELM_WIN_TOOLBAR,
-        ELM_WIN_MENU,
-        ELM_WIN_UTILITY,
-        ELM_WIN_SPLASH
-     } Elm_Win_Type;
+        unsigned int policy;
+        int          new_value;
+        int          old_value;
+     } Elm_Event_Policy_Changed;
 
-   typedef enum _Elm_Win_Keyboard_Mode
+   /**
+    * Policy identifiers.
+    *
+    * @see elm_policy_set()
+    */
+   typedef enum _Elm_Policy
      {
-        ELM_WIN_KEYBOARD_UNKNOWN,
-        ELM_WIN_KEYBOARD_OFF,
-        ELM_WIN_KEYBOARD_ON,
-        ELM_WIN_KEYBOARD_ALPHA,
-        ELM_WIN_KEYBOARD_NUMERIC,
-        ELM_WIN_KEYBOARD_PIN,
-        ELM_WIN_KEYBOARD_PHONE_NUMBER,
-        ELM_WIN_KEYBOARD_HEX,
-        ELM_WIN_KEYBOARD_TERMINAL,
-        ELM_WIN_KEYBOARD_PASSWORD,
-        ELM_WIN_KEYBOARD_IP,
-        ELM_WIN_KEYBOARD_HOST,
-        ELM_WIN_KEYBOARD_FILE,
-        ELM_WIN_KEYBOARD_URL,
-        ELM_WIN_KEYBOARD_KEYPAD,
-        ELM_WIN_KEYBOARD_J2ME
-     } Elm_Win_Keyboard_Mode;
+       ELM_POLICY_QUIT, /**< when should quit application automatically.
+                         * @see Elm_Policy_Quit.
+                         */
+       ELM_POLICY_LAST
+     } Elm_Policy;
 
-  /**
-   * Emitted when policy value changed.
-   */
-  EAPI extern int ELM_EVENT_POLICY_CHANGED;
-  typedef struct _Elm_Event_Policy_Changed
-    {
-       unsigned int policy;
-       int new_value;
-       int old_value;
-    } Elm_Event_Policy_Changed;
+   typedef enum _Elm_Policy_Quit
+     {
+        ELM_POLICY_QUIT_NONE = 0, /**< never quit application automatically */
+        ELM_POLICY_QUIT_LAST_WINDOW_CLOSED /**< quit when last window is closed */
+     } Elm_Policy_Quit;
 
-  /**
-   * Policy identifiers.
-   *
-   * @see elm_policy_set()
-   */
-  typedef enum _Elm_Policy
-    {
-      ELM_POLICY_QUIT, /**< when should quit application automatically.
-                       * @see Elm_Policy_Quit.
-                       */
-      ELM_POLICY_LAST
-    } Elm_Policy;
+   typedef enum _Elm_Focus_Direction
+     {
+        ELM_FOCUS_PREVIOUS,
+        ELM_FOCUS_NEXT
+     } Elm_Focus_Direction;
 
-  typedef enum _Elm_Policy_Quit
-    {
-      ELM_POLICY_QUIT_NONE = 0, /**< never quit application automatically */
-      ELM_POLICY_QUIT_LAST_WINDOW_CLOSED /**< quit when last window is closed */
-    } Elm_Policy_Quit;
+   typedef enum _Elm_Text_Format
+     {
+        ELM_TEXT_FORMAT_PLAIN_UTF8,
+        ELM_TEXT_FORMAT_MARKUP_UTF8
+     } Elm_Text_Format;
 
-  typedef enum _Elm_Thumb_Animation_Setting
-    {
-       ELM_THUMB_ANIMATION_START = 0, /* Play animation once */
-       ELM_THUMB_ANIMATION_LOOP,      /* Keep playing animation until stop is requested */
-       ELM_THUMB_ANIMATION_STOP,
-       ELM_THUMB_ANIMATION_LAST
-    } Elm_Thumb_Animation_Setting;
+   /**
+    * Called back when a widget's tooltip is activated and needs content.
+    * @param data user-data given to elm_object_tooltip_content_cb_set()
+    * @param obj owner widget.
+    */
+   typedef Evas_Object *(*Elm_Tooltip_Content_Cb) (void *data, Evas_Object *obj);
 
-   typedef struct _Elm_Theme Elm_Theme;
+   /**
+    * Called back when a widget's item tooltip is activated and needs content.
+    * @param data user-data given to elm_object_tooltip_content_cb_set()
+    * @param obj owner widget.
+    * @param item context dependent item. As an example, if tooltip was
+    *        set on Elm_List_Item, then it is of this type.
+    */
+   typedef Evas_Object *(*Elm_Tooltip_Item_Content_Cb) (void *data, Evas_Object *obj, void *item);
 
-   typedef enum _Elm_Clock_Digedit
-     {
-        ELM_CLOCK_NONE         = 0,
-        ELM_CLOCK_HOUR_DECIMAL = 1 << 0,
-        ELM_CLOCK_HOUR_UNIT    = 1 << 1,
-        ELM_CLOCK_MIN_DECIMAL  = 1 << 2,
-        ELM_CLOCK_MIN_UNIT     = 1 << 3,
-        ELM_CLOCK_SEC_DECIMAL  = 1 << 4,
-        ELM_CLOCK_SEC_UNIT     = 1 << 5,
-        ELM_CLOCK_ALL         = (1 << 6) - 1
-     } Elm_Clock_Digedit;
+   typedef Eina_Bool (*Elm_Event_Cb) (void *data, Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info);
 
 #ifndef ELM_LIB_QUICKLAUNCH
 #define ELM_MAIN() int main(int argc, char **argv) {elm_init(argc, argv); return elm_main(argc, argv);}
@@ -236,7 +230,8 @@ extern "C" {
    EAPI void         elm_run(void);
    EAPI void         elm_exit(void);
 
-   EAPI void         elm_quicklaunch_mode_set(Eina_Bool ql_on); 
+   EAPI void         elm_quicklaunch_mode_set(Eina_Bool ql_on);
+   EAPI Eina_Bool    elm_quicklaunch_mode_get(void);
    EAPI int          elm_quicklaunch_init(int argc, char **argv);
    EAPI int          elm_quicklaunch_sub_init(int argc, char **argv);
    EAPI int          elm_quicklaunch_sub_shutdown(void);
@@ -248,120 +243,292 @@ extern "C" {
    EAPI int          elm_quicklaunch_fallback(int argc, char **argv);
    EAPI char        *elm_quicklaunch_exe_path_get(const char *exe);
 
-   EAPI void         elm_need_efreet(void);
-   EAPI void         elm_need_e_dbus(void);
-   EAPI void        elm_need_ethumb(void);
+   EAPI Eina_Bool    elm_need_efreet(void);
+   EAPI Eina_Bool    elm_need_e_dbus(void);
+   EAPI Eina_Bool    elm_need_ethumb(void);
 
    EAPI Eina_Bool    elm_policy_set(unsigned int policy, int value);
    EAPI int          elm_policy_get(unsigned int policy);
 
    EAPI void         elm_all_flush(void);
-
-   EAPI void         elm_object_scale_set(Evas_Object *obj, double scale);
-   EAPI double       elm_object_scale_get(const Evas_Object *obj);
-   EAPI void         elm_object_style_set(Evas_Object *obj, const char *style);
-   EAPI const char  *elm_object_style_get(const Evas_Object *obj);
-   EAPI void         elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled);
-   EAPI Eina_Bool    elm_object_disabled_get(const Evas_Object *obj);
-
-   EAPI Eina_Bool    elm_object_widget_check(const Evas_Object *obj);
-   EAPI Evas_Object *elm_object_parent_widget_get(const Evas_Object *obj);
-   EAPI Evas_Object *elm_object_top_widget_get(const Evas_Object *obj);
-   EAPI const char  *elm_object_widget_type_get(const Evas_Object *obj);
+   EAPI int          elm_cache_flush_interval_get(void);
+   EAPI void         elm_cache_flush_interval_set(int size);
+   EAPI void         elm_cache_flush_interval_all_set(int size);
+   EAPI Eina_Bool    elm_cache_flush_enmabled_get(void);
+   EAPI void         elm_cache_flush_enabled_set(Eina_Bool enabled);
+   EAPI void         elm_cache_flush_enabled_all_set(Eina_Bool enabled);
+   EAPI int          elm_font_cache_get(void);
+   EAPI void         elm_font_cache_set(int size);
+   EAPI void         elm_font_cache_all_set(int size);
+   EAPI int          elm_image_cache_get(void);
+   EAPI void         elm_image_cache_set(int size);
+   EAPI void         elm_image_cache_all_set(int size);
+   EAPI int          elm_edje_file_cache_get(void);
+   EAPI void         elm_edje_file_cache_set(int size);
+   EAPI void         elm_edje_file_cache_all_set(int size);
+   EAPI int          elm_edje_collection_cache_get(void);
+   EAPI void         elm_edje_collection_cache_set(int size);
+   EAPI void         elm_edje_collection_cache_all_set(int size);
+
+   EAPI void         elm_object_scale_set(Evas_Object *obj, double scale) EINA_ARG_NONNULL(1);
+   EAPI double       elm_object_scale_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_object_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_object_disabled_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+   EAPI Eina_Bool    elm_object_widget_check(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Evas_Object *elm_object_parent_widget_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Evas_Object *elm_object_top_widget_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_object_widget_type_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
 
    EAPI double       elm_scale_get(void);
    EAPI void         elm_scale_set(double scale);
    EAPI void         elm_scale_all_set(double scale);
-   EAPI Evas_Coord   elm_finger_size_get(void);
-   EAPI void         elm_finger_size_set(Evas_Coord size);
-   EAPI void         elm_finger_size_all_set(Evas_Coord size);
 
-   EAPI void         elm_autocapitalization_allow_all_set(Eina_Bool autocap);
-   EAPI void         elm_autoperiod_allow_all_set(Eina_Bool autoperiod);
+   EAPI Eina_Bool    elm_config_save(void);
+   EAPI void         elm_config_reload(void);
 
-   EAPI Eina_Bool    elm_object_focus_get(Evas_Object *obj);
-   EAPI void         elm_object_focus(Evas_Object *obj);
-   EAPI void         elm_object_unfocus(Evas_Object *obj);
-   EAPI void         elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable);
-   EAPI Eina_Bool    elm_object_focus_allow_get(const Evas_Object *obj);
-
-   EAPI void         elm_object_scroll_hold_push(Evas_Object *obj);
-   EAPI void         elm_object_scroll_hold_pop(Evas_Object *obj);
-   EAPI void         elm_object_scroll_freeze_push(Evas_Object *obj);
-   EAPI void         elm_object_scroll_freeze_pop(Evas_Object *obj);
-   EAPI void         elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock);
-   EAPI void         elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock);
-   EAPI Eina_Bool    elm_object_scroll_lock_x_get(const Evas_Object *obj);
-   EAPI Eina_Bool    elm_object_scroll_lock_y_get(const Evas_Object *obj);
-       
-   EAPI void         elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source);
-   EAPI void         elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data);
-   EAPI void        *elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source));
+   EAPI const char  *elm_profile_current_get(void);
+   EAPI const char  *elm_profile_dir_get(const char *profile, Eina_Bool is_user);
+   EAPI void         elm_profile_dir_free(const char *p_dir);
+   EAPI Eina_List   *elm_profile_list_get(void);
+   EAPI void         elm_profile_list_free(Eina_List *l);
+   EAPI void         elm_profile_set(const char *profile);
+   EAPI void         elm_profile_all_set(const char *profile);
+
+   EAPI const char  *elm_engine_current_get(void);
+   EAPI void         elm_engine_set(const char *engine);
 
-   EAPI void         elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h);
+  typedef struct _Elm_Text_Class
+    {
+       const char *name;
+       const char *desc;
+    } Elm_Text_Class;
+
+  typedef struct _Elm_Font_Overlay
+    {
+       const char     *text_class;
+       const char     *font;
+       Evas_Font_Size  size;
+    } Elm_Font_Overlay;
+
+  typedef struct _Elm_Font_Properties
+    {
+       const char *name;
+       Eina_List  *styles;
+    } Elm_Font_Properties;
+
+   EAPI const Eina_List     *elm_text_classes_list_get(void);
+   EAPI void                 elm_text_classes_list_free(const Eina_List *list);
+
+   EAPI const Eina_List     *elm_font_overlay_list_get(void);
+   EAPI void                 elm_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size);
+   EAPI void                 elm_font_overlay_unset(const char *text_class);
+   EAPI void                 elm_font_overlay_apply();
+   EAPI void                 elm_font_overlay_all_apply();
+
+   EAPI Elm_Font_Properties *elm_font_properties_get(const char *font) EINA_ARG_NONNULL(1);
+   EAPI void                 elm_font_properties_free(Elm_Font_Properties *efp) EINA_ARG_NONNULL(1);
+   EAPI const char          *elm_font_fontconfig_name_get(const char *name, const char *style) EINA_ARG_NONNULL(1);
+   EAPI void                 elm_font_fontconfig_name_free(const char *name) EINA_ARG_NONNULL(1);
+   EAPI Eina_Hash           *elm_font_available_hash_add(Eina_List *list);
+   EAPI void                 elm_font_available_hash_del(Eina_Hash *hash);
+
+   EAPI Evas_Coord       elm_finger_size_get(void);
+   EAPI void             elm_finger_size_set(Evas_Coord size);
+   EAPI void             elm_finger_size_all_set(Evas_Coord size);
+
+   EAPI Eina_Bool        elm_focus_highlight_enabled_get(void);
+   EAPI void             elm_focus_highlight_enabled_set(Eina_Bool enable);
+   EAPI Eina_Bool        elm_focus_highlight_animate_get(void);
+   EAPI void             elm_focus_highlight_animate_set(Eina_Bool animate);
+
+   EAPI Eina_Bool        elm_object_focus_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_focus(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_unfocus(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool        elm_object_focus_allow_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+   EAPI void             elm_object_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_focus_custom_chain_unset(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI const Eina_List *elm_object_focus_custom_chain_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_focus_custom_chain_append(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child) EINA_ARG_NONNULL(1, 2);
+   EAPI void             elm_object_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child) EINA_ARG_NONNULL(1, 2);
+   EAPI void             elm_object_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_focus_direction_go(Evas_Object *obj, int x, int y) EINA_ARG_NONNULL(1);
+
+   EAPI Eina_Bool        elm_scroll_bounce_enabled_get(void);
+   EAPI void             elm_scroll_bounce_enabled_set(Eina_Bool enabled);
+   EAPI void             elm_scroll_bounce_enabled_all_set(Eina_Bool enabled);
+   EAPI double           elm_scroll_bounce_friction_get(void);
+   EAPI void             elm_scroll_bounce_friction_set(double friction);
+   EAPI void             elm_scroll_bounce_friction_all_set(double friction);
+   EAPI double           elm_scroll_page_scroll_friction_get(void);
+   EAPI void             elm_scroll_page_scroll_friction_set(double friction);
+   EAPI void             elm_scroll_page_scroll_friction_all_set(double friction);
+   EAPI double           elm_scroll_bring_in_scroll_friction_get(void);
+   EAPI void             elm_scroll_bring_in_scroll_friction_set(double friction);
+   EAPI void             elm_scroll_bring_in_scroll_friction_all_set(double friction);
+   EAPI double           elm_scroll_zoom_friction_get(void);
+   EAPI void             elm_scroll_zoom_friction_set(double friction);
+   EAPI void             elm_scroll_zoom_friction_all_set(double friction);
+   EAPI Eina_Bool        elm_scroll_thumbscroll_enabled_get(void);
+   EAPI void             elm_scroll_thumbscroll_enabled_set(Eina_Bool enabled);
+   EAPI void             elm_scroll_thumbscroll_enabled_all_set(Eina_Bool enabled);
+   EAPI unsigned int     elm_scroll_thumbscroll_threshold_get(void);
+   EAPI void             elm_scroll_thumbscroll_threshold_set(unsigned int threshold);
+   EAPI void             elm_scroll_thumbscroll_threshold_all_set(unsigned int threshold);
+   EAPI double           elm_scroll_thumbscroll_momentum_threshold_get(void);
+   EAPI void             elm_scroll_thumbscroll_momentum_threshold_set(double threshold);
+   EAPI void             elm_scroll_thumbscroll_momentum_threshold_all_set(double threshold);
+   EAPI double           elm_scroll_thumbscroll_friction_get(void);
+   EAPI void             elm_scroll_thumbscroll_friction_set(double friction);
+   EAPI void             elm_scroll_thumbscroll_friction_all_set(double friction);
+   EAPI double           elm_scroll_thumbscroll_border_friction_get(void);
+   EAPI void             elm_scroll_thumbscroll_border_friction_set(double friction);
+   EAPI void             elm_scroll_thumbscroll_border_friction_all_set(double friction);
+
+   EAPI void             elm_object_scroll_hold_push(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_scroll_hold_pop(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_scroll_freeze_push(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_scroll_freeze_pop(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool        elm_object_scroll_lock_x_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool        elm_object_scroll_lock_y_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+   EAPI void             elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source) EINA_ARG_NONNULL(1);
+   EAPI void             elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data) EINA_ARG_NONNULL(1, 4);
+   EAPI void            *elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source)) EINA_ARG_NONNULL(1, 4);
+
+   EAPI void             elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+   EAPI void            *elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 2);
+
+   EAPI void             elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h);
+
+   EAPI double           elm_longpress_timeout_get(void);
+   EAPI void             elm_longpress_timeout_set(double longpress_timeout);
+
+   /* debug
+    * don't use it unless you are sure
+    */
+   EAPI void             elm_object_tree_dump(const Evas_Object *top);
+   EAPI void             elm_object_tree_dot_dump(const Evas_Object *top, const char *file);
 
-   EAPI double       elm_longpress_timeout_get(void);
-   EAPI void         elm_longpress_timeout_set(double longpress_timeout);
+   EAPI void         elm_autocapitalization_allow_all_set(Eina_Bool autocap);
+   EAPI void         elm_autoperiod_allow_all_set(Eina_Bool autoperiod);
 
-   EAPI Elm_Theme   *elm_theme_new(void);
-   EAPI void         elm_theme_free(Elm_Theme *th);
-   EAPI void         elm_theme_overlay_add(Elm_Theme *th, const char *item);
-   EAPI void         elm_theme_overlay_del(Elm_Theme *th, const char *item);
-   EAPI void         elm_theme_extension_add(Elm_Theme *th, const char *item);
-   EAPI void         elm_theme_extension_del(Elm_Theme *th, const char *item);
-   EAPI void         elm_theme_set(Elm_Theme *th, const char *theme);
-   EAPI const char  *elm_theme_get(Elm_Theme *th);
-   EAPI void         elm_theme_flush(Elm_Theme *th);
-   EAPI void         elm_theme_full_flush(void);
+   /* theme */
+   typedef struct _Elm_Theme Elm_Theme;
 
-   EAPI void         elm_theme_all_set(const char *theme);
+   EAPI Elm_Theme       *elm_theme_new(void);
+   EAPI void             elm_theme_free(Elm_Theme *th);
+   EAPI void             elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst);
+   EAPI void             elm_theme_ref_set(Elm_Theme *th, Elm_Theme *thref);
+   EAPI Elm_Theme       *elm_theme_ref_get(Elm_Theme *th);
+   EAPI Elm_Theme       *elm_theme_default_get(void);
+   EAPI void             elm_theme_overlay_add(Elm_Theme *th, const char *item);
+   EAPI void             elm_theme_overlay_del(Elm_Theme *th, const char *item);
+   EAPI void             elm_theme_extension_add(Elm_Theme *th, const char *item);
+   EAPI void             elm_theme_extension_del(Elm_Theme *th, const char *item);
+   EAPI void             elm_theme_set(Elm_Theme *th, const char *theme);
+   EAPI const char      *elm_theme_get(Elm_Theme *th);
+   EAPI const Eina_List *elm_theme_list_get(const Elm_Theme *th);
+   EAPI char            *elm_theme_list_item_path_get(const char *f, Eina_Bool *in_search_path);
+   EAPI void             elm_theme_flush(Elm_Theme *th);
+   EAPI void             elm_theme_full_flush(void);
+
+   EAPI void             elm_theme_all_set(const char *theme);
+
+   EAPI Eina_List       *elm_theme_name_available_list_new(void);
+   EAPI void             elm_theme_name_available_list_free(Eina_List *list);
+
+   EAPI void             elm_object_theme_set(Evas_Object *obj, Elm_Theme *th) EINA_ARG_NONNULL(1);
+   EAPI Elm_Theme       *elm_object_theme_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+   /* win */
+   typedef enum _Elm_Win_Type
+     {
+        ELM_WIN_BASIC,
+        ELM_WIN_DIALOG_BASIC,
+        ELM_WIN_DESKTOP,
+        ELM_WIN_DOCK,
+        ELM_WIN_TOOLBAR,
+        ELM_WIN_MENU,
+        ELM_WIN_UTILITY,
+        ELM_WIN_SPLASH
+     } Elm_Win_Type;
 
-   EAPI void         elm_object_theme_set(Evas_Object *obj, Elm_Theme *th);
-   EAPI Elm_Theme   *elm_object_theme_get(Evas_Object *obj);
+   typedef enum _Elm_Win_Keyboard_Mode
+     {
+        ELM_WIN_KEYBOARD_UNKNOWN,
+        ELM_WIN_KEYBOARD_OFF,
+        ELM_WIN_KEYBOARD_ON,
+        ELM_WIN_KEYBOARD_ALPHA,
+        ELM_WIN_KEYBOARD_NUMERIC,
+        ELM_WIN_KEYBOARD_PIN,
+        ELM_WIN_KEYBOARD_PHONE_NUMBER,
+        ELM_WIN_KEYBOARD_HEX,
+        ELM_WIN_KEYBOARD_TERMINAL,
+        ELM_WIN_KEYBOARD_PASSWORD,
+        ELM_WIN_KEYBOARD_IP,
+        ELM_WIN_KEYBOARD_HOST,
+        ELM_WIN_KEYBOARD_FILE,
+        ELM_WIN_KEYBOARD_URL,
+        ELM_WIN_KEYBOARD_KEYPAD,
+        ELM_WIN_KEYBOARD_J2ME
+     } Elm_Win_Keyboard_Mode;
 
    EAPI Evas_Object *elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type);
-   EAPI void         elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj);
-   EAPI void         elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj);
-   EAPI void         elm_win_title_set(Evas_Object *obj, const char *title);
-   EAPI void         elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel);
-   EAPI void         elm_win_activate(Evas_Object *obj);
-   EAPI void         elm_win_lower(Evas_Object *obj);
-   EAPI void         elm_win_raise(Evas_Object *obj);
-   EAPI void         elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless);
-   EAPI Eina_Bool    elm_win_borderless_get(const Evas_Object *obj);
-   EAPI void         elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped);
-   EAPI Eina_Bool    elm_win_shaped_get(const Evas_Object *obj);
-   EAPI void         elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha);
-   EAPI Eina_Bool    elm_win_transparent_get(const Evas_Object *obj);
-   EAPI void         elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent);
-   EAPI Eina_Bool    elm_win_alpha_get(const Evas_Object *obj);
-   EAPI void         elm_win_override_set(Evas_Object *obj, Eina_Bool override);
-   EAPI Eina_Bool    elm_win_override_get(const Evas_Object *obj);
-   EAPI void         elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen);
-   EAPI Eina_Bool    elm_win_fullscreen_get(const Evas_Object *obj);
-   EAPI void         elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized);
-   EAPI Eina_Bool    elm_win_maximized_get(const Evas_Object *obj);
-   EAPI void         elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified);
-   EAPI Eina_Bool    elm_win_iconified_get(const Evas_Object *obj);
-   EAPI void         elm_win_layer_set(Evas_Object *obj, int layer);
-   EAPI int          elm_win_layer_get(const Evas_Object *obj);
-   EAPI void         elm_win_rotation_set(Evas_Object *obj, int rotation);
-   EAPI void         elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation);
-   EAPI int          elm_win_rotation_get(const Evas_Object *obj);
-   EAPI void         elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky);
-   EAPI Eina_Bool    elm_win_sticky_get(const Evas_Object *obj);
-   EAPI void         elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant);
-   EAPI Eina_Bool    elm_win_conformant_get(const Evas_Object *obj);
-   EAPI void         elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel);
-   EAPI Eina_Bool    elm_win_quickpanel_get(const Evas_Object *obj);
-   EAPI void         elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority);
-   EAPI int          elm_win_quickpanel_priority_major_get(const Evas_Object *obj);
-   EAPI void         elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority);
-   EAPI int          elm_win_quickpanel_priority_minor_get(const Evas_Object *obj);
-   EAPI void         elm_win_quickpanel_zone_set(Evas_Object *obj, int zone);
+   EAPI void         elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_title_set(Evas_Object *obj, const char *title) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_win_title_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_autodel_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_activate(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_lower(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_raise(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_borderless_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_shaped_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_transparent_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_alpha_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_override_set(Evas_Object *obj, Eina_Bool override) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_override_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_fullscreen_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_maximized_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_iconified_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_layer_set(Evas_Object *obj, int layer) EINA_ARG_NONNULL(1);
+   EAPI int          elm_win_layer_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_rotation_set(Evas_Object *obj, int rotation) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation) EINA_ARG_NONNULL(1);
+   EAPI int          elm_win_rotation_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_sticky_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_conformant_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_quickpanel_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority) EINA_ARG_NONNULL(1);
+   EAPI int          elm_win_quickpanel_priority_major_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority) EINA_ARG_NONNULL(1);
+   EAPI int          elm_win_quickpanel_priority_minor_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_quickpanel_zone_set(Evas_Object *obj, int zone) EINA_ARG_NONNULL(1);
+   EAPI int          elm_win_quickpanel_zone_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_win_focus_highlight_enabled_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_win_focus_highlight_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
    EAPI void         elm_win_indicator_state_set(Evas_Object *obj, int show_state);
    EAPI int          elm_win_indicator_state_get(Evas_Object *obj);
-
    /*...
     * ecore_x_icccm_hints_set -> accepts_focus (add to ecore_evas)
     * ecore_x_icccm_hints_set -> window_group (add to ecore_evas)
@@ -416,6 +583,7 @@ extern "C" {
     * "clicked" - the user clicked the icon
     */
 
+   /* image */
    typedef enum _Elm_Image_Orient
      {
        ELM_IMAGE_ORIENT_NONE,
@@ -676,6 +844,19 @@ extern "C" {
     * "drag,stop" - Gengrid is not being dragged.
     */
 
+   /* clock */
+   typedef enum _Elm_Clock_Digedit
+     {
+        ELM_CLOCK_NONE         = 0,
+        ELM_CLOCK_HOUR_DECIMAL = 1 << 0,
+        ELM_CLOCK_HOUR_UNIT    = 1 << 1,
+        ELM_CLOCK_MIN_DECIMAL  = 1 << 2,
+        ELM_CLOCK_MIN_UNIT     = 1 << 3,
+        ELM_CLOCK_SEC_DECIMAL  = 1 << 4,
+        ELM_CLOCK_SEC_UNIT     = 1 << 5,
+        ELM_CLOCK_ALL         = (1 << 6) - 1
+     } Elm_Clock_Digedit;
+
    EAPI Evas_Object *elm_clock_add(Evas_Object *parent);
    EAPI void         elm_clock_time_set(Evas_Object *obj, int hrs, int min, int sec);
    EAPI void         elm_clock_time_get(const Evas_Object *obj, int *hrs, int *min, int *sec);
@@ -872,11 +1053,6 @@ extern "C" {
 
    /* composite widgets - these basically put together basic widgets above
     * in convenient packages that do more than basic stuff */
-   typedef enum _Elm_Text_Format
-     {
-       ELM_TEXT_FORMAT_PLAIN_UTF8,
-       ELM_TEXT_FORMAT_MARKUP_UTF8
-     } Elm_Text_Format;
    EINA_DEPRECATED EAPI Evas_Object *elm_notepad_add(Evas_Object *parent);
    EINA_DEPRECATED EAPI void         elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format);
    EINA_DEPRECATED EAPI void         elm_notepad_file_save(Evas_Object *obj, const char *file, Elm_Text_Format format);
@@ -916,6 +1092,7 @@ extern "C" {
     * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchorview_Info
     */
 
+   /* anchorblock */
    typedef struct _Elm_Entry_Anchorblock_Info Elm_Entry_Anchorblock_Info;
    struct _Elm_Entry_Anchorblock_Info
      {
@@ -974,6 +1151,15 @@ extern "C" {
     * "clicked" - the user clicked the icon
     */
 
+   /* thumb */
+   typedef enum _Elm_Thumb_Animation_Setting
+     {
+        ELM_THUMB_ANIMATION_START = 0, /* Play animation once */
+        ELM_THUMB_ANIMATION_LOOP,      /* Keep playing animation until stop is requested */
+        ELM_THUMB_ANIMATION_STOP,
+        ELM_THUMB_ANIMATION_LAST
+     } Elm_Thumb_Animation_Setting;
+
    EAPI Evas_Object *elm_thumb_add(Evas_Object *parent);
    EAPI void        elm_thumb_file_set(Evas_Object *obj, const char *file, const char *key);
    EAPI void        elm_thumb_file_get(const Evas_Object *obj, const char **file, const char **key);
@@ -1061,6 +1247,29 @@ extern "C" {
     * "clicked" - when the user clicks on a toolbar item and becomes selected
     */
 
+   /* tooltip */
+   EAPI double       elm_tooltip_delay_get(void);
+   EAPI Eina_Bool    elm_tooltip_delay_set(double delay);
+   EAPI void         elm_object_tooltip_show(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_tooltip_hide(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_tooltip_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1, 2);
+   EAPI void         elm_object_tooltip_content_cb_set(Evas_Object *obj, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_tooltip_unset(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_tooltip_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_object_tooltip_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_cursor_set(Evas_Object *obj, const char *cursor) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_object_cursor_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_cursor_unset(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_cursor_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+   EAPI const char  *elm_object_cursor_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_object_cursor_engine_only_set(Evas_Object *obj, Eina_Bool engine_only) EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_object_cursor_engine_only_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+   /* cursors */
+   EAPI int          elm_cursor_engine_only_get(void);
+   EAPI Eina_Bool    elm_cursor_engine_only_set(int engine_only);
+
+   /* menu */
    typedef struct _Menu_Item Elm_Menu_Item;
    EAPI Evas_Object     *elm_menu_add(Evas_Object *parent);
    EAPI void            elm_menu_parent_set(Evas_Object *obj, Evas_Object *parent);
@@ -1084,6 +1293,7 @@ extern "C" {
     * "clicked" - the user clicked the empty space in the menu to dismiss. event_info is NULL.
     */
 
+   /* list */
    typedef enum _Elm_List_Mode
      {
        ELM_LIST_COMPRESS = 0,
@@ -1566,6 +1776,7 @@ extern "C" {
     * "scroll,drag,stop" - dragging the contents around has stopped
     */
 
+   /* map */
    typedef enum _Elm_Map_Zoom_Mode
      {
         ELM_MAP_ZOOM_MODE_MANUAL,
@@ -1587,6 +1798,7 @@ extern "C" {
         ELM_MAP_SOURCE_CUSTOM_4,
         ELM_MAP_SOURCE_CUSTOM_5,
         ELM_MAP_SOURCE_CUSTOM_6,
+        ELM_MAP_SOURCE_MODULE,
         ELM_MAP_SOURCE_LAST
      } Elm_Map_Sources;
 
@@ -1661,6 +1873,7 @@ extern "C" {
     * "scroll,drag,stop" - dragging the contents around has stopped
     */
 
+   /* panel */
    typedef enum _Elm_Panel_Orient
      {
         ELM_PANEL_ORIENT_TOP,
@@ -1678,6 +1891,7 @@ extern "C" {
    EAPI void                  elm_panel_toggle(Evas_Object *obj);
 
 
+   /* panes */
    /**
     * TODO
     *
@@ -1698,6 +1912,7 @@ extern "C" {
    EAPI void                  elm_panes_fixed_set(Evas_Object *obj, Eina_Bool fixed);
    EAPI Eina_Bool             elm_panes_fixed_get(const Evas_Object *obj);
 
+   /* flip */
    typedef enum _Elm_Flip_Mode
      {
         ELM_FLIP_ROTATE_Y_CENTER_AXIS,
diff --git a/src/lib/Elementary_Cursor.h b/src/lib/Elementary_Cursor.h
new file mode 100644 (file)
index 0000000..78a7c40
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef _ELM_CURSOR_H
+#define _ELM_CURSOR_H
+
+/**
+ * @file
+ * @brief Defines the various cursor types for the X Windows system.
+ */
+
+#define ELM_CURSOR_X                   "x"
+#define ELM_CURSOR_ARROW               "arrow"
+#define ELM_CURSOR_BASED_ARROW_DOWN    "based_arrow_down"
+#define ELM_CURSOR_BASED_ARROW_UP      "based_arrow_up"
+#define ELM_CURSOR_BOAT                "boat"
+#define ELM_CURSOR_BOGOSITY            "bogosity"
+#define ELM_CURSOR_BOTTOM_LEFT_CORNER  "bottom_left_corner"
+#define ELM_CURSOR_BOTTOM_RIGHT_CORNER "bottom_right_corner"
+#define ELM_CURSOR_BOTTOM_SIDE         "bottom_side"
+#define ELM_CURSOR_BOTTOM_TEE          "bottom_tee"
+#define ELM_CURSOR_BOX_SPIRAL          "box_spiral"
+#define ELM_CURSOR_CENTER_PTR          "center_ptr"
+#define ELM_CURSOR_CIRCLE              "circle"
+#define ELM_CURSOR_CLOCK               "clock"
+#define ELM_CURSOR_COFFEE_MUG          "coffee_mug"
+#define ELM_CURSOR_CROSS               "cross"
+#define ELM_CURSOR_CROSS_REVERSE       "cross_reverse"
+#define ELM_CURSOR_CROSSHAIR           "crosshair"
+#define ELM_CURSOR_DIAMOND_CROSS       "diamond_cross"
+#define ELM_CURSOR_DOT                 "dot"
+#define ELM_CURSOR_DOT_BOX_MASK        "dot_box_mask"
+#define ELM_CURSOR_DOUBLE_ARROW        "double_arrow"
+#define ELM_CURSOR_DRAFT_LARGE         "draft_large"
+#define ELM_CURSOR_DRAFT_SMALL         "draft_small"
+#define ELM_CURSOR_DRAPED_BOX          "draped_box"
+#define ELM_CURSOR_EXCHANGE            "exchange"
+#define ELM_CURSOR_FLEUR               "fleur"
+#define ELM_CURSOR_GOBBLER             "gobbler"
+#define ELM_CURSOR_GUMBY               "gumby"
+#define ELM_CURSOR_HAND1               "hand1"
+#define ELM_CURSOR_HAND2               "hand2"
+#define ELM_CURSOR_HEART               "heart"
+#define ELM_CURSOR_ICON                "icon"
+#define ELM_CURSOR_IRON_CROSS          "iron_cross"
+#define ELM_CURSOR_LEFT_PTR            "left_ptr"
+#define ELM_CURSOR_LEFT_SIDE           "left_side"
+#define ELM_CURSOR_LEFT_TEE            "left_tee"
+#define ELM_CURSOR_LEFTBUTTON          "leftbutton"
+#define ELM_CURSOR_LL_ANGLE            "ll_angle"
+#define ELM_CURSOR_LR_ANGLE            "lr_angle"
+#define ELM_CURSOR_MAN                 "man"
+#define ELM_CURSOR_MIDDLEBUTTON        "middlebutton"
+#define ELM_CURSOR_MOUSE               "mouse"
+#define ELM_CURSOR_PENCIL              "pencil"
+#define ELM_CURSOR_PIRATE              "pirate"
+#define ELM_CURSOR_PLUS                "plus"
+#define ELM_CURSOR_QUESTION_ARROW      "question_arrow"
+#define ELM_CURSOR_RIGHT_PTR           "right_ptr"
+#define ELM_CURSOR_RIGHT_SIDE          "right_side"
+#define ELM_CURSOR_RIGHT_TEE           "right_tee"
+#define ELM_CURSOR_RIGHTBUTTON         "rightbutton"
+#define ELM_CURSOR_RTL_LOGO            "rtl_logo"
+#define ELM_CURSOR_SAILBOAT            "sailboat"
+#define ELM_CURSOR_SB_DOWN_ARROW       "sb_down_arrow"
+#define ELM_CURSOR_SB_H_DOUBLE_ARROW   "sb_h_double_arrow"
+#define ELM_CURSOR_SB_LEFT_ARROW       "sb_left_arrow"
+#define ELM_CURSOR_SB_RIGHT_ARROW      "sb_right_arrow"
+#define ELM_CURSOR_SB_UP_ARROW         "sb_up_arrow"
+#define ELM_CURSOR_SB_V_DOUBLE_ARROW   "sb_v_double_arrow"
+#define ELM_CURSOR_SHUTTLE             "shuttle"
+#define ELM_CURSOR_SIZING              "sizing"
+#define ELM_CURSOR_SPIDER              "spider"
+#define ELM_CURSOR_SPRAYCAN            "spraycan"
+#define ELM_CURSOR_STAR                "star"
+#define ELM_CURSOR_TARGET              "target"
+#define ELM_CURSOR_TCROSS              "tcross"
+#define ELM_CURSOR_TOP_LEFT_ARROW      "top_left_arrow"
+#define ELM_CURSOR_TOP_LEFT_CORNER     "top_left_corner"
+#define ELM_CURSOR_TOP_RIGHT_CORNER    "top_right_corner"
+#define ELM_CURSOR_TOP_SIDE            "top_side"
+#define ELM_CURSOR_TOP_TEE             "top_tee"
+#define ELM_CURSOR_TREK                "trek"
+#define ELM_CURSOR_UL_ANGLE            "ul_angle"
+#define ELM_CURSOR_UMBRELLA            "umbrella"
+#define ELM_CURSOR_UR_ANGLE            "ur_angle"
+#define ELM_CURSOR_WATCH               "watch"
+#define ELM_CURSOR_XTERM               "xterm"
+
+#endif // ifndef _ELM_CURSOR_H
+
index bad3571..a768a39 100644 (file)
@@ -26,7 +26,10 @@ endif
 
 lib_LTLIBRARIES = libelementary.la
 
-includes_HEADERS = Elementary.h elm_priv.h
+includes_HEADERS = \
+Elementary.h \
+Elementary_Cursor.h \
+elm_widget.h
 includesdir = $(includedir)/elementary-@VMAJ@
 
 libelementary_la_SOURCES = \
@@ -60,6 +63,7 @@ elm_searchbar.c \
 elm_list.c \
 elm_carousel.c \
 elm_slider.c \
+elm_actionslider.c \
 elm_genlist.c \
 elm_check.c \
 elm_radio.c \
@@ -104,7 +108,6 @@ elm_ctxpopup.c \
 elm_actionsheet.c \
 elm_gridbox.c \
 elm_softkey.c \
-elm_actionslider.c \
 elm_hor_scroller.c \
 elm_autocompleteview.c \
 elm_controlbar.c \
@@ -123,6 +126,7 @@ elm_multibuttonentry.c \
 elm_stackedicon.c \
 elm_calendar.c \
 elm_xml_animator.c \
+elm_font.c \
 \
 elc_anchorblock.c \
 elc_anchorview.c \
@@ -141,7 +145,9 @@ els_hor_scroller.h \
 els_box.c \
 els_box.h \
 els_icon.c \
-els_icon.h
+els_icon.h \
+els_cursor.c \
+els_tooltip.c
 
 
 libelementary_la_CFLAGS =
index dff4e3e..24b325d 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 // FIXME: this is NOT the carousel - yet!
 
index e8c66af..42c09a5 100644 (file)
 Elm_Config *_elm_config = NULL;
 char *_elm_profile = NULL;
 static Eet_Data_Descriptor *_config_edd = NULL;
+static Eet_Data_Descriptor *_config_font_overlay_edd = NULL;
+
+static Ecore_Poller *_elm_cache_flush_poller = NULL;
+
+const char *_elm_engines[] = {
+   "software_x11",
+   "fb",
+   "directfb",
+   "software_16_x11",
+   "software_8_x11",
+   "xrender_x11",
+   "opengl_x11",
+   "software_gdi",
+   "software_16_wince_gdi",
+   "sdl",
+   "software_16_sdl",
+   "opengl_sdl",
+   NULL
+};
+
+/* whenever you want to add a new text class support into Elementary,
+   declare it both here and in the (default) theme */
+static const Elm_Text_Class _elm_text_classes[] = {
+   {"button", "Button Labels"},
+   {"label", "Text Labels"},
+   {"entry", "Text Entries"},
+   {"title_bar", "Title Bar"},
+   {"list_item", "List Items"},
+   {"grid_item", "Grid Items"},
+   {"toolbar_item", "Toolbar Items"},
+   {"menu_item", "Menu Items"},
+   {NULL, NULL}
+};
 
-static void _desc_init(void);
-static void _desc_shutdown(void);
-static void _profile_get(void);
-static void _config_free(void);
-static void _config_apply(void);
-static Elm_Config * _config_user_load(void);
-static Elm_Config * _config_system_load(void);
-static void _config_load(void);
-static void _config_update(void);
-static void _env_get(void);
+static void        _desc_init(void);
+static void        _desc_shutdown(void);
+static void        _profile_fetch_from_conf(void);
+static void        _config_free(void);
+static void        _config_apply(void);
+static Elm_Config *_config_user_load(void);
+static Elm_Config *_config_system_load(void);
+static void        _config_load(void);
+static void        _config_update(void);
+static void        _env_get(void);
+static size_t      _elm_data_dir_snprintf(char       *dst,
+                                          size_t      size,
+                                          const char *fmt, ...)
+                                          EINA_PRINTF(3, 4);
+static size_t _elm_user_dir_snprintf(char       *dst,
+                                     size_t      size,
+                                     const char *fmt, ...)
+                                     EINA_PRINTF(3, 4);
+
+#define ELM_CONFIG_VAL(edd, type, member, dtype) \
+  EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
+#define ELM_CONFIG_LIST(edd, type, member, eddtype) \
+  EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
 
 #ifdef HAVE_ELEMENTARY_X
 static Ecore_Event_Handler *_prop_change_handler = NULL;
 static Ecore_X_Window _root_1st = 0;
-#define ATOM_COUNT 8
+#define ATOM_COUNT 25
 static Ecore_X_Atom _atom[ATOM_COUNT];
 static Ecore_X_Atom _atom_config = 0;
-static Ecore_X_Atom _atom_config_specific = 0;
 static const char *_atom_names[ATOM_COUNT] =
 {
-     "ENLIGHTENMENT_SCALE",
-     "ENLIGHTENMENT_FINGER_SIZE",
-     "ENLIGHTENMENT_THEME",
-     "ENLIGHTENMENT_PROFILE",
-     "ENLIGHTENMENT_CONFIG",
-     "ENLIGHTENMENT_INPUT_PANEL",
-     "ENLIGHTENMENT_AUTOCAPITAL_ALLOW",
-     "ENLIGHTENMENT_AUTOPERIOD_ALLOW",
+   "ENLIGHTENMENT_SCALE",
+   "ENLIGHTENMENT_FINGER_SIZE",
+   "ENLIGHTENMENT_THEME",
+   "ENLIGHTENMENT_PROFILE",
+   "ENLIGHTENMENT_FONT_OVERLAY",
+   "ENLIGHTENMENT_CACHE_FLUSH_INTERVAL",
+   "ENLIGHTENMENT_CACHE_FLUSH_ENABLE",
+   "ENLIGHTENMENT_FONT_CACHE",
+   "ENLIGHTENMENT_IMAGE_CACHE",
+   "ENLIGHTENMENT_EDJE_FILE_CACHE",
+   "ENLIGHTENMENT_EDJE_COLLECTION_CACHE",
+   "ENLIGHTENMENT_THUMBSCROLL_BOUNCE_ENABLE",
+   "ENLIGHTENMENT_THUMBSCROLL_BOUNCE_FRICTION",
+   "ENLIGHTENMENT_THUMBSCROLL_ENABLE",
+   "ENLIGHTENMENT_THUMBSCROLL_THRESHOLD",
+   "ENLIGHTENMENT_THUMBSCROLL_MOMENTUM_THRESHOLD",
+   "ENLIGHTENMENT_THUMBSCROLL_FRICTION",
+   "ENLIGHTENMENT_THUMBSCROLL_BORDER_FRICTION",
+   "ENLIGHTENMENT_THUMBSCROLL_PAGE_SCROLL_FRICTION",
+   "ENLIGHTENMENT_THUMBSCROLL_BRING_IN_SCROLL_FRICTION",
+   "ENLIGHTENMENT_THUMBSCROLL_ZOOM_FRICTION",
+   "ENLIGHTENMENT_INPUT_PANEL",
+   "ENLIGHTENMENT_AUTOCAPITAL_ALLOW",
+   "ENLIGHTENMENT_AUTOPERIOD_ALLOW",
+   "ENLIGHTENMENT_CONFIG"
 };
-#define ATOM_E_SCALE 0
-#define ATOM_E_FINGER_SIZE 1
-#define ATOM_E_THEME 2
-#define ATOM_E_PROFILE 3
-#define ATOM_E_CONFIG 4
-#define ATOM_E_INPUT_PANEL 5
-#define ATOM_E_AUTOCAPITAL_ALLOW 6
-#define ATOM_E_AUTOPERIOD_ALLOW 7
+#define ATOM_E_SCALE                                0
+#define ATOM_E_FINGER_SIZE                          1
+#define ATOM_E_THEME                                2
+#define ATOM_E_PROFILE                              3
+#define ATOM_E_FONT_OVERLAY                         4
+#define ATOM_E_CACHE_FLUSH_INTERVAL                 5
+#define ATOM_E_CACHE_FLUSH_ENABLE                   6
+#define ATOM_E_FONT_CACHE                           7
+#define ATOM_E_IMAGE_CACHE                          8
+#define ATOM_E_EDJE_FILE_CACHE                      9
+#define ATOM_E_EDJE_COLLECTION_CACHE                10
+#define ATOM_E_THUMBSCROLL_BOUNCE_ENABLE            11
+#define ATOM_E_THUMBSCROLL_BOUNCE_FRICTION          12
+#define ATOM_E_THUMBSCROLL_ENABLE                   13
+#define ATOM_E_THUMBSCROLL_THRESHOLD                14
+#define ATOM_E_THUMBSCROLL_MOMENTUM_THRESHOLD       15
+#define ATOM_E_THUMBSCROLL_FRICTION                 16
+#define ATOM_E_THUMBSCROLL_BORDER_FRICTION          17
+#define ATOM_E_THUMBSCROLL_PAGE_SCROLL_FRICTION     18
+#define ATOM_E_THUMBSCROLL_BRING_IN_SCROLL_FRICTION 19
+#define ATOM_E_THUMBSCROLL_ZOOM_FRICTION            20
+#define ATOM_E_INPUT_PANEL 21
+#define ATOM_E_AUTOCAPITAL_ALLOW 22
+#define ATOM_E_AUTOPERIOD_ALLOW 23
+#define ATOM_E_CONFIG                               24
 
 static Eina_Bool _prop_config_get(void);
-static Eina_Bool _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev);
+static Eina_Bool _prop_change(void *data  __UNUSED__,
+                              int ev_type __UNUSED__,
+                              void       *ev);
 
 static Eina_Bool
 _prop_config_get(void)
@@ -67,12 +148,12 @@ _prop_config_get(void)
    atom = ecore_x_atom_get(buf);
    _atom_config = atom;
    if (!ecore_x_window_prop_property_get(_root_1st,
-                                         atom, _atom[ATOM_E_CONFIG], 
+                                         atom, _atom[ATOM_E_CONFIG],
                                          8, &data, &size))
      {
-        if (!ecore_x_window_prop_property_get(_root_1st, 
-                                              _atom[ATOM_E_CONFIG], 
-                                              _atom[ATOM_E_CONFIG], 
+        if (!ecore_x_window_prop_property_get(_root_1st,
+                                              _atom[ATOM_E_CONFIG],
+                                              _atom[ATOM_E_CONFIG],
                                               8, &data, &size))
           return EINA_FALSE;
         else
@@ -88,23 +169,29 @@ _prop_config_get(void)
    config_data = eet_data_descriptor_decode(_config_edd, data, size);
    free(data);
    if (!config_data) return EINA_FALSE;
- /* What do we do on version mismatch when someone changes the
- * config in the rootwindow? */
- /* Most obvious case, new version and we are still linked to
- * whatever was there before, we just ignore until user restarts us */
- if (config_data->config_version > ELM_CONFIG_VERSION)
- return EINA_TRUE;
-/* What in the case the version is older? Do we even support those
-* cases or we only check for equality above? */
+
+   /* What do we do on version mismatch when someone changes the
+    * config in the rootwindow? */
+   /* Most obvious case, new version and we are still linked to
+    * whatever was there before, we just ignore until user restarts us */
+   if (config_data->config_version > ELM_CONFIG_VERSION)
+     return EINA_TRUE;
+   /* What in the case the version is older? Do we even support those
+    * cases or we only check for equality above? */
+
    _config_free();
    _elm_config = config_data;
    _config_apply();
+   _elm_config_font_overlay_apply();
    _elm_rescale();
+   _elm_recache();
    return EINA_TRUE;
 }
 
 static Eina_Bool
-_prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
+_prop_change(void *data  __UNUSED__,
+             int ev_type __UNUSED__,
+             void       *ev)
 {
    Ecore_X_Event_Window_Property *event = ev;
 
@@ -122,7 +209,11 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
 
                   pscale = _elm_config->scale;
                   if (val > 0) _elm_config->scale = (double)val / 1000.0;
-                  if (pscale != _elm_config->scale) _elm_rescale();
+                  if (pscale != _elm_config->scale)
+                    {
+                       _elm_rescale();
+                       _elm_recache();
+                    }
                }
           }
         else if (event->atom == _atom[ATOM_E_FINGER_SIZE])
@@ -137,7 +228,11 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
 
                   pfinger_size = _elm_config->finger_size;
                   _elm_config->finger_size = val;
-                  if (pfinger_size != _elm_config->finger_size) _elm_rescale();
+                  if (pfinger_size != _elm_config->finger_size)
+                    {
+                       _elm_rescale();
+                       _elm_recache();
+                    }
                }
           }
         else if (event->atom == _atom[ATOM_E_THEME])
@@ -152,6 +247,7 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
                   _elm_theme_parse(NULL, val);
                   free(val);
                   _elm_rescale();
+                  _elm_recache();
                }
           }
         else if (event->atom == _atom[ATOM_E_PROFILE])
@@ -177,11 +273,245 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
                             _config_free();
                             _config_load();
                             _config_apply();
+                            _elm_config_font_overlay_apply();
                             _elm_rescale();
                          }
                     }
                }
           }
+        else if (event->atom == _atom[ATOM_E_FONT_OVERLAY])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  _config_free();
+                  _config_load();
+                  _config_apply();
+                  _elm_config_font_overlay_apply();
+                  _elm_rescale();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_CACHE_FLUSH_INTERVAL])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  int cache_flush_interval;
+
+                  cache_flush_interval = _elm_config->cache_flush_poll_interval;
+                  _elm_config->cache_flush_poll_interval = val;
+                  if (cache_flush_interval !=
+                      _elm_config->cache_flush_poll_interval)
+                    _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_CACHE_FLUSH_ENABLE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  _elm_config->cache_flush_enable = !!val;
+                  _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_FONT_CACHE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  int font_cache;
+
+                  font_cache = _elm_config->font_cache;
+                  _elm_config->font_cache = val;
+                  if (font_cache != _elm_config->font_cache)
+                    _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_IMAGE_CACHE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  int image_cache;
+
+                  image_cache = _elm_config->image_cache;
+                  _elm_config->image_cache = val;
+                  if (image_cache != _elm_config->image_cache)
+                    _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_EDJE_FILE_CACHE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  int edje_file_cache;
+
+                  edje_file_cache = _elm_config->edje_cache;
+                  _elm_config->edje_cache = val;
+                  if (edje_file_cache != _elm_config->edje_cache)
+                    _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_EDJE_COLLECTION_CACHE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  int edje_collection_cache;
+
+                  edje_collection_cache = _elm_config->edje_collection_cache;
+                  _elm_config->edje_collection_cache = val;
+                  if (edje_collection_cache !=
+                      _elm_config->edje_collection_cache)
+                    _elm_recache();
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_BOUNCE_ENABLE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  _elm_config->thumbscroll_bounce_enable = !!val;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_BOUNCE_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->thumbscroll_bounce_friction =
+                      (double)val / 1000.0;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_ENABLE])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  _elm_config->thumbscroll_enable = !!val;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_THRESHOLD])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0) _elm_config->thumbscroll_threshold = val;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_MOMENTUM_THRESHOLD])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->thumbscroll_momentum_threshold =
+                      (double)val / 1000.0;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->thumbscroll_friction = (double)val / 1000.0;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_BORDER_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->thumbscroll_border_friction =
+                      (double)val / 1000.0;
+               }
+          }
+        else if (event->atom == _atom[ATOM_E_THUMBSCROLL_PAGE_SCROLL_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->page_scroll_friction =
+                      (double)val / 1000.0;
+               }
+          }
+        else if (event->atom ==
+                 _atom[ATOM_E_THUMBSCROLL_BRING_IN_SCROLL_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->bring_in_scroll_friction =
+                      (double)val / 1000.0;
+               }
+          }
+        else if (event->atom ==
+                 _atom[ATOM_E_THUMBSCROLL_ZOOM_FRICTION])
+          {
+             unsigned int val = 1000;
+
+             if (ecore_x_window_prop_card32_get(event->win,
+                                                event->atom,
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    _elm_config->zoom_friction = (double)val / 1000.0;
+               }
+          }
         else if (event->atom == _atom[ATOM_E_INPUT_PANEL])
           {
              unsigned int val = 0;
@@ -242,70 +572,408 @@ _prop_change(void *data __UNUSED__, int ev_type __UNUSED__, void *ev)
              _prop_config_get();
           }
      }
-
    return ECORE_CALLBACK_PASS_ON;
 }
+
 #endif
 
 static void
 _desc_init(void)
 {
    Eet_Data_Descriptor_Class eddc;
-   
+
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config);
    eddc.func.str_direct_alloc = NULL;
    eddc.func.str_direct_free = NULL;
-   
+
    _config_edd = eet_data_descriptor_file_new(&eddc);
    if (!_config_edd)
      {
         printf("EEEK! eet_data_descriptor_file_new() failed\n");
         return;
      }
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "config_version", config_version, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "engine", engine, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_enable", thumbscroll_enable, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_threshhold", thumbscroll_threshhold, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_momentum_threshhold", thumbscroll_momentum_threshhold, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_friction", thumbscroll_friction, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_bounce_friction", thumbscroll_bounce_friction, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "page_scroll_friction", page_scroll_friction, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "bring_in_scroll_friction", bring_in_scroll_friction, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "zoom_friction", zoom_friction, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "thumbscroll_bounce_enable", thumbscroll_bounce_enable, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "scale", scale, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "bgpixmap", bgpixmap, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "compositing", compositing, EET_T_INT);
-   // EET_DATA_DESCRIPTOR_ADD_LIST(_config_edd, Elm_Config, "font_dirs", font_dirs, sub_edd);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "font_hinting", font_hinting, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "image_cache", image_cache, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "font_cache", font_cache, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "finger_size", finger_size, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "fps", fps, EET_T_DOUBLE);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "theme", theme, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "modules", modules, EET_T_STRING);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "password_show_last_character", password_show_last_character, EET_T_INT);
-   EET_DATA_DESCRIPTOR_ADD_BASIC(_config_edd, Elm_Config, "longpress_timeout", longpress_timeout, EET_T_DOUBLE);
+
+   memset(&eddc, 0, sizeof(eddc)); /* just in case... */
+   EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Font_Overlay);
+   eddc.func.str_direct_alloc = NULL;
+   eddc.func.str_direct_free = NULL;
+
+   _config_font_overlay_edd = eet_data_descriptor_stream_new(&eddc);
+   if (!_config_font_overlay_edd)
+     {
+        printf("EEEK! eet_data_descriptor_stream_new() failed\n");
+        eet_data_descriptor_free(_config_edd);
+        return;
+     }
+#define T_INT    EET_T_INT
+#define T_DOUBLE EET_T_DOUBLE
+#define T_STRING EET_T_STRING
+#define T_UCHAR  EET_T_UCHAR
+
+#define T        Elm_Font_Overlay
+#define D        _config_font_overlay_edd
+   ELM_CONFIG_VAL(D, T, text_class, EET_T_STRING);
+   ELM_CONFIG_VAL(D, T, font, EET_T_STRING);
+   ELM_CONFIG_VAL(D, T, size, EET_T_INT);
+#undef T
+#undef D
+
+#define T Elm_Config
+#define D _config_edd
+   ELM_CONFIG_VAL(D, T, config_version, T_INT);
+   ELM_CONFIG_VAL(D, T, engine, T_STRING);
+   ELM_CONFIG_VAL(D, T, thumbscroll_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, thumbscroll_threshold, T_INT);
+   ELM_CONFIG_VAL(D, T, thumbscroll_momentum_threshold, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, thumbscroll_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, thumbscroll_bounce_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, thumbscroll_border_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, page_scroll_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, bring_in_scroll_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, zoom_friction, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, thumbscroll_bounce_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, scale, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, bgpixmap, T_INT);
+   ELM_CONFIG_VAL(D, T, compositing, T_INT);
+   /* EET_DATA_DESCRIPTOR_ADD_LIST(D, T, "font_dirs", font_dirs, sub_edd); */
+   ELM_CONFIG_LIST(D, T, font_overlays, _config_font_overlay_edd);
+   ELM_CONFIG_VAL(D, T, font_hinting, T_INT);
+   ELM_CONFIG_VAL(D, T, cache_flush_poll_interval, T_INT);
+   ELM_CONFIG_VAL(D, T, cache_flush_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, image_cache, T_INT);
+   ELM_CONFIG_VAL(D, T, font_cache, T_INT);
+   ELM_CONFIG_VAL(D, T, edje_cache, T_INT);
+   ELM_CONFIG_VAL(D, T, edje_collection_cache, T_INT);
+   ELM_CONFIG_VAL(D, T, finger_size, T_INT);
+   ELM_CONFIG_VAL(D, T, fps, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, theme, T_STRING);
+   ELM_CONFIG_VAL(D, T, modules, T_STRING);
+   ELM_CONFIG_VAL(D, T, tooltip_delay, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, cursor_engine_only, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, focus_highlight_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, focus_highlight_animate, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, toolbar_shrink_mode, T_INT);
+   ELM_CONFIG_VAL(D, T, fileselector_expand_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, inwin_dialogs_enable, T_UCHAR);
+   ELM_CONFIG_VAL(D, T, icon_size, T_INT);
+   ELM_CONFIG_VAL(D, T, longpress_timeout, T_DOUBLE);
+   ELM_CONFIG_VAL(D, T, password_show_last_character, T_INT);
+#undef T
+#undef D
+#undef T_INT
+#undef T_DOUBLE
+#undef T_STRING
+#undef T_UCHAR
 }
 
 static void
 _desc_shutdown(void)
 {
-   if (!_config_edd) return;
-   eet_data_descriptor_free(_config_edd);
-   _config_edd = NULL;
+   if (_config_edd)
+     {
+        eet_data_descriptor_free(_config_edd);
+        _config_edd = NULL;
+     }
+
+   if (_config_font_overlay_edd)
+     {
+        eet_data_descriptor_free(_config_font_overlay_edd);
+        _config_font_overlay_edd = NULL;
+     }
+}
+
+static int
+_sort_files_cb(const void *f1,
+               const void *f2)
+{
+   return strcmp(f1, f2);
+}
+
+const char *
+_elm_config_current_profile_get(void)
+{
+   return _elm_profile;
+}
+
+static size_t
+_elm_data_dir_snprintf(char       *dst,
+                       size_t      size,
+                       const char *fmt,
+                       ...)
+{
+   size_t data_dir_len, off;
+   va_list ap;
+
+   data_dir_len = eina_strlcpy(dst, _elm_data_dir, size);
+
+   off = data_dir_len + 1;
+   if (off >= size)
+     goto end;
+
+   va_start(ap, fmt);
+   dst[data_dir_len] = '/';
+
+   off = off + vsnprintf(dst + off, size - off, fmt, ap);
+   va_end(ap);
+
+end:
+   return off;
+}
+
+static size_t
+_elm_user_dir_snprintf(char       *dst,
+                       size_t      size,
+                       const char *fmt,
+                       ...)
+{
+   const char *home;
+   size_t user_dir_len, off;
+   va_list ap;
+
+   home = getenv("HOME");
+   if (!home)
+     home = "/";
+
+   user_dir_len = eina_str_join_len(dst, size, '/', home, strlen(home),
+                                    ".elementary", sizeof(".elementary") - 1);
+
+   off = user_dir_len + 1;
+   if (off >= size)
+     goto end;
+
+   va_start(ap, fmt);
+   dst[user_dir_len] = '/';
+
+   off = off + vsnprintf(dst + off, size - off, fmt, ap);
+   va_end(ap);
+
+end:
+   return off;
+}
+
+const char *
+_elm_config_profile_dir_get(const char *prof,
+                            Eina_Bool   is_user)
+{
+   char buf[PATH_MAX];
+
+   if (!is_user)
+     goto not_user;
+
+   _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", prof);
+
+   if (ecore_file_is_dir(buf))
+     return strdup(buf);
+
+   return NULL;
+
+not_user:
+   snprintf(buf, sizeof(buf), "%s/config/%s", _elm_data_dir, prof);
+
+   if (ecore_file_is_dir(buf))
+     return strdup(buf);
+
+   return NULL;
+}
+
+Eina_List *
+_elm_config_font_overlays_list(void)
+{
+   return _elm_config->font_overlays;
+}
+
+void
+_elm_config_font_overlay_set(const char    *text_class,
+                             const char    *font,
+                             Evas_Font_Size size)
+{
+   Elm_Font_Overlay *efd;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
+     {
+        if (strcmp(efd->text_class, text_class))
+          continue;
+
+        if (efd->font) eina_stringshare_del(efd->font);
+        efd->font = eina_stringshare_add(font);
+        efd->size = size;
+        _elm_config->font_overlays =
+          eina_list_promote_list(_elm_config->font_overlays, l);
+        return;
+     }
+
+   /* the text class doesn't exist */
+   efd = calloc(1, sizeof(Elm_Font_Overlay));
+   efd->text_class = eina_stringshare_add(text_class);
+   efd->font = eina_stringshare_add(font);
+   efd->size = size;
+
+   _elm_config->font_overlays = eina_list_prepend(_elm_config->font_overlays,
+                                                  efd);
+}
+
+void
+_elm_config_font_overlay_remove(const char *text_class)
+{
+   Elm_Font_Overlay *efd;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
+     {
+        if (strcmp(efd->text_class, text_class))
+          continue;
+
+        _elm_config->font_overlays =
+          eina_list_remove_list(_elm_config->font_overlays, l);
+        if (efd->text_class) eina_stringshare_del(efd->text_class);
+        if (efd->font) eina_stringshare_del(efd->font);
+        free(efd);
+
+        return;
+     }
+}
+
+void
+_elm_config_font_overlay_apply(void)
+{
+   Elm_Font_Overlay *efd;
+   Eina_List *l;
+   int i;
+
+   for (i = 0; _elm_text_classes[i].desc; i++)
+     edje_text_class_del(_elm_text_classes[i].name);
+
+   EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
+     edje_text_class_set(efd->text_class, efd->font, efd->size);
+}
+
+Eina_List *
+_elm_config_text_classes_get(void)
+{
+   Eina_List *ret = NULL;
+   int i;
+
+   for (i = 0; _elm_text_classes[i].desc; i++)
+     {
+        Elm_Text_Class *tc;
+        tc = malloc(sizeof(*tc));
+
+        *tc = _elm_text_classes[i];
+
+        ret = eina_list_append(ret, tc);
+     }
+
+   return ret;
+}
+
+void
+_elm_config_text_classes_free(Eina_List *l)
+{
+   Elm_Text_Class *tc;
+
+   EINA_LIST_FREE(l, tc)
+     free(tc);
+}
+
+Eina_List *
+_elm_config_profiles_list(void)
+{
+   const Eina_File_Direct_Info *info;
+   Eina_List *flist = NULL;
+   Eina_Iterator *file_it;
+   char buf[PATH_MAX];
+   const char *dir;
+   size_t len;
+
+   len = _elm_user_dir_snprintf(buf, sizeof(buf), "config");
+
+   file_it = eina_file_direct_ls(buf);
+   if (!file_it)
+     goto sys;
+
+   buf[len] = '/';
+   len++;
+
+   len = sizeof(buf) - len;
+
+   EINA_ITERATOR_FOREACH(file_it, info)
+     {
+        if (info->name_length >= len)
+          continue;
+
+        if (info->type == EINA_FILE_DIR)
+          {
+             flist =
+               eina_list_sorted_insert(flist, _sort_files_cb,
+                                       eina_stringshare_add(info->path +
+                                                            info->name_start));
+          }
+     }
+
+   eina_iterator_free(file_it);
+
+sys:
+   len = eina_str_join_len(buf, sizeof(buf), '/', _elm_data_dir,
+                           strlen(_elm_data_dir), "config",
+                           sizeof("config") - 1);
+
+   file_it = eina_file_direct_ls(buf);
+   if (!file_it)
+     goto list_free;
+
+   buf[len] = '/';
+   len++;
+
+   len = sizeof(buf) - len;
+   EINA_ITERATOR_FOREACH(file_it, info)
+     {
+        if (info->name_length >= len)
+          continue;
+
+        switch (info->type)
+          {
+           case EINA_FILE_DIR:
+           {
+              const Eina_List *l;
+              const char *tmp;
+
+              EINA_LIST_FOREACH(flist, l, tmp)
+                if (!strcmp(info->path + info->name_start, tmp))
+                  break;
+
+              if (!l)
+                flist =
+                  eina_list_sorted_insert(flist, _sort_files_cb,
+                                          eina_stringshare_add(info->path +
+                                                               info->name_start));
+           }
+           break;
+
+           default:
+             continue;
+          }
+     }
+   return flist;
+
+   eina_iterator_free(file_it);
+
+list_free:
+   EINA_LIST_FREE(flist, dir)
+     eina_stringshare_del(dir);
+
+   return NULL;
 }
 
 static void
-_profile_get(void)
+_profile_fetch_from_conf(void)
 {
-   Eet_File *ef = NULL;
-   const char *home = NULL;
    char buf[PATH_MAX], *p, *s;
+   Eet_File *ef = NULL;
    int len = 0;
 
    _elm_profile = strdup("default");
-   
+
    // if env var - use profile without question
    s = getenv("ELM_PROFILE");
    if (s)
@@ -314,12 +982,9 @@ _profile_get(void)
         _elm_profile = strdup(s);
         return;
      }
-   
-   home = getenv("HOME");
-   if (!home) home = "/";
-   
-   // usser profile
-   snprintf(buf, sizeof(buf), "%s/.elementary/config/profile.cfg", home);
+
+   // user profile
+   _elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
    ef = eet_open(buf, EET_FILE_MODE_READ);
    if (ef)
      {
@@ -336,9 +1001,9 @@ _profile_get(void)
         if (!p) ef = NULL;
      }
    if (ef) return;
-   
+
    // system profile
-   snprintf(buf, sizeof(buf), "%s/config/profile.cfg", _elm_data_dir);
+   _elm_data_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
    ef = eet_open(buf, EET_FILE_MODE_READ);
    if (ef)
      {
@@ -358,13 +1023,21 @@ _profile_get(void)
 static void
 _config_free(void)
 {
+   Elm_Font_Overlay *fo;
    const char *fontdir;
-   
+
    if (!_elm_config) return;
    EINA_LIST_FREE(_elm_config->font_dirs, fontdir)
      {
         eina_stringshare_del(fontdir);
      }
+   if (_elm_config->engine) eina_stringshare_del(_elm_config->engine);
+   EINA_LIST_FREE(_elm_config->font_overlays, fo)
+     {
+        if (fo->text_class) eina_stringshare_del(fo->text_class);
+        if (fo->font) eina_stringshare_del(fo->font);
+        free(fo);
+     }
    if (_elm_config->theme) eina_stringshare_del(_elm_config->theme);
    if (_elm_config->modules) eina_stringshare_del(_elm_config->modules);
    free(_elm_config);
@@ -389,19 +1062,57 @@ _config_sub_apply(void)
    edje_autoperiod_allow_set(_elm_config->autoperiod_allow);
 }
 
+static Eina_Bool
+_elm_cache_flush_cb(void *data __UNUSED__)
+{
+   elm_all_flush();
+   return ECORE_CALLBACK_RENEW;
+}
+
+/* kind of abusing this call right now -- shared between all of those
+ * properties -- but they are not meant to be called that periodically
+ * anyway */
+void
+_elm_recache(void)
+{
+   Eina_List *l;
+   Evas_Object *win;
+
+   elm_all_flush();
+
+   EINA_LIST_FOREACH(_elm_win_list, l, win)
+     {
+        Evas *e = evas_object_evas_get(win);
+        evas_image_cache_set(e, _elm_config->image_cache);
+        evas_font_cache_set(e, _elm_config->font_cache);
+     }
+   edje_file_cache_set(_elm_config->edje_cache);
+   edje_collection_cache_set(_elm_config->edje_collection_cache);
+
+   if (_elm_cache_flush_poller)
+     {
+        ecore_poller_del(_elm_cache_flush_poller);
+        _elm_cache_flush_poller = NULL;
+     }
+   if (_elm_config->cache_flush_poll_interval > 0)
+     {
+        _elm_cache_flush_poller =
+          ecore_poller_add(ECORE_POLLER_CORE,
+                           _elm_config->cache_flush_poll_interval,
+                           _elm_cache_flush_cb, NULL);
+     }
+}
+
 static Elm_Config *
 _config_user_load(void)
 {
    Elm_Config *cfg = NULL;
    Eet_File *ef;
    char buf[PATH_MAX];
-   const char *home;
 
-   home = getenv("HOME");
-   if (!home) home = "";
+   _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
+                          _elm_profile);
 
-   snprintf(buf, sizeof(buf), "%s/.elementary/config/%s/base.cfg", home,
-            _elm_profile);
    ef = eet_open(buf, EET_FILE_MODE_READ);
    if (ef)
      {
@@ -418,8 +1129,9 @@ _config_system_load(void)
    Eet_File *ef;
    char buf[PATH_MAX];
 
-   snprintf(buf, sizeof(buf), "%s/config/%s/base.cfg", _elm_data_dir,
-            _elm_profile);
+   _elm_data_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
+                          _elm_profile);
+
    ef = eet_open(buf, EET_FILE_MODE_READ);
    if (ef)
      {
@@ -429,14 +1141,10 @@ _config_system_load(void)
    return cfg;
 }
 
-
 static void
 _config_load(void)
 {
    _elm_config = _config_user_load();
-   
-   
-   // user config
    if (_elm_config)
      {
         if (_elm_config->config_version < ELM_CONFIG_VERSION)
@@ -457,56 +1165,252 @@ _config_load(void)
     * without the config, but do we want that? */
    _elm_config = ELM_NEW(Elm_Config);
    _elm_config->config_version = ELM_CONFIG_VERSION;
-   _elm_config->engine = ELM_SOFTWARE_X11;
-   _elm_config->thumbscroll_enable = 1;
-   _elm_config->thumbscroll_threshhold = 24;
-   _elm_config->thumbscroll_momentum_threshhold = 100.0;
+   _elm_config->engine = eina_stringshare_add("software_x11");
+   _elm_config->thumbscroll_enable = EINA_TRUE;
+   _elm_config->thumbscroll_threshold = 24;
+   _elm_config->thumbscroll_momentum_threshold = 100.0;
    _elm_config->thumbscroll_friction = 1.0;
    _elm_config->thumbscroll_bounce_friction = 0.5;
+   _elm_config->thumbscroll_bounce_enable = EINA_TRUE;
    _elm_config->page_scroll_friction = 0.5;
    _elm_config->bring_in_scroll_friction = 0.5;
    _elm_config->zoom_friction = 0.5;
-   _elm_config->thumbscroll_bounce_enable = 1;
+   _elm_config->thumbscroll_border_friction = 0.5;
    _elm_config->scale = 1.0;
    _elm_config->bgpixmap = 0;
+   _elm_config->compositing = 1;
    _elm_config->font_hinting = 2;
+   _elm_config->cache_flush_poll_interval = 512;
+   _elm_config->cache_flush_enable = EINA_TRUE;
    _elm_config->font_dirs = NULL;
    _elm_config->image_cache = 4096;
    _elm_config->font_cache = 512;
+   _elm_config->edje_cache = 32;
+   _elm_config->edje_collection_cache = 64;
    _elm_config->finger_size = 40;
-   _elm_config->compositing = 1;
    _elm_config->fps = 60.0;
    _elm_config->theme = eina_stringshare_add("default");
    _elm_config->modules = NULL;
-   _elm_config->password_show_last_character = 0;
+   _elm_config->tooltip_delay = 1.0;
+   _elm_config->cursor_engine_only = EINA_TRUE;
+   _elm_config->focus_highlight_enable = EINA_FALSE;
+   _elm_config->focus_highlight_animate = EINA_TRUE;
+   _elm_config->toolbar_shrink_mode = 2;
+   _elm_config->fileselector_expand_enable = EINA_FALSE;
+   _elm_config->inwin_dialogs_enable = EINA_FALSE;
+   _elm_config->icon_size = 32;
    _elm_config->longpress_timeout = 1.0;
+   _elm_config->password_show_last_character = 0;
+}
+
+static const char *
+_elm_config_eet_close_error_get(Eet_File *ef,
+                                char     *file)
+{
+   Eet_Error err;
+   const char *erstr = NULL;
+
+   err = eet_close(ef);
+   switch (err)
+     {
+      case EET_ERROR_WRITE_ERROR:
+        erstr = "An error occurred while saving Elementary's "
+                "settings to disk. The error could not be "
+                "deterimined. The file where the error occurred was: "
+                "%s. This file has been deleted to avoid corrupt data.";
+        break;
+
+      case EET_ERROR_WRITE_ERROR_FILE_TOO_BIG:
+        erstr = "Elementary's settings files are too big "
+                "for the file system they are being saved to. "
+                "This error is very strange as the files should "
+                "be extremely small. Please check the settings "
+                "for your home directory. "
+                "The file where the error occurred was: %s ."
+                "This file has been deleted to avoid corrupt data.";
+        break;
+
+      case EET_ERROR_WRITE_ERROR_IO_ERROR:
+        erstr = "An output error occurred when writing the settings "
+                "files for Elementary. Your disk is having troubles "
+                "and possibly needs replacement. "
+                "The file where the error occurred was: %s ."
+                "This file has been deleted to avoid corrupt data.";
+        break;
+
+      case EET_ERROR_WRITE_ERROR_OUT_OF_SPACE:
+        erstr = "Elementary cannot write its settings file "
+                "because it ran out of space to write the file. "
+                "You have either run out of disk space or have "
+                "gone over your quota limit. "
+                "The file where the error occurred was: %s ."
+                "This file has been deleted to avoid corrupt data.";
+        break;
+
+      case EET_ERROR_WRITE_ERROR_FILE_CLOSED:
+        erstr = "Elementary unexpectedly had the settings file "
+                "it was writing closed on it. This is very unusual. "
+                "The file where the error occurred was: %s "
+                "This file has been deleted to avoid corrupt data.";
+        break;
+
+      default:
+        break;
+     }
+   if (erstr)
+     {
+        /* delete any partially-written file */
+         ecore_file_unlink(file);
+         return strdup(erstr);
+     }
+
+   return NULL;
+}
+
+static Eina_Bool
+_elm_config_profile_save(void)
+{
+   char buf[4096], buf2[4096];
+   int ok = 0, ret;
+   const char *err;
+   Eet_File *ef;
+   size_t len;
+
+   len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
+   if (len + 1 >= sizeof(buf))
+     return EINA_FALSE;
+
+   len = _elm_user_dir_snprintf(buf2, sizeof(buf2), "config/profile.cfg.tmp");
+   if (len + 1 >= sizeof(buf2))
+     return EINA_FALSE;
+
+   ef = eet_open(buf2, EET_FILE_MODE_WRITE);
+   if (!ef)
+     return EINA_FALSE;
+
+   ok = eet_write(ef, "config", _elm_profile, strlen(_elm_profile), 0);
+   if (!ok)
+     goto err;
+
+   err = _elm_config_eet_close_error_get(ef, buf2);
+   if (err)
+     {
+        ERR("%s", err);
+        free((void *)err);
+        goto err;
+     }
+
+   ret = ecore_file_mv(buf2, buf);
+   if (!ret)
+     {
+        ERR("Error saving Elementary's configuration file");
+        goto err;
+     }
+
+   ecore_file_unlink(buf2);
+   return EINA_TRUE;
+
+err:
+   ecore_file_unlink(buf2);
+   return EINA_FALSE;
+}
+
+Eina_Bool
+_elm_config_save(void)
+{
+   char buf[4096], buf2[4096];
+   int ok = 0, ret;
+   const char *err;
+   Eet_File *ef;
+   size_t len;
+
+   len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", _elm_profile);
+   if (len + 1 >= sizeof(buf))
+     return EINA_FALSE;
+
+   ok = ecore_file_mkpath(buf);
+   if (!ok)
+     {
+        ERR("Problem acessing Elementary's user configuration directory: %s",
+            buf);
+        return EINA_FALSE;
+     }
+
+   if (!_elm_config_profile_save())
+     return EINA_FALSE;
+
+   buf[len] = '/';
+   len++;
+
+   if (len + sizeof("base.cfg") >= sizeof(buf) - len)
+     return EINA_FALSE;
+
+   memcpy(buf + len, "base.cfg", sizeof("base.cfg"));
+   len += sizeof("base.cfg") - 1;
+
+   if (len + sizeof(".tmp") >= sizeof(buf))
+     return EINA_FALSE;
+
+   memcpy(buf2, buf, len);
+   memcpy(buf2 + len, ".tmp", sizeof(".tmp"));
+
+   ef = eet_open(buf2, EET_FILE_MODE_WRITE);
+   if (!ef)
+     return EINA_FALSE;
+
+   ok = eet_data_write(ef, _config_edd, "config", _elm_config, 1);
+   if (!ok)
+     goto err;
+
+   err = _elm_config_eet_close_error_get(ef, buf2);
+   if (err)
+     {
+        ERR("%s", err);
+        free((void *)err);
+        goto err;
+     }
+
+   ret = ecore_file_mv(buf2, buf);
+   if (!ret)
+     {
+        ERR("Error saving Elementary's configuration file");
+        goto err;
+     }
+
+   ecore_file_unlink(buf2);
+   return EINA_TRUE;
+
+err:
+   ecore_file_unlink(buf2);
+   return EINA_FALSE;
 }
+
 static void
 _config_update(void)
 {
    Elm_Config *tcfg;
+
    tcfg = _config_system_load();
    if (!tcfg)
      {
-        return;
+        /* weird profile or something? We should probably fill
+         * with hardcoded defaults, or get from default previx */
+          return;
      }
-#define IFCFG(v) if ((_elm_config->config_version & 0xffff) < (v)) {
+#define IFCFG(v)   if ((_elm_config->config_version & 0xffff) < (v)) {
 #define IFCFGELSE } else {
-#define IFCFGEND }
-#define COPYVAL(x) do {_elm_config->x = tcfg->x;} while(0)
+#define IFCFGEND  }
+#define COPYVAL(x) do {_elm_config->x = tcfg->x; } while(0)
 #define COPYPTR(x) do {_elm_config->x = tcfg->x; tcfg->x = NULL; } while(0)
 #define COPYSTR(x) COPYPTR(x)
 
-   /* we also need to update for property changes in the root window
-    * if needed, but that will be dependant on new properties added
-    * with each version */
+     /* we also need to update for property changes in the root window
+      * if needed, but that will be dependent on new properties added
+      * with each version */
 
-   /* nothing here, just an example */
-   /*
-   IFCFG(0x0002);
-   COPYVAL(some_value);
-   IFCFGEND;
-   */
+     IFCFG(0x0003);
+     COPYVAL(longpress_timeout);
+     IFCFGEND;
 
 #undef COPYSTR
 #undef COPYPTR
@@ -515,14 +1419,15 @@ _config_update(void)
 #undef IFCFGELSE
 #undef IFCFG
 
-   /* after updating user config, we must save */
+     /* after updating user config, we must save */
 }
 
 static void
 _env_get(void)
 {
    char *s;
-   
+   double friction;
+
    s = getenv("ELM_ENGINE");
    if (s)
      {
@@ -530,117 +1435,137 @@ _env_get(void)
             (!strcasecmp(s, "x")) ||
             (!strcasecmp(s, "software-x11")) ||
             (!strcasecmp(s, "software_x11")))
-          _elm_config->engine = ELM_SOFTWARE_X11;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_X11);
+        else if ((!strcasecmp(s, "opengl")) ||
+                 (!strcasecmp(s, "gl")) ||
+                 (!strcasecmp(s, "opengl-x11")) ||
+                 (!strcasecmp(s, "opengl_x11")))
+          eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_X11);
+        else if ((!strcasecmp(s, "x11-8")) ||
+                 (!strcasecmp(s, "x18")) ||
+                 (!strcasecmp(s, "software-8-x11")) ||
+                 (!strcasecmp(s, "software_8_x11")))
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_8_X11);
         else if ((!strcasecmp(s, "x11-16")) ||
                  (!strcasecmp(s, "x16")) ||
                  (!strcasecmp(s, "software-16-x11")) ||
                  (!strcasecmp(s, "software_16_x11")))
-          _elm_config->engine = ELM_SOFTWARE_16_X11;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_X11);
         else if ((!strcasecmp(s, "xrender")) ||
                  (!strcasecmp(s, "xr")) ||
                  (!strcasecmp(s, "xrender-x11")) ||
                  (!strcasecmp(s, "xrender_x11")))
-          _elm_config->engine = ELM_XRENDER_X11;
+          eina_stringshare_replace(&_elm_config->engine, ELM_XRENDER_X11);
         else if ((!strcasecmp(s, "fb")) ||
                  (!strcasecmp(s, "software-fb")) ||
                  (!strcasecmp(s, "software_fb")))
-          _elm_config->engine = ELM_SOFTWARE_FB;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_FB);
         else if ((!strcasecmp(s, "directfb")) ||
                  (!strcasecmp(s, "dfb")))
-          _elm_config->engine = ELM_SOFTWARE_DIRECTFB;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_DIRECTFB);
         else if ((!strcasecmp(s, "sdl")) ||
                  (!strcasecmp(s, "software-sdl")) ||
                  (!strcasecmp(s, "software_sdl")))
-          _elm_config->engine = ELM_SOFTWARE_SDL;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_SDL);
         else if ((!strcasecmp(s, "sdl-16")) ||
                  (!strcasecmp(s, "software-16-sdl")) ||
                  (!strcasecmp(s, "software_16_sdl")))
-          _elm_config->engine = ELM_SOFTWARE_16_SDL;
-        else if ((!strcasecmp(s, "opengl")) ||
-                 (!strcasecmp(s, "gl")) ||
-                 (!strcasecmp(s, "opengl-x11")) ||
-                 (!strcasecmp(s, "opengl_x11")))
-          _elm_config->engine = ELM_OPENGL_X11;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_SDL);
         else if ((!strcasecmp(s, "opengl-sdl")) ||
                  (!strcasecmp(s, "opengl_sdl")) ||
                  (!strcasecmp(s, "gl-sdl")) ||
                  (!strcasecmp(s, "gl_sdl")))
-          _elm_config->engine = ELM_OPENGL_SDL;
+          eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_SDL);
         else if ((!strcasecmp(s, "gdi")) ||
                  (!strcasecmp(s, "software-gdi")) ||
                  (!strcasecmp(s, "software_gdi")))
-          _elm_config->engine = ELM_SOFTWARE_WIN32;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_WIN32);
         else if ((!strcasecmp(s, "wince-gdi")) ||
                  (!strcasecmp(s, "software-16-wince-gdi")) ||
                  (!strcasecmp(s, "software_16_wince_gdi")))
-          _elm_config->engine = ELM_SOFTWARE_16_WINCE;
+          eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_WINCE);
      }
 
    s = getenv("ELM_THUMBSCROLL_ENABLE");
-   if (s) _elm_config->thumbscroll_enable = atoi(s);
+   if (s) _elm_config->thumbscroll_enable = !!atoi(s);
    s = getenv("ELM_THUMBSCROLL_THRESHOLD");
-   if (s) _elm_config->thumbscroll_threshhold = atoi(s);
+   if (s) _elm_config->thumbscroll_threshold = atoi(s);
    // FIXME: floatformat locale issues here 1.0 vs 1,0 - should just be 1.0
    s = getenv("ELM_THUMBSCROLL_MOMENTUM_THRESHOLD");
-   if (s) _elm_config->thumbscroll_momentum_threshhold = atof(s);
+   if (s) _elm_config->thumbscroll_momentum_threshold = atof(s);
    s = getenv("ELM_THUMBSCROLL_FRICTION");
    if (s) _elm_config->thumbscroll_friction = atof(s);
+   s = getenv("ELM_THUMBSCROLL_BOUNCE_ENABLE");
+   if (s) _elm_config->thumbscroll_bounce_enable = !!atoi(s);
+   s = getenv("ELM_THUMBSCROLL_BOUNCE_FRICTION");
+   if (s) _elm_config->thumbscroll_bounce_friction = atof(s);
    s = getenv("ELM_PAGE_SCROLL_FRICTION");
    if (s) _elm_config->page_scroll_friction = atof(s);
    s = getenv("ELM_BRING_IN_SCROLL_FRICTION");
    if (s) _elm_config->bring_in_scroll_friction = atof(s);
    s = getenv("ELM_ZOOM_FRICTION");
    if (s) _elm_config->zoom_friction = atof(s);
-   s = getenv("ELM_THUMBSCROLL_BOUNCE_FRICTION");
-   if (s) _elm_config->thumbscroll_bounce_friction = atof(s);
+   s = getenv("ELM_THUMBSCROLL_BORDER_FRICTION");
+   if (s)
+     {
+        friction = atof(s);
+        if (friction < 0.0)
+          friction = 0.0;
+
+        if (friction > 1.0)
+          friction = 1.0;
 
+        _elm_config->thumbscroll_border_friction = friction;
+     }
    s = getenv("ELM_THEME");
    if (s) eina_stringshare_replace(&_elm_config->theme, s);
 
    s = getenv("ELM_FONT_HINTING");
    if (s)
      {
-       if      (!strcasecmp(s, "none"))     _elm_config->font_hinting = 0;
-       else if (!strcasecmp(s, "auto"))     _elm_config->font_hinting = 1;
-       else if (!strcasecmp(s, "bytecode")) _elm_config->font_hinting = 2;
+        if      (!strcasecmp(s, "none")) _elm_config->font_hinting = 0;
+        else if (!strcasecmp(s, "auto"))
+          _elm_config->font_hinting = 1;
+        else if (!strcasecmp(s, "bytecode"))
+          _elm_config->font_hinting = 2;
      }
 
    s = getenv("ELM_FONT_PATH");
    if (s)
      {
-       const char *p, *pp;
-       char *buf2;
+        const char *p, *pp;
+        char *buf2;
 
         EINA_LIST_FREE(_elm_config->font_dirs, p)
           {
              eina_stringshare_del(p);
           }
-        
-       buf2 = alloca(strlen(s) + 1);
-       p = s;
-       pp = p;
-       for (;;)
-         {
-            if ((*p == ':') || (*p == 0))
-              {
-                 int len;
-
-                 len = p - pp;
-                 strncpy(buf2, pp, len);
-                 buf2[len] = 0;
-                 _elm_config->font_dirs = 
-                    eina_list_append(_elm_config->font_dirs, 
+
+        buf2 = alloca(strlen(s) + 1);
+        p = s;
+        pp = p;
+        for (;; )
+          {
+             if ((*p == ':') || (*p == 0))
+               {
+                  int len;
+
+                  len = p - pp;
+                  strncpy(buf2, pp, len);
+                  buf2[len] = 0;
+                  _elm_config->font_dirs =
+                    eina_list_append(_elm_config->font_dirs,
                                      eina_stringshare_add(buf2));
-                 if (*p == 0) break;
-                 p++;
-                 pp = p;
-              }
-            else
-              {
-                 if (*p == 0) break;
-                 p++;
-              }
-         }
+                  if (*p == 0) break;
+                  p++;
+                  pp = p;
+               }
+             else
+               {
+                  if (*p == 0) break;
+                  p++;
+               }
+          }
      }
 
    s = getenv("ELM_IMAGE_CACHE");
@@ -651,8 +1576,9 @@ _env_get(void)
 
    s = getenv("ELM_SCALE");
    if (s) _elm_config->scale = atof(s);
-   
-   _elm_config->finger_size = (double)_elm_config->finger_size * _elm_config->scale;
+
+   _elm_config->finger_size =
+     (double)_elm_config->finger_size * _elm_config->scale;
    s = getenv("ELM_FINGER_SIZE");
    if (s) _elm_config->finger_size = atoi(s);
 
@@ -666,101 +1592,137 @@ _env_get(void)
    s = getenv("ELM_MODULES");
    if (s) eina_stringshare_replace(&_elm_config->modules, s);
 
+   s = getenv("ELM_TOOLTIP_DELAY");
+   if (s)
+     {
+        double delay = atof(s);
+        if (delay >= 0.0)
+          _elm_config->tooltip_delay = delay;
+     }
+
+   s = getenv("ELM_CURSOR_ENGINE_ONLY");
+   if (s) _elm_config->cursor_engine_only = !!atoi(s);
+
+   s = getenv("ELM_FOCUS_HIGHLIGHT_ENABLE");
+   if (s) _elm_config->focus_highlight_enable = !!atoi(s);
+
+   s = getenv("ELM_FOCUS_HIGHLIGHT_ANIMATE");
+   if (s) _elm_config->focus_highlight_animate = !!atoi(s);
+
+   s = getenv("ELM_TOOLBAR_SHRINK_MODE");
+   if (s) _elm_config->toolbar_shrink_mode = atoi(s);
+
+   s = getenv("ELM_FILESELECTOR_EXPAND_ENABLE");
+   if (s) _elm_config->fileselector_expand_enable = !!atoi(s);
+
+   s = getenv("ELM_INWIN_DIALOGS_ENABLE");
+   if (s) _elm_config->inwin_dialogs_enable = !!atoi(s);
+
+   s = getenv("ELM_ICON_SIZE");
+   if (s) _elm_config->icon_size = atoi(s);
+
    s = getenv("ELM_INPUT_PANEL");
    if (s) _elm_config->input_panel_enable = atoi(s);
 
    s = getenv("ELM_LONGPRESS_TIMEOUT");
    if (s) _elm_config->longpress_timeout = atof(s);
-   if (_elm_config->longpress_timeout < 0.0) _elm_config->longpress_timeout = 0.0;
+   if (_elm_config->longpress_timeout < 0.0)
+     _elm_config->longpress_timeout = 0.0;
 }
 
 void
 _elm_config_init(void)
 {
    _desc_init();
-   _profile_get();
+   _profile_fetch_from_conf();
    _config_load();
+   _env_get();
+   _config_apply();
+   _elm_config_font_overlay_apply();
+   _elm_recache();
 }
 
 void
 _elm_config_sub_init(void)
 {
-   _env_get();
-   _config_apply();
-   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
-       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
-       (_elm_config->engine == ELM_XRENDER_X11) ||
-       (_elm_config->engine == ELM_OPENGL_X11))
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+       ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+       ENGINE_COMPARE(ELM_XRENDER_X11) ||
+       ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
      {
 #ifdef HAVE_ELEMENTARY_X
-       unsigned int val = 1000;
+        unsigned int val = 1000;
 
-       if (!ecore_x_init(NULL))
-         {
-            ERR("Cannot connect to X11 display. check $DISPLAY variable");
-            exit(1);
-         }
+        if (!ecore_x_init(NULL))
+          {
+             ERR("Cannot connect to X11 display. check $DISPLAY variable");
+             exit(1);
+          }
         _root_1st = ecore_x_window_root_first_get();
-        
-       if (!ecore_x_screen_is_composited(0))
-         _elm_config->compositing = 0;
+
+        if (!ecore_x_screen_is_composited(0))
+          _elm_config->compositing = 0;
 
         ecore_x_atoms_get(_atom_names, ATOM_COUNT, _atom);
-       ecore_x_event_mask_set(_root_1st,
-                              ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
-       _prop_change_handler = ecore_event_handler_add
-         (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL);
-       if (!getenv("ELM_SCALE"))
-         {
-            if (ecore_x_window_prop_card32_get(_root_1st,
-                                               _atom[ATOM_E_SCALE],
-                                               &val, 1) > 0)
-              {
-                 if (val > 0)
-                   {
-                      _elm_config->scale = (double)val / 1000.0;
-                      // FIXME: hack until e export finger size too
-                      if (!getenv("ELM_FINGER_SIZE"))
-                        _elm_config->finger_size = 40.0 * _elm_config->scale;
+        ecore_x_event_mask_set(_root_1st,
+                               ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
+        _prop_change_handler = ecore_event_handler_add
+            (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL);
+        if (!getenv("ELM_SCALE"))
+          {
+             if (ecore_x_window_prop_card32_get(_root_1st,
+                                                _atom[ATOM_E_SCALE],
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    {
+                       _elm_config->scale = (double)val / 1000.0;
+     // FIXME: hack until e export finger size too
+                       if (!getenv("ELM_FINGER_SIZE"))
+                         {
+                            _elm_config->finger_size = 40.0 * _elm_config->scale;
+                         }
                        edje_scale_set(_elm_config->scale);
-                   }
-              }
-         }
-       if (!getenv("ELM_FINGER_SIZE"))
-         {
-            if (ecore_x_window_prop_card32_get(_root_1st,
-                                               _atom[ATOM_E_FINGER_SIZE],
-                                               &val, 1) > 0)
-              {
-                 if (val > 0)
-                   {
-                      _elm_config->finger_size = val;
-                   }
-              }
-         }
-       if (!getenv("ELM_THEME"))
-         {
+                    }
+               }
+          }
+        if (!getenv("ELM_FINGER_SIZE"))
+          {
+             if (ecore_x_window_prop_card32_get(_root_1st,
+                                                _atom[ATOM_E_FINGER_SIZE],
+                                                &val, 1) > 0)
+               {
+                  if (val > 0)
+                    {
+                       _elm_config->finger_size = val;
+                    }
+               }
+          }
+        if (!getenv("ELM_THEME"))
+          {
              char *s;
-             
+
              s = ecore_x_window_prop_string_get(_root_1st,
-                                               _atom[ATOM_E_THEME]);
+                                                _atom[ATOM_E_THEME]);
              if (s)
-              {
-                 eina_stringshare_replace(&_elm_config->theme, s);
+               {
+                  eina_stringshare_replace(&_elm_config->theme, s);
                   _elm_theme_parse(NULL, s);
                   free(s);
-              }
-         }
-       if (!getenv("ELM_PROFILE"))
-         {
+               }
+          }
+        if (!getenv("ELM_PROFILE"))
+          {
              char *s;
-             
+
              s = ecore_x_window_prop_string_get(_root_1st,
-                                               _atom[ATOM_E_PROFILE]);
+                                                _atom[ATOM_E_PROFILE]);
              if (s)
-              {
+               {
                   int changed = 0;
-                  
+
                   if (_elm_profile)
                     {
                        if (strcmp(_elm_profile, s)) changed = 1;
@@ -804,26 +1766,68 @@ _elm_config_sub_init(void)
                }
           }
 #endif
-      }
+     }
    _config_sub_apply();
 }
 
 void
+_elm_config_reload(void)
+{
+   _config_free();
+   _config_load();
+   _config_apply();
+   _elm_config_font_overlay_apply();
+   _elm_rescale();
+   _elm_recache();
+}
+
+void
+_elm_config_engine_set(const char *engine)
+{
+   if (_elm_config->engine && strcmp(_elm_config->engine, engine))
+     eina_stringshare_del(_elm_config->engine);
+
+   _elm_config->engine = eina_stringshare_add(engine);
+}
+
+void
+_elm_config_profile_set(const char *profile)
+{
+   Eina_Bool changed = EINA_FALSE;
+
+   if (_elm_profile)
+     {
+        if (strcmp(_elm_profile, profile))
+          changed = 1;
+        free(_elm_profile);
+     }
+
+   _elm_profile = strdup(profile);
+
+   if (changed)
+     {
+        _config_free();
+        _config_load();
+        _config_apply();
+        _elm_config_font_overlay_apply();
+        _elm_rescale();
+        _elm_recache();
+     }
+}
+
+void
 _elm_config_shutdown(void)
 {
-   if ((_elm_config->engine == ELM_SOFTWARE_X11) ||
-       (_elm_config->engine == ELM_SOFTWARE_16_X11) ||
-       (_elm_config->engine == ELM_XRENDER_X11) ||
-       (_elm_config->engine == ELM_OPENGL_X11) ||
-       (_elm_config->engine == ELM_SOFTWARE_SDL) ||
-       (_elm_config->engine == ELM_SOFTWARE_16_SDL) ||
-       (_elm_config->engine == ELM_OPENGL_SDL) ||
-       (_elm_config->engine == ELM_SOFTWARE_WIN32) ||
-       (_elm_config->engine == ELM_SOFTWARE_16_WINCE))
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+       ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+       ENGINE_COMPARE(ELM_XRENDER_X11) ||
+       ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
      {
 #ifdef HAVE_ELEMENTARY_X
-       ecore_event_handler_del(_prop_change_handler);
-       _prop_change_handler = NULL;
+        ecore_event_handler_del(_prop_change_handler);
+        _prop_change_handler = NULL;
 #endif
      }
    _config_free();
@@ -835,4 +1839,3 @@ _elm_config_shutdown(void)
    _desc_shutdown();
 }
 
-/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
index 63d3e63..672a6ca 100644 (file)
@@ -23,7 +23,6 @@
 \r
 #include <Elementary.h>\r
 #include "elm_priv.h"\r
-#include "els_scroller.h"\r
 \r
 #ifndef EAPI\r
 #define EAPI __attribute__ ((visibility("default")))\r
index b8f5d60..f5d0071 100644 (file)
@@ -178,7 +178,7 @@ static int _stringshare_key_value_replace(const char **srcstring, char *key, con
 static int _is_width_over(Evas_Object *obj);
 static void _ellipsis_entry_to_width(Evas_Object *obj);
 static void _reverse_ellipsis_entry(Evas_Object *obj);
-static int _textinput_control_function(void *data,void *input_data);
+static Eina_Bool *_textinput_control_function(void *data,void *input_data);
 static int _entry_length_get(Evas_Object *obj);
 
 static const char SIG_CHANGED[] = "changed";
@@ -481,7 +481,7 @@ _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *so
 }
 
 static void *
-_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source))
+_signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return NULL;
@@ -2013,7 +2013,7 @@ _ellipsis_entry_to_width(Evas_Object *obj)
    _sizing_eval(obj);
 }
 
-static int _textinput_control_function(void *data,void *input_data)
+static Eina_Bool *_textinput_control_function(void *data,void *input_data)
 {
    /* calculate character count */
    Evas_Object *entry = (Evas_Object *)data;
diff --git a/src/lib/elm_font.c b/src/lib/elm_font.c
new file mode 100644 (file)
index 0000000..844fc7b
--- /dev/null
@@ -0,0 +1,128 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+Elm_Font_Properties *
+_elm_font_properties_get(Eina_Hash **font_hash,
+                         const char *font)
+{
+   Elm_Font_Properties *efp = NULL;
+   char *s1;
+
+   s1 = strchr(font, ':');
+   if (s1)
+     {
+        char *s2, *name, *style;
+        int len;
+
+        len = s1 - font;
+        name = calloc(sizeof(char), len + 1);
+        strncpy(name, font, len);
+
+        /* get subname (should be english)  */
+        s2 = strchr(name, ',');
+        if (s2)
+          {
+             len = s2 - name;
+             name = realloc(name, sizeof(char) * len + 1);
+             memset(name, 0, sizeof(char) * len + 1);
+             strncpy(name, font, len);
+          }
+
+        if (!strncmp(s1, ELM_FONT_TOKEN_STYLE, strlen(ELM_FONT_TOKEN_STYLE)))
+          {
+             style = s1 + strlen(ELM_FONT_TOKEN_STYLE);
+
+             if (font_hash) efp = eina_hash_find(*font_hash, name);
+             if (!efp)
+               {
+                  efp = calloc(1, sizeof(Elm_Font_Properties));
+                  efp->name = eina_stringshare_add(name);
+                  if (font_hash)
+                    {
+                       if (!*font_hash)
+                         *font_hash = eina_hash_string_superfast_new(NULL);
+                       eina_hash_add(*font_hash, name, efp);
+                    }
+               }
+             s2 = strchr(style, ',');
+             if (s2)
+               {
+                  char *style_old;
+
+                  len = s2 - style;
+                  style_old = style;
+                  style = calloc(sizeof(char), len + 1);
+                  strncpy(style, style_old, len);
+                  efp->styles = eina_list_append(efp->styles,
+                                                 eina_stringshare_add(style));
+                  free(style);
+               }
+             else
+               efp->styles = eina_list_append(efp->styles,
+                                              eina_stringshare_add(style));
+          }
+        free(name);
+     }
+   else
+     {
+        if (font_hash) efp = eina_hash_find(*font_hash, font);
+        if (!efp)
+          {
+             efp = calloc(1, sizeof(Elm_Font_Properties));
+             efp->name = eina_stringshare_add(font);
+             if (font_hash)
+               {
+                  if (!*font_hash)
+                    *font_hash = eina_hash_string_superfast_new(NULL);
+                  eina_hash_add(*font_hash, font, efp);
+               }
+          }
+     }
+   return efp;
+}
+
+/* FIXME: do we really need it? */
+Eina_Hash *
+_elm_font_available_hash_add(Eina_Hash  *font_hash,
+                             const char *full_name)
+{
+   _elm_font_properties_get(&font_hash, full_name);
+   return font_hash;
+}
+
+static void
+_elm_font_properties_free(Elm_Font_Properties *efp)
+{
+   const char *str;
+
+   EINA_LIST_FREE(efp->styles, str)
+     if (str) eina_stringshare_del(str);
+
+   if (efp->name) eina_stringshare_del(efp->name);
+   free(efp);
+}
+
+static Eina_Bool
+_font_hash_free_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
+{
+   Elm_Font_Properties *efp;
+
+   efp = data;
+   _elm_font_properties_free(efp);
+   return EINA_TRUE;
+}
+
+void
+_elm_font_available_hash_del(Eina_Hash *hash)
+{
+   eina_hash_foreach(hash, _font_hash_free_cb, NULL);
+   eina_hash_free(hash);
+}
index e54cf63..1cfbe32 100644 (file)
@@ -460,7 +460,7 @@ _item_realize(Elm_Gengrid_Item *item)
        const Eina_List *l;
        const char *key;
 
-       item->labels = _elm_stringlist_get(edje_object_data_get(item->base,
+       item->labels = elm_widget_stringlist_get(edje_object_data_get(item->base,
                                                                "labels"));
        EINA_LIST_FOREACH(item->labels, l, key)
          {
@@ -479,7 +479,7 @@ _item_realize(Elm_Gengrid_Item *item)
        const Eina_List *l;
        const char *key;
 
-       item->icons = _elm_stringlist_get(edje_object_data_get(item->base,
+       item->icons = elm_widget_stringlist_get(edje_object_data_get(item->base,
                                                               "icons"));
        EINA_LIST_FOREACH(item->icons, l, key)
          {
@@ -501,7 +501,7 @@ _item_realize(Elm_Gengrid_Item *item)
        const Eina_List *l;
        const char *key;
 
-       item->states = _elm_stringlist_get(edje_object_data_get(item->base,
+       item->states = elm_widget_stringlist_get(edje_object_data_get(item->base,
                                                                "states"));
        EINA_LIST_FOREACH(item->states, l, key)
          {
@@ -556,11 +556,11 @@ _item_unrealize(Elm_Gengrid_Item *item)
    item->base = NULL;
    evas_object_del(item->spacer);
    item->spacer = NULL;
-   _elm_stringlist_free(item->labels);
+   elm_widget_stringlist_free(item->labels);
    item->labels = NULL;
-   _elm_stringlist_free(item->icons);
+   elm_widget_stringlist_free(item->icons);
    item->icons = NULL;
-   _elm_stringlist_free(item->states);
+   elm_widget_stringlist_free(item->states);
 
    EINA_LIST_FREE(item->icon_objs, icon)
      evas_object_del(icon);
index 3ed9bcb..a5b10aa 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 #define SWIPE_MOVES 12
 #define MAX_ITEMS_PER_BLOCK 32
@@ -1439,7 +1438,7 @@ _groupitem_realize(Elm_Genlist_Item *it, int calc)
         const Eina_List *l;
         const char *key;
 
-        git->labels = _elm_stringlist_get(edje_object_data_get(git->base, "labels"));
+        git->labels = elm_widget_stringlist_get(edje_object_data_get(git->base, "labels"));
         EINA_LIST_FOREACH(git->labels, l, key)
           {
              char *s = git->itc->func.label_get(git->data, git->wd->obj, l->data);
@@ -1457,7 +1456,7 @@ _groupitem_realize(Elm_Genlist_Item *it, int calc)
         const Eina_List *l;
         const char *key;
 
-        git->icons = _elm_stringlist_get(edje_object_data_get(git->base, "icons"));
+        git->icons = elm_widget_stringlist_get(edje_object_data_get(git->base, "icons"));
         EINA_LIST_FOREACH(git->icons, l, key)
           {
              Evas_Object *ic = git->itc->func.icon_get(git->data, git->wd->obj, l->data);
@@ -1477,7 +1476,7 @@ _groupitem_realize(Elm_Genlist_Item *it, int calc)
         const Eina_List *l;
         const char *key;
 
-        git->states = _elm_stringlist_get(edje_object_data_get(git->base, "states"));
+        git->states = elm_widget_stringlist_get(edje_object_data_get(git->base, "states"));
         EINA_LIST_FOREACH(git->states, l, key)
           {
              Eina_Bool on = git->itc->func.state_get(git->data, git->wd->obj, l->data);
@@ -1524,11 +1523,11 @@ _groupitem_unrealize(Elm_Genlist_GroupItem *git)
    if (!git->realized) return;
    evas_object_del(git->base);
    git->base = NULL;
-   _elm_stringlist_free(git->labels);
+   elm_widget_stringlist_free(git->labels);
    git->labels = NULL;
-   _elm_stringlist_free(git->icons);
+   elm_widget_stringlist_free(git->icons);
    git->icons = NULL;
-   _elm_stringlist_free(git->states);
+   elm_widget_stringlist_free(git->states);
 
    EINA_LIST_FREE(git->icon_objs, icon)
       evas_object_del(icon);
@@ -1651,7 +1650,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
              const Eina_List *l;
              const char *key;
 
-             it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
+             it->labels = elm_widget_stringlist_get(edje_object_data_get(it->base, "labels"));
              EINA_LIST_FOREACH(it->labels, l, key) {
                   edje_object_part_text_set(it->base, l->data, "Select all");
              }
@@ -1662,7 +1661,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
              const Eina_List *l;
              const char *key;
 
-             it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
+             it->labels = elm_widget_stringlist_get(edje_object_data_get(it->base, "labels"));
              EINA_LIST_FOREACH(it->labels, l, key)
                {
                   char *s = it->itc->func.label_get
@@ -1682,7 +1681,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
              const Eina_List *l;
              const char *key;
 
-             it->icons = _elm_stringlist_get(edje_object_data_get(it->base, "icons"));
+             it->icons = elm_widget_stringlist_get(edje_object_data_get(it->base, "icons"));
              EINA_LIST_FOREACH(it->icons, l, key)
                {
                   Evas_Object *ic = it->itc->func.icon_get
@@ -1702,7 +1701,7 @@ _item_realize(Elm_Genlist_Item *it, int in, int calc)
              const Eina_List *l;
              const char *key;
 
-             it->states = _elm_stringlist_get(edje_object_data_get(it->base, "states"));
+             it->states = elm_widget_stringlist_get(edje_object_data_get(it->base, "states"));
              EINA_LIST_FOREACH(it->states, l, key)
                {
                   Eina_Bool on = it->itc->func.state_get
@@ -1775,11 +1774,11 @@ _item_unrealize(Elm_Genlist_Item *it)
    if (it->edit_obj)
       evas_object_del(it->edit_obj);
    it->edit_obj = NULL;
-   _elm_stringlist_free(it->labels);
+   elm_widget_stringlist_free(it->labels);
    it->labels = NULL;
-   _elm_stringlist_free(it->icons);
+   elm_widget_stringlist_free(it->icons);
    it->icons = NULL;
-   _elm_stringlist_free(it->states);
+   elm_widget_stringlist_free(it->states);
 
    EINA_LIST_FREE(it->icon_objs, icon) 
       evas_object_del(icon);
@@ -5792,7 +5791,7 @@ _edit_controls_eval(Elm_Genlist_Item *it)
                   const Eina_List *l;
                   const char *key;
 
-                  it->icons = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "icons"));
+                  it->icons = elm_widget_stringlist_get(edje_object_data_get(it->edit_obj, "icons"));
                   EINA_LIST_FOREACH(it->icons, l, key)
                     {
                        Evas_Object *ic = it->itc->func.icon_get(it->data, it->wd->obj, l->data);
@@ -6476,7 +6475,7 @@ elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode)
      {
         it->renamed = EINA_TRUE;
 
-        it->labels = _elm_stringlist_get(edje_object_data_get(it->base, "labels"));
+        it->labels = elm_widget_stringlist_get(edje_object_data_get(it->base, "labels"));
         EINA_LIST_FOREACH(it->labels, list, label)
           {
              edje_object_signal_emit(it->edit_obj, "elm,state,rename,enable", "elm");
@@ -6491,7 +6490,7 @@ elm_genlist_item_rename_mode_set(Elm_Genlist_Item *it, int emode)
 
                   EINA_LIST_FREE(it->edit_icon_objs, icon)
                      evas_object_del(icon);
-                  Eina_List *rename = _elm_stringlist_get(edje_object_data_get(it->edit_obj, "rename"));
+                  Eina_List *rename = elm_widget_stringlist_get(edje_object_data_get(it->edit_obj, "rename"));
                   EINA_LIST_FOREACH(rename, l, rename_swallow_part)
                     {
                        if (label_cnt == swallow_part_cnt)
index a502204..6b2a34e 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 /**
  * @defgroup Scroller Scroller
index 2ba1c1b..f57ec9f 100644 (file)
@@ -2,11 +2,7 @@
 # include "elementary_config.h"
 #endif
 
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#include <dlfcn.h>      /* dlopen,dlclose,etc */
+#include <dlfcn.h> /* dlopen,dlclose,etc */
 
 #ifdef HAVE_CRT_EXTERNS_H
 # include <crt_externs.h>
@@ -36,7 +32,7 @@ _elm_dangerous_call_check(const char *call)
 {
    char buf[256];
    const char *eval;
-   
+
    snprintf(buf, sizeof(buf), "%i.%i.%i.%i", VMAJ, VMIN, VMIC, VREV);
    eval = getenv("ELM_NO_FINGER_WAGGLING");
    if ((eval) && (!strcmp(eval, buf)))
@@ -298,7 +294,9 @@ myapp_CFLAGS =
  *
  */
 
-static Eina_Bool _elm_signal_exit(void *data, int ev_type, void *ev);
+static Eina_Bool _elm_signal_exit(void *data,
+                                  int   ev_type,
+                                  void *ev);
 
 char *_elm_appname = NULL;
 const char *_elm_data_dir = NULL;
@@ -308,14 +306,16 @@ int _elm_log_dom = -1;
 EAPI int ELM_EVENT_POLICY_CHANGED = 0;
 
 static int _elm_init_count = 0;
-static int _elm_sub_init_count = 0;  
-static int _elm_ql_init_count = 0; 
+static int _elm_sub_init_count = 0;
+static int _elm_ql_init_count = 0;
 static int _elm_policies[ELM_POLICY_LAST];
 static Ecore_Event_Handler *_elm_exit_handler = NULL;
 static Eina_Bool quicklaunch_on = 0;
 
 static Eina_Bool
-_elm_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__)
+_elm_signal_exit(void *data  __UNUSED__,
+                 int ev_type __UNUSED__,
+                 void *ev    __UNUSED__)
 {
    elm_exit();
    return ECORE_CALLBACK_PASS_ON;
@@ -325,27 +325,7 @@ void
 _elm_rescale(void)
 {
    edje_scale_set(_elm_config->scale);
-   _elm_win_rescale();
-}
-
-static Eina_List *widtypes = NULL;
-
-void
-_elm_widtype_register(const char **ptr)
-{
-   widtypes = eina_list_append(widtypes, (void *)ptr);
-}
-
-static void
-_elm_widtype_clear(void)
-{
-   const char **ptr;
-   
-   EINA_LIST_FREE(widtypes, ptr)
-     {
-        eina_stringshare_del(*ptr);
-        *ptr = NULL;
-     }
+   _elm_win_rescale(NULL, EINA_FALSE);
 }
 
 /**
@@ -357,13 +337,14 @@ _elm_widtype_clear(void)
  * Inititalise Elementary
  *
  * @return The init counter value.
- * 
+ *
  * This call is exported only for use by the ELM_MAIN() macro. There is no
  * need to use this if you use this macro (which is highly advisable).
  * @ingroup General
  */
 EAPI int
-elm_init(int argc, char **argv)
+elm_init(int    argc,
+         char **argv)
 {
    _elm_init_count++;
    if (_elm_init_count > 1) return _elm_init_count;
@@ -375,6 +356,8 @@ elm_init(int argc, char **argv)
 /**
  * Shut down Elementary
  *
+ * @return The init counter value.
+ *
  * This should be called at the end of your application just before it ceases
  * to do any more processing. This will clean up any permanent resources your
  * application may have allocated via Elementary that would otherwise persist
@@ -385,55 +368,55 @@ EAPI int
 elm_shutdown(void)
 {
    _elm_init_count--;
-   if (_elm_init_count > 0) return _elm_init_count;   
+   if (_elm_init_count > 0) return _elm_init_count;
    elm_quicklaunch_sub_shutdown();
    elm_quicklaunch_shutdown();
    return _elm_init_count;
 }
 
 #ifdef ELM_EDBUS
-static Eina_Bool _elm_need_e_dbus = EINA_FALSE;
+static int _elm_need_e_dbus = 0;
 #endif
-EAPI void
+EAPI Eina_Bool
 elm_need_e_dbus(void)
 {
 #ifdef ELM_EDBUS
-   if (_elm_need_e_dbus) return;
-   _elm_need_e_dbus = 1;
+   if (_elm_need_e_dbus++) return EINA_TRUE;
    e_dbus_init();
    e_hal_init();
-#endif   
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+#endif
 }
 
 static void
 _elm_unneed_e_dbus(void)
 {
 #ifdef ELM_EDBUS
-   if (_elm_need_e_dbus)
-     {
-        _elm_need_e_dbus = 0;
-        e_hal_shutdown();
-        e_dbus_shutdown();
-     }
-#endif   
+   if (--_elm_need_e_dbus) return;
+
+   _elm_need_e_dbus = 0;
+   e_hal_shutdown();
+   e_dbus_shutdown();
+#endif
 }
 
 #ifdef ELM_EFREET
-static Eina_Bool _elm_need_efreet = EINA_FALSE;
+static int _elm_need_efreet = 0;
 #endif
-EAPI void
+EAPI Eina_Bool
 elm_need_efreet(void)
 {
 #ifdef ELM_EFREET
-   if (_elm_need_efreet) return;
-   _elm_need_efreet = 1;
+   if (_elm_need_efreet++) return EINA_TRUE;
    efreet_init();
    efreet_mime_init();
    efreet_trash_init();
-   /*
+    /*
      {
         Eina_List **list;
-        
+
         list = efreet_icon_extra_list_get();
         if (list)
           {
@@ -444,6 +427,9 @@ elm_need_efreet(void)
           }
      }
    */
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
 #endif
 }
 
@@ -451,35 +437,41 @@ static void
 _elm_unneed_efreet(void)
 {
 #ifdef ELM_EFREET
-   if (_elm_need_efreet)
-     {
-        _elm_need_efreet = 0;
-        efreet_trash_shutdown();
-        efreet_mime_shutdown();
-        efreet_shutdown();
-     }
-#endif   
+   if (--_elm_need_efreet) return;
+
+   _elm_need_efreet = 0;
+   efreet_trash_shutdown();
+   efreet_mime_shutdown();
+   efreet_shutdown();
+#endif
 }
 
-EAPI void  
-elm_quicklaunch_mode_set(Eina_Bool ql_on)  
-{  
-   quicklaunch_on = ql_on;  
+EAPI void
+elm_quicklaunch_mode_set(Eina_Bool ql_on)
+{
+   quicklaunch_on = ql_on;
+}
+
+EAPI Eina_Bool
+elm_quicklaunch_mode_get(void)
+{
+   return quicklaunch_on;
 }
 
 EAPI int
-elm_quicklaunch_init(int argc, char **argv)
+elm_quicklaunch_init(int    argc,
+                     char **argv)
 {
    char buf[PATH_MAX], *s;
-   
-   _elm_ql_init_count++;  
+
+   _elm_ql_init_count++;
    if (_elm_ql_init_count > 1) return _elm_ql_init_count;
    eina_init();
    _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE);
    if (!_elm_log_dom)
      {
-   EINA_LOG_ERR("could not register elementary log domain.");
-   _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
+        EINA_LOG_ERR("could not register elementary log domain.");
+        _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
      }
 
    eet_init();
@@ -487,7 +479,7 @@ elm_quicklaunch_init(int argc, char **argv)
    ecore_app_args_set(argc, (const char **)argv);
 
    memset(_elm_policies, 0, sizeof(_elm_policies));
-   if (ELM_EVENT_POLICY_CHANGED == 0)
+   if (!ELM_EVENT_POLICY_CHANGED)
      ELM_EVENT_POLICY_CHANGED = ecore_event_type_new();
 
    ecore_file_init();
@@ -498,44 +490,44 @@ elm_quicklaunch_init(int argc, char **argv)
 
    if (!_elm_data_dir)
      {
-   s = getenv("ELM_DATA_DIR");
-   _elm_data_dir = eina_stringshare_add(s);
+        s = getenv("ELM_DATA_DIR");
+        _elm_data_dir = eina_stringshare_add(s);
      }
    if (!_elm_data_dir)
      {
-   s = getenv("ELM_PREFIX");
-   if (s)
-     {
-        snprintf(buf, sizeof(buf), "%s/share/elementary", s);
-        _elm_data_dir = eina_stringshare_add(buf);
-     }
+        s = getenv("ELM_PREFIX");
+        if (s)
+          {
+             snprintf(buf, sizeof(buf), "%s/share/elementary", s);
+             _elm_data_dir = eina_stringshare_add(buf);
+          }
      }
    if (!_elm_lib_dir)
      {
-   s = getenv("ELM_LIB_DIR");
-   _elm_lib_dir = eina_stringshare_add(s);
+        s = getenv("ELM_LIB_DIR");
+        _elm_lib_dir = eina_stringshare_add(s);
      }
    if (!_elm_lib_dir)
      {
-   s = getenv("ELM_PREFIX");
-   if (s)
-     {
-        snprintf(buf, sizeof(buf), "%s/lib", s);
-        _elm_lib_dir = eina_stringshare_add(buf);
-     }
+        s = getenv("ELM_PREFIX");
+        if (s)
+          {
+             snprintf(buf, sizeof(buf), "%s/lib", s);
+             _elm_lib_dir = eina_stringshare_add(buf);
+          }
      }
 #ifdef HAVE_DLADDR
    if ((!_elm_data_dir) || (!_elm_lib_dir))
      {
-   Dl_info elementary_dl;
-   // libelementary.so/../../share/elementary/
-   if (dladdr(elm_init, &elementary_dl))
-     {
-        char *dir, *dir2;
-
-        dir = ecore_file_dir_get(elementary_dl.dli_fname);
-        if (dir)
+        Dl_info elementary_dl;
+        // libelementary.so/../../share/elementary/
+        if (dladdr(elm_init, &elementary_dl))
           {
+             char *dir, *dir2;
+
+             dir = ecore_file_dir_get(elementary_dl.dli_fname);
+             if (dir)
+               {
                   if (!_elm_lib_dir)
                     {
                        if (ecore_file_is_dir(dir))
@@ -552,14 +544,14 @@ elm_quicklaunch_init(int argc, char **argv)
                             free(dir2);
                          }
                     }
-        free(dir);
+                  free(dir);
+               }
           }
      }
-     }
 #endif
    if (!_elm_data_dir)
      _elm_data_dir = eina_stringshare_add(PACKAGE_DATA_DIR);
-  if (!_elm_data_dir)
+   if (!_elm_data_dir)
      _elm_data_dir = eina_stringshare_add("/");
    if (!_elm_lib_dir)
      _elm_lib_dir = eina_stringshare_add(PACKAGE_LIB_DIR);
@@ -571,86 +563,92 @@ elm_quicklaunch_init(int argc, char **argv)
 }
 
 EAPI int
-elm_quicklaunch_sub_init(int argc, char **argv)
-{
-   _elm_sub_init_count++;  
-   if (_elm_sub_init_count > 1) return _elm_sub_init_count;  
-   if (quicklaunch_on)  
-     {  
-#ifdef SEMI_BROKEN_QUICKLAUNCH  
-        return _elm_sub_init_count;  
-#endif  
-     }  
-   if (!quicklaunch_on)  
-     {  
-        ecore_app_args_set(argc, (const char **)argv);  
-        evas_init();  
-        edje_init();  
-        _elm_module_init();  
-        _elm_config_sub_init();  
-        if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
-            (_elm_config->engine == ELM_XRENDER_X11) ||  
-            (_elm_config->engine == ELM_OPENGL_X11))  
-          {             
-#ifdef HAVE_ELEMENTARY_X  
-            ecore_x_init(NULL);  
-#endif  
-          }  
-        ecore_evas_init(); // FIXME: check errors  
-        ecore_imf_init();  
-
-     }           
-   return _elm_sub_init_count;      
+elm_quicklaunch_sub_init(int    argc,
+                         char **argv)
+{
+   _elm_sub_init_count++;
+   if (_elm_sub_init_count > 1) return _elm_sub_init_count;
+   if (quicklaunch_on)
+     {
+#ifdef SEMI_BROKEN_QUICKLAUNCH
+        return _elm_sub_init_count;
+#endif
+     }
+   if (!quicklaunch_on)
+     {
+        ecore_app_args_set(argc, (const char **)argv);
+        evas_init();
+        edje_init();
+        _elm_module_init();
+        _elm_config_sub_init();
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+        if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+            ENGINE_COMPARE(ELM_XRENDER_X11) ||
+            ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
+          {
+#ifdef HAVE_ELEMENTARY_X
+             ecore_x_init(NULL);
+#endif
+          }
+        ecore_evas_init(); // FIXME: check errors
+        ecore_imf_init();
+     }
+   return _elm_sub_init_count;
 }
 
 EAPI int
 elm_quicklaunch_sub_shutdown(void)
 {
-   _elm_sub_init_count--;  
-   if (_elm_sub_init_count > 0) return _elm_sub_init_count;  
-   if (quicklaunch_on)  
-     {  
-#ifdef SEMI_BROKEN_QUICKLAUNCH  
-        return _elm_sub_init_count;  
-#endif  
-     }  
-   if (!quicklaunch_on)  
-     {  
-        _elm_win_shutdown();  
-        _elm_module_shutdown();  
-        ecore_imf_shutdown();  
-        ecore_evas_shutdown();  
-        if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
-            (_elm_config->engine == ELM_XRENDER_X11) ||  
-            (_elm_config->engine == ELM_OPENGL_X11))  
-          {                                                                     
+   _elm_sub_init_count--;
+   if (_elm_sub_init_count > 0) return _elm_sub_init_count;
+   if (quicklaunch_on)
+     {
+#ifdef SEMI_BROKEN_QUICKLAUNCH
+        return _elm_sub_init_count;
+#endif
+     }
+   if (!quicklaunch_on)
+     {
+        _elm_win_shutdown();
+        _elm_module_shutdown();
+        ecore_imf_shutdown();
+        ecore_evas_shutdown();
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+        if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+            ENGINE_COMPARE(ELM_XRENDER_X11) ||
+            ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
+          {
 #ifdef HAVE_ELEMENTARY_X
-             ecore_x_disconnect();  
-#endif  
-          }  
-        if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
-            (_elm_config->engine == ELM_XRENDER_X11) ||  
-            (_elm_config->engine == ELM_OPENGL_X11) ||  
-            (_elm_config->engine == ELM_SOFTWARE_SDL) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_SDL) ||  
-            (_elm_config->engine == ELM_OPENGL_SDL) ||  
-            (_elm_config->engine == ELM_SOFTWARE_WIN32) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_WINCE))  
-           evas_cserve_disconnect();  
-        edje_shutdown();  
-        evas_shutdown();  
-     }                
-   return _elm_sub_init_count;   
+             ecore_x_disconnect();
+#endif
+          }
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+        if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+            ENGINE_COMPARE(ELM_XRENDER_X11) ||
+            ENGINE_COMPARE(ELM_OPENGL_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
+            ENGINE_COMPARE(ELM_OPENGL_SDL) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_WIN32) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
+#undef ENGINE_COMPARE
+          evas_cserve_disconnect();
+        edje_shutdown();
+        evas_shutdown();
+     }
+   return _elm_sub_init_count;
 }
 
 EAPI int
 elm_quicklaunch_shutdown(void)
 {
-   _elm_ql_init_count--;  
-   if (_elm_ql_init_count > 0) return _elm_ql_init_count; 
+   _elm_ql_init_count--;
+   if (_elm_ql_init_count > 0) return _elm_ql_init_count;
    eina_stringshare_del(_elm_data_dir);
    _elm_data_dir = NULL;
    eina_stringshare_del(_elm_lib_dir);
@@ -658,9 +656,9 @@ elm_quicklaunch_shutdown(void)
 
    free(_elm_appname);
    _elm_appname = NULL;
-   
+
    _elm_config_shutdown();
-   
+
    ecore_event_handler_del(_elm_exit_handler);
    _elm_exit_handler = NULL;
 
@@ -674,12 +672,12 @@ elm_quicklaunch_shutdown(void)
 
    if ((_elm_log_dom > -1) && (_elm_log_dom != EINA_LOG_DOMAIN_GLOBAL))
      {
-   eina_log_domain_unregister(_elm_log_dom);
-   _elm_log_dom = -1;
+        eina_log_domain_unregister(_elm_log_dom);
+        _elm_log_dom = -1;
      }
 
-   _elm_widtype_clear();
-   
+   _elm_widget_type_clear();
+
    eina_shutdown();
    return _elm_ql_init_count;
 }
@@ -687,94 +685,100 @@ elm_quicklaunch_shutdown(void)
 EAPI void
 elm_quicklaunch_seed(void)
 {
-#ifndef SEMI_BROKEN_QUICKLAUNCH    
-   if (quicklaunch_on)  
-     {  
-         Evas_Object *win, *bg, *bt;  
-           
-         win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);  
-         bg = elm_bg_add(win);  
-         elm_win_resize_object_add(win, bg);  
-         evas_object_show(bg);  
-         bt = elm_button_add(win);  
-         elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");  
-         elm_win_resize_object_add(win, bt);  
-         ecore_main_loop_iterate();  
-         evas_object_del(win);  
-         ecore_main_loop_iterate();  
-         if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
-             (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
-             (_elm_config->engine == ELM_XRENDER_X11) ||  
-             (_elm_config->engine == ELM_OPENGL_X11))  
-           {  
-# ifdef HAVE_ELEMENTARY_X  
-              ecore_x_sync();  
-# endif  
-           }  
-         ecore_main_loop_iterate();  
-     }                                                                       
+#ifndef SEMI_BROKEN_QUICKLAUNCH
+   if (quicklaunch_on)
+     {
+        Evas_Object *win, *bg, *bt;
+
+        win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);
+        bg = elm_bg_add(win);
+        elm_win_resize_object_add(win, bg);
+        evas_object_show(bg);
+        bt = elm_button_add(win);
+        elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");
+        elm_win_resize_object_add(win, bt);
+        ecore_main_loop_iterate();
+        evas_object_del(win);
+        ecore_main_loop_iterate();
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+        if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+            ENGINE_COMPARE(ELM_XRENDER_X11) ||
+            ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
+          {
+# ifdef HAVE_ELEMENTARY_X
+             ecore_x_sync();
+# endif
+          }
+        ecore_main_loop_iterate();
+     }
 #endif
 }
 
 static void *qr_handle = NULL;
-static int (*qr_main) (int argc, char **argv) = NULL;
+static int (*qr_main)(int    argc,
+                      char **argv) = NULL;
 
 EAPI Eina_Bool
-elm_quicklaunch_prepare(int argc __UNUSED__, char **argv)
+elm_quicklaunch_prepare(int argc __UNUSED__,
+                        char   **argv)
 {
 #ifdef HAVE_FORK
    char *exe = elm_quicklaunch_exe_path_get(argv[0]);
    if (!exe)
      {
-   ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
-   return EINA_FALSE;
+        ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
+        return EINA_FALSE;
      }
    else
      {
-   char *exe2, *p;
-   char *exename;
-
-   exe2 = malloc(strlen(exe) + 1 + 10);
-   strcpy(exe2, exe);
-   p = strrchr(exe2, '/');
-   if (p) p++;
-   else p = exe2;
-   exename = alloca(strlen(p) + 1);
-   strcpy(exename, p);
-   *p = 0;
-   strcat(p, "../lib/");
-   strcat(p, exename);
-   strcat(p, ".so");
-   if (access(exe2, R_OK | X_OK) == 0)
-     {
-        free(exe);
-        exe = exe2;
-     }
-   else
-     free(exe2);
+        char *exe2, *p;
+        char *exename;
+
+        exe2 = malloc(strlen(exe) + 1 + 10);
+        strcpy(exe2, exe);
+        p = strrchr(exe2, '/');
+        if (p) p++;
+        else p = exe2;
+        exename = alloca(strlen(p) + 1);
+        strcpy(exename, p);
+        *p = 0;
+        strcat(p, "../lib/");
+        strcat(p, exename);
+        strcat(p, ".so");
+        if (!access(exe2, R_OK | X_OK))
+          {
+             free(exe);
+             exe = exe2;
+          }
+        else
+          free(exe2);
      }
    qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
    if (!qr_handle)
      {
         fprintf(stderr, "dlerr: %s\n", dlerror());
-   WRN("dlopen('%s') failed: %s", exe, dlerror());
-   free(exe);
-   return EINA_FALSE;
+        WRN("dlopen('%s') failed: %s", exe, dlerror());
+        free(exe);
+        return EINA_FALSE;
      }
    INF("dlopen('%s') = %p", exe, qr_handle);
-   free(exe);
    qr_main = dlsym(qr_handle, "elm_main");
    INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
    if (!qr_main)
      {
-   WRN("not quicklauncher capable: no elm_main in '%s'", exe);
-   dlclose(qr_handle);
-   qr_handle = NULL;
-   return EINA_FALSE;
+        WRN("not quicklauncher capable: no elm_main in '%s'", exe);
+        dlclose(qr_handle);
+        qr_handle = NULL;
+        free(exe);
+        return EINA_FALSE;
      }
+   free(exe);
    return EINA_TRUE;
 #else
    return EINA_FALSE;
+   (void)argv;
 #endif
 }
 
@@ -800,10 +804,15 @@ save_env(void)
      environ[i] = strdup(oldenv[i]);
    environ[i] = NULL;
 }
+
 #endif
 
 EAPI Eina_Bool
-elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), void *postfork_data)
+elm_quicklaunch_fork(int    argc,
+                     char **argv,
+                     char  *cwd,
+                     void (postfork_func) (void *data),
+                     void  *postfork_data)
 {
 #ifdef HAVE_FORK
    pid_t child;
@@ -815,9 +824,27 @@ elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (voi
    // need to accept current environment from elementary_run
    if (!qr_main)
      {
-   int i;
-   char **args;
+        int i;
+        char **args;
 
+        child = fork();
+        if (child > 0) return EINA_TRUE;
+        else if (child < 0)
+          {
+             perror("could not fork");
+             return EINA_FALSE;
+          }
+        setsid();
+        if (chdir(cwd) != 0)
+          perror("could not chdir");
+        args = alloca((argc + 1) * sizeof(char *));
+        for (i = 0; i < argc; i++) args[i] = argv[i];
+        args[argc] = NULL;
+        WRN("%s not quicklaunch capable, fallback...", argv[0]);
+        execvp(argv[0], args);
+        ERR("failed to execute '%s': %s", argv[0], strerror(errno));
+        exit(-1);
+     }
    child = fork();
    if (child > 0) return EINA_TRUE;
    else if (child < 0)
@@ -825,48 +852,32 @@ elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (voi
         perror("could not fork");
         return EINA_FALSE;
      }
-   setsid();
-   if (chdir(cwd) != 0)
-     perror("could not chdir");
-   args = alloca((argc + 1) * sizeof(char *));
-   for (i = 0; i < argc; i++) args[i] = argv[i];
-   args[argc] = NULL;
-   WRN("%s not quicklaunch capable, fallback...", argv[0]);
-   execvp(argv[0], args);
-   ERR("failed to execute '%s': %s", argv[0], strerror(errno));
-   exit(-1);
-     }
-   child = fork();
-   if (child > 0) return EINA_TRUE;
-   else if (child < 0)
+   if (postfork_func) postfork_func(postfork_data);
+
+   if (quicklaunch_on)
      {
-   perror("could not fork");
-   return EINA_FALSE;
+#ifdef SEMI_BROKEN_QUICKLAUNCH
+        ecore_app_args_set(argc, (const char **)argv);
+        evas_init();
+        edje_init();
+        _elm_config_sub_init();
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+        if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
+            ENGINE_COMPARE(ELM_XRENDER_X11) ||
+            ENGINE_COMPARE(ELM_OPENGL_X11))
+#undef ENGINE_COMPARE
+          {
+# ifdef HAVE_ELEMENTARY_X
+             ecore_x_init(NULL);
+# endif
+          }
+        ecore_evas_init(); // FIXME: check errors
+        ecore_imf_init();
+        _elm_module_init();
+#endif
      }
-   if (postfork_func) postfork_func(postfork_data);
 
-   if (quicklaunch_on)  
-     {  
-#ifdef SEMI_BROKEN_QUICKLAUNCH  
-        ecore_app_args_set(argc, (const char **)argv);  
-        evas_init();  
-        edje_init();  
-        _elm_config_sub_init();  
-        if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
-            (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
-            (_elm_config->engine == ELM_XRENDER_X11) ||  
-            (_elm_config->engine == ELM_OPENGL_X11))  
-          {  
-# ifdef HAVE_ELEMENTARY_X  
-             ecore_x_init(NULL);  
-# endif  
-         }  
-        ecore_evas_init(); // FIXME: check errors  
-        ecore_imf_init();  
-        _elm_module_init();  
-#endif  
-     }                                                      
-   
    setsid();
    if (chdir(cwd) != 0)
      perror("could not chdir");
@@ -876,12 +887,12 @@ elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (voi
    save_env();
    if (argv)
      {
-   char *lastarg, *p;
+        char *lastarg, *p;
 
-   ecore_app_args_get(&real_argc, &real_argv);
-   lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
-   for (p = real_argv[0]; p < lastarg; p++) *p = 0;
-   strcpy(real_argv[0], argv[0]);
+        ecore_app_args_get(&real_argc, &real_argv);
+        lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
+        for (p = real_argv[0]; p < lastarg; p++) *p = 0;
+        strcpy(real_argv[0], argv[0]);
      }
    ecore_app_args_set(argc, (const char **)argv);
    ret = qr_main(argc, argv);
@@ -889,6 +900,11 @@ elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (voi
    return EINA_TRUE;
 #else
    return EINA_FALSE;
+   (void)argc;
+   (void)argv;
+   (void)cwd;
+   (void)postfork_func;
+   (void)postfork_data;
 #endif
 }
 
@@ -898,15 +914,16 @@ elm_quicklaunch_cleanup(void)
 #ifdef HAVE_FORK
    if (qr_handle)
      {
-   dlclose(qr_handle);
-   qr_handle = NULL;
-   qr_main = NULL;
+        dlclose(qr_handle);
+        qr_handle = NULL;
+        qr_main = NULL;
      }
 #endif
 }
 
 EAPI int
-elm_quicklaunch_fallback(int argc, char **argv)
+elm_quicklaunch_fallback(int    argc,
+                         char **argv)
 {
    int ret;
    elm_quicklaunch_init(argc, argv);
@@ -930,37 +947,37 @@ elm_quicklaunch_exe_path_get(const char *exe)
    if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
    if (!path)
      {
-   const char *p, *pp;
-   char *buf2;
-   path = getenv("PATH");
-   buf2 = alloca(strlen(path) + 1);
-   p = path;
-   pp = p;
-   for (;;)
-     {
-        if ((*p == ':') || (*p == 0))
-          {
-        int len;
-
-        len = p - pp;
-        strncpy(buf2, pp, len);
-        buf2[len] = 0;
-        pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
-        if (*p == 0) break;
-        p++;
+        const char *p, *pp;
+        char *buf2;
+        path = getenv("PATH");
+        buf2 = alloca(strlen(path) + 1);
+        p = path;
         pp = p;
-          }
-        else
+        for (;; )
           {
-        if (*p == 0) break;
-        p++;
+             if ((*p == ':') || (!*p))
+               {
+                  int len;
+
+                  len = p - pp;
+                  strncpy(buf2, pp, len);
+                  buf2[len] = 0;
+                  pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
+                  if (!*p) break;
+                  p++;
+                  pp = p;
+               }
+             else
+               {
+                  if (!*p) break;
+                  p++;
+               }
           }
      }
-     }
    EINA_LIST_FOREACH(pathlist, l, pathitr)
      {
-   snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
-   if (access(buf, R_OK | X_OK) == 0) return strdup(buf);
+        snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
+        if (!access(buf, R_OK | X_OK)) return strdup(buf);
      }
    return NULL;
 }
@@ -992,7 +1009,6 @@ elm_exit(void)
    ecore_main_loop_quit();
 }
 
-
 /**
  * Set new policy value.
  *
@@ -1005,13 +1021,15 @@ elm_exit(void)
  *        an enumeration with the same prefix as the policy name, for
  *        example: ELM_POLICY_QUIT and Elm_Policy_Quit
  *        (ELM_POLICY_QUIT_NONE, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED).
+ * @ingroup General
  *
  * @return @c EINA_TRUE on success or @c EINA_FALSE on error (right
  *         now just invalid policy identifier, but in future policy
  *         value might be enforced).
  */
 EAPI Eina_Bool
-elm_policy_set(unsigned int policy, int value)
+elm_policy_set(unsigned int policy,
+               int          value)
 {
    Elm_Event_Policy_Changed *ev;
 
@@ -1039,6 +1057,7 @@ elm_policy_set(unsigned int policy, int value)
  * Gets the policy value set for given identifier.
  *
  * @param policy policy identifier as in Elm_Policy.
+ * @ingroup Main
  *
  * @return policy value. Will be 0 if policy identifier is invalid.
  */
@@ -1051,27 +1070,6 @@ elm_policy_get(unsigned int policy)
 }
 
 /**
- * Flush all caches & dump all data that can be to lean down to use less memory
- */
-EAPI void
-elm_all_flush(void)
-{
-   const Eina_List *l;
-   Evas_Object *obj;
-   
-   EINA_LIST_FOREACH(_elm_win_list, l, obj)
-     {
-        Evas *e = evas_object_evas_get(obj);
-        edje_file_cache_flush();
-        edje_collection_cache_flush();
-               eet_clearcache();
-        evas_image_cache_flush(e);
-        evas_font_cache_flush(e);
-        evas_render_dump(e);
-     }
-}
-
-/**
  * @defgroup Scaling Selective Widget Scaling
  * @ingroup Main
  *
@@ -1091,8 +1089,10 @@ elm_all_flush(void)
  * @ingroup Scaling
  */
 EAPI void
-elm_object_scale_set(Evas_Object *obj, double scale)
+elm_object_scale_set(Evas_Object *obj,
+                     double       scale)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_scale_set(obj, scale);
 }
 
@@ -1106,10 +1106,64 @@ elm_object_scale_set(Evas_Object *obj, double scale)
 EAPI double
 elm_object_scale_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0.0);
    return elm_widget_scale_get(obj);
 }
 
 /**
+ * Get the global scaling factor
+ *
+ * This gets the globally configured scaling factor that is applied to all
+ * objects.
+ *
+ * @return The scaling factor
+ * @ingroup Scaling
+ */
+EAPI double
+elm_scale_get(void)
+{
+   return _elm_config->scale;
+}
+
+/**
+ * Set the global scaling factor
+ *
+ * This sets the globally configured scaling factor that is applied to all
+ * objects.
+ *
+ * @param scale The scaling factor to set
+ * @ingroup Scaling
+ */
+EAPI void
+elm_scale_set(double scale)
+{
+   if (_elm_config->scale == scale) return;
+   _elm_config->scale = scale;
+   _elm_rescale();
+}
+
+/**
+ * Set the global scaling factor for all applications on the display
+ *
+ * This sets the globally configured scaling factor that is applied to all
+ * objects for all applications.
+ * @param scale The scaling factor to set
+ * @ingroup Scaling
+ */
+EAPI void
+elm_scale_all_set(double scale)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int scale_i = (unsigned int)(scale * 1000.0);
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &scale_i, 1);
+#endif
+}
+
+/**
  * @defgroup Styles Styles
  * @ingroup Main
  *
@@ -1126,8 +1180,10 @@ elm_object_scale_get(const Evas_Object *obj)
  * @ingroup Styles
  */
 EAPI void
-elm_object_style_set(Evas_Object *obj, const char *style)
+elm_object_style_set(Evas_Object *obj,
+                     const char  *style)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_style_set(obj, style);
 }
 
@@ -1145,6 +1201,7 @@ elm_object_style_set(Evas_Object *obj, const char *style)
 EAPI const char *
 elm_object_style_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
    return elm_widget_style_get(obj);
 }
 
@@ -1158,8 +1215,10 @@ elm_object_style_get(const Evas_Object *obj)
  * @ingroup Styles
  */
 EAPI void
-elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
+elm_object_disabled_set(Evas_Object *obj,
+                        Eina_Bool    disabled)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_disabled_set(obj, disabled);
 }
 
@@ -1175,257 +1234,1843 @@ elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
 EAPI Eina_Bool
 elm_object_disabled_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
    return elm_widget_disabled_get(obj);
 }
 
 /**
- * Get the global scaling factor
- *
- * This gets the globally configured scaling factor that is applied to all
- * objects.
+ * @defgroup Config Elementary Config
+ * @ingroup Main
  *
- * @return The scaling factor
- * @ingroup Scaling
+ * Elementary configuration is formed by a set options bounded to a
+ * given @ref Profile profile, like @ref Theme theme, @ref Fingers
+ * "finger size", etc. These are functions with which one syncronizes
+ * changes made to those values to the configuration storing files, de
+ * facto. You most probably don't want to use the functions in this
+ * group unlees you're writing an elementary configuration manager.
  */
-EAPI double
-elm_scale_get(void)
-{
-   return _elm_config->scale;
-}
 
 /**
- * Set the global scaling factor
+ * Save back Elementary's configuration, so that it will persist on
+ * future sessions.
  *
- * This sets the globally configured scaling factor that is applied to all
- * objects.
+ * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
+ * @ingroup Config
+ *
+ * This function will take effect -- thus, do I/O -- immediately. Use
+ * it when you want to apply all configuration changes at once. The
+ * current configuration set will get saved onto the current profile
+ * configuration file.
  *
- * @param scale The scaling factor to set
- * @ingroup Scaling
  */
-EAPI void
-elm_scale_set(double scale)
+EAPI Eina_Bool
+elm_config_save(void)
 {
-   if (_elm_config->scale == scale) return;
-   _elm_config->scale = scale;
-   _elm_rescale();
+   return _elm_config_save();
 }
 
 /**
- * Set the global scaling factor for all applications on the display
- * 
- * This sets the globally configured scaling factor that is applied to all
- * objects for all applications.
- * @param scale The scaling factor to set
- * @ingroup Scaling
+ * Reload Elementary's configuration, bounded to current selected
+ * profile.
+ *
+ * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
+ * @ingroup Config
+ *
+ * Useful when you want to force reloading of configuration values for
+ * a profile. If one removes user custom configuration directories,
+ * for example, it will force a reload with system values insted.
+ *
  */
 EAPI void
-elm_scale_all_set(double scale)
+elm_config_reload(void)
 {
-#ifdef HAVE_ELEMENTARY_X
-   static Ecore_X_Atom atom = 0;
-   unsigned int scale_i = (unsigned int)(scale * 1000.0);
-
-   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
-   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
-                                  atom, &scale_i, 1);
-#endif   
+   _elm_config_reload();
 }
 
 /**
- * @defgroup Fingers Fingers
+ * @defgroup Profile Elementary Profile
  * @ingroup Main
  *
- * Elementary is designed to be finger-friendly for touchscreens, and so in
- * addition to scaling for display resolution, it can also scale based on
- * finger "resolution" (or size).
+ * Profiles are pre-set options that affect the whole look-and-feel of
+ * Elementary-based applications. There are, for example, profiles
+ * aimed at desktop computer applications and others aimed at mobile,
+ * touchscreen-based ones. You most probably don't want to use the
+ * functions in this group unlees you're writing an elementary
+ * configuration manager.
  */
 
 /**
- * Get the configured finger size
+ * Get Elementary's profile in use.
  *
- * This gets the globally configured finger size in pixels
+ * This gets the global profile that is applied to all Elementary
+ * applications.
  *
- * @return The finger size
- * @ingroup Fingers
+ * @return The profile's name
+ * @ingroup Profile
  */
-EAPI Evas_Coord
-elm_finger_size_get(void)
+EAPI const char *
+elm_profile_current_get(void)
 {
-   return _elm_config->finger_size;
+   return _elm_config_current_profile_get();
 }
 
 /**
- * Set the configured finger size
+ * Get an Elementary's profile directory path in the filesystem. One
+ * may want to fetch a system profile's dir or an user one (fetched
+ * inside $HOME).
  *
- * This sets the globally configured finger size in pixels
+ * @param profile The profile's name
+ * @param is_user Whether to lookup for an user profile (@c EINA_TRUE)
+ *                or a system one (@c EINA_FALSE)
+ * @return The profile's directory path.
+ * @ingroup Profile
  *
- * @param size The finger size
+ * @note You must free it with elm_profile_dir_free().
+ */
+EAPI const char *
+elm_profile_dir_get(const char *profile,
+                    Eina_Bool   is_user)
+{
+   return _elm_config_profile_dir_get(profile, is_user);
+}
+
+/**
+ * Free an Elementary's profile directory path, as returned by
+ * elm_profile_dir_get().
+ *
+ * @param p_dir The profile's path
+ * @ingroup Profile
+ *
+ */
+EAPI void
+elm_profile_dir_free(const char *p_dir)
+{
+   free((void *)p_dir);
+}
+
+/**
+ * Get Elementary's list of available profiles.
+ *
+ * @return The profiles list. List node data are the profile name
+ *         strings.
+ * @ingroup Profile
+ *
+ * @note One must free this list, after usage, with the function
+ *       elm_profile_list_free().
+ */
+EAPI Eina_List *
+elm_profile_list_get(void)
+{
+   return _elm_config_profiles_list();
+}
+
+/**
+ * Free Elementary's list of available profiles.
+ *
+ * @param The profiles list, as returned by elm_profile_list_get().
+ * @ingroup Profile
+ *
+ */
+EAPI void
+elm_profile_list_free(Eina_List *l)
+{
+   const char *dir;
+
+   EINA_LIST_FREE(l, dir)
+     eina_stringshare_del(dir);
+}
+
+/**
+ * Set Elementary's profile.
+ *
+ * This sets the global profile that is applied to Elementary
+ * applications. Just the process the call comes from will be
+ * affected.
+ *
+ * @param profile The profile's name
+ * @ingroup Profile
+ *
+ */
+EAPI void
+elm_profile_set(const char *profile)
+{
+   EINA_SAFETY_ON_NULL_RETURN(profile);
+   _elm_config_profile_set(profile);
+}
+
+/**
+ * Set Elementary's profile.
+ *
+ * This sets the global profile that is applied to all Elementary
+ * applications. All running Elementary windows will be affected.
+ *
+ * @param profile The profile's name
+ * @ingroup Profile
+ *
+ */
+EAPI void
+elm_profile_all_set(const char *profile)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_PROFILE");
+   ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
+                                  atom, profile);
+#endif
+}
+
+/**
+ * @defgroup Engine Elementary Engine
+ * @ingroup Main
+ *
+ * These are functions setting and querying which rendering engine
+ * Elementary will use for drawing its windows' pixels.
+ */
+
+/**
+ * Get Elementary's rendering engine in use.
+ *
+ * This gets the global rendering engine that is applied to all
+ * Elementary applications.
+ *
+ * @return The rendering engine's name
+ * @ingroup Engine
+ *
+ * @note there's no need to free the returned string, here.
+ */
+EAPI const char *
+elm_engine_current_get(void)
+{
+   return _elm_config->engine;
+}
+
+/**
+ * Set Elementary's rendering engine for use.
+ *
+ * This gets sets global rendering engine that is applied to all
+ * Elementary applications. Note that it will take effect only to
+ * subsequent Elementary window creations.
+ *
+ * @param The rendering engine's name
+ * @ingroup Engine
+ *
+ * @note there's no need to free the returned string, here.
+ */
+EAPI void
+elm_engine_set(const char *engine)
+{
+   EINA_SAFETY_ON_NULL_RETURN(engine);
+
+   _elm_config_engine_set(engine);
+}
+
+/**
+ * @defgroup Fonts Elementary Fonts
+ * @ingroup Main
+ *
+ * These are functions dealing with font rendering, selection and the
+ * like for Elementary applications. One might fetch which system
+ * fonts are there to use and set custom fonts for individual classes
+ * of UI items containing text (text classes).
+ */
+
+/**
+ * Get Elementary's list of supported text classes.
+ *
+ * @return The text classes list, with @c Elm_Text_Class blobs as data.
+ * @ingroup Fonts
+ *
+ * Release the list with elm_text_classes_list_free().
+ */
+EAPI const Eina_List *
+elm_text_classes_list_get(void)
+{
+   return _elm_config_text_classes_get();
+}
+
+/**
+ * Free Elementary's list of supported text classes.
+ *
+ * @ingroup Fonts
+ *
+ * @see elm_text_classes_list_get().
+ */
+EAPI void
+elm_text_classes_list_free(const Eina_List *list)
+{
+   _elm_config_text_classes_free((Eina_List *)list);
+}
+
+/**
+ * Get Elementary's list of font overlays, set with
+ * elm_font_overlay_set().
+ *
+ * @return The font overlays list, with @c Elm_Font_Overlay blobs as
+ * data.
+ *
+ * @ingroup Fonts
+ *
+ * For each text class, one can set a <b>font overlay</b> for it,
+ * overriding the default font properties for that class coming from
+ * the theme in use. There is no need to free this list.
+ *
+ * @see elm_font_overlay_set() and elm_font_overlay_unset().
+ */
+EAPI const Eina_List *
+elm_font_overlay_list_get(void)
+{
+   return _elm_config_font_overlays_list();
+}
+
+/**
+ * Set a font overlay for a given Elementary text class.
+ *
+ * @param text_class Text class name
+ * @param font Font name and style string
+ * @param size Font size
+ *
+ * @ingroup Fonts
+ *
+ * @p font has to be in the format returned by
+ * elm_font_fontconfig_name_get(). @see elm_font_overlay_list_get()
+ * and @elm_font_overlay_unset().
+ */
+EAPI void
+elm_font_overlay_set(const char    *text_class,
+                     const char    *font,
+                     Evas_Font_Size size)
+{
+   _elm_config_font_overlay_set(text_class, font, size);
+}
+
+/**
+ * Unset a font overlay for a given Elementary text class.
+ *
+ * @param text_class Text class name
+ *
+ * @ingroup Fonts
+ *
+ * This will bring back text elements belonging to text class @p
+ * text_class back to their default font settings.
+ */
+EAPI void
+elm_font_overlay_unset(const char *text_class)
+{
+   _elm_config_font_overlay_remove(text_class);
+}
+
+/**
+ * Apply the changes made with elm_font_overlay_set() and
+ * elm_font_overlay_unset() on the current Elementary window.
+ *
+ * @ingroup Fonts
+ *
+ * This applies all font overlays set to all objects in the UI.
+ */
+EAPI void
+elm_font_overlay_apply(void)
+{
+   _elm_config_font_overlay_apply();
+}
+
+/**
+ * Apply the changes made with elm_font_overlay_set() and
+ * elm_font_overlay_unset() on all Elementary application windows.
+ *
+ * @ingroup Fonts
+ *
+ * This applies all font overlays set to all objects in the UI.
+ */
+EAPI void
+elm_font_overlay_all_apply(void)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int dummy = (unsigned int)(1 * 1000.0);
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_OVERLAY");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(), atom, &dummy,
+                                  1);
+#endif
+}
+
+/**
+ * Translate a font (family) name string in fontconfig's font names
+ * syntax into an @c Elm_Font_Properties struct.
+ *
+ * @param font The font name and styles string
+ * @return the font properties struct
+ *
+ * @ingroup Fonts
+ *
+ * @note The reverse translation can be achived with
+ * elm_font_fontconfig_name_get(), for one style only (single font
+ * instance, not family).
+ */
+EAPI Elm_Font_Properties *
+elm_font_properties_get(const char *font)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(font, NULL);
+   return _elm_font_properties_get(NULL, font);
+}
+
+/**
+ * Free font properties return by elm_font_properties_get().
+ *
+ * @param efp the font properties struct
+ *
+ * @ingroup Fonts
+ */
+EAPI void
+elm_font_properties_free(Elm_Font_Properties *efp)
+{
+   const char *str;
+
+   EINA_SAFETY_ON_NULL_RETURN(efp);
+   EINA_LIST_FREE(efp->styles, str)
+     if (str) eina_stringshare_del(str);
+   if (efp->name) eina_stringshare_del(efp->name);
+   free(efp);
+}
+
+/**
+ * Translate a font name, bound to a style, into fontconfig's font names
+ * syntax.
+ *
+ * @param name The font (family) name
+ * @param style The given style (may be @c NULL)
+ *
+ * @return the font name and style string
+ *
+ * @ingroup Fonts
+ *
+ * @note The reverse translation can be achived with
+ * elm_font_properties_get(), for one style only (single font
+ * instance, not family).
+ */
+EAPI const char *
+elm_font_fontconfig_name_get(const char *name,
+                             const char *style)
+{
+   char buf[256];
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
+   if (!style || style[0] == 0) return eina_stringshare_add(name);
+   snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style);
+   return eina_stringshare_add(buf);
+}
+
+/**
+ * Free the font string return by elm_font_fontconfig_name_get().
+ *
+ * @param efp the font properties struct
+ *
+ * @ingroup Fonts
+ */
+EAPI void
+elm_font_fontconfig_name_free(const char *name)
+{
+   eina_stringshare_del(name);
+}
+
+/**
+ * Create a font hash table of available system fonts.
+ *
+ * One must call it with @p list being the return value of
+ * evas_font_available_list(). The hash will be indexed by font
+ * (family) names, being its values @c Elm_Font_Properties blobs.
+ *
+ * @param list The list of available system fonts, as returned by
+ * evas_font_available_list().
+ * @return the font hash.
+ *
+ * @ingroup Fonts
+ *
+ * @note The user is supposed to get it populated at least with 3
+ * default font families (Sans, Serif, Monospace), which should be
+ * present on most systems.
+ */
+EAPI Eina_Hash *
+elm_font_available_hash_add(Eina_List *list)
+{
+   Eina_Hash *font_hash;
+   Eina_List *l;
+   void *key;
+
+   font_hash = NULL;
+
+   /* populate with default font families */
+   font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular");
+   font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold");
+   font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique");
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Sans:style=Bold Oblique");
+
+   font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular");
+   font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold");
+   font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique");
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Serif:style=Bold Oblique");
+
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Monospace:style=Regular");
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Monospace:style=Bold");
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Monospace:style=Oblique");
+   font_hash = _elm_font_available_hash_add(font_hash,
+                                            "Monospace:style=Bold Oblique");
+
+   EINA_LIST_FOREACH(list, l, key)
+     font_hash = _elm_font_available_hash_add(font_hash, key);
+
+   return font_hash;
+}
+
+/**
+ * Free the hash return by elm_font_available_hash_add().
+ *
+ * @param hash the hash to be freed.
+ *
+ * @ingroup Fonts
+ */
+EAPI void
+elm_font_available_hash_del(Eina_Hash *hash)
+{
+   _elm_font_available_hash_del(hash);
+}
+
+/**
+ * @defgroup Fingers Fingers
+ * @ingroup Main
+ *
+ * Elementary is designed to be finger-friendly for touchscreens, and so in
+ * addition to scaling for display resolution, it can also scale based on
+ * finger "resolution" (or size).
+ */
+
+/**
+ * Get the configured finger size
+ *
+ * This gets the globally configured finger size in pixels
+ *
+ * @return The finger size
+ * @ingroup Fingers
+ */
+EAPI Evas_Coord
+elm_finger_size_get(void)
+{
+   return _elm_config->finger_size;
+}
+
+/**
+ * Set the configured finger size
+ *
+ * This sets the globally configured finger size in pixels
+ *
+ * @param size The finger size
+ * @ingroup Fingers
+ */
+EAPI void
+elm_finger_size_set(Evas_Coord size)
+{
+   if (_elm_config->finger_size == size) return;
+   _elm_config->finger_size = size;
+   _elm_rescale();
+}
+
+/**
+ * Set the configured finger size for all applications on the display
+ *
+ * This sets the globally configured finger size in pixels for all applications
+ * on the display
+ *
+ * @param size The finger size
  * @ingroup Fingers
  */
 EAPI void
-elm_finger_size_set(Evas_Coord size)
+elm_finger_size_all_set(Evas_Coord size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif   
+}
+
+EAPI void
+elm_autocapitalization_allow_all_set(Eina_Bool on)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int on_i = (unsigned int)on;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOCAPITAL_ALLOW");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &on_i, 1);
+#endif
+}
+
+EAPI void
+elm_autoperiod_allow_all_set(Eina_Bool on)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int on_i = (unsigned int)on;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOPERIOD_ALLOW");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &on_i, 1);
+#endif
+}
+
+
+/**
+ * Adjust size of an element for finger usage
+ *
+ * This takes width and height sizes (in pixels) as input and a size multiple
+ * (which is how many fingers you want to place within the area), and adjusts
+ * the size tobe large enough to accommodate finger. On return the w and h
+ * sizes poiner do by these parameters will be modified.
+ *
+ * @param times_w How many fingers should fit horizontally
+ * @param w Pointer to the width size to adjust
+ * @param times_h How many fingers should fit vertically
+ * @param h Pointer to the height size to adjust
+ * @ingroup Fingers
+ */
+EAPI void
+elm_coords_finger_size_adjust(int         times_w,
+                              Evas_Coord *w,
+                              int         times_h,
+                              Evas_Coord *h)
+{
+   if ((w) && (*w < (_elm_config->finger_size * times_w)))
+     *w = _elm_config->finger_size * times_w;
+   if ((h) && (*h < (_elm_config->finger_size * times_h)))
+     *h = _elm_config->finger_size * times_h;
+}
+
+/**
+ * @defgroup Caches Caches
+ * @ingroup Main
+ *
+ * These are functions which let one fine-tune some cache values for
+ * Elementary applications, thus allowing for performance adjustments.
+ */
+
+/**
+ * Flush all caches & dump all data that can be to lean down to use
+ * less memory
+ *
+ * @ingroup Caches
+ */
+EAPI void
+elm_all_flush(void)
+{
+   const Eina_List *l;
+   Evas_Object *obj;
+
+   EINA_LIST_FOREACH(_elm_win_list, l, obj)
+     {
+        Evas *e = evas_object_evas_get(obj);
+        edje_file_cache_flush();
+        edje_collection_cache_flush();
+        eet_clearcache();
+        evas_image_cache_flush(e);
+        evas_font_cache_flush(e);
+        evas_render_dump(e);
+     }
+}
+
+/**
+ * Get the configured cache flush interval time
+ *
+ * This gets the globally configured cache flush interval time, in
+ * ticks
+ *
+ * @return The cache flush interval time
+ * @ingroup Caches
+ *
+ * @see elm_all_flush()
+ */
+EAPI int
+elm_cache_flush_interval_get(void)
+{
+   return _elm_config->cache_flush_poll_interval;
+}
+
+/**
+ * Set the configured cache flush interval time
+ *
+ * This sets the globally configured cache flush interval time, in ticks
+ *
+ * @param size The cache flush interval time
+ * @ingroup Caches
+ *
+ * @see elm_all_flush()
+ */
+EAPI void
+elm_cache_flush_interval_set(int size)
+{
+   if (_elm_config->cache_flush_poll_interval == size) return;
+   _elm_config->cache_flush_poll_interval = size;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured cache flush interval time for all applications on the
+ * display
+ *
+ * This sets the globally configured cache flush interval time -- in ticks
+ * -- for all applications on the display.
+ *
+ * @param size The cache flush interval time
+ * @ingroup Caches
+ */
+EAPI void
+elm_cache_flush_interval_all_set(int size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_INTERVAL");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif
+}
+
+/**
+ * Get the configured cache flush enabled state
+ *
+ * This gets the globally configured cache flush state - if it is enabled
+ * or not. When cache flushing is enabled, elementary will regularly
+ * (see elm_cache_flush_interval_get() ) flush caches and dump data out of
+ * memory and allow usage to re-seed caches and data in memory where it
+ * can do so. An idle application will thus minimise its memory usage as
+ * data will be freed from memory and not be re-loaded as it is idle and
+ * not rendering or doing anything graphically right now.
+ *
+ * @return The cache flush state
+ * @ingroup Caches
+ *
+ * @see elm_all_flush()
+ */
+EAPI Eina_Bool
+elm_cache_flush_enmabled_get(void)
+{
+   return _elm_config->cache_flush_enable;
+}
+
+/**
+ * Set the configured cache flush enabled state
+ *
+ * This sets the globally configured cache flush enabled state
+ *
+ * @param size The cache flush enabled state
+ * @ingroup Caches
+ *
+ * @see elm_all_flush()
+ */
+EAPI void
+elm_cache_flush_enabled_set(Eina_Bool enabled)
+{
+   enabled = !!enabled;
+   if (_elm_config->cache_flush_enable == enabled) return;
+   _elm_config->cache_flush_enable = enabled;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured cache flush enabled state for all applications on the
+ * display
+ *
+ * This sets the globally configured cache flush enabled state for all 
+ * applications on the display.
+ *
+ * @param size The cache flush enabled state
+ * @ingroup Caches
+ */
+EAPI void
+elm_cache_flush_enabled_all_set(Eina_Bool enabled)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int enabled_i = (unsigned int)enabled;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_ENABLE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &enabled_i, 1);
+#endif
+}
+
+/**
+ * Get the configured font cache size
+ *
+ * This gets the globally configured font cache size, in bytes
+ *
+ * @return The font cache size
+ * @ingroup Caches
+ */
+EAPI int
+elm_font_cache_get(void)
+{
+   return _elm_config->font_cache;
+}
+
+/**
+ * Set the configured font cache size
+ *
+ * This sets the globally configured font cache size, in bytes
+ *
+ * @param size The font cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_font_cache_set(int size)
+{
+   if (_elm_config->font_cache == size) return;
+   _elm_config->font_cache = size;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured font cache size for all applications on the
+ * display
+ *
+ * This sets the globally configured font cache size -- in bytes
+ * -- for all applications on the display.
+ *
+ * @param size The font cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_font_cache_all_set(int size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_CACHE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif
+}
+
+/**
+ * Get the configured image cache size
+ *
+ * This gets the globally configured image cache size, in bytes
+ *
+ * @return The image cache size
+ * @ingroup Caches
+ */
+EAPI int
+elm_image_cache_get(void)
+{
+   return _elm_config->image_cache;
+}
+
+/**
+ * Set the configured image cache size
+ *
+ * This sets the globally configured image cache size, in bytes
+ *
+ * @param size The image cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_image_cache_set(int size)
+{
+   if (_elm_config->image_cache == size) return;
+   _elm_config->image_cache = size;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured image cache size for all applications on the
+ * display
+ *
+ * This sets the globally configured image cache size -- in bytes
+ * -- for all applications on the display.
+ *
+ * @param size The image cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_image_cache_all_set(int size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_IMAGE_CACHE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif
+}
+
+/**
+ * Get the configured edje file cache size.
+ *
+ * This gets the globally configured edje file cache size, in number
+ * of files.
+ *
+ * @return The edje file cache size
+ * @ingroup Caches
+ */
+EAPI int
+elm_edje_file_cache_get(void)
+{
+   return _elm_config->edje_cache;
+}
+
+/**
+ * Set the configured edje file cache size
+ *
+ * This sets the globally configured edje file cache size, in number
+ * of files.
+ *
+ * @param size The edje file cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_edje_file_cache_set(int size)
+{
+   if (_elm_config->edje_cache == size) return;
+   _elm_config->edje_cache = size;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured edje file cache size for all applications on the
+ * display
+ *
+ * This sets the globally configured edje file cache size -- in number
+ * of files -- for all applications on the display.
+ *
+ * @param size The edje file cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_edje_file_cache_all_set(int size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_FILE_CACHE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif
+}
+
+/**
+ * Get the configured edje collections (groups) cache size.
+ *
+ * This gets the globally configured edje collections cache size, in
+ * number of collections.
+ *
+ * @return The edje collections cache size
+ * @ingroup Caches
+ */
+EAPI int
+elm_edje_collection_cache_get(void)
+{
+   return _elm_config->edje_collection_cache;
+}
+
+/**
+ * Set the configured edje collections (groups) cache size
+ *
+ * This sets the globally configured edje collections cache size, in
+ * number of collections.
+ *
+ * @param size The edje collections cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_edje_collection_cache_set(int size)
+{
+   if (_elm_config->edje_collection_cache == size) return;
+   _elm_config->edje_collection_cache = size;
+
+   _elm_recache();
+}
+
+/**
+ * Set the configured edje collections (groups) cache size for all
+ * applications on the display
+ *
+ * This sets the globally configured edje collections cache size -- in
+ * number of collections -- for all applications on the display.
+ *
+ * @param size The edje collections cache size
+ * @ingroup Caches
+ */
+EAPI void
+elm_edje_collection_cache_all_set(int size)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int size_i = (unsigned int)size;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_COLLECTION_CACHE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &size_i, 1);
+#endif
+}
+
+/**
+ * @defgroup Focus Focus
+ * @ingroup Main
+ *
+ * Objects have focus. This is what determines where the keyboard input goes to
+ * within the application window.
+ */
+
+/**
+ * Get the focus of the object
+ *
+ * This gets the focused property of the object.
+ *
+ * @param obj The object
+ * @return 1 if the object is focused, 0 if not.
+ * @ingroup Focus
+ */
+EAPI Eina_Bool
+elm_object_focus_get(const Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
+   return elm_widget_focus_get(obj);
+}
+
+/**
+ * Set the focus to the object
+ *
+ * This sets the focus target for keyboard input to be the object indicated.
+ *
+ * @param obj The object
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus(Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   if (elm_widget_focus_get(obj))
+     return;
+
+   elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
+}
+
+/**
+ * Remove the focus from the object
+ *
+ * This removes the focus target for keyboard input from be the object
+ * indicated.
+ *
+ * @param obj The object
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_unfocus(Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   if (!elm_widget_can_focus_get(obj)) return;
+   elm_widget_focused_object_clear(obj);
+}
+
+/**
+ * Set the ability for the object to focus
+ *
+ * This sets the ability for the object to be able to get keyboard focus or
+ * not. By default all objects are able to be focused.
+ *
+ * @param obj The object
+ * @param enable 1 if the object can be focused, 0 if not
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_allow_set(Evas_Object *obj,
+                           Eina_Bool    enable)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_can_focus_set(obj, enable);
+}
+
+/**
+ * Get the ability for the object to focus
+ *
+ * This gets the ability for the object to be able to get keyboard focus or
+ * not. By default all objects are able to be focused.
+ *
+ * @param obj The object
+ * @return 1 if the object is allowed to be focused, 0 if not.
+ * @ingroup Focus
+ */
+EAPI Eina_Bool
+elm_object_focus_allow_get(const Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
+   return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj));
+}
+
+/**
+ * Set custom focus chain.
+ *
+ * This function i set one new and overwrite any previous custom focus chain
+ * with the list of objects. The previous list will be deleted and this list
+ * will be managed. After setted, don't modity it.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container object
+ * @param objs Chain of objects to pass focus
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_custom_chain_set(Evas_Object *obj,
+                                  Eina_List   *objs)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_focus_custom_chain_set(obj, objs);
+}
+
+/**
+ * Unset custom focus chain
+ *
+ * @param obj The container object
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_custom_chain_unset(Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_focus_custom_chain_unset(obj);
+}
+
+/**
+ * Get custom focus chain
+ *
+ * @param obj The container object
+ * @ingroup Focus
+ */
+EAPI const Eina_List *
+elm_object_focus_custom_chain_get(const Evas_Object *obj)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
+   return elm_widget_focus_custom_chain_get(obj);
+}
+
+/**
+ * Append object to custom focus chain.
+ *
+ * @note If relative_child equal to NULL or not in custom chain, the object
+ * will be added in end.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container object
+ * @param child The child to be added in custom chain
+ * @param relative_child The relative object to position the child
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_custom_chain_append(Evas_Object *obj,
+                                     Evas_Object *child,
+                                     Evas_Object *relative_child)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(child);
+   elm_widget_focus_custom_chain_append(obj, child, relative_child);
+}
+
+/**
+ * Prepend object to custom focus chain.
+ *
+ * @note If relative_child equal to NULL or not in custom chain, the object
+ * will be added in begin.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container object
+ * @param child The child to be added in custom chain
+ * @param relative_child The relative object to position the child
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_custom_chain_prepend(Evas_Object *obj,
+                                      Evas_Object *child,
+                                      Evas_Object *relative_child)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(child);
+   elm_widget_focus_custom_chain_prepend(obj, child, relative_child);
+}
+
+/**
+ * Give focus to next object in object tree.
+ *
+ * Give focus to next object in focus chain of one object sub-tree.
+ * If the last object of chain already have focus, the focus will go to the
+ * first object of chain.
+ *
+ * @param obj The object root of sub-tree
+ * @param dir Direction to cycle the focus
+ *
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_cycle(Evas_Object        *obj,
+                       Elm_Focus_Direction dir)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_focus_cycle(obj, dir);
+}
+
+/**
+ * Give focus to near object in one direction.
+ *
+ * Give focus to near object in direction of one object.
+ * If none focusable object in given direction, the focus will not change.
+ *
+ * @param obj The reference object
+ * @param x Horizontal component of direction to focus
+ * @param y Vertical component of direction to focus
+ *
+ * @ingroup Focus
+ */
+EAPI void
+elm_object_focus_direction_go(Evas_Object *obj,
+                              int          x,
+                              int          y)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_focus_direction_go(obj, x, y);
+}
+
+/**
+ * Get the enable status of the focus highlight
+ *
+ * This gets whether the highlight on focused objects is enabled or not
+ * @ingroup Focus
+ */
+EAPI Eina_Bool
+elm_focus_highlight_enabled_get(void)
+{
+   return _elm_config->focus_highlight_enable;
+}
+
+/**
+ * Set the enable status of the focus highlight
+ *
+ * Set whether to show or not the highlight on focused objects
+ * @param enable Enable highlight if EINA_TRUE, disable otherwise
+ * @ingroup Focus
+ */
+EAPI void
+elm_focus_highlight_enabled_set(Eina_Bool enable)
+{
+   _elm_config->focus_highlight_enable = !!enable;
+}
+
+/**
+ * Get the enable status of the highlight animation
+ *
+ * Get whether the focus highlight, if enabled, will animate its switch from
+ * one object to the next
+ * @ingroup Focus
+ */
+EAPI Eina_Bool
+elm_focus_highlight_animate_get(void)
+{
+   return _elm_config->focus_highlight_animate;
+}
+
+/**
+ * Set the enable status of the highlight animation
+ *
+ * Set whether the focus highlight, if enabled, will animate its switch from
+ * one object to the next
+ * @param animate Enable animation if EINA_TRUE, disable otherwise
+ * @ingroup Focus
+ */
+EAPI void
+elm_focus_highlight_animate_set(Eina_Bool animate)
+{
+   _elm_config->focus_highlight_animate = !!animate;
+}
+
+/**
+ * @defgroup Scrolling Scrolling
+ * @ingroup Main
+ *
+ * These are functions setting how scrollable views in Elementary
+ * widgets should behave on user interaction.
+ */
+
+/**
+ * Get whether scrollers should bounce when they reach their
+ * viewport's edge during a scroll.
+ *
+ * @return the thumb scroll bouncing state
+ *
+ * This is the default behavior for touch screens, in general.
+ * @ingroup Scrolling
+ */
+EAPI Eina_Bool
+elm_scroll_bounce_enabled_get(void)
+{
+   return _elm_config->thumbscroll_bounce_enable;
+}
+
+/**
+ * Set whether scrollers should bounce when they reach their
+ * viewport's edge during a scroll.
+ *
+ * @param enabled the thumb scroll bouncing state
+ *
+ * @see elm_thumbscroll_bounce_enabled_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_bounce_enabled_set(Eina_Bool enabled)
+{
+   _elm_config->thumbscroll_bounce_enable = enabled;
+}
+
+/**
+ * Set whether scrollers should bounce when they reach their
+ * viewport's edge during a scroll, for all Elementary application
+ * windows.
+ *
+ * @param enabled the thumb scroll bouncing state
+ *
+ * @see elm_thumbscroll_bounce_enabled_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_bounce_enabled_all_set(Eina_Bool enabled)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int bounce_enable_i = (unsigned int)enabled;
+
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_ENABLE");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &bounce_enable_i, 1);
+#endif
+}
+
+/**
+ * Get the amount of inertia a scroller will impose at bounce
+ * animations.
+ *
+ * @return the thumb scroll bounce friction
+ *
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_bounce_friction_get(void)
+{
+   return _elm_config->thumbscroll_bounce_friction;
+}
+
+/**
+ * Set the amount of inertia a scroller will impose at bounce
+ * animations.
+ *
+ * @param friction the thumb scroll bounce friction
+ *
+ * @see elm_thumbscroll_bounce_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_bounce_friction_set(double friction)
+{
+   _elm_config->thumbscroll_bounce_friction = friction;
+}
+
+/**
+ * Set the amount of inertia a scroller will impose at bounce
+ * animations, for all Elementary application windows.
+ *
+ * @param friction the thumb scroll bounce friction
+ *
+ * @see elm_thumbscroll_bounce_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_bounce_friction_all_set(double friction)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int bounce_friction_i = (unsigned int)(friction * 1000.0);
+
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_FRICTION");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &bounce_friction_i, 1);
+#endif
+}
+
+/**
+ * Get the amount of inertia a <b>paged</b> scroller will impose at
+ * page fitting animations.
+ *
+ * @return the page scroll friction
+ *
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_page_scroll_friction_get(void)
+{
+   return _elm_config->page_scroll_friction;
+}
+
+/**
+ * Set the amount of inertia a <b>paged</b> scroller will impose at
+ * page fitting animations.
+ *
+ * @param friction the page scroll friction
+ *
+ * @see elm_thumbscroll_page_scroll_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_page_scroll_friction_set(double friction)
+{
+   _elm_config->page_scroll_friction = friction;
+}
+
+/**
+ * Set the amount of inertia a <b>paged</b> scroller will impose at
+ * page fitting animations, for all Elementary application windows.
+ *
+ * @param friction the page scroll friction
+ *
+ * @see elm_thumbscroll_page_scroll_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_page_scroll_friction_all_set(double friction)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int page_scroll_friction_i = (unsigned int)(friction * 1000.0);
+
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_PAGE_SCROLL_FRICTION");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &page_scroll_friction_i, 1);
+#endif
+}
+
+/**
+ * Get the amount of inertia a scroller will impose at region bring
+ * animations.
+ *
+ * @return the bring in scroll friction
+ *
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_bring_in_scroll_friction_get(void)
+{
+   return _elm_config->bring_in_scroll_friction;
+}
+
+/**
+ * Set the amount of inertia a scroller will impose at region bring
+ * animations.
+ *
+ * @param friction the bring in scroll friction
+ *
+ * @see elm_thumbscroll_bring_in_scroll_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_bring_in_scroll_friction_set(double friction)
 {
-   if (_elm_config->finger_size == size) return;
-   _elm_config->finger_size = size;
-   _elm_rescale();
+   _elm_config->bring_in_scroll_friction = friction;
 }
 
 /**
- * Set the configured finger size for all applications on the display
+ * Set the amount of inertia a scroller will impose at region bring
+ * animations, for all Elementary application windows.
  *
- * This sets the globally configured finger size in pixels for all applications
- * on the display
+ * @param friction the bring in scroll friction
  *
- * @param size The finger size
- * @ingroup Fingers
+ * @see elm_thumbscroll_bring_in_scroll_friction_get()
+ * @ingroup Scrolling
  */
 EAPI void
-elm_finger_size_all_set(Evas_Coord size)
+elm_scroll_bring_in_scroll_friction_all_set(double friction)
 {
 #ifdef HAVE_ELEMENTARY_X
    static Ecore_X_Atom atom = 0;
-   unsigned int size_i = (unsigned int)size;
+   unsigned int bring_in_scroll_friction_i = (unsigned int)(friction * 1000.0);
 
-   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
+   if (!atom)
+     atom =
+       ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BRING_IN_SCROLL_FRICTION");
    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
-                                  atom, &size_i, 1);
-#endif   
+                                  atom, &bring_in_scroll_friction_i, 1);
+#endif
+}
+
+/**
+ * Get the amount of inertia scrollers will impose at animations
+ * triggered by Elementary widgets' zooming API.
+ *
+ * @return the zoom friction
+ *
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_zoom_friction_get(void)
+{
+   return _elm_config->zoom_friction;
 }
 
+/**
+ * Set the amount of inertia scrollers will impose at animations
+ * triggered by Elementary widgets' zooming API.
+ *
+ * @param friction the zoom friction
+ *
+ * @see elm_thumbscroll_zoom_friction_get()
+ * @ingroup Scrolling
+ */
 EAPI void
-elm_autocapitalization_allow_all_set(Eina_Bool on)
+elm_scroll_zoom_friction_set(double friction)
+{
+   _elm_config->zoom_friction = friction;
+}
+
+/**
+ * Set the amount of inertia scrollers will impose at animations
+ * triggered by Elementary widgets' zooming API, for all Elementary
+ * application windows.
+ *
+ * @param friction the zoom friction
+ *
+ * @see elm_thumbscroll_zoom_friction_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_zoom_friction_all_set(double friction)
 {
 #ifdef HAVE_ELEMENTARY_X
    static Ecore_X_Atom atom = 0;
-   unsigned int on_i = (unsigned int)on;
+   unsigned int zoom_friction_i = (unsigned int)(friction * 1000.0);
 
-   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOCAPITAL_ALLOW");
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ZOOM_FRICTION");
    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
-                                  atom, &on_i, 1);
+                                  atom, &zoom_friction_i, 1);
 #endif
 }
 
+/**
+ * Get whether scrollers should be draggable from any point in their
+ * views.
+ *
+ * @return the thumb scroll state
+ *
+ * @note This is the default behavior for touch screens, in general.
+ * @note All other functions namespaced with "thumbscroll" will only
+ *       have effect if this mode is enabled.
+ *
+ * @ingroup Scrolling
+ */
+EAPI Eina_Bool
+elm_scroll_thumbscroll_enabled_get(void)
+{
+   return _elm_config->thumbscroll_enable;
+}
+
+/**
+ * Set whether scrollers should be draggable from any point in their
+ * views.
+ *
+ * @param enabled the thumb scroll state
+ *
+ * @see elm_thumbscroll_enabled_get()
+ * @ingroup Scrolling
+ */
 EAPI void
-elm_autoperiod_allow_all_set(Eina_Bool on)
+elm_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
+{
+   _elm_config->thumbscroll_enable = enabled;
+}
+
+/**
+ * Set whether scrollers should be draggable from any point in their
+ * views, for all Elementary application windows.
+ *
+ * @param enabled the thumb scroll state
+ *
+ * @see elm_thumbscroll_enabled_get()
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_thumbscroll_enabled_all_set(Eina_Bool enabled)
 {
 #ifdef HAVE_ELEMENTARY_X
    static Ecore_X_Atom atom = 0;
-   unsigned int on_i = (unsigned int)on;
+   unsigned int ts_enable_i = (unsigned int)enabled;
 
-   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOPERIOD_ALLOW");
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ENABLE");
    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
-                                  atom, &on_i, 1);
+                                  atom, &ts_enable_i, 1);
 #endif
 }
 
+/**
+ * Get the number of pixels one should travel while dragging a
+ * scroller's view to actually trigger scrolling.
+ *
+ * @return the thumb scroll threshould
+ *
+ * One would use higher values for touch screens, in general, because
+ * of their inherent imprecision.
+ * @ingroup Scrolling
+ */
+EAPI unsigned int
+elm_scroll_thumbscroll_threshold_get(void)
+{
+   return _elm_config->thumbscroll_threshold;
+}
 
 /**
- * Adjust size of an element for finger usage
+ * Set the number of pixels one should travel while dragging a
+ * scroller's view to actually trigger scrolling.
  *
- * This takes width and height sizes (in pixels) as input and a size multiple
- * (which is how many fingers you want to place within the area), and adjusts
- * the size tobe large enough to accomodate finger. On return the w and h
- * sizes poiner do by these parameters will be modified.
+ * @param threshold the thumb scroll threshould
  *
- * @param times_w How many fingers should fit horizontally
- * @param w Pointer to the width size to adjust
- * @param times_h How many fingers should fit vertically
- * @param h Pointer to the height size to adjust
- * @ingroup Fingers
+ * @see elm_thumbscroll_threshould_get()
+ * @ingroup Scrolling
  */
 EAPI void
-elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h)
+elm_scroll_thumbscroll_threshold_set(unsigned int threshold)
 {
-   if ((w) && (*w < (_elm_config->finger_size * times_w)))
-     *w = _elm_config->finger_size * times_w;
-   if ((h) && (*h < (_elm_config->finger_size * times_h)))
-     *h = _elm_config->finger_size * times_h;
+   _elm_config->thumbscroll_threshold = threshold;
 }
 
 /**
- * @defgroup Focus Focus
- * @ingroup Main
+ * Set the number of pixels one should travel while dragging a
+ * scroller's view to actually trigger scrolling, for all Elementary
+ * application windows.
  *
- * Objects have focus. This is what determines where the keyboard input goes to
- * within the application window.
+ * @param threshold the thumb scroll threshould
+ *
+ * @see elm_thumbscroll_threshould_get()
+ * @ingroup Scrolling
  */
+EAPI void
+elm_scroll_thumbscroll_threshold_all_set(unsigned int threshold)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int ts_threshold_i = (unsigned int)threshold;
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_THRESHOLD");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &ts_threshold_i, 1);
+#endif
+}
 
 /**
- * Get the focus of the object
+ * Get the minimum speed of mouse cursor movement which will trigger
+ * list self scrolling animation after a mouse up event
+ * (pixels/second).
  *
- * This gets the focused property of the object.
+ * @return the thumb scroll momentum threshould
  *
- * @param obj The object
- * @return 1 if the object is focused, 0 if not.
- * @ingroup Focus
+ * @ingroup Scrolling
  */
-EAPI Eina_Bool
-elm_object_focus_get(Evas_Object *obj)
+EAPI double
+elm_scroll_thumbscroll_momentum_threshold_get(void)
 {
-   return elm_widget_focus_get(obj);
+   return _elm_config->thumbscroll_momentum_threshold;
 }
 
 /**
- * Set the focus to the object
+ * Set the minimum speed of mouse cursor movement which will trigger
+ * list self scrolling animation after a mouse up event
+ * (pixels/second).
  *
- * This sets the focus target for keyboard input to be the object indicated.
+ * @param threshold the thumb scroll momentum threshould
  *
- * @param obj The object
- * @ingroup Focus
+ * @see elm_thumbscroll_momentum_threshould_get()
+ * @ingroup Scrolling
  */
 EAPI void
-elm_object_focus(Evas_Object *obj)
+elm_scroll_thumbscroll_momentum_threshold_set(double threshold)
 {
-   if (!elm_widget_can_focus_get(obj)) return;
-   elm_widget_focus_steal(obj);
+   _elm_config->thumbscroll_momentum_threshold = threshold;
 }
 
 /**
- * Remove the focus from the object
+ * Set the minimum speed of mouse cursor movement which will trigger
+ * list self scrolling animation after a mouse up event
+ * (pixels/second), for all Elementary application windows.
  *
- * This removes the focus target for keyboard input from be the object
- * indicated.
+ * @param threshold the thumb scroll momentum threshould
  *
- * @param obj The object
- * @ingroup Focus
+ * @see elm_thumbscroll_momentum_threshould_get()
+ * @ingroup Scrolling
  */
 EAPI void
-elm_object_unfocus(Evas_Object *obj)
+elm_scroll_thumbscroll_momentum_threshold_all_set(double threshold)
 {
-   if (!elm_widget_can_focus_get(obj)) return;
-   elm_widget_focused_object_clear(obj);
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int ts_momentum_threshold_i = (unsigned int)(threshold * 1000.0);
+
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_MOMENTUM_THRESHOLD");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &ts_momentum_threshold_i, 1);
+#endif
 }
 
 /**
- * Set the ability for the object to focus
+ * Get the amount of inertia a scroller will impose at self scrolling
+ * animations.
  *
- * This sets the ability for the object to be able to get keyboard focus or
- * not. By default all objects are able to be focused.
+ * @return the thumb scroll friction
  *
- * @param obj The object
- * @param enable 1 if the object can be focused, 0 if not
- * @ingroup Focus
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_thumbscroll_friction_get(void)
+{
+   return _elm_config->thumbscroll_friction;
+}
+
+/**
+ * Set the amount of inertia a scroller will impose at self scrolling
+ * animations.
+ *
+ * @param friction the thumb scroll friction
+ *
+ * @see elm_thumbscroll_friction_get()
+ * @ingroup Scrolling
  */
 EAPI void
-elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable)
+elm_scroll_thumbscroll_friction_set(double friction)
 {
-   elm_widget_can_focus_set(obj, enable);
+   _elm_config->thumbscroll_friction = friction;
 }
 
 /**
- * Get the ability for the object to focus
+ * Set the amount of inertia a scroller will impose at self scrolling
+ * animations, for all Elementary application windows.
  *
- * This gets the ability for the object to be able to get keyboard focus or
- * not. By default all objects are able to be focused.
+ * @param friction the thumb scroll friction
  *
- * @param obj The object
- * @return 1 if the object is allowed to be focused, 0 if not.
- * @ingroup Focus
+ * @see elm_thumbscroll_friction_get()
+ * @ingroup Scrolling
  */
-EAPI Eina_Bool
-elm_object_focus_allow_get(const Evas_Object *obj)
+EAPI void
+elm_scroll_thumbscroll_friction_all_set(double friction)
+{
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int ts_friction_i = (unsigned int)(friction * 1000.0);
+
+   if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_FRICTION");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &ts_friction_i, 1);
+#endif
+}
+
+/**
+ * Get the amount of lag between your actual mouse cursor dragging
+ * movement and a scroller's view movement itself, while pushing it
+ * into bounce state manually.
+ *
+ * @return the thumb scroll border friction
+ *
+ * @ingroup Scrolling
+ */
+EAPI double
+elm_scroll_thumbscroll_border_friction_get(void)
+{
+   return _elm_config->thumbscroll_border_friction;
+}
+
+/**
+ * Set the amount of lag between your actual mouse cursor dragging
+ * movement and a scroller's view movement itself, while pushing it
+ * into bounce state manually.
+ *
+ * @param friction the thumb scroll border friction. @c 0.0 for
+ *        perfect synchrony between two movements, @c 1.0 for maximum
+ *        lag.
+ *
+ * @see elm_thumbscroll_border_friction_get()
+ * @note parameter value will get bound to 0.0 - 1.0 interval, always
+ *
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_thumbscroll_border_friction_set(double friction)
+{
+   if (friction < 0.0)
+     friction = 0.0;
+
+   if (friction > 1.0)
+     friction = 1.0;
+
+   _elm_config->thumbscroll_friction = friction;
+}
+
+/**
+ * Set the amount of lag between your actual mouse cursor dragging
+ * movement and a scroller's view movement itself, while pushing it
+ * into bounce state manually, for all Elementary application windows.
+ *
+ * @param friction the thumb scroll border friction. @c 0.0 for
+ *        perfect synchrony between two movements, @c 1.0 for maximum
+ *        lag.
+ *
+ * @see elm_thumbscroll_border_friction_get()
+ * @note parameter value will get bound to 0.0 - 1.0 interval, always
+ *
+ * @ingroup Scrolling
+ */
+EAPI void
+elm_scroll_thumbscroll_border_friction_all_set(double friction)
 {
-   return elm_widget_can_focus_get(obj);
+   if (friction < 0.0)
+     friction = 0.0;
+
+   if (friction > 1.0)
+     friction = 1.0;
+
+#ifdef HAVE_ELEMENTARY_X
+   static Ecore_X_Atom atom = 0;
+   unsigned int border_friction_i = (unsigned int)(friction * 1000.0);
+
+   if (!atom)
+     atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BORDER_FRICTION");
+   ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
+                                  atom, &border_friction_i, 1);
+#endif
 }
 
 /**
@@ -1433,9 +3078,9 @@ elm_object_focus_allow_get(const Evas_Object *obj)
  * @ingroup Main
  *
  * Objects when inside a scroller can scroll, but this may not always be
- * desireable in certain situations. This allows an object to hint to itself
+ * desirable in certain situations. This allows an object to hint to itself
  * and parents to "not scroll" in one of 2 ways.
- * 
+ *
  * 1. To hold on scrolling. This means just flicking and dragging may no
  * longer scroll, but pressing/dragging near an edge of the scroller will
  * still scroll. This is automastically used by the entry object when
@@ -1455,6 +3100,7 @@ elm_object_focus_allow_get(const Evas_Object *obj)
 EAPI void
 elm_object_scroll_hold_push(Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_scroll_hold_push(obj);
 }
 
@@ -1470,6 +3116,7 @@ elm_object_scroll_hold_push(Evas_Object *obj)
 EAPI void
 elm_object_scroll_hold_pop(Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_scroll_hold_pop(obj);
 }
 
@@ -1485,6 +3132,7 @@ elm_object_scroll_hold_pop(Evas_Object *obj)
 EAPI void
 elm_object_scroll_freeze_push(Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_scroll_freeze_push(obj);
 }
 
@@ -1499,8 +3147,10 @@ elm_object_scroll_freeze_push(Evas_Object *obj)
  * @ingroup Scrollhints
  */
 EAPI void
-elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock)
+elm_object_scroll_lock_x_set(Evas_Object *obj,
+                             Eina_Bool    lock)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_drag_lock_x_set(obj, lock);
 }
 
@@ -1515,8 +3165,10 @@ elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock)
  * @ingroup Scrollhints
  */
 EAPI void
-elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock)
+elm_object_scroll_lock_y_set(Evas_Object *obj,
+                             Eina_Bool    lock)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_drag_lock_y_set(obj, lock);
 }
 
@@ -1531,6 +3183,7 @@ elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock)
 EAPI Eina_Bool
 elm_object_scroll_lock_x_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
    return elm_widget_drag_lock_x_get(obj);
 }
 
@@ -1545,6 +3198,7 @@ elm_object_scroll_lock_x_get(const Evas_Object *obj)
 EAPI Eina_Bool
 elm_object_scroll_lock_y_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
    return elm_widget_drag_lock_y_get(obj);
 }
 
@@ -1560,9 +3214,18 @@ elm_object_scroll_lock_y_get(const Evas_Object *obj)
 EAPI void
 elm_object_scroll_freeze_pop(Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_scroll_freeze_pop(obj);
 }
 
+/**
+ * @defgroup WidgetNavigation Widget Tree Navigation.
+ * @ingroup Main
+ *
+ * How to check if an Evas Object is an Elementary widget? How to get
+ * the first elementary widget that is parent of the given object?
+ * These are all covered in widget tree navigation.
+ */
 
 /**
  * Check if the given Evas Object is an Elementary widget.
@@ -1570,10 +3233,12 @@ elm_object_scroll_freeze_pop(Evas_Object *obj)
  * @param obj the object to query.
  * @return @c EINA_TRUE if it is an elementary widget variant,
  *         @c EINA_FALSE otherwise
+ * @ingroup WidgetNavigation
  */
 EAPI Eina_Bool
 elm_object_widget_check(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
    return elm_widget_is(obj);
 }
 
@@ -1583,10 +3248,12 @@ elm_object_widget_check(const Evas_Object *obj)
  * @param obj the object to query.
  * @return the parent object that is an Elementary widget, or @c NULL
  *         if no parent is, or no parents at all.
+ * @ingroup WidgetNavigation
  */
 EAPI Evas_Object *
 elm_object_parent_widget_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
    return elm_widget_parent_widget_get(obj);
 }
 
@@ -1596,10 +3263,12 @@ elm_object_parent_widget_get(const Evas_Object *obj)
  * @param obj The object to query.
  * @return The top level Elementary widget, or @c NULL if parent cannot be
  * found.
+ * @ingroup WidgetNavigation
  */
 EAPI Evas_Object *
 elm_object_top_widget_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
    return elm_widget_top_get(obj);
 }
 
@@ -1615,10 +3284,12 @@ elm_object_top_widget_get(const Evas_Object *obj)
  *
  * @param obj the object to query.
  * @return Elementary widget name, or @c NULL if not a valid widget.
+ * @ingroup WidgetNavigation
  */
 EAPI const char *
 elm_object_widget_type_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
    return elm_widget_type_get(obj);
 }
 
@@ -1634,9 +3305,13 @@ elm_object_widget_type_get(const Evas_Object *obj)
  * @param source The signal's source.
  * @ingroup General
  */
-EAPI void elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source)
+EAPI void
+elm_object_signal_emit(Evas_Object *obj,
+                       const char  *emission,
+                       const char  *source)
 {
-    elm_widget_signal_emit(obj, emission, source);
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_widget_signal_emit(obj, emission, source);
 }
 
 /**
@@ -1654,8 +3329,11 @@ EAPI void elm_object_signal_emit(Evas_Object *obj, const char *emission, const c
  * @param data A pointer to data to pass in to the callback function.
  * @ingroup General
  */
-EAPI void elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
+EAPI void 
+elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
 {
+    EINA_SAFETY_ON_NULL_RETURN(obj);
+    EINA_SAFETY_ON_NULL_RETURN(func);
     elm_widget_signal_callback_add(obj, emission, source, func, data);
 }
 
@@ -1676,12 +3354,109 @@ EAPI void elm_object_signal_callback_add(Evas_Object *obj, const char *emission,
  * @return The data pointer
  * @ingroup General
  */
-EAPI void *elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
+EAPI void *
+elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
 {
+    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
+    EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
     return elm_widget_signal_callback_del(obj, emission, source, func);
 }
 
 /**
+ * Add a callback for a event emitted by widget or their children.
+ *
+ * This function connects a callback function to any key_down key_up event
+ * emitted by the @p obj or their children.
+ * This only will be called if no other callback has consumed the event.
+ * If you want consume the event, and no other get it, func should return
+ * EINA_TRUE and put EVAS_EVENT_FLAG_ON_HOLD in event_flags.
+ *
+ * @warning Accept duplicated callback addition.
+ *
+ * @param obj The object
+ * @param func The callback function to be executed when the event is
+ * emitted.
+ * @param data Data to pass in to the callback function.
+ * @ingroup General
+ */
+EAPI void
+elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(func);
+   elm_widget_event_callback_add(obj, func, data);
+}
+
+/**
+ * Remove a event callback from an widget.
+ *
+ * This function removes a callback, previoulsy attached to event emission
+ * by the @p obj.
+ * The parameters func and data must match exactly those passed to
+ * a previous call to elm_object_event_callback_add(). The data pointer that
+ * was passed to this call will be returned.
+ *
+ * @param obj The object
+ * @param func The callback function to be executed when the event is
+ * emitted.
+ * @param data Data to pass in to the callback function.
+ * @return The data pointer
+ * @ingroup General
+ */
+EAPI void *
+elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
+   return elm_widget_event_callback_del(obj, func, data);
+}
+
+
+/**
+ * @defgroup Debug Debug
+ * @ingroup Main
+ */
+
+/**
+ * Print Tree object hierarchy in stdout
+ *
+ * @param obj The root object
+ * @ingroup Debug
+ */
+EAPI void
+elm_object_tree_dump(const Evas_Object *top)
+{
+#ifdef ELM_DEBUG
+   elm_widget_tree_dump(top);
+#else
+   return;
+   (void)top;
+#endif
+}
+
+/**
+ * Print Elm Objects tree hierarchy in file as dot(graphviz) syntax.
+ *
+ * @param obj The root object
+ * @param file The path of output file
+ * @ingroup Debug
+ */
+EAPI void
+elm_object_tree_dot_dump(const Evas_Object *top,
+                         const char        *file)
+{
+#ifdef ELM_DEBUG
+   FILE *f = fopen(file, "w");
+   elm_widget_tree_dot_dump(top, f);
+   fclose(f);
+#else
+   return;
+   (void)top;
+   (void)file;
+#endif
+}
+
+/**
  * Set the duration for occuring long press event.
  *
  * @param lonpress_timeout Timeout for long press event
index 7c177ce..ef020a1 100644 (file)
@@ -1,7 +1,6 @@
 #include <Elementary.h>
 #include "elm_priv.h"
 #include "elm_module_priv.h"
-#include "els_scroller.h"
 
 /**
  * @defgroup Map Map
index 0659044..ad78943 100644 (file)
@@ -3,7 +3,7 @@
 
 /* what are moodules in elementary for? for modularising behavior and features
  * so they can be plugged in and out where you dont want the core source to
- * alwyas behave like that or do it that way. plug it at runtime!
+ * always behave like that or do it that way. plug it at runtime!
  * 
  * they have module names (in config) and "slots" to plug that module into
  * to server a purpose. eg you plug plugin "xx" into the "entry-copy-paste"
  * creation/deletion of the entry as well as replace the longpress behavior.
  */
 
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
 #ifdef HAVE_CONFIG_H
 # include "elementary_config.h"
 #endif
@@ -49,9 +45,9 @@ void
 _elm_module_shutdown(void)
 {
    // FIXME: unload all modules
-   eina_hash_free(modules);
+   if (modules) eina_hash_free(modules);
    modules = NULL;
-   eina_hash_free(modules_as);
+   if (modules_as) eina_hash_free(modules_as);
    modules_as = NULL;
 }
 
@@ -64,7 +60,7 @@ _elm_module_parse(const char *s)
    pe = p;
    for (;;)
      {
-        if ((*pe == ':') || (*pe == 0))
+        if ((*pe == ':') || (!*pe))
           { // p -> pe == 'name:'
              if (pe > p)
                {
@@ -85,7 +81,7 @@ _elm_module_parse(const char *s)
                        free(n);
                     }
                }
-             if (*pe == 0) break;
+             if (!*pe) break;
              p = pe + 1;
              pe = p;
           }
index 1c56503..a435f64 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 /**
  * @defgroup Panel Panel
index 162da1f..37b5178 100644 (file)
 # include <Ecore_WinCE.h>
 #endif
 
-// FIXME: totally disorganised. clean this up!
-// 
-// Why EAPI in a private header ?
-// EAPI is temporaty - that widget api will change, but makign it EAPI right now to indicate its bound for externalness
+#include "els_pan.h"
+#include "els_scroller.h"
+#include "els_box.h"
+#include "els_icon.h"
+
+#include "elm_widget.h"
+
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_elm_log_dom, __VA_ARGS__)
+#define ERR(...)      EINA_LOG_DOM_ERR (_elm_log_dom, __VA_ARGS__)
+#define WRN(...)      EINA_LOG_DOM_WARN(_elm_log_dom, __VA_ARGS__)
+#define INF(...)      EINA_LOG_DOM_INFO(_elm_log_dom, __VA_ARGS__)
+#define DBG(...)      EINA_LOG_DOM_DBG (_elm_log_dom, __VA_ARGS__)
 
 typedef struct _Elm_Config    Elm_Config;
 typedef struct _Elm_Module    Elm_Module;
-typedef struct _Elm_Selection_Data Elm_Selection_Data;
-
-typedef Eina_Bool (*Elm_Drop_Cb) (void *d, Evas_Object *o, Elm_Selection_Data *data);
 
 struct _Elm_Theme
 {
-   Eina_List *overlay;
-   Eina_List *themes;
-   Eina_List *extension;
-   Eina_Hash *cache;
+   Eina_List  *overlay;
+   Eina_List  *themes;
+   Eina_List  *extension;
+   Eina_Hash  *cache;
+   Elm_Theme  *ref_theme;
+   Eina_List  *referrers;
    const char *theme;
-   int ref;
+   int         ref;
 };
 
-typedef enum _Elm_Engine
-{
-   ELM_SOFTWARE_X11,
-   ELM_SOFTWARE_FB,
-   ELM_SOFTWARE_DIRECTFB,
-   ELM_SOFTWARE_16_X11,
-   ELM_XRENDER_X11,
-   ELM_OPENGL_X11,
-   ELM_SOFTWARE_WIN32,
-   ELM_SOFTWARE_16_WINCE,
-   ELM_SOFTWARE_SDL,
-   ELM_SOFTWARE_16_SDL,
-   ELM_OPENGL_SDL
-} Elm_Engine;
-
-typedef enum _Elm_Sel_Type
-{
-   ELM_SEL_PRIMARY,
-   ELM_SEL_SECONDARY,
-   ELM_SEL_CLIPBOARD,
-   ELM_SEL_XDND,
-   
-   ELM_SEL_MAX,
-} Elm_Sel_Type;
-
-typedef enum _Elm_Sel_Format
-{
-   /** Plain unformated text: Used for things that don't want rich markup */
-   ELM_SEL_FORMAT_TEXT   = 0x01,
-   /** Edje textblock markup, including inline images */
-   ELM_SEL_FORMAT_MARKUP = 0x02,
-   /** Images */
-   ELM_SEL_FORMAT_IMAGE         = 0x04,
-   /** Vcards */
-   ELM_SEL_FORMAT_VCARD =  0x08,
-   /** Raw HTMLish things for widgets that want that stuff (hello webkit!) */
-   ELM_SEL_FORMAT_HTML = 0x10,
-} Elm_Sel_Format;
-
-struct _Elm_Selection_Data
-{
-   int                   x, y;
-   Elm_Sel_Format        format;
-   void                 *data;
-   int                   len;
-};
-
-
 /* increment this whenever we change config enough that you need new
  * defaults for elm to work.
  */
@@ -89,200 +48,166 @@ struct _Elm_Selection_Data
 /* increment this whenever a new set of config values are added but the users
  * config doesn't need to be wiped - simply new values need to be put in
  */
-#define ELM_CONFIG_FILE_GENERATION 0x0001
+#define ELM_CONFIG_FILE_GENERATION 0x0003
 #define ELM_CONFIG_VERSION         ((ELM_CONFIG_EPOCH << 16) | ELM_CONFIG_FILE_GENERATION)
-
+/* NB: profile configuration files (.src) must have their
+ * "config_version" entry's value up-to-date with ELM_CONFIG_VERSION
+ * (in decimal)!! */
+
+/* note: always remember to sync it with elm_config.c */
+extern const char *_elm_engines[];
+
+#define ELM_SOFTWARE_X11      (_elm_engines[0])
+#define ELM_SOFTWARE_FB       (_elm_engines[1])
+#define ELM_SOFTWARE_DIRECTFB (_elm_engines[2])
+#define ELM_SOFTWARE_16_X11   (_elm_engines[3])
+#define ELM_SOFTWARE_8_X11    (_elm_engines[4])
+#define ELM_XRENDER_X11       (_elm_engines[5])
+#define ELM_OPENGL_X11        (_elm_engines[6])
+#define ELM_SOFTWARE_WIN32    (_elm_engines[7])
+#define ELM_SOFTWARE_16_WINCE (_elm_engines[8])
+#define ELM_SOFTWARE_SDL      (_elm_engines[9])
+#define ELM_SOFTWARE_16_SDL   (_elm_engines[10])
+#define ELM_OPENGL_SDL        (_elm_engines[11])
+
+#define ELM_FONT_TOKEN_STYLE ":style="
 
 struct _Elm_Config
 {
-   int config_version;
-   int engine;
-   int thumbscroll_enable;
-   int thumbscroll_threshhold;
-   double thumbscroll_momentum_threshhold;
-   double thumbscroll_friction;
-   double thumbscroll_bounce_friction;
-   double page_scroll_friction;
-   double bring_in_scroll_friction;
-   double zoom_friction;
-   int thumbscroll_bounce_enable;
-   double scale;
-   int bgpixmap;
-   int compositing;
-   Eina_List *font_dirs;
-   int font_hinting;
-   int image_cache;
-   int font_cache;
-   int finger_size;
-   double fps;
-   const char *theme;
-   const char *modules;
+   int          config_version;
+   const char  *engine;
+   Eina_Bool    thumbscroll_enable;
+   int          thumbscroll_threshold;
+   double       thumbscroll_momentum_threshold;
+   double       thumbscroll_friction;
+   double       thumbscroll_bounce_friction;
+   double       page_scroll_friction;
+   double       bring_in_scroll_friction;
+   double       zoom_friction;
+   Eina_Bool    thumbscroll_bounce_enable;
+   double       thumbscroll_border_friction;
+   double       scale;
+   int          bgpixmap;
+   int          compositing;
+   Eina_List   *font_dirs;
+   Eina_List   *font_overlays;
+   int          font_hinting;
+   int          cache_flush_poll_interval;
+   Eina_Bool    cache_flush_enable;
+   int          image_cache;
+   int          font_cache;
+   int          edje_cache;
+   int          edje_collection_cache;
+   int          finger_size;
+   double       fps;
+   const char  *theme;
+   const char  *modules;
+   double       tooltip_delay;
+   Eina_Bool    cursor_engine_only;
+   Eina_Bool    focus_highlight_enable;
+   Eina_Bool    focus_highlight_animate;
+   int          toolbar_shrink_mode;
+   Eina_Bool    fileselector_expand_enable;
+   Eina_Bool    inwin_dialogs_enable;
+   int          icon_size;
+   double       longpress_timeout;
    int input_panel_enable;
    int autocapital_allow;
    int autoperiod_allow;   
    int password_show_last_character;
-   double       longpress_timeout;
 };
 
 struct _Elm_Module
 {
-   int version;
-   const char *name;
-   const char *as;
-   const char *so_path;
-   const char *data_dir;
-   const char *bin_dir;
-   void *handle;
-   void *data;
-   void *api;
-   int (*init_func) (Elm_Module *m);
-   int (*shutdown_func) (Elm_Module *m);
-   int references;
+   int          version;
+   const char  *name;
+   const char  *as;
+   const char  *so_path;
+   const char  *data_dir;
+   const char  *bin_dir;
+   void        *handle;
+   void        *data;
+   void        *api;
+   int        (*init_func) (Elm_Module *m);
+   int        (*shutdown_func) (Elm_Module *m);
+   int          references;
 };
 
 #define ELM_NEW(t) calloc(1, sizeof(t))
 
-void _elm_win_shutdown(void);
-void _elm_win_rescale(void);
+void                _elm_win_shutdown(void);
+void                _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme);
 
-int _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
-int _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);
-int _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style);
-int _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style);
-int _elm_theme_parse(Elm_Theme *th, const char *theme);
-void _elm_theme_shutdown(void);
+Eina_Bool           _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
+Eina_Bool           _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);
+Eina_Bool           _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style);
+Eina_Bool           _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style);
+Eina_Bool           _elm_theme_parse(Elm_Theme *th, const char *theme);
+void                _elm_theme_shutdown(void);
 
-void _elm_module_init(void);
-void _elm_module_shutdown(void);
-void _elm_module_parse(const char *s);
-Elm_Module *_elm_module_find_as(const char *as);
-Elm_Module *_elm_module_add(const char *name, const char *as);
-void _elm_module_del(Elm_Module *m);
-const void *_elm_module_symbol_get(Elm_Module *m, const char *name);
-    
-/* FIXME: should this be public? for now - private (but public symbols) */
-EAPI Evas_Object *elm_widget_add(Evas *evas);
-EAPI void         elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
-EAPI void         elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source));
-EAPI void         elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
-EAPI void         elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *(*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source)));
-EAPI void         elm_widget_theme(Evas_Object *obj);
-EAPI void         elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
-EAPI void         elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
-#ifdef HAVE_CONFORMANT_AUTOSCROLL
-EAPI void         elm_widget_imp_region_get_hook_set(Evas_Object *obj, Evas_Object * (*func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h), void *data);
-#endif
-EAPI void         elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
-EAPI void         elm_widget_data_set(Evas_Object *obj, void *data);
-EAPI void        *elm_widget_data_get(const Evas_Object *obj);
-EAPI void         elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj);
-EAPI void         elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj);
-EAPI void         elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj);
-EAPI void         elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj);
-EAPI void         elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source);
-EAPI void         elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data);
-EAPI void         *elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source));
-EAPI void         elm_widget_can_focus_set(Evas_Object *obj, int can_focus);
-EAPI int          elm_widget_can_focus_get(const Evas_Object *obj);
-EAPI int          elm_widget_focus_get(const Evas_Object *obj);
-EAPI Evas_Object *elm_widget_focused_object_get(const Evas_Object *obj);
-EAPI Evas_Object *elm_widget_top_get(const Evas_Object *obj);
-EAPI int          elm_widget_focus_jump(Evas_Object *obj, int forward);
-EAPI void         elm_widget_focus_set(Evas_Object *obj, int first);
-EAPI void         elm_widget_focused_object_clear(Evas_Object *obj);
-EAPI Evas_Object *elm_widget_parent_get(const Evas_Object *obj);
-EAPI void         elm_widget_focus_steal(Evas_Object *obj);
-EAPI void         elm_widget_activate(Evas_Object *obj);
-EAPI void         elm_widget_change(Evas_Object *obj);
-EAPI void         elm_widget_disabled_set(Evas_Object *obj, int disabled);
-EAPI int          elm_widget_disabled_get(const Evas_Object *obj);
-#ifdef HAVE_CONFORMANT_AUTOSCROLL
-EAPI Evas_Object *elm_widget_imp_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
-#endif
-EAPI void         elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
-EAPI void         elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
-EAPI void         elm_widget_scroll_hold_push(Evas_Object *obj);
-EAPI void         elm_widget_scroll_hold_pop(Evas_Object *obj);
-EAPI int          elm_widget_scroll_hold_get(const Evas_Object *obj);
-EAPI void         elm_widget_scroll_freeze_push(Evas_Object *obj);
-EAPI void         elm_widget_scroll_freeze_pop(Evas_Object *obj);
-EAPI int          elm_widget_scroll_freeze_get(const Evas_Object *obj);
-EAPI void         elm_widget_scale_set(Evas_Object *obj, double scale);
-EAPI double       elm_widget_scale_get(const Evas_Object *obj);
-EAPI void         elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th);
-EAPI Elm_Theme   *elm_widget_theme_get(const Evas_Object *obj);
-EAPI void         elm_widget_style_set(Evas_Object *obj, const char *style);
-EAPI const char  *elm_widget_style_get(const Evas_Object *obj);
-EAPI void         elm_widget_type_set(Evas_Object *obj, const char *type);
-EAPI const char  *elm_widget_type_get(const Evas_Object *obj);
-EAPI void         elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock);
-EAPI void         elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock);
-EAPI Eina_Bool    elm_widget_drag_lock_x_get(const Evas_Object *obj);
-EAPI Eina_Bool    elm_widget_drag_lock_y_get(const Evas_Object *obj);
-EAPI int          elm_widget_drag_child_locked_x_get(const Evas_Object *obj);
-EAPI int          elm_widget_drag_child_locked_y_get(const Evas_Object *obj);
-    
-EAPI Eina_Bool    elm_widget_is(const Evas_Object *obj);
-EAPI Evas_Object *elm_widget_parent_widget_get(const Evas_Object *obj);
+void                _elm_module_init(void);
+void                _elm_module_shutdown(void);
+void                _elm_module_parse(const char *s);
+Elm_Module         *_elm_module_find_as(const char *as);
+Elm_Module         *_elm_module_add(const char *name, const char *as);
+void                _elm_module_del(Elm_Module *m);
+const void         *_elm_module_symbol_get(Elm_Module *m, const char *name);
+
+void                _elm_widget_type_clear(void);
+void                _elm_widget_focus_region_show(const Evas_Object *obj);
+
+void               _elm_unneed_ethumb(void);
 
-EAPI Eina_List   *_elm_stringlist_get(const char *str);
-EAPI void         _elm_stringlist_free(Eina_List *list);
+void                _elm_rescale(void);
 
-Eina_Bool         _elm_widget_type_check(const Evas_Object *obj, const char *type);
+void                _elm_config_init(void);
+void                _elm_config_sub_init(void);
+void                _elm_config_shutdown(void);
+Eina_Bool           _elm_config_save(void);
+void                _elm_config_reload(void);
 
-void             _elm_unneed_ethumb(void);
+void                _elm_recache(void);
 
-void              _elm_rescale(void);
+const char         *_elm_config_current_profile_get(void);
+const char         *_elm_config_profile_dir_get(const char *prof, Eina_Bool is_user);
+Eina_List          *_elm_config_profiles_list(void);
+void                _elm_config_profile_set(const char *profile);
 
-void              _elm_config_init(void);
-void              _elm_config_sub_init(void);
-void              _elm_config_shutdown(void);
+void                _elm_config_engine_set(const char *engine);
 
-Eina_Bool            elm_selection_set(Elm_Sel_Type selection, Evas_Object *widget, Elm_Sel_Format format, const char *buf);
-Eina_Bool            elm_selection_clear(Elm_Sel_Type selection, Evas_Object *widget);
-Eina_Bool            elm_selection_get(Elm_Sel_Type selection, Elm_Sel_Format format, Evas_Object *widget, Elm_Drop_Cb datacb, void *udata);
-Eina_Bool            elm_drop_target_add(Evas_Object *widget, Elm_Sel_Type, Elm_Drop_Cb, void *);
-Eina_Bool            elm_drop_target_del(Evas_Object *widget);
-Eina_Bool            elm_drag_start(Evas_Object *, Elm_Sel_Format, const char *, void (*)(void *,Evas_Object*),void*);
+Eina_List          *_elm_config_font_overlays_list(void);
+void                _elm_config_font_overlay_set(const char *text_class, const char *font, Evas_Font_Size size);
+void                _elm_config_font_overlay_remove(const char *text_class);
+void                _elm_config_font_overlay_apply(void);
+Eina_List          *_elm_config_text_classes_get(void);
+void                _elm_config_text_classes_free(Eina_List *l);
 
-Eina_Bool         _elm_dangerous_call_check(const char *call);
+Elm_Font_Properties *_elm_font_properties_get(Eina_Hash **font_hash, const char *font);
+Eina_Hash           *_elm_font_available_hash_add(Eina_Hash *font_hash, const char *full_name);
+void                 _elm_font_available_hash_del(Eina_Hash *hash);
 
-void              _elm_widtype_register(const char **ptr);
+void                 elm_tooltip_theme(Elm_Tooltip *tt);
+void                 elm_object_sub_tooltip_content_cb_set(Evas_Object *eventarea, Evas_Object *owner, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb);
+void                 elm_cursor_theme(Elm_Cursor *cur);
+void                 elm_object_sub_cursor_set(Evas_Object *eventarea, Evas_Object *owner, const char *cursor);
 
+void                 elm_menu_clone(Evas_Object *from_menu, Evas_Object *to_menu, Elm_Menu_Item *parent);
 
+Eina_Bool           _elm_dangerous_call_check(const char *call);
+
+Evas_Object        *_elm_scroller_edje_object_get(Evas_Object *obj);
+
+char               *_elm_util_mkup_to_text(const char *mkup);
+char               *_elm_util_text_to_mkup(const char *text);
 /* do not use except clipboard history module */
 EAPI Eina_Bool    elm_cbhm_helper_init(Evas_Object *self);
 EAPI void         elm_cbhm_send_raw_data(char *cmd);
 
-#define ELM_SET_WIDTYPE(widtype, type) \
-   do { \
-      if (!widtype) { \
-         widtype = eina_stringshare_add(type); \
-         _elm_widtype_register(&widtype); \
-      } \
-   } while (0)
-
-//#define ELM_CHECK_WIDTYPE(obj, widtype) if (elm_widget_type_get(obj) != widtype) return
-#define ELM_CHECK_WIDTYPE(obj, widtype) if (!_elm_widget_type_check((obj), (widtype))) return
-
 extern char *_elm_appname;
 extern Elm_Config *_elm_config;
 extern const char *_elm_data_dir;
 extern const char *_elm_lib_dir;
 extern int _elm_log_dom;
-
 extern Eina_List *_elm_win_list;
 
-#define CRITICAL(...) EINA_LOG_DOM_CRIT(_elm_log_dom, __VA_ARGS__)
-#define ERR(...) EINA_LOG_DOM_ERR(_elm_log_dom, __VA_ARGS__)
-#define WRN(...) EINA_LOG_DOM_WARN(_elm_log_dom, __VA_ARGS__)
-#define INF(...) EINA_LOG_DOM_INFO(_elm_log_dom, __VA_ARGS__)
-#define DBG(...) EINA_LOG_DOM_DBG(_elm_log_dom, __VA_ARGS__)
-
 #endif
index c0b74cb..51120fa 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 /**
  * @defgroup Scroller Scroller
index 320a635..c74ff21 100644 (file)
@@ -68,7 +68,7 @@ _del_hook(Evas_Object *obj)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    elm_slideshow_clear(obj);
-   _elm_stringlist_free(wd->transitions);
+   elm_widget_stringlist_free(wd->transitions);
    if (wd->timer) ecore_timer_del(wd->timer);
    EINA_LIST_FREE(wd->layout.list, layout)
           eina_stringshare_del(layout);
@@ -259,11 +259,11 @@ elm_slideshow_add(Evas_Object *parent)
    elm_widget_resize_object_set(obj, wd->slideshow);
    evas_object_show(wd->slideshow);
 
-   wd->transitions = _elm_stringlist_get(edje_object_data_get(wd->slideshow, "transitions"));
+   wd->transitions = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "transitions"));
    if (eina_list_count(wd->transitions) > 0)
      wd->transition = eina_stringshare_add(eina_list_data_get(wd->transitions));
 
-   wd->layout.list = _elm_stringlist_get(edje_object_data_get(wd->slideshow, "layouts"));
+   wd->layout.list = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "layouts"));
    if (eina_list_count(wd->layout.list) > 0)
        wd->layout.current = eina_list_data_get(wd->layout.list);
 
index 308e64f..c10bd53 100644 (file)
@@ -10,8 +10,7 @@
 
 static Elm_Theme theme_default =
 {
-   NULL, NULL, NULL, NULL,
-     NULL, 1
+   NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1
 };
 
 static Eina_List *themes = NULL;
@@ -36,6 +35,13 @@ _elm_theme_clear(Elm_Theme *th)
         eina_stringshare_del(th->theme);
         th->theme = NULL;
      }
+  if (th->ref_theme)
+    {
+      th->ref_theme->referrers = 
+        eina_list_remove(th->ref_theme->referrers, th);
+      elm_theme_free(th->ref_theme);
+      th->ref_theme = NULL;
+    }
 }
 
 static const char *
@@ -63,7 +69,7 @@ _elm_theme_theme_element_try(Elm_Theme *th, const char *home, const char *f, con
 
    if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
        ((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
-       (isalpha(f[0]) && f[1] == ':'))
+       ((isalpha(f[0])) && (f[1] == ':')))
      return _elm_theme_find_try(th, f, group);
    else if (((f[0] == '~') && (f[1] == '/')))
      {
@@ -107,10 +113,11 @@ _elm_theme_group_file_find(Elm_Theme *th, const char *group)
        file = _elm_theme_theme_element_try(th, home, f, group);
        if (file) return file;
      }
+   if (th->ref_theme) return _elm_theme_group_file_find(th->ref_theme, group);
    return NULL;
 }
 
-int
+Eina_Bool
 _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style)
 {
    Elm_Theme *th = NULL;
@@ -118,7 +125,7 @@ _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, con
    return _elm_theme_set(th, o, clas, group, style);
 }
 
-int
+Eina_Bool
 _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style)
 {
    Elm_Theme *th = NULL;
@@ -126,12 +133,12 @@ _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *grou
    return _elm_theme_icon_set(th, o, group, style);
 }
 
-int
+Eina_Bool
 _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style)
 {
    const char *file;
    char buf2[1024];
-   int ok;
+   Eina_Bool ok;
 
    if (!th) th = &(theme_default);
    snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
@@ -139,16 +146,22 @@ _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *grou
    if (file)
      {
        ok = edje_object_file_set(o, file, buf2);
-       if (ok) return 1;
+       if (ok) return EINA_TRUE;
+        else
+          DBG("could not set theme group '%s' from file '%s': %s",
+              buf2, file, edje_load_error_str(edje_object_load_error_get(o)));
      }
    snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
    file = _elm_theme_group_file_find(th, buf2);
-   if (!file) return 0;
+   if (!file) return EINA_FALSE;
    ok = edje_object_file_set(o, file, buf2);
+   if (!ok)
+     DBG("could not set theme group '%s' from file '%s': %s",
+         buf2, file, edje_load_error_str(edje_object_load_error_get(o)));
    return ok;
 }
 
-int
+Eina_Bool
 _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style)
 {
    const char *file;
@@ -162,17 +175,17 @@ _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char
      {
        _els_smart_icon_file_edje_set(o, file, buf2);
        _els_smart_icon_size_get(o, &w, &h);
-       if (w > 0) return 1;
+       if (w > 0) return EINA_TRUE;
      }
    snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
    file = _elm_theme_group_file_find(th, buf2);
-   if (!file) return 0;
+   if (!file) return EINA_FALSE;
    _els_smart_icon_file_edje_set(o, file, buf2);
    _els_smart_icon_size_get(o, &w, &h);
    return (w > 0);
 }
 
-int
+Eina_Bool
 _elm_theme_parse(Elm_Theme *th, const char *theme)
 {
    Eina_List *names = NULL;
@@ -185,7 +198,7 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
         pe = p;
         for (;;)
           {
-             if ((*pe == ':') || (*pe == 0))
+             if ((*pe == ':') || (!*pe))
                { // p -> pe == 'name:'
                   if (pe > p)
                     {
@@ -193,7 +206,7 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
                        if (n)
                          {
                             const char *nn;
-                            
+
                             strncpy(n, p, pe - p);
                             n[pe - p] = 0;
                             nn = eina_stringshare_add(n);
@@ -201,7 +214,7 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
                             free(n);
                          }
                     }
-                  if (*pe == 0) break;
+                  if (!*pe) break;
                   p = pe + 1;
                   pe = p;
                }
@@ -221,7 +234,7 @@ _elm_theme_parse(Elm_Theme *th, const char *theme)
    EINA_LIST_FREE(th->themes, p) eina_stringshare_del(p);
 
    th->themes = names;
-   return 1;
+   return EINA_TRUE;
 }
 
 void
@@ -270,6 +283,7 @@ elm_theme_new(void)
 EAPI void
 elm_theme_free(Elm_Theme *th)
 {
+   EINA_SAFETY_ON_NULL_RETURN(th);
    th->ref--;
    if (th->ref < 1)
      {
@@ -280,6 +294,109 @@ elm_theme_free(Elm_Theme *th)
 }
 
 /**
+ * Copy the theme fom the source to the destination theme
+ * 
+ * @param th The source theme to copy from
+ * @param thdst The destination theme to copy data to
+ * 
+ * This makes a one-time static copy of all the theme config, extensions
+ * and overlays from @p th to @p thdst. If @p th references a theme, then
+ * @p thdst is also set to reference it, with all the theme settings,
+ * overlays and extensions that @p th had.
+ */
+EAPI void
+elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst)
+{
+   const Eina_List *l;
+   const char *f;
+   
+   if (!th) th = &(theme_default);
+   if (!thdst) thdst = &(theme_default);
+   _elm_theme_clear(thdst);
+   if (th->ref_theme)
+     {
+       thdst->ref_theme = th->ref_theme;
+       thdst->ref_theme->referrers = 
+         eina_list_append(thdst->ref_theme->referrers, thdst);
+       thdst->ref_theme->ref++;
+     }
+   EINA_LIST_FOREACH(th->overlay, l, f)
+     {
+       const char *s = eina_stringshare_add(f);
+       if (s) thdst->overlay = eina_list_append(thdst->overlay, s);
+     }
+   EINA_LIST_FOREACH(th->themes, l, f)
+     {
+       const char *s = eina_stringshare_add(f);
+       if (s) thdst->themes = eina_list_append(thdst->themes, s);
+     }
+   EINA_LIST_FOREACH(th->extension, l, f)
+     {
+       const char *s = eina_stringshare_add(f);
+       if (s) thdst->extension = eina_list_append(thdst->extension, s);
+     }
+   if (th->theme) thdst->theme = eina_stringshare_add(th->theme);
+   elm_theme_flush(thdst);
+}
+
+/**
+ * Tell the source theme to reference the ref theme
+ * 
+ * @param th The theme that will do the referencing
+ * @param thref The theme that is the reference source
+ * 
+ * This clears @p th to be empty and then sets it to refer to @p thref
+ * so @p th acts as an override to @p thdst, but where its overrides
+ * don't apply, it will fall through to @pthref for configuration.
+ */
+EAPI void
+elm_theme_ref_set(Elm_Theme *th, Elm_Theme *thref)
+{
+   if (!th) th = &(theme_default);
+   if (!thref) thref = &(theme_default);
+   if (th->ref_theme == thref) return;
+   _elm_theme_clear(th);
+   if (thref)
+     {
+       thref->referrers = eina_list_append(thref->referrers, th);
+       thref->ref++;
+     }
+   th->ref_theme = thref;
+   elm_theme_flush(th);
+}
+
+/**
+ * Return the theme referred to
+ * 
+ * @param th The theme to get the reference from
+ * @return The referenced theme handle
+ * 
+ * This gets the theme set as the reference theme by elm_theme_ref_set().
+ * If no theme is set as a reference, NULL is returned.
+ */
+EAPI Elm_Theme *
+elm_theme_ref_get(Elm_Theme *th)
+{
+   if (!th) th = &(theme_default);
+   return th->ref_theme;
+}
+
+/**
+ * Return the default theme
+ * 
+ * @return The default theme handle
+ * 
+ * This returns the internal default theme setup handle that all widgets
+ * use implicitly unless a specific theme is set. This is also often use
+ * as a shorthand of NULL.
+ */
+EAPI Elm_Theme *
+elm_theme_default_get(void)
+{
+   return &theme_default;
+}
+
+/**
  * Prepends a theme overlay to the list of overlays
  *
  * @param th The theme to add to, or if NULL, the default theme
@@ -441,7 +558,7 @@ elm_theme_get(Elm_Theme *th)
         const char *f;
         char *tmp;
         int len;
-        
+
         len = 0;
         EINA_LIST_FOREACH(th->themes, l, f)
           {
@@ -461,6 +578,90 @@ elm_theme_get(Elm_Theme *th)
 }
 
 /**
+ * Return a list of theme elements to be used in a theme.
+ * 
+ * @param th Theme to get the list of theme elements from.
+ * @return The internal list of theme elements
+ * 
+ * This returns the internal list of theme elements (will only be valid as
+ * long as the theme is not modified by elm_theme_set() or theme is not
+ * freed by elm_theme_free(). This is a list of strings which must not be
+ * altered as they are also internal. If @p th is NULL, then the default
+ * theme element list is returned.
+ */
+EAPI const Eina_List *
+elm_theme_list_get(const Elm_Theme *th)
+{
+   if (!th) th = &(theme_default);
+   return th->themes;
+}
+
+/**
+ * Return the full patrh for a theme element
+ * 
+ * @param f The theme element name
+ * @param in_search_path Pointer to a boolean to indicate if item is in the search path or not
+ * @return The full path to the file found.
+ * 
+ * This returns a string you should free with free() on success, NULL on
+ * failure. This will search for the given theme element, and if it is a
+ * full or relative path element or a simple searchable name. The returned
+ * path is the full path to the file, if searched, and the file exists, or it
+ * is simply the full path given in the element or a resolved path if
+ * relative to home. The @p in_search_path boolean pointed to is set to
+ * EINA_TRUE if the file was a searchable file andis in the search path,
+ * and EINA_FALSE otherwise.
+ */
+EAPI char *
+elm_theme_list_item_path_get(const char *f, Eina_Bool *in_search_path)
+{
+   static const char *home = NULL;
+   char buf[PATH_MAX];
+   
+   if (!f)
+     {
+        if (in_search_path) *in_search_path = EINA_FALSE;
+        return NULL;
+     }
+   
+   if (!home)
+     {
+       home = getenv("HOME");
+       if (!home) home = "";
+     }
+   
+   if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
+       ((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
+       ((isalpha(f[0])) && (f[1] == ':')))
+     {
+        if (in_search_path) *in_search_path = EINA_FALSE;
+        return strdup(f);
+     }
+   else if (((f[0] == '~') && (f[1] == '/')))
+     {
+        if (in_search_path) *in_search_path = EINA_FALSE;
+       snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
+        return strdup(buf);
+     }
+   snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, f);
+   if (ecore_file_exists(buf))
+     {
+        if (in_search_path) *in_search_path = EINA_TRUE;
+        return strdup(buf);
+     }
+   
+   snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
+   if (ecore_file_exists(buf))
+     {
+        if (in_search_path) *in_search_path = EINA_TRUE;
+        return strdup(buf);
+     }
+   
+   if (in_search_path) *in_search_path = EINA_FALSE;
+   return NULL;
+}
+
+/**
  * Flush the current theme.
  * 
  * @param th Theme to flush
@@ -478,11 +679,18 @@ elm_theme_flush(Elm_Theme *th)
    if (!th) th = &(theme_default);
    if (th->cache) eina_hash_free(th->cache);
    th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
-   _elm_win_rescale();
+   _elm_win_rescale(th, EINA_TRUE);
+   if (th->referrers)
+     {
+        Eina_List *l;
+        Elm_Theme *th2;
+
+        EINA_LIST_FOREACH(th->referrers, l, th2) elm_theme_flush(th2);
+     }
 }
 
 /**
- * This flushes all themems (default and specific ones).
+ * This flushes all themes (default and specific ones).
  * 
  * This will flush all themes in the current application context, by calling
  * elm_theme_flush() on each of them.
@@ -524,6 +732,97 @@ elm_theme_all_set(const char *theme)
 }
 
 /**
+ * Return a list of theme elements in the theme search path
+ * 
+ * @return A list of strings that are the theme element names.
+ * 
+ * This lists all available theme files in the standard Elementary search path
+ * for theme elements, and returns them in alphabetical order as theme
+ * element names in a list of strings. Free this with 
+ * elm_theme_name_available_list_free() when you are done with the list.
+ */
+EAPI Eina_List *
+elm_theme_name_available_list_new(void)
+{
+   Eina_List *list = NULL;
+   Eina_List *dir, *l;
+   char buf[PATH_MAX], *file, *s, *th;
+   static const char *home = NULL;
+   
+   if (!home)
+     {
+        home = getenv("HOME");
+        if (!home) home = "";
+     }
+   
+   snprintf(buf, sizeof(buf), "%s/.elementary/themes", home);
+   dir = ecore_file_ls(buf);
+   EINA_LIST_FREE(dir, file)
+     {
+        snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s", home, file);
+        if ((!ecore_file_is_dir(buf)) && (ecore_file_size(buf) > 0))
+          {
+             s = strchr(file, '.');
+             if ((s) && (!strcasecmp(s, ".edj")))
+               {
+                  th = strdup(file);
+                  s = strchr(th, '.');
+                  *s = 0;
+                  list = eina_list_append(list, th);
+               }
+          }
+        free(file);
+     }
+
+   snprintf(buf, sizeof(buf), "%s/themes", _elm_data_dir);
+   dir = ecore_file_ls(buf);
+   EINA_LIST_FREE(dir, file)
+     {
+        snprintf(buf, sizeof(buf), "%s/themes/%s", _elm_data_dir, file);
+        if ((!ecore_file_is_dir(buf)) && (ecore_file_size(buf) > 0))
+          {
+             s = strchr(file, '.');
+             if ((s) && (!strcasecmp(s, ".edj")))
+               {
+                  int dup;
+                  
+                  th = strdup(file);
+                  s = strchr(th, '.');
+                  *s = 0;
+                  dup = 0;
+                  EINA_LIST_FOREACH(list, l, s)
+                    {
+                       if (!strcmp(s, th))
+                         {
+                            dup = 1;
+                            break;
+                         }
+                    }
+                  if (dup) free(th);
+                  else list = eina_list_append(list, th);
+               }
+          }
+        free(file);
+     }
+   list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcasecmp));
+   return list;
+}
+
+/**
+ * Free the list returned by elm_theme_name_available_list_new()
+ * 
+ * This frees the list of themes returned by 
+ * elm_theme_name_available_list_new(). Once freed the list should no longer
+ * be used. a new list mys be created.
+ */
+EAPI void
+elm_theme_name_available_list_free(Eina_List *list)
+{
+   char *s;
+   EINA_LIST_FREE(list, s) free(s);
+}
+
+/**
  * Set a specific theme to be used for this object and its children
  * 
  * @param obj The object to set the theme on
@@ -543,6 +842,7 @@ elm_theme_all_set(const char *theme)
 EAPI void
 elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
 {
+   EINA_SAFETY_ON_NULL_RETURN(obj);
    elm_widget_theme_set(obj, th);
 }
 
@@ -560,7 +860,8 @@ elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
  * @ingroup Theme
  */
 EAPI Elm_Theme *
-elm_object_theme_get(Evas_Object *obj)
+elm_object_theme_get(const Evas_Object *obj)
 {
+   EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
    return elm_widget_theme_get(obj);
 }
index e9687e8..cabef97 100644 (file)
@@ -383,7 +383,7 @@ _elm_thumb_dropcb(void *data __UNUSED__, Evas_Object *o, Elm_Selection_Data *dro
  *
  * @ingroup Thumb
  */
-EAPI void
+EAPI Eina_Bool
 elm_need_ethumb(void)
 {
 #ifdef ELM_ETHUMB
index 90afe12..842ac8e 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 
 /**
  * @defgroup Toolbar Toolbar
index ba3fb11..48393b5 100644 (file)
@@ -11,6 +11,8 @@ static const char SMART_NAME[] = "elm_widget";
    if (!sd) return;
 
 typedef struct _Smart_Data Smart_Data;
+typedef struct _Edje_Signal_Data Edje_Signal_Data;
+typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
 
 struct _Smart_Data
 {
@@ -21,29 +23,35 @@ struct _Smart_Data
    Eina_List     *subobjs;
    Evas_Object   *resize_obj;
    Evas_Object   *hover_obj;
+   Eina_List     *tooltips, *cursors;
    void         (*del_func) (Evas_Object *obj);
    void         (*del_pre_func) (Evas_Object *obj);
    void         (*focus_func) (Evas_Object *obj);
    void         (*activate_func) (Evas_Object *obj);
    void         (*disable_func) (Evas_Object *obj);
    void         (*theme_func) (Evas_Object *obj);
+   Eina_Bool    (*event_func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info);
    void         (*signal_func) (Evas_Object *obj, const char *emission,
                                const char *source);
    void         (*callback_add_func) (Evas_Object *obj, const char *emission,
                                const char *source, void (*func) (void *data,
                                   Evas_Object *o, const char *emission,
                                   const char *source), void *data);
-   void         *(*callback_del_func) (Evas_Object *obj, const char *emission,
+   void         (*callback_del_func) (Evas_Object *obj, const char *emission,
                                  const char *source, void (*func) (void *data,
                                     Evas_Object *o, const char *emission,
-                                    const char *source));
+                                    const char *source), void *data);
    void         (*changed_func) (Evas_Object *obj);
+   Eina_Bool    (*focus_next_func) (const Evas_Object *obj, Elm_Focus_Direction dir,
+                                    Evas_Object **next);
    void         (*on_focus_func) (void *data, Evas_Object *obj);
    void          *on_focus_data;
    void         (*on_change_func) (void *data, Evas_Object *obj);
    void          *on_change_data;
    void         (*on_show_region_func) (void *data, Evas_Object *obj);
    void          *on_show_region_data;
+   void         (*focus_region_func) (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+   void         (*on_focus_region_func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
    void          *data;
    Evas_Coord     rx, ry, rw, rh;
    int            scroll_hold;
@@ -52,16 +60,39 @@ struct _Smart_Data
    Elm_Theme     *theme;
    const char    *style;
    unsigned int   focus_order;
+   Eina_Bool      focus_order_on_calc;
    
    int            child_drag_x_locked;
    int            child_drag_y_locked;
+
+   Eina_List     *edje_signals;
+
    Eina_Bool      drag_x_locked : 1;
    Eina_Bool      drag_y_locked : 1;
    
    Eina_Bool      can_focus : 1;
    Eina_Bool      child_can_focus : 1;
    Eina_Bool      focused : 1;
+   Eina_Bool      highlight_ignore : 1;
+   Eina_Bool      highlight_in_theme : 1;
    Eina_Bool      disabled : 1;
+
+   Eina_List     *focus_chain;
+   Eina_List     *event_cb;
+};
+
+struct _Edje_Signal_Data
+{
+   Evas_Object *obj;
+   Edje_Signal_Cb func;
+   const char *emission;
+   const char *source;
+   void *data;
+};
+
+struct _Elm_Event_Cb_Data {
+     Elm_Event_Cb func;
+     const void *data;
 };
 
 /* local subsystem functions */
@@ -77,48 +108,64 @@ static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
 static void _smart_clip_unset(Evas_Object *obj);
 static void _smart_calculate(Evas_Object *obj);
 static void _smart_init(void);
-static inline Eina_Bool _elm_widget_is(const Evas_Object *obj);
 
-static void _if_focused_revert(Evas_Object *obj);
+static void _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only);
+static Evas_Object *_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only);
 
 /* local subsystem globals */
 static Evas_Smart *_e_smart = NULL;
+static Eina_List  *widtypes = NULL;
 
 static unsigned int focus_order = 0;
 
-static void  
-_unfocus_parents(Evas_Object *obj)  
-{  
-       for (; obj; obj = elm_widget_parent_get(obj))  
-       {  
-               Smart_Data *sd = evas_object_smart_data_get(obj);  
-               if (!sd) return;  
-               if (!sd->focused) return;  
-               sd->focused = 0;  
-       }  
-}  
-
-static void  
-_focus_parents(Evas_Object *obj)  
-{  
-       for (; obj; obj = elm_widget_parent_get(obj))  
-       {  
-               Smart_Data *sd = evas_object_smart_data_get(obj);  
-               if (!sd) return;  
-               if (sd->focused) return;  
-               sd->focused = 1;  
-       }  
-}  
+// internal funcs
+static inline Eina_Bool
+_elm_widget_is(const Evas_Object *obj)
+{
+   const char *type = evas_object_type_get(obj);
+   return type == SMART_NAME;
+}
+
+static inline Eina_Bool
+_is_focusable(Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->can_focus || (sd->child_can_focus);
+}
+
+static void
+_unfocus_parents(Evas_Object *obj)
+{
+   for (; obj; obj = elm_widget_parent_get(obj))
+     {
+        Smart_Data *sd = evas_object_smart_data_get(obj);
+        if (!sd) return;
+        if (!sd->focused) return;
+        sd->focused = 0;
+     }
+}
+
+static void
+_focus_parents(Evas_Object *obj)
+{
+   for (; obj; obj = elm_widget_parent_get(obj))
+     {
+        Smart_Data *sd = evas_object_smart_data_get(obj);
+        if (!sd) return;
+        if (sd->focused) return;
+        sd->focused = 1;
+     }
+}
 
 static void
 _sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Smart_Data *sd = data;
 
-   if (_elm_widget_is(obj))  
-      {  
-         if (elm_widget_focus_get(obj)) _unfocus_parents(sd->obj);  
-      }     
+   if (_elm_widget_is(obj))
+     {
+        if (elm_widget_focus_get(obj)) _unfocus_parents(sd->obj);
+     }
    if (obj == sd->resize_obj)
      sd->resize_obj = NULL;
    else if (obj == sd->hover_obj)
@@ -139,10 +186,191 @@ _sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
      }
    while (o);
    if (!o) return;
-   if (!elm_widget_can_focus_get(o)) return;
+   if (!_is_focusable(o)) return;
    elm_widget_focus_steal(o);
 }
 
+static void
+_propagate_x_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_x_locked += dir;
+             _propagate_x_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+static void
+_propagate_y_drag_lock(Evas_Object *obj, int dir)
+{
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+   if (sd->parent_obj)
+     {
+        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
+        if (sd2)
+          {
+             sd2->child_drag_y_locked += dir;
+             _propagate_y_drag_lock(sd->parent_obj, dir);
+          }
+     }
+}
+
+static void
+_propagate_event(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   INTERNAL_ENTRY;
+   Evas_Callback_Type type = (Evas_Callback_Type)(long) data;
+   Evas_Event_Flags *event_flags = NULL;
+
+   switch (type)
+     {
+     case EVAS_CALLBACK_KEY_DOWN:
+          {
+             Evas_Event_Key_Down *ev = event_info;
+             event_flags = &(ev->event_flags);
+             break;
+          }
+     case EVAS_CALLBACK_KEY_UP:
+          {
+             Evas_Event_Key_Up *ev = event_info;
+             event_flags = &(ev->event_flags);
+             break;
+          }
+     case EVAS_CALLBACK_MOUSE_WHEEL:
+          {
+             Evas_Event_Mouse_Wheel *ev = event_info;
+             event_flags = &(ev->event_flags);
+             break;
+          }
+     default:
+        break;
+     }
+
+   elm_widget_event_propagate(obj, type, event_info, event_flags);
+}
+
+static void
+_parent_focus(Evas_Object *obj)
+{
+   API_ENTRY return;
+
+   Evas_Object *o = elm_widget_parent_get(obj);
+   sd->focus_order_on_calc = EINA_TRUE;
+
+   if (sd->focused) return;
+   if (o)
+     {
+       unsigned int i = 0;
+       Evas_Object *ret;
+
+       ret = _newest_focus_order_get(o, &i, EINA_TRUE);
+
+       /* we don't want to bump a common widget ancestor's
+          focus_order *twice* while parent focusing */
+       if (!ret || (!i) || (i != focus_order))
+         _parent_focus(o);
+     }
+
+   if (!sd->focus_order_on_calc)
+     return; /* we don't want to override it if by means of any of the
+               callbacks below one gets to calculate our order
+               first. */
+
+   focus_order++;
+   sd->focus_order = focus_order;
+   sd->focused = EINA_TRUE;
+   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+   if (sd->focus_func) sd->focus_func(obj);
+
+   _elm_widget_focus_region_show(obj);
+
+   sd->focus_order_on_calc = EINA_FALSE;
+}
+
+static void
+_elm_object_focus_chain_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Smart_Data *sd = data;
+
+   sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
+}
+
+// exposed util funcs to elm
+void
+_elm_widget_type_clear(void)
+{
+   const char **ptr;
+   
+   EINA_LIST_FREE(widtypes, ptr)
+     {
+        eina_stringshare_del(*ptr);
+        *ptr = NULL;
+     }
+}
+
+void
+_elm_widget_focus_region_show(const Evas_Object *obj)
+{
+   Evas_Coord x, y, w, h, ox, oy;
+   Smart_Data *sd2;
+   Evas_Object *o;
+
+   API_ENTRY return;
+
+   o = elm_widget_parent_get(obj);
+   if (!o) return;
+
+   elm_widget_focus_region_get(obj, &x, &y, &w, &h);
+   evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
+   while (o)
+     {
+        Evas_Coord px, py;
+        sd2 = evas_object_smart_data_get(o);
+        if (sd2->focus_region_func)
+          {
+             sd2->focus_region_func(o, x, y, w, h);
+             elm_widget_focus_region_get(o, &x, &y, &w, &h);
+          }
+        else
+          {
+             evas_object_geometry_get(o, &px, &py, NULL, NULL);
+             x += ox - px;
+             y += oy - py;
+             ox = px;
+             oy = py;
+          }
+        o = elm_widget_parent_get(o);
+     }
+}
+
+/**
+ * @defgroup Widget Widget
+ *
+ * @internal
+ * Exposed api for making widgets
+ */
+EAPI void
+elm_widget_type_register(const char **ptr)
+{
+   widtypes = eina_list_append(widtypes, (void *)ptr);
+}
+
+EAPI Eina_Bool
+elm_widget_api_check(int ver)
+{
+   if (ver != ELM_INTERNAL_API_VERSION)
+     {
+        CRITICAL("Elementary widget api versions do not match");
+        return EINA_FALSE;
+     }
+   return EINA_TRUE;
+}
+
 EAPI Evas_Object *
 elm_widget_add(Evas *evas)
 {
@@ -193,6 +421,13 @@ elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
 }
 
 EAPI void
+elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info))
+{
+   API_ENTRY return;
+   sd->event_func = func;
+}
+
+EAPI void
 elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
 {
    API_ENTRY return;
@@ -214,7 +449,7 @@ elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Obj
 }
 
 EAPI void
-elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *(*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source)))
+elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data))
 {
    API_ENTRY return;
    sd->callback_del_func = func;
@@ -225,15 +460,68 @@ elm_widget_theme(Evas_Object *obj)
 {
    const Eina_List *l;
    Evas_Object *child;
+   Elm_Tooltip *tt;
+   Elm_Cursor *cur;
 
    API_ENTRY return;
+   EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_theme(child);
+   if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
+   if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
+   EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
+   EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur);
+   if (sd->theme_func) sd->theme_func(obj);
+}
+
+EAPI void
+elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+   Elm_Tooltip *tt;
+   Elm_Cursor *cur;
+   Elm_Theme *th2;
+
+   API_ENTRY return;
+   if (!force)
+     {
+        th2 = sd->theme;
+        while (th2)
+          {
+             if (th2 == th)
+               {
+                 force = EINA_TRUE;
+                 break;
+               }
+            th2 = th->ref_theme;
+          }
+     }
+   if (!force) return;
    EINA_LIST_FOREACH(sd->subobjs, l, child)
-     elm_widget_theme(child);
+     elm_widget_theme_specific(child, th, force);
    if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
    if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
+   EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
+   EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur);
    if (sd->theme_func) sd->theme_func(obj);
 }
 
+/**
+ * @internal
+ *
+ * Set hook to get next object in object focus chain.
+ *
+ * @param obj The widget object.
+ * @param func The hook to be used with this widget.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_next_hook_set(Evas_Object *obj, Eina_Bool (*func) (const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next))
+{
+   API_ENTRY return;
+   sd->focus_next_func = func;
+}
+
 EAPI void
 elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
 {
@@ -258,6 +546,50 @@ elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, E
    sd->on_show_region_data = data;
 }
 
+/**
+ * @internal
+ *
+ * Set the hook to use to show the focused region.
+ *
+ * Whenever a new widget gets focused or it's needed to show the focused
+ * area of the current one, this hook will be called on objects that may
+ * want to move their children into their visible area.
+ * The area given in the hook function is relative to the @p obj widget.
+ *
+ * @param obj The widget object
+ * @param func The function to call to show the specified area.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_region_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h))
+{
+   API_ENTRY return;
+   sd->focus_region_func = func;
+}
+
+/**
+ * @internal
+ *
+ * Set the hook to retrieve the focused region of a widget.
+ *
+ * This hook will be called by elm_widget_focus_region_get() whenever
+ * it's needed to get the focused area of a widget. The area must be relative
+ * to the widget itself and if no hook is set, it will default to the entire
+ * object.
+ *
+ * @param obj The widget object
+ * @param func The function used to retrieve the focus region.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_on_focus_region_hook_set(Evas_Object *obj, void (*func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h))
+{
+   API_ENTRY return;
+   sd->on_focus_region_func = func;
+}
+
 EAPI void
 elm_widget_data_set(Evas_Object *obj, void *data)
 {
@@ -279,31 +611,38 @@ elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
    double scale, pscale = elm_widget_scale_get(sobj);
    Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
 
-   sd->subobjs = eina_list_append(sd->subobjs, sobj);
-   if (!sd->child_can_focus)
+   if (_elm_widget_is(sobj))
      {
-       if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 1;
+        Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+        if (sd2)
+          {
+             if (sd2->parent_obj == obj)
+               return;
+             elm_widget_sub_object_del(sd2->parent_obj, sobj);
+             sd2->parent_obj = obj;
+             if (!sd->child_can_focus && (_is_focusable(sobj)))
+               sd->child_can_focus = EINA_TRUE;
+          }
      }
-   if (_elm_widget_is(sobj))
+   else
      {
-       Smart_Data *sd2 = evas_object_smart_data_get(sobj);
-       if (sd2)
-         {
-            if (sd2->parent_obj)
-               elm_widget_sub_object_del(sd2->parent_obj, sobj);
-            sd2->parent_obj = obj;
-         }
+        void *data = evas_object_data_get(sobj, "elm-parent");
+        if (data)
+          {
+             if (data == obj) return;
+             evas_object_event_callback_del(sobj, EVAS_CALLBACK_DEL, 
+                                            _sub_obj_del);
+          }
      }
+
+   sd->subobjs = eina_list_append(sd->subobjs, sobj);
    evas_object_data_set(sobj, "elm-parent", obj);
    evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
    evas_object_smart_callback_call(obj, "sub-object-add", sobj);
    scale = elm_widget_scale_get(sobj);
    th = elm_widget_theme_get(sobj);
    if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
-   if (_elm_widget_is(sobj))  
-      {  
-         if (elm_widget_focus_get(sobj)) _focus_parents(obj);  
-      }
+   if (elm_widget_focus_get(sobj)) _focus_parents(obj);
 }
 
 EAPI void
@@ -327,18 +666,29 @@ elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
          }
        if (abort_on_warn == 1) abort();
      }
-   sd->subobjs = eina_list_remove(sd->subobjs, sobj);
    if (!sd->child_can_focus)
      {
-       if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 0;
+       if (_is_focusable(sobj)) sd->child_can_focus = 0;
      }
    if (_elm_widget_is(sobj))
      {
-       Smart_Data *sd2 = evas_object_smart_data_get(sobj);
-       if (sd2) sd2->parent_obj = NULL;
-       if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
+        Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+        if (sd2)
+          {
+             sd2->parent_obj = NULL;
+             if (sd2->resize_obj == sobj)
+               sd2->resize_obj = NULL;
+             else
+               sd->subobjs = eina_list_remove(sd->subobjs, sobj);
+          }
+        else
+          sd->subobjs = eina_list_remove(sd->subobjs, sobj);
+        if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
      }
-   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+   else
+     sd->subobjs = eina_list_remove(sd->subobjs, sobj);
+   evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, 
+                                       _sub_obj_del, sd);
    evas_object_smart_callback_call(obj, "sub-object-del", sobj);
 }
 
@@ -346,8 +696,10 @@ EAPI void
 elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
 {
    API_ENTRY return;
+   // orphan previous resize obj
    if (sd->resize_obj)
      {
+       evas_object_clip_unset(sd->resize_obj);
        evas_object_data_del(sd->resize_obj, "elm-parent");
        if (_elm_widget_is(sd->resize_obj))
          {
@@ -355,15 +707,35 @@ elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
             if (sd2) sd2->parent_obj = NULL;
          }
        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
-           _sub_obj_del, sd);
+                                            _sub_obj_del, sd);
        evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
-           _sub_obj_mouse_down, sd);
+                                            _sub_obj_mouse_down, sd);
        evas_object_smart_member_del(sd->resize_obj);
-        if (_elm_widget_is(sd->resize_obj))  
-           {  
-              if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);  
-           }
+        if (_elm_widget_is(sd->resize_obj))
+          {
+             if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
+          }
+     }
+   // orphan new resize obj
+   if (sobj)
+     {
+        evas_object_data_del(sobj, "elm-parent");
+        if (_elm_widget_is(sobj))
+          {
+             Smart_Data *sd2 = evas_object_smart_data_get(sobj);
+             if (sd2) sd2->parent_obj = NULL;
+          }
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
+                                            _sub_obj_del, sd);
+        evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN,
+                                            _sub_obj_mouse_down, sd);
+        evas_object_smart_member_del(sobj);
+        if (_elm_widget_is(sobj))
+          {
+             if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
+          }
      }
+   // set the resize obj up
    sd->resize_obj = sobj;
    if (sd->resize_obj)
      {
@@ -374,16 +746,17 @@ elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
          }
        evas_object_clip_set(sobj, evas_object_clip_get(obj));
        evas_object_smart_member_add(sobj, obj);
-       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
+                                       _sub_obj_del, sd);
        evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
                                        _sub_obj_mouse_down, sd);
        _smart_reconfigure(sd);
        evas_object_data_set(sobj, "elm-parent", obj);
        evas_object_smart_callback_call(obj, "sub-object-add", sobj);
-       if (_elm_widget_is(sobj))  
-           {  
-              if (elm_widget_focus_get(sobj)) _focus_parents(obj);  
-           }                         
+        if (_elm_widget_is(sobj))
+          {
+             if (elm_widget_focus_get(sobj)) _focus_parents(obj);
+          }
      }
 }
 
@@ -399,31 +772,87 @@ elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
    sd->hover_obj = sobj;
    if (sd->hover_obj)
      {
-       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
+       evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
+                                       _sub_obj_del, sd);
        _smart_reconfigure(sd);
      }
 }
 
 EAPI void
-elm_widget_can_focus_set(Evas_Object *obj, int can_focus)
+elm_widget_can_focus_set(Evas_Object *obj, Eina_Bool can_focus)
 {
    API_ENTRY return;
    sd->can_focus = can_focus;
+   if (can_focus)
+     {
+        evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
+                                       _propagate_event,
+                                       (void *)(long) EVAS_CALLBACK_KEY_DOWN);
+        evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
+                                       _propagate_event,
+                                       (void *)(long) EVAS_CALLBACK_KEY_UP);
+        evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
+                                       _propagate_event,
+                                       (void *)(long)EVAS_CALLBACK_MOUSE_WHEEL);
+     }
+   else
+     {
+        evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_DOWN,
+                                       _propagate_event);
+        evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_UP,
+                                       _propagate_event);
+        evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_WHEEL,
+                                       _propagate_event);
+     }
 }
 
-EAPI int
+EAPI Eina_Bool
 elm_widget_can_focus_get(const Evas_Object *obj)
 {
-   API_ENTRY return 0;
-   if (sd->can_focus) return 1;
-   if (sd->child_can_focus) return 1;
-   return 0;
+   API_ENTRY return EINA_FALSE;
+   return sd->can_focus;
 }
 
-EAPI int
+EAPI Eina_Bool
+elm_widget_child_can_focus_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->child_can_focus;
+}
+
+EAPI void
+elm_widget_highlight_ignore_set(Evas_Object *obj, Eina_Bool ignore)
+{
+   API_ENTRY return;
+   sd->highlight_ignore = !!ignore;
+}
+
+EAPI Eina_Bool
+elm_widget_highlight_ignore_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->highlight_ignore;
+}
+
+EAPI void
+elm_widget_highlight_in_theme_set(Evas_Object *obj, Eina_Bool highlight)
+{
+   API_ENTRY return;
+   sd->highlight_in_theme = !!highlight;
+   /* FIXME: if focused, it should switch from one mode to the other */
+}
+
+EAPI Eina_Bool
+elm_widget_highlight_in_theme_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->highlight_in_theme;
+}
+
+EAPI Eina_Bool
 elm_widget_focus_get(const Evas_Object *obj)
 {
-   API_ENTRY return 0;
+   API_ENTRY return EINA_FALSE;
    return sd->focused;
 }
 
@@ -446,26 +875,9 @@ elm_widget_focused_object_get(const Evas_Object *obj)
 EAPI Evas_Object *
 elm_widget_top_get(const Evas_Object *obj)
 {
-#if 1 // strict way  
    API_ENTRY return NULL;
    if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
    return (Evas_Object *)obj;
-#else // loose way
-   Smart_Data *sd = evas_object_smart_data_get(obj);
-   Evas_Object *par;
-   
-   if (!obj) return NULL;
-   if ((sd) && _elm_widget_is(obj))
-     {
-        if ((sd->type) && (!strcmp(sd->type, "win"))) 
-          return (Evas_Object *)obj;
-        if (sd->parent_obj)
-          return elm_widget_top_get(sd->parent_obj);
-     }
-   par = evas_object_smart_parent_get(obj);
-   if (!par) return (Evas_Object *)obj;
-   return elm_widget_top_get(par);
-#endif   
 }
 
 EAPI Eina_Bool
@@ -488,8 +900,7 @@ elm_widget_parent_widget_get(const Evas_Object *obj)
    else
      {
        parent = evas_object_data_get(obj, "elm-parent");
-       if (!parent)
-         parent = evas_object_smart_data_get(obj);
+       if (!parent) parent = evas_object_smart_parent_get(obj);
      }
 
    while (parent)
@@ -497,171 +908,405 @@ elm_widget_parent_widget_get(const Evas_Object *obj)
        Evas_Object *elm_parent;
        if (_elm_widget_is(parent)) break;
        elm_parent = evas_object_data_get(parent, "elm-parent");
-       if (elm_parent)
-         parent = elm_parent;
-       else
-         parent = evas_object_smart_parent_get(parent);
+        if (elm_parent) parent = elm_parent;
+       else parent = evas_object_smart_parent_get(parent);
      }
    return parent;
 }
 
-EAPI int
-elm_widget_focus_jump(Evas_Object *obj, int forward)
+EAPI void
+elm_widget_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
 {
-   API_ENTRY return 0;
-   if (!elm_widget_can_focus_get(obj)) return 0;
+   API_ENTRY return;
+   EINA_SAFETY_ON_NULL_RETURN(func);
+   Elm_Event_Cb_Data *ecb = ELM_NEW(Elm_Event_Cb_Data);
+   ecb->func = func;
+   ecb->data = data;
+   sd->event_cb = eina_list_append(sd->event_cb, ecb);
+}
 
-   /* if it has a focus func its an end-point widget like a button */
-   if (sd->focus_func)
+EAPI void *
+elm_widget_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
+{
+   API_ENTRY return NULL;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
+   Eina_List *l;
+   Elm_Event_Cb_Data *ecd;
+   EINA_LIST_FOREACH(sd->event_cb, l, ecd)
+      if ((ecd->func == func) && (ecd->data == data))
+        {
+           free(ecd);
+           sd->event_cb = eina_list_remove_list(sd->event_cb, l);
+           return (void *)data;
+        }
+   return NULL;
+}
+
+EAPI Eina_Bool
+elm_widget_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info, Evas_Event_Flags *event_flags)
+{
+   API_ENTRY return EINA_FALSE; //TODO reduce.
+   if (!_elm_widget_is(obj)) return EINA_FALSE;
+   Evas_Object *parent = obj;
+   Elm_Event_Cb_Data *ecd;
+   Eina_List *l, *l_prev;
+
+   while (parent &&
+          (!(event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))))
      {
-       if (!sd->focused)
+        sd = evas_object_smart_data_get(parent);
+        if ((!sd) || (!_elm_widget_is(obj)))
+          return EINA_FALSE; //Not Elm Widget
+
+        if (sd->event_func && (sd->event_func(parent, obj, type, event_info)))
+          return EINA_TRUE;
+
+        EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
           {
-             focus_order++;
-             sd->focus_order = focus_order;
-             sd->focused = 1;
+             if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
+                 (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
+                 return EINA_TRUE;
           }
-       else sd->focused = 0;
-       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
-       sd->focus_func(obj);
-       return sd->focused;
+        parent = sd->parent_obj;
+     }
+
+   return EINA_FALSE;
+}
+
+/**
+ * @internal
+ *
+ * Set custom focus chain.
+ *
+ * This function i set one new and overwrite any previous custom focus chain
+ * with the list of objects. The previous list will be deleted and this list
+ * will be managed. After setted, don't modity it.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container widget
+ * @param objs Chain of objects to pass focus
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs)
+{
+   API_ENTRY return;
+   if (!sd->focus_next_func)
+     return;
+
+   elm_widget_focus_custom_chain_unset(obj);
+
+   Eina_List *l;
+   Evas_Object *o;
+
+   EINA_LIST_FOREACH(objs, l, o)
+     {
+        evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
+                                       _elm_object_focus_chain_del_cb, sd);
      }
-   /* its some container */
+
+   sd->focus_chain = objs;
+}
+
+/**
+ * @internal
+ *
+ * Get custom focus chain
+ *
+ * @param obj The container widget
+ * @ingroup Widget
+ */
+EAPI const Eina_List *
+elm_widget_focus_custom_chain_get(const Evas_Object *obj)
+{
+   API_ENTRY return NULL;
+   return (const Eina_List *) sd->focus_chain;
+}
+
+/**
+ * @internal
+ *
+ * Unset custom focus chain
+ *
+ * @param obj The container widget
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_custom_chain_unset(Evas_Object *obj)
+{
+   API_ENTRY return;
+   Eina_List *l, *l_next;
+   Evas_Object *o;
+
+   EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
+     {
+        evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
+                                            _elm_object_focus_chain_del_cb, sd);
+        sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
+     }
+}
+
+/**
+ * @internal
+ *
+ * Append object to custom focus chain.
+ *
+ * @note If relative_child equal to NULL or not in custom chain, the object
+ * will be added in end.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container widget
+ * @param child The child to be added in custom chain
+ * @param relative_child The relative object to position the child
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_custom_chain_append(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child)
+{
+   API_ENTRY return;
+   EINA_SAFETY_ON_NULL_RETURN(child);
+   if (!sd->focus_next_func)
+     return;
+
+   evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
+                                       _elm_object_focus_chain_del_cb, sd);
+
+   if (!relative_child)
+     {
+        sd->focus_chain = eina_list_append(sd->focus_chain, child);
+        return;
+     }
+
+   sd->focus_chain = eina_list_append_relative(sd->focus_chain, child, relative_child);
+   return;
+}
+
+/**
+ * @internal
+ *
+ * Prepend object to custom focus chain.
+ *
+ * @note If relative_child equal to NULL or not in custom chain, the object
+ * will be added in begin.
+ *
+ * @note On focus cycle, only will be evaluated children of this container.
+ *
+ * @param obj The container widget
+ * @param child The child to be added in custom chain
+ * @param relative_child The relative object to position the child
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child)
+{
+   API_ENTRY return;
+   EINA_SAFETY_ON_NULL_RETURN(child);
+   if (!sd->focus_next_func)
+     return;
+
+   evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
+                                       _elm_object_focus_chain_del_cb, sd);
+
+   if (!relative_child)
+     {
+        sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
+        return;
+     }
+
+   sd->focus_chain = eina_list_prepend_relative(sd->focus_chain, child, relative_child);
+   return;
+}
+
+/**
+ * @internal
+ *
+ * Give focus to next object in object tree.
+ *
+ * Give focus to next object in focus chain of one object sub-tree.
+ * If the last object of chain already have focus, the focus will go to the
+ * first object of chain.
+ *
+ * @param obj The widget root of sub-tree
+ * @param dir Direction to cycle the focus
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
+{
+   Evas_Object *target = NULL;
+   if (!_elm_widget_is(obj))
+     return;
+   elm_widget_focus_next_get(obj, dir, &target);
+   if (target)
+     elm_widget_focus_steal(target);
+}
+
+/**
+ * @internal
+ *
+ * Give focus to near object in one direction.
+ *
+ * Give focus to near object in direction of one object.
+ * If none focusable object in given direction, the focus will not change.
+ *
+ * @param obj The reference widget
+ * @param x Horizontal component of direction to focus
+ * @param y Vertical component of direction to focus
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__, int x __UNUSED__, int y __UNUSED__)
+{
+   return; /* TODO */
+}
+
+/**
+ * @internal
+ *
+ * Get next object in focus chain of object tree.
+ *
+ * Get next object in focus chain of one object sub-tree.
+ * Return the next object by reference. If don't have any candidate to receive
+ * focus before chain end, the first candidate will be returned.
+ *
+ * @param obj The widget root of sub-tree
+ * @param dir Direction os focus chain
+ * @param next The next object in focus chain
+ * @return EINA_TRUE if don't need focus chain restart/loop back
+ *         to use 'next' obj.
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_Bool
+elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
+{
+   if (!next)
+     return EINA_FALSE;
+   *next = NULL;
+
+   API_ENTRY return EINA_FALSE;
+
+   /* Ignore if disabled */
+   if ((!evas_object_visible_get(obj)) || (elm_widget_disabled_get(obj)))
+     return EINA_FALSE;
+
+   /* Try use hook */
+   if (sd->focus_next_func)
+     return sd->focus_next_func(obj, dir, next);
+
+   if (!elm_widget_can_focus_get(obj))
+     return EINA_FALSE;
+
+   /* Return */
+   *next = (Evas_Object *)obj;
+   return !elm_widget_focus_get(obj);
+}
+
+
+/**
+ * @internal
+ *
+ * Get next object in focus chain of object tree in list.
+ *
+ * Get next object in focus chain of one object sub-tree ordered by one list.
+ * Return the next object by reference. If don't have any candidate to receive
+ * focus before list end, the first candidate will be returned.
+ *
+ * @param obj The widget root of sub-tree
+ * @param dir Direction os focus chain
+ * @param items list with ordered objects
+ * @param list_data_get function to get the object from one item of list
+ * @param next The next object in focus chain
+ * @return EINA_TRUE if don't need focus chain restart/loop back
+ *         to use 'next' obj.
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_Bool
+elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Evas_Object **next)
+{
+   Eina_List *(*list_next) (const Eina_List *list);
+
+   if (!next)
+     return EINA_FALSE;
+   *next = NULL;
+
+   if (!_elm_widget_is(obj))
+     return EINA_FALSE;
+
+   if (!items)
+     return EINA_FALSE;
+
+   /* Direction */
+   if (dir == ELM_FOCUS_PREVIOUS)
+     {
+        items = eina_list_last(items);
+        list_next = eina_list_prev;
+     }
+   else if (dir == ELM_FOCUS_NEXT)
+     list_next = eina_list_next;
    else
+     return EINA_FALSE;
+
+   const Eina_List *l = items;
+
+   /* Recovery last focused sub item */
+   if (elm_widget_focus_get(obj))
+     for (; l; l = list_next(l))
+       {
+          Evas_Object *cur = list_data_get(l);
+          if (elm_widget_focus_get(cur)) break;
+       }
+
+   const Eina_List *start = l;
+   Evas_Object *to_focus = NULL;
+
+   /* Interate sub items */
+   /* Go to end of list */
+   for (; l; l = list_next(l))
      {
-       int focus_next;
-       int noloop = 0;
+        Evas_Object *tmp = NULL;
+        Evas_Object *cur = list_data_get(l);
 
-       focus_next = 0;
-       if (!sd->focused)
-         {
-            elm_widget_focus_set(obj, forward);
-            return 1;
-         }
-       else
-         {
-            if (forward)
-              {
-                 if (elm_widget_can_focus_get(sd->resize_obj))
-                   {
-                      if ((focus_next) &&
-                          (!elm_widget_disabled_get(sd->resize_obj)))
-                        {
-                           /* the previous focused item was unfocused - so focus
-                            * the next one (that can be focused) */
-                           if (elm_widget_focus_jump(sd->resize_obj, forward))
-                              return 1;
-                           else noloop = 1;
-                        }
-                      else
-                        {
-                           if (elm_widget_focus_get(sd->resize_obj))
-                             {
-                                /* jump to the next focused item or focus this item */
-                                if (elm_widget_focus_jump(sd->resize_obj, forward))
-                                   return 1;
-                                /* it returned 0 - it got to the last item and is past it */
-                                focus_next = 1;
-                             }
-                        }
-                   }
-                 if (!noloop)
-                   {
-                      const Eina_List *l;
-                      Evas_Object *child;
-                      EINA_LIST_FOREACH(sd->subobjs, l, child)
-                        {
-                           if (elm_widget_can_focus_get(child))
-                             {
-                                if ((focus_next) &&
-                                    (!elm_widget_disabled_get(child)))
-                                  {
-                                     /* the previous focused item was unfocused - so focus
-                                      * the next one (that can be focused) */
-                                     if (elm_widget_focus_jump(child, forward))
-                                        return 1;
-                                     else break;
-                                  }
-                                else
-                                  {
-                                     if (elm_widget_focus_get(child))
-                                       {
-                                          /* jump to the next focused item or focus this item */
-                                          if (elm_widget_focus_jump(child, forward))
-                                             return 1;
-                                          /* it returned 0 - it got to the last item and is past it */
-                                          focus_next = 1;
-                                       }
-                                  }
-                             }
-                        }
-                   }
-              }
-            else
-              {
-                 const Eina_List *l;
-                 Evas_Object *child;
+        if (elm_widget_parent_get(cur) != obj)
+          continue;
 
-                 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
-                   {
-                      if (elm_widget_can_focus_get(child))
-                        {
-                           if ((focus_next) &&
-                               (!elm_widget_disabled_get(child)))
-                             {
-                                /* the previous focused item was unfocused - so focus
-                                 * the next one (that can be focused) */
-                                if (elm_widget_focus_jump(child, forward))
-                                   return 1;
-                                else break;
-                             }
-                           else
-                             {
-                                if (elm_widget_focus_get(child))
-                                  {
-                                     /* jump to the next focused item or focus this item */
-                                     if (elm_widget_focus_jump(child, forward))
-                                        return 1;
-                                     /* it returned 0 - it got to the last item and is past it */
-                                     focus_next = 1;
-                                  }
-                             }
-                        }
-                   }
-                 if (!l)
-                   {
-                      if (elm_widget_can_focus_get(sd->resize_obj))
-                        {
-                           if ((focus_next) &&
-                               (!elm_widget_disabled_get(sd->resize_obj)))
-                             {
-                                /* the previous focused item was unfocused - so focus
-                                 * the next one (that can be focused) */
-                                if (elm_widget_focus_jump(sd->resize_obj, forward))
-                                   return 1;
-                             }
-                           else
-                             {
-                                if (elm_widget_focus_get(sd->resize_obj))
-                                  {
-                                     /* jump to the next focused item or focus this item */
-                                     if (elm_widget_focus_jump(sd->resize_obj, forward))
-                                        return 1;
-                                     /* it returned 0 - it got to the last item and is past it */
-                                     focus_next = 1;
-                                  }
-                             }
-                        }
-                   }
-              }
-         }
+        /* Try Focus cycle in subitem */
+        if (elm_widget_focus_next_get(cur, dir, &tmp))
+          {
+             *next = tmp;
+             return EINA_TRUE;
+          }
+        else if ((tmp) && (!to_focus))
+          to_focus = tmp;
      }
-   /* no next item can be focused */
-   if (sd->focused)
+
+   l = items;
+
+   /* Get First possible */
+   for (;l != start; l = list_next(l))
      {
-       sd->focused = 0;
-       if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+        Evas_Object *tmp = NULL;
+        Evas_Object *cur = list_data_get(l);
+
+        if (elm_widget_parent_get(cur) != obj)
+          continue;
+
+        /* Try Focus cycle in subitem */
+        elm_widget_focus_next_get(cur, dir, &tmp);
+        if (tmp)
+          {
+             *next = tmp;
+             return EINA_FALSE;
+          }
      }
-   return 0;
+
+   *next = to_focus;
+   return EINA_FALSE;
 }
 
 EAPI void
@@ -672,20 +1317,57 @@ elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *sourc
    sd->signal_func(obj, emission, source);
 }
 
+static void
+_edje_signal_callback(void *data, Evas_Object *obj __UNUSED__, const char *emission, const char *source)
+{
+   Edje_Signal_Data *esd = data;
+   esd->func(esd->data, esd->obj, emission, source);
+}
+
 EAPI void
 elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
 {
+   Edje_Signal_Data *esd;
    API_ENTRY return;
    if (!sd->callback_add_func) return;
-   sd->callback_add_func(obj, emission, source, func, data);
+   EINA_SAFETY_ON_NULL_RETURN(func);
+
+   esd = ELM_NEW(Edje_Signal_Data);
+   if (!esd) return;
+
+   esd->obj = obj;
+   esd->func = func;
+   esd->emission = eina_stringshare_add(emission);
+   esd->source = eina_stringshare_add(source);
+   esd->data = data;
+   sd->edje_signals = eina_list_append(sd->edje_signals, esd);
+   sd->callback_add_func(obj, emission, source, _edje_signal_callback, esd);
 }
 
 EAPI void *
 elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
 {
+   Edje_Signal_Data *esd;
+   Eina_List *l;
+   void *data = NULL;
    API_ENTRY return NULL;
    if (!sd->callback_del_func) return NULL;
-   return sd->callback_del_func(obj, emission, source, func);
+
+   EINA_LIST_FOREACH(sd->edje_signals, l, esd)
+     {
+        if ((esd->func == func) && (!strcmp(esd->emission, emission)) &&
+            (!strcmp(esd->source, source)))
+          {
+             sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
+             eina_stringshare_del(esd->emission);
+             eina_stringshare_del(esd->source);
+             data = esd->data;
+             free(esd);
+             break;
+          }
+     }
+   sd->callback_del_func(obj, emission, source, _edje_signal_callback, esd);
+   return data;
 }
 
 EAPI void
@@ -696,7 +1378,7 @@ elm_widget_focus_set(Evas_Object *obj, int first)
      {
         focus_order++;
         sd->focus_order = focus_order;
-       sd->focused = 1;
+       sd->focused = EINA_TRUE;
        if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
      }
    if (sd->focus_func)
@@ -708,7 +1390,7 @@ elm_widget_focus_set(Evas_Object *obj, int first)
      {
        if (first)
          {
-            if ((elm_widget_can_focus_get(sd->resize_obj)) &&
+            if ((_is_focusable(sd->resize_obj)) &&
                 (!elm_widget_disabled_get(sd->resize_obj)))
               {
                  elm_widget_focus_set(sd->resize_obj, first);
@@ -719,7 +1401,7 @@ elm_widget_focus_set(Evas_Object *obj, int first)
                  Evas_Object *child;
                  EINA_LIST_FOREACH(sd->subobjs, l, child)
                    {
-                      if ((elm_widget_can_focus_get(child)) &&
+                      if ((_is_focusable(child)) &&
                           (!elm_widget_disabled_get(child)))
                         {
                            elm_widget_focus_set(child, first);
@@ -734,7 +1416,7 @@ elm_widget_focus_set(Evas_Object *obj, int first)
             Evas_Object *child;
             EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
               {
-                 if ((elm_widget_can_focus_get(child)) &&
+                 if ((_is_focusable(child)) &&
                      (!elm_widget_disabled_get(child)))
                    {
                       elm_widget_focus_set(child, first);
@@ -743,7 +1425,7 @@ elm_widget_focus_set(Evas_Object *obj, int first)
               }
             if (!l)
               {
-                 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
+                 if ((_is_focusable(sd->resize_obj)) &&
                      (!elm_widget_disabled_get(sd->resize_obj)))
                    {
                       elm_widget_focus_set(sd->resize_obj, first);
@@ -766,7 +1448,7 @@ elm_widget_focused_object_clear(Evas_Object *obj)
    API_ENTRY return;
    if (!sd->focused) return;
    if (elm_widget_focus_get(sd->resize_obj))
-     elm_widget_focused_object_clear(sd->resize_obj);
+      elm_widget_focused_object_clear(sd->resize_obj);
    else
      {
        const Eina_List *l;
@@ -780,22 +1462,7 @@ elm_widget_focused_object_clear(Evas_Object *obj)
               }
          }
      }
-   sd->focused = 0;
-   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
-   if (sd->focus_func) sd->focus_func(obj);
-}
-
-static void
-_elm_widget_parent_focus(Evas_Object *obj)
-{
-   API_ENTRY return;
-   Evas_Object *o = elm_widget_parent_get(obj);
-
-   if (sd->focused) return;
-   if (o) _elm_widget_parent_focus(o);
-   focus_order++;
-   sd->focus_order = focus_order;
-   sd->focused = 1;
+   sd->focused = EINA_FALSE;
    if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
    if (sd->focus_func) sd->focus_func(obj);
 }
@@ -841,7 +1508,7 @@ elm_widget_focus_steal(Evas_Object *obj)
               }
          }
      }
-   _elm_widget_parent_focus(obj);
+   _parent_focus(obj);
    return;
 }
 
@@ -879,7 +1546,8 @@ elm_widget_disabled_set(Evas_Object *obj, int disabled)
             if (!o) break;
             parent = o;
          }
-       elm_widget_focus_jump(parent, 1);
+        if (elm_widget_focus_get(obj))
+          elm_widget_focus_cycle(parent, ELM_FOCUS_NEXT);
      }
    if (sd->disable_func) sd->disable_func(obj);
 }
@@ -894,6 +1562,9 @@ elm_widget_disabled_get(const Evas_Object *obj)
 EAPI void
 elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
 {
+   Evas_Object *parent_obj, *child_obj;
+   Evas_Coord px, py, cx, cy;
+
    API_ENTRY return;
    if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
    sd->rx = x;
@@ -901,34 +1572,32 @@ elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Co
    sd->rw = w;
    sd->rh = h;
    if (sd->on_show_region_func)
-     sd->on_show_region_func(sd->on_show_region_data, obj);
-     
-       Evas_Object *parent_obj, *child_obj;
-       Evas_Coord px, py, cx, cy;
-       do
-         {
-            parent_obj = sd->parent_obj; 
-                child_obj = sd->obj;
-            sd = evas_object_smart_data_get(parent_obj);
+      sd->on_show_region_func(sd->on_show_region_data, obj);
 
-            if ((!parent_obj) || (!sd) || (!_elm_widget_is(parent_obj))) break;
+   do
+     {
+        parent_obj = sd->parent_obj; 
+        child_obj = sd->obj;
+        sd = evas_object_smart_data_get(parent_obj);
 
-                evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
-                evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
+        if ((!parent_obj) || (!sd) || (!_elm_widget_is(parent_obj))) break;
 
-                x += (cx - px);
-                y += (cy - py);
-                sd->rx = x;
-                sd->ry = y;
-                sd->rw = w;
-                sd->rh = h;
+        evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
+        evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
 
-            if (sd->on_show_region_func)
-              {
-                 sd->on_show_region_func(sd->on_show_region_data, parent_obj);
-              }
-         }
-       while (parent_obj);
+        x += (cx - px);
+        y += (cy - py);
+        sd->rx = x;
+        sd->ry = y;
+        sd->rw = w;
+        sd->rh = h;
+
+        if (sd->on_show_region_func)
+          {
+             sd->on_show_region_func(sd->on_show_region_data, parent_obj);
+          }
+     }
+   while (parent_obj);
 }
 
 EAPI void
@@ -941,13 +1610,51 @@ elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y,
    if (h) *h = sd->rh;
 }
 
+/**
+ * @internal
+ *
+ * Get the focus region of the given widget.
+ *
+ * The focus region is the area of a widget that should brought into the
+ * visible area when the widget is focused. Mostly used to show the part of
+ * an entry where the cursor is, for example. The area returned is relative
+ * to the object @p obj.
+ * If the @p obj doesn't have the proper on_focus_region_hook set, this
+ * function will return the full size of the object.
+ *
+ * @param obj The widget object
+ * @param x Where to store the x coordinate of the area
+ * @param y Where to store the y coordinate of the area
+ * @param w Where to store the width of the area
+ * @param h Where to store the height of the area
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_focus_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   Smart_Data *sd;
+
+   if (!obj) return;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd || !_elm_widget_is(obj) || !sd->on_focus_region_func)
+     {
+        evas_object_geometry_get(obj, NULL, NULL, w, h);
+        if (x) *x = 0;
+        if (y) *y = 0;
+        return;
+     }
+   sd->on_focus_region_func(obj, x, y, w, h);
+}
+
 EAPI void
 elm_widget_scroll_hold_push(Evas_Object *obj)
 {
    API_ENTRY return;
    sd->scroll_hold++;
    if (sd->scroll_hold == 1)
-     evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
+      evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
    if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
    // FIXME: on delete/reparent hold pop
 }
@@ -958,8 +1665,8 @@ elm_widget_scroll_hold_pop(Evas_Object *obj)
    API_ENTRY return;
    sd->scroll_hold--;
    if (sd->scroll_hold < 0) sd->scroll_hold = 0;
-   if (sd->scroll_hold == 0)
-     evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
+   if (!sd->scroll_hold)
+      evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
    if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
 }
 
@@ -976,7 +1683,7 @@ elm_widget_scroll_freeze_push(Evas_Object *obj)
    API_ENTRY return;
    sd->scroll_freeze++;
    if (sd->scroll_freeze == 1)
-     evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
+      evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
    if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
    // FIXME: on delete/reparent freeze pop
 }
@@ -987,8 +1694,8 @@ elm_widget_scroll_freeze_pop(Evas_Object *obj)
    API_ENTRY return;
    sd->scroll_freeze--;
    if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
-   if (sd->scroll_freeze == 0)
-     evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
+   if (!sd->scroll_freeze)
+      evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
    if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
 }
 
@@ -1019,9 +1726,9 @@ elm_widget_scale_get(const Evas_Object *obj)
    if (sd->scale == 0.0)
      {
        if (sd->parent_obj)
-         return elm_widget_scale_get(sd->parent_obj);
+           return elm_widget_scale_get(sd->parent_obj);
        else
-         return 1.0;
+           return 1.0;
      }
    return sd->scale;
 }
@@ -1046,9 +1753,9 @@ elm_widget_theme_get(const Evas_Object *obj)
    if (!sd->theme)
      {
         if (sd->parent_obj)
-          return elm_widget_theme_get(sd->parent_obj);
+           return elm_widget_theme_get(sd->parent_obj);
         else
-          return NULL;
+           return NULL;
      }
    return sd->theme;
 }
@@ -1057,15 +1764,15 @@ EAPI void
 elm_widget_style_set(Evas_Object *obj, const char *style)
 {
    API_ENTRY return;
-
+   
    if (eina_stringshare_replace(&sd->style, style))
-     elm_widget_theme(obj);
+      elm_widget_theme(obj);
 }
 
 EAPI const char *
 elm_widget_style_get(const Evas_Object *obj)
 {
-   API_ENTRY return "";
+   API_ENTRY return NULL;
    if (sd->style) return sd->style;
    return "default";
 }
@@ -1080,40 +1787,39 @@ elm_widget_type_set(Evas_Object *obj, const char *type)
 EAPI const char *
 elm_widget_type_get(const Evas_Object *obj)
 {
-   API_ENTRY return "";
+   API_ENTRY return NULL;
    if (sd->type) return sd->type;
    return "";
 }
 
-static void
-_propagate_x_drag_lock(Evas_Object *obj, int dir)
+EAPI void
+elm_widget_tooltip_add(Evas_Object *obj, Elm_Tooltip *tt)
 {
-   Smart_Data *sd = evas_object_smart_data_get(obj);
-   if (sd->parent_obj)
-     {
-        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
-        if (sd2)
-          {
-             sd2->child_drag_x_locked += dir;
-             _propagate_x_drag_lock(sd->parent_obj, dir);
-          }
-     }
+   API_ENTRY return;
+   sd->tooltips = eina_list_append(sd->tooltips, tt);
 }
 
-static void
-_propagate_y_drag_lock(Evas_Object *obj, int dir)
+EAPI void
+elm_widget_tooltip_del(Evas_Object *obj, Elm_Tooltip *tt)
 {
-   Smart_Data *sd = evas_object_smart_data_get(obj);
-   if (sd->parent_obj)
-     {
-        Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
-        if (sd2)
-          {
-             sd2->child_drag_y_locked += dir;
-             _propagate_y_drag_lock(sd->parent_obj, dir);
-          }
-     }
+   API_ENTRY return;
+   sd->tooltips = eina_list_remove(sd->tooltips, tt);
+}
+
+EAPI void
+elm_widget_cursor_add(Evas_Object *obj, Elm_Cursor *cur)
+{
+   API_ENTRY return;
+   sd->cursors = eina_list_append(sd->cursors, cur);
+}
+
+EAPI void
+elm_widget_cursor_del(Evas_Object *obj, Elm_Cursor *cur)
+{
+   API_ENTRY return;
+   sd->cursors = eina_list_remove(sd->cursors, cur);
 }
+
 EAPI void
 elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
 {
@@ -1162,17 +1868,527 @@ elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
    return sd->child_drag_y_locked;
 }
 
+EAPI Eina_Bool
+elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
+{
+   API_ENTRY return EINA_FALSE;
+   return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
+}
+
+EAPI Eina_Bool
+elm_widget_type_check(const Evas_Object *obj, const char *type)
+{
+   const char *provided, *expected = "(unknown)";
+   static int abort_on_warn = -1;
+   provided = elm_widget_type_get(obj);
+   if (EINA_LIKELY(provided == type)) return EINA_TRUE;
+   if (type) expected = type;
+   if ((!provided) || (!provided[0]))
+     {
+        provided = evas_object_type_get(obj);
+        if ((!provided) || (!provided[0]))
+           provided = "(unknown)";
+     }
+   ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
+   if (abort_on_warn == -1)
+     {
+        if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
+        else abort_on_warn = 0;
+     }
+   if (abort_on_warn == 1) abort();
+   return EINA_FALSE;
+}
+
+/**
+ * @internal
+ *
+ * Split string in words
+ *
+ * @param str Source string
+ * @return List of const words
+ *
+ * @see elm_widget_stringlist_free()
+ * @ingroup Widget
+ */
+EAPI Eina_List *
+elm_widget_stringlist_get(const char *str)
+{
+   Eina_List *list = NULL;
+   const char *s, *b;
+   if (!str) return NULL;
+   for (b = s = str; 1; s++)
+     {
+       if ((*s == ' ') || (!*s))
+         {
+            char *t = malloc(s - b + 1);
+            if (t)
+              {
+                 strncpy(t, b, s - b);
+                 t[s - b] = 0;
+                 list = eina_list_append(list, eina_stringshare_add(t));
+                 free(t);
+              }
+            b = s + 1;
+         }
+       if (!*s) break;
+     }
+   return list;
+}
+
+EAPI void
+elm_widget_stringlist_free(Eina_List *list)
+{
+   const char *s;
+   EINA_LIST_FREE(list, s) eina_stringshare_del(s);
+}
+
+/**
+ * @internal
+ *
+ * Allocate a new Elm_Widget_Item-derived structure.
+ *
+ * The goal of this structure is to provide common ground for actions
+ * that a widget item have, such as the owner widget, callback to
+ * notify deletion, data pointer and maybe more.
+ *
+ * @param widget the owner widget that holds this item, must be an elm_widget!
+ * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
+ *        be used to allocate memory.
+ *
+ * @return allocated memory that is already zeroed out, or NULL on errors.
+ *
+ * @see elm_widget_item_new() convenience macro.
+ * @see elm_widget_item_del() to release memory.
+ * @ingroup Widget
+ */
+EAPI Elm_Widget_Item *
+_elm_widget_item_new(Evas_Object *widget, size_t alloc_size)
+{
+   if (!_elm_widget_is(widget))
+     return NULL;
+
+   Elm_Widget_Item *item;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(alloc_size < sizeof(Elm_Widget_Item), NULL);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!_elm_widget_is(widget), NULL);
+
+   item = calloc(1, alloc_size);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
+
+   EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
+   item->widget = widget;
+   return item;
+}
+
+/**
+ * @internal
+ *
+ * Releases widget item memory, calling back del_cb() if it exists.
+ *
+ * If there is a Elm_Widget_Item::del_cb, then it will be called prior
+ * to memory release. Note that elm_widget_item_pre_notify_del() calls
+ * this function and then unset it, thus being useful for 2 step
+ * cleanup whenever the del_cb may use any of the data that must be
+ * deleted from item.
+ *
+ * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
+ * is presented!
+ *
+ * @param item a valid #Elm_Widget_Item to be deleted.
+ * @see elm_widget_item_del() convenience macro.
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_del(Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
 
+   if (item->del_cb)
+     item->del_cb((void *)item->data, item->widget, item);
 
+   if (item->view)
+     evas_object_del(item->view);
 
+   EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
+   free(item);
+}
 
+/**
+ * @internal
+ *
+ * Notify object will be deleted without actually deleting it.
+ *
+ * This function will callback Elm_Widget_Item::del_cb if it is set
+ * and then unset it so it is not called twice (ie: from
+ * elm_widget_item_del()).
+ *
+ * @param item a valid #Elm_Widget_Item to be notified
+ * @see elm_widget_item_pre_notify_del() convenience macro.
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (!item->del_cb) return;
+   item->del_cb((void *)item->data, item->widget, item);
+   item->del_cb = NULL;
+}
+
+/**
+ * @internal
+ *
+ * Set the function to notify when item is being deleted.
+ *
+ * This function will complain if there was a callback set already,
+ * however it will set the new one.
+ *
+ * The callback will be called from elm_widget_item_pre_notify_del()
+ * or elm_widget_item_del() will be called with:
+ *   - data: the Elm_Widget_Item::data value.
+ *   - obj: the Elm_Widget_Item::widget evas object.
+ *   - event_info: the item being deleted.
+ *
+ * @param item a valid #Elm_Widget_Item to be notified
+ * @see elm_widget_item_del_cb_set() convenience macro.
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Smart_Cb del_cb)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+
+   if ((item->del_cb) && (item->del_cb != del_cb))
+     WRN("You're replacing a previously set del_cb %p of item %p with %p",
+         item->del_cb, item, del_cb);
+
+   item->del_cb = del_cb;
+}
+
+/**
+ * @internal
+ *
+ * Set user-data in this item.
+ *
+ * User data may be used to identify this item or just store any
+ * application data. It is automatically given as the first parameter
+ * of the deletion notify callback.
+ *
+ * @param item a valid #Elm_Widget_Item to store data in.
+ * @param data user data to store.
+ * @see elm_widget_item_del_cb_set() convenience macro.
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_data_set(Elm_Widget_Item *item, const void *data)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if ((item->data) && (item->data != data))
+     DBG("Replacing item %p data %p with %p", item, item->data, data);
+   item->data = data;
+}
+
+/**
+ * @internal
+ *
+ * Retrieves user-data of this item.
+ *
+ * @param item a valid #Elm_Widget_Item to get data from.
+ * @see elm_widget_item_data_set()
+ * @ingroup Widget
+ */
+EAPI void *
+_elm_widget_item_data_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   return (void *)item->data;
+}
 
+typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
 
+struct _Elm_Widget_Item_Tooltip
+{
+   Elm_Widget_Item             *item;
+   Elm_Tooltip_Item_Content_Cb  func;
+   Evas_Smart_Cb                del_cb;
+   const void                  *data;
+};
 
+static Evas_Object *
+_elm_widget_item_tooltip_label_create(void *data, Evas_Object *obj, void *item __UNUSED__)
+{
+   Evas_Object *label = elm_label_add(obj);
+   if (!label)
+     return NULL;
+   elm_object_style_set(label, "tooltip");
+   elm_label_label_set(label, data);
+   return label;
+}
 
+static void
+_elm_widget_item_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   eina_stringshare_del(data);
+}
+
+/**
+ * @internal
+ *
+ * Set the text to be shown in the widget item.
+ *
+ * @param item Target item
+ * @param text The text to set in the content
+ *
+ * Setup the text as tooltip to object. The item can have only one tooltip,
+ * so any previous tooltip data is removed.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   EINA_SAFETY_ON_NULL_RETURN(text);
 
+   text = eina_stringshare_add(text);
+   _elm_widget_item_tooltip_content_cb_set
+     (item, _elm_widget_item_tooltip_label_create, text,
+      _elm_widget_item_tooltip_label_del_cb);
+}
 
-/* local subsystem functions */
+static Evas_Object *
+_elm_widget_item_tooltip_create(void *data, Evas_Object *obj)
+{
+   Elm_Widget_Item_Tooltip *wit = data;
+   return wit->func((void *)wit->data, obj, wit->item);
+}
+
+static void
+_elm_widget_item_tooltip_del_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Elm_Widget_Item_Tooltip *wit = data;
+   if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item);
+   free(wit);
+}
+
+/**
+ * @internal
+ *
+ * Set the content to be shown in the tooltip item
+ *
+ * Setup the tooltip to item. The item can have only one tooltip,
+ * so any previous tooltip data is removed. @p func(with @p data) will
+ * be called every time that need show the tooltip and it should
+ * return a valid Evas_Object. This object is then managed fully by
+ * tooltip system and is deleted when the tooltip is gone.
+ *
+ * @param item the widget item being attached a tooltip.
+ * @param func the function used to create the tooltip contents.
+ * @param data what to provide to @a func as callback data/context.
+ * @param del_cb called when data is not needed anymore, either when
+ *        another callback replaces @func, the tooltip is unset with
+ *        elm_widget_item_tooltip_unset() or the owner @a item
+ *        dies. This callback receives as the first parameter the
+ *        given @a data, and @c event_info is the item.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
+{
+   Elm_Widget_Item_Tooltip *wit;
+
+   ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
+
+   if (!func)
+     {
+        _elm_widget_item_tooltip_unset(item);
+        return;
+     }
+
+   wit = ELM_NEW(Elm_Widget_Item_Tooltip);
+   if (!wit) goto error;
+   wit->item = item;
+   wit->func = func;
+   wit->data = data;
+   wit->del_cb = del_cb;
+
+   elm_object_sub_tooltip_content_cb_set
+     (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
+      _elm_widget_item_tooltip_del_cb);
+
+   return;
+
+ error_noitem:
+   if (del_cb) del_cb((void *)data, NULL, item);
+   return;
+ error:
+   if (del_cb) del_cb((void *)data, item->widget, item);
+}
+
+/**
+ * @internal
+ *
+ * Unset tooltip from item
+ *
+ * @param item widget item to remove previously set tooltip.
+ *
+ * Remove tooltip from item. The callback provided as del_cb to
+ * elm_widget_item_tooltip_content_cb_set() will be called to notify
+ * it is not used anymore.
+ *
+ * @see elm_widget_item_tooltip_content_cb_set()
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_tooltip_unset(item->view);
+}
+
+/**
+ * @internal
+ *
+ * Sets a different style for this item tooltip.
+ *
+ * @note before you set a style you should define a tooltip with
+ *       elm_widget_item_tooltip_content_cb_set() or
+ *       elm_widget_item_tooltip_text_set()
+ *
+ * @param item widget item with tooltip already set.
+ * @param style the theme style to use (default, transparent, ...)
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_tooltip_style_set(Elm_Widget_Item *item, const char *style)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_tooltip_style_set(item->view, style);
+}
+
+/**
+ * @internal
+ *
+ * Get the style for this item tooltip.
+ *
+ * @param item widget item with tooltip already set.
+ * @return style the theme style in use, defaults to "default". If the
+ *         object does not have a tooltip set, then NULL is returned.
+ *
+ * @ingroup Widget
+ */
+EAPI const char *
+_elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   return elm_object_tooltip_style_get(item->view);
+}
+
+EAPI void
+_elm_widget_item_cursor_set(Elm_Widget_Item *item, const char *cursor)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_sub_cursor_set(item->view, item->widget, cursor);
+}
+
+EAPI const char *
+_elm_widget_item_cursor_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   return elm_object_cursor_get(item->view);
+}
+
+EAPI void
+_elm_widget_item_cursor_unset(Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_cursor_unset(item->view);
+}
+
+/**
+ * @internal
+ *
+ * Sets a different style for this item cursor.
+ *
+ * @note before you set a style you should define a cursor with
+ *       elm_widget_item_cursor_set()
+ *
+ * @param item widget item with cursor already set.
+ * @param style the theme style to use (default, transparent, ...)
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_cursor_style_set(Elm_Widget_Item *item, const char *style)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_cursor_style_set(item->view, style);
+}
+
+/**
+ * @internal
+ *
+ * Get the style for this item cursor.
+ *
+ * @param item widget item with cursor already set.
+ * @return style the theme style in use, defaults to "default". If the
+ *         object does not have a cursor set, then NULL is returned.
+ *
+ * @ingroup Widget
+ */
+EAPI const char *
+_elm_widget_item_cursor_style_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   return elm_object_cursor_style_get(item->view);
+}
+
+/**
+ * @internal
+ *
+ * Set if the cursor set should be searched on the theme or should use
+ * the provided by the engine, only.
+ *
+ * @note before you set if should look on theme you should define a cursor
+ * with elm_object_cursor_set(). By default it will only look for cursors
+ * provided by the engine.
+ *
+ * @param item widget item with cursor already set.
+ * @param engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well.
+ *
+ * @ingroup Widget
+ */
+EAPI void
+_elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item, Eina_Bool engine_only)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   elm_object_cursor_engine_only_set(item->view, engine_only);
+}
+
+/**
+ * @internal
+ *
+ * Get the cursor engine only usage for this item cursor.
+ *
+ * @param item widget item with cursor already set.
+ * @return engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well. If
+ *         the object does not have a cursor set, then EINA_FALSE is returned.
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_Bool
+_elm_widget_item_cursor_engine_only_get(const Elm_Widget_Item *item)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
+   return elm_object_cursor_engine_only_get(item->view);
+}
+
+// smart object funcs
 static void
 _smart_reconfigure(Smart_Data *sd)
 {
@@ -1196,16 +2412,13 @@ _smart_add(Evas_Object *obj)
    sd = calloc(1, sizeof(Smart_Data));
    if (!sd) return;
    sd->obj = obj;
-   sd->x = 0;
-   sd->y = 0;
-   sd->w = 0;
-   sd->h = 0;
+   sd->x = sd->y = sd->w = sd->h = 0;
    sd->can_focus = 1;
    evas_object_smart_data_set(obj, sd);
 }
 
 static Evas_Object *
-_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order)
+_newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
 {
    const Eina_List *l;
    Evas_Object *child, *ret, *best;
@@ -1220,29 +2433,30 @@ _newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order)
      }
    EINA_LIST_FOREACH(sd->subobjs, l, child)
      {
-        ret = _newest_focus_order_get(child, newest_focus_order);
+        ret = _newest_focus_order_get(child, newest_focus_order, can_focus_only);
         if (!ret) continue;
         best = ret;
      }
+   if ((can_focus_only) && (!elm_widget_can_focus_get(best))) return NULL;
    return best;
 }
 
 static void
-_if_focused_revert(Evas_Object *obj)
+_if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only)
 {
    Evas_Object *top;
    Evas_Object *newest = NULL;
    unsigned int newest_focus_order = 0;
    
    INTERNAL_ENTRY;
-   
+
    if (!sd->focused) return;
    if (!sd->parent_obj) return;
 
    top = elm_widget_top_get(sd->parent_obj);
    if (top)
      {
-        newest = _newest_focus_order_get(top, &newest_focus_order);
+        newest = _newest_focus_order_get(top, &newest_focus_order, can_focus_only);
         if (newest)
           {
              elm_object_unfocus(newest);
@@ -1255,8 +2469,10 @@ static void
 _smart_del(Evas_Object *obj)
 {
    Evas_Object *sobj;
+   Edje_Signal_Data *esd;
 
    INTERNAL_ENTRY;
+
    if (sd->del_pre_func) sd->del_pre_func(obj);
    if (sd->resize_obj)
      {
@@ -1280,11 +2496,20 @@ _smart_del(Evas_Object *obj)
        evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
        evas_object_del(sobj);
      }
+   eina_list_free(sd->tooltips); /* should be empty anyway */
+   eina_list_free(sd->cursors); /* should be empty anyway */
+   EINA_LIST_FREE(sd->edje_signals, esd)
+     {
+        eina_stringshare_del(esd->emission);
+        eina_stringshare_del(esd->source);
+        free(esd);
+     }
+   eina_list_free(sd->event_cb); /* should be empty anyway */
    if (sd->del_func) sd->del_func(obj);
    if (sd->style) eina_stringshare_del(sd->style);
    if (sd->type) eina_stringshare_del(sd->type);
    if (sd->theme) elm_theme_free(sd->theme);
-   _if_focused_revert(obj);
+   _if_focused_revert(obj, EINA_TRUE);
    free(sd);
 }
 
@@ -1309,71 +2534,79 @@ _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
 static void
 _smart_show(Evas_Object *obj)
 {
-   Eina_List *list, *l;
+   Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
-   list = evas_object_smart_members_get(obj);
-   EINA_LIST_FOREACH(list, l, o)
+   if ((list = evas_object_smart_members_get(obj)))
      {
-        if (evas_object_data_get(o, "_elm_leaveme")) continue;
-        evas_object_show(o);
+        EINA_LIST_FREE(list, o)
+          {
+             if (evas_object_data_get(o, "_elm_leaveme")) continue;
+             evas_object_show(o);
+          }
      }
 }
 
 static void
 _smart_hide(Evas_Object *obj)
 {
-   Eina_List *list, *l;
+   Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
    list = evas_object_smart_members_get(obj);
-   EINA_LIST_FOREACH(list, l, o)
+   EINA_LIST_FREE(list, o)
      {
         if (evas_object_data_get(o, "_elm_leaveme")) continue;
         evas_object_hide(o);
      }
-   _if_focused_revert(obj);
+   _if_focused_revert(obj, EINA_TRUE);
 }
 
 static void
 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
 {
-   Eina_List *list, *l;
+   Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
-   list = evas_object_smart_members_get(obj);
-   EINA_LIST_FOREACH(list, l, o)
+   if ((list = evas_object_smart_members_get(obj)))
      {
-        if (evas_object_data_get(o, "_elm_leaveme")) continue;
-        evas_object_color_set(o, r, g, b, a);
+        EINA_LIST_FREE(list, o)
+          {
+             if (evas_object_data_get(o, "_elm_leaveme")) continue;
+             evas_object_color_set(o, r, g, b, a);
+          }
      }
 }
 
 static void
 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
 {
-   Eina_List *list, *l;
+   Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
-   list = evas_object_smart_members_get(obj);
-   EINA_LIST_FOREACH(list, l, o)
+   if ((list = evas_object_smart_members_get(obj)))
      {
-        if (evas_object_data_get(o, "_elm_leaveme")) continue;
-        evas_object_clip_set(o, clip);
+        EINA_LIST_FREE(list, o)
+          {
+             if (evas_object_data_get(o, "_elm_leaveme")) continue;
+             evas_object_clip_set(o, clip);
+          }
      }
 }
 
 static void
 _smart_clip_unset(Evas_Object *obj)
 {
-   Eina_List *list, *l;
+   Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY;
-   list = evas_object_smart_members_get(obj);
-   EINA_LIST_FOREACH(list, l, o)
+   if ((list = evas_object_smart_members_get(obj)))
      {
-        if (evas_object_data_get(o, "_elm_leaveme")) continue;
-        evas_object_clip_unset(o);
+        EINA_LIST_FREE(list, o)
+          {
+             if (evas_object_data_get(o, "_elm_leaveme")) continue;
+             evas_object_clip_unset(o);
+          }
      }
 }
 
@@ -1385,7 +2618,6 @@ _smart_calculate(Evas_Object *obj)
 }
 
 /* never need to touch this */
-
 static void
 _smart_init(void)
 {
@@ -1394,89 +2626,128 @@ _smart_init(void)
        static const Evas_Smart_Class sc =
          {
             SMART_NAME,
-              EVAS_SMART_CLASS_VERSION,
-              _smart_add,
-              _smart_del,
-              _smart_move,
-              _smart_resize,
-              _smart_show,
-              _smart_hide,
-              _smart_color_set,
-              _smart_clip_set,
-              _smart_clip_unset,
-              _smart_calculate,
-              NULL,
-              NULL,
-              NULL,
-               NULL,
-               NULL,
-               NULL
+             EVAS_SMART_CLASS_VERSION,
+             _smart_add,
+             _smart_del,
+             _smart_move,
+             _smart_resize,
+             _smart_show,
+             _smart_hide,
+             _smart_color_set,
+             _smart_clip_set,
+             _smart_clip_unset,
+             _smart_calculate,
+             NULL,
+             NULL,
+             NULL,
+             NULL,
+             NULL,
+             NULL
          };
        _e_smart = evas_smart_class_new(&sc);
      }
 }
 
-/* utilities */
-
-Eina_List *
-_elm_stringlist_get(const char *str)
+/* happy debug functions */
+#ifdef ELM_DEBUG
+static void
+_sub_obj_tree_dump(const Evas_Object *o, int lvl)
 {
-   Eina_List *list = NULL;
-   const char *s, *b;
-   if (!str) return NULL;
-   for (b = s = str; 1; s++)
+   int i;
+
+   for (i = 0; i < lvl*3; i++)
+     putchar(' ');
+
+   if (_elm_widget_is(o))
      {
-       if ((*s == ' ') || (*s == 0))
-         {
-            char *t = malloc(s - b + 1);
-            if (t)
-              {
-                 strncpy(t, b, s - b);
-                 t[s - b] = 0;
-                 list = eina_list_append(list, eina_stringshare_add(t));
-                 free(t);
-              }
-            b = s + 1;
-         }
-       if (*s == 0) break;
+        Eina_List *l;
+        Smart_Data *sd = evas_object_smart_data_get(o);
+        printf("+ %s(%p)\n", sd->type, o);
+        if (sd->resize_obj)
+          _sub_obj_tree_dump(sd->resize_obj, lvl + 1);
+        EINA_LIST_FOREACH(sd->subobjs, l, o)
+          {
+             if (o != sd->resize_obj)
+               _sub_obj_tree_dump(o, lvl + 1);
+          }
      }
-   return list;
+   else
+     printf("+ %s(%p)\n", evas_object_type_get(o), o);
 }
 
-void
-_elm_stringlist_free(Eina_List *list)
+static void
+_sub_obj_tree_dot_dump(const Evas_Object *obj, FILE *output)
 {
-   const char *s;
-   EINA_LIST_FREE(list, s) eina_stringshare_del(s);
-}
+   if (!_elm_widget_is(obj))
+     return;
 
-Eina_Bool
-_elm_widget_type_check(const Evas_Object *obj, const char *type)
-{
-   const char *provided, *expected = "(unknown)";
-   static int abort_on_warn = -1;
-   provided = elm_widget_type_get(obj);
-   if (EINA_LIKELY(provided == type)) return EINA_TRUE;
-   if (type) expected = type;
-   if ((!provided) || (provided[0] == 0))
-     {
-        provided = evas_object_type_get(obj);
-        if ((!provided) || (provided[0] == 0))
-          provided = "(unknown)";
-     }
-   ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
-   if (abort_on_warn == -1)
+   Smart_Data *sd = evas_object_smart_data_get(obj);
+
+   Eina_Bool visible = evas_object_visible_get(obj);
+   Eina_Bool disabled = elm_widget_disabled_get(obj);
+   Eina_Bool focused = elm_widget_focus_get(obj);
+   Eina_Bool can_focus = elm_widget_can_focus_get(obj);
+
+   if (sd->parent_obj)
      {
-        if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
-        else abort_on_warn = 0;
+        fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
+
+        if (focused)
+          fprintf(output, ", style=bold");
+
+        if (!visible)
+          fprintf(output, ", color=gray28");
+
+        fprintf(output, " ];\n");
      }
-   if (abort_on_warn == 1) abort();
-   return EINA_FALSE;
+
+   fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
+           "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type,
+           evas_object_name_get(obj), visible, disabled, focused, can_focus,
+           sd->focus_order);
+
+   if (focused)
+        fprintf(output, ", style=bold");
+
+   if (!visible)
+        fprintf(output, ", fontcolor=gray28");
+
+   if ((disabled) || (!visible))
+        fprintf(output, ", color=gray");
+
+
+   fprintf(output, " ];\n");
+
+   Eina_List *l;
+   Evas_Object *o;
+   EINA_LIST_FOREACH(sd->subobjs, l, o)
+      _sub_obj_tree_dot_dump(o, output);
 }
+#endif
 
-static inline Eina_Bool
-_elm_widget_is(const Evas_Object *obj)
+EAPI void
+elm_widget_tree_dump(const Evas_Object *top)
 {
-   const char *type = evas_object_type_get(obj);
-   return type == SMART_NAME;
+#ifdef ELM_DEBUG
+   _sub_obj_tree_dump(top, 0);
+#else
+   return;
+   (void)top;
+#endif
+}
+
+EAPI void
+elm_widget_tree_dot_dump(const Evas_Object *top, FILE *output)
+{
+#ifdef ELM_DEBUG
+   if (!_elm_widget_is(top))
+     return;
+   fprintf(output, "graph "" { node [shape=record];\n");
+   _sub_obj_tree_dot_dump(top, output);
+   fprintf(output, "}\n");
+#else
+   return;
+   (void)top;
+   (void)output;
+#endif
 }
diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h
new file mode 100644 (file)
index 0000000..bb25156
--- /dev/null
@@ -0,0 +1,545 @@
+#ifndef ELM_WIDGET_H
+#define ELM_WIDGET_H
+
+/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR
+ * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT
+ * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK IT
+ * AT RUNTIME
+ * 
+ * How to make your own widget? like this:
+ * 
+ * #include <Elementary.h>
+ * #include "elm_priv.h"
+ * 
+ * typedef struct _Widget_Data Widget_Data;
+ *    
+ * struct _Widget_Data
+ * {
+ *   Evas_Object *sub;
+ *   // add any other widget data here too
+ * };
+ * 
+ * static const char *widtype = NULL;
+ * static void _del_hook(Evas_Object *obj);
+ * static void _theme_hook(Evas_Object *obj);
+ * static void _disable_hook(Evas_Object *obj);
+ * static void _sizing_eval(Evas_Object *obj);
+ * static void _on_focus_hook(void *data, Evas_Object *obj);
+ * 
+ * static const char SIG_CLICKED[] = "clicked";
+ * static const Evas_Smart_Cb_Description _signals[] = {
+ *   {SIG_CLICKED, ""},
+ *   {NULL, NULL}
+ * };
+ * 
+ * static void
+ * _del_hook(Evas_Object *obj)
+ * {
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    if (!wd) return;
+ *    // delete hook - on delete of object delete object struct etc.
+ *    free(wd);
+ * }
+ * 
+ * static void
+ * _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+ * {
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    if (!wd) return;
+ *    // handle focus going in and out - optional, but if you want to, set
+ *    // this hook and handle it (eg emit a signal to an edje obj)
+ *    if (elm_widget_focus_get(obj))
+ *      {
+ *         edje_object_signal_emit(wd->sub, "elm,action,focus", "elm");
+ *         evas_object_focus_set(wd->sub, EINA_TRUE);
+ *      }
+ *    else
+ *      {
+ *         edje_object_signal_emit(wd->sub, "elm,action,unfocus", "elm");
+ *         evas_object_focus_set(wd->sub, EINA_FALSE);
+ *      }
+ * }
+ * 
+ * static void
+ * _theme_hook(Evas_Object *obj)
+ * {
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    if (!wd) return;
+ *    // handle change in theme/scale etc.
+ *    elm_widget_theme_object_set(obj, wd->sub, "mywidget", "base", 
+ *                                elm_widget_style_get(obj));
+ * }
+ * 
+ * static void
+ * _disable_hook(Evas_Object *obj)
+ * {
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    if (!wd) return;
+ *    // optional, but handle if the widget gets disabled or not
+ *    if (elm_widget_disabled_get(obj))
+ *      edje_object_signal_emit(wd->sub, "elm,state,disabled", "elm");
+ *    else
+ *      edje_object_signal_emit(wd->sub, "elm,state,enabled", "elm");
+ * }
+ * 
+ * static void
+ * _sizing_eval(Evas_Object *obj)
+ * {
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
+ *    if (!wd) return;
+ *    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ *    edje_object_size_min_restricted_calc(wd->sub, &minw, &minh, minw, minh);
+ *    elm_coords_finger_size_adjust(1, &minw, 1, &minh);
+ *    evas_object_size_hint_min_set(obj, minw, minh);
+ *    evas_object_size_hint_max_set(obj, maxw, maxh);
+ * }
+ * 
+ * // actual api to create your widget. add more to manipulate it as needed
+ * // mark your calls with EAPI to make them "external api" calls.
+ * EAPI Evas_Object *
+ * elm_mywidget_add(Evas_Object *parent)
+ * {
+ *    Evas_Object *obj;
+ *    Evas *e;
+ *    Widget_Data *wd;
+ * 
+ *    // ALWAYS call this - this checks that your widget matches that of
+ *    // elementary and that the api hasn't broken. if it has this returns
+ *    // false and you need to handle this error gracefully
+ *    if (!elm_widget_api_check(ELM_INTERNAL_API_VERSION)) return NULL;
+ * 
+ *    // basic - allocate data for widget and fill it
+ *    wd = ELM_NEW(Widget_Data);
+ *    e = evas_object_evas_get(parent);
+ *    if (!e) return NULL;
+ *    obj = elm_widget_add(e);
+ *    // give it a type name and set up a mywidget type string if needed
+ *    ELM_SET_WIDTYPE(widtype, "mywidget");
+ *    elm_widget_type_set(obj, "mywidget");
+ *    // tell the parent widget that we are a sub object
+ *    elm_widget_sub_object_add(parent, obj);
+ *    // setup hooks we need (some are optional)
+ *    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
+ *    elm_widget_data_set(obj, wd);
+ *    elm_widget_del_hook_set(obj, _del_hook);
+ *    elm_widget_theme_hook_set(obj, _theme_hook);
+ *    elm_widget_disable_hook_set(obj, _disable_hook);
+ *    // this widget can focus (true means yes it can, false means it can't)
+ *    elm_widget_can_focus_set(obj, EINA_TRUE);
+ * 
+ *    // for this widget we will add 1 sub object that is an edje object
+ *    wd->sub = edje_object_add(e);
+ *    // set the theme. this follows a scheme for group name like this:
+ *    //   "elm/WIDGETNAME/ELEMENT/STYLE"
+ *    // so here it will be:
+ *    //   "elm/mywidget/base/default"
+ *    // changing style changes style name from default (all widgets start
+ *    // with the default style) and element is for your widget internal
+ *    // structure as you see fit
+ *    elm_widget_theme_object_set(obj, wd->sub, "mywidget", "base", "default");
+ *    // listen to a signal from the edje object to produce widget smart
+ *    // callback (like click)
+ *    edje_object_signal_callback_add(wd->sub, "elm,action,click", "",
+ *                                    _signal_clicked, obj);
+ *    // set this sub object as the "resize object". widgets get 1 resize
+ *    // object that is resized along with the object wrapper.
+ *    elm_widget_resize_object_set(obj, wd->sub);
+ * 
+ *    // evaluate sizing of the widget (minimum size calc etc.). optional but
+ *    // not a bad idea to do here. it will get queued for later anyway
+ *    _sizing_eval(obj);
+ * 
+ *    // register the smart callback descriptions so we can have some runtime
+ *    // info as to what the smart callback strings mean
+ *    evas_object_smart_callbacks_descriptions_set(obj, _signals);
+ *    return obj;
+ * }
+ * 
+ * // example - do "whatever" to the widget (here just emit a signal)
+ * EAPI void
+ * elm_mywidget_whatever(Evas_Object *obj)
+ * {
+ *    // check if type is correct - check will return if it fails
+ *    ELM_CHECK_WIDTYPE(obj, widtype);
+ *    // get widget data - type is correct and sane by this point, so this
+ *    // should never fail
+ *    Widget_Data *wd = elm_widget_data_get(obj);
+ *    // do whatever you like
+ *    edje_object_signal_emit(wd->sub, "elm,state,action,whatever", "elm");
+ * }
+ * 
+ * // you can add more - you need to see elementary's code to know how to
+ * // handle all cases. remember this api is not stable and may change. it's
+ * // internal
+ * 
+ */
+
+#ifndef ELM_INTERAL_API_MDFGELQ
+# warning "You are using an internal elementary API. This API is not stable"
+# warning "and is subject to change. You use this at your own risk."
+# warning "Remember to call elm_widget_api_check(ELM_INTERNAL_API_VERSION);"
+# warning "in your widgets before you call any other elm_widget calls to do"
+# warning "a correct runtime version check."
+#endif
+#define ELM_INTERNAL_API_VERSION 7000
+
+typedef struct _Elm_Tooltip Elm_Tooltip;
+typedef struct _Elm_Cursor Elm_Cursor;
+typedef struct _Elm_Widget_Item Elm_Widget_Item; /**< base structure for all widget items that are not Elm_Widget themselves */
+
+struct _Elm_Widget_Item
+{
+   /* ef1 ~~ efl, el3 ~~ elm */
+#define ELM_WIDGET_ITEM_MAGIC 0xef1e1301
+   EINA_MAGIC;
+   
+   Evas_Object   *widget; /**< the owner widget that owns this item */
+   Evas_Object   *view; /**< the base view object */
+   const void    *data; /**< item specific data */
+   Evas_Smart_Cb  del_cb; /**< used to notify the item is being deleted */
+   /* widget variations should have data from here and on */
+   /* @todo: TODO check if this is enough for 1.0 release, maybe add padding! */
+};
+
+#define ELM_NEW(t) calloc(1, sizeof(t))
+
+EAPI Eina_Bool        elm_widget_api_check(int ver);
+EAPI Evas_Object     *elm_widget_add(Evas *evas);
+EAPI void             elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_event_hook_set(Evas_Object *obj, Eina_Bool (*func) (Evas_Object *obj, Evas_Object *source, Evas_Callback_Type type, void *event_info));
+EAPI void             elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj));
+EAPI void             elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source));
+EAPI void             elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
+EAPI void             elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
+EAPI void             elm_widget_theme(Evas_Object *obj);
+EAPI void             elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force);
+EAPI void             elm_widget_focus_next_hook_set(Evas_Object *obj, Eina_Bool (*func) (const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next));
+EAPI void             elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void             elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void             elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
+EAPI void             elm_widget_focus_region_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h));
+EAPI void             elm_widget_on_focus_region_hook_set(Evas_Object *obj, void (*func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h));
+EAPI void             elm_widget_data_set(Evas_Object *obj, void *data);
+EAPI void            *elm_widget_data_get(const Evas_Object *obj);
+EAPI void             elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj);
+EAPI void             elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj);
+EAPI void             elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj);
+EAPI void             elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj);
+EAPI void             elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source);
+EAPI void             elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data);
+EAPI void            *elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source));
+EAPI void             elm_widget_can_focus_set(Evas_Object *obj, Eina_Bool can_focus);
+EAPI Eina_Bool        elm_widget_can_focus_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_child_can_focus_get(const Evas_Object *obj);
+EAPI void             elm_widget_highlight_ignore_set(Evas_Object *obj, Eina_Bool ignore);
+EAPI Eina_Bool        elm_widget_highlight_ignore_get(const Evas_Object *obj);
+EAPI void             elm_widget_highlight_in_theme_set(Evas_Object *obj, Eina_Bool highlight);
+EAPI Eina_Bool        elm_widget_highlight_in_theme_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_focus_get(const Evas_Object *obj);
+EAPI Evas_Object     *elm_widget_focused_object_get(const Evas_Object *obj);
+EAPI Evas_Object     *elm_widget_top_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_is(const Evas_Object *obj);
+EAPI Evas_Object     *elm_widget_parent_widget_get(const Evas_Object *obj);
+EAPI void             elm_widget_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data);
+EAPI void            *elm_widget_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data);
+EAPI Eina_Bool        elm_widget_event_propagate(Evas_Object *obj, Evas_Callback_Type type, void *event_info, Evas_Event_Flags *event_flags);
+EAPI void             elm_widget_focus_custom_chain_set(Evas_Object *obj, Eina_List *objs);
+EAPI void             elm_widget_focus_custom_chain_unset(Evas_Object *obj);
+EAPI const Eina_List *elm_widget_focus_custom_chain_get(const Evas_Object *obj);
+EAPI void             elm_widget_focus_custom_chain_append(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child);
+EAPI void             elm_widget_focus_custom_chain_prepend(Evas_Object *obj, Evas_Object *child, Evas_Object *relative_child);
+EAPI void             elm_widget_focus_cycle(Evas_Object *obj, Elm_Focus_Direction dir);
+EAPI void             elm_widget_focus_direction_go(Evas_Object *obj, int x, int y);
+EAPI Eina_Bool        elm_widget_focus_next_get(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next);
+EAPI Eina_Bool        elm_widget_focus_list_next_get(const Evas_Object *obj, const Eina_List *items, void *(*list_data_get) (const Eina_List *list), Elm_Focus_Direction dir, Evas_Object **next);
+EAPI void             elm_widget_focus_set(Evas_Object *obj, int first);
+EAPI void             elm_widget_focused_object_clear(Evas_Object *obj);
+EAPI Evas_Object     *elm_widget_parent_get(const Evas_Object *obj);
+EAPI void             elm_widget_focus_steal(Evas_Object *obj);
+EAPI void             elm_widget_activate(Evas_Object *obj);
+EAPI void             elm_widget_change(Evas_Object *obj);
+EAPI void             elm_widget_disabled_set(Evas_Object *obj, int disabled);
+EAPI int              elm_widget_disabled_get(const Evas_Object *obj);
+EAPI void             elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+EAPI void             elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+EAPI void             elm_widget_focus_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+EAPI void             elm_widget_scroll_hold_push(Evas_Object *obj);
+EAPI void             elm_widget_scroll_hold_pop(Evas_Object *obj);
+EAPI int              elm_widget_scroll_hold_get(const Evas_Object *obj);
+EAPI void             elm_widget_scroll_freeze_push(Evas_Object *obj);
+EAPI void             elm_widget_scroll_freeze_pop(Evas_Object *obj);
+EAPI int              elm_widget_scroll_freeze_get(const Evas_Object *obj);
+EAPI void             elm_widget_scale_set(Evas_Object *obj, double scale);
+EAPI double           elm_widget_scale_get(const Evas_Object *obj);
+EAPI void             elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th);
+EAPI Elm_Theme       *elm_widget_theme_get(const Evas_Object *obj);
+EAPI void             elm_widget_style_set(Evas_Object *obj, const char *style);
+EAPI const char      *elm_widget_style_get(const Evas_Object *obj);
+EAPI void             elm_widget_type_set(Evas_Object *obj, const char *type);
+EAPI const char      *elm_widget_type_get(const Evas_Object *obj);
+EAPI void             elm_widget_tooltip_add(Evas_Object *obj, Elm_Tooltip *tt);
+EAPI void             elm_widget_tooltip_del(Evas_Object *obj, Elm_Tooltip *tt);
+EAPI void             elm_widget_cursor_add(Evas_Object *obj, Elm_Cursor *cur);
+EAPI void             elm_widget_cursor_del(Evas_Object *obj, Elm_Cursor *cur);
+EAPI void             elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock);
+EAPI void             elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock);
+EAPI Eina_Bool        elm_widget_drag_lock_x_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_drag_lock_y_get(const Evas_Object *obj);
+EAPI int              elm_widget_drag_child_locked_x_get(const Evas_Object *obj);
+EAPI int              elm_widget_drag_child_locked_y_get(const Evas_Object *obj);
+EAPI Eina_Bool        elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle);
+EAPI void             elm_widget_type_register(const char **ptr);
+EAPI Eina_Bool        elm_widget_type_check(const Evas_Object *obj, const char *type);
+EAPI Eina_List       *elm_widget_stringlist_get(const char *str);
+EAPI void             elm_widget_stringlist_free(Eina_List *list);
+
+EAPI Elm_Widget_Item *_elm_widget_item_new(Evas_Object *parent, size_t alloc_size);
+EAPI void             _elm_widget_item_del(Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_pre_notify_del(Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_del_cb_set(Elm_Widget_Item *item, Evas_Smart_Cb del_cb);
+EAPI void             _elm_widget_item_data_set(Elm_Widget_Item *item, const void *data);
+EAPI void            *_elm_widget_item_data_get(const Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item, const char *text);
+EAPI void             _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item, Elm_Tooltip_Item_Content_Cb func, const void *data, Evas_Smart_Cb del_cb);
+EAPI void             _elm_widget_item_tooltip_unset(Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_tooltip_style_set(Elm_Widget_Item *item, const char *style);
+EAPI const char      *_elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_cursor_set(Elm_Widget_Item *item, const char *cursor);
+EAPI const char      *_elm_widget_item_cursor_get(const Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_cursor_unset(Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_cursor_style_set(Elm_Widget_Item *item, const char *style);
+EAPI const char      *_elm_widget_item_cursor_style_get(const Elm_Widget_Item *item);
+EAPI void             _elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item, Eina_Bool engine_only);
+EAPI Eina_Bool        _elm_widget_item_cursor_engine_only_get(const Elm_Widget_Item *item);
+
+/* debug function. don't use it unless you are tracking parenting issues */
+EAPI void             elm_widget_tree_dump(const Evas_Object *top);
+EAPI void             elm_widget_tree_dot_dump(const Evas_Object *top, FILE *output);
+
+/**
+ * Convenience macro to create new widget item, doing casts for you.
+ * @see _elm_widget_item_new()
+ * @param parent a valid elm_widget variant.
+ * @param type the C type that extends Elm_Widget_Item
+ */
+#define elm_widget_item_new(parent, type) \
+  (type *)_elm_widget_item_new((parent), sizeof(type))
+/**
+ * Convenience macro to delete widget item, doing casts for you.
+ * @see _elm_widget_item_del()
+ * @param item a valid item.
+ */
+#define elm_widget_item_del(item) \
+  _elm_widget_item_del((Elm_Widget_Item *)item)
+/**
+ * Convenience macro to notify deletion of widget item, doing casts for you.
+ * @see _elm_widget_item_pre_notify_del()
+ */
+#define elm_widget_item_pre_notify_del(item) \
+  _elm_widget_item_pre_notify_del((Elm_Widget_Item *)item)
+/**
+ * Convenience macro to set deletion callback of widget item, doing casts for you.
+ * @see _elm_widget_item_del_cb_set()
+ */
+#define elm_widget_item_del_cb_set(item, del_cb) \
+  _elm_widget_item_del_cb_set((Elm_Widget_Item *)item, del_cb)
+
+/**
+ * Set item's data
+ * @see _elm_widget_item_data_set()
+ */
+#define elm_widget_item_data_set(item, data) \
+  _elm_widget_item_data_set((Elm_Widget_Item *)item, data)
+/**
+ * Get item's data
+ * @see _elm_widget_item_data_get()
+ */
+#define elm_widget_item_data_get(item) \
+  _elm_widget_item_data_get((const Elm_Widget_Item *)item)
+
+/**
+ * Convenience function to set widget item tooltip as a text string.
+ * @see _elm_widget_item_tooltip_text_set()
+ */
+#define elm_widget_item_tooltip_text_set(item, text) \
+  _elm_widget_item_tooltip_text_set((Elm_Widget_Item *)item, text)
+/**
+ * Convenience function to set widget item tooltip.
+ * @see _elm_widget_item_tooltip_content_cb_set()
+ */
+#define elm_widget_item_tooltip_content_cb_set(item, func, data, del_cb) \
+  _elm_widget_item_tooltip_content_cb_set((Elm_Widget_Item *)item, \
+                                          func, data, del_cb)
+/**
+ * Convenience function to unset widget item tooltip.
+ * @see _elm_widget_item_tooltip_unset()
+ */
+#define elm_widget_item_tooltip_unset(item) \
+  _elm_widget_item_tooltip_unset((Elm_Widget_Item *)item)
+/**
+ * Convenience function to change item's tooltip style.
+ * @see _elm_widget_item_tooltip_style_set()
+ */
+#define elm_widget_item_tooltip_style_set(item, style) \
+  _elm_widget_item_tooltip_style_set((Elm_Widget_Item *)item, style)
+/**
+ * Convenience function to query item's tooltip style.
+ * @see _elm_widget_item_tooltip_style_get()
+ */
+#define elm_widget_item_tooltip_style_get(item) \
+  _elm_widget_item_tooltip_style_get((const Elm_Widget_Item *)item)
+/**
+ * Convenience function to set widget item cursor.
+ * @see _elm_widget_item_cursor_set()
+ */
+#define elm_widget_item_cursor_set(item, cursor) \
+  _elm_widget_item_cursor_set((Elm_Widget_Item *)item, cursor)
+/**
+ * Convenience function to get widget item cursor.
+ * @see _elm_widget_item_cursor_get()
+ */
+#define elm_widget_item_cursor_get(item) \
+  _elm_widget_item_cursor_get((const Elm_Widget_Item *)item)
+/**
+ * Convenience function to unset widget item cursor.
+ * @see _elm_widget_item_cursor_unset()
+ */
+#define elm_widget_item_cursor_unset(item) \
+  _elm_widget_item_cursor_unset((Elm_Widget_Item *)item)
+/**
+ * Convenience function to change item's cursor style.
+ * @see _elm_widget_item_cursor_style_set()
+ */
+#define elm_widget_item_cursor_style_set(item, style) \
+  _elm_widget_item_cursor_style_set((Elm_Widget_Item *)item, style)
+/**
+ * Convenience function to query item's cursor style.
+ * @see _elm_widget_item_cursor_style_get()
+ */
+#define elm_widget_item_cursor_style_get(item) \
+  _elm_widget_item_cursor_style_get((const Elm_Widget_Item *)item)
+/**
+ * Convenience function to change item's cursor engine_only.
+ * @see _elm_widget_item_cursor_engine_only_set()
+ */
+#define elm_widget_item_cursor_engine_only_set(item, engine_only) \
+  _elm_widget_item_cursor_engine_only_set((Elm_Widget_Item *)item, engine_only)
+/**
+ * Convenience function to query item's cursor engine_only.
+ * @see _elm_widget_item_cursor_engine_only_get()
+ */
+#define elm_widget_item_cursor_engine_only_get(item) \
+  _elm_widget_item_cursor_engine_only_get((const Elm_Widget_Item *)item)
+
+/**
+ * Cast and ensure the given pointer is an Elm_Widget_Item or return NULL.
+ */
+#define ELM_WIDGET_ITEM(item) \
+   (((item) && (EINA_MAGIC_CHECK(item, ELM_WIDGET_ITEM_MAGIC))) ? \
+       ((Elm_Widget_Item *)(item)) : NULL)
+
+#define ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, ...) \
+   do { \
+      if (!item) { \
+         CRITICAL("Elm_Widget_Item " # item " is NULL!"); \
+         return __VA_ARGS__; \
+      } \
+      if (!EINA_MAGIC_CHECK(item, ELM_WIDGET_ITEM_MAGIC)) { \
+         EINA_MAGIC_FAIL(item, ELM_WIDGET_ITEM_MAGIC); \
+         return __VA_ARGS__; \
+      } \
+   } while (0)
+
+#define ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, label) \
+   do { \
+      if (!item) { \
+         CRITICAL("Elm_Widget_Item " # item " is NULL!"); \
+         goto label; \
+      } \
+      if (!EINA_MAGIC_CHECK(item, ELM_WIDGET_ITEM_MAGIC)) { \
+         EINA_MAGIC_FAIL(item, ELM_WIDGET_ITEM_MAGIC); \
+         goto label; \
+      } \
+   } while (0)
+
+#define ELM_SET_WIDTYPE(widtype, type) \
+   do { \
+      if (!widtype) { \
+         widtype = eina_stringshare_add(type); \
+         elm_widget_type_register(&widtype); \
+      } \
+   } while (0)
+
+#define ELM_CHECK_WIDTYPE(obj, widtype) \
+   if (!elm_widget_type_check((obj), (widtype))) return
+
+#define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(it, ...)                \
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
+   ELM_CHECK_WIDTYPE(it->base.widget, widtype) __VA_ARGS__;
+
+#define ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_GOTO(it, label)                \
+   ELM_WIDGET_ITEM_CHECK_OR_GOTO((Elm_Widget_Item *)it, label);         \
+   if (!elm_widget_type_check((it->base.widget), (widtype))) goto label;
+
+
+/**
+ * The drag and drop API.
+ * Currently experimental, and will change when it does dynamic type
+ * addition RSN.
+ *
+ * Here so applications can start to use it, if they ask elm nicely.
+ *
+ * And yes, elm_widget, should probably be elm_experimental...
+ * Complaints about this code should go to /dev/null, or failing that nash.
+ */
+typedef struct _Elm_Selection_Data Elm_Selection_Data;
+
+typedef Eina_Bool (*Elm_Drop_Cb) (void *d, Evas_Object *o, Elm_Selection_Data *data);
+
+typedef enum _Elm_Sel_Type
+{
+   ELM_SEL_PRIMARY,
+   ELM_SEL_SECONDARY,
+   ELM_SEL_CLIPBOARD,
+   ELM_SEL_XDND,
+
+   ELM_SEL_MAX,
+} Elm_Sel_Type;
+
+typedef enum _Elm_Sel_Format
+{
+   /** Plain unformated text: Used for things that don't want rich markup */
+   ELM_SEL_FORMAT_TEXT   = 0x01,
+   /** Edje textblock markup, including inline images */
+   ELM_SEL_FORMAT_MARKUP = 0x02,
+   /** Images */
+   ELM_SEL_FORMAT_IMAGE         = 0x04,
+   /** Vcards */
+   ELM_SEL_FORMAT_VCARD =  0x08,
+   /** Raw HTMLish things for widgets that want that stuff (hello webkit!) */
+   ELM_SEL_FORMAT_HTML = 0x10,
+} Elm_Sel_Format;
+
+struct _Elm_Selection_Data
+{
+   int                   x, y;
+   Elm_Sel_Format        format;
+   void                 *data;
+   int                   len;
+};
+
+Eina_Bool            elm_selection_set(Elm_Sel_Type selection, Evas_Object *widget, Elm_Sel_Format format, const char *buf);
+Eina_Bool            elm_selection_clear(Elm_Sel_Type selection, Evas_Object *widget);
+Eina_Bool            elm_selection_get(Elm_Sel_Type selection, Elm_Sel_Format format, Evas_Object *widget, Elm_Drop_Cb datacb, void *udata);
+Eina_Bool            elm_drop_target_add(Evas_Object *widget, Elm_Sel_Type, Elm_Drop_Cb, void *);
+Eina_Bool            elm_drop_target_del(Evas_Object *widget);
+Eina_Bool            elm_drag_start(Evas_Object *, Elm_Sel_Format, const char *, void (*)(void *,Evas_Object*),void*);
+
+
+#endif
index 3924079..31a5b39 100644 (file)
@@ -20,7 +20,7 @@ struct _Elm_Win
 #ifdef HAVE_ELEMENTARY_X
    Ecore_X_Window xwin;
    Ecore_Event_Handler *client_message_handler;
-#endif   
+#endif
    Ecore_Job *deferred_resize_job;
    Ecore_Job *deferred_child_eval_job;
 
@@ -31,6 +31,24 @@ struct _Elm_Win
    struct {
       int x, y;
    } screen;
+
+   struct {
+      Evas_Object *top;
+
+      struct {
+         Evas_Object *target;
+         Eina_Bool visible : 1;
+         Eina_Bool handled : 1;
+      } cur, prev;
+
+      const char *style;
+      Ecore_Job *reconf_job;
+
+      Eina_Bool enabled : 1;
+      Eina_Bool changed_theme : 1;
+      Eina_Bool top_animate : 1;
+      Eina_Bool geometry_changed : 1;
+   } focus_highlight;
 };
 
 static const char *widtype = NULL;
@@ -47,6 +65,13 @@ static void _elm_win_xwin_update(Elm_Win *win);
 static void _elm_win_eval_subobjs(Evas_Object *obj);
 static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
 static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _elm_win_focus_highlight_init(Elm_Win *win);
+static void _elm_win_focus_highlight_shutdown(Elm_Win *win);
+static void _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible);
+static void _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win);
+static void _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win);
+static void _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _elm_win_focus_highlight_reconfigure(Elm_Win *win);
 
 Eina_List *_elm_win_list = NULL;
 
@@ -56,7 +81,7 @@ _elm_win_move(Ecore_Evas *ee)
    Evas_Object *obj = ecore_evas_object_associate_get(ee);
    Elm_Win *win;
    int x, y;
-   
+
    if (!obj) return;
    win = elm_widget_data_get(obj);
    if (!win) return;
@@ -71,7 +96,7 @@ _elm_win_resize(Ecore_Evas *ee)
 {
    Evas_Object *obj = ecore_evas_object_associate_get(ee);
    Elm_Win *win;
-   
+
    if (!obj) return;
    win = elm_widget_data_get(obj);
    if (!win) return;
@@ -84,13 +109,15 @@ _elm_win_focus_in(Ecore_Evas *ee)
 {
    Evas_Object *obj = ecore_evas_object_associate_get(ee);
    Elm_Win *win;
-   
+
    if (!obj) return;
    win = elm_widget_data_get(obj);
    if (!win) return;
    /*NB: Why two different "focus signals" here ??? */
    evas_object_smart_callback_call(win->win_obj, "focus-in", NULL); // FIXME: remove me
    evas_object_smart_callback_call(win->win_obj, "focus,in", NULL);
+   win->focus_highlight.cur.visible = EINA_TRUE;
+   _elm_win_focus_highlight_reconfigure_job_start(win);
 }
 
 static void
@@ -98,12 +125,74 @@ _elm_win_focus_out(Ecore_Evas *ee)
 {
    Evas_Object *obj = ecore_evas_object_associate_get(ee);
    Elm_Win *win;
-   
+
    if (!obj) return;
    win = elm_widget_data_get(obj);
    if (!win) return;
    evas_object_smart_callback_call(win->win_obj, "focus-out", NULL); // FIXME: remove me
    evas_object_smart_callback_call(win->win_obj, "focus,out", NULL);
+   win->focus_highlight.cur.visible = EINA_FALSE;
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static Eina_Bool
+_elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
+{
+   Elm_Win *wd = elm_widget_data_get(obj);
+   const Eina_List *items;
+   void *(*list_data_get) (const Eina_List *list);
+
+   if (!wd)
+     return EINA_FALSE;
+
+   /* Focus chain */
+   if (wd->subobjs)
+     {
+        if (!(items = elm_widget_focus_custom_chain_get(obj)))
+          {
+             items = wd->subobjs;
+             if (!items)
+               return EINA_FALSE;
+          }
+        list_data_get = eina_list_data_get;
+
+        elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
+
+        if (*next)
+          return EINA_TRUE;
+     }
+
+   *next = (Evas_Object *)obj;
+   return EINA_FALSE;
+}
+
+static void
+_elm_win_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
+{
+   if (elm_widget_focus_get(obj))
+     evas_object_focus_set(obj, EINA_TRUE);
+   else
+     evas_object_focus_set(obj, EINA_FALSE);
+}
+
+static Eina_Bool
+_elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
+{
+   if (type == EVAS_CALLBACK_KEY_DOWN)
+     {
+        Evas_Event_Key_Down *ev = event_info;
+        if (!strcmp(ev->keyname, "Tab"))
+          {
+             if(evas_key_modifier_is_set(ev->modifiers, "Shift"))
+               elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
+             else
+               elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
+             ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+             return EINA_TRUE;
+          }
+     }
+
+   return EINA_FALSE;
 }
 
 static void
@@ -113,6 +202,12 @@ _deferred_ecore_evas_free(void *data)
 }
 
 static void
+_elm_win_obj_callback_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   elm_object_focus(obj);
+}
+
+static void
 _elm_win_obj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Elm_Win *win = data;
@@ -144,25 +239,29 @@ _elm_win_obj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void
 #ifdef HAVE_ELEMENTARY_X
    if (win->client_message_handler)
      ecore_event_handler_del(win->client_message_handler);
-#endif   
+#endif
 // FIXME: Why are we flushing edje on every window destroy ??
-//   evas_image_cache_flush(win->evas);
-//   evas_font_cache_flush(win->evas);
 //   edje_file_cache_flush();
 //   edje_collection_cache_flush();
+//   evas_image_cache_flush(win->evas);
+//   evas_font_cache_flush(win->evas);
 // FIXME: we are in the del handler for the object and delete the canvas
-// that lives under it from the handler... nasty. deferring doesnt help either
+// that lives under it from the handler... nasty. deferring doesn't help either
    ecore_job_add(_deferred_ecore_evas_free, win->ee);
 //   ecore_evas_free(win->ee);
+
+   _elm_win_focus_highlight_shutdown(win);
+   eina_stringshare_del(win->focus_highlight.style);
+
    free(win);
 
    if ((!_elm_win_list) &&
        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
      {
-        evas_image_cache_flush(e);
-        evas_font_cache_flush(e);
         edje_file_cache_flush();
         edje_collection_cache_flush();
+        evas_image_cache_flush(e);
+        evas_font_cache_flush(e);
        elm_exit();
      }
 }
@@ -190,7 +289,7 @@ _elm_win_delete_request(Ecore_Evas *ee)
    Evas_Object *obj = ecore_evas_object_associate_get(ee);
    Elm_Win *win;
    if (strcmp(elm_widget_type_get(obj), "win")) return;
-   
+
    win = elm_widget_data_get(obj);
    if (!win) return;
    int autodel = win->autodel;
@@ -225,33 +324,41 @@ static void
 _elm_win_xwindow_get(Elm_Win *win)
 {
    win->xwin = 0;
-   switch (_elm_config->engine)
+
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
+     {
+       if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
+            ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
+            ENGINE_COMPARE(ELM_OPENGL_SDL))
+     {
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
      {
-      case ELM_SOFTWARE_X11:
-       if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
-       break;
-      case ELM_SOFTWARE_FB:
-      case ELM_SOFTWARE_DIRECTFB:
-      case ELM_SOFTWARE_16_WINCE:
-      case ELM_SOFTWARE_SDL:
-      case ELM_SOFTWARE_16_SDL:
-      case ELM_OPENGL_SDL:
-       break;
-      case ELM_SOFTWARE_16_X11:
        if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee);
-       break;
-      case ELM_XRENDER_X11:
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
+     {
+       if (win->ee) win->xwin = ecore_evas_software_x11_8_window_get(win->ee);
+     }
+   else if (ENGINE_COMPARE(ELM_XRENDER_X11))
+     {
        if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee);
-       break;
-      case ELM_OPENGL_X11:
+     }
+   else if (ENGINE_COMPARE(ELM_OPENGL_X11))
+     {
        if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee);
-       break;
-      case ELM_SOFTWARE_WIN32:
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
+     {
        if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee);
-       break;
-      default:
-       break;
      }
+#undef ENGINE_COMPARE
 }
 #endif
 
@@ -313,7 +420,7 @@ _elm_win_eval_subobjs(Evas_Object *obj)
 {
    const Eina_List *l;
    const Evas_Object *child;
-   
+
    Elm_Win *win = elm_widget_data_get(obj);
    Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
    int xx = 1, xy = 1;
@@ -339,8 +446,6 @@ _elm_win_eval_subobjs(Evas_Object *obj)
        if (maxh == -1) maxh = h;
        else if ((h > 0) && (h < maxh)) maxh = h;
      }
-   if ((maxw >= 0) && (maxw < minw)) maxw = minw;
-   if ((maxh >= 0) && (maxh < minh)) maxh = minh;
    if (!xx) maxw = minw;
    else maxw = 32767;
    if (!xy) maxh = minh;
@@ -358,7 +463,9 @@ _elm_win_eval_subobjs(Evas_Object *obj)
 static void
 _elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
 {
-   elm_win_resize_object_del(data, obj);
+   Elm_Win *win = elm_widget_data_get(data);
+   win->subobjs = eina_list_remove(win->subobjs, obj);
+   _elm_win_eval_subobjs(win->win_obj);
 }
 
 static void
@@ -375,13 +482,21 @@ _elm_win_shutdown(void)
 }
 
 void
-_elm_win_rescale(void)
+_elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme)
 {
    const Eina_List *l;
    Evas_Object *obj;
 
-   EINA_LIST_FOREACH(_elm_win_list, l, obj)
-     elm_widget_theme(obj);
+   if (!use_theme)
+     {
+        EINA_LIST_FOREACH(_elm_win_list, l, obj)
+          elm_widget_theme(obj);
+     }
+   else
+     {
+        EINA_LIST_FOREACH(_elm_win_list, l, obj)
+          elm_widget_theme_specific(obj, th, EINA_FALSE);
+     }
 }
 
 #ifdef HAVE_ELEMENTARY_X
@@ -394,7 +509,7 @@ _elm_win_client_message(void *data, int type __UNUSED__, void *event)
    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
      {
-        if (e->data.l[0] == win->xwin)
+        if ((unsigned)e->data.l[0] == win->xwin)
           {
              Evas *evas = evas_object_evas_get(win->win_obj);
              if (evas)
@@ -408,7 +523,7 @@ _elm_win_client_message(void *data, int type __UNUSED__, void *event)
      }
    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
      {
-        if (e->data.l[0] == win->xwin)
+        if ((unsigned)e->data.l[0] == win->xwin)
           {
              Evas *evas = evas_object_evas_get(win->win_obj);
              if (evas)
@@ -425,6 +540,358 @@ _elm_win_client_message(void *data, int type __UNUSED__, void *event)
 }
 #endif
 
+static void
+_elm_win_focus_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+
+   win->focus_highlight.geometry_changed = EINA_TRUE;
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_focus_target_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+
+   win->focus_highlight.geometry_changed = EINA_TRUE;
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_focus_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+
+   win->focus_highlight.cur.target = NULL;
+
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_focus_target_callbacks_add(Elm_Win *win)
+{
+   Evas_Object *obj = win->focus_highlight.cur.target;
+
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
+                                 _elm_win_focus_target_move, win);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
+                                 _elm_win_focus_target_resize, win);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+                                 _elm_win_focus_target_del, win);
+}
+
+static void
+_elm_win_focus_target_callbacks_del(Elm_Win *win)
+{
+   Evas_Object *obj = win->focus_highlight.cur.target;
+
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
+                                      _elm_win_focus_target_move, win);
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
+                                      _elm_win_focus_target_resize, win);
+   evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
+                                      _elm_win_focus_target_del, win);
+}
+
+static Evas_Object *
+_elm_win_focus_target_get(Evas_Object *obj)
+{
+   Evas_Object *o = obj;
+
+   do
+     {
+        if (elm_widget_is(o))
+          {
+             if (!elm_widget_highlight_ignore_get(o))
+               break;
+             o = elm_widget_parent_get(o);
+             if (!o)
+               o = evas_object_smart_parent_get(o);
+          }
+        else
+          {
+             o = elm_widget_parent_widget_get(o);
+             if (!o)
+               o = evas_object_smart_parent_get(o);
+          }
+     }
+   while (o);
+
+   return o;
+}
+
+static void
+_elm_win_object_focus_in(void *data, Evas *e __UNUSED__, void *event_info)
+{
+   Evas_Object *obj = event_info, *target;
+   Elm_Win *win = data;
+
+   if (win->focus_highlight.cur.target == obj)
+     return;
+
+   target = _elm_win_focus_target_get(obj);
+   win->focus_highlight.cur.target = target;
+   if (elm_widget_highlight_in_theme_get(target))
+     win->focus_highlight.cur.handled = EINA_TRUE;
+   else
+     _elm_win_focus_target_callbacks_add(win);
+
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_object_focus_out(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+
+   if (!win->focus_highlight.cur.target)
+     return;
+
+   if (!win->focus_highlight.cur.handled)
+     _elm_win_focus_target_callbacks_del(win);
+   win->focus_highlight.cur.target = NULL;
+   win->focus_highlight.cur.handled = EINA_FALSE;
+
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_focus_highlight_hide(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   evas_object_hide(obj);
+}
+
+static void
+_elm_win_focus_highlight_init(Elm_Win *win)
+{
+   evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
+                           _elm_win_object_focus_in, win);
+   evas_event_callback_add(win->evas,
+                           EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
+                           _elm_win_object_focus_out, win);
+
+   win->focus_highlight.cur.target = evas_focus_get(win->evas);
+
+   win->focus_highlight.top = edje_object_add(win->evas);
+   win->focus_highlight.changed_theme = EINA_TRUE;
+   edje_object_signal_callback_add(win->focus_highlight.top,
+                                   "elm,action,focus,hide,end", "",
+                                   _elm_win_focus_highlight_hide, NULL);
+   edje_object_signal_callback_add(win->focus_highlight.top,
+                                   "elm,action,focus,anim,end", "",
+                                   _elm_win_focus_highlight_anim_end, win);
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+static void
+_elm_win_focus_highlight_shutdown(Elm_Win *win)
+{
+   _elm_win_focus_highlight_reconfigure_job_stop(win);
+   if (win->focus_highlight.cur.target)
+     {
+        _elm_win_focus_target_callbacks_del(win);
+        win->focus_highlight.cur.target = NULL;
+     }
+   if (win->focus_highlight.top)
+     {
+        evas_object_del(win->focus_highlight.top);
+        win->focus_highlight.top = NULL;
+     }
+
+     evas_event_callback_del_full(win->evas,
+                                  EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
+                                  _elm_win_object_focus_in, win);
+     evas_event_callback_del_full(win->evas,
+                                  EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
+                                  _elm_win_object_focus_out, win);
+}
+
+static void
+_elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible)
+{
+   Evas_Object *top;
+
+   top = win->focus_highlight.top;
+   if (visible)
+     {
+        if (top)
+          {
+             evas_object_show(top);
+             edje_object_signal_emit(top, "elm,action,focus,show", "elm");
+          }
+     }
+   else
+     {
+        if (top)
+          edje_object_signal_emit(top, "elm,action,focus,hide", "elm");
+     }
+}
+
+static void
+_elm_win_focus_highlight_reconfigure_job(void *data)
+{
+   _elm_win_focus_highlight_reconfigure((Elm_Win *)data);
+}
+
+static void
+_elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win)
+{
+   if (win->focus_highlight.reconf_job)
+     ecore_job_del(win->focus_highlight.reconf_job);
+   win->focus_highlight.reconf_job = ecore_job_add(
+      _elm_win_focus_highlight_reconfigure_job, win);
+}
+
+static void
+_elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win)
+{
+   if (win->focus_highlight.reconf_job)
+     ecore_job_del(win->focus_highlight.reconf_job);
+   win->focus_highlight.reconf_job = NULL;
+}
+
+static void
+_elm_win_focus_highlight_simple_setup(Elm_Win *win, Evas_Object *obj)
+{
+   Evas_Object *clip, *target = win->focus_highlight.cur.target;
+   Evas_Coord x, y, w, h;
+
+   clip = evas_object_clip_get(target);
+   evas_object_geometry_get(target, &x, &y, &w, &h);
+
+   evas_object_move(obj, x, y);
+   evas_object_resize(obj, w, h);
+   evas_object_clip_set(obj, clip);
+}
+
+static void
+_elm_win_focus_highlight_anim_setup(Elm_Win *win, Evas_Object *obj)
+{
+   Evas_Coord tx, ty, tw, th;
+   Evas_Coord w, h, px, py, pw, ph;
+   Edje_Message_Int_Set *m;
+   Evas_Object *previous = win->focus_highlight.prev.target;
+   Evas_Object *target = win->focus_highlight.cur.target;
+
+   evas_object_geometry_get(win->win_obj, NULL, NULL, &w, &h);
+   evas_object_geometry_get(target, &tx, &ty, &tw, &th);
+   evas_object_geometry_get(previous, &px, &py, &pw, &ph);
+   evas_object_move(obj, 0, 0);
+   evas_object_resize(obj, tw, th);
+   evas_object_clip_unset(obj);
+
+   m = alloca(sizeof(*m) + (sizeof(int) * 8));
+   m->count = 8;
+   m->val[0] = px;
+   m->val[1] = py;
+   m->val[2] = pw;
+   m->val[3] = ph;
+   m->val[4] = tx;
+   m->val[5] = ty;
+   m->val[6] = tw;
+   m->val[7] = th;
+   edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
+}
+
+static void
+_elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Win *win = data;
+   _elm_win_focus_highlight_simple_setup(win, obj);
+}
+
+static void
+_elm_win_focus_highlight_reconfigure(Elm_Win *win)
+{
+   Evas_Object *target = win->focus_highlight.cur.target;
+   Evas_Object *previous = win->focus_highlight.prev.target;
+   Evas_Object *top = win->focus_highlight.top;
+   Eina_Bool visible_changed;
+   Eina_Bool common_visible;
+   const char *sig = NULL;
+
+   _elm_win_focus_highlight_reconfigure_job_stop(win);
+
+   visible_changed = (win->focus_highlight.cur.visible !=
+                      win->focus_highlight.prev.visible);
+
+   if ((target == previous) && (!visible_changed) &&
+       (!win->focus_highlight.geometry_changed))
+     return;
+
+   if ((previous) && (win->focus_highlight.prev.handled))
+     elm_widget_signal_emit(previous, "elm,action,focus_highlight,hide", "elm");
+
+   if (!target)
+     common_visible = EINA_FALSE;
+   else if (win->focus_highlight.cur.handled)
+     {
+        common_visible = EINA_FALSE;
+        if (win->focus_highlight.cur.visible)
+          sig = "elm,action,focus_highlight,show";
+        else
+          sig = "elm,action,focus_highlight,hide";
+     }
+   else
+     common_visible = win->focus_highlight.cur.visible;
+
+   _elm_win_focus_highlight_visible_set(win, common_visible);
+   if (sig)
+     elm_widget_signal_emit(target, sig, "elm");
+
+   if ((!target) || (!common_visible) || (win->focus_highlight.cur.handled))
+     goto the_end;
+
+   if (win->focus_highlight.changed_theme)
+     {
+        const char *str;
+        if (win->focus_highlight.style)
+          str = win->focus_highlight.style;
+        else
+          str = "default";
+        _elm_theme_object_set(win->win_obj, top, "focus_highlight", "top",
+                              str);
+        win->focus_highlight.changed_theme = EINA_FALSE;
+
+        if (_elm_config->focus_highlight_animate)
+          {
+             str = edje_object_data_get(win->focus_highlight.top, "animate");
+             win->focus_highlight.top_animate = ((str) && (!strcmp(str, "on")));
+          }
+     }
+
+   if ((win->focus_highlight.top_animate) && (previous) &&
+       (!win->focus_highlight.prev.handled))
+     _elm_win_focus_highlight_anim_setup(win, top);
+   else
+     _elm_win_focus_highlight_simple_setup(win, top);
+   evas_object_raise(top);
+
+the_end:
+   win->focus_highlight.geometry_changed = EINA_FALSE;
+   win->focus_highlight.prev = win->focus_highlight.cur;
+}
+
+#ifdef ELM_DEBUG
+static void
+_debug_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   Evas_Event_Key_Down *ev = event_info;
+
+   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
+      return;
+
+
+   if ((strcmp(ev->keyname, "F12")) ||
+       (!evas_key_modifier_is_set(ev->modifiers, "Control")))
+     return;
+
+   printf("Tree graph generated.\n");
+   elm_object_tree_dot_dump(obj, "./dump.dot");
+}
+#endif
+
 /**
  * Adds a window object. If this is the first window created, pass NULL as
  * @p parent.
@@ -453,90 +920,96 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
    const char *fontpath;
 
    win = ELM_NEW(Elm_Win);
-   switch (_elm_config->engine)
+
+#define FALLBACK_TRY(engine)                                            \
+   if (!win->ee)                                                        \
+     do {                                                               \
+       CRITICAL(engine " engine creation failed. Trying software X11."); \
+       win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);      \
+     } while (0)
+
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
      {
-      case ELM_SOFTWARE_X11:
        win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
 #ifdef HAVE_ELEMENTARY_X
         win->client_message_handler = ecore_event_handler_add
           (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
-#endif        
-       break;
-      case ELM_SOFTWARE_FB:
+#endif
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
+     {
        win->ee = ecore_evas_fb_new(NULL, 0, 1, 1);
-       break;
-      case ELM_SOFTWARE_DIRECTFB:
+        FALLBACK_TRY("Sofware FB");
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_DIRECTFB))
+     {
         win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1);
-       break;
-      case ELM_SOFTWARE_16_X11:
+        FALLBACK_TRY("Sofware DirectFB");
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
+     {
        win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1);
-        if (!win->ee)
-          {
-             CRITICAL("Software-16 engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
+        FALLBACK_TRY("Sofware-16");
 #ifdef HAVE_ELEMENTARY_X
         win->client_message_handler = ecore_event_handler_add
           (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
-#endif        
-       break;
-      case ELM_XRENDER_X11:
+#endif
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
+     {
+       win->ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1);
+        FALLBACK_TRY("Sofware-8");
+#ifdef HAVE_ELEMENTARY_X
+        win->client_message_handler = ecore_event_handler_add
+          (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
+#endif
+     }
+   else if (ENGINE_COMPARE(ELM_XRENDER_X11))
+     {
        win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1);
-        if (!win->ee)
-          {
-             CRITICAL("XRender engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
+        FALLBACK_TRY("XRender");
 #ifdef HAVE_ELEMENTARY_X
         win->client_message_handler = ecore_event_handler_add
           (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
-#endif        
-       break;
-      case ELM_OPENGL_X11:
+#endif
+     }
+   else if (ENGINE_COMPARE(ELM_OPENGL_X11))
+     {
        win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
-        if (!win->ee)
-          {
-             CRITICAL("OpenGL engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
+        FALLBACK_TRY("OpenGL");
 #ifdef HAVE_ELEMENTARY_X
         win->client_message_handler = ecore_event_handler_add
           (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
-#endif        
-       break;
-      case ELM_SOFTWARE_WIN32:
+#endif
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
+     {
        win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
-       break;
-      case ELM_SOFTWARE_16_WINCE:
+        FALLBACK_TRY("Sofware Win32");
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
+     {
        win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1);
-       break;
-      case ELM_SOFTWARE_SDL:
+        FALLBACK_TRY("Sofware-16-WinCE");
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_SDL))
+     {
        win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
-        if (!win->ee)
-          {
-             CRITICAL("Software SDL engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
-       break;
-      case ELM_SOFTWARE_16_SDL:
+        FALLBACK_TRY("Sofware SDL");
+     }
+   else if (ENGINE_COMPARE(ELM_SOFTWARE_16_SDL))
+     {
        win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1);
-        if (!win->ee)
-          {
-             CRITICAL("Sofware-16-SDL engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
-       break;
-      case ELM_OPENGL_SDL:
+        FALLBACK_TRY("Sofware-16-SDL");
+     }
+   else if (ENGINE_COMPARE(ELM_OPENGL_SDL))
+     {
        win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
-        if (!win->ee)
-          {
-             CRITICAL("OpenGL SDL engine create failed. Try software.");
-             win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
-          }
-       break;
-      default:
-       break;
+        FALLBACK_TRY("OpenGL SDL");
      }
+#undef FALLBACK_TRY
+
    if (!win->ee)
      {
        ERR("Cannot create window.");
@@ -545,7 +1018,7 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
      }
 #ifdef HAVE_ELEMENTARY_X
    _elm_win_xwindow_get(win);
-#endif   
+#endif
    if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
      ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
 // bg pixmap done by x - has other issues like can be redrawn by x before it
@@ -563,11 +1036,16 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
    elm_widget_type_set(win->win_obj, "win");
    ELM_SET_WIDTYPE(widtype, "win");
    elm_widget_data_set(win->win_obj, win);
+   elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb);
+   elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL);
+   elm_widget_can_focus_set(win->win_obj, EINA_TRUE);
+   elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE);
+   elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook);
    evas_object_color_set(win->win_obj, 0, 0, 0, 0);
    evas_object_move(win->win_obj, 0, 0);
    evas_object_resize(win->win_obj, 1, 1);
    evas_object_layer_set(win->win_obj, 50);
-   evas_object_pass_events_set(win->win_obj, 1);
+   evas_object_pass_events_set(win->win_obj, EINA_TRUE);
 
    evas_object_intercept_show_callback_add(win->win_obj,
                                            _elm_win_obj_intercept_show, win);
@@ -575,6 +1053,8 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
                               ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
                               ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
                               ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
+   evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW,
+                                 _elm_win_obj_callback_show, win);
    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
                                  _elm_win_obj_callback_del, win);
 
@@ -588,7 +1068,7 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
    evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
      evas_font_path_append(win->evas, fontpath);
-   if (_elm_config->font_hinting == 0)
+   if (!_elm_config->font_hinting)
      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
    else if (_elm_config->font_hinting == 1)
      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
@@ -598,27 +1078,25 @@ elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
 #ifdef HAVE_ELEMENTARY_X
    _elm_win_xwin_update(win);
 #endif
-   
+
    _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
 
-   switch (_elm_config->engine)
+   if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
      {
-      case ELM_SOFTWARE_16_WINCE:
-      case ELM_SOFTWARE_FB:
        ecore_evas_fullscreen_set(win->ee, 1);
-       break;
-      case ELM_SOFTWARE_X11:
-      case ELM_SOFTWARE_16_X11:
-      case ELM_XRENDER_X11:
-      case ELM_OPENGL_X11:
-      case ELM_SOFTWARE_WIN32:
-      case ELM_SOFTWARE_SDL:
-      case ELM_SOFTWARE_16_SDL:
-      case ELM_OPENGL_SDL:
-      default:
-       break;
      }
-   
+#undef ENGINE_COMPARE
+
+   if (_elm_config->focus_highlight_enable)
+     elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE);
+
+#ifdef ELM_DEBUG
+   Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control");
+   evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN,
+                                  _debug_key_down, win);
+   Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0, EINA_TRUE);
+   printf("Key F12 exclusive for dot tree generation. (%d)\n", ret);
+#endif
    return win->win_obj;
 }
 
@@ -696,6 +1174,24 @@ elm_win_title_set(Evas_Object *obj, const char *title)
 }
 
 /**
+ * Get the title of the window
+ *
+ * @param obj The window object
+ * @return The title
+ *
+ * @ingroup Win
+ */
+EAPI const char *
+elm_win_title_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   win = elm_widget_data_get(obj);
+   if (!win) return NULL;
+   return ecore_evas_title_get(win->ee);
+}
+
+/**
  * Set the window's autodel state.
  *
  * @param obj The window object
@@ -714,6 +1210,24 @@ elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
 }
 
 /**
+ * Get the window's autodel state.
+ *
+ * @param obj The window object
+ * @return If the window will automatically delete itself when closed
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_autodel_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+   return win->autodel;
+}
+
+/**
  * Activate a window object.
  *
  * @param obj The window object
@@ -909,11 +1423,11 @@ elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
    ELM_CHECK_WIDTYPE(obj, widtype);
    win = elm_widget_data_get(obj);
    if (!win) return;
-   
+
 #ifdef HAVE_ELEMENTARY_X
    if (win->xwin)
      {
-       ecore_evas_transparent_set(win->ee, transparent);         
+       ecore_evas_transparent_set(win->ee, transparent);
        _elm_win_xwin_update(win);
      }
    else
@@ -994,19 +1508,22 @@ elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
    ELM_CHECK_WIDTYPE(obj, widtype);
    win = elm_widget_data_get(obj);
    if (!win) return;
-   switch (_elm_config->engine)
+
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
+       ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
      {
-     case ELM_SOFTWARE_16_WINCE:
-     case ELM_SOFTWARE_FB:
        // these engines... can ONLY be fullscreen
-       break;
-     default:
+       return;
+     }
+   else
+     {
        ecore_evas_fullscreen_set(win->ee, fullscreen);
 #ifdef HAVE_ELEMENTARY_X
        _elm_win_xwin_update(win);
 #endif
-       break;
      }
+#undef ENGINE_COMPARE
 }
 
 /**
@@ -1024,18 +1541,19 @@ elm_win_fullscreen_get(const Evas_Object *obj)
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    win = elm_widget_data_get(obj);
    if (!win) return EINA_FALSE;
-   switch (_elm_config->engine)
+
+#define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
+   if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
+       ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
      {
-     case ELM_SOFTWARE_16_WINCE:
-     case ELM_SOFTWARE_FB:
        // these engines... can ONLY be fullscreen
        return EINA_TRUE;
-       break;
-     default:
+     }
+   else
+     {
        return ecore_evas_fullscreen_get(win->ee);
-       break;
      }
-   return EINA_FALSE;
+#undef ENGINE_COMPARE
 }
 
 /**
@@ -1131,7 +1649,7 @@ elm_win_layer_set(Evas_Object *obj, int layer)
    ELM_CHECK_WIDTYPE(obj, widtype);
    win = elm_widget_data_get(obj);
    if (!win) return;
-   ecore_evas_layer_set(win->ee, layer); 
+   ecore_evas_layer_set(win->ee, layer);
 #ifdef HAVE_ELEMENTARY_X
    _elm_win_xwin_update(win);
 #endif
@@ -1308,6 +1826,40 @@ elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
 }
 
 /**
+ * Gets the keyboard mode of the window.
+ *
+ * @param obj The window object
+ * @return The mode; one of:
+ * ELM_WIN_KEYBOARD_UNKNOWN
+ * ELM_WIN_KEYBOARD_OFF
+ * ELM_WIN_KEYBOARD_ON
+ * ELM_WIN_KEYBOARD_ALPHA
+ * ELM_WIN_KEYBOARD_NUMERIC
+ * ELM_WIN_KEYBOARD_PIN
+ * ELM_WIN_KEYBOARD_PHONE_NUMBER
+ * ELM_WIN_KEYBOARD_HEX
+ * ELM_WIN_KEYBOARD_TERMINAL
+ * ELM_WIN_KEYBOARD_PASSWORD
+ * ELM_WIN_KEYBOARD_IP
+ * ELM_WIN_KEYBOARD_HOST
+ * ELM_WIN_KEYBOARD_FILE
+ * ELM_WIN_KEYBOARD_URL
+ * ELM_WIN_KEYBOARD_KEYPAD
+ * ELM_WIN_KEYBOARD_J2ME
+ *
+ * @ingroup Win
+ */
+EAPI Elm_Win_Keyboard_Mode
+elm_win_keyboard_mode_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN;
+   win = elm_widget_data_get(obj);
+   if (!win) return ELM_WIN_KEYBOARD_UNKNOWN;
+   return win->kbdmode;
+}
+
+/**
  * Sets whether the window is a keyboard.
  *
  * @param obj The window object
@@ -1330,6 +1882,29 @@ elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
 }
 
 /**
+ * Gets whether the window is a keyboard.
+ *
+ * @param obj The window object
+ * @return If the window is a virtual keyboard
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_keyboard_win_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_virtual_keyboard_get(win->xwin);
+#endif
+   return EINA_FALSE;
+}
+
+/**
  * Get the screen position of a window.
  *
  * @param obj The window object
@@ -1564,6 +2139,127 @@ elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
 #endif
 }
 
+/**
+ * Get which zone this quickpanel should appear in
+ *
+ * @param obj The window object
+ * @return The requested zone for this quickpanel
+ *
+ * @ingroup Win
+ */
+EAPI int
+elm_win_quickpanel_zone_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   win = elm_widget_data_get(obj);
+   if (!win) return 0;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+   if (win->xwin)
+     return ecore_x_e_illume_quickpanel_zone_get(win->xwin);
+#endif
+   return 0;
+}
+
+/**
+ * Set the enabled status for the focus highlight in a window
+ *
+ * This function will enable or disable the focus highlight only for the
+ * given window, regardless of the global setting for it
+ *
+ * @param obj The window where to enable the highlight
+ * @param enabled The enabled value for the highlight
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   Elm_Win *win;
+
+   ELM_CHECK_WIDTYPE(obj, widtype);
+
+   win = elm_widget_data_get(obj);
+   enabled = !!enabled;
+   if (win->focus_highlight.enabled == enabled)
+     return;
+
+   win->focus_highlight.enabled = enabled;
+
+   if (win->focus_highlight.enabled)
+     _elm_win_focus_highlight_init(win);
+   else
+     _elm_win_focus_highlight_shutdown(win);
+}
+
+/**
+ * Get the enabled value of the focus highlight for this window
+ *
+ * @param obj The window in which to check if the focus highlight is enabled
+ *
+ * @return EINA_TRUE if enabled, EINA_FALSE otherwise
+ *
+ * @ingroup Win
+ */
+EAPI Eina_Bool
+elm_win_focus_highlight_enabled_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+
+   win = elm_widget_data_get(obj);
+   return win->focus_highlight.enabled;
+}
+
+/**
+ * Set the style for the focus highlight on this window
+ *
+ * Sets the style to use for theming the highlight of focused objects on
+ * the given window. If @p style is NULL, the default will be used.
+ *
+ * @param obj The window where to set the style
+ * @param style The style to set
+ *
+ * @ingroup Win
+ */
+EAPI void
+elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style)
+{
+   Elm_Win *win;
+
+   ELM_CHECK_WIDTYPE(obj, widtype);
+
+   win = elm_widget_data_get(obj);
+   eina_stringshare_replace(&win->focus_highlight.style, style);
+   win->focus_highlight.changed_theme = EINA_TRUE;
+   _elm_win_focus_highlight_reconfigure_job_start(win);
+}
+
+/**
+ * Get the style set for the focus highlight object
+ *
+ * Gets the style set for this windows highilght object, or NULL if none
+ * is set.
+ *
+ * @param obj The window to retrieve the highlights style from
+ *
+ * @return The style set or NULL if none was. Default is used in that case.
+ *
+ * @ingroup Win
+ */
+EAPI const char *
+elm_win_focus_highlight_style_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+
+   win = elm_widget_data_get(obj);
+   return win->focus_highlight.style;
+}
+
 EAPI void
 elm_win_indicator_state_set(Evas_Object *obj, int show_state)
 {
@@ -1644,6 +2340,26 @@ _theme_hook(Evas_Object *obj)
    _sizing_eval(obj);
 }
 
+static Eina_Bool
+_elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd)
+     return EINA_FALSE;
+
+   /* Try Focus cycle in subitem */
+   if (wd->content)
+     {
+        elm_widget_focus_next_get(wd->content, dir, next);
+        if (*next)
+          return EINA_TRUE;
+     }
+
+   *next = (Evas_Object *)obj;
+   return EINA_FALSE;
+}
+
 static void
 _sizing_eval(Evas_Object *obj)
 {
@@ -1678,7 +2394,6 @@ _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
 
 /**
  * @defgroup Inwin Inwin
- * @ingroup  Elementary
  *
  * An inwin is a window inside a window that is useful for a quick popup.  It does not hover.
  */
@@ -1704,6 +2419,9 @@ elm_win_inwin_add(Evas_Object *obj)
    elm_widget_data_set(obj2, wd);
    elm_widget_del_hook_set(obj2, _del_hook);
    elm_widget_theme_hook_set(obj2, _theme_hook);
+   elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook);
+   elm_widget_can_focus_set(obj2, EINA_TRUE);
+   elm_widget_highlight_ignore_set(obj2, EINA_TRUE);
 
    wd->frm = edje_object_add(win->evas);
    _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
@@ -1731,7 +2449,7 @@ elm_win_inwin_activate(Evas_Object *obj)
    evas_object_raise(obj);
    evas_object_show(obj);
    edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
-   elm_widget_focused_object_clear(elm_widget_parent_get(obj));
+   elm_object_focus(obj);
 }
 
 /**
@@ -1766,6 +2484,25 @@ elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
 }
 
 /**
+ * Get the content of an inwin object.
+ *
+ * Return the content object which is set for this widget.
+ *
+ * @param obj The inwin object
+ * @return The content that is being used
+ *
+ * @ingroup Inwin
+ */
+EAPI Evas_Object *
+elm_win_inwin_content_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return NULL;
+   return wd->content;
+}
+
+/**
  * Unset the content of an inwin object.
  *
  * Unparent and return the content object which was set for this widget.
diff --git a/src/lib/els_cursor.c b/src/lib/els_cursor.c
new file mode 100644 (file)
index 0000000..45b0ed1
--- /dev/null
@@ -0,0 +1,617 @@
+#include <Elementary.h>
+#include <Elementary_Cursor.h>
+#include "elm_priv.h"
+
+#ifdef HAVE_ELEMENTARY_X
+#include <Ecore_X.h>
+#include <Ecore_X_Cursor.h>
+#endif
+
+/**
+ * @defgroup Cursors Cursors
+ *
+ * The Cursor is an internal smart object used to customize the
+ * cursor displayed over objects (or widgets).
+ * It can use default X cursors (if using X), or cursors from a
+ * theme.
+ */
+
+#define _cursor_key "_elm_cursor"
+
+struct _Cursor_Id 
+{
+   const char *name;
+#ifdef HAVE_ELEMENTARY_X
+   int id;
+#endif
+};
+
+#ifdef HAVE_ELEMENTARY_X
+#define CURSOR(_name, _xid) \
+   {_name , _xid}
+# else
+#define CURSOR(_name, _xid) \
+   {_name}
+#endif
+
+/* Please keep order in sync with Ecore_X_Cursor.h values! */
+struct _Cursor_Id _cursors[] =
+{
+   CURSOR(ELM_CURSOR_X                  , ECORE_X_CURSOR_X                  ),
+   CURSOR(ELM_CURSOR_ARROW              , ECORE_X_CURSOR_ARROW              ),
+   CURSOR(ELM_CURSOR_BASED_ARROW_DOWN   , ECORE_X_CURSOR_BASED_ARROW_DOWN   ),
+   CURSOR(ELM_CURSOR_BASED_ARROW_UP     , ECORE_X_CURSOR_UP                 ),
+   CURSOR(ELM_CURSOR_BOAT               , ECORE_X_CURSOR_BOAT               ),
+   CURSOR(ELM_CURSOR_BOGOSITY           , ECORE_X_CURSOR_BOGOSITY           ),
+   CURSOR(ELM_CURSOR_BOTTOM_LEFT_CORNER , ECORE_X_CURSOR_BOTTOM_LEFT_CORNER ),
+   CURSOR(ELM_CURSOR_BOTTOM_RIGHT_CORNER, ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER),
+   CURSOR(ELM_CURSOR_BOTTOM_SIDE        , ECORE_X_CURSOR_BOTTOM_SIDE        ),
+   CURSOR(ELM_CURSOR_BOTTOM_TEE         , ECORE_X_CURSOR_BOTTOM_TEE         ),
+   CURSOR(ELM_CURSOR_BOX_SPIRAL         , ECORE_X_CURSOR_BOX_SPIRAL         ),
+   CURSOR(ELM_CURSOR_CENTER_PTR         , ECORE_X_CURSOR_CENTER_PTR         ),
+   CURSOR(ELM_CURSOR_CIRCLE             , ECORE_X_CURSOR_CIRCLE             ),
+   CURSOR(ELM_CURSOR_CLOCK              , ECORE_X_CURSOR_CLOCK              ),
+   CURSOR(ELM_CURSOR_COFFEE_MUG         , ECORE_X_CURSOR_COFFEE_MUG         ),
+   CURSOR(ELM_CURSOR_CROSS              , ECORE_X_CURSOR_CROSS              ),
+   CURSOR(ELM_CURSOR_CROSS_REVERSE      , ECORE_X_CURSOR_CROSS_REVERSE      ),
+   CURSOR(ELM_CURSOR_CROSSHAIR          , ECORE_X_CURSOR_CROSSHAIR          ),
+   CURSOR(ELM_CURSOR_DIAMOND_CROSS      , ECORE_X_CURSOR_DIAMOND_CROSS      ),
+   CURSOR(ELM_CURSOR_DOT                , ECORE_X_CURSOR_DOT                ),
+   CURSOR(ELM_CURSOR_DOT_BOX_MASK       , ECORE_X_CURSOR_DOT_BOX_MASK       ),
+   CURSOR(ELM_CURSOR_DOUBLE_ARROW       , ECORE_X_CURSOR_DOUBLE_ARROW       ),
+   CURSOR(ELM_CURSOR_DRAFT_LARGE        , ECORE_X_CURSOR_DRAFT_LARGE        ),
+   CURSOR(ELM_CURSOR_DRAFT_SMALL        , ECORE_X_CURSOR_DRAFT_SMALL        ),
+   CURSOR(ELM_CURSOR_DRAPED_BOX         , ECORE_X_CURSOR_DRAPED_BOX         ),
+   CURSOR(ELM_CURSOR_EXCHANGE           , ECORE_X_CURSOR_EXCHANGE           ),
+   CURSOR(ELM_CURSOR_FLEUR              , ECORE_X_CURSOR_FLEUR              ),
+   CURSOR(ELM_CURSOR_GOBBLER            , ECORE_X_CURSOR_GOBBLER            ),
+   CURSOR(ELM_CURSOR_GUMBY              , ECORE_X_CURSOR_GUMBY              ),
+   CURSOR(ELM_CURSOR_HAND1              , ECORE_X_CURSOR_HAND1              ),
+   CURSOR(ELM_CURSOR_HAND2              , ECORE_X_CURSOR_HAND2              ),
+   CURSOR(ELM_CURSOR_HEART              , ECORE_X_CURSOR_HEART              ),
+   CURSOR(ELM_CURSOR_ICON               , ECORE_X_CURSOR_ICON               ),
+   CURSOR(ELM_CURSOR_IRON_CROSS         , ECORE_X_CURSOR_IRON_CROSS         ),
+   CURSOR(ELM_CURSOR_LEFT_PTR           , ECORE_X_CURSOR_LEFT_PTR           ),
+   CURSOR(ELM_CURSOR_LEFT_SIDE          , ECORE_X_CURSOR_LEFT_SIDE          ),
+   CURSOR(ELM_CURSOR_LEFT_TEE           , ECORE_X_CURSOR_LEFT_TEE           ),
+   CURSOR(ELM_CURSOR_LEFTBUTTON         , ECORE_X_CURSOR_LEFTBUTTON         ),
+   CURSOR(ELM_CURSOR_LL_ANGLE           , ECORE_X_CURSOR_LL_ANGLE           ),
+   CURSOR(ELM_CURSOR_LR_ANGLE           , ECORE_X_CURSOR_LR_ANGLE           ),
+   CURSOR(ELM_CURSOR_MAN                , ECORE_X_CURSOR_MAN                ),
+   CURSOR(ELM_CURSOR_MIDDLEBUTTON       , ECORE_X_CURSOR_MIDDLEBUTTON       ),
+   CURSOR(ELM_CURSOR_MOUSE              , ECORE_X_CURSOR_MOUSE              ),
+   CURSOR(ELM_CURSOR_PENCIL             , ECORE_X_CURSOR_PENCIL             ),
+   CURSOR(ELM_CURSOR_PIRATE             , ECORE_X_CURSOR_PIRATE             ),
+   CURSOR(ELM_CURSOR_PLUS               , ECORE_X_CURSOR_PLUS               ),
+   CURSOR(ELM_CURSOR_QUESTION_ARROW     , ECORE_X_CURSOR_QUESTION_ARROW     ),
+   CURSOR(ELM_CURSOR_RIGHT_PTR          , ECORE_X_CURSOR_RIGHT_PTR          ),
+   CURSOR(ELM_CURSOR_RIGHT_SIDE         , ECORE_X_CURSOR_RIGHT_SIDE         ),
+   CURSOR(ELM_CURSOR_RIGHT_TEE          , ECORE_X_CURSOR_RIGHT_TEE          ),
+   CURSOR(ELM_CURSOR_RIGHTBUTTON        , ECORE_X_CURSOR_RIGHTBUTTON        ),
+   CURSOR(ELM_CURSOR_RTL_LOGO           , ECORE_X_CURSOR_RTL_LOGO           ),
+   CURSOR(ELM_CURSOR_SAILBOAT           , ECORE_X_CURSOR_SAILBOAT           ),
+   CURSOR(ELM_CURSOR_SB_DOWN_ARROW      , ECORE_X_CURSOR_SB_DOWN_ARROW      ),
+   CURSOR(ELM_CURSOR_SB_H_DOUBLE_ARROW  , ECORE_X_CURSOR_SB_H_DOUBLE_ARROW  ),
+   CURSOR(ELM_CURSOR_SB_LEFT_ARROW      , ECORE_X_CURSOR_SB_LEFT_ARROW      ),
+   CURSOR(ELM_CURSOR_SB_RIGHT_ARROW     , ECORE_X_CURSOR_SB_RIGHT_ARROW     ),
+   CURSOR(ELM_CURSOR_SB_UP_ARROW        , ECORE_X_CURSOR_SB_UP_ARROW        ),
+   CURSOR(ELM_CURSOR_SB_V_DOUBLE_ARROW  , ECORE_X_CURSOR_SB_V_DOUBLE_ARROW  ),
+   CURSOR(ELM_CURSOR_SHUTTLE            , ECORE_X_CURSOR_SHUTTLE            ),
+   CURSOR(ELM_CURSOR_SIZING             , ECORE_X_CURSOR_SIZING             ),
+   CURSOR(ELM_CURSOR_SPIDER             , ECORE_X_CURSOR_SPIDER             ),
+   CURSOR(ELM_CURSOR_SPRAYCAN           , ECORE_X_CURSOR_SPRAYCAN           ),
+   CURSOR(ELM_CURSOR_STAR               , ECORE_X_CURSOR_STAR               ),
+   CURSOR(ELM_CURSOR_TARGET             , ECORE_X_CURSOR_TARGET             ),
+   CURSOR(ELM_CURSOR_TCROSS             , ECORE_X_CURSOR_TCROSS             ),
+   CURSOR(ELM_CURSOR_TOP_LEFT_ARROW     , ECORE_X_CURSOR_TOP_LEFT_ARROW     ),
+   CURSOR(ELM_CURSOR_TOP_LEFT_CORNER    , ECORE_X_CURSOR_TOP_LEFT_CORNER    ),
+   CURSOR(ELM_CURSOR_TOP_RIGHT_CORNER   , ECORE_X_CURSOR_TOP_RIGHT_CORNER   ),
+   CURSOR(ELM_CURSOR_TOP_SIDE           , ECORE_X_CURSOR_TOP_SIDE           ),
+   CURSOR(ELM_CURSOR_TOP_TEE            , ECORE_X_CURSOR_TOP_TEE            ),
+   CURSOR(ELM_CURSOR_TREK               , ECORE_X_CURSOR_TREK               ),
+   CURSOR(ELM_CURSOR_UL_ANGLE           , ECORE_X_CURSOR_UL_ANGLE           ),
+   CURSOR(ELM_CURSOR_UMBRELLA           , ECORE_X_CURSOR_UMBRELLA           ),
+   CURSOR(ELM_CURSOR_UR_ANGLE           , ECORE_X_CURSOR_UR_ANGLE           ),
+   CURSOR(ELM_CURSOR_WATCH              , ECORE_X_CURSOR_WATCH              ),
+   CURSOR(ELM_CURSOR_XTERM              , ECORE_X_CURSOR_XTERM              )
+};
+static const int _cursors_count = sizeof(_cursors)/sizeof(struct _Cursor_Id);
+
+#define ELM_CURSOR_GET_OR_RETURN(cur, obj, ...)         \
+  Elm_Cursor *cur;                                      \
+  do                                                    \
+    {                                                   \
+       if (!(obj))                                      \
+         {                                              \
+            CRITICAL("Null pointer: " #obj);            \
+            return __VA_ARGS__;                         \
+         }                                              \
+       cur = evas_object_data_get((obj), _cursor_key);  \
+       if (!cur)                                        \
+         {                                              \
+            ERR("Object does not have cursor: " #obj);  \
+            return __VA_ARGS__;                         \
+         }                                              \
+    }                                                   \
+  while (0)
+
+struct _Elm_Cursor
+{
+   Evas_Object *obj;
+   Evas_Object *eventarea, *owner;
+   const char *style, *cursor_name;
+   int hot_x, hot_y;
+   Ecore_Evas *ee;
+   Evas *evas;
+#ifdef HAVE_ELEMENTARY_X
+   Ecore_X_Cursor cursor;
+   Ecore_X_Window win;
+#endif
+   Eina_Bool visible:1;
+   Eina_Bool use_engine:1;
+   Eina_Bool engine_only:1;
+};
+
+static void
+_elm_cursor_obj_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Cursor *cur = data;
+
+   if (cur) cur->obj = NULL;
+}
+
+static Eina_Bool
+_elm_cursor_obj_add(Evas_Object *obj, Elm_Cursor *cur)
+{
+   int x, y;
+
+   cur->obj = edje_object_add(cur->evas);
+
+   if (!cur->obj)
+     return EINA_FALSE;
+
+   if (!_elm_theme_object_set(obj, cur->obj, "cursor", cur->cursor_name,
+                              cur->style ? cur->style : "default"))
+     {
+        evas_object_del(cur->obj);
+        cur->obj = NULL;
+        return EINA_FALSE;
+     }
+
+   evas_object_event_callback_add(cur->obj, EVAS_CALLBACK_DEL,
+                                  _elm_cursor_obj_del, cur);
+
+   edje_object_size_min_get(cur->obj, &x, &y);
+   evas_object_resize(cur->obj, x, y);
+   return EINA_TRUE;
+}
+
+static void
+_elm_cursor_set_hot_spots(Elm_Cursor *cur)
+{
+   const char *str;
+
+   str = edje_object_data_get(cur->obj, "hot_x");
+   if (str) cur->hot_x = atoi(str);
+   else cur->hot_x = 0;
+
+   str = edje_object_data_get(cur->obj, "hot_y");
+   if (str) cur->hot_y = atoi(str);
+   else cur->hot_y = 0;
+}
+
+static void
+_elm_cursor_mouse_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Cursor *cur = data;
+
+   if (cur->visible) return;
+   evas_event_freeze(cur->evas);
+   cur->visible = EINA_TRUE;
+   if ((!cur->engine_only) && (!cur->use_engine))
+     {
+        if (!cur->obj)
+          _elm_cursor_obj_add(cur->eventarea, cur);
+        ecore_evas_object_cursor_set(cur->ee, cur->obj,
+                                     ELM_OBJECT_LAYER_CURSOR, cur->hot_x,
+                                     cur->hot_y);
+     }
+   else
+     {
+#ifdef HAVE_ELEMENTARY_X
+        ecore_x_window_cursor_set(cur->win, cur->cursor);
+#endif
+     }
+   evas_event_thaw(cur->evas);
+}
+
+static void
+_elm_cursor_mouse_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Evas_Object *sobj_parent;
+   Elm_Cursor *pcur = NULL;
+   Elm_Cursor *cur = data;
+
+   if (!cur->visible) return;
+   evas_event_freeze(cur->evas);
+   cur->visible = EINA_FALSE;
+
+   sobj_parent = evas_object_data_get(cur->eventarea, "elm-parent");
+   while (sobj_parent)
+     {
+        pcur = evas_object_data_get((sobj_parent), _cursor_key);
+        if ((pcur) && (pcur->visible)) break;
+        sobj_parent = evas_object_data_get(sobj_parent, "elm-parent");
+     }
+
+   if (pcur)
+     {
+        pcur->visible = EINA_FALSE;
+        evas_event_thaw(cur->evas);
+        _elm_cursor_mouse_in(pcur, NULL, NULL, NULL);
+        return;
+     }
+
+   if ((!cur->engine_only) || (!cur->use_engine))
+     {
+        ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR,
+                                     cur->hot_x, cur->hot_y);
+     }
+   else
+     {
+#ifdef HAVE_ELEMENTARY_X
+        ecore_x_window_cursor_set(cur->win, ECORE_X_CURSOR_X);
+#endif
+     }
+   evas_event_thaw(cur->evas);
+}
+
+static void
+_elm_cursor_del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   elm_object_cursor_unset(obj);
+}
+
+static int
+_elm_cursor_strcmp(const void *data1, const void *data2)
+{
+   const struct _Cursor_Id *c1 = data1;
+   const struct _Cursor_Id *c2 = data2;
+   return strcmp (c1->name, c2->name);
+}
+
+static void
+_elm_cursor_cur_set(Elm_Cursor *cur)
+{
+   if (cur->engine_only)
+     {
+        INF("Using only engine cursors");
+        cur->use_engine = EINA_TRUE;
+     }
+   else if (_elm_cursor_obj_add(cur->eventarea, cur))
+     {
+        _elm_cursor_set_hot_spots(cur);
+        cur->use_engine = EINA_FALSE;
+        elm_widget_cursor_add(cur->owner, cur);
+     }
+   else
+     {
+        INF("Cursor couldn't be found on theme: %s", cur->cursor_name);
+        cur->use_engine = EINA_TRUE;
+     }
+
+   if (cur->use_engine)
+     {
+#ifdef HAVE_ELEMENTARY_X
+        struct _Cursor_Id cur_search, *cur_id;
+
+        cur_search.name = cur->cursor_name;
+        cur_id = bsearch(&(cur->cursor_name), _cursors, _cursors_count,
+                         sizeof(struct _Cursor_Id), _elm_cursor_strcmp);
+
+        cur->win = elm_win_xwindow_get(cur->eventarea);
+        if (!cur_id)
+          {
+             INF("X cursor couldn't be found: %s. Using default.",
+                 cur->cursor_name);
+             cur->cursor = ecore_x_cursor_shape_get(ECORE_X_CURSOR_X);
+          }
+        else
+           cur->cursor = ecore_x_cursor_shape_get(cur_id->id);
+#endif
+     }
+}
+
+/**
+ * Set the cursor to be shown when mouse is over the object
+ *
+ * Set the cursor that will be displayed when mouse is over the
+ * object. The object can have only one cursor set to it, so if
+ * this function is called twice for an object, the previous set
+ * will be unset.
+ * If using X cursors, a definition of all the valid cursor names
+ * is listed on Elementary_Cursors.h. If an invalid name is set
+ * the default cursor will be used.
+ *
+ * This is an internal function that is used by objects with sub-items
+ * that want to provide different cursors for each of them. The @a
+ * owner object should be an elm_widget and will be used to track
+ * theme changes and to feed @a func and @a del_cb. The @a eventarea
+ * may be any object and is the one that should be used later on with
+ * elm_object_cursor apis, such as elm_object_cursor_unset().
+ *
+ * @param eventarea the object being attached a cursor.
+ * @param owner the elm_widget that owns this object, will be used to
+ *        track theme changes and to be used in @a func or @a del_cb.
+ * @param cursor the cursor name to be used.
+ *
+ * @internal
+ * @ingroup Cursors
+ */
+void
+elm_object_sub_cursor_set(Evas_Object *eventarea, Evas_Object *owner, const char *cursor)
+{
+   Elm_Cursor *cur = NULL;
+
+   cur = evas_object_data_get(eventarea, _cursor_key);
+   if (cur)
+     elm_object_cursor_unset(eventarea);
+
+   if (!cursor) return;
+
+   cur = ELM_NEW(Elm_Cursor);
+   if (!cur) return;
+
+   cur->owner = owner;
+   cur->eventarea = eventarea;
+   cur->engine_only = _elm_config->cursor_engine_only;
+   cur->visible = EINA_FALSE;
+
+   cur->cursor_name = eina_stringshare_add(cursor);
+   if (!cur->cursor_name)
+     ERR("Could not store cursor name %s", cursor);
+
+   cur->evas = evas_object_evas_get(eventarea);
+   cur->ee = ecore_evas_ecore_evas_get(cur->evas);
+
+   _elm_cursor_cur_set(cur);
+
+   evas_object_data_set(eventarea, _cursor_key, cur);
+
+   evas_object_event_callback_add(eventarea, EVAS_CALLBACK_MOUSE_IN,
+                                  _elm_cursor_mouse_in, cur);
+   evas_object_event_callback_add(eventarea, EVAS_CALLBACK_MOUSE_OUT,
+                                  _elm_cursor_mouse_out, cur);
+   evas_object_event_callback_add(eventarea, EVAS_CALLBACK_DEL,
+                                  _elm_cursor_del, cur);
+}
+
+/**
+ * Set the cursor to be shown when mouse is over the object
+ *
+ * Set the cursor that will be displayed when mouse is over the
+ * object. The object can have only one cursor set to it, so if
+ * this function is called twice for an object, the previous set
+ * will be unset.
+ * If using X cursors, a definition of all the valid cursor names
+ * is listed on Elementary_Cursors.h. If an invalid name is set
+ * the default cursor will be used.
+ *
+ * @param obj the object being set a cursor.
+ * @param cursor the cursor name to be used.
+ *
+ * @ingroup Cursors
+ */
+EAPI void
+elm_object_cursor_set(Evas_Object *obj, const char *cursor)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   elm_object_sub_cursor_set(obj, obj, cursor);
+}
+
+/**
+ * Get the cursor to be shown when mouse is over the object
+ *
+ * @param obj an object with cursor already set.
+ * @return the cursor name.
+ *
+ * @ingroup Cursors
+ */
+EAPI const char *
+elm_object_cursor_get(const Evas_Object *obj)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj, NULL);
+   return cur->cursor_name;
+}
+
+/**
+ * Unset cursor for object
+ *
+ * Unset cursor for object, and set the cursor to default if the mouse
+ * was over this object.
+ *
+ * @param obj Target object
+ * @see elm_object_cursor_set()
+ *
+ * @ingroup Cursors
+ */
+EAPI void
+elm_object_cursor_unset(Evas_Object *obj)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj);
+
+   eina_stringshare_del(cur->cursor_name);
+   eina_stringshare_del(cur->style);
+
+   if (cur->owner)
+     elm_widget_cursor_del(cur->owner, cur);
+
+   if (cur->obj)
+     evas_object_del(cur->obj);
+
+   if (cur->visible)
+     {
+        if (!cur->use_engine)
+          ecore_evas_object_cursor_set(cur->ee, NULL, ELM_OBJECT_LAYER_CURSOR,
+                                       cur->hot_x, cur->hot_y);
+#ifdef HAVE_ELEMENTARY_X
+        else
+          ecore_x_window_cursor_set(cur->win, ECORE_X_CURSOR_X);
+#endif
+     }
+
+   evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_IN,
+                                  _elm_cursor_mouse_in);
+   evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_OUT,
+                                  _elm_cursor_mouse_out);
+   evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _elm_cursor_del);
+
+   evas_object_data_del(obj, _cursor_key);
+   free(cur);
+}
+
+/**
+ * Sets a different style for this object cursor.
+ *
+ * @note before you set a style you should define a cursor with
+ *       elm_object_cursor_set()
+ *
+ * @param obj an object with cursor already set.
+ * @param style the theme style to use (default, transparent, ...)
+ *
+ * @ingroup Cursors
+ */
+EAPI void
+elm_object_cursor_style_set(Evas_Object *obj, const char *style)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj);
+
+   if (!eina_stringshare_replace(&cur->style, style))
+     ERR("Could not set current style=%s", style);
+
+   if (cur->use_engine) return;
+
+   if (!cur->obj)
+     {
+        if (!_elm_cursor_obj_add(obj, cur))
+          ERR("Could not create cursor object");
+        else
+          _elm_cursor_set_hot_spots(cur);
+     }
+   else
+     {
+        if (!_elm_theme_object_set(obj, cur->obj, "cursor", cur->cursor_name,
+                                   style))
+          ERR("Could not apply the theme to the cursor style=%s", style);
+        else
+          _elm_cursor_set_hot_spots(cur);
+     }
+}
+
+/**
+ * Get the style for this object cursor.
+ *
+ * @param obj an object with cursor already set.
+ * @return style the theme style in use, defaults to "default". If the
+ *         object does not have a cursor set, then NULL is returned.
+ *
+ * @ingroup Cursors
+ */
+EAPI const char *
+elm_object_cursor_style_get(const Evas_Object *obj)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj, NULL);
+   return cur->style ? cur->style : "default";
+}
+
+/**
+ * Notify cursor should recalculate its theme.
+ * @internal
+ */
+void
+elm_cursor_theme(Elm_Cursor *cur)
+{
+   if ((!cur) || (!cur->obj)) return;
+   if (!_elm_theme_object_set(cur->eventarea, cur->obj, "cursor",
+                              cur->cursor_name, cur->style))
+     ERR("Could not apply the theme to the cursor style=%s", cur->style);
+   else
+     _elm_cursor_set_hot_spots(cur);
+}
+
+/**
+ * Set if the cursor set should be searched on the theme or should use
+ * the provided by the engine, only.
+ *
+ * @note before you set if should look on theme you should define a cursor
+ * with elm_object_cursor_set(). By default it will only look for cursors
+ * provided by the engine.
+ *
+ * @param obj an object with cursor already set.
+ * @param engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well.
+ *
+ * @ingroup Cursors
+ */
+EAPI void
+elm_object_cursor_engine_only_set(Evas_Object *obj, Eina_Bool engine_only)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj);
+   cur->engine_only = engine_only;
+   if (cur->obj)
+     {
+        evas_object_del(cur->obj);
+        cur->obj = NULL;
+     }
+   _elm_cursor_cur_set(cur);
+}
+
+/**
+ * Get the cursor engine only usage for this object cursor.
+ *
+ * @param obj an object with cursor already set.
+ * @return engine_only boolean to define it cursors should be looked only
+ * between the provided by the engine or searched on widget's theme as well. If
+ *         the object does not have a cursor set, then EINA_FALSE is returned.
+ *
+ * @ingroup Cursors
+ */
+EAPI Eina_Bool
+elm_object_cursor_engine_only_get(const Evas_Object *obj)
+{
+   ELM_CURSOR_GET_OR_RETURN(cur, obj, EINA_FALSE);
+   return cur->engine_only;
+}
+
+/**
+ * Get the configured cursor engine only usage
+ *
+ * This gets the globally configured exclusive usage of engine cursors.
+ *
+ * @return 1 if only engine cursors should be used
+ * @ingroup Cursors
+ */
+EAPI int
+elm_cursor_engine_only_get(void)
+{
+   return _elm_config->cursor_engine_only;
+}
+
+/**
+ * Set the configured cursor engine only usage
+ *
+ * This sets the globally configured exclusive usage of engine cursors.
+ * It won't affect cursors set before changing this value.
+ *
+ * @param engine_only If 1 only engine cursors will be enabled, if 0 will
+ * look for them on theme before.
+ * @return EINA_TRUE if value is valid and setted (0 or 1)
+ * @ingroup Cursors
+ */
+EAPI Eina_Bool
+elm_cursor_engine_only_set(int engine_only)
+{
+   if ((engine_only < 0) || (engine_only > 1)) return EINA_FALSE;
+   _elm_config->cursor_engine_only = engine_only;
+   return EINA_TRUE;
+}
index 358645c..16bd62b 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_pan.h"
 #include "els_hor_scroller.h"
 
 #define SMART_NAME "els_hor_scroller"
@@ -1472,7 +1471,7 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info)
                          {
                             vel = sqrt((dx * dx) + (dy * dy)) / at;
                             if ((_elm_config->thumbscroll_friction > 0.0) &&
-                                (vel > _elm_config->thumbscroll_momentum_threshhold) &&
+                                (vel > _elm_config->thumbscroll_momentum_threshold) &&
                                 (!sd->freeze))
                               {
                                  sd->down.dx = ((double)dx / at);
@@ -1553,8 +1552,8 @@ _smart_onhold_animator(void *data)
    if (sd->down.onhold_tlast > 0.0)
      {
         td = t - sd->down.onhold_tlast;
-        vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
-        vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+        vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshold * 2.0;
+        vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshold * 2.0;
         hor_elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
         sd->down.onhold_vxe += vx;
         sd->down.onhold_vye += vy;
@@ -1707,7 +1706,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
             if ((sd->one_dir_at_a_time) &&
                 (!sd->down.dir_x) && (!sd->down.dir_y) && (!sd->down.dir_none))
               {
-                  if (x > _elm_config->thumbscroll_threshhold)
+                  if (x > _elm_config->thumbscroll_threshold)
                     {
                        if (x > (y * 2))
                          {
@@ -1716,7 +1715,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
                         }
                        else faildir++;
                    }
-                  if (y > _elm_config->thumbscroll_threshhold)
+                  if (y > _elm_config->thumbscroll_threshold)
                    {
                        if (y > (x * 2))
                         {
@@ -1749,8 +1748,8 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
 
                   if ((sd->down.dragged) ||
                       (((x * x) + (y * y)) >
-                       (_elm_config->thumbscroll_threshhold *
-                        _elm_config->thumbscroll_threshhold)) )
+                       (_elm_config->thumbscroll_threshold *
+                        _elm_config->thumbscroll_threshold)) )
                                          //|| x < SMART_MOVE_THRESHOLD)
                     {
                        if (!sd->down.dragged)
@@ -1795,35 +1794,35 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
                   evas_object_geometry_get(sd->event_obj, &ex, &ey, &ew, &eh);
                   x = ev->cur.canvas.x - ex;
                   y = ev->cur.canvas.y - ey;
-                  if (x < _elm_config->thumbscroll_threshhold)
+                  if (x < _elm_config->thumbscroll_threshold)
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vx = -(double)(_elm_config->thumbscroll_threshhold - x) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vx = -(double)(_elm_config->thumbscroll_threshold - x) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vx = -1.0;
                     }
-                  else if (x > (ew - _elm_config->thumbscroll_threshhold))
+                  else if (x > (ew - _elm_config->thumbscroll_threshold))
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vx = (double)(_elm_config->thumbscroll_threshhold - (ew - x)) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vx = (double)(_elm_config->thumbscroll_threshold - (ew - x)) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vx = 1.0;
                     }
-                  if (y < _elm_config->thumbscroll_threshhold)
+                  if (y < _elm_config->thumbscroll_threshold)
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vy = -(double)(_elm_config->thumbscroll_threshhold - y) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vy = -(double)(_elm_config->thumbscroll_threshold - y) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vy = -1.0;
                     }
-                  else if (y > (eh - _elm_config->thumbscroll_threshhold))
+                  else if (y > (eh - _elm_config->thumbscroll_threshold))
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vy = (double)(_elm_config->thumbscroll_threshhold - (eh - y)) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vy = (double)(_elm_config->thumbscroll_threshold - (eh - y)) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vy = 1.0;
                     }
index 7d39442..461cc9b 100644 (file)
@@ -1,6 +1,5 @@
 #include <Elementary.h>
 #include "elm_priv.h"
-#include "els_scroller.h"
 #include "els_pan.h"
 
 #define SMART_NAME "els_scroller"
@@ -1576,12 +1575,12 @@ _smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj , void *event_info)
                             vel = sqrt((dx * dx) + (dy * dy)) / at;
 
                             if(sd->one_page) {
-                                 if(vel < _elm_config->thumbscroll_momentum_threshhold)
-                                      vel = _elm_config->thumbscroll_momentum_threshhold +1;
+                                 if(vel < _elm_config->thumbscroll_momentum_threshold)
+                                      vel = _elm_config->thumbscroll_momentum_threshold +1;
                             }
 
                             if ((_elm_config->thumbscroll_friction > 0.0) &&
-                                (vel > _elm_config->thumbscroll_momentum_threshhold) &&
+                                (vel > _elm_config->thumbscroll_momentum_threshold) &&
                                 (!sd->freeze))
                               {
                                  sd->down.dx = ((double)dx / at);
@@ -1719,8 +1718,8 @@ _smart_onhold_animator(void *data)
    if (sd->down.onhold_tlast > 0.0)
      {
         td = t - sd->down.onhold_tlast;
-        vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
-        vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshhold * 2.0;
+        vx = sd->down.onhold_vx * td * (double)_elm_config->thumbscroll_threshold * 2.0;
+        vy = sd->down.onhold_vy * td * (double)_elm_config->thumbscroll_threshold * 2.0;
         elm_smart_scroller_child_pos_get(sd->smart_obj, &ox, &oy);
         x = ox;
         y = oy;
@@ -1865,7 +1864,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                   if ((sd->one_dir_at_a_time) &&
                       (!((sd->down.dir_x) || (sd->down.dir_y))))
                     {
-                       if (x > _elm_config->thumbscroll_threshhold)
+                       if (x > _elm_config->thumbscroll_threshold)
                          {
                             if (x > (y * 2))
                               {
@@ -1874,7 +1873,7 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                                  dodir++;
                               }
                          }
-                       if (y > _elm_config->thumbscroll_threshhold)
+                       if (y > _elm_config->thumbscroll_threshold)
                          {
                             if (y > (x * 2))
                               {
@@ -1903,8 +1902,8 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                {
                   if ((sd->down.dragged) ||
                       (((x * x) + (y * y)) >
-                       (_elm_config->thumbscroll_threshhold *
-                        _elm_config->thumbscroll_threshhold)))
+                       (_elm_config->thumbscroll_threshold *
+                        _elm_config->thumbscroll_threshold)))
                     {
                        sd->down.dragged_began = 1;
                        if (!sd->down.dragged)
@@ -1972,35 +1971,35 @@ _smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *
                   evas_object_geometry_get(sd->event_obj, &ex, &ey, &ew, &eh);
                   x = ev->cur.canvas.x - ex;
                   y = ev->cur.canvas.y - ey;
-                  if (x < _elm_config->thumbscroll_threshhold)
+                  if (x < _elm_config->thumbscroll_threshold)
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vx = -(double)(_elm_config->thumbscroll_threshhold - x) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vx = -(double)(_elm_config->thumbscroll_threshold - x) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vx = -1.0;
                     }
-                  else if (x > (ew - _elm_config->thumbscroll_threshhold))
+                  else if (x > (ew - _elm_config->thumbscroll_threshold))
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vx = (double)(_elm_config->thumbscroll_threshhold - (ew - x)) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vx = (double)(_elm_config->thumbscroll_threshold - (ew - x)) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vx = 1.0;
                     }
-                  if (y < _elm_config->thumbscroll_threshhold)
+                  if (y < _elm_config->thumbscroll_threshold)
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vy = -(double)(_elm_config->thumbscroll_threshhold - y) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vy = -(double)(_elm_config->thumbscroll_threshold - y) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vy = -1.0;
                     }
-                  else if (y > (eh - _elm_config->thumbscroll_threshhold))
+                  else if (y > (eh - _elm_config->thumbscroll_threshold))
                     {
-                       if (_elm_config->thumbscroll_threshhold > 0.0)
-                         vy = (double)(_elm_config->thumbscroll_threshhold - (eh - y)) /
-                         _elm_config->thumbscroll_threshhold;
+                       if (_elm_config->thumbscroll_threshold > 0.0)
+                         vy = (double)(_elm_config->thumbscroll_threshold - (eh - y)) /
+                         _elm_config->thumbscroll_threshold;
                        else
                          vy = 1.0;
                     }
diff --git a/src/lib/els_tooltip.c b/src/lib/els_tooltip.c
new file mode 100644 (file)
index 0000000..060f06f
--- /dev/null
@@ -0,0 +1,787 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+/**
+ * @defgroup Tooltips Tooltips
+ *
+ * The Tooltip is an (internal, for now) smart object used to show a
+ * content in a frame on mouse hover of objects(or widgets), with
+ * tips/information about them.
+ */
+
+static const char _tooltip_key[] = "_elm_tooltip";
+
+#define ELM_TOOLTIP_GET_OR_RETURN(tt, obj, ...)         \
+  Elm_Tooltip *tt;                                      \
+  do                                                    \
+    {                                                   \
+       if (!(obj))                                      \
+         {                                              \
+            CRITICAL("Null pointer: " #obj);            \
+            return __VA_ARGS__;                         \
+         }                                              \
+       tt = evas_object_data_get((obj), _tooltip_key);  \
+       if (!tt)                                         \
+         {                                              \
+            ERR("Object does not have tooltip: " #obj); \
+            return __VA_ARGS__;                         \
+         }                                              \
+    }                                                   \
+  while (0)
+
+struct _Elm_Tooltip
+{
+   Elm_Tooltip_Content_Cb   func;
+   Evas_Smart_Cb            del_cb;
+   const void              *data;
+   const char              *style;
+   Evas                    *evas;
+   Evas_Object             *eventarea, *owner;
+   Evas_Object             *tooltip, *content;
+   Ecore_Timer             *show_timer;
+   Ecore_Timer             *hide_timer;
+   Ecore_Job               *reconfigure_job;
+   struct {
+      Evas_Coord            x, y, bx, by;
+   } pad;
+   struct {
+      double                x, y;
+   } rel_pos;
+   double                   hide_timeout; /* from theme */
+   Eina_Bool                visible_lock:1;
+   Eina_Bool                changed_style:1;
+};
+
+static void _elm_tooltip_reconfigure(Elm_Tooltip *tt);
+static void _elm_tooltip_reconfigure_job_start(Elm_Tooltip *tt);
+static void _elm_tooltip_reconfigure_job_stop(Elm_Tooltip *tt);
+static void _elm_tooltip_hide_anim_start(Elm_Tooltip *tt);
+static void _elm_tooltip_hide_anim_stop(Elm_Tooltip *tt);
+static void _elm_tooltip_show_timer_stop(Elm_Tooltip *tt);
+static void _elm_tooltip_hide(Elm_Tooltip *tt);
+static void _elm_tooltip_data_clean(Elm_Tooltip *tt);
+
+
+static void
+_elm_tooltip_content_changed_hints_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   _elm_tooltip_reconfigure_job_start(data);
+}
+
+static void
+_elm_tooltip_content_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+   tt->content = NULL;
+   tt->visible_lock = EINA_FALSE;
+   _elm_tooltip_hide(tt);
+}
+
+static void
+_elm_tooltip_obj_move_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+   _elm_tooltip_reconfigure_job_start(tt);
+}
+
+static void
+_elm_tooltip_obj_resize_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+   _elm_tooltip_reconfigure_job_start(tt);
+}
+
+static void
+_elm_tooltip_obj_mouse_move_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+   _elm_tooltip_reconfigure_job_start(tt);
+}
+
+static void
+_elm_tooltip_show(Elm_Tooltip *tt)
+{
+   _elm_tooltip_show_timer_stop(tt);
+   _elm_tooltip_hide_anim_stop(tt);
+
+   if (tt->tooltip)
+     {
+        _elm_tooltip_reconfigure_job_start(tt);
+        return;
+     }
+   tt->tooltip = edje_object_add(tt->evas);
+   if (!tt->tooltip) return;
+
+   evas_object_layer_set(tt->tooltip, ELM_OBJECT_LAYER_TOOLTIP);
+
+   evas_object_event_callback_add
+     (tt->eventarea, EVAS_CALLBACK_MOVE, _elm_tooltip_obj_move_cb, tt);
+   evas_object_event_callback_add
+     (tt->eventarea, EVAS_CALLBACK_RESIZE, _elm_tooltip_obj_resize_cb, tt);
+   evas_object_event_callback_add
+     (tt->eventarea, EVAS_CALLBACK_MOUSE_MOVE, _elm_tooltip_obj_mouse_move_cb, tt);
+
+   evas_object_pass_events_set(tt->tooltip, EINA_TRUE);
+   tt->changed_style = EINA_TRUE;
+   _elm_tooltip_reconfigure_job_start(tt);
+}
+
+static void
+_elm_tooltip_content_del(Elm_Tooltip *tt)
+{
+   if (!tt->content) return;
+
+   evas_object_event_callback_del_full
+     (tt->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+      _elm_tooltip_content_changed_hints_cb, tt);
+   evas_object_event_callback_del_full
+     (tt->content, EVAS_CALLBACK_DEL,
+      _elm_tooltip_content_del_cb, tt);
+   evas_object_del(tt->content);
+   tt->content = NULL;
+}
+
+
+static void
+_elm_tooltip_hide(Elm_Tooltip *tt)
+{
+   _elm_tooltip_show_timer_stop(tt);
+   _elm_tooltip_hide_anim_stop(tt);
+   _elm_tooltip_reconfigure_job_stop(tt);
+
+   if (!tt->tooltip) return;
+   if (tt->visible_lock) return;
+
+   _elm_tooltip_content_del(tt);
+
+   evas_object_event_callback_del_full
+     (tt->eventarea, EVAS_CALLBACK_MOVE, _elm_tooltip_obj_move_cb, tt);
+   evas_object_event_callback_del_full
+     (tt->eventarea, EVAS_CALLBACK_RESIZE, _elm_tooltip_obj_resize_cb, tt);
+   evas_object_event_callback_del_full
+     (tt->eventarea, EVAS_CALLBACK_MOUSE_MOVE, _elm_tooltip_obj_mouse_move_cb, tt);
+
+   evas_object_del(tt->tooltip);
+   tt->tooltip = NULL;
+}
+
+static void
+_elm_tooltip_reconfigure_job(void *data)
+{
+   Elm_Tooltip *tt = data;
+   tt->reconfigure_job = NULL;
+   _elm_tooltip_reconfigure(data);
+}
+
+static void
+_elm_tooltip_reconfigure_job_stop(Elm_Tooltip *tt)
+{
+   if (!tt->reconfigure_job) return;
+   ecore_job_del(tt->reconfigure_job);
+   tt->reconfigure_job = NULL;
+}
+
+static void
+_elm_tooltip_reconfigure_job_start(Elm_Tooltip *tt)
+{
+   if (tt->reconfigure_job) ecore_job_del(tt->reconfigure_job);
+   tt->reconfigure_job = ecore_job_add
+     (_elm_tooltip_reconfigure_job, tt);
+}
+
+static Eina_Bool
+_elm_tooltip_hide_anim_cb(void *data)
+{
+   Elm_Tooltip *tt = data;
+   tt->hide_timer = NULL;
+   _elm_tooltip_hide(tt);
+   return EINA_FALSE;
+}
+
+static void
+_elm_tooltip_hide_anim_start(Elm_Tooltip *tt)
+{
+   if (tt->hide_timer) return;
+   edje_object_signal_emit(tt->tooltip, "elm,action,hide", "elm");
+   tt->hide_timer = ecore_timer_add
+     (tt->hide_timeout, _elm_tooltip_hide_anim_cb, tt);
+}
+
+static void
+_elm_tooltip_hide_anim_stop(Elm_Tooltip *tt)
+{
+   if (!tt->hide_timer) return;
+   if (tt->tooltip)
+     edje_object_signal_emit(tt->tooltip, "elm,action,show", "elm");
+   ecore_timer_del(tt->hide_timer);
+   tt->hide_timer = NULL;
+}
+
+static void
+_elm_tooltip_reconfigure(Elm_Tooltip *tt)
+{
+   Evas_Coord ox, oy, ow, oh, px, py, tx, ty, tw, th, cw, ch;
+   Evas_Coord eminw, eminh, ominw, ominh;
+   double rel_x, rel_y;
+   Eina_Bool inside_eventarea;
+
+   _elm_tooltip_reconfigure_job_stop(tt);
+
+   if (tt->hide_timer) return;
+   if (!tt->tooltip) return;
+   if (tt->changed_style)
+     {
+        const char *style = tt->style ? tt->style : "default";
+        const char *str;
+        if (!_elm_theme_object_set
+            (tt->owner, tt->tooltip, "tooltip", "base", style))
+          {
+             ERR("Could not apply the theme to the tooltip! style=%s", style);
+             evas_object_del(tt->tooltip);
+             tt->tooltip = NULL;
+             return;
+          }
+
+        tt->rel_pos.x = 0;
+        tt->rel_pos.y = 0;
+
+        tt->pad.x = 0;
+        tt->pad.y = 0;
+        tt->pad.bx = 0;
+        tt->pad.by = 0;
+        tt->hide_timeout = 0.0;
+
+        str = edje_object_data_get(tt->tooltip, "pad_x");
+        if (str) tt->pad.x = atoi(str);
+        str = edje_object_data_get(tt->tooltip, "pad_y");
+        if (str) tt->pad.y = atoi(str);
+
+        str = edje_object_data_get(tt->tooltip, "pad_border_x");
+        if (str) tt->pad.bx = atoi(str);
+        str = edje_object_data_get(tt->tooltip, "pad_border_y");
+        if (str) tt->pad.by = atoi(str);
+
+        str = edje_object_data_get(tt->tooltip, "hide_timeout");
+        if (str)
+          {
+             tt->hide_timeout = atof(str);
+             if (tt->hide_timeout < 0.0) tt->hide_timeout = 0.0;
+          }
+
+        evas_object_pass_events_set(tt->tooltip, EINA_TRUE);
+        tt->changed_style = EINA_FALSE;
+        if (tt->tooltip)
+          edje_object_part_swallow
+            (tt->tooltip, "elm.swallow.content", tt->content);
+
+        edje_object_signal_emit(tt->tooltip, "elm,action,show", "elm");
+     }
+
+   if (!tt->content)
+     {
+        tt->content = tt->func((void *)tt->data, tt->owner);
+        if (!tt->content)
+          {
+             WRN("could not create tooltip content!");
+             evas_object_del(tt->tooltip);
+             tt->tooltip = NULL;
+             return;
+          }
+        evas_object_layer_set(tt->content, ELM_OBJECT_LAYER_TOOLTIP);
+        evas_object_pass_events_set(tt->content, EINA_TRUE);
+        edje_object_part_swallow
+          (tt->tooltip, "elm.swallow.content", tt->content);
+        evas_object_event_callback_add
+          (tt->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+           _elm_tooltip_content_changed_hints_cb, tt);
+        evas_object_event_callback_add
+          (tt->content, EVAS_CALLBACK_DEL,
+           _elm_tooltip_content_del_cb, tt);
+
+     }
+
+   evas_object_size_hint_min_get(tt->content, &ominw, &ominh);
+   edje_object_size_min_get(tt->tooltip, &eminw, &eminh);
+
+   if (ominw < eminw) ominw = eminw;
+   if (ominh < eminh) ominh = eminh;
+
+   if (ominw < 1) ominw = 10; /* at least it is noticeable */
+   if (ominh < 1) ominh = 10; /* at least it is noticeable */
+
+   edje_object_size_min_restricted_calc
+     (tt->tooltip, &tw, &th, ominw, ominh);
+
+   evas_output_size_get(tt->evas, &cw, &ch);
+   evas_pointer_canvas_xy_get(tt->evas, &px, &py);
+
+   evas_object_geometry_get(tt->eventarea, &ox, &oy, &ow, &oh);
+
+   inside_eventarea = ((px >= ox) && (py >= oy) &&
+                       (px <= ox + ow) && (py <= oy + oh));
+   if (inside_eventarea)
+     {
+        tx = px;
+        ty = py;
+
+        if (tx + tw + tt->pad.x < cw) tx += tt->pad.x;
+        if (ty + th + tt->pad.y < ch) ty += tt->pad.y;
+     }
+   else
+     {
+        tx = ox + (ow / 2) - (tw / 2);
+        if (ch < (th + oy + oh)) ty = oy - th;
+        else ty = oy + oh;
+     }
+
+   if (tt->pad.bx * 2 + tw < cw)
+     {
+        if (tx < tt->pad.bx) tx = tt->pad.bx;
+        else if (tx + tw >= cw - tt->pad.bx) tx = cw - tw - tt->pad.bx;
+     }
+
+   if (tt->pad.by * 2 + th < ch)
+     {
+        if (ty < tt->pad.by) ty = tt->pad.by;
+        else if (ty + th >= ch - tt->pad.by) ty = ch - th - tt->pad.by;
+     }
+
+   evas_object_move(tt->tooltip, tx, ty);
+   evas_object_resize(tt->tooltip, tw, th);
+   evas_object_show(tt->tooltip);
+
+   if (inside_eventarea)
+     {
+        rel_x = (px - tx) / (double)tw;
+        rel_y = (py - ty) / (double)th;
+     }
+   else
+     {
+        rel_x = (ox + (ow / 2) - tx) / (double)tw;
+        rel_y = (oy + (oh / 2) - ty) / (double)th;
+     }
+
+#define FDIF(a, b) (fabs((a) - (b)) > 0.0001)
+   if ((FDIF(rel_x, tt->rel_pos.x)) || (FDIF(rel_y, tt->rel_pos.y)))
+     {
+        Edje_Message_Float_Set *msg;
+
+        msg = alloca(sizeof(Edje_Message_Float_Set) + sizeof(double));
+        msg->count = 2;
+        msg->val[0] = rel_x;
+        msg->val[1] = rel_y;
+        tt->rel_pos.x = rel_x;
+        tt->rel_pos.y = rel_y;
+
+        edje_object_message_send(tt->tooltip, EDJE_MESSAGE_FLOAT_SET, 1, msg);
+     }
+#undef FDIF
+}
+
+static void
+_elm_tooltip_show_timer_stop(Elm_Tooltip *tt)
+{
+   if (!tt->show_timer) return;
+   ecore_timer_del(tt->show_timer);
+   tt->show_timer = NULL;
+}
+
+static Eina_Bool
+_elm_tooltip_timer_show_cb(void *data)
+{
+   Elm_Tooltip *tt = data;
+   tt->show_timer = NULL;
+   _elm_tooltip_show(tt);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_elm_tooltip_obj_mouse_in_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+
+   _elm_tooltip_hide_anim_stop(tt);
+
+   if ((tt->show_timer) || (tt->tooltip)) return;
+
+   tt->show_timer = ecore_timer_add
+     (_elm_config->tooltip_delay, _elm_tooltip_timer_show_cb, tt);
+}
+
+static void
+_elm_tooltip_obj_mouse_out_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+
+   if (tt->visible_lock) return;
+
+   if (!tt->tooltip)
+     {
+        _elm_tooltip_show_timer_stop(tt);
+        return;
+     }
+
+   _elm_tooltip_hide_anim_start(tt);
+}
+
+static void _elm_tooltip_obj_del_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj, void *event_info  __UNUSED__);
+
+static void
+_elm_tooltip_unset(Elm_Tooltip *tt)
+{
+   tt->visible_lock = EINA_FALSE;
+   _elm_tooltip_hide(tt);
+   _elm_tooltip_data_clean(tt);
+
+   if (tt->eventarea)
+     {
+        evas_object_event_callback_del_full
+          (tt->eventarea, EVAS_CALLBACK_MOUSE_IN,
+           _elm_tooltip_obj_mouse_in_cb, tt);
+        evas_object_event_callback_del_full
+          (tt->eventarea, EVAS_CALLBACK_MOUSE_OUT,
+           _elm_tooltip_obj_mouse_out_cb, tt);
+        evas_object_event_callback_del_full
+          (tt->eventarea, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+
+        evas_object_data_del(tt->eventarea, _tooltip_key);
+     }
+   if (tt->owner)
+     {
+        evas_object_event_callback_del_full
+          (tt->owner, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+        elm_widget_tooltip_del(tt->owner, tt);
+     }
+
+   eina_stringshare_del(tt->style);
+   free(tt);
+}
+
+static void
+_elm_tooltip_obj_del_cb(void *data, Evas *e  __UNUSED__, Evas_Object *obj, void *event_info  __UNUSED__)
+{
+   Elm_Tooltip *tt = data;
+   if (tt->eventarea == obj) tt->eventarea = NULL;
+   if (tt->owner == obj) tt->owner = NULL;
+   _elm_tooltip_unset(tt);
+}
+
+static Evas_Object *
+_elm_tooltip_label_create(void *data, Evas_Object *obj)
+{
+   Evas_Object *label = elm_label_add(obj);
+   if (!label)
+     return NULL;
+   elm_object_style_set(label, "tooltip");
+   elm_label_label_set(label, data);
+   return label;
+}
+
+static void
+_elm_tooltip_label_del_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   eina_stringshare_del(data);
+}
+
+static void
+_elm_tooltip_data_clean(Elm_Tooltip *tt)
+{
+   if (tt->del_cb) tt->del_cb((void *)tt->data, tt->owner, NULL);
+
+   _elm_tooltip_content_del(tt);
+
+   tt->data = NULL;
+   tt->del_cb = NULL;
+}
+
+/**
+ * Notify tooltip should recalculate its theme.
+ * @internal
+ */
+void
+elm_tooltip_theme(Elm_Tooltip *tt)
+{
+   if (!tt->tooltip) return;
+   tt->changed_style = EINA_TRUE;
+   _elm_tooltip_reconfigure_job_start(tt);
+}
+
+
+/**
+ * Set the content to be shown in the tooltip object for specific event area.
+ *
+ * Setup the tooltip to object. The object @a eventarea can have only
+ * one tooltip, so any previous tooltip data is removed. @p func(with
+ * @p data) will be called every time that need show the tooltip and
+ * it should return a valid Evas_Object. This object is then managed
+ * fully by tooltip system and is deleted when the tooltip is gone.
+ *
+ * This is an internal function that is used by objects with sub-items
+ * that want to provide different tooltips for each of them. The @a
+ * owner object should be an elm_widget and will be used to track
+ * theme changes and to feed @a func and @a del_cb. The @a eventarea
+ * may be any object and is the one that should be used later on with
+ * elm_object_tooltip apis, such as elm_object_tooltip_hide(),
+ * elm_object_tooltip_show() or elm_object_tooltip_unset().
+ *
+ * @param eventarea the object being attached a tooltip.
+ * @param owner the elm_widget that owns this object, will be used to
+ *        track theme changes and to be used in @a func or @a del_cb.
+ * @param func the function used to create the tooltip contents. The
+ *        @a Evas_Object parameters will receive @a owner as value.
+ * @param data what to provide to @a func as callback data/context.
+ * @param del_cb called when data is not needed anymore, either when
+ *        another callback replaces @func, the tooltip is unset with
+ *        elm_object_tooltip_unset() or the owner object @a obj
+ *        dies. This callback receives as the first parameter the
+ *        given @a data, and @c event_info is NULL.
+ *
+ * @internal
+ * @ingroup Tooltips
+ */
+void
+elm_object_sub_tooltip_content_cb_set(Evas_Object *eventarea, Evas_Object *owner, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
+{
+   Elm_Tooltip *tt = NULL;
+   Eina_Bool just_created;
+
+   EINA_SAFETY_ON_NULL_GOTO(owner, error);
+   EINA_SAFETY_ON_NULL_GOTO(eventarea, error);
+
+   if (!func)
+     {
+        elm_object_tooltip_unset(eventarea);
+        return;
+     }
+
+   tt = evas_object_data_get(eventarea, _tooltip_key);
+   if (tt)
+     {
+        if (tt->owner != owner)
+          {
+             if (tt->owner != eventarea)
+               evas_object_event_callback_del_full
+                 (tt->owner, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+
+             elm_widget_tooltip_del(tt->owner, tt);
+
+             if (owner != eventarea)
+               evas_object_event_callback_add
+                 (owner, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+
+             elm_widget_tooltip_add(tt->owner, tt);
+          }
+
+        if ((tt->func == func) && (tt->data == data) &&
+            (tt->del_cb == del_cb))
+          return;
+        _elm_tooltip_data_clean(tt);
+        just_created = EINA_FALSE;
+     }
+   else
+     {
+        tt = ELM_NEW(Elm_Tooltip);
+        if (!tt) goto error;
+
+        tt->owner = owner;
+        tt->eventarea = eventarea;
+        tt->evas = evas_object_evas_get(eventarea);
+        evas_object_data_set(eventarea, _tooltip_key, tt);
+
+        just_created = EINA_TRUE;
+
+        evas_object_event_callback_add
+          (eventarea, EVAS_CALLBACK_MOUSE_IN,
+           _elm_tooltip_obj_mouse_in_cb, tt);
+        evas_object_event_callback_add
+          (eventarea, EVAS_CALLBACK_MOUSE_OUT,
+           _elm_tooltip_obj_mouse_out_cb, tt);
+        evas_object_event_callback_add
+          (eventarea, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+
+        if (owner != eventarea)
+          evas_object_event_callback_add
+            (owner, EVAS_CALLBACK_DEL, _elm_tooltip_obj_del_cb, tt);
+
+        elm_widget_tooltip_add(tt->owner, tt);
+     }
+
+   tt->func = func;
+   tt->data = data;
+   tt->del_cb = del_cb;
+
+   if (!just_created) _elm_tooltip_reconfigure_job_start(tt);
+   return;
+
+ error:
+   if (del_cb) del_cb((void *)data, owner, NULL);
+}
+
+/**
+ * Force show tooltip of object
+ *
+ * @param obj Target object
+ *
+ * Force show the tooltip and disable hide on mouse_out.
+ * If another content is set as tooltip, the visible tooltip will hididen and
+ * showed again with new content.
+ * This can force show more than one tooltip at a time.
+ *
+ * @ingroup Tooltips
+ */
+EAPI void
+elm_object_tooltip_show(Evas_Object *obj)
+{
+   ELM_TOOLTIP_GET_OR_RETURN(tt, obj);
+   tt->visible_lock = EINA_TRUE;
+   _elm_tooltip_show(tt);
+}
+
+/**
+ * Force hide tooltip of object
+ *
+ * @param obj Target object
+ *
+ * Force hide the tooltip and (re)enable future mouse interations.
+ *
+ * @ingroup Tooltips
+ */
+EAPI void
+elm_object_tooltip_hide(Evas_Object *obj)
+{
+   ELM_TOOLTIP_GET_OR_RETURN(tt, obj);
+   tt->visible_lock = EINA_FALSE;
+   _elm_tooltip_hide_anim_start(tt);
+}
+
+/**
+ * Set the text to be shown in the tooltip object
+ *
+ * @param obj Target object
+ * @param text The text to set in the content
+ *
+ * Setup the text as tooltip to object. The object can have only one tooltip,
+ * so any previous tooltip data is removed.
+ * This method call internaly the elm_tooltip_content_cb_set().
+ *
+ * @ingroup Tooltips
+ */
+EAPI void
+elm_object_tooltip_text_set(Evas_Object *obj, const char *text)
+{
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+   EINA_SAFETY_ON_NULL_RETURN(text);
+
+   text = eina_stringshare_add(text);
+   elm_object_tooltip_content_cb_set
+     (obj, _elm_tooltip_label_create, text, _elm_tooltip_label_del_cb);
+}
+
+/**
+ * Set the content to be shown in the tooltip object
+ *
+ * Setup the tooltip to object. The object can have only one tooltip,
+ * so any previous tooltip data is removed. @p func(with @p data) will
+ * be called every time that need show the tooltip and it should
+ * return a valid Evas_Object. This object is then managed fully by
+ * tooltip system and is deleted when the tooltip is gone.
+ *
+ * @param obj the object being attached a tooltip.
+ * @param func the function used to create the tooltip contents.
+ * @param data what to provide to @a func as callback data/context.
+ * @param del_cb called when data is not needed anymore, either when
+ *        another callback replaces @func, the tooltip is unset with
+ *        elm_object_tooltip_unset() or the owner object @a obj
+ *        dies. This callback receives as the first parameter the
+ *        given @a data, and @c event_info is NULL.
+ *
+ * @ingroup Tooltips
+ */
+EAPI void
+elm_object_tooltip_content_cb_set(Evas_Object *obj, Elm_Tooltip_Content_Cb func, const void *data, Evas_Smart_Cb del_cb)
+{
+   elm_object_sub_tooltip_content_cb_set(obj, obj, func, data, del_cb);
+}
+
+/**
+ * Unset tooltip from object
+ *
+ * @param obj Target object
+ *
+ * Remove tooltip from object. The callback provided as del_cb to
+ * elm_object_tooltip_content_cb_set() will be called to notify it is
+ * not used anymore.
+ *
+ * @see elm_object_tooltip_content_cb_set()
+ *
+ * @ingroup Tooltips
+ */
+EAPI void
+elm_object_tooltip_unset(Evas_Object *obj)
+{
+   ELM_TOOLTIP_GET_OR_RETURN(tt, obj);
+   _elm_tooltip_unset(tt);
+}
+
+/**
+ * Sets a different style for this object tooltip.
+ *
+ * @note before you set a style you should define a tooltip with
+ *       elm_object_tooltip_content_cb_set() or
+ *       elm_object_tooltip_text_set().
+ *
+ * @param obj an object with tooltip already set.
+ * @param style the theme style to use (default, transparent, ...)
+ */
+EAPI void
+elm_object_tooltip_style_set(Evas_Object *obj, const char *style)
+{
+   ELM_TOOLTIP_GET_OR_RETURN(tt, obj);
+   if (!eina_stringshare_replace(&tt->style, style)) return;
+   elm_tooltip_theme(tt);
+}
+
+/**
+ * Get the style for this object tooltip.
+ *
+ * @param obj an object with tooltip already set.
+ * @return style the theme style in use, defaults to "default". If the
+ *         object does not have a tooltip set, then NULL is returned.
+ */
+EAPI const char *
+elm_object_tooltip_style_get(const Evas_Object *obj)
+{
+   ELM_TOOLTIP_GET_OR_RETURN(tt, obj, NULL);
+   return tt->style ? tt->style : "default";
+}
+
+/**
+ * Get the configured tooltip delay
+ *
+ * This gets the globally configured tooltip delay in seconds
+ *
+ * @return The tooltip delay
+ * @ingroup Tooltips
+ */
+EAPI double
+elm_tooltip_delay_get(void)
+{
+   return _elm_config->tooltip_delay;
+}
+
+/**
+ * Set the configured tooltip delay
+ *
+ * This sets the globally configured delay to tooltip
+ *
+ * @param delay The delay to show the tooltip
+ * @return EINA_TRUE if value is valid and setted
+ * @ingroup Tooltips
+ */
+EAPI Eina_Bool
+elm_tooltip_delay_set(double delay)
+{
+   if (delay < 0.0) return EINA_FALSE;
+   _elm_config->tooltip_delay = delay;
+   return EINA_TRUE;
+}