From: Chris Michael Date: Tue, 11 Jun 2013 13:54:50 +0000 (+0100) Subject: Big giant "e18-wayland-only starting to work" commit so I can continue X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=49ba7f21573bc85a635c5e671ed4751e3651a99f;p=platform%2Fupstream%2Fenlightenment.git Big giant "e18-wayland-only starting to work" commit so I can continue from home. Signed-off-by: Chris Michael --- diff --git a/src/bin/e_wayland/Makefile.am b/src/bin/e_wayland/Makefile.am index 2481a61543..5a409e9381 100644 --- a/src/bin/e_wayland/Makefile.am +++ b/src/bin/e_wayland/Makefile.am @@ -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 index 0000000000..2c4f0cc95a --- /dev/null +++ b/src/bin/e_wayland/e_about.c @@ -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", + _( + "Copyright © 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 index 0000000000..7636b8a52f --- /dev/null +++ b/src/bin/e_wayland/e_about.h @@ -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 index 0000000000..6e692613ef --- /dev/null +++ b/src/bin/e_wayland/e_acpi.c @@ -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 index 0000000000..6928245110 --- /dev/null +++ b/src/bin/e_wayland/e_acpi.h @@ -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 index 0000000000..2467f13804 --- /dev/null +++ b/src/bin/e_wayland/e_actions.c @@ -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 index 0000000000..7381d0dcc3 --- /dev/null +++ b/src/bin/e_wayland/e_actions.h @@ -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 index 0000000000..dead6c7434 --- /dev/null +++ b/src/bin/e_wayland/e_alert.h @@ -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 index 0000000000..178e262bf0 --- /dev/null +++ b/src/bin/e_wayland/e_bg.c @@ -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 index 0000000000..fe10d6f34b --- /dev/null +++ b/src/bin/e_wayland/e_bg.h @@ -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 index 0000000000..3adb0e80c5 --- /dev/null +++ b/src/bin/e_wayland/e_bindings.c @@ -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 index 0000000000..e64ea36086 --- /dev/null +++ b/src/bin/e_wayland/e_bindings.h @@ -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 index 0000000000..55790ffc19 --- /dev/null +++ b/src/bin/e_wayland/e_border.c @@ -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; +} diff --git a/src/bin/e_wayland/e_border.h b/src/bin/e_wayland/e_border.h index a966981aa7..c60bf3a013 100644 --- a/src/bin/e_wayland/e_border.h +++ b/src/bin/e_wayland/e_border.h @@ -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 index 0000000000..1ed6383a5d --- /dev/null +++ b/src/bin/e_wayland/e_box.c @@ -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 index 0000000000..75a0e74ad4 --- /dev/null +++ b/src/bin/e_wayland/e_box.h @@ -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 diff --git a/src/bin/e_wayland/e_comp.c b/src/bin/e_wayland/e_comp.c index ac889b7265..e9637f0a0a 100644 --- a/src/bin/e_wayland/e_comp.c +++ b/src/bin/e_wayland/e_comp.c @@ -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, diff --git a/src/bin/e_wayland/e_comp.h b/src/bin/e_wayland/e_comp.h index bb014bebb6..c5e602dc22 100644 --- a/src/bin/e_wayland/e_comp.h +++ b/src/bin/e_wayland/e_comp.h @@ -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 index 0000000000..412ecaa8db --- /dev/null +++ b/src/bin/e_wayland/e_config_dialog.c @@ -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 index 0000000000..7e1e5b4bf5 --- /dev/null +++ b/src/bin/e_wayland/e_config_dialog.h @@ -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 index 0000000000..b8738196f1 --- /dev/null +++ b/src/bin/e_wayland/e_configure.c @@ -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 index 0000000000..4e5466e9a7 --- /dev/null +++ b/src/bin/e_wayland/e_configure.h @@ -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 diff --git a/src/bin/e_wayland/e_container.c b/src/bin/e_wayland/e_container.c index 9f85c9f7db..b44c01f077 100644 --- a/src/bin/e_wayland/e_container.c +++ b/src/bin/e_wayland/e_container.c @@ -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; +} diff --git a/src/bin/e_wayland/e_container.h b/src/bin/e_wayland/e_container.h index 392295b465..c13c5a121c 100644 --- a/src/bin/e_wayland/e_container.h +++ b/src/bin/e_wayland/e_container.h @@ -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 index 0000000000..8bc04012d5 --- /dev/null +++ b/src/bin/e_wayland/e_desk.c @@ -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 index 0000000000..94666f8915 --- /dev/null +++ b/src/bin/e_wayland/e_desk.h @@ -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 index 0000000000..c40473c108 --- /dev/null +++ b/src/bin/e_wayland/e_dialog.c @@ -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 index 0000000000..da7b218a8d --- /dev/null +++ b/src/bin/e_wayland/e_dialog.h @@ -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 index 0000000000..f5a4dc051b --- /dev/null +++ b/src/bin/e_wayland/e_exec.c @@ -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 index 0000000000..2e66aa1089 --- /dev/null +++ b/src/bin/e_wayland/e_exec.h @@ -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 index 0000000000..7c317824fc --- /dev/null +++ b/src/bin/e_wayland/e_exehist.c @@ -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 index 0000000000..27758372ff --- /dev/null +++ b/src/bin/e_wayland/e_exehist.h @@ -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 index 0000000000..bac371a981 --- /dev/null +++ b/src/bin/e_wayland/e_gadcon.c @@ -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 index 0000000000..911cb052c4 --- /dev/null +++ b/src/bin/e_wayland/e_gadcon.h @@ -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 index 0000000000..7d25e97b26 --- /dev/null +++ b/src/bin/e_wayland/e_icon.c @@ -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 index 0000000000..6b33fa534d --- /dev/null +++ b/src/bin/e_wayland/e_icon.h @@ -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 diff --git a/src/bin/e_wayland/e_includes.h b/src/bin/e_wayland/e_includes.h index 1ae7279d66..c2d9d39c1f 100644 --- a/src/bin/e_wayland/e_includes.h +++ b/src/bin/e_wayland/e_includes.h @@ -31,6 +31,33 @@ #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 index 0000000000..6ef214ac97 --- /dev/null +++ b/src/bin/e_wayland/e_int_menus.c @@ -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); +} diff --git a/src/bin/e_wayland/e_int_menus.h b/src/bin/e_wayland/e_int_menus.h index d692f5405f..88c339e2bd 100644 --- a/src/bin/e_wayland/e_int_menus.h +++ b/src/bin/e_wayland/e_int_menus.h @@ -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 index 0000000000..28ebb91f67 --- /dev/null +++ b/src/bin/e_wayland/e_ipc.c @@ -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 index 0000000000..ccb98688e2 --- /dev/null +++ b/src/bin/e_wayland/e_ipc.h @@ -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 index 0000000000..d237a78006 --- /dev/null +++ b/src/bin/e_wayland/e_ipc_codec.c @@ -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 index 0000000000..d03eb95be8 --- /dev/null +++ b/src/bin/e_wayland/e_ipc_codec.h @@ -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 diff --git a/src/bin/e_wayland/e_main.c b/src/bin/e_wayland/e_main.c index 7f18e22b35..1f762d1983 100644 --- a/src/bin/e_wayland/e_main.c +++ b/src/bin/e_wayland/e_main.c @@ -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 index 0000000000..ab6e18ac14 --- /dev/null +++ b/src/bin/e_wayland/e_menu.c @@ -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 index 0000000000..d15f436488 --- /dev/null +++ b/src/bin/e_wayland/e_menu.h @@ -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 diff --git a/src/bin/e_wayland/e_module.c b/src/bin/e_wayland/e_module.c index e38b415f19..4a0cfeba8e 100644 --- a/src/bin/e_wayland/e_module.c +++ b/src/bin/e_wayland/e_module.c @@ -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 index 0000000000..0abed26631 --- /dev/null +++ b/src/bin/e_wayland/e_obj_dialog.c @@ -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 index 0000000000..920aa3bb3e --- /dev/null +++ b/src/bin/e_wayland/e_obj_dialog.h @@ -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 diff --git a/src/bin/e_wayland/e_output.c b/src/bin/e_wayland/e_output.c index cc5fa8ae8d..f3cada4646 100644 --- a/src/bin/e_wayland/e_output.c +++ b/src/bin/e_wayland/e_output.c @@ -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 index 0000000000..9b282a4f26 --- /dev/null +++ b/src/bin/e_wayland/e_popup.c @@ -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 index 0000000000..af2fa4226d --- /dev/null +++ b/src/bin/e_wayland/e_popup.h @@ -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 diff --git a/src/bin/e_wayland/e_renderer.c b/src/bin/e_wayland/e_renderer.c index 2d54c3b59e..c87f0ee46c 100644 --- a/src/bin/e_wayland/e_renderer.c +++ b/src/bin/e_wayland/e_renderer.c @@ -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 index 0000000000..5bbddb7280 --- /dev/null +++ b/src/bin/e_wayland/e_shelf.c @@ -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 index 0000000000..ba5db0e301 --- /dev/null +++ b/src/bin/e_wayland/e_shelf.h @@ -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 diff --git a/src/bin/e_wayland/e_surface.c b/src/bin/e_wayland/e_surface.c index ad3623e7d2..941aa51004 100644 --- a/src/bin/e_wayland/e_surface.c +++ b/src/bin/e_wayland/e_surface.c @@ -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 index 0000000000..b781f71a18 --- /dev/null +++ b/src/bin/e_wayland/e_sys.c @@ -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 index 0000000000..7f372ecb68 --- /dev/null +++ b/src/bin/e_wayland/e_sys.h @@ -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 index 0000000000..500824cd73 --- /dev/null +++ b/src/bin/e_wayland/e_theme_about.c @@ -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 index 0000000000..c8a12ba8f9 --- /dev/null +++ b/src/bin/e_wayland/e_theme_about.h @@ -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 index 0000000000..12ab83b253 --- /dev/null +++ b/src/bin/e_wayland/e_thumb.c @@ -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(ð->file, file); + eina_stringshare_replace(ð->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 index 0000000000..8a17936cc8 --- /dev/null +++ b/src/bin/e_wayland/e_thumb.h @@ -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 diff --git a/src/bin/e_wayland/e_utils.c b/src/bin/e_wayland/e_utils.c index f59e607b2c..bf91924f1e 100644 --- a/src/bin/e_wayland/e_utils.c +++ b/src/bin/e_wayland/e_utils.c @@ -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; +} diff --git a/src/bin/e_wayland/e_utils.h b/src/bin/e_wayland/e_utils.h index cbd984a58a..821b3fe326 100644 --- a/src/bin/e_wayland/e_utils.h +++ b/src/bin/e_wayland/e_utils.h @@ -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 index 0000000000..8f9f70bf1d --- /dev/null +++ b/src/bin/e_wayland/e_win.c @@ -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 index 0000000000..e9a3ccb27a --- /dev/null +++ b/src/bin/e_wayland/e_win.h @@ -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 index 0000000000..bd5523f8b5 --- /dev/null +++ b/src/bin/e_wayland/e_zone.c @@ -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 index 0000000000..7cadb50f34 --- /dev/null +++ b/src/bin/e_wayland/e_zone.h @@ -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