Big giant "e18-wayland-only starting to work" commit so I can continue
authorChris Michael <cp.michael@samsung.com>
Tue, 11 Jun 2013 13:54:50 +0000 (14:54 +0100)
committerChris Michael <cp.michael@samsung.com>
Tue, 11 Jun 2013 13:54:50 +0000 (14:54 +0100)
from home.

Signed-off-by: Chris Michael <cp.michael@samsung.com>
68 files changed:
src/bin/e_wayland/Makefile.am
src/bin/e_wayland/e_about.c [new file with mode: 0644]
src/bin/e_wayland/e_about.h [new file with mode: 0644]
src/bin/e_wayland/e_acpi.c [new file with mode: 0644]
src/bin/e_wayland/e_acpi.h [new file with mode: 0644]
src/bin/e_wayland/e_actions.c [new file with mode: 0644]
src/bin/e_wayland/e_actions.h [new file with mode: 0644]
src/bin/e_wayland/e_alert.h [new file with mode: 0644]
src/bin/e_wayland/e_bg.c [new file with mode: 0644]
src/bin/e_wayland/e_bg.h [new file with mode: 0644]
src/bin/e_wayland/e_bindings.c [new file with mode: 0644]
src/bin/e_wayland/e_bindings.h [new file with mode: 0644]
src/bin/e_wayland/e_border.c [new file with mode: 0644]
src/bin/e_wayland/e_border.h
src/bin/e_wayland/e_box.c [new file with mode: 0644]
src/bin/e_wayland/e_box.h [new file with mode: 0644]
src/bin/e_wayland/e_comp.c
src/bin/e_wayland/e_comp.h
src/bin/e_wayland/e_config_dialog.c [new file with mode: 0644]
src/bin/e_wayland/e_config_dialog.h [new file with mode: 0644]
src/bin/e_wayland/e_configure.c [new file with mode: 0644]
src/bin/e_wayland/e_configure.h [new file with mode: 0644]
src/bin/e_wayland/e_container.c
src/bin/e_wayland/e_container.h
src/bin/e_wayland/e_desk.c [new file with mode: 0644]
src/bin/e_wayland/e_desk.h [new file with mode: 0644]
src/bin/e_wayland/e_dialog.c [new file with mode: 0644]
src/bin/e_wayland/e_dialog.h [new file with mode: 0644]
src/bin/e_wayland/e_exec.c [new file with mode: 0644]
src/bin/e_wayland/e_exec.h [new file with mode: 0644]
src/bin/e_wayland/e_exehist.c [new file with mode: 0644]
src/bin/e_wayland/e_exehist.h [new file with mode: 0644]
src/bin/e_wayland/e_gadcon.c [new file with mode: 0644]
src/bin/e_wayland/e_gadcon.h [new file with mode: 0644]
src/bin/e_wayland/e_icon.c [new file with mode: 0644]
src/bin/e_wayland/e_icon.h [new file with mode: 0644]
src/bin/e_wayland/e_includes.h
src/bin/e_wayland/e_int_menus.c [new file with mode: 0644]
src/bin/e_wayland/e_int_menus.h
src/bin/e_wayland/e_ipc.c [new file with mode: 0644]
src/bin/e_wayland/e_ipc.h [new file with mode: 0644]
src/bin/e_wayland/e_ipc_codec.c [new file with mode: 0644]
src/bin/e_wayland/e_ipc_codec.h [new file with mode: 0644]
src/bin/e_wayland/e_main.c
src/bin/e_wayland/e_menu.c [new file with mode: 0644]
src/bin/e_wayland/e_menu.h [new file with mode: 0644]
src/bin/e_wayland/e_module.c
src/bin/e_wayland/e_obj_dialog.c [new file with mode: 0644]
src/bin/e_wayland/e_obj_dialog.h [new file with mode: 0644]
src/bin/e_wayland/e_output.c
src/bin/e_wayland/e_popup.c [new file with mode: 0644]
src/bin/e_wayland/e_popup.h [new file with mode: 0644]
src/bin/e_wayland/e_renderer.c
src/bin/e_wayland/e_shelf.c [new file with mode: 0644]
src/bin/e_wayland/e_shelf.h [new file with mode: 0644]
src/bin/e_wayland/e_surface.c
src/bin/e_wayland/e_sys.c [new file with mode: 0644]
src/bin/e_wayland/e_sys.h [new file with mode: 0644]
src/bin/e_wayland/e_theme_about.c [new file with mode: 0644]
src/bin/e_wayland/e_theme_about.h [new file with mode: 0644]
src/bin/e_wayland/e_thumb.c [new file with mode: 0644]
src/bin/e_wayland/e_thumb.h [new file with mode: 0644]
src/bin/e_wayland/e_utils.c
src/bin/e_wayland/e_utils.h
src/bin/e_wayland/e_win.c [new file with mode: 0644]
src/bin/e_wayland/e_win.h [new file with mode: 0644]
src/bin/e_wayland/e_zone.c [new file with mode: 0644]
src/bin/e_wayland/e_zone.h [new file with mode: 0644]

index 2481a6154321e163ddf655aa51f7c1ee9e46cea3..5a409e93814f41f0fa87e17c5647f0486cf469b0 100644 (file)
@@ -57,6 +57,34 @@ ENLIGHTENMENTHEADERS = \
   e_canvas.h \
   e_manager.h \
   e_container.h \
+  e_zone.h \
+  e_desk.h \
+  e_bg.h \
+  e_box.h \
+  e_icon.h \
+  e_menu.h \
+  e_int_menus.h \
+  e_win.h \
+  e_dialog.h \
+  e_about.h \
+  e_theme_about.h \
+  e_actions.h \
+  e_acpi.h \
+  e_exec.h \
+  e_configure.h \
+  e_config_dialog.h \
+  e_thumb.h \
+  e_shelf.h \
+  e_gadcon.h \
+  e_popup.h \
+  e_obj_dialog.h \
+  e_border.h \
+  e_sys.h \
+  e_bindings.h \
+  e_ipc.h \
+  e_ipc_codec.h \
+  e_exehist.h \
+  e_alert.h \
   e_output.h \
   e_shader.h \
   e_renderer.h
@@ -89,6 +117,33 @@ enlightenment_wl_src = \
   e_canvas.c \
   e_manager.c \
   e_container.c \
+  e_zone.c \
+  e_desk.c \
+  e_bg.c \
+  e_box.c \
+  e_icon.c \
+  e_menu.c \
+  e_int_menus.c \
+  e_win.c \
+  e_dialog.c \
+  e_about.c \
+  e_theme_about.c \
+  e_actions.c \
+  e_acpi.c \
+  e_exec.c \
+  e_configure.c \
+  e_config_dialog.c \
+  e_thumb.c \
+  e_shelf.c \
+  e_gadcon.c \
+  e_popup.c \
+  e_obj_dialog.c \
+  e_border.c \
+  e_sys.c \
+  e_bindings.c \
+  e_ipc.c \
+  e_ipc_codec.c \
+  e_exehist.c \
   e_output.c \
   e_renderer.c \
   $(ENLIGHTENMENTHEADERS)
diff --git a/src/bin/e_wayland/e_about.c b/src/bin/e_wayland/e_about.c
new file mode 100644 (file)
index 0000000..2c4f0cc
--- /dev/null
@@ -0,0 +1,119 @@
+#include "e.h"
+
+/* local subsystem functions */
+
+/* local subsystem globals */
+
+/* externally accessible functions */
+
+EAPI E_About *
+e_about_new(E_Container *con)
+{
+   E_Obj_Dialog *od;
+   char buf[16384];
+   FILE *f;
+   Eina_Strbuf *tbuf;
+
+   od = e_obj_dialog_new(con, _("About Enlightenment"), "E", "_about");
+   if (!od) return NULL;
+   e_obj_dialog_obj_theme_set(od, "base/theme/about", "e/widgets/about/main");
+   e_obj_dialog_obj_part_text_set(od, "e.text.label", _("Close"));
+   e_obj_dialog_obj_part_text_set(od, "e.text.title", _("Enlightenment"));
+   e_obj_dialog_obj_part_text_set(od, "e.text.version", VERSION);
+   snprintf
+     (buf, sizeof(buf), "%s%s",
+     _(
+       "<title>Copyright &copy; 2000-2013, by the Enlightenment "
+       "Development Team</><br>"
+       "<br>"
+       "We hope you enjoy using this software as much as we enjoyed "
+       "writing it.<br>"
+       "<br>"
+       "To contact us please visit:<br>"
+       "<hilight>http://www.enlightenment.org</><br>"
+       "<br>"
+       ),
+     "All rights reserved.<br>"
+     "<br>"
+     "Redistribution and use in source and binary forms, with or without "
+     "modification, are permitted provided that the following conditions "
+     "are met:<br>"
+     "<br>"
+     "1. Redistributions of source code must retain the above copyright "
+     "notice, this list of conditions and the following disclaimer.<br>"
+     "2. Redistributions in binary form must reproduce the above copyright "
+     "notice, this list of conditions and the following disclaimer in the "
+     "documentation and/or other materials provided with the "
+     "distribution.<br>"
+     "<br>"
+     "<hilight>THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR "
+     "IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED "
+     "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE "
+     "ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR "
+     "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, "
+     "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT "
+     "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF "
+     "USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED "
+     "AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT "
+     "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN "
+     "ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE "
+     "POSSIBILITY OF SUCH DAMAGE.</><br>"
+     );
+   e_obj_dialog_obj_part_text_set(od, "e.textblock.about", buf);
+
+   e_prefix_data_concat_static(buf, "AUTHORS");
+   f = fopen(buf, "r");
+   if (f)
+     {
+        tbuf = eina_strbuf_new();
+        eina_strbuf_append(tbuf, _("<title>The Team</><br><br>"));
+        while (fgets(buf, sizeof(buf), f))
+          {
+             int len;
+
+             len = strlen(buf);
+             if (len > 0)
+               {
+                  if (buf[len - 1] == '\n')
+                    {
+                       buf[len - 1] = 0;
+                       len--;
+                    }
+                  if (len > 0)
+                    {
+                       char *p;
+
+                       do
+                         {
+                            p = strchr(buf, '<');
+                            if (p) *p = 0;
+                         }
+                       while (p);
+                       do
+                         {
+                            p = strchr(buf, '>');
+                            if (p) *p = 0;
+                         }
+                       while (p);
+                       eina_strbuf_append_printf(tbuf, "%s<br>", buf);
+                    }
+               }
+          }
+        fclose(f);
+        if (tbuf)
+          {
+             e_obj_dialog_obj_part_text_set(od, "e.textblock.authors",
+                                            (char *)eina_strbuf_string_get(tbuf));
+             eina_strbuf_free(tbuf);
+          }
+     }
+   return (E_About *)od;
+}
+
+EAPI void
+e_about_show(E_About *about)
+{
+   e_obj_dialog_show((E_Obj_Dialog *)about);
+   e_obj_dialog_icon_set((E_Obj_Dialog *)about, "help-about");
+}
+
diff --git a/src/bin/e_wayland/e_about.h b/src/bin/e_wayland/e_about.h
new file mode 100644 (file)
index 0000000..7636b8a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Obj_Dialog E_About;
+
+#else
+#ifndef E_ABOUT_H
+#define E_ABOUT_H
+
+EAPI E_About  *e_about_new         (E_Container *con);
+EAPI void      e_about_show        (E_About *about);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_acpi.c b/src/bin/e_wayland/e_acpi.c
new file mode 100644 (file)
index 0000000..6e69261
--- /dev/null
@@ -0,0 +1,382 @@
+#include "e.h"
+
+/* TODO:
+ *
+ * Sanatize data received from acpi for message status into something
+ * meaningful (ie: 00000002 == LID_CLOSED, etc, etc).
+ *
+ * Find someone with a WIFI that actually emits ACPI events and add/debug the
+ * E_EVENT_ACPI for wifi.
+ *
+ */
+
+/* local structures */
+/* for simple acpi device mapping */
+typedef struct _E_ACPI_Device_Simple      E_ACPI_Device_Simple;
+typedef struct _E_ACPI_Device_Multiplexed E_ACPI_Device_Multiplexed;
+
+struct _E_ACPI_Device_Simple
+{
+   const char *name;
+   // ->
+   int         type;
+};
+
+struct _E_ACPI_Device_Multiplexed
+{
+   const char *name;
+   const char *bus;
+   int         status;
+   // ->
+   int         type;
+};
+
+/* local function prototypes */
+static Eina_Bool _e_acpi_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event);
+static void      _e_acpi_cb_event_free(void *data __UNUSED__, void *event);
+static int       _e_acpi_lid_status_get(const char *device, const char *bus);
+static Eina_Bool _e_acpi_cb_event(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+/* local variables */
+static int _e_acpi_events_frozen = 0;
+static Ecore_Con_Server *_e_acpid = NULL;
+static Eina_List *_e_acpid_hdls = NULL;
+static Eina_Strbuf *acpibuf = NULL;
+
+static E_ACPI_Device_Simple _devices_simple[] =
+{
+   /* NB: DO NOT TRANSLATE THESE. */
+   {"ac_adapter", E_ACPI_TYPE_AC_ADAPTER},
+   {"battery", E_ACPI_TYPE_BATTERY},
+   {"button/lid", E_ACPI_TYPE_LID},
+   {"button/power", E_ACPI_TYPE_POWER},
+   {"button/sleep", E_ACPI_TYPE_SLEEP},
+   {"fan", E_ACPI_TYPE_FAN},
+   {"processor", E_ACPI_TYPE_PROCESSOR},
+   {"thermal_zone", E_ACPI_TYPE_THERMAL},
+   {"video", E_ACPI_TYPE_VIDEO},
+
+   {NULL, E_ACPI_TYPE_UNKNOWN}
+};
+
+static E_ACPI_Device_Multiplexed _devices_multiplexed[] =
+{
+   /* NB: DO NOT TRANSLATE THESE. */
+/* Sony VAIO - VPCF115FM / PCG-81114L - nvidia gfx */
+   {"sony/hotkey", NULL, 0x10, E_ACPI_TYPE_BRIGHTNESS_DOWN},
+   {"sony/hotkey", NULL, 0x11, E_ACPI_TYPE_BRIGHTNESS_UP},
+   {"sony/hotkey", NULL, 0x12, E_ACPI_TYPE_VIDEO},
+   {"sony/hotkey", NULL, 0x14, E_ACPI_TYPE_ZOOM_OUT},
+   {"sony/hotkey", NULL, 0x15, E_ACPI_TYPE_ZOOM_IN},
+   {"sony/hotkey", NULL, 0x17, E_ACPI_TYPE_HIBERNATE},
+   {"sony/hotkey", NULL, 0xa6, E_ACPI_TYPE_ASSIST},
+   {"sony/hotkey", NULL, 0x20, E_ACPI_TYPE_S1},
+   {"sony/hotkey", NULL, 0xa5, E_ACPI_TYPE_VAIO},
+
+/* Sony VAIO - X505 - intel gfx */
+   {"sony/hotkey", NULL, 0x0e, E_ACPI_TYPE_MUTE},
+   {"sony/hotkey", NULL, 0x0f, E_ACPI_TYPE_VOLUME},
+   {"sony/hotkey", NULL, 0x10, E_ACPI_TYPE_BRIGHTNESS},
+   {"sony/hotkey", NULL, 0x12, E_ACPI_TYPE_VIDEO},
+
+/* HP Compaq Presario - CQ61 - intel gfx */
+/** interesting these get auto-mapped to keys in x11. here for documentation
+** but not enabled as we can use regular keybinds for these
+   {"video",       "DD03", 0x87, E_ACPI_TYPE_BRIGHTNESS_DOWN},
+   {"video",       "DD03", 0x86, E_ACPI_TYPE_BRIGHTNESS_UP},
+   {"video",       "OVGA", 0x80, E_ACPI_TYPE_VIDEO},
+*/
+/* END */
+   {NULL, NULL, 0x00, E_ACPI_TYPE_UNKNOWN}
+};
+
+/* public variables */
+EAPI int E_EVENT_ACPI = 0;
+
+/* public functions */
+EINTERN int
+e_acpi_init(void)
+{
+   E_EVENT_ACPI = ecore_event_type_new();
+
+   /* check for running acpid */
+   if (!ecore_file_exists("/var/run/acpid.socket")) return 1;
+
+   /* try to connect to acpid socket */
+   _e_acpid = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM,
+                                       "/var/run/acpid.socket", -1, NULL);
+   if (!_e_acpid) return 1;
+
+   /* setup handlers */
+   _e_acpid_hdls =
+     eina_list_append(_e_acpid_hdls,
+                      ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
+                                              _e_acpi_cb_server_del, NULL));
+   _e_acpid_hdls =
+     eina_list_append(_e_acpid_hdls,
+                      ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
+                                              _e_acpi_cb_server_data, NULL));
+
+   /* Add handlers for standard acpi events */
+   _e_acpid_hdls =
+     eina_list_append(_e_acpid_hdls,
+                      ecore_event_handler_add(E_EVENT_ACPI,
+                                              _e_acpi_cb_event, NULL));
+   return 1;
+}
+
+EINTERN int
+e_acpi_shutdown(void)
+{
+   Ecore_Event_Handler *hdl;
+
+   /* cleanup event handlers */
+   EINA_LIST_FREE(_e_acpid_hdls, hdl)
+     ecore_event_handler_del(hdl);
+
+   /* kill the server if existing */
+   if (_e_acpid)
+     {
+        ecore_con_server_del(_e_acpid);
+        _e_acpid = NULL;
+     }
+   return 1;
+}
+
+EAPI void
+e_acpi_events_freeze(void)
+{
+   _e_acpi_events_frozen++;
+}
+
+EAPI void
+e_acpi_events_thaw(void)
+{
+   _e_acpi_events_frozen--;
+   if (_e_acpi_events_frozen < 0) _e_acpi_events_frozen = 0;
+}
+
+/* local functions */
+static Eina_Bool
+_e_acpi_cb_server_del(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Server_Del *ev;
+   Ecore_Event_Handler *hdl;
+
+   ev = event;
+   if (ev->server != _e_acpid) return ECORE_CALLBACK_PASS_ON;
+
+   /* cleanup event handlers */
+   EINA_LIST_FREE(_e_acpid_hdls, hdl)
+     ecore_event_handler_del(hdl);
+
+   /* kill the server if existing */
+   if (_e_acpid)
+     {
+        ecore_con_server_del(_e_acpid);
+        _e_acpid = NULL;
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_acpi_cb_server_data(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Con_Event_Server_Data *ev;
+   E_Event_Acpi *acpi_event;
+   int sig, status, i, done = 0;
+   char device[1024], bus[1024], *sdata;
+   const char *str, *p;
+
+   ev = event;
+
+   if ((!ev->data) || (ev->size < 1)) return ECORE_CALLBACK_PASS_ON;
+
+   /* write out actual acpi received data to stdout for debugging
+      res = fwrite(ev->data, ev->size, 1, stdout);
+    */
+   /* data from a server isnt a string - its not 0 byte terminated. it's just
+    * a blob of data. copy to string and 0 byte terminate it so it can be
+    * string-swizzled/parsed etc. */
+   if (!acpibuf) acpibuf = eina_strbuf_new();
+   eina_strbuf_append_length(acpibuf, ev->data, ev->size);
+   str = eina_strbuf_string_get(acpibuf);
+   p = strchr(str, '\n');
+   if (!p) return ECORE_CALLBACK_PASS_ON;
+   while (p)
+     {
+        sdata = alloca(p - str + 1);
+        strncpy(sdata, str, (int)(p - str));
+        sdata[p - str] = 0;
+        /* parse out this acpi string into separate pieces */
+        if (sscanf(sdata, "%1023s %1023s %x %x",
+                   device, bus, &sig, &status) != 4)
+          {
+             sig = -1;
+             status = -1;
+             if (sscanf(sdata, "%1023s %1023s", device, bus) != 2)
+               goto done_event;
+          }
+
+        /* create new event structure to raise */
+        acpi_event = E_NEW(E_Event_Acpi, 1);
+        acpi_event->bus_id = eina_stringshare_add(bus);
+        acpi_event->signal = sig;
+        acpi_event->status = status;
+
+        /* FIXME: add in a key faking layer */
+        if ((!done) && (sig >= 0) && (status >= 0))
+          {
+             for (i = 0; _devices_multiplexed[i].name; i++)
+               {
+                  // if device name matches
+                  if ((!strcmp(device, _devices_multiplexed[i].name)) &&
+                      // AND busname not set OR device name matches
+                      (!_devices_multiplexed[i].bus ||
+                       (_devices_multiplexed[i].bus &&
+                        (!strcmp(bus, _devices_multiplexed[i].bus)))) &&
+                      // AND status matches
+                      (_devices_multiplexed[i].status == status))
+                    {
+                       acpi_event->type = _devices_multiplexed[i].type;
+                       done = 1;
+                       break;
+                    }
+               }
+          }
+        if (!done)
+          {
+             // if device name matches
+             for (i = 0; _devices_simple[i].name; i++)
+               {
+                  if (!strcmp(device, _devices_simple[i].name))
+                    {
+                       acpi_event->type = _devices_simple[i].type;
+                       done = 1;
+                       break;
+                    }
+               }
+          }
+        if (!done)
+          {
+             free(acpi_event);
+             acpi_event = NULL;
+          }
+        else
+          {
+             switch (acpi_event->type)
+               {
+                case E_ACPI_TYPE_LID:
+                  acpi_event->status =
+                    _e_acpi_lid_status_get(device, bus);
+                  break;
+
+                default:
+                  break;
+               }
+             /* actually raise the event */
+             ecore_event_add(E_EVENT_ACPI, acpi_event,
+                             _e_acpi_cb_event_free, NULL);
+          }
+done_event:
+        str = p + 1;
+        p = strchr(str, '\n');
+     }
+   if (str[0] == 0)
+     {
+        eina_strbuf_free(acpibuf);
+        acpibuf = NULL;
+     }
+   else
+     {
+        Eina_Strbuf *newbuf;
+
+        newbuf = eina_strbuf_new();
+        eina_strbuf_append(newbuf, str);
+        eina_strbuf_free(acpibuf);
+        acpibuf = newbuf;
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_e_acpi_cb_event_free(void *data __UNUSED__, void *event)
+{
+   E_Event_Acpi *ev;
+
+   if (!(ev = event)) return;
+   if (ev->device) eina_stringshare_del(ev->device);
+   if (ev->bus_id) eina_stringshare_del(ev->bus_id);
+   E_FREE(ev);
+}
+
+static int
+_e_acpi_lid_status_get(const char *device, const char *bus)
+{
+   FILE *f;
+   int i = 0;
+   char buff[PATH_MAX], *ret;
+
+   /* the acpi driver code in the kernel has a nice acpi function to return
+    * the lid status easily, but that function is not exposed for user_space
+    * so we need to check the proc fs to get the actual status */
+
+   /* make sure we have a device and bus */
+   if ((!device) || (!bus)) return E_ACPI_LID_UNKNOWN;
+
+   /* open the state file from /proc */
+   snprintf(buff, sizeof(buff), "/proc/acpi/%s/%s/state", device, bus);
+   if (!(f = fopen(buff, "r")))
+     {
+        /* hack around ppurka's Thinkpad (G460 + Linux) that reports lid
+         * state as "/proc/acpi/button/lid/LID0/state" but where the lid
+         * event says "button/lid LID close".
+         *
+         * so let's take the base device name "LID" and add a numeric like
+         * 0, 1, 2, 3 so we have LID0, LID1, LID2 etc. - try up to LID9
+         * and then give up.
+         */
+        for (i = 0; i < 10; i++)
+          {
+             snprintf(buff, sizeof(buff), "/proc/acpi/%s/%s%i/state",
+                      device, bus, i);
+             if ((f = fopen(buff, "r"))) break;
+             f = NULL;
+          }
+        if (!f) return E_ACPI_LID_UNKNOWN;
+     }
+
+   /* read the line from state file */
+   ret = fgets(buff, sizeof(buff), f);
+   fclose(f);
+
+   /* parse out state file */
+   i = 0;
+   while (buff[i] != ':')
+     i++;
+   while (!isalnum(buff[i]))
+     i++;
+   ret = &(buff[i]);
+   while (isalnum(buff[i]))
+     i++;
+   buff[i] = 0;
+
+   /* compare value from state file and return something sane */
+   if (!strcmp(ret, "open")) return E_ACPI_LID_OPEN;
+   else if (!strcmp(ret, "closed"))
+     return E_ACPI_LID_CLOSED;
+   else return E_ACPI_LID_UNKNOWN;
+}
+
+static Eina_Bool
+_e_acpi_cb_event(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   E_Event_Acpi *ev;
+
+   ev = event;
+   if (_e_acpi_events_frozen > 0) return ECORE_CALLBACK_PASS_ON;
+   e_bindings_acpi_event_handle(E_BINDING_CONTEXT_NONE, NULL, ev);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
diff --git a/src/bin/e_wayland/e_acpi.h b/src/bin/e_wayland/e_acpi.h
new file mode 100644 (file)
index 0000000..6928245
--- /dev/null
@@ -0,0 +1,72 @@
+#ifdef E_TYPEDEFS
+
+/* enum for various event types */
+typedef enum _E_Acpi_Type
+{
+   E_ACPI_TYPE_UNKNOWN = 0,
+
+   E_ACPI_TYPE_AC_ADAPTER, // 1
+   E_ACPI_TYPE_BATTERY, // 2
+   E_ACPI_TYPE_BUTTON, // 3
+   E_ACPI_TYPE_FAN, // 4
+   E_ACPI_TYPE_LID, // 5
+   E_ACPI_TYPE_POWER, // 6
+   E_ACPI_TYPE_PROCESSOR, // 7
+   E_ACPI_TYPE_SLEEP, // 8
+   E_ACPI_TYPE_THERMAL, // 9
+   E_ACPI_TYPE_VIDEO, // 10
+   E_ACPI_TYPE_WIFI, // 11
+   E_ACPI_TYPE_HIBERNATE, // 12
+   E_ACPI_TYPE_ZOOM_OUT, // 13
+   E_ACPI_TYPE_ZOOM_IN, // 14
+   E_ACPI_TYPE_BRIGHTNESS_DOWN, // 15
+   E_ACPI_TYPE_BRIGHTNESS_UP, // 16
+   E_ACPI_TYPE_ASSIST, // 17
+   E_ACPI_TYPE_S1, // 18
+   E_ACPI_TYPE_VAIO, // 19
+   E_ACPI_TYPE_MUTE, // 20
+   E_ACPI_TYPE_VOLUME, // 21
+   E_ACPI_TYPE_BRIGHTNESS // 22
+} E_Acpi_Type;
+
+/* enum for acpi signals */
+typedef enum _E_Acpi_Device_Signal
+{
+   E_ACPI_DEVICE_SIGNAL_UNKNOWN, // 0
+   E_ACPI_DEVICE_SIGNAL_NOTIFY = 80,
+   E_ACPI_DEVICE_SIGNAL_CHANGED = 82, // device added or removed
+   E_ACPI_DEVICE_SIGNAL_AWAKE = 83,
+   E_ACPI_DEVICE_SIGNAL_EJECT = 84
+} E_Acpi_Device_Signal;
+
+/* enum for lid status */
+typedef enum _E_Acpi_Lid_Status
+{
+   E_ACPI_LID_UNKNOWN, // 0
+   E_ACPI_LID_CLOSED, // 1
+   E_ACPI_LID_OPEN // 2
+} E_Acpi_Lid_Status;
+
+/* struct used to pass to event handlers */
+typedef struct _E_Event_Acpi E_Event_Acpi;
+
+#else
+# ifndef E_ACPI_H
+#  define E_ACPI_H
+
+struct _E_Event_Acpi
+{
+   const char *device, *bus_id;
+   int         type, signal, status;
+};
+
+EINTERN int e_acpi_init(void);
+EINTERN int e_acpi_shutdown(void);
+
+EAPI void e_acpi_events_freeze(void);
+EAPI void e_acpi_events_thaw(void);
+
+extern EAPI int E_EVENT_ACPI;
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_actions.c b/src/bin/e_wayland/e_actions.c
new file mode 100644 (file)
index 0000000..2467f13
--- /dev/null
@@ -0,0 +1,3392 @@
+#include "e.h"
+
+#ifndef MAX
+# define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#endif
+
+#define INITS
+#define ACT_GO(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go = _e_actions_act_##name##_go; \
+   }
+#define ACT_FN_GO(act, use) \
+   static void _e_actions_act_##act##_go(E_Object *obj __UNUSED__, const char *params use)
+
+#define ACT_GO_MOUSE(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_mouse = _e_actions_act_##name##_go_mouse; \
+   }
+#define ACT_FN_GO_MOUSE(act, use) \
+   static void _e_actions_act_##act##_go_mouse(E_Object *obj __UNUSED__, const char *params use, Ecore_Event_Mouse_Button *ev __UNUSED__)
+
+#define ACT_GO_WHEEL(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_wheel = _e_actions_act_##name##_go_wheel; \
+   }
+#define ACT_FN_GO_WHEEL(act, use) \
+   static void _e_actions_act_##act##_go_wheel(E_Object *obj __UNUSED__, const char *params use, Ecore_Event_Mouse_Wheel *ev __UNUSED__)
+
+#define ACT_GO_EDGE(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_edge = _e_actions_act_##name##_go_edge; \
+   }
+#define ACT_FN_GO_EDGE(act, use) \
+   static void _e_actions_act_##act##_go_edge(E_Object *obj __UNUSED__, const char *params use, E_Event_Zone_Edge *ev __UNUSED__)
+
+#define ACT_GO_SIGNAL(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_signal = _e_actions_act_##name##_go_signal; \
+   }
+#define ACT_FN_GO_SIGNAL(act, use) \
+   static void _e_actions_act_##act##_go_signal(E_Object *obj __UNUSED__, const char *params use, const char *sig, const char *src)
+
+#define ACT_GO_KEY(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_key = _e_actions_act_##name##_go_key; \
+   }
+#define ACT_FN_GO_KEY(act, use) \
+   static void _e_actions_act_##act##_go_key(E_Object *obj __UNUSED__, const char *params use, Ecore_Event_Key *ev __UNUSED__)
+
+#define ACT_END(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.end = _e_actions_act_##name##_end; \
+   }
+#define ACT_FN_END(act, use) \
+   static void _e_actions_act_##act##_end(E_Object *obj __UNUSED__, const char *params use)
+
+#define ACT_END_MOUSE(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.end_mouse = _e_actions_act_##name##_end_mouse; \
+   }
+#define ACT_FN_END_MOUSE(act, use) \
+   static void _e_actions_act_##act##_end_mouse(E_Object *obj __UNUSED__, const char *params use, Ecore_Event_Mouse_Button *ev __UNUSED__)
+
+#define ACT_END_KEY(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.end_key = _e_actions_act_##name##_end_key; \
+   }
+#define ACT_FN_END_KEY(act, use) \
+   static void _e_actions_act_##act##_end_key(E_Object *obj __UNUSED__, const char *params use, Ecore_Event_Key *ev __UNUSED__)
+
+#define ACT_GO_ACPI(name) \
+   { \
+      act = e_action_add(#name); \
+      if (act) act->func.go_acpi = _e_actions_act_##name##_go_acpi; \
+   }
+#define ACT_FN_GO_ACPI(act, use) \
+   static void _e_actions_act_##act##_go_acpi(E_Object *obj __UNUSED__, const char *params use, E_Event_Acpi *ev __UNUSED__)
+
+/* local subsystem functions */
+static void _e_action_free(E_Action *act);
+static E_Maximize _e_actions_maximize_parse(const char *maximize);
+static int _action_groups_sort_cb(const void *d1, const void *d2);
+
+/* to save writing this in N places - the sections are defined here */
+/***************************************************************************/
+ACT_FN_GO(window_move, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* if (!((E_Border *)obj)->lock_user_location) */
+   /*   e_border_act_move_begin((E_Border *)obj, NULL); */
+}
+
+ACT_FN_GO_MOUSE(window_move, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* e_border_act_move_begin((E_Border *)obj, ev); */
+}
+
+ACT_FN_GO_SIGNAL(window_move, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* if (!((E_Border *)obj)->lock_user_location) */
+   /*   { */
+   /*  if ((params) && (!strcmp(params, "end"))) */
+   /*        e_border_signal_move_end((E_Border *)obj, sig, src); */
+   /*  else */
+   /*    { */
+   /*       if (((E_Border *)obj)->moving) */
+   /*         e_border_signal_move_end((E_Border *)obj, sig, src); */
+   /*       else */
+   /*         e_border_signal_move_begin((E_Border *)obj, sig, src); */
+   /*    } */
+   /*   } */
+}
+
+ACT_FN_END(window_move, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* e_border_act_move_end((E_Border *)obj, NULL); */
+}
+
+ACT_FN_END_MOUSE(window_move, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* e_border_act_move_end((E_Border *)obj, ev); */
+}
+
+ACT_FN_GO_KEY(window_move, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_location) */
+   /*   e_border_act_move_keyboard((E_Border *)obj); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_resize, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* if (!((E_Border *)obj)->lock_user_size) */
+   /*   e_border_act_resize_begin((E_Border *)obj, NULL); */
+}
+
+ACT_FN_GO_MOUSE(window_resize, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* if (!((E_Border *)obj)->lock_user_size) */
+   /*   e_border_act_resize_begin((E_Border *)obj, ev); */
+}
+
+ACT_FN_GO_SIGNAL(window_resize, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* if (!((E_Border *)obj)->lock_user_size) */
+   /*   { */
+   /*  if ((params) && (!strcmp(params, "end"))) */
+   /*    e_border_signal_resize_end((E_Border *)obj, params, sig, src); */
+   /*  else */
+   /*    { */
+   /*       if (!params) params = ""; */
+   /*       if (e_border_resizing_get((E_Border *)obj)) */
+   /*         e_border_signal_resize_end((E_Border *)obj, params, sig, src); */
+   /*       else */
+   /*         e_border_signal_resize_begin((E_Border *)obj, params, sig, src); */
+   /*    } */
+   /*   } */
+}
+
+ACT_FN_END(window_resize, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* e_border_act_resize_end((E_Border *)obj, NULL); */
+}
+
+ACT_FN_END_MOUSE(window_resize, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE) return;
+   /* e_border_act_resize_end((E_Border *)obj, ev); */
+}
+
+ACT_FN_GO_KEY(window_resize, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_size) */
+   /*   e_border_act_resize_keyboard((E_Border *)obj); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_menu, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* e_border_act_menu_begin((E_Border *)obj, NULL, 0); */
+}
+
+ACT_FN_GO_MOUSE(window_menu, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* e_border_act_menu_begin((E_Border *)obj, ev, 0); */
+}
+
+ACT_FN_GO_KEY(window_menu, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* e_border_act_menu_begin((E_Border *)obj, NULL, 1); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_raise, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_stacking) */
+   /*   e_border_raise((E_Border *)obj); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_lower, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_stacking) */
+   /*   e_border_lower((E_Border *)obj); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_close, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_close) */
+   /*   e_border_act_close_begin((E_Border *)obj); */
+}
+
+/***************************************************************************/
+static E_Dialog *kill_dialog = NULL;
+
+static void
+_e_actions_cb_kill_dialog_ok(void *data, E_Dialog *dia)
+{
+   E_Object *obj;
+
+   obj = data;
+   if (dia)
+     {
+       e_object_del(E_OBJECT(kill_dialog));
+       kill_dialog = NULL;
+     }
+   /* if ((!((E_Border *)obj)->lock_close) && (!((E_Border *)obj)->internal)) */
+   /*   e_border_act_kill_begin((E_Border *)obj); */
+}
+
+static void
+_e_actions_cb_kill_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(kill_dialog));
+   kill_dialog = NULL;
+}
+
+static void
+_e_actions_cb_kill_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_kill_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(window_kill, __UNUSED__)
+{
+   E_Border *bd;
+   char dialog_text[1024];
+
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   bd = (E_Border *)obj;
+   /* if ((bd->lock_close) || (bd->internal)) return; */
+
+   if (kill_dialog) e_object_del(E_OBJECT(kill_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_kill_dialog_ok(obj, NULL);
+       return;
+     }
+
+   snprintf(dialog_text, sizeof(dialog_text),
+           _("You are about to kill %s.<br><br>"
+           "Please keep in mind that all data from this window<br>"
+           "which has not yet been saved will be lost!<br><br>"
+           "Are you sure you want to kill this window?"),
+            "A Border");
+           /* bd->client.icccm.name); */
+
+   kill_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()),
+                             "E", "_kill_dialog");
+   if (!kill_dialog) return;
+   e_win_delete_callback_set(kill_dialog->win,
+                            _e_actions_cb_kill_dialog_delete);
+   e_dialog_title_set(kill_dialog,
+                     _("Are you sure you want to kill this window?"));
+   e_dialog_text_set(kill_dialog, _(dialog_text));
+   e_dialog_icon_set(kill_dialog, "application-exit", 64);
+   e_dialog_button_add(kill_dialog, _("Yes"), NULL,
+                      _e_actions_cb_kill_dialog_ok, obj);
+   e_dialog_button_add(kill_dialog, _("No"), NULL,
+                      _e_actions_cb_kill_dialog_cancel, NULL);
+   e_dialog_button_focus_num(kill_dialog, 1);
+   e_win_centered_set(kill_dialog->win, 1);
+   e_dialog_show(kill_dialog);
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_sticky_toggle, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_sticky) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (bd->sticky) e_border_unstick(bd); */
+   /*  else e_border_stick(bd); */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_sticky, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_sticky) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (params) */
+   /*    { */
+   /*       if (atoi(params) == 1) */
+   /*         e_border_stick(bd);       */
+   /*       else if (atoi(params) == 0) */
+   /*         e_border_unstick(bd); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_iconic_toggle, __UNUSED__)
+{
+   E_Border *bd;
+
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   bd = (E_Border *)obj;
+
+   /* if ((!bd->lock_user_iconify) && (!bd->fullscreen) && */
+   /*     ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) || */
+   /*      (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN))) */
+   /*   { */
+   /*  if (bd->iconic) e_border_uniconify(bd); */
+   /*  else e_border_iconify(bd); */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_iconic, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_iconify) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (params) */
+   /*    { */
+   /*       if (atoi(params) == 1) */
+   /*         e_border_iconify(bd); */
+   /*       else if (atoi(params) == 0) */
+   /*         e_border_uniconify(bd); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_fullscreen_toggle, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_fullscreen) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (bd->fullscreen) */
+   /*    e_border_unfullscreen(bd); */
+   /*  else if (!params || *params == '\0') */
+   /*    e_border_fullscreen(bd, e_config->fullscreen_policy); */
+   /*  else if (! strcmp(params, "resize")) */
+   /*    e_border_fullscreen(bd, E_FULLSCREEN_RESIZE); */
+   /*  else if (! strcmp(params, "zoom")) */
+   /*    e_border_fullscreen(bd, E_FULLSCREEN_ZOOM); */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_fullscreen, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_fullscreen) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (params) */
+   /*    { */
+   /*       int v; */
+   /*       char buf[32]; */
+
+   /*       buf[0] = 0; */
+   /*       if (sscanf(params, "%i %20s", &v, buf) == 2) */
+   /*         { */
+   /*            if (v == 1) */
+   /*              { */
+   /*                if (*buf == '\0') */
+   /*                  e_border_fullscreen(bd, e_config->fullscreen_policy); */
+   /*                else if (!strcmp(buf, "resize")) */
+   /*                  e_border_fullscreen(bd, E_FULLSCREEN_RESIZE); */
+   /*                else if (!strcmp(buf, "zoom")) */
+   /*                  e_border_fullscreen(bd, E_FULLSCREEN_ZOOM); */
+   /*              } */
+   /*            else if (v == 0) */
+   /*              e_border_unfullscreen(bd); */
+   /*         } */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_maximized_toggle, )
+{
+   E_Border *bd;
+
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   bd = (E_Border *)obj;
+
+   /* if ((!bd->lock_user_maximize) && (!bd->fullscreen) && */
+   /*     ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) || */
+   /*      (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN))) */
+   /*   { */
+   /*  if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE) */
+   /*    { */
+   /*       if (!params) */
+   /*         e_border_unmaximize(bd, E_MAXIMIZE_BOTH); */
+   /*       else */
+   /*         { */
+   /*            E_Maximize max; */
+
+   /*            max = _e_actions_maximize_parse(params); */
+   /*            max &= E_MAXIMIZE_DIRECTION; */
+   /*            if (max == E_MAXIMIZE_VERTICAL) */
+   /*              { */
+   /*                 if (bd->maximized & E_MAXIMIZE_VERTICAL) */
+   /*                   e_border_unmaximize(bd, E_MAXIMIZE_VERTICAL); */
+   /*                 else */
+   /*                   goto maximize; */
+   /*              } */
+   /*            else if (max == E_MAXIMIZE_HORIZONTAL) */
+   /*              { */
+   /*                 if (bd->maximized & E_MAXIMIZE_HORIZONTAL) */
+   /*                   e_border_unmaximize(bd, E_MAXIMIZE_HORIZONTAL); */
+   /*                 else */
+   /*                   goto maximize; */
+   /*              } */
+   /*            else */
+   /*              e_border_unmaximize(bd, E_MAXIMIZE_BOTH); */
+   /*         } */
+   /*    } */
+   /*  else */
+   /*    { */
+/* maximize: */
+   /*       e_border_maximize(bd, _e_actions_maximize_parse(params)); */
+   /*    } */
+   /*   } */
+}
+/***************************************************************************/
+ACT_FN_GO(window_maximized, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_maximize) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (params) */
+   /*    { */
+   /*       E_Maximize max; */
+   /*       int v, ret; */
+   /*       char s1[32], s2[32]; */
+
+   /*       max = (e_config->maximize_policy & E_MAXIMIZE_DIRECTION); */
+   /*       ret = sscanf(params, "%i %20s %20s", &v, s1, s2); */
+   /*       if (ret == 3) */
+   /*         { */
+   /*            if (!strcmp(s2, "horizontal")) */
+   /*              max = E_MAXIMIZE_HORIZONTAL; */
+   /*            else if (!strcmp(s2, "vertical")) */
+   /*              max = E_MAXIMIZE_VERTICAL; */
+   /*            else */
+   /*              max = E_MAXIMIZE_BOTH; */
+   /*         } */
+   /*       if (ret > 1) */
+   /*         { */
+   /*            if (v == 1) */
+   /*              { */
+   /*                 if (!strcmp(s1, "fullscreen")) */
+   /*                       e_border_maximize(bd, E_MAXIMIZE_FULLSCREEN | max); */
+   /*                 else if (!strcmp(s1, "smart")) */
+   /*                       e_border_maximize(bd, E_MAXIMIZE_SMART | max); */
+   /*                 else if (!strcmp(s1, "expand")) */
+   /*                       e_border_maximize(bd, E_MAXIMIZE_EXPAND | max); */
+   /*                 else if (!strcmp(s1, "fill")) */
+   /*                       e_border_maximize(bd, E_MAXIMIZE_FILL | max); */
+   /*                 else */
+   /*                       e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) | max); */
+   /*              } */
+   /*            else if (v == 0) */
+   /*              e_border_unmaximize(bd, max); */
+   /*         } */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_shaded_toggle, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_shade) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (bd->shaded) */
+   /*    { */
+   /*       if (!params) */
+   /*         e_border_unshade(bd, E_DIRECTION_UP); */
+   /*       else */
+   /*         { */
+   /*            if (!strcmp(params, "up")) */
+   /*                  e_border_unshade(bd, E_DIRECTION_UP); */
+   /*            else if (!strcmp(params, "down")) */
+   /*                  e_border_unshade(bd, E_DIRECTION_DOWN); */
+   /*            else if (!strcmp(params, "left")) */
+   /*                  e_border_unshade(bd, E_DIRECTION_LEFT); */
+   /*            else if (!strcmp(params, "right")) */
+   /*                  e_border_unshade(bd, E_DIRECTION_RIGHT); */
+   /*            else */
+   /*                  e_border_unshade(bd, E_DIRECTION_UP); */
+   /*         } */
+   /*    } */
+   /*  else */
+   /*    { */
+   /*       if (!params) */
+   /*         e_border_shade(bd, E_DIRECTION_UP); */
+   /*       else */
+   /*         { */
+   /*            if (!strcmp(params, "up")) */
+   /*                  e_border_shade(bd, E_DIRECTION_UP); */
+   /*            else if (!strcmp(params, "down")) */
+   /*                  e_border_shade(bd, E_DIRECTION_DOWN); */
+   /*            else if (!strcmp(params, "left")) */
+   /*                  e_border_shade(bd, E_DIRECTION_LEFT); */
+   /*            else if (!strcmp(params, "right")) */
+   /*                  e_border_shade(bd, E_DIRECTION_RIGHT); */
+   /*            else */
+   /*                  e_border_shade(bd, E_DIRECTION_UP); */
+   /*         } */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_shaded, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (!((E_Border *)obj)->lock_user_shade) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if (params) */
+   /*    { */
+   /*       int v; */
+   /*       char buf[32]; */
+
+   /*       if (sscanf(params, "%i %20s", &v, buf) == 2) */
+   /*         { */
+   /*            if (v == 1) */
+   /*              { */
+   /*                 if (!strcmp(buf, "up")) */
+   /*                   e_border_shade(bd, E_DIRECTION_UP); */
+   /*                 else if (!strcmp(buf, "down")) */
+   /*                   e_border_shade(bd, E_DIRECTION_DOWN); */
+   /*                 else if (!strcmp(buf, "left")) */
+   /*                   e_border_shade(bd, E_DIRECTION_LEFT); */
+   /*                 else if (!strcmp(buf, "right")) */
+   /*                   e_border_shade(bd, E_DIRECTION_RIGHT); */
+   /*              } */
+   /*            else if (v == 0) */
+   /*              { */
+   /*                 if (!strcmp(buf, "up")) */
+   /*                   e_border_unshade(bd, E_DIRECTION_UP); */
+   /*                 else if (!strcmp(buf, "down")) */
+   /*                   e_border_unshade(bd, E_DIRECTION_DOWN); */
+   /*                 else if (!strcmp(buf, "left")) */
+   /*                   e_border_unshade(bd, E_DIRECTION_LEFT); */
+   /*                 else if (!strcmp(buf, "right")) */
+   /*                   e_border_unshade(bd, E_DIRECTION_RIGHT); */
+   /*              } */
+   /*         } */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_borderless_toggle, __UNUSED__)
+{
+   /* if ((!obj) || (obj->type != E_BORDER_TYPE)) */
+   /*   obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   /* if (!((E_Border *)obj)->lock_border) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  bd->borderless = !bd->borderless; */
+
+   /*  bd->client.border.changed = 1; */
+   /*  bd->changed = 1; */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_border_set, __UNUSED__)
+{
+   /* if ((!obj) || (obj->type != E_BORDER_TYPE)) */
+   /*   obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   /* if (!((E_Border *)obj)->lock_border) */
+   /*   { */
+   /*      E_Border *bd; */
+
+   /*      bd = (E_Border *)obj; */
+   /*      if (bd && params) */
+   /*        { */
+   /*           eina_stringshare_replace(&bd->bordername, params); */
+   /*           bd->client.border.changed = 1; */
+   /*           bd->changed = 1; */
+   /*        } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_border_cycle, __UNUSED__)
+{
+   /* if ((!obj) || (obj->type != E_BORDER_TYPE)) */
+   /*   obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   /* if (!((E_Border *)obj)->lock_border) */
+   /*   { */
+   /*      E_Border *bd; */
+
+   /*      bd = (E_Border *)obj; */
+   /*      if (bd && params) */
+   /*        { */
+   /*           const char *space; */
+
+   /*           while (*params == ' ') */
+   /*              params++; */
+
+   /*           if (bd->bordername) */
+   /*             { */
+   /*                const char *bdname = params; */
+
+   /*                while (bdname && (space = strchr(bdname, ' '))) */
+   /*                  { */
+   /*                     if (strncmp(bd->bordername, bdname, space - bdname) == 0) */
+   /*                       { */
+   /*                          bdname = space + 1; */
+   /*                          while (*bdname == ' ') */
+   /*                             bdname++; */
+   /*                          space = strchr(bdname, ' '); */
+   /*                          if (space) */
+   /*                            eina_stringshare_replace_length( */
+   /*                               &bd->bordername, */
+   /*                               bdname, space - bdname); */
+   /*                          else */
+   /*                            eina_stringshare_replace(&bd->bordername, bdname); */
+   /*                          bd->client.border.changed = 1; */
+   /*                          bd->changed = 1; */
+   /*                          return; */
+   /*                       } */
+   /*                     bdname = space + 1; */
+   /*                     while (*bdname == ' ') */
+   /*                        bdname++; */
+   /*                  } */
+   /*             } */
+
+   /*           space = strchr(params, ' '); */
+   /*           if (space) */
+   /*             eina_stringshare_replace_length(&bd->bordername, */
+   /*                                             params, space - params); */
+   /*           else */
+   /*             eina_stringshare_replace(&bd->bordername, params); */
+   /*           bd->client.border.changed = 1; */
+   /*           bd->changed = 1; */
+   /*        } */
+   /*   } */
+}
+
+ /***************************************************************************/
+ACT_FN_GO(window_pinned_toggle, __UNUSED__)
+{
+   /* if ((!obj) || (obj->type != E_BORDER_TYPE)) */
+   /*   obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   /* if (!((E_Border *)obj)->lock_border) */
+   /*   { */
+   /*  E_Border *bd; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  if ((bd->client.netwm.state.stacking == E_STACKING_BELOW) && */
+   /*          (bd->user_skip_winlist) && (bd->borderless)) */
+   /*    e_border_pinned_set(bd, 0); */
+   /*  else */
+   /*    e_border_pinned_set(bd, 1); */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_move_by, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (params) */
+   /*   { */
+   /*  int dx, dy; */
+
+   /*  if (sscanf(params, "%i %i", &dx, &dy) == 2) */
+   /*    { */
+   /*       E_Border *bd; */
+
+   /*       bd = (E_Border *)obj; */
+   /*       e_border_move(bd, bd->x + dx, bd->y + dy); */
+
+   /*       if (e_config->focus_policy != E_FOCUS_CLICK) */
+   /*         ecore_x_pointer_warp(bd->zone->container->win, */
+   /*                              bd->x + (bd->w / 2), */
+   /*                              bd->y + (bd->h / 2)); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_move_to, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+   /* if (params) */
+   /*   { */
+   /*  E_Border *bd; */
+   /*  int x, y, zx, zy, zw, zh; */
+   /*  char cx, cy; */
+
+   /*  bd = (E_Border *)obj; */
+   /*  e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh); */
+
+   /*  if (sscanf(params, "%c%i %c%i", &cx, &x, &cy, &y) == 4) */
+   /*    { */
+   /*       x += zx; */
+   /*       y += zy; */
+   /*    } */
+   /*  else if (sscanf(params, "* %c%i", &cy, &y) == 2) */
+   /*    { */
+   /*       y += zy; */
+   /*       x = bd->x; */
+   /*       cx = 0; */
+   /*    } */
+   /*  else if (sscanf(params, "%c%i *", &cx, &x) == 2) */
+   /*    { */
+   /*       x += zx; */
+   /*       y = bd->y; */
+   /*       cy = 0; */
+   /*    } */
+   /*  else return; */
+
+   /*  if (cx == '-') x = zw - bd->w - x + 2 * zx; */
+   /*  if (cy == '-') y = zh - bd->h - y + 2 * zy; */
+
+   /*  if ((x != bd->x) || (y != bd->y)) */
+   /*    { */
+   /*       e_border_move(bd, x, y); */
+
+   /*       if (e_config->focus_policy != E_FOCUS_CLICK) */
+   /*         ecore_x_pointer_warp(bd->zone->container->win, */
+   /*                              bd->x + (bd->w / 2), */
+   /*                              bd->y + (bd->h / 2)); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_move_to_center, __UNUSED__)
+{
+   E_Border *bd;
+   int x, y;
+
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+
+   bd = (E_Border *)obj;
+   /* e_border_center_pos_get(bd, &x, &y); */
+
+   /* if ((x != bd->x) || (y != bd->y)) */
+   /*   { */
+   /*      e_border_move(bd, x, y); */
+
+   /*      if (e_config->focus_policy != E_FOCUS_CLICK) */
+   /*        ecore_x_pointer_warp(bd->zone->container->win, */
+   /*                             x + (bd->w / 2), */
+   /*                             y + (bd->h / 2)); */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_resize_by, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+
+   /* if (params) */
+   /*   { */
+   /*  int dw, dh; */
+
+   /*  if (sscanf(params, "%i %i", &dw, &dh) == 2) */
+   /*    { */
+   /*       E_Border *bd; */
+
+   /*       bd = (E_Border *)obj; */
+
+   /*       dw += bd->w; */
+   /*       dh += bd->h; */
+   /*       e_border_resize_limit(bd, &dw, &dh); */
+   /*       e_border_resize(bd, dw, dh); */
+
+   /*       if (e_config->focus_policy != E_FOCUS_CLICK) */
+   /*         ecore_x_pointer_warp(bd->zone->container->win, */
+   /*                              bd->x + (dw / 2), bd->y + (dh / 2)); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_push, )
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+
+   /* if (params) */
+   /*   { */
+   /*      E_Border *bd, *cur; */
+   /*      E_Border_List *bd_list; */
+   /*      int hdir, vdir; */
+   /*      int x, y, zx, zy, zw, zh; */
+
+   /*      if (strcmp(params, "left") == 0) */
+   /*    { */
+   /*       hdir = -1; */
+   /*       vdir = 0; */
+   /*    } */
+   /*      else if (strcmp(params, "right") == 0) */
+   /*    { */
+   /*       hdir = +1; */
+   /*       vdir = 0; */
+   /*    } */
+   /*      else if (strcmp(params, "up") == 0) */
+   /*    { */
+   /*       hdir = 0; */
+   /*       vdir = -1; */
+   /*    } */
+   /*      else if (strcmp(params, "down") == 0) */
+   /*    { */
+   /*       hdir = 0; */
+   /*       vdir = +1; */
+   /*    } */
+   /*      else if (strcmp(params, "up-left") == 0) */
+   /*    { */
+   /*       hdir = -1; */
+   /*       vdir = -1; */
+   /*    } */
+   /*      else if (strcmp(params, "up-right") == 0) */
+   /*    { */
+   /*       hdir = +1; */
+   /*       vdir = -1; */
+   /*    } */
+   /*      else if (strcmp(params, "down-left") == 0) */
+   /*    { */
+   /*       hdir = -1; */
+   /*       vdir = +1; */
+   /*    } */
+   /*      else if (strcmp(params, "down-right") == 0) */
+   /*    { */
+   /*       hdir = +1; */
+   /*       vdir = +1; */
+   /*    } */
+   /*      else */
+   /*        return; */
+
+   /*      bd = (E_Border *)obj; */
+   /*      e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh); */
+
+   /*  if (hdir < 0)      x = zx; */
+   /*  else if (hdir > 0) x = zx + zw - bd->w; */
+   /*  else               x = bd->x; */
+
+   /*  if (vdir < 0)      y = zy; */
+   /*  else if (vdir > 0) y = zy + zh - bd->h; */
+   /*  else               y = bd->y; */
+
+   /*      bd_list = e_container_border_list_first(bd->zone->container); */
+   /*      cur = e_container_border_list_next(bd_list); */
+
+   /*      while (cur) */
+   /*        { */
+   /*          if ((bd->desk == cur->desk) && (bd != cur) && (!cur->iconic)) */
+   /*             { */
+   /*            if ((hdir < 0) */
+   /*                && (cur->x + cur->w < bd->x) */
+   /*                && (E_SPANS_COMMON(bd->y, bd->h, cur->y, cur->h))) */
+   /*              x = MAX(x, cur->x + cur->w); */
+   /*            else if ((hdir > 0) */
+   /*                     && (cur->x > bd->x + bd->w) */
+   /*                     && (E_SPANS_COMMON(bd->y, bd->h, cur->y, cur->h))) */
+   /*              x = MIN(x, zx + cur->x - bd->w); */
+
+   /*            if ((vdir < 0) */
+   /*                && (cur->y + cur->h < bd->y) */
+   /*                && (E_SPANS_COMMON(bd->x, bd->w, cur->x, cur->w))) */
+   /*              y = MAX(y, cur->y + cur->h); */
+   /*            else if ((vdir > 0) */
+   /*                     && (cur->y > bd->y + bd->h) */
+   /*                     && (E_SPANS_COMMON(bd->x, bd->w, cur->x, cur->w))) */
+   /*              y = MIN(y, zy + cur->y - bd->h); */
+   /*             } */
+   /*           cur = e_container_border_list_next(bd_list); */
+   /*        } */
+   /*      e_container_border_list_free(bd_list); */
+
+   /*  if ((x != bd->x) || (y != bd->y)) */
+   /*    { */
+   /*           e_border_move(bd, x, y); */
+   /*       if (e_config->focus_policy != E_FOCUS_CLICK) */
+   /*         ecore_x_pointer_warp(bd->zone->container->win, */
+   /*                              bd->x + (bd->w / 2), bd->y + (bd->h / 2)); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_drag_icon, __UNUSED__)
+{
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+     /* { */
+     /*        E_Border *bd; */
+
+     /*        bd = (E_Border *)obj; */
+     /*        bd->drag.start = 1; */
+     /*        bd->drag.x = -1; */
+     /*        bd->drag.y = -1; */
+     /* } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_desk_move_by, )
+{
+   E_Border *bd;
+   int x, y;
+
+   if (!params) return;
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+
+   bd = (E_Border *)obj;
+   /* if ((!bd->zone) || (!bd->desk)) return; */
+   /* if (sscanf(params, "%d %d", &x, &y) == 2) */
+   /*   { */
+   /*  E_Desk *desk; */
+   /*  int dx, dy; */
+   /*  int to_x = 0, to_y = 0; */
+
+   /*  e_desk_xy_get(bd->desk, &dx, &dy); */
+
+   /*  to_x = dx + x; */
+   /*  to_y = dy + y; */
+   /*  while (!(desk = e_desk_at_xy_get(bd->zone, to_x, to_y))) */
+   /*    { */
+   /*       while (to_x >= bd->zone->desk_x_count) */
+   /*         { */
+   /*            to_x -= bd->zone->desk_x_count; */
+   /*            to_y++; */
+   /*         } */
+   /*       while (to_x < 0) */
+   /*         { */
+   /*            to_x += bd->zone->desk_x_count; */
+   /*            to_y--; */
+   /*         } */
+
+   /*       while (to_y >= bd->zone->desk_y_count) */
+   /*         to_y -= bd->zone->desk_y_count; */
+   /*       while (to_y < 0) */
+   /*         to_y += bd->zone->desk_y_count; */
+   /*    } */
+       
+   /*  if (desk) */
+   /*    { */
+   /*       e_zone_desk_flip_by(bd->zone, to_x - dx, to_y - dy); */
+   /*       e_border_desk_set(bd, desk); */
+   /*       if (!bd->lock_user_stacking) */
+   /*         e_border_raise(bd); */
+   /*       e_border_focus_set(bd, 1, 1); */
+   /*    } */
+   /*   } */
+}
+
+/***************************************************************************/
+ACT_FN_GO(window_desk_move_to, )
+{
+   E_Border *bd;
+   int x, y;
+
+   if (!params) return;
+   /* if (!obj) obj = E_OBJECT(e_border_focused_get()); */
+   if (!obj) return;
+   if (obj->type != E_BORDER_TYPE)
+     {
+       /* obj = E_OBJECT(e_border_focused_get()); */
+       if (!obj) return;
+     }
+
+   bd = (E_Border *)obj;
+   /* if ((!bd->zone) || (!bd->desk)) return; */
+   /* if (sscanf(params, "%d %d", &x, &y) == 2) */
+   /*   { */
+   /*  E_Desk *desk; */
+
+   /*  desk = e_desk_at_xy_get(bd->zone, x, y); */
+   /*  if (desk) e_border_desk_set(bd, desk); */
+   /*   } */
+}
+
+/***************************************************************************/
+static E_Zone *
+_e_actions_zone_get(E_Object *obj)
+{
+   if (obj)
+     {
+       if      (obj->type == (int)E_MANAGER_TYPE)   return e_util_zone_current_get((E_Manager *)obj);
+       else if (obj->type == (int)E_CONTAINER_TYPE) return e_util_zone_current_get(((E_Container *)obj)->man);
+       else if (obj->type == (int)E_ZONE_TYPE)      return (E_Zone *)obj;
+       /* else if (obj->type == (int)E_BORDER_TYPE)    return ((E_Border *)obj)->zone; */
+       else if (obj->type == (int)E_SHELF_TYPE)     return ((E_Shelf *)obj)->zone;
+       else if (obj->type == (int)E_POPUP_TYPE)     return ((E_Popup *)obj)->zone;
+       /* else if (obj->type == (int)E_WIN_TYPE)       return ((E_Win *)obj)->border->zone; */
+     }
+   return e_util_zone_current_get(e_manager_current_get());
+}
+
+ACT_FN_GO(desk_flip_by, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            /* int dx = 0, dy = 0; */
+
+            /* if (sscanf(params, "%i %i", &dx, &dy) == 2) */
+            /*   e_zone_desk_flip_by(zone, dx, dy); */
+         }
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_flip_to, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            /* int dx = 0, dy = 0; */
+
+            /* if (sscanf(params, "%i %i", &dx, &dy) == 2) */
+            /*   e_zone_desk_flip_to(zone, dx, dy); */
+         }
+     }
+}
+
+/***************************************************************************/
+#define ACT_FLIP_LEFT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0))
+#define ACT_FLIP_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || (((zone)->desk_x_current + 1) < (zone)->desk_x_count))
+#define ACT_FLIP_UP(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0))
+#define ACT_FLIP_DOWN(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || (((zone)->desk_y_current + 1) < (zone)->desk_y_count))
+#define ACT_FLIP_UP_LEFT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || (((zone)->desk_x_current > 0) && ((zone)->desk_y_current > 0)))
+#define ACT_FLIP_UP_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || ((((zone)->desk_x_current + 1) < (zone)->desk_x_count) && ((zone)->desk_y_current > 0)))
+#define ACT_FLIP_DOWN_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || ((((zone)->desk_x_current + 1) < (zone)->desk_x_count) && (((zone)->desk_y_current + 1) < (zone)->desk_y_count)))
+#define ACT_FLIP_DOWN_LEFT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1) && ((zone)->desk_y_count > 1)) || (((zone)->desk_x_current > 0) && (((zone)->desk_y_current + 1) < (zone)->desk_y_count)))
+
+ACT_FN_GO_EDGE(desk_flip_in_direction, )
+{
+   /* E_Zone *zone; */
+   /* E_Desk *current = NULL; */
+   /* E_Event_Pointer_Warp *wev; */
+   /* int x, y, offset = 25; */
+
+   /* if (!ev) return; */
+   /* zone = _e_actions_zone_get(obj); */
+   /* wev = E_NEW(E_Event_Pointer_Warp, 1); */
+   /* if ((!wev) || (!zone)) return; */
+   /* ecore_wl_pointer_xy_get(&x, &y); */
+   /* wev->prev.x = x; */
+   /* wev->prev.y = y; */
+   /* if (params) */
+   /*   { */
+   /*  if (sscanf(params, "%i", &offset) != 1) */
+   /*    offset = 25; */
+   /*   } */
+   /* switch (ev->edge) */
+   /*   { */
+   /*   case E_ZONE_EDGE_LEFT: */
+   /*  if (ACT_FLIP_LEFT(zone)) */
+   /*    { */
+   /*       e_zone_desk_flip_by(zone, -1, 0); */
+   /*       ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + zone->w - offset, y); */
+   /*       wev->curr.y = y; */
+   /*       wev->curr.x = zone->w - offset; */
+   /*    } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_RIGHT: */
+   /*      if (ACT_FLIP_RIGHT(zone)) */
+   /*        { */
+   /*           e_zone_desk_flip_by(zone, 1, 0); */
+   /*           ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + offset, y); */
+   /*           wev->curr.y = y; */
+   /*           wev->curr.x = offset; */
+   /*        } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_TOP: */
+   /*      if (ACT_FLIP_UP(zone)) */
+   /*        { */
+   /*           e_zone_desk_flip_by(zone, 0, -1); */
+   /*           ecore_x_pointer_warp(zone->container->win, x, zone->container->y + zone->y + zone->h - offset); */
+   /*           wev->curr.x = x; */
+   /*           wev->curr.y = zone->h - offset; */
+   /*        } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_BOTTOM: */
+   /*  if (ACT_FLIP_DOWN(zone)) */
+   /*    { */
+   /*       e_zone_desk_flip_by(zone, 0, 1); */
+   /*       ecore_x_pointer_warp(zone->container->win, x, zone->container->y + zone->y + offset); */
+   /*       wev->curr.x = x; */
+   /*       wev->curr.y = offset; */
+   /*    } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_TOP_LEFT: */
+   /*      if (ACT_FLIP_UP_LEFT(zone)) */
+   /*        { */
+   /*           e_zone_desk_flip_by(zone, -1, -1); */
+   /*           ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + zone->w - offset, zone->container->y + zone->y + zone->h - offset); */
+   /*           wev->curr.x = zone->w - offset; */
+   /*           wev->curr.y = zone->h - offset; */
+   /*        } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_TOP_RIGHT: */
+   /*      if (ACT_FLIP_UP_RIGHT(zone)) */
+   /*        { */
+   /*           e_zone_desk_flip_by(zone, 1, -1); */
+   /*           ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + offset, zone->container->y + zone->y + zone->h - offset); */
+   /*           wev->curr.x = offset; */
+   /*           wev->curr.y = zone->h - offset; */
+   /*        } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_BOTTOM_LEFT: */
+   /*  if (ACT_FLIP_DOWN_LEFT(zone)) */
+   /*    { */
+   /*       e_zone_desk_flip_by(zone, -1, 1); */
+   /*       ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + zone->w - offset, zone->container->y + zone->y + offset); */
+   /*       wev->curr.y = offset; */
+   /*       wev->curr.x = zone->w - offset; */
+   /*    } */
+   /*      break; */
+   /*   case E_ZONE_EDGE_BOTTOM_RIGHT: */
+   /*  if (ACT_FLIP_DOWN_RIGHT(zone)) */
+   /*    { */
+   /*       e_zone_desk_flip_by(zone, 1, 1); */
+   /*       ecore_x_pointer_warp(zone->container->win, zone->container->x + zone->x + offset, zone->container->y + zone->y + offset); */
+   /*       wev->curr.y = offset; */
+   /*       wev->curr.x = offset; */
+   /*    } */
+   /*      break; */
+   /*   default: */
+   /*      break; */
+   /*   } */
+
+   /* current = e_desk_current_get(zone); */
+   /* if (current) */
+   /*   ecore_event_add(E_EVENT_POINTER_WARP, wev, NULL, NULL); */
+   /* else */
+   /*   free(wev); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_linear_flip_by, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            /* int dx = 0; */
+
+            /* if (sscanf(params, "%i", &dx) == 1) */
+            /*   e_zone_desk_linear_flip_by(zone, dx); */
+         }
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_linear_flip_to, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            /* int dx = 0; */
+
+            /* if (sscanf(params, "%i", &dx) == 1) */
+            /*   e_zone_desk_linear_flip_to(zone, dx); */
+         }
+     }
+}
+
+
+#define DESK_ACTION_ALL(zone, act) \
+  E_Zone *zone;                           \
+  Eina_List *lm, *lc, *lz;        \
+  E_Container *con;               \
+  E_Manager *man;                              \
+  \
+  EINA_LIST_FOREACH(e_manager_list(), lm, man) {          \
+    EINA_LIST_FOREACH(man->containers, lc, con) {         \
+      EINA_LIST_FOREACH(con->zones, lz, zone) {                   \
+       act;                                               \
+      }                                                           \
+    }                                                     \
+  }
+
+
+/***************************************************************************/
+ACT_FN_GO(desk_flip_by_all, )
+{
+   if (params)
+     {
+        /* int dx = 0, dy = 0; */
+
+        /* if (sscanf(params, "%i %i", &dx, &dy) == 2) */
+        /*   { */
+        /*      DESK_ACTION_ALL(zone, e_zone_desk_flip_by(zone, dx, dy)); */
+        /*   } */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_flip_to_all, )
+{
+   if (params)
+     {
+        /* int dx = 0, dy = 0; */
+
+        /* if (sscanf(params, "%i %i", &dx, &dy) == 2) */
+        /*   { */
+        /*      DESK_ACTION_ALL(zone, e_zone_desk_flip_to(zone, dx, dy)); */
+        /*   } */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_linear_flip_by_all, )
+{
+   if (params)
+     {
+        /* int dx = 0; */
+
+        /* if (sscanf(params, "%i", &dx) == 1) */
+        /*   { */
+        /*      DESK_ACTION_ALL(zone, e_zone_desk_linear_flip_by(zone, dx)); */
+        /*   } */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_linear_flip_to_all, )
+{
+   if (params)
+     {
+        /* int dx = 0; */
+
+        /* if (sscanf(params, "%i", &dx) == 1) */
+        /*   { */
+        /*      DESK_ACTION_ALL(zone, e_zone_desk_linear_flip_to(zone, dx)); */
+        /*   } */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(screen_send_to, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
+   if (zone)
+     {
+       if (params)
+         {
+            int scr = 0;
+
+            if (sscanf(params, "%i", &scr) == 1)
+              {
+                 E_Zone *zone2 = NULL;
+
+                  if (eina_list_count(e_manager_list()) > 1)
+                   {
+                      scr = scr % eina_list_count(e_manager_list());
+                      if (scr < 0) scr += eina_list_count(e_manager_list());
+                      zone2 = e_util_container_zone_number_get(scr, 0);
+                   }
+                 else
+                   {
+                      scr = scr % eina_list_count(zone->container->zones);
+                      if (scr < 0) scr += eina_list_count(zone->container->zones);
+                      zone2 = e_util_container_zone_number_get(0, scr);
+                   }
+                 /* if ((zone2) && (zone != zone2)) */
+                 /*   ecore_x_pointer_warp(zone2->container->win, */
+                 /*                     zone2->x + (zone2->w / 2), */
+                 /*                     zone2->y + (zone2->h / 2)); */
+              }
+         }
+     }
+}
+
+ACT_FN_GO(screen_send_by, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
+   if (zone)
+     {
+       if (params)
+         {
+            int scr = 0;
+
+            if (sscanf(params, "%i", &scr) == 1)
+              {
+                 E_Zone *zone2 = NULL;
+
+                  if (eina_list_count(e_manager_list()) > 1)
+                   {
+                      scr += zone->container->num;
+                      scr = scr % eina_list_count(e_manager_list());
+                      if (scr < 0) scr += eina_list_count(e_manager_list());
+                      zone2 = e_util_container_zone_number_get(scr, 0);
+                   }
+                 else
+                   {
+                       scr += zone->num;
+                      scr = scr % eina_list_count(zone->container->zones);
+                      if (scr < 0) scr += eina_list_count(zone->container->zones);
+                      zone2 = e_util_container_zone_number_get(0, scr);
+                   }
+                 /* if ((zone2) && (zone != zone2)) */
+                 /*   ecore_x_pointer_warp(zone2->container->win, */
+                 /*                     zone2->x + (zone2->w / 2), */
+                 /*                     zone2->y + (zone2->h / 2)); */
+              }
+         }
+     }
+}
+
+#define ZONE_DESK_ACTION(con_num, zone_num, zone, act) \
+   E_Zone *zone; \
+   if ((con_num < 0) || (zone_num < 0)) { \
+      Eina_List *l, *ll, *lll; \
+      E_Container *con; \
+      E_Manager *man; \
+      if ((con_num >= 0) && (zone_num < 0)) /* con=1 zone=all */ { \
+         con = e_util_container_number_get(con_num); \
+         EINA_LIST_FOREACH(con->zones, l, zone) { \
+            act; \
+         } } \
+      else if ((con_num < 0) && (zone_num >= 0)) /* con=all zone=1 */ { \
+         EINA_LIST_FOREACH(e_manager_list(), l, man) { \
+            EINA_LIST_FOREACH(man->containers, ll, con) { \
+               zone = e_container_zone_number_get(con, zone_num); \
+               if (zone) \
+                 act; \
+            } } } \
+      else if ((con_num < 0) && (zone_num < 0)) /* con=all zone=all */ { \
+         EINA_LIST_FOREACH(e_manager_list(), l, man) { \
+            EINA_LIST_FOREACH(man->containers, ll, con) { \
+               EINA_LIST_FOREACH(con->zones, lll, zone) { \
+                  act; \
+               } } } } } \
+   else { \
+      zone = e_util_container_zone_number_get(con_num, zone_num); \
+      if (zone) act; \
+   }
+
+/***************************************************************************/
+#if 0
+ACT_FN_GO(zone_desk_flip_by, )
+{
+   if (params)
+     {
+       /* int con_num = 0, zone_num = 0; */
+       /* int dx = 0, dy = 0; */
+
+       /* if (sscanf(params, "%i %i %i %i", &con_num, &zone_num, &dx, &dy) == 4) */
+        /*   ZONE_DESK_ACTION(con_num, zone_num, zone, */
+        /*                    e_zone_desk_flip_by(zone, dx, dy)); */
+     }
+}
+#endif
+
+/***************************************************************************/
+#if 0
+ACT_FN_GO(zone_desk_flip_to, )
+{
+   if (params)
+     {
+       /* int con_num = 0, zone_num = 0; */
+       /* int dx = 0, dy = 0; */
+
+       /* if (sscanf(params, "%i %i %i %i", &con_num, &zone_num, &dx, &dy) == 4) */
+        /*   ZONE_DESK_ACTION(con_num, zone_num, zone, */
+        /*                    e_zone_desk_flip_to(zone, dx, dy)); */
+     }
+}
+#endif
+
+/***************************************************************************/
+#if 0
+ACT_FN_GO(zone_desk_linear_flip_by, )
+{
+   if (params)
+     {
+       /* int con_num = 0, zone_num = 0; */
+       /* int dx = 0; */
+
+       /* if (sscanf(params, "%i %i %i", &con_num, &zone_num, &dx) == 3) */
+        /*   ZONE_DESK_ACTION(con_num, zone_num, zone, */
+        /*                    e_zone_desk_linear_flip_by(zone, dx)); */
+     }
+}
+#endif
+
+/***************************************************************************/
+#if 0
+ACT_FN_GO(zone_desk_linear_flip_to, )
+{
+   if (params)
+     {
+       /* int con_num = 0, zone_num = 0; */
+       /* int dx = 0; */
+
+       /* if (sscanf(params, "%i %i %i", &con_num, &zone_num, &dx) == 3) */
+        /*   ZONE_DESK_ACTION(con_num, zone_num, zone, */
+        /*                    e_zone_desk_linear_flip_to(zone, dx)); */
+     }
+}
+#endif
+
+/***************************************************************************/
+static void
+_e_actions_cb_menu_end(void *data __UNUSED__, E_Menu *m)
+{
+   e_object_del(E_OBJECT(m));
+}
+
+static E_Menu *
+_e_actions_menu_find(const char *name)
+{
+   if (!strcmp(name, "main"))
+     return e_int_menus_main_new();
+   else if (!strcmp(name, "favorites"))
+     return e_int_menus_favorite_apps_new();
+   else if (!strcmp(name, "all"))
+     return e_int_menus_all_apps_new();
+   /* else if (!strcmp(name, "clients")) */
+   /*   return e_int_menus_clients_new(); */
+   /* else if (!strcmp(name, "lost_clients")) */
+   /*   return e_int_menus_lost_clients_new(); */
+   /* else if (!strcmp(name, "configuration")) */
+   /*   return e_int_menus_config_new(); */
+   return NULL;
+}
+
+ACT_FN_GO(menu_show, )
+{
+   E_Zone *zone;
+
+   /* menu is active - abort */
+   /* if (e_menu_grab_window_get()) return; */
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            E_Menu *m = NULL;
+
+            m = _e_actions_menu_find(params);  
+            if (m)
+              {
+                 int x, y;
+
+                 /* FIXME: this is a bit of a hack... setting m->con - bad hack */
+                 m->zone = zone;
+                 ecore_wl_pointer_xy_get(&x, &y);
+                 e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
+                 e_menu_activate_mouse(m, zone, x, y, 1, 1,
+                                       E_MENU_POP_DIRECTION_DOWN,
+                                        e_compositor_get_time());
+              }
+         }
+     }
+}
+
+ACT_FN_GO_MOUSE(menu_show, )
+{
+   E_Zone *zone;
+
+   /* menu is active - abort */
+   /* if (e_menu_grab_window_get()) return; */
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            E_Menu *m = NULL;
+
+            m = _e_actions_menu_find(params);  
+            if (m)
+              {
+                 int x, y;
+
+                 /* FIXME: this is a bit of a hack... setting m->con - bad hack */
+                 m->zone = zone;
+                 x = ev->root.x;
+                 y = ev->root.y;
+                 x -= zone->container->x;
+                 y -= zone->container->y;
+                 e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
+                 e_menu_activate_mouse(m, zone, x, y, 1, 1,
+                                       E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
+              }
+         }
+     }
+}
+
+ACT_FN_GO_KEY(menu_show, )
+{
+   E_Zone *zone;
+
+   /* menu is active - abort */
+   /* if (e_menu_grab_window_get()) return; */
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            E_Menu *m = NULL;
+
+            m = _e_actions_menu_find(params);  
+            if (m)
+              {
+                 int x, y;
+
+                 /* FIXME: this is a bit of a hack... setting m->con - bad hack */
+                 m->zone = zone;
+                 ecore_wl_pointer_xy_get(&x, &y);
+                 e_menu_post_deactivate_callback_set(m, _e_actions_cb_menu_end, NULL);
+                 e_menu_activate_key(m, zone, x, y, 1, 1,
+                                     E_MENU_POP_DIRECTION_DOWN);
+              }
+         }
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(exec, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+          e_exec(zone, NULL, params, NULL, "action/exec");
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(app, )
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (zone)
+     {
+       if (params)
+         {
+            Efreet_Desktop *desktop = NULL;
+            char *p, *p2;
+
+            p2 = alloca(strlen(params) + 1);
+            strcpy(p2, params);
+            p = strchr(p2, ' ');
+            if (p)
+              {
+                 *p = 0;
+                 if (!strcmp(p2, "file:"))
+                   desktop = efreet_util_desktop_file_id_find(p + 1);
+                 else if (!strcmp(p2, "name:"))
+                   desktop = efreet_util_desktop_name_find(p + 1);
+                 else if (!strcmp(p2, "generic:"))
+                   desktop = efreet_util_desktop_generic_name_find(p + 1);
+                 else if (!strcmp(p2, "exe:"))
+                   desktop = efreet_util_desktop_exec_find(p + 1);
+                 if (desktop)
+                   {
+                      e_exec(zone, desktop, NULL, NULL, "action/app");
+                      efreet_desktop_free(desktop);
+                   }
+              }
+         }
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_deskshow_toggle, __UNUSED__)
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
+   /* if (zone) e_desk_deskshow(zone); */
+}
+
+ACT_FN_GO(cleanup_windows, __UNUSED__)
+{
+   E_Zone *zone;
+
+   zone = _e_actions_zone_get(obj);
+   if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
+   /* if (zone) e_place_zone_region_smart_cleanup(zone); */
+}
+
+/***************************************************************************/
+static E_Dialog *exit_dialog = NULL;
+
+static void
+_e_actions_cb_exit_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(exit_dialog));
+       exit_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_EXIT, NULL);
+}
+
+static void
+_e_actions_cb_exit_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(exit_dialog));
+   exit_dialog = NULL;
+}
+
+static void
+_e_actions_cb_exit_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_exit_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(exit, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_EXIT, NULL);
+       return;
+     }
+   if (exit_dialog) e_object_del(E_OBJECT(exit_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_exit_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   exit_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_exit_dialog");
+   if (!exit_dialog) return;
+   e_win_delete_callback_set(exit_dialog->win, _e_actions_cb_exit_dialog_delete);
+   e_dialog_title_set(exit_dialog, _("Are you sure you want to exit?"));
+   e_dialog_text_set(exit_dialog,
+                    _("You requested to exit Enlightenment.<br>"
+                      "<br>"
+                      "Are you sure you want to exit?"));
+   e_dialog_icon_set(exit_dialog, "application-exit", 64);
+   e_dialog_button_add(exit_dialog, _("Yes"), NULL,
+                      _e_actions_cb_exit_dialog_ok, NULL);
+   e_dialog_button_add(exit_dialog, _("No"), NULL,
+                      _e_actions_cb_exit_dialog_cancel, NULL);
+   e_dialog_button_focus_num(exit_dialog, 1);
+   e_win_centered_set(exit_dialog->win, 1);
+   e_dialog_show(exit_dialog);
+}
+
+/***************************************************************************/
+ACT_FN_GO(restart, __UNUSED__)
+{
+   e_sys_action_do(E_SYS_RESTART, NULL);
+}
+
+/***************************************************************************/
+ACT_FN_GO(exit_now, __UNUSED__)
+{
+   e_sys_action_do(E_SYS_EXIT_NOW, NULL);
+}
+
+/***************************************************************************/
+ACT_FN_GO(halt_now, __UNUSED__)
+{
+   e_sys_action_do(E_SYS_HALT_NOW, NULL);
+}
+
+/***************************************************************************/
+ACT_FN_GO(mode_presentation_toggle, __UNUSED__)
+{
+   e_config->mode.presentation = !e_config->mode.presentation;
+   e_config_mode_changed();
+   e_config_save_queue();
+}
+
+/***************************************************************************/
+ACT_FN_GO(mode_offline_toggle, __UNUSED__)
+{
+   e_config->mode.offline = !e_config->mode.offline;
+   e_config_mode_changed();
+   e_config_save_queue();
+}
+
+/***************************************************************************/
+static E_Dialog *logout_dialog = NULL;
+
+static void
+_e_actions_cb_logout_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(logout_dialog));
+       logout_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_LOGOUT, NULL);
+}
+
+static void
+_e_actions_cb_logout_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(logout_dialog));
+   logout_dialog = NULL;
+}
+
+static void
+_e_actions_cb_logout_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_logout_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(logout, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_LOGOUT, NULL);
+       return;
+     }
+   if (logout_dialog) e_object_del(E_OBJECT(logout_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_logout_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   logout_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_logout_dialog");
+   if (!logout_dialog) return;
+   e_win_delete_callback_set(logout_dialog->win, _e_actions_cb_logout_dialog_delete);
+   e_dialog_title_set(logout_dialog, _("Are you sure you want to log out?"));
+   e_dialog_text_set(logout_dialog,
+                    _("You are about to log out.<br>"
+                      "<br>"
+                      "Are you sure you want to do this?"));
+   e_dialog_icon_set(logout_dialog, "system-log-out", 64);
+   e_dialog_button_add(logout_dialog, _("Yes"), NULL,
+                      _e_actions_cb_logout_dialog_ok, NULL);
+   e_dialog_button_add(logout_dialog, _("No"), NULL,
+                      _e_actions_cb_logout_dialog_cancel, NULL);
+   e_dialog_button_focus_num(logout_dialog, 1);
+   e_win_centered_set(logout_dialog->win, 1);
+   e_dialog_show(logout_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *halt_dialog = NULL;
+
+static void
+_e_actions_cb_halt_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(halt_dialog));
+       halt_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_HALT, NULL);
+}
+
+static void
+_e_actions_cb_halt_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(halt_dialog));
+   halt_dialog = NULL;
+}
+
+static void
+_e_actions_cb_halt_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_halt_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(halt, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_HALT, NULL);
+       return;
+     }
+   if (halt_dialog) e_object_del(E_OBJECT(halt_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_halt_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   halt_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_halt_dialog");
+   if (!halt_dialog) return;
+   e_win_delete_callback_set(halt_dialog->win, _e_actions_cb_halt_dialog_delete);
+   e_dialog_title_set(halt_dialog, _("Are you sure you want to turn off?"));
+   e_dialog_text_set(halt_dialog,
+                    _("You requested to turn off your Computer.<br>"
+                      "<br>"
+                      "Are you sure you want to shut down?"));
+   e_dialog_icon_set(halt_dialog, "system-shutdown", 64);
+   e_dialog_button_add(halt_dialog, _("Yes"), NULL,
+                      _e_actions_cb_halt_dialog_ok, NULL);
+   e_dialog_button_add(halt_dialog, _("No"), NULL,
+                      _e_actions_cb_halt_dialog_cancel, NULL);
+   e_dialog_button_focus_num(halt_dialog, 1);
+   e_win_centered_set(halt_dialog->win, 1);
+   e_dialog_show(halt_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *reboot_dialog = NULL;
+
+static void
+_e_actions_cb_reboot_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(reboot_dialog));
+       reboot_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_REBOOT, NULL);
+}
+
+static void
+_e_actions_cb_reboot_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(reboot_dialog));
+   reboot_dialog = NULL;
+}
+
+static void
+_e_actions_cb_reboot_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_reboot_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(reboot, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_REBOOT, NULL);
+       return;
+     }
+   if (reboot_dialog) e_object_del(E_OBJECT(reboot_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_reboot_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   reboot_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_reboot_dialog");
+   if (!reboot_dialog) return;
+   e_win_delete_callback_set(reboot_dialog->win, _e_actions_cb_reboot_dialog_delete);
+   e_dialog_title_set(reboot_dialog, _("Are you sure you want to reboot?"));
+   e_dialog_text_set(reboot_dialog,
+                    _("You requested to reboot your Computer.<br>"
+                      "<br>"
+                      "Are you sure you want to restart it?"));
+   e_dialog_icon_set(reboot_dialog, "system-restart", 64);
+   e_dialog_button_add(reboot_dialog, _("Yes"), NULL,
+                      _e_actions_cb_reboot_dialog_ok, NULL);
+   e_dialog_button_add(reboot_dialog, _("No"), NULL,
+                      _e_actions_cb_reboot_dialog_cancel, NULL);
+   e_dialog_button_focus_num(reboot_dialog, 1);
+   e_win_centered_set(reboot_dialog->win, 1);
+   e_dialog_show(reboot_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *suspend_dialog = NULL;
+
+static void
+_e_actions_cb_suspend_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(suspend_dialog));
+       suspend_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_SUSPEND, NULL);
+}
+
+static void
+_e_actions_cb_suspend_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(suspend_dialog));
+   suspend_dialog = NULL;
+}
+
+static void
+_e_actions_cb_suspend_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_suspend_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(suspend_now, __UNUSED__)
+{
+   e_sys_action_do(E_SYS_SUSPEND, NULL);
+}
+
+ACT_FN_GO(suspend, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_SUSPEND, NULL);
+       return;
+     }
+   if (suspend_dialog) e_object_del(E_OBJECT(suspend_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_suspend_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   suspend_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_suspend_dialog");
+   if (!suspend_dialog) return;
+   e_win_delete_callback_set(suspend_dialog->win, _e_actions_cb_suspend_dialog_delete);
+   e_dialog_title_set(suspend_dialog, _("Are you sure you want to turn off?"));
+   e_dialog_text_set(suspend_dialog,
+                    _("You requested to suspend your Computer.<br>"
+                      "<br>"
+                      "Are you sure you want to suspend?"));
+   e_dialog_icon_set(suspend_dialog, "system-suspend", 64);
+   e_dialog_button_add(suspend_dialog, _("Yes"), NULL,
+                      _e_actions_cb_suspend_dialog_ok, NULL);
+   e_dialog_button_add(suspend_dialog, _("No"), NULL,
+                      _e_actions_cb_suspend_dialog_cancel, NULL);
+   e_dialog_button_focus_num(suspend_dialog, 1);
+   e_win_centered_set(suspend_dialog->win, 1);
+   e_dialog_show(suspend_dialog);
+}
+
+/***************************************************************************/
+static E_Dialog *hibernate_dialog = NULL;
+
+static void
+_e_actions_cb_hibernate_dialog_ok(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (dia)
+     {
+       e_object_del(E_OBJECT(hibernate_dialog));
+       hibernate_dialog = NULL;
+     }
+   e_sys_action_do(E_SYS_HIBERNATE, NULL);
+}
+
+static void
+_e_actions_cb_hibernate_dialog_cancel(void *data __UNUSED__, E_Dialog *dia __UNUSED__)
+{
+   e_object_del(E_OBJECT(hibernate_dialog));
+   hibernate_dialog = NULL;
+}
+
+static void
+_e_actions_cb_hibernate_dialog_delete(E_Win *win)
+{
+   E_Dialog *dia;
+
+   dia = win->data;
+   _e_actions_cb_hibernate_dialog_cancel(NULL, dia);
+}
+
+ACT_FN_GO(hibernate_now, __UNUSED__)
+{
+   e_sys_action_do(E_SYS_HIBERNATE, NULL);
+}
+
+ACT_FN_GO(hibernate, )
+{
+   if ((params) && (!strcmp(params, "now")))
+     {
+       e_sys_action_do(E_SYS_HIBERNATE, NULL);
+       return;
+     }
+   if (hibernate_dialog) e_object_del(E_OBJECT(hibernate_dialog));
+
+   if (e_config->cnfmdlg_disabled)
+     {
+       _e_actions_cb_hibernate_dialog_ok(NULL, NULL);
+       return;
+     }
+
+   hibernate_dialog = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_hibernate_dialog");
+   if (!hibernate_dialog) return;
+   e_win_delete_callback_set(hibernate_dialog->win, _e_actions_cb_hibernate_dialog_delete);
+   e_dialog_title_set(hibernate_dialog, _("Are you sure you want to hibernate?"));
+   e_dialog_text_set(hibernate_dialog,
+                    _("You requested to hibernate your Computer.<br>"
+                      "<br>"
+                      "Are you sure you want to suspend to disk?"));
+   e_dialog_icon_set(hibernate_dialog, "system-suspend-hibernate", 64);
+   e_dialog_button_add(hibernate_dialog, _("Yes"), NULL,
+                      _e_actions_cb_hibernate_dialog_ok, NULL);
+   e_dialog_button_add(hibernate_dialog, _("No"), NULL,
+                      _e_actions_cb_hibernate_dialog_cancel, NULL);
+   e_dialog_button_focus_num(hibernate_dialog, 1);
+   e_win_centered_set(hibernate_dialog->win, 1);
+   e_dialog_show(hibernate_dialog);
+}
+
+/***************************************************************************/
+ACT_FN_GO(pointer_resize_push, )
+{
+   if (!obj) return;
+   if (obj->type == E_BORDER_TYPE)
+     {
+       E_Border *bd;
+
+       bd = (E_Border *)obj;
+       /* if ((bd->lock_user_size) || (bd->shaded) || (bd->shading) || */
+       /*     (bd->fullscreen) || ((bd->maximized) && (!e_config->allow_manip))) */
+       /*   return; */
+       /* e_pointer_type_push(bd->pointer, bd, params); */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(pointer_resize_pop, )
+{
+   if (!obj) return;
+   if (obj->type == E_BORDER_TYPE)
+     {
+       E_Border *bd;
+
+       bd = (E_Border *)obj;
+       /* if ((bd->lock_user_size) || (bd->shaded) || (bd->shading) || */
+       /*     (bd->fullscreen) || ((bd->maximized) && (!e_config->allow_manip))) */
+       /*   return; */
+       /* e_pointer_type_pop(bd->pointer, bd, params); */
+     }
+}
+
+/***************************************************************************/
+ACT_FN_GO(desk_lock, __UNUSED__)
+{
+/*  E_Zone *zone;
+
+  zone = _e_actions_zone_get(obj);
+  if (zone)*/
+  /* e_desklock_show(); */
+}
+
+/***************************************************************************/
+ACT_FN_GO(shelf_show, )
+{
+   Eina_List *l;
+   E_Shelf *es;
+
+   if (params)
+     {
+       for (; *params != '\0'; params++)
+         if (!isspace(*params))
+           break;
+       if (*params == '\0')
+         params = NULL;
+     }
+
+   EINA_LIST_FOREACH(e_shelf_list(), l, es)
+     {
+       if ((!params) || (params && (fnmatch(params, es->name, 0) == 0)))
+         {
+            e_shelf_toggle(es, 1);
+            e_shelf_toggle(es, 0);
+         }
+     }
+}
+/***************************************************************************/
+#define ACT_SHELF_SHOW(params, es) \
+if ((!params) || (params && (fnmatch(params, es->name, 0) == 0))) \
+  { \
+     e_shelf_toggle(es, 1); \
+     e_shelf_toggle(es, 0); \
+  }
+
+ACT_FN_GO_EDGE(shelf_show, )
+{
+   Eina_List *l;
+   E_Shelf *es;
+
+   if (params)
+     {
+       for (; *params != '\0'; params++)
+          {
+             if (!isspace(*params))
+               break;
+          }
+       if (*params == '\0')
+         params = NULL;
+     }
+
+   EINA_LIST_FOREACH(e_shelf_list(), l, es)
+     {
+       switch(ev->edge)
+         {
+          case E_ZONE_EDGE_LEFT:
+             if ((es->gadcon->orient == E_GADCON_ORIENT_LEFT ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_LT ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_LB) &&
+                 (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
+               ACT_SHELF_SHOW(params, es);
+             break;
+          case E_ZONE_EDGE_RIGHT:
+             if ((es->gadcon->orient == E_GADCON_ORIENT_RIGHT ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_RT ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_RB) &&
+                 (ev->y >= es->y) && (ev->y <= (es->y + es->h)))
+               ACT_SHELF_SHOW(params, es);
+             break;
+          case E_ZONE_EDGE_TOP:
+             if ((es->gadcon->orient == E_GADCON_ORIENT_TOP ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_TL ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_TR) &&
+                 (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
+               ACT_SHELF_SHOW(params, es);
+             break;
+          case E_ZONE_EDGE_BOTTOM:
+             if ((es->gadcon->orient == E_GADCON_ORIENT_BOTTOM ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_BL ||
+                  es->gadcon->orient == E_GADCON_ORIENT_CORNER_BR) &&
+                 (ev->x >= es->x) && (ev->x <= (es->x + es->w)))
+               ACT_SHELF_SHOW(params, es);
+             break;
+          default:
+             break;
+         }
+     }
+}
+#undef ACT_SHELF_SHOW
+
+/***************************************************************************/
+typedef struct _Delayed_Action Delayed_Action;
+
+struct _Delayed_Action
+{
+   int mouse, button;
+   const char *keyname;
+   E_Object *obj;
+   Ecore_Timer *timer;
+   struct
+     {
+        const char *action, *params;
+     } def, delayed;
+};
+
+static Eina_List *_delayed_actions = NULL;
+
+static void
+_delayed_action_free(Delayed_Action *da)
+{
+   if (da->obj) e_object_unref(da->obj);
+   if (da->keyname) eina_stringshare_del(da->keyname);
+   if (da->timer) ecore_timer_del(da->timer);
+   if (da->def.action) eina_stringshare_del(da->def.action);
+   if (da->def.params) eina_stringshare_del(da->def.params);
+   if (da->delayed.action) eina_stringshare_del(da->delayed.action);
+   if (da->delayed.params) eina_stringshare_del(da->delayed.params);
+   free(da);
+}
+
+static Eina_Bool
+_delayed_action_cb_timer(void *data)
+{
+   Delayed_Action *da;
+   E_Action *act;
+
+   da = data;
+   da->timer = NULL;
+   act = e_action_find(da->delayed.action);
+   if (act)
+     {
+       if (act->func.go) act->func.go(da->obj, da->delayed.params);
+     }
+   _delayed_actions = eina_list_remove(_delayed_actions, da);
+   _delayed_action_free(da);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_delayed_action_do(Delayed_Action *da)
+{
+   E_Action *act;
+
+   act = e_action_find(da->def.action);
+   if (act)
+     {
+       if (act->func.go) act->func.go(da->obj, da->def.params);
+     }
+}
+
+static void
+_delayed_action_list_parse_action(const char *str, double *delay, const char **action, const char **params)
+{
+   char fbuf[16];
+   char buf[1024];
+   const char *p;
+
+   buf[0] = 0;
+   sscanf(str, "%10s %1000s", fbuf, buf);
+   *action = eina_stringshare_add(buf);
+   *delay = atof(fbuf);
+   p = strchr(str, ' ');
+   if (p)
+     {
+       p++;
+       p = strchr(p, ' ');
+       if (p)
+         {
+            p++;
+            *params = eina_stringshare_add(p);
+         }
+     }
+}
+
+static void
+_delayed_action_list_parse(Delayed_Action *da, const char *params)
+{
+   double delay = 2.0;
+   const char *p, *a1start = NULL, *a1stop = NULL;
+   const char *a2start = NULL, *a2stop = NULL;
+
+   // FORMAT: "[0.0 default_action param1 param2] [x.x action2 param1 param2]"
+   p = params;
+   while (*p)
+     {
+       if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1start = p + 1; break;}
+       p++;
+     }
+   while (*p)
+     {
+       if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1stop = p; break;}
+       p++;
+     }
+   while (*p)
+     {
+       if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2start = p + 1; break;}
+       p++;
+     }
+   while (*p)
+     {
+       if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2stop = p; break;}
+       p++;
+     }
+   if ((a1start) && (a2start) && (a1stop) && (a2stop))
+     {
+       char *a1, *a2;
+       const char *action, *params;
+
+       a1 = alloca(a1stop - a1start + 1);
+       eina_strlcpy(a1, a1start, a1stop - a1start + 1);
+       action = NULL;
+       params = NULL;
+       _delayed_action_list_parse_action(a1, &delay, &da->def.action, &da->def.params);
+
+       a2 = alloca(a1stop - a1start + 1);
+       eina_strlcpy(a2, a2start, a2stop - a2start + 1);
+       _delayed_action_list_parse_action(a2, &delay, &da->delayed.action, &da->delayed.params);
+     }
+   da->timer = ecore_timer_add(delay, _delayed_action_cb_timer, da);
+}
+
+static void
+_delayed_action_key_add(E_Object *obj, const char *params, Ecore_Event_Key *ev)
+{
+   Delayed_Action *da;
+
+   da = E_NEW(Delayed_Action, 1);
+   if (!da) return;
+   if (obj)
+     {
+       da->obj = obj;
+       e_object_ref(da->obj);
+     }
+   da->mouse = 0;
+   da->keyname = eina_stringshare_add(ev->keyname);
+   if (params) _delayed_action_list_parse(da, params);
+   _delayed_actions = eina_list_append(_delayed_actions, da);
+}
+
+static void
+_delayed_action_key_del(E_Object *obj, const char *params __UNUSED__, Ecore_Event_Key *ev)
+{
+   Eina_List *l;
+   Delayed_Action *da;
+
+   EINA_LIST_FOREACH(_delayed_actions, l, da)
+     {
+       if ((da->obj == obj) && (!da->mouse) &&
+           (!strcmp(da->keyname, ev->keyname)))
+         {
+            _delayed_action_do(da);
+            _delayed_action_free(da);
+            _delayed_actions = eina_list_remove_list(_delayed_actions, l);
+            return;
+         }
+     }
+}
+
+static void
+_delayed_action_mouse_add(E_Object *obj, const char *params, Ecore_Event_Mouse_Button *ev)
+{
+   Delayed_Action *da;
+
+   da = E_NEW(Delayed_Action, 1);
+   if (!da) return;
+   if (obj)
+     {
+       da->obj = obj;
+       e_object_ref(da->obj);
+     }
+   da->mouse = 1;
+   da->button = ev->buttons;
+   if (params) _delayed_action_list_parse(da, params);
+   _delayed_actions = eina_list_append(_delayed_actions, da);
+}
+
+static void
+_delayed_action_mouse_del(E_Object *obj, const char *params __UNUSED__, Ecore_Event_Mouse_Button *ev)
+{
+   Eina_List *l;
+   Delayed_Action *da;
+
+   EINA_LIST_FOREACH(_delayed_actions, l, da)
+     {
+       if ((da->obj == obj) && (da->mouse) &&
+           ((int) ev->buttons == da->button))
+         {
+            _delayed_action_do(da);
+            _delayed_action_free(da);
+            _delayed_actions = eina_list_remove_list(_delayed_actions, l);
+            return;
+         }
+     }
+}
+
+// obj , params  , ev
+ACT_FN_GO_KEY(delayed_action, )
+{
+   _delayed_action_key_add(obj, params, ev);
+}
+
+ACT_FN_GO_MOUSE(delayed_action, )
+{
+   _delayed_action_mouse_add(obj, params, ev);
+}
+
+ACT_FN_END_KEY(delayed_action, )
+{
+   _delayed_action_key_del(obj, params, ev);
+}
+
+ACT_FN_END_MOUSE(delayed_action, )
+{
+   _delayed_action_mouse_del(obj, params, ev);
+}
+
+ACT_FN_GO_ACPI(dim_screen, __UNUSED__)
+{
+   E_Zone *zone = _e_actions_zone_get(obj);
+   /* e_backlight_mode_set(zone, E_BACKLIGHT_MODE_DIM); */
+}
+
+ACT_FN_GO_ACPI(undim_screen, __UNUSED__)
+{
+   E_Zone *zone = _e_actions_zone_get(obj);
+   /* e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); */
+}
+
+ACT_FN_GO(backlight_set, )
+{
+   E_Zone *zone = _e_actions_zone_get(obj);
+   int v;
+   if (params)
+      v = atoi(params);
+   else
+     {
+        /* v = e_backlight_level_get(zone) * 100.0; */
+        if (v == 0) v = 100;
+        else v = 0;
+     }
+   /* e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); */
+   /* e_backlight_level_set(zone, ((double)v / 100.0), -1.0); */
+}
+
+ACT_FN_GO(backlight_adjust, )
+{
+   E_Zone *zone = _e_actions_zone_get(obj);
+   int v;
+   if (!params) return;
+   v = atoi(params);
+   /* e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL); */
+   /* e_backlight_level_set(zone, e_backlight_level_get(zone) + ((double)v / 100.0), -1.0); */
+}
+
+/* local subsystem globals */
+static Eina_Hash *actions = NULL;
+static Eina_List *action_list = NULL;
+static Eina_List *action_names = NULL;
+static Eina_List *action_groups = NULL;
+
+/* externally accessible functions */
+
+EINTERN int
+e_actions_init(void)
+{
+   E_Action *act;
+
+   actions = eina_hash_string_superfast_new(NULL);
+   ACT_GO(window_move);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Move"),
+                           "window_move", NULL, NULL, 0);
+
+   ACT_GO_MOUSE(window_move);
+   ACT_GO_SIGNAL(window_move);
+   ACT_END(window_move);
+   ACT_END_MOUSE(window_move);
+   ACT_GO_KEY(window_move);
+
+   /* window_resize */
+   ACT_GO(window_resize);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Resize"),
+                           "window_resize", NULL, NULL, 0);
+
+   ACT_GO_MOUSE(window_resize);
+   ACT_GO_SIGNAL(window_resize);
+   ACT_END(window_resize);
+   ACT_END_MOUSE(window_resize);
+   ACT_GO_KEY(window_resize);
+
+   /* window_menu */
+   ACT_GO(window_menu);
+   e_action_predef_name_set(N_("Menu"), N_("Window Menu"),
+                           "window_menu", NULL, NULL, 0);
+
+   ACT_GO_MOUSE(window_menu);
+   ACT_GO_KEY(window_menu);
+
+   /* window_raise */
+   ACT_GO(window_raise);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Raise"),
+                           "window_raise", NULL, NULL, 0);
+
+   /* window_lower */
+   ACT_GO(window_lower);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Lower"),
+                           "window_lower", NULL, NULL, 0);
+
+   /* window_close */
+   ACT_GO(window_close);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Close"),
+                           "window_close", NULL, NULL, 0);
+
+   /* window_kill */
+   ACT_GO(window_kill);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Kill"),
+                           "window_kill", NULL, NULL, 0);
+
+   /* window_sticky_toggle */
+   ACT_GO(window_sticky_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Sticky Mode Toggle"),
+                           "window_sticky_toggle", NULL, NULL, 0);
+
+   ACT_GO(window_sticky);
+
+   /* window_iconic_toggle */
+   ACT_GO(window_iconic_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Iconic Mode Toggle"),
+                           "window_iconic_toggle", NULL, NULL, 0);
+
+   ACT_GO(window_iconic);
+
+   /* window_fullscreen_toggle */
+   ACT_GO(window_fullscreen_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Fullscreen Mode Toggle"),
+                           "window_fullscreen_toggle", NULL, NULL, 0);
+
+   ACT_GO(window_fullscreen);
+
+   /* window_maximized_toggle */
+   ACT_GO(window_maximized_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize"),
+                           "window_maximized_toggle", NULL, NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Vertically"),
+                           "window_maximized_toggle", "default vertical",
+                           NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Horizontally"),
+                           "window_maximized_toggle", "default horizontal",
+                           NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Fullscreen"),
+                           "window_maximized_toggle", "fullscreen", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Smart\""),
+                           "window_maximized_toggle", "smart", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Expand\""),
+                           "window_maximized_toggle", "expand", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Maximize Mode \"Fill\""),
+                           "window_maximized_toggle", "fill", NULL, 0);
+
+   ACT_GO(window_maximized);
+
+   /* window_shaded_toggle */
+   ACT_GO(window_shaded_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Shade Up Mode Toggle"),
+                           "window_shaded_toggle", "up", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Shade Down Mode Toggle"),
+                           "window_shaded_toggle", "down", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Shade Left Mode Toggle"),
+                           "window_shaded_toggle", "left", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Shade Right Mode Toggle"),
+                           "window_shaded_toggle", "right", NULL, 0);
+   e_action_predef_name_set(N_("Window : State"), N_("Shade Mode Toggle"),
+                           "window_shaded_toggle", NULL, NULL, 0);
+
+   ACT_GO(window_shaded);
+
+   /* window_borderless_toggle */
+   ACT_GO(window_borderless_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Toggle Borderless State"),
+                           "window_borderless_toggle", NULL, NULL, 0);
+
+   /* window_border_set */
+   ACT_GO(window_border_set);
+   e_action_predef_name_set(N_("Window : State"), N_("Set Border"),
+                            "window_border_set", NULL,
+                            "syntax: BorderName, example: pixel", 1);
+
+   /* window_border_cycle */
+   ACT_GO(window_border_cycle);
+   e_action_predef_name_set(N_("Window : State"), N_("Cycle between Borders"),
+                            "window_border_cycle", NULL,
+                            "syntax: BorderNames, example: default pixel", 1);
+
+   /* window_pinned_toggle */
+   ACT_GO(window_pinned_toggle);
+   e_action_predef_name_set(N_("Window : State"), N_("Toggle Pinned State"),
+                           "window_pinned_toggle", NULL, NULL, 0);
+
+   /* desk_flip_by */
+   ACT_GO(desk_flip_by);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Left"),
+                           "desk_flip_by", "-1 0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Right"),
+                           "desk_flip_by", "1 0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Up"),
+                           "desk_flip_by", "0 -1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Down"),
+                           "desk_flip_by", "0 1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop By..."),
+                           "desk_flip_by", NULL,
+                           "syntax: X-offset Y-offset, example: -1 0", 1);
+
+   /* desk_deskshow_toggle */
+   ACT_GO(desk_deskshow_toggle);
+   e_action_predef_name_set(N_("Desktop"), N_("Show The Desktop"),
+                           "desk_deskshow_toggle", NULL, NULL, 0);
+
+   /* shelf_show */
+   ACT_GO(shelf_show);
+   ACT_GO_EDGE(shelf_show);
+   e_action_predef_name_set(N_("Desktop"), N_("Show The Shelf"), "shelf_show",
+                           NULL, "shelf name glob: Shelf-* ", 1);
+
+   /* desk_linear_flip_to */
+   ACT_GO(desk_flip_to);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop To..."),
+                           "desk_flip_to", NULL,
+                           "syntax: X Y, example: 1 2", 1);
+
+   /* desk_linear_flip_by */
+   ACT_GO(desk_linear_flip_by);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Linearly..."),
+                           "desk_linear_flip_by",
+                           NULL, "syntax: N-offset, example: -2", 1);
+
+   /* desk_linear_flip_to */
+   ACT_GO(desk_linear_flip_to);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 0"),
+                           "desk_linear_flip_to", "0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 1"),
+                           "desk_linear_flip_to", "1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 2"),
+                           "desk_linear_flip_to", "2", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 3"),
+                           "desk_linear_flip_to", "3", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 4"),
+                           "desk_linear_flip_to", "4", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 5"),
+                           "desk_linear_flip_to", "5", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 6"),
+                           "desk_linear_flip_to", "6", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 7"),
+                           "desk_linear_flip_to", "7", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 8"),
+                           "desk_linear_flip_to", "8", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 9"),
+                           "desk_linear_flip_to", "9", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 10"),
+                           "desk_linear_flip_to", "10", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 11"),
+                           "desk_linear_flip_to", "11", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop..."),
+                           "desk_linear_flip_to", NULL,
+                           "syntax: N, example: 1", 1);
+
+   /* desk_flip_by_all */
+   ACT_GO(desk_flip_by_all);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Left (All Screens)"),
+                           "desk_flip_by_all", "-1 0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Right (All Screens)"),
+                           "desk_flip_by_all", "1 0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Up (All Screens)"),
+                           "desk_flip_by_all", "0 -1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Down (All Screens)"),
+                           "desk_flip_by_all", "0 1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop By... (All Screens)"),
+                           "desk_flip_by_all", NULL,
+                           "syntax: X-offset Y-offset, example: -1 0", 1);
+
+   /* desk_flip_to_all */
+   ACT_GO(desk_flip_to_all);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop To... (All Screens)"),
+                           "desk_flip_to_all", NULL,
+                           "syntax: X Y, example: 1 2", 1);
+
+   /* desk_linear_flip_by_all */
+   ACT_GO(desk_linear_flip_by_all);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop Linearly... (All Screens)"),
+                           "desk_linear_flip_by_all",
+                           NULL, "syntax: N-offset, example: -2", 1);
+
+   /* desk_flip_in_direction */
+   ACT_GO_EDGE(desk_flip_in_direction);
+   e_action_predef_name_set(N_("Desktop"), N_("Flip Desktop In Direction..."),
+                           "desk_flip_in_direction", NULL, "syntax: N-pixel-offset, example: 25", 1);
+
+   /* desk_linear_flip_to_all */
+   ACT_GO(desk_linear_flip_to_all);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 0 (All Screens)"),
+                           "desk_linear_flip_to_all", "0", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 1 (All Screens)"),
+                           "desk_linear_flip_to_all", "1", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 2 (All Screens)"),
+                           "desk_linear_flip_to_all", "2", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 3 (All Screens)"),
+                           "desk_linear_flip_to_all", "3", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 4 (All Screens)"),
+                           "desk_linear_flip_to_all", "4", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 5 (All Screens)"),
+                           "desk_linear_flip_to_all", "5", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 6 (All Screens)"),
+                           "desk_linear_flip_to_all", "6", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 7 (All Screens)"),
+                           "desk_linear_flip_to_all", "7", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 8 (All Screens)"),
+                           "desk_linear_flip_to_all", "8", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 9 (All Screens)"),
+                           "desk_linear_flip_to_all", "9", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 10 (All Screens)"),
+                           "desk_linear_flip_to_all", "10", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop 11 (All Screens)"),
+                           "desk_linear_flip_to_all", "11", NULL, 0);
+   e_action_predef_name_set(N_("Desktop"), N_("Switch To Desktop... (All Screens)"),
+                           "desk_linear_flip_to_all", NULL,
+                           "syntax: N, example: 1", 1);
+
+   /* screen_send_to */
+   ACT_GO(screen_send_to);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen 0"),
+                           "screen_send_to", "0", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen 1"),
+                           "screen_send_to", "1", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse To Screen..."),
+                           "screen_send_to", NULL,
+                           "syntax: N, example: 0", 1);
+
+   /* screen_send_by */
+   ACT_GO(screen_send_by);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse Forward 1 Screen"),
+                           "screen_send_by", "1", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse Back 1 Screen"),
+                           "screen_send_by", "-1", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Send Mouse Forward/Back Screens..."),
+                           "screen_send_by", NULL,
+                           "syntax: N-offset, example: -2", 1);
+
+   ACT_GO_ACPI(dim_screen);
+   e_action_predef_name_set(N_("Screen"), N_("Dim"), "dim_screen",
+                           NULL, NULL, 0);
+   ACT_GO_ACPI(undim_screen);
+   e_action_predef_name_set(N_("Screen"), N_("Undim"), "undim_screen",
+                           NULL, NULL, 0);
+   ACT_GO(backlight_set);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Set"), "backlight_set",
+                           NULL, "syntax: brightness(0 - 100), example: 50", 1);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Min"), "backlight_set",
+                           "0", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Mid"), "backlight_set",
+                           "50", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Max"), "backlight_set",
+                           "100", NULL, 0);
+   ACT_GO(backlight_adjust);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Adjust"), "backlight_adjust",
+                           NULL, "syntax: brightness(-100 - 100), example: -20", 1);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Up"), "backlight_adjust",
+                           "10", NULL, 0);
+   e_action_predef_name_set(N_("Screen"), N_("Backlight Down"), "backlight_adjust",
+                           "-10", NULL, 0);
+
+   /* window_move_to_center */
+   ACT_GO(window_move_to_center);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Move To Center"),
+                           "window_move_to_center", NULL, NULL, 0);
+   /* window_move_to */
+   ACT_GO(window_move_to);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Move To..."),
+                           "window_move_to", NULL,
+                           "syntax: [+,-]X [+,-]Y or * [+,-]Y or [+,-]X *, example: -1 +1", 1);
+   /* window_move_by */
+   ACT_GO(window_move_by);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Move By..."),
+                           "window_move_by", NULL,
+                           "syntax: X-offset Y-offset, example: -1 0", 1);
+
+   /* window_resize_by */
+   ACT_GO(window_resize_by);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Resize By..."),
+                           "window_resize_by", NULL,
+                           "syntax: W H, example: 100 150", 1);
+
+   /* window_push */
+   ACT_GO(window_push);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Push in Direction..."),
+                           "window_push", NULL,
+                           "syntax: direction, example: up, down, left, right, up-left, up-right, down-left, down-right", 1);
+
+   /* window_drag_icon */
+   ACT_GO(window_drag_icon);
+   e_action_predef_name_set(N_("Window : Actions"), N_("Drag Icon..."),
+                           "window_drag_icon", NULL, NULL, 0);
+
+   /* window_desk_move_by */
+   ACT_GO(window_desk_move_by);
+   e_action_predef_name_set(N_("Window : Moving"), N_("To Next Desktop"),
+                           "window_desk_move_by", "1 0", NULL, 0);
+   e_action_predef_name_set(N_("Window : Moving"), N_("To Previous Desktop"),
+                           "window_desk_move_by", "-1 0", NULL, 0);
+   e_action_predef_name_set(N_("Window : Moving"), N_("By Desktop #..."),
+                           "window_desk_move_by", NULL,
+                           "syntax: X-offset Y-offset, example: -2 2", 1);
+
+   /* window_desk_move_to */
+   ACT_GO(window_desk_move_to);
+   e_action_predef_name_set(N_("Window : Moving"), N_("To Desktop..."),
+                           "window_desk_move_to", NULL,
+                           "syntax: X Y, example: 0 1", 1);
+
+   /* menu_show */
+   ACT_GO(menu_show);
+   e_action_predef_name_set(N_("Menu"), N_("Show Main Menu"),
+                           "menu_show", "main", NULL, 0);
+   e_action_predef_name_set(N_("Menu"), N_("Show Favorites Menu"), "menu_show",
+                           "favorites", NULL, 0);
+   e_action_predef_name_set(N_("Menu"), N_("Show All Applications Menu"),
+                           "menu_show", "all", NULL, 0);
+   e_action_predef_name_set(N_("Menu"), N_("Show Clients Menu"), "menu_show",
+                           "clients", NULL, 0);
+   e_action_predef_name_set(N_("Menu"), N_("Show Menu..."), "menu_show", NULL,
+                           "syntax: MenuName, example: MyMenu", 1);
+   ACT_GO_MOUSE(menu_show);
+   ACT_GO_KEY(menu_show);
+
+   /* exec */
+   ACT_GO(exec);
+   e_action_predef_name_set(N_("Launch"), N_("Command"), "exec", NULL,
+                           "syntax: CommandName, example: /usr/bin/xmms", 1);
+
+   /* app */
+   ACT_GO(app);
+   e_action_predef_name_set(N_("Launch"), N_("Application"), "app", NULL,
+                           "syntax: , example:", 1);
+
+   ACT_GO(restart);
+   e_action_predef_name_set(N_("Enlightenment"), N_("Restart"), "restart",
+                           NULL, NULL, 0);
+
+   ACT_GO(exit);
+   e_action_predef_name_set(N_("Enlightenment"), N_("Exit"), "exit",
+                           NULL, NULL, 0);
+
+   ACT_GO(exit_now);
+   e_action_predef_name_set(N_("Enlightenment"), N_("Exit Now"),
+                           "exit_now", NULL, NULL, 0);
+
+   ACT_GO(mode_presentation_toggle);
+   e_action_predef_name_set(N_("Enlightenment : Mode"),
+                           N_("Presentation Mode Toggle"),
+                           "mode_presentation_toggle", NULL, NULL, 0);
+
+   ACT_GO(mode_offline_toggle);
+   e_action_predef_name_set(N_("Enlightenment : Mode"),
+                           N_("Offline Mode Toggle"),
+                           "mode_offline_toggle", NULL, NULL, 0);
+
+   ACT_GO(logout);
+   e_action_predef_name_set(N_("System"), N_("Log Out"), "logout",
+                           NULL, NULL, 0);
+
+   ACT_GO(halt_now);
+   e_action_predef_name_set(N_("System"), N_("Power Off Now"),
+                           "halt_now", NULL, NULL, 0);
+
+   ACT_GO(halt);
+   e_action_predef_name_set(N_("System"), N_("Power Off"), "halt",
+                           NULL, NULL, 0);
+
+   ACT_GO(reboot);
+   e_action_predef_name_set(N_("System"), N_("Reboot"), "reboot",
+                           NULL, NULL, 0);
+
+   ACT_GO(suspend_now);
+   e_action_predef_name_set(N_("System"), N_("Suspend Now"), "suspend_now",
+                           NULL, NULL, 0);
+
+   ACT_GO(suspend);
+   e_action_predef_name_set(N_("System"), N_("Suspend"), "suspend",
+                           NULL, NULL, 0);
+
+   ACT_GO(hibernate);
+   e_action_predef_name_set(N_("System"), N_("Hibernate"), "hibernate",
+                           NULL, NULL, 0);
+
+   ACT_GO(hibernate_now);
+   e_action_predef_name_set(N_("System"), N_("Hibernate Now"), "hibernate_now",
+                           NULL, NULL, 0);
+
+   ACT_GO(pointer_resize_push);
+   ACT_GO(pointer_resize_pop);
+
+   /* desk_lock */
+   ACT_GO(desk_lock);
+   e_action_predef_name_set(N_("Desktop"), N_("Lock"), "desk_lock",
+                           NULL, NULL, 0);
+
+   /* cleanup_windows */
+   ACT_GO(cleanup_windows);
+   e_action_predef_name_set(N_("Desktop"), N_("Cleanup Windows"),
+                           "cleanup_windows", NULL, NULL, 0);
+
+   /* delayed_action */
+   ACT_GO_KEY(delayed_action);
+   e_action_predef_name_set(N_("Generic : Actions"), N_("Delayed Action"),
+                           "delayed_action", NULL, "[0.0 exec xterm] [0.3 exec xev]", 1);
+   ACT_GO_MOUSE(delayed_action);
+   ACT_END_KEY(delayed_action);
+   ACT_END_MOUSE(delayed_action);
+
+   return 1;
+}
+
+EINTERN int
+e_actions_shutdown(void)
+{
+   e_action_predef_name_all_del();
+
+   while(action_list)
+     e_object_del(action_list->data);
+
+   action_names = eina_list_free(action_names);
+   eina_hash_free(actions);
+   actions = NULL;
+
+   return 1;
+}
+
+EAPI Eina_List *
+e_action_name_list(void)
+{
+   return action_names;
+}
+
+EAPI E_Action *
+e_action_add(const char *name)
+{
+   E_Action *act;
+
+   act = e_action_find(name);
+   if (!act)
+     {
+       act = E_OBJECT_ALLOC(E_Action, E_ACTION_TYPE, _e_action_free);
+       if (!act) return NULL;
+       act->name = name;
+       eina_hash_direct_add(actions, act->name, act);
+       action_names = eina_list_append(action_names, name);
+       action_list = eina_list_append(action_list, act);
+     }
+   return act;
+}
+
+EAPI void
+e_action_del(const char *name)
+{
+   E_Action *act;
+
+   act = eina_hash_find(actions, name);
+   if (act) _e_action_free(act);
+}
+
+EAPI E_Action *
+e_action_find(const char *name)
+{
+   E_Action *act;
+
+   act = eina_hash_find(actions, name);
+   return act;
+}
+
+EAPI const char *
+e_action_predef_label_get(const char *action, const char *params)
+{
+   E_Action_Group *actg = NULL;
+   E_Action_Description *actd = NULL;
+   Eina_List *l, *l2;
+
+   EINA_LIST_FOREACH(action_groups, l, actg)
+     {
+       EINA_LIST_FOREACH(actg->acts, l2, actd)
+          {
+             if (!strcmp(actd->act_cmd, action))
+               {
+                  if ((params) && (actd->act_params))
+                    {
+                       if (!strcmp(params, actd->act_params))
+                         return actd->act_name;
+                    }
+                  else return actd->act_name;
+               }
+          }
+     }
+   if (params) return e_action_predef_label_get(action, NULL);
+   return NULL;
+}
+
+EAPI void
+e_action_predef_name_set(const char *act_grp, const char *act_name, const char *act_cmd, const char *act_params, const char *param_example, int editable)
+{
+   E_Action_Group *actg = NULL;
+   E_Action_Description *actd = NULL;
+   Eina_List *l;
+
+   if ((!act_grp) || (!act_name)) return;
+
+   EINA_LIST_FOREACH(action_groups, l, actg)
+     {
+       if (!strcmp(actg->act_grp, act_grp)) break;
+       actg = NULL;
+     }
+
+   if (!actg)
+     {
+       actg = E_NEW(E_Action_Group, 1);
+       if (!actg) return;
+
+       actg->act_grp = eina_stringshare_add(act_grp);
+       actg->acts = NULL;
+
+       action_groups = eina_list_append(action_groups, actg);
+       action_groups =
+          eina_list_sort(action_groups, -1, _action_groups_sort_cb);
+     }
+
+   EINA_LIST_FOREACH(actg->acts, l, actd)
+     {
+       if (!strcmp(actd->act_name, act_name)) break;
+       actd = NULL;
+     }
+
+   if (actd) return;
+
+   actd = E_NEW(E_Action_Description, 1);
+   if (!actd) return;
+
+   actd->act_name = eina_stringshare_add(act_name);
+   actd->act_cmd = !act_cmd ? NULL : eina_stringshare_add(act_cmd);
+   actd->act_params = !act_params ? NULL : eina_stringshare_add(act_params);
+   actd->param_example = !param_example ? NULL : eina_stringshare_add(param_example);
+   actd->editable = editable;
+
+   actg->acts = eina_list_append(actg->acts, actd);
+}
+
+EAPI void
+e_action_predef_name_del(const char *act_grp, const char *act_name)
+{
+   E_Action_Group *actg = NULL;
+   E_Action_Description *actd = NULL;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(action_groups, l, actg)
+     {
+       if (!strcmp(actg->act_grp, act_grp)) break;
+       actg = NULL;
+     }
+
+   if (!actg) return;
+
+   EINA_LIST_FOREACH(actg->acts, l, actd)
+     {
+       if (!strcmp(actd->act_name, act_name))
+         {
+            actg->acts = eina_list_remove(actg->acts, actd);
+
+            if (actd->act_name) eina_stringshare_del(actd->act_name);
+            if (actd->act_cmd) eina_stringshare_del(actd->act_cmd);
+            if (actd->act_params) eina_stringshare_del(actd->act_params);
+            if (actd->param_example) eina_stringshare_del(actd->param_example);
+
+            E_FREE(actd);
+
+            if (!eina_list_count(actg->acts))
+              {
+                 action_groups = eina_list_remove(action_groups, actg);
+                 if (actg->act_grp) eina_stringshare_del(actg->act_grp);
+                 E_FREE(actg);
+              }
+            break;
+         }
+     }
+}
+
+EAPI void
+e_action_predef_name_all_del(void)
+{
+   E_Action_Group *actg = NULL;
+   E_Action_Description *actd = NULL;
+
+   EINA_LIST_FREE(action_groups, actg)
+     {
+       EINA_LIST_FREE(actg->acts, actd)
+         {
+            if (actd->act_name) eina_stringshare_del(actd->act_name);
+            if (actd->act_cmd) eina_stringshare_del(actd->act_cmd);
+            if (actd->act_params) eina_stringshare_del(actd->act_params);
+            if (actd->param_example) eina_stringshare_del(actd->param_example);
+
+            E_FREE(actd);
+         }
+       if (actg->act_grp) eina_stringshare_del(actg->act_grp);
+       E_FREE(actg);
+     }
+   action_groups = NULL;
+}
+
+EAPI Eina_List *
+e_action_groups_get(void)
+{
+   return action_groups;
+}
+
+/* local subsystem functions */
+
+static void
+_e_action_free(E_Action *act)
+{
+   eina_hash_del(actions, act->name, act);
+   action_names = eina_list_remove(action_names, act->name);
+   action_list = eina_list_remove(action_list, act);
+   free(act);
+}
+
+static E_Maximize
+_e_actions_maximize_parse(const char *params)
+{
+   E_Maximize max = 0;
+   int ret;
+   char s1[32], s2[32];
+
+   if (!params) return e_config->maximize_policy;
+   ret = sscanf(params, "%20s %20s", s1, s2);
+   if (ret == 2)
+     {
+       if (!strcmp(s2, "horizontal"))
+          max = E_MAXIMIZE_HORIZONTAL;
+       else if (!strcmp(s2, "vertical"))
+          max = E_MAXIMIZE_VERTICAL;
+       else
+          max = E_MAXIMIZE_BOTH;
+     }
+   if (ret >= 1)
+     {
+       if (!strcmp(s1, "fullscreen"))
+          max |= E_MAXIMIZE_FULLSCREEN;
+       else if (!strcmp(s1, "smart"))
+          max |= E_MAXIMIZE_SMART;
+       else if (!strcmp(s1, "expand"))
+          max |= E_MAXIMIZE_EXPAND;
+       else if (!strcmp(s1, "fill"))
+          max |= E_MAXIMIZE_FILL;
+       else
+          max |= (e_config->maximize_policy & E_MAXIMIZE_TYPE);
+     }
+   else
+     max = e_config->maximize_policy;
+   return max;
+}
+
+static int
+_action_groups_sort_cb(const void *d1, const void *d2)
+{
+   const E_Action_Group *g1, *g2;
+
+   if (!(g1 = d1)) return 1;
+   if (!(g2 = d2)) return -1;
+   return strcmp(g1->act_grp, g2->act_grp);
+}
diff --git a/src/bin/e_wayland/e_actions.h b/src/bin/e_wayland/e_actions.h
new file mode 100644 (file)
index 0000000..7381d0d
--- /dev/null
@@ -0,0 +1,64 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Action E_Action;
+typedef struct _E_Action_Description E_Action_Description;
+typedef struct _E_Action_Group E_Action_Group;
+
+#else
+#ifndef E_ACTIONS_H
+#define E_ACTIONS_H
+
+#define E_ACTION_TYPE 0xE0b01010
+
+struct _E_Action
+{
+   E_Object e_obj_inherit;
+
+   const char *name;
+   struct 
+     {
+       void (*go)        (E_Object *obj, const char *params);
+       void (*go_mouse)  (E_Object *obj, const char *params, Ecore_Event_Mouse_Button *ev);
+       void (*go_wheel)  (E_Object *obj, const char *params, Ecore_Event_Mouse_Wheel *ev);
+       void (*go_edge)   (E_Object *obj, const char *params, E_Event_Zone_Edge *ev);
+       void (*go_key)    (E_Object *obj, const char *params, Ecore_Event_Key *ev);
+       void (*go_signal) (E_Object *obj, const char *params, const char *sig, const char *src);
+       void (*go_acpi)   (E_Object *obj, const char *params, E_Event_Acpi *ev);
+       void (*end)       (E_Object *obj, const char *params);
+       void (*end_mouse) (E_Object *obj, const char *params, Ecore_Event_Mouse_Button *ev);
+       void (*end_key)   (E_Object *obj, const char *params, Ecore_Event_Key *ev);
+     } func;
+};
+
+struct _E_Action_Description
+{
+   const char *act_name;
+   const char *act_cmd;
+   const char *act_params;
+   const char *param_example;
+   int editable;
+};
+
+struct _E_Action_Group
+{
+   const char *act_grp;
+   Eina_List *acts;
+};
+
+EINTERN int         e_actions_init(void);
+EINTERN int         e_actions_shutdown(void);
+
+EAPI Eina_List  *e_action_name_list(void);
+EAPI E_Action   *e_action_add(const char *name);
+/* e_action_del allows, for example, modules to define their own actions dynamically. */
+EAPI void      e_action_del(const char *name);
+EAPI E_Action   *e_action_find(const char *name);
+
+EAPI const char *e_action_predef_label_get(const char *action, const char *params);
+EAPI void       e_action_predef_name_set(const char *act_grp, const char *act_name, const char *act_cmd, const char *act_params, const char *param_example, int editable);
+EAPI void       e_action_predef_name_del(const char *act_grp, const char *act_name);
+EAPI void       e_action_predef_name_all_del(void);
+EAPI Eina_List  *e_action_groups_get(void);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_alert.h b/src/bin/e_wayland/e_alert.h
new file mode 100644 (file)
index 0000000..dead6c7
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Alert_Op_Type
+{
+   E_ALERT_OP_RESTART = 0,
+   E_ALERT_OP_EXIT
+} E_Alert_Op_Type;
+
+#else
+#ifndef E_ALERT_H
+#define E_ALERT_H
+
+EINTERN int e_alert_init(void);
+EINTERN int e_alert_shutdown(void);
+
+EAPI void e_alert_show(void);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_bg.c b/src/bin/e_wayland/e_bg.c
new file mode 100644 (file)
index 0000000..178e262
--- /dev/null
@@ -0,0 +1,412 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_bg_signal(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__);
+
+/* local variables */
+EAPI int E_EVENT_BG_UPDATE = 0;
+
+EINTERN int 
+e_bg_init(void)
+{
+   Eina_List *l = NULL;
+   E_Config_Desktop_Background *cfbg = NULL;
+
+   if (e_config->desktop_default_background)
+     e_filereg_register(e_config->desktop_default_background);
+
+   EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cfbg)
+     {
+        if (!cfbg) continue;
+        e_filereg_register(cfbg->file);
+     }
+
+   E_EVENT_BG_UPDATE = ecore_event_type_new();
+
+   return 1;
+}
+
+EINTERN int 
+e_bg_shutdown(void)
+{
+   Eina_List *l = NULL;
+   E_Config_Desktop_Background *cfbg = NULL;
+
+   if (e_config->desktop_default_background)
+     e_filereg_deregister(e_config->desktop_default_background);
+
+   EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cfbg)
+     {
+        if (!cfbg) continue;
+        e_filereg_deregister(cfbg->file);
+     }
+
+   return 1;
+}
+
+EAPI void 
+e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition)
+{
+   const char *bgfile = "", *trans = "";
+   E_Desk *desk;
+
+   if (transition == E_BG_TRANSITION_START) 
+     trans = e_config->transition_start;
+   else if (transition == E_BG_TRANSITION_DESK) 
+     trans = e_config->transition_desk;
+   else if (transition == E_BG_TRANSITION_CHANGE) 
+     trans = e_config->transition_change;
+   if ((!trans) || (!trans[0])) transition = E_BG_TRANSITION_NONE;
+
+   desk = e_desk_current_get(zone);
+   if (desk)
+     bgfile = e_bg_file_get(zone->container->num, zone->num, desk->x, desk->y);
+   else
+     bgfile = e_bg_file_get(zone->container->num, zone->num, -1, -1);
+
+   printf("Bg File: %s\n", bgfile);
+
+   if (zone->o_bg) 
+     {
+        const char *pfile = "";
+
+        edje_object_file_get(zone->o_bg, &pfile, NULL);
+        if (!strcmp(pfile, bgfile)) return;
+     }
+
+   if (transition == E_BG_TRANSITION_NONE)
+     {
+        if (zone->o_bg) 
+          {
+             evas_object_del(zone->o_bg);
+             zone->o_bg = NULL;
+          }
+     }
+   else 
+     {
+        char buff[PATH_MAX];
+
+        if (zone->o_bg)
+          {
+             if (zone->o_prev_bg) evas_object_del(zone->o_prev_bg);
+             zone->o_prev_bg = zone->o_bg;
+             if (zone->o_trans) evas_object_del(zone->o_trans);
+             zone->o_trans = NULL;
+             zone->o_bg = NULL;
+          }
+        zone->o_trans = edje_object_add(zone->container->bg_evas);
+        evas_object_data_set(zone->o_trans, "e_zone", zone);
+        snprintf(buff, sizeof(buff), "e/transitions/%s", trans);
+        e_theme_edje_object_set(zone->o_trans, "base/theme/transitions", buff);
+        edje_object_signal_callback_add(zone->o_trans, "e,state,done", "*", 
+                                        _e_bg_signal, zone);
+        evas_object_move(zone->o_trans, zone->x, zone->y);
+        evas_object_resize(zone->o_trans, zone->w, zone->h);
+        evas_object_layer_set(zone->o_trans, -1);
+        evas_object_clip_set(zone->o_trans, zone->o_bg_clip);
+        evas_object_show(zone->o_trans);
+     }
+
+   if (eina_str_has_extension(bgfile, ".edj"))
+     {
+        zone->o_bg = edje_object_add(zone->container->bg_evas);
+        evas_object_move(zone->o_bg, zone->x, zone->y);
+        evas_object_resize(zone->o_bg, zone->w, zone->h);
+        evas_object_data_set(zone->o_bg, "e_zone", zone);
+        edje_object_file_set(zone->o_bg, bgfile, "e/desktop/background");
+     }
+   else 
+     {
+        /* TODO */
+     }
+
+   if (transition == E_BG_TRANSITION_NONE)
+     {
+        evas_object_move(zone->o_bg, zone->x, zone->y);
+        evas_object_resize(zone->o_bg, zone->w, zone->h);
+        evas_object_layer_set(zone->o_bg, -1);
+     }
+   evas_object_clip_set(zone->o_bg, zone->o_bg_clip);
+   evas_object_show(zone->o_bg);
+
+   if (transition != E_BG_TRANSITION_NONE)
+     {
+       edje_extern_object_max_size_set(zone->o_prev_bg, 65536, 65536);
+       edje_extern_object_min_size_set(zone->o_prev_bg, 0, 0);
+       edje_object_part_swallow(zone->o_trans, "e.swallow.bg.old",
+                                zone->o_prev_bg);
+       edje_extern_object_max_size_set(zone->o_bg, 65536, 65536);
+       edje_extern_object_min_size_set(zone->o_bg, 0, 0);
+       edje_object_part_swallow(zone->o_trans, "e.swallow.bg.new",
+                                zone->o_bg);
+       edje_object_signal_emit(zone->o_trans, "e,action,start", "e");
+     }
+}
+
+EAPI const char *
+e_bg_file_get(int con_num, int zone_num, int desk_x, int desk_y)
+{
+   const E_Config_Desktop_Background *cfbg;
+   Eina_List *l, *entries;
+   const char *bgfile = "";
+   char *entry;
+   Eina_Bool ok = EINA_FALSE;
+
+   cfbg = e_bg_config_get(con_num, zone_num, desk_x, desk_y);
+
+   /* fall back to default */
+   if (cfbg)
+     {
+       bgfile = cfbg->file;
+       if (bgfile)
+         {
+            if (bgfile[0] != '/')
+              {
+                 const char *bf;
+
+                 bf = e_path_find(path_backgrounds, bgfile);
+                 if (bf) bgfile = bf;
+              }
+         }
+     }
+   else
+     {
+       bgfile = e_config->desktop_default_background;
+       if (bgfile)
+         {
+            if (bgfile[0] != '/')
+              {
+                 const char *bf;
+
+                 bf = e_path_find(path_backgrounds, bgfile);
+                 if (bf) bgfile = bf;
+              }
+         }
+        if ((bgfile) && (eina_str_has_extension(bgfile, ".edj")))
+          {
+             entries = edje_file_collection_list(bgfile);
+             if (entries)
+               {
+                  EINA_LIST_FOREACH(entries, l, entry)
+                    {
+                       if (!strcmp(entry, "e/desktop/background"))
+                         {
+                            ok = EINA_TRUE;
+                            break;
+                         }
+                    }
+                  edje_file_collection_list_free(entries);
+               }
+          }
+        else if ((bgfile) && (bgfile[0])) 
+          ok = EINA_TRUE;
+
+       if (!ok)
+         bgfile = e_theme_edje_file_get("base/theme/background",
+                                        "e/desktop/background");
+     }
+
+   return bgfile;
+}
+
+EAPI const E_Config_Desktop_Background *
+e_bg_config_get(int con_num, int zone_num, int desk_x, int desk_y)
+{
+   Eina_List *l, *ll, *entries;
+   E_Config_Desktop_Background *bg = NULL, *cfbg = NULL;
+   const char *bgfile = "";
+   char *entry;
+   int current_spec = 0; /* how specific the setting is - we want the least general one that applies */
+
+   /* look for desk specific background. */
+   if ((con_num >= 0) || (zone_num >= 0) || (desk_x >= 0) || (desk_y >= 0))
+     {
+       EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cfbg)
+         {
+            int spec;
+             
+            if (!cfbg) continue;
+            spec = 0;
+            if (cfbg->container == con_num) spec++;
+            else if (cfbg->container >= 0) continue;
+            if (cfbg->zone == zone_num) spec++;
+            else if (cfbg->zone >= 0) continue;
+            if (cfbg->desk_x == desk_x) spec++;
+            else if (cfbg->desk_x >= 0) continue;
+            if (cfbg->desk_y == desk_y) spec++;
+            else if (cfbg->desk_y >= 0) continue;
+
+            if (spec <= current_spec) continue;
+            bgfile = cfbg->file;
+            if (bgfile)
+              {
+                 if (bgfile[0] != '/')
+                   {
+                      const char *bf;
+
+                      bf = e_path_find(path_backgrounds, bgfile);
+                      if (bf) bgfile = bf;
+                   }
+              }
+             if (eina_str_has_extension(bgfile, ".edj"))
+               {
+                  entries = edje_file_collection_list(bgfile);
+                  if (entries)
+                    {
+                       EINA_LIST_FOREACH(entries, ll, entry)
+                         {
+                            if (!strcmp(entry, "e/desktop/background"))
+                              {
+                                 bg = cfbg;
+                                 current_spec = spec;
+                              }
+                         }
+                       edje_file_collection_list_free(entries);
+                    }
+               }
+             else
+               {
+                  bg = cfbg;
+                  current_spec = spec;
+               }
+         }
+     }
+
+   return bg;
+}
+
+EAPI void 
+e_bg_default_set(const char *file)
+{
+   /* E_Event_Bg_Update *ev; */
+   Eina_Bool changed;
+
+   file = eina_stringshare_add(file);
+   changed = file != e_config->desktop_default_background;
+
+   if (!changed)
+     {
+       eina_stringshare_del(file);
+       return;
+     }
+
+   if (e_config->desktop_default_background)
+     {
+       e_filereg_deregister(e_config->desktop_default_background);
+       eina_stringshare_del(e_config->desktop_default_background);
+     }
+
+   if (file)
+     {
+       e_filereg_register(file);
+       e_config->desktop_default_background = file;
+     }
+   else
+     e_config->desktop_default_background = NULL;
+
+   /* ev = E_NEW(E_Event_Bg_Update, 1); */
+   /* ev->container = -1; */
+   /* ev->zone = -1; */
+   /* ev->desk_x = -1; */
+   /* ev->desk_y = -1; */
+   /* ecore_event_add(E_EVENT_BG_UPDATE, ev, _e_bg_event_bg_update_free, NULL); */
+}
+
+EAPI void 
+e_bg_add(int con, int zone, int dx, int dy, const char *file)
+{
+   const Eina_List *l;
+   E_Config_Desktop_Background *cfbg;
+
+   file = eina_stringshare_add(file);
+
+   EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cfbg)
+     {
+       if ((cfbg) && (cfbg->container == con) && (cfbg->zone == zone) &&
+           (cfbg->desk_x == dx) && (cfbg->desk_y == dy) &&
+           (cfbg->file == file))
+         {
+            eina_stringshare_del(file);
+            return;
+         }
+     }
+
+   e_bg_del(con, zone, dx, dy);
+
+   cfbg = E_NEW(E_Config_Desktop_Background, 1);
+   cfbg->container = con;
+   cfbg->zone = zone;
+   cfbg->desk_x = dx;
+   cfbg->desk_y = dy;
+   cfbg->file = file;
+   e_config->desktop_backgrounds = 
+     eina_list_append(e_config->desktop_backgrounds, cfbg);
+
+   e_filereg_register(cfbg->file);
+}
+
+EAPI void 
+e_bg_del(int con, int zone, int dx, int dy)
+{
+   Eina_List *l;
+   E_Config_Desktop_Background *cfbg;
+
+   EINA_LIST_FOREACH(e_config->desktop_backgrounds, l, cfbg)
+     {
+       if (!cfbg) continue;
+       if ((cfbg->container == con) && (cfbg->zone == zone) &&
+           (cfbg->desk_x == dx) && (cfbg->desk_y == dy))
+         {
+            e_config->desktop_backgrounds = 
+               eina_list_remove_list(e_config->desktop_backgrounds, l);
+            e_filereg_deregister(cfbg->file);
+            if (cfbg->file) eina_stringshare_del(cfbg->file);
+            free(cfbg);
+            break;
+         }
+     }
+}
+
+EAPI void 
+e_bg_update(void)
+{
+   Eina_List *l, *ll, *lll;
+   E_Manager *man;
+   E_Container *con;
+   E_Zone *zone;
+
+   EINA_LIST_FOREACH(e_manager_list(), l, man)
+     {
+       EINA_LIST_FOREACH(man->containers, ll, con)
+         {
+            EINA_LIST_FOREACH(con->zones, lll, zone)
+              {
+                 e_zone_bg_reconfigure(zone);
+              }
+         }
+     }
+}
+
+/* local functions */
+static void
+_e_bg_signal(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   E_Zone *zone;
+
+   zone = data;
+   if (zone->o_prev_bg)
+     {
+       evas_object_del(zone->o_prev_bg);
+       zone->o_prev_bg = NULL;
+     }
+   if (zone->o_trans)
+     {
+       evas_object_del(zone->o_trans);
+       zone->o_trans = NULL;
+     }
+   evas_object_move(zone->o_bg, zone->x, zone->y);
+   evas_object_resize(zone->o_bg, zone->w, zone->h);
+   evas_object_layer_set(zone->o_bg, -1);
+   evas_object_clip_set(zone->o_bg, zone->o_bg_clip);
+   evas_object_show(zone->o_bg);
+}
diff --git a/src/bin/e_wayland/e_bg.h b/src/bin/e_wayland/e_bg.h
new file mode 100644 (file)
index 0000000..fe10d6f
--- /dev/null
@@ -0,0 +1,29 @@
+#ifdef E_TYPEDEFS
+
+typedef enum 
+{
+   E_BG_TRANSITION_NONE,
+   E_BG_TRANSITION_START,
+   E_BG_TRANSITION_DESK,
+   E_BG_TRANSITION_CHANGE
+} E_Bg_Transition;
+
+#else
+# ifndef E_BG_H
+#  define E_BG_H
+
+extern EAPI int E_EVENT_BG_UPDATE;
+
+EINTERN int e_bg_init(void);
+EINTERN int e_bg_shutdown(void);
+
+EAPI void e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition);
+EAPI const char *e_bg_file_get(int con_num, int zone_num, int desk_x, int desk_y);
+EAPI const E_Config_Desktop_Background *e_bg_config_get(int con_num, int zone_num, int desk_x, int desk_y);
+EAPI void e_bg_default_set(const char *file);
+EAPI void e_bg_add(int con, int zone, int dx, int dy, const char *file);
+EAPI void e_bg_del(int con, int zone, int dx, int dy);
+EAPI void e_bg_update(void);
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_bindings.c b/src/bin/e_wayland/e_bindings.c
new file mode 100644 (file)
index 0000000..3adb0e8
--- /dev/null
@@ -0,0 +1,13 @@
+#include "e.h"
+
+EAPI E_Action *
+e_bindings_acpi_event_handle(E_Binding_Context ctxt __UNUSED__, E_Object *obj __UNUSED__, E_Event_Acpi *ev __UNUSED__)
+{
+   return NULL;
+}
+
+EAPI E_Action *
+e_bindings_key_down_event_find(E_Binding_Context ctxt __UNUSED__, Ecore_Event_Key *ev)
+{
+   return NULL;
+}
diff --git a/src/bin/e_wayland/e_bindings.h b/src/bin/e_wayland/e_bindings.h
new file mode 100644 (file)
index 0000000..e64ea36
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Binding_Context
+{
+   E_BINDING_CONTEXT_NONE,
+   E_BINDING_CONTEXT_UNKNOWN,
+   E_BINDING_CONTEXT_BORDER,
+   E_BINDING_CONTEXT_ZONE,
+   E_BINDING_CONTEXT_CONTAINER,
+   E_BINDING_CONTEXT_MANAGER,
+   E_BINDING_CONTEXT_MENU,
+   E_BINDING_CONTEXT_WINLIST,
+   E_BINDING_CONTEXT_POPUP,
+   E_BINDING_CONTEXT_ANY
+} E_Binding_Context;
+
+#else
+# ifndef E_BINDINGS_H
+#  define E_BINDINGS_H
+
+EAPI E_Action *e_bindings_acpi_event_handle(E_Binding_Context ctxt __UNUSED__, E_Object *obj __UNUSED__, E_Event_Acpi *ev __UNUSED__);
+EAPI E_Action *e_bindings_key_down_event_find(E_Binding_Context ctxt __UNUSED__, Ecore_Event_Key *ev);
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_border.c b/src/bin/e_wayland/e_border.c
new file mode 100644 (file)
index 0000000..55790ff
--- /dev/null
@@ -0,0 +1,31 @@
+#include "e.h"
+
+EAPI void 
+e_border_uniconify(void *bd)
+{
+
+}
+
+EAPI void 
+e_border_unshade(void *bd, int dir)
+{
+
+}
+
+EAPI void 
+e_border_focus_set(void *bd, int focus, int set)
+{
+
+}
+
+EAPI void 
+e_border_desk_set(void *bd, E_Desk *desk)
+{
+
+}
+
+EAPI Eina_List *
+e_border_client_list(void)
+{
+   return NULL;
+}
index a966981aa7611be6ab613fee45f57862d44dc4d2..c60bf3a01308c39644c73dc99311a26498fc56f7 100644 (file)
@@ -11,8 +11,6 @@ typedef enum _E_Maximize
    E_MAXIMIZE_VERTICAL = 0x00000010,
    E_MAXIMIZE_HORIZONTAL = 0x00000020,
    E_MAXIMIZE_BOTH = 0x00000030,
-   E_MAXIMIZE_LEFT = 0x00000070,
-   E_MAXIMIZE_RIGHT = 0x000000b0,
    E_MAXIMIZE_DIRECTION = 0x000000f0
 } E_Maximize;
 
@@ -24,4 +22,28 @@ typedef enum _E_Window_Placement
    E_WINDOW_PLACEMENT_MANUAL
 } E_Window_Placement;
 
+typedef struct _E_Border E_Border;
+
+#else
+# ifndef E_BORDER_H
+#  define E_BORDER_H
+
+#  define E_BORDER_TYPE 0xE0b01002
+
+struct _E_Border
+{
+   E_Object e_obj_inherit;
+};
+
+EAPI void e_border_uniconify(void *bd);
+EAPI void e_border_unshade(void *bd, int dir);
+EAPI void e_border_focus_set(void *bd, int focus, int set);
+EAPI void e_border_desk_set(void *bd, E_Desk *desk);
+
+EAPI Eina_List *e_border_client_list(void);
+
+EAPI void e_border_activate(E_Border *bd, Eina_Bool just_do_it);
+EAPI void e_border_raise(E_Border *bd);
+
+# endif
 #endif
diff --git a/src/bin/e_wayland/e_box.c b/src/bin/e_wayland/e_box.c
new file mode 100644 (file)
index 0000000..1ed6383
--- /dev/null
@@ -0,0 +1,901 @@
+#include "e.h"
+
+typedef struct _E_Smart_Data E_Smart_Data;
+typedef struct _E_Box_Item   E_Box_Item;
+
+struct _E_Smart_Data
+{
+   Evas_Coord    x, y, w, h;
+   Evas_Object  *obj;
+   Evas_Object  *clip;
+   int           frozen;
+   unsigned char changed : 1;
+   unsigned char horizontal : 1;
+   unsigned char homogenous : 1;
+   E_Box_Item   *items;
+   unsigned int  item_count;
+   struct
+   {
+      Evas_Coord w, h;
+   } min, max;
+   struct
+   {
+      double x, y;
+   } align;
+};
+
+struct _E_Box_Item
+{
+   EINA_INLIST;
+   E_Smart_Data *sd;
+   unsigned char fill_w : 1;
+   unsigned char fill_h : 1;
+   unsigned char expand_w : 1;
+   unsigned char expand_h : 1;
+   struct
+   {
+      Evas_Coord w, h;
+   } min, max;
+   struct
+   {
+      double x, y;
+   } align;
+   int           x, y, w, h;
+   Evas_Object  *obj;
+};
+
+/* local subsystem functions */
+static void        _e_box_unpack_internal(E_Smart_Data *sd, E_Box_Item *bi);
+static E_Box_Item *_e_box_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
+static void        _e_box_smart_disown(E_Box_Item *bi);
+static void        _e_box_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void        _e_box_smart_reconfigure(E_Smart_Data *sd);
+static void        _e_box_smart_extents_calculate(E_Smart_Data *sd);
+
+static void        _e_box_smart_init(void);
+static void        _e_box_smart_add(Evas_Object *obj);
+static void        _e_box_smart_del(Evas_Object *obj);
+static void        _e_box_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void        _e_box_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void        _e_box_smart_show(Evas_Object *obj);
+static void        _e_box_smart_hide(Evas_Object *obj);
+static void        _e_box_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void        _e_box_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
+static void        _e_box_smart_clip_unset(Evas_Object *obj);
+
+/* local subsystem globals */
+static Evas_Smart *_e_smart = NULL;
+
+static inline Evas_Object *
+_e_box_item_object_get(E_Box_Item *bi)
+{
+   if (!bi) return NULL;
+   return bi->obj;
+}
+
+static inline Evas_Object *
+_e_box_item_nth_get(E_Smart_Data *sd, unsigned int n)
+{
+   unsigned int x;
+   E_Box_Item *bi;
+
+   if (!sd->items) return NULL;
+   if (n > sd->item_count / 2)
+     {
+        x = sd->item_count - 1;
+        EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(sd->items), bi)
+          {
+             if (n == x) return bi->obj;
+             x--;
+          }
+        return NULL;
+     }
+   x = 0;
+   EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+     {
+        if (n == x) return bi->obj;
+        x++;
+     }
+   return NULL;
+}
+
+/* externally accessible functions */
+EAPI Evas_Object *
+e_box_add(Evas *evas)
+{
+   _e_box_smart_init();
+   return evas_object_smart_add(evas, _e_smart);
+}
+
+EAPI int
+e_box_freeze(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   sd->frozen++;
+   return sd->frozen;
+}
+
+EAPI int
+e_box_thaw(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   sd->frozen--;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+   return sd->frozen;
+}
+
+EAPI void
+e_box_orientation_set(Evas_Object *obj, int horizontal)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->horizontal == horizontal) return;
+   sd->horizontal = horizontal;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+}
+
+EAPI int
+e_box_orientation_get(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   return sd->horizontal;
+}
+
+EAPI void
+e_box_homogenous_set(Evas_Object *obj, int homogenous)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->homogenous == homogenous) return;
+   sd->homogenous = homogenous;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+}
+
+EAPI int
+e_box_pack_start(Evas_Object *obj, Evas_Object *child)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi;
+   Eina_Inlist *l;
+
+   if (!child) return 0;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   bi = _e_box_smart_adopt(sd, child);
+   l = EINA_INLIST_GET(sd->items);
+   l = eina_inlist_prepend(l, EINA_INLIST_GET(bi));
+   sd->items = EINA_INLIST_CONTAINER_GET(l, E_Box_Item);
+   sd->item_count++;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+   return 0;
+}
+
+EAPI int
+e_box_pack_end(Evas_Object *obj, Evas_Object *child)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi;
+   Eina_Inlist *l;
+
+   if (!child) return 0;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   bi = _e_box_smart_adopt(sd, child);
+   l = EINA_INLIST_GET(sd->items);
+   l = eina_inlist_append(l, EINA_INLIST_GET(bi));
+   sd->items = EINA_INLIST_CONTAINER_GET(l, E_Box_Item);
+   sd->item_count++;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+   return sd->item_count - 1;
+}
+
+EAPI int
+e_box_pack_before(Evas_Object *obj, Evas_Object *child, Evas_Object *before)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi, *bi2;
+   int i = 0;
+   Eina_Inlist *l;
+
+   if (!child) return 0;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   bi2 = evas_object_data_get(before, "e_box_data");
+   if (!bi2) return 0;
+   bi = _e_box_smart_adopt(sd, child);
+   l = EINA_INLIST_GET(sd->items);
+   l = eina_inlist_prepend_relative(l, EINA_INLIST_GET(bi), EINA_INLIST_GET(bi2));
+   sd->items = EINA_INLIST_CONTAINER_GET(l, E_Box_Item);
+   sd->item_count++;
+
+   for (l = EINA_INLIST_GET(bi)->prev; l; l = l->prev)
+     i++;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+   return i;
+}
+
+EAPI int
+e_box_pack_after(Evas_Object *obj, Evas_Object *child, Evas_Object *after)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi, *bi2;
+   int i = 0;
+   Eina_Inlist *l;
+
+   if (!child) return 0;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   bi2 = evas_object_data_get(after, "e_box_data");
+   if (!bi2) return 0;
+   bi = _e_box_smart_adopt(sd, child);
+   l = EINA_INLIST_GET(sd->items);
+   l = eina_inlist_append_relative(l, EINA_INLIST_GET(bi), EINA_INLIST_GET(bi2));
+   sd->items = EINA_INLIST_CONTAINER_GET(l, E_Box_Item);
+   sd->item_count++;
+   for (l = EINA_INLIST_GET(bi)->prev; l; l = l->prev)
+     i++;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+   return i;
+}
+
+EAPI int
+e_box_pack_count_get(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!sd) return 0;
+   return sd->item_count;
+}
+
+EAPI Evas_Object *
+e_box_pack_object_nth(Evas_Object *obj, int n)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return NULL;
+   return _e_box_item_nth_get(sd, n);
+}
+
+EAPI Evas_Object *
+e_box_pack_object_first(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return NULL;
+   return sd->items ? sd->items->obj : NULL;
+}
+
+EAPI Evas_Object *
+e_box_pack_object_last(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
+   sd = evas_object_smart_data_get(obj);
+   if ((!sd) || (!sd->items)) return NULL;
+   return EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(sd->items)->last, E_Box_Item)->obj;
+}
+
+EAPI void
+e_box_pack_options_set(Evas_Object *obj, int fill_w, int fill_h, int expand_w, int expand_h, double align_x, double align_y, Evas_Coord min_w, Evas_Coord min_h, Evas_Coord max_w, Evas_Coord max_h)
+{
+   E_Box_Item *bi;
+
+   bi = evas_object_data_get(obj, "e_box_data");
+   if (!bi) return;
+   bi->fill_w = fill_w;
+   bi->fill_h = fill_h;
+   bi->expand_w = expand_w;
+   bi->expand_h = expand_h;
+   bi->align.x = align_x;
+   bi->align.y = align_y;
+   bi->min.w = min_w;
+   bi->min.h = min_h;
+   bi->max.w = max_w;
+   bi->max.h = max_h;
+   bi->sd->changed = 1;
+   if (bi->sd->frozen <= 0) _e_box_smart_reconfigure(bi->sd);
+}
+
+EAPI void
+e_box_unpack(Evas_Object *obj)
+{
+   E_Box_Item *bi;
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_box_data");
+   if (!bi) return;
+   sd = bi->sd;
+   if (!sd) return;
+   _e_box_unpack_internal(sd, bi);
+}
+
+EAPI void
+e_box_size_min_get(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->changed) _e_box_smart_extents_calculate(sd);
+   if (minw) *minw = sd->min.w;
+   if (minh) *minh = sd->min.h;
+}
+
+EAPI void
+e_box_size_max_get(Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->changed) _e_box_smart_extents_calculate(sd);
+   if (maxw) *maxw = sd->max.w;
+   if (maxh) *maxh = sd->max.h;
+}
+
+EAPI void
+e_box_align_get(Evas_Object *obj, double *ax, double *ay)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (ax) *ax = sd->align.x;
+   if (ay) *ay = sd->align.y;
+}
+
+EAPI void
+e_box_align_set(Evas_Object *obj, double ax, double ay)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((sd->align.x == ax) && (sd->align.y == ay)) return;
+   sd->align.x = ax;
+   sd->align.y = ay;
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+}
+
+/*
+ * Returns the number of pixels that are hidden on the left/top side.
+ */
+EAPI void
+e_box_align_pixel_offset_get(Evas_Object *obj, int *x, int *y)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (x) *x = (sd->min.w - sd->w) * (1.0 - sd->align.x);
+   if (y) *y = (sd->min.h - sd->h) * (1.0 - sd->align.y);
+}
+
+EAPI Evas_Object *
+e_box_item_at_xy_get(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR() NULL;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return NULL;
+   if (!E_INSIDE(x, y, sd->x, sd->y, sd->w, sd->h)) return NULL;
+   if (sd->horizontal)
+     {
+        if (x < sd->w / 2)
+          {
+             EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+               {
+                  if (E_INSIDE(x, y, bi->x, bi->y, bi->w, bi->h)) return bi->obj;
+               }
+             return NULL;
+          }
+        EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(sd->items), bi)
+          {
+             if (E_INSIDE(x, y, bi->x, bi->y, bi->w, bi->h)) return bi->obj;
+          }
+        return NULL;
+     }
+   if (y < sd->h / 2)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+          {
+             if (E_INSIDE(x, y, bi->x, bi->y, bi->w, bi->h)) return bi->obj;
+          }
+        return NULL;
+     }
+   EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(sd->items), bi)
+     {
+        if (E_INSIDE(x, y, bi->x, bi->y, bi->w, bi->h)) return bi->obj;
+     }
+   return NULL;
+}
+
+EAPI Eina_Bool
+e_box_item_size_get(Evas_Object *obj, int *w, int *h)
+{
+   E_Box_Item *bi;
+
+   bi = evas_object_data_get(obj, "e_box_data");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(bi, EINA_FALSE);
+   if (w) *w = bi->w;
+   if (h) *h = bi->h;
+   return EINA_TRUE;
+}
+
+/* local subsystem functions */
+static void
+_e_box_unpack_internal(E_Smart_Data *sd, E_Box_Item *bi)
+{
+   Eina_Inlist *l;
+
+   l = EINA_INLIST_GET(sd->items);
+   l = eina_inlist_remove(l, EINA_INLIST_GET(bi));
+   sd->items = EINA_INLIST_CONTAINER_GET(l, E_Box_Item);
+   sd->item_count--;
+   _e_box_smart_disown(bi);
+   sd->changed = 1;
+   if (sd->frozen <= 0) _e_box_smart_reconfigure(sd);
+}
+
+static E_Box_Item *
+_e_box_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
+{
+   E_Box_Item *bi;
+
+   bi = calloc(1, sizeof(E_Box_Item));
+   if (!bi) return NULL;
+   bi->sd = sd;
+   bi->obj = obj;
+   /* defaults */
+   bi->fill_w = 0;
+   bi->fill_h = 0;
+   bi->expand_w = 0;
+   bi->expand_h = 0;
+   bi->align.x = 0.5;
+   bi->align.y = 0.5;
+   bi->min.w = 0;
+   bi->min.h = 0;
+   bi->max.w = 0;
+   bi->max.h = 0;
+   evas_object_clip_set(obj, sd->clip);
+   evas_object_smart_member_add(obj, bi->sd->obj);
+   evas_object_data_set(obj, "e_box_data", bi);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
+                                  _e_box_smart_item_del_hook, NULL);
+   if ((!evas_object_visible_get(sd->clip)) &&
+       (evas_object_visible_get(sd->obj)))
+     evas_object_show(sd->clip);
+   return bi;
+}
+
+static void
+_e_box_smart_disown(E_Box_Item *bi)
+{
+   if (!bi) return;
+   if (!bi->sd->items)
+     {
+        if (evas_object_visible_get(bi->sd->clip))
+          evas_object_hide(bi->sd->clip);
+     }
+   evas_object_event_callback_del(bi->obj,
+                                  EVAS_CALLBACK_FREE,
+                                  _e_box_smart_item_del_hook);
+   evas_object_smart_member_del(bi->obj);
+   evas_object_clip_unset(bi->obj);
+   evas_object_data_del(bi->obj, "e_box_data");
+   free(bi);
+}
+
+static void
+_e_box_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   e_box_unpack(obj);
+}
+
+static void
+_e_box_smart_reconfigure(E_Smart_Data *sd)
+{
+   Evas_Coord x, y, w, h, xx, yy;
+   E_Box_Item *bi;
+   int minw, minh, wdif, hdif;
+   int count, expand;
+
+   if (!sd->changed) return;
+
+   x = sd->x;
+   y = sd->y;
+   w = sd->w;
+   h = sd->h;
+
+   _e_box_smart_extents_calculate(sd);
+   minw = sd->min.w;
+   minh = sd->min.h;
+   count = sd->item_count;
+   expand = 0;
+   if (w < minw)
+     {
+        x = x + ((w - minw) * (1.0 - sd->align.x));
+        w = minw;
+     }
+   if (h < minh)
+     {
+        y = y + ((h - minh) * (1.0 - sd->align.y));
+        h = minh;
+     }
+   EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+     {
+        if (sd->horizontal)
+          {
+             if (bi->expand_w) expand++;
+          }
+        else
+          {
+             if (bi->expand_h) expand++;
+          }
+     }
+   if (expand == 0)
+     {
+        if (sd->horizontal)
+          {
+             x += (double)(w - minw) * sd->align.x;
+             w = minw;
+          }
+        else
+          {
+             y += (double)(h - minh) * sd->align.y;
+             h = minh;
+          }
+     }
+   wdif = w - minw;
+   hdif = h - minh;
+   xx = x;
+   yy = y;
+   EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+     {
+        if (sd->horizontal)
+          {
+             if (sd->homogenous)
+               {
+                  Evas_Coord ww, hh, ow, oh;
+
+                  ww = (w / (Evas_Coord)count);
+                  hh = h;
+                  ow = bi->min.w;
+                  if (bi->fill_w) ow = ww;
+                  if ((bi->max.w >= 0) && (bi->max.w < ow))
+                    ow = bi->max.w;
+                  oh = bi->min.h;
+                  if (bi->fill_h) oh = hh;
+                  if ((bi->max.h >= 0) && (bi->max.h < oh))
+                    oh = bi->max.h;
+                  bi->x = xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x);
+                  bi->y = yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y);
+                  evas_object_move(bi->obj, bi->x, bi->y);
+                  evas_object_resize(bi->obj, bi->w = ow, bi->h = oh);
+                  xx += ww;
+               }
+             else
+               {
+                  Evas_Coord ww, hh, ow, oh;
+
+                  ww = bi->min.w;
+                  if ((expand > 0) && (bi->expand_w))
+                    {
+                       if (expand == 1) ow = wdif;
+                       else ow = (w - minw) / expand;
+                       wdif -= ow;
+                       ww += ow;
+                    }
+                  hh = h;
+                  ow = bi->min.w;
+                  if (bi->fill_w) ow = ww;
+                  if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
+                  oh = bi->min.h;
+                  if (bi->fill_h) oh = hh;
+                  if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
+                  bi->x = xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x);
+                  bi->y = yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y);
+                  evas_object_move(bi->obj, bi->x, bi->y);
+                  evas_object_resize(bi->obj, bi->w = ow, bi->h = oh);
+                  xx += ww;
+               }
+          }
+        else
+          {
+             if (sd->homogenous)
+               {
+                  Evas_Coord ww, hh, ow, oh;
+
+                  ww = w;
+                  hh = (h / (Evas_Coord)count);
+                  ow = bi->min.w;
+                  if (bi->fill_w) ow = ww;
+                  if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
+                  oh = bi->min.h;
+                  if (bi->fill_h) oh = hh;
+                  if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
+                  bi->x = xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x);
+                  bi->y = yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y);
+                  evas_object_move(bi->obj, bi->x, bi->y);
+                  evas_object_resize(bi->obj, bi->w = ow, bi->h = oh);
+                  yy += hh;
+               }
+             else
+               {
+                  Evas_Coord ww, hh, ow, oh;
+
+                  ww = w;
+                  hh = bi->min.h;
+                  if ((expand > 0) && (bi->expand_h))
+                    {
+                       if (expand == 1) oh = hdif;
+                       else oh = (h - minh) / expand;
+                       hdif -= oh;
+                       hh += oh;
+                    }
+                  ow = bi->min.w;
+                  if (bi->fill_w) ow = ww;
+                  if ((bi->max.w >= 0) && (bi->max.w < ow)) ow = bi->max.w;
+                  oh = bi->min.h;
+                  if (bi->fill_h) oh = hh;
+                  if ((bi->max.h >= 0) && (bi->max.h < oh)) oh = bi->max.h;
+                  bi->x = xx + (Evas_Coord)(((double)(ww - ow)) * bi->align.x);
+                  bi->y = yy + (Evas_Coord)(((double)(hh - oh)) * bi->align.y);
+                  evas_object_move(bi->obj, bi->x, bi->y);
+                  evas_object_resize(bi->obj, bi->w = ow, bi->h = oh);
+                  yy += hh;
+               }
+          }
+     }
+   sd->changed = 0;
+}
+
+static void
+_e_box_smart_extents_calculate(E_Smart_Data *sd)
+{
+   E_Box_Item *bi;
+   int minw, minh;
+
+   /* FIXME: need to calc max */
+   sd->max.w = -1; /* max < 0 == unlimited */
+   sd->max.h = -1;
+
+   minw = 0;
+   minh = 0;
+   if (sd->homogenous)
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+          {
+             if (minh < bi->min.h) minh = bi->min.h;
+             if (minw < bi->min.w) minw = bi->min.w;
+          }
+        if (sd->horizontal)
+          minw *= sd->item_count;
+        else
+          minh *= sd->item_count;
+     }
+   else
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+          {
+             if (sd->horizontal)
+               {
+                  if (minh < bi->min.h) minh = bi->min.h;
+                  minw += bi->min.w;
+               }
+             else
+               {
+                  if (minw < bi->min.w) minw = bi->min.w;
+                  minh += bi->min.h;
+               }
+          }
+     }
+   sd->min.w = minw;
+   sd->min.h = minh;
+}
+
+static void
+_e_box_smart_init(void)
+{
+   if (_e_smart) return;
+   {
+      static const Evas_Smart_Class sc =
+      {
+         "e_box",
+         EVAS_SMART_CLASS_VERSION,
+         _e_box_smart_add,
+         _e_box_smart_del,
+         _e_box_smart_move,
+         _e_box_smart_resize,
+         _e_box_smart_show,
+         _e_box_smart_hide,
+         _e_box_smart_color_set,
+         _e_box_smart_clip_set,
+         _e_box_smart_clip_unset,
+         NULL,
+         NULL,
+         NULL,
+         NULL,
+         NULL,
+         NULL,
+         NULL
+      };
+      _e_smart = evas_smart_class_new(&sc);
+   }
+}
+
+static void
+_e_box_smart_add(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = calloc(1, sizeof(E_Smart_Data));
+   if (!sd) return;
+   sd->obj = obj;
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->align.x = 0.5;
+   sd->align.y = 0.5;
+   sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
+   evas_object_smart_member_add(sd->clip, obj);
+   evas_object_move(sd->clip, -100004, -100004);
+   evas_object_resize(sd->clip, 200008, 200008);
+   evas_object_color_set(sd->clip, 255, 255, 255, 255);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_e_box_smart_del(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   /* FIXME: this gets into an infinite loop when changin basic->advanced on
+    * ibar config dialog
+    */
+   e_box_freeze(obj);
+   while (sd->items)
+     e_box_unpack(sd->items->obj);
+   e_box_thaw(obj);
+   evas_object_del(sd->clip);
+   free(sd);
+
+   evas_object_smart_data_set(obj, NULL);
+}
+
+static void
+_e_box_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Smart_Data *sd;
+   E_Box_Item *bi;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((x == sd->x) && (y == sd->y)) return;
+   {
+      Evas_Coord dx, dy;
+
+      dx = x - sd->x;
+      dy = y - sd->y;
+      EINA_INLIST_FOREACH(EINA_INLIST_GET(sd->items), bi)
+        {
+           bi->x += dx;
+           bi->y += dy;
+           evas_object_move(bi->obj, bi->x, bi->y);
+        }
+   }
+   sd->x = x;
+   sd->y = y;
+}
+
+static void
+_e_box_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((w == sd->w) && (h == sd->h)) return;
+   sd->w = w;
+   sd->h = h;
+   sd->changed = 1;
+   _e_box_smart_reconfigure(sd);
+}
+
+static void
+_e_box_smart_show(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->items) evas_object_show(sd->clip);
+}
+
+static void
+_e_box_smart_hide(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_hide(sd->clip);
+}
+
+static void
+_e_box_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_color_set(sd->clip, r, g, b, a);
+}
+
+static void
+_e_box_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_set(sd->clip, clip);
+}
+
+static void
+_e_box_smart_clip_unset(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_unset(sd->clip);
+}
+
diff --git a/src/bin/e_wayland/e_box.h b/src/bin/e_wayland/e_box.h
new file mode 100644 (file)
index 0000000..75a0e74
--- /dev/null
@@ -0,0 +1,30 @@
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_BOX_H
+#define E_BOX_H
+
+EAPI Evas_Object *e_box_add               (Evas *evas);
+EAPI int          e_box_freeze            (Evas_Object *obj);
+EAPI int          e_box_thaw              (Evas_Object *obj);
+EAPI void         e_box_orientation_set   (Evas_Object *obj, int horizontal);
+EAPI int          e_box_orientation_get   (Evas_Object *obj);
+EAPI void         e_box_homogenous_set    (Evas_Object *obj, int homogenous);
+EAPI int          e_box_pack_start        (Evas_Object *obj, Evas_Object *child);
+EAPI int          e_box_pack_end          (Evas_Object *obj, Evas_Object *child);
+EAPI int          e_box_pack_before       (Evas_Object *obj, Evas_Object *child, Evas_Object *before);
+EAPI int          e_box_pack_after        (Evas_Object *obj, Evas_Object *child, Evas_Object *after);
+EAPI int          e_box_pack_count_get    (Evas_Object *obj);
+EAPI Evas_Object *e_box_pack_object_nth   (Evas_Object *obj, int n);
+EAPI Evas_Object *e_box_pack_object_first (Evas_Object *obj);
+EAPI Evas_Object *e_box_pack_object_last  (Evas_Object *obj);
+EAPI void         e_box_pack_options_set  (Evas_Object *obj, int fill_w, int fill_h, int expand_w, int expand_h, double align_x, double align_y, Evas_Coord min_w, Evas_Coord min_h, Evas_Coord max_w, Evas_Coord max_h);
+EAPI void         e_box_unpack            (Evas_Object *obj);
+EAPI void         e_box_size_min_get      (Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh);
+EAPI void         e_box_size_max_get      (Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh);
+EAPI void         e_box_align_get         (Evas_Object *obj, double *ax, double *ay);
+EAPI void         e_box_align_set         (Evas_Object *obj, double ax, double ay);
+EAPI void        e_box_align_pixel_offset_get (Evas_Object *obj, int *x, int *y);
+EAPI Evas_Object *e_box_item_at_xy_get(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+EAPI Eina_Bool e_box_item_size_get(Evas_Object *obj, int *w, int *h);
+#endif
+#endif
index ac889b726500be82dbb016bfe743e7d2baecd56c..e9637f0a0a07714389a1d19b75e2b31df18a7abc 100644 (file)
@@ -2,7 +2,7 @@
 
 /* local function prototypes */
 static void _e_comp_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id);
-static void _e_comp_cb_bind_manager(struct wl_client *client, void *data, unsigned int version, unsigned int id);
+static void _e_comp_cb_bind_manager(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id);
 static void _e_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
 static void _e_comp_cb_surface_destroy(struct wl_resource *resource);
 static void _e_comp_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id);
@@ -289,8 +289,6 @@ e_compositor_damage_calculate(E_Compositor *comp)
    Eina_List *l;
    pixman_region32_t clip, opaque;
 
-   printf("E_Comp Damage Calculate\n");
-
    /* check for valid compositor */
    if (!comp) return;
 
@@ -324,10 +322,13 @@ e_compositor_damage_calculate(E_Compositor *comp)
      }
 }
 
-EAPI void 
-e_compositor_damage_flush(E_Compositor *comp, E_Surface *es)
+EAPI unsigned int 
+e_compositor_get_time(void)
 {
+   struct timeval tv;
 
+   gettimeofday(&tv, NULL);
+   return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
 }
 
 /* local functions */
@@ -344,7 +345,7 @@ _e_comp_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_
 }
 
 static void 
-_e_comp_cb_bind_manager(struct wl_client *client, void *data, unsigned int version, unsigned int id)
+_e_comp_cb_bind_manager(struct wl_client *client, void *data EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id)
 {
    /* add the data device manager to the client */
    wl_client_add_object(client, &wl_data_device_manager_interface, 
index bb014bebb6e123036a74883d1b0b111345e674fb..c5e602dc223635fccfdc4d553fbf795c9c9e2d39 100644 (file)
@@ -66,7 +66,7 @@ EAPI E_Compositor *e_compositor_get(void);
 EAPI void e_compositor_plane_stack(E_Compositor *comp, E_Plane *plane, E_Plane *above);
 EAPI int e_compositor_input_read(int fd EINA_UNUSED, unsigned int mask EINA_UNUSED, void *data);
 EAPI void e_compositor_damage_calculate(E_Compositor *comp);
-EAPI void e_compositor_damage_flush(E_Compositor *comp, E_Surface *es);
+EAPI unsigned int e_compositor_get_time(void);
 
 # endif
 #endif
diff --git a/src/bin/e_wayland/e_config_dialog.c b/src/bin/e_wayland/e_config_dialog.c
new file mode 100644 (file)
index 0000000..412ecaa
--- /dev/null
@@ -0,0 +1,19 @@
+#include "e.h"
+
+EAPI E_Config_Dialog *
+e_config_dialog_new(E_Container *con, const char *title, const char *name, const char *class, const char *icon, int icon_size, E_Config_Dialog_View *view, void *data)
+{
+   return NULL;
+}
+
+EAPI int
+e_config_dialog_find(const char *name, const char *class)
+{
+   return 0;
+}
+
+EAPI E_Config_Dialog *
+e_config_dialog_get(const char *name, const char *class)
+{
+   return NULL;
+}
diff --git a/src/bin/e_wayland/e_config_dialog.h b/src/bin/e_wayland/e_config_dialog.h
new file mode 100644 (file)
index 0000000..7e1e5b4
--- /dev/null
@@ -0,0 +1,66 @@
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Config_Dialog_CFData_Type
+{
+   E_CONFIG_DIALOG_CFDATA_TYPE_BASIC,
+   E_CONFIG_DIALOG_CFDATA_TYPE_ADVANCED,
+   E_CONFIG_DIALOG_CFDATA_TYPE_NORMAL_WINDOW
+} E_Config_Dialog_CFData_Type;
+
+typedef struct _E_Config_Dialog      E_Config_Dialog;
+typedef struct _E_Config_Dialog_View E_Config_Dialog_View;
+typedef struct _E_Config_Dialog_Data E_Config_Dialog_Data;
+
+#else
+#ifndef E_CONFIG_DIALOG_H
+#define E_CONFIG_DIALOG_H
+
+#define E_CONFIG_DIALOG_TYPE 0xE0b01017
+
+struct _E_Config_Dialog_View
+{
+   unsigned char override_auto_apply : 1;
+   unsigned char basic_only : 1;
+   unsigned char normal_win : 1;
+   unsigned char scroll : 1;
+
+   void           *(*create_cfdata)     (E_Config_Dialog *cfd);
+   void            (*free_cfdata)       (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+   int             (*close_cfdata)      (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+   struct {
+      int          (*apply_cfdata)      (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+      Evas_Object *(*create_widgets)    (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
+      int          (*check_changed)     (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+   } basic, advanced;
+};
+
+struct _E_Config_Dialog
+{
+   E_Object                     e_obj_inherit;
+
+   E_Config_Dialog_CFData_Type  view_type;
+   E_Config_Dialog_View        *view;
+   E_Config_Dialog_Data        *cfdata;
+   E_Container                 *con;
+   const char                  *title;
+   const char                  *icon;
+   const char                  *name;
+   const char                  *class;
+   int                          icon_size;
+   E_Dialog                    *dia;
+   void                        *data;
+   Ecore_Timer                 *auto_apply_timer;
+   unsigned char                hide_buttons : 1;
+   unsigned char                cfg_changed : 1;
+   unsigned char                cfg_changed_auto : 1;
+};
+
+EAPI E_Config_Dialog *e_config_dialog_new(E_Container *con, const char *title, const char *name, const char *class, const char *icon, int icon_size, E_Config_Dialog_View *view, void *data);
+EAPI int e_config_dialog_find(const char *name, const char *class);
+EAPI E_Config_Dialog *e_config_dialog_get(const char *name, const char *class);
+
+EAPI void e_config_dialog_changed_auto_set(E_Config_Dialog *cfd, unsigned char value);
+EAPI void e_config_dialog_changed_set(E_Config_Dialog *cfd, unsigned char value);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_configure.c b/src/bin/e_wayland/e_configure.c
new file mode 100644 (file)
index 0000000..b873819
--- /dev/null
@@ -0,0 +1,517 @@
+#include "e.h"
+
+static void      _e_configure_menu_module_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void      _e_configure_menu_add(void *data, E_Menu *m);
+static void      _e_configure_efreet_desktop_cleanup(void);
+static void      _e_configure_efreet_desktop_update(void);
+static Eina_Bool _e_configure_cb_efreet_desktop_cache_update(void *data, int type, void *event);
+static void      _e_configure_registry_item_full_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func)(E_Container * con, const char *params), void (*generic_func)(E_Container *con, const char *params), Efreet_Desktop *desktop, const char *params);
+static void      _e_configure_registry_item_free(E_Configure_It *eci);
+
+static void      _configure_job(void *data);
+static Eina_Bool _configure_init_timer(void *data);
+
+EAPI Eina_List *e_configure_registry = NULL;
+
+static Eina_List *handlers = NULL;
+static E_Int_Menu_Augmentation *maug = NULL;
+static Ecore_Job *update_job = NULL;
+
+static struct
+{
+   void        (*func)(const void *data, E_Container *con, const char *params, Efreet_Desktop *desktop);
+   const char *data;
+} custom_desktop_exec = { NULL, NULL };
+
+EINTERN void
+e_configure_init(void)
+{
+   e_configure_registry_category_add("extensions", 90, _("Extensions"), NULL, "preferences-extensions");
+   /* e_configure_registry_item_add("extensions/modules", 10, _("Modules"), NULL, "preferences-plugin", e_int_config_modules); */
+
+   maug = e_int_menus_menu_augmentation_add_sorted
+       ("config/1", _("Modules"), _e_configure_menu_add, NULL, NULL, NULL);
+
+   if (update_job)
+     {
+        ecore_job_del(update_job);
+        update_job = NULL;
+     }
+   ecore_timer_add(0.0, _configure_init_timer, NULL);
+}
+
+EAPI void
+e_configure_registry_call(const char *path, E_Container *con, const char *params)
+{
+   E_Configure_Cat *ecat;
+   Eina_List *l;
+   char *cat;
+   const char *item;
+
+   /* path is "category/item" */
+   cat = ecore_file_dir_get(path);
+   if (!cat) return;
+   item = ecore_file_file_get(path);
+   if (!con) con = e_container_current_get(e_manager_current_get());
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     if (!strcmp(cat, ecat->cat))
+       {
+          E_Configure_It *eci;
+          Eina_List *ll;
+
+          EINA_LIST_FOREACH(ecat->items, ll, eci)
+            if (!strcmp(item, eci->item))
+              {
+                 if (!params) params = eci->params;
+
+                 if (eci->func) eci->func(con, params);
+                 else if (eci->generic_func)
+                   eci->generic_func(con, params);
+                 else if (eci->desktop)
+                   {
+                      if (custom_desktop_exec.func)
+                        custom_desktop_exec.func(custom_desktop_exec.data,
+                                                 con, params, eci->desktop);
+                      else
+                        e_exec(e_util_zone_current_get(con->man),
+                               eci->desktop, NULL, NULL, "config");
+                   }
+                 break;
+              }
+          break;
+       }
+   free(cat);
+}
+
+EAPI void
+e_configure_registry_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func)(E_Container * con, const char *params))
+{
+   _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, func, NULL, NULL, NULL);
+}
+
+EAPI void
+e_configure_registry_generic_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, void (*generic_func)(E_Container *con, const char *params))
+{
+   _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, NULL, generic_func, NULL, NULL);
+}
+
+EAPI void
+e_configure_registry_item_params_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func)(E_Container * con, const char *params), const char *params)
+{
+   _e_configure_registry_item_full_add(path, pri, label, icon_file, icon, func, NULL, NULL, params);
+}
+
+/**
+ * Delete an item  in the configuration panel.
+ *
+ * @param path location the item to delete
+ */
+EAPI void
+e_configure_registry_item_del(const char *path)
+{
+   E_Configure_Cat *ecat;
+   Eina_List *l;
+   const char *item;
+   char *cat;
+
+   /* path is "category/item" */
+   cat = ecore_file_dir_get(path);
+   if (!cat) return;
+   item = ecore_file_file_get(path);
+
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     if (!strcmp(cat, ecat->cat))
+       {
+          E_Configure_It *eci;
+          Eina_List *ll;
+
+          EINA_LIST_FOREACH(ecat->items, ll, eci)
+            if (!strcmp(item, eci->item))
+              {
+                 ecat->items = eina_list_remove_list(ecat->items, ll);
+
+                 _e_configure_registry_item_free(eci);
+                 break;
+              }
+          break;
+       }
+   free(cat);
+}
+
+/**
+ * Add a category to the configuration panel.
+ *
+ * @param path location the new category
+ * @param pri the priority for sorting the category in the category list
+ * @param label the name the user will see in configuration panel
+ * @param icon_file the edje file that holds the icon for the category.
+ * Can be null to use current theme.
+ * @param icon the name of the edje group to use as icon
+ */
+static int
+_E_configure_category_pri_cb(E_Configure_Cat *ecat, E_Configure_Cat *ecat2)
+{
+   if (ecat->pri == ecat2->pri)
+     return strcmp(ecat->label, ecat2->label);
+   return ecat->pri - ecat2->pri;
+}
+
+EAPI void
+e_configure_registry_category_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon)
+{
+   E_Configure_Cat *ecat2;
+   E_Configure_Cat *ecat;
+   Eina_List *l;
+
+   /* if it exists - ignore this */
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat2)
+     if (!strcmp(ecat2->cat, path)) return;
+
+   ecat = E_NEW(E_Configure_Cat, 1);
+   if (!ecat) return;
+
+   ecat->cat = eina_stringshare_add(path);
+   ecat->pri = pri;
+   ecat->label = eina_stringshare_add(label);
+   if (icon_file) ecat->icon_file = eina_stringshare_add(icon_file);
+   if (icon) ecat->icon = eina_stringshare_add(icon);
+   e_configure_registry = eina_list_sorted_insert(e_configure_registry,
+                                                  EINA_COMPARE_CB(_E_configure_category_pri_cb),
+                                                  ecat);
+}
+
+/**
+ * Delete a category in the configuration panel.
+ *
+ * @param path location the category to delete
+ */
+EAPI void
+e_configure_registry_category_del(const char *path)
+{
+   E_Configure_Cat *ecat;
+   Eina_List *l;
+   char *cat;
+
+   cat = ecore_file_dir_get(path);
+   if (!cat) return;
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     if (!strcmp(cat, ecat->cat))
+       {
+          if (ecat->items) break;
+          e_configure_registry = eina_list_remove_list(e_configure_registry, l);
+          eina_stringshare_del(ecat->cat);
+          eina_stringshare_del(ecat->label);
+          if (ecat->icon) eina_stringshare_del(ecat->icon);
+          if (ecat->icon_file) eina_stringshare_del(ecat->icon_file);
+          free(ecat);
+          break;
+       }
+   free(cat);
+}
+
+/**
+ * Add a item to the configuration panel.
+ *
+ * @param path location the location to place configuration item
+ * @param pri the priority for sorting the item in the category list
+ * @param label the name the user will see in configuration panel
+ * @param icon_file the edje file that holds the icon for the category.
+ * Can be null to use current theme.
+ * @param icon the name of the edje group to use as icon
+ * @param func the callback to use when the configuration item is clicked
+ */
+
+EAPI void
+e_configure_registry_custom_desktop_exec_callback_set(void (*func)(const void *data, E_Container *con, const char *params, Efreet_Desktop *desktop), const void *data)
+{
+   custom_desktop_exec.func = func;
+   custom_desktop_exec.data = data;
+}
+
+EAPI int
+e_configure_registry_exists(const char *path)
+{
+   E_Configure_Cat *ecat;
+   Eina_List *l;
+   char *cat;
+   const char *item;
+   int ret = 0;
+
+   /* path is "category/item" */
+   cat = ecore_file_dir_get(path);
+   if (!cat) return 0;
+   item = ecore_file_file_get(path);
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     if (!strcmp(cat, ecat->cat))
+       {
+          E_Configure_It *eci;
+          Eina_List *ll;
+
+          if (!item)
+            {
+               ret = 1;
+               break;
+            }
+          EINA_LIST_FOREACH(ecat->items, ll, eci)
+            if (!strcmp(item, eci->item))
+              {
+                 ret = 1;
+                 break;
+              }
+          break;
+       }
+
+   free(cat);
+   return ret;
+}
+
+static void
+_e_configure_menu_module_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
+{
+   /* e_int_config_modules(m->zone->container, NULL); */
+}
+
+static void
+_e_configure_menu_add(void *data __UNUSED__, E_Menu *m)
+{
+   E_Menu_Item *mi;
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Modules"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-plugin");
+   e_menu_item_callback_set(mi, _e_configure_menu_module_item_cb, NULL);
+}
+
+static void
+_configure_job(void *data __UNUSED__)
+{
+   _e_configure_efreet_desktop_update();
+   update_job = NULL;
+}
+
+static Eina_Bool
+_configure_init_timer(void *data __UNUSED__)
+{
+   handlers = eina_list_append
+       (handlers, ecore_event_handler_add
+         (EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_configure_cb_efreet_desktop_cache_update, NULL));
+   if (update_job) ecore_job_del(update_job);
+   update_job = ecore_job_add(_configure_job, NULL);
+   return EINA_FALSE;
+}
+
+static void
+_e_configure_efreet_desktop_cleanup(void)
+{
+   Eina_List *l;
+   E_Configure_Cat *ecat;
+
+//   printf("_e_configure_efreet_desktop_cleanup\n");
+/* remove anything with a desktop entry */
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     {
+        E_Configure_It *eci;
+        Eina_List *ll, *ln;
+
+        EINA_LIST_FOREACH_SAFE(ecat->items, ll, ln, eci)
+          if (eci->desktop)
+            {
+               _e_configure_registry_item_free(eci);
+               ecat->items = eina_list_remove_list(ecat->items, ll);
+            }
+     }
+}
+
+static void
+_e_configure_efreet_desktop_update(void)
+{
+   Eina_List *settings_desktops, *system_desktops;
+   Efreet_Desktop *desktop;
+   Eina_List *l;
+   char buf[1024];
+
+   /* get desktops */
+   settings_desktops = efreet_util_desktop_category_list("Settings");
+   system_desktops = efreet_util_desktop_category_list("System");
+   if ((!settings_desktops) || (!system_desktops))
+     {
+        EINA_LIST_FREE(settings_desktops, desktop)
+          efreet_desktop_free(desktop);
+        EINA_LIST_FREE(system_desktops, desktop)
+          efreet_desktop_free(desktop);
+        return;
+     }
+
+   /* get ones in BOTH lists */
+   EINA_LIST_FOREACH(settings_desktops, l, desktop)
+     {
+        char *s;
+        char *cfg_cat_name;
+        const char *cfg_cat_icon;
+        char *cfg_cat;
+        char *cfg_cat_cfg;
+        const char *cfg_icon;
+        char *label;
+        int cfg_pri;
+        int dopref;
+
+        dopref = 0;
+        cfg_cat = NULL;
+        cfg_icon = NULL;
+        cfg_cat_cfg = NULL;
+        cfg_pri = 1000;
+        cfg_cat_name = NULL;
+        cfg_cat_icon = NULL;
+        label = NULL;
+        if (!eina_list_data_find(system_desktops, desktop))
+          {
+             /* settings desktop but not in system -> put in preferences */
+             dopref = 1;
+          }
+        if (desktop->x)
+          {
+             cfg_cat_cfg = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category");
+             s = eina_hash_find(desktop->x, "X-Enlightenment-Config-Priority");
+             if (s) cfg_pri = atoi(s);
+             cfg_cat_name = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Name");
+             cfg_cat_icon = eina_hash_find(desktop->x, "X-Enlightenment-Config-Category-Icon");
+             if ((cfg_cat_icon) && (cfg_cat_icon[0] != '/'))
+               cfg_cat_icon = efreet_icon_path_find(e_config->icon_theme,
+                                                    cfg_cat_icon, 64);
+          }
+        if (desktop->icon)
+          {
+             if (desktop->icon[0] == '/')
+               cfg_icon = desktop->icon;
+             else
+               cfg_icon = efreet_icon_path_find(e_config->icon_theme,
+                                                desktop->icon, 64);
+          }
+        if (desktop->name) label = desktop->name;
+        else if (desktop->generic_name)
+          label = desktop->generic_name;
+        else label = "???";
+        if (!cfg_cat_cfg)
+          {
+             const char *ic = cfg_cat_icon;
+
+             if (dopref)
+               {
+                  snprintf(buf, sizeof(buf), "preferences/%s", label);
+                  if (!ic) ic = "preferences-preferences";
+                  e_configure_registry_category_add("preferences", 900,
+                                                    _("Preferences"),
+                                                    NULL, ic);
+               }
+             else
+               {
+                  snprintf(buf, sizeof(buf), "system/%s", label);
+                  if (!ic) ic = "preferences-system";
+                  e_configure_registry_category_add("system", 1000,
+                                                    _("System"),
+                                                    NULL, ic);
+               }
+             cfg_cat_cfg = buf;
+          }
+        else
+          {
+             cfg_cat = ecore_file_dir_get(cfg_cat_cfg);
+             if (!cfg_cat) cfg_cat = strdup(cfg_cat_cfg);
+             if (cfg_cat)
+               {
+                  if (!cfg_cat_name) cfg_cat_name = cfg_cat;
+                  e_configure_registry_category_add(cfg_cat,
+                                                    1000, cfg_cat_name,
+                                                    NULL, cfg_cat_icon);
+                  free(cfg_cat);
+                  cfg_cat = NULL;
+               }
+          }
+        _e_configure_registry_item_full_add(cfg_cat_cfg, cfg_pri, label,
+                                            NULL, cfg_icon,
+                                            NULL, NULL, desktop, NULL);
+     }
+   EINA_LIST_FREE(settings_desktops, desktop)
+     efreet_desktop_free(desktop);
+   EINA_LIST_FREE(system_desktops, desktop)
+     efreet_desktop_free(desktop);
+}
+
+static Eina_Bool
+_e_configure_cb_efreet_desktop_cache_update(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+{
+   _e_configure_efreet_desktop_cleanup();
+   if (update_job) ecore_job_del(update_job);
+   update_job = ecore_job_add(_configure_job, NULL);
+   return 1;
+}
+
+static int
+_e_configure_compare_cb(E_Configure_It *eci, E_Configure_It *eci2)
+{
+   return e_util_strcasecmp(eci->label, eci2->label);
+}
+
+static int
+_e_configure_compare_pri_cb(E_Configure_It *eci, E_Configure_It *eci2)
+{
+   if (eci->pri == eci2->pri)
+     return strcmp(eci->label, eci2->label);
+   return eci->pri - eci2->pri;
+}
+
+static void
+_e_configure_registry_item_full_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func)(E_Container * con, const char *params), void (*generic_func)(E_Container *con, const char *params), Efreet_Desktop *desktop, const char *params)
+{
+   Eina_List *l;
+   char *cat;
+   const char *item;
+   E_Configure_It *eci;
+   E_Configure_Cat *ecat;
+   Eina_Bool external;
+
+   EINA_SAFETY_ON_NULL_RETURN(path);
+   EINA_SAFETY_ON_NULL_RETURN(label);
+   /* path is "category/item" */
+   cat = ecore_file_dir_get(path);
+   if (!cat) return;
+
+   EINA_LIST_FOREACH(e_configure_registry, l, ecat)
+     {
+        if (strcmp(cat, ecat->cat)) continue;
+        item = ecore_file_file_get(path);
+        eci = E_NEW(E_Configure_It, 1);
+
+        eci->item = eina_stringshare_add(item);
+        eci->pri = pri;
+        eci->label = eina_stringshare_add(label);
+        if (icon_file) eci->icon_file = eina_stringshare_add(icon_file);
+        if (icon) eci->icon = eina_stringshare_add(icon);
+        if (params) eci->params = eina_stringshare_add(params);
+        eci->func = func;
+        eci->generic_func = generic_func;
+        eci->desktop = desktop;
+        if (eci->desktop) efreet_desktop_ref(eci->desktop);
+        external = !strncmp(path, "preferences/", sizeof("preferences/") - 1);
+        if (!external) external = !strncmp(path, "system/", sizeof("system/") - 1);
+        if (external)
+          ecat->items = eina_list_sorted_insert(ecat->items, EINA_COMPARE_CB(_e_configure_compare_cb), eci);
+        else
+          ecat->items = eina_list_sorted_insert(ecat->items, EINA_COMPARE_CB(_e_configure_compare_pri_cb), eci);
+        break;
+     }
+   free(cat);
+}
+
+static void
+_e_configure_registry_item_free(E_Configure_It *eci)
+{
+   eina_stringshare_del(eci->item);
+   eina_stringshare_del(eci->label);
+   eina_stringshare_del(eci->icon);
+   if (eci->icon_file) eina_stringshare_del(eci->icon_file);
+   if (eci->desktop) efreet_desktop_free(eci->desktop);
+   if (eci->params) eina_stringshare_del(eci->params);
+   free(eci);
+}
+
diff --git a/src/bin/e_wayland/e_configure.h b/src/bin/e_wayland/e_configure.h
new file mode 100644 (file)
index 0000000..4e5466e
--- /dev/null
@@ -0,0 +1,47 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Configure_Cat E_Configure_Cat;
+typedef struct _E_Configure_It E_Configure_It;
+
+#else
+#ifndef E_CONFIGURE_H
+#define E_CONFIGURE_H
+
+struct _E_Configure_Cat
+{
+   const char *cat;
+   int         pri;
+   const char *label;
+   const char *icon_file;
+   const char *icon;
+   Eina_List  *items;
+};
+
+struct _E_Configure_It
+{
+   const char        *item;
+   int                pri;
+   const char        *label;
+   const char        *icon_file;
+   const char        *icon;
+   const char        *params;
+   E_Config_Dialog *(*func) (E_Container *con, const char *params);
+   void             (*generic_func) (E_Container *con, const char *params);
+   Efreet_Desktop    *desktop;
+};
+
+EAPI void e_configure_registry_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params));
+EAPI void e_configure_registry_item_params_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, E_Config_Dialog *(*func) (E_Container *con, const char *params), const char *params);
+EAPI void e_configure_registry_generic_item_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon, void (*generic_func) (E_Container *con, const char *params));
+EAPI void e_configure_registry_item_del(const char *path);
+EAPI void e_configure_registry_category_add(const char *path, int pri, const char *label, const char *icon_file, const char *icon);
+EAPI void e_configure_registry_category_del(const char *path);
+EAPI void e_configure_registry_call(const char *path, E_Container *con, const char *params);
+EAPI int  e_configure_registry_exists(const char *path);
+EAPI void e_configure_registry_custom_desktop_exec_callback_set(void (*func) (const void *data, E_Container *con, const char *params, Efreet_Desktop *desktop), const void *data);
+EINTERN void e_configure_init(void);
+
+extern EAPI Eina_List *e_configure_registry;
+
+#endif
+#endif
index 9f85c9f7db7aaf95fb1d0e7c807ad21d2fed24b2..b44c01f07704ae258075da2b8727a7a8e4cc9b08 100644 (file)
@@ -3,6 +3,7 @@
 /* local function prototypes */
 static void _e_container_cb_free(E_Container *con);
 static Eina_Bool _e_container_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
+static E_Container *_e_container_find_by_event_window(unsigned int win);
 
 /* local variables */
 static Eina_List *_hdlrs = NULL;
@@ -28,7 +29,10 @@ EAPI E_Container *
 e_container_new(E_Manager *man)
 {
    E_Container *con;
-   static unsigned int num = 0;
+   E_Output *output;
+   Eina_List *l;
+   static unsigned int con_num = 0;
+   int num = 0;
 
    /* check for valid manager */
    E_OBJECT_CHECK_RETURN(man, NULL);
@@ -45,8 +49,8 @@ e_container_new(E_Manager *man)
    con->y = man->y;
    con->w = man->w;
    con->h = man->h;
-   con->num = num;
-   num++;
+   con->num = con_num;
+   con_num++;
 
    /* add this container to the managers list */
    man->containers = eina_list_append(man->containers, con);
@@ -67,16 +71,21 @@ e_container_new(E_Manager *man)
    /* get the background canvas */
    con->bg_evas = ecore_evas_get(con->bg_ee);
 
-   Evas_Object *o;
-   o = evas_object_rectangle_add(con->bg_evas);
-   evas_object_color_set(o, 255, 0, 0, 255);
-   evas_object_move(o, 0, 0);
-   evas_object_resize(o, con->w, con->h);
-   evas_object_show(o);
-   ecore_evas_object_associate(con->bg_ee, o, 
-                               ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
+   con->o_blank = evas_object_rectangle_add(con->bg_evas);
+   evas_object_layer_set(con->o_blank, -100);
+   evas_object_move(con->o_blank, con->x, con->y);
+   evas_object_resize(con->o_blank, con->w, con->h);
+   evas_object_color_set(con->o_blank, 255, 0, 0, 255);
+   evas_object_name_set(con->o_blank, "e/desktop/background");
+   evas_object_data_set(con->o_blank, "e_container", con);
+   evas_object_show(con->o_blank);
 
-   /* TODO: create zones */
+   EINA_LIST_FOREACH(_e_comp->outputs, l, output)
+     {
+        e_zone_new(con, num, output->x, output->y, 
+                   output->current->w, output->current->h);
+        num++;
+     }
 
    return con;
 }
@@ -84,6 +93,9 @@ e_container_new(E_Manager *man)
 EAPI void 
 e_container_show(E_Container *con)
 {
+   E_Zone *zone;
+   Eina_List *l;
+
    /* check for valid container */
    E_OBJECT_CHECK(con);
    E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
@@ -94,7 +106,9 @@ e_container_show(E_Container *con)
    /* show the ecore_evas */
    ecore_evas_show(con->bg_ee);
 
-   /* TODO: show zones */
+   /* show zones */
+   EINA_LIST_FOREACH(con->zones, l, zone)
+     e_zone_show(zone);
 
    /* check for valid pointer */
    if (!con->ptr)
@@ -109,6 +123,9 @@ e_container_show(E_Container *con)
 EAPI void 
 e_container_hide(E_Container *con)
 {
+   E_Zone *zone;
+   Eina_List *l;
+
    /* check for valid container */
    E_OBJECT_CHECK(con);
    E_OBJECT_TYPE_CHECK(con, E_CONTAINER_TYPE);
@@ -116,7 +133,9 @@ e_container_hide(E_Container *con)
    /* check for already invisible */
    if (!con->visible) return;
 
-   /* TODO: hide zones */
+   /* hide zones */
+   EINA_LIST_FOREACH(con->zones, l, zone)
+     e_zone_hide(zone);
 
    /* hide the ecore_evas */
    ecore_evas_hide(con->bg_ee);
@@ -162,6 +181,57 @@ e_container_all_thaw(void)
      }
 }
 
+EAPI E_Container *
+e_container_current_get(E_Manager *man)
+{
+   Eina_List *l;
+   E_Container *con;
+
+   E_OBJECT_CHECK_RETURN(man, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
+
+   EINA_LIST_FOREACH(man->containers, l, con)
+     {
+        if (!con) continue;
+        if (con->visible) return con;
+     }
+
+   if (!man->containers) return NULL;
+   l = man->containers;
+
+   return (E_Container *)eina_list_data_get(l);
+}
+
+EAPI E_Container *
+e_container_number_get(E_Manager *man, int num)
+{
+   Eina_List *l;
+   E_Container *con;
+
+   E_OBJECT_CHECK_RETURN(man, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
+
+   EINA_LIST_FOREACH(man->containers, l, con)
+     if ((int)con->num == num) return con;
+
+   return NULL;
+}
+
+EAPI E_Zone *
+e_container_zone_number_get(E_Container *con, int num)
+{
+   Eina_List *l;
+   E_Zone *zone;
+
+   E_OBJECT_CHECK_RETURN(con, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
+
+   EINA_LIST_FOREACH(con->zones, l, zone)
+     if (((int)zone->num == num)) return zone;
+
+   return NULL;
+}
+
 /* local functions */
 static void 
 _e_container_cb_free(E_Container *con)
@@ -191,10 +261,38 @@ static Eina_Bool
 _e_container_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
 {
    Ecore_Wl_Event_Mouse_In *ev;
+   E_Container *con;
 
    ev = event;
 
-   /* TODO: code me */
+   if (!(con = _e_container_find_by_event_window(ev->window)))
+     return ECORE_CALLBACK_PASS_ON;
+
+   if (con->ptr)
+     {
+        E_Pointer *ptr;
+        struct wl_surface *surf;
+
+        ptr = con->ptr;
+        surf = ecore_wl_window_surface_get(ptr->win);
+        ecore_wl_window_pointer_set(ptr->win, surf, ptr->hot.x, ptr->hot.y);
+     }
 
    return ECORE_CALLBACK_PASS_ON;
 }
+
+static E_Container *
+_e_container_find_by_event_window(unsigned int win)
+{
+   Eina_List *l, *ll;
+   E_Manager *man;
+   E_Container *con;
+
+   EINA_LIST_FOREACH(e_manager_list(), l, man)
+     {
+        EINA_LIST_FOREACH(man->containers, ll, con)
+          if (con->win->id == (int)win) return con;
+     }
+
+   return NULL;
+}
index 392295b4650bca6609460ed2f0f0b5324bdad485..c13c5a121cb13a35ed832f06f3916e2a38adf8f3 100644 (file)
@@ -18,8 +18,11 @@ struct _E_Container
 
    Ecore_Wl_Window *win;
    E_Manager *man;
+
    Ecore_Evas *bg_ee;
    Evas *bg_evas;
+   Evas_Object *o_blank;
+
    E_Pointer *ptr;
 
    Eina_List *zones;
@@ -33,6 +36,9 @@ EAPI void e_container_show(E_Container *con);
 EAPI void e_container_hide(E_Container *con);
 EAPI void e_container_all_freeze(void);
 EAPI void e_container_all_thaw(void);
+EAPI E_Container *e_container_current_get(E_Manager *man);
+EAPI E_Container *e_container_number_get(E_Manager *man, int num);
+EAPI E_Zone *e_container_zone_number_get(E_Container *con, int num);
 
 # endif
 #endif
diff --git a/src/bin/e_wayland/e_desk.c b/src/bin/e_wayland/e_desk.c
new file mode 100644 (file)
index 0000000..8bc0401
--- /dev/null
@@ -0,0 +1,93 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_desk_cb_free(E_Desk *desk);
+
+EINTERN int 
+e_desk_init(void)
+{
+   return 1;
+}
+
+EINTERN int 
+e_desk_shutdown(void)
+{
+   return 1;
+}
+
+EAPI E_Desk *
+e_desk_new(E_Zone *zone, int x, int y)
+{
+   E_Desk *desk;
+
+   E_OBJECT_CHECK_RETURN(zone, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
+
+   desk = E_OBJECT_ALLOC(E_Desk, E_DESK_TYPE, _e_desk_cb_free);
+   if (!desk)
+     {
+        printf("FAILED TO ALLOCATE DESK\n");
+        return NULL;
+     }
+
+   printf("Created New Desktop: %d %d\n", x, y);
+
+   desk->zone = zone;
+   desk->x = x;
+   desk->y = y;
+
+   return desk;
+}
+
+EAPI void 
+e_desk_show(E_Desk *desk)
+{
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   if (desk->visible) return;
+
+   desk->visible = EINA_TRUE;
+   e_bg_zone_update(desk->zone, E_BG_TRANSITION_START);
+}
+
+EAPI void 
+e_desk_hide(E_Desk *desk)
+{
+   E_OBJECT_CHECK(desk);
+   E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
+
+   if (!desk->visible) return;
+
+   desk->visible = EINA_FALSE;
+}
+
+EAPI E_Desk *
+e_desk_current_get(E_Zone *zone)
+{
+   E_OBJECT_CHECK_RETURN(zone, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
+
+   return e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current);
+}
+
+EAPI E_Desk *
+e_desk_at_xy_get(E_Zone *zone, int x, int  y)
+{
+   E_OBJECT_CHECK_RETURN(zone, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
+
+   if ((x >= zone->desk_x_count) || (y >= zone->desk_y_count))
+     return NULL;
+   else if ((x < 0) || (y < 0))
+     return NULL;
+
+   return zone->desks[x + (y * zone->desk_x_count)];
+}
+
+/* local functions */
+static void 
+_e_desk_cb_free(E_Desk *desk)
+{
+   free(desk);
+}
diff --git a/src/bin/e_wayland/e_desk.h b/src/bin/e_wayland/e_desk.h
new file mode 100644 (file)
index 0000000..94666f8
--- /dev/null
@@ -0,0 +1,40 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Desk E_Desk;
+typedef struct _E_Event_Desk_Show E_Event_Desk_Show;
+
+#else
+# ifndef E_DESK_H
+#  define E_DESK_H
+
+#  define E_DESK_TYPE 0xE0b01005
+
+struct _E_Desk
+{
+   E_Object e_obj_inherit;
+
+   E_Zone *zone;
+   int x, y;
+   const char *name;
+   Eina_Bool visible : 1;
+   Evas_Object *o_bg;
+};
+
+struct _E_Event_Desk_Show
+{
+   E_Desk   *desk;
+};
+
+extern EAPI int E_EVENT_DESK_SHOW;
+
+EINTERN int e_desk_init(void);
+EINTERN int e_desk_shutdown(void);
+
+EAPI E_Desk *e_desk_new(E_Zone *zone, int x, int y);
+EAPI void e_desk_show(E_Desk *desk);
+EAPI void e_desk_hide(E_Desk *desk);
+EAPI E_Desk *e_desk_current_get(E_Zone *zone);
+EAPI E_Desk *e_desk_at_xy_get(E_Zone *zone, int x, int  y);
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_dialog.c b/src/bin/e_wayland/e_dialog.c
new file mode 100644 (file)
index 0000000..c40473c
--- /dev/null
@@ -0,0 +1,219 @@
+#include "e.h"
+
+/* local function prototypes */
+static E_Dialog *_e_dialog_internal_new(E_Container *con, const char *name, const char *class, Eina_Bool dialog);
+static void _e_dialog_cb_free(E_Dialog *dia);
+
+EAPI E_Dialog *
+e_dialog_new(E_Container *con, const char *name, const char *class)
+{
+   return _e_dialog_internal_new(con, name, class, EINA_TRUE);
+}
+
+EAPI E_Dialog *
+e_dialog_normal_win_new(E_Container *con, const char *name, const char *class)
+{
+   return _e_dialog_internal_new(con, name, class, EINA_FALSE);
+}
+
+EAPI void 
+e_dialog_button_add(E_Dialog *dia, const char *label, const char *icon, void (*func) (void *data, E_Dialog *dia), void *data)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   /* Evas_Object *o; */
+
+   /* if (!func) func = _e_dialog_cb_delete; */
+   /* TODO: e_widgets */
+}
+
+EAPI int 
+e_dialog_button_focus_num(E_Dialog *dia, int button)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   return 0;
+}
+
+EAPI int 
+e_dialog_button_disable_num_set(E_Dialog *dia, int button, int disabled)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   return 0;
+}
+
+EAPI int 
+e_dialog_button_disable_num_get(E_Dialog *dia, int button)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   return 0;
+}
+
+EAPI void 
+e_dialog_title_set(E_Dialog *dia, const char *title)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   e_win_title_set(dia->win, title);
+}
+
+EAPI void 
+e_dialog_text_set(E_Dialog *dia, const char *text)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   if (!dia->o_text)
+     {
+        dia->o_text = edje_object_add(dia->win->evas);
+        e_theme_edje_object_set(dia->o_text, "base/theme/dialog", 
+                                "e/widgets/dialog/text");
+        edje_object_part_swallow(dia->o_bg, "e.swallow.content", dia->o_text);
+        evas_object_show(dia->o_text);
+     }
+   edje_object_part_text_set(dia->o_text, "e.textblock.message", text);
+}
+
+EAPI void 
+e_dialog_icon_set(E_Dialog *dia, const char *icon, Evas_Coord size)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   /* TODO: e_icon */
+}
+
+EAPI void 
+e_dialog_border_icon_set(E_Dialog *dia, const char *icon)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+}
+
+EAPI void 
+e_dialog_content_set(E_Dialog *dia, Evas_Object *obj, Evas_Coord minw, Evas_Coord minh)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   dia->o_content = obj;
+   /* TODO: e_widget on focus_hook */
+   edje_extern_object_min_size_set(obj, minw, minh);
+   edje_object_part_swallow(dia->o_bg, "e.swallow.content", obj);
+   evas_object_show(obj);
+}
+
+EAPI void 
+e_dialog_resizable_set(E_Dialog *dia, int resizable)
+{
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   dia->resizable = resizable;
+   if (dia->win)
+     {
+        /* TODO: Finish */
+        /* if (resizable)  */
+        /*   { */
+        /*   } */
+        /* else */
+        /*   { */
+        /*   } */
+     }
+}
+
+EAPI void 
+e_dialog_show(E_Dialog *dia)
+{
+   Evas_Coord mw, mh;
+
+   E_OBJECT_CHECK(dia);
+   E_OBJECT_TYPE_CHECK(dia, E_DIALOG_TYPE);
+
+   if (dia->o_text)
+     {
+        edje_object_size_min_calc(dia->o_text, &mw, &mh);
+        edje_extern_object_min_size_set(dia->o_text, mw, mh);
+        edje_object_part_swallow(dia->o_bg, "e.swallow.content", dia->o_text);
+     }
+
+   /* TODO: e_widget_size_min_get */
+
+   e_win_show(dia->win);
+}
+
+/* local functions */
+static E_Dialog *
+_e_dialog_internal_new(E_Container *con, const char *name, const char *class, Eina_Bool dialog)
+{
+   E_Dialog *dia;
+
+   if (!con)
+     {
+        E_Manager *man;
+
+        if (!(man = e_manager_current_get())) return NULL;
+        if (!(con = e_container_current_get(man)))
+          con = e_container_number_get(man, 0);
+        if (!con) return NULL;
+     }
+
+   dia = E_OBJECT_ALLOC(E_Dialog, E_DIALOG_TYPE, _e_dialog_cb_free);
+   if (!dia) return NULL;
+
+   if (!(dia->win = e_win_new(con)))
+     {
+        free(dia);
+        return NULL;
+     }
+
+   /* TODO: e_win callbacks */
+   dia->win->data = dia;
+
+   e_win_dialog_set(dia->win, dialog);
+   e_win_name_class_set(dia->win, name, class);
+
+   dia->o_bg = edje_object_add(dia->win->evas);
+   e_theme_edje_object_set(dia->o_bg, "base/theme/dialog", 
+                           "e/widgets/dialog/main");
+   evas_object_move(dia->o_bg, 0, 0);
+   evas_object_show(dia->o_bg);
+
+   /* TODO: box object & event object */
+
+   return dia;
+}
+
+static void 
+_e_dialog_cb_free(E_Dialog *dia)
+{
+   if (dia->buttons)
+     {
+        E_FREE_LIST(dia->buttons, evas_object_del);
+        /* Eina_List *l; */
+        /* Evas_Object *o; */
+
+        /* EINA_LIST_FOREACH(dia->buttons, l, o) */
+        /*   evas_object_del(o); */
+
+        /* eina_list_free(dia->buttons); */
+     }
+
+   if (dia->o_text) evas_object_del(dia->o_text);
+   if (dia->o_icon) evas_object_del(dia->o_icon);
+   if (dia->o_box) evas_object_del(dia->o_box);
+   if (dia->o_bg) evas_object_del(dia->o_bg);
+   if (dia->o_content) evas_object_del(dia->o_content);
+   if (dia->o_event) evas_object_del(dia->o_event);
+
+   e_object_del(E_OBJECT(dia->win));
+   free(dia);
+}
diff --git a/src/bin/e_wayland/e_dialog.h b/src/bin/e_wayland/e_dialog.h
new file mode 100644 (file)
index 0000000..da7b218
--- /dev/null
@@ -0,0 +1,40 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Dialog E_Dialog;
+
+#else
+# ifndef E_DIALOG_H
+#  define E_DIALOG_H
+
+#  define E_DIALOG_TYPE 0xE0b01012
+
+struct _E_Dialog
+{
+   E_Object e_obj_inherit;
+
+   E_Win *win;
+   Evas_Object *o_bg, *o_box;
+   Evas_Object *o_text, *o_content;
+   Evas_Object *o_icon, *o_event;
+   Eina_List *buttons;
+   void *data;
+   int min_w, min_h;
+   Eina_Bool resizable : 1;
+};
+
+EAPI E_Dialog *e_dialog_new(E_Container *con, const char *name, const char *class);
+EAPI E_Dialog *e_dialog_normal_win_new(E_Container *con, const char *name, const char *class);
+EAPI void e_dialog_button_add(E_Dialog *dia, const char *label, const char *icon, void (*func) (void *data, E_Dialog *dia), void *data);
+EAPI int e_dialog_button_focus_num(E_Dialog *dia, int button);
+EAPI int e_dialog_button_disable_num_set(E_Dialog *dia, int button, int disabled);
+EAPI int e_dialog_button_disable_num_get(E_Dialog *dia, int button);
+EAPI void e_dialog_title_set(E_Dialog *dia, const char *title);
+EAPI void e_dialog_text_set(E_Dialog *dia, const char *text);
+EAPI void e_dialog_icon_set(E_Dialog *dia, const char *icon, Evas_Coord size);
+EAPI void e_dialog_border_icon_set(E_Dialog *dia, const char *icon);
+EAPI void e_dialog_content_set(E_Dialog *dia, Evas_Object *obj, Evas_Coord minw, Evas_Coord minh);
+EAPI void e_dialog_resizable_set(E_Dialog *dia, int resizable);
+EAPI void e_dialog_show(E_Dialog *dia);
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_exec.c b/src/bin/e_wayland/e_exec.c
new file mode 100644 (file)
index 0000000..f5a4dc0
--- /dev/null
@@ -0,0 +1,64 @@
+#include "e.h"
+
+#define MAX_OUTPUT_CHARACTERS 5000
+
+/* externally accessible functions */
+EINTERN int
+e_exec_init(void)
+{
+   return 1;
+}
+
+EINTERN int
+e_exec_shutdown(void)
+{
+   return 1;
+}
+
+EAPI void
+e_exec_executor_set(E_Exec_Instance *(*func)(void *data, E_Zone * zone, Efreet_Desktop * desktop, const char *exec, Eina_List *files, const char *launch_method), const void *data)
+{
+
+}
+
+EAPI E_Exec_Instance *
+e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Eina_List *files, const char *launch_method)
+{
+   return NULL;
+}
+
+EAPI E_Exec_Instance *
+e_exec_startup_id_pid_instance_find(int id, pid_t pid)
+{
+   return NULL;
+}
+
+EAPI Efreet_Desktop *
+e_exec_startup_id_pid_find(int id, pid_t pid)
+{
+   return NULL;
+}
+
+EAPI E_Exec_Instance *
+e_exec_startup_desktop_instance_find(Efreet_Desktop *desktop)
+{
+   return NULL;
+}
+
+EAPI void
+e_exec_instance_found(E_Exec_Instance *inst)
+{
+
+}
+
+EAPI void
+e_exec_instance_watcher_add(E_Exec_Instance *inst, void (*func)(void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data)
+{
+
+}
+
+EAPI void
+e_exec_instance_watcher_del(E_Exec_Instance *inst, void (*func)(void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data)
+{
+
+}
diff --git a/src/bin/e_wayland/e_exec.h b/src/bin/e_wayland/e_exec.h
new file mode 100644 (file)
index 0000000..2e66aa1
--- /dev/null
@@ -0,0 +1,43 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Exec_Instance E_Exec_Instance;
+
+#else
+#ifndef E_EXEC_H
+#define E_EXEC_H
+
+struct _E_Exec_Instance
+{
+   Efreet_Desktop *desktop;
+   const char     *key;
+   Ecore_Exe      *exe;
+   int             startup_id;
+   double          launch_time;
+   Ecore_Timer    *expire_timer;
+   int             screen;
+   int             desk_x, desk_y;
+   int             used;
+   int             walking;
+   Eina_List      *watchers;
+};
+
+typedef enum
+{
+   E_EXEC_WATCH_STARTED,
+   E_EXEC_WATCH_STOPPED,
+   E_EXEC_WATCH_TIMEOUT
+} E_Exec_Watch_Type;
+
+EINTERN int  e_exec_init(void);
+EINTERN int  e_exec_shutdown(void);
+EAPI void e_exec_executor_set(E_Exec_Instance *(*func) (void *data, E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Eina_List *files, const char *launch_method), const void *data);
+EAPI E_Exec_Instance *e_exec(E_Zone *zone, Efreet_Desktop *desktop, const char *exec, Eina_List *files, const char *launch_method);
+EAPI E_Exec_Instance *e_exec_startup_id_pid_instance_find(int id, pid_t pid);
+EAPI Efreet_Desktop *e_exec_startup_id_pid_find(int startup_id, pid_t pid);
+EAPI E_Exec_Instance *e_exec_startup_desktop_instance_find(Efreet_Desktop *desktop);
+EAPI void e_exec_instance_found(E_Exec_Instance *inst);
+EAPI void e_exec_instance_watcher_add(E_Exec_Instance *inst, void (*func) (void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data);
+EAPI void e_exec_instance_watcher_del(E_Exec_Instance *inst, void (*func) (void *data, E_Exec_Instance *inst, E_Exec_Watch_Type type), const void *data);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_exehist.c b/src/bin/e_wayland/e_exehist.c
new file mode 100644 (file)
index 0000000..7c31782
--- /dev/null
@@ -0,0 +1,539 @@
+#include "e.h"
+#include <libgen.h>
+
+EAPI int E_EVENT_EXEHIST_UPDATE = 0;
+
+/* local subsystem functions */
+typedef struct _E_Exehist      E_Exehist;
+typedef struct _E_Exehist_Item E_Exehist_Item;
+
+struct _E_Exehist
+{
+   Eina_List *history;
+   Eina_List *mimes;
+};
+
+struct _E_Exehist_Item
+{
+   const char  *exe;
+   const char  *normalized_exe;
+   const char  *launch_method;
+   double       exetime;
+   unsigned int count;
+};
+
+static void        _e_exehist_unload_queue(void);
+static void        _e_exehist_load(void);
+static void        _e_exehist_clear(void);
+static void        _e_exehist_unload(void);
+static void        _e_exehist_limit(void);
+static const char *_e_exehist_normalize_exe(const char *exe);
+static void        _e_exehist_cb_unload(void *data);
+static int         _e_exehist_sort_exe_cb(const void *d1, const void *d2);
+static int         _e_exehist_sort_pop_cb(const void *d1, const void *d2);
+
+/* local subsystem globals */
+static E_Config_DD *_e_exehist_config_edd = NULL;
+static E_Config_DD *_e_exehist_config_item_edd = NULL;
+static E_Exehist *_e_exehist = NULL;
+static E_Powersave_Deferred_Action *_e_exehist_unload_defer = NULL;
+static int _e_exehist_changes = 0;
+
+/* externally accessible functions */
+EINTERN int
+e_exehist_init(void)
+{
+   _e_exehist_config_item_edd = E_CONFIG_DD_NEW("E_Exehist_Item", E_Exehist_Item);
+#undef T
+#undef D
+#define T E_Exehist_Item
+#define D _e_exehist_config_item_edd
+   E_CONFIG_VAL(D, T, exe, STR);
+   E_CONFIG_VAL(D, T, normalized_exe, STR);
+   E_CONFIG_VAL(D, T, launch_method, STR);
+   E_CONFIG_VAL(D, T, exetime, DOUBLE);
+
+   _e_exehist_config_edd = E_CONFIG_DD_NEW("E_Exehist", E_Exehist);
+#undef T
+#undef D
+#define T E_Exehist
+#define D _e_exehist_config_edd
+   E_CONFIG_LIST(D, T, history, _e_exehist_config_item_edd);
+   E_CONFIG_LIST(D, T, mimes, _e_exehist_config_item_edd);
+
+   E_EVENT_EXEHIST_UPDATE = ecore_event_type_new();
+
+   return 1;
+}
+
+EINTERN int
+e_exehist_shutdown(void)
+{
+   if (_e_exehist_unload_defer)
+     {
+        e_powersave_deferred_action_del(_e_exehist_unload_defer);
+        _e_exehist_unload_defer = NULL;
+     }
+   _e_exehist_cb_unload(NULL);
+   E_CONFIG_DD_FREE(_e_exehist_config_item_edd);
+   E_CONFIG_DD_FREE(_e_exehist_config_edd);
+   return 1;
+}
+
+EAPI void
+e_exehist_add(const char *launch_method, const char *exe)
+{
+   E_Exehist_Item *ei;
+
+   _e_exehist_load();
+   if (!_e_exehist) return;
+   ei = E_NEW(E_Exehist_Item, 1);
+   if (!ei)
+     {
+        _e_exehist_unload_queue();
+        return;
+     }
+   ei->launch_method = eina_stringshare_add(launch_method);
+   ei->exe = eina_stringshare_add(exe);
+   ei->normalized_exe = _e_exehist_normalize_exe(exe);
+   ei->exetime = ecore_time_unix_get();
+   _e_exehist->history = eina_list_append(_e_exehist->history, ei);
+   _e_exehist_limit();
+   _e_exehist_changes++;
+   ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
+   _e_exehist_unload_queue();
+}
+
+EAPI void
+e_exehist_del(const char *exe)
+{
+   E_Exehist_Item *ei;
+   Eina_List *l;
+   Eina_Bool ok = EINA_FALSE;
+
+   _e_exehist_load();
+   if (!_e_exehist) return;
+   EINA_LIST_FOREACH(_e_exehist->history, l, ei)
+     {
+        if ((ei->exe) && (!strcmp(exe, ei->exe)))
+          {
+             eina_stringshare_del(ei->exe);
+             eina_stringshare_del(ei->normalized_exe);
+             eina_stringshare_del(ei->launch_method);
+             free(ei);
+             _e_exehist->history = eina_list_remove_list(_e_exehist->history,
+                                                         l);
+             _e_exehist_changes++;
+             _e_exehist_unload_queue();
+             ok = EINA_TRUE;
+          }
+     }
+   if (ok)
+     ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
+}
+
+EAPI void
+e_exehist_clear(void)
+{
+   _e_exehist_load();
+   if (!_e_exehist) return;
+   _e_exehist_clear();
+   _e_exehist_changes++;
+   ecore_event_add(E_EVENT_EXEHIST_UPDATE, NULL, NULL, NULL);
+   _e_exehist_unload_queue();
+}
+
+EAPI int
+e_exehist_popularity_get(const char *exe)
+{
+   Eina_List *l;
+   E_Exehist_Item *ei;
+   const char *normal;
+   int count = 0;
+
+   _e_exehist_load();
+   if (!_e_exehist) return 0;
+   normal = _e_exehist_normalize_exe(exe);
+   if (!normal) return 0;
+   EINA_LIST_FOREACH(_e_exehist->history, l, ei)
+     {
+        if ((ei->normalized_exe) && (!strcmp(normal, ei->normalized_exe)))
+          count++;
+     }
+   eina_stringshare_del(normal);
+   _e_exehist_unload_queue();
+   return count;
+}
+
+EAPI double
+e_exehist_newest_run_get(const char *exe)
+{
+   Eina_List *l;
+   E_Exehist_Item *ei;
+   const char *normal;
+
+   _e_exehist_load();
+   if (!_e_exehist) return 0.0;
+   normal = _e_exehist_normalize_exe(exe);
+   if (!normal) return 0.0;
+   EINA_LIST_REVERSE_FOREACH(_e_exehist->history, l, ei)
+     {
+        if ((ei->normalized_exe) && (!strcmp(normal, ei->normalized_exe)))
+          {
+             eina_stringshare_del(normal);
+             _e_exehist_unload_queue();
+             return ei->exetime;
+          }
+     }
+   eina_stringshare_del(normal);
+   _e_exehist_unload_queue();
+   return 0.0;
+}
+
+EAPI Eina_List *
+e_exehist_list_get(void)
+{
+   return e_exehist_sorted_list_get(E_EXEHIST_SORT_BY_DATE, 0);
+}
+
+EAPI Eina_List *
+e_exehist_sorted_list_get(E_Exehist_Sort sort_type, int max)
+{
+   Eina_List *list = NULL, *pop = NULL, *l = NULL, *m;
+   Eina_Iterator *iter;
+   E_Exehist_Item *ei;
+   int count = 1;
+   E_Exehist_Item *prev = NULL;
+
+   if (!max) max = 20;
+   _e_exehist_load();
+   switch (sort_type)
+     {
+      case E_EXEHIST_SORT_BY_EXE:
+      case E_EXEHIST_SORT_BY_POPULARITY:
+        l = eina_list_clone(_e_exehist->history);
+        l = eina_list_sort(l, 0, _e_exehist_sort_exe_cb);
+        iter = eina_list_iterator_new(l);
+        break;
+
+      default:
+        iter = eina_list_iterator_reversed_new(_e_exehist->history);
+        break;
+     }
+   EINA_ITERATOR_FOREACH(iter, ei)
+     {
+        int bad = 0;
+
+        if (!(ei->normalized_exe)) continue;
+        if (sort_type == E_EXEHIST_SORT_BY_POPULARITY)
+          {
+             if (!prev || (strcmp(prev->normalized_exe, ei->normalized_exe)))
+               {
+                  prev = ei;
+                  pop = eina_list_append(pop, ei);
+               }
+             prev->count++;
+          }
+        else
+          {
+             const char *exe;
+
+             EINA_LIST_FOREACH(list, m, exe)
+               {
+                  if (!exe) continue;
+                  if (!strcmp(exe, ei->exe))
+                    {
+                       bad = 1;
+                       break;
+                    }
+               }
+             if (!(bad))
+               {
+                  list = eina_list_append(list, ei->exe);
+                  count++;
+               }
+          }
+        if (count > max) break;
+     }
+   if (sort_type == E_EXEHIST_SORT_BY_POPULARITY)
+     {
+        count = 1;
+        pop = eina_list_sort(pop, 0, _e_exehist_sort_pop_cb);
+        EINA_LIST_FOREACH(pop, l, prev)
+          {
+             list = eina_list_append(list, prev->exe);
+             count++;
+             if (count > max) break;
+          }
+        eina_list_free(pop);
+     }
+   eina_list_free(l);
+   eina_iterator_free(iter);
+   _e_exehist_unload_queue();
+   return list;
+}
+
+EAPI void
+e_exehist_mime_desktop_add(const char *mime, Efreet_Desktop *desktop)
+{
+   const char *f;
+   E_Exehist_Item *ei;
+   Eina_List *l;
+   char buf[PATH_MAX];
+   Efreet_Ini *ini;
+
+   if ((!mime) || (!desktop)) return;
+   if (!desktop->orig_path) return;
+   _e_exehist_load();
+   if (!_e_exehist) return;
+
+   f = efreet_util_path_to_file_id(desktop->orig_path);
+   if (!f) return;
+
+   snprintf(buf, sizeof(buf), "%s/applications/defaults.list",
+            efreet_data_home_get());
+   ini = efreet_ini_new(buf);
+   //fprintf(stderr, "try open %s = %p\n", buf, ini);
+   if (ini)
+     {
+        //fprintf(stderr, "SAVE mime %s with %s\n", mime, desktop->orig_path);
+        if (!efreet_ini_section_set(ini, "Default Applications"))
+          {
+             efreet_ini_section_add(ini, "Default Applications");
+             efreet_ini_section_set(ini, "Default Applications");
+          }
+        if (desktop->orig_path)
+          efreet_ini_string_set(ini, mime, ecore_file_file_get(desktop->orig_path));
+        efreet_ini_save(ini, buf);
+        efreet_ini_free(ini);
+     }
+
+   EINA_LIST_FOREACH(_e_exehist->mimes, l, ei)
+     {
+        if ((ei->launch_method) && (!strcmp(mime, ei->launch_method)))
+          {
+             if ((ei->exe) && (!strcmp(f, ei->exe)))
+               {
+                  _e_exehist_unload_queue();
+                  return;
+               }
+             if (ei->exe) eina_stringshare_del(ei->exe);
+             if (ei->launch_method) eina_stringshare_del(ei->launch_method);
+             free(ei);
+             _e_exehist->mimes = eina_list_remove_list(_e_exehist->mimes, l);
+             _e_exehist_changes++;
+             break;
+          }
+     }
+   ei = E_NEW(E_Exehist_Item, 1);
+   if (!ei)
+     {
+        _e_exehist_unload_queue();
+        return;
+     }
+   ei->launch_method = eina_stringshare_add(mime);
+   ei->exe = eina_stringshare_add(f);
+   ei->exetime = ecore_time_unix_get();
+   _e_exehist->mimes = eina_list_append(_e_exehist->mimes, ei);
+   _e_exehist_limit();
+   _e_exehist_changes++;
+   _e_exehist_unload_queue();
+}
+
+EAPI Efreet_Desktop *
+e_exehist_mime_desktop_get(const char *mime)
+{
+   Efreet_Desktop *desktop;
+   E_Exehist_Item *ei;
+   Eina_List *l;
+
+   //fprintf(stderr, "e_exehist_mime_desktop_get(%s)\n", mime);
+   if (!mime) return NULL;
+   _e_exehist_load();
+   //fprintf(stderr, "x\n");
+   if (!_e_exehist) return NULL;
+   EINA_LIST_FOREACH(_e_exehist->mimes, l, ei)
+     {
+        //fprintf(stderr, "look for %s == %s\n", mime, ei->launch_method);
+        if ((ei->launch_method) && (!strcmp(mime, ei->launch_method)))
+          {
+             desktop = NULL;
+             if (ei->exe) desktop = efreet_util_desktop_file_id_find(ei->exe);
+             //fprintf(stderr, "  desk = %p\n", desktop);
+             if (desktop)
+               {
+                  _e_exehist_unload_queue();
+                  return desktop;
+               }
+          }
+     }
+   _e_exehist_unload_queue();
+   return NULL;
+}
+
+/* local subsystem functions */
+static void
+_e_exehist_unload_queue(void)
+{
+   if (_e_exehist_unload_defer)
+     e_powersave_deferred_action_del(_e_exehist_unload_defer);
+   _e_exehist_unload_defer =
+     e_powersave_deferred_action_add(_e_exehist_cb_unload, NULL);
+}
+
+static void
+_e_exehist_load(void)
+{
+   if (!_e_exehist)
+     _e_exehist = e_config_domain_load("exehist", _e_exehist_config_edd);
+   if (!_e_exehist)
+     _e_exehist = E_NEW(E_Exehist, 1);
+}
+
+static void
+_e_exehist_clear(void)
+{
+   if (_e_exehist)
+     {
+        E_Exehist_Item *ei;
+        EINA_LIST_FREE(_e_exehist->history, ei)
+          {
+             eina_stringshare_del(ei->exe);
+             eina_stringshare_del(ei->normalized_exe);
+             eina_stringshare_del(ei->launch_method);
+             free(ei);
+          }
+        EINA_LIST_FREE(_e_exehist->mimes, ei)
+          {
+             eina_stringshare_del(ei->exe);
+             eina_stringshare_del(ei->launch_method);
+             free(ei);
+          }
+     }
+}
+
+static void
+_e_exehist_unload(void)
+{
+   _e_exehist_clear();
+   E_FREE(_e_exehist);
+}
+
+static void
+_e_exehist_limit(void)
+{
+   /* go from first item in hist on and either delete all items before a
+    * specific timestamp, or if the list count > limit then delete items
+    *
+    * for now - limit to 500
+    */
+   if (_e_exehist)
+     {
+        while (eina_list_count(_e_exehist->history) > 500)
+          {
+             E_Exehist_Item *ei;
+
+             ei = eina_list_data_get(_e_exehist->history);
+             eina_stringshare_del(ei->exe);
+             eina_stringshare_del(ei->normalized_exe);
+             eina_stringshare_del(ei->launch_method);
+             free(ei);
+             _e_exehist->history = eina_list_remove_list(_e_exehist->history, _e_exehist->history);
+          }
+        while (eina_list_count(_e_exehist->mimes) > 500)
+          {
+             E_Exehist_Item *ei;
+
+             ei = eina_list_data_get(_e_exehist->mimes);
+             eina_stringshare_del(ei->exe);
+             eina_stringshare_del(ei->launch_method);
+             free(ei);
+             _e_exehist->mimes = eina_list_remove_list(_e_exehist->mimes, _e_exehist->mimes);
+          }
+     }
+}
+
+static const char *
+_e_exehist_normalize_exe(const char *exe)
+{
+   char *base, *buf, *cp, *space = NULL;
+   const char *ret;
+   Eina_Bool flag = EINA_FALSE;
+
+   buf = strdup(exe);
+   base = basename(buf);
+   if ((base[0] == '.') && (base[1] == '\0'))
+     {
+        free(buf);
+        return NULL;
+     }
+
+   cp = base;
+   while (*cp)
+     {
+        if (isspace(*cp))
+          {
+             if (!space) space = cp;
+             if (flag) flag = EINA_FALSE;
+          }
+        else if (!flag)
+          {
+             /* usually a variable in the desktop exe field */
+             if (space && *cp == '%')
+               flag = EINA_TRUE;
+             else
+               {
+                  char lower = tolower(*cp);
+
+                  space = NULL;
+                  if (lower != *cp) *cp = lower;
+               }
+          }
+        cp++;
+     }
+
+   if (space) *space = '\0';
+
+   ret = eina_stringshare_add(base);
+   free(buf);
+
+   return ret;
+}
+
+static void
+_e_exehist_cb_unload(void *data __UNUSED__)
+{
+   if (_e_exehist_changes)
+     {
+        e_config_domain_save("exehist", _e_exehist_config_edd, _e_exehist);
+        _e_exehist_changes = 0;
+     }
+   _e_exehist_unload();
+   _e_exehist_unload_defer = NULL;
+}
+
+static int
+_e_exehist_sort_exe_cb(const void *d1, const void *d2)
+{
+   const E_Exehist_Item *ei1, *ei2;
+
+   ei1 = d1;
+   ei2 = d2;
+
+   if ((!ei1) || (!ei1->normalized_exe)) return 1;
+   if ((!ei2) || (!ei2->normalized_exe)) return -1;
+
+   return strcmp(ei1->normalized_exe, ei2->normalized_exe);
+}
+
+static int
+_e_exehist_sort_pop_cb(const void *d1, const void *d2)
+{
+   const E_Exehist_Item *ei1, *ei2;
+
+   if (!(ei1 = d1)) return 1;
+   if (!(ei2 = d2)) return -1;
+
+   return ei2->count - ei1->count;
+}
+
diff --git a/src/bin/e_wayland/e_exehist.h b/src/bin/e_wayland/e_exehist.h
new file mode 100644 (file)
index 0000000..2775837
--- /dev/null
@@ -0,0 +1,30 @@
+#ifdef E_TYPEDEFS
+
+#else
+#ifndef E_EXEHIST_H
+#define E_EXEHIST_H
+
+typedef enum _E_Exehist_Sort
+{
+   E_EXEHIST_SORT_BY_DATE,
+   E_EXEHIST_SORT_BY_EXE,
+   E_EXEHIST_SORT_BY_POPULARITY
+} E_Exehist_Sort;
+
+EINTERN int e_exehist_init(void);
+EINTERN int e_exehist_shutdown(void);
+
+EAPI void e_exehist_add(const char *launch_method, const char *exe);
+EAPI void e_exehist_del(const char *exe);
+EAPI void e_exehist_clear(void);
+EAPI int e_exehist_popularity_get(const char *exe);
+EAPI double e_exehist_newest_run_get(const char *exe);
+EAPI Eina_List *e_exehist_list_get(void);
+EAPI Eina_List *e_exehist_sorted_list_get(E_Exehist_Sort sort_type, int max);
+EAPI void e_exehist_mime_desktop_add(const char *mime, Efreet_Desktop *desktop);
+EAPI Efreet_Desktop *e_exehist_mime_desktop_get(const char *mime);
+
+extern EAPI int E_EVENT_EXEHIST_UPDATE;
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_gadcon.c b/src/bin/e_wayland/e_gadcon.c
new file mode 100644 (file)
index 0000000..bac371a
--- /dev/null
@@ -0,0 +1,5140 @@
+#include "e.h"
+
+/*
+ * TODO: gadcon client ordering on drop
+ */
+
+#define E_LAYOUT_ITEM_DRAG_RESIST_LEVEL 10
+
+static void _e_gadcon_free(E_Gadcon *gc);
+static void _e_gadcon_client_free(E_Gadcon_Client *gcc);
+
+static void _e_gadcon_moveresize_handle(E_Gadcon_Client *gcc);
+static Eina_Bool _e_gadcon_cb_client_scroll_timer(void *data);
+static Eina_Bool _e_gadcon_cb_client_scroll_animator(void *data);
+static void _e_gadcon_cb_client_frame_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_frame_moveresize(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_client_save(E_Gadcon_Client *gcc);
+static void _e_gadcon_client_drag_begin(E_Gadcon_Client *gcc, int x, int y);
+/* static void _e_gadcon_client_inject(E_Gadcon *gc, E_Gadcon_Client *gcc, int x, int y); */
+
+static void _e_gadcon_cb_min_size_request(void *data, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_size_request(void *data, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_moveresize(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_mouse_in(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_mouse_out(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_move(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+static void _e_gadcon_cb_client_resize(void *data, Evas *evas, Evas_Object *obj, void *event_info);
+
+static void _e_gadcon_client_move_start(E_Gadcon_Client *gcc);
+static void _e_gadcon_client_move_stop(E_Gadcon_Client *gcc);
+static void _e_gadcon_client_move_go(E_Gadcon_Client *gcc);
+
+static void _e_gadcon_cb_signal_move_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_move_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_move_go(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_left_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_left_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_left_go(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_right_start(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_right_stop(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_gadcon_cb_signal_resize_right_go(void *data, Evas_Object *obj, const char *emission, const char *source);
+/* static void _e_gadcon_cb_drag_finished(E_Drag *drag, int dropped); */
+/* static void _e_gadcon_cb_dnd_enter(void *data, const char *type, void *event); */
+/* static void _e_gadcon_cb_dnd_move(void *data, const char *type, void *event); */
+/* static void _e_gadcon_cb_dnd_leave(void *data, const char *type, void *event); */
+/* static void _e_gadcon_cb_drop(void *data, const char *type, void *event); */
+
+static int _e_gadcon_client_class_feature_check(const E_Gadcon_Client_Class *cc, const char *name, void *feature);
+static void _e_gadcon_client_cb_menu_post(void *data, E_Menu *m);
+static void _e_gadcon_client_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_client_cb_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_client_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_client_cb_menu_style_plain(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_gadcon_client_cb_menu_style_inset(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_gadcon_client_cb_menu_autoscroll(void *data, E_Menu *m, E_Menu_Item *mi);
+/*static void _e_gadcon_client_cb_menu_resizable(void *data, E_Menu *m, E_Menu_Item *mi);*/
+static void _e_gadcon_client_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_gadcon_client_cb_menu_remove(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_gadcon_client_cb_menu_pre(void *data, E_Menu *m, E_Menu_Item *mi);
+
+static void _e_gadcon_client_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+static Evas_Object *e_gadcon_layout_add(Evas *evas);
+static void e_gadcon_layout_orientation_set(Evas_Object *obj, int horizontal);
+static int e_gadcon_layout_orientation_get(Evas_Object *obj);
+static void e_gadcon_layout_freeze(Evas_Object *obj);
+static void e_gadcon_layout_thaw(Evas_Object *obj);
+static void e_gadcon_layout_min_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+static void e_gadcon_layout_asked_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
+static int e_gadcon_layout_pack(Evas_Object *obj, Evas_Object *child);
+static void e_gadcon_layout_pack_size_set(Evas_Object *obj, int size);
+static void e_gadcon_layout_pack_request_set(Evas_Object *obj, int pos, int size);
+static void e_gadcon_layout_pack_options_set(Evas_Object *obj, E_Gadcon_Client *gcc);
+static void e_gadcon_layout_pack_min_size_set(Evas_Object *obj, int w, int h);
+static void e_gadcon_layout_pack_aspect_set(Evas_Object *obj, int w, int h);
+static void e_gadcon_layout_pack_aspect_pad_set(Evas_Object *obj, int w, int h);
+static void e_gadcon_layout_unpack(Evas_Object *obj);
+static void _e_gadcon_provider_populate_request(const E_Gadcon_Client_Class *cc);
+static void _e_gadcon_provider_populate_unrequest(const E_Gadcon_Client_Class *cc);
+static Eina_Bool  _e_gadcon_provider_populate_idler(void *data);
+static Eina_Bool  _e_gadcon_custom_populate_idler(void *data);
+
+static int _e_gadcon_location_change(E_Gadcon_Client * gcc, E_Gadcon_Location *src, E_Gadcon_Location *dst);
+
+typedef struct _E_Smart_Data E_Smart_Data;
+typedef struct _E_Layout_Item_Container E_Layout_Item_Container;
+
+static void _e_gadcon_client_current_position_sync(E_Gadcon_Client *gcc);
+static void _e_gadcon_layout_smart_sync_clients(E_Gadcon *gc);
+static void _e_gadcon_layout_smart_gadcon_position_shrinked_mode(E_Smart_Data *sd);
+static void _e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd);
+static Eina_List *_e_gadcon_layout_smart_gadcons_wrap(E_Smart_Data *sd);
+static void _e_gadcon_layout_smart_gadcons_position(E_Smart_Data *sd, Eina_List **list);
+static void _e_gadcon_layout_smart_gadcons_position_static(E_Smart_Data *sd, Eina_List **list);
+static E_Layout_Item_Container * _e_gadcon_layout_smart_containers_position_adjust(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2);
+static void _e_gadcon_layout_smart_position_items_inside_container(E_Smart_Data *sd, E_Layout_Item_Container *lc);
+static void _e_gadcon_layout_smart_containers_merge(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2);
+static void _e_gadcon_layout_smart_restore_gadcons_position_before_move(E_Smart_Data *sd, E_Layout_Item_Container **lc_moving, E_Layout_Item_Container *lc_back, Eina_List **con_list);
+
+typedef enum _E_Gadcon_Layout_Item_State
+{
+   E_LAYOUT_ITEM_STATE_NONE,
+   E_LAYOUT_ITEM_STATE_POS_INC,
+   E_LAYOUT_ITEM_STATE_POS_DEC,
+   E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC,
+   E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC,
+   E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC,
+   E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC,
+} E_Gadcon_Layout_Item_State;
+
+typedef enum _E_Gadcon_Layout_Item_Flags
+{
+   E_GADCON_LAYOUT_ITEM_LOCK_NONE     = 0x00000000,
+   E_GADCON_LAYOUT_ITEM_LOCK_POSITION = 0x00000001,
+   E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE = 0x00000002
+} E_Gadcon_Layout_Item_Flags;
+
+typedef enum _E_Layout_Item_Container_State
+{
+   E_LAYOUT_ITEM_CONTAINER_STATE_NONE, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC, 
+   E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED
+} E_Layout_Item_Container_State;
+
+struct _E_Layout_Item_Container
+{
+   int pos, size, prev_pos, prev_size;
+
+   struct 
+     {
+        int min_seq, max_seq;
+     } state_info;
+
+   E_Smart_Data *sd;
+   Eina_List *items;
+
+   E_Layout_Item_Container_State state;
+};
+
+#define LC_FREE(__lc) \
+   if (__lc->items) \
+     eina_list_free(__lc->items); \
+   E_FREE(__lc)
+
+#define E_LAYOUT_ITEM_CONTAINER_STATE_SET(__con_state, __bi_state) \
+   if (__bi_state == E_LAYOUT_ITEM_STATE_NONE) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_POS_INC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_POS_DEC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC; \
+   else if (__bi_state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC) \
+      __con_state = E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC
+
+#define LC_OVERLAP(__lc, __lc2) \
+   ((((__lc2)->pos >= (__lc)->pos) && ((__lc2)->pos < ((__lc)->pos + (__lc)->size))) || \
+    (((__lc)->pos >= (__lc2)->pos) && ((__lc)->pos < ((__lc2)->pos + (__lc2)->size))))
+
+#define E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(__lc, __bi, __increase) \
+     { \
+       if (__increase) \
+         __lc->size += __bi->w; \
+       else \
+         __lc->size -= __bi->w; \
+     }
+
+/********************/
+
+static Eina_Hash *providers = NULL;
+static Eina_List *providers_list = NULL;
+static Eina_List *gadcons = NULL;
+static Eina_List *populate_requests = NULL;
+static Ecore_Idler *populate_idler = NULL;
+static Eina_List *custom_populate_requests = NULL;
+static Ecore_Idler *custom_populate_idler = NULL;
+static Eina_List *gadcon_locations = NULL;
+
+/* This is the gadcon client which is currently dragged */
+static E_Gadcon_Client *drag_gcc = NULL;
+/* This is the gadcon client created on entering a new shelf */
+static E_Gadcon_Client *new_gcc = NULL;
+
+/* externally accessible functions */
+EINTERN int
+e_gadcon_init(void)
+{
+   return 1;
+}
+
+EINTERN int
+e_gadcon_shutdown(void)
+{
+   populate_requests = eina_list_free(populate_requests);
+   if (populate_idler)
+     {
+       ecore_idler_del(populate_idler);
+       populate_idler = NULL;
+     }
+   custom_populate_requests = eina_list_free(custom_populate_requests);
+   if (custom_populate_idler)
+     {
+       ecore_idler_del(custom_populate_idler);
+       custom_populate_idler = NULL;
+     }
+
+   return 1;
+}
+
+EAPI void
+e_gadcon_provider_register(const E_Gadcon_Client_Class *cc)
+{
+   if (!providers) providers = eina_hash_string_superfast_new(NULL);
+   eina_hash_direct_add(providers, cc->name, cc);
+   providers_list = eina_list_append(providers_list, cc);
+   _e_gadcon_provider_populate_request(cc);
+}
+
+EAPI void
+e_gadcon_provider_unregister(const E_Gadcon_Client_Class *cc)
+{
+   Eina_List *l, *ll, *dlist = NULL;
+   E_Gadcon *gc;
+   E_Gadcon_Client *gcc;
+
+   _e_gadcon_provider_populate_unrequest(cc);
+
+   EINA_LIST_FOREACH(gadcons, l, gc)
+     {
+       EINA_LIST_FOREACH(gc->clients, ll, gcc)
+         {
+            if (gcc->client_class == cc)
+              dlist = eina_list_append(dlist, gcc);
+         }
+     }
+   EINA_LIST_FREE(dlist, gcc)
+     e_object_del(E_OBJECT(gcc));
+
+   eina_hash_del(providers, cc->name, cc);
+   providers_list = eina_list_remove(providers_list, cc);
+}
+
+EAPI Eina_List *
+e_gadcon_provider_list(void)
+{
+   return providers_list;
+}
+
+EAPI void
+e_gadcon_custom_new(E_Gadcon *gc)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+
+   gadcons = eina_list_append(gadcons, gc);
+
+   if (!custom_populate_idler) 
+     {
+        custom_populate_idler = 
+          ecore_idler_add(_e_gadcon_custom_populate_idler, NULL);
+     }
+   if (!eina_list_data_find(custom_populate_requests, gc))
+     custom_populate_requests = eina_list_append(custom_populate_requests, gc);
+}
+
+EAPI void
+e_gadcon_custom_del(E_Gadcon *gc)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gadcons = eina_list_remove(gadcons, gc);
+}
+
+EAPI E_Gadcon *
+e_gadcon_swallowed_new(const char *name, int id, Evas_Object *obj, const char *swallow_name)
+{
+   E_Gadcon *gc;
+   E_Config_Gadcon *cf_gc;
+   Eina_List *l;
+   Evas_Coord x, y, w, h;
+   const char *drop_types[] = { "enlightenment/gadcon_client" };
+
+   gc = E_OBJECT_ALLOC(E_Gadcon, E_GADCON_TYPE, _e_gadcon_free);
+   if (!gc) return NULL;
+
+   gc->name = eina_stringshare_add(name);
+   gc->id = id;
+   gc->layout_policy = E_GADCON_LAYOUT_POLICY_PANEL;
+   gc->location = NULL;
+
+   gc->edje.o_parent = obj;
+   gc->edje.swallow_name = eina_stringshare_add(swallow_name);
+
+   gc->orient = E_GADCON_ORIENT_HORIZ;
+   gc->evas = evas_object_evas_get(obj);
+   gc->o_container = e_gadcon_layout_add(gc->evas);
+   evas_object_geometry_get(gc->o_container, &x, &y, &w, &h);
+   /* gc->drop_handler =  */
+   /*   e_drop_handler_add(E_OBJECT(gc), gc, */
+   /*                      _e_gadcon_cb_dnd_enter, _e_gadcon_cb_dnd_move, */
+   /*                      _e_gadcon_cb_dnd_leave, _e_gadcon_cb_drop, */
+   /*                      drop_types, 1, x, y, w, h); */
+   evas_object_event_callback_add(gc->o_container, EVAS_CALLBACK_MOVE,
+                                 _e_gadcon_cb_moveresize, gc);
+   evas_object_event_callback_add(gc->o_container, EVAS_CALLBACK_RESIZE,
+                                 _e_gadcon_cb_moveresize, gc);
+   evas_object_smart_callback_add(gc->o_container, "size_request",
+                                 _e_gadcon_cb_size_request, gc);
+   evas_object_smart_callback_add(gc->o_container, "min_size_request",
+                                 _e_gadcon_cb_min_size_request, gc);
+   evas_object_show(gc->o_container);
+   edje_object_part_swallow(gc->edje.o_parent, gc->edje.swallow_name,
+                           gc->o_container);
+   gadcons = eina_list_append(gadcons, gc);
+
+   EINA_LIST_FOREACH(e_config->gadcons, l, cf_gc)
+     {
+       if ((!strcmp(cf_gc->name, gc->name)) && (cf_gc->id == gc->id))
+         {
+            gc->cf = cf_gc;
+            break;
+         }
+     }
+   if (!gc->cf)
+     {
+       gc->cf = E_NEW(E_Config_Gadcon, 1);
+       gc->cf->name = eina_stringshare_add(gc->name);
+       gc->cf->id = gc->id;
+        if (gc->zone) gc->cf->zone = gc->zone->num;
+       e_config->gadcons = eina_list_append(e_config->gadcons, gc->cf);
+       e_config_save_queue();
+     }
+   return gc;
+}
+
+EAPI void
+e_gadcon_swallowed_min_size_set(E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   if (gc->edje.o_parent)
+     {
+       edje_extern_object_min_size_set(gc->o_container, w, h);
+       edje_object_part_swallow(gc->edje.o_parent, gc->edje.swallow_name,
+                                gc->o_container);
+     }
+}
+
+EAPI void
+e_gadcon_min_size_request_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->min_size_request.func = func;
+   gc->min_size_request.data = data;
+}
+
+EAPI void
+e_gadcon_size_request_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->resize_request.func = func;
+   gc->resize_request.data = data;
+}
+
+EAPI void
+e_gadcon_frame_request_callback_set(E_Gadcon *gc, Evas_Object *(*func) (void *data, E_Gadcon_Client *gcc, const char *style), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->frame_request.func = func;
+   gc->frame_request.data = data;
+}
+
+EAPI void
+e_gadcon_populate_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->populate_class.func = func;
+   gc->populate_class.data = data;
+}
+
+EAPI void
+e_gadcon_layout_policy_set(E_Gadcon *gc, E_Gadcon_Layout_Policy layout_policy)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   if (gc->layout_policy == layout_policy) return;
+   gc->layout_policy = layout_policy;
+   /* FIXME: delete container obj, re-pack all clients */
+}
+
+EAPI void
+e_gadcon_populate(E_Gadcon *gc)
+{
+   Eina_List *l;
+   E_Config_Gadcon_Client *cf_gcc;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   e_gadcon_layout_freeze(gc->o_container);
+   EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
+     {
+       E_Gadcon_Client_Class *cc;
+
+       if (!cf_gcc->name) continue;
+       cc = eina_hash_find(providers, cf_gcc->name);
+       if (cc)
+         {
+            E_Gadcon_Client *gcc;
+
+            if (eina_list_data_find(populate_requests, cc))
+              continue;
+
+            if ((!cf_gcc->id) &&
+                (_e_gadcon_client_class_feature_check(cc, "id_new", cc->func.id_new)))
+              cf_gcc->id = eina_stringshare_add(cc->func.id_new(cc));
+
+            if (!cf_gcc->style)
+               gcc = cc->func.init(gc, cf_gcc->name, cf_gcc->id,
+                                   cc->default_style);
+            else
+              gcc = cc->func.init(gc, cf_gcc->name, cf_gcc->id,
+                                   cf_gcc->style);
+
+            if (gcc)
+              {
+                 gcc->cf = cf_gcc;
+                 gcc->client_class = cc;
+                 gcc->config.pos = cf_gcc->geom.pos;
+                 gcc->config.size = cf_gcc->geom.size;
+                 gcc->config.res = cf_gcc->geom.res;
+                 gcc->state_info.seq = cf_gcc->state_info.seq;
+                 gcc->state_info.flags = cf_gcc->state_info.flags;
+                 if (gcc->o_frame)
+                   e_gadcon_layout_pack_options_set(gcc->o_frame, gcc);
+                 else if (gcc->o_base)
+                   e_gadcon_layout_pack_options_set(gcc->o_base, gcc);
+
+                  if (!gcc->autoscroll_set)
+                    e_gadcon_client_autoscroll_set(gcc, cf_gcc->autoscroll);
+//               e_gadcon_client_resizable_set(gcc, cf_gcc->resizable);
+                 if (gcc->client_class->func.orient)
+                   gcc->client_class->func.orient(gcc, gc->orient);
+
+                 _e_gadcon_client_save(gcc);
+                 if (gc->editing) e_gadcon_client_edit_begin(gcc);
+                 if (gc->instant_edit)
+                   e_gadcon_client_util_menu_attach(gcc);
+              }
+         }
+     }
+   e_gadcon_layout_thaw(gc->o_container);
+}
+
+EAPI void
+e_gadcon_unpopulate(E_Gadcon *gc)
+{
+   E_Gadcon_Client *gcc;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   /* Be careful, e_object_del does remove gcc from gc->clients */
+   while (gc->clients)
+     {
+       gcc = eina_list_data_get(gc->clients);
+       if (gcc->menu)
+         {
+            e_menu_post_deactivate_callback_set(gcc->menu, NULL, NULL);
+            e_object_del(E_OBJECT(gcc->menu));
+            gcc->menu = NULL;
+         }
+       e_object_del(E_OBJECT(gcc));
+     }
+}
+
+EAPI void
+e_gadcon_populate_class(E_Gadcon *gc, const E_Gadcon_Client_Class *cc)
+{
+   Eina_List *l;
+   E_Config_Gadcon_Client *cf_gcc;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   e_gadcon_layout_freeze(gc->o_container);
+   EINA_LIST_FOREACH(gc->cf->clients, l, cf_gcc)
+     {
+       if ((cf_gcc->name) && (cc->name) && 
+           (!strcmp(cf_gcc->name, cc->name)) &&
+           (cf_gcc->id) && (cf_gcc->style))
+         {
+            E_Gadcon_Client *gcc;
+
+            if ((!cf_gcc->id) &&
+                (_e_gadcon_client_class_feature_check((E_Gadcon_Client_Class *)cc, "id_new", cc->func.id_new)))
+              cf_gcc->id = eina_stringshare_add(cc->func.id_new((E_Gadcon_Client_Class *)cc));
+
+            gcc = cc->func.init(gc, cf_gcc->name, cf_gcc->id,
+                                cf_gcc->style);
+            if (gcc)
+              {
+                 gcc->cf = cf_gcc;
+                 gcc->client_class = cc;
+                 gcc->config.pos = cf_gcc->geom.pos;
+                 gcc->config.size = cf_gcc->geom.size;
+                 gcc->config.res = cf_gcc->geom.res;
+                 gcc->state_info.seq = cf_gcc->state_info.seq;
+                 gcc->state_info.flags = cf_gcc->state_info.flags;
+                 if (gcc->o_frame)
+                   e_gadcon_layout_pack_options_set(gcc->o_frame, gcc);
+                 else if (gcc->o_base)
+                   e_gadcon_layout_pack_options_set(gcc->o_base, gcc);
+
+                  if (!gcc->autoscroll_set)
+                    e_gadcon_client_autoscroll_set(gcc, cf_gcc->autoscroll);
+//               e_gadcon_client_resizable_set(gcc, cf_gcc->resizable);
+                 if (gcc->client_class->func.orient)
+                   gcc->client_class->func.orient(gcc, gc->orient); 
+
+                 _e_gadcon_client_save(gcc);
+                 if (gc->editing) e_gadcon_client_edit_begin(gcc);
+                 if (gc->instant_edit)
+                   e_gadcon_client_util_menu_attach(gcc);
+              }
+         }
+     }
+   e_gadcon_layout_thaw(gc->o_container);
+}
+
+EAPI void
+e_gadcon_orient(E_Gadcon *gc, E_Gadcon_Orient orient)
+{
+   Eina_List *l;
+   E_Gadcon_Client *gcc;
+   int horiz = 0;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   if (gc->orient == orient) return;
+   gc->orient = orient;
+   e_gadcon_layout_freeze(gc->o_container);
+   switch (gc->orient)
+     {
+      case E_GADCON_ORIENT_FLOAT:
+      case E_GADCON_ORIENT_HORIZ:
+      case E_GADCON_ORIENT_TOP:
+      case E_GADCON_ORIENT_BOTTOM:
+      case E_GADCON_ORIENT_CORNER_TL:
+      case E_GADCON_ORIENT_CORNER_TR:
+      case E_GADCON_ORIENT_CORNER_BL:
+      case E_GADCON_ORIENT_CORNER_BR:
+       horiz = 1;
+       break;
+      case E_GADCON_ORIENT_VERT:
+      case E_GADCON_ORIENT_LEFT:
+      case E_GADCON_ORIENT_RIGHT:
+      case E_GADCON_ORIENT_CORNER_LT:
+      case E_GADCON_ORIENT_CORNER_RT:
+      case E_GADCON_ORIENT_CORNER_LB:
+      case E_GADCON_ORIENT_CORNER_RB:
+       horiz = 0;
+       break;
+      default:
+       break;
+     }
+   e_gadcon_layout_orientation_set(gc->o_container, horiz);
+   EINA_LIST_FOREACH(gc->clients, l, gcc)
+     {
+       e_box_orientation_set(gcc->o_box, horiz);
+       if (gcc->client_class->func.orient)
+         gcc->client_class->func.orient(gcc, gc->orient);
+     }
+   e_gadcon_layout_thaw(gc->o_container);
+}
+
+EAPI void
+e_gadcon_edit_begin(E_Gadcon *gc)
+{
+   Eina_List *l;
+   E_Gadcon_Client *gcc;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   e_gadcon_layout_freeze(gc->o_container);
+   e_gadcon_locked_set(gc, 1);
+   gc->editing = 1;
+   EINA_LIST_FOREACH(gc->clients, l, gcc)
+     e_gadcon_client_edit_begin(gcc);
+   e_gadcon_layout_thaw(gc->o_container);
+}
+
+EAPI void
+e_gadcon_edit_end(E_Gadcon *gc)
+{
+   Eina_List *l;
+   E_Gadcon_Client *gcc;
+
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   e_gadcon_layout_freeze(gc->o_container);
+   gc->editing = 0;
+   EINA_LIST_FOREACH(gc->clients, l, gcc)
+     e_gadcon_client_edit_end(gcc);
+   e_gadcon_layout_thaw(gc->o_container);
+   e_gadcon_locked_set(gc, 0);
+}
+
+EAPI void
+e_gadcon_all_edit_begin(void)
+{
+   Eina_List *l;
+   E_Gadcon *gc;
+
+   EINA_LIST_FOREACH(gadcons, l, gc)
+     e_gadcon_edit_begin(gc);
+}
+
+EAPI void
+e_gadcon_all_edit_end(void)
+{
+   Eina_List *l;
+   E_Gadcon *gc;
+
+   EINA_LIST_FOREACH(gadcons, l, gc)
+     e_gadcon_edit_end(gc);
+}
+
+EAPI void
+e_gadcon_zone_set(E_Gadcon *gc, E_Zone *zone)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->zone = zone;
+   if (gc->cf) gc->cf->zone = zone->num;
+}
+
+EAPI E_Zone *
+e_gadcon_zone_get(E_Gadcon *gc)
+{
+   E_OBJECT_CHECK_RETURN(gc, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
+   return gc->zone;
+}
+
+EAPI void
+e_gadcon_ecore_evas_set(E_Gadcon *gc, Ecore_Evas *ee)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->ecore_evas = ee;
+}
+
+EAPI int
+e_gadcon_canvas_zone_geometry_get(E_Gadcon *gc, int *x, int *y, int *w, int *h)
+{
+   E_OBJECT_CHECK_RETURN(gc, 0);
+   E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0);
+   if (!gc->ecore_evas) return 0;
+   ecore_evas_geometry_get(gc->ecore_evas, x, y, w, h);
+// so much relies on this down here to have been broken... ie return container-relative coords.
+//   if (gc->zone)
+//     {
+//     if (x) *x = *x - gc->zone->x;
+//     if (y) *y = *y - gc->zone->y;
+//     }
+   return 1;
+}
+
+EAPI void
+e_gadcon_util_menu_attach_func_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon_Client *gcc, E_Menu *menu), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->menu_attach.func = func;
+   gc->menu_attach.data = data;
+}
+
+EAPI void
+e_gadcon_util_lock_func_set(E_Gadcon *gc, void (*func) (void *data, int lock), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->locked_set.func = func;
+   gc->locked_set.data = data;
+}
+
+EAPI void
+e_gadcon_util_urgent_show_func_set(E_Gadcon *gc, void (*func) (void *data), void *data)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->urgent_show.func = func;
+   gc->urgent_show.data = data;
+}
+
+/* EAPI void */
+/* e_gadcon_dnd_window_set(E_Gadcon *gc, Ecore_X_Window win) */
+/* { */
+/*    E_OBJECT_CHECK(gc); */
+/*    E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE); */
+/*    gc->dnd_win = win; */
+/* } */
+                                                        
+/* EAPI Ecore_X_Window */
+/* e_gadcon_dnd_window_get(E_Gadcon *gc) */
+/* { */
+/*    E_OBJECT_CHECK_RETURN(gc, 0); */
+/*    E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0); */
+/*    return gc->dnd_win; */
+/* } */
+
+/* EAPI void */
+/* e_gadcon_xdnd_window_set(E_Gadcon *gc, Ecore_X_Window win) */
+/* { */
+/*    E_OBJECT_CHECK(gc); */
+/*    E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE); */
+/*    gc->xdnd_win = win; */
+/* } */
+                                                        
+/* EAPI Ecore_X_Window */
+/* e_gadcon_xdnd_window_get(E_Gadcon *gc) */
+/* { */
+/*    E_OBJECT_CHECK_RETURN(gc, 0); */
+/*    E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, 0); */
+/*    return gc->xdnd_win; */
+/* } */
+
+EAPI void
+e_gadcon_shelf_set(E_Gadcon *gc, E_Shelf *shelf)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   gc->shelf = shelf;
+}
+                                                        
+EAPI E_Shelf *
+e_gadcon_shelf_get(E_Gadcon *gc)
+{
+   E_OBJECT_CHECK_RETURN(gc, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
+   return gc->shelf;
+}
+
+/* EAPI void  */
+/* e_gadcon_toolbar_set(E_Gadcon *gc, E_Toolbar *toolbar)  */
+/* { */
+/*    E_OBJECT_CHECK(gc); */
+/*    E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE); */
+/*    gc->toolbar = toolbar; */
+/* } */
+
+/* EAPI E_Toolbar * */
+/* e_gadcon_toolbar_get(E_Gadcon *gc)  */
+/* { */
+/*    E_OBJECT_CHECK_RETURN(gc, NULL); */
+/*    E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL); */
+/*    return gc->toolbar; */
+/* } */
+
+EAPI E_Config_Gadcon_Client *
+e_gadcon_client_config_new(E_Gadcon *gc, const char *name)
+{
+   E_Gadcon_Client_Class *cc;
+   E_Config_Gadcon_Client *cf_gcc;
+
+   E_OBJECT_CHECK_RETURN(gc, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
+   if (!name) return NULL;
+   cc = eina_hash_find(providers, name);
+   if (!cc) return NULL;
+   if (!_e_gadcon_client_class_feature_check(cc, "id_new", cc->func.id_new)) 
+     return NULL;
+
+   cf_gcc = E_NEW(E_Config_Gadcon_Client, 1);
+   if (!cf_gcc) return NULL;
+   cf_gcc->id = eina_stringshare_add(cc->func.id_new(cc));
+   if (!cf_gcc->id)
+     {
+        free(cf_gcc);
+        return NULL;
+     }
+   cf_gcc->name = eina_stringshare_add(name);
+   if (gc->zone)
+     cf_gcc->geom.res = gc->zone->w;
+   else
+     cf_gcc->geom.res = 800;
+   cf_gcc->geom.size = 80;
+   cf_gcc->geom.pos = cf_gcc->geom.res - cf_gcc->geom.size;
+   cf_gcc->style = NULL;
+   cf_gcc->autoscroll = 0;
+   cf_gcc->resizable = 0;
+   gc->cf->clients = eina_list_append(gc->cf->clients, cf_gcc);
+   e_config_save_queue();
+   return cf_gcc;
+}
+
+EAPI void
+e_gadcon_client_config_del(E_Config_Gadcon *cf_gc, E_Config_Gadcon_Client *cf_gcc)
+{
+   if (!cf_gcc) return;
+   if (cf_gcc->name) eina_stringshare_del(cf_gcc->name);
+   if (cf_gcc->id) eina_stringshare_del(cf_gcc->id);
+   if (cf_gcc->style) eina_stringshare_del(cf_gcc->style);
+   if (cf_gc) cf_gc->clients = eina_list_remove(cf_gc->clients, cf_gcc);
+   free(cf_gcc);
+}
+
+EAPI E_Gadcon_Client *
+e_gadcon_client_new(E_Gadcon *gc, const char *name, const char *id __UNUSED__, const char *style, Evas_Object *base_obj)
+{
+   E_Gadcon_Client *gcc;
+
+   E_OBJECT_CHECK_RETURN(gc, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(gc, E_GADCON_TYPE, NULL);
+   gcc = E_OBJECT_ALLOC(E_Gadcon_Client, E_GADCON_CLIENT_TYPE, 
+                        _e_gadcon_client_free);
+   if (!gcc) return NULL;
+   gcc->name = eina_stringshare_add(name);
+   gcc->gadcon = gc;
+   gcc->o_base = base_obj;
+   if (gc->clients)
+     gcc->id = E_GADCON_CLIENT(eina_list_data_get(eina_list_last(gc->clients)))->id + 1;
+   gc->clients = eina_list_append(gc->clients, gcc);
+   /* This must only be unique during runtime */
+   if (gcc->o_base)
+     evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_DEL,
+                                   _e_gadcon_client_del_hook, gcc);
+   if ((gc->frame_request.func) && (style))
+     {
+       gcc->o_frame = gc->frame_request.func(gc->frame_request.data, gcc, style);
+       gcc->style = eina_stringshare_add(style);
+       if (gcc->o_frame)
+         {
+            edje_object_size_min_calc(gcc->o_frame, &(gcc->pad.w), &(gcc->pad.h));
+            gcc->o_box = e_box_add(gcc->gadcon->evas);
+            switch (gcc->gadcon->orient)
+              {
+               case E_GADCON_ORIENT_FLOAT:
+               case E_GADCON_ORIENT_HORIZ:
+               case E_GADCON_ORIENT_TOP:
+               case E_GADCON_ORIENT_BOTTOM:
+               case E_GADCON_ORIENT_CORNER_TL:
+               case E_GADCON_ORIENT_CORNER_TR:
+               case E_GADCON_ORIENT_CORNER_BL:
+               case E_GADCON_ORIENT_CORNER_BR:
+                 e_box_orientation_set(gcc->o_box, 1);
+                 break;
+               case E_GADCON_ORIENT_VERT:
+               case E_GADCON_ORIENT_LEFT:
+               case E_GADCON_ORIENT_RIGHT:
+               case E_GADCON_ORIENT_CORNER_LT:
+               case E_GADCON_ORIENT_CORNER_RT:
+               case E_GADCON_ORIENT_CORNER_LB:
+               case E_GADCON_ORIENT_CORNER_RB:
+                 e_box_orientation_set(gcc->o_box, 0);
+                 break;
+               default:
+                 break;
+              }
+            evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_MOVE,
+                                           _e_gadcon_cb_client_frame_moveresize, gcc);
+            evas_object_event_callback_add(gcc->o_box, EVAS_CALLBACK_RESIZE,
+                                           _e_gadcon_cb_client_frame_moveresize, gcc);
+            evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_MOVE,
+                                           _e_gadcon_cb_client_frame_mouse_move, gcc);
+            if (gcc->o_base)
+              {
+                 e_box_pack_end(gcc->o_box, gcc->o_base);
+                 e_box_pack_options_set(gcc->o_base,
+                                        1, 1, /* fill */
+                                        1, 1, /* expand */
+                                        0.5, 0.5, /* align */
+                                        0, 0, /* min */
+                                        -1, -1 /* max */
+                                        );
+              }
+            edje_object_part_swallow(gcc->o_frame, gc->edje.swallow_name, gcc->o_box);
+            evas_object_show(gcc->o_box);
+            evas_object_show(gcc->o_frame);
+         }
+     }
+   if (gcc->o_frame)
+     e_gadcon_layout_pack(gc->o_container, gcc->o_frame);
+   else if (gcc->o_base)
+     e_gadcon_layout_pack(gc->o_container, gcc->o_base);
+   if (gcc->o_base) evas_object_show(gcc->o_base);
+   return gcc;
+}
+
+EAPI void
+e_gadcon_client_edit_begin(E_Gadcon_Client *gcc)
+{
+   Evas_Coord x, y, w, h;
+
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   if (gcc->o_control) return;
+
+   if (gcc->o_frame)
+     evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
+   else if (gcc->o_base)
+     evas_object_geometry_get(gcc->o_base, &x, &y, &w, &h);
+   else return; /* make clang happy */
+
+   gcc->o_control = edje_object_add(gcc->gadcon->evas);
+   evas_object_layer_set(gcc->o_control, 100);
+   e_gadcon_locked_set(gcc->gadcon, 1);
+   gcc->gadcon->editing = 1;
+
+   evas_object_move(gcc->o_control, x, y);
+   evas_object_resize(gcc->o_control, w, h);
+   e_theme_edje_object_set(gcc->o_control, "base/theme/gadman", 
+                           "e/gadman/control");
+
+   if ((gcc->autoscroll)/* || (gcc->resizable)*/)
+     {
+       if (e_box_orientation_get(gcc->o_box))
+         edje_object_signal_emit(gcc->o_control, "e,state,hsize,on", "e");
+       else
+         edje_object_signal_emit(gcc->o_control, "e,state,vsize,on", "e");
+     }
+   else
+     {
+       edje_object_signal_emit(gcc->o_control, "e,state,hsize,off", "e");
+       edje_object_signal_emit(gcc->o_control, "e,state,vsize,off", "e");
+     }
+   edje_object_signal_emit(gcc->o_control, "e,state,move,on", "e");
+
+   gcc->o_event = evas_object_rectangle_add(gcc->gadcon->evas);
+   evas_object_color_set(gcc->o_event, 0, 0, 0, 0);
+   evas_object_repeat_events_set(gcc->o_event, 1);
+   evas_object_layer_set(gcc->o_event, 100);
+   evas_object_move(gcc->o_event, x, y);
+   evas_object_resize(gcc->o_event, w, h);
+
+   edje_object_signal_callback_add(gcc->o_control, "e,action,move,start", "",
+                                  _e_gadcon_cb_signal_move_start, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,move,stop", "",
+                                  _e_gadcon_cb_signal_move_stop, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,move,go", "",
+                                  _e_gadcon_cb_signal_move_go, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,start", "",
+                                  _e_gadcon_cb_signal_resize_left_start, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,stop", "",
+                                  _e_gadcon_cb_signal_resize_left_stop, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,left,go", "",
+                                  _e_gadcon_cb_signal_resize_left_go, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,start", "",
+                                  _e_gadcon_cb_signal_resize_right_start, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,stop", "",
+                                  _e_gadcon_cb_signal_resize_right_stop, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,right,go", "",
+                                  _e_gadcon_cb_signal_resize_right_go, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,start", "",
+                                  _e_gadcon_cb_signal_resize_left_start, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,stop", "",
+                                  _e_gadcon_cb_signal_resize_left_stop, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,up,go", "",
+                                  _e_gadcon_cb_signal_resize_left_go, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,start", "",
+                                  _e_gadcon_cb_signal_resize_right_start, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,stop", "",
+                                  _e_gadcon_cb_signal_resize_right_stop, gcc);
+   edje_object_signal_callback_add(gcc->o_control, "e,action,resize,down,go", "",
+                                  _e_gadcon_cb_signal_resize_right_go, gcc);
+
+   evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_DOWN, 
+                                  _e_gadcon_cb_client_mouse_down, gcc);
+   evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_IN, 
+                                  _e_gadcon_cb_client_mouse_in, gcc);
+   evas_object_event_callback_add(gcc->o_event, EVAS_CALLBACK_MOUSE_OUT, 
+                                  _e_gadcon_cb_client_mouse_out, gcc);
+
+   if (gcc->o_frame)
+     {
+       evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOVE, 
+                                       _e_gadcon_cb_client_move, gcc);
+       evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_RESIZE, 
+                                       _e_gadcon_cb_client_resize, gcc);
+     }
+   else if (gcc->o_base)
+     {
+       evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOVE, 
+                                       _e_gadcon_cb_client_move, gcc);
+       evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_RESIZE, 
+                                       _e_gadcon_cb_client_resize, gcc);
+     }
+
+   evas_object_show(gcc->o_event);
+   evas_object_show(gcc->o_control);
+}
+
+EAPI void
+e_gadcon_client_edit_end(E_Gadcon_Client *gcc)
+{
+   Eina_List *l = NULL;
+   E_Gadcon_Client *client = NULL;
+
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (gcc->o_frame)
+     {
+       evas_object_event_callback_del(gcc->o_frame, EVAS_CALLBACK_MOVE, 
+                                       _e_gadcon_cb_client_move);
+       evas_object_event_callback_del(gcc->o_frame, EVAS_CALLBACK_RESIZE, 
+                                       _e_gadcon_cb_client_resize);
+     }
+   else if (gcc->o_base)
+     {
+       evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_MOVE, 
+                                       _e_gadcon_cb_client_move);
+       evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_RESIZE, 
+                                       _e_gadcon_cb_client_resize);
+     }
+
+   if (gcc->moving)
+     {
+       gcc->moving = 0;
+       _e_gadcon_client_save(gcc);
+     }
+   if (gcc->o_event) evas_object_del(gcc->o_event);
+   gcc->o_event = NULL;
+   if (gcc->o_control) evas_object_del(gcc->o_control);
+   gcc->o_control = NULL;
+
+   EINA_LIST_FOREACH(gcc->gadcon->clients, l, client)
+     {
+       if (!client) continue;
+       if (client->o_control) return;
+     }
+   gcc->gadcon->editing = 0;
+   e_gadcon_locked_set(gcc->gadcon, 0);
+}
+
+EAPI void
+e_gadcon_client_show(E_Gadcon_Client *gcc)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (!gcc->hidden) return;
+   if (gcc->o_box) evas_object_show(gcc->o_box);
+   if (gcc->o_frame) evas_object_show(gcc->o_frame);
+   if (gcc->o_base) evas_object_show(gcc->o_base);
+   if (gcc->o_control) evas_object_show(gcc->o_control);
+   if (gcc->o_event) evas_object_show(gcc->o_event);
+   if (gcc->o_frame)
+     {
+       e_gadcon_layout_pack(gcc->gadcon->o_container, gcc->o_frame);
+       e_gadcon_layout_pack_options_set(gcc->o_frame, gcc);
+     }
+   else if (gcc->o_base)
+     {
+       e_gadcon_layout_pack(gcc->gadcon->o_container, gcc->o_base);
+       e_gadcon_layout_pack_options_set(gcc->o_base, gcc);
+     }
+   gcc->hidden = 0;
+}
+
+EAPI void
+e_gadcon_client_hide(E_Gadcon_Client *gcc)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (gcc->hidden) return;
+   if (gcc->o_box) evas_object_hide(gcc->o_box);
+   if (gcc->o_frame) evas_object_hide(gcc->o_frame);
+   if (gcc->o_base) evas_object_hide(gcc->o_base);
+   if (gcc->o_control) evas_object_hide(gcc->o_control);
+   if (gcc->o_event) evas_object_hide(gcc->o_event);
+   if (gcc->o_frame)
+     e_gadcon_layout_unpack(gcc->o_frame);
+   else if (gcc->o_base)
+     e_gadcon_layout_unpack(gcc->o_base);
+   gcc->hidden = 1;
+}
+
+EAPI void
+e_gadcon_client_size_request(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   switch (gcc->gadcon->orient)
+     {
+      case E_GADCON_ORIENT_HORIZ:
+      case E_GADCON_ORIENT_TOP:
+      case E_GADCON_ORIENT_BOTTOM:
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_size_set(gcc->o_frame, w + gcc->pad.w);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_size_set(gcc->o_base, w);
+       break;
+      case E_GADCON_ORIENT_VERT:
+      case E_GADCON_ORIENT_LEFT:
+      case E_GADCON_ORIENT_RIGHT:
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_size_set(gcc->o_frame, h + gcc->pad.h);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_size_set(gcc->o_base, h);
+       break;
+      case E_GADCON_ORIENT_FLOAT:
+      case E_GADCON_ORIENT_CORNER_TL:
+      case E_GADCON_ORIENT_CORNER_TR:
+      case E_GADCON_ORIENT_CORNER_BL:
+      case E_GADCON_ORIENT_CORNER_BR:
+      case E_GADCON_ORIENT_CORNER_LT:
+      case E_GADCON_ORIENT_CORNER_RT:
+      case E_GADCON_ORIENT_CORNER_LB:
+      case E_GADCON_ORIENT_CORNER_RB:
+      default:
+       break;
+     }
+}
+
+EAPI void
+e_gadcon_client_min_size_set(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   gcc->min.w = w;
+   gcc->min.h = h;
+/*   if (!gcc->resizable)*/
+     {
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_min_size_set(gcc->o_frame, w + gcc->pad.w, 
+                                            h + gcc->pad.h);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_min_size_set(gcc->o_base, w, h);
+     }
+   _e_gadcon_moveresize_handle(gcc);
+}
+
+EAPI void
+e_gadcon_client_aspect_set(E_Gadcon_Client *gcc, int w, int h)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   gcc->aspect.w = w;
+   gcc->aspect.h = h;
+//   if ((!gcc->autoscroll)/* && (!gcc->resizable)*/)
+     {
+       if (gcc->o_frame)
+         {
+            e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w, 
+                                                 gcc->pad.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_frame, w, h);
+         }
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_aspect_set(gcc->o_base, w, h);
+     }
+   _e_gadcon_moveresize_handle(gcc);
+}
+
+EAPI void
+e_gadcon_client_autoscroll_set(E_Gadcon_Client *gcc, int autoscroll)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   gcc->autoscroll = autoscroll;
+   gcc->autoscroll_set = 1;
+/*   
+   if (gcc->autoscroll)
+     {
+       if (gcc->o_frame)
+         {
+            e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w, 
+                                                 gcc->pad.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_frame, 0, 0);
+            e_gadcon_layout_pack_min_size_set(gcc->o_frame, 0, 0);
+         }
+       else if (gcc->o_base)
+         {
+            e_gadcon_layout_pack_aspect_set(gcc->o_base, 0, 0);
+            e_gadcon_layout_pack_min_size_set(gcc->o_base, 0, 0);
+         }
+     }
+   else
+ */
+     {
+       if (gcc->o_frame)
+         {
+            e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w, 
+                                                 gcc->pad.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_frame, gcc->aspect.w, 
+                                             gcc->aspect.h);
+            e_gadcon_layout_pack_min_size_set(gcc->o_frame, gcc->min.w, 
+                                               gcc->min.h);
+         }
+       else if (gcc->o_base)
+         {
+            e_gadcon_layout_pack_min_size_set(gcc->o_base, gcc->min.w, 
+                                               gcc->min.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_base, gcc->aspect.w, 
+                                             gcc->aspect.h);
+         }
+     }
+}
+    
+EAPI void
+e_gadcon_client_resizable_set(E_Gadcon_Client *gcc, int resizable)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+/*
+   gcc->resizable = resizable;
+   if (gcc->resizable)
+     {
+       if (gcc->o_frame)
+         {
+            e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w, 
+                                                 gcc->pad.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_frame, 0, 0);
+            e_gadcon_layout_pack_min_size_set(gcc->o_frame, 0, 0);
+         }
+       else if (gcc->o_base)
+         {
+            e_gadcon_layout_pack_min_size_set(gcc->o_base, 0, 0);
+            e_gadcon_layout_pack_aspect_set(gcc->o_base, 0, 0);
+         }
+     }
+   else
+     {
+       if (gcc->o_frame)
+         {
+            e_gadcon_layout_pack_aspect_pad_set(gcc->o_frame, gcc->pad.w, 
+                                                 gcc->pad.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_frame, gcc->aspect.w, 
+                                             gcc->aspect.h);
+            e_gadcon_layout_pack_min_size_set(gcc->o_frame, gcc->min.w, 
+                                               gcc->min.h);
+         }
+       else if (gcc->o_base)
+         {
+            e_gadcon_layout_pack_min_size_set(gcc->o_base, gcc->min.w, 
+                                               gcc->min.h);
+            e_gadcon_layout_pack_aspect_set(gcc->o_base, gcc->aspect.w, 
+                                             gcc->aspect.h);
+         }
+     }
+ */
+   resizable = 0;
+   gcc = NULL;
+}
+
+EAPI int
+e_gadcon_client_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h)
+{
+   int gx = 0, gy = 0;
+
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   if (!e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &gx, &gy, NULL, NULL)) 
+     return 0;
+   if (gcc->o_base) evas_object_geometry_get(gcc->o_base, x, y, w, h);
+   if (x) *x += gx;
+   if (y) *y += gy;
+   return 1;
+}
+
+EAPI int
+e_gadcon_client_viewport_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (gcc->o_box) evas_object_geometry_get(gcc->o_base, x, y, w, h);
+   else if (gcc->o_base) evas_object_geometry_get(gcc->o_base, x, y, w, h);
+   else
+     {
+        if (x) *x = 0;
+        if (y) *y = 0;
+        if (w) *w = 0;
+        if (h) *h = 0;
+     }
+   return 1;
+}
+
+EAPI E_Zone *
+e_gadcon_client_zone_get(E_Gadcon_Client *gcc)
+{
+   E_OBJECT_CHECK_RETURN(gcc, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(gcc, E_GADCON_CLIENT_TYPE, NULL);
+   return e_gadcon_zone_get(gcc->gadcon);
+}
+
+static void
+_e_gadcon_client_change_gadcon(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi)
+{
+   E_Gadcon_Location *src, *dst;
+   E_Gadcon_Client * gcc;
+
+   gcc = data;
+   src = gcc->gadcon->location;
+   dst = e_object_data_get(E_OBJECT(mi));
+   _e_gadcon_location_change(gcc, src, dst);
+}
+
+static void
+_e_gadcon_add_locations_menu_for_site(E_Menu *m, E_Gadcon_Client *gcc, E_Gadcon_Site site, int * count)
+{
+   E_Menu_Item *mi;
+   const Eina_List *l;
+   E_Gadcon_Location * loc;
+   int k = *count;
+
+   EINA_LIST_FOREACH(gadcon_locations, l, loc)
+     {
+       if (loc->site == site)
+         {
+             if (k)
+               {
+                  k = 0;
+                  mi = e_menu_item_new(m);
+                  e_menu_item_separator_set(mi, 1);
+                  (*count) = 0;
+               }
+             mi = e_menu_item_new(m);
+             e_menu_item_label_set(mi, loc->name);
+             e_object_data_set(E_OBJECT(mi), loc);
+             e_menu_item_callback_set(mi, _e_gadcon_client_change_gadcon, gcc);
+             if (loc == gcc->gadcon->location) e_menu_item_disabled_set(mi, 1);
+             if (loc->icon_name) 
+               e_util_menu_item_theme_icon_set(mi, loc->icon_name);
+             (*count)++;
+         }
+     }
+}
+
+static void 
+_e_gadcon_gadget_move_to_pre_cb(void *data, E_Menu *m) 
+{
+   E_Gadcon_Client *gcc;
+   int n = 0;
+
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+   gcc = data;
+
+   if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_SHELF))
+     _e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_SHELF, &n);
+   if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_DESKTOP))
+     _e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_DESKTOP, &n);
+   if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_TOOLBAR))
+     _e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_TOOLBAR, &n);
+   if (!gcc->client_class->func.is_site || gcc->client_class->func.is_site(E_GADCON_SITE_EFM_TOOLBAR))
+     _e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_EFM_TOOLBAR, &n);
+   _e_gadcon_add_locations_menu_for_site(m, gcc, E_GADCON_SITE_UNKNOWN, &n);
+}
+
+EAPI void
+e_gadcon_client_add_location_menu(E_Gadcon_Client *gcc, E_Menu *menu)
+{
+   E_Menu *mn;
+   E_Menu_Item *mi;
+
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (gcc->gadcon->location)
+     {
+       mn = e_menu_new();
+       mi = e_menu_item_new(menu);
+       e_menu_item_label_set(mi, _("Move to"));
+       e_util_menu_item_theme_icon_set(mi, "preferences-look");
+       e_menu_item_submenu_set(mi, mn);
+       e_menu_pre_activate_callback_set(mn, _e_gadcon_gadget_move_to_pre_cb, gcc);
+     }
+}
+
+EAPI E_Menu *
+e_gadcon_client_util_menu_items_append(E_Gadcon_Client *gcc, E_Menu *menu_gadget, int flags __UNUSED__)
+{
+   E_Menu *mo, *menu_main = NULL;
+   E_Menu_Item *mi;
+   char buf[256];
+
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (e_config->menu_gadcon_client_toplevel)
+     menu_main = menu_gadget;
+   else
+     menu_main = e_menu_new();
+   
+   if ((gcc->gadcon->shelf))
+     {
+        if (e_menu_item_nth(menu_gadget, 0))
+          {
+             mi = e_menu_item_new(menu_gadget);
+             e_menu_item_separator_set(mi, 1);
+          }
+       if (!gcc->o_control)
+         {
+             mi = e_menu_item_new(menu_gadget);
+             e_menu_item_label_set(mi, _("Move"));
+             e_util_menu_item_theme_icon_set(mi, "transform-scale");
+             e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_edit, gcc);
+         }
+/*
+       mi = e_menu_item_new(menu_gadget);
+       e_menu_item_label_set(mi, _("Resizeable"));
+       e_util_menu_item_theme_icon_set(mi, "transform-scale");
+       e_menu_item_check_set(mi, 1);
+       if (gcc->resizable) e_menu_item_toggle_set(mi, 1);
+       e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_resizable, gcc);
+ */
+       mi = e_menu_item_new(menu_gadget);
+       e_menu_item_label_set(mi, _("Automatically scroll contents"));
+       e_util_menu_item_theme_icon_set(mi, "transform-move");
+       e_menu_item_check_set(mi, 1);
+       if (gcc->autoscroll) e_menu_item_toggle_set(mi, 1);
+       e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_autoscroll, gcc);
+
+        if (gcc->gadcon->shelf) 
+          {
+             mo = e_menu_new();
+
+             mi = e_menu_item_new(mo);
+             e_menu_item_label_set(mi, _("Plain"));
+             e_util_menu_item_theme_icon_set(mi, "enlightenment/plain");
+             e_menu_item_radio_group_set(mi, 1);
+             e_menu_item_radio_set(mi, 1);
+             if ((gcc->style) && (!strcmp(gcc->style, E_GADCON_CLIENT_STYLE_PLAIN)))
+               e_menu_item_toggle_set(mi, 1);
+             e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_style_plain, gcc);
+
+             mi = e_menu_item_new(mo);
+             e_menu_item_label_set(mi, _("Inset"));
+             e_util_menu_item_theme_icon_set(mi, "enlightenment/inset");
+             e_menu_item_radio_group_set(mi, 1);
+             e_menu_item_radio_set(mi, 1);
+             if ((gcc->style) && (!strcmp(gcc->style, E_GADCON_CLIENT_STYLE_INSET)))
+               e_menu_item_toggle_set(mi, 1);
+             e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_style_inset, gcc);
+
+             mi = e_menu_item_new(menu_gadget);
+             e_menu_item_label_set(mi, _("Look"));
+             e_util_menu_item_theme_icon_set(mi, "preferences-look");
+             e_menu_item_submenu_set(mi, mo);
+          }
+
+       mi = e_menu_item_new(menu_gadget);
+       e_menu_item_separator_set(mi, 1);
+
+       e_gadcon_client_add_location_menu(gcc, menu_gadget);
+
+       mi = e_menu_item_new(menu_gadget);
+       e_menu_item_label_set(mi, _("Remove"));
+       e_util_menu_item_theme_icon_set(mi, "list-remove");
+       e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_remove, gcc);
+     }
+
+   if (!e_config->menu_gadcon_client_toplevel)
+     {
+       mi = e_menu_item_new(menu_main);
+       if (gcc->client_class->func.label)
+         snprintf(buf, sizeof(buf), "%s", 
+                  gcc->client_class->func.label((E_Gadcon_Client_Class *)gcc->client_class));
+       else
+         snprintf(buf, sizeof(buf), "%s", gcc->name);
+
+       e_menu_item_label_set(mi, _(buf));
+       e_menu_item_realize_callback_set(mi, _e_gadcon_client_cb_menu_pre, gcc);
+       e_menu_item_submenu_set(mi, menu_gadget);
+     }
+   
+   if (gcc->gadcon->menu_attach.func)
+     {
+        if ((gcc->gadcon->shelf))
+         {
+            if (e_config->menu_gadcon_client_toplevel)
+              {
+                 mi = e_menu_item_new(menu_main);
+                 e_menu_item_separator_set(mi, 1);     
+              }             
+            gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data, gcc, menu_main);
+         }     
+        else
+          gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data, gcc, menu_gadget);
+     }
+   
+   return menu_main;
+}
+    
+EAPI void
+e_gadcon_client_util_menu_attach(E_Gadcon_Client *gcc)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   if (gcc->o_frame)
+     {
+       evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_DOWN, 
+                                       _e_gadcon_client_cb_mouse_down, gcc);
+       evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_UP, 
+                                       _e_gadcon_client_cb_mouse_up, gcc);
+       evas_object_event_callback_add(gcc->o_frame, EVAS_CALLBACK_MOUSE_MOVE, 
+                                       _e_gadcon_client_cb_mouse_move, gcc);
+     }
+   else if (gcc->o_base)
+     {
+       evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_DOWN, 
+                                       _e_gadcon_client_cb_mouse_down, gcc);
+       evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_UP, 
+                                       _e_gadcon_client_cb_mouse_up, gcc);
+       evas_object_event_callback_add(gcc->o_base, EVAS_CALLBACK_MOUSE_MOVE, 
+                                       _e_gadcon_client_cb_mouse_move, gcc);
+     }
+}
+
+EAPI void
+e_gadcon_locked_set(E_Gadcon *gc, int lock)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   if (gc->locked_set.func)
+     gc->locked_set.func(gc->locked_set.data, lock);
+}
+
+EAPI void
+e_gadcon_urgent_show(E_Gadcon *gc)
+{
+   E_OBJECT_CHECK(gc);
+   E_OBJECT_TYPE_CHECK(gc, E_GADCON_TYPE);
+   if (gc->urgent_show.func)
+     gc->urgent_show.func(gc->urgent_show.data);
+}
+
+/*
+ * NOTE: x & y are relative to the o_box of the gadcon.
+ */
+EAPI void
+e_gadcon_client_autoscroll_update(E_Gadcon_Client *gcc, Evas_Coord x, Evas_Coord y)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+
+   if (gcc->autoscroll)
+     {
+       Evas_Coord w, h;
+       double d;
+
+        /* TODO: When using gadman there is no o_box! */
+       evas_object_geometry_get(gcc->o_box, NULL, NULL, &w, &h);
+        if (e_box_orientation_get(gcc->o_box))
+         {
+            if (w > 1) d = (double)x / (double)(w - 1);
+            else d = 0;
+         }
+       else
+         {
+            if (h > 1) d = (double)y / (double)(h - 1);
+            else d = 0;
+         }
+       if (d < 0.0) d = 0.0;
+       else if (d > 1.0) d = 1.0;
+       if (!gcc->scroll_timer)
+         gcc->scroll_timer = 
+          ecore_timer_add(0.01, _e_gadcon_cb_client_scroll_timer, gcc);
+       if (!gcc->scroll_animator)
+         gcc->scroll_animator = 
+          ecore_animator_add(_e_gadcon_cb_client_scroll_animator, gcc);
+       gcc->scroll_wanted = d;
+     }
+}
+
+EAPI void
+e_gadcon_client_autoscroll_cb_set(E_Gadcon_Client *gcc, void (*func)(void *data), void *data)
+{
+   E_OBJECT_CHECK(gcc);
+   E_OBJECT_TYPE_CHECK(gcc, E_GADCON_CLIENT_TYPE);
+   gcc->scroll_cb.func = func;
+   gcc->scroll_cb.data = data;
+}
+
+EAPI Eina_Bool
+e_gadcon_site_is_shelf(E_Gadcon_Site site)
+{
+   return (site == E_GADCON_SITE_SHELF);
+}
+
+EAPI Eina_Bool
+e_gadcon_site_is_desktop(E_Gadcon_Site site)
+{
+   return (site == E_GADCON_SITE_DESKTOP);
+}
+
+EAPI Eina_Bool
+e_gadcon_site_is_efm_toolbar(E_Gadcon_Site site)
+{
+   return (site == E_GADCON_SITE_EFM_TOOLBAR);
+}
+
+EAPI Eina_Bool
+e_gadcon_site_is_any_toolbar(E_Gadcon_Site site)
+{
+   switch (site)
+     {
+        // there should be all toolbar sities identifiers
+      case E_GADCON_SITE_TOOLBAR:
+      case E_GADCON_SITE_EFM_TOOLBAR:
+        return EINA_TRUE;
+      default:
+        return EINA_FALSE;
+     }
+   return EINA_FALSE;
+}
+
+EAPI Eina_Bool
+e_gadcon_site_is_not_toolbar(E_Gadcon_Site site)
+{
+   switch (site)
+     {
+        // there should be all toolbar sities identifiers
+      case E_GADCON_SITE_TOOLBAR:
+      case E_GADCON_SITE_EFM_TOOLBAR:
+        return EINA_FALSE;
+      default:
+        return EINA_TRUE;
+     }
+   return EINA_TRUE;
+}
+
+/* local subsystem functions */
+static void
+_e_gadcon_free(E_Gadcon *gc)
+{
+   e_gadcon_unpopulate(gc);
+   gadcons = eina_list_remove(gadcons, gc);
+   if (gc->o_container) evas_object_del(gc->o_container);
+   eina_stringshare_del(gc->name);
+   eina_stringshare_del(gc->edje.swallow_name);
+   if (gc->config_dialog) e_object_del(E_OBJECT(gc->config_dialog));
+   /* if (gc->drop_handler) e_drop_handler_del(gc->drop_handler); */
+   free(gc);
+}
+
+static void
+_e_gadcon_client_free(E_Gadcon_Client *gcc)
+{
+   if (gcc->instant_edit_timer)
+     {
+       ecore_timer_del(gcc->instant_edit_timer);
+       gcc->instant_edit_timer = NULL;
+     }
+   if (gcc->o_base)
+     evas_object_event_callback_del(gcc->o_base, EVAS_CALLBACK_DEL,
+                                   _e_gadcon_client_del_hook);
+   if (gcc->menu)
+     {
+        e_menu_post_deactivate_callback_set(gcc->menu, NULL, NULL);
+       e_object_del(E_OBJECT(gcc->menu));
+       gcc->menu = NULL;
+     }
+   e_gadcon_client_edit_end(gcc);
+   gcc->client_class->func.shutdown(gcc);
+   if ((gcc->client_class->func.id_del) && (gcc->cf))
+     gcc->client_class->func.id_del((E_Gadcon_Client_Class *)gcc->client_class,
+                                    gcc->cf->id);
+   gcc->gadcon->clients = eina_list_remove(gcc->gadcon->clients, gcc);
+   if (gcc->o_box) evas_object_del(gcc->o_box);
+   if (gcc->o_frame) evas_object_del(gcc->o_frame);
+   eina_stringshare_del(gcc->name);
+   if (gcc->scroll_timer) ecore_timer_del(gcc->scroll_timer);
+   if (gcc->scroll_animator) ecore_animator_del(gcc->scroll_animator);
+   if (gcc->style) eina_stringshare_del(gcc->style);
+   free(gcc);
+}
+
+static void
+_e_gadcon_moveresize_handle(E_Gadcon_Client *gcc)
+{
+   Evas_Coord w, h;
+
+   evas_object_geometry_get(gcc->o_box, NULL, NULL, &w, &h);
+/*   
+   if (gcc->resizable)
+     {
+       if (e_box_orientation_get(gcc->o_box))
+         {
+            if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
+              w = (h * gcc->aspect.w) / gcc->aspect.h;
+         }
+       else
+         {
+            if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
+              h = (w * gcc->aspect.h) / gcc->aspect.w;
+         }
+     }
+ */
+   if (gcc->autoscroll)
+     {
+       if (e_box_orientation_get(gcc->o_box))
+         {
+             if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
+               {
+                  w = (h * gcc->aspect.w) / gcc->aspect.h; // ZZZZ
+//                  w = gcc->min.w;
+               }
+             else
+               {
+                  w = gcc->min.w;
+               }
+         }
+       else
+         {
+             if ((gcc->aspect.w > 0) && (gcc->aspect.h > 0))
+               {
+                  h = (w * gcc->aspect.h) / gcc->aspect.w; // ZZZZ
+//                  h = gcc->min.h;
+               }
+             else
+               {
+                  h = gcc->min.h;
+               }
+         }
+     }
+   if (gcc->o_base)
+     e_box_pack_options_set(gcc->o_base,
+                            1, 1, /* fill */
+                            1, 1, /* expand */
+                            0.5, 0.5, /* align */
+                            w, h, /* min */
+                            w, h /* max */
+                           );
+}
+
+static Eina_Bool
+_e_gadcon_cb_client_scroll_timer(void *data)
+{
+   E_Gadcon_Client *gcc;
+   double d, v;
+
+   gcc = data;
+   d = gcc->scroll_wanted - gcc->scroll_pos;
+   if (d < 0) d = -d;
+   if (d < 0.001)
+     {
+       gcc->scroll_pos =  gcc->scroll_wanted;
+       gcc->scroll_timer = NULL;
+       return ECORE_CALLBACK_CANCEL;
+     }
+   v = 0.05;
+   gcc->scroll_pos = (gcc->scroll_pos * (1.0 - v)) + (gcc->scroll_wanted * v);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_e_gadcon_cb_client_scroll_animator(void *data)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   if (e_box_orientation_get(gcc->o_box))
+     e_box_align_set(gcc->o_box, 1.0 - gcc->scroll_pos, 0.5);
+   else
+     e_box_align_set(gcc->o_box, 0.5, 1.0 - gcc->scroll_pos);
+   if (!gcc->scroll_timer)
+     {
+       gcc->scroll_animator = NULL;
+       return ECORE_CALLBACK_CANCEL;
+     }
+
+   if (gcc->scroll_cb.func)
+     gcc->scroll_cb.func(gcc->scroll_cb.data);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_gadcon_cb_client_frame_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Move *ev;
+   E_Gadcon_Client *gcc;
+   Evas_Coord x, y;
+
+   ev = event_info;
+   gcc = data;
+   evas_object_geometry_get(gcc->o_box, &x, &y, NULL, NULL);
+   e_gadcon_client_autoscroll_update(gcc, ev->cur.output.x - x, 
+                                     ev->cur.output.y - y);
+}
+
+static void
+_e_gadcon_cb_client_frame_moveresize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   _e_gadcon_moveresize_handle(gcc);
+}
+    
+static void
+_e_gadcon_client_save(E_Gadcon_Client *gcc)
+{
+   gcc->cf->geom.pos = gcc->config.pos;
+   gcc->cf->geom.size = gcc->config.size;
+   gcc->cf->geom.res = gcc->config.res;
+   gcc->cf->geom.pos_x = gcc->config.pos_x;
+   gcc->cf->geom.pos_y = gcc->config.pos_y;
+   gcc->cf->geom.size_w = gcc->config.size_w;
+   gcc->cf->geom.size_h = gcc->config.size_h;
+   gcc->cf->state_info.seq = gcc->state_info.seq;
+   gcc->cf->state_info.flags = gcc->state_info.flags;
+   gcc->cf->autoscroll = gcc->autoscroll;
+   if (gcc->cf->style) eina_stringshare_del(gcc->cf->style);
+   gcc->cf->style = NULL;
+   if (gcc->style)
+     gcc->cf->style = eina_stringshare_add(gcc->style);
+/*   gcc->cf->resizable = gcc->resizable;*/
+   gcc->cf->resizable = 0;
+   e_config_save_queue();
+}
+
+static void
+_e_gadcon_client_drag_begin(E_Gadcon_Client *gcc, int x, int y)
+{
+   /* E_Drag *drag; */
+   Evas_Object *o = NULL;
+   Evas_Coord w = 0, h = 0;
+   const char *drag_types[] = { "enlightenment/gadcon_client" };
+
+   if ((drag_gcc) || (!gcc->gadcon->zone) || (!gcc->gadcon->zone->container))
+     return;
+
+   drag_gcc = gcc;
+
+   e_object_ref(E_OBJECT(gcc));
+   /* Remove this config from the current gadcon */
+   gcc->gadcon->cf->clients = 
+     eina_list_remove(gcc->gadcon->cf->clients, gcc->cf);
+   gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
+   gcc->state_info.resist = 0;
+
+   /* if (!e_drop_inside(gcc->gadcon->drop_handler, x, y)) */
+   /*   e_gadcon_client_hide(gcc); */
+
+   ecore_wl_pointer_xy_get(&x, &y);
+   
+   /* drag = e_drag_new(gcc->gadcon->zone->container, x, y, */
+   /*               drag_types, 1, gcc, -1, NULL,  */
+   /*               _e_gadcon_cb_drag_finished); */
+   /* if (drag)  */
+   /*   { */
+   /*  o = gcc->client_class->func.icon((E_Gadcon_Client_Class *)gcc->client_class,  */
+   /*                                       e_drag_evas_get(drag)); */
+   /*  evas_object_geometry_get(o, NULL, NULL, &w, &h); */
+   /*  if (!o) */
+   /*    { */
+   /*       o = evas_object_rectangle_add(e_drag_evas_get(drag)); */
+   /*       evas_object_color_set(o, 255, 255, 255, 100); */
+   /*    } */
+   /*  if (w < 10) */
+   /*        w = h = 50; */
+   /*  e_drag_object_set(drag, o); */
+   /*  e_drag_resize(drag, w, h); */
+   /*  e_drag_start(drag, x + w/2, y + h/2); */
+   /*   } */
+}
+
+/* static void */
+/* _e_gadcon_client_inject(E_Gadcon *gc, E_Gadcon_Client *gcc, int x, int y) */
+/* { */
+/*    Eina_List *l; */
+/*    E_Gadcon_Client *gcc2; */
+/*    Evas_Coord cx, cy, cw, ch; */
+/*    int seq = 1; */
+
+/*    if (!gcc->hidden) */
+/*      { */
+/*     if (gcc->o_frame) */
+/*       evas_object_geometry_get(gcc->o_frame, &cx, &cy, &cw, &ch); */
+/*     else if (gcc->o_base) */
+/*       evas_object_geometry_get(gcc->o_base, &cx, &cy, &cw, &ch); */
+/*     else return; */
+
+/*     if (E_INSIDE(x, y, cx, cy, cw, ch)) return; */
+/*      } */
+
+/*    gcc->state_info.seq = 0; */
+/*    EINA_LIST_FOREACH(gc->clients, l, gcc2) */
+/*      { */
+/*     if (gcc == gcc2) continue; */
+/*     if (gcc2->hidden) continue; */
+/*     if (gcc2->o_frame) */
+/*       evas_object_geometry_get(gcc2->o_frame, &cx, &cy, &cw, &ch); */
+/*     else if (gcc2->o_base) */
+/*       evas_object_geometry_get(gcc2->o_base, &cx, &cy, &cw, &ch); */
+/*     else return; */
+/*     if (e_gadcon_layout_orientation_get(gc->o_container)) */
+/*       { */
+/*          if (E_INSIDE(x, y, cx, cy, cw / 2, ch)) */
+/*            { */
+/*               gcc->state_info.seq = seq++; */
+/*               gcc2->state_info.seq = seq++; */
+/*            } */
+/*          else if (E_INSIDE(x, y, cx + cw / 2, cy, cw / 2, ch)) */
+/*            { */
+/*               gcc2->state_info.seq = seq++; */
+/*               gcc->state_info.seq = seq++; */
+/*            } */
+/*          else */
+/*                gcc2->state_info.seq = seq++; */
+/*       } */
+/*     else */
+/*       { */
+/*          if (E_INSIDE(x, y, cx, cy, cw, ch / 2)) */
+/*            { */
+/*               gcc->state_info.seq = seq++; */
+/*               gcc2->state_info.seq = seq++; */
+/*            } */
+/*          else if (E_INSIDE(x, y, cx, cy + ch / 2, cw, ch / 2)) */
+/*            { */
+/*               gcc2->state_info.seq = seq++; */
+/*               gcc->state_info.seq = seq++; */
+/*            } */
+/*          else */
+/*                gcc2->state_info.seq = seq++; */
+/*       } */
+/*      } */
+/* } */
+
+static void
+_e_gadcon_cb_min_size_request(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon *gc;
+
+   gc = data;
+   if (gc->min_size_request.func)
+     {
+       Evas_Coord w = 0, h = 0;
+
+       e_gadcon_layout_min_size_get(gc->o_container, &w, &h);
+       gc->min_size_request.func(gc->min_size_request.data, gc, w, h);
+     }
+}
+
+static void
+_e_gadcon_cb_size_request(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon *gc;
+
+   gc = data;
+   if (gc->resize_request.func)
+     {
+       Evas_Coord w = 0, h = 0;
+
+       e_gadcon_layout_asked_size_get(gc->o_container, &w, &h);
+       gc->resize_request.func(gc->resize_request.data, gc, w, h);
+     }
+}
+
+static void
+_e_gadcon_cb_moveresize(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon *gc;
+   Evas_Coord x, y, w, h;
+
+   gc = data;
+   evas_object_geometry_get(gc->o_container, &x, &y, &w, &h);
+   /* if (gc->drop_handler)  */
+   /*   e_drop_handler_geometry_set(gc->drop_handler, x, y, w, h); */
+}
+
+static void
+_e_gadcon_cb_client_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev;
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   ev = event_info;
+   if (ev->button == 3)
+     {
+       E_Zone *zone;
+       E_Menu *mn;
+       E_Menu_Item *mi;
+       int cx, cy;
+
+       zone = e_util_zone_current_get(e_manager_current_get());
+
+       e_gadcon_locked_set(gcc->gadcon, 1);
+       mn = e_menu_new();
+       e_menu_post_deactivate_callback_set(mn, _e_gadcon_client_cb_menu_post,
+                                           gcc);
+       gcc->menu = mn;
+
+       mi = e_menu_item_new(mn);
+       e_menu_item_label_set(mi, _("Stop moving"));
+       e_util_menu_item_theme_icon_set(mi, "enlightenment/edit");
+       e_menu_item_callback_set(mi, _e_gadcon_client_cb_menu_edit, gcc);
+
+       if (gcc->gadcon->menu_attach.func)
+         {
+            mi = e_menu_item_new(mn);
+            e_menu_item_separator_set(mi, 1);
+
+            gcc->gadcon->menu_attach.func(gcc->gadcon->menu_attach.data, 
+                                           gcc, mn);
+         }
+
+       /* if (gcc->gadcon->toolbar) */
+       /*   ecore_x_pointer_xy_get(zone->container->win, &cx, &cy); */
+       /* else */ 
+         {
+            e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, NULL, NULL);
+            cx = cx + ev->output.x;
+            cy = cy + ev->output.y;
+         }
+       e_menu_activate_mouse(mn, zone, cx, cy, 1, 1, 
+                             E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
+     }
+}
+
+static void
+_e_gadcon_cb_client_mouse_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   edje_object_signal_emit(gcc->o_control, "e,state,focused", "e");
+}
+
+static void
+_e_gadcon_cb_client_mouse_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   edje_object_signal_emit(gcc->o_control, "e,state,unfocused", "e");
+}
+
+static void
+_e_gadcon_cb_client_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   Evas_Coord x, y;
+
+   gcc = data;
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   if (gcc->o_control) evas_object_move(gcc->o_control, x, y);
+   if (gcc->o_event) evas_object_move(gcc->o_event, x, y);
+}
+
+static void
+_e_gadcon_cb_client_resize(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   Evas_Coord w, h;
+
+   gcc = data;
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (gcc->o_control) evas_object_resize(gcc->o_control, w, h);
+   if (gcc->o_event) evas_object_resize(gcc->o_event, w, h);
+}
+
+static void
+_e_gadcon_client_move_start(E_Gadcon_Client *gcc)
+{
+   int x, y, gcx, gcy, gy ,gx;
+   
+   evas_object_raise(gcc->o_event);
+   evas_object_stack_below(gcc->o_control, gcc->o_event);
+   gcc->moving = 1;
+   /* if (gcc->gadcon->toolbar) */
+   /*   evas_pointer_canvas_xy_get(gcc->gadcon->evas, &gcc->dx, &gcc->dy); */
+   /* else */
+     {
+       ecore_wl_pointer_xy_get(&gcc->dx, &gcc->dy);
+       e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &gcx, &gcy, NULL, NULL);
+       evas_object_geometry_get(gcc->gadcon->o_container, &gx, &gy, NULL, NULL);
+       gcc->dx -= (gcx + gx);
+       gcc->dy -= (gcy + gy);
+     }
+   
+   if (gcc->o_frame)
+     evas_object_geometry_get(gcc->o_frame, &x, &y, NULL, NULL);
+   else if (gcc->o_base)
+     evas_object_geometry_get(gcc->o_base, &x, &y, NULL, NULL);
+   else
+     return;
+
+   /* using drag pos to calc offset between pointer and gcc pos */
+   gcc->drag.x = (x - gcc->dx);
+   gcc->drag.y = (y - gcc->dy);
+
+   gcc->state_info.resist = 0;
+}
+
+static void
+_e_gadcon_client_move_stop(E_Gadcon_Client *gcc)
+{
+   gcc->moving = 0;
+   gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
+   gcc->state_info.resist = 0;
+   _e_gadcon_layout_smart_sync_clients(gcc->gadcon);
+}
+
+static void
+_e_gadcon_client_move_go(E_Gadcon_Client *gcc)
+{
+   Evas_Coord x, y, w, h;
+   int cx, cy;
+   int gx, gy, gw, gh;
+   int gcx = 0, gcy = 0;
+   int changes = 0;
+   
+   if (!gcc->moving) return;
+   /* we need to get output not canvas because things like systray
+      can reparent another window so we get no position here */
+   /* maybe we should better grab mouse while move resize is active...*/
+   //evas_pointer_canvas_xy_get(gcc->gadcon->evas, &cx, &cy);
+   /* if (gcc->gadcon->toolbar) */
+   /*   evas_pointer_canvas_xy_get(gcc->gadcon->evas, &cx, &cy); */
+   /* else */
+     {
+       ecore_wl_pointer_xy_get(&cx, &cy);
+       e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &gcx, &gcy, NULL, NULL);
+     }
+   
+   evas_object_geometry_get(gcc->gadcon->o_container, &gx, &gy, &gw, &gh);
+
+   cx -= (gx + gcx);
+   cy -= (gy + gcy);
+   
+   x = cx - gcc->dx;
+   y = cy - gcc->dy; 
+   
+   gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION | E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+   _e_gadcon_client_current_position_sync(gcc);
+
+   if (gcc->o_frame)
+     evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
+   else if (gcc->o_base)
+     evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
+   else
+     return; /* make clang happy */
+
+   if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
+     { 
+       if (cy + e_config->drag_resist < 0 || cy - e_config->drag_resist > gh)
+         {
+            _e_gadcon_client_drag_begin(gcc, cx, cy);
+            return;
+         }
+
+       if (x > 0 && (cx + gcc->drag.x > gcc->config.pos))
+         {
+            if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_INC)
+              gcc->state_info.resist = 0;
+            gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_INC;
+            changes = 1;
+         }
+       else if (x < 0 && (cx + gcc->drag.x < gcc->config.pos))
+         {
+            if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_DEC)
+              gcc->state_info.resist = 0; 
+            gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_DEC;
+            changes = 1;
+         }
+
+       if (changes)
+         {
+            if (gcc->o_frame)
+              e_gadcon_layout_pack_request_set(gcc->o_frame, cx + gcc->drag.x, w);
+            else if (gcc->o_base)
+              e_gadcon_layout_pack_request_set(gcc->o_base, cx + gcc->drag.x, w);
+
+            gcc->config.size = w;
+            evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+            gcc->config.res = w;
+         }
+     }
+   else
+     {
+       if (cx + e_config->drag_resist < 0 || cx - e_config->drag_resist > gw)
+         {
+            _e_gadcon_client_drag_begin(gcc, cx, cy);
+            return;
+         }
+
+       if (y > 0 && (cy + gcc->drag.y > gcc->config.pos))
+         {
+            if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_INC)
+              gcc->state_info.resist = 0;
+            gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_INC;
+            changes = 1;
+         }
+       else if (y < 0 && (cy + gcc->drag.y < gcc->config.pos))
+         {
+            if (gcc->state_info.state != E_LAYOUT_ITEM_STATE_POS_DEC)
+              gcc->state_info.resist = 0;
+            gcc->state_info.state = E_LAYOUT_ITEM_STATE_POS_DEC;
+            changes = 1;
+         }
+
+       if (changes)
+         {
+            if (gcc->o_frame)
+              e_gadcon_layout_pack_request_set(gcc->o_frame, cy + gcc->drag.y, h);
+            else if (gcc->o_base)
+              e_gadcon_layout_pack_request_set(gcc->o_base, cy + gcc->drag.y, h);
+
+            gcc->config.size = h;
+            evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+            gcc->config.res = h;
+         }
+
+     }
+   
+   gcc->dx += x;
+   gcc->dy += y;
+}
+
+static void
+_e_gadcon_cb_signal_move_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadcon_client_move_start(data);
+}
+
+static void
+_e_gadcon_cb_signal_move_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadcon_client_move_stop(data);
+}
+
+static void
+_e_gadcon_cb_signal_move_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadcon_client_move_go(data);
+}
+
+static void
+_e_gadcon_client_resize_start(E_Gadcon_Client *gcc)
+{
+   evas_object_raise(gcc->o_event);
+   evas_object_stack_below(gcc->o_control, gcc->o_event);
+   gcc->resizing = 1;
+   evas_pointer_canvas_xy_get(gcc->gadcon->evas, &gcc->dx, &gcc->dy);
+}
+
+static void
+_e_gadconclient_resize_stop(E_Gadcon_Client *gcc)
+{
+   gcc->resizing = 0;
+   gcc->state_info.state = E_LAYOUT_ITEM_STATE_NONE;
+   _e_gadcon_layout_smart_sync_clients(gcc->gadcon);
+   _e_gadcon_client_save(gcc);
+}
+
+static void
+_e_gadcon_cb_signal_resize_left_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadcon_client_resize_start(data);
+}
+
+static void
+_e_gadcon_cb_signal_resize_left_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadconclient_resize_stop(data);
+}
+
+static void
+_e_gadcon_cb_signal_resize_left_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   Evas_Coord x, y, w, h;
+
+   gcc = data;
+   if (!gcc->resizing) return;
+   evas_pointer_canvas_xy_get(gcc->gadcon->evas, &x, &y);
+   x = x - gcc->dx;
+   y = y - gcc->dy;
+
+   gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION | 
+     E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+
+   if (gcc->o_frame)
+     evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
+   else if (gcc->o_base)
+     evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
+   else return; /* make clang happy */
+
+   _e_gadcon_client_current_position_sync(gcc);
+
+   if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
+     {
+       if (x > 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC;
+       else if (x < 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC;
+     }
+   else
+     {
+       if (y > 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC;
+       else if (y < 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC;
+     }
+
+   if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
+     {
+       if (gcc->o_frame) 
+         e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos + x, w - x);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos + x, w - x);
+       evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+       gcc->config.res = w;
+     }
+   else
+     {
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos + y, h - y);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos + y, h - y);
+       evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+       gcc->config.res = h;
+     }
+   gcc->dx += x;
+   gcc->dy += y;
+}
+
+static void
+_e_gadcon_cb_signal_resize_right_start(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadcon_client_resize_start(data);
+}
+
+static void
+_e_gadcon_cb_signal_resize_right_stop(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   _e_gadconclient_resize_stop(data);
+}
+
+static void
+_e_gadcon_cb_signal_resize_right_go(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   Evas_Coord x, y, w, h;
+
+   gcc = data;
+   if (!gcc->resizing) return;
+   evas_pointer_canvas_xy_get(gcc->gadcon->evas, &x, &y);
+   x = x - gcc->dx;
+   y = y - gcc->dy;
+
+   gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_POSITION | 
+     E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+
+   if (gcc->o_frame)
+     evas_object_geometry_get(gcc->o_frame, NULL, NULL, &w, &h);
+   else if (gcc->o_base)
+     evas_object_geometry_get(gcc->o_base, NULL, NULL, &w, &h);
+   else return; /* make clang happy */
+
+   _e_gadcon_client_current_position_sync(gcc);
+
+   if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
+     {
+       if (x > 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
+       else if (x < 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC;
+     }
+   else
+     {
+       if (y > 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
+       else if (y < 0)
+         gcc->state_info.state = E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC;
+     }
+
+   if (e_gadcon_layout_orientation_get(gcc->gadcon->o_container))
+     {
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos, w + x);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos, w + x);
+       evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+       gcc->config.res = w;
+     }
+   else
+     {
+       if (gcc->o_frame)
+         e_gadcon_layout_pack_request_set(gcc->o_frame, gcc->config.pos, h + y);
+       else if (gcc->o_base)
+         e_gadcon_layout_pack_request_set(gcc->o_base, gcc->config.pos, h + y);
+       evas_object_geometry_get(gcc->gadcon->o_container, NULL, NULL, &w, &h);
+       gcc->config.res = h;
+     }
+   gcc->dx += x;
+   gcc->dy += y;
+}
+
+/* static void */
+/* _e_gadcon_cb_drag_finished(E_Drag *drag, int dropped) */
+/* { */
+/*    E_Gadcon_Client *gcc; */
+
+/*    gcc = drag->data; */
+/*    if (!dropped) */
+/*      { */
+/*     e_gadcon_client_config_del(NULL, gcc->cf); */
+/*     e_object_del(E_OBJECT(gcc)); */
+/*      } */
+/*    else if (new_gcc) */
+/*      { */
+/*     e_object_del(E_OBJECT(gcc)); */
+/*      } */
+/*    e_object_unref(E_OBJECT(gcc)); */
+/*    new_gcc = NULL; */
+/*    drag_gcc = NULL; */
+/* } */
+
+/* static void */
+/* _e_gadcon_cb_dnd_enter(void *data, const char *type __UNUSED__, void *event) */
+/* { */
+/*    E_Event_Dnd_Enter *ev; */
+/*    E_Gadcon *gc; */
+/*    E_Gadcon_Client *gcc; */
+
+/*    ev = event; */
+/*    gc = data; */
+/*    e_gadcon_layout_freeze(gc->o_container); */
+/*    gcc = drag_gcc; */
+
+/*    if (gcc->gadcon == gc) */
+/*      { */
+/*     Evas_Coord dx, dy; */
+/*     Evas_Object *o; */
+
+/*     if (e_gadcon_layout_orientation_get(gc->o_container)) */
+/*       gcc->config.pos = ev->x - gcc->config.size / 2; */
+/*     else */
+/*       gcc->config.pos = ev->y - gcc->config.size / 2; */
+/*     gcc->state_info.prev_pos = gcc->config.pos; */
+
+/*     evas_object_geometry_get(gc->o_container, &dx, &dy, NULL, NULL); */
+/*     _e_gadcon_client_inject(gc, gcc, ev->x + dx, ev->y + dy); */
+/*     e_gadcon_client_show(gcc); */
+
+/*     o = gcc->o_frame ? gcc->o_frame : gcc->o_base; */
+/*     if (o) */
+/*       { */
+/*          if (e_gadcon_layout_orientation_get(gc->o_container)) */
+/*            e_gadcon_layout_pack_request_set(o, gcc->config.pos, gcc->config.size); */
+/*          else */
+/*            e_gadcon_layout_pack_request_set(o, gcc->config.pos, gcc->config.size); */
+/*       } */
+/*     gcc->state_info.resist = 1; */
+/*      } */
+/*    else if (ev->data) */
+/*      { */
+/*     E_Gadcon_Client_Class *cc; */
+
+/*     gcc = ev->data; */
+/*     cc = eina_hash_find(providers, gcc->name); */
+/*     if (cc) */
+/*       { */
+/*          if (!gcc->style) */
+/*            { */
+/*               new_gcc = cc->func.init(gc, gcc->name, gcc->cf->id, */
+/*                                           cc->default_style); */
+/*            } */
+/*          else */
+/*            new_gcc = cc->func.init(gc, gcc->name, gcc->cf->id, */
+/*                                        gcc->style); */
+
+/*          if (new_gcc) */
+/*            { */
+/*               new_gcc->cf = gcc->cf; */
+/*               new_gcc->client_class = cc; */
+/*               new_gcc->config.pos = gcc->config.pos; */
+/*               new_gcc->config.size = gcc->config.size; */
+/*               new_gcc->config.res = gcc->config.res; */
+/*               new_gcc->state_info.seq = gcc->state_info.seq; */
+/*               new_gcc->state_info.flags = gcc->state_info.flags; */
+/*               if (new_gcc->o_frame) */
+/*                 e_gadcon_layout_pack_options_set(new_gcc->o_frame, new_gcc); */
+/*               else if (new_gcc->o_base) */
+/*                 e_gadcon_layout_pack_options_set(new_gcc->o_base, new_gcc); */
+
+/*               e_gadcon_client_autoscroll_set(new_gcc, gcc->autoscroll); */
+/*               e_gadcon_client_resizable_set(new_gcc, gcc->resizable);*/
+/*               if (new_gcc->client_class->func.orient) */
+/*                 new_gcc->client_class->func.orient(new_gcc, gc->orient); */
+/*               new_gcc->state_info.resist = 1; */
+/*               if (gc->instant_edit) */
+/*                 e_gadcon_client_util_menu_attach(new_gcc); */
+/*            } */
+/*       } */
+/*      } */
+/*    else */
+/*      { */
+/*      } */
+/*    e_gadcon_layout_thaw(gc->o_container); */
+/* } */
+
+/* static void */
+/* _e_gadcon_cb_dnd_move(void *data, const char *type __UNUSED__, void *event) */
+/* { */
+/*    E_Event_Dnd_Move *ev; */
+/*    E_Gadcon *gc; */
+/*    E_Gadcon_Client *gcc = NULL; */
+
+/*    ev = event; */
+/*    gc = data; */
+
+/*    if (drag_gcc->gadcon == gc) gcc = drag_gcc; */
+/*    else if (new_gcc->gadcon == gc) gcc = new_gcc; */
+/*    if (gcc) */
+/*      { */
+/*     Evas_Coord dx, dy; */
+/*     Evas_Object *o; */
+
+/*     if (gcc->state_info.resist > 0) */
+/*       { */
+/*          gcc->state_info.resist--; */
+/*          return; */
+/*       } */
+/*     e_gadcon_layout_freeze(gc->o_container); */
+
+/*     if (e_gadcon_layout_orientation_get(gc->o_container)) */
+/*       gcc->config.pos = ev->x - gcc->config.size / 2; */
+/*     else */
+/*       gcc->config.pos = ev->y - gcc->config.size / 2; */
+/*     gcc->state_info.prev_pos = gcc->config.pos; */
+
+/*     evas_object_geometry_get(gc->o_container, &dx, &dy, NULL, NULL); */
+/*     _e_gadcon_client_inject(gc, gcc, ev->x + dx, ev->y + dy); */
+
+/*     o = gcc->o_frame ? gcc->o_frame : gcc->o_base; */
+/*     if (o) */
+/*       { */
+/*          if (e_gadcon_layout_orientation_get(gc->o_container)) */
+/*            e_gadcon_layout_pack_request_set(o, gcc->config.pos,  */
+/*                                                 gcc->config.size); */
+/*          else */
+/*            e_gadcon_layout_pack_request_set(o, gcc->config.pos,  */
+/*                                                 gcc->config.size); */
+/*       } */
+/*     e_gadcon_layout_thaw(gc->o_container); */
+/*      } */
+/* } */
+
+/* static void */
+/* _e_gadcon_cb_dnd_leave(void *data, const char *type __UNUSED__, void *event __UNUSED__) */
+/* { */
+/*    E_Gadcon *gc; */
+
+/*    gc = data; */
+/*    if (drag_gcc->gadcon == gc) e_gadcon_client_hide(drag_gcc); */
+
+/*    if (new_gcc) */
+/*      { */
+/*             e_object_del(E_OBJECT(new_gcc)); */
+/*     new_gcc = NULL; */
+/*      } */
+/* } */
+
+/* static void */
+/* _e_gadcon_cb_drop(void *data, const char *type __UNUSED__, void *event __UNUSED__) */
+/* { */
+/*    E_Gadcon *gc; */
+/*    E_Gadcon_Client *gcc = NULL; */
+
+/*    gc = data; */
+/*    if (drag_gcc->gadcon == gc) gcc = drag_gcc; */
+/*    else if ((new_gcc) && (new_gcc->gadcon == gc)) gcc = new_gcc; */
+/*    else return; */
+
+/*    gc->cf->clients = eina_list_append(gc->cf->clients, gcc->cf); */
+
+/*    if (gc->editing) e_gadcon_client_edit_begin(gcc); */
+/*    e_config_save_queue(); */
+/* } */
+
+static int
+_e_gadcon_client_class_feature_check(const E_Gadcon_Client_Class *cc, const char *name, void *feature)
+{
+   if (!feature)
+     {
+       e_util_dialog_show("Insufficent gadcon support",
+                          "Module %s needs to support %s",
+                          cc->name, name);
+       return 0;
+     }
+   return 1;
+}
+
+static void 
+_e_gadcon_client_cb_menu_post(void *data, E_Menu *m __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   if (!(gcc = data)) return;
+   if (gcc->gadcon) e_gadcon_locked_set(gcc->gadcon, 0);
+   if (!gcc->menu) return;
+   e_object_del(E_OBJECT(gcc->menu));
+   gcc->menu = NULL;
+}
+
+static Eina_Bool
+_e_gadcon_client_cb_instant_edit_timer(void *data)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   e_gadcon_client_edit_begin(gcc);
+   _e_gadcon_client_move_start(gcc);
+   gcc->instant_edit_timer = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_gadcon_client_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Down *ev;
+   E_Gadcon_Client *gcc;
+
+   ev = event_info;
+   gcc = data;
+   if (gcc->menu) return;
+   if (ev->button == 3)
+     {
+       E_Menu *m;
+        E_Zone *zone;
+       int cx, cy, cw, ch;
+
+       e_gadcon_locked_set(gcc->gadcon, 1);
+       m = e_menu_new();
+
+       m = e_gadcon_client_util_menu_items_append(gcc, m, 0);
+       e_menu_post_deactivate_callback_set(m, _e_gadcon_client_cb_menu_post,
+                                           gcc);
+       gcc->menu = m;
+
+       e_gadcon_canvas_zone_geometry_get(gcc->gadcon, &cx, &cy, &cw, &ch);
+        zone = gcc->gadcon->zone;
+        if (!zone) zone = e_util_zone_current_get(e_manager_current_get());
+       e_menu_activate_mouse(m, zone, 
+                             cx + ev->output.x, 
+                              cy + ev->output.y, 1, 1,
+                             E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
+     }
+   else if (ev->button == 1)
+     {
+       if ((!gcc->o_control) && (gcc->gadcon->instant_edit))
+         {
+            if (gcc->instant_edit_timer) 
+               ecore_timer_del(gcc->instant_edit_timer);
+            gcc->instant_edit_timer = 
+              ecore_timer_add(1.0, _e_gadcon_client_cb_instant_edit_timer, 
+                              gcc);
+         }
+     }
+}
+
+static void
+_e_gadcon_client_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Evas_Event_Mouse_Up *ev;
+   E_Gadcon_Client *gcc;
+
+   ev = event_info;
+   gcc = data;
+   if ((ev->button == 1) && (gcc->gadcon->instant_edit))
+     {
+       if (gcc->instant_edit_timer)
+         {
+            ecore_timer_del(gcc->instant_edit_timer);
+            gcc->instant_edit_timer = NULL;
+         }
+       if (gcc->o_control)
+         {
+            _e_gadcon_client_move_stop(gcc);
+            e_gadcon_client_edit_end(gcc);
+         }
+     }
+}
+
+static void
+_e_gadcon_client_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   if ((gcc->gadcon->instant_edit))
+     {
+       if (gcc->o_control) _e_gadcon_client_move_go(gcc);
+     }
+}
+
+static void
+_e_gadcon_client_cb_menu_style_plain(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   E_Gadcon *gc;
+
+   gcc = data;
+   gc = gcc->gadcon;
+   if (gcc->style) eina_stringshare_del(gcc->style);
+   gcc->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_PLAIN);
+   _e_gadcon_client_save(gcc);
+   e_gadcon_unpopulate(gc);
+   e_gadcon_populate(gc);
+}
+
+static void
+_e_gadcon_client_cb_menu_style_inset(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+   E_Gadcon *gc;
+
+   gcc = data;
+   gc = gcc->gadcon;
+   if (gcc->style) eina_stringshare_del(gcc->style);
+   gcc->style = eina_stringshare_add(E_GADCON_CLIENT_STYLE_INSET);
+   _e_gadcon_client_save(gcc);
+   e_gadcon_unpopulate(gc);
+   e_gadcon_populate(gc);
+}
+
+static void
+_e_gadcon_client_cb_menu_autoscroll(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   e_gadcon_layout_freeze(gcc->gadcon->o_container);
+   if (gcc->autoscroll) gcc->autoscroll = 0;
+   else gcc->autoscroll = 1; 
+   e_gadcon_client_autoscroll_set(gcc, gcc->autoscroll);
+   _e_gadcon_client_save(gcc);
+   e_gadcon_layout_thaw(gcc->gadcon->o_container);
+}
+/*
+static void
+_e_gadcon_client_cb_menu_resizable(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   e_gadcon_layout_freeze(gcc->gadcon->o_container);
+   if (gcc->resizable) gcc->resizable = 0;
+   else gcc->resizable = 1;
+   e_gadcon_client_resizable_set(gcc, gcc->resizable);
+   _e_gadcon_client_save(gcc);
+   e_gadcon_layout_thaw(gcc->gadcon->o_container);
+}
+*/
+static void
+_e_gadcon_client_cb_menu_edit(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   if (gcc->o_control)
+     e_gadcon_client_edit_end(gcc);
+   else
+     e_gadcon_client_edit_begin(gcc);
+}
+
+static void
+_e_gadcon_client_cb_menu_remove(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Gadcon *gc;
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   gc = gcc->gadcon;
+
+   e_gadcon_client_config_del(gc->cf, gcc->cf);
+   e_gadcon_unpopulate(gc);
+   e_gadcon_populate(gc);
+   e_config_save_queue();
+}
+
+static void 
+_e_gadcon_client_cb_menu_pre(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi) 
+{
+   E_Gadcon_Client *gcc;
+
+   if (!(gcc = data)) return;
+   if (gcc->client_class->func.icon) 
+     {
+        Evas_Object *ic;
+        
+        // e menu ASSUMES... EXPECTS the icon to be an.... e_icon! make it so.
+        ic = gcc->client_class->func.icon
+           ((E_Gadcon_Client_Class *)gcc->client_class, 
+               mi->menu->evas);
+        mi->o_icon = e_icon_add(mi->menu->evas);
+        e_icon_object_set(mi->o_icon, ic);
+     }
+   else
+      e_util_menu_item_theme_icon_set(mi, "preferences-gadget"); // FIXME: Needs icon in theme
+}
+
+static void
+_e_gadcon_client_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Gadcon_Client *gcc;
+
+   gcc = data;
+   gcc->o_base = NULL;
+   if (gcc->o_frame)
+     {
+       evas_object_del(gcc->o_frame);
+       gcc->o_frame = NULL;
+     }
+   e_object_del(E_OBJECT(gcc));
+}
+
+/* a smart object JUST for gadcon */
+
+typedef struct _E_Gadcon_Layout_Item  E_Gadcon_Layout_Item;
+
+struct _E_Smart_Data
+{ 
+   Evas_Coord x, y, w, h;
+   Evas_Object *obj, *clip;
+   unsigned char horizontal : 1;
+   unsigned char doing_config : 1;
+   unsigned char redo_config : 1;
+   Eina_List *items;
+   int frozen;
+   Evas_Coord minw, minh, req;
+}; 
+
+struct _E_Gadcon_Layout_Item
+{
+   E_Smart_Data *sd;
+   struct 
+     {
+        int pos, size, size2, res, prev_pos, prev_size;
+     } ask;
+   int hookp;
+   struct 
+     {
+        int w, h;
+     } min, aspect, aspect_pad;
+
+   E_Gadcon_Client *gcc;
+
+   Evas_Coord x, y, w, h;
+   Evas_Object *obj;
+   unsigned char can_move : 1;
+};
+
+/* local subsystem functions */
+static E_Gadcon_Layout_Item *_e_gadcon_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
+static void _e_gadcon_layout_smart_disown(Evas_Object *obj);
+static void _e_gadcon_layout_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_gadcon_layout_smart_reconfigure(E_Smart_Data *sd);
+static void _e_gadcon_layout_smart_init(void);
+static void _e_gadcon_layout_smart_add(Evas_Object *obj);
+static void _e_gadcon_layout_smart_del(Evas_Object *obj);
+static void _e_gadcon_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _e_gadcon_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _e_gadcon_layout_smart_show(Evas_Object *obj);
+static void _e_gadcon_layout_smart_hide(Evas_Object *obj);
+static void _e_gadcon_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _e_gadcon_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
+static void _e_gadcon_layout_smart_clip_unset(Evas_Object *obj);
+static void _e_gadcon_layout_smart_min_cur_size_calc(E_Smart_Data *sd, int *min, int *mino, int *cur);
+static void _e_gadcon_layout_smart_gadcons_width_adjust(E_Smart_Data *sd, int min, int cur);
+static int _e_gadcon_layout_smart_sort_by_sequence_number_cb(const void *d1, const void *d2);
+static int _e_gadcon_layout_smart_sort_by_position_cb(const void *d1, const void *d2);
+
+/* local subsystem globals */
+static Evas_Smart *_e_smart = NULL;
+
+/* externally accessible functions */
+static Evas_Object *
+e_gadcon_layout_add(Evas *evas)
+{   
+   _e_gadcon_layout_smart_init();
+   return evas_object_smart_add(evas, _e_smart);
+}
+
+static void
+e_gadcon_layout_orientation_set(Evas_Object *obj, int horizontal)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (((sd->horizontal) && (horizontal)) || 
+       ((!sd->horizontal) && (!horizontal))) return;
+   sd->horizontal = horizontal;
+   _e_gadcon_layout_smart_reconfigure(sd);
+}
+
+static int
+e_gadcon_layout_orientation_get(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return 0;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   return sd->horizontal;
+}
+
+static void
+e_gadcon_layout_freeze(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   sd->frozen++;
+}
+
+static void
+e_gadcon_layout_thaw(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   sd->frozen--;
+   _e_gadcon_layout_smart_reconfigure(sd);
+}
+
+static void
+e_gadcon_layout_min_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   E_Smart_Data *sd;
+/*   
+   Eina_List *l;
+   Evas_Object *obj;
+   Evas_Coord tw = 0, th = 0;
+ */
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->horizontal)
+     {
+       if (w) *w = sd->minw;
+       if (h) *h = sd->minh;
+     }
+   else
+     {
+       if (w) *w = sd->minh;
+       if (h) *h = sd->minw;
+     }
+   
+/*   
+   EINA_LIST_FOREACH(sd->items, l, obj)
+     {
+       E_Gadcon_Layout_Item *bi;
+       
+       bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+       if (sd->horizontal)
+         {
+            tw += bi->min.w;
+            if (bi->min.h > th) th = bi->min.h;
+         }
+       else
+         {
+            th += bi->min.h;
+            if (bi->min.w > tw) tw = bi->min.w;
+         }
+     }
+   if (w) *w = tw;
+   if (h) *h = th;
+ */
+}
+
+static void
+e_gadcon_layout_asked_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
+{
+   E_Smart_Data *sd;
+   Evas_Coord tw = 0, th = 0;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->horizontal)
+     tw = sd->req;
+   else
+     th = sd->req;
+/*   
+   Evas_Object *obj;
+   EINA_LIST_FOREACH(sd->items, l, obj)
+     {
+       E_Gadcon_Layout_Item *bi;
+       
+       bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+       if (sd->horizontal)
+         {
+            tw += bi->ask.size;
+         }
+       else
+         {
+            th += bi->ask.size;
+         }
+     }
+ */
+   if (w) *w = tw;
+   if (h) *h = th;
+}
+
+static int
+e_gadcon_layout_pack(Evas_Object *obj, Evas_Object *child)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return 0;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return 0;
+   _e_gadcon_layout_smart_adopt(sd, child);
+   sd->items = eina_list_prepend(sd->items, child);
+   _e_gadcon_layout_smart_reconfigure(sd);
+   return 0;
+}
+
+static void
+e_gadcon_layout_pack_size_set(Evas_Object *obj, int size)
+{
+   /*
+    * FIXME:
+    * simplify this function until the is redone
+    * _e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd)
+    */
+   E_Gadcon_Layout_Item *bi;
+   int pos;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   pos = bi->ask.pos + (bi->ask.size / 2);
+   if (pos < (bi->ask.res / 3))
+     { 
+        /* hooked to start */
+       bi->ask.size = size;
+     }
+   else if (pos > ((2 * bi->ask.res) / 3))
+     { 
+        /* hooked to end */
+       bi->ask.pos = (bi->ask.pos + bi->ask.size) - size;
+       bi->ask.size = size;
+     }
+   else
+     { 
+        /* hooked to middle */
+       if ((bi->ask.pos <= (bi->ask.res / 2)) &&
+           ((bi->ask.pos + bi->ask.size) > (bi->ask.res / 2)))
+         { 
+             /* straddles middle */
+            if (bi->ask.res > 2)
+              bi->ask.pos = (bi->ask.res / 2) +
+              (((bi->ask.pos + (bi->ask.size / 2) -
+                 (bi->ask.res / 2)) *
+                (bi->ask.res / 2)) /
+               (bi->ask.res / 2)) - (bi->ask.size / 2);
+            else
+              bi->x = bi->ask.res / 2;
+            bi->ask.size = size;
+         }
+       else
+         { 
+            if (pos < (bi->ask.res / 2))
+              {
+                 bi->ask.pos = (bi->ask.pos + bi->ask.size) - size;
+                 bi->ask.size = size;
+              }
+            else
+              bi->ask.size = size;
+         }
+        bi->ask.size = size;
+     }
+   _e_gadcon_layout_smart_reconfigure(bi->sd);
+}
+
+/* called when a users moves/resizes the gadcon client explicitly */
+static void
+e_gadcon_layout_pack_request_set(Evas_Object *obj, int pos, int size)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+
+   bi->ask.res = bi->sd->w;
+   if (pos < 0) pos = 0;
+   if ((bi->ask.res - pos) < size) pos = bi->ask.res - size;
+   bi->ask.size = size;
+   bi->ask.pos = pos;
+   _e_gadcon_layout_smart_reconfigure(bi->sd);
+}
+
+/* called when restoring config from saved config */
+static void
+e_gadcon_layout_pack_options_set(Evas_Object *obj, E_Gadcon_Client *gcc)
+{
+   int ok, seq;
+   Eina_List *l;
+   Evas_Object *item;
+   E_Gadcon_Layout_Item *bi, *bi2;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   bi->ask.res = gcc->config.res;
+   bi->ask.size = gcc->config.size;
+   bi->ask.pos = gcc->config.pos;
+   bi->gcc = gcc;
+
+   ok = 0;
+   if (!gcc->state_info.seq) ok = 1;
+
+   seq = 1;
+   EINA_LIST_FOREACH(bi->sd->items, l, item)
+     {
+       bi2 = evas_object_data_get(item, "e_gadcon_layout_data");
+       if (bi == bi2) continue;
+       if (bi->gcc->state_info.seq == bi2->gcc->state_info.seq)
+         ok = 1;
+
+       if (bi2->gcc->state_info.seq > seq)
+         seq = bi2->gcc->state_info.seq;
+     }
+
+   if (ok)
+     { 
+       gcc->state_info.seq = seq + 1; 
+       gcc->state_info.want_save = 1;
+       gcc->state_info.flags = E_GADCON_LAYOUT_ITEM_LOCK_NONE;
+     }
+   _e_gadcon_layout_smart_reconfigure(bi->sd); 
+}
+
+static void
+e_gadcon_layout_pack_min_size_set(Evas_Object *obj, int w, int h)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   if (bi->sd->horizontal)
+     {
+       bi->min.w = w;
+       bi->min.h = h;
+     }
+   else
+     {
+       bi->min.w = h;
+       bi->min.h = w;
+     }
+   
+   _e_gadcon_layout_smart_reconfigure(bi->sd);
+}
+
+static void
+e_gadcon_layout_pack_aspect_set(Evas_Object *obj, int w, int h)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   if (bi->sd->horizontal)
+     {
+       bi->aspect.w = w;
+       bi->aspect.h = h;
+     }
+   else
+     {
+       bi->aspect.w = h;
+       bi->aspect.h = w;
+     }
+     
+   _e_gadcon_layout_smart_reconfigure(bi->sd);
+}
+
+static void
+e_gadcon_layout_pack_aspect_pad_set(Evas_Object *obj, int w, int h)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   if (bi->sd->horizontal)
+     {
+       bi->aspect_pad.w = w;
+       bi->aspect_pad.h = h;
+     }
+   else
+     {
+       bi->aspect_pad.w = h;
+       bi->aspect_pad.h = w;
+     }   
+}
+
+static void
+e_gadcon_layout_unpack(Evas_Object *obj)
+{
+   E_Gadcon_Layout_Item *bi;
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   sd = bi->sd;
+   if (!sd) return;
+   sd->items = eina_list_remove(sd->items, obj);
+   _e_gadcon_layout_smart_disown(obj);
+   _e_gadcon_layout_smart_reconfigure(sd);
+}
+
+/* local subsystem functions */
+static E_Gadcon_Layout_Item *
+_e_gadcon_layout_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return NULL;
+   bi = E_NEW(E_Gadcon_Layout_Item, 1);
+   if (!bi) return NULL;
+   bi->sd = sd;
+   bi->obj = obj;
+   /* defaults */
+   evas_object_clip_set(obj, sd->clip);
+   evas_object_smart_member_add(obj, bi->sd->obj);
+   evas_object_data_set(obj, "e_gadcon_layout_data", bi);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+                                 _e_gadcon_layout_smart_item_del_hook, NULL);
+   if ((!evas_object_visible_get(sd->clip)) &&
+       (evas_object_visible_get(sd->obj)))
+     evas_object_show(sd->clip);
+   return bi;
+}
+
+static void
+_e_gadcon_layout_smart_disown(Evas_Object *obj)
+{
+   E_Gadcon_Layout_Item *bi;
+
+   if (!obj) return;
+   bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+   if (!bi) return;
+   if (!bi->sd->items)
+     {
+       if (evas_object_visible_get(bi->sd->clip))
+         evas_object_hide(bi->sd->clip);
+     }
+   evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
+                                 _e_gadcon_layout_smart_item_del_hook);
+   evas_object_smart_member_del(obj);
+   evas_object_clip_unset(obj);
+   evas_object_data_del(obj, "e_gadcon_layout_data");
+   E_FREE(bi);
+}
+
+static void
+_e_gadcon_layout_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   if (!obj) return;
+   e_gadcon_layout_unpack(obj);
+}
+
+static void
+_e_gadcon_layout_smart_reconfigure(E_Smart_Data *sd)
+{
+   Evas_Coord xx, yy;
+   Eina_List *l;
+   Evas_Object *obj;
+   int min, mino, cur;
+   Eina_List *list = NULL;
+   E_Gadcon_Layout_Item *bi;
+   E_Layout_Item_Container *lc;
+   int i, set_prev_pos = 0;
+   static int recurse = 0;
+
+   if (sd->frozen) return;
+   if (sd->doing_config)
+     {
+       sd->redo_config = 1;
+       return;
+     }
+
+   recurse++;
+   min = mino = cur = 0;
+
+   _e_gadcon_layout_smart_min_cur_size_calc(sd, &min, &mino, &cur); 
+
+   if ((sd->minw != min) || (sd->minh != mino))
+     {
+       sd->minw = min;
+       sd->minh = mino;
+       evas_object_smart_callback_call(sd->obj, "min_size_request", NULL);
+     }
+
+   if (sd->req != cur)
+     {
+       if (cur >= sd->minw)
+         {
+            sd->req = cur;
+            evas_object_smart_callback_call(sd->obj, "size_request", NULL);
+         }
+       else
+         {
+            sd->req = sd->minw;     
+         }
+     }
+   if (recurse == 1) _e_gadcon_layout_smart_gadcons_width_adjust(sd, min, cur);
+
+   if (sd->w <= sd->req)
+     { 
+       _e_gadcon_layout_smart_gadcon_position_shrinked_mode(sd);
+       set_prev_pos = 0;
+     }
+   else
+     { 
+       _e_gadcon_layout_smart_gadcons_asked_position_set(sd);
+
+       list = _e_gadcon_layout_smart_gadcons_wrap(sd);
+
+       _e_gadcon_layout_smart_gadcons_position(sd, &list);
+
+       EINA_LIST_FREE(list, lc)
+         LC_FREE(lc);
+
+       set_prev_pos = 1;
+     }
+
+   sd->items = eina_list_sort(sd->items, eina_list_count(sd->items),
+                             _e_gadcon_layout_smart_sort_by_position_cb);
+   i = 1;
+   EINA_LIST_FOREACH(sd->items, l, obj)
+     {
+       bi = evas_object_data_get(obj, "e_gadcon_layout_data"); 
+       if (bi->gcc->gadcon->editing) bi->gcc->state_info.seq = i; 
+
+       if (set_prev_pos)
+         {
+           bi->ask.prev_pos = bi->x; 
+           bi->ask.prev_size = bi->w;
+         }
+
+       if ((bi->x == bi->ask.pos) &&
+           (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION))
+         bi->gcc->state_info.flags |= E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+
+       if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
+           (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE))
+         {
+           if (bi->x != bi->ask.pos)
+             bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+         }
+       i++;
+     } 
+
+   EINA_LIST_FOREACH(sd->items, l, obj)
+     {
+       E_Gadcon_Layout_Item *bi;
+
+       bi = evas_object_data_get(obj, "e_gadcon_layout_data");
+       if (!bi) continue;
+
+       bi->h = sd->h;
+       xx = sd->x + bi->x;
+       yy = sd->y; // + ((sd->h - bi->h) / 2);
+        
+       if (sd->horizontal)
+         {
+            evas_object_move(obj, xx, yy);
+            evas_object_resize(obj, bi->w, bi->h);
+         }
+       else
+         {
+            evas_object_move(obj, yy, xx);
+            evas_object_resize(obj, bi->h, bi->w);
+         }
+     }
+   sd->doing_config = 0;
+   if (sd->redo_config)
+     {
+       _e_gadcon_layout_smart_reconfigure(sd);
+       sd->redo_config = 0;
+     }
+
+   if ((sd->minw != min) || (sd->minh != mino))
+     {
+       sd->minw = min;
+       sd->minh = mino;
+       evas_object_smart_callback_call(sd->obj, "min_size_request", NULL);
+     }
+
+   if (sd->req != cur)
+     {
+         if (cur >= sd->minw)
+         {
+            sd->req = cur;
+            evas_object_smart_callback_call(sd->obj, "size_request", NULL);
+         }
+     }
+   recurse--;
+}
+
+static void
+_e_gadcon_layout_smart_init(void)
+{
+   if (_e_smart) return;
+     {
+       static const Evas_Smart_Class sc =
+         {
+            "e_gadcon_layout",
+              EVAS_SMART_CLASS_VERSION,
+              _e_gadcon_layout_smart_add,
+              _e_gadcon_layout_smart_del,
+              _e_gadcon_layout_smart_move,
+              _e_gadcon_layout_smart_resize,
+              _e_gadcon_layout_smart_show,
+              _e_gadcon_layout_smart_hide,
+              _e_gadcon_layout_smart_color_set,
+              _e_gadcon_layout_smart_clip_set,
+              _e_gadcon_layout_smart_clip_unset,
+              NULL, NULL, NULL, NULL, NULL, NULL, NULL
+         };
+       _e_smart = evas_smart_class_new(&sc);
+     }
+}
+
+static void
+_e_gadcon_layout_smart_add(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = calloc(1, sizeof(E_Smart_Data));
+   if (!sd) return;
+   sd->obj = obj;
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
+   sd->horizontal = 1;
+   evas_object_smart_member_add(sd->clip, obj);
+   evas_object_move(sd->clip, -100005, -100005);
+   evas_object_resize(sd->clip, 200010, 200010);
+   evas_object_color_set(sd->clip, 255, 255, 255, 255);
+   evas_object_smart_data_set(obj, sd);
+}
+   
+static void
+_e_gadcon_layout_smart_del(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   while (sd->items)
+     {
+       Evas_Object *child;
+
+       child = eina_list_data_get(sd->items);
+       e_gadcon_layout_unpack(child);
+     }
+   evas_object_del(sd->clip);
+   free(sd);
+}
+
+static void
+_e_gadcon_layout_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((x == sd->x) && (y == sd->y)) return;
+     {
+       Eina_List *l;
+       Evas_Object *item;
+       Evas_Coord dx, dy;
+
+       if (sd->horizontal)
+         {
+            dx = x - sd->x;
+            dy = y - sd->y;
+         }
+       else
+         {
+            dx = x - sd->y;
+            dy = y - sd->x;
+         }
+       
+       EINA_LIST_FOREACH(sd->items, l, item)
+         {
+            Evas_Coord ox, oy;
+
+            evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
+            evas_object_move(item, ox + dx, oy + dy);
+         }
+     }
+
+     if (sd->horizontal)
+       {
+         sd->x = x;
+         sd->y = y;
+       }
+     else
+       {
+         sd->x = y;
+         sd->y = x;
+       }
+}
+
+static void
+_e_gadcon_layout_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if ((w == sd->w) && (h == sd->h)) return;
+   if (sd->horizontal)
+     { 
+       sd->w = w;
+       sd->h = h;
+     }
+   else
+     {
+       sd->w = h;
+       sd->h = w;
+
+     }
+   
+   _e_gadcon_layout_smart_reconfigure(sd);
+}
+
+static void
+_e_gadcon_layout_smart_show(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   if (sd->items) evas_object_show(sd->clip);
+}
+
+static void
+_e_gadcon_layout_smart_hide(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_hide(sd->clip);
+}
+
+static void
+_e_gadcon_layout_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;   
+   evas_object_color_set(sd->clip, r, g, b, a);
+}
+
+static void
+_e_gadcon_layout_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_set(sd->clip, clip);
+}
+
+static void
+_e_gadcon_layout_smart_clip_unset(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!obj) return;
+   sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   evas_object_clip_unset(sd->clip);
+}  
+
+/*
+ * @min - the minimum width required by all the gadcons
+ * @cur - the current width required by all the gadcons
+ * @mino - the smalest width/height among all the objects
+ */
+static void
+_e_gadcon_layout_smart_min_cur_size_calc(E_Smart_Data *sd, int *min, int *mino, int *cur)
+{
+   E_Gadcon_Layout_Item        *bi;
+   Eina_List *l;
+   Evas_Object *item;
+
+   EINA_LIST_FOREACH(sd->items, l, item)
+     {
+       bi = evas_object_data_get(item, "e_gadcon_layout_data");
+       bi->ask.size2 = bi->ask.size;
+
+       if ((bi->aspect.w > 0) && (bi->aspect.h > 0))
+         {
+            bi->ask.size2 =
+              (((sd->h - bi->aspect_pad.h) * bi->aspect.w) / bi->aspect.h) + bi->aspect_pad.w;
+            
+            if (bi->ask.size2 > bi->min.w)
+              {
+                 *min += bi->ask.size2;
+                 *cur += bi->ask.size2;
+              }
+            else
+              {
+                 *min += bi->min.w;
+                 *cur += bi->min.w;
+              }
+         }
+       else
+         {
+             bi->ask.size2 = bi->ask.size = bi->min.w;
+            *min += bi->min.w;
+            if (bi->min.h > *mino) *mino = bi->min.h;
+            if (bi->ask.size < bi->min.w)
+              *cur += bi->min.w;
+            else
+              *cur += bi->ask.size;
+         }
+     }
+}
+
+static int 
+_e_gadcon_layout_smart_width_smart_sort_reverse_cb(const void *d1, const void *d2)
+{
+   const E_Gadcon_Layout_Item *bi, *bi2;
+
+   bi = evas_object_data_get(d1, "e_gadcon_layout_data");
+   bi2 = evas_object_data_get(d2, "e_gadcon_layout_data"); 
+
+   if (bi->ask.size2 > bi->min.w)
+     {
+       if (bi2->ask.size2 > bi2->min.w) 
+         { 
+            if (bi->ask.size2 < bi2->ask.size2)
+              return 1;
+            else
+              return -1;
+         }
+       else
+         {
+            if (bi->ask.size2 == bi2->ask.size2)
+              return -1;
+            else
+              { 
+                 if (bi->ask.size2 < bi2->ask.size2)
+                   return 1;
+                 else
+                   return -1;
+              }
+         }
+     }
+   else
+     {
+       if (bi2->ask.size2 > bi2->min.w)
+         {
+            if (bi->ask.size2 == bi2->ask.size2)
+              return 1;
+            else
+              { 
+                 if (bi->ask.size2 < bi2->ask.size2)
+                   return 1;
+                 else
+                   return -1;
+              }
+         }
+       else
+         { 
+            if (bi->ask.size2 < bi2->ask.size2)
+              return 1;
+            else if (bi->ask.size2 > bi2->ask.size2)
+              return -1;
+         }
+     }
+
+   return 0;
+}
+
+static void 
+_e_gadcon_layout_smart_gadcons_width_adjust(E_Smart_Data *sd, int min, int cur)
+{ 
+   E_Gadcon_Layout_Item *bi = NULL;
+   Eina_List *l, *l2;
+   Evas_Object *item;
+   int needed = 0;
+   int need = 0;
+   int max_size, autosize = 0;
+
+   if (sd->w < cur)
+     {
+       if (sd->w < min) max_size = min;
+       else max_size = cur;
+       need = max_size - sd->w;
+     }
+   else
+     return;
+   
+   sd->items = eina_list_sort(sd->items, eina_list_count(sd->items), 
+                             _e_gadcon_layout_smart_width_smart_sort_reverse_cb);
+   EINA_LIST_FOREACH(sd->items, l, item)
+     { 
+        bi = evas_object_data_get(item, "e_gadcon_layout_data");
+        if (bi->gcc->autoscroll) autosize += bi->ask.size2;
+     } 
+
+   if (autosize < 1) autosize = 1;
+   while (need > 0)
+     { 
+        needed = need;
+        EINA_LIST_REVERSE_FOREACH(sd->items, l2, item)
+          { 
+             if (need <= 0) break;
+             bi = evas_object_data_get(item, "e_gadcon_layout_data");
+             if (bi->gcc->autoscroll)
+               {
+                  int reduce_by; 
+                  
+                  reduce_by = (need * bi->ask.size2) / autosize;
+                  if (reduce_by < 1) reduce_by = 1;
+                  if (bi->ask.size2 - reduce_by > 8)
+                    {
+                       bi->ask.size2 -= reduce_by;
+                       need -= reduce_by ; 
+                    }
+                  else
+                    {
+                       need -= bi->ask.size2 - 8;
+                       bi->ask.size2 = 8;
+                    }
+              }
+         } 
+        /* If the 'needed' size change didn't get modified (no gadget has autoscroll)
+           then we must break or we end up in an infinite loop */
+        if (need == needed) break;
+     }
+}
+
+static int 
+_e_gadcon_layout_smart_sort_by_sequence_number_cb(const void *d1, const void *d2)
+{
+   const E_Gadcon_Layout_Item *bi, *bi2;
+
+   bi = evas_object_data_get(d1, "e_gadcon_layout_data");
+   bi2 = evas_object_data_get(d2, "e_gadcon_layout_data");
+
+   if ((!bi->gcc->state_info.seq) && (!bi2->gcc->state_info.seq)) return 0;
+   else if (!bi->gcc->state_info.seq) return 1;
+   else if (!bi2->gcc->state_info.seq) return -1;
+   return bi->gcc->state_info.seq - bi2->gcc->state_info.seq;
+} 
+
+static int
+_e_gadcon_layout_smart_sort_by_position_cb(const void *d1, const void *d2)
+{
+   const E_Gadcon_Layout_Item *bi, *bi2;
+
+   bi = evas_object_data_get(d1, "e_gadcon_layout_data");
+   bi2 = evas_object_data_get(d2, "e_gadcon_layout_data");
+
+   return (bi->x - bi2->x);
+}
+
+static int
+_e_gadcon_layout_smart_containers_sort_cb(const void *d1, const void *d2)
+{
+   const E_Layout_Item_Container *lc, *lc2;
+
+   lc = d1;
+   lc2 = d2;
+   if (lc->pos < lc2->pos) return -1;
+   else if (lc->pos > lc2->pos) return 1;
+   return 0;
+}
+
+static int
+_e_gadcon_layout_smart_seq_sort_cb(const void *d1, const void *d2)
+{
+   const E_Gadcon_Layout_Item *bi, *bi2;
+
+   bi = d1;
+   bi2 = d2;
+   return (bi->gcc->state_info.seq - bi2->gcc->state_info.seq);
+}
+
+static void
+_e_gadcon_layout_smart_sync_clients(E_Gadcon *gc)
+{
+   E_Gadcon_Client *gcc;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(gc->clients, l, gcc)
+     {
+       _e_gadcon_client_save(gcc);
+     }
+}
+
+static void
+_e_gadcon_client_current_position_sync(E_Gadcon_Client *gcc)
+{
+   E_Gadcon_Layout_Item *bi;
+   Evas_Object *o;
+
+   o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
+   if (o)
+     {
+       bi = evas_object_data_get(o, "e_gadcon_layout_data");
+       if (!bi) return;
+     }
+   else return; /* make clang happy */
+
+   gcc->state_info.prev_pos = gcc->config.pos;
+   gcc->state_info.prev_size = gcc->config.size;
+   gcc->config.pos = bi->x;
+}
+
+static void
+_e_gadcon_layout_smart_gadcon_position_shrinked_mode(E_Smart_Data *sd)
+{ 
+   Eina_List *l;
+   Evas_Object *item;
+   E_Gadcon_Layout_Item *bi, *bi2; 
+   void *tp; 
+   int pos = 0; 
+
+   sd->items = eina_list_sort(sd->items, eina_list_count(sd->items),
+                             _e_gadcon_layout_smart_sort_by_sequence_number_cb); 
+   EINA_LIST_FOREACH(sd->items, l, item)
+     { 
+       bi = evas_object_data_get(item, "e_gadcon_layout_data"); 
+       if (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_INC) 
+         { 
+            if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL) 
+              { 
+                 bi->gcc->state_info.resist++; 
+                 bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+              } 
+            else
+              { 
+                 bi->gcc->state_info.resist = 0; 
+                 if (eina_list_next(l)) 
+                   { 
+                      tp = eina_list_data_get(eina_list_next(l));
+                      l->next->data = eina_list_data_get(l); 
+                      l->data = tp; 
+
+                      bi2 = evas_object_data_get(tp, "e_gadcon_layout_data");
+                      
+                      if (bi2->x + bi2->w/2 > bi->ask.pos + bi->w)
+                        {
+                           bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+                           return;
+                        }
+                      
+                      bi->gcc->config.pos = bi->ask.pos = bi2->ask.pos;
+                      bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+                      bi->gcc->state_info.want_save = 1;
+                      bi2->gcc->state_info.want_save = 1;
+                      break;
+                   }
+                 else
+                   bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+              } 
+         } 
+       else if (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_DEC)
+         { 
+            if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
+              {
+                 bi->gcc->state_info.resist++;
+                 bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+              }
+            else
+              {
+                 bi->gcc->state_info.resist = 0; 
+                 if (eina_list_prev(l))
+                   { 
+                      E_Gadcon_Layout_Item *bi2;
+                      void *tp;
+
+                      tp = eina_list_data_get(eina_list_prev(l));
+                      l->prev->data = eina_list_data_get(l);
+
+                      l->data = tp; 
+                      bi2 = evas_object_data_get(tp, "e_gadcon_layout_data");
+
+                      if (bi->ask.pos > bi2->x + bi2->w/2)
+                        {
+                           bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+                           return;
+                        }
+
+                      bi->gcc->config.pos = bi->ask.pos = bi2->ask.pos;
+                      bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+                      bi->gcc->state_info.want_save = 1;
+                      bi2->gcc->state_info.want_save = 1;
+                      break;
+                   }
+                 else
+                   bi->gcc->config.pos = bi->ask.pos = bi->gcc->state_info.prev_pos;
+              }
+         }
+       else if ((bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_INC) ||
+                (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_DEC) ||
+                (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MIN_END_DEC) ||
+                (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_SIZE_MAX_END_INC))
+         { 
+            if (bi->w < bi->min.w) 
+              bi->gcc->config.size = bi->w = bi->min.w;
+            else
+              bi->gcc->config.size = bi->w;
+
+            bi->gcc->config.pos = bi->gcc->state_info.prev_pos;
+         }     
+     } 
+
+   EINA_LIST_FOREACH(sd->items, l, item)
+     { 
+       bi = evas_object_data_get(item, "e_gadcon_layout_data");
+
+       bi->x = pos;
+       bi->w = bi->ask.size2; 
+       bi->gcc->config.size = bi->w;
+       pos = bi->x + bi->w;
+     }
+}
+
+static void
+_e_gadcon_layout_smart_gadcons_asked_position_set(E_Smart_Data *sd)
+{
+   E_Gadcon_Layout_Item *bi;
+   Eina_List *l;
+   Evas_Object *item;
+
+#if 0
+   EINA_LIST_FOREACH(sd->items, l, item)
+     {
+       bi = evas_object_data_get(item, "e_gadcon_layout_data");
+       if (!bi) continue;
+       
+       bi->x = bi->ask.pos;
+       bi->w = bi->ask.size2;
+     }
+#else
+   int pos;
+   EINA_LIST_FOREACH(sd->items, l, item)
+     {
+       bi = evas_object_data_get(item, "e_gadcon_layout_data");
+       if (!bi) continue;
+
+       pos = bi->ask.pos + (bi->ask.size / 2);
+       if (pos < (bi->ask.res / 3))
+         { 
+            /* hooked to start */
+            bi->x = bi->ask.pos;
+            bi->w = bi->ask.size2;
+            bi->hookp = 0;
+         }
+       else if (pos > ((2 * bi->ask.res) / 3))
+         { 
+            /* hooked to end */
+            bi->x = (bi->ask.pos - bi->ask.res) + sd->w;
+            bi->w = bi->ask.size2;
+            bi->hookp = bi->ask.res;
+         }
+       else
+         { 
+            /* hooked to middle */
+            if ((bi->ask.pos <= (bi->ask.res / 2)) &&
+                ((bi->ask.pos + bi->ask.size2) > (bi->ask.res / 2)))
+              { 
+                 /* straddles middle */
+                 if (bi->ask.res > 2)
+                   bi->x = (sd->w / 2) + 
+                     (((bi->ask.pos + (bi->ask.size2 / 2) - 
+                        (bi->ask.res / 2)) * 
+                       (bi->ask.res / 2)) /
+                      (bi->ask.res / 2)) - (bi->ask.size2 / 2);
+                 else
+                   bi->x = sd->w / 2;
+                 bi->w = bi->ask.size2;
+              }
+            else
+              { 
+                 /* either side of middle */
+                 bi->x = (bi->ask.pos - (bi->ask.res / 2)) + (sd->w / 2);
+                 bi->w = bi->ask.size2;
+              }
+            bi->hookp = bi->ask.res / 2;
+         }
+     }
+#endif
+}
+
+/* 
+ * The function returns a list of E_Gadcon_Layout_Item_Container
+ */
+static Eina_List *
+_e_gadcon_layout_smart_gadcons_wrap(E_Smart_Data *sd)
+{
+   Eina_List *l, *list = NULL;
+   Evas_Object *item;
+   E_Layout_Item_Container *lc;
+   E_Gadcon_Layout_Item *bi;
+
+   
+   EINA_LIST_FOREACH(sd->items, l, item)
+     {
+       bi = evas_object_data_get(item, "e_gadcon_layout_data");
+       lc = E_NEW(E_Layout_Item_Container, 1);
+       lc->state_info.min_seq = lc->state_info.max_seq = bi->gcc->state_info.seq;
+       lc->sd = sd;
+
+       lc->pos = bi->x;
+       lc->size = bi->w;
+
+       lc->prev_pos = bi->ask.prev_pos;
+       lc->prev_size = bi->ask.prev_size;
+
+       E_LAYOUT_ITEM_CONTAINER_STATE_SET(lc->state, bi->gcc->state_info.state);
+
+       if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
+           (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
+         lc->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+
+       lc->items = eina_list_append(lc->items, bi);
+       list = eina_list_append(list, lc);
+     }
+   return list;
+}
+
+static void
+_e_gadcon_layout_smart_gadcons_position(E_Smart_Data *sd, Eina_List **list)
+{
+   int ok, lc_moving_prev_pos;
+   Eina_List *l, *l2, *l3;
+   E_Layout_Item_Container *lc_moving = NULL, *lc_back = NULL, *lc, *lc3;
+   E_Gadcon_Layout_Item *bi, *bi_moving = NULL;
+
+   if ((!list) || (!*list)) return;
+
+   EINA_LIST_FOREACH(*list, l, lc_moving)
+     {
+       if ((lc_moving->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
+           (lc_moving->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED))
+         {
+            lc_back = E_NEW(E_Layout_Item_Container, 1);
+            lc_back->pos = lc_moving->pos;
+            lc_back->prev_pos = lc_moving->prev_pos;
+            lc_back->size = lc_moving->size;
+            lc_back->prev_size = lc_moving->prev_size;
+            lc_back->state_info.min_seq = lc_moving->state_info.min_seq;
+            lc_back->state_info.max_seq = lc_moving->state_info.max_seq;
+            lc_back->sd = lc_moving->sd;
+            EINA_LIST_FOREACH(lc_moving->items, l2, lc)
+              lc_back->items = eina_list_append(lc_back->items, lc);
+            lc_back->state = lc_moving->state;
+            bi_moving = eina_list_data_get(lc_back->items);
+            
+            break;
+         }
+       lc_moving = NULL;
+     }
+
+   if (!lc_moving)
+     {
+       _e_gadcon_layout_smart_gadcons_position_static(sd, list);
+       return;
+     } 
+
+   lc_moving_prev_pos = lc_moving->prev_pos;
+   if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC) 
+     { 
+       _e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list); 
+       EINA_LIST_FOREACH(*list, l, lc)
+          if (lc == lc_moving) break;
+
+       ok = 0;
+       if ((l) && eina_list_prev(l))
+         {
+            lc = eina_list_data_get(eina_list_prev(l));
+
+            if (lc_moving->pos < (lc->pos + lc->size))
+              {
+                 bi = eina_list_data_get(lc_moving->items);
+                 if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
+                   {
+                      if (lc_moving->prev_pos == (lc->pos + lc->size))
+                        ok = 1;
+                      bi->gcc->state_info.resist++;
+                      lc_moving->pos = lc->pos + lc->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+                   }
+                 else
+                   {
+                      bi->gcc->state_info.resist = 0;
+                      if (lc_moving->pos < lc->pos) 
+                        { 
+                           lc_moving->pos = (lc->pos + lc->size) - 1;
+                           _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+                        }
+                      lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc, lc_moving);
+                      if (lc3)
+                        {
+                           if (lc_moving->prev_pos == (lc->pos + lc->size))
+                             ok = 1;
+
+                           l->data = lc3;
+                           *list = eina_list_remove_list(*list, eina_list_prev(l));
+                           LC_FREE(lc_moving);
+                           LC_FREE(lc);
+                           lc_moving = lc3;
+                        }
+                   }
+              }
+         }
+       if (!ok) 
+         { 
+            int pos, prev_pos, stop;
+
+            EINA_LIST_FOREACH(*list, l, lc)
+               if (lc == lc_moving) break;
+
+            pos = lc_moving->pos + lc_moving->size;
+            prev_pos = lc_moving_prev_pos;
+            if ((l) && (eina_list_next(l)))
+              { 
+                 stop = 0;
+                 EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
+                   {
+                      if (stop) break;
+                      if (lc->pos != prev_pos) break;
+                      prev_pos = lc->pos + lc->size;
+
+                      EINA_LIST_FOREACH(lc->items, l3, bi)
+                        {
+                           if (bi->ask.pos <= pos)
+                             {
+                               bi->x = pos;
+                               pos = (bi->x) + (bi->w);
+                             }
+                           else if (bi->ask.pos < bi->x)
+                             {
+                               bi->x = bi->ask.pos;
+                               pos = (bi->x) + (bi->w);                                
+                             }
+                           else if (bi->ask.pos == bi->x)
+                             {
+                                stop = 1;
+                                break;
+                             }
+                        }
+                   }
+              }
+         }
+     }
+   else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC)
+     {
+       _e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list); 
+       EINA_LIST_FOREACH(*list, l, lc)
+          if (lc == lc_moving) break;
+
+       ok = 0;
+       if ((l) && eina_list_next(l))
+         {
+            lc = eina_list_data_get(eina_list_next(l));
+
+            if ((lc_moving->pos + lc_moving->size) > lc->pos)
+              {
+                 bi = eina_list_data_get(lc_moving->items);
+                 if (bi->gcc->state_info.resist <= E_LAYOUT_ITEM_DRAG_RESIST_LEVEL)
+                   {
+                      if ((lc_moving->prev_pos + lc_moving->size) == lc->pos)
+                        ok = 1;
+                      bi->gcc->state_info.resist++;
+                      lc_moving->pos = lc->pos - lc_moving->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+                   } 
+                 else
+                   {
+                      bi->gcc->state_info.resist = 0;
+                      if ((lc_moving->pos + lc_moving->size) > lc->pos)
+                        {
+                           lc_moving->pos = (lc->pos - lc_moving->size) + 1;
+                           _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+                        }
+                      lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc_moving, lc);
+                      if (lc3)
+                        {
+                           if ((lc_moving->prev_pos + lc_moving->size) == lc->pos)
+                             ok = 1;
+
+                           l->data = lc3;
+                           *list = eina_list_remove_list(*list, eina_list_next(l));
+                           LC_FREE(lc_moving);
+                           LC_FREE(lc);
+                           lc_moving = lc3;
+                        }
+                   }
+              }
+         }
+
+       if (!ok)
+         {
+            int pos, prev_pos, stop;
+            
+            EINA_LIST_FOREACH(*list, l, lc)
+               if (lc == lc_moving) break;
+
+            pos = lc_moving->pos;
+            prev_pos = lc_moving_prev_pos;
+
+            if ((l) && eina_list_prev(l))
+              {
+                 stop = 0;
+                 /* EINA_FUCK_REVERSE_FOREACH(eina_list_prev(l), l2, lc) */
+                 for (l2 = l->prev; l2; l2 = l2->prev)
+                   {
+                      lc = l2->data;
+                      
+                      if (stop) break;
+                      if ((lc->pos + lc->size) == prev_pos) break;
+                      prev_pos = lc->pos;
+
+                      EINA_LIST_REVERSE_FOREACH(lc->items, l3, bi)
+                        {
+                           if ((bi->ask.pos + bi->w) >= pos)
+                             {
+                                bi->x = pos - bi->w;
+                                pos = bi->x;
+                             }
+                           else if (bi->ask.pos > bi->x)
+                             {
+                                bi->x = bi->ask.pos;
+                                pos = bi->x;
+                             }
+                           else if (bi->ask.pos == bi->x)
+                             {
+                                stop = 1;
+                                break;
+                             }
+                        }
+                   }
+              }
+         }
+     } 
+   else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC)
+     { 
+       _e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list); 
+       EINA_LIST_FOREACH(*list, l, lc)
+          if (lc == lc_moving) break;
+
+       if ((l) && eina_list_prev(l))
+         {
+            int new_pos = 0;
+
+            ok = 0;
+            new_pos = lc_moving->pos;
+            /* EINA_FUCK_REVERSE_FOREACH(eina_list_prev(l), l2, lc) */
+            for (l2 = l->prev; l2; l2 = l2->prev)
+              {
+                 lc = l2->data;                  
+                 if (new_pos >= (lc->pos + lc->size)) break;
+
+                 ok = 1;
+                 new_pos -= lc->size;
+              }
+
+            if (new_pos < 0)
+              {
+                 lc_moving->size += new_pos;
+                 lc_moving->pos -= new_pos;
+
+                 bi = eina_list_data_get(lc_moving->items);
+                 bi->w = lc_moving->size;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+
+                 new_pos = 0;
+              }
+
+            if (ok)
+              { 
+                 if (!l2) l2 = *list; 
+                 else l2 = eina_list_next(l2);
+
+                 EINA_LIST_FOREACH(l2, l2, lc)
+                   { 
+                      if (l2 == l) break;
+                      lc->pos = new_pos; 
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc); 
+                      EINA_LIST_FOREACH(lc->items, l3, bi)
+                        {
+                           bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+                        }
+                      new_pos += lc->size; 
+                   }
+              }
+         }
+       else if ((l) && (!eina_list_prev(l)))
+         {
+            if (lc_moving->pos <= 0)
+              {
+                 lc_moving->size = lc_moving->prev_size;
+                 lc_moving->pos = 0;
+
+                 bi = eina_list_data_get(lc_moving->items);
+                 bi->w = lc_moving->size;
+
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc_moving);
+              }
+         }
+     }
+   else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC)
+     {
+       lc_moving->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+       _e_gadcon_layout_smart_gadcons_position_static(sd, list);
+       if (lc_back) LC_FREE(lc_back);
+     }
+   else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC)
+     {
+       _e_gadcon_layout_smart_restore_gadcons_position_before_move(sd, &lc_moving, lc_back, list); 
+       EINA_LIST_FOREACH(*list, l, lc)
+          if (lc == lc_moving) break;
+
+       if ((l) && eina_list_next(l))
+         {
+            Eina_List *stop = NULL;
+            int new_pos = 0;
+
+            ok = 0;
+            new_pos = lc_moving->pos + lc_moving->size;
+            EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
+              {
+                 if (new_pos <= lc->pos)
+                   {
+                      stop = l2;
+                      break;
+                   }
+
+                 ok = 1;
+                 /* new_pos += lc->size; */
+              }
+
+            if (new_pos > sd->w)
+              {
+                 lc_moving->size -= (new_pos - sd->w);
+                 bi = eina_list_data_get(lc_moving->items);
+                 bi->w = lc_moving->size;
+
+                 new_pos = lc_moving->pos + lc_moving->size;
+              }
+
+            if (ok)
+              {
+                 EINA_LIST_FOREACH(eina_list_next(l), l2, lc)
+                   {
+                      if (l2 == stop) break;
+                      lc->pos = new_pos;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+                      EINA_LIST_FOREACH(lc->items, l3, bi)
+                        {
+                           bi->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+                        }
+                      new_pos += lc->size;
+                   }
+              }
+         }
+       else if ((l) && (!eina_list_next(l)))
+         {
+            if ((lc_moving->pos + lc_moving->size) >= sd->w)
+              {
+                 lc_moving->size = lc_moving->prev_size;
+                 bi = eina_list_data_get(lc_moving->items);
+                 bi->w = lc_moving->size;
+              }
+         }
+     }
+   else if (lc_moving->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC)
+     {
+       lc_moving->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+       _e_gadcon_layout_smart_gadcons_position_static(sd, list);
+       if (lc_back) LC_FREE(lc_back);
+     }
+
+   if (bi_moving)
+     {
+       bi_moving->gcc->config.pos = bi_moving->ask.pos = bi_moving->x; 
+       bi_moving->gcc->config.size = bi_moving->w;
+     }
+}
+
+static void
+_e_gadcon_layout_smart_gadcons_position_static(E_Smart_Data *sd, Eina_List **list)
+{
+   int ok;
+   Eina_List *l;
+   E_Layout_Item_Container *lc, *lc2, *lc3;
+
+   *list = eina_list_sort(*list, eina_list_count(*list), _e_gadcon_layout_smart_containers_sort_cb);
+
+   __reposition_again:
+   EINA_LIST_FOREACH(*list, l, lc)
+     {
+       if (!eina_list_next(l)) continue;
+
+       lc2 = eina_list_data_get(eina_list_next(l));
+
+       if (LC_OVERLAP(lc, lc2))
+         {
+            lc3 = _e_gadcon_layout_smart_containers_position_adjust(sd, lc, lc2);
+            if (lc3)
+              { 
+                 l->data = lc3; 
+                 *list = eina_list_remove_list(*list, eina_list_next(l)); 
+                 LC_FREE(lc);
+                 LC_FREE(lc2);
+                 goto __reposition_again;
+              }
+         }
+     }
+
+   ok = 1;
+   EINA_LIST_FOREACH(*list, l, lc)
+     {
+       if (lc->pos < 0)
+         {
+            ok = 0;
+            lc->pos = 0;
+            _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+            continue;
+         }
+
+       if (((lc->pos + lc->size) > sd->w) && (lc->size <= sd->w))
+         {
+            ok = 0;
+            lc->pos = sd->w - lc->size;
+            _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+         }
+     }
+   if (!ok)
+     _e_gadcon_layout_smart_gadcons_position_static(sd, list);
+}
+
+static E_Layout_Item_Container *
+_e_gadcon_layout_smart_containers_position_adjust(E_Smart_Data *sd, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2)
+{
+   int create_new = 0;
+   Eina_List *l;
+   E_Layout_Item_Container *lc3 = NULL;
+   E_Layout_Item_Container_State new_state;
+   E_Gadcon_Layout_Item *bi, *bi2;
+
+   if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
+       (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
+     {
+       if (lc->state_info.max_seq <= lc2->state_info.min_seq)
+         {
+            lc2->pos = lc->pos + lc->size;
+            _e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
+         }
+       else if (lc->state_info.min_seq > lc2->state_info.max_seq)
+         {
+            lc->pos = lc2->pos + lc2->size;
+            _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+         }
+       else if (((lc->state_info.min_seq > lc2->state_info.min_seq) &&
+                 (lc->state_info.min_seq < lc2->state_info.max_seq)) ||
+                ((lc2->state_info.min_seq > lc->state_info.min_seq) &&
+                 (lc2->state_info.min_seq < lc->state_info.max_seq)))
+         {
+            _e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
+         } 
+       create_new = 1; 
+       new_state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
+     }
+   else if ((lc->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
+           (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
+     {
+       if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC)
+         {
+            int t;
+
+            bi = eina_list_data_get(lc->items);
+            bi2 = eina_list_data_get(lc2->items);
+
+            bi->x = ((bi2->x) + (bi2->w)) - (bi->w);
+            bi->gcc->config.pos = bi->ask.pos = bi->x;
+            bi->gcc->config.size = bi->w;
+            bi2->x = (bi->x) - (bi2->w);
+
+            bi2->gcc->state_info.flags &= ~E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE;
+
+            t = bi->gcc->state_info.seq;
+            bi->gcc->state_info.seq = bi2->gcc->state_info.seq;
+            bi2->gcc->state_info.seq = t;
+
+            _e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
+         }
+       else if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED)
+         {
+            if (lc->state_info.max_seq < lc2->state_info.min_seq)
+              {
+                 lc2->pos = lc->pos + lc->size;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
+              }
+            else if (lc->state_info.min_seq > lc2->state_info.max_seq)
+              {
+                 lc2->pos = lc->pos - lc2->size;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
+              } 
+            else if (((lc->state_info.min_seq > lc2->state_info.min_seq) && 
+                     (lc->state_info.min_seq < lc2->state_info.max_seq)) || 
+                    ((lc2->state_info.min_seq > lc->state_info.min_seq) && 
+                     (lc2->state_info.min_seq < lc->state_info.max_seq)))
+              {
+                 int shift = 0;
+
+                 _e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
+
+                 EINA_LIST_FOREACH(lc->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION)
+                        {
+                           shift = bi->ask.pos - bi->x;
+                        }
+
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        break;
+                   }
+
+                 if (shift)
+                   {
+                      EINA_LIST_FOREACH(lc->items, l, bi)
+                        {
+                           bi->x += shift;
+                           
+                           if (l == lc->items)
+                             lc->pos = bi->x;
+                        }
+                   } 
+              } 
+         }
+       create_new = 1; 
+       new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+     }
+   else if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
+           (lc2->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
+     {
+       if (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED)
+         {
+            if (lc->state_info.max_seq < lc2->state_info.min_seq)
+              {
+                 lc->pos = lc2->pos - lc->size;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+              }
+            else if (lc->state_info.min_seq > lc2->state_info.max_seq)
+              {
+                 lc->pos = lc2->pos + lc2->size;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+              }
+            else if (((lc->state_info.min_seq > lc2->state_info.min_seq) && 
+                     (lc->state_info.min_seq < lc2->state_info.max_seq)) || 
+                    ((lc2->state_info.min_seq > lc->state_info.min_seq) && 
+                     (lc2->state_info.min_seq < lc->state_info.max_seq)))
+              {
+                 int shift = 0;
+
+                 EINA_LIST_FOREACH(lc->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION)
+                        {
+                           shift = bi->ask.pos - bi->x;
+                        }
+
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        break;
+                   }
+
+                 if (shift)
+                   {
+                      EINA_LIST_FOREACH(lc->items, l, bi)
+                        {
+                           bi->x += shift;
+
+                           if (l == lc->items)
+                             lc->pos = bi->x;
+                        }
+                   }
+              }
+         }
+       else if (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC)
+         {
+            int t;
+
+            bi = eina_list_data_get(eina_list_last(lc->items));
+            bi2 = eina_list_data_get(lc2->items);
+
+            bi2->gcc->config.pos = bi2->ask.pos = (bi2->x) = (bi->x);
+            bi2->gcc->config.size = bi2->w;
+            bi->x = bi2->x + bi2->w;
+
+            t = bi->gcc->state_info.seq;
+            bi->gcc->state_info.seq = bi2->gcc->state_info.seq;
+            bi2->gcc->state_info.seq = t;
+
+            lc->items = eina_list_remove_list(lc->items, eina_list_last(lc->items));
+            lc->items = eina_list_append(lc->items, bi2);
+            lc->items = eina_list_append(lc->items, bi);
+            lc2->items = eina_list_free(lc2->items);
+            E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc, bi2, 1);
+            lc2->pos = lc->pos + lc->size;
+            lc2->size = 0;
+         }
+       create_new = 1;
+       new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+     }
+   else if ((lc->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE) &&
+           (lc2->state != E_LAYOUT_ITEM_CONTAINER_STATE_NONE))
+     {
+       if ((lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED) &&
+           (lc2->state == E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED))
+         {
+            if (lc->state_info.max_seq < lc2->state_info.min_seq)
+              {
+                 int move_lc1 = 1;
+                 int move_lc2 = 1;
+
+                 EINA_LIST_FOREACH(lc->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        {
+                           move_lc1 = 0;
+                           break;
+                        }
+                   }
+                 EINA_LIST_FOREACH(lc2->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        {
+                           move_lc2 = 0;
+                           break;
+                        }
+                   }
+
+                 if ((move_lc1) && (!move_lc2))
+                   {
+                      lc->pos = lc2->pos - lc->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+                   }
+                 else
+                   {
+                      lc2->pos = lc->pos + lc->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
+                   }
+              }
+            else if (lc->state_info.min_seq > lc2->state_info.max_seq)
+              {
+                 int move_lc1 = 1;
+                 int move_lc2 = 1;
+
+                 EINA_LIST_FOREACH(lc->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        {
+                           move_lc1 = 0;
+                           break;
+                        }
+                   }
+                 EINA_LIST_FOREACH(lc2->items, l, bi)
+                   {
+                      if (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE)
+                        {
+                           move_lc2 = 0;
+                           break;
+                        }
+                   }
+
+                 if ((!move_lc1) && (move_lc2))
+                   {
+                      lc2->pos = lc->pos - lc2->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc2);
+                   }
+                 else
+                   {
+                      lc->pos = lc2->pos + lc2->size;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, lc);
+                   }
+              }
+            else if (((lc->state_info.min_seq > lc2->state_info.min_seq) && 
+                     (lc->state_info.min_seq < lc2->state_info.max_seq)) || 
+                    ((lc2->state_info.min_seq > lc->state_info.min_seq) && 
+                     (lc2->state_info.min_seq < lc->state_info.max_seq)))
+              {
+                 int shift = 0;
+
+                 _e_gadcon_layout_smart_containers_merge(sd, lc, lc2);
+
+                 EINA_LIST_FOREACH(lc->items, l, bi)
+                   {
+                      if ((bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_POSITION) &&
+                          (bi->gcc->state_info.flags & E_GADCON_LAYOUT_ITEM_LOCK_ABSOLUTE))
+                        {
+                           shift = bi->ask.pos - bi->x;
+                           break;
+                        }
+                   }
+
+                 if (shift)
+                   {
+                      EINA_LIST_FOREACH(lc->items, l, bi)
+                        {
+                           bi->x += shift;
+                           
+                           if (l == lc->items)
+                             lc->pos = bi->x;
+                        }
+                   }
+              } 
+            create_new = 1; 
+            new_state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+         }
+     }
+
+   if (create_new)
+     {
+       lc3 = E_NEW(E_Layout_Item_Container, 1);
+       lc3->sd = sd;
+       if (lc->pos < lc2->pos)
+         {
+            lc3->pos = lc->pos;
+            EINA_LIST_FOREACH(lc->items, l, bi)
+               lc3->items = eina_list_append(lc3->items, bi);
+            EINA_LIST_FOREACH(lc2->items, l, bi)
+               lc3->items = eina_list_append(lc3->items, bi);
+
+            lc3->state_info.min_seq = lc->state_info.min_seq;
+            if (lc2->items)
+              lc3->state_info.max_seq = lc2->state_info.max_seq;
+            else
+              lc3->state_info.max_seq = lc->state_info.max_seq;
+         }
+       else
+         {
+            lc3->pos = lc2->pos;
+            EINA_LIST_FOREACH(lc2->items, l, bi)
+              lc3->items = eina_list_append(lc3->items, bi);
+            EINA_LIST_FOREACH(lc->items, l, bi)
+              lc3->items = eina_list_append(lc3->items, bi);
+
+            lc3->state_info.min_seq = lc2->state_info.min_seq;
+            if (lc->items)
+              lc3->state_info.max_seq = lc->state_info.max_seq;
+            else
+              lc3->state_info.max_seq = lc2->state_info.max_seq;
+         }
+       lc3->size = lc->size + lc2->size;
+       lc3->state = new_state;
+     }
+
+   return lc3;
+} 
+
+static void
+_e_gadcon_layout_smart_position_items_inside_container(E_Smart_Data *sd __UNUSED__, E_Layout_Item_Container *lc)
+{
+   int shift;
+   Eina_List *l;
+   E_Gadcon_Layout_Item *bi;
+
+   if (!lc->items) return;
+
+   bi = eina_list_data_get(lc->items);
+   shift = lc->pos - bi->x;
+   
+   if (!shift) return;
+
+   EINA_LIST_FOREACH(lc->items, l, bi)
+     {
+       bi->x += shift;
+       
+       if ((bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_DEC) ||
+           (bi->gcc->state_info.state == E_LAYOUT_ITEM_STATE_POS_INC))
+         {
+            bi->gcc->config.pos = bi->ask.pos = bi->x;
+         }
+     }
+} 
+
+static void
+_e_gadcon_layout_smart_containers_merge(E_Smart_Data *sd __UNUSED__, E_Layout_Item_Container *lc, E_Layout_Item_Container *lc2)
+{
+   int start = 0, size = 0, next = 0, min_seq = 0, max_seq = 0;
+   Eina_List *l, *nl = NULL;
+   E_Gadcon_Layout_Item *bi;
+
+   EINA_LIST_FOREACH(lc->items, l, bi)
+     nl = eina_list_append(nl, bi);
+   EINA_LIST_FOREACH(lc2->items, l, bi)
+     nl = eina_list_append(nl, bi);
+
+   nl = eina_list_sort(nl, eina_list_count(nl), _e_gadcon_layout_smart_seq_sort_cb);
+
+   EINA_LIST_FOREACH(nl, l, bi)
+     {
+       if (l == nl)
+         {
+            min_seq = max_seq = bi->gcc->state_info.seq;
+            start = bi->x;
+            size = bi->w;
+            next = bi->x + bi->w;
+
+            continue;
+         }
+
+       max_seq = bi->gcc->state_info.seq;
+
+       bi->x = next;
+       size += bi->w;
+       next = bi->x + bi->w;
+     }
+
+   lc->items = eina_list_free(lc->items);
+   lc2->items = eina_list_free(lc->items);
+   lc->items = nl;
+   lc->pos = start;
+   lc->size = size;
+   lc->state_info.min_seq = min_seq;
+   lc->state_info.max_seq = max_seq;
+   lc2->pos = lc->pos + lc->size;
+   lc2->size = 0;
+} 
+
+static void
+_e_gadcon_layout_smart_restore_gadcons_position_before_move(E_Smart_Data *sd, E_Layout_Item_Container **lc_moving, E_Layout_Item_Container *lc_back, Eina_List **con_list)
+{
+   int ok;
+   Eina_List *l, *l2, *l3;
+   E_Gadcon_Layout_Item *bi, *bi2;
+   E_Layout_Item_Container *lc, *lc2, *lc3;
+
+   (*lc_moving)->pos = (*lc_moving)->prev_pos;
+   if (((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_INC) || 
+       ((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MIN_END_DEC) || 
+       ((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_INC) || 
+       ((*lc_moving)->state == E_LAYOUT_ITEM_CONTAINER_STATE_SIZE_MAX_END_DEC))
+     {
+       (*lc_moving)->size = (*lc_moving)->prev_size;
+       bi = eina_list_data_get((*lc_moving)->items);
+
+       bi->w = (*lc_moving)->prev_size;
+     }
+   _e_gadcon_layout_smart_position_items_inside_container(sd, (*lc_moving));
+   (*lc_moving)->state = E_LAYOUT_ITEM_CONTAINER_STATE_POS_LOCKED;
+   _e_gadcon_layout_smart_gadcons_position_static(sd, con_list);
+
+   lc2 = NULL;
+   lc3 = NULL;
+   ok = 0;
+   EINA_LIST_FOREACH(*con_list, l, lc)
+     {
+       if (lc->state == E_LAYOUT_ITEM_CONTAINER_STATE_NONE) continue;
+
+       if (eina_list_count(lc->items) == 1)
+         {
+            bi = eina_list_data_get(lc->items);
+            if (bi->gcc->state_info.state != E_LAYOUT_ITEM_STATE_NONE)
+              {
+                 LC_FREE(lc);
+                 l->data = *lc_moving = lc_back;
+                 _e_gadcon_layout_smart_position_items_inside_container(sd, (*lc_moving));
+
+                 if (((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC) &&
+                     ((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC))
+                   {
+                      bi = eina_list_data_get((*lc_moving)->items);
+                      bi->w = (*lc_moving)->size;
+                   }
+              }
+         }
+       else
+         {
+            EINA_LIST_FOREACH(lc->items, l2, bi)
+              {
+                 if (bi->gcc->state_info.state != E_LAYOUT_ITEM_STATE_NONE)
+                   {
+                      ok = 1;
+                      if (l2 != lc->items)
+                        {
+                           lc2 = E_NEW(E_Layout_Item_Container, 1);
+                           lc2->sd = sd;
+                           lc2->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
+                           EINA_LIST_FOREACH(lc->items, l3, bi2)
+                             {
+                                if(l2 == l3) break;
+                                lc2->items = eina_list_append(lc2->items, bi2);
+                                if (l3 == lc->items)
+                                  {
+                                     lc2->state_info.min_seq = bi2->gcc->state_info.seq;
+                                     lc2->pos = lc2->prev_pos = bi2->x;
+                                  }
+                                lc2->state_info.max_seq = bi2->gcc->state_info.seq;
+                                E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc2, bi2, 1);
+                             }
+                        }
+
+                      if (eina_list_next(l2))
+                        {
+                           lc3 = E_NEW(E_Layout_Item_Container, 1);
+                           lc3->sd = sd;
+                           lc3->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
+                           EINA_LIST_FOREACH(eina_list_next(l2), l3, bi2)
+                             {
+                                lc3->items = eina_list_append(lc3->items, bi2);
+                                if (l3 == eina_list_next(l2))
+                                  {
+                                     lc3->state_info.min_seq = bi2->gcc->state_info.seq;
+                                     lc3->pos = lc3->prev_pos = bi2->x;
+                                  }
+                                lc3->state_info.max_seq = bi2->gcc->state_info.seq;
+                                E_LAYOUT_ITEM_CONTAINER_SIZE_CHANGE_BY(lc3, bi2, 1);
+                             }
+                        }
+                      *lc_moving = lc_back;
+                      _e_gadcon_layout_smart_position_items_inside_container(sd, *lc_moving); 
+
+                      if (((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_INC) && 
+                          ((*lc_moving)->state != E_LAYOUT_ITEM_CONTAINER_STATE_POS_DEC)) 
+                        { 
+                           bi = eina_list_data_get((*lc_moving)->items); 
+                           bi->w = (*lc_moving)->size; 
+                        }
+                      break;
+                   }
+              }
+            if (ok)
+              {
+                 LC_FREE(lc);
+                 if (lc2)
+                   {
+                      l->data = lc2;
+                      *con_list = eina_list_append(*con_list, *lc_moving);
+                      if (lc3)
+                        *con_list = eina_list_append(*con_list, lc3);
+                      *con_list = eina_list_sort(*con_list, eina_list_count(*con_list),
+                                                 _e_gadcon_layout_smart_containers_sort_cb);
+                   }
+                 else
+                   {
+                      l->data = *lc_moving;
+                      if (lc3)
+                        {
+                           *con_list = eina_list_append(*con_list, lc3);
+                           *con_list = eina_list_sort(*con_list, eina_list_count(*con_list),
+                                                      _e_gadcon_layout_smart_containers_sort_cb);
+                        }
+                   }
+                 break;
+              }
+         }
+     }
+
+   EINA_LIST_FOREACH(*con_list, l, lc)
+     {
+       if (lc == *lc_moving) continue;
+       lc->state = E_LAYOUT_ITEM_CONTAINER_STATE_NONE;
+     }
+}
+
+static Eina_Bool
+_e_gadcon_custom_populate_idler(void *data __UNUSED__)
+{
+   const E_Gadcon_Client_Class *cc;
+   const Eina_List *l;
+   E_Gadcon *gc;
+
+   EINA_LIST_FREE(custom_populate_requests, gc)
+     {
+       e_gadcon_layout_freeze(gc->o_container);
+       EINA_LIST_FOREACH(providers_list, l, cc)
+         {
+            if (gc->populate_class.func)
+              gc->populate_class.func(gc->populate_class.data, gc, cc);
+            else
+              e_gadcon_populate_class(gc, cc);
+         }
+       e_gadcon_layout_thaw(gc->o_container);
+     }
+
+   custom_populate_idler = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_e_gadcon_provider_populate_idler(void *data __UNUSED__)
+{
+   const E_Gadcon_Client_Class *cc;
+   const Eina_List *l;
+   E_Gadcon *gc;
+
+   EINA_LIST_FOREACH(gadcons, l, gc)
+     e_gadcon_layout_freeze(gc->o_container);
+
+   EINA_LIST_FREE(populate_requests, cc)
+     {
+       EINA_LIST_FOREACH(gadcons, l, gc)
+         {
+            if (gc->populate_class.func)
+              gc->populate_class.func(gc->populate_class.data, gc, cc);
+            else
+              e_gadcon_populate_class(gc, cc);
+         }
+     }
+
+   EINA_LIST_FOREACH(gadcons, l, gc)
+     e_gadcon_layout_thaw(gc->o_container);
+
+   populate_idler = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_gadcon_provider_populate_request(const E_Gadcon_Client_Class *cc)
+{
+   if (!populate_idler)
+     populate_idler = ecore_idler_add(_e_gadcon_provider_populate_idler, NULL);
+   if (!eina_list_data_find(populate_requests, cc))
+     populate_requests = eina_list_append(populate_requests, cc);
+}
+
+static void
+_e_gadcon_provider_populate_unrequest(const E_Gadcon_Client_Class *cc)
+{
+   populate_requests = eina_list_remove(populate_requests, cc);
+   if ((!populate_requests) && (populate_idler))
+     {
+       ecore_idler_del(populate_idler);
+       populate_idler = NULL;
+     }
+}
+
+/* gadgets movement between different gadcons */
+
+EAPI E_Gadcon_Location *
+e_gadcon_location_new(const char * name, 
+                     E_Gadcon_Site site,
+                     int (*add_func) (void *data, const E_Gadcon_Client_Class *cc),
+                     void * add_data,
+                     void (*remove_func) (void *data, E_Gadcon_Client *cc),
+                     void * remove_data)
+{
+   E_Gadcon_Location *loc;
+
+   loc  = E_NEW(E_Gadcon_Location, 1);
+   loc->name = eina_stringshare_add(name);
+   loc->site = site;
+   loc->gadget_add.func = add_func; 
+   loc->gadget_add.data = add_data; 
+   loc->gadget_remove.func = remove_func; 
+   loc->gadget_remove.data = remove_data; 
+   loc->icon_name = NULL;
+   return loc;
+}
+
+EAPI void
+e_gadcon_location_set_icon_name(E_Gadcon_Location *loc, const char *name)
+{
+   if (loc->icon_name) eina_stringshare_del(loc->icon_name);
+   if (name)
+     loc->icon_name = eina_stringshare_add(name);
+   else
+     loc->icon_name = NULL;
+}
+
+EAPI void
+e_gadcon_location_free(E_Gadcon_Location *loc)
+{
+   eina_stringshare_del(loc->name);
+   if (loc->icon_name) eina_stringshare_del(loc->icon_name);
+   free(loc);
+}
+
+EAPI void
+e_gadcon_location_register(E_Gadcon_Location * loc)
+{
+   gadcon_locations = eina_list_append(gadcon_locations, loc);
+}
+
+EAPI void
+e_gadcon_location_unregister(E_Gadcon_Location * loc)
+{
+   gadcon_locations = eina_list_remove(gadcon_locations, loc);
+}
+
+static int
+_e_gadcon_location_change(E_Gadcon_Client * gcc, E_Gadcon_Location *src, E_Gadcon_Location *dst)
+{
+   E_Gadcon_Client_Class *cc;
+
+   cc = eina_hash_find(providers, gcc->cf->name);
+   if (!cc) return 0;
+   if (!dst->gadget_add.func(dst->gadget_add.data, cc)) return 0;
+   src->gadget_remove.func(src->gadget_remove.data, gcc);
+   return 1;
+}
+
diff --git a/src/bin/e_wayland/e_gadcon.h b/src/bin/e_wayland/e_gadcon.h
new file mode 100644 (file)
index 0000000..911cb05
--- /dev/null
@@ -0,0 +1,343 @@
+#ifdef E_TYPEDEFS
+
+#define E_GADCON_CLIENT(x) ((E_Gadcon_Client *)(x))
+
+/* different layout policies - only 1 supported for now */
+typedef enum _E_Gadcon_Layout_Policy
+{
+   E_GADCON_LAYOUT_POLICY_PANEL
+} E_Gadcon_Layout_Policy;
+
+typedef enum _E_Gadcon_Orient
+{
+   /* generic orientations */
+   E_GADCON_ORIENT_FLOAT,
+     E_GADCON_ORIENT_HORIZ,
+     E_GADCON_ORIENT_VERT,
+     E_GADCON_ORIENT_LEFT,
+     E_GADCON_ORIENT_RIGHT,
+     E_GADCON_ORIENT_TOP,
+     E_GADCON_ORIENT_BOTTOM,
+     E_GADCON_ORIENT_CORNER_TL,
+     E_GADCON_ORIENT_CORNER_TR,
+     E_GADCON_ORIENT_CORNER_BL,
+     E_GADCON_ORIENT_CORNER_BR,
+     E_GADCON_ORIENT_CORNER_LT,
+     E_GADCON_ORIENT_CORNER_RT,
+     E_GADCON_ORIENT_CORNER_LB,
+     E_GADCON_ORIENT_CORNER_RB
+} E_Gadcon_Orient;
+
+typedef enum _E_Gadcon_Site
+{
+   E_GADCON_SITE_UNKNOWN = 0,        // when target site is unknown
+   /* generic sities */
+   E_GADCON_SITE_SHELF,
+   E_GADCON_SITE_DESKTOP,
+   E_GADCON_SITE_TOOLBAR,            // generic toolbar
+   E_GADCON_SITE_EFM_TOOLBAR         // filemanager window toolbar
+} E_Gadcon_Site;
+
+#define E_GADCON_CLIENT_STYLE_PLAIN "plain"
+#define E_GADCON_CLIENT_STYLE_INSET "inset"
+
+typedef struct _E_Gadcon E_Gadcon;
+typedef struct _E_Gadcon_Client E_Gadcon_Client;
+typedef struct _E_Gadcon_Client_Class E_Gadcon_Client_Class;
+typedef struct _E_Gadcon_Location E_Gadcon_Location;
+
+#else
+#ifndef E_GADCON_H
+#define E_GADCON_H
+
+#define E_GADCON_TYPE 0xE0b01006
+#define E_GADCON_CLIENT_TYPE 0xE0b01007
+
+struct _E_Gadcon
+{
+   E_Object e_obj_inherit;
+
+   const char *name;
+   int id;
+
+   E_Gadcon_Layout_Policy layout_policy;
+
+   struct 
+     {
+       Evas_Object *o_parent;
+       const char *swallow_name;
+     } edje;
+   Ecore_Evas *ecore_evas;
+   E_Zone *zone;
+
+   E_Gadcon_Orient orient;
+
+   Evas *evas;
+   Evas_Object *o_container;
+   Eina_List *clients;
+
+   struct 
+     {
+       void (*func) (void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
+       void *data;
+     } resize_request, min_size_request;
+   struct 
+     {
+       Evas_Object *(*func) (void *data, E_Gadcon_Client *gcc, const char *style);
+       void *data;
+     } frame_request;
+   struct 
+     {
+       void (*func) (void *data, E_Gadcon_Client *gcc, E_Menu *menu);
+       void *data;
+     } menu_attach;
+   struct 
+     {
+       void (*func) (void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc);
+       void *data;
+     } populate_class;
+   struct 
+     {
+       void (*func) (void *data, int lock);
+       void *data;
+     } locked_set;
+   struct 
+     {
+       void (*func) (void *data);
+       void *data;
+     } urgent_show;
+   
+   E_Config_Dialog *config_dialog;
+   unsigned char editing : 1;
+//   Ecore_X_Window dnd_win, xdnd_win;
+   E_Shelf *shelf;
+//   E_Toolbar *toolbar;
+   E_Gadcon_Location *location;
+
+//   E_Drop_Handler *drop_handler;
+
+   E_Config_Gadcon *cf;
+
+   unsigned char instant_edit : 1;
+};
+
+#define GADCON_CLIENT_CLASS_VERSION 3
+/* Version 3 add the *client_class param to icon(),label(),id_new(), id_del() */
+/*           and the *orient param to orient() */
+struct _E_Gadcon_Client_Class
+{
+   int   version;
+   /* All members below are part of version 1 */
+   const char *name;
+   struct 
+     {
+       E_Gadcon_Client *(*init)     (E_Gadcon *gc, const char *name, const char *id, const char *style);
+       void             (*shutdown) (E_Gadcon_Client *gcc);
+       void             (*orient)   (E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
+       const char      *(*label)    (E_Gadcon_Client_Class *client_class);
+       Evas_Object     *(*icon)     (E_Gadcon_Client_Class *client_class, Evas *evas);
+       /* All members below are part of version 2 */
+       /* Create new id, so that the gadcon client can refer to a config set inside the module */
+       const char      *(*id_new)   (E_Gadcon_Client_Class *client_class);
+       /* Del an id when a gadcon client is removed from the system */
+       void             (*id_del)   (E_Gadcon_Client_Class *client_class, const char *id);
+       /* All members below are part of version 3 */
+       Eina_Bool        (*is_site)  (E_Gadcon_Site site);
+     } func;
+   char *default_style;
+};
+
+struct _E_Gadcon_Client
+{
+   E_Object e_obj_inherit;
+   E_Gadcon *gadcon;
+   const char *name;
+   int id;
+   Evas_Object *o_base;
+   Evas_Object *o_box;
+   Evas_Object *o_frame;
+   Evas_Object *o_control;
+   Evas_Object *o_event;
+   const E_Gadcon_Client_Class *client_class;
+   void *data;
+
+   struct 
+     {
+       int pos, size, res;                 //gadcon
+       double pos_x, pos_y, size_w, size_h;   //gadman
+     } config; 
+
+   struct 
+     { 
+       int seq, flags; /* goes to save */
+       int state, resist;
+       int prev_pos, prev_size;
+       int want_save : 1;
+     } state_info;
+
+   struct 
+     {
+       Evas_Coord w, h;
+     } pad, min, aspect;
+
+   Ecore_Timer *scroll_timer;
+   Ecore_Timer *instant_edit_timer;
+   Ecore_Animator *scroll_animator;
+   double scroll_pos, scroll_wanted;
+
+   struct 
+     {
+       void *data;
+       void (*func) (void *data);
+     } scroll_cb;
+
+   E_Menu *menu;
+   const char *style;
+   unsigned char autoscroll : 1;
+   unsigned char resizable : 1;
+   unsigned char moving : 1;
+   unsigned char resizing : 1;
+   unsigned char autoscroll_set : 1;
+   Evas_Coord dx, dy;
+
+   struct 
+     {
+       int x, y;
+     } drag;
+
+   unsigned char hidden : 1;
+
+   E_Config_Gadcon_Client *cf;
+};
+
+/* defines usable gadget placements such as Desktop, Shelf #, etc */
+/* next fields are mandatory (not NULL): name, add_gadget.func, remove_gadget.func */
+struct _E_Gadcon_Location
+{
+   /* location name */
+   const char * name;
+   /* icon related to location, such as "preferences-desktop-shelf" for shelves, "preferences-desktop" for menus */
+   const char * icon_name;
+   E_Gadcon_Site site;
+   /* adds gadcon client to location. Returns nonzero on success */
+   struct 
+     {
+       int (*func) (void *data, const E_Gadcon_Client_Class *cc);
+       void *data;
+     } gadget_add;
+   /* removes existing gadcon client from location */
+   struct 
+     {
+       void (*func) (void *data, E_Gadcon_Client *gcc);
+       void *data;
+     } gadget_remove;
+};
+
+EINTERN int              e_gadcon_init(void);
+EINTERN int              e_gadcon_shutdown(void);
+EAPI void             e_gadcon_provider_register(const E_Gadcon_Client_Class *cc);
+EAPI void             e_gadcon_provider_unregister(const E_Gadcon_Client_Class *cc);
+EAPI Eina_List       *e_gadcon_provider_list(void);
+EAPI E_Gadcon        *e_gadcon_swallowed_new(const char *name, int id, Evas_Object *obj, const char *swallow_name);
+EAPI void             e_gadcon_custom_new(E_Gadcon *gc);
+EAPI void             e_gadcon_custom_del(E_Gadcon *gc);
+EAPI void             e_gadcon_swallowed_min_size_set(E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
+EAPI void             e_gadcon_min_size_request_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data);
+EAPI void             e_gadcon_size_request_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h), void *data);
+EAPI void             e_gadcon_frame_request_callback_set(E_Gadcon *gc, Evas_Object *(*func) (void *data, E_Gadcon_Client *gcc, const char *style), void *data);
+EAPI void             e_gadcon_populate_callback_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon *gc, const E_Gadcon_Client_Class *cc), void *data);
+EAPI void             e_gadcon_layout_policy_set(E_Gadcon *gc, E_Gadcon_Layout_Policy layout_policy);
+EAPI void             e_gadcon_populate(E_Gadcon *gc);
+EAPI void             e_gadcon_unpopulate(E_Gadcon *gc);
+EAPI void             e_gadcon_populate_class(E_Gadcon *gc, const E_Gadcon_Client_Class *cc);
+EAPI void             e_gadcon_orient(E_Gadcon *gc, E_Gadcon_Orient orient);
+EAPI void             e_gadcon_edit_begin(E_Gadcon *gc);
+EAPI void             e_gadcon_edit_end(E_Gadcon *gc);
+EAPI void             e_gadcon_all_edit_begin(void);
+EAPI void             e_gadcon_all_edit_end(void);
+EAPI void             e_gadcon_zone_set(E_Gadcon *gc, E_Zone *zone);
+EAPI E_Zone          *e_gadcon_zone_get(E_Gadcon *gc);
+EAPI void             e_gadcon_ecore_evas_set(E_Gadcon *gc, Ecore_Evas *ee);
+EAPI int              e_gadcon_canvas_zone_geometry_get(E_Gadcon *gc, int *x, int *y, int *w, int *h);
+EAPI void             e_gadcon_util_menu_attach_func_set(E_Gadcon *gc, void (*func) (void *data, E_Gadcon_Client *gcc, E_Menu *menu), void *data);
+EAPI void             e_gadcon_util_lock_func_set(E_Gadcon *gc, void (*func) (void *data, int lock), void *data);
+EAPI void             e_gadcon_util_urgent_show_func_set(E_Gadcon *gc, void (*func) (void *data), void *data);
+EAPI void             e_gadcon_dnd_window_set(E_Gadcon *gc, Ecore_X_Window win);
+EAPI Ecore_X_Window   e_gadcon_dnd_window_get(E_Gadcon *gc);
+EAPI void             e_gadcon_xdnd_window_set(E_Gadcon *gc, Ecore_X_Window win);
+EAPI Ecore_X_Window   e_gadcon_xdnd_window_get(E_Gadcon *gc);
+EAPI void             e_gadcon_shelf_set(E_Gadcon *gc, E_Shelf *shelf);
+EAPI E_Shelf         *e_gadcon_shelf_get(E_Gadcon *gc);
+/* EAPI void             e_gadcon_toolbar_set(E_Gadcon *gc, E_Toolbar *toolbar); */
+/* EAPI E_Toolbar       *e_gadcon_toolbar_get(E_Gadcon *gc); */
+EAPI E_Config_Gadcon_Client *e_gadcon_client_config_new(E_Gadcon *gc, const char *name);
+EAPI void             e_gadcon_client_config_del(E_Config_Gadcon *cf_gc, E_Config_Gadcon_Client *cf_gcc);
+EAPI E_Gadcon_Client *e_gadcon_client_new(E_Gadcon *gc, const char *name, const char *id, const char *style, Evas_Object *base_obj);
+EAPI void             e_gadcon_client_edit_begin(E_Gadcon_Client *gcc);
+EAPI void             e_gadcon_client_edit_end(E_Gadcon_Client *gcc);
+EAPI void             e_gadcon_client_show(E_Gadcon_Client *gcc);
+EAPI void             e_gadcon_client_hide(E_Gadcon_Client *gcc);
+EAPI void             e_gadcon_client_size_request(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h);
+EAPI void             e_gadcon_client_min_size_set(E_Gadcon_Client *gcc, Evas_Coord w, Evas_Coord h);
+EAPI void             e_gadcon_client_aspect_set(E_Gadcon_Client *gcc, int w, int h);
+EAPI void             e_gadcon_client_autoscroll_set(E_Gadcon_Client *gcc, int autoscroll);
+EAPI void             e_gadcon_client_autoscroll_update(E_Gadcon_Client *gcc, int mx, int my);
+EAPI void             e_gadcon_client_autoscroll_cb_set(E_Gadcon_Client *gcc, void (*func)(void *data), void *data);
+EAPI void             e_gadcon_client_resizable_set(E_Gadcon_Client *gcc, int resizable);
+EAPI int             e_gadcon_client_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h);
+EAPI int              e_gadcon_client_viewport_geometry_get(E_Gadcon_Client *gcc, int *x, int *y, int *w, int *h);
+EAPI E_Zone          *e_gadcon_client_zone_get(E_Gadcon_Client *gcc);
+EAPI E_Menu          *e_gadcon_client_util_menu_items_append(E_Gadcon_Client *gcc, E_Menu *menu_gadget, int flags);
+EAPI void             e_gadcon_client_util_menu_attach(E_Gadcon_Client *gcc);
+EAPI void             e_gadcon_locked_set(E_Gadcon *gc, int lock);
+EAPI void             e_gadcon_urgent_show(E_Gadcon *gc);
+
+/* site helpers */
+
+EAPI Eina_Bool        e_gadcon_site_is_shelf(E_Gadcon_Site site);
+EAPI Eina_Bool        e_gadcon_site_is_desktop(E_Gadcon_Site site);
+EAPI Eina_Bool        e_gadcon_site_is_efm_toolbar(E_Gadcon_Site site);
+
+EAPI Eina_Bool        e_gadcon_site_is_any_toolbar(E_Gadcon_Site site); // all toolbar sities
+EAPI Eina_Bool        e_gadcon_site_is_not_toolbar(E_Gadcon_Site site); // all non-toolbar sities
+
+/* location helpers */
+
+EAPI E_Gadcon_Location *
+e_gadcon_location_new(const char * name, E_Gadcon_Site site,
+                      int (*add_func) (void *data, const E_Gadcon_Client_Class *cc),
+                      void *add_data,
+                      void (*remove_func) (void *data, E_Gadcon_Client *cc),
+                      void *remove_data);
+EAPI void e_gadcon_location_free(E_Gadcon_Location *loc);
+EAPI void e_gadcon_location_register (E_Gadcon_Location *loc);
+EAPI void e_gadcon_location_unregister (E_Gadcon_Location *loc);
+EAPI void e_gadcon_location_set_icon_name(E_Gadcon_Location *loc, const char *name);
+EAPI void e_gadcon_client_add_location_menu(E_Gadcon_Client *gcc, E_Menu *menu);
+
+#define GADCON_CLIENT_CONFIG_GET(_type, _items, _gc_class, _id)                \
+  if (!_id)                                                            \
+    {                                                                  \
+       char buf[128];                                                  \
+       int num = 0;                                                    \
+       _type *ci;                                                      \
+       if (_items)                                                     \
+        {                                                              \
+           const char *p;                                              \
+           ci = eina_list_last(_items)->data;                          \
+           p = strrchr (ci->id, '.');                                  \
+           if (p) num = atoi (p + 1) + 1;                              \
+        }                                                              \
+       snprintf (buf, sizeof (buf), "%s.%d", _gc_class.name, num);     \
+       _id = buf;                                                      \
+    }                                                                  \
+  else                                                                 \
+    {                                                                  \
+       Eina_List *l;                                                   \
+       _type *ci;                                                      \
+       EINA_LIST_FOREACH(_items, l, ci)                                        \
+        if ((ci->id) && (!strcmp(ci->id, id))) return ci;              \
+    }
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_icon.c b/src/bin/e_wayland/e_icon.c
new file mode 100644 (file)
index 0000000..7d25e97
--- /dev/null
@@ -0,0 +1,1243 @@
+#include "e.h"
+
+//#define USE_ICON_CACHE
+
+typedef struct _E_Smart_Data E_Smart_Data;
+typedef struct _Cache_Item   Cache_Item;
+typedef struct _Cache        Cache;
+
+struct _E_Smart_Data
+{
+   Evas_Coord    x, y, w, h;
+   Evas_Object  *obj;
+   Evas_Object  *eventarea;
+   const char   *fdo;
+   Ecore_Timer  *guessing_animation;
+   Ecore_Timer  *timer, *fdo_reload_timer;
+#ifdef USE_ICON_CACHE
+   const char   *file;
+   Cache_Item   *ci;
+#endif
+   double        last_resize;
+   int           size;
+   int           frame, frame_count;
+   unsigned char fill_inside : 1;
+   unsigned char scale_up : 1;
+   unsigned char preload : 1;
+   unsigned char loading : 1;
+   unsigned char animated : 1;
+   Eina_Bool     edje : 1;
+};
+
+struct _Cache_Item
+{
+   unsigned int timestamp;
+
+   Evas_Object *icon, *obj;
+   const char  *id;
+   Eina_List   *objs;
+};
+
+struct _Cache
+{
+   Eina_Hash   *hash;
+
+   char        *file;
+   Eet_File    *ef;
+   Ecore_Timer *timer;
+   Eina_List   *load_queue;
+};
+
+/* local subsystem functions */
+static void      _e_icon_smart_reconfigure(E_Smart_Data *sd);
+static void      _e_icon_smart_init(void);
+static void      _e_icon_smart_add(Evas_Object *obj);
+static void      _e_icon_smart_del(Evas_Object *obj);
+static void      _e_icon_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void      _e_icon_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void      _e_icon_smart_show(Evas_Object *obj);
+static void      _e_icon_smart_hide(Evas_Object *obj);
+static void      _e_icon_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void      _e_icon_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
+static void      _e_icon_smart_clip_unset(Evas_Object *obj);
+static void      _e_icon_obj_prepare(Evas_Object *obj, E_Smart_Data *sd);
+static void      _e_icon_preloaded(void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+#ifdef USE_ICON_CACHE
+static Eina_Bool _e_icon_cache_find(Evas_Object *o, const char *file);
+static void      _e_icon_cache_icon_loaded(Cache_Item *ci);
+static void      _e_icon_cache_icon_try_next(Cache_Item *ci);
+static void      _e_icon_cache_item_free(void *data);
+static void      _e_icon_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
+#endif
+
+/* local subsystem globals */
+static Evas_Smart *_e_smart = NULL;
+
+#ifdef USE_ICON_CACHE
+static Cache *_cache = NULL;
+static E_Config_DD *cache_edd = NULL;
+static E_Config_DD *cache_item_edd = NULL;
+#define DBG(...)
+#endif
+
+EINTERN int
+e_icon_init(void)
+{
+#ifdef USE_ICON_CACHE
+
+   Eet_File *ef;
+   char buf[PATH_MAX];
+
+#undef T
+#undef D
+#define T Cache_Item
+#define D cache_item_edd
+   D = E_CONFIG_DD_NEW("Cache_Item", T);
+   E_CONFIG_VAL(D, T, timestamp, UINT);
+#undef T
+#undef D
+#define T Cache
+#define D cache_edd
+   D = E_CONFIG_DD_NEW("Cache", T);
+   E_CONFIG_HASH(D, T, hash, cache_item_edd);
+#undef T
+#undef D
+
+   e_user_dir_concat_static(buf, "icon_cache.eet");
+
+   ef = eet_open(buf, EET_FILE_MODE_READ_WRITE);
+   if (!ef) return 1;  /* not critical */
+
+   _cache = eet_data_read(ef, cache_edd, "idx");
+   if (!_cache)
+     _cache = E_NEW(Cache, 1);
+
+   if (!_cache->hash)
+     _cache->hash = eina_hash_string_superfast_new(_e_icon_cache_item_free);
+
+   eet_close(ef);
+
+   _cache->file = strdup(buf);
+
+   _cache->ef = NULL;
+#endif
+   return 1;
+}
+
+EINTERN int
+e_icon_shutdown(void)
+{
+#ifdef USE_ICON_CACHE
+   if (_cache)
+     {
+        E_FREE(_cache->file);
+
+        if (_cache->ef)
+          eet_close(_cache->ef);
+
+        if (_cache->load_queue)
+          eina_list_free(_cache->load_queue);
+
+        eina_hash_free(_cache->hash);
+        E_FREE(_cache);
+     }
+
+   E_CONFIG_DD_FREE(cache_item_edd);
+   E_CONFIG_DD_FREE(cache_edd);
+#endif
+
+   return 1;
+}
+
+/* externally accessible functions */
+EAPI Evas_Object *
+e_icon_add(Evas *evas)
+{
+   _e_icon_smart_init();
+   return evas_object_smart_add(evas, _e_smart);
+}
+
+static void
+_e_icon_obj_prepare(Evas_Object *obj, E_Smart_Data *sd)
+{
+   if (!sd->obj) return;
+
+   if (sd->edje)
+     {
+        Evas_Object *pclip;
+
+        pclip = evas_object_clip_get(sd->obj);
+        evas_object_del(sd->obj);
+#ifdef USE_ICON_CACHE
+        sd->ci = NULL;
+        eina_stringshare_replace(&sd->file, NULL);
+#endif
+        sd->obj = evas_object_image_add(evas_object_evas_get(obj));
+        if (!sd->animated)
+          evas_object_image_scale_hint_set(sd->obj,
+                                           EVAS_IMAGE_SCALE_HINT_STATIC);
+        evas_object_smart_member_add(sd->obj, obj);
+        evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
+                                       _e_icon_preloaded, obj);
+        evas_object_clip_set(sd->obj, pclip);
+     }
+}
+
+static Eina_Bool
+_frame_anim(void *data)
+{
+   E_Smart_Data *sd = data;
+   double t;
+   int fr;
+
+   sd->frame++;
+   fr = (sd->frame % (sd->frame_count)) + 1;
+   evas_object_image_animated_frame_set(sd->obj, fr);
+   t = evas_object_image_animated_frame_duration_get(sd->obj, fr, 0);
+   sd->timer = ecore_timer_add(t, _frame_anim, sd);
+   return EINA_FALSE;
+}
+
+static int
+_handle_anim(E_Smart_Data *sd)
+{
+   double t;
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   if (!evas_object_image_animated_get(sd->obj)) return 0;
+   // FIXME: hack around jiyouns BUG!!!!!!!!
+   {
+      const char *file;
+      char buf[256];
+      snprintf(buf, sizeof(buf), "%ld", (long)sd);
+      evas_object_image_file_get(sd->obj, &file, NULL);
+      evas_object_image_file_set(sd->obj, file, buf);
+   }
+   sd->frame_count = evas_object_image_animated_frame_count_get(sd->obj);
+   if (sd->frame_count < 2) return 0;
+   evas_object_show(sd->obj);
+   t = evas_object_image_animated_frame_duration_get(sd->obj, sd->frame, 0);
+   sd->timer = ecore_timer_add(t, _frame_anim, sd);
+   return 1;
+}
+
+EAPI Eina_Bool
+e_icon_file_set(Evas_Object *obj, const char *file)
+{
+   E_Smart_Data *sd;
+   int len;
+
+   if (!file) return EINA_FALSE;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   len = strlen(file);
+   if ((len > 4) && (!strcasecmp(file + len - 4, ".edj")))
+     return e_icon_file_edje_set(obj, file, "icon");
+
+   /* smart code here */
+   _e_icon_obj_prepare(obj, sd);
+   /* FIXME: 64x64 - unhappy about this. use icon size */
+   sd->loading = 0;
+   if (sd->fdo)
+     {
+        eina_stringshare_del(sd->fdo);
+        sd->fdo = NULL;
+     }
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_FALSE;
+
+   if (sd->size != 0)
+     evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+   if (sd->preload) evas_object_hide(sd->obj);
+
+#ifdef USE_ICON_CACHE
+   if (_e_icon_cache_find(obj, file))
+     {
+        _e_icon_smart_reconfigure(sd);
+        return EINA_TRUE;
+     }
+#endif
+
+   evas_object_image_file_set(sd->obj, file, NULL);
+   if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
+     return EINA_FALSE;
+
+   if (!_handle_anim(sd))
+     {
+        if (sd->preload)
+          {
+             sd->loading = 1;
+             evas_object_image_preload(sd->obj, EINA_FALSE);
+          }
+        else if (evas_object_visible_get(obj))
+          {
+             evas_object_show(sd->obj);
+#ifdef USE_ICON_CACHE
+             _e_icon_cache_icon_loaded(sd->ci);
+#endif
+          }
+     }
+#ifdef USE_ICON_CACHE
+   else
+     {
+        evas_object_event_callback_del_full(sd->obj, EVAS_CALLBACK_DEL,
+                                            _e_icon_obj_del, obj);
+        _cache->load_queue = eina_list_remove(_cache->load_queue, sd->ci);
+        eina_stringshare_del(sd->ci->id);
+        E_FREE(sd->ci);
+        sd->ci = NULL;
+     }
+#endif
+
+   _e_icon_smart_reconfigure(sd);
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+e_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   /* smart code here */
+   sd->loading = 0;
+   if (sd->fdo)
+     {
+        eina_stringshare_del(sd->fdo);
+        sd->fdo = NULL;
+     }
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_FALSE;
+
+   _e_icon_obj_prepare(obj, sd);
+   if (sd->size != 0)
+     evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+   if (sd->preload) evas_object_hide(sd->obj);
+   evas_object_image_file_set(sd->obj, file, key);
+   if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
+     return EINA_FALSE;
+   if (!_handle_anim(sd))
+     {
+        if (sd->preload)
+          {
+             sd->loading = 1;
+             evas_object_image_preload(sd->obj, 0);
+          }
+        else if (evas_object_visible_get(obj))
+          evas_object_show(sd->obj);
+     }
+   _e_icon_smart_reconfigure(sd);
+   return EINA_TRUE;
+}
+
+EAPI void
+e_icon_edje_object_set(Evas_Object *obj, Evas_Object *edje)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+
+   /* smart code here */
+   if (sd->obj) evas_object_del(sd->obj);
+   sd->loading = 0;
+   if (sd->fdo)
+     {
+        eina_stringshare_del(sd->fdo);
+        sd->fdo = NULL;
+     }
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_TRUE;
+   sd->obj = edje;
+
+   if (evas_object_visible_get(obj)) evas_object_show(sd->obj);
+   evas_object_smart_member_add(sd->obj, obj);
+   _e_icon_smart_reconfigure(sd);
+}
+
+EAPI Eina_Bool
+e_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   /* smart code here */
+   if (sd->obj) evas_object_del(sd->obj);
+   sd->loading = 0;
+   if (sd->fdo)
+     {
+        eina_stringshare_del(sd->fdo);
+        sd->fdo = NULL;
+     }
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_TRUE;
+
+   sd->obj = edje_object_add(evas_object_evas_get(obj));
+   edje_object_file_set(sd->obj, file, part);
+   if (edje_object_load_error_get(sd->obj) != EDJE_LOAD_ERROR_NONE)
+     return EINA_FALSE;
+   if (evas_object_visible_get(obj)) evas_object_show(sd->obj);
+   evas_object_smart_member_add(sd->obj, obj);
+   _e_icon_smart_reconfigure(sd);
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+e_icon_fdo_icon_set(Evas_Object *obj, const char *icon)
+{
+   E_Smart_Data *sd;
+   const char *path;
+   int len;
+
+   if (!icon) return EINA_FALSE;
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (icon[0] == '/') return e_icon_file_set(obj, icon);
+
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_FALSE;
+
+   eina_stringshare_replace(&sd->fdo, icon);
+   if (!sd->fdo) return EINA_FALSE;
+
+   path = efreet_icon_path_find(e_config->icon_theme, sd->fdo, sd->size);
+   if (!path) return EINA_FALSE;
+
+   len = strlen(icon);
+   if ((len > 4) && (!strcasecmp(icon + len - 4, ".edj")))
+     return e_icon_file_edje_set(obj, path, "icon");
+
+   /* smart code here */
+   _e_icon_obj_prepare(obj, sd);
+   sd->loading = 0;
+   if (sd->size != 0)
+     evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+   if (sd->preload) evas_object_hide(sd->obj);
+   evas_object_image_file_set(sd->obj, path, NULL);
+   if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
+     return EINA_FALSE;
+   if (sd->preload)
+     {
+        sd->loading = 1;
+        evas_object_image_preload(sd->obj, 0);
+     }
+   else if (evas_object_visible_get(obj))
+     evas_object_show(sd->obj);
+   _e_icon_smart_reconfigure(sd);
+   return EINA_TRUE;
+}
+
+EAPI void
+e_icon_object_set(Evas_Object *obj, Evas_Object *o)
+{
+   E_Smart_Data *sd;
+   const char *str;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   str = evas_object_type_get(o);
+   if ((!str) || strcmp(str, "image"))
+     CRI(EINA_COLOR_RED "******************\ntrying to set an image object of type '%s'! this is not what you want!\n******************\n"EINA_COLOR_RESET, str);
+
+   if (sd->timer) ecore_timer_del(sd->timer);
+   sd->timer = NULL;
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   sd->guessing_animation = NULL;
+   sd->frame = 0;
+   sd->frame_count = 0;
+   sd->edje = EINA_FALSE;
+
+   /* smart code here */
+   if (sd->obj) evas_object_del(sd->obj);
+   sd->loading = 0;
+   sd->obj = o;
+   evas_object_smart_member_add(sd->obj, obj);
+   if (evas_object_visible_get(obj)) evas_object_show(sd->obj);
+   _e_icon_smart_reconfigure(sd);
+}
+
+EAPI Eina_Bool
+e_icon_file_get(const Evas_Object *obj, const char **file, const char **group)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(EINA_FALSE);
+   if ((!file) && (!group)) return EINA_FALSE;
+   if (file) *file = NULL;
+   if (group) *group = NULL;
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+#ifdef USE_ICON_CACHE
+   if (sd->file)
+     {
+        if (file) *file = sd->file;
+        return EINA_TRUE;
+     }
+#endif
+   if (sd->edje)
+     {
+        edje_object_file_get(sd->obj, file, group);
+        return file || group;
+     }
+   evas_object_image_file_get(sd->obj, file, group);
+   return file || group;
+}
+
+EAPI void
+e_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if (sd->edje) return;
+   evas_object_image_smooth_scale_set(sd->obj, smooth);
+}
+
+EAPI Eina_Bool
+e_icon_smooth_scale_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+   if (sd->edje)
+     return EINA_FALSE;
+   return evas_object_image_smooth_scale_get(sd->obj);
+}
+
+EAPI void
+e_icon_alpha_set(Evas_Object *obj, Eina_Bool alpha)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if (sd->edje) return;
+   evas_object_image_alpha_set(sd->obj, alpha);
+}
+
+EAPI Eina_Bool
+e_icon_alpha_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+   if (sd->edje) return EINA_FALSE;
+   return evas_object_image_alpha_get(sd->obj);
+}
+
+EAPI void
+e_icon_preload_set(Evas_Object *obj, Eina_Bool preload)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   sd->preload = preload;
+}
+
+EAPI Eina_Bool
+e_icon_preload_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+   return sd->preload;
+}
+
+EAPI void
+e_icon_size_get(const Evas_Object *obj, int *w, int *h)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj)))
+     {
+        if (w) *w = 0;
+        if (h) *h = 0;
+        return;
+     }
+   if (sd->edje)
+     edje_object_size_min_calc(sd->obj, w, h);
+   else
+     evas_object_image_size_get(sd->obj, w, h);
+}
+
+EAPI Eina_Bool
+e_icon_fill_inside_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+   return sd->fill_inside;
+}
+
+EAPI void
+e_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   fill_inside = !!fill_inside;
+   if (sd->fill_inside == fill_inside) return;
+   sd->fill_inside = fill_inside;
+   _e_icon_smart_reconfigure(sd);
+}
+
+EAPI Eina_Bool
+e_icon_scale_up_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
+   return sd->scale_up;
+}
+
+EAPI void
+e_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   scale_up = !!scale_up;
+   if (sd->scale_up == scale_up) return;
+   sd->scale_up = scale_up;
+   _e_icon_smart_reconfigure(sd);
+}
+
+EAPI void
+e_icon_data_set(Evas_Object *obj, void *data, int w, int h)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if (sd->edje) return;
+   evas_object_image_size_set(sd->obj, w, h);
+   evas_object_image_data_copy_set(sd->obj, data);
+}
+
+EAPI void *
+e_icon_data_get(const Evas_Object *obj, int *w, int *h)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(NULL);
+   if (!(sd = evas_object_smart_data_get(obj))) return NULL;
+   if (sd->edje) return NULL;
+   evas_object_image_size_get(sd->obj, w, h);
+   return evas_object_image_data_get(sd->obj, 0);
+}
+
+EAPI void
+e_icon_scale_size_set(Evas_Object *obj, int size)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   sd->size = size;
+   if (sd->edje) return;
+   evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+}
+
+EAPI int
+e_icon_scale_size_get(const Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
+   if (!(sd = evas_object_smart_data_get(obj))) return 0;
+   return sd->size;
+}
+
+EAPI void
+e_icon_selected_set(const Evas_Object *obj, Eina_Bool selected)
+{
+   E_Smart_Data *sd;
+
+   if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if (!sd->edje) return;
+   if (selected)
+     edje_object_signal_emit(sd->obj, "e,state,selected", "e");
+   else
+     edje_object_signal_emit(sd->obj, "e,state,unselected", "e");
+}
+
+/* local subsystem globals */
+static void
+_e_icon_smart_reconfigure(E_Smart_Data *sd)
+{
+   int iw, ih;
+   Evas_Coord x, y, w, h;
+
+   if (!sd->obj) return;
+   if (sd->edje)
+     {
+        w = sd->w;
+        h = sd->h;
+        x = sd->x;
+        y = sd->y;
+        evas_object_move(sd->obj, x, y);
+        evas_object_resize(sd->obj, w, h);
+        evas_object_move(sd->eventarea, x, y);
+        evas_object_resize(sd->eventarea, w, h);
+     }
+   else
+     {
+        ih = 0;
+        ih = 0;
+        evas_object_image_size_get(sd->obj, &iw, &ih);
+        if (iw < 1) iw = 1;
+        if (ih < 1) ih = 1;
+
+        if (sd->fill_inside)
+          {
+             w = sd->w;
+             h = ((double)ih * w) / (double)iw;
+             if (h > sd->h)
+               {
+                  h = sd->h;
+                  w = ((double)iw * h) / (double)ih;
+               }
+          }
+        else
+          {
+             w = sd->w;
+             h = ((double)ih * w) / (double)iw;
+             if (h < sd->h)
+               {
+                  h = sd->h;
+                  w = ((double)iw * h) / (double)ih;
+               }
+          }
+        if (!sd->scale_up)
+          {
+             if ((w > iw) || (h > ih))
+               {
+                  w = iw;
+                  h = ih;
+               }
+          }
+        x = sd->x + ((sd->w - w) / 2);
+        y = sd->y + ((sd->h - h) / 2);
+        evas_object_move(sd->obj, x, y);
+        evas_object_image_fill_set(sd->obj, 0, 0, w, h);
+        evas_object_resize(sd->obj, w, h);
+        evas_object_move(sd->eventarea, x, y);
+        evas_object_resize(sd->eventarea, w, h);
+     }
+}
+
+static void
+_e_icon_smart_init(void)
+{
+   if (_e_smart) return;
+   {
+      static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION("e_icon");
+      if (!sc.add)
+        {
+           sc.add = _e_icon_smart_add;
+           sc.del = _e_icon_smart_del;
+           sc.move = _e_icon_smart_move;
+           sc.resize = _e_icon_smart_resize;
+           sc.show = _e_icon_smart_show;
+           sc.hide = _e_icon_smart_hide;
+           sc.color_set = _e_icon_smart_color_set;
+           sc.clip_set = _e_icon_smart_clip_set;
+           sc.clip_unset = _e_icon_smart_clip_unset;
+        }
+      _e_smart = evas_smart_class_new(&sc);
+   }
+}
+
+static void
+_e_icon_preloaded(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(data))) return;
+
+   evas_object_smart_callback_call(data, "preloaded", NULL);
+   evas_object_show(sd->obj);
+   sd->loading = 0;
+
+#ifdef USE_ICON_CACHE
+   _e_icon_cache_icon_loaded(sd->ci);
+#endif
+}
+
+static void
+_e_icon_smart_add(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = calloc(1, sizeof(E_Smart_Data)))) return;
+   sd->eventarea = evas_object_rectangle_add(evas_object_evas_get(obj));
+   evas_object_color_set(sd->eventarea, 0, 0, 0, 0);
+   evas_object_smart_member_add(sd->eventarea, obj);
+
+   sd->obj = evas_object_image_add(evas_object_evas_get(obj));
+   evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
+                                  _e_icon_preloaded, obj);
+   sd->x = 0;
+   sd->y = 0;
+   sd->w = 0;
+   sd->h = 0;
+   sd->fill_inside = 1;
+   sd->scale_up = 1;
+   sd->size = 64;
+   evas_object_smart_member_add(sd->obj, obj);
+   evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_e_icon_smart_del(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   evas_object_del(sd->obj);
+   evas_object_del(sd->eventarea);
+   if (sd->fdo) eina_stringshare_del(sd->fdo);
+#ifdef USE_ICON_CACHE
+   if (sd->file) eina_stringshare_del(sd->file);
+#endif
+   if (sd->fdo_reload_timer) ecore_timer_del(sd->fdo_reload_timer);
+   if (sd->timer) ecore_timer_del(sd->timer);
+   if (sd->guessing_animation) ecore_timer_del(sd->guessing_animation);
+   evas_object_smart_data_set(obj, NULL);
+   memset(sd, 0, sizeof(*sd));
+   free(sd);
+}
+
+static void
+_e_icon_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if ((sd->x == x) && (sd->y == y)) return;
+   sd->x = x;
+   sd->y = y;
+   _e_icon_smart_reconfigure(sd);
+}
+
+static Eina_Bool
+_e_icon_guess_anim(void *data)
+{
+   E_Smart_Data *sd = data;
+   double t = ecore_loop_time_get();
+
+   if (t - sd->last_resize < 0.2)
+     {
+        evas_object_image_scale_hint_set(sd->obj,
+                                         EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+        sd->animated = EINA_TRUE;
+     }
+   else
+     {
+        evas_object_image_scale_hint_set(sd->obj,
+                                         EVAS_IMAGE_SCALE_HINT_STATIC);
+     }
+
+   sd->guessing_animation = NULL;
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_icon_fdo_reload(void *data)
+{
+   E_Smart_Data *sd = data;
+   const char *path;
+
+   sd->fdo_reload_timer = NULL;
+   sd->size = MAX(sd->w, sd->h);
+   path = efreet_icon_path_find(e_config->icon_theme, sd->fdo, sd->size);
+   if (!path) return EINA_FALSE;
+
+   /* smart code here */
+   evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
+   evas_object_image_file_set(sd->obj, path, NULL);
+   if (sd->preload)
+     {
+        sd->loading = 1;
+        evas_object_image_preload(sd->obj, 0);
+     }
+   return EINA_FALSE;
+}
+
+static void
+_e_icon_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if ((sd->w == w) && (sd->h == h)) return;
+   sd->w = w;
+   sd->h = h;
+   if (sd->fdo)
+     {
+        if (sd->fdo_reload_timer) ecore_timer_del(sd->fdo_reload_timer);
+        sd->fdo_reload_timer = ecore_timer_add(0.1, _e_icon_fdo_reload, sd);
+     }
+
+   if ((!sd->edje) && ((sd->loading && sd->preload) ||
+                       (!sd->loading && !sd->preload))
+       && !sd->animated)
+     {
+        evas_object_image_scale_hint_set(sd->obj,
+                                         EVAS_IMAGE_SCALE_HINT_DYNAMIC);
+        if (!sd->guessing_animation)
+          sd->guessing_animation = ecore_timer_add(0.3,
+                                                   _e_icon_guess_anim,
+                                                   sd);
+     }
+
+   sd->last_resize = ecore_loop_time_get();
+   _e_icon_smart_reconfigure(sd);
+}
+
+static void
+_e_icon_smart_show(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   if (!((sd->preload) && (sd->loading)))
+     {
+        evas_object_show(sd->obj);
+#ifdef USE_ICON_CACHE
+        if (!sd->preload)
+          _e_icon_cache_icon_loaded(sd->ci);
+#endif
+     }
+
+   evas_object_show(sd->eventarea);
+}
+
+static void
+_e_icon_smart_hide(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   evas_object_hide(sd->obj);
+   evas_object_hide(sd->eventarea);
+}
+
+static void
+_e_icon_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   evas_object_color_set(sd->obj, r, g, b, a);
+}
+
+static void
+_e_icon_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   evas_object_clip_set(sd->obj, clip);
+   evas_object_clip_set(sd->eventarea, clip);
+}
+
+static void
+_e_icon_smart_clip_unset(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj))) return;
+   evas_object_clip_unset(sd->obj);
+   evas_object_clip_unset(sd->eventarea);
+}
+
+#ifdef USE_ICON_CACHE
+
+static void
+_e_icon_cache_item_free(void *data)
+{
+   Cache_Item *ci = data;
+   eina_stringshare_del(ci->id);
+   E_FREE(ci);
+}
+
+static Eina_Bool
+_e_icon_cache_save(void *data)
+{
+   if (_cache->load_queue)
+     {
+        Cache_Item *ci;
+        Eina_List *l;
+
+        /* EINA_LIST_FOREACH(_cache->load_queue, l, ci)
+         *   printf("  : %s\n", ci->id); */
+
+        return ECORE_CALLBACK_RENEW;
+     }
+
+   eet_sync(_cache->ef);
+   eet_close(_cache->ef);
+
+   _cache->ef = NULL;
+   _cache->timer = NULL;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_e_icon_cache_find(Evas_Object *obj, const char *file)
+{
+   E_Smart_Data *sd;
+   Cache_Item *ci;
+   char buf[4096];
+   const char *id;
+   Eina_List *l;
+
+   if (!_cache) return EINA_FALSE;
+
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   snprintf(buf, sizeof(buf), "%d:%s", sd->size, file);
+
+   if ((ci = eina_hash_find(_cache->hash, buf)))
+     {
+        unsigned int w, h, alpha;
+        void *data;
+        int found = 0;
+
+        if (!_cache->ef)
+          _cache->ef = eet_open(_cache->file, EET_FILE_MODE_READ_WRITE);
+
+        if (_cache->ef && (data = eet_data_image_read(_cache->ef, buf,
+                                                      &w, &h, &alpha,
+                                                      NULL, NULL, NULL)))
+          {
+             evas_object_image_size_set(sd->obj, w, h);
+             evas_object_image_alpha_set(sd->obj, alpha);
+             evas_object_image_data_copy_set(sd->obj, data);
+             evas_object_smart_callback_call(obj, "preloaded", NULL);
+             evas_object_show(sd->obj);
+             free(data);
+             found = 1;
+          }
+
+        if ((_cache->ef) && !(_cache->timer))
+          _cache->timer = ecore_timer_add(3.0, _e_icon_cache_save, NULL);
+
+        if (found)
+          return EINA_TRUE;
+
+        eina_hash_del_by_key(_cache->hash, ci->id);
+        ci = NULL;
+     }
+
+   id = eina_stringshare_add(buf);
+
+   /* not found in cache, check load queue */
+   EINA_LIST_FOREACH(_cache->load_queue, l, ci)
+     {
+        if (ci->id != id) continue;
+        ci->objs = eina_list_append(ci->objs, obj);
+        sd->ci = ci;
+        evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_DEL,
+                                       _e_icon_obj_del, obj);
+        eina_stringshare_del(id);
+        return EINA_TRUE;
+     }
+
+   ci = E_NEW(Cache_Item, 1);
+   ci->id = id;
+   ci->icon = sd->obj;
+   ci->obj = obj;
+   sd->ci = ci;
+   sd->file = eina_stringshare_add(file);
+
+   evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_DEL, _e_icon_obj_del, obj);
+
+   _cache->load_queue = eina_list_append(_cache->load_queue, ci);
+
+   return EINA_FALSE;
+}
+
+static void
+_e_icon_cache_icon_try_next(Cache_Item *ci)
+{
+   Evas_Object *obj;
+   E_Smart_Data *sd;
+
+   if (!ci->objs)
+     {
+        /* no more e_icon wait for this object to bet loaded */
+        _cache->load_queue = eina_list_remove(_cache->load_queue, ci);
+        _e_icon_cache_item_free(ci);
+        return;
+     }
+
+   obj = eina_list_data_get(ci->objs);
+   ci->objs = eina_list_remove_list(ci->objs, ci->objs);
+
+   if (!obj)
+     goto __try_next;
+
+   if (!(sd = evas_object_smart_data_get(obj)))
+     goto __try_next;
+
+   evas_object_image_file_set(sd->obj, sd->file, NULL);
+   if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
+     goto __try_next;
+
+   sd->ci->icon = sd->obj;
+   sd->ci->obj = obj;
+   evas_object_image_preload(sd->obj, EINA_FALSE);
+   return;
+
+__try_next:
+   evas_object_event_callback_del_full(sd->obj, EVAS_CALLBACK_DEL,
+                                       _e_icon_obj_del, obj);
+   _e_icon_cache_icon_try_next(ci);
+}
+
+static void
+_e_icon_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(data))) return;
+   if (!sd->ci) return;
+
+   /* check if the deleted object is the one that is used for
+      preloading.  when other objs wait for this image data start
+      preloading again with the next. */
+
+   if (sd->ci->icon == obj)
+     {
+        _e_icon_cache_icon_try_next(sd->ci);
+        sd->ci = NULL;
+     }
+   else
+     {
+        sd->ci->objs = eina_list_remove(sd->ci->objs, data);
+        sd->ci = NULL;
+     }
+}
+
+static void
+_e_icon_cache_icon_loaded(Cache_Item *ci)
+{
+   int w, h, alpha;
+   E_Smart_Data *sd;
+   Evas_Object *obj;
+   void *data;
+
+   if (!_cache) return;
+
+   if (!ci || !ci->id) return;
+   _cache->load_queue = eina_list_remove(_cache->load_queue, ci);
+
+   data = evas_object_image_data_get(ci->icon, EINA_FALSE);
+   evas_object_image_size_get(ci->icon, &w, &h);
+   alpha = evas_object_image_alpha_get(ci->icon);
+
+   evas_object_event_callback_del_full(ci->icon, EVAS_CALLBACK_DEL,
+                                       _e_icon_obj_del, ci->obj);
+   evas_object_smart_callback_call(ci->obj, "preloaded", NULL);
+
+   DBG("icon loaded %p, %s\n", data, ci->id);
+
+   sd = evas_object_smart_data_get(ci->obj);
+   sd->ci = NULL;
+
+   /* pass loaded data to other e_icon wating for this */
+   EINA_LIST_FREE(ci->objs, obj)
+     {
+        sd = evas_object_smart_data_get(obj);
+        sd->ci = NULL;
+        evas_object_event_callback_del_full(sd->obj, EVAS_CALLBACK_DEL,
+                                            _e_icon_obj_del, obj);
+        if (!data) continue;
+
+        evas_object_image_size_set(sd->obj, w, h);
+        evas_object_image_alpha_set(sd->obj, alpha);
+        evas_object_image_data_copy_set(sd->obj, data);
+        evas_object_show(sd->obj);
+        evas_object_smart_callback_call(obj, "preloaded", NULL);
+     }
+
+   if (data)
+     {
+        if (!_cache->ef)
+          _cache->ef = eet_open(_cache->file, EET_FILE_MODE_READ_WRITE);
+        if (_cache->ef && eet_data_image_write(_cache->ef, ci->id, data,
+                                               w, h, alpha, 1, 100, 0))
+          {
+             eina_hash_add(_cache->hash, ci->id, ci);
+             eet_data_write(_cache->ef, cache_edd, "idx", _cache, 1);
+
+             if (!_cache->timer)
+               _cache->timer = ecore_timer_add(3.0, _e_icon_cache_save, NULL);
+
+             eina_stringshare_replace(&ci->id, NULL);
+             return;
+          }
+     }
+
+   DBG("couldnt write cache %p !!!\n", _cache->ef);
+   _e_icon_cache_item_free(ci);
+}
+
+#endif
diff --git a/src/bin/e_wayland/e_icon.h b/src/bin/e_wayland/e_icon.h
new file mode 100644 (file)
index 0000000..6b33fa5
--- /dev/null
@@ -0,0 +1,35 @@
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_ICON_H
+#define E_ICON_H
+
+EINTERN int e_icon_init(void);
+EINTERN int e_icon_shutdown(void);
+
+EAPI Evas_Object *e_icon_add              (Evas *evas);
+EAPI Eina_Bool    e_icon_file_set         (Evas_Object *obj, const char *file);
+EAPI Eina_Bool    e_icon_file_key_set     (Evas_Object *obj, const char *file, const char *key);
+EAPI Eina_Bool    e_icon_file_edje_set    (Evas_Object *obj, const char *file, const char *part);
+EAPI Eina_Bool    e_icon_fdo_icon_set     (Evas_Object *obj, const char *icon);
+EAPI void         e_icon_edje_object_set(Evas_Object *obj, Evas_Object *edje);
+EAPI void         e_icon_object_set       (Evas_Object *obj, Evas_Object *o) EINA_DEPRECATED;
+EAPI Eina_Bool   e_icon_file_get(const Evas_Object *obj, const char **file, const char **group);
+EAPI void         e_icon_smooth_scale_set (Evas_Object *obj, Eina_Bool smooth);
+EAPI Eina_Bool    e_icon_smooth_scale_get (const Evas_Object *obj);
+EAPI void         e_icon_alpha_set        (Evas_Object *obj, Eina_Bool smooth);
+EAPI Eina_Bool    e_icon_alpha_get        (const Evas_Object *obj);
+EAPI void         e_icon_preload_set      (Evas_Object *obj, Eina_Bool preload);
+EAPI Eina_Bool    e_icon_preload_get      (const Evas_Object *obj);
+EAPI void         e_icon_size_get         (const Evas_Object *obj, int *w, int *h);
+EAPI Eina_Bool    e_icon_fill_inside_get  (const Evas_Object *obj);
+EAPI void         e_icon_fill_inside_set  (Evas_Object *obj, Eina_Bool fill_inside);
+EAPI Eina_Bool    e_icon_scale_up_get     (const Evas_Object *obj);
+EAPI void         e_icon_scale_up_set     (Evas_Object *obj, Eina_Bool scale_up);
+EAPI void         e_icon_data_set         (Evas_Object *obj, void *data, int w, int h);
+EAPI void        *e_icon_data_get         (const Evas_Object *obj, int *w, int *h);
+EAPI void         e_icon_scale_size_set   (Evas_Object *obj, int size);
+EAPI int          e_icon_scale_size_get   (const Evas_Object *obj);
+EAPI void         e_icon_selected_set    (const Evas_Object *obj, Eina_Bool selected);
+
+#endif
+#endif
index 1ae7279d66a2d4b2432bc9b2dd26062efbe36e79..c2d9d39c1f57cde00eeca3621e62b94dacb407b5 100644 (file)
 #include "e_canvas.h"
 #include "e_manager.h"
 #include "e_container.h"
+#include "e_zone.h"
+#include "e_desk.h"
+#include "e_bg.h"
+#include "e_box.h"
+#include "e_icon.h"
+#include "e_menu.h"
+#include "e_win.h"
+#include "e_dialog.h"
+#include "e_about.h"
+#include "e_theme_about.h"
+#include "e_actions.h"
+#include "e_acpi.h"
+#include "e_exec.h"
+#include "e_configure.h"
+#include "e_config_dialog.h"
+#include "e_thumb.h"
+#include "e_shelf.h"
+#include "e_gadcon.h"
+#include "e_popup.h"
+#include "e_obj_dialog.h"
+#include "e_sys.h"
+#include "e_bindings.h"
+#include "e_ipc.h"
+#include "e_ipc_codec.h"
+#include "e_exehist.h"
+#include "e_alert.h"
+
 #include "e_output.h"
 #include "e_shader.h"
 #include "e_renderer.h"
diff --git a/src/bin/e_wayland/e_int_menus.c b/src/bin/e_wayland/e_int_menus.c
new file mode 100644 (file)
index 0000000..6ef214a
--- /dev/null
@@ -0,0 +1,1569 @@
+#include "e.h"
+
+/*
+ * TODO: Listen to EFREET_EVENT_DESKTOP_CACHE_UPDATE
+ */
+
+typedef struct _Main_Data Main_Data;
+
+struct _Main_Data
+{
+   E_Menu *menu;
+   E_Menu *apps;
+   E_Menu *all_apps;
+   E_Menu *desktops;
+   E_Menu *clients;
+   E_Menu *enlightenment;
+   E_Menu *config;
+   E_Menu *lost_clients;
+};
+
+/* local subsystem functions */
+static void _e_int_menus_main_del_hook(void *obj);
+static void _e_int_menus_main_about(void *data, E_Menu *m, E_Menu_Item *mi);
+//static void _e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu);
+static void _e_int_menus_apps_start(void *data, E_Menu *m);
+static void _e_int_menus_apps_free_hook(void *obj);
+static void _e_int_menus_apps_free_hook2(void *obj);
+static void _e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_config_pre_cb(void *data, E_Menu *m);
+static void _e_int_menus_config_free_hook(void *obj);
+/* static void _e_int_menus_clients_pre_cb(void *data, E_Menu *m); */
+/* static void _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m); */
+/* static void _e_int_menus_clients_free_hook(void *obj); */
+/* static void _e_int_menus_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi); */
+/* static void _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi); */
+/* static void _e_int_menus_clients_cleanup_cb(void *data, E_Menu *m, E_Menu_Item *mi); */
+/* static int _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2); */
+/* static int _e_int_menus_clients_group_class_cb(const void *d1, const void *d2); */
+/* static int _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2); */
+/* static int _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2); */
+/* static void _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m); */
+/* static void _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m); */
+/* static void _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m); */
+/* static void _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m); */
+/* static const char *_e_int_menus_clients_title_abbrv(const char *title); */
+static void _e_int_menus_virtuals_pre_cb(void *data, E_Menu *m);
+static void _e_int_menus_virtuals_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_themes_about(void *data, E_Menu *m, E_Menu_Item *mi);
+/* static void _e_int_menus_lost_clients_pre_cb(void *data, E_Menu *m); */
+/* static void _e_int_menus_lost_clients_free_hook(void *obj); */
+/* static void _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi); */
+static void _e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation);
+static void _e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation);
+static void _e_int_menus_shelves_pre_cb(void *data, E_Menu *m);
+static void _e_int_menus_shelves_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_shelves_add_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_shelves_del_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_showhide(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_restart(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_main_exit(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_desktops_free_hook(void *obj);
+static void _e_int_menus_desk_item_cb(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi);
+
+//static void _e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__);
+
+/* local subsystem globals */
+static Eina_Hash *_e_int_menus_augmentation = NULL;
+static Eina_List *_e_int_menus_augmentation_disabled = NULL;
+
+static Eina_List *
+_e_int_menus_augmentation_find(const char *key)
+{
+   Eina_List *l;
+   char *data;
+
+   if ((!_e_int_menus_augmentation) || (!key)) return NULL;
+
+   EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
+     if (!strcmp(data, key)) return NULL;
+   return eina_hash_find(_e_int_menus_augmentation, key);
+}
+
+/* externally accessible functions */
+EAPI E_Menu *
+e_int_menus_main_new(void)
+{
+   E_Menu *m, *subm;
+   E_Menu_Item *mi;
+   Main_Data *dat;
+   Eina_List *l = NULL;
+   int separator = 0;
+
+   dat = calloc(1, sizeof(Main_Data));
+   m = e_menu_new();
+   e_menu_title_set(m, _("Main"));
+   dat->menu = m;
+   e_object_data_set(E_OBJECT(m), dat);
+   e_object_del_attach_func_set(E_OBJECT(m), _e_int_menus_main_del_hook);
+
+   e_menu_category_set(m, "main");
+
+   l = _e_int_menus_augmentation_find("main/0");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   if (e_config->menu_favorites_show)
+     {
+       subm = e_int_menus_favorite_apps_new();
+       if (subm)
+         {
+            dat->apps = subm;
+            mi = e_menu_item_new(m);
+            e_menu_item_label_set(mi, _("Favorite Applications"));
+            e_util_menu_item_theme_icon_set(mi, "user-bookmarks");
+            e_menu_item_submenu_set(mi, subm);
+         }
+     }
+
+   if (e_config->menu_apps_show) 
+     {
+       subm = e_int_menus_all_apps_new();
+       dat->all_apps = subm;
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, _("Applications"));
+       e_util_menu_item_theme_icon_set(mi, "preferences-applications");
+       e_menu_item_submenu_set(mi, subm);
+     }
+
+   l = _e_int_menus_augmentation_find("main/1");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   l = _e_int_menus_augmentation_find("main/2");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   subm = e_int_menus_desktops_new();
+   dat->desktops = subm;
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Desktop"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
+   e_menu_item_submenu_set(mi, subm);
+
+   /* subm = e_int_menus_clients_new(); */
+   /* dat->clients = subm; */
+   /* mi = e_menu_item_new(m); */
+   /* e_menu_item_label_set(mi, _("Windows")); */
+   /* e_util_menu_item_theme_icon_set(mi, "preferences-system-windows"); */
+   /* e_menu_item_submenu_set(mi, subm); */
+   /* e_object_data_set(E_OBJECT(subm), dat); */
+
+/* #if 0 // lost windows already handled inside "Windows" from main menu. */
+   /* subm = e_int_menus_lost_clients_new(); */
+   /* e_object_data_set(E_OBJECT(subm), dat);    */
+   /* dat->lost_clients = subm; */
+   /* mi = e_menu_item_new(m); */
+   /* e_menu_item_label_set(mi, _("Lost Windows")); */
+   /* e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost"); */
+   /* e_menu_item_submenu_set(mi, subm); */
+/* #endif */
+
+   l = _e_int_menus_augmentation_find("main/3");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   l = _e_int_menus_augmentation_find("main/4");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   subm = e_menu_new();
+   dat->enlightenment = subm;
+   
+   l = _e_int_menus_augmentation_find("enlightenment/0");
+   if (l) _e_int_menus_augmentation_add(subm, l);
+   
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Enlightenment"));
+   e_util_menu_item_theme_icon_set(mi, "enlightenment");
+   e_menu_item_submenu_set(mi, subm);
+
+   mi = e_menu_item_new(subm);
+   e_menu_item_label_set(mi, _("About"));
+   e_util_menu_item_theme_icon_set(mi, "help-about");
+   e_menu_item_callback_set(mi, _e_int_menus_main_about, NULL);
+
+   mi = e_menu_item_new(subm);
+   e_menu_item_label_set(mi, _("Theme"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop-theme");
+   e_menu_item_callback_set(mi, _e_int_menus_themes_about, NULL);
+
+   l = _e_int_menus_augmentation_find("enlightenment/1");
+   if (l) _e_int_menus_augmentation_add(subm, l);
+
+   mi = e_menu_item_new(subm);
+   e_menu_item_separator_set(mi, 1);
+
+   l = _e_int_menus_augmentation_find("enlightenment/2");
+   if (l) _e_int_menus_augmentation_add(subm, l);
+
+   mi = e_menu_item_new(subm);
+   e_menu_item_label_set(mi, _("Restart"));
+   e_util_menu_item_theme_icon_set(mi, "system-restart");
+   e_menu_item_callback_set(mi, _e_int_menus_main_restart, NULL);
+
+   mi = e_menu_item_new(subm);
+   e_menu_item_label_set(mi, _("Exit"));
+   e_util_menu_item_theme_icon_set(mi, "application-exit");
+   e_menu_item_callback_set(mi, _e_int_menus_main_exit, NULL);
+
+   l = _e_int_menus_augmentation_find("enlightenment/3");
+   if (l) _e_int_menus_augmentation_add(subm, l);
+   
+   l = _e_int_menus_augmentation_find("main/5");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   l = _e_int_menus_augmentation_find("main/6");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   subm = e_int_menus_config_new();
+   dat->config = subm;
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Settings"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-system");
+   e_menu_item_submenu_set(mi, subm);
+
+   l = _e_int_menus_augmentation_find("main/7");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   l = eina_hash_find(_e_int_menus_augmentation, "main/8");
+   if (l) 
+     {
+        separator = 1;
+        mi = e_menu_item_new(m);
+        e_menu_item_separator_set(mi, 1);
+        _e_int_menus_augmentation_add(m, l);
+     }
+
+   l = eina_hash_find(_e_int_menus_augmentation, "main/9");
+   if (l) 
+     {
+        if (!separator) 
+          {
+             mi = e_menu_item_new(m);
+             e_menu_item_separator_set(mi, 1);
+          }
+        _e_int_menus_augmentation_add(m, l);
+     }
+
+   return m;
+}
+
+EAPI E_Menu *
+e_int_menus_apps_new(const char *dir)
+{
+   E_Menu *m;
+
+   m = e_menu_new();
+   if (dir) e_object_data_set(E_OBJECT(m), strdup(dir));
+   e_menu_pre_activate_callback_set(m, _e_int_menus_apps_start, NULL);
+   e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_apps_free_hook);
+   return m;
+}
+
+EAPI E_Menu *
+e_int_menus_desktops_new(void)
+{
+   E_Menu *m, *subm;
+   E_Menu_Item *mi;
+
+   m = e_menu_new();
+
+   subm = e_menu_new();
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Virtual"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
+   e_menu_pre_activate_callback_set(subm, _e_int_menus_virtuals_pre_cb, NULL);
+   e_menu_item_submenu_set(mi, subm);
+
+   subm = e_menu_new();
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Shelves"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
+   e_menu_pre_activate_callback_set(subm, _e_int_menus_shelves_pre_cb, NULL);
+   e_menu_item_submenu_set(mi, subm);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Show/Hide All Windows"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");
+   e_menu_item_callback_set(mi, _e_int_menus_main_showhide, NULL);
+
+   e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_desktops_free_hook);
+   return m;
+}
+
+EAPI E_Menu *
+e_int_menus_favorite_apps_new(void)
+{
+   E_Menu *m = NULL;
+   char buf[PATH_MAX];
+
+   e_user_dir_concat_static(buf, "applications/menu/favorite.menu");
+   if (ecore_file_exists(buf)) m = e_int_menus_apps_new(buf);
+   return m;
+}
+
+EAPI E_Menu *
+e_int_menus_all_apps_new(void)
+{
+   E_Menu *m;
+
+   m = e_int_menus_apps_new(NULL);
+   return m;
+}
+
+EAPI E_Menu *
+e_int_menus_config_new(void)
+{
+   E_Menu *m;
+
+   m = e_menu_new();
+   e_menu_pre_activate_callback_set(m, _e_int_menus_config_pre_cb, NULL);
+   return m;
+}
+
+/* EAPI E_Menu * */
+/* e_int_menus_clients_new(void) */
+/* { */
+/*    E_Menu *m; */
+
+/*    m = e_menu_new(); */
+/*    e_menu_pre_activate_callback_set(m, _e_int_menus_clients_pre_cb, NULL); */
+/*    return m; */
+/* } */
+
+/* EAPI E_Menu * */
+/* e_int_menus_lost_clients_new(void) */
+/* { */
+/*    E_Menu *m; */
+
+/*    m = e_menu_new(); */
+/*    e_menu_pre_activate_callback_set(m, _e_int_menus_lost_clients_pre_cb, NULL); */
+/*    return m; */
+/* } */
+
+EAPI E_Int_Menu_Augmentation *
+e_int_menus_menu_augmentation_add_sorted(const char *menu,
+                                        const char *sort_key,
+                                        void (*func_add) (void *data, E_Menu *m),
+                                        void *data_add,
+                                        void (*func_del) (void *data, E_Menu *m),
+                                        void *data_del)
+{
+   E_Int_Menu_Augmentation *maug;
+   Eina_List *l;
+   Eina_Bool old = EINA_FALSE;
+
+   maug = E_NEW(E_Int_Menu_Augmentation, 1);
+   if (!maug) return NULL;
+
+   maug->sort_key = eina_stringshare_add(sort_key);
+
+   maug->add.func = func_add;
+   maug->add.data = data_add;
+
+   maug->del.func = func_del;
+   maug->del.data = data_del;
+
+   if (_e_int_menus_augmentation)
+     {
+       if ((l = eina_hash_find(_e_int_menus_augmentation, menu)))
+          old = EINA_TRUE;
+     }
+   else
+     {
+       _e_int_menus_augmentation = eina_hash_string_superfast_new(NULL);
+       l = NULL;
+       old = EINA_FALSE;
+     }
+
+   if ((!l) || (!maug->sort_key))
+     l = eina_list_append(l, maug);
+   else
+     {
+       E_Int_Menu_Augmentation *m2;
+       Eina_List *l2;
+
+       /* keep list sorted, those missing sort_key at the end. */
+       EINA_LIST_FOREACH(l, l2, m2)
+         {
+            if (!m2->sort_key)
+              break;
+            if (strcasecmp(maug->sort_key, m2->sort_key) < 0)
+              break;
+         }
+
+       if (l2)
+         l = eina_list_prepend_relative_list(l, maug, l2);
+       else
+         l = eina_list_append(l, maug);
+     }
+
+   if (old)
+     eina_hash_modify(_e_int_menus_augmentation, menu, l);
+   else
+     eina_hash_add(_e_int_menus_augmentation, menu, l);
+
+   return maug;
+}
+
+EAPI E_Int_Menu_Augmentation *
+e_int_menus_menu_augmentation_add(const char *menu,
+                                 void (*func_add) (void *data, E_Menu *m),
+                                 void *data_add,
+                                 void (*func_del) (void *data, E_Menu *m),
+                                 void *data_del)
+{
+   return e_int_menus_menu_augmentation_add_sorted
+     (menu, NULL, func_add, data_add, func_del, data_del);
+}
+
+EAPI void
+e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *maug)
+{
+   Eina_List *l;
+
+   if (!_e_int_menus_augmentation)
+     {
+       eina_stringshare_del(maug->sort_key);
+       free(maug);
+       return;
+     }
+
+   l = eina_hash_find(_e_int_menus_augmentation, menu);
+   if (l)
+     {
+       l = eina_list_remove(l, maug);
+
+       if (l)
+         eina_hash_modify(_e_int_menus_augmentation, menu, l);
+       else
+         eina_hash_del_by_key(_e_int_menus_augmentation, menu);
+     }
+   eina_stringshare_del(maug->sort_key);
+   free(maug);
+}
+
+EAPI void
+e_int_menus_menu_augmentation_point_disabled_set(const char *menu, Eina_Bool disabled)
+{
+   if (!menu) return;
+   if (disabled) 
+     {
+        _e_int_menus_augmentation_disabled = 
+          eina_list_append(_e_int_menus_augmentation_disabled, menu);
+     }
+   else 
+     {
+        _e_int_menus_augmentation_disabled = 
+          eina_list_remove(_e_int_menus_augmentation_disabled, menu);
+     }
+}
+
+/* local subsystem functions */
+static void
+_e_int_menus_main_del_hook(void *obj)
+{
+   Main_Data *dat;
+   E_Menu *m;
+
+   m = obj;
+   dat = e_object_data_get(E_OBJECT(obj));
+   if (dat->apps) e_object_del(E_OBJECT(dat->apps));
+   if (dat->all_apps) e_object_del(E_OBJECT(dat->all_apps));
+   if (dat->desktops) e_object_del(E_OBJECT(dat->desktops));
+   if (dat->clients) e_object_del(E_OBJECT(dat->clients));
+   if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients));
+   if (dat->enlightenment) e_object_del(E_OBJECT(dat->enlightenment));
+   if (dat->config) e_object_del(E_OBJECT(dat->config));
+   free(dat);
+
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/0"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/1"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/2"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/3"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/4"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/5"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/6"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/7"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/8"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/9"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/10"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("main/11"));
+}
+
+static void
+_e_int_menus_main_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_About *about;
+
+   about = e_about_new(e_container_current_get(e_manager_current_get()));
+   if (about) e_about_show(about);
+}
+
+static void
+_e_int_menus_themes_about(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Theme_About *about;
+
+   about = e_theme_about_new(e_container_current_get(e_manager_current_get()));
+   if (about) e_theme_about_show(about);
+}
+
+/*
+static void
+_e_int_menus_fwin_favorites_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+   e_fwin_new(m->zone->container, "favorites", "/");
+}
+*/
+
+static void
+_e_int_menus_main_showhide(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
+{
+   /* E_Action *act; */
+
+   /* act = e_action_find("desk_deskshow_toggle"); */
+   /* if (act) act->func.go(E_OBJECT(m->zone), NULL); */
+}
+
+static void
+_e_int_menus_main_restart(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Action *a;
+
+   a = e_action_find("restart");
+   if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_main_exit(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Action *a;
+
+   a = e_action_find("exit");
+   if ((a) && (a->func.go)) a->func.go(NULL, NULL);
+}
+
+static void
+_e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu)
+{
+   E_Menu_Item *mi;
+   Eina_List *l;
+
+   if (menu->entries)
+     {
+       Efreet_Menu *entry;
+
+       EINA_LIST_FOREACH(menu->entries, l, entry)
+         {
+            mi = e_menu_item_new(m);
+
+            _e_int_menus_item_label_set(entry, mi);
+
+            if (entry->icon)
+              {
+                 if (entry->icon[0] == '/')
+                   e_menu_item_icon_file_set(mi, entry->icon);
+                 else
+                   e_util_menu_item_theme_icon_set(mi, entry->icon);
+              }
+            if (entry->type == EFREET_MENU_ENTRY_SEPARATOR)
+              e_menu_item_separator_set(mi, 1);
+            else if (entry->type == EFREET_MENU_ENTRY_DESKTOP)
+              {
+                 e_menu_item_callback_set(mi, _e_int_menus_apps_run, 
+                                           entry->desktop);
+                 e_menu_item_drag_callback_set(mi, _e_int_menus_apps_drag, 
+                                                entry->desktop);
+              }
+            else if (entry->type == EFREET_MENU_ENTRY_MENU)
+              {
+                 E_Menu *subm;
+
+                 subm = e_menu_new();
+                 e_menu_pre_activate_callback_set(subm, 
+                                                   _e_int_menus_apps_start, 
+                                                   entry);
+                 e_menu_item_submenu_set(mi, subm);
+                  e_object_free_attach_func_set(E_OBJECT(subm), 
+                                                _e_int_menus_apps_free_hook2);
+              }
+            /* TODO: Highlight header
+            else if (entry->type == EFREET_MENU_ENTRY_HEADER)
+            */
+         }
+     }
+   else
+     {
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, _("(No Applications)"));
+     }
+}
+
+static void
+_e_int_menus_apps_start(void *data, E_Menu *m)
+{
+   Efreet_Menu *menu;
+
+   menu = data;
+   if (!menu)
+     {
+       char *dir = NULL;
+
+       dir = e_object_data_get(E_OBJECT(m));
+       if (dir)
+         {
+            menu = efreet_menu_parse(dir);
+            free(dir);
+         }
+       else menu = efreet_menu_get();
+       e_object_data_set(E_OBJECT(m), menu);
+       e_object_free_attach_func_set(E_OBJECT(m), 
+                                      _e_int_menus_apps_free_hook2);
+     }
+   if (menu) _e_int_menus_apps_scan(m, menu);
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+}
+
+static void
+_e_int_menus_apps_free_hook(void *obj)
+{
+   E_Menu *m;
+   char *dir;
+
+   m = obj;
+   dir = e_object_data_get(E_OBJECT(m));
+   E_FREE(dir);
+}
+
+static void
+_e_int_menus_apps_free_hook2(void *obj)
+{
+   E_Menu *m;
+   Efreet_Menu *menu;
+   Eina_List *l, *l_next;
+   E_Menu_Item *mi;
+
+   m = obj;
+   // XXX TODO: this should be automatic in e_menu, just get references right!
+   // XXX TODO: fix references and remove me!!!
+   EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
+     {
+        if (mi->submenu)
+          e_object_del(E_OBJECT(mi->submenu));
+     }
+   menu = e_object_data_get(E_OBJECT(m));
+   if (menu) efreet_menu_free(menu);
+}
+
+static void
+_e_int_menus_apps_run(void *data, E_Menu *m, E_Menu_Item *mi __UNUSED__)
+{
+   Efreet_Desktop *desktop;
+
+   desktop = data;
+   e_exec(m->zone, desktop, NULL, NULL, "menu/apps");
+}
+
+/*
+static void
+_e_int_menus_apps_drag_finished(E_Drag *drag, int dropped __UNUSED__)
+{
+   Efreet_Desktop *desktop;
+
+   desktop = drag->data;
+   efreet_desktop_free(desktop);
+}
+*/
+
+static void
+_e_int_menus_apps_drag(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+   /* Efreet_Desktop *desktop; */
+
+   /* desktop = data; */
+
+   /* start drag! */
+   /* if (mi->o_icon) */
+   /*    { */
+        /* E_Drag *drag; */
+        /* Evas_Object *o = NULL; */
+        /* Evas_Coord x, y, w, h; */
+        /* unsigned int size; */
+        /* const char *drag_types[] = { "enlightenment/desktop" }; */
+
+        /* evas_object_geometry_get(mi->o_icon, &x, &y, &w, &h); */
+         /* efreet_desktop_ref(desktop); */
+        /* drag = e_drag_new(m->zone->container, x, y, drag_types, 1, desktop, -1, */
+        /*                NULL, NULL); */
+
+        /* size = MIN(w, h); */
+         /* o = e_util_desktop_icon_add(desktop, size, e_drag_evas_get(drag)); */
+        /* e_drag_object_set(drag, o); */
+         /* e_drag_resize(drag, w, h); */
+        /* e_drag_start(drag, mi->drag.x + w, mi->drag.y + h); */
+      /* } */
+}
+
+static void
+_e_int_menus_virtuals_pre_cb(void *data __UNUSED__, E_Menu *m)
+{
+   E_Menu_Item *mi;
+   E_Menu *root;
+
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+
+   root = e_menu_root_get(m);
+   if ((root) && (root->zone))
+     {
+       E_Zone *zone;
+       int i;
+
+       zone = root->zone;
+       for (i = 0; i < (zone->desk_x_count * zone->desk_y_count); i++)
+         {
+            E_Desk *desk;
+
+             desk = zone->desks[i];
+            mi = e_menu_item_new(m);
+            e_menu_item_radio_group_set(mi, 1);
+            e_menu_item_radio_set(mi, 1);
+            e_menu_item_label_set(mi, desk->name);
+            if (desk == e_desk_current_get(zone)) 
+              e_menu_item_toggle_set(mi, 1); 
+            e_menu_item_callback_set(mi, _e_int_menus_virtuals_item_cb, desk);
+            e_menu_item_realize_callback_set(mi, _e_int_menus_virtuals_icon_cb, desk);
+         }
+     }
+
+   if (e_configure_registry_exists("screen/virtual_desktops"))
+     {
+       mi = e_menu_item_new(m);
+       e_menu_item_separator_set(mi, 1);
+
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, _("Set Virtual Desktops"));
+       e_util_menu_item_theme_icon_set(mi, "preferences-desktop");
+       e_menu_item_callback_set(mi, _e_int_menus_desk_item_cb, NULL);
+     }
+}
+
+static void
+_e_int_menus_desktops_free_hook(void *obj)
+{
+   E_Menu *m;
+   Eina_List *l, *l_next;
+   E_Menu_Item *mi;
+
+   m = obj;
+   // XXX TODO: this should be automatic in e_menu, just get references right!
+   // XXX TODO: fix references and remove me!!!
+   EINA_LIST_FOREACH_SAFE(m->items, l, l_next, mi)
+     {
+        if (mi->submenu)
+          e_object_del(E_OBJECT(mi->submenu));
+     }
+}
+
+static void
+_e_int_menus_desk_item_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__)
+{
+   e_configure_registry_call("screen/virtual_desktops", m->zone->container, NULL);
+}
+
+static void
+_e_int_menus_virtuals_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Desk *desk;
+
+   if (!(desk = data)) return;
+   e_desk_show(desk);
+}
+
+static void
+_e_int_menus_virtuals_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi)
+{
+   E_Desk *desk;
+   Evas_Object *o;
+   const char *bgfile;
+   int tw, th;
+
+   desk = data;
+   E_OBJECT_CHECK(desk);
+
+   tw = 50;
+   th = (tw * desk->zone->h) / desk->zone->w;
+
+   bgfile = e_bg_file_get(desk->zone->container->num, desk->zone->num, desk->x, desk->y);
+   o = e_thumb_icon_add(m->evas);
+   e_thumb_icon_file_set(o, bgfile, "e/desktop/background");
+   e_thumb_icon_size_set(o, tw, th);
+   e_thumb_icon_begin(o);
+   mi->o_icon = o;
+}
+
+static void
+_e_int_menus_config_pre_cb(void *data __UNUSED__, E_Menu *m)
+{
+   E_Menu_Item *mi;
+   Eina_List *l = NULL;
+
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+
+   l = _e_int_menus_augmentation_find("config/0");
+   if (l)
+     {
+       _e_int_menus_augmentation_add(m, l);
+       if (_e_int_menus_augmentation_find("config/1"))
+         {
+             mi = e_menu_item_new(m);
+             e_menu_item_separator_set(mi, 1);
+         }
+     }
+
+   l = _e_int_menus_augmentation_find("config/1");
+   if (l) _e_int_menus_augmentation_add(m, l);
+
+   l = _e_int_menus_augmentation_find("config/2");
+   if (l)
+     {
+       mi = e_menu_item_new(m);
+       e_menu_item_separator_set(mi, 1);
+       _e_int_menus_augmentation_add(m, l);
+     }
+
+   e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_config_free_hook);
+}
+
+static void
+_e_int_menus_config_free_hook(void *obj)
+{
+   E_Menu *m;
+
+   m = obj;
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/0"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/1"));
+   _e_int_menus_augmentation_del(m, _e_int_menus_augmentation_find("config/2"));
+}
+
+/* static int */
+/* _e_int_menus_clients_group_desk_cb(const void *d1, const void *d2) */
+/* { */
+/*    const E_Border *bd1; */
+/*    const E_Border *bd2; */
+/*    int j, k; */
+
+/*    if (!d1) return 1; */
+/*    if (!d2) return -1; */
+
+/*    bd1 = d1; */
+/*    bd2 = d2; */
+
+/*    j = bd1->desk->y * 12 + bd1->desk->x; */
+/*    k = bd2->desk->y * 12 + bd2->desk->x; */
+
+/*    if (j > k) return 1; */
+/*    if (j < k) return -1; */
+/* } */
+
+/* static int */
+/* _e_int_menus_clients_group_class_cb(const void *d1, const void *d2) */
+/* { */
+/*    const E_Border *bd1, *bd2; */
+
+/*    if (!d1) return 1; */
+/*    if (!d2) return -1; */
+
+/*    bd1 = d1; */
+/*    bd2 = d2; */
+
+/*    if (!bd1->client.icccm.class) */
+/*      return -1; */
+/*    if (!bd2->client.icccm.class) */
+/*      return 1; */
+
+/*    return (strcmp(bd1->client.icccm.class, bd2->client.icccm.class) > 0 ? 1 : -1); */
+/* } */
+
+/* static int */
+/* _e_int_menus_clients_sort_alpha_cb(const void *d1, const void *d2) */
+/* { */
+/*    const E_Border *bd1, *bd2; */
+/*    const char *name1, *name2; */
+
+/*    if (!d1) return 1; */
+/*    if (!d2) return -1; */
+
+/*    bd1 = d1; */
+/*    bd2 = d2; */
+/*    name1 = e_border_name_get(bd1); */
+/*    name2 = e_border_name_get(bd2); */
+
+/*    if (strcasecmp(name1, name2) > 0) return 1; */
+/*    if (strcasecmp(name1, name2) < 0) return -1; */
+/*    return 0; */
+/* } */
+
+/* static int */
+/* _e_int_menus_clients_sort_z_order_cb(const void *d1, const void *d2) */
+/* { */
+/*    const E_Border *bd1, *bd2; */
+
+/*    if (!d1) return 1; */
+/*    if (!d2) return -1; */
+
+/*    bd1 = d1; */
+/*    bd2 = d2; */
+
+/*    if (bd1->layer < bd2->layer) return 1; */
+/*    if (bd1->layer > bd2->layer) return -1; */
+/*    return 0;    */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_menu_add_iconified(Eina_List *borders, E_Menu *m) */
+/* { */
+/*    if (eina_list_count(borders) > 0) */
+/*      {  */
+/*         Eina_List *l = NULL; */
+/*         E_Border *bd = NULL; */
+/*         E_Menu_Item *mi = NULL; */
+
+/*     mi = e_menu_item_new(m);  */
+/*     e_menu_item_separator_set(mi, 1);  */
+
+/*     EINA_LIST_FOREACH(borders, l, bd) */
+/*           _e_int_menus_clients_item_create(bd, m); */
+/*      } */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_add_by_class(Eina_List *borders, E_Menu *m) */
+/* { */
+/*    Eina_List *l = NULL, *ico = NULL; */
+/*    E_Border *bd;  */
+/*    E_Menu *subm = NULL; */
+/*    E_Menu_Item *mi = NULL; */
+/*    char *class = NULL; */
+
+/*    class = strdup(""); */
+/*    EINA_LIST_FOREACH(borders, l, bd) */
+/*      { */
+/*     if ((bd->iconic) &&  */
+/*         (e_config->clientlist_separate_iconified_apps == E_CLIENTLIST_GROUPICONS_SEP)) */
+/*       { */
+/*          ico = eina_list_append(ico, bd);  */
+/*          continue; */
+/*       } */
+
+/*     if (((strcmp(class, bd->client.icccm.class) != 0) &&  */
+/*         e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE)) */
+/*       { */
+/*          if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)  */
+/*            { */
+/*               if ((subm) && (mi)) e_menu_item_submenu_set(mi, subm);  */
+/*               mi = e_menu_item_new(m);  */
+/*               e_menu_item_label_set(mi, bd->client.icccm.class);  */
+/*               e_util_menu_item_theme_icon_set(mi, "preferences-system-windows");  */
+/*               subm = e_menu_new();  */
+/*            } */
+/*          else  */
+/*            { */
+/*               mi = e_menu_item_new(m);  */
+/*               e_menu_item_separator_set(mi, 1);  */
+/*            } */
+/*          class = strdup(bd->client.icccm.class);  */
+/*       } */
+/*     if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)  */
+/*       _e_int_menus_clients_item_create(bd, subm);  */
+/*     else   */
+/*       _e_int_menus_clients_item_create(bd, m);  */
+/*      } */
+
+/*    if ((e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)  */
+/*        && (subm) && (mi))  */
+/*      e_menu_item_submenu_set(mi, subm); */
+
+/*    _e_int_menus_clients_menu_add_iconified(ico, m); */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_add_by_desk(E_Desk *curr_desk, Eina_List *borders, E_Menu *m) */
+/* { */
+/*    E_Desk *desk = NULL; */
+/*    Eina_List *l = NULL, *alt = NULL, *ico = NULL; */
+/*    E_Border *bd; */
+/*    E_Menu *subm; */
+/*    E_Menu_Item *mi = NULL; */
+
+/*    EINA_LIST_FOREACH(borders, l, bd) */
+/*      { */
+/*     if (bd->iconic && e_config->clientlist_separate_iconified_apps && E_CLIENTLIST_GROUPICONS_SEP)  */
+/*       { */
+/*          ico = eina_list_append(ico, bd);  */
+/*          continue;  */
+/*       } */
+
+/*     if (bd->desk != curr_desk) */
+/*       { */
+/*          if ((!bd->iconic) ||  */
+/*              (bd->iconic && e_config->clientlist_separate_iconified_apps ==  */
+/*               E_CLIENTLIST_GROUPICONS_OWNER)) */
+/*            { */
+/*               alt = eina_list_append(alt, bd);  */
+/*               continue; */
+/*            } */
+/*       } */
+/*     else */
+/*       _e_int_menus_clients_item_create(bd, m); */
+/*      } */
+
+/*    desk = NULL; */
+/*    subm = NULL; */
+/*    if (eina_list_count(alt) > 0)  */
+/*      { */
+/*     if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) */
+/*       { */
+/*          mi = e_menu_item_new(m); */
+/*          e_menu_item_separator_set(mi, 1); */
+/*       } */
+
+/*     EINA_LIST_FOREACH(alt, l, bd) */
+/*       { */
+/*          if ((bd->desk != desk) &&  */
+/*              (e_config->clientlist_separate_with != E_CLIENTLIST_GROUP_SEP_NONE)) */
+/*            { */
+/*               if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU) */
+/*                 { */
+/*                    if (subm && mi) e_menu_item_submenu_set(mi, subm);  */
+/*                    mi = e_menu_item_new(m);  */
+/*                    e_menu_item_label_set(mi, bd->desk->name);  */
+/*                    e_util_menu_item_theme_icon_set(mi, "preferences-desktop"); */
+/*                    subm = e_menu_new();  */
+/*                 } */
+/*               else */
+/*                 { */
+/*                    mi = e_menu_item_new(m);  */
+/*                    e_menu_item_separator_set(mi, 1); */
+/*                 } */
+/*               desk = bd->desk; */
+/*            } */
+/*          if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU)  */
+/*            _e_int_menus_clients_item_create(bd, subm);  */
+/*          else   */
+/*            _e_int_menus_clients_item_create(bd, m); */
+/*       } */
+/*     if (e_config->clientlist_separate_with == E_CLIENTLIST_GROUP_SEP_MENU  */
+/*         && (subm) && (mi))  */
+/*       e_menu_item_submenu_set(mi, subm); */
+/*      } */
+
+/*    _e_int_menus_clients_menu_add_iconified(ico, m); */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_add_by_none(Eina_List *borders, E_Menu *m) */
+/* { */
+/*    Eina_List *l = NULL, *ico = NULL; */
+/*    E_Border *bd; */
+
+/*    EINA_LIST_FOREACH(borders, l, bd) */
+/*      { */
+/*     if ((bd->iconic) && (e_config->clientlist_separate_iconified_apps) &&  */
+/*             (E_CLIENTLIST_GROUPICONS_SEP))  */
+/*       { */
+/*          ico = eina_list_append(ico, bd);  */
+/*          continue;  */
+/*       } */
+/*     _e_int_menus_clients_item_create(bd, m); */
+/*      } */
+/*    _e_int_menus_clients_menu_add_iconified(ico, m); */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_pre_cb(void *data __UNUSED__, E_Menu *m) */
+/* { */
+/*    E_Menu *subm; */
+/*    E_Menu_Item *mi = NULL; */
+/*    Eina_List *l = NULL, *borders = NULL; */
+/*    E_Border *border; */
+/*    E_Zone *zone = NULL; */
+/*    E_Desk *desk = NULL; */
+/*    Main_Data *dat; */
+
+/*    e_menu_pre_activate_callback_set(m, NULL, NULL); */
+/*    zone = e_zone_current_get(e_container_current_get(e_manager_current_get())); */
+/*    desk = e_desk_current_get(zone); */
+
+/*    if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_MOST_RECENT)  */
+/*      l = e_border_focus_stack_get();  */
+/*    else */
+/*      l = e_border_client_list(); */
+/*    EINA_LIST_FOREACH(l, l, border) */
+/*      { */
+/*     if (border->user_skip_winlist) continue; */
+/*     if ((border->zone == zone) || (border->iconic) || */
+/*         (border->zone != zone && e_config->clientlist_include_all_zones)) */
+/*       borders = eina_list_append(borders, border); */
+/*      } */
+
+/*    dat = (Main_Data *)e_object_data_get(E_OBJECT(m)); */
+/*    if (!dat) e_menu_title_set(m, _("Windows")); */
+
+/*    if (!borders) */
+/*      { */
+/*     mi = e_menu_item_new(m); */
+/*     e_menu_item_label_set(mi, _("(No Windows)")); */
+/*      } */
+
+/*    if (borders)  */
+/*      { */
+/*     if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ALPHA) */
+/*           borders = eina_list_sort(borders, eina_list_count(borders),  */
+/*                                    _e_int_menus_clients_sort_alpha_cb); */
+
+/*     if (e_config->clientlist_sort_by == E_CLIENTLIST_SORT_ZORDER) */
+/*       borders = eina_list_sort(borders, eina_list_count(borders), */
+/*                                    _e_int_menus_clients_sort_z_order_cb); */
+
+/*         if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_DESK) */
+/*       { */
+/*              borders = eina_list_sort(borders, eina_list_count(borders),  */
+/*                                       _e_int_menus_clients_group_desk_cb); */
+/*              _e_int_menus_clients_add_by_desk(desk, borders, m); */
+/*       } */
+/*         if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_CLASS)  */
+/*       { */
+/*          borders = eina_list_sort(borders, eina_list_count(borders),  */
+/*                                       _e_int_menus_clients_group_class_cb);  */
+/*          _e_int_menus_clients_add_by_class(borders, m); */
+/*       } */
+/*     if (e_config->clientlist_group_by == E_CLIENTLIST_GROUP_NONE) */
+/*           _e_int_menus_clients_add_by_none(borders, m); */
+/*      } */
+
+/*    mi = e_menu_item_new(m); */
+/*    e_menu_item_separator_set(mi, 1); */
+
+/*    mi = e_menu_item_new(m); */
+/*    e_menu_item_label_set(mi, _("Cleanup Windows")); */
+/*    e_util_menu_item_theme_icon_set(mi, "preferences-system-windows"); */
+/*    e_menu_item_callback_set(mi, _e_int_menus_clients_cleanup_cb, zone); */
+
+/*    if (dat) */
+/*      { */
+/*     mi = e_menu_item_new(m); */
+/*     e_menu_item_separator_set(mi, 1); */
+
+/*     subm = e_int_menus_lost_clients_new(); */
+/*     e_object_data_set(E_OBJECT(subm), e_object_data_get(E_OBJECT(m)));    */
+/*     dat->lost_clients = subm; */
+/*     mi = e_menu_item_new(m); */
+/*     e_menu_item_label_set(mi, _("Lost Windows")); */
+/*     e_util_menu_item_theme_icon_set(mi, "preferences-windows-lost"); */
+/*     e_menu_item_submenu_set(mi, subm); */
+/*      } */
+
+/*    e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_clients_free_hook); */
+/*    e_object_data_set(E_OBJECT(m), borders); */
+/* } */
+
+/* static const char * */
+/* _e_int_menus_clients_title_abbrv(const char *title) */
+/* { */
+/*    int max_len; */
+
+/*    max_len = e_config->clientlist_max_caption_len; */
+/*    if ((e_config->clientlist_limit_caption_len) && ((int) strlen(title) > max_len)) */
+/*      { */
+/*     char *abbv; */
+/*     const char *left, *right; */
+
+/*     abbv = calloc(E_CLIENTLIST_MAX_CAPTION_LEN + 4, sizeof(char)); */
+/*     left = title; */
+/*     right = title + (strlen(title) - (max_len / 2)); */
+
+/*     strncpy(abbv, left, max_len / 2); */
+/*     strncat(abbv, "...", 3); */
+/*     strncat(abbv, right, max_len / 2); */
+
+/*     return abbv; */
+/*      } */
+/*    else */
+/*      return title; */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_item_create(E_Border *bd, E_Menu *m) */
+/* { */
+/*    E_Menu_Item *mi; */
+/*    const char *title; */
+
+/*    title = _e_int_menus_clients_title_abbrv(e_border_name_get(bd)); */
+/*    mi = e_menu_item_new(m); */
+/*    e_menu_item_check_set(mi, 1); */
+/*    if ((title) && (title[0])) */
+/*      e_menu_item_label_set(mi, title); */
+/*    else */
+/*      e_menu_item_label_set(mi, _("No name!!")); */
+/*    e_object_ref(E_OBJECT(bd)); */
+/*    e_menu_item_callback_set(mi, _e_int_menus_clients_item_cb, bd); */
+/*    e_menu_item_realize_callback_set(mi, _e_int_menus_clients_icon_cb, bd); */
+/*    if (!bd->iconic) e_menu_item_toggle_set(mi, 1); */
+/* } */
+
+/* static void */
+/* _e_int_menus_clients_free_hook(void *obj) */
+/* { */
+/*    Eina_List *borders; */
+/*    E_Border *bd; */
+/*    E_Menu *m; */
+
+/*    m = obj; */
+/*    borders = e_object_data_get(E_OBJECT(m)); */
+/*    EINA_LIST_FREE(borders, bd) */
+/*      e_object_unref(E_OBJECT(bd)); */
+/* } */
+
+/* static void  */
+/* _e_int_menus_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) */
+/* { */
+/*    E_Border *bd; */
+
+/*    bd = data; */
+/*    E_OBJECT_CHECK(bd); */
+
+/*    if (bd->iconic) */
+/*      { */
+/*         if (e_config->clientlist_warp_to_iconified_desktop == 1) */
+/*           e_desk_show(bd->desk); */
+/*     if (!bd->lock_user_iconify) */
+/*       e_border_uniconify(bd); */
+/*      } */
+
+/*    if (!bd->iconic) e_desk_show(bd->desk); */
+/*    if (!bd->lock_user_stacking) e_border_raise(bd); */
+/*    if (!bd->lock_focus_out) */
+/*      { */
+/*     if (e_config->focus_policy != E_FOCUS_CLICK) */
+/*       ecore_x_pointer_warp(bd->zone->container->win, */
+/*                            bd->x + (bd->w / 2), bd->y + (bd->h / 2)); */
+/*     e_border_focus_set(bd, 1, 1); */
+/*      } */
+/* } */
+
+/* static void  */
+/* _e_int_menus_clients_icon_cb(void *data, E_Menu *m, E_Menu_Item *mi) */
+/* { */
+/*    E_Border *bd; */
+/*    Evas_Object *o; */
+
+/*    bd = data; */
+/*    E_OBJECT_CHECK(bd); */
+/*    o = e_icon_add(m->evas); */
+/*    e_icon_object_set(o, e_border_icon_add(bd, m->evas)); */
+/*    mi->o_icon = o; */
+/* } */
+
+/* static void  */
+/* _e_int_menus_clients_cleanup_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__) */
+/* { */
+/*    E_Action *act; */
+
+/*    act = e_action_find("cleanup_windows"); */
+/*    if (act) act->func.go(E_OBJECT(m->zone), NULL); */
+/* } */
+
+/* static void */
+/* _e_int_menus_lost_clients_pre_cb(void *data __UNUSED__, E_Menu *m) */
+/* { */
+/*    E_Menu_Item *mi; */
+/*    Eina_List *l, *borders = NULL; */
+/*    E_Border *bd;  */
+/*    E_Menu *root; */
+/*    E_Zone *zone = NULL; */
+
+/*    e_menu_pre_activate_callback_set(m, NULL, NULL); */
+/*    root = e_menu_root_get(m); */
+/*    if (root) zone = root->zone; */
+/*    borders = e_border_lost_windows_get(zone); */
+
+/*    if (!borders) */
+/*      { */
+/*     mi = e_menu_item_new(m); */
+/*     e_menu_item_label_set(mi, _("(No Windows)")); */
+/*     return; */
+/*      } */
+/*    EINA_LIST_FOREACH(borders, l, bd) */
+/*      { */
+/*     const char *title = ""; */
+
+/*     title = e_border_name_get(bd); */
+/*     mi = e_menu_item_new(m); */
+/*     if ((title) && (title[0])) */
+/*       e_menu_item_label_set(mi, title); */
+/*     else */
+/*       e_menu_item_label_set(mi, _("No name!!")); */
+/*     e_object_ref(E_OBJECT(bd)); */
+/*     e_menu_item_callback_set(mi, _e_int_menus_lost_clients_item_cb, bd); */
+/*     if (bd->desktop)  */
+/*           e_util_desktop_menu_item_icon_add(bd->desktop, 24, mi); */
+/*      } */
+/*    e_object_free_attach_func_set(E_OBJECT(m),  */
+/*                              _e_int_menus_lost_clients_free_hook); */
+/*    e_object_data_set(E_OBJECT(m), borders); */
+/* } */
+
+/* static void */
+/* _e_int_menus_lost_clients_free_hook(void *obj) */
+/* { */
+/*    Eina_List *borders; */
+/*    E_Border *bd; */
+/*    E_Menu *m; */
+
+/*    m = obj; */
+/*    borders = e_object_data_get(E_OBJECT(m)); */
+/*    EINA_LIST_FREE(borders, bd) */
+/*      e_object_unref(E_OBJECT(bd)); */
+/* } */
+
+/* static void  */
+/* _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) */
+/* { */
+/*    E_Border *bd = data; */
+
+/*    E_OBJECT_CHECK(bd); */
+/*    if (bd->iconic) e_border_uniconify(bd); */
+/*    if (bd->desk) e_desk_show(bd->desk); */
+/*    e_border_center(bd); */
+/*    e_border_raise(bd); */
+/*    if (!bd->lock_focus_out) */
+/*      e_border_focus_set(bd, 1, 1); */
+/* } */
+
+static void
+_e_int_menus_augmentation_add(E_Menu *m, Eina_List *augmentation)
+{
+   E_Int_Menu_Augmentation *aug;
+   Eina_List *l;
+   char *data;
+
+   if ((!augmentation) || (!m)) return;
+   EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
+     if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
+       return;
+
+   EINA_LIST_FOREACH(augmentation, l, aug)
+     if (aug->add.func) aug->add.func(aug->add.data, m);
+}
+
+static void
+_e_int_menus_augmentation_del(E_Menu *m, Eina_List *augmentation)
+{
+   E_Int_Menu_Augmentation *aug;
+   Eina_List *l;
+   char *data;
+
+   if ((!augmentation) || (!m)) return;
+   EINA_LIST_FOREACH(_e_int_menus_augmentation_disabled, l, data)
+     if (eina_hash_find(_e_int_menus_augmentation, data) == augmentation)
+       return;
+
+   EINA_LIST_FOREACH(augmentation, l, aug)
+     if (aug->del.func) aug->del.func(aug->del.data, m);
+}
+
+static void 
+_e_int_menus_shelves_pre_cb(void *data __UNUSED__, E_Menu *m) 
+{
+   E_Menu_Item *mi;
+   Eina_List *l, *shelves = NULL;
+   E_Shelf *s;
+   E_Container *con;
+   E_Zone *zone;
+
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+   con = e_container_current_get(e_manager_current_get());
+   zone = e_zone_current_get(con);
+
+   shelves = e_shelf_list();
+
+   if (!shelves)
+     {
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, _("(No Shelves)"));
+     }
+
+   EINA_LIST_FOREACH(shelves, l, s)
+     {
+       const char *name;
+       char buf[PATH_MAX];
+
+       if (!s) continue;
+       if (s->zone->num != zone->num) continue;
+       if (s->cfg->container != (int) con->num) continue;
+
+        name = e_shelf_orient_string_get (s);
+       snprintf(buf, sizeof(buf), "Shelf %s", name);
+
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, buf);
+       e_menu_item_callback_set(mi, _e_int_menus_shelves_item_cb, s);
+       switch (s->cfg->orient) 
+         {
+          case E_GADCON_ORIENT_LEFT:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-left");
+            break;
+          case E_GADCON_ORIENT_RIGHT:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-right");
+            break;
+          case E_GADCON_ORIENT_TOP:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-top");
+            break;
+          case E_GADCON_ORIENT_BOTTOM:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom");
+            break;
+          case E_GADCON_ORIENT_CORNER_TL:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-top-left");
+            break;
+          case E_GADCON_ORIENT_CORNER_TR:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-top-right");
+            break;
+          case E_GADCON_ORIENT_CORNER_BL:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-left");
+            break;
+          case E_GADCON_ORIENT_CORNER_BR:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-bottom-right");
+            break;
+          case E_GADCON_ORIENT_CORNER_LT:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-left-top");
+            break;
+          case E_GADCON_ORIENT_CORNER_RT:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-right-top");
+            break;
+          case E_GADCON_ORIENT_CORNER_LB:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-left-bottom");
+            break;
+          case E_GADCON_ORIENT_CORNER_RB:
+            e_util_menu_item_theme_icon_set(mi, "preferences-position-right-bottom");
+            break;
+          default:
+            e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
+            break;
+         }
+     }
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Add A Shelf"));
+   e_util_menu_item_theme_icon_set(mi, "list-add");
+   e_menu_item_callback_set(mi, _e_int_menus_shelves_add_cb, NULL);
+
+   if (shelves)
+     {
+       mi = e_menu_item_new(m);
+       e_menu_item_label_set(mi, _("Delete A Shelf"));
+       e_util_menu_item_theme_icon_set(mi, "list-remove");
+       e_menu_item_callback_set(mi, _e_int_menus_shelves_del_cb, NULL);
+     }
+}
+
+static void 
+_e_int_menus_shelves_item_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
+{
+   E_Shelf *s = data;
+
+   E_OBJECT_CHECK(s);
+   /* e_int_shelf_config(s); */
+}
+
+static void 
+_e_int_menus_shelves_add_cb(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__) 
+{
+   E_Container *con;
+   E_Zone *zone;
+   E_Config_Shelf *cs;
+
+   con = e_container_current_get(e_manager_current_get());
+   zone = e_zone_current_get(con);
+   cs = E_NEW(E_Config_Shelf, 1);
+   cs->name = eina_stringshare_add("shelf");
+   cs->container = con->num;
+   cs->zone = zone->num;
+   cs->popup = 1;
+   cs->layer = 200;
+   cs->orient = E_GADCON_ORIENT_CORNER_BR;
+   cs->fit_along = 1;
+   cs->fit_size = 0;
+   cs->style = eina_stringshare_add("default");
+   cs->size = 40;
+   cs->overlap = 0;
+   e_config->shelves = eina_list_append(e_config->shelves, cs);
+   e_config_save_queue();
+
+   e_shelf_config_update();
+}
+
+static void 
+_e_int_menus_shelves_del_cb(void *data __UNUSED__, E_Menu *m, E_Menu_Item *mi __UNUSED__) 
+{
+   e_configure_registry_call("extensions/shelves", m->zone->container, NULL);
+}
+
+static void 
+_e_int_menus_item_label_set(Efreet_Menu *entry, E_Menu_Item *mi) 
+{
+   Efreet_Desktop *desktop;
+   char label[4096];
+   int opt = 0;
+
+   if ((!entry) || (!mi)) return;
+
+   desktop = entry->desktop;
+   if ((e_config->menu_eap_name_show) && (entry->name)) opt |= 0x4;
+   if (desktop) 
+     {
+       if ((e_config->menu_eap_generic_show) && (desktop->generic_name) &&
+           (desktop->generic_name[0] != 0))
+         opt |= 0x2;
+       if ((e_config->menu_eap_comment_show) && (desktop->comment) &&
+           (desktop->comment[0] != 0))
+         opt |= 0x1;
+     }
+
+   if (opt == 0x7) 
+     snprintf(label, sizeof(label), "%s (%s) [%s]", entry->name, 
+              desktop->generic_name, desktop->comment);
+   else if (opt == 0x6) 
+     snprintf(label, sizeof(label), "%s (%s)", entry->name, 
+              desktop->generic_name);
+   else if (opt == 0x5) 
+     snprintf(label, sizeof(label), "%s [%s]", entry->name, desktop->comment);
+   else if (opt == 0x4) 
+     snprintf(label, sizeof(label), "%s", entry->name);
+   else if (opt == 0x3) 
+     snprintf(label, sizeof(label), "%s [%s]", desktop->generic_name, 
+              desktop->comment);
+   else if (opt == 0x2) 
+     snprintf(label, sizeof(label), "%s", desktop->generic_name);
+   else if (opt == 0x1) 
+     snprintf(label, sizeof(label), "%s", desktop->comment);
+   else
+     snprintf(label, sizeof(label), "%s", entry->name);
+
+   e_menu_item_label_set(mi, label);
+}
index d692f5405f8e0c49362993b544dec81ca8b52d86..88c339e2bd2c7f485eb14054b4bbf409c647a6c6 100644 (file)
@@ -1,39 +1,66 @@
 #ifdef E_TYPEDEFS
 
+typedef struct _E_Int_Menu_Augmentation E_Int_Menu_Augmentation;
+
 #else
-# ifndef E_INT_MENUS_H
-#  define E_INT_MENUS_H
+#ifndef E_INT_MENUS_H
+#define E_INT_MENUS_H
 
-typedef enum
-{
-   E_CLIENTLIST_GROUP_NONE,
-   E_CLIENTLIST_GROUP_DESK,
-   E_CLIENTLIST_GROUP_CLASS
-} E_Clientlist_Group_Type;
+#define E_CLIENTLIST_GROUP_NONE 0
+#define E_CLIENTLIST_GROUP_DESK 1
+#define E_CLIENTLIST_GROUP_CLASS 2
 
-typedef enum
-{
-   E_CLIENTLIST_GROUP_SEP_NONE,
-   E_CLIENTLIST_GROUP_SEP_BAR,
-   E_CLIENTLIST_GROUP_SEP_MENU
-} E_Clientlist_Group_Sep_Type;
+#define E_CLIENTLIST_GROUP_SEP_NONE 0
+#define E_CLIENTLIST_GROUP_SEP_BAR 1
+#define E_CLIENTLIST_GROUP_SEP_MENU 2
 
-typedef enum
-{
-   E_CLIENTLIST_SORT_NONE,
-   E_CLIENTLIST_SORT_ALPHA,
-   E_CLIENTLIST_SORT_ZORDER,
-   E_CLIENTLIST_SORT_MOST_RECENT
-} E_Clientlist_Group_Sort_Type;
+#define E_CLIENTLIST_SORT_NONE 0
+#define E_CLIENTLIST_SORT_ALPHA 1
+#define E_CLIENTLIST_SORT_ZORDER 2
+#define E_CLIENTLIST_SORT_MOST_RECENT 3
 
-typedef enum
+#define E_CLIENTLIST_GROUPICONS_OWNER 0
+#define E_CLIENTLIST_GROUPICONS_CURRENT 1
+#define E_CLIENTLIST_GROUPICONS_SEP 2
+
+#define E_CLIENTLIST_MAX_CAPTION_LEN 256
+
+struct _E_Int_Menu_Augmentation
 {
-   E_CLIENTLIST_GROUPICONS_OWNER,
-   E_CLIENTLIST_GROUPICONS_CURRENT,
-   E_CLIENTLIST_GROUPICONS_SEP,
-} E_Clientlist_Groupicons_Type;
+   const char *sort_key;
+   struct 
+     {
+        void (*func) (void *data, E_Menu *m);
+        void *data;
+     } add, del;
+};
 
-#  define E_CLIENTLIST_MAX_CAPTION_LEN 256
+EAPI E_Menu *e_int_menus_main_new(void);    
+EAPI E_Menu *e_int_menus_desktops_new(void);
+EAPI E_Menu *e_int_menus_clients_new(void);
+EAPI E_Menu *e_int_menus_apps_new(const char *dir);
+EAPI E_Menu *e_int_menus_favorite_apps_new(void);
+EAPI E_Menu *e_int_menus_all_apps_new(void);
+EAPI E_Menu *e_int_menus_config_new(void);
+EAPI E_Menu *e_int_menus_lost_clients_new(void);
+EAPI E_Menu *e_int_menus_shelves_new(void);
 
-# endif
+EAPI E_Int_Menu_Augmentation *e_int_menus_menu_augmentation_add(const char *menu,
+                                                               void (*func_add) (void *data, E_Menu *m),
+                                                               void *data_add,
+                                                               void (*func_del) (void *data, E_Menu *m),
+                                                               void *data_del);
+EAPI E_Int_Menu_Augmentation *e_int_menus_menu_augmentation_add_sorted(const char *menu,
+                                                                      const char *sort_key,
+                                                                      void (*func_add) (void *data, E_Menu *m),
+                                                                      void *data_add,
+                                                                      void (*func_del) (void *data, E_Menu *m),
+                                                                      void *data_del);
+EAPI void                     e_int_menus_menu_augmentation_del(const char *menu,
+                                                               E_Int_Menu_Augmentation *maug);
+
+EAPI void                     e_int_menus_menu_augmentation_point_disabled_set(const char *menu,
+                                       Eina_Bool disabled);
+    
+#endif
 #endif
diff --git a/src/bin/e_wayland/e_ipc.c b/src/bin/e_wayland/e_ipc.c
new file mode 100644 (file)
index 0000000..28ebb91
--- /dev/null
@@ -0,0 +1,229 @@
+#include "e.h"
+
+#ifdef USE_IPC
+/* local subsystem functions */
+static Eina_Bool _e_ipc_cb_client_add(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+/* local subsystem globals */
+static Ecore_Ipc_Server *_e_ipc_server = NULL;
+#endif
+
+/* externally accessible functions */
+EINTERN int
+e_ipc_init(void)
+{
+#ifdef USE_IPC
+   char buf[4096], buf2[128], buf3[4096];
+   char *tmp, *user, *disp, *base;
+   int pid, trynum = 0;
+
+   tmp = getenv("TMPDIR");
+   if (!tmp) tmp = "/tmp";
+   base = tmp;
+
+   tmp = getenv("XDG_RUNTIME_DIR");
+   if (tmp) base = tmp;
+   tmp = getenv("SD_USER_SOCKETS_DIR");
+   if (tmp) base = tmp;
+
+   user = getenv("USER");
+   if (!user)
+     {
+        int uidint;
+
+        user = "__unknown__";
+        uidint = getuid();
+        if (uidint >= 0)
+          {
+             snprintf(buf2, sizeof(buf2), "%i", uidint);
+             user = buf2;
+          }
+     }
+
+   disp = getenv("DISPLAY");
+   if (!disp) disp = ":0";
+
+   e_util_env_set("E_IPC_SOCKET", "");
+
+   pid = (int)getpid();
+   for (trynum = 0; trynum <= 4096; trynum++)
+     {
+        struct stat st;
+        int id1 = 0;
+
+        snprintf(buf, sizeof(buf), "%s/e-%s@%x",
+                 base, user, id1);
+        mkdir(buf, S_IRWXU);
+        if (stat(buf, &st) == 0)
+          {
+             if ((st.st_uid == getuid()) &&
+                 ((st.st_mode & (S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)) ==
+                  (S_IRWXU | S_IFDIR)))
+               {
+                  snprintf(buf3, sizeof(buf3), "%s/%s-%i",
+                           buf, disp, pid);
+                  _e_ipc_server = ecore_ipc_server_add
+                      (ECORE_IPC_LOCAL_SYSTEM, buf3, 0, NULL);
+                  if (_e_ipc_server) break;
+               }
+          }
+        id1 = rand();
+     }
+   if (!_e_ipc_server) return 0;
+
+   e_util_env_set("E_IPC_SOCKET", buf3);
+   ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
+                           _e_ipc_cb_client_add, NULL);
+   ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
+                           _e_ipc_cb_client_del, NULL);
+   ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
+                           _e_ipc_cb_client_data, NULL);
+
+   e_ipc_codec_init();
+#endif
+   return 1;
+}
+
+EINTERN int
+e_ipc_shutdown(void)
+{
+#ifdef USE_IPC
+   e_ipc_codec_shutdown();
+   if (_e_ipc_server)
+     {
+        ecore_ipc_server_del(_e_ipc_server);
+        _e_ipc_server = NULL;
+     }
+#endif
+   return 1;
+}
+
+#ifdef USE_IPC
+/* local subsystem globals */
+static Eina_Bool
+_e_ipc_cb_client_add(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Ipc_Event_Client_Add *e;
+
+   e = event;
+   if (ecore_ipc_client_server_get(e->client) != _e_ipc_server)
+     return ECORE_CALLBACK_PASS_ON;
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Ipc_Event_Client_Del *e;
+
+   e = event;
+   if (ecore_ipc_client_server_get(e->client) != _e_ipc_server)
+     return ECORE_CALLBACK_PASS_ON;
+   /* delete client sruct */
+   e_thumb_client_del(e);
+   /* e_fm2_client_del(e); */
+   ecore_ipc_client_del(e->client);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Ipc_Event_Client_Data *e;
+
+   e = event;
+   if (ecore_ipc_client_server_get(e->client) != _e_ipc_server)
+     return ECORE_CALLBACK_PASS_ON;
+   switch (e->major)
+     {
+      case E_IPC_DOMAIN_SETUP:
+      case E_IPC_DOMAIN_REQUEST:
+      case E_IPC_DOMAIN_REPLY:
+      case E_IPC_DOMAIN_EVENT:
+        switch (e->minor)
+          {
+           case E_IPC_OP_EXEC_ACTION:
+           {
+              E_Ipc_2Str *req = NULL;
+
+              if (e_ipc_codec_2str_dec(e->data, e->size, &req))
+                {
+                   Eina_List *m = e_manager_list();
+                   int len, ok = 0;
+                   void *d;
+
+                   if (m)
+                     {
+                        E_Manager *man = eina_list_data_get(m);
+
+                        if (man)
+                          {
+                             E_Action *act = e_action_find(req->str1);
+
+                             if ((act) && (act->func.go))
+                               {
+                                  act->func.go(E_OBJECT(man), req->str2);
+                                  ok = 1;
+                               }
+                          }
+                     }
+
+                   d = e_ipc_codec_int_enc(ok, &len);
+                   if (d)
+                     {
+                        ecore_ipc_client_send(e->client,
+                                              E_IPC_DOMAIN_REPLY,
+                                              E_IPC_OP_EXEC_ACTION_REPLY,
+                                              0, 0, 0, d, len);
+                        free(d);
+                     }
+
+                   if (req)
+                     {
+                        E_FREE(req->str1);
+                        E_FREE(req->str2);
+                        E_FREE(req);
+                     }
+                }
+           }
+           break;
+
+           default:
+             break;
+          }
+        break;
+
+      case E_IPC_DOMAIN_THUMB:
+        e_thumb_client_data(e);
+        break;
+
+      case E_IPC_DOMAIN_FM:
+        /* e_fm2_client_data(e); */
+        break;
+
+      case E_IPC_DOMAIN_ALERT:
+      {
+         switch (e->minor)
+           {
+            case E_ALERT_OP_RESTART:
+              if (getenv("E_START_MTRACK"))
+                e_util_env_set("MTRACK", "track");
+              ecore_app_restart();
+              break;
+
+            case E_ALERT_OP_EXIT:
+              exit(-11);
+              break;
+           }
+      }
+      break;
+
+      default:
+        break;
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+#endif
diff --git a/src/bin/e_wayland/e_ipc.h b/src/bin/e_wayland/e_ipc.h
new file mode 100644 (file)
index 0000000..ccb9868
--- /dev/null
@@ -0,0 +1,32 @@
+#ifdef E_TYPEDEFS
+
+#ifdef USE_IPC
+
+#define E_IPC_OP_EXEC_ACTION 386
+#define E_IPC_OP_EXEC_ACTION_REPLY 387
+
+typedef enum _E_Ipc_Domain
+{
+   E_IPC_DOMAIN_NONE,
+   E_IPC_DOMAIN_SETUP,
+   E_IPC_DOMAIN_REQUEST,
+   E_IPC_DOMAIN_REPLY,
+   E_IPC_DOMAIN_EVENT,
+   E_IPC_DOMAIN_THUMB,
+   E_IPC_DOMAIN_FM,
+   E_IPC_DOMAIN_ALERT,
+   E_IPC_DOMAIN_LAST
+} E_Ipc_Domain;
+
+typedef int E_Ipc_Op;
+#endif
+
+#else
+#ifndef E_IPC_H
+#define E_IPC_H
+
+EINTERN int e_ipc_init(void);
+EINTERN int e_ipc_shutdown(void);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_ipc_codec.c b/src/bin/e_wayland/e_ipc_codec.c
new file mode 100644 (file)
index 0000000..d237a78
--- /dev/null
@@ -0,0 +1,667 @@
+#include "e.h"
+
+#ifdef USE_IPC
+/* local subsystem functions */
+
+/* encode functions, Should these be global? */
+
+/* local subsystem globals */
+static Eet_Data_Descriptor *_e_ipc_int_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_double_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_2int_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_2str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_2str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_int_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_int_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_2str_int_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_2str_int_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_4int_2str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_4int_2str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_5int_2str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_5int_2str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_3int_4str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_3int_4str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_3int_3str_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_3int_3str_list_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_4int_edd = NULL;
+static Eet_Data_Descriptor *_e_ipc_str_4int_list_edd = NULL;
+
+#define E_IPC_DD(Edd, Eddc, Name, Type) \
+  Eddc.name = Name;                     \
+  Eddc.size = sizeof (Type);            \
+  Edd = eet_data_descriptor_stream_new(&Eddc);
+
+/* externally accessible functions */
+EINTERN int
+e_ipc_codec_init(void)
+{
+   Eet_Data_Descriptor_Class eddc;
+
+   if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "int", sizeof (E_Ipc_Int)))
+     return 0;
+   _e_ipc_int_edd = eet_data_descriptor_stream_new(&eddc);
+   E_CONFIG_VAL(_e_ipc_int_edd, E_Ipc_Int, val, INT);
+
+   E_IPC_DD(_e_ipc_double_edd, eddc, "double", E_Ipc_Double);
+   E_CONFIG_VAL(_e_ipc_double_edd, E_Ipc_Double, val, DOUBLE);
+
+   E_IPC_DD(_e_ipc_2int_edd, eddc, "2int", E_Ipc_2Int);
+   E_CONFIG_VAL(_e_ipc_2int_edd, E_Ipc_2Int, val1, INT);
+   E_CONFIG_VAL(_e_ipc_2int_edd, E_Ipc_2Int, val2, INT);
+
+   E_IPC_DD(_e_ipc_str_edd, eddc, "str", E_Ipc_Str);
+   E_CONFIG_VAL(_e_ipc_str_edd, E_Ipc_Str, str, STR);
+
+   E_IPC_DD(_e_ipc_str_list_edd, eddc, "str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_str_list_edd, E_Ipc_List, list, _e_ipc_str_edd);
+
+   E_IPC_DD(_e_ipc_2str_edd, eddc, "2str", E_Ipc_2Str);
+   E_CONFIG_VAL(_e_ipc_2str_edd, E_Ipc_2Str, str1, STR);
+   E_CONFIG_VAL(_e_ipc_2str_edd, E_Ipc_2Str, str2, STR);
+
+   E_IPC_DD(_e_ipc_2str_list_edd, eddc, "2str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_2str_list_edd, E_Ipc_List, list, _e_ipc_2str_edd);
+
+   E_IPC_DD(_e_ipc_str_int_edd, eddc, "str_int", E_Ipc_Str_Int);
+   E_CONFIG_VAL(_e_ipc_str_int_edd, E_Ipc_Str_Int, str, STR);
+   E_CONFIG_VAL(_e_ipc_str_int_edd, E_Ipc_Str_Int, val, INT);
+
+   E_IPC_DD(_e_ipc_str_int_list_edd, eddc, "str_int_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_str_int_list_edd, E_Ipc_List, list, _e_ipc_str_int_edd);
+
+   E_IPC_DD(_e_ipc_2str_int_edd, eddc, "2str_int", E_Ipc_2Str_Int);
+   E_CONFIG_VAL(_e_ipc_2str_int_edd, E_Ipc_2Str_Int, str1, STR);
+   E_CONFIG_VAL(_e_ipc_2str_int_edd, E_Ipc_2Str_Int, str2, STR);
+   E_CONFIG_VAL(_e_ipc_2str_int_edd, E_Ipc_2Str_Int, val, INT);
+
+   E_IPC_DD(_e_ipc_2str_int_list_edd, eddc, "2str_int_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_2str_int_list_edd, E_Ipc_List, list, _e_ipc_2str_int_edd);
+
+   E_IPC_DD(_e_ipc_4int_2str_edd, eddc, "4int_2str", E_Ipc_4Int_2Str);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, val1, INT);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, val2, INT);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, val3, INT);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, val4, INT);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, str1, STR);
+   E_CONFIG_VAL(_e_ipc_4int_2str_edd, E_Ipc_4Int_2Str, str2, STR);
+
+   E_IPC_DD(_e_ipc_4int_2str_list_edd, eddc, "4int_2str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_4int_2str_list_edd, E_Ipc_List, list, _e_ipc_4int_2str_edd);
+
+   E_IPC_DD(_e_ipc_5int_2str_edd, eddc, "5int_2str", E_Ipc_5Int_2Str);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, val1, INT);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, val2, INT);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, val3, INT);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, val4, INT);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, val5, INT);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, str1, STR);
+   E_CONFIG_VAL(_e_ipc_5int_2str_edd, E_Ipc_5Int_2Str, str2, STR);
+
+   E_IPC_DD(_e_ipc_5int_2str_list_edd, eddc, "5int_2str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_5int_2str_list_edd, E_Ipc_List, list, _e_ipc_5int_2str_edd);
+
+   E_IPC_DD(_e_ipc_3int_4str_edd, eddc, "3int_4str", E_Ipc_3Int_4Str);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, val1, INT);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, val2, INT);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, val3, INT);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, str1, STR);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, str2, STR);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, str3, STR);
+   E_CONFIG_VAL(_e_ipc_3int_4str_edd, E_Ipc_3Int_4Str, str4, STR);
+
+   E_IPC_DD(_e_ipc_3int_4str_list_edd, eddc, "3int_4str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_3int_4str_list_edd, E_Ipc_List, list, _e_ipc_3int_4str_edd);
+
+   E_IPC_DD(_e_ipc_3int_3str_edd, eddc, "3int_3str", E_Ipc_3Int_3Str);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, val1, INT);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, val2, INT);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, val3, INT);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, str1, STR);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, str2, STR);
+   E_CONFIG_VAL(_e_ipc_3int_3str_edd, E_Ipc_3Int_3Str, str3, STR);
+
+   E_IPC_DD(_e_ipc_3int_3str_list_edd, eddc, "3int_3str_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_3int_3str_list_edd, E_Ipc_List, list, _e_ipc_3int_3str_edd);
+
+   E_IPC_DD(_e_ipc_str_4int_edd, eddc, "str_4int", E_Ipc_Str_4Int);
+   E_CONFIG_VAL(_e_ipc_str_4int_edd, E_Ipc_Str_4Int, str, STR);
+   E_CONFIG_VAL(_e_ipc_str_4int_edd, E_Ipc_Str_4Int, val1, INT);
+   E_CONFIG_VAL(_e_ipc_str_4int_edd, E_Ipc_Str_4Int, val2, INT);
+   E_CONFIG_VAL(_e_ipc_str_4int_edd, E_Ipc_Str_4Int, val3, INT);
+   E_CONFIG_VAL(_e_ipc_str_4int_edd, E_Ipc_Str_4Int, val4, INT);
+
+   E_IPC_DD(_e_ipc_str_4int_list_edd, eddc, "str_4int_list", E_Ipc_List);
+   E_CONFIG_LIST(_e_ipc_str_4int_list_edd, E_Ipc_List, list, _e_ipc_str_4int_edd);
+
+   return 1;
+}
+
+EINTERN void
+e_ipc_codec_shutdown(void)
+{
+   E_CONFIG_DD_FREE(_e_ipc_int_edd);
+   E_CONFIG_DD_FREE(_e_ipc_double_edd);
+   E_CONFIG_DD_FREE(_e_ipc_2int_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_2str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_2str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_int_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_int_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_2str_int_edd);
+   E_CONFIG_DD_FREE(_e_ipc_2str_int_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_4int_2str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_4int_2str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_5int_2str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_5int_2str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_3int_4str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_3int_4str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_3int_3str_edd);
+   E_CONFIG_DD_FREE(_e_ipc_3int_3str_list_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_4int_edd);
+   E_CONFIG_DD_FREE(_e_ipc_str_4int_list_edd);
+}
+
+EAPI int
+e_ipc_codec_int_dec(char *data, int bytes, int *dest)
+{
+   E_Ipc_Int *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_int_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->val;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_int_enc(int val, int *size_ret)
+{
+   E_Ipc_Int dat;
+
+   dat.val = val;
+   return eet_data_descriptor_encode(_e_ipc_int_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_double_dec(char *data, int bytes, double *dest)
+{
+   E_Ipc_Double *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_double_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->val;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_double_enc(double val, int *size_ret)
+{
+   E_Ipc_Double dat;
+
+   dat.val = val;
+   return eet_data_descriptor_encode(_e_ipc_double_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_2int_dec(char *data, int bytes, int *dest, int *dest2)
+{
+   E_Ipc_2Int *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_2int_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->val1;
+   if (dest2) *dest2 = dat->val2;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_2int_enc(int val1, int val2, int *size_ret)
+{
+   E_Ipc_2Int dat;
+
+   dat.val1 = val1;
+   dat.val2 = val2;
+   return eet_data_descriptor_encode(_e_ipc_2int_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_str_dec(char *data, int bytes, char **dest)
+{
+   E_Ipc_Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->str;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_enc(const char *str, int *size_ret)
+{
+   E_Ipc_Str dat;
+
+   dat.str = (char *)str;
+   return eet_data_descriptor_encode(_e_ipc_str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_2str_dec(char *data, int bytes, E_Ipc_2Str **dest)
+{
+   E_Ipc_2Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_2str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_2str_enc(const char *str1, const char *str2, int *size_ret)
+{
+   E_Ipc_2Str dat;
+
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   return eet_data_descriptor_encode(_e_ipc_2str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_2str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_2str_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_2str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_2str_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+   Eina_List *list = NULL, *l;
+   E_Ipc_Str *str_node;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_list_edd, data, bytes);
+   if (!dat) return 0;
+   EINA_LIST_FOREACH(dat->list, l, str_node)
+     {
+        list = eina_list_append(list, str_node->str);
+     }
+   if (dest) *dest = list;
+   E_FREE_LIST(dat->list, free);
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   Eina_List *l;
+   E_Ipc_Str *str_node;
+   char *str;
+   void *data;
+
+   dat.list = NULL;
+   EINA_LIST_FOREACH(list, l, str)
+     {
+        str_node = malloc(sizeof(E_Ipc_Str));
+        str_node->str = str;
+        dat.list = eina_list_append(dat.list, str_node);
+     }
+   data = eet_data_descriptor_encode(_e_ipc_str_list_edd, &dat, size_ret);
+   E_FREE_LIST(dat.list, free);
+   return data;
+}
+
+EAPI int
+e_ipc_codec_str_int_dec(char *data, int bytes, E_Ipc_Str_Int **dest)
+{
+   E_Ipc_Str_Int *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_int_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_int_enc(const char *str, int val, int *size_ret)
+{
+   E_Ipc_Str_Int dat;
+
+   dat.str = (char *)str;
+   dat.val = val;
+   return eet_data_descriptor_encode(_e_ipc_str_int_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_str_int_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_int_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_int_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_str_int_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_2str_int_dec(char *data, int bytes, E_Ipc_2Str_Int **dest)
+{
+   E_Ipc_2Str_Int *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_2str_int_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_2str_int_enc(const char *str1, const char *str2, int val, int *size_ret)
+{
+   E_Ipc_2Str_Int dat;
+
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   dat.val = val;
+   return eet_data_descriptor_encode(_e_ipc_2str_int_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_2str_int_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_2str_int_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_2str_int_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_2str_int_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_4int_2str_dec(char *data, int bytes, E_Ipc_4Int_2Str **dest)
+{
+   E_Ipc_4Int_2Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_4int_2str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_4int_2str_enc(int val1, int val2, int val3, int val4, const char *str1, const char *str2, int *size_ret)
+{
+   E_Ipc_4Int_2Str dat;
+
+   dat.val1 = val1;
+   dat.val2 = val2;
+   dat.val3 = val3;
+   dat.val4 = val4;
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   return eet_data_descriptor_encode(_e_ipc_4int_2str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_4int_2str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_4int_2str_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_4int_2str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_4int_2str_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_5int_2str_dec(char *data, int bytes, E_Ipc_5Int_2Str **dest)
+{
+   E_Ipc_5Int_2Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_5int_2str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_5int_2str_enc(int val1, int val2, int val3, int val4, int val5, const char *str1, const char *str2, int *size_ret)
+{
+   E_Ipc_5Int_2Str dat;
+
+   dat.val1 = val1;
+   dat.val2 = val2;
+   dat.val3 = val3;
+   dat.val4 = val4;
+   dat.val5 = val5;
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   return eet_data_descriptor_encode(_e_ipc_5int_2str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_5int_2str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_5int_2str_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_5int_2str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_5int_2str_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_3int_4str_dec(char *data, int bytes, E_Ipc_3Int_4Str **dest)
+{
+   E_Ipc_3Int_4Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_3int_4str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_3int_4str_enc(int val1, int val2, int val3, const char *str1, const char *str2, const char *str3, const char *str4, int *size_ret)
+{
+   E_Ipc_3Int_4Str dat;
+
+   dat.val1 = val1;
+   dat.val2 = val2;
+   dat.val3 = val3;
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   dat.str3 = (char *)str3;
+   dat.str4 = (char *)str4;
+   return eet_data_descriptor_encode(_e_ipc_3int_4str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_3int_4str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_3int_4str_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_3int_4str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_3int_4str_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_3int_3str_dec(char *data, int bytes, E_Ipc_3Int_3Str **dest)
+{
+   E_Ipc_3Int_3Str *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_3int_3str_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_3int_3str_enc(int val1, int val2, int val3, const char *str1, const char *str2, const char *str3, int *size_ret)
+{
+   E_Ipc_3Int_3Str dat;
+
+   dat.val1 = val1;
+   dat.val2 = val2;
+   dat.val3 = val3;
+   dat.str1 = (char *)str1;
+   dat.str2 = (char *)str2;
+   dat.str3 = (char *)str3;
+   return eet_data_descriptor_encode(_e_ipc_3int_3str_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_3int_3str_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_3int_3str_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_3int_3str_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_3int_3str_list_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_str_4int_dec(char *data, int bytes, E_Ipc_Str_4Int **dest)
+{
+   E_Ipc_Str_4Int *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_4int_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat;
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_4int_enc(const char *str1, int val1, int val2, int val3, int val4, int *size_ret)
+{
+   E_Ipc_Str_4Int dat;
+
+   dat.str = (char *)str1;
+   dat.val1 = val1;
+   dat.val2 = val2;
+   dat.val3 = val3;
+   dat.val4 = val4;
+
+   return eet_data_descriptor_encode(_e_ipc_str_4int_edd, &dat, size_ret);
+}
+
+EAPI int
+e_ipc_codec_str_4int_list_dec(char *data, int bytes, Eina_List **dest)
+{
+   E_Ipc_List *dat;
+
+   if (!data) return 0;
+   dat = eet_data_descriptor_decode(_e_ipc_str_4int_list_edd, data, bytes);
+   if (!dat) return 0;
+   if (dest) *dest = dat->list;
+   free(dat);
+   return 1;
+}
+
+EAPI void *
+e_ipc_codec_str_4int_list_enc(Eina_List *list, int *size_ret)
+{
+   E_Ipc_List dat;
+   dat.list = list;
+   return eet_data_descriptor_encode(_e_ipc_str_4int_list_edd, &dat, size_ret);
+}
+
+/* local subsystem globals */
+
+#endif
diff --git a/src/bin/e_wayland/e_ipc_codec.h b/src/bin/e_wayland/e_ipc_codec.h
new file mode 100644 (file)
index 0000000..d03eb95
--- /dev/null
@@ -0,0 +1,155 @@
+#ifdef E_TYPEDEFS
+
+#ifdef USE_IPC
+typedef struct _E_Ipc_Int              E_Ipc_Int;
+typedef struct _E_Ipc_Double           E_Ipc_Double;
+typedef struct _E_Ipc_2Int             E_Ipc_2Int;
+typedef struct _E_Ipc_List             E_Ipc_List;
+typedef struct _E_Ipc_Str              E_Ipc_Str;
+typedef struct _E_Ipc_2Str             E_Ipc_2Str;
+typedef struct _E_Ipc_Str_Int          E_Ipc_Str_Int;
+typedef struct _E_Ipc_Str_Int_List     E_Ipc_Str_Int_List;
+typedef struct _E_Ipc_2Str_Int         E_Ipc_2Str_Int;
+typedef struct _E_Ipc_2Str_Int_List    E_Ipc_2Str_Int_List;
+typedef struct _E_Ipc_4Int_2Str               E_Ipc_4Int_2Str;
+typedef struct _E_Ipc_5Int_2Str               E_Ipc_5Int_2Str;
+typedef struct _E_Ipc_3Int_4Str               E_Ipc_3Int_4Str;
+typedef struct _E_Ipc_3Int_3Str               E_Ipc_3Int_3Str;
+typedef struct _E_Ipc_Str_4Int        E_Ipc_Str_4Int;
+#endif
+
+#else
+#ifndef E_IPC_CODEC_H
+#define E_IPC_CODEC_H
+
+#ifdef USE_IPC
+struct _E_Ipc_Int
+{
+   int val;
+};
+
+struct _E_Ipc_Double
+{
+   double val;
+};
+
+struct _E_Ipc_2Int
+{
+   int val1, val2;
+};
+
+struct _E_Ipc_List
+{
+   Eina_List *list;
+};
+
+struct _E_Ipc_Str
+{
+   char *str;
+};
+
+struct _E_Ipc_2Str
+{
+   char *str1, *str2;
+};
+
+struct _E_Ipc_Str_Int
+{
+   char *str;
+   int   val;
+};
+
+struct _E_Ipc_2Str_Int
+{
+   char *str1, *str2;
+   int   val;
+};
+
+struct _E_Ipc_4Int_2Str
+{
+   int  val1, val2, val3, val4;
+   char *str1, *str2;
+};
+
+struct _E_Ipc_5Int_2Str
+{
+   int  val1, val2, val3, val4, val5;
+   char *str1, *str2;
+};
+
+struct _E_Ipc_3Int_4Str
+{
+   int  val1, val2, val3;
+   char *str1, *str2, *str3, *str4;
+};
+
+struct _E_Ipc_3Int_3Str
+{
+   int   val1, val2, val3;
+   char *str1, *str2, *str3;
+};
+
+struct _E_Ipc_Str_4Int
+{
+   char *str;
+   int   val1, val2, val3, val4;
+};
+
+EINTERN int      e_ipc_codec_init(void);
+EINTERN void     e_ipc_codec_shutdown(void);
+
+EAPI int      e_ipc_codec_int_dec(char *data, int bytes, int *dest);
+EAPI void    *e_ipc_codec_int_enc(int val, int *size_ret);
+EAPI int      e_ipc_codec_double_dec(char *data, int bytes, double *dest);
+EAPI void    *e_ipc_codec_double_enc(double val, int *size_ret);
+EAPI int      e_ipc_codec_2int_dec(char *data, int bytes, int *dest, int *dest2x);
+EAPI void    *e_ipc_codec_2int_enc(int val1, int val2, int *size_ret);
+
+EAPI int      e_ipc_codec_str_dec(char *data, int bytes, char **dest);
+EAPI void    *e_ipc_codec_str_enc(const char *str, int *size_ret);
+EAPI int      e_ipc_codec_str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_2str_dec(char *data, int bytes, E_Ipc_2Str **dest);
+EAPI void    *e_ipc_codec_2str_enc(const char *str1, const char *str2, int *size_ret);
+EAPI int      e_ipc_codec_2str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_2str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_str_int_dec(char *data, int bytes, E_Ipc_Str_Int **dest);
+EAPI void    *e_ipc_codec_str_int_enc(const char *str, int val, int *size_ret);
+EAPI int      e_ipc_codec_str_int_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_str_int_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_2str_int_dec(char *data, int bytes, E_Ipc_2Str_Int **dest);
+EAPI void    *e_ipc_codec_2str_int_enc(const char *str1, const char *str2, int val, int *size_ret);
+EAPI int      e_ipc_codec_2str_int_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_2str_int_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_4int_2str_dec(char *data, int bytes, E_Ipc_4Int_2Str **dest);
+EAPI void    *e_ipc_codec_4int_2str_enc(int val1, int val2, int val3, int val4, const char *str1, const char *str2, int *size_ret);
+EAPI int      e_ipc_codec_4int_2str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_4int_2str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_5int_2str_dec(char *data, int bytes, E_Ipc_5Int_2Str **dest);
+EAPI void    *e_ipc_codec_5int_2str_enc(int val1, int val2, int val3, int val4, int val5, const char *str1, const char *str2, int *size_ret);
+EAPI int      e_ipc_codec_5int_2str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_5int_2str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_3int_4str_dec(char *data, int bytes, E_Ipc_3Int_4Str **dest);
+EAPI void    *e_ipc_codec_3int_4str_enc(int val1, int val2, int val3, const char *str1, const char *str2, const char *str3, const char *str4, int *size_ret);
+EAPI int      e_ipc_codec_3int_4str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_3int_4str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_3int_3str_dec(char *data, int bytes, E_Ipc_3Int_3Str **dest);
+EAPI void    *e_ipc_codec_3int_3str_enc(int val1, int val2, int val3, const char *str1, const char *str2, const char *str3, int *size_ret);
+EAPI int      e_ipc_codec_3int_3str_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_3int_3str_list_enc(Eina_List *list, int *size_ret);
+
+EAPI int      e_ipc_codec_str_4int_dec(char *data, int bytes, E_Ipc_Str_4Int **dest);
+EAPI void    *e_ipc_codec_str_4int_enc(const char *str1, int val1, int val2, int val3, int val4, int *size_ret);
+EAPI int      e_ipc_codec_str_4int_list_dec(char *data, int bytes, Eina_List **dest);
+EAPI void    *e_ipc_codec_str_4int_list_enc(Eina_List *list, int *size_ret);
+#endif
+
+#endif
+#endif
index 7f18e22b356add96c309fc2698381c19e7a9e559..1f762d198319a9a2463267a2a6ac4c96fba867ef 100644 (file)
@@ -45,12 +45,15 @@ static Eina_Bool _e_main_cb_idle_before(void *data EINA_UNUSED);
 static Eina_Bool _e_main_cb_idle_after(void *data EINA_UNUSED);
 static Eina_Bool _e_main_cb_idle_flush(void *data EINA_UNUSED);
 static Eina_Bool _e_main_cb_bound(void *data, int type EINA_UNUSED, void *event);
+static Eina_Bool _e_main_cb_timer(void *data EINA_UNUSED);
+static void _e_main_modules_load(Eina_Bool safe_mode);
 
 /* local variables */
 static Eina_Bool really_know = EINA_FALSE;
 static Eina_Bool locked = EINA_FALSE;
 static Eina_Bool inloop = EINA_FALSE;
 static Eina_Bool bound = EINA_FALSE;
+static Eina_Bool safe_mode = EINA_FALSE;
 static jmp_buf wl_fatal_buff;
 static int _e_main_lvl = 0;
 static int (*_e_main_shutdown_func[MAX_LEVEL])(void);
@@ -75,7 +78,6 @@ int
 main(int argc, char **argv)
 {
    Eina_Bool nostartup = EINA_FALSE;
-   Eina_Bool safe_mode = EINA_FALSE;
    Eina_Bool after_restart = EINA_FALSE;
    Eina_Bool waslocked = EINA_FALSE;
    double t = 0.0, tstart = 0.0;
@@ -489,6 +491,33 @@ main(int argc, char **argv)
    e_container_all_freeze();
    TS("E_Container Freeze Done");
 
+   TS("E_Bg Init");
+   if (!e_bg_init())
+     {
+        e_error_message_show(_("Enlightenment cannot setup its background subsystem"));
+        _e_main_shutdown(-1);
+     }
+   TS("E_Bg Init Done");
+   _e_main_shutdown_push(e_bg_shutdown);
+
+   TS("E_Popup Init");
+   if (!e_popup_init())
+     {
+        e_error_message_show(_("Enlightenment cannot setup its popup subsystem"));
+        _e_main_shutdown(-1);
+     }
+   TS("E_Popup Init Done");
+   _e_main_shutdown_push(e_popup_shutdown);
+
+   TS("E_Shelf Init");
+   if (!e_shelf_init())
+     {
+        e_error_message_show(_("Enlightenment cannot setup its shelf subsystem"));
+        _e_main_shutdown(-1);
+     }
+   TS("E_Shelf Init Done");
+   _e_main_shutdown_push(e_shelf_shutdown);
+
    /* TODO: init other stuff */
 
    _idle_flush = ecore_idle_enterer_add(_e_main_cb_idle_flush, NULL);
@@ -497,6 +526,10 @@ main(int argc, char **argv)
    e_container_all_thaw();
    TS("E_Container Thaw Done");
 
+   TS("E_Shelf Config Update");
+   e_shelf_config_update();
+   TS("E_Shelf Config Update Done");
+
    _idle_after = ecore_idle_enterer_add(_e_main_cb_idle_after, NULL);
 
    /*** Main Loop ***/
@@ -504,6 +537,8 @@ main(int argc, char **argv)
    starting = EINA_FALSE;
    inloop = EINA_TRUE;
 
+   ecore_timer_add(0.25, _e_main_cb_timer, NULL);
+
    e_util_env_set("E_RESTART", "1");
 
    /* TODO: set callback for fatal wayland errors */
@@ -705,17 +740,17 @@ _e_main_parse_arguments(int argc, char **argv)
 static Eina_Bool
 _e_main_cb_signal_exit(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
 {
-   ecore_main_loop_quit();
+   /* ecore_main_loop_quit(); */
 
    /* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
-   /* e_sys_action_do(E_SYS_EXIT, NULL); */
+   e_sys_action_do(E_SYS_EXIT, NULL);
    return ECORE_CALLBACK_RENEW;
 }
 
 static Eina_Bool
 _e_main_cb_signal_hup(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev EINA_UNUSED)
 {
-   /* e_sys_action_do(E_SYS_RESTART, NULL); */
+   e_sys_action_do(E_SYS_RESTART, NULL);
    return ECORE_CALLBACK_RENEW;
 }
 
@@ -1007,9 +1042,16 @@ _e_main_screens_init(void)
    if (!e_container_init()) return 0;
 
    TS("\tScreens: zone");
+   if (!e_zone_init()) return 0;
+
    TS("\tScreens: desk");
+   if (!e_desk_init()) return 0;
+
    TS("\tScreens: menu");
-   /* TODO: exehist */
+   if (!e_menu_init()) return 0;
+
+   TS("\tScreens: exehist");
+   if (!e_exehist_init()) return 0;
 
    EINA_LIST_FOREACH(comp->outputs, l, output)
      {
@@ -1031,8 +1073,6 @@ _e_main_screens_init(void)
              return 0;
           }
 
-        e_container_show(con);
-
         i++;
      }
 
@@ -1042,9 +1082,10 @@ _e_main_screens_init(void)
 static int 
 _e_main_screens_shutdown(void)
 {
-   /* e_menu_shutdown(); */
-   /* e_desk_shutdown(); */
-   /* e_zone_shutdown(); */
+   e_exehist_shutdown();
+   e_menu_shutdown();
+   e_desk_shutdown();
+   e_zone_shutdown();
    e_container_shutdown();
    e_manager_shutdown();
    return 1;
@@ -1054,8 +1095,8 @@ static Eina_Bool
 _e_main_cb_idle_before(void *data EINA_UNUSED)
 {
    /* TODO: finish */
+   e_menu_idler_before();
    e_pointer_idler_before();
-
    edje_thaw();
 
    return ECORE_CALLBACK_RENEW;
@@ -1082,3 +1123,28 @@ _e_main_cb_bound(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_
    bound = EINA_TRUE;
    return ECORE_CALLBACK_CANCEL;
 }
+
+static Eina_Bool 
+_e_main_cb_timer(void *data EINA_UNUSED)
+{
+   E_Manager *man;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(e_manager_list(), l, man)
+     e_manager_show(man);
+
+   _e_main_modules_load(safe_mode);
+
+   return EINA_FALSE;
+}
+
+static void 
+_e_main_modules_load(Eina_Bool safe_mode)
+{
+   if (!safe_mode)
+     e_module_all_load();
+   else
+     {
+
+     }
+}
diff --git a/src/bin/e_wayland/e_menu.c b/src/bin/e_wayland/e_menu.c
new file mode 100644 (file)
index 0000000..ab6e18a
--- /dev/null
@@ -0,0 +1,1759 @@
+#include "e.h"
+
+typedef struct _E_Menu_Category E_Menu_Category;
+struct _E_Menu_Category
+{
+   void *data;
+   Eina_List *callbacks;
+};
+
+/* local function prototypes */
+static Eina_Bool _e_menu_categories_cb_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__);
+static void _e_menu_cb_free(E_Menu *m);
+static void _e_menu_cb_ee_resize(Ecore_Evas *ee);
+static void _e_menu_cb_container_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _e_menu_cb_container_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static Eina_Bool _e_menu_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+static void _e_menu_item_cb_free(E_Menu_Item *mi);
+static void _e_menu_item_cb_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _e_menu_item_cb_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _e_menu_item_cb_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
+static void _e_menu_item_cb_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
+static void _e_menu_item_cb_submenu_post(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi);
+
+static int _e_menu_auto_place(E_Menu *m, int x, int y, int w, int h);
+static void _e_menu_activate_internal(E_Menu *m, E_Zone *zone);
+static void _e_menu_realize(E_Menu *m);
+static void _e_menu_reposition(E_Menu *m);
+static void _e_menu_layout_update(E_Menu *m);
+static void _e_menu_unrealize(E_Menu *m);
+static void _e_menu_deactivate_above(E_Menu *m);
+static int _e_menu_active_call(void);
+static void _e_menu_deactivate_all(void);
+
+static void _e_menu_item_realize(E_Menu_Item *mi);
+static void _e_menu_item_unrealize(E_Menu_Item *mi);
+static Eina_Bool _e_menu_item_realize_call(E_Menu_Item *mi);
+static void _e_menu_item_submenu_activate(E_Menu_Item *mi);
+static void _e_menu_item_submenu_deactivate(E_Menu_Item *mi);
+
+/* local variables */
+static Eina_Hash *_categories = NULL;
+static Eina_List *_active_menus = NULL;
+static Eina_List *_handlers = NULL;
+static E_Menu_Item *_active_item = NULL;
+static int _menu_x = 0;
+static int _menu_y = 0;
+static unsigned int _menu_time = 0;
+
+EINTERN int 
+e_menu_init(void)
+{
+   /* TODO: Handlers */
+   _handlers = 
+     eina_list_append(_handlers, 
+                      ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
+                                              _e_menu_cb_mouse_move, NULL));
+   _handlers = 
+     eina_list_append(_handlers, 
+                      ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
+                                              _e_menu_cb_mouse_up, NULL));
+
+   _categories = eina_hash_string_superfast_new(NULL);
+
+   return 1;
+}
+
+EINTERN int 
+e_menu_shutdown(void)
+{
+   Ecore_Event_Handler *hdl;
+
+   EINA_LIST_FREE(_handlers, hdl)
+     ecore_event_handler_del(hdl);
+
+   if (!wl_fatal)
+     {
+        E_Menu *m;
+
+        EINA_LIST_FREE(_active_menus, m)
+          {
+             m->active = EINA_FALSE;
+             _e_menu_unrealize(m);
+             e_object_unref(E_OBJECT(m));
+          }
+     }
+
+   if (_categories)
+     {
+        eina_hash_foreach(_categories, _e_menu_categories_cb_free, NULL);
+        eina_hash_free(_categories);
+     }
+   _categories = NULL;
+
+   return 1;
+}
+
+EAPI E_Menu *
+e_menu_new(void)
+{
+   E_Menu *m;
+
+   m = E_OBJECT_ALLOC(E_Menu, E_MENU_TYPE, _e_menu_cb_free);
+   if (!m) return NULL;
+
+   m->cur.w = 1;
+   m->cur.h = 1;
+   m->category = NULL;
+
+   return m;
+}
+
+EAPI void 
+e_menu_activate_key(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+}
+
+EAPI void 
+e_menu_activate_mouse(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir, unsigned int activate_time)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   _e_menu_activate_internal(m, zone);
+
+   if (!m->zone)
+     {
+        e_menu_deactivate(m);
+        return;
+     }
+
+   switch (dir)
+     {
+      case E_MENU_POP_DIRECTION_LEFT:
+        break;
+      case E_MENU_POP_DIRECTION_RIGHT:
+        break;
+      case E_MENU_POP_DIRECTION_UP:
+        break;
+      case E_MENU_POP_DIRECTION_DOWN:
+        break;
+      case E_MENU_POP_DIRECTION_AUTO:
+        _e_menu_auto_place(m, x, y, w, h);
+        _e_menu_realize(m);
+        break;
+      default:
+        m->cur.x = x + w;
+        m->cur.y = y + h;
+        break;
+     }
+
+   if (!_active_item) return;
+   e_menu_item_active_set(_active_item, 0);
+}
+
+EAPI void 
+e_menu_activate(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+}
+
+EAPI void 
+e_menu_deactivate(E_Menu *m)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   m->cur.visible = EINA_FALSE;
+   m->active = EINA_FALSE;
+
+   if (m->post_deactivate_cb.func)
+     m->post_deactivate_cb.func(m->post_deactivate_cb.data, m);
+}
+
+EAPI int 
+e_menu_freeze(E_Menu *m)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   m->frozen++;
+
+   return m->frozen;
+}
+
+EAPI int 
+e_menu_thaw(E_Menu *m)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   m->frozen--;
+   if (m->frozen < 0) m->frozen = 0;
+
+   return m->frozen;
+}
+
+EAPI void 
+e_menu_title_set(E_Menu *m, char *title)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   if ((m->header.title) && (title) && (!strcmp(m->header.title, title)))
+     return;
+
+   eina_stringshare_replace(&m->header.title, title);
+   m->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_icon_file_set(E_Menu *m __UNUSED__, char *icon __UNUSED__)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+}
+
+EAPI void 
+e_menu_category_set(E_Menu *m, char *category)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   if ((m->category) && (category) && (!strcmp(m->category, category)))
+     return;
+
+   eina_stringshare_replace(&m->category, category);
+   m->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_category_data_set(char *category, void *data)
+{
+   E_Menu_Category *cat;
+
+   if ((cat = eina_hash_find(_categories, category)))
+     cat->data = data;
+   else
+     {
+        cat = calloc(1, sizeof(E_Menu_Category));
+        cat->data = data;
+        eina_hash_add(_categories, category, cat);
+     }
+}
+
+EAPI E_Menu_Category_Callback *
+e_menu_category_callback_add(char *category, void (*create) (E_Menu *m, void *category_data, void *data), void (free) (void *data), void *data)
+{
+   E_Menu_Category *cat;
+   E_Menu_Category_Callback *cb = NULL;
+
+   cat = eina_hash_find(_categories, category);
+   if (!cat)
+     {
+        cat = calloc(1, sizeof(E_Menu_Category));
+        eina_hash_add(_categories, category, cat);
+     }
+
+   if (cat)
+     {
+        if ((cb = calloc(1, sizeof(E_Menu_Category_Callback))))
+          {
+             cb->data = data;
+             cb->create = create;
+             cb->free = free;
+             cb->category = eina_stringshare_add(category);
+             cat->callbacks = eina_list_append(cat->callbacks, cb);
+          }
+     }
+
+   return cb;
+}
+
+EAPI void 
+e_menu_category_callback_del(E_Menu_Category_Callback *cb)
+{
+   if (cb)
+     {
+        E_Menu_Category *cat;
+
+        if ((cat = eina_hash_find(_categories, cb->category)))
+          cat->callbacks = eina_list_remove(cat->callbacks, cb);
+
+        eina_stringshare_del(cb->category);
+        free(cb);
+     }
+}
+
+EAPI void 
+e_menu_pre_activate_callback_set(E_Menu *m,  void (*func) (void *data, E_Menu *m), void *data)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   m->pre_activate_cb.func = func;
+   m->pre_activate_cb.data = data;
+}
+
+EAPI void 
+e_menu_post_deactivate_callback_set(E_Menu *m,  void (*func) (void *data, E_Menu *m), void *data)
+{
+   E_OBJECT_CHECK(m);
+   E_OBJECT_TYPE_CHECK(m, E_MENU_TYPE);
+
+   m->post_deactivate_cb.func = func;
+   m->post_deactivate_cb.data = data;
+}
+
+EAPI E_Menu *
+e_menu_root_get(E_Menu *m)
+{
+   E_Menu *ret;
+
+   E_OBJECT_CHECK_RETURN(m, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL);
+
+   ret = m;
+   while ((ret->parent_item) && (ret->parent_item->menu))
+     ret = ret->parent_item->menu;
+
+   return ret;
+}
+
+EAPI void 
+e_menu_idler_before(void)
+{
+   Eina_List *l;
+   E_Menu *m;
+
+   /* EINA_LIST_FOREACH(_active_menus, l, m) */
+   /*   { */
+   /*      if ((!m->cur.visible) && (m->prev.visible)) */
+   /*        { */
+   /*           m->prev.visible = m->cur.visible; */
+   /*           ecore_evas_hide(m->ee); */
+   /*        } */
+   /*   } */
+
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        if ((m->cur.visible) && (!m->prev.visible))
+          {
+             if (!m->realized) _e_menu_realize(m);
+             m->prev.visible = m->cur.visible;
+             ecore_evas_raise(m->ee);
+             ecore_evas_show(m->ee);
+          }
+     }
+
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        if (m->realized)
+          {
+             if ((m->cur.x != m->prev.x) || (m->cur.y != m->prev.y))
+               {
+                  m->prev.x = m->cur.x;
+                  m->prev.y = m->cur.y;
+                  ecore_evas_move(m->ee, m->cur.x, m->cur.y);
+               }
+             if ((m->cur.w != m->prev.w) || (m->cur.h != m->prev.h))
+               {
+                  m->prev.w = m->cur.w;
+                  m->prev.h = m->cur.h;
+                  ecore_evas_resize(m->ee, m->cur.w, m->cur.h);
+               }
+          }
+     }
+
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        if (!m->active)
+          {
+             _active_menus = eina_list_remove(_active_menus, m);
+             _e_menu_unrealize(m);
+             e_object_unref(E_OBJECT(m));
+          }
+     }
+
+}
+
+EAPI E_Menu_Item *
+e_menu_item_new(E_Menu *m)
+{
+   E_Menu_Item *mi;
+
+   E_OBJECT_CHECK_RETURN(m, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL);
+
+   mi = E_OBJECT_ALLOC(E_Menu_Item, E_MENU_ITEM_TYPE, _e_menu_item_cb_free);
+   if (!mi) return NULL;
+
+   mi->menu = m;
+   mi->menu->items = eina_list_append(mi->menu->items, mi);
+
+   return mi;
+}
+
+EAPI E_Menu_Item *
+e_menu_item_new_relative(E_Menu *m, E_Menu_Item *rel)
+{
+   E_Menu_Item *mi;
+
+   E_OBJECT_CHECK_RETURN(m, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL);
+
+   if (rel)
+     {
+        E_OBJECT_CHECK_RETURN(rel, NULL);
+        E_OBJECT_TYPE_CHECK_RETURN(rel, E_MENU_ITEM_TYPE, NULL);
+
+        if (rel->menu != m) return NULL;
+     }
+
+   mi = E_OBJECT_ALLOC(E_Menu_Item, E_MENU_ITEM_TYPE, _e_menu_item_cb_free);
+   if (!mi) return NULL;
+
+   mi->menu = m;
+
+   if (rel)
+     {
+        Eina_List *l;
+
+        l = eina_list_data_find_list(m->items, rel);
+        m->items = eina_list_append_relative_list(m->items, mi, l);
+     }
+   else
+     m->items = eina_list_prepend(m->items, mi);
+
+   return mi;
+}
+
+EAPI E_Menu_Item *
+e_menu_item_nth(E_Menu *m, int n)
+{
+   E_OBJECT_CHECK_RETURN(m, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(m, E_MENU_TYPE, NULL);
+
+   return (E_Menu_Item *)eina_list_nth(m->items, n);
+}
+
+EAPI int 
+e_menu_item_num_get(const E_Menu_Item *mi)
+{
+   const Eina_List *l;
+   const E_Menu_Item *mi2;
+   int i = 0;
+
+   E_OBJECT_CHECK_RETURN(mi, -1);
+   E_OBJECT_CHECK_RETURN(mi->menu, -1);
+   E_OBJECT_TYPE_CHECK_RETURN(mi, E_MENU_ITEM_TYPE, -1);
+
+   EINA_LIST_FOREACH(mi->menu->items, l, mi2)
+     {
+        if (mi2 == mi) return i;
+        i++;
+     }
+
+   return -1;
+}
+
+EAPI void 
+e_menu_item_icon_file_set(E_Menu_Item *mi, const char *icon)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if ((mi->icon) && (icon) && (!strcmp(mi->icon, icon)))
+     return;
+
+   eina_stringshare_replace(&mi->icon, icon);
+   if (mi->icon_key) eina_stringshare_del(mi->icon_key);
+
+   if (icon)
+     {
+        int len = 0;
+
+        len = strlen(icon);
+        if ((len > 4) && (!strcasecmp(icon + len - 4, ".edj")))
+          mi->icon_key = eina_stringshare_add("icon");
+     }
+
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_icon_edje_set(E_Menu_Item *mi, const char *icon, const char *key)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (((mi->icon) && (icon) && (!strcmp(mi->icon, icon))) || 
+       ((mi->icon_key) && (key) && (!strcmp(mi->icon_key, key))))
+     return;
+
+   eina_stringshare_replace(&mi->icon, icon);
+   eina_stringshare_replace(&mi->icon_key, key);
+
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_label_set(E_Menu_Item *mi, const char *label)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if ((mi->label) && (label) && (!strcmp(mi->label, label)))
+     return;
+
+   eina_stringshare_replace(&mi->label, label);
+
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->submenu) e_object_unref(E_OBJECT(mi->submenu));
+   if (sub) e_object_ref(E_OBJECT(sub));
+
+   mi->submenu = sub;
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_separator_set(E_Menu_Item *mi, int sep)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->separator == sep) return;
+
+   mi->separator = sep;
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_check_set(E_Menu_Item *mi, int chk)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->check == chk) return;
+
+   mi->check = chk;
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_radio_set(E_Menu_Item *mi, int rad)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->radio == rad) return;
+
+   mi->radio = rad;
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_radio_group_set(E_Menu_Item *mi, int radg)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->radio_group == radg) return;
+
+   mi->radio_group = radg;
+   mi->changed = EINA_TRUE;
+   mi->menu->changed = EINA_TRUE;
+}
+
+EAPI void 
+e_menu_item_toggle_set(E_Menu_Item *mi, int tog)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->separator) return;
+   if (mi->toggle == tog) return;
+   mi->toggle = tog;
+   if (tog)
+     {
+        if (mi->o_bg) 
+          edje_object_signal_emit(mi->o_bg, "e,state,on", "e");
+        if (mi->o_icon_bg)
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,on", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,on", "e");
+        if (mi->o_submenu)
+          edje_object_signal_emit(mi->o_submenu, "e,state,on", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,on", "e");
+        if (mi->menu->o_bg)
+          edje_object_signal_emit(mi->menu->o_bg, "e,state,on", "e");
+
+        if (mi->radio)
+          {
+             const Eina_List *l;
+             E_Menu_Item *mi2;
+
+             EINA_LIST_FOREACH(mi->menu->items, l, mi2)
+               {
+                  if ((mi2 != mi) && (mi2->radio) && 
+                      (mi2->radio_group == mi->radio_group))
+                    e_menu_item_toggle_set(mi2, 0);
+               }
+          }
+     }
+   else
+     {
+        if (mi->o_bg) 
+          edje_object_signal_emit(mi->o_bg, "e,state,off", "e");
+        if (mi->o_icon_bg)
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,off", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,off", "e");
+        if (mi->o_submenu)
+          edje_object_signal_emit(mi->o_submenu, "e,state,off", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,off", "e");
+        if (mi->menu->o_bg)
+          edje_object_signal_emit(mi->menu->o_bg, "e,state,off", "e");
+     }
+}
+
+EAPI int 
+e_menu_item_toggle_get(E_Menu_Item *mi)
+{
+   E_OBJECT_CHECK_RETURN(mi, 0);
+   E_OBJECT_TYPE_CHECK_RETURN(mi, E_MENU_ITEM_TYPE, 0);
+
+   return mi->toggle;
+}
+
+EAPI void 
+e_menu_item_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   mi->cb.func = func;
+   mi->cb.data = data;
+}
+
+EAPI void 
+e_menu_item_realize_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   mi->realize_cb.func = func;
+   mi->realize_cb.data = data;
+}
+
+EAPI void 
+e_menu_item_submenu_pre_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   mi->submenu_pre_cb.func = func;
+   mi->submenu_pre_cb.data = data;
+
+   if (!mi->submenu_post_cb.func)
+     mi->submenu_post_cb.func = _e_menu_item_cb_submenu_post;
+}
+
+EAPI void 
+e_menu_item_submenu_post_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   mi->submenu_post_cb.func = func;
+   mi->submenu_post_cb.data = data;
+}
+
+EAPI void 
+e_menu_item_drag_callback_set(E_Menu_Item *mi __UNUSED__,  E_Menu_Cb func __UNUSED__, void *data __UNUSED__)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+}
+
+EAPI void 
+e_menu_item_active_set(E_Menu_Item *mi, int active)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->separator) return;
+   if ((active) && (!mi->active))
+     {
+        E_Menu_Item *pmi;
+
+        if (mi->disabled) return;
+        pmi = _active_item;
+        if (mi == pmi) return;
+        if (pmi) e_menu_item_active_set(pmi, 0);
+        mi->active = EINA_TRUE;
+        _active_item = mi;
+        if (mi->o_bg)
+          edje_object_signal_emit(mi->o_bg, "e,state,selected", "e");
+        if (mi->o_icon_bg)
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,selected", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,selected", "e");
+        if (mi->o_submenu)
+          edje_object_signal_emit(mi->o_submenu, "e,state,selected", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,selected", "e");
+        if (mi->icon_key)
+          {
+             if (mi->o_icon)
+               {
+                  if (strcmp(evas_object_type_get(mi->o_icon), "e_icon"))
+                    edje_object_signal_emit(mi->o_icon, "e,state,selected", "e");
+                  else
+                    e_icon_selected_set(mi->o_icon, EINA_TRUE);
+               }
+          }
+        edje_object_signal_emit(mi->menu->o_bg, "e,state,selected", "e");
+       _e_menu_item_submenu_activate(mi);
+     }
+   else if ((!active) && (mi->active))
+     {
+        mi->active = EINA_FALSE;
+        _active_item = NULL;
+        if (mi->o_bg)
+          edje_object_signal_emit(mi->o_bg, "e,state,unselected", "e");
+        if (mi->o_icon_bg)
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,unselected", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,unselected", "e");
+        if (mi->o_submenu)
+          edje_object_signal_emit(mi->o_submenu, "e,state,unselected", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,unselected", "e");
+        if (mi->icon_key)
+          {
+             if (mi->o_icon)
+               {
+                  if (strcmp(evas_object_type_get(mi->o_icon), "e_icon"))
+                    edje_object_signal_emit(mi->o_icon, "e,state,unselected", "e");
+                  else
+                    e_icon_selected_set(mi->o_icon, EINA_FALSE);
+               }
+          }
+        edje_object_signal_emit(mi->menu->o_bg, "e,state,unselected", "e");
+       _e_menu_item_submenu_deactivate(mi);
+     }
+}
+
+EAPI void 
+e_menu_item_disabled_set(E_Menu_Item *mi, int disable)
+{
+   E_OBJECT_CHECK(mi);
+   E_OBJECT_TYPE_CHECK(mi, E_MENU_ITEM_TYPE);
+
+   if (mi->separator) return;
+   if (disable)
+     {
+        if (mi->active) e_menu_item_active_set(mi, 0);
+        mi->disabled = EINA_TRUE;
+        if (mi->o_icon_bg) 
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,disable", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,disable", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,disable", "e");
+     }
+   else
+     {
+        mi->disabled = EINA_FALSE;
+        if (mi->o_icon_bg) 
+          edje_object_signal_emit(mi->o_icon_bg, "e,state,enable", "e");
+        if (mi->o_lbl)
+          edje_object_signal_emit(mi->o_lbl, "e,state,enable", "e");
+        if (mi->o_toggle)
+          edje_object_signal_emit(mi->o_toggle, "e,state,enable", "e");
+     }
+}
+
+/* local functions */
+static Eina_Bool 
+_e_menu_categories_cb_free(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
+{
+   E_Menu_Category_Callback *cb;
+   E_Menu_Category *cat;
+
+   cat = (E_Menu_Category *)data;
+
+   EINA_LIST_FREE(cat->callbacks, cb)
+     free(cb);
+
+   free(cat);
+
+   return EINA_TRUE;
+}
+
+static void 
+_e_menu_cb_free(E_Menu *m)
+{
+   Eina_List *l, *ll;
+   E_Menu_Item *mi;
+
+   if (m->category) 
+     {
+        E_Menu_Category *cat = NULL;
+
+        if ((cat = eina_hash_find(_categories, m->category)))
+          {
+             E_Menu_Category_Callback *cb;
+
+             EINA_LIST_FOREACH(cat->callbacks, l, cb)
+               if (cb->free) cb->free(cb->data);
+          }
+     }
+
+   _e_menu_unrealize(m);
+
+   EINA_LIST_FOREACH_SAFE(m->items, l, ll, mi)
+     e_object_del(E_OBJECT(mi));
+
+   _active_menus = eina_list_remove(_active_menus, m);
+   e_object_unref(E_OBJECT(m));
+
+   if (m->header.title) eina_stringshare_del(m->header.title);
+   if (m->header.icon_file) eina_stringshare_del(m->header.icon_file);
+
+   E_FREE(m);
+}
+
+static void 
+_e_menu_cb_ee_resize(Ecore_Evas *ee)
+{
+   Evas *evas;
+   Evas_Object *o;
+   Evas_Coord w, h;
+
+   evas = ecore_evas_get(ee);
+   evas_output_viewport_get(evas, NULL, NULL, &w, &h);
+   o = evas_object_name_find(evas, "menu/background");
+   evas_object_resize(o, w, h);
+}
+
+static void 
+_e_menu_cb_container_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Menu *m;
+
+   if (!(m = data)) return;
+   m->cx = x;
+   m->cy = y;
+   if (m->parent_item) _e_menu_reposition(m);
+   evas_object_move(obj, x, y);
+}
+
+static void 
+_e_menu_cb_container_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   E_Menu *m;
+
+   if (!(m = data)) return;
+   m->cw = w;
+   m->ch = h;
+   if (m->parent_item) _e_menu_reposition(m);
+   evas_object_resize(obj, w, h);
+}
+
+static Eina_Bool 
+_e_menu_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Event_Mouse_Move *ev;
+   Eina_List *l;
+   E_Menu *m;
+   int dx, dy, d;
+   double dt, fast_move_threshold;
+   Eina_Bool is_fast = EINA_FALSE;
+   Eina_Bool event_sent = EINA_FALSE;
+
+   ev = event;
+
+   fast_move_threshold = e_config->menus_fast_mouse_move_threshhold;
+   dx = ev->x - _menu_x;
+   dy = ev->y - _menu_y;
+   d = (dx * dy) + (dy * dy);
+   dt = (double)(ev->timestamp - _menu_time) / 1000.0;
+   dt = dt * dt;
+   if ((dt > 0.0) && ((d / dt) >= (fast_move_threshold * fast_move_threshold)))
+     is_fast = EINA_TRUE;
+
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        if ((m->realized) && (m->cur.visible))
+          {
+             if (ev->event_window == m->id)
+               {
+                  int x = 0, y = 0;
+
+                  if (is_fast)
+                    m->fast_mouse = EINA_TRUE;
+                  else if (dt > 0.0)
+                    {
+                       m->fast_mouse = EINA_FALSE;
+                       if (m->pending_new_submenu)
+                         {
+                            if (_active_item)
+                              _e_menu_item_submenu_deactivate(_active_item);
+                         }
+                    }
+
+                  x = ev->x - m->cur.x + m->zone->x;
+                  y = ev->y - m->cur.y + m->zone->y;
+
+                  if (ev->x < m->cur.x)
+                    x = m->cur.x - ev->x + m->zone->x;
+
+                  printf("Menu Position: %d %d\n", m->cur.x, m->cur.y);
+                  printf("Feeding Mouse Move On Menu: %d: %d %d\n", 
+                         m->id, x, y);
+                  evas_event_feed_mouse_move(m->evas, x, y, ev->timestamp, NULL);
+                  event_sent = EINA_TRUE;
+               }
+          }
+     }
+
+   _menu_x = ev->x;
+   _menu_y = ev->y;
+   _menu_time = ev->timestamp;
+
+   if (event_sent) return ECORE_CALLBACK_DONE;
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_e_menu_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Event_Mouse_Button *ev;
+   int ret = 0;
+   unsigned int t;
+
+   ev = event;
+   t = ev->timestamp - _menu_time;
+   if ((_menu_time != 0) && 
+       (t < (e_config->menus_click_drag_timeout * 1000)))
+     {
+        return ECORE_CALLBACK_PASS_ON;
+     }
+
+   ret = _e_menu_active_call();
+   if ((ret == 1) || (ret == -1))
+     _e_menu_deactivate_all();
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void 
+_e_menu_item_cb_free(E_Menu_Item *mi)
+{
+   if (mi == _active_item) _active_item = NULL;
+   if (mi->submenu)
+     {
+        mi->submenu->parent_item = NULL;
+        e_object_unref(E_OBJECT(mi->submenu));
+     }
+
+   if (mi->menu->realized) _e_menu_item_unrealize(mi);
+
+   mi->menu->items = eina_list_remove(mi->menu->items, mi);
+
+   if (mi->icon) eina_stringshare_del(mi->icon);
+   if (mi->icon_key) eina_stringshare_del(mi->icon_key);
+   if (mi->label) eina_stringshare_del(mi->label);
+
+   E_FREE(mi);
+}
+
+static void 
+_e_menu_item_cb_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+   E_Menu_Item *mi;
+
+   if (!(mi = data)) return;
+   mi->x = x;
+   mi->y = y;
+   evas_object_move(mi->o_event, x, y);
+   evas_object_move(obj, x, y);
+   if ((mi->submenu) && (mi->submenu->parent_item))
+     _e_menu_reposition(mi->submenu);
+}
+
+static void 
+_e_menu_item_cb_resize(void *data, Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+   E_Menu_Item *mi;
+
+   if (!(mi = data)) return;
+   mi->w = w;
+   mi->h = h;
+   evas_object_resize(mi->o_event, w, h);
+   evas_object_resize(obj, w, h);
+   if ((mi->submenu) && (mi->submenu->parent_item))
+     _e_menu_reposition(mi->submenu);
+}
+
+static void 
+_e_menu_item_cb_in(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
+{
+   E_Menu_Item *mi;
+
+   if (!(mi = data)) return;
+   printf("Menu Item Mouse In\n");
+   e_menu_item_active_set(mi, 1);
+}
+
+static void 
+_e_menu_item_cb_out(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
+{
+   E_Menu_Item *mi;
+
+   if (!(mi = data)) return;
+   printf("Menu Item Mouse Out\n");
+   e_menu_item_active_set(mi, 0);
+}
+
+static void 
+_e_menu_item_cb_submenu_post(void *data __UNUSED__, E_Menu *m __UNUSED__, E_Menu_Item *mi)
+{
+   E_Menu *sm;
+
+   if (!mi->submenu) return;
+   sm = mi->submenu;
+   e_menu_item_submenu_set(mi, NULL);
+   e_object_del(E_OBJECT(sm));
+}
+
+static int 
+_e_menu_auto_place(E_Menu *m, int x, int y, int w, int h)
+{
+   m->cur.x = x;
+   m->cur.y = y;
+   m->cur.w = w;
+   m->cur.h = h;
+   return 0;
+}
+
+static void 
+_e_menu_activate_internal(E_Menu *m, E_Zone *zone)
+{
+   m->zone = zone;
+   m->fast_mouse = EINA_FALSE;
+   m->pending_new_submenu = EINA_FALSE;
+
+   if (m->pre_activate_cb.func)
+     m->pre_activate_cb.func(m->pre_activate_cb.data, m);
+
+   if (!m->active)
+     {
+        _active_menus = eina_list_append(_active_menus, m);
+        m->active = EINA_TRUE;
+        e_object_ref(E_OBJECT(m));
+     }
+
+   if (m->category)
+     {
+        E_Menu_Category *cat = NULL;
+
+        if ((cat = eina_hash_find(_categories, m->category)))
+          {
+             Eina_List *l;
+             E_Menu_Category_Callback *cb;
+
+             EINA_LIST_FOREACH(cat->callbacks, l, cb)
+               if (cb->create) cb->create(m, cat->data, cb->data);
+          }
+     }
+   m->cur.visible = EINA_TRUE;
+}
+
+static void 
+_e_menu_realize(E_Menu *m)
+{
+   Ecore_Wl_Window *win = NULL;
+   unsigned int parent = 0;
+   Eina_List *l;
+   E_Menu_Item *mi;
+   int x, y;
+
+   if (m->realized) return;
+
+   if (!m->zone) return;
+   if (!m->zone->container) return;
+   if (!m->zone->container->bg_ee) return;
+
+   m->realized = EINA_TRUE;
+
+   x = m->cur.x;
+   y = m->cur.y;
+   if (m->parent_item)
+     {
+        E_Menu *pm;
+
+        pm = m->parent_item->menu;
+        x = pm->cur.x + pm->cur.w;
+        y = pm->cur.y + m->parent_item->y;
+        /* if ((win = ecore_evas_wayland_window_get(pm->ee))) */
+        /*   parent = win->id; */
+     }
+   /* else */
+   /*   { */
+        if ((win = ecore_evas_wayland_window_get(m->zone->container->bg_ee)))
+          parent = win->id;
+     /* } */
+
+   m->ee = 
+     e_canvas_new(parent, x, y, m->cur.w, m->cur.h, 
+                  EINA_TRUE, EINA_FALSE, NULL);
+   e_canvas_add(m->ee);
+
+   m->id = ecore_evas_wayland_window_get(m->ee)->id;
+   printf("Menu Id: %d\n", m->id);
+
+   ecore_evas_name_class_set(m->ee, "E", "_e_menu_window");
+   ecore_evas_title_set(m->ee, "E Menu");
+   ecore_evas_wayland_type_set(m->ee, ECORE_WL_WINDOW_TYPE_MENU);
+   ecore_evas_callback_resize_set(m->ee, _e_menu_cb_ee_resize);
+
+   m->evas = ecore_evas_get(m->ee);
+
+   evas_event_freeze(m->evas);
+
+   m->o_bg = edje_object_add(m->evas);
+   evas_object_name_set(m->o_bg, "menu/background");
+   evas_object_data_set(m->o_bg, "e_menu", m);
+   evas_object_move(m->o_bg, 0, 0);
+   evas_object_resize(m->o_bg, m->cur.w, m->cur.h);
+   if ((e_theme_edje_object_set(m->o_bg, "base/theme/menus", 
+                                "e/widgets/menu/default/background")))
+     {
+        const char *shaped;
+
+        if ((shaped = edje_object_data_get(m->o_bg, "shaped")))
+          if (!strcmp(shaped, "1")) 
+            m->shaped = EINA_TRUE;
+
+        ecore_evas_alpha_set(m->ee, m->shaped);
+     }
+   if (m->header.title)
+     {
+        edje_object_part_text_set(m->o_bg, "e.text.title", m->header.title);
+        edje_object_signal_emit(m->o_bg, "e,action,show,title", "e");
+        edje_object_message_signal_process(m->o_bg);
+     }
+   evas_object_show(m->o_bg);
+
+   m->o_con = e_box_add(m->evas);
+   evas_object_intercept_move_callback_add(m->o_con, 
+                                           _e_menu_cb_container_move, m);
+   evas_object_intercept_resize_callback_add(m->o_con, 
+                                             _e_menu_cb_container_resize, m);
+   e_box_freeze(m->o_con);
+   evas_object_show(m->o_con);
+   e_box_homogenous_set(m->o_con, 0);
+   edje_object_part_swallow(m->o_bg, "e.swallow.content", m->o_con);
+
+   EINA_LIST_FOREACH(m->items, l, mi)
+     _e_menu_item_realize(mi);
+
+   _e_menu_layout_update(m);
+
+   e_box_thaw(m->o_con);
+
+   evas_object_resize(m->o_bg, m->cur.w, m->cur.h);
+   evas_event_thaw(m->evas);
+}
+
+static void 
+_e_menu_reposition(E_Menu *m)
+{
+   Eina_List *l;
+   E_Menu_Item *mi;
+   int bottom = 0;
+
+   if (!m->parent_item) return;
+//   if ((!m->parent_item) || (!m->parent_item->menu)) return;
+   m->cur.x = m->parent_item->menu->cur.x + m->parent_item->menu->cur.w;
+   bottom = m->parent_item->menu->cur.y + m->parent_item->y;
+   if (m->cur.h > m->zone->h)
+     {
+        if (bottom > (m->zone->h / 2))
+          m->cur.y = (bottom - (m->ch + 1));
+        else
+          m->cur.y = bottom - m->cy;
+     }
+   else
+     {
+        if (((bottom + m->cur.h - m->cy) > m->zone->h) && 
+            (bottom > (m->zone->h / 2)))
+          m->cur.y = (bottom - (m->ch + 1)) + m->parent_item->h;
+        else
+          m->cur.y = bottom - m->cy;
+     }
+
+   printf("Menu Reposition: %d: %d %d\n", m->id, m->cur.x, m->cur.y);
+
+   EINA_LIST_FOREACH(m->items, l, mi)
+     if ((mi->active) && (mi->submenu))
+       _e_menu_reposition(mi->submenu);
+}
+
+static void 
+_e_menu_layout_update(E_Menu *m)
+{
+   Eina_List *l;
+   E_Menu_Item *mi;
+   Eina_Bool icons = EINA_FALSE;
+   Eina_Bool labels = EINA_FALSE;
+   Eina_Bool submenus = EINA_FALSE;
+   Eina_Bool toggles = EINA_FALSE;
+   Evas_Coord mw = 0, mh = 0, bw = 0, bh = 0;
+   int miw = 0, mih = 0;
+   int mlw = 0, mlh = 0;
+   int msw = 0, msh = 0;
+   int mtw = 0, mth = 0;
+
+   e_box_freeze(m->o_con);
+   EINA_LIST_FOREACH(m->items, l, mi)
+     {
+        if ((mi->icon) || (mi->o_icon)) icons = EINA_TRUE;
+        if (mi->label) labels = EINA_TRUE;
+        if (mi->submenu) submenus = EINA_TRUE;
+        if ((mi->check) || (mi->radio)) toggles = EINA_TRUE;
+
+        if (mi->iw > miw) miw = mi->iw;
+        if (mi->ih > mih) mih = mi->ih;
+        if (mi->lw > mlw) mlw = mi->lw;
+        if (mi->lh > mlh) mlh = mi->lh;
+        if (mi->subw > msw) msw = mi->subw;
+        if (mi->subh > msh) msh = mi->subh;
+        if (mi->tw > mtw) mtw = mi->tw;
+        if (mi->th > mth) mth = mi->th;
+     }
+
+   if (labels)
+     {
+        if (submenus)
+          {
+             if (mlh < msh) mlh = msh;
+          }
+        if (toggles)
+          {
+             if (mlh < mth) mlh = mth;
+          }
+        if ((icons) && (mih > 0))
+          {
+             miw = (miw * mlh) / mih;
+             miw = mlh;
+          }
+        mw = (mlw + miw + msw + mtw);
+        mh = mlh;
+     }
+   else if (icons)
+     {
+        if (submenus)
+          {
+             if (mih < msh) mih = msh;
+          }
+        if (toggles)
+          {
+             if (mih < mth) mih = mth;
+          }
+        mw = (miw + mtw + msw);
+        mh = mih;
+     }
+   else if (toggles)
+     {
+        if (submenus)
+          {
+             if (mth < msh) mth = msh;
+          }
+        mw = (mtw + msw);
+        mh = mth;
+     }
+
+   EINA_LIST_FOREACH(m->items, l, mi)
+     {
+        if (mi->separator)
+          e_box_pack_options_set(mi->o_separator, 1, 1, 1, 0, 0.5, 0.5, 
+                                 mi->sepw, mi->seph, -1, mi->seph);
+        else
+          {
+             e_box_freeze(mi->o_con);
+
+             if (toggles)
+               e_box_pack_options_set(mi->o_toggle, 1, 1, 0, 1, 0.5, 0.5, 
+                                      mtw, mth, -1, -1);
+             else
+               e_box_pack_options_set(mi->o_toggle, 1, 1, 0, 0, 0.5, 0.5, 
+                                      0, 0, 0, 0);
+
+             if (icons)
+               {
+                  if (mi->o_icon_bg)
+                    e_box_pack_options_set(mi->o_icon_bg, 1, 1, 0, 1, 0.5, 0.5,
+                                           miw, mih, -1, -1);
+                  else
+                    e_box_pack_options_set(mi->o_icon, 1, 1, 0, 1, 0.5, 0.5, 
+                                           miw, mih, -1, -1);
+               }
+             else
+               e_box_pack_options_set(mi->o_icon, 1, 1, 0, 1, 0.5, 0.5, 
+                                      0, 0, 0, 0);
+
+             if (labels)
+               e_box_pack_options_set(mi->o_lbl, 1, 1, 0, 1, 0.5, 0.5, 
+                                      mlw, mlh, -1, -1);
+             else
+               e_box_pack_options_set(mi->o_lbl, 1, 1, 0, 0, 0.5, 0.5, 
+                                      0, 0, 0, 0);
+
+             if (submenus)
+               e_box_pack_options_set(mi->o_submenu, 1, 1, 0, 1, 0.5, 0.5,
+                                      msw, msh, -1, -1);
+             else
+               e_box_pack_options_set(mi->o_submenu, 1, 1, 0, 0, 0.5, 0.5, 
+                                      0, 0, 0, 0);
+
+             edje_extern_object_min_size_set(mi->o_con, mw, mh);
+             edje_object_part_swallow(mi->o_bg, "e.swallow.content", mi->o_con);
+             edje_object_size_min_calc(mi->o_bg, &mw, &mh);
+             e_box_pack_options_set(mi->o_bg, 1, 1, 1, 0, 0.5, 0.5, 
+                                    mw, mh, -1, -1);
+
+             e_box_thaw(mi->o_con);
+          }
+     }
+
+   e_box_size_min_get(m->o_con, &bw, &bh);
+   edje_extern_object_min_size_set(m->o_con, bw, bh);
+   edje_extern_object_max_size_set(m->o_con, bw, bh);
+   edje_object_part_swallow(m->o_bg, "e.swallow.content", m->o_con);
+   edje_object_size_min_calc(m->o_bg, &mw, &mh);
+   e_box_thaw(m->o_con);
+
+   m->cur.w = mw;
+   m->cur.h = mh;
+}
+
+static void 
+_e_menu_unrealize(E_Menu *m)
+{
+   Eina_List *l;
+   E_Menu_Item *mi;
+
+   if (!m->realized) return;
+
+   evas_event_freeze(m->evas);
+
+   e_box_freeze(m->o_con);
+   EINA_LIST_FOREACH(m->items, l, mi)
+     _e_menu_item_unrealize(mi);
+   e_box_thaw(m->o_con);
+
+   if (m->header.icon) evas_object_del(m->header.icon);
+   m->header.icon = NULL;
+   if (m->o_bg) evas_object_del(m->o_bg);
+   m->o_bg = NULL;
+   if (m->o_con) evas_object_del(m->o_con);
+   m->o_con = NULL;
+
+   evas_event_thaw(m->evas);
+
+   e_canvas_del(m->ee);
+   ecore_evas_free(m->ee);
+
+   m->ee = NULL;
+   m->evas = NULL;
+   m->cur.visible = EINA_FALSE;
+   m->prev.visible = EINA_FALSE;
+   m->realized = EINA_FALSE;
+   m->zone = NULL;
+}
+
+static void 
+_e_menu_deactivate_above(E_Menu *m)
+{
+   Eina_List *l;
+   E_Menu *pm;
+   Eina_Bool above = EINA_FALSE;
+
+   EINA_LIST_FOREACH(_active_menus, l, pm)
+     {
+        if (above)
+          {
+             e_menu_deactivate(pm);
+             pm->parent_item = NULL;
+          }
+        if (m == pm) above = EINA_TRUE;
+//        e_object_unref(E_OBJECT(pm));
+     }
+}
+
+static int 
+_e_menu_active_call(void)
+{
+   E_Menu_Item *mi;
+
+   mi = _active_item;
+   if (mi)
+     {
+        if (mi->submenu) return 0;
+
+        if (mi->check)
+          e_menu_item_toggle_set(mi, !mi->toggle);
+        if ((mi->radio) && (!e_menu_item_toggle_get(mi)))
+          e_menu_item_toggle_set(mi, 1);
+        if (mi->cb.func)
+          mi->cb.func(mi->cb.data, mi->menu, mi);
+
+        return 1;
+     }
+
+   return -1;
+}
+
+static void 
+_e_menu_deactivate_all(void)
+{
+   Eina_List *l;
+   E_Menu *m;
+
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        e_menu_deactivate(m);
+        m->parent_item = NULL;
+     }
+}
+
+static void 
+_e_menu_item_realize(E_Menu_Item *mi)
+{
+   Evas *evas;
+
+   evas = mi->menu->evas;
+   if (mi->separator)
+     {
+        mi->o_separator = edje_object_add(evas);
+        e_theme_edje_object_set(mi->o_separator, "base/theme/menus", 
+                                "e/widgets/menu/default/separator");
+        evas_object_show(mi->o_separator);
+        edje_object_size_min_calc(mi->o_separator, &mi->sepw, &mi->seph);
+        e_box_pack_end(mi->menu->o_con, mi->o_separator);
+     }
+   else
+     {
+        mi->o_bg = edje_object_add(evas);
+        evas_object_intercept_move_callback_add(mi->o_bg, 
+                                                _e_menu_item_cb_move, mi);
+        evas_object_intercept_resize_callback_add(mi->o_bg, 
+                                                  _e_menu_item_cb_resize, mi);
+        if ((mi->submenu) || (mi->submenu_pre_cb.func))
+          {
+             if (!e_theme_edje_object_set(mi->o_bg, "base/theme/menus", 
+                                          "e/widgets/menu/default/submenu_bg"))
+               e_theme_edje_object_set(mi->o_bg, "base/theme/menus", 
+                                       "e/widgets/menu/default/item_bg");
+          }
+        else
+          e_theme_edje_object_set(mi->o_bg, "base/theme/menus", 
+                                  "e/widgets/menu/default/item_bg");
+        evas_object_show(mi->o_bg);
+
+        mi->o_con = e_box_add(evas);
+        e_box_homogenous_set(mi->o_con, 0);
+        e_box_orientation_set(mi->o_con, 1);
+        evas_object_show(mi->o_con);
+
+        e_box_freeze(mi->o_con);
+
+        if (mi->check)
+          {
+             mi->o_toggle = edje_object_add(evas);
+             e_theme_edje_object_set(mi->o_toggle, "base/theme/menus", 
+                                     "e/widgets/menu/default/check");
+             evas_object_pass_events_set(mi->o_toggle, 1);
+             evas_object_show(mi->o_toggle);
+             e_box_pack_end(mi->o_con, mi->o_toggle);
+             edje_object_size_min_calc(mi->o_toggle, &mi->tw, &mi->th);
+          }
+        else if (mi->radio)
+          {
+             mi->o_toggle = edje_object_add(evas);
+             e_theme_edje_object_set(mi->o_toggle, "base/theme/menus", 
+                                     "e/widgets/menu/default/radio");
+             evas_object_pass_events_set(mi->o_toggle, 1);
+             evas_object_show(mi->o_toggle);
+             e_box_pack_end(mi->o_con, mi->o_toggle);
+             edje_object_size_min_calc(mi->o_toggle, &mi->tw, &mi->th);
+          }
+        else
+          {
+             mi->o_toggle = evas_object_rectangle_add(evas);
+             evas_object_color_set(mi->o_toggle, 0, 0, 0, 0);
+             evas_object_pass_events_set(mi->o_toggle, 1);
+             e_box_pack_end(mi->o_con, mi->o_toggle);
+          }
+
+        if ((mi->icon) || (mi->realize_cb.func))
+          {
+             int icon_w = 0, icon_h = 0;
+
+             mi->o_icon_bg = edje_object_add(evas);
+             if (e_theme_edje_object_set(mi->o_icon_bg, "base/theme/menus", 
+                                         "e/widgets/menu/default/icon"))
+               evas_object_show(mi->o_icon_bg);
+             else
+               {
+                  evas_object_del(mi->o_icon_bg);
+                  mi->o_icon_bg = NULL;
+               }
+
+             if (mi->icon)
+               {
+                  if (mi->icon_key)
+                    {
+                       Evas_Coord iww, ihh;
+
+                       mi->o_icon = edje_object_add(evas);
+                       if (edje_object_file_set(mi->o_icon, mi->icon, 
+                                                mi->icon_key))
+                         {
+                            edje_object_size_max_get(mi->o_icon, &iww, &ihh);
+                            icon_w = iww;
+                            icon_h = ihh;
+                         }
+                       else
+                         {
+                            evas_object_del(mi->o_icon);
+                            mi->o_icon = NULL;
+                         }
+                    }
+
+                  if (!mi->o_icon)
+                    {
+                       mi->o_icon = e_icon_add(evas);
+                       e_icon_scale_size_set(mi->o_icon, 
+                                             e_util_icon_size_normalize(24 * e_scale));
+                       e_icon_preload_set(mi->o_icon, 1);
+                       e_icon_file_set(mi->o_icon, mi->icon);
+                       e_icon_fill_inside_set(mi->o_icon, 1);
+                       e_icon_size_get(mi->o_icon, &icon_w, &icon_h);
+                    }
+               }
+
+             if (_e_menu_item_realize_call(mi))
+               {
+                  e_icon_fill_inside_set(mi->o_icon, 1);
+                  e_icon_size_get(mi->o_icon, &icon_w, &icon_h);
+               }
+
+             evas_object_pass_events_set(mi->o_icon, 1);
+             evas_object_show(mi->o_icon);
+
+             if (mi->o_icon_bg)
+               {
+                  edje_extern_object_min_size_set(mi->o_icon, icon_w, icon_h);
+                  edje_object_part_swallow(mi->o_icon_bg, "e.swallow.content",
+                                           mi->o_icon);
+                  edje_object_size_min_calc(mi->o_icon_bg, &mi->iw, &mi->ih);
+
+                  edje_extern_object_min_size_set(mi->o_icon, 0, 0);
+                  edje_object_part_swallow(mi->o_icon_bg, "e.swallow.content", 
+                                           mi->o_icon);
+                  e_box_pack_end(mi->o_con, mi->o_icon_bg);
+               }
+             else
+               {
+                  Evas_Object  *o;
+
+                  o = edje_object_add(evas);
+                  e_icon_size_get(mi->o_icon, &mi->iw, &mi->ih);
+                  e_box_pack_end(mi->o_con, o);
+               }
+          }
+        else
+          {
+             mi->o_icon = evas_object_rectangle_add(evas);
+             evas_object_color_set(mi->o_icon, 0, 0, 0, 0);
+             evas_object_pass_events_set(mi->o_icon, 1);
+             e_box_pack_end(mi->o_con, mi->o_icon);
+          }
+
+        if (mi->label)
+          {
+             mi->o_lbl = edje_object_add(evas);
+             e_theme_edje_object_set(mi->o_lbl, "base/theme/menus", 
+                                     "e/widgets/menu/default/label");
+             edje_object_part_text_set(mi->o_lbl, "e.text.label", mi->label);
+             evas_object_pass_events_set(mi->o_lbl, 1);
+             evas_object_show(mi->o_lbl);
+             e_box_pack_end(mi->o_con, mi->o_lbl);
+             edje_object_size_min_calc(mi->o_lbl, &mi->lw, &mi->lh);
+          }
+        else
+          {
+             mi->o_lbl = evas_object_rectangle_add(evas);
+             evas_object_color_set(mi->o_lbl, 0, 0, 0, 0);
+             evas_object_pass_events_set(mi->o_lbl, 1);
+             e_box_pack_end(mi->o_con, mi->o_lbl);
+          }
+
+        if ((mi->submenu) || (mi->submenu_pre_cb.func))
+          {
+             mi->o_submenu = edje_object_add(evas);
+             e_theme_edje_object_set(mi->o_submenu, "base/theme/menus", 
+                                     "e/widgets/menu/default/submenu");
+             evas_object_pass_events_set(mi->o_submenu, 1);
+             evas_object_show(mi->o_submenu);
+             e_box_pack_end(mi->o_con, mi->o_submenu);
+             edje_object_size_min_calc(mi->o_submenu, &mi->subw, &mi->subh);
+          }
+        else
+          {
+             mi->o_submenu = evas_object_rectangle_add(evas);
+             evas_object_color_set(mi->o_submenu, 0, 0, 0, 0);
+             evas_object_pass_events_set(mi->o_submenu, 1);
+             e_box_pack_end(mi->o_con, mi->o_submenu);
+          }
+
+        edje_object_part_swallow(mi->o_bg, "e.swallow.content", mi->o_con);
+
+        mi->o_event = evas_object_rectangle_add(evas);
+        evas_object_color_set(mi->o_event, 0, 0, 0, 0);
+        evas_object_layer_set(mi->o_event, 1);
+        evas_object_repeat_events_set(mi->o_event, 1);
+        evas_object_event_callback_add(mi->o_event, EVAS_CALLBACK_MOUSE_IN, 
+                                       _e_menu_item_cb_in, mi);
+        evas_object_event_callback_add(mi->o_event, EVAS_CALLBACK_MOUSE_OUT, 
+                                       _e_menu_item_cb_out, mi);
+        evas_object_show(mi->o_event);
+
+        e_box_thaw(mi->o_con);
+        e_box_pack_end(mi->menu->o_con, mi->o_bg);
+     }
+   if (mi->active) e_menu_item_active_set(mi, 1);
+   if (mi->toggle) e_menu_item_toggle_set(mi, 1);
+   if (mi->disabled) e_menu_item_disabled_set(mi, 1);
+}
+
+static void 
+_e_menu_item_unrealize(E_Menu_Item *mi)
+{
+   if (mi->o_con) e_box_freeze(mi->o_con);
+   if (mi->o_separator) evas_object_del(mi->o_separator);
+   mi->o_separator = NULL;
+   if (mi->o_bg) evas_object_del(mi->o_bg);
+   mi->o_bg = NULL;
+   if (mi->o_toggle) evas_object_del(mi->o_toggle);
+   mi->o_toggle = NULL;
+   if (mi->o_icon_bg) evas_object_del(mi->o_icon_bg);
+   mi->o_icon_bg = NULL;
+   if (mi->o_icon) evas_object_del(mi->o_icon);
+   mi->o_icon = NULL;
+   if (mi->o_lbl) evas_object_del(mi->o_lbl);
+   mi->o_lbl = NULL;
+   if (mi->o_submenu) evas_object_del(mi->o_submenu);
+   mi->o_submenu = NULL;
+   if (mi->o_event) evas_object_del(mi->o_event);
+   mi->o_event = NULL;
+   if (mi->o_con)
+     {
+        e_box_thaw(mi->o_con);
+        evas_object_del(mi->o_con);
+     }
+   mi->o_con = NULL;
+}
+
+static Eina_Bool 
+_e_menu_item_realize_call(E_Menu_Item *mi)
+{
+   if ((mi) && (mi->realize_cb.func))
+     {
+        mi->realize_cb.func(mi->realize_cb.data, mi->menu, mi);
+        return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static void 
+_e_menu_item_submenu_activate(E_Menu_Item *mi)
+{
+   if (!mi->menu->active) return;
+
+   if (mi->menu->fast_mouse)
+     {
+        mi->menu->pending_new_submenu = EINA_TRUE;
+        return;
+     }
+
+   mi->menu->pending_new_submenu = EINA_FALSE;
+   _e_menu_deactivate_above(mi->menu);
+
+   if (mi->submenu_pre_cb.func)
+     mi->submenu_pre_cb.func(mi->submenu_pre_cb.data, mi->menu, mi);
+
+   if (mi->submenu)
+     {
+        E_Menu *m;
+
+        m = mi->submenu;
+        e_object_ref(E_OBJECT(m));
+        m->parent_item = mi;
+
+        _e_menu_activate_internal(m, mi->menu->zone);
+        _e_menu_realize(m);
+        _e_menu_reposition(m);
+
+        e_object_unref(E_OBJECT(m));
+     }
+}
+
+static void 
+_e_menu_item_submenu_deactivate(E_Menu_Item *mi)
+{
+   if (!mi->menu->active) return;
+   if (mi->submenu_post_cb.func)
+     {
+        printf("Menu Calling Submenu Post\n");
+        mi->submenu_post_cb.func(mi->submenu_post_cb.data, mi->menu, mi);
+     }
+   /* else */
+   /*   { */
+   /*      if (mi->submenu) */
+   /*        mi->submenu->active = EINA_FALSE; */
+
+   /*      if (mi->menu) */
+   /*        mi->menu->active = EINA_TRUE; */
+   /*   } */
+}
diff --git a/src/bin/e_wayland/e_menu.h b/src/bin/e_wayland/e_menu.h
new file mode 100644 (file)
index 0000000..d15f436
--- /dev/null
@@ -0,0 +1,167 @@
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Menu_Pop_Direction E_Menu_Pop_Direction;
+typedef struct _E_Menu E_Menu;
+typedef struct _E_Menu_Item E_Menu_Item;
+typedef struct _E_Menu_Category_Callback E_Menu_Category_Callback;
+
+#else
+# ifndef E_MENU_H
+#  define E_MENU_H
+
+#  define E_MENU_TYPE 0xE0b01009
+#  define E_MENU_ITEM_TYPE 0xE0b0100a
+
+enum _E_Menu_Pop_Direction
+{
+   E_MENU_POP_DIRECTION_NONE,
+   E_MENU_POP_DIRECTION_LEFT,
+   E_MENU_POP_DIRECTION_RIGHT,
+   E_MENU_POP_DIRECTION_UP,
+   E_MENU_POP_DIRECTION_DOWN,
+   E_MENU_POP_DIRECTION_AUTO,
+   E_MENU_POP_DIRECTION_LAST
+};
+
+typedef void (*E_Menu_Cb) (void *data, E_Menu *m, E_Menu_Item *mi);
+
+struct _E_Menu
+{
+   E_Object e_obj_inherit;
+
+   Ecore_Evas *ee;
+   Evas *evas;
+   Evas_Object *o_bg, *o_con;
+
+   E_Zone *zone;
+   E_Menu_Item *parent_item;
+   Eina_List *items;
+
+   unsigned int id;
+   const char *category;
+
+   struct 
+     {
+        int x, y, w, h;
+        Eina_Bool visible : 1;
+     } cur, prev;
+
+   int frozen;
+   int cx, cy, cw, ch;
+
+   struct 
+     {
+        const char *title, *icon_file;
+        Evas_Object *icon;
+     } header;
+
+   struct 
+     {
+        void *data;
+        void (*func) (void *data, E_Menu *m);
+     } pre_activate_cb, post_deactivate_cb;
+
+   Eina_Bool fast_mouse : 1;
+   Eina_Bool shaped : 1;
+   Eina_Bool realized : 1;
+   Eina_Bool active : 1;
+   Eina_Bool changed : 1;
+   Eina_Bool have_submenu : 1;
+   Eina_Bool pending_new_submenu : 1;
+};
+
+struct _E_Menu_Item 
+{
+   E_Object e_obj_inherit;
+
+   E_Menu *menu, *submenu;
+
+   Evas_Object *o_bg, *o_con;
+   Evas_Object *o_separator;
+   Evas_Object *o_icon_bg, *o_icon;
+   Evas_Object *o_lbl, *o_toggle;
+   Evas_Object *o_submenu, *o_event;
+
+   int x, y, w, h;
+   const char *icon, *icon_key;
+   const char *label;
+
+   int lw, lh, iw, ih;
+   int sepw, seph, subw, subh;
+   int tw, th;
+
+   struct 
+     {
+        void *data;
+        E_Menu_Cb func;
+     } cb, realize_cb;
+
+   struct 
+     {
+        void *data;
+        E_Menu_Cb func;
+     } submenu_pre_cb, submenu_post_cb;
+
+   Eina_Bool separator : 1;
+   Eina_Bool radio : 1;
+   Eina_Bool radio_group : 1;
+   Eina_Bool check : 1;
+   Eina_Bool toggle : 1;
+   Eina_Bool changed : 1;
+   Eina_Bool active : 1;
+   Eina_Bool disabled : 1;
+};
+
+struct _E_Menu_Category_Callback
+{
+   const char *category;
+   void *data;
+   void (*create) (E_Menu *m, void *category_data, void *data);
+   void (*free) (void *data);
+};
+
+EINTERN int e_menu_init(void);
+EINTERN int e_menu_shutdown(void);
+
+EAPI E_Menu *e_menu_new(void);
+EAPI void e_menu_activate_key(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir);
+EAPI void e_menu_activate_mouse(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir, unsigned int activate_time);
+EAPI void e_menu_activate(E_Menu *m, E_Zone *zone, int x, int y, int w, int h, int dir);
+EAPI void e_menu_deactivate(E_Menu *m);
+EAPI int e_menu_freeze(E_Menu *m);
+EAPI int e_menu_thaw(E_Menu *m);
+EAPI void e_menu_title_set(E_Menu *m, char *title);
+EAPI void e_menu_icon_file_set(E_Menu *m, char *icon);
+EAPI void e_menu_category_set(E_Menu *m, char *category);
+EAPI void e_menu_category_data_set(char *category, void *data);
+EAPI E_Menu_Category_Callback *e_menu_category_callback_add(char *category, void (*create) (E_Menu *m, void *category_data, void *data), void (free) (void *data), void *data);
+EAPI void e_menu_category_callback_del(E_Menu_Category_Callback *cb);
+EAPI void e_menu_pre_activate_callback_set(E_Menu *m,  void (*func) (void *data, E_Menu *m), void *data);
+EAPI void e_menu_post_deactivate_callback_set(E_Menu *m,  void (*func) (void *data, E_Menu *m), void *data);
+EAPI E_Menu *e_menu_root_get(E_Menu *m);
+EAPI void e_menu_idler_before(void);
+
+EAPI E_Menu_Item *e_menu_item_new(E_Menu *m);
+EAPI E_Menu_Item *e_menu_item_new_relative(E_Menu *m, E_Menu_Item *rel);
+EAPI E_Menu_Item *e_menu_item_nth(E_Menu *m, int n);
+EAPI int e_menu_item_num_get(const E_Menu_Item *mi);
+EAPI void e_menu_item_icon_file_set(E_Menu_Item *mi, const char *icon);
+EAPI void e_menu_item_icon_edje_set(E_Menu_Item *mi, const char *icon, const char *key);
+EAPI void e_menu_item_label_set(E_Menu_Item *mi, const char *label);
+EAPI void e_menu_item_submenu_set(E_Menu_Item *mi, E_Menu *sub);
+EAPI void e_menu_item_separator_set(E_Menu_Item *mi, int sep);
+EAPI void e_menu_item_check_set(E_Menu_Item *mi, int chk);
+EAPI void e_menu_item_radio_set(E_Menu_Item *mi, int rad);
+EAPI void e_menu_item_radio_group_set(E_Menu_Item *mi, int radg);
+EAPI void e_menu_item_toggle_set(E_Menu_Item *mi, int tog);
+EAPI int e_menu_item_toggle_get(E_Menu_Item *mi);
+EAPI void e_menu_item_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data);
+EAPI void e_menu_item_realize_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data);
+EAPI void e_menu_item_submenu_pre_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data);
+EAPI void e_menu_item_submenu_post_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data);
+EAPI void e_menu_item_drag_callback_set(E_Menu_Item *mi,  E_Menu_Cb func, void *data);
+EAPI void e_menu_item_active_set(E_Menu_Item *mi, int active);
+EAPI void e_menu_item_disabled_set(E_Menu_Item *mi, int disable);
+
+# endif
+#endif
index e38b415f191b7e72489ab0f9fa596da6a4b0acc7..4a0cfeba8e5703955272c0494955934c612c4bfa 100644 (file)
@@ -239,11 +239,15 @@ e_module_all_load(void)
 
              e_util_env_set("E_MODULE_LOAD", em->name);
              snprintf(buf, sizeof(buf), _("Loading Module: %s"), em->name);
+
              /* FIXME: Wayland */
              /* e_init_status_set(buf); */
 
-             m = e_module_new(em->name);
-             if (m) e_module_enable(m);
+             if (!(m = e_module_find(em->name)))
+               {
+                  if ((m = e_module_new(em->name)))
+                    e_module_enable(m);
+               }
           }
      }
 
diff --git a/src/bin/e_wayland/e_obj_dialog.c b/src/bin/e_wayland/e_obj_dialog.c
new file mode 100644 (file)
index 0000000..0abed26
--- /dev/null
@@ -0,0 +1,163 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_obj_dialog_cb_free(E_Obj_Dialog *od);
+static void _e_obj_dialog_cb_delete(E_Win *win);
+static void _e_obj_dialog_cb_close(void *data, Evas_Object *obj, const char *emission, const char *source);
+static void _e_obj_dialog_cb_resize(E_Win *win);
+
+EAPI E_Obj_Dialog *
+e_obj_dialog_new(E_Container *con, char *title, char *class_name, char *class_class)
+{
+   E_Obj_Dialog *od;
+   E_Manager *man;
+   Evas_Object *o;
+   
+   if (!con)
+     {
+       man = e_manager_current_get();
+       if (!man) return NULL;
+       con = e_container_current_get(man);
+       if (!con) con = e_container_number_get(man, 0);
+       if (!con) return NULL;
+     }
+
+   od = E_OBJECT_ALLOC(E_Obj_Dialog, E_OBJ_DIALOG_TYPE, _e_obj_dialog_cb_free);
+   if (!od) return NULL;
+
+   od->win = e_win_new(con);
+   if (!od->win)
+     {
+       free(od);
+       return NULL;
+     }
+   e_win_delete_callback_set(od->win, _e_obj_dialog_cb_delete);
+   e_win_resize_callback_set(od->win, _e_obj_dialog_cb_resize);
+   od->win->data = od;
+   e_win_dialog_set(od->win, 1);
+   e_win_name_class_set(od->win, class_name, class_class);
+   e_win_title_set(od->win, title);
+
+   o = edje_object_add(e_win_evas_get(od->win));
+   od->o_bg = o;
+
+   e_win_centered_set(od->win, 1);
+   od->cb_delete = NULL;
+
+   return od;
+}
+
+EAPI void
+e_obj_dialog_cb_delete_set(E_Obj_Dialog *od, void (*func)(E_Obj_Dialog *od))
+{
+   od->cb_delete = func;
+}
+
+EAPI void
+e_obj_dialog_icon_set(E_Obj_Dialog *od __UNUSED__, char *icon __UNUSED__)
+{
+   /* E_OBJECT_CHECK(od); */
+   /* E_OBJECT_TYPE_CHECK(od, E_OBJ_DIALOG_TYPE); */
+   /* if (od->win->border->internal_icon) */
+   /*   { */
+   /*  eina_stringshare_del(od->win->border->internal_icon); */
+   /*  od->win->border->internal_icon = NULL; */
+   /*   } */
+   /* if (icon) */
+   /*   od->win->border->internal_icon = eina_stringshare_add(icon); */
+}
+
+EAPI void
+e_obj_dialog_show(E_Obj_Dialog *od)
+{
+   Evas_Coord w, h, mw, mh;
+   const char *s;
+
+   E_OBJECT_CHECK(od);
+   E_OBJECT_TYPE_CHECK(od, E_OBJ_DIALOG_TYPE);
+
+   edje_object_size_min_get(od->o_bg, &mw, &mh);
+   edje_object_size_min_restricted_calc(od->o_bg, &mw, &mh, mw, mh);
+   evas_object_resize(od->o_bg, mw, mh);
+   e_win_resize(od->win, mw, mh);
+   e_win_size_min_set(od->win, mw, mh);
+
+   edje_object_size_max_get(od->o_bg, &w, &h);
+   if ((w > 0) && (h > 0))
+     {
+       if (w < mw) w = mw;
+       if (h < mh) h = mh;
+       e_win_size_max_set(od->win, w, h);
+     }
+
+   s = edje_object_data_get(od->o_bg, "borderless");
+   if (s && (!strcmp(s, "1")))
+     e_win_borderless_set(od->win, 1);
+
+   s = edje_object_data_get(od->o_bg, "shaped");
+   if (s && (!strcmp(s, "1")))
+     e_win_shaped_set(od->win, 1);
+
+   e_win_show(od->win);
+}
+
+EAPI void
+e_obj_dialog_obj_part_text_set(E_Obj_Dialog *od, char *part, char *text)
+{
+   E_OBJECT_CHECK(od);
+   E_OBJECT_TYPE_CHECK(od, E_OBJ_DIALOG_TYPE);
+   edje_object_part_text_set(od->o_bg, part, text);
+}
+
+EAPI void
+e_obj_dialog_obj_theme_set(E_Obj_Dialog *od, char *theme_cat, char *theme_obj)
+{
+   E_OBJECT_CHECK(od);
+   E_OBJECT_TYPE_CHECK(od, E_OBJ_DIALOG_TYPE);
+   
+   e_theme_edje_object_set(od->o_bg, theme_cat, theme_obj);
+   evas_object_move(od->o_bg, 0, 0);
+   evas_object_show(od->o_bg);
+   edje_object_signal_callback_add(od->o_bg, "e,action,close", "",
+                                  _e_obj_dialog_cb_close, od);
+}
+
+/* local subsystem functions */
+static void
+_e_obj_dialog_cb_free(E_Obj_Dialog *od)
+{
+   if (od->o_bg) evas_object_del(od->o_bg);
+   e_object_del(E_OBJECT(od->win));
+   free(od);
+}
+
+static void
+_e_obj_dialog_cb_delete(E_Win *win)
+{
+   E_Obj_Dialog *od;
+   
+   od = win->data;
+   if (od->cb_delete)
+     od->cb_delete(od);
+   e_object_del(E_OBJECT(od));
+}
+
+static void
+_e_obj_dialog_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   E_Obj_Dialog *od;
+
+   od = data;
+   if (od->cb_delete)
+     od->cb_delete(od);
+   e_util_defer_object_del(E_OBJECT(od));
+}
+
+static void
+_e_obj_dialog_cb_resize(E_Win *win)
+{
+   E_Obj_Dialog *od;
+   
+   od = win->data;
+   evas_object_resize(od->o_bg, od->win->w, od->win->h);
+}
diff --git a/src/bin/e_wayland/e_obj_dialog.h b/src/bin/e_wayland/e_obj_dialog.h
new file mode 100644 (file)
index 0000000..920aa3b
--- /dev/null
@@ -0,0 +1,29 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Obj_Dialog E_Obj_Dialog;
+
+#else
+# ifndef E_OBJ_DIALOG_H
+#  define E_OBJ_DIALOG_H
+
+#  define E_OBJ_DIALOG_TYPE 0xE0b0101b
+
+struct _E_Obj_Dialog
+{
+   E_Object e_obj_inherit;
+
+   E_Win *win;
+   Evas_Object *o_bg;
+   void *data;
+   void (*cb_delete)(E_Obj_Dialog *od);
+};
+
+EAPI E_Obj_Dialog *e_obj_dialog_new(E_Container *con, char *title, char *class_name, char *class_class);
+EAPI void e_obj_dialog_icon_set(E_Obj_Dialog *od __UNUSED__, char *icon __UNUSED__);
+EAPI void e_obj_dialog_show(E_Obj_Dialog *od);
+EAPI void e_obj_dialog_obj_part_text_set(E_Obj_Dialog *od, char *part, char *text);
+EAPI void e_obj_dialog_obj_theme_set(E_Obj_Dialog *od, char *theme_cat, char *theme_obj);
+EAPI void e_obj_dialog_cb_delete_set(E_Obj_Dialog *od, void (*func)(E_Obj_Dialog *od));
+    
+#endif
+#endif
index cc5fa8ae8d8aeb44f423764351de2dcf73654a3e..f3cada4646c7812c311d0ac831569d985c7f236a 100644 (file)
@@ -68,8 +68,6 @@ e_output_repaint(E_Output *output, unsigned int secs)
    Eina_List *l;
    struct wl_list frames;
 
-   printf("Output Repaint\n");
-
    comp = output->compositor;
 
    EINA_LIST_FOREACH(comp->surfaces, l, es)
@@ -118,8 +116,6 @@ e_output_repaint_schedule(E_Output *output)
    E_Compositor *comp;
    struct wl_event_loop *loop;
 
-   printf("Output Repaint Schedule\n");
-
    comp = output->compositor;
 
    loop = wl_display_get_event_loop(comp->wl.display);
diff --git a/src/bin/e_wayland/e_popup.c b/src/bin/e_wayland/e_popup.c
new file mode 100644 (file)
index 0000000..9b282a4
--- /dev/null
@@ -0,0 +1,195 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_popup_cb_free(E_Popup *pop);
+
+/* local variables */
+static Eina_Hash *_popups = NULL;
+
+EINTERN int 
+e_popup_init(void)
+{
+   if (!_popups) _popups = eina_hash_string_superfast_new(NULL);
+
+   return 1;
+}
+
+EINTERN int 
+e_popup_shutdown(void)
+{
+   if (_popups) eina_hash_free(_popups);
+   _popups = NULL;
+
+   return 1;
+}
+
+EAPI E_Popup *
+e_popup_new(E_Zone *zone, int x, int y, int w, int h)
+{
+   E_Popup *p;
+   Ecore_Wl_Window *win = NULL;
+   unsigned int parent = 0;
+
+   p = E_OBJECT_ALLOC(E_Popup, E_POPUP_TYPE, _e_popup_cb_free);
+   if (!p) return NULL;
+
+   p->zone = zone;
+   p->x = x;
+   p->y = y;
+   p->w = w;
+   p->h = h;
+
+   if (p->zone->container)
+     {
+        if ((win = ecore_evas_wayland_window_get(zone->container->bg_ee)))
+          parent = win->id;
+     }
+
+   p->ee = 
+     e_canvas_new(parent, zone->x + p->x, zone->y + p->y, 
+                  p->w, p->h, EINA_TRUE, EINA_FALSE, NULL);
+   if (!p->ee)
+     {
+        free(p);
+        return NULL;
+     }
+
+   e_canvas_add(p->ee);
+   p->evas = ecore_evas_get(p->ee);
+
+   /* TODO: window raise ? */
+
+   ecore_evas_name_class_set(p->ee, "E", "_e_popup_window");
+   ecore_evas_title_set(p->ee, "E Popup");
+
+   e_object_ref(E_OBJECT(p->zone));
+   zone->popups = eina_list_append(zone->popups, p);
+
+   win = ecore_evas_wayland_window_get(p->ee);
+   eina_hash_add(_popups, e_util_winid_str_get(win), p);
+
+   return p;
+}
+
+EAPI void 
+e_popup_show(E_Popup *pop)
+{
+   if (pop->visible) return;
+   pop->visible = EINA_TRUE;
+   ecore_evas_show(pop->ee);
+}
+
+EAPI void 
+e_popup_hide(E_Popup *pop)
+{
+   if (!pop->visible) return;
+   pop->visible = EINA_FALSE;
+   ecore_evas_hide(pop->ee);
+}
+
+EAPI void 
+e_popup_move(E_Popup *pop, int x, int y)
+{
+   if ((pop->x == x) && (pop->y == y)) return;
+   pop->x = x;
+   pop->y = y;
+   ecore_evas_move(pop->ee, pop->zone->x + x, pop->zone->y + y);
+}
+
+EAPI void 
+e_popup_resize(E_Popup *pop, int w, int h)
+{
+   if ((pop->w == w) && (pop->h == h)) return;
+   pop->w = w;
+   pop->h = h;
+   ecore_evas_resize(pop->ee, w, h);
+}
+
+EAPI void 
+e_popup_move_resize(E_Popup *pop, int x, int y, int w, int h)
+{
+   if ((pop->x == x) && (pop->y == y) && (pop->w == w) && (pop->h == h))
+     return;
+   pop->x = x;
+   pop->y = y;
+   pop->w = w;
+   pop->h = h;
+   ecore_evas_move_resize(pop->ee, pop->zone->x + x, pop->zone->y + y, w, h);
+}
+
+EAPI void 
+e_popup_layer_set(E_Popup *pop, int layer)
+{
+   pop->layer = layer;
+}
+
+EAPI void 
+e_popup_name_set(E_Popup *pop, const char *name)
+{
+   if (eina_stringshare_replace(&pop->name, name))
+     ecore_evas_name_class_set(pop->ee, "E", pop->name);
+}
+
+EAPI void 
+e_popup_ignore_events_set(E_Popup *pop, Eina_Bool ignore)
+{
+   ecore_evas_ignore_events_set(pop->ee, ignore);
+}
+
+EAPI void 
+e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *obj)
+{
+   const char *shaped;
+
+   if ((shaped = edje_object_data_get(obj, "shaped")))
+     {
+        if (!strcmp(shaped, "1"))
+          pop->shaped = EINA_TRUE;
+        else
+          pop->shaped = EINA_FALSE;
+        ecore_evas_alpha_set(pop->ee, pop->shaped);
+     }
+   else
+     ecore_evas_shaped_set(pop->ee, pop->shaped);
+}
+
+EAPI void 
+e_popup_idler_before(void)
+{
+
+}
+
+EAPI E_Popup *
+e_popup_find_by_window(Ecore_Wl_Window *win)
+{
+   E_Popup *pop;
+
+   if ((pop = eina_hash_find(_popups, e_util_winid_str_get(win))))
+     {
+        Ecore_Wl_Window *w;
+
+        if ((w = ecore_evas_wayland_window_get(pop->ee)))
+          if (w != win) 
+            return NULL;
+     }
+
+   return pop;
+}
+
+/* local functions */
+static void 
+_e_popup_cb_free(E_Popup *pop)
+{
+   Ecore_Wl_Window *win;
+
+   win = ecore_evas_wayland_window_get(pop->ee);
+
+   e_canvas_del(pop->ee);
+   ecore_evas_free(pop->ee);
+   e_object_unref(E_OBJECT(pop->zone));
+   pop->zone->popups = eina_list_remove(pop->zone->popups, pop);
+   eina_hash_del(_popups, e_util_winid_str_get(win), pop);
+   if (pop->name) eina_stringshare_del(pop->name);
+   pop->name = NULL;
+   free(pop);
+}
diff --git a/src/bin/e_wayland/e_popup.h b/src/bin/e_wayland/e_popup.h
new file mode 100644 (file)
index 0000000..af2fa42
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Popup E_Popup;
+
+#else
+# ifndef E_POPUP_H
+#  define E_POPUP_H
+
+#  define E_POPUP_TYPE 0xE0b0100e
+
+struct _E_Popup
+{
+   E_Object e_obj_inherit;
+
+   int x, y, w, h;
+   int layer;
+   const char *name;
+
+   Ecore_Evas *ee;
+   Evas *evas;
+   E_Zone *zone;
+
+   Eina_Bool visible : 1;
+   Eina_Bool shaped : 1;
+};
+
+EINTERN int e_popup_init(void);
+EINTERN int e_popup_shutdown(void);
+
+EAPI E_Popup *e_popup_new(E_Zone *zone, int x, int y, int w, int h);
+EAPI void e_popup_show(E_Popup *pop);
+EAPI void e_popup_hide(E_Popup *pop);
+EAPI void e_popup_move(E_Popup *pop, int x, int y);
+EAPI void e_popup_resize(E_Popup *pop, int w, int h);
+EAPI void e_popup_move_resize(E_Popup *pop, int x, int y, int w, int h);
+EAPI void e_popup_layer_set(E_Popup *pop, int layer);
+EAPI void e_popup_name_set(E_Popup *pop, const char *name);
+EAPI void e_popup_ignore_events_set(E_Popup *pop, Eina_Bool ignore);
+EAPI void e_popup_edje_bg_object_set(E_Popup *pop, Evas_Object *obj);
+EAPI void e_popup_idler_before(void);
+EAPI E_Popup *e_popup_find_by_window(Ecore_Wl_Window *win);
+
+# endif
+#endif
index 2d54c3b59e0c4845e8f284574490c96c3ad1275d..c87f0ee46c05c895be4705e43a91c08e5044f1ba 100644 (file)
@@ -89,11 +89,7 @@ _e_renderer_region_repaint(E_Surface *surface, E_Output *output, pixman_region32
    E_Renderer_Surface_State *surf_state;
    pixman_region32_t fregion;
    pixman_box32_t *ext;
-//   pixman_fixed_t fw = 0, fh = 0;
 
-   printf("E_Renderer Region Repaint\n");
-
-//   rend = output->compositor->renderer;
    out_state = output->state;
    surf_state = surface->state;
 
@@ -109,9 +105,9 @@ _e_renderer_region_repaint(E_Surface *surface, E_Output *output, pixman_region32
      pixman_region32_copy(&fregion, region);
 
    ext = pixman_region32_extents(&fregion);
-   printf("\tRepainting Region: %d %d %d %d\n", 
-          ext->x1, ext->y1, (ext->x2 - ext->x1), 
-          (ext->y2 - ext->y1));
+   /* printf("\tRepainting Region: %d %d %d %d\n",  */
+   /*        ext->x1, ext->y1, (ext->x2 - ext->x1),  */
+   /*        (ext->y2 - ext->y1)); */
 
    /* global to output ? */
 
@@ -133,16 +129,11 @@ _e_renderer_surfaces_repaint(E_Output *output, pixman_region32_t *damage)
    Eina_List *l;
    E_Surface *es;
 
-   printf("E_Renderer Surfaces Repaint\n");
-
    comp = output->compositor;
    EINA_LIST_FOREACH(comp->surfaces, l, es)
      {
         if (es->plane == &comp->plane)
-          {
-             printf("\tDraw Surface: %p\n", es);
-             _e_renderer_surface_draw(es, output, damage);
-          }
+          _e_renderer_surface_draw(es, output, damage);
      }
 }
 
@@ -169,8 +160,6 @@ _e_renderer_surface_draw(E_Surface *surface, E_Output *output, pixman_region32_t
         return;
      }
 
-   printf("E_Renderer Surface Draw: %p\n", surface);
-
    /* TODO: handle transforms ? */
 
    pixman_region32_init_rect(&blend, 0, 0, 
@@ -195,8 +184,6 @@ _e_renderer_cb_pixels_read(E_Output *output, int format, void *pixels, Evas_Coor
    E_Renderer_Output_State *state;
    pixman_image_t *buffer;
 
-   printf("E_Renderer Pixels Read\n");
-
    if (!(state = output->state)) return EINA_FALSE;
    if (!state->hw_buffer) return EINA_FALSE;
 
@@ -219,8 +206,6 @@ _e_renderer_cb_output_buffer_set(E_Output *output, pixman_image_t *buffer)
 {
    E_Renderer_Output_State *state;
 
-   printf("E_Renderer Output Buffer Set\n");
-
    state = output->state;
    if (state->hw_buffer) pixman_image_unref(state->hw_buffer);
    state->hw_buffer = buffer;
@@ -237,8 +222,6 @@ _e_renderer_cb_output_repaint(E_Output *output, pixman_region32_t *damage)
    E_Renderer_Output_State *state;
    pixman_region32_t region;
 
-   printf("E_Renderer Output Repaint\n");
-
    state = output->state;
    if (!state->hw_buffer) return;
 
@@ -265,7 +248,7 @@ _e_renderer_cb_output_repaint(E_Output *output, pixman_region32_t *damage)
 static void 
 _e_renderer_cb_damage_flush(E_Surface *surface)
 {
-   printf("E_Renderer Damage Flush\n");
+
 }
 
 static void 
@@ -286,8 +269,6 @@ _e_renderer_cb_attach(E_Surface *surface, struct wl_buffer *buffer)
 
    if (!buffer) return;
 
-   printf("E_Renderer Attach\n");
-
    switch (wl_shm_buffer_get_format(buffer))
      {
       case WL_SHM_FORMAT_XRGB8888:
@@ -340,7 +321,7 @@ _e_renderer_cb_output_create(E_Output *output, unsigned int window)
 static void 
 _e_renderer_cb_output_destroy(E_Output *output)
 {
-   printf("E_Renderer Output Destroy\n");
+
 }
 
 static Eina_Bool 
@@ -381,5 +362,5 @@ _e_renderer_cb_surface_color_set(E_Surface *surface, int r, int g, int b, int a)
 static void 
 _e_renderer_cb_destroy(E_Compositor *comp)
 {
-   printf("E_Renderer Destroy\n");
+
 }
diff --git a/src/bin/e_wayland/e_shelf.c b/src/bin/e_wayland/e_shelf.c
new file mode 100644 (file)
index 0000000..5bbddb7
--- /dev/null
@@ -0,0 +1,1029 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_shelf_cb_free(E_Shelf *es);
+static void _e_shelf_gadcon_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
+static void _e_shelf_gadcon_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h);
+static Evas_Object *_e_shelf_gadcon_frame_request(void *data, E_Gadcon_Client *gcc, const char *style);
+static void _e_shelf_cb_locked_set(void *data, int lock);
+static void _e_shelf_cb_urgent_show(void *data);
+static void _e_shelf_gadcon_client_remove(void *data, E_Gadcon_Client *gcc);
+static int _e_shelf_gadcon_client_add(void *data, const E_Gadcon_Client_Class *cc);
+static void _e_shelf_cb_menu_items_append(void *data, E_Gadcon_Client *gcc, E_Menu *mn);
+static void _e_shelf_menu_append(E_Shelf *es, E_Menu *mn);
+static void _e_shelf_menu_pre_cb(void *data, E_Menu *m);
+static void _e_shelf_menu_append(E_Shelf *es, E_Menu *mn);
+static void _e_shelf_cb_menu_config(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_shelf_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_shelf_cb_menu_contents(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_shelf_cb_confirm_dialog_yes(void *data);
+static void _e_shelf_cb_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_shelf_menu_item_free(void *data);
+static const char *_e_shelf_orient_icon_name_get(E_Shelf *s);
+
+/* local variables */
+static Eina_List *_shelves = NULL;
+
+EINTERN int 
+e_shelf_init(void)
+{
+   return 1;
+}
+
+EINTERN int 
+e_shelf_shutdown(void)
+{
+   if (wl_fatal) return 1;
+
+   while (_shelves)
+     {
+        E_Shelf *es;
+
+        es = eina_list_data_get(_shelves);
+        e_object_del(E_OBJECT(es));
+     }
+
+   return 1;
+}
+
+EAPI void 
+e_shelf_config_update(void)
+{
+   Eina_List *l;
+   E_Config_Shelf *cfg;
+   int id = 0;
+
+   while (_shelves)
+     {
+        E_Shelf *es;
+
+        es = eina_list_data_get(_shelves);
+        e_object_del(E_OBJECT(es));
+     }
+
+   EINA_LIST_FOREACH(e_config->shelves, l, cfg)
+     {
+        E_Zone *zone;
+
+        if (cfg->id <= 0) cfg->id = id + 1;
+        zone = e_util_container_zone_number_get(cfg->container, cfg->zone);
+        if (zone) e_shelf_config_new(zone, cfg);
+        id = cfg->id;
+     }
+}
+
+EAPI E_Shelf *
+e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cfg)
+{
+   E_Shelf *es;
+
+   E_OBJECT_CHECK_RETURN(zone, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
+
+   es = e_shelf_zone_new(zone, cfg->name, cfg->style, cfg->popup, 
+                         cfg->layer, cfg->id);
+   if (!es) return NULL;
+
+   if (!cfg->hide_timeout) cfg->hide_timeout = 1.0;
+   if (!cfg->hide_duration) cfg->hide_duration = 1.0;
+
+   es->cfg = cfg;
+   es->fit_along = cfg->fit_along;
+   es->fit_size = cfg->fit_size;
+
+   e_shelf_orient(es, cfg->orient);
+   e_shelf_position_calc(es);
+   e_shelf_populate(es);
+
+   if (cfg->desk_show_mode)
+     {
+        E_Desk *desk;
+        Eina_List *l;
+        E_Config_Shelf_Desk *sd;
+
+        desk = e_desk_current_get(zone);
+        EINA_LIST_FOREACH(cfg->desk_list, l, sd)
+          {
+             if ((desk->x == sd->x) && (desk->y == sd->y))
+               {
+                  e_shelf_show(es);
+                  break;
+               }
+          }
+     }
+   else
+     e_shelf_show(es);
+
+   e_shelf_toggle(es, EINA_FALSE);
+
+   return es;
+}
+
+EAPI E_Shelf *
+e_shelf_zone_new(E_Zone *zone, const char *name, const char *style, int popup, int layer, int id)
+{
+   E_Shelf *es;
+   char buff[1024];
+   const char *locname;
+
+   es = E_OBJECT_ALLOC(E_Shelf, E_SHELF_TYPE, _e_shelf_cb_free);
+   if (!es) return NULL;
+
+   es->id = id;
+   es->x = 0;
+   es->y = 0;
+   es->w = 32;
+   es->h = 32;
+   es->zone = zone;
+
+   if (popup)
+     {
+        es->popup = e_popup_new(zone, es->x, es->y, es->w, es->h);
+        e_popup_name_set(es->popup, "shelf");
+        e_popup_layer_set(es->popup, layer);
+        es->ee = es->popup->ee;
+        es->evas = es->popup->evas;
+     }
+   else
+     {
+        es->ee = zone->container->bg_ee;
+        es->evas = zone->container->bg_evas;
+     }
+
+   es->fit_along = EINA_TRUE;
+   es->layer = layer;
+   es->style = eina_stringshare_add(style);
+   es->name = eina_stringshare_add(name);
+
+   es->o_event = evas_object_rectangle_add(es->evas);
+   evas_object_color_set(es->o_event, 255, 0, 0, 128);
+   evas_object_resize(es->o_event, es->w, es->h);
+   /* TODO: add callback */
+
+   /* TODO: add handlers */
+
+   es->o_base = edje_object_add(es->evas);
+   evas_object_resize(es->o_base, es->w, es->h);
+   snprintf(buff, sizeof(buff), "e/shelf/%s/base", es->style);
+   if (!e_theme_edje_object_set(es->o_base, "base/theme/shelf", buff))
+     e_theme_edje_object_set(es->o_base, "base/theme/shelf", 
+                             "e/shelf/default/base");
+
+   if (es->popup)
+     {
+        evas_object_show(es->o_event);
+        evas_object_show(es->o_base);
+        e_popup_edje_bg_object_set(es->popup, es->o_base);
+        /* TODO: window type set */
+     }
+   else
+     {
+        evas_object_move(es->o_event, es->zone->x + es->x, 
+                         es->zone->y + es->y);
+        evas_object_move(es->o_base, es->zone->x + es->x, 
+                         es->zone->y + es->y);
+        evas_object_layer_set(es->o_event, layer);
+        evas_object_layer_set(es->o_base, layer);
+     }
+
+   es->gadcon = 
+     e_gadcon_swallowed_new(es->name, es->id, es->o_base, "e.swallow.content");
+   locname = es->name;
+   if (!name) locname = _("Shelf #");
+   snprintf(buff, sizeof(buff), "%s %i", locname, es->id);
+   es->gadcon->location = 
+     e_gadcon_location_new(buff, E_GADCON_SITE_SHELF, 
+                           _e_shelf_gadcon_client_add, es, 
+                           _e_shelf_gadcon_client_remove, es);
+   e_gadcon_location_register(es->gadcon->location);
+// hmm dnd in ibar and ibox kill this. ok. need to look into this more   
+//   es->gadcon->instant_edit = 1;
+   e_gadcon_min_size_request_callback_set(es->gadcon,
+                                         _e_shelf_gadcon_min_size_request, es);
+
+   e_gadcon_size_request_callback_set(es->gadcon,
+                                     _e_shelf_gadcon_size_request, es);
+   e_gadcon_frame_request_callback_set(es->gadcon,
+                                      _e_shelf_gadcon_frame_request, es);
+   e_gadcon_orient(es->gadcon, E_GADCON_ORIENT_TOP);
+   snprintf(buff, sizeof(buff), "e,state,orientation,%s", 
+           e_shelf_orient_string_get(es));
+   edje_object_signal_emit(es->o_base, buff, "e");
+   edje_object_message_signal_process(es->o_base);
+   e_gadcon_zone_set(es->gadcon, zone);
+   e_gadcon_ecore_evas_set(es->gadcon, es->ee);
+   e_gadcon_shelf_set(es->gadcon, es);
+
+   e_gadcon_util_menu_attach_func_set(es->gadcon,
+                                     _e_shelf_cb_menu_items_append, es);
+
+   e_gadcon_util_lock_func_set(es->gadcon,
+                              _e_shelf_cb_locked_set, es);
+   e_gadcon_util_urgent_show_func_set(es->gadcon,
+                                     _e_shelf_cb_urgent_show, es);
+
+   _shelves = eina_list_append(_shelves, es);
+
+   es->hidden = EINA_FALSE;
+   /* TODO: hide step */
+   es->locked = EINA_FALSE;
+
+   /* TODO: hidden_state_size & instant_delay */
+
+   return es;
+}
+
+EAPI void 
+e_shelf_show(E_Shelf *es)
+{
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   if (es->popup)
+     e_popup_show(es->popup);
+   else
+     {
+        evas_object_show(es->o_event);
+        evas_object_show(es->o_base);
+     }
+}
+
+EAPI void 
+e_shelf_hide(E_Shelf *es)
+{
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   if (es->popup)
+     e_popup_hide(es->popup);
+   else
+     {
+        evas_object_hide(es->o_event);
+        evas_object_hide(es->o_base);
+     }
+}
+
+EAPI void 
+e_shelf_toggle(E_Shelf *es, Eina_Bool show)
+{
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   es->toggle = show;
+   if (es->locked) return;
+   es->urgent_show = EINA_FALSE;
+   if ((show) && (es->hidden))
+     {
+        es->hidden = EINA_FALSE;
+        edje_object_signal_emit(es->o_base, "e,state,visible", "e");
+        /* TODO: autohide */
+     }
+   else if ((!show) && (!es->hidden))
+     {
+        es->hidden = EINA_TRUE;
+        edje_object_signal_emit(es->o_base, "e,state,hidden", "e");
+        /* TODO: instant delay */
+     }
+}
+
+EAPI void 
+e_shelf_populate(E_Shelf *es)
+{
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+   e_gadcon_populate(es->gadcon);
+}
+
+EAPI void 
+e_shelf_position_calc(E_Shelf *es)
+{
+   E_Gadcon_Orient orient = E_GADCON_ORIENT_FLOAT;
+   int size = 40;
+
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   if (es->cfg)
+     {
+        orient = es->cfg->orient;
+        size = es->cfg->size * e_scale;
+     }
+   /* TODO: handle gadcon->orient */
+
+   switch (orient)
+     {
+      case E_GADCON_ORIENT_FLOAT:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        break;
+      case E_GADCON_ORIENT_HORIZ:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = (es->zone->w - es->w) / 2;
+        break;
+      case E_GADCON_ORIENT_VERT:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->y = (es->zone->h - es->h) / 2;
+        break;
+      case E_GADCON_ORIENT_LEFT:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = 0;
+        es->y = (es->zone->h - es->h) / 2;
+        break;
+      case E_GADCON_ORIENT_RIGHT:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = (es->zone->w - es->w);
+        es->y = (es->zone->h - es->h) / 2;
+        break;
+      case E_GADCON_ORIENT_TOP:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = (es->zone->w - es->w) / 2;
+        es->y = 0;
+        break;
+      case E_GADCON_ORIENT_BOTTOM:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = (es->zone->w - es->w) / 2;
+        es->y = (es->zone->h - es->h);
+        break;
+      case E_GADCON_ORIENT_CORNER_TL:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = 0;
+        es->y = 0;
+        break;
+      case E_GADCON_ORIENT_CORNER_TR:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = (es->zone->w - es->w);
+        es->y = 0;
+        break;
+      case E_GADCON_ORIENT_CORNER_BL:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = 0;
+        es->y = (es->zone->h - es->h);
+        break;
+      case E_GADCON_ORIENT_CORNER_BR:
+        if (!es->fit_along) es->w = es->zone->w;
+        if (!es->fit_size) es->h = size;
+        es->x = (es->zone->w - es->w);
+        es->y = (es->zone->h - es->h);
+        break;
+      case E_GADCON_ORIENT_CORNER_LT:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = 0;
+        es->y = 0;
+        break;
+      case E_GADCON_ORIENT_CORNER_RT:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = (es->zone->w - es->w);
+        es->y = 0;
+        break;
+      case E_GADCON_ORIENT_CORNER_LB:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = 0;
+        es->y = (es->zone->h - es->h);
+        break;
+      case E_GADCON_ORIENT_CORNER_RB:
+        if (!es->fit_along) es->h = es->zone->h;
+        if (!es->fit_size) es->w = size;
+        es->x = (es->zone->w - es->w);
+        es->y = (es->zone->h - es->h);
+        break;
+      default:
+        break;
+     }
+
+   /* TODO: hide_step, hide_origin */
+
+   e_shelf_move_resize(es, es->x, es->y, es->w, es->h);
+   if (es->hidden)
+     {
+        es->hidden = EINA_FALSE;
+        e_shelf_toggle(es, EINA_FALSE);
+     }
+}
+
+EAPI void 
+e_shelf_move_resize(E_Shelf *es, int x, int y, int w, int h)
+{
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   es->x = x;
+   es->y = y;
+   es->w = w;
+   es->h = h;
+   if (es->popup)
+     e_popup_move_resize(es->popup, es->x, es->y, es->w, es->h);
+   else
+     {
+        evas_object_move(es->o_event, es->zone->x + es->x, 
+                         es->zone->y + es->y);
+        evas_object_move(es->o_base, es->zone->x + es->x, 
+                         es->zone->y + es->y);
+     }
+   evas_object_resize(es->o_event, es->w, es->h);
+   evas_object_resize(es->o_base, es->w, es->h);
+}
+
+EAPI Eina_List *
+e_shelf_list(void)
+{
+   return _shelves;
+}
+
+EAPI const char *
+e_shelf_orient_string_get(E_Shelf *es)
+{
+   const char *sig = "";
+
+   switch (es->gadcon->orient)
+     {
+      case E_GADCON_ORIENT_FLOAT:
+       sig = "float";
+       break;
+      case E_GADCON_ORIENT_HORIZ:
+       sig = "horizontal";
+       break;
+      case E_GADCON_ORIENT_VERT:
+       sig = "vertical";
+       break;
+      case E_GADCON_ORIENT_LEFT:
+       sig = "left";
+       break;
+      case E_GADCON_ORIENT_RIGHT:
+       sig = "right";
+       break;
+      case E_GADCON_ORIENT_TOP:
+       sig = "top";
+       break;
+      case E_GADCON_ORIENT_BOTTOM:
+       sig = "bottom";
+       break;
+      case E_GADCON_ORIENT_CORNER_TL:
+       sig = "top_left";
+       break;
+      case E_GADCON_ORIENT_CORNER_TR:
+       sig = "top_right";
+       break;
+      case E_GADCON_ORIENT_CORNER_BL:
+       sig = "bottom_left";
+       break;
+      case E_GADCON_ORIENT_CORNER_BR:
+       sig = "bottom_right";
+       break;
+      case E_GADCON_ORIENT_CORNER_LT:
+       sig = "left_top";
+       break;
+      case E_GADCON_ORIENT_CORNER_RT:
+       sig = "right_top";
+       break;
+      case E_GADCON_ORIENT_CORNER_LB:
+       sig = "left_bottom";
+       break;
+      case E_GADCON_ORIENT_CORNER_RB:
+       sig = "right_bottom";
+       break;
+      default:
+       break;
+     }
+   return sig;
+}
+
+EAPI void 
+e_shelf_orient(E_Shelf *es, E_Gadcon_Orient orient)
+{
+   char buf[PATH_MAX];
+
+   E_OBJECT_CHECK(es);
+   E_OBJECT_TYPE_CHECK(es, E_SHELF_TYPE);
+
+   e_gadcon_orient(es->gadcon, orient);
+   snprintf(buf, sizeof(buf), "e,state,orientation,%s", 
+            e_shelf_orient_string_get(es));
+   edje_object_signal_emit(es->o_base, buf, "e");
+   edje_object_message_signal_process(es->o_base);
+   e_gadcon_location_set_icon_name(es->gadcon->location, _e_shelf_orient_icon_name_get(es));
+}
+
+EAPI void
+e_shelf_locked_set(E_Shelf *es, int lock)
+{
+   if (lock)
+     {
+       e_shelf_toggle(es, 1);
+       es->locked++;
+     }
+   else
+     {
+       if (es->locked > 0)
+        es->locked--;
+       if (!es->locked)
+        e_shelf_toggle(es, es->toggle);
+     }
+}
+
+EAPI void
+e_shelf_urgent_show(E_Shelf *es)
+{
+   e_shelf_toggle(es, 1);
+   es->urgent_show = 1;
+}
+
+/* local functions */
+static void 
+_e_shelf_cb_free(E_Shelf *es)
+{
+   _shelves = eina_list_remove(_shelves, es);
+   if (es->name) eina_stringshare_del(es->name);
+   if (es->style) eina_stringshare_del(es->style);
+   if (es->o_event) evas_object_del(es->o_event);
+   if (es->o_base) evas_object_del(es->o_base);
+   free(es);
+}
+
+static void
+_e_shelf_gadcon_min_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__)
+{
+   return;
+}
+
+static void
+_e_shelf_gadcon_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h)
+{
+   E_Shelf *es;
+   Evas_Coord nx, ny, nw, nh, ww, hh, wantw, wanth;
+
+   es = data;
+   nx = es->x;
+   ny = es->y;
+   nw = es->w;
+   nh = es->h;
+   ww = hh = 0;
+   evas_object_geometry_get(gc->o_container, NULL, NULL, &ww, &hh);
+   switch (gc->orient)
+     {
+      case E_GADCON_ORIENT_FLOAT:
+      case E_GADCON_ORIENT_HORIZ:
+      case E_GADCON_ORIENT_TOP:
+      case E_GADCON_ORIENT_BOTTOM:
+      case E_GADCON_ORIENT_CORNER_TL:
+      case E_GADCON_ORIENT_CORNER_TR:
+      case E_GADCON_ORIENT_CORNER_BL:
+      case E_GADCON_ORIENT_CORNER_BR:
+       if (!es->fit_along) w = ww;
+       if (!es->fit_size) h = hh;
+       break;
+      case E_GADCON_ORIENT_VERT:
+      case E_GADCON_ORIENT_LEFT:
+      case E_GADCON_ORIENT_RIGHT:
+      case E_GADCON_ORIENT_CORNER_LT:
+      case E_GADCON_ORIENT_CORNER_RT:
+      case E_GADCON_ORIENT_CORNER_LB:
+      case E_GADCON_ORIENT_CORNER_RB:
+       if (!es->fit_along) h = hh;
+       if (!es->fit_size) w = ww;
+       break;
+      default:
+       break;
+     }
+   e_gadcon_swallowed_min_size_set(gc, w, h);
+   edje_object_size_min_calc(es->o_base, &nw, &nh);
+   wantw = nw;
+   wanth = nh;
+   switch (gc->orient)
+     {
+      case E_GADCON_ORIENT_FLOAT:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = es->x + ((es->w - nw) / 2);
+       break;
+      case E_GADCON_ORIENT_HORIZ:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = es->x + ((es->w - nw) / 2);
+       break;
+      case E_GADCON_ORIENT_VERT:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = es->y + ((es->h - nh) / 2);
+       break;
+      case E_GADCON_ORIENT_LEFT:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = (es->zone->h - nh) / 2;
+       // nx = 0;
+       break;
+      case E_GADCON_ORIENT_RIGHT:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = (es->zone->h - nh) / 2;
+       // nx = es->zone->w - nw;
+       break;
+      case E_GADCON_ORIENT_TOP:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = (es->zone->w - nw) / 2;
+       // ny = 0;
+       break;
+      case E_GADCON_ORIENT_BOTTOM:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = (es->zone->w - nw) / 2;
+       //ny = es->zone->h - nh;
+       break;
+      case E_GADCON_ORIENT_CORNER_TL:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = 0;
+       // ny = 0;
+       break;
+      case E_GADCON_ORIENT_CORNER_TR:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       nx = es->zone->w - nw;
+       // ny = 0;
+       break;
+      case E_GADCON_ORIENT_CORNER_BL:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nw != es->w) nx = 0;
+       // ny = es->zone->h - nh;
+       break;
+      case E_GADCON_ORIENT_CORNER_BR:
+       if (!es->fit_along) nw = es->w;
+       if (!es->fit_size) nh = es->h;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       nx = es->zone->w - nw;
+       //ny = es->zone->h - nh;
+       break;
+      case E_GADCON_ORIENT_CORNER_LT:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = 0;
+       // nx = 0;
+       break;
+      case E_GADCON_ORIENT_CORNER_RT:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = 0;
+       // nx = es->zone->w - nw;
+       break;
+      case E_GADCON_ORIENT_CORNER_LB:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = es->zone->h - nh;
+       // nx = 0;
+       break;
+      case E_GADCON_ORIENT_CORNER_RB:
+       if (!es->fit_along) nh = es->h;
+       if (!es->fit_size) nw = es->w;
+       if (nw > es->zone->w) nw = es->zone->w;
+       if (nh > es->zone->h) nh = es->zone->h;
+       if (nh != es->h) ny = es->zone->h - nh;
+       // nx = es->zone->w - nw;
+       break;
+      default:
+       break;
+     }
+   w -= (wantw - nw);
+   h -= (wanth - nh);
+   e_gadcon_swallowed_min_size_set(gc, w, h);
+   e_shelf_move_resize(es, nx, ny, nw, nh);
+}
+
+static Evas_Object *
+_e_shelf_gadcon_frame_request(void *data, E_Gadcon_Client *gcc, const char *style)
+{
+   E_Shelf *es;
+   Evas_Object *o;
+   char buf[PATH_MAX];
+
+   es = data;
+   o = edje_object_add(gcc->gadcon->evas);
+
+   snprintf(buf, sizeof(buf), "e/shelf/%s/%s", es->style, style);
+   if (!e_theme_edje_object_set(o, "base/theme/shelf", buf))
+     {
+       /* if an inset style (e.g. plain) isn't implemented for a given
+        * shelf style, fall back to the default one. no need for every
+        * theme to implement the plain style */
+       snprintf(buf, sizeof(buf), "e/shelf/default/%s", style);
+       if (!e_theme_edje_object_set(o, "base/theme/shelf", buf))
+         {
+            evas_object_del(o);
+            return NULL;
+         }
+     }
+   snprintf(buf, sizeof(buf), "e,state,orientation,%s", 
+            e_shelf_orient_string_get(es));
+   edje_object_signal_emit(es->o_base, buf, "e");
+   edje_object_message_signal_process(o);
+   return o;
+}
+
+static void
+_e_shelf_cb_locked_set(void *data, int lock)
+{
+   E_Shelf *es;
+
+   es = data;
+   e_shelf_locked_set(es, lock);
+}
+
+static void
+_e_shelf_cb_urgent_show(void *data)
+{
+   E_Shelf *es;
+
+   es = data;
+   e_shelf_urgent_show(es);
+}
+
+static void
+_e_shelf_gadcon_client_remove(void *data, E_Gadcon_Client *gcc)
+{
+   E_Shelf *s;
+   E_Gadcon *gc;
+
+   s = data;
+   gc = s->gadcon;
+   e_gadcon_client_config_del(gc->cf, gcc->cf);
+   e_gadcon_unpopulate(gc);
+   e_gadcon_populate(gc);
+   e_config_save_queue();
+}
+
+static int
+_e_shelf_gadcon_client_add(void *data, const E_Gadcon_Client_Class *cc)
+{
+   E_Shelf *s;
+   E_Gadcon *gc;
+
+   s = data;
+   gc = s->gadcon;
+   if (!e_gadcon_client_config_new(gc, cc->name)) return 0;
+   e_gadcon_unpopulate(gc);
+   e_gadcon_populate(gc);
+   e_config_save_queue();
+   return 1;
+}
+
+static void
+_e_shelf_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn)
+{
+   E_Shelf *es;
+
+   es = data;
+   _e_shelf_menu_append(es, mn);
+}
+
+static void
+_e_shelf_menu_append(E_Shelf *es, E_Menu *mn)
+{
+   E_Menu_Item *mi;
+   E_Menu *subm;
+   const char *name;
+   char buf[256];
+
+   name = e_shelf_orient_string_get (es);
+   snprintf(buf, sizeof(buf), "Shelf %s", name);
+
+   e_shelf_locked_set(es, 1);
+
+   subm = e_menu_new();
+   mi = e_menu_item_new(mn);
+   e_menu_item_label_set(mi, buf);
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
+   e_menu_pre_activate_callback_set(subm, _e_shelf_menu_pre_cb, es);
+   e_object_free_attach_func_set(E_OBJECT(mi), _e_shelf_menu_item_free);
+   e_object_data_set(E_OBJECT(mi), es);
+   e_menu_item_submenu_set(mi, subm);
+}
+
+static void 
+_e_shelf_menu_pre_cb(void *data, E_Menu *m) 
+{
+   E_Shelf *es;
+   E_Menu_Item *mi;
+
+   es = data;
+   e_menu_pre_activate_callback_set(m, NULL, NULL);
+
+   mi = e_menu_item_new(m);
+   if (es->gadcon->editing)
+     e_menu_item_label_set(mi, _("Stop Moving/Resizing Gadgets"));
+   else
+     e_menu_item_label_set(mi, _("Begin Moving/Resizing Gadgets"));
+   e_util_menu_item_theme_icon_set(mi, "transform-scale");
+   e_menu_item_callback_set(mi, _e_shelf_cb_menu_edit, es);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Contents"));
+   e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf");
+   e_menu_item_callback_set(mi, _e_shelf_cb_menu_contents, es);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Settings"));
+   e_util_menu_item_theme_icon_set(mi, "configure");
+   e_menu_item_callback_set(mi, _e_shelf_cb_menu_config, es);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_separator_set(mi, 1);
+
+   mi = e_menu_item_new(m);
+   e_menu_item_label_set(mi, _("Delete"));
+   e_util_menu_item_theme_icon_set(mi, "list-remove");
+   e_menu_item_callback_set(mi, _e_shelf_cb_menu_delete, es);   
+}
+
+static void
+_e_shelf_cb_menu_config(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Shelf *es;
+
+   es = data;
+//   if (!es->config_dialog) e_int_shelf_config(es);
+}
+
+static void
+_e_shelf_cb_menu_edit(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Shelf *es;
+
+   es = data;
+   if (es->gadcon->editing)
+     {
+       e_gadcon_edit_end(es->gadcon);
+       e_shelf_toggle(es, 0);
+     }
+   else
+     {
+       e_shelf_toggle(es, 1);
+       e_gadcon_edit_begin(es->gadcon);
+     }
+}
+
+static void
+_e_shelf_cb_menu_contents(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Shelf *es;
+
+   es = data;
+//   if (!es->gadcon->config_dialog) e_int_gadcon_config_shelf(es->gadcon);
+}
+
+static void
+_e_shelf_cb_confirm_dialog_destroy(void *data)
+{
+   E_Shelf *es;
+
+   es = data;
+   e_object_unref(E_OBJECT(es));
+}
+
+static void
+_e_shelf_cb_confirm_dialog_yes(void *data)
+{
+   E_Config_Shelf *cfg;
+   E_Shelf *es;
+
+   es = data;
+   cfg = es->cfg;
+   if (e_object_is_del(E_OBJECT(es))) return;
+   e_object_del(E_OBJECT(es));
+   e_config->shelves = eina_list_remove(e_config->shelves, cfg);
+   if (cfg->name) eina_stringshare_del(cfg->name);
+   if (cfg->style) eina_stringshare_del(cfg->style);
+   E_FREE(cfg);
+
+   e_config_save_queue();
+}
+
+static void
+_e_shelf_cb_menu_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
+{
+   E_Shelf *es;
+   E_Config_Shelf *cfg;
+
+   es = data;
+   if (e_config->cnfmdlg_disabled) 
+     {
+       cfg = es->cfg;
+       if (e_object_is_del(E_OBJECT(es))) return;
+       e_object_del(E_OBJECT(es));
+       e_config->shelves = eina_list_remove(e_config->shelves, cfg);
+       if (cfg->name) eina_stringshare_del(cfg->name);
+       if (cfg->style) eina_stringshare_del(cfg->style);
+       E_FREE(cfg);
+
+       e_config_save_queue();
+       return;
+     }
+
+   e_object_ref(E_OBJECT(es));
+   /* e_confirm_dialog_show(_("Are you sure you want to delete this shelf?"), "enlightenment", */
+   /*                   _("You requested to delete this shelf.<br>" */
+   /*                        "<br>" */
+   /*                        "Are you sure you want to delete it?"), NULL, NULL, */
+   /*                   _e_shelf_cb_confirm_dialog_yes, NULL, data, NULL,  */
+   /*                   _e_shelf_cb_confirm_dialog_destroy, data); */
+}
+
+static void
+_e_shelf_menu_item_free(void *data)
+{
+   E_Shelf *es;
+
+   es = e_object_data_get(data);
+   e_shelf_locked_set(es, 0);
+}
+
+static const char *
+_e_shelf_orient_icon_name_get(E_Shelf *s)
+{
+   const char *name = NULL;
+
+   switch (s->cfg->orient) 
+     {
+      case E_GADCON_ORIENT_LEFT:
+       name = "preferences-position-left";
+       break;
+      case E_GADCON_ORIENT_RIGHT:
+       name = "preferences-position-right";
+       break;
+      case E_GADCON_ORIENT_TOP:
+       name = "preferences-position-top";
+       break;
+      case E_GADCON_ORIENT_BOTTOM:
+       name = "preferences-position-bottom";
+       break;
+      case E_GADCON_ORIENT_CORNER_TL:
+       name = "preferences-position-top-left";
+       break;
+      case E_GADCON_ORIENT_CORNER_TR:
+       name = "preferences-position-top-right";
+       break;
+      case E_GADCON_ORIENT_CORNER_BL:
+       name = "preferences-position-bottom-left";
+       break;
+      case E_GADCON_ORIENT_CORNER_BR:
+       name = "preferences-position-bottom-right";
+       break;
+      case E_GADCON_ORIENT_CORNER_LT:
+       name = "preferences-position-left-top";
+       break;
+      case E_GADCON_ORIENT_CORNER_RT:
+       name = "preferences-position-right-top";
+       break;
+      case E_GADCON_ORIENT_CORNER_LB:
+       name = "preferences-position-left-bottom";
+       break;
+      case E_GADCON_ORIENT_CORNER_RB:
+       name = "preferences-position-right-bottom";
+       break;
+      default:
+       name = "preferences-desktop-shelf";
+       break;
+     }
+   return name;
+}
diff --git a/src/bin/e_wayland/e_shelf.h b/src/bin/e_wayland/e_shelf.h
new file mode 100644 (file)
index 0000000..ba5db0e
--- /dev/null
@@ -0,0 +1,57 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Shelf E_Shelf;
+
+#else
+# ifndef E_SHELF_H
+#  define E_SHELF_H
+
+#  define E_SHELF_TYPE 0xE0b0101e
+
+struct _E_Shelf
+{
+   E_Object e_obj_inherit;
+
+   int id;
+   int x, y, w, h;
+   int layer, size;
+
+   const char *name, *style;
+
+   E_Popup *popup;
+   E_Zone *zone;
+   E_Gadcon *gadcon;
+
+   Ecore_Evas *ee;
+   Evas *evas;
+   Evas_Object *o_base, *o_event;
+
+   E_Config_Shelf *cfg;
+
+   Eina_Bool fit_along : 1;
+   Eina_Bool fit_size : 1;
+   Eina_Bool hidden : 1;
+   Eina_Bool toggle : 1;
+   Eina_Bool edge : 1;
+   Eina_Bool urgent_show : 1;
+   Eina_Bool locked : 1;
+};
+
+EINTERN int e_shelf_init(void);
+EINTERN int e_shelf_shutdown(void);
+
+EAPI void e_shelf_config_update(void);
+EAPI E_Shelf *e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cfg);
+EAPI E_Shelf *e_shelf_zone_new(E_Zone *zone, const char *name, const char *style, int popup, int layer, int id);
+EAPI void e_shelf_show(E_Shelf *es);
+EAPI void e_shelf_hide(E_Shelf *es);
+EAPI void e_shelf_toggle(E_Shelf *es, Eina_Bool show);
+EAPI void e_shelf_populate(E_Shelf *es);
+EAPI void e_shelf_position_calc(E_Shelf *es);
+EAPI void e_shelf_move_resize(E_Shelf *es, int x, int y, int w, int h);
+EAPI Eina_List *e_shelf_list(void);
+EAPI const char *e_shelf_orient_string_get(E_Shelf *es);
+EAPI void e_shelf_orient(E_Shelf *es, E_Gadcon_Orient orient);
+
+# endif
+#endif
index ad3623e7d21abf2fe3292a30a06538db17ac743e..941aa5100492e815e6eb25a0cf686a090573db90 100644 (file)
@@ -179,15 +179,10 @@ e_surface_repaint_schedule(E_Surface *es)
    E_Output *output;
    Eina_List *l;
 
-   printf("E_Surface Repaint Schedule\n");
-
    EINA_LIST_FOREACH(_e_comp->outputs, l, output)
      {
         if ((es->output == output) || (es->output_mask & (1 << output->id)))
-          {
-             printf("\tSchedule Output Repaint\n");
-             e_output_repaint_schedule(output);
-          }
+          e_output_repaint_schedule(output);
      }
 }
 
diff --git a/src/bin/e_wayland/e_sys.c b/src/bin/e_wayland/e_sys.c
new file mode 100644 (file)
index 0000000..b781f71
--- /dev/null
@@ -0,0 +1,701 @@
+#include "e.h"
+
+/* local subsystem functions */
+static Eina_Bool _e_sys_cb_timer(void *data);
+static Eina_Bool _e_sys_cb_exit(void *data, int type, void *event);
+static void _e_sys_cb_logout_logout(void *data, E_Dialog *dia);
+static void _e_sys_cb_logout_wait(void *data, E_Dialog *dia);
+static void _e_sys_cb_logout_abort(void *data, E_Dialog *dia);
+static Eina_Bool _e_sys_cb_logout_timer(void *data);
+static void _e_sys_logout_after(void);
+static void _e_sys_logout_begin(E_Sys_Action a_after);
+static void _e_sys_current_action(void);
+static void _e_sys_action_failed(void);
+static int _e_sys_action_do(E_Sys_Action a, char *param);
+static void _e_sys_dialog_cb_delete(E_Obj_Dialog * od);
+
+static Ecore_Event_Handler *_e_sys_exe_exit_handler = NULL;
+static Ecore_Exe *_e_sys_halt_check_exe = NULL;
+static Ecore_Exe *_e_sys_reboot_check_exe = NULL;
+static Ecore_Exe *_e_sys_suspend_check_exe = NULL;
+static Ecore_Exe *_e_sys_hibernate_check_exe = NULL;
+static int _e_sys_can_halt = 0;
+static int _e_sys_can_reboot = 0;
+static int _e_sys_can_suspend = 0;
+static int _e_sys_can_hibernate = 0;
+
+static E_Sys_Action _e_sys_action_current = E_SYS_NONE;
+static E_Sys_Action _e_sys_action_after = E_SYS_NONE;
+static Ecore_Exe *_e_sys_exe = NULL;
+static double _e_sys_begin_time = 0.0;
+static double _e_sys_logout_begin_time = 0.0;
+static Ecore_Timer *_e_sys_logout_timer = NULL;
+static E_Obj_Dialog *_e_sys_dialog = NULL;
+static E_Dialog *_e_sys_logout_confirm_dialog = NULL;
+
+static const int E_LOGOUT_AUTO_TIME = 60;
+static const int E_LOGOUT_WAIT_TIME = 15;
+
+/* externally accessible functions */
+EINTERN int
+e_sys_init(void)
+{
+   /* this is not optimal - but it does work cleanly */
+   _e_sys_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+                                                    _e_sys_cb_exit, NULL);
+   /* delay this for 1.0 seconds while the rest of e starts up */
+   ecore_timer_add(1.0, _e_sys_cb_timer, NULL);
+   return 1;
+}
+
+EINTERN int
+e_sys_shutdown(void)
+{
+   if (_e_sys_exe_exit_handler)
+     ecore_event_handler_del(_e_sys_exe_exit_handler);
+   _e_sys_exe_exit_handler = NULL;
+   _e_sys_halt_check_exe = NULL;
+   _e_sys_reboot_check_exe = NULL;
+   _e_sys_suspend_check_exe = NULL;
+   _e_sys_hibernate_check_exe = NULL;
+   return 1;
+}
+
+EAPI int
+e_sys_action_possible_get(E_Sys_Action a)
+{
+   switch (a)
+     {
+      case E_SYS_EXIT:
+      case E_SYS_RESTART:
+      case E_SYS_EXIT_NOW:
+       return 1;
+      case E_SYS_LOGOUT:
+       return 1;
+      case E_SYS_HALT:
+      case E_SYS_HALT_NOW:
+       return _e_sys_can_halt;
+      case E_SYS_REBOOT:
+       return _e_sys_can_reboot;
+      case E_SYS_SUSPEND:
+       return _e_sys_can_suspend;
+      case E_SYS_HIBERNATE:
+       return _e_sys_can_hibernate;
+      default:
+       return 0;
+     }
+   return 0;
+}
+
+EAPI int
+e_sys_action_do(E_Sys_Action a, char *param)
+{
+   int ret = 0;
+
+   if (_e_sys_action_current != E_SYS_NONE)
+     {
+       _e_sys_current_action();
+       return 0;
+     }
+   switch (a)
+     {
+      case E_SYS_EXIT:
+      case E_SYS_RESTART:
+      case E_SYS_EXIT_NOW:
+      case E_SYS_LOGOUT:
+      case E_SYS_SUSPEND:
+      case E_SYS_HIBERNATE:
+      case E_SYS_HALT_NOW:
+       ret = _e_sys_action_do(a, param);
+       break;
+      case E_SYS_HALT:
+      case E_SYS_REBOOT:
+       if (!e_util_immortal_check()) _e_sys_logout_begin(a);
+       return 1;
+       break;
+      default:
+        break;
+     }
+
+   if (ret) _e_sys_action_current = a;
+   else _e_sys_action_current = E_SYS_NONE;
+
+   return ret;
+}
+
+static Eina_List *extra_actions = NULL;
+
+EAPI E_Sys_Con_Action *
+e_sys_con_extra_action_register(const char *label,
+                                const char *icon_group,
+                                const char *button_name,
+                                void (*func) (void *data),
+                                const void *data)
+{
+   E_Sys_Con_Action *sca;
+   
+   sca = E_NEW(E_Sys_Con_Action, 1);
+   if (label)
+     sca->label = eina_stringshare_add(label);
+   if (icon_group)
+     sca->icon_group = eina_stringshare_add(icon_group);
+   if (button_name)
+     sca->button_name = eina_stringshare_add(button_name);
+   sca->func = func;
+   sca->data = data;
+   extra_actions = eina_list_append(extra_actions, sca);
+   return sca;
+}
+
+EAPI void
+e_sys_con_extra_action_unregister(E_Sys_Con_Action *sca)
+{
+   extra_actions = eina_list_remove(extra_actions, sca);
+   if (sca->label) eina_stringshare_del(sca->label);
+   if (sca->icon_group) eina_stringshare_del(sca->icon_group);
+   if (sca->button_name) eina_stringshare_del(sca->button_name);
+   free(sca);
+}
+
+EAPI const Eina_List *
+e_sys_con_extra_action_list_get(void)
+{
+   return extra_actions;
+}
+
+/* local subsystem functions */
+static Eina_Bool
+_e_sys_cb_timer(void *data __UNUSED__)
+{
+   /* exec out sys helper and ask it to test if we are allowed to do these
+    * things
+    */
+   char buf[PATH_MAX];
+
+//   e_init_status_set(_("Checking System Permissions"));
+   snprintf(buf, sizeof(buf), 
+            "%s/enlightenment/utils/enlightenment_sys -t halt", 
+            e_prefix_lib_get());
+   _e_sys_halt_check_exe = ecore_exe_run(buf, NULL);
+   snprintf(buf, sizeof(buf), 
+            "%s/enlightenment/utils/enlightenment_sys -t reboot", 
+            e_prefix_lib_get());
+   _e_sys_reboot_check_exe = ecore_exe_run(buf, NULL);
+   snprintf(buf, sizeof(buf), 
+            "%s/enlightenment/utils/enlightenment_sys -t suspend", 
+            e_prefix_lib_get());
+   _e_sys_suspend_check_exe = ecore_exe_run(buf, NULL);
+   snprintf(buf, sizeof(buf), 
+            "%s/enlightenment/utils/enlightenment_sys -t hibernate", 
+            e_prefix_lib_get());
+   _e_sys_hibernate_check_exe = ecore_exe_run(buf, NULL);
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_e_sys_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Exe_Event_Del *ev;
+
+   ev = event;
+   if ((_e_sys_exe) && (ev->exe == _e_sys_exe))
+     {
+       if (ev->exit_code != 0) _e_sys_action_failed();
+       if (((_e_sys_action_current != E_SYS_HALT) &&
+            (_e_sys_action_current != E_SYS_HALT_NOW) &&
+            (_e_sys_action_current != E_SYS_REBOOT)) ||
+           (ev->exit_code != 0))
+         {
+            if (_e_sys_dialog)
+              {
+                 e_object_del(E_OBJECT(_e_sys_dialog));
+                 _e_sys_dialog = NULL;
+              }
+         }
+       _e_sys_action_current = E_SYS_NONE;
+       _e_sys_exe = NULL;
+       return ECORE_CALLBACK_RENEW;
+     }
+   if ((_e_sys_halt_check_exe) && (ev->exe == _e_sys_halt_check_exe))
+     {
+//     e_init_status_set(_("System Check Done"));
+       /* exit_code: 0 == OK, 5 == suid root removed, 7 == group id error
+        * 10 == permission denied, 20 == action undefined */
+       if (ev->exit_code == 0)
+         {
+            _e_sys_can_halt = 1;
+            _e_sys_halt_check_exe = NULL;
+         }
+     }
+   else if ((_e_sys_reboot_check_exe) && (ev->exe == _e_sys_reboot_check_exe))
+     {
+//     e_init_status_set(_("System Check Done"));
+       if (ev->exit_code == 0)
+         {
+            _e_sys_can_reboot = 1;
+            _e_sys_reboot_check_exe = NULL;
+         }
+     }
+   else if ((_e_sys_suspend_check_exe) && (ev->exe == _e_sys_suspend_check_exe))
+     {
+//     e_init_status_set(_("System Check Done"));
+       if (ev->exit_code == 0)
+         {
+            _e_sys_can_suspend = 1;
+            _e_sys_suspend_check_exe = NULL;
+         }
+     }
+   else if ((_e_sys_hibernate_check_exe) && (ev->exe == _e_sys_hibernate_check_exe))
+     {
+//     e_init_status_set(_("System Check Done"));
+       if (ev->exit_code == 0)
+         {
+            _e_sys_can_hibernate = 1;
+            _e_sys_hibernate_check_exe = NULL;
+         }
+     }
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_e_sys_cb_logout_logout(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (_e_sys_logout_timer)
+     {
+       ecore_timer_del(_e_sys_logout_timer);
+       _e_sys_logout_timer = NULL;
+     }
+   _e_sys_logout_begin_time = 0.0;
+   _e_sys_logout_after();
+   e_object_del(E_OBJECT(dia));
+   _e_sys_logout_confirm_dialog = NULL;
+}
+
+static void
+_e_sys_cb_logout_wait(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer);
+   _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL);
+   _e_sys_logout_begin_time = ecore_time_get();
+   e_object_del(E_OBJECT(dia));
+   _e_sys_logout_confirm_dialog = NULL;
+}
+
+static void
+_e_sys_cb_logout_abort(void *data __UNUSED__, E_Dialog *dia)
+{
+   if (_e_sys_logout_timer)
+     {
+       ecore_timer_del(_e_sys_logout_timer);
+       _e_sys_logout_timer = NULL;
+     }
+   _e_sys_logout_begin_time = 0.0;
+   e_object_del(E_OBJECT(dia));
+   _e_sys_logout_confirm_dialog = NULL;
+   _e_sys_action_current = E_SYS_NONE;
+   _e_sys_action_after = E_SYS_NONE;
+   if (_e_sys_dialog)
+     {
+       e_object_del(E_OBJECT(_e_sys_dialog));
+       _e_sys_dialog = NULL;
+     }
+}
+
+static void
+_e_sys_logout_confirm_dialog_update(int remaining)
+{
+   char txt[PATH_MAX];
+
+   if (!_e_sys_logout_confirm_dialog)
+     {
+       fputs("ERROR: updating logout confirm dialog, but none exists!\n",
+             stderr);
+       return;
+     }
+
+   snprintf(txt, sizeof(txt),
+           _("Logout is taking too long.<br>"
+             "Some applications refuse to close.<br>"
+             "Do you want to finish the logout<br>"
+             "anyway without closing these<br>"
+             "applications first?<br><br>"
+             "Auto logout in %d seconds."), remaining);
+
+   e_dialog_text_set(_e_sys_logout_confirm_dialog, txt);
+}
+
+static Eina_Bool
+_e_sys_cb_logout_timer(void *data __UNUSED__)
+{
+   /* Eina_List *l; */
+   /* E_Border *bd; */
+   int pending = 0;
+
+   /* EINA_LIST_FOREACH(e_border_client_list(), l, bd) */
+   /*   { */
+   /*  if (!bd->internal) pending++; */
+   /*   } */
+   if (pending == 0) goto after;
+   else if (_e_sys_logout_confirm_dialog)
+     {
+       int remaining;
+
+        remaining = E_LOGOUT_AUTO_TIME -
+         round(ecore_loop_time_get() - _e_sys_logout_begin_time);
+       /* it has taken 60 (E_LOGOUT_AUTO_TIME) seconds of waiting the
+        * confirm dialog and we still have apps that will not go
+        * away. Do the action as user may be far away or forgot it.
+        *
+        * NOTE: this is the behavior for many operating systems and I
+        *       guess the reason is people that hit "shutdown" and
+        *       put their laptops in their backpacks in the hope
+        *       everything will be turned off properly.
+        */
+       if (remaining > 0)
+         {
+            _e_sys_logout_confirm_dialog_update(remaining);
+            return ECORE_CALLBACK_RENEW;
+         }
+       else
+         {
+            _e_sys_cb_logout_logout(NULL, _e_sys_logout_confirm_dialog);
+            return ECORE_CALLBACK_CANCEL;
+         }
+     }
+   else
+     {
+       /* it has taken 15 seconds of waiting and we still have apps that
+        * will not go away
+        */
+       double now = ecore_loop_time_get();
+       if ((now - _e_sys_logout_begin_time) > E_LOGOUT_WAIT_TIME)
+         {
+            E_Dialog *dia;
+
+            dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_sys_error_logout_slow");
+            if (dia)
+              {
+                 _e_sys_logout_confirm_dialog = dia;
+                 e_dialog_title_set(dia, _("Logout problems"));
+                 e_dialog_icon_set(dia, "system-log-out", 64);
+                 e_dialog_button_add(dia, _("Logout now"), NULL, 
+                                      _e_sys_cb_logout_logout, NULL);
+                 e_dialog_button_add(dia, _("Wait longer"), NULL, 
+                                      _e_sys_cb_logout_wait, NULL);
+                 e_dialog_button_add(dia, _("Cancel Logout"), NULL, 
+                                      _e_sys_cb_logout_abort, NULL);
+                 e_dialog_button_focus_num(dia, 1);
+                 _e_sys_logout_confirm_dialog_update(E_LOGOUT_AUTO_TIME);
+                 e_win_centered_set(dia->win, 1);
+                 e_dialog_show(dia);
+                 _e_sys_logout_begin_time = now;
+              }
+            return ECORE_CALLBACK_RENEW;
+         }
+     }
+   return ECORE_CALLBACK_RENEW;
+   after:
+   _e_sys_logout_after();
+   _e_sys_logout_timer = NULL;
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_sys_logout_after(void)
+{
+   if (_e_sys_dialog)
+     {
+       e_object_del(E_OBJECT(_e_sys_dialog));
+       _e_sys_dialog = NULL;
+     }
+   _e_sys_action_current = _e_sys_action_after;
+   _e_sys_action_do(_e_sys_action_after, NULL);
+   _e_sys_action_after = E_SYS_NONE;
+}
+
+static void
+_e_sys_logout_begin(E_Sys_Action a_after)
+{
+   /* Eina_List *l; */
+   /* E_Border *bd; */
+   E_Obj_Dialog *od;
+
+   /* start logout - at end do the e_after action */
+   od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
+                        _("Logout in progress"), "E", "_sys_logout");
+   e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/logout");
+   e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
+                                 _("Logout in progress.<br>"
+                                   "<hilight>Please wait.</hilight>"));
+   e_obj_dialog_show(od);
+   e_obj_dialog_icon_set(od, "system-log-out");
+   if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
+   _e_sys_dialog = od;
+   _e_sys_action_after = a_after;
+   /* EINA_LIST_FOREACH(e_border_client_list(), l, bd) */
+   /*   { */
+   /*  e_border_act_close_begin(bd); */
+   /*   } */
+   /* and poll to see if all pending windows are gone yet every 0.5 sec */
+   _e_sys_logout_begin_time = ecore_time_get();
+   if (_e_sys_logout_timer) ecore_timer_del(_e_sys_logout_timer);
+   _e_sys_logout_timer = ecore_timer_add(0.5, _e_sys_cb_logout_timer, NULL);
+}
+
+static void
+_e_sys_current_action(void)
+{
+   /* display dialog that currently an action is in progress */
+   E_Dialog *dia;
+
+   dia = e_dialog_new(e_container_current_get(e_manager_current_get()), 
+                      "E", "_sys_error_action_busy");
+   if (!dia) return;
+
+   e_dialog_title_set(dia, _("Enlightenment is busy with another request"));
+   e_dialog_icon_set(dia, "enlightenment/sys", 64);
+   switch (_e_sys_action_current)
+     {
+      case E_SYS_LOGOUT:
+       e_dialog_text_set(dia, _("Logging out.<br>"
+                                 "You cannot perform other system actions<br>"
+                                 "once a logout has begun."));
+       break;
+      case E_SYS_HALT:
+      case E_SYS_HALT_NOW:
+       e_dialog_text_set(dia, _("Powering off.<br>"
+                                 "You cannot do any other system actions<br>"
+                                 "once a shutdown has been started."));
+       break;
+      case E_SYS_REBOOT:
+       e_dialog_text_set(dia, _("Resetting.<br>"
+                                 "You cannot do any other system actions<br>"
+                                 "once a reboot has begun."));
+       break;
+      case E_SYS_SUSPEND:
+       e_dialog_text_set(dia, _("Suspending.<br>"
+                                 "Until suspend is complete you cannot perform<br>"
+                                 "any other system actions."));
+       break;
+      case E_SYS_HIBERNATE:
+       e_dialog_text_set(dia, _("Hibernating.<br>"
+                                 "You cannot perform any other system actions<br>"
+                                 "until this is complete."));
+       break;
+      default:
+       e_dialog_text_set(dia, _("EEK! This should not happen"));
+       break;
+     }
+   e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
+   e_dialog_button_focus_num(dia, 0);
+   e_win_centered_set(dia->win, 1);
+   e_dialog_show(dia);
+}
+
+static void
+_e_sys_action_failed(void)
+{
+   /* display dialog that the current action failed */
+   E_Dialog *dia;
+
+   dia = e_dialog_new(e_container_current_get(e_manager_current_get()), 
+                      "E", "_sys_error_action_failed");
+   if (!dia) return;
+
+   e_dialog_title_set(dia, _("Enlightenment is busy with another request"));
+   e_dialog_icon_set(dia, "enlightenment/sys", 64);
+   switch (_e_sys_action_current)
+     {
+      case E_SYS_HALT:
+      case E_SYS_HALT_NOW:
+       e_dialog_text_set(dia, _("Power off failed."));
+       break;
+      case E_SYS_REBOOT:
+       e_dialog_text_set(dia, _("Reset failed."));
+       break;
+      case E_SYS_SUSPEND:
+       e_dialog_text_set(dia, _("Suspend failed."));
+       break;
+      case E_SYS_HIBERNATE:
+       e_dialog_text_set(dia, _("Hibernate failed."));
+       break;
+      default:
+       e_dialog_text_set(dia, _("EEK! This should not happen"));
+       break;
+     }
+   e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
+   e_dialog_button_focus_num(dia, 0);
+   e_win_centered_set(dia->win, 1);
+   e_dialog_show(dia);
+}
+
+static int
+_e_sys_action_do(E_Sys_Action a, char *param __UNUSED__)
+{
+   char buf[PATH_MAX];
+   E_Obj_Dialog *od;
+
+   switch (a)
+     {
+      case E_SYS_EXIT:
+       // XXX TODO: check for e_fm_op_registry entries and confirm
+       if (!e_util_immortal_check()) 
+          ecore_main_loop_quit();
+        else 
+          return 0;
+       break;
+      case E_SYS_RESTART:
+       // XXX TODO: check for e_fm_op_registry entries and confirm
+        // FIXME: we dont   share out immortal info to restarted e. :(
+//     if (!e_util_immortal_check())
+         {
+            restart = 1;
+            ecore_main_loop_quit();
+         }
+//        else
+//          return 0;
+       break;
+      case E_SYS_EXIT_NOW:
+       exit(0);
+       break;
+      case E_SYS_LOGOUT:
+       // XXX TODO: check for e_fm_op_registry entries and confirm
+       _e_sys_logout_begin(E_SYS_EXIT);
+       break;
+      case E_SYS_HALT:
+      case E_SYS_HALT_NOW:
+       /* shutdown -h now */
+       if (e_util_immortal_check()) return 0;
+       snprintf(buf, sizeof(buf), 
+                 "%s/enlightenment/utils/enlightenment_sys halt", 
+                 e_prefix_lib_get());
+       if (_e_sys_exe)
+         {
+             if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
+                _e_sys_current_action();
+            return 0;
+         }
+       else
+         {
+             _e_sys_begin_time = ecore_time_get();
+            _e_sys_exe = ecore_exe_run(buf, NULL);
+            od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
+                                  _("Power off"), "E", "_sys_halt");
+            e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/halt");
+            e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
+                                           _("Power off.<br>"
+                                             "<hilight>Please wait.</hilight>"));
+            e_obj_dialog_show(od);
+            e_obj_dialog_icon_set(od, "system-shutdown");
+            if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
+            e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
+            _e_sys_dialog = od;
+            /* FIXME: display halt status */
+         }
+       break;
+      case E_SYS_REBOOT:
+       /* shutdown -r now */
+       if (e_util_immortal_check()) return 0;
+       snprintf(buf, sizeof(buf), 
+                 "%s/enlightenment/utils/enlightenment_sys reboot",
+                e_prefix_lib_get());
+       if (_e_sys_exe)
+         {
+             if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
+                _e_sys_current_action();
+            return 0;
+         }
+       else
+         {
+             _e_sys_begin_time = ecore_time_get();
+            _e_sys_exe = ecore_exe_run(buf, NULL);
+            od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
+                                  _("Resetting"), "E", "_sys_reboot");
+            e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/reboot");
+            e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
+                                           _("Resetting.<br>"
+                                             "<hilight>Please wait.</hilight>"));
+            e_obj_dialog_show(od);
+            e_obj_dialog_icon_set(od, "system-restart");
+            if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
+            e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
+            _e_sys_dialog = od;
+            /* FIXME: display reboot status */
+         }
+       break;
+      case E_SYS_SUSPEND:
+       /* /etc/acpi/sleep.sh force */
+       snprintf(buf, sizeof(buf), 
+                 "%s/enlightenment/utils/enlightenment_sys suspend",
+                e_prefix_lib_get());
+       if (_e_sys_exe)
+         {
+             if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
+                _e_sys_current_action();
+            return 0;
+         }
+       else
+         {
+             /* if (e_config->desklock_on_suspend) e_desklock_show(); */
+             
+             _e_sys_begin_time = ecore_time_get();
+            _e_sys_exe = ecore_exe_run(buf, NULL);
+            od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
+                                  _("Suspending"), "E", "_sys_suspend");
+            e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/suspend");
+            e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
+                                           _("Suspending.<br>"
+                                             "<hilight>Please wait.</hilight>"));
+            e_obj_dialog_show(od);
+            e_obj_dialog_icon_set(od, "system-suspend");
+            if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
+            e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
+            _e_sys_dialog = od;
+            /* FIXME: display suspend status */
+         }
+       break;
+      case E_SYS_HIBERNATE:
+       /* /etc/acpi/hibernate.sh force */
+       snprintf(buf, sizeof(buf), 
+                 "%s/enlightenment/utils/enlightenment_sys hibernate",
+                e_prefix_lib_get());
+       if (_e_sys_exe)
+         {
+             if ((ecore_time_get() - _e_sys_begin_time) > 2.0)
+                _e_sys_current_action();
+            return 0;
+         }
+       else
+         {
+             /* if (e_config->desklock_on_suspend) e_desklock_show(); */
+
+             _e_sys_begin_time = ecore_time_get();
+            _e_sys_exe = ecore_exe_run(buf, NULL);
+            od = e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
+                                  _("Hibernating"), "E", "_sys_hibernate");
+            e_obj_dialog_obj_theme_set(od, "base/theme/sys", "e/sys/hibernate");
+            e_obj_dialog_obj_part_text_set(od, "e.textblock.message",
+                                           _("Hibernating.<br>"
+                                             "<hilight>Please wait.</hilight>"));
+            e_obj_dialog_show(od);
+            e_obj_dialog_icon_set(od, "system-suspend-hibernate");
+            if (_e_sys_dialog) e_object_del(E_OBJECT(_e_sys_dialog));
+            _e_sys_dialog = od;
+            e_obj_dialog_cb_delete_set(od, _e_sys_dialog_cb_delete);
+            /* FIXME: display hibernate status */
+         }
+       break;
+      default:
+       return 0;
+     }
+   return 1;
+}
+
+static void 
+_e_sys_dialog_cb_delete(E_Obj_Dialog *od __UNUSED__)
+{
+   /* If we don't NULL out the _e_sys_dialog, then the
+    * ECORE_EXE_EVENT_DEL callback will trigger and segv if the window
+    * is deleted in some other way. */
+   _e_sys_dialog = NULL;
+}
diff --git a/src/bin/e_wayland/e_sys.h b/src/bin/e_wayland/e_sys.h
new file mode 100644 (file)
index 0000000..7f372ec
--- /dev/null
@@ -0,0 +1,48 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Sys_Con_Action E_Sys_Con_Action;
+typedef enum _E_Sys_Action E_Sys_Action;
+
+enum _E_Sys_Action
+{
+   E_SYS_NONE,
+   E_SYS_EXIT,
+   E_SYS_RESTART,
+   E_SYS_EXIT_NOW,
+   E_SYS_LOGOUT,
+   E_SYS_HALT,
+   E_SYS_HALT_NOW,
+   E_SYS_REBOOT,
+   E_SYS_SUSPEND,
+   E_SYS_HIBERNATE
+};
+
+struct _E_Sys_Con_Action
+{
+   const char *label;
+   const char *icon_group;
+   const char *button_name;
+   void (*func) (void *data);
+   const void *data;
+   Eina_Bool disabled : 1;
+};
+
+#else
+#ifndef E_SYS_H
+#define E_SYS_H
+
+EINTERN int e_sys_init(void);
+EINTERN int e_sys_shutdown(void);
+EAPI int e_sys_action_possible_get(E_Sys_Action a);
+EAPI int e_sys_action_do(E_Sys_Action a, char *param);
+
+EAPI E_Sys_Con_Action *e_sys_con_extra_action_register(const char *label,
+                                                       const char *icon_group,
+                                                       const char *button_name,
+                                                       void (*func) (void *data),
+                                                       const void *data);
+EAPI void e_sys_con_extra_action_unregister(E_Sys_Con_Action *sca);
+EAPI const Eina_List *e_sys_con_extra_action_list_get(void);
+    
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_theme_about.c b/src/bin/e_wayland/e_theme_about.c
new file mode 100644 (file)
index 0000000..500824c
--- /dev/null
@@ -0,0 +1,38 @@
+#include "e.h"
+
+/* local subsystem functions */
+static void
+_cb_settings_theme(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   E_Obj_Dialog *od = data;
+
+   e_configure_registry_call("appearance/theme", od->win->con, NULL);
+}
+
+/* local subsystem globals */
+
+/* externally accessible functions */
+
+EAPI E_Theme_About *
+e_theme_about_new(E_Container *con)
+{
+   E_Obj_Dialog *od;
+
+   od = e_obj_dialog_new(con, _("About Theme"), "E", "_theme_about");
+   if (!od) return NULL;
+   e_obj_dialog_obj_theme_set(od, "base/theme", "e/theme/about");
+   e_obj_dialog_obj_part_text_set(od, "e.text.label", _("Close"));
+   e_obj_dialog_obj_part_text_set(od, "e.text.theme", _("Select Theme"));
+   edje_object_signal_callback_add(od->o_bg,
+                                   "e,action,settings,theme", "",
+                                   _cb_settings_theme, od);
+   return (E_Theme_About *)od;
+}
+
+EAPI void
+e_theme_about_show(E_Theme_About *about)
+{
+   e_obj_dialog_show((E_Obj_Dialog *)about);
+   e_obj_dialog_icon_set((E_Obj_Dialog *)about, "preferences-desktop-theme");
+}
+
diff --git a/src/bin/e_wayland/e_theme_about.h b/src/bin/e_wayland/e_theme_about.h
new file mode 100644 (file)
index 0000000..c8a12ba
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Obj_Dialog E_Theme_About;
+
+#else
+#ifndef E_THEME_ABOUT_H
+#define E_THEME_ABOUT_H
+
+EAPI E_Theme_About  *e_theme_about_new  (E_Container *con);
+EAPI void            e_theme_about_show (E_Theme_About *about);
+
+#endif
+#endif
diff --git a/src/bin/e_wayland/e_thumb.c b/src/bin/e_wayland/e_thumb.c
new file mode 100644 (file)
index 0000000..12ab83b
--- /dev/null
@@ -0,0 +1,435 @@
+#include "e.h"
+
+typedef struct _E_Thumb E_Thumb;
+
+struct _E_Thumb
+{
+   int           objid;
+   int           w, h;
+   const char   *file;
+   const char   *key;
+   char         *sort_id;
+   unsigned char queued : 1;
+   unsigned char busy : 1;
+   unsigned char done : 1;
+};
+
+/* local subsystem functions */
+static void         _e_thumb_gen_begin(int objid, const char *file, const char *key, int w, int h);
+static void         _e_thumb_gen_end(int objid);
+static void         _e_thumb_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void         _e_thumb_hash_add(int objid, Evas_Object *obj);
+static void         _e_thumb_hash_del(int objid);
+static Evas_Object *_e_thumb_hash_find(int objid);
+static void         _e_thumb_thumbnailers_kill(void);
+static void         _e_thumb_thumbnailers_kill_cancel(void);
+static Eina_Bool    _e_thumb_cb_kill(void *data);
+static Eina_Bool    _e_thumb_cb_exe_event_del(void *data, int type, void *event);
+
+/* local subsystem globals */
+static Eina_List *_thumbnailers = NULL;
+static Eina_List *_thumbnailers_exe = NULL;
+static Eina_List *_thumb_queue = NULL;
+static int _objid = 0;
+static Eina_Hash *_thumbs = NULL;
+static int _pending = 0;
+static int _num_thumbnailers = 1;
+static Ecore_Event_Handler *_exe_del_handler = NULL;
+static Ecore_Timer *_kill_timer = NULL;
+
+/* externally accessible functions */
+EINTERN int
+e_thumb_init(void)
+{
+   _exe_del_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+                                              _e_thumb_cb_exe_event_del,
+                                              NULL);
+   _thumbs = eina_hash_string_superfast_new(NULL);
+   return 1;
+}
+
+EINTERN int
+e_thumb_shutdown(void)
+{
+   _e_thumb_thumbnailers_kill_cancel();
+   _e_thumb_cb_kill(NULL);
+   if (_exe_del_handler) ecore_event_handler_del(_exe_del_handler);
+   _exe_del_handler = NULL;
+   _thumbnailers = eina_list_free(_thumbnailers);
+   E_FREE_LIST(_thumbnailers_exe, ecore_exe_free);
+   _thumb_queue = eina_list_free(_thumb_queue);
+   _objid = 0;
+   eina_hash_free(_thumbs);
+   _thumbs = NULL;
+   _pending = 0;
+   return 1;
+}
+
+static void
+_thumb_preloaded(void *data, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
+{
+   evas_object_smart_callback_call(data, "e_thumb_gen", NULL);
+}
+
+EAPI Evas_Object *
+e_thumb_icon_add(Evas *evas)
+{
+   Evas_Object *obj;
+   E_Thumb *eth;
+
+   obj = e_icon_add(evas);
+   evas_object_smart_callback_add(obj, "preloaded", _thumb_preloaded, obj);
+   _objid++;
+   eth = E_NEW(E_Thumb, 1);
+   eth->objid = _objid;
+   eth->w = 64;
+   eth->h = 64;
+   evas_object_data_set(obj, "e_thumbdata", eth);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
+                                  _e_thumb_del_hook, NULL);
+   _e_thumb_hash_add(eth->objid, obj);
+   return obj;
+}
+
+EAPI void
+e_thumb_icon_file_set(Evas_Object *obj, const char *file, const char *key)
+{
+   E_Thumb *eth;
+
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+   eina_stringshare_replace(&eth->file, file);
+   eina_stringshare_replace(&eth->key, key);
+   E_FREE(eth->sort_id);
+}
+
+EAPI void
+e_thumb_icon_size_set(Evas_Object *obj, int w, int h)
+{
+   E_Thumb *eth;
+
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+   if ((w < 1) || (h < 1)) return;
+   eth->w = w;
+   eth->h = h;
+}
+
+EAPI void
+e_thumb_icon_begin(Evas_Object *obj)
+{
+   E_Thumb *eth, *eth2;
+   char buf[4096];
+
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+   if (eth->queued) return;
+   if (eth->busy) return;
+   if (eth->done) return;
+   if (!eth->file) return;
+   if (!_thumbnailers)
+     {
+        while ((int)eina_list_count(_thumbnailers_exe) < _num_thumbnailers)
+          {
+             Ecore_Exe *exe;
+
+             snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_thumb --nice=%d", e_prefix_lib_get(),
+                      e_config->thumb_nice);
+             exe = ecore_exe_run(buf, NULL);
+             _thumbnailers_exe = eina_list_append(_thumbnailers_exe, exe);
+          }
+        _thumb_queue = eina_list_append(_thumb_queue, eth);
+        eth->queued = 1;
+        return;
+     }
+   EINA_LIST_FREE(_thumb_queue, eth2)
+     {
+        eth2->queued = 0;
+        eth2->busy = 1;
+        _pending++;
+        if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
+        _e_thumb_gen_begin(eth2->objid, eth2->file, eth2->key, eth2->w, eth2->h);
+     }
+   eth->busy = 1;
+   _pending++;
+   if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
+   _e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h);
+}
+
+EAPI void
+e_thumb_icon_end(Evas_Object *obj)
+{
+   E_Thumb *eth;
+
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+   if (eth->queued)
+     {
+        _thumb_queue = eina_list_remove(_thumb_queue, eth);
+        eth->queued = 0;
+     }
+   if (eth->busy)
+     {
+        _e_thumb_gen_end(eth->objid);
+        eth->busy = 0;
+        _pending--;
+        if (_pending == 0) _e_thumb_thumbnailers_kill();
+     }
+}
+
+EAPI void
+e_thumb_icon_rethumb(Evas_Object *obj)
+{
+   E_Thumb *eth;
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+
+   if (eth->done) eth->done = 0;
+   else e_thumb_icon_end(obj);
+
+   e_thumb_icon_begin(obj);
+}
+
+#define A(v)          (((v) >> 24) & 0xff)
+#define R(v)          (((v) >> 16) & 0xff)
+#define G(v)          (((v) >> 8) & 0xff)
+#define B(v)          (((v)) & 0xff)
+#define PIX(p, x, y)  p[((y) << 2) + (x)]
+#define PIX2(p, x, y) p[((y) << 1) + (x)]
+
+static void
+_e_thumb_key_load(E_Thumb *eth, const char *icon)
+{
+   Eet_File *ef;
+   int size = 0;
+
+   ef = eet_open(icon, EET_FILE_MODE_READ);
+   if (!ef) return;
+   eth->sort_id = eet_read(ef, "/thumbnail/sort_id", &size);
+   if (eth->sort_id)
+     {
+        if (size > 0) eth->sort_id[size - 1] = 0;
+        else
+          {
+             free(eth->sort_id);
+             eth->sort_id = NULL;
+          }
+     }
+   eet_close(ef);
+}
+
+EAPI const char *
+e_thumb_sort_id_get(Evas_Object *obj)
+{
+   E_Thumb *eth;
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return "";
+   if (!eth->sort_id) return "";
+   return eth->sort_id;
+}
+
+EAPI void
+e_thumb_client_data(Ecore_Ipc_Event_Client_Data *e)
+{
+   int objid;
+   char *icon;
+   E_Thumb *eth;
+   Evas_Object *obj;
+
+   if (!eina_list_data_find(_thumbnailers, e->client))
+     _thumbnailers = eina_list_prepend(_thumbnailers, e->client);
+   if (e->minor == 2)
+     {
+        objid = e->ref;
+        icon = e->data;
+        if ((icon) && (e->size > 1) && (icon[e->size - 1] == 0))
+          {
+             obj = _e_thumb_hash_find(objid);
+             if (obj)
+               {
+                  eth = evas_object_data_get(obj, "e_thumbdata");
+                  if (eth)
+                    {
+                       eth->busy = 0;
+                       _pending--;
+                       eth->done = 1;
+                       if (_pending == 0) _e_thumb_thumbnailers_kill();
+                       if (ecore_file_exists(icon))
+                         {
+                            e_icon_file_key_set(obj, icon, "/thumbnail/data");
+                            _e_thumb_key_load(eth, icon);
+                            e_icon_preload_set(obj, 1);
+                         }
+                       evas_object_smart_callback_call(obj, "e_thumb_gen", NULL);
+                    }
+               }
+          }
+     }
+   if (e->minor == 1)
+     {
+        /* hello message */
+        EINA_LIST_FREE(_thumb_queue, eth)
+          {
+             eth->queued = 0;
+             eth->busy = 1;
+             _pending++;
+             if (_pending == 1) _e_thumb_thumbnailers_kill_cancel();
+             _e_thumb_gen_begin(eth->objid, eth->file, eth->key, eth->w, eth->h);
+          }
+     }
+}
+
+EAPI void
+e_thumb_client_del(Ecore_Ipc_Event_Client_Del *e)
+{
+   if (!eina_list_data_find(_thumbnailers, e->client)) return;
+   _thumbnailers = eina_list_remove(_thumbnailers, e->client);
+   if ((!_thumbs) && (!_thumbnailers)) _objid = 0;
+}
+
+/* local subsystem functions */
+static void
+_e_thumb_gen_begin(int objid, const char *file, const char *key, int w, int h)
+{
+   char *buf;
+   int l1, l2;
+   Ecore_Ipc_Client *cli;
+
+   /* send thumb req */
+   l1 = strlen(file);
+   l2 = 0;
+   if (key) l2 = strlen(key);
+   buf = alloca(l1 + 1 + l2 + 1);
+   strcpy(buf, file);
+   if (key) strcpy(buf + l1 + 1, key);
+   else buf[l1 + 1] = 0;
+   cli = eina_list_data_get(_thumbnailers);
+   if (!cli) return;
+   _thumbnailers = eina_list_remove_list(_thumbnailers, _thumbnailers);
+   _thumbnailers = eina_list_append(_thumbnailers, cli);
+   ecore_ipc_client_send(cli, E_IPC_DOMAIN_THUMB, 1, objid, w, h, buf, l1 + 1 + l2 + 1);
+}
+
+static void
+_e_thumb_gen_end(int objid)
+{
+   Eina_List *l;
+   Ecore_Ipc_Client *cli;
+
+   /* send thumb cancel */
+   EINA_LIST_FOREACH(_thumbnailers, l, cli)
+     {
+        ecore_ipc_client_send(cli, E_IPC_DOMAIN_THUMB, 2, objid, 0, 0, NULL, 0);
+     }
+}
+
+static void
+_e_thumb_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   E_Thumb *eth;
+
+   eth = evas_object_data_get(obj, "e_thumbdata");
+   if (!eth) return;
+   evas_object_data_del(obj, "e_thumbdata");
+   _e_thumb_hash_del(eth->objid);
+   if (eth->busy)
+     {
+        _e_thumb_gen_end(eth->objid);
+        eth->busy = 0;
+        _pending--;
+        if (_pending == 0) _e_thumb_thumbnailers_kill();
+     }
+   if (eth->queued)
+     _thumb_queue = eina_list_remove(_thumb_queue, eth);
+   if (eth->file) eina_stringshare_del(eth->file);
+   if (eth->key) eina_stringshare_del(eth->key);
+   free(eth->sort_id);
+   free(eth);
+}
+
+static void
+_e_thumb_hash_add(int objid, Evas_Object *obj)
+{
+   char buf[32];
+
+   snprintf(buf, sizeof(buf), "%i", objid);
+   eina_hash_add(_thumbs, buf, obj);
+}
+
+static void
+_e_thumb_hash_del(int objid)
+{
+   char buf[32];
+
+   snprintf(buf, sizeof(buf), "%i", objid);
+   if (_thumbs) eina_hash_del(_thumbs, buf, NULL);
+   if ((!_thumbs) && (!_thumbnailers)) _objid = 0;
+}
+
+static Evas_Object *
+_e_thumb_hash_find(int objid)
+{
+   char buf[32];
+
+   snprintf(buf, sizeof(buf), "%i", objid);
+   return eina_hash_find(_thumbs, buf);
+}
+
+static void
+_e_thumb_thumbnailers_kill(void)
+{
+   if (_kill_timer) ecore_timer_del(_kill_timer);
+   _kill_timer = ecore_timer_add(1.0, _e_thumb_cb_kill, NULL);
+}
+
+static void
+_e_thumb_thumbnailers_kill_cancel(void)
+{
+   if (_kill_timer) ecore_timer_del(_kill_timer);
+   _kill_timer = NULL;
+}
+
+static Eina_Bool
+_e_thumb_cb_kill(void *data __UNUSED__)
+{
+   Eina_List *l;
+   Ecore_Exe *exe;
+
+   EINA_LIST_FOREACH(_thumbnailers_exe, l, exe)
+     ecore_exe_terminate(exe);
+   _kill_timer = NULL;
+   return ECORE_CALLBACK_DONE;
+}
+
+static Eina_Bool
+_e_thumb_cb_exe_event_del(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Exe_Event_Del *ev;
+   Ecore_Exe *exe;
+   Eina_List *l;
+
+   ev = event;
+   EINA_LIST_FOREACH(_thumbnailers_exe, l, exe)
+     {
+        if (exe == ev->exe)
+          {
+             _thumbnailers_exe = eina_list_remove_list(_thumbnailers_exe, l);
+             break;
+          }
+     }
+   if ((!_thumbnailers_exe) && (_thumb_queue))
+     {
+        while ((int)eina_list_count(_thumbnailers_exe) < _num_thumbnailers)
+          {
+             Ecore_Exe *exe_thumb;
+             char buf[4096];
+
+             snprintf(buf, sizeof(buf), "%s/enlightenment/utils/enlightenment_thumb --nice=%d", e_prefix_lib_get(),
+                      e_config->thumb_nice);
+             exe_thumb = ecore_exe_run(buf, NULL);
+             _thumbnailers_exe = eina_list_append(_thumbnailers_exe, exe_thumb);
+          }
+     }
+   return ECORE_CALLBACK_PASS_ON;
+}
+
diff --git a/src/bin/e_wayland/e_thumb.h b/src/bin/e_wayland/e_thumb.h
new file mode 100644 (file)
index 0000000..8a17936
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef E_TYPEDEFS
+
+#else
+#ifndef E_THUMB_H
+#define E_THUMB_H
+
+
+EINTERN int                   e_thumb_init(void);
+EINTERN int                   e_thumb_shutdown(void);
+
+EAPI Evas_Object          *e_thumb_icon_add(Evas *evas);
+EAPI void                  e_thumb_icon_file_set(Evas_Object *obj, const char *file, const char *key);
+EAPI void                  e_thumb_icon_size_set(Evas_Object *obj, int w, int h);
+EAPI void                  e_thumb_icon_begin(Evas_Object *obj);
+EAPI void                  e_thumb_icon_end(Evas_Object *obj);
+EAPI void                 e_thumb_icon_rethumb(Evas_Object *obj);
+EAPI const char           *e_thumb_sort_id_get(Evas_Object *obj);
+
+EAPI void                  e_thumb_client_data(Ecore_Ipc_Event_Client_Data *e);
+EAPI void                  e_thumb_client_del(Ecore_Ipc_Event_Client_Del *e);
+
+#endif
+#endif
index f59e607b2cbe2cc3d9154b4f53f428fc152774ee..bf91924f1eea9defb272441c95eb48d6dbedceca 100644 (file)
@@ -1,10 +1,19 @@
 #include "e.h"
 
-/* local variables */
-static Ecore_Timer *_e_util_dummy_timer = NULL;
-
 /* local function prototypes */
+static Eina_Bool _e_util_cb_delayed_del(void *data);
 static Eina_Bool _e_util_wakeup_cb(void *data);
+static int _e_util_menu_item_fdo_icon_set(E_Menu_Item *mi, const char *icon);
+static int _e_util_menu_item_edje_icon_set(E_Menu_Item *mi, const char *name, Eina_Bool fallback);
+static Evas_Object *_e_util_icon_add(const char *path, Evas *evas, int size);
+static int _e_util_icon_fdo_set(Evas_Object *obj, const char *icon);
+static int _e_util_icon_theme_set(Evas_Object *obj, const char *icon, Eina_Bool fallback);
+static Efreet_Desktop *_e_util_default_terminal_get(const char *defaults_list);
+
+/* local variables */
+static Ecore_Timer *_e_util_dummy_timer = NULL;
+static char *prev_ld_library_path = NULL;
+static char *prev_path = NULL;
 
 /* external variables */
 EAPI E_Path *path_data = NULL;
@@ -16,45 +25,613 @@ EAPI E_Path *path_modules = NULL;
 EAPI E_Path *path_backgrounds = NULL;
 EAPI E_Path *path_messages = NULL;
 
+EAPI void 
+e_util_wakeup(void)
+{
+   if (_e_util_dummy_timer) return;
+   _e_util_dummy_timer = ecore_timer_add(0.0, _e_util_wakeup_cb, NULL);
+}
+
 EAPI void 
 e_util_env_set(const char *var, const char *val)
 {
    if (val)
      {
 #ifdef HAVE_SETENV
-        setenv(var, val, 1);
+       setenv(var, val, 1);
 #else
-        char buf[8192];
+       char buf[8192];
 
-        snprintf(buf, sizeof(buf), "%s=%s", var, val);
-        if (getenv(var))
-          putenv(buf);
-        else
-          putenv(strdup(buf));
+       snprintf(buf, sizeof(buf), "%s=%s", var, val);
+       if (getenv(var))
+         putenv(buf);
+       else
+         putenv(strdup(buf));
 #endif
      }
    else
      {
 #ifdef HAVE_UNSETENV
-        unsetenv(var);
+       unsetenv(var);
 #else
-        if (getenv(var)) putenv(var);
+       if (getenv(var)) putenv(var);
 #endif
      }
 }
 
-EAPI int
+EAPI void 
+e_util_dialog_internal(const char *title, const char *txt)
+{
+   E_Dialog *dia;
+
+   dia = 
+     e_dialog_new(e_container_current_get(e_manager_current_get()), 
+                  "E", "_error_dialog");
+   if (!dia) return;
+   e_dialog_title_set(dia, title);
+   e_dialog_text_set(dia, txt);
+   e_dialog_icon_set(dia, "dialog-error", 64);
+   e_dialog_button_add(dia, _("OK"), NULL, NULL, NULL);
+   e_dialog_button_focus_num(dia, 0);
+   e_win_centered_set(dia->win, EINA_TRUE);
+   e_dialog_show(dia);
+}
+
+EAPI int 
 e_util_strcmp(const char *s1, const char *s2)
 {
-   if ((s1) && (s2))
+   if ((s1) && (s2)) return strcmp(s1, s2);
+   return 0x7fffffff;
+}
+
+EAPI int 
+e_util_immortal_check(void)
+{
+   return 0;
+}
+
+EAPI const char *
+e_util_filename_escape(const char *filename)
+{
+   const char *p;
+   char *q;
+   static char buf[PATH_MAX];
+
+   if (!filename) return NULL;
+   p = filename;
+   q = buf;
+   while (*p)
      {
-        if (s1 == s2) return 0;
-        return strcmp(s1, s2);
+       if ((q - buf) > 4090) return NULL;
+       if (
+           (*p == ' ') || (*p == '\t') || (*p == '\n') ||
+           (*p == '\\') || (*p == '\'') || (*p == '\"') ||
+           (*p == ';') || (*p == '!') || (*p == '#') ||
+           (*p == '$') || (*p == '%') || (*p == '&') ||
+           (*p == '*') || (*p == '(') || (*p == ')') ||
+           (*p == '[') || (*p == ']') || (*p == '{') ||
+           (*p == '}') || (*p == '|') || (*p == '<') ||
+           (*p == '>') || (*p == '?')
+           )
+         {
+            *q = '\\';
+            q++;
+         }
+       *q = *p;
+       q++;
+       p++;
      }
-   return 0x7fffffff;
+   *q = 0;
+   return buf;
+}
+
+EAPI void 
+e_util_defer_object_del(E_Object *obj)
+{
+   if (stopping)
+     e_object_del(obj);
+   else
+     ecore_idle_enterer_before_add(_e_util_cb_delayed_del, obj);
+}
+
+EAPI Evas_Object *
+e_util_icon_add(const char *path, Evas *evas)
+{
+   Evas_Object *o = NULL;
+   const char *ext;
+   int size = 64;
+
+   if (!path) return NULL;
+   if (!ecore_file_exists(path)) return NULL;
+
+   o = e_icon_add(evas);
+   e_icon_scale_size_set(o, size); 
+   e_icon_preload_set(o, 1);
+   ext = strrchr(path, '.');
+   if (ext)
+     {
+       if (!strcmp(ext, ".edj"))
+         e_icon_file_edje_set(o, path, "icon");
+       else
+         e_icon_file_set(o, path);
+     }
+   else
+     e_icon_file_set(o, path);
+   e_icon_fill_inside_set(o, 1);
+
+   return o;
+}
+
+EAPI Evas_Object *
+e_util_icon_theme_icon_add(const char *name, unsigned int size, Evas *evas)
+{
+   if (!name) return NULL;
+   if (name[0] == '/') return _e_util_icon_add(name, evas, size);
+   else
+     {
+       Evas_Object *obj;
+       const char *path;
+
+       path = efreet_icon_path_find(e_config->icon_theme, name, size);
+       if (path)
+         {
+            obj = _e_util_icon_add(path, evas, size);
+            return obj;
+         }
+     }
+   return NULL;
+}
+
+EAPI unsigned int
+e_util_icon_size_normalize(unsigned int desired)
+{
+   const unsigned int *itr, known_sizes[] =
+     {
+        16, 22, 24, 32, 36, 48, 64, 72, 96, 128, 192, 256, -1
+     };
+
+   for (itr = known_sizes; *itr > 0; itr++)
+     if (*itr >= desired)
+       return *itr;
+
+   return 256; /* largest know size? */
+}
+
+EAPI int
+e_util_menu_item_theme_icon_set(E_Menu_Item *mi, const char *icon)
+{
+   if (e_config->icon_theme_overrides)
+     {
+       if (_e_util_menu_item_fdo_icon_set(mi, icon))
+         return 1;
+       if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
+         return 1;
+       return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
+     }
+   else
+     {
+       if (_e_util_menu_item_edje_icon_set(mi, icon, EINA_FALSE))
+         return 1;
+       if (_e_util_menu_item_fdo_icon_set(mi, icon))
+         return 1;
+       return _e_util_menu_item_edje_icon_set(mi, icon, EINA_TRUE);
+     }
+}
+
+EAPI const char *
+e_util_winid_str_get(Ecore_Wl_Window *win)
+{
+   const char *vals = "qWeRtYuIoP5-$&<~";
+   static char id[9];
+   unsigned int val;
+
+   val = (unsigned int)win->id;
+   id[0] = vals[(val >> 28) & 0xf];
+   id[1] = vals[(val >> 24) & 0xf];
+   id[2] = vals[(val >> 20) & 0xf];
+   id[3] = vals[(val >> 16) & 0xf];
+   id[4] = vals[(val >> 12) & 0xf];
+   id[5] = vals[(val >> 8) & 0xf];
+   id[6] = vals[(val >> 4) & 0xf];
+   id[7] = vals[(val) & 0xf];
+   id[8] = 0;
+
+   return id;
+}
+
+EAPI E_Container *
+e_util_container_number_get(int num)
+{
+   Eina_List *l;
+   E_Manager *man;
+
+   EINA_LIST_FOREACH(e_manager_list(), l, man)
+     {
+        E_Container *con;
+
+        if ((con = e_container_number_get(man, num)))
+          return con;
+     }
+
+   return NULL;
+}
+
+EAPI E_Zone *
+e_util_container_zone_number_get(int con, int zone)
+{
+   E_Container *c;
+
+   if (!(c = e_util_container_number_get(con)))
+     return NULL;
+
+   return e_container_zone_number_get(c, zone);
+}
+
+EAPI E_Zone *
+e_util_zone_current_get(E_Manager *man)
+{
+   E_Container *con;
+
+   E_OBJECT_CHECK_RETURN(man, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL);
+
+   if ((con = e_container_current_get(man)))
+     {
+       E_Zone *zone;
+
+       zone = e_zone_current_get(con);
+       return zone;
+     }
+   return NULL;
+}
+
+EAPI int
+e_util_glob_match(const char *str, const char *glob)
+{
+   if ((!str) || (!glob)) return 0;
+   if (glob[0] == 0)
+     {
+       if (str[0] == 0) return 1;
+       return 0;
+     }
+   if (!strcmp(glob, "*")) return 1;
+   if (!fnmatch(glob, str, 0)) return 1;
+   return 0;
 }
 
 EAPI int 
+e_util_glob_case_match(const char *str, const char *glob)
+{
+   const char *p;
+   char *tstr, *tglob, *tp;
+
+   if (glob[0] == 0)
+     {
+       if (str[0] == 0) return 1;
+       return 0;
+     }
+   if (!strcmp(glob, "*")) return 1;
+   tstr = alloca(strlen(str) + 1);
+   for (tp = tstr, p = str; *p != 0; p++, tp++) *tp = tolower(*p);
+   *tp = 0;
+   tglob = alloca(strlen(glob) + 1);
+   for (tp = tglob, p = glob; *p != 0; p++, tp++) *tp = tolower(*p);
+   *tp = 0;
+   if (!fnmatch(tglob, tstr, 0)) return 1;
+   return 0;
+}
+
+EAPI int 
+e_util_edje_icon_set(Evas_Object *obj, const char *name)
+{
+   const char *file;
+   char buf[PATH_MAX];
+
+   if ((!name) || (!name[0])) return 0;
+   snprintf(buf, sizeof(buf), "e/icons/%s", name);
+   file = e_theme_edje_file_get("base/theme/icons", buf);
+   if (file[0])
+     {
+       edje_object_file_set(obj, file, buf);
+       return 1;
+     }
+   return 0;
+}
+
+EAPI int 
+e_util_icon_theme_set(Evas_Object *obj, const char *icon)
+{
+   if (e_config->icon_theme_overrides)
+     {
+       if (_e_util_icon_fdo_set(obj, icon))
+         return 1;
+       if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
+         return 1;
+       return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
+     }
+   else
+     {
+       if (_e_util_icon_theme_set(obj, icon, EINA_FALSE))
+         return 1;
+       if (_e_util_icon_fdo_set(obj, icon))
+         return 1;
+       return _e_util_icon_theme_set(obj, icon, EINA_TRUE);
+     }
+}
+
+EAPI char *
+e_util_size_string_get(off_t size)
+{
+   double dsize;
+   char buf[256];
+
+   dsize = (double)size;
+   if (dsize < 1024.0) snprintf(buf, sizeof(buf), _("%'.0f Bytes"), dsize);
+   else
+     {
+       dsize /= 1024.0;
+       if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.0f KB"), dsize);
+       else
+         {
+            dsize /= 1024.0;
+            if (dsize < 1024) snprintf(buf, sizeof(buf), _("%'.0f MB"), dsize);
+            else
+              {
+                 dsize /= 1024.0;
+                 snprintf(buf, sizeof(buf), _("%'.1f GB"), dsize);
+              }
+         }
+     }
+   return strdup(buf);
+}
+
+EAPI char *
+e_util_file_time_get(time_t ftime)
+{
+   time_t diff;
+   time_t ltime;
+   char buf[256];
+   char *s = NULL;
+
+   ltime = time(NULL);
+   diff = ltime - ftime;
+   buf[0] = 0;
+   if (ftime > ltime)
+     snprintf(buf, sizeof(buf), _("In the Future"));
+   else
+     {
+       if (diff <= 60)
+         snprintf(buf, sizeof(buf), _("In the last Minute"));
+       else if (diff >= 31526000)
+         snprintf(buf, sizeof(buf), _("%li Years ago"), (diff / 31526000));
+       else if (diff >= 2592000)
+         snprintf(buf, sizeof(buf), _("%li Months ago"), (diff / 2592000));
+       else if (diff >= 604800)
+         snprintf(buf, sizeof(buf), _("%li Weeks ago"), (diff / 604800));
+       else if (diff >= 86400)
+         snprintf(buf, sizeof(buf), _("%li Days ago"), (diff / 86400));
+       else if (diff >= 3600)
+         snprintf(buf, sizeof(buf), _("%li Hours ago"), (diff / 3600));
+       else if (diff > 60)
+         snprintf(buf, sizeof(buf), _("%li Minutes ago"), (diff / 60));
+     }
+
+   if (buf[0])
+     s = strdup(buf);
+   else
+     s = strdup(_("Unknown"));
+   return s;
+}
+
+EAPI void 
+e_util_library_path_strip(void)
+{
+   char *p, *p2;
+
+   p = getenv("LD_LIBRARY_PATH");
+   E_FREE(prev_ld_library_path);
+   if (p)
+     {
+       prev_ld_library_path = strdup(p);
+       p2 = strchr(p, ':');
+       if (p2) p2++;
+       e_util_env_set("LD_LIBRARY_PATH", p2);
+     }
+   p = getenv("PATH");
+   E_FREE(prev_path);
+   if (p)
+     {
+       prev_path = strdup(p);
+       p2 = strchr(p, ':');
+       if (p2) p2++;
+       e_util_env_set("PATH", p2);
+     }
+}
+
+EAPI void 
+e_util_library_path_restore(void)
+{
+   if (prev_ld_library_path)
+     {
+        e_util_env_set("LD_LIBRARY_PATH", prev_ld_library_path);
+        E_FREE(prev_ld_library_path);
+     }
+   if (prev_path)
+     {
+        e_util_env_set("PATH", prev_path);
+        E_FREE(prev_path);
+     }
+}
+
+EAPI void 
+e_util_win_auto_resize_fill(E_Win *win)
+{
+
+}
+
+EAPI Evas_Object *
+e_util_desktop_icon_add(Efreet_Desktop *desktop, unsigned int size, Evas *evas)
+{
+   if ((!desktop) || (!desktop->icon)) return NULL;
+   return e_util_icon_theme_icon_add(desktop->icon, size, evas);
+}
+
+EAPI char *
+e_util_shell_env_path_eval(const char *path)
+{
+   /* evaluate things like:
+    * $HOME/bling -> /home/user/bling
+    * $HOME/bin/$HOSTNAME/blah -> /home/user/bin/localhost/blah
+    * etc. etc.
+    */
+   const char *p, *v2, *v1 = NULL;
+   char buf[PATH_MAX], *pd, *s, *vp;
+   char *v = NULL;
+   int esc = 0, invar = 0;
+
+   for (p = path, pd = buf; (pd < (buf + sizeof(buf) - 1)); p++)
+     {
+       if (invar)
+         {
+            if (!((isalnum(*p)) || (*p == '_')))
+              {
+                 v2 = p;
+                 invar = 0;
+                 if ((v2 - v1) > 1)
+                   {
+                      s = alloca(v2 - v1);
+                      strncpy(s, v1 + 1, v2 - v1 - 1);
+                      s[v2 - v1 - 1] = 0;
+                      if (strncmp(s, "XDG", 3))
+                        v = getenv(s);
+                      else
+                        {
+                           if (!strcmp(s, "XDG_CONFIG_HOME"))
+                             v = (char *)efreet_config_home_get();
+                           else if (!strcmp(s, "XDG_CACHE_HOME"))
+                             v = (char *)efreet_cache_home_get();
+                           else if (!strcmp(s, "XDG_DATA_HOME"))
+                             v = (char *)efreet_data_home_get();
+                        }
+
+                      if (v)
+                        {
+                           vp = v;
+                           while ((*vp) && (pd < (buf + sizeof(buf) - 1)))
+                             {
+                                *pd = *vp;
+                                vp++;
+                                pd++;
+                             }
+                        }
+                   }
+                 if (pd < (buf + sizeof(buf) - 1))
+                   {
+                      *pd = *p;
+                      pd++;
+                   }
+              }
+         }
+       else
+         {
+            if (esc)
+              {
+                 *pd = *p;
+                 pd++;
+              }
+            else
+              {
+                 if (*p == '\\') esc = 1;
+                 else if (*p == '$')
+                   {
+                      invar = 1;
+                      v1 = p;
+                   }
+                 else
+                   {
+                      *pd = *p;
+                      pd++;
+                   }
+              }
+         }
+       if (*p == 0) break;
+     }
+   *pd = 0;
+   return strdup(buf);
+}
+
+EAPI int
+e_util_edje_collection_exists(const char *file, const char *coll)
+{
+   Eina_List *clist, *l;
+   char *str;
+
+   clist = edje_file_collection_list(file);
+   EINA_LIST_FOREACH(clist, l, str)
+     {
+       if (!strcmp(coll, str))
+         {
+            edje_file_collection_list_free(clist);
+            return 1;
+         }
+     }
+   edje_file_collection_list_free(clist);
+   return 0;
+}
+
+EAPI void
+e_util_desktop_menu_item_icon_add(Efreet_Desktop *desktop, unsigned int size, E_Menu_Item *mi)
+{
+   const char *path = NULL;
+
+   if ((!desktop) || (!desktop->icon)) return;
+
+   if (desktop->icon[0] == '/') path = desktop->icon;
+   else path = efreet_icon_path_find(e_config->icon_theme, desktop->icon, size);
+
+   if (path)
+     {
+       const char *ext;
+
+       ext = strrchr(path, '.');
+       if (ext)
+         {
+            if (strcmp(ext, ".edj") == 0)
+              e_menu_item_icon_edje_set(mi, path, "icon");
+            else
+              e_menu_item_icon_file_set(mi, path);
+         }
+       else
+         e_menu_item_icon_file_set(mi, path);
+     }
+}
+
+EAPI int 
+e_util_container_desk_count_get(E_Container *con)
+{
+   Eina_List *zl;
+   E_Zone *zone;
+   int count = 0;
+
+   E_OBJECT_CHECK_RETURN(con, 0);
+   E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, 0);
+
+   EINA_LIST_FOREACH(con->zones, zl, zone)
+     {
+        int x, y;
+        int cx = 0, cy = 0;
+
+        e_zone_desk_count_get(zone, &cx, &cy);
+        for (x = 0; x < cx; x++)
+          {
+             for (y = 0; y < cy; y++)
+               count += 1;
+          }
+     }
+   return count;
+}
+
+EAPI int
 e_util_strcasecmp(const char *s1, const char *s2)
 {
    if ((!s1) && (!s2)) return 0;
@@ -63,17 +640,200 @@ e_util_strcasecmp(const char *s1, const char *s2)
    return strcasecmp(s1, s2);
 }
 
-EAPI void 
-e_util_wakeup(void)
+EAPI Efreet_Desktop *
+e_util_terminal_desktop_get(void)
 {
-   if (_e_util_dummy_timer) return;
-   _e_util_dummy_timer = ecore_timer_add(0.0, _e_util_wakeup_cb, NULL);
+   const char *terms[] =
+   {
+      "terminology.desktop",
+      "xterm.desktop",
+      "rxvt.desktop",
+      "gnome-terminal.desktop",
+      "konsole.desktop",
+      NULL
+   };
+   const char *s;
+   char buf[PATH_MAX];
+   Efreet_Desktop *tdesktop = NULL, *td;
+   Eina_List *l;
+   int i;
+
+   s = efreet_data_home_get();
+   if (s)
+     {
+        snprintf(buf, sizeof(buf), "%s/applications/defaults.list", s);
+        tdesktop = _e_util_default_terminal_get(buf);
+     }
+   if (tdesktop) return tdesktop;
+   EINA_LIST_FOREACH(efreet_data_dirs_get(), l, s)
+     {
+        snprintf(buf, sizeof(buf), "%s/applications/defaults.list", s);
+        tdesktop = _e_util_default_terminal_get(buf);
+        if (tdesktop) return tdesktop;
+     }
+
+   for (i = 0; terms[i]; i++)
+     {
+        tdesktop = efreet_util_desktop_file_id_find(terms[i]);
+        if (tdesktop) return tdesktop;
+     }
+   if (!tdesktop)
+     {
+        l = efreet_util_desktop_category_list("TerminalEmulator");
+        if (l)
+          {
+             // just take first one since above list doesn't work.
+             tdesktop = l->data;
+             EINA_LIST_FREE(l, td)
+               {
+                  // free/unref the desktosp we are not going to use
+                  if (td != tdesktop) efreet_desktop_free(td);
+               }
+          }
+     }
+   return tdesktop;
 }
 
 /* local functions */
 static Eina_Bool
-_e_util_wakeup_cb(void *data EINA_UNUSED)
+_e_util_cb_delayed_del(void *data)
+{
+   e_object_del(E_OBJECT(data));
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_e_util_wakeup_cb(void *data __UNUSED__)
 {
    _e_util_dummy_timer = NULL;
    return ECORE_CALLBACK_CANCEL;
 }
+
+static int
+_e_util_menu_item_fdo_icon_set(E_Menu_Item *mi, const char *icon)
+{
+   const char *path = NULL;
+   unsigned int size;
+
+   if ((!icon) || (!icon[0])) return 0;
+   size = e_util_icon_size_normalize(24 * e_scale);
+   path = efreet_icon_path_find(e_config->icon_theme, icon, size);
+   if (!path) return 0;
+   e_menu_item_icon_file_set(mi, path);
+   return 1;
+}
+
+static int
+_e_util_menu_item_edje_icon_set(E_Menu_Item *mi, const char *name, Eina_Bool fallback)
+{
+   const char *file;
+   char buf[PATH_MAX];
+
+   if ((!name) || (!name[0])) return 0;
+
+   if ((!fallback) && (name[0]=='/') && ecore_file_exists(name))
+     {
+       e_menu_item_icon_edje_set(mi, name, "icon");
+       return 1;
+     }
+   snprintf(buf, sizeof(buf), "e/icons/%s", name);
+
+   if (fallback)
+     file = e_theme_edje_icon_fallback_file_get(buf);
+   else
+     file = e_theme_edje_file_get("base/theme/icons", buf);
+
+   if (file[0])
+     {
+       e_menu_item_icon_edje_set(mi, file, buf);
+       return 1;
+     }
+   return 0;
+}
+
+static Evas_Object *
+_e_util_icon_add(const char *path, Evas *evas, int size)
+{
+   Evas_Object *o = NULL;
+   const char *ext;
+
+   if (!path) return NULL;
+   if (!ecore_file_exists(path)) return NULL;
+
+   o = e_icon_add(evas);
+   e_icon_scale_size_set(o, size); 
+   e_icon_preload_set(o, 1);
+   ext = strrchr(path, '.');
+   if (ext)
+     {
+       if (!strcmp(ext, ".edj"))
+         e_icon_file_edje_set(o, path, "icon");
+       else
+         e_icon_file_set(o, path);
+     }
+   else
+     e_icon_file_set(o, path);
+   e_icon_fill_inside_set(o, 1);
+
+   return o;
+}
+
+static int
+_e_util_icon_fdo_set(Evas_Object *obj, const char *icon)
+{
+   const char *path = NULL;
+   unsigned int size;
+   
+   if ((!icon) || (!icon[0])) return 0;
+   size = e_icon_scale_size_get(obj);
+   if (size < 16) size = 16;
+   size = e_util_icon_size_normalize(size * e_scale);
+
+   path = efreet_icon_path_find(e_config->icon_theme, icon, size);
+   if (!path) return 0;
+
+   e_icon_file_set(obj, path);
+   return 1;
+}
+
+static int
+_e_util_icon_theme_set(Evas_Object *obj, const char *icon, Eina_Bool fallback)
+{
+   const char *file;
+   char buf[PATH_MAX];
+
+   if ((!icon) || (!icon[0])) return 0;
+   snprintf(buf, sizeof(buf), "e/icons/%s", icon);
+
+   if (fallback)
+     file = e_theme_edje_icon_fallback_file_get(buf);
+   else
+     file = e_theme_edje_file_get("base/theme/icons", buf);
+
+   if (file[0])
+     {
+       e_icon_file_edje_set(obj, file, buf);
+       return 1;
+     }
+
+   return 0;
+}
+
+static Efreet_Desktop *
+_e_util_default_terminal_get(const char *defaults_list)
+{
+   Efreet_Desktop *tdesktop = NULL;
+   Efreet_Ini *ini;
+   const char *s;
+
+   ini = efreet_ini_new(defaults_list);
+   if ((ini) && (ini->data) &&
+       (efreet_ini_section_set(ini, "Default Applications")) &&
+       (ini->section))
+     {
+        s = efreet_ini_string_get(ini, "x-scheme-handler/terminal");
+        if (s) tdesktop = efreet_util_desktop_file_id_find(s);
+     }
+   if (ini) efreet_ini_free(ini);
+   return tdesktop;
+}
index cbd984a58a2de7248d07e24ccc96641da96e6695..821b3fe326968651772d84f65e5df15b228133f9 100644 (file)
@@ -3,10 +3,45 @@
 # ifndef E_UTILS_H
 #  define E_UTILS_H
 
+#define e_util_dialog_show(title, args...) \
+{ \
+   char __tmpbuf[PATH_MAX]; \
+   \
+   snprintf(__tmpbuf, sizeof(__tmpbuf), ##args); \
+   e_util_dialog_internal(title, __tmpbuf); \
+}
+
+EAPI void e_util_wakeup(void);
 EAPI void e_util_env_set(const char *var, const char *val);
+EAPI void e_util_dialog_internal(const char *title, const char *txt);
 EAPI int e_util_strcmp(const char *s1, const char *s2);
+EAPI int e_util_immortal_check(void);
+EAPI const char *e_util_filename_escape(const char *filename);
+EAPI void e_util_defer_object_del(E_Object *obj);
+EAPI Evas_Object *e_util_icon_add(const char *path, Evas *evas);
+EAPI Evas_Object *e_util_icon_theme_icon_add(const char *name, unsigned int size, Evas *evas);
+EAPI unsigned int e_util_icon_size_normalize(unsigned int desired);
+EAPI int e_util_menu_item_theme_icon_set(E_Menu_Item *mi, const char *icon);
+EAPI const char *e_util_winid_str_get(Ecore_Wl_Window *win);
+EAPI E_Container *e_util_container_number_get(int num);
+EAPI E_Zone *e_util_container_zone_number_get(int con, int zone);
+EAPI E_Zone *e_util_zone_current_get(E_Manager *man);
+EAPI int e_util_glob_match(const char *str, const char *glob);
+EAPI int e_util_glob_case_match(const char *str, const char *glob);
+EAPI int e_util_edje_icon_set(Evas_Object *obj, const char *name);
+EAPI int e_util_icon_theme_set(Evas_Object *obj, const char *icon);
+EAPI char *e_util_size_string_get(off_t size);
+EAPI char *e_util_file_time_get(time_t ftime);
+EAPI void e_util_library_path_strip(void);
+EAPI void e_util_library_path_restore(void);
+EAPI void e_util_win_auto_resize_fill(E_Win *win);
+EAPI Evas_Object *e_util_desktop_icon_add(Efreet_Desktop *desktop, unsigned int size, Evas *evas);
+EAPI char *e_util_shell_env_path_eval(const char *path);
+EAPI int e_util_edje_collection_exists(const char *file, const char *coll);
+EAPI void e_util_desktop_menu_item_icon_add(Efreet_Desktop *desktop, unsigned int size, E_Menu_Item *mi);
+EAPI int e_util_container_desk_count_get(E_Container *con);
 EAPI int e_util_strcasecmp(const char *s1, const char *s2);
-EAPI void e_util_wakeup(void);
+EAPI Efreet_Desktop *e_util_terminal_desktop_get(void);
 
 # endif
 #endif
diff --git a/src/bin/e_wayland/e_win.c b/src/bin/e_wayland/e_win.c
new file mode 100644 (file)
index 0000000..8f9f70b
--- /dev/null
@@ -0,0 +1,338 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_win_cb_free(E_Win *win);
+static void _e_win_cb_move(Ecore_Evas *ee);
+static void _e_win_cb_resize(Ecore_Evas *ee);
+static void _e_win_cb_delete(Ecore_Evas *ee);
+
+static void _e_win_prop_update(E_Win *win);
+
+EAPI E_Win *
+e_win_new(E_Container *con)
+{
+   E_Win *win;
+   unsigned int parent = 0;
+
+   E_OBJECT_CHECK_RETURN(con, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
+
+   win = E_OBJECT_ALLOC(E_Win, E_WIN_TYPE, _e_win_cb_free);
+   if (!win) return NULL;
+
+   win->x = 0;
+   win->y = 0;
+   win->w = 1;
+   win->h = 1;
+   win->placed = EINA_FALSE;
+   win->min.w = 0;
+   win->min.h = 0;
+   win->max.w = 9999;
+   win->max.h = 9999;
+   win->base.w = 0;
+   win->base.h = 0;
+   win->step_x = 1;
+   win->step_y = 1;
+   win->aspect.min = 0.0;
+   win->aspect.max = 0.0;
+   win->con = con;
+   win->state.centered = EINA_FALSE;
+
+   /* FIXME: Ideally, frame should be false and e_border should handle 
+    * adding the frame */
+
+   parent = ecore_evas_wayland_window_get(con->bg_ee)->id;
+
+   win->ee = e_canvas_new(parent, win->x, win->y, win->w, win->h, 
+                          EINA_FALSE, EINA_TRUE, NULL);
+   e_canvas_add(win->ee);
+
+   ecore_evas_data_set(win->ee, "E_Win", win);
+   ecore_evas_callback_move_set(win->ee, _e_win_cb_move);
+   ecore_evas_callback_resize_set(win->ee, _e_win_cb_resize);
+   ecore_evas_callback_delete_request_set(win->ee, _e_win_cb_delete);
+
+   win->evas = ecore_evas_get(win->ee);
+   ecore_evas_name_class_set(win->ee, "E", "_e_internal_window");
+   ecore_evas_title_set(win->ee, "E");
+
+   /* TODO: create pointer */
+
+   return win;
+}
+
+EAPI void 
+e_win_show(E_Win *win)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   /* TODO: create e_border ? */
+
+   _e_win_prop_update(win);
+   ecore_evas_show(win->ee);
+}
+
+EAPI void 
+e_win_hide(E_Win *win)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   /* TODO: hide border ? */
+   ecore_evas_hide(win->ee);
+}
+
+EAPI void 
+e_win_centered_set(E_Win *win, int centered)
+{
+   E_Zone *zone;
+   int x, y, w, h;
+
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   if ((win->state.centered) && (!centered))
+     {
+        win->state.centered = EINA_FALSE;
+     }
+   else if ((!win->state.centered) && (centered))
+     {
+        win->state.centered = EINA_TRUE;
+     }
+
+   if (!win->state.centered) return;
+
+   zone = e_zone_current_get(win->con);
+   e_zone_useful_geometry_get(zone, &x, &y, &w, &h);
+   printf("Center Window: %d %d\n", 
+          x + (w - win->w) / 2, y + (h - win->h) / 2);
+   ecore_evas_move(win->ee, x + (w - win->w) / 2, y + (h - win->h) / 2);
+}
+
+EAPI void 
+e_win_title_set(E_Win *win, const char *title)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   ecore_evas_title_set(win->ee, title);
+}
+
+EAPI void 
+e_win_move(E_Win *win, int x, int y)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   /* FIXME: e_border ? */
+   win->x = x;
+   win->y = y;
+   ecore_evas_move(win->ee, x, y);
+}
+
+EAPI void 
+e_win_resize(E_Win *win, int w, int h)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   /* FIXME: e_border */
+   win->w = w;
+   win->h = h;
+   ecore_evas_resize(win->ee, w, h);
+}
+
+EAPI void 
+e_win_name_class_set(E_Win *win, const char *name, const char *class)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   ecore_evas_name_class_set(win->ee, name, class);
+}
+
+EAPI void 
+e_win_dialog_set(E_Win *win, int dialog)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   if (win->state.dialog == dialog) return;
+   win->state.dialog = dialog;
+   _e_win_prop_update(win);
+}
+
+EAPI void 
+e_win_move_callback_set(E_Win *win, void (*func)(E_Win *win))
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->cb_move = func;
+}
+
+EAPI void 
+e_win_resize_callback_set(E_Win *win, void (*func)(E_Win *win))
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->cb_resize = func;
+}
+
+EAPI void 
+e_win_delete_callback_set(E_Win *win, void (*func)(E_Win *win))
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->cb_delete = func;
+}
+
+EAPI Evas *
+e_win_evas_get(E_Win *win)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   return win->evas;
+}
+
+EAPI void 
+e_win_size_min_set(E_Win *win, int w, int h)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->min.w = w;
+   win->min.h = h;
+}
+
+EAPI void 
+e_win_size_max_set(E_Win *win, int w, int h)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->max.w = w;
+   win->max.h = h;
+}
+
+EAPI void 
+e_win_size_base_set(E_Win *win, int w, int h)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->base.w = w;
+   win->base.h = h;
+}
+
+EAPI void 
+e_win_step_set(E_Win *win, int x, int y)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   win->step_x = x;
+   win->step_y = y;
+}
+
+EAPI void 
+e_win_borderless_set(E_Win *win, int borderless)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   ecore_evas_borderless_set(win->ee, borderless);
+}
+
+EAPI void 
+e_win_shaped_set(E_Win *win, int shaped)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   ecore_evas_shaped_set(win->ee, shaped);
+}
+
+EAPI void 
+e_win_raise(E_Win *win)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+
+   ecore_evas_raise(win->ee);
+}
+
+EAPI void 
+e_win_border_icon_set(E_Win *win, const char *icon)
+{
+   E_OBJECT_CHECK(win);
+   E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
+}
+
+EAPI E_Win *
+e_win_evas_object_win_get(Evas_Object *obj)
+{
+   Evas *evas;
+   Evas_Object *wobj;
+   E_Win *win;
+   
+   if (!obj) return NULL;
+   evas = evas_object_evas_get(obj);
+   wobj = evas_object_name_find(evas, "E_Win");
+   if (!wobj) return NULL;
+   win = evas_object_data_get(wobj, "E_Win");
+   return win;
+}
+
+/* local functions */
+static void 
+_e_win_cb_free(E_Win *win)
+{
+   if (win->ee)
+     {
+        e_canvas_del(win->ee);
+        ecore_evas_free(win->ee);
+     }
+}
+
+static void 
+_e_win_cb_move(Ecore_Evas *ee)
+{
+   E_Win *win;
+
+   if (!(win = ecore_evas_data_get(ee, "E_Win"))) return;
+   ecore_evas_geometry_get(win->ee, &win->x, &win->y, &win->w, &win->h);
+   if (win->cb_move) win->cb_move(win);
+}
+
+static void 
+_e_win_cb_resize(Ecore_Evas *ee)
+{
+   E_Win *win;
+
+   if (!(win = ecore_evas_data_get(ee, "E_Win"))) return;
+   ecore_evas_geometry_get(win->ee, &win->x, &win->y, &win->w, &win->h);
+   if (win->cb_resize) win->cb_resize(win);
+}
+
+static void 
+_e_win_cb_delete(Ecore_Evas *ee)
+{
+   E_Win *win;
+
+   if (!(win = ecore_evas_data_get(ee, "E_Win"))) return;
+   if (win->cb_delete) win->cb_delete(win);
+}
+
+static void 
+_e_win_prop_update(E_Win *win)
+{
+   if (win->state.dialog)
+     ecore_evas_wayland_type_set(win->ee, ECORE_WL_WINDOW_TYPE_TRANSIENT);
+   else
+     ecore_evas_wayland_type_set(win->ee, ECORE_WL_WINDOW_TYPE_TOPLEVEL);
+}
diff --git a/src/bin/e_wayland/e_win.h b/src/bin/e_wayland/e_win.h
new file mode 100644 (file)
index 0000000..e9a3ccb
--- /dev/null
@@ -0,0 +1,72 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Win E_Win;
+
+#else
+# ifndef E_WIN_H
+#  define E_WIN_H
+
+#  define E_WIN_TYPE 0xE0b01011
+
+struct _E_Win
+{
+   E_Object e_obj_inherit;
+
+   int x, y, w, h;
+
+   E_Container *con;
+   Ecore_Evas *ee;
+   Evas *evas;
+
+   E_Border *border;
+
+   Eina_Bool placed : 1;
+   struct 
+     {
+        int w, h;
+     } min, max, base;
+   int step_x, step_y;
+   struct 
+     {
+        double min, max;
+     } aspect;
+
+   void (*cb_move) (E_Win *win);
+   void (*cb_resize) (E_Win *win);
+   void (*cb_delete) (E_Win *win);
+   void *data;
+
+   struct 
+     {
+        Eina_Bool centered : 1;
+        Eina_Bool dialog : 1;
+        Eina_Bool no_remember : 1;
+     } state;
+};
+
+EAPI E_Win *e_win_new(E_Container *con);
+EAPI void e_win_show(E_Win *win);
+EAPI void e_win_hide(E_Win *win);
+EAPI void e_win_centered_set(E_Win *win, int centered);
+EAPI void e_win_title_set(E_Win *win, const char *title);
+EAPI void e_win_move(E_Win *win, int x, int y);
+EAPI void e_win_resize(E_Win *win, int w, int h);
+EAPI void e_win_name_class_set(E_Win *win, const char *name, const char *class);
+EAPI void e_win_dialog_set(E_Win *win, int dialog);
+EAPI void e_win_move_callback_set(E_Win *win, void (*func)(E_Win *win));
+EAPI void e_win_resize_callback_set(E_Win *win, void (*func)(E_Win *win));
+EAPI void e_win_delete_callback_set(E_Win *win, void (*func)(E_Win *win));
+EAPI Evas *e_win_evas_get(E_Win *win);
+EAPI void e_win_size_min_set(E_Win *win, int w, int h);
+EAPI void e_win_size_max_set(E_Win *win, int w, int h);
+EAPI void e_win_size_base_set(E_Win *win, int w, int h);
+EAPI void e_win_step_set(E_Win *win, int x, int y);
+EAPI void e_win_borderless_set(E_Win *win, int borderless);
+EAPI void e_win_shaped_set(E_Win *win, int shaped);
+EAPI void e_win_raise(E_Win *win);
+EAPI void e_win_border_icon_set(E_Win *win, const char *icon);
+
+EAPI E_Win *e_win_evas_object_win_get(Evas_Object *obj);
+
+# endif
+#endif
diff --git a/src/bin/e_wayland/e_zone.c b/src/bin/e_wayland/e_zone.c
new file mode 100644 (file)
index 0000000..bd5523f
--- /dev/null
@@ -0,0 +1,306 @@
+#include "e.h"
+
+/* local function prototypes */
+static void _e_zone_cb_free(E_Zone *zone);
+static void _e_zone_cb_bg_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
+static void _e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event);
+static void _e_zone_cb_menu_deactivate(void *data EINA_UNUSED, E_Menu *m);
+
+EINTERN int 
+e_zone_init(void)
+{
+   return 1;
+}
+
+EINTERN int 
+e_zone_shutdown(void)
+{
+   return 1;
+}
+
+EAPI E_Zone *
+e_zone_new(E_Container *con, int num, int x, int y, int w, int h)
+{
+   E_Zone *zone;
+   char name[40];
+
+   E_OBJECT_CHECK_RETURN(con, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
+
+   zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_cb_free);
+   if (!zone)
+     {
+        printf("FAILED TO ALLOCATE ZONE\n");
+        return NULL;
+     }
+
+   zone->container = con;
+   zone->x = x;
+   zone->y = y;
+   zone->w = w;
+   zone->h = h;
+   zone->num = num;
+   zone->desk_x_count = 0;
+   zone->desk_y_count = 0;
+   zone->desk_x_current = 0;
+   zone->desk_y_current = 0;
+
+   zone->o_bg_clip = evas_object_rectangle_add(zone->container->bg_evas);
+   evas_object_move(zone->o_bg_clip, zone->x, zone->y);
+   evas_object_resize(zone->o_bg_clip, zone->w, zone->h);
+   evas_object_color_set(zone->o_bg_clip, 255, 255, 255, 255);
+
+   zone->o_bg_event = evas_object_rectangle_add(zone->container->bg_evas);
+   evas_object_clip_set(zone->o_bg_event, zone->o_bg_clip);
+   evas_object_move(zone->o_bg_event, zone->x, zone->y);
+   evas_object_resize(zone->o_bg_event, zone->w, zone->h);
+   evas_object_color_set(zone->o_bg_event, 0, 0, 0, 0);
+   evas_object_repeat_events_set(zone->o_bg_event, 1);
+
+   evas_object_event_callback_add(zone->o_bg_event, EVAS_CALLBACK_MOUSE_DOWN, 
+                                  _e_zone_cb_bg_mouse_down, zone);
+   evas_object_event_callback_add(zone->o_bg_event, EVAS_CALLBACK_MOUSE_UP, 
+                                  _e_zone_cb_bg_mouse_up, zone);
+
+   e_zone_desk_count_set(zone, e_config->zone_desks_x_count, 
+                         e_config->zone_desks_y_count);
+
+   /* TODO: add event handlers */
+
+   snprintf(name, sizeof(name), "Zone %d", zone->num);
+   zone->name = eina_stringshare_add(name);
+
+   con->zones = eina_list_append(con->zones, zone);
+
+   return zone;
+}
+
+EAPI void 
+e_zone_desk_count_set(E_Zone *zone, int x, int y)
+{
+   E_Desk **new_desks;
+   E_Desk *desk;
+   int xx = 0, yy = 0, nx = 0, ny = 0;
+   Eina_Bool moved = EINA_FALSE;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   xx = x;
+   if (xx < 1) xx = 1;
+   yy = y;
+   if (yy < 1) yy = 1;
+
+   if (zone->desk_x_current >= xx) moved = EINA_TRUE;
+   if (zone->desk_y_current >= yy) moved = EINA_TRUE;
+
+   if (moved)
+     {
+        nx = zone->desk_x_current;
+        ny = zone->desk_y_current;
+        if (zone->desk_x_current >= xx) nx = xx - 1;
+        if (zone->desk_y_current >= yy) ny = yy - 1;
+        if (zone->visible)
+          e_desk_show(e_desk_at_xy_get(zone, nx, ny));
+     }
+
+   new_desks = malloc(xx * yy * sizeof(E_Desk *));
+   for (x = 0; x < xx; x++)
+     {
+        for (y = 0; y < yy; y++)
+          {
+             if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
+               desk = zone->desks[x + (y * zone->desk_x_count)];
+             else
+               desk = e_desk_new(zone, x, y);
+             new_desks[x + (y * xx)] = desk;
+          }
+     }
+
+   if (zone->desks) free(zone->desks);
+   zone->desks = new_desks;
+
+   zone->desk_x_count = xx;
+   zone->desk_y_count = yy;
+   e_config->zone_desks_x_count = xx;
+   e_config->zone_desks_y_count = yy;
+   e_config_save_queue();
+
+   /* Cannot call desk_current_get until the zone desk counts have been set
+    * or else we end up with a "white background" because desk_current_get will
+    * return NULL.
+    */
+   desk = e_desk_current_get(zone);
+   if (desk)
+     {
+        desk->visible = 0;
+        if (zone->visible) e_desk_show(desk);
+     }
+}
+
+EAPI void 
+e_zone_show(E_Zone *zone)
+{
+   int x = 0, y = 0;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   if (zone->visible) return;
+
+   evas_object_show(zone->o_bg_clip);
+   evas_object_show(zone->o_bg_event);
+   if (zone->o_bg) evas_object_show(zone->o_bg);
+
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          e_desk_show(zone->desks[x + (y * zone->desk_x_count)]);
+     }
+
+   zone->visible = EINA_TRUE;
+}
+
+EAPI void 
+e_zone_hide(E_Zone *zone)
+{
+   int x = 0, y = 0;
+
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   if (!zone->visible) return;
+
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          e_desk_hide(zone->desks[x + (y * zone->desk_x_count)]);
+     }
+
+   evas_object_hide(zone->o_bg_event);
+   evas_object_hide(zone->o_bg_clip);
+   if (zone->o_bg) evas_object_hide(zone->o_bg);
+
+   zone->visible = EINA_FALSE;
+}
+
+EAPI E_Zone *
+e_zone_current_get(E_Container *con)
+{
+   Eina_List *l = NULL;
+   E_Zone *zone;
+
+   E_OBJECT_CHECK_RETURN(con, NULL);
+   E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
+
+   if (!starting)
+     {
+        int x, y;
+
+        ecore_wl_pointer_xy_get(&x, &y);
+        EINA_LIST_FOREACH(con->zones, l, zone)
+          {
+             if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
+               return zone;
+          }
+     }
+   if (!con->zones) return NULL;
+   return (E_Zone *)eina_list_data_get(con->zones);
+}
+
+EAPI void 
+e_zone_bg_reconfigure(E_Zone *zone)
+{
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE);
+}
+
+EAPI void 
+e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int *w, int *h)
+{
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   if (x) *x = zone->x;
+   if (y) *y = zone->y;
+   if (w) *w = zone->w;
+   if (h) *h = zone->h;
+}
+
+EAPI void 
+e_zone_desk_count_get(E_Zone *zone, int *x, int *y)
+{
+   E_OBJECT_CHECK(zone);
+   E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
+
+   if (x) *x = zone->desk_x_count;
+   if (y) *y = zone->desk_y_count;
+}
+
+/* local functions */
+static void 
+_e_zone_cb_free(E_Zone *zone)
+{
+   E_Container *con;
+   int x = 0, y = 0;
+
+   if (zone->name) eina_stringshare_del(zone->name);
+
+   evas_object_event_callback_del(zone->o_bg_event, EVAS_CALLBACK_MOUSE_DOWN, 
+                                  _e_zone_cb_bg_mouse_down);
+   evas_object_event_callback_del(zone->o_bg_event, EVAS_CALLBACK_MOUSE_UP, 
+                                  _e_zone_cb_bg_mouse_up);
+
+   con = zone->container;
+   con->zones = eina_list_remove(con->zones, zone);
+
+   evas_object_del(zone->o_bg_event);
+   evas_object_del(zone->o_bg_clip);
+   evas_object_del(zone->o_bg);
+   if (zone->o_prev_bg) evas_object_del(zone->o_prev_bg);
+   if (zone->o_trans) evas_object_del(zone->o_trans);
+
+   for (x = 0; x < zone->desk_x_count; x++)
+     {
+        for (y = 0; y < zone->desk_y_count; y++)
+          e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
+     }
+
+   free(zone->desks);
+   free(zone);
+}
+
+static void 
+_e_zone_cb_bg_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Zone *zone;
+
+   if (!(zone = data)) return;
+   printf("Zone Mouse Down\n");
+}
+
+static void 
+_e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event)
+{
+   E_Zone *zone;
+   E_Menu *m;
+   int x, y;
+
+   if (!(zone = data)) return;
+   if (!(m = e_int_menus_main_new())) return;
+
+   m->zone = zone;
+
+   ecore_wl_pointer_xy_get(&x, &y);
+   printf("Zone Mouse Up: %d %d\n", x, y);
+   e_menu_post_deactivate_callback_set(m, _e_zone_cb_menu_deactivate, NULL);
+   e_menu_activate_mouse(m, zone, x, y, 1, 1, E_MENU_POP_DIRECTION_AUTO, 0);
+}
+
+static void 
+_e_zone_cb_menu_deactivate(void *data EINA_UNUSED, E_Menu *m)
+{
+   e_object_del(E_OBJECT(m));
+}
diff --git a/src/bin/e_wayland/e_zone.h b/src/bin/e_wayland/e_zone.h
new file mode 100644 (file)
index 0000000..7cadb50
--- /dev/null
@@ -0,0 +1,67 @@
+#ifdef E_TYPEDEFS
+
+typedef enum _E_Zone_Edge 
+{
+   E_ZONE_EDGE_NONE,
+   E_ZONE_EDGE_LEFT,
+   E_ZONE_EDGE_RIGHT,
+   E_ZONE_EDGE_TOP,
+   E_ZONE_EDGE_BOTTOM,
+   E_ZONE_EDGE_TOP_LEFT,
+   E_ZONE_EDGE_TOP_RIGHT,
+   E_ZONE_EDGE_BOTTOM_RIGHT,
+   E_ZONE_EDGE_BOTTOM_LEFT
+} E_Zone_Edge;
+
+typedef struct _E_Zone E_Zone;
+typedef struct _E_Event_Zone_Edge E_Event_Zone_Edge;
+
+#else
+# ifndef E_ZONE_H
+#  define E_ZONE_H
+
+#  define E_ZONE_TYPE 0xE0b0100d
+
+struct _E_Zone
+{
+   E_Object e_obj_inherit;
+
+   E_Container *container;
+   int x, y, w, h;
+   unsigned int num;
+   const char *name;
+
+   Evas_Object *o_bg, *o_prev_bg, *o_bg_clip, *o_bg_event;
+   Evas_Object *o_trans;
+
+   E_Desk **desks;
+
+   Eina_Bool visible : 1;
+
+   int desk_x_count, desk_y_count;
+   int desk_x_current, desk_y_current;
+
+   Eina_List *popups;
+};
+
+struct _E_Event_Zone_Edge
+{
+   E_Zone *zone;
+   E_Zone_Edge edge;
+   int x, y, modifiers;
+};
+
+EINTERN int e_zone_init(void);
+EINTERN int e_zone_shutdown(void);
+
+EAPI E_Zone *e_zone_new(E_Container *con, int num, int x, int y, int w, int h);
+EAPI void e_zone_desk_count_set(E_Zone *zone, int x, int y);
+EAPI void e_zone_show(E_Zone *zone);
+EAPI void e_zone_hide(E_Zone *zone);
+EAPI E_Zone *e_zone_current_get(E_Container *con);
+EAPI void e_zone_bg_reconfigure(E_Zone *zone);
+EAPI void e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int *w, int *h);
+EAPI void e_zone_desk_count_get(E_Zone *zone, int *x, int *y);
+
+# endif
+#endif