From 0006745e2f14d56fd1cb9bd6bcb9bd3de1a0be9e Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Fri, 19 Feb 2010 03:00:58 +0000 Subject: [PATCH] Readd new illume2 code (ugg, svn is a pita) ;) SVN revision: 46290 --- src/modules/illume-home/Makefile.am | 33 + .../illume-home/e-module-illume-home.edj | Bin 0 -> 37177 bytes src/modules/illume-home/e_busycover.c | 92 + src/modules/illume-home/e_busycover.h | 26 + src/modules/illume-home/e_mod_config.c | 200 ++ src/modules/illume-home/e_mod_config.h | 27 + src/modules/illume-home/e_mod_main.c | 903 +++++++++ src/modules/illume-home/e_mod_main.h | 12 + src/modules/illume-home/module.desktop.in | 8 + src/modules/illume-indicator/Makefile.am | 51 + .../e-module-illume-indicator.edc | 57 + src/modules/illume-indicator/e_mod_ind_win.c | 475 +++++ src/modules/illume-indicator/e_mod_ind_win.h | 32 + src/modules/illume-indicator/e_mod_main.c | 72 + src/modules/illume-indicator/e_mod_main.h | 12 + .../illume-indicator/images/Makefile.am | 4 + .../illume-indicator/images/base_bg.png | Bin 0 -> 125 bytes .../illume-indicator/images/module_icon.png | Bin 0 -> 2815 bytes .../illume-indicator/module.desktop.in | 6 + src/modules/illume-softkey/Makefile.am | 51 + .../e-module-illume-softkey.edc | 133 ++ src/modules/illume-softkey/e_mod_main.c | 76 + src/modules/illume-softkey/e_mod_main.h | 12 + src/modules/illume-softkey/e_mod_sft_win.c | 333 ++++ src/modules/illume-softkey/e_mod_sft_win.h | 24 + src/modules/illume-softkey/images/Makefile.am | 6 + .../illume-softkey/images/module_icon.png | Bin 0 -> 2815 bytes .../illume-softkey/images/shelf_alt_bg.png | Bin 0 -> 1232 bytes .../illume-softkey/images/shelf_alt_over.png | Bin 0 -> 502 bytes .../illume-softkey/images/shelf_alt_shine.png | Bin 0 -> 393 bytes src/modules/illume-softkey/module.desktop.in | 6 + src/modules/illume2/Makefile.am | 80 + src/modules/illume2/doc/Doxyfile | 1349 ++++++++++++++ src/modules/illume2/doc/Makefile.am | 22 + src/modules/illume2/doc/e.css | 273 +++ src/modules/illume2/doc/foot.html | 18 + src/modules/illume2/doc/head.html | 69 + src/modules/illume2/doc/img/e.png | Bin 0 -> 30052 bytes src/modules/illume2/doc/img/edoxy.css | 486 +++++ src/modules/illume2/doc/img/foot_bg.png | Bin 0 -> 173 bytes src/modules/illume2/doc/img/head_bg.png | Bin 0 -> 214 bytes .../doc/img/header_menu_background.png | Bin 0 -> 192 bytes .../doc/img/header_menu_background_last.png | Bin 0 -> 637 bytes .../img/header_menu_current_background.png | Bin 0 -> 1200 bytes .../img/header_menu_unselected_background.png | Bin 0 -> 1596 bytes src/modules/illume2/doc/img/logo.png | Bin 0 -> 3825 bytes src/modules/illume2/e-module-illume2.edc | 25 + src/modules/illume2/e_illume.c | 931 ++++++++++ src/modules/illume2/e_illume.h | 329 ++++ src/modules/illume2/e_illume_private.h | 24 + src/modules/illume2/e_mod_config.c | 262 +++ src/modules/illume2/e_mod_config.h | 11 + src/modules/illume2/e_mod_config_animation.c | 127 ++ src/modules/illume2/e_mod_config_animation.h | 6 + src/modules/illume2/e_mod_config_policy.c | 175 ++ src/modules/illume2/e_mod_config_policy.h | 6 + src/modules/illume2/e_mod_config_windows.c | 221 +++ src/modules/illume2/e_mod_config_windows.h | 6 + src/modules/illume2/e_mod_kbd.c | 564 ++++++ src/modules/illume2/e_mod_kbd.h | 19 + src/modules/illume2/e_mod_kbd_dbus.c | 279 +++ src/modules/illume2/e_mod_kbd_dbus.h | 7 + src/modules/illume2/e_mod_main.c | 127 ++ src/modules/illume2/e_mod_main.h | 10 + src/modules/illume2/e_mod_policy.c | 520 ++++++ src/modules/illume2/e_mod_policy.h | 7 + src/modules/illume2/e_mod_quickpanel.c | 415 +++++ src/modules/illume2/e_mod_quickpanel.h | 13 + src/modules/illume2/e_mod_select_window.c | 277 +++ src/modules/illume2/e_mod_select_window.h | 15 + src/modules/illume2/images/Makefile.am | 3 + src/modules/illume2/images/module_icon.png | Bin 0 -> 2814 bytes src/modules/illume2/keyboards/Makefile.am | 11 + .../keyboards/ignore_built_in_keyboards | 1 + src/modules/illume2/module.desktop.in | 6 + src/modules/illume2/policies/Makefile.am | 2 + .../illume2/policies/illume/Makefile.am | 27 + src/modules/illume2/policies/illume/illume.c | 58 + src/modules/illume2/policies/illume/illume.h | 9 + src/modules/illume2/policies/illume/policy.c | 1607 +++++++++++++++++ src/modules/illume2/policies/illume/policy.h | 34 + 81 files changed, 11082 insertions(+) create mode 100644 src/modules/illume-home/Makefile.am create mode 100644 src/modules/illume-home/e-module-illume-home.edj create mode 100644 src/modules/illume-home/e_busycover.c create mode 100644 src/modules/illume-home/e_busycover.h create mode 100644 src/modules/illume-home/e_mod_config.c create mode 100644 src/modules/illume-home/e_mod_config.h create mode 100644 src/modules/illume-home/e_mod_main.c create mode 100644 src/modules/illume-home/e_mod_main.h create mode 100644 src/modules/illume-home/module.desktop.in create mode 100644 src/modules/illume-indicator/Makefile.am create mode 100644 src/modules/illume-indicator/e-module-illume-indicator.edc create mode 100644 src/modules/illume-indicator/e_mod_ind_win.c create mode 100644 src/modules/illume-indicator/e_mod_ind_win.h create mode 100644 src/modules/illume-indicator/e_mod_main.c create mode 100644 src/modules/illume-indicator/e_mod_main.h create mode 100644 src/modules/illume-indicator/images/Makefile.am create mode 100644 src/modules/illume-indicator/images/base_bg.png create mode 100644 src/modules/illume-indicator/images/module_icon.png create mode 100644 src/modules/illume-indicator/module.desktop.in create mode 100644 src/modules/illume-softkey/Makefile.am create mode 100644 src/modules/illume-softkey/e-module-illume-softkey.edc create mode 100644 src/modules/illume-softkey/e_mod_main.c create mode 100644 src/modules/illume-softkey/e_mod_main.h create mode 100644 src/modules/illume-softkey/e_mod_sft_win.c create mode 100644 src/modules/illume-softkey/e_mod_sft_win.h create mode 100644 src/modules/illume-softkey/images/Makefile.am create mode 100644 src/modules/illume-softkey/images/module_icon.png create mode 100644 src/modules/illume-softkey/images/shelf_alt_bg.png create mode 100644 src/modules/illume-softkey/images/shelf_alt_over.png create mode 100644 src/modules/illume-softkey/images/shelf_alt_shine.png create mode 100644 src/modules/illume-softkey/module.desktop.in create mode 100644 src/modules/illume2/Makefile.am create mode 100644 src/modules/illume2/doc/Doxyfile create mode 100644 src/modules/illume2/doc/Makefile.am create mode 100644 src/modules/illume2/doc/e.css create mode 100644 src/modules/illume2/doc/foot.html create mode 100644 src/modules/illume2/doc/head.html create mode 100644 src/modules/illume2/doc/img/e.png create mode 100644 src/modules/illume2/doc/img/edoxy.css create mode 100644 src/modules/illume2/doc/img/foot_bg.png create mode 100644 src/modules/illume2/doc/img/head_bg.png create mode 100644 src/modules/illume2/doc/img/header_menu_background.png create mode 100644 src/modules/illume2/doc/img/header_menu_background_last.png create mode 100644 src/modules/illume2/doc/img/header_menu_current_background.png create mode 100644 src/modules/illume2/doc/img/header_menu_unselected_background.png create mode 100644 src/modules/illume2/doc/img/logo.png create mode 100644 src/modules/illume2/e-module-illume2.edc create mode 100644 src/modules/illume2/e_illume.c create mode 100644 src/modules/illume2/e_illume.h create mode 100644 src/modules/illume2/e_illume_private.h create mode 100644 src/modules/illume2/e_mod_config.c create mode 100644 src/modules/illume2/e_mod_config.h create mode 100644 src/modules/illume2/e_mod_config_animation.c create mode 100644 src/modules/illume2/e_mod_config_animation.h create mode 100644 src/modules/illume2/e_mod_config_policy.c create mode 100644 src/modules/illume2/e_mod_config_policy.h create mode 100644 src/modules/illume2/e_mod_config_windows.c create mode 100644 src/modules/illume2/e_mod_config_windows.h create mode 100644 src/modules/illume2/e_mod_kbd.c create mode 100644 src/modules/illume2/e_mod_kbd.h create mode 100644 src/modules/illume2/e_mod_kbd_dbus.c create mode 100644 src/modules/illume2/e_mod_kbd_dbus.h create mode 100644 src/modules/illume2/e_mod_main.c create mode 100644 src/modules/illume2/e_mod_main.h create mode 100644 src/modules/illume2/e_mod_policy.c create mode 100644 src/modules/illume2/e_mod_policy.h create mode 100644 src/modules/illume2/e_mod_quickpanel.c create mode 100644 src/modules/illume2/e_mod_quickpanel.h create mode 100644 src/modules/illume2/e_mod_select_window.c create mode 100644 src/modules/illume2/e_mod_select_window.h create mode 100644 src/modules/illume2/images/Makefile.am create mode 100644 src/modules/illume2/images/module_icon.png create mode 100644 src/modules/illume2/keyboards/Makefile.am create mode 100644 src/modules/illume2/keyboards/ignore_built_in_keyboards create mode 100644 src/modules/illume2/module.desktop.in create mode 100644 src/modules/illume2/policies/Makefile.am create mode 100644 src/modules/illume2/policies/illume/Makefile.am create mode 100644 src/modules/illume2/policies/illume/illume.c create mode 100644 src/modules/illume2/policies/illume/illume.h create mode 100644 src/modules/illume2/policies/illume/policy.c create mode 100644 src/modules/illume2/policies/illume/policy.h diff --git a/src/modules/illume-home/Makefile.am b/src/modules/illume-home/Makefile.am new file mode 100644 index 000000000..35bbe3ea6 --- /dev/null +++ b/src/modules/illume-home/Makefile.am @@ -0,0 +1,33 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume-home + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ +e-module-$(MODULE).edj module.desktop + +EXTRA_DIST = $(files_DATA) + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = e_mod_main.c \ + e_mod_main.h \ + e_mod_config.c \ + e_mod_config.h \ + e_busycover.c \ + e_busycover.h + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/illume-home/e-module-illume-home.edj b/src/modules/illume-home/e-module-illume-home.edj new file mode 100644 index 0000000000000000000000000000000000000000..f6dc6094669bab0e502dcd12b5586dfd52653c19 GIT binary patch literal 37177 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 + + cover->o_base = edje_object_add(e_win_evas_get(win)); + if (!e_theme_edje_object_set(cover->o_base, + "base/theme/modules/illume-home", + "modules/illume-home/busycover")) + edje_object_file_set(cover->o_base, buff, "modules/illume-home/busycover"); + edje_object_part_text_set(cover->o_base, "e.text.title", _("LOADING")); + evas_object_move(cover->o_base, win->x, win->y); + evas_object_resize(cover->o_base, win->w, win->h); + evas_object_layer_set(cover->o_base, 999); + return cover; +} + +EAPI E_Busycover_Handle * +e_busycover_push(E_Busycover *cover, const char *msg, const char *icon) +{ + E_Busycover_Handle *handle; + + E_OBJECT_CHECK(cover); + E_OBJECT_TYPE_CHECK_RETURN(cover, E_BUSYCOVER_TYPE, NULL); + + handle = E_NEW(E_Busycover_Handle, 1); + handle->cover = cover; + if (msg) handle->msg = eina_stringshare_add(msg); + if (icon) handle->icon = eina_stringshare_add(icon); + cover->handles = eina_list_append(cover->handles, handle); + edje_object_part_text_set(cover->o_base, "e.text.title", msg); + evas_object_show(cover->o_base); + return handle; +} + +EAPI void +e_busycover_pop(E_Busycover *cover, E_Busycover_Handle *handle) +{ + E_OBJECT_CHECK(cover); + E_OBJECT_TYPE_CHECK(cover, E_BUSYCOVER_TYPE); + if (!eina_list_data_find(cover->handles, handle)) return; + cover->handles = eina_list_remove(cover->handles, handle); + if (handle->msg) eina_stringshare_del(handle->msg); + if (handle->icon) eina_stringshare_del(handle->icon); + E_FREE(handle); + if (cover->handles) + { + handle = cover->handles->data; + edje_object_part_text_set(cover->o_base, "e.text.title", handle->msg); + } + else + evas_object_hide(cover->o_base); +} + +EAPI void +e_busycover_resize(E_Busycover *cover, int w, int h) +{ + E_OBJECT_CHECK(cover); + E_OBJECT_TYPE_CHECK(cover, E_BUSYCOVER_TYPE); + evas_object_resize(cover->o_base, w, h); +} + +/* local function prototypes */ +static void +_e_busycover_cb_free(E_Busycover *cover) +{ + Eina_List *l; + E_Busycover_Handle *handle; + + EINA_LIST_FREE(cover->handles, handle) + { + if (handle->msg) eina_stringshare_del(handle->msg); + if (handle->icon) eina_stringshare_del(handle->icon); + E_FREE(handle); + } + + if (cover->o_base) evas_object_del(cover->o_base); + E_FREE(cover); +} diff --git a/src/modules/illume-home/e_busycover.h b/src/modules/illume-home/e_busycover.h new file mode 100644 index 000000000..35e084984 --- /dev/null +++ b/src/modules/illume-home/e_busycover.h @@ -0,0 +1,26 @@ +#ifndef E_BUSYCOVER_H +# define E_BUSYCOVER_H + +# define E_BUSYCOVER_TYPE 0xE1b0782 + +typedef struct _E_Busycover E_Busycover; +typedef struct _E_Busycover_Handle E_Busycover_Handle; + +struct _E_Busycover +{ + E_Object e_obj_inherit; + Evas_Object *o_base; + Eina_List *handles; +}; +struct _E_Busycover_Handle +{ + E_Busycover *cover; + const char *msg, *icon; +}; + +EAPI E_Busycover *e_busycover_new(E_Win *win); +EAPI E_Busycover_Handle *e_busycover_push(E_Busycover *cover, const char *msg, const char *icon); +EAPI void e_busycover_pop(E_Busycover *cover, E_Busycover_Handle *handle); +EAPI void e_busycover_resize(E_Busycover *cover, int w, int h); + +#endif diff --git a/src/modules/illume-home/e_mod_config.c b/src/modules/illume-home/e_mod_config.c new file mode 100644 index 000000000..5e206c62f --- /dev/null +++ b/src/modules/illume-home/e_mod_config.c @@ -0,0 +1,200 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_config.h" + +/* local function prototypes */ +static void *_il_home_config_create(E_Config_Dialog *cfd); +static void _il_home_config_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_il_home_config_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static void _il_home_config_changed(void *data, Evas_Object *obj, void *event); +static void _il_home_config_click_changed(void *data, Evas_Object *obj, void *event); +static int _il_home_config_change_timeout(void *data); + +/* local variables */ +EAPI Il_Home_Config *il_home_cfg = NULL; +static E_Config_DD *conf_edd = NULL; +Ecore_Timer *_il_home_config_change_timer = NULL; +Evas_Object *delay_label, *delay_slider; + +/* public functions */ +int +il_home_config_init(E_Module *m) +{ + conf_edd = E_CONFIG_DD_NEW("Illume-Home_Cfg", Il_Home_Config); + #undef T + #undef D + #define T Il_Home_Config + #define D conf_edd + E_CONFIG_VAL(D, T, version, INT); + E_CONFIG_VAL(D, T, icon_size, INT); + E_CONFIG_VAL(D, T, single_click, INT); + E_CONFIG_VAL(D, T, single_click_delay, INT); + + il_home_cfg = e_config_domain_load("module.illume-home", conf_edd); + if ((il_home_cfg) && + ((il_home_cfg->version >> 16) < IL_CONFIG_MAJ)) + { + E_FREE(il_home_cfg); + il_home_cfg = NULL; + } + if (!il_home_cfg) + { + il_home_cfg = E_NEW(Il_Home_Config, 1); + il_home_cfg->version = 0; + il_home_cfg->icon_size = 120; + il_home_cfg->single_click = 1; + il_home_cfg->single_click_delay = 50; + } + if (il_home_cfg) + { + /* Add new config variables here */ + /* if ((il_home_cfg->version & 0xffff) < 1) */ + il_home_cfg->version = (IL_CONFIG_MAJ << 16) | IL_CONFIG_MIN; + } + + il_home_cfg->mod_dir = eina_stringshare_add(m->dir); + + e_configure_registry_category_add("illume", 0, _("Illume"), NULL, + "enlightenment/display"); + e_configure_registry_generic_item_add("illume/home", 0, _("Home"), + NULL, "enlightenment/launcher", + il_home_config_show); + return 1; +} + +int +il_home_config_shutdown(void) +{ + il_home_cfg->cfd = NULL; + + e_configure_registry_item_del("illume/home"); + e_configure_registry_category_del("illume"); + + if (il_home_cfg->mod_dir) eina_stringshare_del(il_home_cfg->mod_dir); + + E_FREE(il_home_cfg); + il_home_cfg = NULL; + + E_CONFIG_DD_FREE(conf_edd); + return 1; +} + +int +il_home_config_save(void) +{ + e_config_domain_save("module.illume-home", conf_edd, il_home_cfg); + return 1; +} + +void +il_home_config_show(E_Container *con, const char *params) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v = NULL; + + if (e_config_dialog_find("E", "_config_illume_home_settings")) return; + + v = E_NEW(E_Config_Dialog_View, 1); + v->create_cfdata = _il_home_config_create; + v->free_cfdata = _il_home_config_free; + v->basic.create_widgets = _il_home_config_ui; + v->basic_only = 1; + v->normal_win = 1; + v->scroll = 1; + + cfd = e_config_dialog_new(con, _("Home Settings"), "E", + "_config_illume_home_settings", + "enlightenment/launcher_settings", 0, v, NULL); + e_dialog_resizable_set(cfd->dia, 1); + il_home_cfg->cfd = cfd; +} + +/* local functions */ +static void * +_il_home_config_create(E_Config_Dialog *cfd) +{ + return NULL; +} + +static void +_il_home_config_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + il_home_cfg->cfd = NULL; + il_home_win_cfg_update(); +} + +static Evas_Object * +_il_home_config_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *list, *of, *o; + E_Radio_Group *rg; + + list = e_widget_list_add(evas, 0, 0); + + of = e_widget_framelist_add(evas, _("Icon Size"), 0); + rg = e_widget_radio_group_new(&(il_home_cfg->icon_size)); + o = e_widget_radio_add(evas, _("Small"), 60, rg); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", _il_home_config_changed, NULL); + o = e_widget_radio_add(evas, _("Medium"), 80, rg); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", _il_home_config_changed, NULL); + o = e_widget_radio_add(evas, _("Large"), 120, rg); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", _il_home_config_changed, NULL); + o = e_widget_radio_add(evas, _("Very Large"), 160, rg); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", _il_home_config_changed, NULL); + o = e_widget_radio_add(evas, _("Massive"), 240, rg); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", _il_home_config_changed, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + of = e_widget_framelist_add(evas, _("Launch Action"), 0); + o = e_widget_check_add(evas, _("Single press"), + &(il_home_cfg->single_click)); + e_widget_framelist_object_append(of, o); + evas_object_smart_callback_add(o, "changed", + _il_home_config_click_changed, NULL); + o = e_widget_label_add(evas, _("Press Delay")); + delay_label = o; + e_widget_disabled_set(o, !(il_home_cfg->single_click)); + e_widget_framelist_object_append(of, o); + o = e_widget_slider_add(evas, 1, 0, "%1.0f ms", 0, 350, 1, 0, NULL, + &(il_home_cfg->single_click_delay), 150); + delay_slider = o; + /* Slider does not emit a changed signal */ +// evas_object_smart_callback_add(o, "changed", +// _il_home_config_changed, NULL); + e_widget_disabled_set(o, !(il_home_cfg->single_click)); + e_widget_framelist_object_append(of, o); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + return list; +} + +static void +_il_home_config_changed(void *data, Evas_Object *obj, void *event) +{ + if (_il_home_config_change_timer) + ecore_timer_del(_il_home_config_change_timer); + _il_home_config_change_timer = + ecore_timer_add(0.5, _il_home_config_change_timeout, data); +} + +static void +_il_home_config_click_changed(void *data, Evas_Object *obj, void *event) +{ + e_widget_disabled_set(delay_label, !il_home_cfg->single_click); + e_widget_disabled_set(delay_slider, !il_home_cfg->single_click); + _il_home_config_changed(data, obj, event); +} + +static int +_il_home_config_change_timeout(void *data) +{ + il_home_win_cfg_update(); + e_config_save_queue(); + _il_home_config_change_timer = NULL; + return 0; +} diff --git a/src/modules/illume-home/e_mod_config.h b/src/modules/illume-home/e_mod_config.h new file mode 100644 index 000000000..b7b04a9ff --- /dev/null +++ b/src/modules/illume-home/e_mod_config.h @@ -0,0 +1,27 @@ +#ifndef E_MOD_CONFIG_H +#define E_MOD_CONFIG_H + +#define IL_CONFIG_MIN 0 +#define IL_CONFIG_MAJ 0 + +typedef struct _Il_Home_Config Il_Home_Config; + +struct _Il_Home_Config +{ + int version; + int mode, icon_size; + int single_click, single_click_delay; + + // Not User Configurable. Placeholders + const char *mod_dir; + E_Config_Dialog *cfd; +}; + +int il_home_config_init(E_Module *m); +int il_home_config_shutdown(void); +int il_home_config_save(void); +void il_home_config_show(E_Container *con, const char *params); + +extern EAPI Il_Home_Config *il_home_cfg; + +#endif diff --git a/src/modules/illume-home/e_mod_main.c b/src/modules/illume-home/e_mod_main.c new file mode 100644 index 000000000..20f2935e6 --- /dev/null +++ b/src/modules/illume-home/e_mod_main.c @@ -0,0 +1,903 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_config.h" +#include "e_busycover.h" + +#define IL_HOME_WIN_TYPE 0xE0b0102f + +/* local structures */ +typedef struct _Instance Instance; +typedef struct _Il_Home_Win Il_Home_Win; +typedef struct _Il_Home_Exec Il_Home_Exec; + +struct _Instance +{ + E_Gadcon_Client *gcc; + Evas_Object *o_btn; + Eina_List *wins, *handlers; +}; + +struct _Il_Home_Win +{ + E_Object e_obj_inherit; + + E_Win *win; + Evas_Object *o_bg, *o_sf, *o_fm, *o_cover; + E_Busycover *cover; + E_Zone *zone; +}; + +struct _Il_Home_Exec +{ + E_Busycover *cover; + Efreet_Desktop *desktop; + Ecore_Exe *exec; + E_Border *border; + E_Zone *zone; + Ecore_Timer *timeout; + int startup_id; + pid_t pid; + void *handle; +}; + +/* local function prototypes */ +static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style); +static void _gc_shutdown(E_Gadcon_Client *gcc); +static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient); +static char *_gc_label(E_Gadcon_Client_Class *cc); +static Evas_Object *_gc_icon(E_Gadcon_Client_Class *cc, Evas *evas); +static const char *_gc_id_new(E_Gadcon_Client_Class *cc); +static void _il_home_btn_cb_click(void *data, void *data2); +static void _il_home_win_new(Instance *inst); +static void _il_home_win_cb_free(Il_Home_Win *hwin); +static void _il_home_win_cb_resize(E_Win *win); +static void _il_home_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y); +static void _il_home_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y); +static void _il_home_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y); +static void _il_home_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h); +static void _il_home_cb_selected(void *data, Evas_Object *obj, void *event); +static void _il_home_desktop_run(Il_Home_Win *hwin, Efreet_Desktop *desktop); +static void _il_home_apps_populate(void); +static void _il_home_apps_unpopulate(void); +static void _il_home_fmc_set(Evas_Object *obj); +static void _il_home_desks_populate(void); +static int _il_home_desktop_list_change(void *data, int type, void *event); +static int _il_home_desktop_change(void *data, int type, void *event); +static int _il_home_update_deferred(void *data); +static int _il_home_win_cb_exe_del(void *data, int type, void *event); +static E_Border *_il_home_desktop_find_border(E_Zone *zone, Efreet_Desktop *desktop); +static int _il_home_win_cb_timeout(void *data); +static int _il_home_border_add(void *data, int type, void *event); +static int _il_home_border_remove(void *data, int type, void *event); +static int _il_home_cb_client_message(void *data, int type, void *event); +static int _il_home_cb_prop_change(void *data, int type, void *event); + +/* local variables */ +static Eina_List *instances = NULL; +static Eina_List *desks = NULL; +static Eina_List *handlers = NULL; +static Eina_List *exes = NULL; +static Ecore_Timer *defer = NULL; + +static const E_Gadcon_Client_Class _gc_class = +{ + GADCON_CLIENT_CLASS_VERSION, "illume-home", + { _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, + e_gadcon_site_is_not_toolbar + }, E_GADCON_CLIENT_STYLE_PLAIN +}; + +/* public functions */ +EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Illume Home" }; + +EAPI void * +e_modapi_init(E_Module *m) +{ + if (!il_home_config_init(m)) return NULL; + + _il_home_apps_unpopulate(); + _il_home_apps_populate(); + + handlers = + eina_list_append(handlers, + ecore_event_handler_add(EFREET_EVENT_DESKTOP_LIST_CHANGE, + _il_home_desktop_list_change, + NULL)); + handlers = + eina_list_append(handlers, + ecore_event_handler_add(EFREET_EVENT_DESKTOP_CHANGE, + _il_home_desktop_change, NULL)); + + handlers = + eina_list_append(handlers, + ecore_event_handler_add(E_EVENT_BORDER_ADD, + _il_home_border_add, NULL)); + handlers = + eina_list_append(handlers, + ecore_event_handler_add(E_EVENT_BORDER_REMOVE, + _il_home_border_remove, NULL)); + + handlers = + eina_list_append(handlers, + ecore_event_handler_add(ECORE_EXE_EVENT_DEL, + _il_home_win_cb_exe_del, NULL)); + + e_gadcon_provider_register(&_gc_class); + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + Ecore_Event_Handler *handle; + Il_Home_Exec *exe; + + EINA_LIST_FREE(exes, exe) + { + if (exe->exec) + { + ecore_exe_terminate(exe->exec); + ecore_exe_free(exe->exec); + exe->exec = NULL; + } + if (exe->handle) + { + e_busycover_pop(exe->cover, exe->handle); + exe->handle = NULL; + } + if (exe->timeout) ecore_timer_del(exe->timeout); + E_FREE(exe); + } + + _il_home_apps_unpopulate(); + + EINA_LIST_FREE(handlers, handle) + ecore_event_handler_del(handle); + + e_gadcon_provider_unregister(&_gc_class); + + il_home_config_shutdown(); + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return il_home_config_save(); +} + +void +il_home_win_cfg_update(void) +{ + _il_home_apps_unpopulate(); + _il_home_apps_populate(); +} + +/* local functions */ +static E_Gadcon_Client * +_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) +{ + Instance *inst; + Evas_Object *icon; + Ecore_X_Window xwin; + Ecore_X_Illume_Mode mode; + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), "%s/e-module-illume-home.edj", + il_home_cfg->mod_dir); + + inst = E_NEW(Instance, 1); + inst->o_btn = e_widget_button_add(gc->evas, NULL, NULL, + _il_home_btn_cb_click, inst, NULL); + icon = e_icon_add(evas_object_evas_get(inst->o_btn)); + e_icon_file_edje_set(icon, buff, "icon"); + e_widget_button_icon_set(inst->o_btn, icon); + + inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->o_btn); + inst->gcc->data = inst; + + _il_home_win_new(inst); + + xwin = inst->gcc->gadcon->zone->black_win; + mode = ecore_x_e_illume_mode_get(xwin); + if (mode > ECORE_X_ILLUME_MODE_SINGLE) + _il_home_win_new(inst); + + inst->handlers = + eina_list_append(inst->handlers, + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + _il_home_cb_client_message, inst)); + inst->handlers = + eina_list_append(inst->handlers, + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _il_home_cb_prop_change, inst)); + + instances = eina_list_append(instances, inst); + return inst->gcc; +} + +static void +_gc_shutdown(E_Gadcon_Client *gcc) +{ + Instance *inst; + Il_Home_Win *hwin; + Ecore_Event_Handler *hdl; + + if (!(inst = gcc->data)) return; + + instances = eina_list_remove(instances, inst); + + EINA_LIST_FREE(inst->handlers, hdl) + ecore_event_handler_del(hdl); + + if (inst->o_btn) evas_object_del(inst->o_btn); + + EINA_LIST_FREE(inst->wins, hwin) + e_object_del(E_OBJECT(hwin)); + + E_FREE(inst); +} + +static void +_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient) +{ + e_gadcon_client_aspect_set(gcc, 16, 16); + e_gadcon_client_min_size_set(gcc, 16, 16); +} + +static char * +_gc_label(E_Gadcon_Client_Class *cc) +{ + return _("Illume-Home"); +} + +static Evas_Object * +_gc_icon(E_Gadcon_Client_Class *cc, Evas *evas) +{ + Evas_Object *o; + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), "%s/e-module-illume-home.edj", + il_home_cfg->mod_dir); + o = edje_object_add(evas); + edje_object_file_set(o, buff, "icon"); + return o; +} + +static const char * +_gc_id_new(E_Gadcon_Client_Class *cc) +{ + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), "%s.%d", _gc_class.name, + eina_list_count(instances)); + return strdup(buff); +} + +static void +_il_home_btn_cb_click(void *data, void *data2) +{ + Instance *inst; + + if (!(inst = data)) return; + + /* if there are less than 2 home windows, create a new one */ + if (eina_list_count(inst->wins) < 2) + _il_home_win_new(inst); + else + { + E_Zone *zone; + + zone = inst->gcc->gadcon->zone; + + /* already 2 home windows, so tell illume to focus one */ + ecore_x_e_illume_focus_home_send(zone->black_win); + } +} + +static void +_il_home_win_new(Instance *inst) +{ + Il_Home_Win *hwin; + E_Zone *zone; + char buff[PATH_MAX]; + + if (!inst) return; + + hwin = E_OBJECT_ALLOC(Il_Home_Win, IL_HOME_WIN_TYPE, + _il_home_win_cb_free); + if (!hwin) return; + inst->wins = eina_list_append(inst->wins, hwin); + + zone = inst->gcc->gadcon->zone; + hwin->zone = zone; + + hwin->win = e_win_new(zone->container); + if (!hwin->win) + { + e_object_del(E_OBJECT(hwin)); + return; + } + hwin->win->data = inst; + e_win_title_set(hwin->win, _("Illume Home")); + e_win_name_class_set(hwin->win, "Illume-Home", "Illume-Home"); + e_win_resize_callback_set(hwin->win, _il_home_win_cb_resize); + e_win_no_remember_set(hwin->win, EINA_TRUE); + + /* don't accept focus */ + ecore_x_icccm_hints_set(hwin->win->evas_win, 0, 0, 0, 0, 0, 0, 0); + + snprintf(buff, sizeof(buff), "%s/e-module-illume-home.edj", + il_home_cfg->mod_dir); + + hwin->o_bg = edje_object_add(e_win_evas_get(hwin->win)); + if (!e_theme_edje_object_set(hwin->o_bg, + "base/theme/modules/illume-home", + "modules/illume-home/window")) + edje_object_file_set(hwin->o_bg, buff, "modules/illume-home/window"); + evas_object_move(hwin->o_bg, 0, 0); + evas_object_show(hwin->o_bg); + + hwin->o_sf = e_scrollframe_add(e_win_evas_get(hwin->win)); + e_scrollframe_single_dir_set(hwin->o_sf, 1); + evas_object_move(hwin->o_sf, 0, 0); + evas_object_show(hwin->o_sf); + + e_scrollframe_custom_edje_file_set(hwin->o_sf, buff, + "modules/illume-home/launcher/scrollview"); + + hwin->o_fm = e_fm2_add(e_win_evas_get(hwin->win)); + _il_home_fmc_set(hwin->o_fm); + evas_object_show(hwin->o_fm); + e_user_dir_concat_static(buff, "appshadow"); + e_fm2_path_set(hwin->o_fm, NULL, buff); + + e_fm2_window_object_set(hwin->o_fm, E_OBJECT(hwin->win)); + + e_scrollframe_extern_pan_set(hwin->o_sf, hwin->o_fm, + _il_home_pan_set, + _il_home_pan_get, + _il_home_pan_max_get, + _il_home_pan_child_size_get); + evas_object_propagate_events_set(hwin->o_fm, 0); + evas_object_smart_callback_add(hwin->o_fm, "selected", + _il_home_cb_selected, hwin); + + hwin->cover = e_busycover_new(hwin->win); + + e_win_move_resize(hwin->win, zone->x, zone->y, zone->w, (zone->h / 2)); + e_win_show(hwin->win); + + e_border_zone_set(hwin->win->border, zone); + + if (hwin->win->evas_win) + e_drop_xdnd_register_set(hwin->win->evas_win, 1); +} + +static void +_il_home_win_cb_free(Il_Home_Win *hwin) +{ + if (hwin->win->evas_win) + e_drop_xdnd_register_set(hwin->win->evas_win, 0); + + if (hwin->cover) e_object_del(E_OBJECT(hwin->cover)); + hwin->cover = NULL; + + if (hwin->o_bg) evas_object_del(hwin->o_bg); + hwin->o_bg = NULL; + if (hwin->o_sf) evas_object_del(hwin->o_sf); + hwin->o_sf = NULL; + if (hwin->o_fm) evas_object_del(hwin->o_fm); + hwin->o_fm = NULL; + + if (hwin->win) e_object_del(E_OBJECT(hwin->win)); + hwin->win = NULL; +} + +static void +_il_home_win_cb_resize(E_Win *win) +{ + Instance *inst; + Il_Home_Win *hwin; + Eina_List *l; + + if (!(inst = win->data)) return; + EINA_LIST_FOREACH(inst->wins, l, hwin) + { + if (hwin->win != win) + { + hwin = NULL; + continue; + } + else break; + } + if (!hwin) return; + + if (hwin->o_bg) evas_object_resize(hwin->o_bg, win->w, win->h); + if (hwin->o_sf) evas_object_resize(hwin->o_sf, win->w, win->h); + if (hwin->cover) e_busycover_resize(hwin->cover, win->w, win->h); +} + +static void +_il_home_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y) +{ + e_fm2_pan_set(obj, x, y); +} + +static void +_il_home_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +{ + e_fm2_pan_get(obj, x, y); +} + +static void +_il_home_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y) +{ + e_fm2_pan_max_get(obj, x, y); +} + +static void +_il_home_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) +{ + e_fm2_pan_child_size_get(obj, w, h); +} + +static void +_il_home_cb_selected(void *data, Evas_Object *obj, void *event) +{ + Il_Home_Win *hwin; + Eina_List *selected; + E_Fm2_Icon_Info *ici; + + if (!(hwin = data)) return; + if (!(selected = e_fm2_selected_list_get(hwin->o_fm))) return; + EINA_LIST_FREE(selected, ici) + { + Efreet_Desktop *desktop; + + if (ici) + { + if (ici->real_link) + { + desktop = efreet_desktop_get(ici->real_link); + if (desktop) + _il_home_desktop_run(hwin, desktop); + } + } + } +} + +static void +_il_home_desktop_run(Il_Home_Win *hwin, Efreet_Desktop *desktop) +{ + E_Exec_Instance *eins; + Il_Home_Exec *exe; + Eina_List *l; + E_Border *b; + char buff[PATH_MAX]; + + if ((!desktop) || (!desktop->exec)) return; + + EINA_LIST_FOREACH(exes, l, exe) + { + if (exe->desktop == desktop) + { + if ((exe->border) && + (exe->border->zone == hwin->win->border->zone)) + { + e_border_uniconify(exe->border); + e_border_show(exe->border); + e_border_raise(exe->border); + e_border_focus_set(exe->border, 1, 1); + return; + } + } + } + + b = _il_home_desktop_find_border(hwin->win->border->zone, desktop); + if (b) + { + e_border_uniconify(b); + e_border_show(b); + e_border_raise(b); + e_border_focus_set(b, 1, 1); + return; + } + + exe = E_NEW(Il_Home_Exec, 1); + if (!exe) return; + exe->cover = hwin->cover; + + eins = e_exec(hwin->win->border->zone, desktop, NULL, NULL, "illume-home"); + exe->desktop = desktop; + exe->zone = hwin->win->border->zone; + if (eins) + { + exe->exec = eins->exe; + exe->startup_id = eins->startup_id; + if (eins->exe) + exe->pid = ecore_exe_pid_get(eins->exe); + } + + exe->timeout = ecore_timer_add(20.0, _il_home_win_cb_timeout, exe); + snprintf(buff, sizeof(buff), "Starting %s", desktop->name); + exe->handle = e_busycover_push(hwin->cover, buff, NULL); + exes = eina_list_append(exes, exe); +} + +static void +_il_home_apps_populate(void) +{ + Eina_List *l, *ll; + Instance *inst; + char buff[PATH_MAX]; + + e_user_dir_concat_static(buff, "appshadow"); + ecore_file_mkpath(buff); + + _il_home_desks_populate(); + + EINA_LIST_FOREACH(instances, l, inst) + { + Il_Home_Win *hwin; + + EINA_LIST_FOREACH(inst->wins, ll, hwin) + { + if (!hwin) continue; + _il_home_fmc_set(hwin->o_fm); + e_fm2_path_set(hwin->o_fm, NULL, buff); + } + } +} + +static void +_il_home_apps_unpopulate(void) +{ + Efreet_Desktop *desktop; + Eina_List *files; + char buff[PATH_MAX], *file; + size_t len; + + EINA_LIST_FREE(desks, desktop) + efreet_desktop_free(desktop); + + len = e_user_dir_concat_static(buff, "appshadow"); + if ((len + 2) >= sizeof(buff)) return; + + files = ecore_file_ls(buff); + buff[len] = '/'; + len++; + + EINA_LIST_FREE(files, file) + { + if (eina_strlcpy(buff + len, file, sizeof(buff) - len) >= sizeof(buff) - len) + continue; + ecore_file_unlink(buff); + free(file); + } +} + +static void +_il_home_fmc_set(Evas_Object *obj) +{ + E_Fm2_Config fmc; + + if (!obj) return; + memset(&fmc, 0, sizeof(E_Fm2_Config)); + fmc.view.mode = E_FM2_VIEW_MODE_GRID_ICONS; + fmc.view.open_dirs_in_place = 1; + fmc.view.selector = 0; + fmc.view.single_click = il_home_cfg->single_click; + fmc.view.single_click_delay = il_home_cfg->single_click_delay; + fmc.view.no_subdir_jump = 1; + fmc.icon.extension.show = 0; + fmc.icon.icon.w = il_home_cfg->icon_size * e_scale / 2.0; + fmc.icon.icon.h = il_home_cfg->icon_size * e_scale / 2.0; + fmc.icon.fixed.w = il_home_cfg->icon_size * e_scale / 2.0; + fmc.icon.fixed.h = il_home_cfg->icon_size * e_scale / 2.0; + fmc.list.sort.no_case = 0; + fmc.list.sort.dirs.first = 1; + fmc.list.sort.dirs.last = 0; + fmc.selection.single = 1; + fmc.selection.windows_modifiers = 0; + e_fm2_config_set(obj, &fmc); +} + +static void +_il_home_desks_populate(void) +{ + Efreet_Menu *menu; + + menu = efreet_menu_get(); + if (menu) + { + Eina_List *l, *ll; + Efreet_Menu *entry, *subentry; + Eina_List *settings, *sys, *kbd; + int num = 0; + + settings = efreet_util_desktop_category_list("Settings"); + sys = efreet_util_desktop_category_list("System"); + kbd = efreet_util_desktop_category_list("Keyboard"); + EINA_LIST_FOREACH(menu->entries, l, entry) + { + if (entry->type != EFREET_MENU_ENTRY_MENU) continue; + EINA_LIST_FOREACH(entry->entries, ll, subentry) + { + Efreet_Desktop *desktop; + + if (subentry->type != EFREET_MENU_ENTRY_DESKTOP) continue; + if (!(desktop = subentry->desktop)) continue; + if ((settings) && (sys) && + (eina_list_data_find(settings, desktop)) && + (eina_list_data_find(sys, desktop))) continue; + if ((kbd) && (eina_list_data_find(kbd, desktop))) + continue; + if (!desktop) continue; + desks = eina_list_append(desks, desktop); + efreet_desktop_ref(desktop); + if (desktop) + { + char buff[PATH_MAX]; + + e_user_dir_snprintf(buff, sizeof(buff), + "appshadow/%04x.desktop", num); + ecore_file_symlink(desktop->orig_path, buff); + } + num++; + } + } + } +} + +static int +_il_home_desktop_list_change(void *data, int type, void *event) +{ + if (defer) ecore_timer_del(defer); + defer = ecore_timer_add(1.0, _il_home_update_deferred, NULL); + return 1; +} + +static int +_il_home_desktop_change(void *data, int type, void *event) +{ + if (defer) ecore_timer_del(defer); + defer = ecore_timer_add(1.0, _il_home_update_deferred, NULL); + return 1; +} + +static int +_il_home_update_deferred(void *data) +{ + _il_home_apps_unpopulate(); + _il_home_apps_populate(); + defer = NULL; + return 0; +} + +static int +_il_home_win_cb_exe_del(void *data, int type, void *event) +{ + Il_Home_Exec *exe; + Ecore_Exe_Event_Del *ev; + Eina_List *l; + + ev = event; + EINA_LIST_FOREACH(exes, l, exe) + { + if (exe->pid == ev->pid) + { + if (exe->handle) + { + e_busycover_pop(exe->cover, exe->handle); + exe->handle = NULL; + } + exes = eina_list_remove_list(exes, l); + if (exe->timeout) ecore_timer_del(exe->timeout); + E_FREE(exe); + return 1; + } + } + return 1; +} + +static E_Border * +_il_home_desktop_find_border(E_Zone *zone, Efreet_Desktop *desktop) +{ + Eina_List *l; + E_Border *bd; + char *exe = NULL, *p; + + if (!desktop) return NULL; + if (!desktop->exec) return NULL; + p = strchr(desktop->exec, ' '); + if (!p) + exe = strdup(desktop->exec); + else + { + exe = malloc(p - desktop->exec + 1); + memset(exe, 0, sizeof(exe)); + if (exe) eina_strlcpy(exe, desktop->exec, p - desktop->exec + 1); + } + if (exe) + { + p = strrchr(exe, '/'); + if (p) strcpy(exe, p + 1); + } + + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + if (bd->zone != zone) continue; + if (e_exec_startup_id_pid_find(bd->client.netwm.pid, + bd->client.netwm.startup_id) == desktop) + { + if (exe) free(exe); + return bd; + } + if (exe) + { + if (bd->client.icccm.command.argv) + { + char *pp; + + pp = strrchr(bd->client.icccm.command.argv[0], '/'); + if (!pp) pp = bd->client.icccm.command.argv[0]; + if (!strcmp(exe, pp)) + { + free(exe); + return bd; + } + } + if ((bd->client.icccm.name) && + (!strcasecmp(bd->client.icccm.name, exe))) + { + free(exe); + return bd; + } + } + } + if (exe) free(exe); + return NULL; +} + +static int +_il_home_win_cb_timeout(void *data) +{ + Il_Home_Exec *exe; + + if (!(exe = data)) return 1; + + if (exe->handle) e_busycover_pop(exe->cover, exe->handle); + exe->handle = NULL; + + if (!exe->border) + { + exes = eina_list_remove(exes, exe); + E_FREE(exe); + return 0; + } + exe->timeout = NULL; + return 0; +} + +static int +_il_home_border_add(void *data, int type, void *event) +{ + E_Event_Border_Add *ev; + Il_Home_Exec *exe; + Eina_List *l; + + ev = event; + EINA_LIST_FOREACH(exes, l, exe) + { + if (!exe->border) + { + if ((exe->startup_id == ev->border->client.netwm.startup_id) || + (exe->pid == ev->border->client.netwm.pid)) + { + exe->border = ev->border; + } + } + if (!exe->border) continue; + if (exe->border->zone != exe->zone) + { + exe->border->zone = exe->zone; + exe->border->x = exe->zone->x; + exe->border->y = exe->zone->y; + exe->border->changes.pos = 1; + exe->border->changed = 1; + } + if (exe->handle) + { + e_busycover_pop(exe->cover, exe->handle); + exe->handle = NULL; + } + if (exe->timeout) ecore_timer_del(exe->timeout); + exe->timeout = NULL; + } + return 1; +} + +static int +_il_home_border_remove(void *data, int type, void *event) +{ + E_Event_Border_Remove *ev; + Il_Home_Exec *exe; + Eina_List *l; + + ev = event; + EINA_LIST_FOREACH(exes, l, exe) + { + if (exe->border == ev->border) + { + if (exe->exec) ecore_exe_free(exe->exec); + exe->exec = NULL; + if (exe->handle) e_busycover_pop(exe->cover, exe->handle); + exe->handle = NULL; + exe->border = NULL; + break; + } + } + return 1; +} + +static int +_il_home_cb_client_message(void *data, int type, void *event) +{ + Ecore_X_Event_Client_Message *ev; + Instance *inst; + + ev = event; + if (!(inst = data)) return 1; + if (ev->message_type == ECORE_X_ATOM_E_ILLUME_HOME_NEW) + { + E_Zone *zone; + + zone = inst->gcc->gadcon->zone; + if (zone->black_win != ev->win) return 1; + _il_home_win_new(inst); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_HOME_DEL) + { + E_Border *bd; + Eina_List *l; + Il_Home_Win *hwin; + + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + EINA_LIST_FOREACH(inst->wins, l, hwin) + { + if (hwin->win->border == bd) + { + inst->wins = eina_list_remove_list(inst->wins, inst->wins); + e_object_del(E_OBJECT(hwin)); + break; + } + } + } + + return 1; +} + +static int +_il_home_cb_prop_change(void *data, int type, void *event) +{ + Instance *inst; + Ecore_X_Event_Window_Property *ev; + Eina_List *l; + Il_Home_Win *hwin; + + ev = event; + if (!(inst = data)) return 1; +// if (ev->win != ecore_x_window_root_first_get()) return 1; + if (strcmp(ecore_x_atom_name_get(ev->atom), "ENLIGHTENMENT_SCALE")) + return 1; + + EINA_LIST_FOREACH(inst->wins, l, hwin) + if (hwin->o_fm) + { + _il_home_fmc_set(hwin->o_fm); + e_fm2_refresh(hwin->o_fm); + } + + return 1; +} diff --git a/src/modules/illume-home/e_mod_main.h b/src/modules/illume-home/e_mod_main.h new file mode 100644 index 000000000..04c4f9724 --- /dev/null +++ b/src/modules/illume-home/e_mod_main.h @@ -0,0 +1,12 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init(E_Module *m); +EAPI int e_modapi_shutdown(E_Module *m); +EAPI int e_modapi_save(E_Module *m); + +void il_home_win_cfg_update(void); + +#endif diff --git a/src/modules/illume-home/module.desktop.in b/src/modules/illume-home/module.desktop.in new file mode 100644 index 000000000..c5e5ce227 --- /dev/null +++ b/src/modules/illume-home/module.desktop.in @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Link +Name=Illume-Home +Icon=e-module-illume-home +X-Enlightenment-ModuleType=system +Comment=Illume Home for Embedded +Comment[fr]=Illume pour l'embarqué – Home +Comment[it]=Illume per sistemi embedded – modulo Home diff --git a/src/modules/illume-indicator/Makefile.am b/src/modules/illume-indicator/Makefile.am new file mode 100644 index 000000000..688486ac9 --- /dev/null +++ b/src/modules/illume-indicator/Makefile.am @@ -0,0 +1,51 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume-indicator +SUBDIRS = images + +EDJE_CC = @edje_cc@ +EDJE_FLAGS = -v \ + -id $(top_srcdir)/src/modules/$(MODULE)/images \ + @EDJE_DEF@ + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ + e-module-$(MODULE).edj \ + module.desktop + +EXTRA_DIST = \ + e-module-$(MODULE).edc \ + module.desktop.in + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ + +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ + e_mod_ind_win.c \ + e_mod_ind_win.h \ + e_mod_main.c \ + e_mod_main.h + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +e-module-$(MODULE).edj: Makefile $(EXTRA_DIST) + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/src/modules/$(MODULE)/e-module-$(MODULE).edc \ + $(top_builddir)/src/modules/$(MODULE)/e-module-$(MODULE).edj + +clean-local: + rm -f *.edj + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/illume-indicator/e-module-illume-indicator.edc b/src/modules/illume-indicator/e-module-illume-indicator.edc new file mode 100644 index 000000000..df8d9197d --- /dev/null +++ b/src/modules/illume-indicator/e-module-illume-indicator.edc @@ -0,0 +1,57 @@ +collections +{ + group + { + images.image: "module_icon.png" COMP; + name: "icon"; + max: 128 128; + parts + { + part + { + name: "base"; + mouse_events: 0; + description + { + state: "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + image.normal: "module_icon.png"; + } + } + } + } + group + { + images.image: "base_bg.png" COMP; + name: "modules/illume-indicator/window"; + parts + { + part + { + name: "base"; + type: IMAGE; + mouse_events: 0; + description + { + state: "default" 0.0; + color_class: "shelf_base"; + image.normal: "base_bg.png"; + image.border: 2 2 2 2; + fill.smooth: 0; + } + } + part + { + name: "e.swallow.content"; + type: SWALLOW; + description + { + state: "default" 0.0; + rel1.offset: 3 3; + rel2.offset: -4 -4; + } + } + } + } +} diff --git a/src/modules/illume-indicator/e_mod_ind_win.c b/src/modules/illume-indicator/e_mod_ind_win.c new file mode 100644 index 000000000..8de4b5d8d --- /dev/null +++ b/src/modules/illume-indicator/e_mod_ind_win.c @@ -0,0 +1,475 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_ind_win.h" + +/* local function prototypes */ +static void _e_mod_ind_win_cb_free(Ind_Win *iwin); +static int _e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event); +static void _e_mod_ind_win_cb_resize(E_Win *win); +static void _e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event); +static void _e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event); +static void _e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event); +static void _e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h); +static void _e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__); +static Evas_Object *_e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__); +static void _e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn); +static void _e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn); +static void _e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn); +static void _e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__); +static void _e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__); +static void _e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__); + +Ind_Win * +e_mod_ind_win_new(E_Zone *zone) +{ + Ind_Win *iwin; + Ecore_X_Window_State states[2]; + + /* create our new indicator window object */ + iwin = E_OBJECT_ALLOC(Ind_Win, IND_WIN_TYPE, _e_mod_ind_win_cb_free); + if (!iwin) return NULL; + + iwin->zone = zone; + + /* hook into property change so we can adjust w/ e_scale */ + iwin->scale_hdl = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _e_mod_ind_win_cb_win_prop, iwin); + + /* create new window */ + iwin->win = e_win_new(zone->container); + iwin->win->data = iwin; + + /* set some properties on the window */ + e_win_title_set(iwin->win, _("Illume Indicator")); + e_win_name_class_set(iwin->win, "Illume-Indicator", "Illume-Indicator"); + e_win_no_remember_set(iwin->win, EINA_TRUE); + + /* hook into window resize so we can resize our objects */ + e_win_resize_callback_set(iwin->win, _e_mod_ind_win_cb_resize); + + /* set this window to not show in taskbar or pager */ + states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER; + ecore_x_netwm_window_state_set(iwin->win->evas_win, states, 2); + + /* set this window to not accept or take focus */ + ecore_x_icccm_hints_set(iwin->win->evas_win, 0, 0, 0, 0, 0, 0, 0); + + /* create our event rectangle */ + iwin->o_event = evas_object_rectangle_add(iwin->win->evas); + evas_object_color_set(iwin->o_event, 0, 0, 0, 0); + evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_DOWN, + _e_mod_ind_win_cb_mouse_down, iwin); + evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_UP, + _e_mod_ind_win_cb_mouse_up, iwin); + evas_object_event_callback_add(iwin->o_event, EVAS_CALLBACK_MOUSE_MOVE, + _e_mod_ind_win_cb_mouse_move, iwin); + evas_object_move(iwin->o_event, 0, 0); + evas_object_show(iwin->o_event); + + /* create our base object */ + iwin->o_base = edje_object_add(iwin->win->evas); + if (!e_theme_edje_object_set(iwin->o_base, + "base/theme/modules/illume-indicator", + "modules/illume-indicator/window")) + { + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), + "%s/e-module-illume-indicator.edj", _ind_mod_dir); + edje_object_file_set(iwin->o_base, buff, + "modules/illume-indicator/window"); + } + evas_object_move(iwin->o_base, 0, 0); + evas_object_show(iwin->o_base); + + /* create our gadget container */ + iwin->gadcon = e_gadcon_swallowed_new("illume-indicator", zone->id, + iwin->o_base, "e.swallow.content"); +// iwin->gadcon->instant_edit = 1; + edje_extern_object_min_size_set(iwin->gadcon->o_container, zone->w, + (32 * e_scale)); + edje_object_part_swallow(iwin->o_base, "e.swallow.container", + iwin->gadcon->o_container); + e_gadcon_min_size_request_callback_set(iwin->gadcon, + _e_mod_ind_win_cb_min_size_request, + iwin); + e_gadcon_size_request_callback_set(iwin->gadcon, + _e_mod_ind_win_cb_size_request, iwin); + e_gadcon_frame_request_callback_set(iwin->gadcon, + _e_mod_ind_win_cb_frame_request, iwin); + e_gadcon_orient(iwin->gadcon, E_GADCON_ORIENT_FLOAT); + e_gadcon_zone_set(iwin->gadcon, zone); + e_gadcon_ecore_evas_set(iwin->gadcon, iwin->win->ecore_evas); + e_gadcon_util_menu_attach_func_set(iwin->gadcon, + _e_mod_ind_win_cb_menu_items_append, iwin); + e_gadcon_populate(iwin->gadcon); + + /* set minimum size of this window */ + e_win_size_min_set(iwin->win, zone->w, (32 * e_scale)); + + /* position and resize this window */ + e_win_move_resize(iwin->win, zone->x, zone->y, zone->w, (32 * e_scale)); + + /* show the window */ + e_win_show(iwin->win); + + /* set this window on proper zone */ + e_border_zone_set(iwin->win->border, zone); + + /* set this window to be a dock window. This needs to be done after show + * as E will sometimes reset the window type */ + ecore_x_netwm_window_type_set(iwin->win->evas_win, ECORE_X_WINDOW_TYPE_DOCK); + + /* tell conformant apps our position and size */ + ecore_x_e_illume_indicator_geometry_set(zone->black_win, zone->x, zone->y, + zone->w, (32 * e_scale)); + + return iwin; +} + +/* local function prototypes */ +static void +_e_mod_ind_win_cb_free(Ind_Win *iwin) +{ + /* delete the scale handler */ + if (iwin->scale_hdl) ecore_event_handler_del(iwin->scale_hdl); + iwin->scale_hdl = NULL; + + /* delete the border hook */ + if (iwin->hook) e_border_hook_del(iwin->hook); + iwin->hook = NULL; + + /* delete the menu */ + if (iwin->menu) + { + e_menu_post_deactivate_callback_set(iwin->menu, NULL, NULL); + e_object_del(E_OBJECT(iwin->menu)); + } + iwin->menu = NULL; + + /* delete the gadget container */ + if (iwin->gadcon) e_object_del(E_OBJECT(iwin->gadcon)); + iwin->gadcon = NULL; + + /* delete the objects */ + if (iwin->o_base) evas_object_del(iwin->o_base); + iwin->o_base = NULL; + if (iwin->o_event) evas_object_del(iwin->o_event); + iwin->o_event = NULL; + + /* tell conformant apps our position and size */ + ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, 0, 0, 0, 0); + ecore_x_e_illume_zone_set(iwin->win->border->client.win, iwin->zone->black_win); + + /* delete the window */ + if (iwin->win) e_object_del(E_OBJECT(iwin->win)); + iwin->win = NULL; + + /* free the allocated object */ + E_FREE(iwin); +} + +static int +_e_mod_ind_win_cb_win_prop(void *data, int type __UNUSED__, void *event) +{ + Ind_Win *iwin; + Ecore_X_Event_Window_Property *ev; + + ev = event; + + if (!(iwin = data)) return 1; + if (ev->win != ecore_x_window_root_get(iwin->win->evas_win)) return 1; + if (strcmp(ecore_x_atom_name_get(ev->atom), "ENLIGHTENMENT_SCALE")) return 1; + + /* set minimum size of this window */ + e_win_size_min_set(iwin->win, iwin->zone->w, (32 * e_scale)); + + /* resize this window */ + e_win_resize(iwin->win, iwin->zone->w, (32 * e_scale)); + + /* tell conformant apps our position and size */ + ecore_x_e_illume_indicator_geometry_set(iwin->zone->black_win, + iwin->win->x, iwin->win->y, + iwin->win->w, (32 * e_scale)); + + return 1; +} + +static void +_e_mod_ind_win_cb_resize(E_Win *win) +{ + Ind_Win *iwin; + + if (!(iwin = win->data)) return; + if (iwin->o_event) evas_object_resize(iwin->o_event, win->w, win->h); + if (iwin->o_base) evas_object_resize(iwin->o_base, win->w, win->h); + if (iwin->gadcon->o_container) + edje_extern_object_min_size_set(iwin->gadcon->o_container, win->w, win->h); +} + +static void +_e_mod_ind_win_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Ind_Win *iwin; + Evas_Event_Mouse_Down *ev; + + ev = event; + if (!(iwin = data)) return; + if (ev->button == 1) + { + iwin->mouse_down = 1; + + /* make sure we can drag */ + if (iwin->win->border->client.illume.drag.locked) return; + + iwin->drag.start = 1; + iwin->drag.dnd = 0; + iwin->drag.y = ev->output.y; + iwin->drag.by = iwin->win->border->y; + + /* change mouse pointer to indicate we are dragging */ + if (iwin->win->border->pointer) + e_pointer_type_push(iwin->win->border->pointer, + iwin->win->border, "move"); + } + else if (ev->button == 3) + { + int x, y; + + /* create our popup menu */ + iwin->menu = e_menu_new(); + e_menu_post_deactivate_callback_set(iwin->menu, + _e_mod_ind_win_cb_menu_post, iwin); + + /* append items to our menu */ + _e_mod_ind_win_cb_menu_append(iwin, iwin->menu); + + /* show menu */ + e_gadcon_canvas_zone_geometry_get(iwin->gadcon, &x, &y, NULL, NULL); + e_menu_activate_mouse(iwin->menu, iwin->zone, x + ev->output.x, + y + ev->output.y, 1, 1, + E_MENU_POP_DIRECTION_AUTO, ev->timestamp); + } +} + +static void +_e_mod_ind_win_cb_mouse_up(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Ind_Win *iwin; + Evas_Event_Mouse_Up *ev; + + ev = event; + if (ev->button != 1) return; + if (!(iwin = data)) return; + + /* if we are not dragging, send message to show quickpanel */ + if ((!iwin->drag.dnd) && (iwin->mouse_down == 1)) + { + Ecore_X_Window xwin; + + xwin = iwin->win->border->zone->black_win; + ecore_x_e_illume_quickpanel_state_send + (xwin, ECORE_X_ILLUME_QUICKPANEL_STATE_ON); + } + else if (iwin->drag.dnd) + { + E_Border *bd; + + bd = iwin->win->border; + + /* reset mouse pointer */ + if (bd->pointer) e_pointer_type_pop(bd->pointer, bd, "move"); + + /* tell edj we are done moving */ + edje_object_signal_emit(iwin->o_base, "e,action,move,stop", "e"); + + /* send message that we are done dragging */ + ecore_x_e_illume_drag_end_send(bd->client.win); + + /* update quickpanel position if needed */ + if (bd->y != iwin->drag.by) + ecore_x_e_illume_quickpanel_position_update_send(bd->client.win); + } + iwin->drag.start = 0; + iwin->drag.dnd = 0; + iwin->drag.y = 0; + iwin->drag.by = 0; + iwin->mouse_down = 0; +} + +static void +_e_mod_ind_win_cb_mouse_move(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event) +{ + Ind_Win *iwin; + Evas_Event_Mouse_Move *ev; + E_Border *bd; + + ev = event; + if (!(iwin = data)) return; + bd = iwin->win->border; + if (iwin->drag.start) + { + iwin->drag.dnd = 1; + iwin->drag.start = 0; + + /* tell edj we are going to start moving */ + edje_object_signal_emit(iwin->o_base, "e,action,move,start", "e"); + + /* send message that we are going to start dragging */ + ecore_x_e_illume_drag_start_send(bd->client.win); + } + + /* make sure we are dragging */ + if (iwin->drag.dnd) + { + int dy, py, ny; + + /* get current mouse position */ + py = ev->cur.output.y; + + /* do moves in 'chunks' of screen size */ + dy = ((bd->zone->h - bd->h) / 8); + + /* are we moving up or down ? */ + if (ev->cur.output.y > ev->prev.output.y) + { + /* moving down */ + if ((py - iwin->drag.y) < dy) return; + } + else if (ev->cur.output.y < ev->prev.output.y) + { + /* moving up */ + if ((iwin->drag.y - py) < dy) return; + } + else return; + + if (py > iwin->drag.y) + ny = bd->y + dy; + else if (py < iwin->drag.y) + ny = bd->y - dy; + else return; + + /* make sure we don't drag off the screen */ + if (ny < iwin->zone->y) + ny = iwin->zone->y; + else if ((ny + bd->h) > (iwin->zone->y + iwin->zone->h)) + return; + + /* move the border if we need to */ + if (bd->y != ny) + { + bd->y = ny; + bd->changes.pos = 1; + bd->changed = 1; + } + } +} + +static void +_e_mod_ind_win_cb_min_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord h) +{ + Ind_Win *iwin; + + if (!(iwin = data)) return; + if (gc != iwin->gadcon) return; + if (h < iwin->win->h) h = iwin->win->h; + edje_extern_object_min_size_set(iwin->gadcon->o_container, w, h); +} + +static void +_e_mod_ind_win_cb_size_request(void *data __UNUSED__, E_Gadcon *gc __UNUSED__, Evas_Coord w __UNUSED__, Evas_Coord h __UNUSED__) +{ + return; +} + +static Evas_Object * +_e_mod_ind_win_cb_frame_request(void *data __UNUSED__, E_Gadcon_Client *gcc __UNUSED__, const char *style __UNUSED__) +{ + return NULL; +} + +static void +_e_mod_ind_win_cb_menu_items_append(void *data, E_Gadcon_Client *gcc __UNUSED__, E_Menu *mn) +{ + Ind_Win *iwin; + + if (!(iwin = data)) return; + _e_mod_ind_win_cb_menu_append(iwin, mn); +} + +static void +_e_mod_ind_win_cb_menu_append(Ind_Win *iwin, E_Menu *mn) +{ + E_Menu *subm; + E_Menu_Item *mi; + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), + "%s/e-module-illume-indicator.edj", _ind_mod_dir); + + subm = e_menu_new(); + mi = e_menu_item_new(mn); + e_menu_item_label_set(mi, _("Illume Indicator")); + e_menu_item_icon_edje_set(mi, buff, "icon"); + e_menu_pre_activate_callback_set(subm, _e_mod_ind_win_cb_menu_pre, iwin); + e_menu_item_submenu_set(mi, subm); +} + +static void +_e_mod_ind_win_cb_menu_pre(void *data, E_Menu *mn) +{ + Ind_Win *iwin; + E_Menu_Item *mi; + + if (!(iwin = data)) return; + e_menu_pre_activate_callback_set(mn, NULL, NULL); + + mi = e_menu_item_new(mn); + e_menu_item_label_set(mi, _("Set Contents")); + e_util_menu_item_theme_icon_set(mi, "preferences-desktop-shelf"); + e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_contents, iwin); + + mi = e_menu_item_new(mn); + if (iwin->gadcon->editing) + e_menu_item_label_set(mi, _("End Move/Resize Items")); + else + e_menu_item_label_set(mi, _("Begin Move/Resize Items")); + + e_util_menu_item_theme_icon_set(mi, "transform-scale"); + e_menu_item_callback_set(mi, _e_mod_ind_win_cb_menu_edit, iwin); +} + +static void +_e_mod_ind_win_cb_menu_post(void *data, E_Menu *mn __UNUSED__) +{ + Ind_Win *iwin; + + if (!(iwin = data)) return; + if (!iwin->menu) return; + e_object_del(E_OBJECT(iwin->menu)); + iwin->menu = NULL; +} + +static void +_e_mod_ind_win_cb_menu_contents(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__) +{ + Ind_Win *iwin; + + if (!(iwin = data)) return; + if (!iwin->gadcon->config_dialog) + e_int_gadcon_config_shelf(iwin->gadcon); +} + +static void +_e_mod_ind_win_cb_menu_edit(void *data, E_Menu *mn __UNUSED__, E_Menu_Item *mi __UNUSED__) +{ + Ind_Win *iwin; + + if (!(iwin = data)) return; + if (iwin->gadcon->editing) + e_gadcon_edit_end(iwin->gadcon); + else + e_gadcon_edit_begin(iwin->gadcon); +} diff --git a/src/modules/illume-indicator/e_mod_ind_win.h b/src/modules/illume-indicator/e_mod_ind_win.h new file mode 100644 index 000000000..1f2036585 --- /dev/null +++ b/src/modules/illume-indicator/e_mod_ind_win.h @@ -0,0 +1,32 @@ +#ifndef E_MOD_IND_WIN_H +# define E_MOD_IND_WIN_H + +/* define indicator window object type */ +# define IND_WIN_TYPE 0xE1b0886 + +/* define structure for indicator window */ +typedef struct _Ind_Win Ind_Win; +struct _Ind_Win +{ + E_Object e_obj_inherit; + + E_Zone *zone; + E_Border_Hook *hook; + Ecore_Event_Handler *scale_hdl; + + E_Win *win; + Evas_Object *o_base, *o_event; + E_Gadcon *gadcon; + E_Menu *menu; + + struct + { + int y, start, dnd, by; + } drag; + + int mouse_down; +}; + +Ind_Win *e_mod_ind_win_new(E_Zone *zone); + +#endif diff --git a/src/modules/illume-indicator/e_mod_main.c b/src/modules/illume-indicator/e_mod_main.c new file mode 100644 index 000000000..c825207ed --- /dev/null +++ b/src/modules/illume-indicator/e_mod_main.c @@ -0,0 +1,72 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_ind_win.h" + +/* local variables */ +static Eina_List *iwins = NULL; + +/* external variables */ +const char *_ind_mod_dir = NULL; + +EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Illume-Indicator" }; + +EAPI void * +e_modapi_init(E_Module *m) +{ + E_Manager *man; + Eina_List *ml; + + /* set module priority so we load before others */ + e_module_priority_set(m, 90); + + /* set module directory variable */ + _ind_mod_dir = eina_stringshare_add(m->dir); + + /* loop through the managers (root windows) */ + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + E_Container *con; + Eina_List *cl; + + /* loop through containers */ + EINA_LIST_FOREACH(man->containers, cl, con) + { + E_Zone *zone; + Eina_List *zl; + + /* for each zone, create an indicator window */ + EINA_LIST_FOREACH(con->zones, zl, zone) + { + Ind_Win *iwin; + + /* try to create new indicator window */ + if (!(iwin = e_mod_ind_win_new(zone))) continue; + iwins = eina_list_append(iwins, iwin); + } + } + } + + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + Ind_Win *iwin; + + /* destroy the indicator windows */ + EINA_LIST_FREE(iwins, iwin) + e_object_del(E_OBJECT(iwin)); + + /* clear module directory variable */ + if (_ind_mod_dir) eina_stringshare_del(_ind_mod_dir); + _ind_mod_dir = NULL; + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return 1; +} diff --git a/src/modules/illume-indicator/e_mod_main.h b/src/modules/illume-indicator/e_mod_main.h new file mode 100644 index 000000000..9591f0c1f --- /dev/null +++ b/src/modules/illume-indicator/e_mod_main.h @@ -0,0 +1,12 @@ +#ifndef E_MOD_MAIN_H +# define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init(E_Module *m); +EAPI int e_modapi_shutdown(E_Module *m); +EAPI int e_modapi_save(E_Module *m); + +extern const char *_ind_mod_dir; + +#endif diff --git a/src/modules/illume-indicator/images/Makefile.am b/src/modules/illume-indicator/images/Makefile.am new file mode 100644 index 000000000..692077fed --- /dev/null +++ b/src/modules/illume-indicator/images/Makefile.am @@ -0,0 +1,4 @@ +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = base_bg.png \ + module_icon.png diff --git a/src/modules/illume-indicator/images/base_bg.png b/src/modules/illume-indicator/images/base_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..a47ea165923aadf3639f3ef90477b71550b4914e GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^Y(T8U!2~2fPqw!QQq09po*^6@9Je3(KLBz~JzX3_ zG|ngg`TyUZSt}vw0D}$>56=m%|NsB{&%3a{{{M<)Ss{-XT=LlSkzd~K&#$lAMZcIB YEQ$_kJ3a6!1scHM>FVdQ&MBb@0Hcp8&Hw-a literal 0 HcmV?d00001 diff --git a/src/modules/illume-indicator/images/module_icon.png b/src/modules/illume-indicator/images/module_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..82c1b76f30170677b37b1e6923e50fc6ff269186 GIT binary patch literal 2815 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 R)rbH9002ovPDHLkV1m0vG@bwe literal 0 HcmV?d00001 diff --git a/src/modules/illume-indicator/module.desktop.in b/src/modules/illume-indicator/module.desktop.in new file mode 100644 index 000000000..249dbf46a --- /dev/null +++ b/src/modules/illume-indicator/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Illume-Indicator +Icon=e-module-illume-indicator +X-Enlightenment-ModuleType=system +Comment=Illume Indicator for Embedded diff --git a/src/modules/illume-softkey/Makefile.am b/src/modules/illume-softkey/Makefile.am new file mode 100644 index 000000000..e9b26d9cf --- /dev/null +++ b/src/modules/illume-softkey/Makefile.am @@ -0,0 +1,51 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume-softkey +SUBDIRS = images + +EDJE_CC = @edje_cc@ +EDJE_FLAGS = -v \ + -id $(top_srcdir)/src/modules/$(MODULE)/images \ + @EDJE_DEF@ + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ + e-module-$(MODULE).edj \ + module.desktop + +EXTRA_DIST = \ + e-module-$(MODULE).edc \ + module.desktop.in + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ + +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ + e_mod_sft_win.c \ + e_mod_sft_win.h \ + e_mod_main.c \ + e_mod_main.h + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +e-module-$(MODULE).edj: Makefile $(EXTRA_DIST) + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/src/modules/$(MODULE)/e-module-$(MODULE).edc \ + $(top_builddir)/src/modules/$(MODULE)/e-module-$(MODULE).edj + +clean-local: + rm -f *.edj + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/illume-softkey/e-module-illume-softkey.edc b/src/modules/illume-softkey/e-module-illume-softkey.edc new file mode 100644 index 000000000..73d4f3ccf --- /dev/null +++ b/src/modules/illume-softkey/e-module-illume-softkey.edc @@ -0,0 +1,133 @@ +collections +{ + group + { + images.image: "module_icon.png" COMP; + name: "icon"; + max: 128 128; + parts + { + part + { + name: "base"; + mouse_events: 0; + description + { + state: "default" 0.0; + aspect: 1.0 1.0; + aspect_preference: BOTH; + image.normal: "module_icon.png"; + } + } + } + } + group + { + images + { + image: "shelf_alt_bg.png" COMP; + image: "shelf_alt_over.png" COMP; + image: "shelf_alt_shine.png" COMP; + } + name: "modules/illume-softkey/window"; + parts + { + part + { + name: "base"; + type: IMAGE; + mouse_events: 0; + description + { + state: "default" 0.0; + color_class: "shelf_base"; + image.normal: "shelf_alt_bg.png"; + fill.smooth: 0; + } + } + part + { + name: "shine"; + type: IMAGE; + mouse_events: 0; + description + { + state: "default" 0.0; + image.normal: "shelf_alt_shine.png"; + rel2.relative: 1.0 0.5; + fill.smooth: 0; + } + } + part + { + name: "over"; + type: IMAGE; + mouse_events: 0; + description + { + state: "default" 0.0; + image + { + normal: "shelf_alt_over.png"; + border: 5 5 5 5; + middle: 0; + } + fill.smooth: 0; + } + } + part + { + name: "e.box.extra_buttons"; + type: BOX; + description + { + state: "default" 0.0; + rel1 + { + offset: 3 3; + to: "base"; + } + rel2 + { + relative: 0.60 1.0; + offset: 0 -4; + to: "base"; + } + box + { + layout: "horizontal"; + padding: 2 0; + align: 0.0 0.5; + min: 1 1; + } + } + } + part + { + name: "e.box.buttons"; + type: BOX; + description + { + state: "default" 0.0; + rel1 + { + relative: 1.0 0.0; + to: "e.box.extra_buttons"; + } + rel2 + { + offset: -2 -4; + to: "base"; + } + box + { + layout: "horizontal"; + padding: 2 0; + align: 1.0 0.5; + min: 1 1; + } + } + } + } + } +} diff --git a/src/modules/illume-softkey/e_mod_main.c b/src/modules/illume-softkey/e_mod_main.c new file mode 100644 index 000000000..0be948f57 --- /dev/null +++ b/src/modules/illume-softkey/e_mod_main.c @@ -0,0 +1,76 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_sft_win.h" + +/* local variables */ +static Eina_List *swins = NULL; + +/* external variables */ +const char *_sft_mod_dir = NULL; + +EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Illume-Softkey" }; + +EAPI void * +e_modapi_init(E_Module *m) +{ + E_Manager *man; + Eina_List *ml; + + /* set module priority so we load before others */ + e_module_priority_set(m, 85); + + /* set module directory variable */ + _sft_mod_dir = eina_stringshare_add(m->dir); + + /* loop through the managers (root windows) */ + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + E_Container *con; + Eina_List *cl; + + /* loop through containers */ + EINA_LIST_FOREACH(man->containers, cl, con) + { + E_Zone *zone; + Eina_List *zl; + + /* for each zone, create a softkey window */ + EINA_LIST_FOREACH(con->zones, zl, zone) + { + Sft_Win *swin; + + /* try to create new softkey window */ + if (!(swin = e_mod_sft_win_new(zone))) continue; + swins = eina_list_append(swins, swin); + } + } + } + + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + Sft_Win *swin; + + /* destroy the softkey windows */ + EINA_LIST_FREE(swins, swin) + e_object_del(E_OBJECT(swin)); + + /* reset softkey geometry for conformant apps */ + ecore_x_e_illume_softkey_geometry_set(ecore_x_window_root_first_get(), + 0, 0, 0, 0); + + /* clear module directory variable */ + if (_sft_mod_dir) eina_stringshare_del(_sft_mod_dir); + _sft_mod_dir = NULL; + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return 1; +} diff --git a/src/modules/illume-softkey/e_mod_main.h b/src/modules/illume-softkey/e_mod_main.h new file mode 100644 index 000000000..78ba22502 --- /dev/null +++ b/src/modules/illume-softkey/e_mod_main.h @@ -0,0 +1,12 @@ +#ifndef E_MOD_MAIN_H +# define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init(E_Module *m); +EAPI int e_modapi_shutdown(E_Module *m); +EAPI int e_modapi_save(E_Module *m); + +extern const char *_sft_mod_dir; + +#endif diff --git a/src/modules/illume-softkey/e_mod_sft_win.c b/src/modules/illume-softkey/e_mod_sft_win.c new file mode 100644 index 000000000..72aec3569 --- /dev/null +++ b/src/modules/illume-softkey/e_mod_sft_win.c @@ -0,0 +1,333 @@ +#include "e.h" +#include "e_mod_main.h" +#include "e_mod_sft_win.h" + +/* local function prototypes */ +static void _e_mod_sft_win_cb_free(Sft_Win *swin); +static void _e_mod_sft_win_cb_hook_eval_end(void *data, void *data2); +static int _e_mod_sft_win_cb_win_prop(void *data, int type __UNUSED__, void *event); +static int _e_mod_sft_win_cb_client_message(void *data, int type __UNUSED__, void *event); +static void _e_mod_sft_win_cb_resize(E_Win *win); +static void _e_mod_sft_win_create_default_buttons(Sft_Win *swin); +static void _e_mod_sft_win_cb_close(void *data, void *data2 __UNUSED__); +static void _e_mod_sft_win_cb_back(void *data, void *data2 __UNUSED__); + +Sft_Win * +e_mod_sft_win_new(E_Zone *zone) +{ + Sft_Win *swin; + Ecore_X_Window_State states[2]; + + /* create our new softkey window object */ + swin = E_OBJECT_ALLOC(Sft_Win, SFT_WIN_TYPE, _e_mod_sft_win_cb_free); + if (!swin) return NULL; + + swin->zone = zone; + + /* hook into eval so we can set the softkey on the correct zone + swin->hook = e_border_hook_add(E_BORDER_HOOK_EVAL_END, + _e_mod_sft_win_cb_hook_eval_end, swin); +*/ + + /* hook into property change so we can adjust w/ e_scale */ + swin->scale_hdl = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _e_mod_sft_win_cb_win_prop, swin); + + /* hook into client messages + swin->msg_hdl = + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + _e_mod_sft_win_cb_client_message, swin); + */ + + /* create new window */ + swin->win = e_win_new(zone->container); + swin->win->data = swin; + + /* set some properties on the window */ + e_win_title_set(swin->win, _("Illume Softkey")); + e_win_name_class_set(swin->win, "Illume-Softkey", "Illume-Softkey"); + e_win_no_remember_set(swin->win, EINA_TRUE); + + /* hook into window resize so we can resize our objects */ + e_win_resize_callback_set(swin->win, _e_mod_sft_win_cb_resize); + + /* set this window to not show in taskbar or pager */ + states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER; + ecore_x_netwm_window_state_set(swin->win->evas_win, states, 2); + + /* set this window to not accept or take focus */ + ecore_x_icccm_hints_set(swin->win->evas_win, 0, 0, 0, 0, 0, 0, 0); + + /* create our base object */ + swin->o_base = edje_object_add(swin->win->evas); + if (!e_theme_edje_object_set(swin->o_base, + "base/theme/modules/illume-softkey", + "modules/illume-softkey/window")) + { + char buff[PATH_MAX]; + + snprintf(buff, sizeof(buff), + "%s/e-module-illume-softkey.edj", _sft_mod_dir); + edje_object_file_set(swin->o_base, buff, + "modules/illume-softkey/window"); + } + evas_object_move(swin->o_base, 0, 0); + evas_object_show(swin->o_base); + + /* create default buttons */ + _e_mod_sft_win_create_default_buttons(swin); + + /* set minimum size of this window */ + e_win_size_min_set(swin->win, zone->w, (32 * e_scale)); + + /* position and resize this window */ + e_win_move_resize(swin->win, zone->x, (zone->y + zone->h - (32 * e_scale)), + zone->w, (32 * e_scale)); + + /* show the window */ + e_win_show(swin->win); + + e_border_zone_set(swin->win->border, zone); + + /* set this window to be a dock window. This needs to be done after show + * as E will sometimes reset the window type */ + ecore_x_netwm_window_type_set(swin->win->evas_win, ECORE_X_WINDOW_TYPE_DOCK); + + /* tell conformant apps our position and size */ + ecore_x_e_illume_softkey_geometry_set(zone->black_win, + zone->x, (zone->h - (32 * e_scale)), + zone->w, (32 * e_scale)); + + return swin; +} + +/* local functions */ +static void +_e_mod_sft_win_cb_free(Sft_Win *swin) +{ + const Evas_Object *box; + + /* delete the message handler */ + if (swin->msg_hdl) ecore_event_handler_del(swin->msg_hdl); + swin->msg_hdl = NULL; + + /* delete the scale handler */ + if (swin->scale_hdl) ecore_event_handler_del(swin->scale_hdl); + swin->scale_hdl = NULL; + + /* delete the border hook */ + if (swin->hook) e_border_hook_del(swin->hook); + swin->hook = NULL; + + if (box = edje_object_part_object_get(swin->o_base, "e.box.buttons")) + { + Evas_Object *btn; + + /* delete the buttons */ + EINA_LIST_FREE(swin->btns, btn) + { + edje_object_part_box_remove(swin->o_base, "e.box.buttons", btn); + evas_object_del(btn); + } + } + if (box = edje_object_part_object_get(swin->o_base, "e.box.extra_buttons")) + { + Evas_Object *btn; + + /* delete the buttons */ + EINA_LIST_FREE(swin->extra_btns, btn) + { + edje_object_part_box_remove(swin->o_base, "e.box.extra_buttons", btn); + evas_object_del(btn); + } + } + + /* delete the objects */ + if (swin->o_base) evas_object_del(swin->o_base); + swin->o_base = NULL; + + /* delete the window */ + if (swin->win) e_object_del(E_OBJECT(swin->win)); + swin->win = NULL; + + /* tell conformant apps our position and size */ + ecore_x_e_illume_softkey_geometry_set(swin->zone->black_win, 0, 0, 0, 0); + + /* free the allocated object */ + E_FREE(swin); +} + +static void +_e_mod_sft_win_cb_hook_eval_end(void *data, void *data2) +{ + Sft_Win *swin; + E_Border *bd; + + if (!(swin = data)) return; + if (!(bd = data2)) return; + if (bd != swin->win->border) return; + + /* check border position and size */ + if (bd->x != swin->zone->x) + { + bd->x = swin->zone->x; + bd->changes.pos = 1; + } + if (bd->y != ((swin->zone->y + swin->zone->h) - bd->h)) + { + bd->y = ((swin->zone->y + swin->zone->h) - bd->h); + bd->changes.pos = 1; + } + if (bd->w != swin->zone->w) + { + bd->w = swin->zone->w; + bd->changes.size = 1; + } + if ((bd->changes.pos) || (bd->changes.size)) bd->changed = 1; + + /* if zone is not correct, set it */ + if (bd->zone != swin->zone) e_border_zone_set(bd, swin->zone); +} + +static int +_e_mod_sft_win_cb_win_prop(void *data, int type __UNUSED__, void *event) +{ + Sft_Win *swin; + Ecore_X_Event_Window_Property *ev; + + ev = event; + + if (!(swin = data)) return 1; + if (ev->win != ecore_x_window_root_get(swin->win->evas_win)) return 1; + if (strcmp(ecore_x_atom_name_get(ev->atom), "ENLIGHTENMENT_SCALE")) return 1; + + /* set minimum size of this window */ + e_win_size_min_set(swin->win, swin->zone->w, (32 * e_scale)); + + /* resize this window */ + e_win_resize(swin->win, swin->zone->w, (32 * e_scale)); + + /* tell conformant apps our position and size */ + ecore_x_e_illume_softkey_geometry_set(swin->zone->black_win, + swin->win->x, swin->win->y, + swin->win->w, (32 * e_scale)); + return 1; +} + +static int +_e_mod_sft_win_cb_client_message(void *data, int type __UNUSED__, void *event) +{ + Sft_Win *swin; + Ecore_X_Event_Client_Message *ev; + + ev = event; + if (!(swin = data)) return 1; + if (ev->win != swin->zone->black_win) return 1; + return 1; +} + +static void +_e_mod_sft_win_cb_resize(E_Win *win) +{ + Sft_Win *swin; + Evas_Object *btn; + const Evas_Object *box; + Eina_List *l; + int mw, mh; + + if (!(swin = win->data)) return; + + /* adjust button(s) size for e_scale */ + EINA_LIST_FOREACH(swin->btns, l, btn) + { + e_widget_size_min_get(btn, &mw, &mh); + evas_object_size_hint_min_set(btn, (mw * e_scale), (mh * e_scale)); + evas_object_resize(btn, (mw * e_scale), (mh * e_scale)); + } + + /* adjust box size for content */ + if (box = edje_object_part_object_get(swin->o_base, "e.box.buttons")) + { + evas_object_size_hint_min_get((Evas_Object *)box, &mw, &mh); + evas_object_resize((Evas_Object *)box, mw, mh); + } + + mw = mh = 0; + /* adjust button(s) size for e_scale */ + EINA_LIST_FOREACH(swin->extra_btns, l, btn) + { + e_widget_size_min_get(btn, &mw, &mh); + evas_object_size_hint_min_set(btn, (mw * e_scale), (mh * e_scale)); + evas_object_resize(btn, (mw * e_scale), (mh * e_scale)); + } + + /* adjust box size for content */ + if (box = edje_object_part_object_get(swin->o_base, "e.box.extra_buttons")) + { + evas_object_size_hint_min_get((Evas_Object *)box, &mw, &mh); + evas_object_resize((Evas_Object *)box, mw, mh); + } + + /* resize the base object */ + if (swin->o_base) evas_object_resize(swin->o_base, win->w, win->h); +} + +static void +_e_mod_sft_win_create_default_buttons(Sft_Win *swin) +{ + Evas_Object *btn; + int mw, mh; + + /* create back button */ + btn = e_widget_button_add(swin->win->evas, _("Back"), "go-previous", + _e_mod_sft_win_cb_back, swin, NULL); + e_widget_size_min_get(btn, &mw, &mh); + evas_object_size_hint_min_set(btn, (mw * e_scale), (mh * e_scale)); + + /* NB: this show is required when packing e_widgets into an edje box else + * the widgets do not receive any events */ + evas_object_show(btn); + + /* add button to box */ + edje_object_part_box_append(swin->o_base, "e.box.buttons", btn); + + /* add button to our list */ + swin->btns = eina_list_append(swin->btns, btn); + + + /* create close button */ + btn = e_widget_button_add(swin->win->evas, _("Close"), "window-close", + _e_mod_sft_win_cb_close, swin, NULL); + e_widget_size_min_get(btn, &mw, &mh); + evas_object_size_hint_min_set(btn, (mw * e_scale), (mh * e_scale)); + + /* NB: this show is required when packing e_widgets into an edje box else + * the widgets do not receive any events */ + evas_object_show(btn); + + /* add button to box */ + edje_object_part_box_append(swin->o_base, "e.box.buttons", btn); + + /* add button to our list */ + swin->btns = eina_list_append(swin->btns, btn); +} + +static void +_e_mod_sft_win_cb_close(void *data, void *data2 __UNUSED__) +{ + Sft_Win *swin; + + if (!(swin = data)) return; + ecore_x_e_illume_close_send(swin->zone->black_win); +} + +static void +_e_mod_sft_win_cb_back(void *data, void *data2 __UNUSED__) +{ + Sft_Win *swin; + + if (!(swin = data)) return; + ecore_x_e_illume_focus_back_send(swin->zone->black_win); +} diff --git a/src/modules/illume-softkey/e_mod_sft_win.h b/src/modules/illume-softkey/e_mod_sft_win.h new file mode 100644 index 000000000..d481ed1f2 --- /dev/null +++ b/src/modules/illume-softkey/e_mod_sft_win.h @@ -0,0 +1,24 @@ +#ifndef E_MOD_SFT_WIN_H +# define E_MOD_SFT_WIN_H + +/* define softkey window object type */ +# define SFT_WIN_TYPE 0xE1b0784 + +/* define structure for softkey window */ +typedef struct _Sft_Win Sft_Win; +struct _Sft_Win +{ + E_Object e_obj_inherit; + + E_Zone *zone; + E_Border_Hook *hook; + Ecore_Event_Handler *scale_hdl, *msg_hdl; + + E_Win *win; + Evas_Object *o_base; + Eina_List *btns, *extra_btns; +}; + +Sft_Win *e_mod_sft_win_new(E_Zone *zone); + +#endif diff --git a/src/modules/illume-softkey/images/Makefile.am b/src/modules/illume-softkey/images/Makefile.am new file mode 100644 index 000000000..e6de6fd76 --- /dev/null +++ b/src/modules/illume-softkey/images/Makefile.am @@ -0,0 +1,6 @@ +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = shelf_alt_bg.png \ + shelf_alt_shine.png \ + module_icon.png \ + shelf_alt_over.png diff --git a/src/modules/illume-softkey/images/module_icon.png b/src/modules/illume-softkey/images/module_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..82c1b76f30170677b37b1e6923e50fc6ff269186 GIT binary patch literal 2815 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 R)rbH9002ovPDHLkV1m0vG@bwe literal 0 HcmV?d00001 diff --git a/src/modules/illume-softkey/images/shelf_alt_bg.png b/src/modules/illume-softkey/images/shelf_alt_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..64e2b2c2c3df3c9d47a5f939e7134baa5503be2c GIT binary patch literal 1232 zcmV;>1TXuEP)2=83?r5N|1WbNtkcOH-Nil>$e=(wNvzm9NJ=FD;TL}l zzx?wY;5oo^fad_u0iFXq2Y3$f9N-s!&f_pZgeX8OH_JouoorrqkB?pZZ<3Jug>IhBseKc~dDsya zTDbfBb^jegdZ*Jv7{W99fDNe!nd7owS_0 zX;|5^e?@Hmc@yqi3#*7d0s;Zsyefb&_fBob;%#Vd%kKhcS){;94YG=HrB>gkGR4rH zmY@=)9rlqmaoSeoFU0Ls12RJg^BlL|ig7xesB2|Dpv`*5o z!0}|K?PYzL1Q;iQB?i-P%X#3i8`97PBMT!6CCFB5+JKiO5yX-T)6QP68DY1Az|C3yuj8|CP1Eo*pM}nUJ_{5^h|j=*GBXNh}M(Nk<`4P*Ygp))9gDK zy?^F4)!p-$J10}=N_2b7dC^N1AqqI{H~_8u7K)IXa!E+Fi-@Tlua`9dAd<8$(UHJ_ z(oF$ZElw3HPiw|L1)PWd?v}v&0i+la>Xhno0W*IyLYnd?k$66p70*qk7r(WB1U-VA zG};LNG#*3a+du>>8B2S^US5p+z)<$7b+`rM3ut$;JdeYsjvr!D!;6#HoMd`{&^#)< z6xVDUDZP#)%SM?+mO->z?XMzkP1uq%4p)LRrM+=!3edHxx22mKl_^x~M!)hVFtLw~ z)4U(h6%;vfrRDLI8#}<2r06`jq1xyt9JQM1iKjQj)^05+F^)flTxynXJ95UDk?LK^ ziU`Z&spG8FX{%CMkyxluWZ5|x_T*{}{tFm=q2Tvv#J{u<-%9=u50;o~V+~T-5X&3% z^bD3Vt-K9LoPd{Fhb_&tsnVu(vd3VMVNPqZR~Yw(nER;EZ5yM!dbAYgo%H{r9rz0( zGi%BdZPe6MWDKs<$t@tQNomjj*=f?Db&hFrZ4Rmg^l_Bfsx zJMOJ3=|y~4bvPnqO6`r_K)>wBdZV@eFm9v3J~)ZdjN8o3HciA<*wfCI7ea69dpEVS z%03DFJUn@ZbW!7-FYmTP3d+Qe(Cp1a5gxf?rC*A8_bWu_GMqZM7 uj#H4Svyj~FvFWG;2Kxp^pMP-t*Uuj?5BVNW09Atk0000 literal 0 HcmV?d00001 diff --git a/src/modules/illume-softkey/images/shelf_alt_over.png b/src/modules/illume-softkey/images/shelf_alt_over.png new file mode 100644 index 0000000000000000000000000000000000000000..cef17132f12b7a0ee2a9edcc40607b86c502fc46 GIT binary patch literal 502 zcmVb;@5Jmr*r9(79k*H~sE6~uOG!#_aCAmlr6NwfHDK#{R zf&w9fVnK+_j>kBS7vmE|-^w(WT>a<&XJ>b9y4~)3zuymgyxcPkkIUbLd0bn|v z+R9h09lsN zMJUTMy#bImvAYKlLI7otkgzwguse{}$ARnhO6P#rTn~W%2>p!%QlHHneGmAlM&gcwjs+9;SVGmSRAvy;tb3j#7!U(1H0bra1m1Q(dQ#uE{=6X2boTGEV zYo-ObTrL#{=;nZklmKxY(>ahNNqMoABne#;$8lUC9K+asT@v5pxN$yBe02nt zrqIneah#Kl+Q(DGIO(jtI#0J95vag!InU@e`c-4&9yL8b3P=O4N2ZWRk?1sM&>}!E zqE7FxAh4G$t6nKjLxL@zmTX3A;b$n6!5Xz$^bzMG>!k8^1T+X%p9U-nYLtzM0@<-t zXg1(viiMLNXd&p$6luUckVbD2;=r8+rYv|>@~=NOUNW~7h3>&+m13S0DMuxJ&<`l6 z`wgVGJ;{kGDx(PnOX>4yKO(R+g{l|yTPjsjnT%=;c&v`V;WyyDTg$JeiS%3x_W#o9 nMIllume Softkey for Embedded diff --git a/src/modules/illume2/Makefile.am b/src/modules/illume2/Makefile.am new file mode 100644 index 000000000..aefdf0639 --- /dev/null +++ b/src/modules/illume2/Makefile.am @@ -0,0 +1,80 @@ +MAINTAINERCLEANFILES = Makefile.in module.desktop +MODULE = illume2 +SUBDIRS = images keyboards policies doc + +EDJE_CC = @edje_cc@ +EDJE_FLAGS = -v \ + -id $(top_srcdir)/src/modules/$(MODULE)/images \ + @EDJE_DEF@ + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ + e-module-$(MODULE).edj \ + module.desktop + +EXTRA_DIST = \ + e-module-$(MODULE).edc \ + module.desktop.in + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ + +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ + e_illume.h \ + e_illume.c \ + e_illume_private.h \ + e_mod_config_policy.h \ + e_mod_config_policy.c \ + e_mod_select_window.h \ + e_mod_select_window.c \ + e_mod_config_windows.h \ + e_mod_config_windows.c \ + e_mod_config_animation.h \ + e_mod_config_animation.c \ + e_mod_quickpanel.h \ + e_mod_quickpanel.c \ + e_mod_kbd_dbus.h \ + e_mod_kbd_dbus.c \ + e_mod_kbd.h \ + e_mod_kbd.c \ + e_mod_policy.h \ + e_mod_policy.c \ + e_mod_config.h \ + e_mod_config.c \ + e_mod_main.h \ + e_mod_main.c + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +e-module-$(MODULE).edj: Makefile $(EXTRA_DIST) + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/src/modules/$(MODULE)/e-module-$(MODULE).edc \ + $(top_builddir)/src/modules/$(MODULE)/e-module-$(MODULE).edj + +.PHONY: doc + +# Documentation + +doc: + @echo "entering doc/" + make -C doc doc + +clean-local: + rm -f *.edj + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)/policies + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)/keyboards diff --git a/src/modules/illume2/doc/Doxyfile b/src/modules/illume2/doc/Doxyfile new file mode 100644 index 000000000..bdd35f508 --- /dev/null +++ b/src/modules/illume2/doc/Doxyfile @@ -0,0 +1,1349 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Illume + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 2 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = YES + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST = YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = NO + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c *.h *.x + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = YES + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = ./img + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 2 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = head.html + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = foot.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = e.css + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = YES + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 1 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = NO + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = __UNUSED__= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = NO + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/modules/illume2/doc/Makefile.am b/src/modules/illume2/doc/Makefile.am new file mode 100644 index 000000000..83826b4c2 --- /dev/null +++ b/src/modules/illume2/doc/Makefile.am @@ -0,0 +1,22 @@ +MAINTAINERCLEANFILES = Makefile.in + +.PHONY: doc + +if EFL_BUILD_DOC + +doc: all + rm -rf html/ latex/ man/ + $(efl_doxygen) + cp img/* html/ + +else + +doc: + @echo "Documentation not built. Run ./configure --help" + +endif + +clean-local: + @rm -rf html/ latex/ man/ + +EXTRA_DIST = Doxyfile $(wildcard img/*.*) e.css head.html foot.html diff --git a/src/modules/illume2/doc/e.css b/src/modules/illume2/doc/e.css new file mode 100644 index 000000000..2dd6b4479 --- /dev/null +++ b/src/modules/illume2/doc/e.css @@ -0,0 +1,273 @@ +/* + Author: + Andres Blanc + DaveMDS Andreoli + + Supported Browsers: + ie7, opera9, konqueror4 and firefox3 + + Please use a different file for ie6, ie5, etc. hacks. +*/ + + +/* Necessary to place the footer at the bottom of the page */ +html, body { + height: 100%; + margin: 0px; + padding: 0px; +} + +#container { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -53px; +} + +#footer, #push { + height: 53px; +} + + +* html #container { + height: 100%; +} + +/* Prevent floating elements overflowing containers */ +.clear { + clear: both; + width: 0px; + height: 0px; +} + +/* Flexible & centered layout from 750 to 960 pixels */ +.layout { + max-width: 960px; + min-width: 760px; + margin-left: auto; + margin-right: auto; +} + +body { + /*font-family: Lucida Grande, Helvetica, sans-serif;*/ + font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif +} + +/* Prevent design overflowing the viewport in small resolutions */ +#container { + padding-right: 17px; + padding-left: 17px; + background-image: url(head_bg.png); + background-repeat: repeat-x; +} + +/****************************/ +/* Top main menu */ +/****************************/ +#header_logo { + background-image : url(logo.png); + width : 61px; +} + +#header_logo a { + position : absolute; + border : 0px; + background-color : transparent; + top : 0px; + width : 60px; + height : 60px; +} + +#header_menu { + background-image : url(header_menu_background.png); + font : normal 10pt verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif; + text-align : right; +} + +#header_last { + background-image : url(header_menu_background_last.png); + width : 15px; +} + +td.nav_passive { + background : url(header_menu_unselected_background.png) 0 0 no-repeat; + height : 63px; + font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + font-size : 11px; + padding : 20px 10px 20px 10px; + vertical-align : middle; +} + +td.nav_active { + background : url(header_menu_current_background.png) 0 0 no-repeat; + height : 63px; + color : #646464; + font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + font-size : 11px; + font-weight : bold; + padding : 20px 10px 20px 10px; + vertical-align : middle; +} + +#header_menu a { + display : block; + text-decoration : none; + cursor : pointer; + color : #cdcdcd; +} + + + +#header { + width: 100%; + height: 102px; +} + +#header h1 { + width: 63px; + height: 63px; + position: absolute; + margin: 0px; +} + +#header h1 span { + display: none; +} + +#header h2 { + display: none; +} + +/* .menu-container is used to set properties common to .menu and .submenu */ +#header .menu-container { +} + +#header .menu-container ul { + list-style-type: none; + list-style-position: inside; + margin: 0; +} + +#header .menu-container li { + display: block; + float: right; +} + +#header .menu { + height: 63px; + display: block; + background-image: url(menu_bg.png); + background-repeat: repeat-x; +} + +#header .menu ul { + height: 100%; + display: block; + background-image: url(menu_bg_last.png); + background-repeat: no-repeat; + background-position: top right; + padding-right: 17px; +} + +#header .menu li { + height: 100%; + text-align: center; + background-image: url(menu_bg_unsel.png); + background-repeat: no-repeat; +} + +#header .menu a { + height: 100%; + display: block; + color: #cdcdcd; + text-decoration: none; + font-size: 10pt; + line-height: 59px; + text-align: center; + padding: 0px 15px 0px 15px; +} + +#header .menu li:hover { + background-image: url(menu_bg_hover.png); + background-repeat: no-repeat; +} + +#header .menu li:hover a { + color: #FFFFFF; +} + +#header .menu li.current { + background-image: url(menu_bg_current.png); + background-repeat: no-repeat; +} + +#header .menu li.current a { + color: #646464; +} + + +/* Hide all the submenus but the current */ +#header .submenu ul { + display: none; +} + +#header .submenu .current { + display: block; +} + +#header .submenu { + font: bold 10px verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif; + margin-top: 10px; +} + +#header .submenu a { + color: #888888; + text-decoration: none; + font-size: 0.9em; + line-height: 15px; + padding:0px 5px 0px 5px; +} + +#header .submenu a:hover { + color: #444444; +} + +#header .submenu li { + border-left: 1px solid #DDDDDD; +} + +#header .submenu li:last-child { + border-left: 0; +} + +#header .doxytitle { + position: absolute; + font-size: 1.8em; + font-weight: bold; + color: #444444; + line-height: 35px; +} + +#header small { + font-size: 0.4em; +} + +#footer { + background-image: url(foot_bg.png); + width: 100%; +} + +#footer table { + width: 100%; + text-align: center; + white-space: nowrap; + padding: 5px 30px 5px 30px; + font-size: 0.8em; + font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + color: #888888; +} + +#footer td.copyright { + width: 100%; +} + diff --git a/src/modules/illume2/doc/foot.html b/src/modules/illume2/doc/foot.html new file mode 100644 index 000000000..d43cf8fcc --- /dev/null +++ b/src/modules/illume2/doc/foot.html @@ -0,0 +1,18 @@ + +
+ + + + + + + + + + + diff --git a/src/modules/illume2/doc/head.html b/src/modules/illume2/doc/head.html new file mode 100644 index 000000000..2c617959f --- /dev/null +++ b/src/modules/illume2/doc/head.html @@ -0,0 +1,69 @@ + + + $title + + + + + + + + + + + + + + +
+ + + +
+
diff --git a/src/modules/illume2/doc/img/e.png b/src/modules/illume2/doc/img/e.png new file mode 100644 index 0000000000000000000000000000000000000000..d42aeb420098578b19a3eab3d6d1e6e73e3277bc GIT binary patch literal 30052 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 EKVH2_NB{r; literal 0 HcmV?d00001 diff --git a/src/modules/illume2/doc/img/edoxy.css b/src/modules/illume2/doc/img/edoxy.css new file mode 100644 index 000000000..311ca23d4 --- /dev/null +++ b/src/modules/illume2/doc/img/edoxy.css @@ -0,0 +1,486 @@ +/* + * This file contain a custom doxygen style to match e.org graphics + */ + + + +/* BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +}*/ +BODY, TD { + font-size: 12px; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { + font-weight: bold +} +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navpath { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { + text-decoration: none; + background-color: #6666cc; + color: #ffffff +} +A.el { + text-decoration: none; + font-weight: bold +} +A.elRef { + font-weight: bold +} +A.code:link { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +A.code:visited { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +A.codeRef:link { + font-weight: normal; + color: #0000FF +} +A.codeRef:visited { + font-weight: normal; + color: #0000FF +} +A:hover, A:visited:hover { + text-decoration: none; + /* background-color: #f2f2ff; */ + color: #000055; +} +A.anchor { + color: #000; +} +DL.el { + margin-left: -1cm +} +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px +} + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { + margin-left: 16px; + font-style: italic; + font-size: 90% +} +/*BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +}*/ +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { + text-align: center; +} +IMG.formulaDsp { +} +IMG.formulaInl { + vertical-align: middle; +} +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +SPAN.vhdldigit { color: #ff00ff } +SPAN.vhdlchar { color: #000000 } +SPAN.vhdlkeyword { color: #700070 } +SPAN.vhdllogic { color: #ff0000 } + +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { + color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { + font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { + background: #e8eef2; + font-weight: bold; +} +HR { + height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; + margin-left: 3px; +} +.memnav { + background-color: #eeeeee; + border: 1px solid #dddddd; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eeeeee; + border-width: 1px; + border-style: solid; + border-color: #dddddd; + -moz-border-radius: 4px 4px 4px 4px; +} +.memname { + white-space: nowrap; + font-weight: bold; + color: #ffffff; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #111111; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #000000; + font-weight: bold; + -moz-border-radius: 4px 4px 4px 4px; +} +.paramkey { + text-align: right; + color: #ffffff; +} +.paramtype { + white-space: nowrap; + color: #aaaaaa; +} +.paramname { + color: #ff0000; + font-style: italic; + white-space: nowrap; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +/* these are for tree view when used as main index */ +.directory { + font-size: 9pt; + font-weight: bold; +} +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* The following two styles can be used to replace the root node title */ +/* with an image of your choice. Simply uncomment the next two styles, */ +/* specify the name of your image and be sure to set 'height' to the */ +/* proper pixel height of your image. */ + +/* .directory h3.swap { */ +/* height: 61px; */ +/* background-repeat: no-repeat; */ +/* background-image: url("yourimage.gif"); */ +/* } */ +/* .directory h3.swap span { */ +/* display: none; */ +/* } */ + +.directory > h3 { + margin-top: 0; +} +.directory p { + margin: 0px; + white-space: nowrap; +} +.directory div { + display: none; + margin: 0px; +} +.directory img { + vertical-align: -30%; +} +/* these are for tree view when not used as main index */ +.directory-alt { + font-size: 100%; + font-weight: bold; +} +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} +.directory-alt > h3 { + margin-top: 0; +} +.directory-alt p { + margin: 0px; + white-space: nowrap; +} +.directory-alt div { + display: none; + margin: 0px; +} +.directory-alt img { + vertical-align: -30%; +} + diff --git a/src/modules/illume2/doc/img/foot_bg.png b/src/modules/illume2/doc/img/foot_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..b24f3a48b4e076b88cf1e802b46087ffbb3fabd5 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^j6iJ9!3HE1Qx}DR1d4;)ofy`glX(f`uqAoByD;nl zL8a%*b^=8>3p^r=85p>QL70(Y)*K0-AbW|YuPgga7CvEi%SZD}LFVdux;TbNTu#2R zIsJTn+kYTPulo1Ll3AD;2!xfDmD#wLvj}>v&@k-CVP=T_%(cphxuXQAk-^i|&t;uc GLK6Ub>Mc;VkfoEM{Qf z76xHPhFNnYfP(BLp1!W^H+WcuRXD>A=l%i;Wq7(chG?8W+i%Esz<`6f_y7NWHH!5o z63R1{^0cb0vMSkFaE_%x<+7O{*?Xs&Ff%xKT5jO&GtAqcqoa~}b>qg&H07ky z617wnX2HUfTT*8{kPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOZ8 z6%`IG`XD&~00I3;L_t(o!^Kz8j>8}fODg_+AF{uksuh}hxC0rJP`W$mkkHl^jB%XM z>f`Y+`Dtd>`gxwMmr`2KIk$cshdiH8N#}XW6$o}5WA?p%5)sKc%eHO9fR!#HlFUqU z&XQ6Z1~3DUmCHm#rjx?$lu|lm24QA+Eh4g2CJ}X<;QbGo;J_$CohD|s1Tu}z3KIrH zRtpQ8-Z|UyQP4caCB~&Z3QG0mMzcQLYIcQ!(sFW-xf9knF@|(?iY~XAOhHzd%#8OD2m>x}XSSsVf@;^obfpX48<@ZgFF$M4@xtjbM#B=Ojp!9yfFNKXj22K7STvD?00000NkvXXu0mjfB76)l literal 0 HcmV?d00001 diff --git a/src/modules/illume2/doc/img/header_menu_current_background.png b/src/modules/illume2/doc/img/header_menu_current_background.png new file mode 100644 index 0000000000000000000000000000000000000000..de97c9268e4ac68310c8b92d6ab6bd8a245611da GIT binary patch literal 1200 zcmV;h1W)^kP)002J-1^@s6XaB>y00001b5ch_0Itp) z=>Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RT3Fc5TrKj#zpOzs?z2=A0p@aw&u*pMn|G)ug+?Vh;0+zHe5dVLoF=!DBW&zJ?E zp99|S_j0@4%Io#|xG+sqdB5NP{rn5Cj%O+78UIn|DpKcsK9>`B2V6JsOB3oD&r;4a z{-e%Sw9ela{A&{jdu5*U-Tgr1~ zQc-ZvZCmQQrCnTG+COg8zWQ3Lv1sjNIKQPlR|Xsq_}(oT0MbDS91lPg3>xeBFKokrh3I+f~!N36>5GNtP zFb=56FWNP#oK=?bNEQ~!rtXW9X1GX=k~FL`OjOeF$R)LGB-wAZi(5xddgID^{pUl5 z$!2zVWE!iC5c%CAFL=jfl{TW1M$7Wjcr9z}SyPKmlC20r0B}G6Q80PClsJ^eQ9Rdb zuHflIJ5saoBdvW)J5o7`LrQ$sb0li*FS@pt^@$vLe#kJ^<1ntHwKLacEE8!V_VYY{ z^jk0Fa-9o0ILfhhgnDcg*`~%yk#UNgFLkMLQ1xp&>oHLMt>=krgKLZ9aoj&)eVyWk z+VI9yb#%knV zBgOT1iW^1q->g9a$6utrxv^4Ql-s5#yS%xS5>LwpJyaYZ1w-06F426k%%gi2p;YTL zn*Zi$*TU&q<}Gq{z5F%GPa}Dt9$}k233)sorIb>h&nNZ+VE-)`LNtIN1b_p=0f8Pk zSwvore6GJZg3A%uh&UU`%8A$z3ApNcvGym`^9BW5y;mkO7OVYaI#wj=im2;bzSt*w z8j*3rXhhk-tiA%ik?Y6P7yM_$}>d^Cl%aa8a!%A!J=gv)gqCjA%RAmjShY zk&jin$jBj)wrhPzE#o_v^@kLW;DnK~k;Uxogc+{8mlL+=3tKP%4hR4$2Lynj z95C}RO)LJ$<@I?2i7h|tH#%lcU&}tk-(ol0<1_foFDdWsgqjV%=7cRA;M<%KLNw4f z2!R6vT{&RuTk7799C>JZ4;!>{ThW;;ZOYD_SA%VO2ZR&C3B68;Eg1NXEf@e0gaF^` zfS#=57JO;X{zkCF($|*uL^8|wn48N;fkQ7R9I3CpA0+QRH%LYRy5b)R!`g7p731Il O0000002J-1^@s6XaB>y00001b5ch_0Itp) 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.zones, l, cz) + { + if (cz->id != id) continue; + return cz; + } + + /* we did not find an existing one for this zone, so create a new one */ + cz = E_NEW(E_Illume_Config_Zone, 1); + cz->id = id; + cz->mode.dual = 0; + cz->mode.side = 0; + + /* add it to the list */ + _e_illume_cfg->policy.zones = + eina_list_append(_e_illume_cfg->policy.zones, cz); + + /* save it in config */ + e_mod_config_save(); + + /* return a fallback */ + return cz; +} + +/** + * Determine if a given border is an Indicator window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is an Indicator window, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @note It is assumed that Indicator windows are of type + * ECORE_X_WINDOW_TYPE_DOCK. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_indicator(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* indicator windows should be set to dock type, so check for that */ + if (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) return EINA_FALSE; + + /* we have a dock window, check against any matches in config */ + + /* check if we are matching on name */ + if (_e_illume_cfg->policy.indicator.match.name) + { + if ((bd->client.icccm.name) && + (!strcmp(bd->client.icccm.name, + _e_illume_cfg->policy.indicator.name))) + return EINA_TRUE; + } + + /* check if we are matching on class */ + if (_e_illume_cfg->policy.indicator.match.class) + { + if ((bd->client.icccm.class) && + (!strcmp(bd->client.icccm.class, + _e_illume_cfg->policy.indicator.class))) + return EINA_TRUE; + } + + /* check if we are matching on title */ + if (_e_illume_cfg->policy.indicator.match.title) + { + const char *title; + + title = e_border_name_get(bd); + if (!strcmp(title, _e_illume_cfg->policy.indicator.title)) + return EINA_TRUE; + } + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a Softkey window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a Softkey window, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @note It is assumed that Softkey windows are of type + * ECORE_X_WINDOW_TYPE_DOCK. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_softkey(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* legacy code from illume 1 */ + if (bd->client.qtopia.soft_menu) return EINA_TRUE; + + /* softkey windows should be set to dock type, so check for that */ + if (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) return EINA_FALSE; + + /* we have a softkey window, check against any matches in config */ + + /* check if we are matching on name */ + if (_e_illume_cfg->policy.softkey.match.name) + { + if ((bd->client.icccm.name) && + (!strcmp(bd->client.icccm.name, + _e_illume_cfg->policy.softkey.name))) + return EINA_TRUE; + } + + /* check if we are matching on class */ + if (_e_illume_cfg->policy.softkey.match.class) + { + if ((bd->client.icccm.class) && + (!strcmp(bd->client.icccm.class, + _e_illume_cfg->policy.softkey.class))) + return EINA_TRUE; + } + + /* check if we are matching on title */ + if (_e_illume_cfg->policy.softkey.match.title) + { + const char *title; + + title = e_border_name_get(bd); + if (!strcmp(title, _e_illume_cfg->policy.softkey.title)) + return EINA_TRUE; + } + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a Keyboard window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a Keyboard window, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_keyboard(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* check for specific flag first */ + if (bd->client.vkbd.vkbd) return EINA_TRUE; + + /* legacy code from illume 1 */ + if ((bd->client.icccm.name) && + ((!strcmp(bd->client.icccm.name, "multitap-pad"))) && + (bd->client.netwm.state.skip_taskbar) && + (bd->client.netwm.state.skip_pager)) + return EINA_TRUE; + + /* check if we are matching on name */ + if (_e_illume_cfg->policy.vkbd.match.name) + { + if ((bd->client.icccm.name) && + (!strcmp(bd->client.icccm.name, + _e_illume_cfg->policy.vkbd.name))) + return EINA_TRUE; + } + + /* check if we are matching on class */ + if (_e_illume_cfg->policy.vkbd.match.class) + { + if ((bd->client.icccm.class) && + (!strcmp(bd->client.icccm.class, + _e_illume_cfg->policy.vkbd.class))) + return EINA_TRUE; + } + + /* check if we are matching on title */ + if (_e_illume_cfg->policy.vkbd.match.title) + { + const char *title; + + title = e_border_name_get(bd); + if (!strcmp(title, _e_illume_cfg->policy.vkbd.title)) + return EINA_TRUE; + } + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a Home window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a Home window, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_home(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* check if we are matching on name */ + if (_e_illume_cfg->policy.home.match.name) + { + if ((bd->client.icccm.name) && + (!strcmp(bd->client.icccm.name, + _e_illume_cfg->policy.home.name))) + return EINA_TRUE; + } + + /* check if we are matching on class */ + if (_e_illume_cfg->policy.home.match.class) + { + if ((bd->client.icccm.class) && + (!strcmp(bd->client.icccm.class, + _e_illume_cfg->policy.home.class))) + return EINA_TRUE; + } + + /* check if we are matching on title */ + if (_e_illume_cfg->policy.home.match.title) + { + const char *title; + + title = e_border_name_get(bd); + if (!strcmp(title, _e_illume_cfg->policy.home.title)) + return EINA_TRUE; + } + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a splash screen. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a splash screen, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_splash(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* check actual type */ + if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_SPLASH) return EINA_TRUE; + + /* check for transient flag */ +// if (bd->client.icccm.transient_for != 0) return EINA_TRUE; + + /* NB: may or may not need to handle these. Needs Testing */ + if (bd->client.netwm.extra_types) + printf("\t\tBorder has extra types: %s\n", bd->client.icccm.class); + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a dialog. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a dialog, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_dialog(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* check actual type */ + if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG) return EINA_TRUE; + + /* check for transient flag */ + if (bd->client.icccm.transient_for != 0) return EINA_TRUE; + + /* check for client leader */ + /* NB: disabled currently as some GTK windows set this even tho they are + * not a dialog. */ +// if (bd->client.icccm.client_leader) return EINA_TRUE; + + /* NB: may or may not need to handle these. Needs Testing */ + if (bd->client.netwm.extra_types) + printf("\t\tBorder has extra types: %s\n", bd->client.icccm.class); + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a QT VCLSalFrame. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a VCLSalFrame, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_qt_frame(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* make sure we have the icccm name and compare it */ + if ((bd->client.icccm.name) && + (!strncmp(bd->client.icccm.name, "VCLSalFrame", 11))) + return EINA_TRUE; + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is a fullscreen window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is fullscreen, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_fullscreen(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* check for fullscreen */ + if ((bd->fullscreen) || (bd->need_fullscreen)) return EINA_TRUE; + + /* return a fallback */ + return EINA_FALSE; +} + +/** + * Determine if a given border is an illume conformant window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is conformant, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_conformant(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* return if it is conformant or not */ + return bd->client.illume.conformant.conformant; +} + +/** + * Determine if a given border is a quickpanel window. + * + * @param bd The border to test. + * @return EINA_TRUE if it is a quickpanel, EINA_FALSE otherwise. + * + * @note If @p bd is NULL then this function will return EINA_FALSE. + * + * @ingroup E_Illume_Main_Group + */ +Eina_Bool +e_illume_border_is_quickpanel(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return EINA_FALSE; + + /* return if it is a quickpanel or not */ + return bd->client.illume.quickpanel.quickpanel; +} + +/** + * Retrieves the minimum space required to display this border. + * + * @param bd The border to get the minium space for. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + * + * @note if @p bd is NULL then @p w and @p h will return @c 0. + * + * @ingroup E_Illume_Main_Group + */ +void +e_illume_border_min_get(E_Border *bd, int *w, int *h) +{ + if (w) *w = 0; + if (h) *h = 0; + if (!bd) return; + + if (w) + { + if (bd->client.icccm.base_w > bd->client.icccm.min_w) + *w = bd->client.icccm.base_w; + else + *w = bd->client.icccm.min_w; + } + if (h) + { + if (bd->client.icccm.base_h > bd->client.icccm.min_h) + *h = bd->client.icccm.base_h; + else + *h = bd->client.icccm.min_h; + } +} + +/** + * Retrieves a border, given an x and y coordinate, from a zone. + * + * @param zone The zone. + * @param x The X coordinate to check for border at. + * @param y The Y coordinate to check for border at. + * + * @note if @p zone is NULL then this function will return NULL. + * + * @warning Both X and Y coordinates are required to reliably detect a border. + * + * @ingroup E_Illume_Main_Group + */ +E_Border * +e_illume_border_at_xy_get(E_Zone *zone, int x, int y) +{ + Eina_List *l; + E_Border *bd; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the border client list */ + /* NB: We use e_border_client_list here, rather than + * e_container_border_list, because e_border_client_list is faster. + * This is done in reverse order so we get the most recent border first */ + EINA_LIST_REVERSE_FOREACH(e_border_client_list(), l, bd) + { + /* check zone and skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip invisibles */ + if (!bd->visible) continue; + + /* filter out borders we don't want */ + if (e_illume_border_is_indicator(bd)) continue; + if (e_illume_border_is_softkey(bd)) continue; + if (e_illume_border_is_keyboard(bd)) continue; + if (e_illume_border_is_quickpanel(bd)) continue; + if (e_illume_border_is_home(bd)) continue; + + /* check position against given coordinates */ + if ((bd->x != x) || (bd->y != y)) continue; + + /* found one, return it */ + return bd; + } + + /* return a fallback */ + return NULL; +} + +/** + * Retrieve the parent of a given dialog. + * + * @param bd The border to get the parent of. + * @return The border's parent, or NULL if no parent exists. + * + * @note If @p bd is NULL then this function will return NULL. + * + * @ingroup E_Illume_Main_Group + */ +E_Border * +e_illume_border_parent_get(E_Border *bd) +{ + /* make sure we have a border */ + if (!bd) return NULL; + + /* check for border's parent */ + if (bd->parent) return bd->parent; + + /* NB: TEST CODE - may need to check bd->leader here */ + if (bd->leader) + { + printf("\tDialog Has Leader: %s\n", bd->client.icccm.name); + } + + /* check for transient */ + if (bd->client.icccm.transient_for) + { + /* try to find this borders parent */ + return e_border_find_by_client_window(bd->client.icccm.transient_for); + } + else if (bd->client.icccm.client_leader) + { + /* NB: using client_leader as parent. THIS NEEDS THOROUGH TESTING !! */ + return e_border_find_by_client_window(bd->client.icccm.client_leader); + } + + /* return a fallback */ + return NULL; +} + +/** + * Show a given border. + * + * @param bd The border to show. + * + * @note If @p bd is NULL then this function will return. + * + * @ingroup E_Illume_Main_Group + */ +void +e_illume_border_show(E_Border *bd) +{ + unsigned int visible = 1; + + /* make sure we have a border */ + if (!bd) return; + + /* NB: We handle shows this way so we don't get extra layout events from + * the e_border calls */ + e_container_border_lower(bd); + e_container_shape_show(bd->shape); + if (!bd->need_reparent) ecore_x_window_show(bd->client.win); + e_hints_window_visible_set(bd); + bd->visible = 1; + bd->changes.visible = 1; + ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1); + ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1); +} + +/** + * Hide a given border. + * + * @param bd The border to hide. + * + * @note If @p bd is NULL then this function will return. + * + * @ingroup E_Illume_Main_Group + */ +void +e_illume_border_hide(E_Border *bd) +{ + unsigned int visible = 0; + + /* make sure we have a border */ + if (!bd) return; + + /* NB: We handle hides this way so we don't get extra layout events from + * the e_border calls */ + e_container_shape_hide(bd->shape); + if (!bd->iconic) e_hints_window_hidden_set(bd); + bd->visible = 0; + bd->changes.visible = 1; + ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1); +} + +/** + * Retrieve the Indicator window on a given zone. + * + * @param zone The zone. + * @return The Indicator border, or NULL if no Indicator exists. + * + * @note If @p zone is NULL then this function will return NULL. + * + * @ingroup E_Illume_Main_Group + */ +E_Border * +e_illume_border_indicator_get(E_Zone *zone) +{ + Eina_List *l; + E_Border *bd; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the border client list */ + /* NB: We use e_border_client_list here, rather than + * e_container_border_list, because e_border_client_list is faster */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* check zone and skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip borders that are not indicators */ + if (!e_illume_border_is_indicator(bd)) continue; + + /* found one, return it */ + return bd; + } + + /* return a fallback */ + return NULL; +} + +/** + * Retrieves the current position of the Indicator window. + * + * @param zone The zone on which to retrieve the Indicator position. + * @param x Pointer to an integer into which the left is to be stored. + * @param y Pointer to an integer into which the top is to be stored. + * + * @note if @p zone is NULL then @p x, @p y, @p w, and @p h will return @c 0. + * + * @ingroup E_Illume_Main_Group + */ +void +e_illume_border_indicator_pos_get(E_Zone *zone, int *x, int *y) +{ + E_Border *ind; + + /* make sure we have a zone */ + if (!zone) + { + if (x) *x = 0; + if (y) *y = 0; + return; + } + + /* set default values */ + if (x) *x = zone->x; + if (y) *y = zone->y; + + /* try and get the Indicator on this zone */ + if (!(ind = e_illume_border_indicator_get(zone))) return; + + /* return Indicator position(s) */ + if (x) *x = ind->x; + if (y) *y = ind->y; +} + +/** + * Retrieve the Softkey window on a given zone. + * + * @param zone The zone. + * @return The Softkey border, or NULL if no Softkey exists. + * + * @note If @p zone is NULL then this function will return NULL. + * + * @ingroup E_Illume_Main_Group + */ +E_Border * +e_illume_border_softkey_get(E_Zone *zone) +{ + Eina_List *l; + E_Border *bd; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the border client list */ + /* NB: We use e_border_client_list here, rather than + * e_container_border_list, because e_border_client_list is faster */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* check zone and skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip borders that are not indicators */ + if (!e_illume_border_is_softkey(bd)) continue; + + /* found one, return it */ + return bd; + } + + /* return a fallback */ + return NULL; +} + +/** + * Retrieves the current position of the Softkey window. + * + * @param zone The zone on which to retrieve the Softkey position. + * @param x Pointer to an integer into which the left is to be stored. + * @param y Pointer to an integer into which the top is to be stored. + * + * @note if @p zone is NULL then @p x, @p y, @p w, and @p h will return @c 0. + * + * @ingroup E_Illume_Main_Group + */ +void +e_illume_border_softkey_pos_get(E_Zone *zone, int *x, int *y) +{ + E_Border *sft; + + /* make sure we have a zone */ + if (!zone) + { + if (x) *x = 0; + if (y) *y = 0; + return; + } + + /* set default values */ + if (x) *x = zone->x; + if (y) *y = zone->y; + + /* try and get the Softkey on this zone */ + if (!(sft = e_illume_border_softkey_get(zone))) return; + + /* return Indicator position(s) */ + if (x) *x = sft->x; + if (y) *y = sft->y; +} + +/** + * Retrieve the Keyboard on a given zone. + * + * @return The @ref E_Illume_Keyboard, or NULL if no keyboard exists. + * + * @ingroup E_Illume_Keyboard_Group + */ +E_Illume_Keyboard * +e_illume_keyboard_get(void) +{ + /* make sure we have a keyboard and a zone */ + if (!_e_illume_kbd) return NULL; + + /* return the keyboard */ + return _e_illume_kbd; +} + +/** + * Retrieves the available screen space not occupied by the virtual keyboard. + * + * @param zone The zone on which to retrieve the available space. + * @param x Pointer to an integer into which the left is to be stored. + * @param y Pointer to an integer into which the top is to be stored. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + * + * @note if @p zone is NULL then @p x, @p y, @p w, and @p h will return @c 0. + * + * @warning This function does not account for space or position of Indicator + * or Softkey windows. + * + * @ingroup E_Illume_Keyboard_Group + */ +void +e_illume_keyboard_safe_app_region_get(E_Zone *zone, int *x, int *y, int *w, int *h) +{ + /* make sure we have a zone */ + if (!zone) + { + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + return; + } + + /* set default values */ + if (x) *x = zone->x; + if (y) *y = zone->y; + if (w) *w = zone->w; + if (h) *h = zone->h; + + /* if the keyboard is disabled, get out */ + if ((!_e_illume_kbd->visible) || (_e_illume_kbd->disabled)) return; + + /* if we don't have a border, get out */ + /* NB: This basically means that we have the vkbd structure, but no + * app or module present to act as the vkbd */ + if (!_e_illume_kbd->border) return; + + /* if the keyboard border is not on this zone, get out */ + if (_e_illume_kbd->border->zone != zone) return; + + if (!_e_illume_kbd->animator) + { + if (h) + { + *h -= _e_illume_kbd->border->h; + if (*h < 0) *h = 0; + } + } +} + +/** + * Retrieve the Home window on a given zone. + * + * @param zone The zone. + * @return The Home window, or NULL if no Home window exists. + * + * @note If @p zone is NULL then this function will return NULL. + * + * @ingroup E_Illume_Main_Group + */ +E_Border * +e_illume_border_home_get(E_Zone *zone) +{ + E_Border *bd; + Eina_List *l; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the border client list */ + /* NB: We use e_border_client_list here, rather than + * e_container_border_list, because e_border_client_list is faster */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* check zone and skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip borders that are not home windows */ + if (!e_illume_border_is_home(bd)) continue; + + /* found one, return it */ + return bd; + } + + /* return a fallback */ + return NULL; +} + +/** + * Retrieve the list of Home windows on a given zone. + * + * @param zone The zone. + * @return A list of existing Home windows, or NULL if none exist. + * + * @note If @p zone is NULL then this function will return NULL. + * + * @ingroup E_Illume_Main_Group + */ +Eina_List * +e_illume_border_home_borders_get(E_Zone *zone) +{ + Eina_List *ret = NULL, *l; + E_Border *bd; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the border client list */ + /* NB: We use e_border_client_list here, rather than + * e_container_border_list, because e_border_client_list is faster */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* check zone and skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip borders that are not home windows */ + if (!e_illume_border_is_home(bd)) continue; + + /* found one, append it to the list */ + ret = eina_list_append(ret, bd); + } + + /* return the list */ + return ret; +} + +/** + * Retrieve the Illume Quickpanel on a given zone. + * + * @param zone The zone on which to retrieve the Quickpanel. + * @return The Quickpanel on this zone, or NULL if none exists. + * + * @note If @p zone is NULL then this function will return NULL. + * + * @ingroup E_Illume_Quickpanel_Group + */ +E_Illume_Quickpanel * +e_illume_quickpanel_by_zone_get(E_Zone *zone) +{ + E_Illume_Quickpanel *qp; + Eina_List *l; + + /* make sure we have a zone */ + if (!zone) return NULL; + + /* loop the list of quickpanels, looking for one on this zone */ + EINA_LIST_FOREACH(_e_illume_qps, l, qp) + if (qp->zone == zone) return qp; + + /* return a fallback */ + return NULL; +} diff --git a/src/modules/illume2/e_illume.h b/src/modules/illume2/e_illume.h new file mode 100644 index 000000000..4cb8f805b --- /dev/null +++ b/src/modules/illume2/e_illume.h @@ -0,0 +1,329 @@ +#ifndef E_ILLUME_H +# define E_ILLUME_H + +/* include standard E header */ +# include "e.h" + +/** + * @mainpage Illume + * + * @image html e.png + * + * @author Christopher Michael + * @date 2010 + * + * @section illume_toc_sec Table of contents + * + *
    + *
  • @ref illume_intro_sec + *
+ * + * @section illume_intro_sec Introduction to Illume + * + * Illume is a module for Enlightenment that modifies the user interface of + * enlightenment to work cleanly and nicely on a mobile device - such as an + * Openmoko phone. It is resolution independent meaning that it can + * accommodate a very wide range of devices, from cell phones and PDAs to + * tablets and desktops. Illume has been designed from the ground up to + * support more than one screen in more than one way (multihead and xinerama). + * + * This is a work in progress and as such is subject to change. + */ + +/** + * @file e_illume.h + * + * This header provides the various defines, structures and functions that + * make writing illume policies easier. + * + * For details on the available functions, see @ref E_Illume_Main_Group. + * + * For details on the configuration structure, see @ref E_Illume_Config_Group. + * + * For details on the virtual keyboard, see @ref E_Illume_Keyboard_Group. + * + * For details on the Policy API, see @ref E_Illume_Policy_Group. + * + * For details on quickpanels, see @ref E_Illume_Quickpanel_Group. + */ + +/** + * @defgroup E_Illume_Keyboard_Group Illume Keyboard Information + * + * The following group defines information needed to interact with the + * Virtual Keyboard. + * + */ + +/* define enumeration for keyboard layout */ +typedef enum _E_Illume_Keyboard_Layout E_Illume_Keyboard_Layout; +enum _E_Illume_Keyboard_Layout +{ + E_ILLUME_KEYBOARD_LAYOUT_NONE, + E_ILLUME_KEYBOARD_LAYOUT_DEFAULT, + E_ILLUME_KEYBOARD_LAYOUT_ALPHA, + E_ILLUME_KEYBOARD_LAYOUT_NUMERIC, + E_ILLUME_KEYBOARD_LAYOUT_PIN, + E_ILLUME_KEYBOARD_LAYOUT_PHONE_NUMBER, + E_ILLUME_KEYBOARD_LAYOUT_HEX, + E_ILLUME_KEYBOARD_LAYOUT_TERMINAL, + E_ILLUME_KEYBOARD_LAYOUT_PASSWORD, + E_ILLUME_KEYBOARD_LAYOUT_IP, + E_ILLUME_KEYBOARD_LAYOUT_HOST, + E_ILLUME_KEYBOARD_LAYOUT_FILE, + E_ILLUME_KEYBOARD_LAYOUT_URL, + E_ILLUME_KEYBOARD_LAYOUT_KEYPAD, + E_ILLUME_KEYBOARD_LAYOUT_J2ME +}; + +/** + * @typedef E_Illume_Keyboard + * @brief structure for keyboard. + * + * @ingroup E_Illume_Keyboard_Group + */ +typedef struct _E_Illume_Keyboard E_Illume_Keyboard; + +/** + * @struct E_Illume_Keyboard + * @brief structure for keyboard. + * + * @ingroup E_Illume_Keyboard_Group + */ +struct _E_Illume_Keyboard +{ + E_Object e_obj_inherit; + + E_Border *border; /**< Test struct member */ + Ecore_Timer *timer; + Ecore_Animator *animator; + + E_Illume_Keyboard_Layout layout; + Eina_List *waiting_borders; + + double start, len; + int adjust, adjust_start, adjust_end; + + unsigned char visible : 1; + unsigned char disabled : 1; + unsigned char fullscreen : 1; +}; + +/** + * @defgroup E_Illume_Policy_Group Illume Policy Information + * + * The following group defines information needed to implement an Illume + * Policy. + * + * @warning There are some requirements that every policy must implement. + */ + +/** + * @def E_ILLUME_POLICY_API_VERSION + * @brief Current version of the Policy API that is supported by the Illume module. + * + * @warning Policies not written to match this version will fail to load. + * + * @ingroup E_Illume_Policy_Group + */ +# define E_ILLUME_POLICY_API_VERSION 2 + +/** + * @struct E_Illume_Policy_Api + * @brief structure for policy api + * + * When Illume tries to load a policy, it will check for the existince of + * this structure. If it is not found, the policy will fail to load. + * + * @warning This structure is required for Illume to load a policy. + * + * @ingroup E_Illume_Policy_Group + */ +typedef struct _E_Illume_Policy_Api E_Illume_Policy_Api; +struct _E_Illume_Policy_Api +{ + int version; /**< The version of this policy. */ + + /**< The name of this policy. */ + const char *name; + /**< The label of this policy. */ + const char *label; +}; + +/** + * @typedef E_Illume_Policy + * @brief structure for policy + * + * This structure actually holds the policy functions to call. + * + * @ingroup E_Illume_Policy_Group + */ +typedef struct _E_Illume_Policy E_Illume_Policy; +struct _E_Illume_Policy +{ + E_Object e_obj_inherit; + + /** pointer to the @ref E_Illume_Policy_Api policy api structure. */ + E_Illume_Policy_Api *api; + + void *handle; + + struct + { + /** @warning Required Functions. */ + void *(*init) (E_Illume_Policy *p); /**< pointer to the function that will be called by Illume to initialize this policy. */ + int (*shutdown) (E_Illume_Policy *p); /**< pointer to the function that Illume will call to shutdown this policy.*/ + + /** @note Optional Functions. */ + void (*border_add) (E_Border *bd); + void (*border_del) (E_Border *bd); + void (*border_focus_in) (E_Border *bd); + void (*border_focus_out) (E_Border *bd); + void (*border_activate) (E_Border *bd); + void (*border_post_fetch) (E_Border *bd); + void (*border_post_assign) (E_Border *bd); + void (*zone_layout) (E_Zone *zone); + void (*zone_move_resize) (E_Zone *zone); + void (*zone_mode_change) (E_Zone *zone, Ecore_X_Atom mode); + void (*zone_close) (E_Zone *zone); + void (*drag_start) (E_Border *bd); + void (*drag_end) (E_Border *bd); + void (*focus_back) (E_Zone *zone); + void (*focus_forward) (E_Zone *zone); + void (*focus_home) (E_Zone *zone); + void (*property_change) (Ecore_X_Event_Window_Property *event); + } funcs; +}; + +/** + * @defgroup E_Illume_Config_Group Illume Configuration Information + * + * The following group defines information pertaining to Illume Configuration. + */ + +/** + * @typedef E_Illume_Config + * @brief structure for Illume configuration. + * + * @ingroup E_Illume_Config_Group + */ +typedef struct _E_Illume_Config E_Illume_Config; +struct _E_Illume_Config +{ + int version; + + struct + { + struct + { + int duration; + } vkbd, quickpanel; + } animation; + + struct + { + const char *name; + struct + { + const char *class, *name, *title; + int type; + struct + { + int class, name, title, type; + } match; + } vkbd, indicator, softkey, home; + Eina_List *zones; + } policy; +}; + + +/** + * @typedef E_Illume_Config_Zone + * @brief structure for Illume zone configuration. + * + * @ingroup E_Illume_Config_Group + */ +typedef struct _E_Illume_Config_Zone E_Illume_Config_Zone; +struct _E_Illume_Config_Zone +{ + int id; /**< Id of the Zone that this config belongs to. */ + struct + { + int dual; + int side; + } mode; + + /* NB: These are not configurable by user...just placeholders */ + struct + { + int size; + } vkbd, indicator, softkey; +}; + +/** + * @defgroup E_Illume_Quickpanel_Group Illume Quickpanel Information + * + * The following group defines information pertaining to Illume Quickpanels. + */ + +/** + * @typedef E_Illume_Quickpanel + * @brief structure for Illume Quickpanels. + * + * @ingroup E_Illume_Quickpanel_Group + */ +typedef struct _E_Illume_Quickpanel E_Illume_Quickpanel; +struct _E_Illume_Quickpanel +{ + E_Object e_obj_inherit; + + E_Zone *zone; + Eina_List *borders; + Ecore_Timer *timer; + Ecore_Animator *animator; + double start, len; + int h, ih, adjust, adjust_start, adjust_end; + unsigned char visible : 1; +}; + +/* define function prototypes that policies can use */ +E_Illume_Config_Zone *e_illume_zone_config_get(int id); + +/* general functions */ +Eina_Bool e_illume_border_is_indicator(E_Border *bd); +Eina_Bool e_illume_border_is_softkey(E_Border *bd); +Eina_Bool e_illume_border_is_keyboard(E_Border *bd); +Eina_Bool e_illume_border_is_home(E_Border *bd); +Eina_Bool e_illume_border_is_splash(E_Border *bd); +Eina_Bool e_illume_border_is_dialog(E_Border *bd); +Eina_Bool e_illume_border_is_qt_frame(E_Border *bd); +Eina_Bool e_illume_border_is_fullscreen(E_Border *bd); +Eina_Bool e_illume_border_is_conformant(E_Border *bd); +Eina_Bool e_illume_border_is_quickpanel(E_Border *bd); + +void e_illume_border_min_get(E_Border *bd, int *w, int *h); +E_Border *e_illume_border_at_xy_get(E_Zone *zone, int x, int y); +E_Border *e_illume_border_parent_get(E_Border *bd); +void e_illume_border_show(E_Border *bd); +void e_illume_border_hide(E_Border *bd); + +/* indicator functions */ +E_Border *e_illume_border_indicator_get(E_Zone *zone); +void e_illume_border_indicator_pos_get(E_Zone *zone, int *x, int *y); + +/* softkey functions */ +E_Border *e_illume_border_softkey_get(E_Zone *zone); +void e_illume_border_softkey_pos_get(E_Zone *zone, int *x, int *y); + +/* keyboard functions */ +E_Illume_Keyboard *e_illume_keyboard_get(void); +void e_illume_keyboard_safe_app_region_get(E_Zone *zone, int *x, int *y, int *w, int *h); + +/* home functions */ +E_Border *e_illume_border_home_get(E_Zone *zone); +Eina_List *e_illume_border_home_borders_get(E_Zone *zone); + +/* quickpanel functions */ +E_Illume_Quickpanel *e_illume_quickpanel_by_zone_get(E_Zone *zone); + +#endif diff --git a/src/modules/illume2/e_illume_private.h b/src/modules/illume2/e_illume_private.h new file mode 100644 index 000000000..41a605544 --- /dev/null +++ b/src/modules/illume2/e_illume_private.h @@ -0,0 +1,24 @@ +#ifndef E_ILLUME_PRIVATE_H +# define E_ILLUME_PRIVATE_H + +# include "e_illume.h" + +/* define policy object type */ +# define E_ILLUME_POLICY_TYPE 0xE0b200b + +/* external variable to store list of quickpanels */ +extern Eina_List *_e_illume_qps; + +/* external variable to store keyboard */ +extern E_Illume_Keyboard *_e_illume_kbd; + +/* external variable to store active config */ +extern E_Illume_Config *_e_illume_cfg; + +/* external variable to store module directory */ +extern const char *_e_illume_mod_dir; + +/* external event for policy changes */ +extern int E_ILLUME_POLICY_EVENT_CHANGE; + +#endif diff --git a/src/modules/illume2/e_mod_config.c b/src/modules/illume2/e_mod_config.c new file mode 100644 index 000000000..bb056edfa --- /dev/null +++ b/src/modules/illume2/e_mod_config.c @@ -0,0 +1,262 @@ +#include "e_illume_private.h" +#include "e_mod_config.h" +#include "e_mod_config_animation.h" +#include "e_mod_config_windows.h" +#include "e_mod_config_policy.h" + +/* local function prototypes */ +static void _e_mod_config_free(void); +static void _e_mod_config_new(void); + +/* local variables */ +static E_Config_DD *_conf_edd = NULL; +static E_Config_DD *_conf_zone_edd = NULL; + +/* external variables */ +E_Illume_Config *_e_illume_cfg = NULL; + +int +e_mod_config_init(void) +{ + char buff[PATH_MAX]; + + /* create config structure for zones */ + _conf_zone_edd = E_CONFIG_DD_NEW("Illume_Config_Zone", E_Illume_Config_Zone); +#undef T +#undef D +#define T E_Illume_Config_Zone +#define D _conf_zone_edd + E_CONFIG_VAL(D, T, id, INT); + E_CONFIG_VAL(D, T, mode.dual, INT); + E_CONFIG_VAL(D, T, mode.side, INT); + + /* create config structure for module */ + _conf_edd = E_CONFIG_DD_NEW("Illume_Config", E_Illume_Config); +#undef T +#undef D +#define T E_Illume_Config +#define D _conf_edd + E_CONFIG_VAL(D, T, version, INT); + E_CONFIG_VAL(D, T, animation.vkbd.duration, INT); + E_CONFIG_VAL(D, T, animation.quickpanel.duration, INT); + E_CONFIG_VAL(D, T, policy.name, STR); + E_CONFIG_VAL(D, T, policy.vkbd.class, STR); + E_CONFIG_VAL(D, T, policy.vkbd.name, STR); + E_CONFIG_VAL(D, T, policy.vkbd.title, STR); + E_CONFIG_VAL(D, T, policy.vkbd.type, INT); + E_CONFIG_VAL(D, T, policy.vkbd.match.class, INT); + E_CONFIG_VAL(D, T, policy.vkbd.match.name, INT); + E_CONFIG_VAL(D, T, policy.vkbd.match.title, INT); + E_CONFIG_VAL(D, T, policy.vkbd.match.type, INT); + E_CONFIG_VAL(D, T, policy.indicator.class, STR); + E_CONFIG_VAL(D, T, policy.indicator.name, STR); + E_CONFIG_VAL(D, T, policy.indicator.title, STR); + E_CONFIG_VAL(D, T, policy.indicator.type, INT); + E_CONFIG_VAL(D, T, policy.indicator.match.class, INT); + E_CONFIG_VAL(D, T, policy.indicator.match.name, INT); + E_CONFIG_VAL(D, T, policy.indicator.match.title, INT); + E_CONFIG_VAL(D, T, policy.indicator.match.type, INT); + E_CONFIG_VAL(D, T, policy.softkey.class, STR); + E_CONFIG_VAL(D, T, policy.softkey.name, STR); + E_CONFIG_VAL(D, T, policy.softkey.title, STR); + E_CONFIG_VAL(D, T, policy.softkey.type, INT); + E_CONFIG_VAL(D, T, policy.softkey.match.class, INT); + E_CONFIG_VAL(D, T, policy.softkey.match.name, INT); + E_CONFIG_VAL(D, T, policy.softkey.match.title, INT); + E_CONFIG_VAL(D, T, policy.softkey.match.type, INT); + E_CONFIG_VAL(D, T, policy.home.class, STR); + E_CONFIG_VAL(D, T, policy.home.name, STR); + E_CONFIG_VAL(D, T, policy.home.title, STR); + E_CONFIG_VAL(D, T, policy.home.type, INT); + E_CONFIG_VAL(D, T, policy.home.match.class, INT); + E_CONFIG_VAL(D, T, policy.home.match.name, INT); + E_CONFIG_VAL(D, T, policy.home.match.title, INT); + E_CONFIG_VAL(D, T, policy.home.match.type, INT); + E_CONFIG_LIST(D, T, policy.zones, _conf_zone_edd); + + /* attempt to load existing configuration */ + _e_illume_cfg = e_config_domain_load("module.illume2", _conf_edd); + + /* check version */ + if ((_e_illume_cfg) && ((_e_illume_cfg->version >> 16) < IL_CONFIG_MAJOR)) + _e_mod_config_free(); + + /* create new config if we need to */ + if (!_e_illume_cfg) _e_mod_config_new(); + + /* setup category for config panel */ + snprintf(buff, sizeof(buff), "%s/e-module-illume2.edj", _e_illume_mod_dir); + e_configure_registry_category_add("illume", 0, _("Illume"), buff, "icon"); + + /* add config items to category */ + e_configure_registry_generic_item_add("illume/policy", 0, _("Policy"), + NULL, "enlightenment/policy", + e_mod_config_policy_show); + e_configure_registry_generic_item_add("illume/animation", 0, _("Animation"), + NULL, "enlightenment/animation", + e_mod_config_animation_show); + e_configure_registry_generic_item_add("illume/windows", 0, _("Windows"), + NULL, "enlightenment/windows", + e_mod_config_windows_show); + + return 1; +} + +int +e_mod_config_shutdown(void) +{ + /* destroy config item entries */ + e_configure_registry_item_del("illume/windows"); + e_configure_registry_item_del("illume/animation"); + e_configure_registry_item_del("illume/policy"); + + /* destroy config category */ + e_configure_registry_category_del("illume"); + + /* free config structure */ + _e_mod_config_free(); + + /* free data descriptors */ + E_CONFIG_DD_FREE(_conf_zone_edd); + E_CONFIG_DD_FREE(_conf_edd); + + return 1; +} + +int +e_mod_config_save(void) +{ + return e_config_domain_save("module.illume2", _conf_edd, _e_illume_cfg); +} + +/* local functions */ +static void +_e_mod_config_free(void) +{ + E_Illume_Config_Zone *cz; + + /* check for config */ + if (!_e_illume_cfg) return; + + /* cleanup any stringshares */ + if (_e_illume_cfg->policy.name) + eina_stringshare_del(_e_illume_cfg->policy.name); + _e_illume_cfg->policy.name = NULL; + + if (_e_illume_cfg->policy.vkbd.class) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.class); + _e_illume_cfg->policy.vkbd.class = NULL; + if (_e_illume_cfg->policy.vkbd.name) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.name); + _e_illume_cfg->policy.vkbd.name = NULL; + if (_e_illume_cfg->policy.vkbd.title) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.title); + _e_illume_cfg->policy.vkbd.title = NULL; + + if (_e_illume_cfg->policy.indicator.class) + eina_stringshare_del(_e_illume_cfg->policy.indicator.class); + _e_illume_cfg->policy.indicator.class = NULL; + if (_e_illume_cfg->policy.indicator.name) + eina_stringshare_del(_e_illume_cfg->policy.indicator.name); + _e_illume_cfg->policy.indicator.name = NULL; + if (_e_illume_cfg->policy.indicator.title) + eina_stringshare_del(_e_illume_cfg->policy.indicator.title); + _e_illume_cfg->policy.indicator.title = NULL; + + if (_e_illume_cfg->policy.softkey.class) + eina_stringshare_del(_e_illume_cfg->policy.softkey.class); + _e_illume_cfg->policy.softkey.class = NULL; + if (_e_illume_cfg->policy.softkey.name) + eina_stringshare_del(_e_illume_cfg->policy.softkey.name); + _e_illume_cfg->policy.softkey.name = NULL; + if (_e_illume_cfg->policy.softkey.title) + eina_stringshare_del(_e_illume_cfg->policy.softkey.title); + _e_illume_cfg->policy.softkey.title = NULL; + + if (_e_illume_cfg->policy.home.class) + eina_stringshare_del(_e_illume_cfg->policy.home.class); + _e_illume_cfg->policy.home.class = NULL; + if (_e_illume_cfg->policy.home.name) + eina_stringshare_del(_e_illume_cfg->policy.home.name); + _e_illume_cfg->policy.home.name = NULL; + if (_e_illume_cfg->policy.home.title) + eina_stringshare_del(_e_illume_cfg->policy.home.title); + _e_illume_cfg->policy.home.title = NULL; + + /* free configured zones */ + EINA_LIST_FREE(_e_illume_cfg->policy.zones, cz) + E_FREE(cz); + + /* free config structure */ + E_FREE(_e_illume_cfg); +} + +static void +_e_mod_config_new(void) +{ + E_Illume_Config_Zone *cz; + + /* create initial config */ + _e_illume_cfg = E_NEW(E_Illume_Config, 1); + _e_illume_cfg->version = 0; + _e_illume_cfg->animation.vkbd.duration = 1000; + _e_illume_cfg->animation.quickpanel.duration = 1000; + _e_illume_cfg->policy.name = eina_stringshare_add("illume"); + + _e_illume_cfg->policy.vkbd.class = eina_stringshare_add("Virtual-Keyboard"); + _e_illume_cfg->policy.vkbd.name = eina_stringshare_add("Virtual-Keyboard"); + _e_illume_cfg->policy.vkbd.title = eina_stringshare_add("Virtual Keyboard"); + _e_illume_cfg->policy.vkbd.type = ECORE_X_WINDOW_TYPE_NORMAL; + _e_illume_cfg->policy.vkbd.match.class = 0; + _e_illume_cfg->policy.vkbd.match.name = 1; + _e_illume_cfg->policy.vkbd.match.title = 1; + _e_illume_cfg->policy.vkbd.match.type = 0; + + _e_illume_cfg->policy.indicator.class = + eina_stringshare_add("Illume-Indicator"); + _e_illume_cfg->policy.indicator.name = + eina_stringshare_add("Illume-Indicator"); + _e_illume_cfg->policy.indicator.title = + eina_stringshare_add("Illume Indicator"); + _e_illume_cfg->policy.indicator.type = ECORE_X_WINDOW_TYPE_DOCK; + _e_illume_cfg->policy.indicator.match.class = 0; + _e_illume_cfg->policy.indicator.match.name = 1; + _e_illume_cfg->policy.indicator.match.title = 1; + _e_illume_cfg->policy.indicator.match.type = 0; + + _e_illume_cfg->policy.softkey.class = + eina_stringshare_add("Illume-Softkey"); + _e_illume_cfg->policy.softkey.name = + eina_stringshare_add("Illume-Softkey"); + _e_illume_cfg->policy.softkey.title = + eina_stringshare_add("Illume Softkey"); + _e_illume_cfg->policy.softkey.type = ECORE_X_WINDOW_TYPE_DOCK; + _e_illume_cfg->policy.softkey.match.class = 0; + _e_illume_cfg->policy.softkey.match.name = 1; + _e_illume_cfg->policy.softkey.match.title = 1; + _e_illume_cfg->policy.softkey.match.type = 0; + + _e_illume_cfg->policy.home.class = eina_stringshare_add("Illume-Home"); + _e_illume_cfg->policy.home.name = eina_stringshare_add("Illume-Home"); + _e_illume_cfg->policy.home.title = eina_stringshare_add("Illume Home"); + _e_illume_cfg->policy.home.type = ECORE_X_WINDOW_TYPE_NORMAL; + _e_illume_cfg->policy.home.match.class = 0; + _e_illume_cfg->policy.home.match.name = 1; + _e_illume_cfg->policy.home.match.title = 1; + _e_illume_cfg->policy.home.match.type = 0; + + /* create config for initial zone */ + cz = E_NEW(E_Illume_Config_Zone, 1); + cz->id = 0; + cz->mode.dual = 0; + cz->mode.side = 0; + + /* add zone config to main config structure */ + _e_illume_cfg->policy.zones = + eina_list_append(_e_illume_cfg->policy.zones, cz); + + /* add any new config variables here */ + /* if ((_e_illume_cfg->version & 0xffff) < 1) */ + + _e_illume_cfg->version = ((IL_CONFIG_MAJOR << 16) | IL_CONFIG_MINOR); +} diff --git a/src/modules/illume2/e_mod_config.h b/src/modules/illume2/e_mod_config.h new file mode 100644 index 000000000..9d740a38f --- /dev/null +++ b/src/modules/illume2/e_mod_config.h @@ -0,0 +1,11 @@ +#ifndef E_MOD_CONFIG_H +# define E_MOD_CONFIG_H + +# define IL_CONFIG_MAJOR 0 +# define IL_CONFIG_MINOR 1 + +int e_mod_config_init(void); +int e_mod_config_shutdown(void); +int e_mod_config_save(void); + +#endif diff --git a/src/modules/illume2/e_mod_config_animation.c b/src/modules/illume2/e_mod_config_animation.c new file mode 100644 index 000000000..b7d2eb1ac --- /dev/null +++ b/src/modules/illume2/e_mod_config_animation.c @@ -0,0 +1,127 @@ +#include "e_illume_private.h" +#include "e_mod_config_animation.h" + +/* local function prototypes */ +static void *_e_mod_config_animation_create(E_Config_Dialog *cfd); +static void _e_mod_config_animation_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_e_mod_config_animation_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static void _e_mod_config_animation_change(void *data, Evas_Object *obj, void *event); +static int _e_mod_config_animation_timeout(void *data); + +/* local variables */ +Ecore_Timer *_anim_change_timer = NULL; + +void +e_mod_config_animation_show(E_Container *con, const char *params __UNUSED__) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "_config_illume_animation_settings")) return; + + v = E_NEW(E_Config_Dialog_View, 1); + if (!v) return; + + v->create_cfdata = _e_mod_config_animation_create; + v->free_cfdata = _e_mod_config_animation_free; + v->basic.create_widgets = _e_mod_config_animation_ui; + v->basic_only = 1; + v->normal_win = 1; + v->scroll = 1; + + cfd = e_config_dialog_new(con, _("Animation Settings"), "E", + "_config_illume_animation_settings", + "enlightenment/animation_settings", 0, v, NULL); + if (!cfd) return; + + e_dialog_resizable_set(cfd->dia, 1); +} + +/* local function prototypes */ +static void * +_e_mod_config_animation_create(E_Config_Dialog *cfd) +{ + return NULL; +} + +static void +_e_mod_config_animation_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + if (_anim_change_timer) ecore_timer_del(_anim_change_timer); + _anim_change_timer = NULL; +} + +static Evas_Object * +_e_mod_config_animation_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *list, *of, *ow; + E_Radio_Group *rg; + + list = e_widget_list_add(evas, 0, 0); + + of = e_widget_framelist_add(evas, _("Keyboard"), 0); + rg = e_widget_radio_group_new(&(_e_illume_cfg->animation.vkbd.duration)); + ow = e_widget_radio_add(evas, _("Slow"), 2000, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Medium"), 1000, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Fast"), 500, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Very Fast"), 250, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Off"), 0, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + of = e_widget_framelist_add(evas, _("Quickpanel"), 0); + rg = e_widget_radio_group_new(&(_e_illume_cfg->animation.quickpanel.duration)); + ow = e_widget_radio_add(evas, _("Slow"), 2000, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Medium"), 1000, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Fast"), 500, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Very Fast"), 250, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + ow = e_widget_radio_add(evas, _("Off"), 0, rg); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_animation_change, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + return list; +} + +static void +_e_mod_config_animation_change(void *data, Evas_Object *obj, void *event) +{ + if (_anim_change_timer) ecore_timer_del(_anim_change_timer); + _anim_change_timer = + ecore_timer_add(0.5, _e_mod_config_animation_timeout, data); +} + +static int +_e_mod_config_animation_timeout(void *data) +{ + e_config_save_queue(); + _anim_change_timer = NULL; + return 0; +} diff --git a/src/modules/illume2/e_mod_config_animation.h b/src/modules/illume2/e_mod_config_animation.h new file mode 100644 index 000000000..84e73bbc7 --- /dev/null +++ b/src/modules/illume2/e_mod_config_animation.h @@ -0,0 +1,6 @@ +#ifndef E_MOD_CONFIG_ANIMATION_H +# define E_MOD_CONFIG_ANIMATION_H + +void e_mod_config_animation_show(E_Container *con, const char *params __UNUSED__); + +#endif diff --git a/src/modules/illume2/e_mod_config_policy.c b/src/modules/illume2/e_mod_config_policy.c new file mode 100644 index 000000000..bdeb61258 --- /dev/null +++ b/src/modules/illume2/e_mod_config_policy.c @@ -0,0 +1,175 @@ +#include "e_illume_private.h" +#include "e_mod_config_policy.h" + +/* local function prototypes */ +static void *_e_mod_config_policy_create(E_Config_Dialog *cfd); +static void _e_mod_config_policy_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_e_mod_config_policy_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static void _e_mod_config_policy_list_changed(void *data); +static int _e_mod_config_policy_change_timeout(void *data); +static Evas_Object *_e_mod_config_policy_settings_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static Eina_List *_e_mod_config_policy_policies_get(void); +static void _e_mod_config_policy_policy_free(E_Illume_Policy *p); + +/* local variables */ +Ecore_Timer *_policy_change_timer = NULL; +const char *_policy_name = NULL; + +void +e_mod_config_policy_show(E_Container *con, const char *params) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "_config_illume_policy")) return; + + v = E_NEW(E_Config_Dialog_View, 1); + if (!v) return; + + v->create_cfdata = _e_mod_config_policy_create; + v->free_cfdata = _e_mod_config_policy_free; + v->basic.create_widgets = _e_mod_config_policy_ui; + v->basic_only = 1; + v->normal_win = 1; + v->scroll = 1; + cfd = e_config_dialog_new(con, _("Policy"), "E", "_config_illume_policy", + "enlightenment/policy", 0, v, NULL); + if (!cfd) return; + e_dialog_resizable_set(cfd->dia, 1); +} + +/* local functions */ +static void * +_e_mod_config_policy_create(E_Config_Dialog *cfd) +{ + return NULL; +} + +static void +_e_mod_config_policy_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + if (_policy_change_timer) ecore_timer_del(_policy_change_timer); + _policy_change_timer = NULL; +} + +static Evas_Object * +_e_mod_config_policy_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *list, *ow; + Eina_List *policies; + E_Illume_Policy *p; + int i = 0, sel = 0; + + list = e_widget_list_add(evas, 0, 0); + ow = e_widget_ilist_add(evas, 24, 24, &(_policy_name)); + e_widget_ilist_selector_set(ow, 1); + evas_event_freeze(evas); + edje_freeze(); + e_widget_ilist_freeze(ow); + e_widget_ilist_clear(ow); + e_widget_ilist_go(ow); + + policies = _e_mod_config_policy_policies_get(); + if (policies) + { + EINA_LIST_FREE(policies, p) + { + e_widget_ilist_append(ow, NULL, strdup(p->api->label), + _e_mod_config_policy_list_changed, NULL, + strdup(p->api->name)); + + if ((p) && (_e_illume_cfg->policy.name) && + (!strcmp(_e_illume_cfg->policy.name, p->api->name))) + sel = i; + + if (p) e_object_del(E_OBJECT(p)); + i++; + } + } + + e_widget_size_min_set(ow, 100, 200); + e_widget_ilist_go(ow); + e_widget_ilist_selected_set(ow, sel); + e_widget_ilist_thaw(ow); + edje_thaw(); + evas_event_thaw(evas); + e_widget_list_object_append(list, ow, 1, 0, 0.0); + return list; +} + +static void +_e_mod_config_policy_list_changed(void *data) +{ + if (_e_illume_cfg->policy.name) + eina_stringshare_del(_e_illume_cfg->policy.name); + if (_policy_name) + _e_illume_cfg->policy.name = eina_stringshare_add(_policy_name); + if (_policy_change_timer) ecore_timer_del(_policy_change_timer); + _policy_change_timer = + ecore_timer_add(0.5, _e_mod_config_policy_change_timeout, data); +} + +static int +_e_mod_config_policy_change_timeout(void *data) +{ + e_config_save_queue(); + _policy_change_timer = NULL; + ecore_event_add(E_ILLUME_POLICY_EVENT_CHANGE, NULL, NULL, NULL); + return 0; +} + +static Eina_List * +_e_mod_config_policy_policies_get(void) +{ + Eina_List *l = NULL, *files; + char dir[PATH_MAX], *file; + + snprintf(dir, sizeof(dir), "%s/policies", _e_illume_mod_dir); + + if (!(files = ecore_file_ls(dir))) return NULL; + + EINA_LIST_FREE(files, file) + { + E_Illume_Policy *p; + + if (!strstr(file, ".so")) continue; + snprintf(dir, sizeof(dir),"%s/policies/%s", _e_illume_mod_dir, file); + + p = E_OBJECT_ALLOC(E_Illume_Policy, E_ILLUME_POLICY_TYPE, + _e_mod_config_policy_policy_free); + if (!p) continue; + + p->handle = dlopen(dir, RTLD_NOW | RTLD_GLOBAL); + if (!p->handle) + { + e_object_del(E_OBJECT(p)); + continue; + } + p->api = dlsym(p->handle, "e_illume_policy_api"); + if (!p->api) + { + e_object_del(E_OBJECT(p)); + continue; + } + if (p->api->version < E_ILLUME_POLICY_API_VERSION) + { + e_object_del(E_OBJECT(p)); + continue; + } + if (file) free(file); + l = eina_list_append(l, p); + } + + return l; +} + +static void +_e_mod_config_policy_policy_free(E_Illume_Policy *p) +{ + p->api = NULL; + + if (p->handle) dlclose(p->handle); + p->handle = NULL; + + E_FREE(p); +} diff --git a/src/modules/illume2/e_mod_config_policy.h b/src/modules/illume2/e_mod_config_policy.h new file mode 100644 index 000000000..161768618 --- /dev/null +++ b/src/modules/illume2/e_mod_config_policy.h @@ -0,0 +1,6 @@ +#ifndef E_MOD_CONFIG_POLICY_H +# define E_MOD_CONFIG_POLICY_H + +void e_mod_config_policy_show(E_Container *con, const char *params __UNUSED__); + +#endif diff --git a/src/modules/illume2/e_mod_config_windows.c b/src/modules/illume2/e_mod_config_windows.c new file mode 100644 index 000000000..856e05375 --- /dev/null +++ b/src/modules/illume2/e_mod_config_windows.c @@ -0,0 +1,221 @@ +#include "e_illume_private.h" +#include "e_mod_config_windows.h" +#include "e_mod_select_window.h" + +/* local function prototypes */ +static void *_e_mod_config_windows_create(E_Config_Dialog *cfd); +static void _e_mod_config_windows_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_e_mod_config_windows_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static void _e_mod_config_windows_check_changed(void *data, Evas_Object *obj, void *event); +static void _e_mod_config_windows_change(void *data, Evas_Object *obj, void *event); +static int _e_mod_config_windows_change_timeout(void *data); +static void _e_mod_config_windows_select_home(void *data, void *data2); +static void _e_mod_config_windows_select_vkbd(void *data, void *data2); +static void _e_mod_config_windows_select_softkey(void *data, void *data2); +static void _e_mod_config_windows_select_indicator(void *data, void *data2); + +/* local variables */ +Ecore_Timer *_windows_change_timer = NULL; + +/* public functions */ +void +e_mod_config_windows_show(E_Container *con, const char *params __UNUSED__) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "_config_illume_windows_settings")) return; + + v = E_NEW(E_Config_Dialog_View, 1); + if (!v) return; + + v->create_cfdata = _e_mod_config_windows_create; + v->free_cfdata = _e_mod_config_windows_free; + v->basic.create_widgets = _e_mod_config_windows_ui; + v->basic_only = 1; + v->normal_win = 1; + v->scroll = 1; + cfd = e_config_dialog_new(con, _("Window Settings"), "E", + "_config_illume_windows_settings", + "preferences-system-windows", 0, v, NULL); + if (!cfd) return; + e_dialog_resizable_set(cfd->dia, 1); +} + +/* local function prototypes */ +static void * +_e_mod_config_windows_create(E_Config_Dialog *cfd) +{ + return NULL; +} + +static void +_e_mod_config_windows_free(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + if (_windows_change_timer) ecore_timer_del(_windows_change_timer); + _windows_change_timer = NULL; +} + +static Evas_Object * +_e_mod_config_windows_ui(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *list, *of, *ow; + + list = e_widget_list_add(evas, 0, 0); + + of = e_widget_framelist_add(evas, _("Home"), 0); + ow = e_widget_button_add(evas, _("Select Window"), NULL, + _e_mod_config_windows_select_home, NULL, NULL); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, _("Match Window Class"), + &_e_illume_cfg->policy.home.match.class); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Name"), + &_e_illume_cfg->policy.home.match.name); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Title"), + &_e_illume_cfg->policy.home.match.title); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Type"), + &_e_illume_cfg->policy.home.match.type); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + of = e_widget_framelist_add(evas, _("Indicator"), 0); + ow = e_widget_button_add(evas, _("Select Window"), NULL, + _e_mod_config_windows_select_indicator, NULL, NULL); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, _("Match Window Class"), + &_e_illume_cfg->policy.indicator.match.class); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Name"), + &_e_illume_cfg->policy.indicator.match.name); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Title"), + &_e_illume_cfg->policy.indicator.match.title); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Type"), + &_e_illume_cfg->policy.indicator.match.type); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + of = e_widget_framelist_add(evas, _("Keyboard"), 0); + ow = e_widget_button_add(evas, _("Select Window"), NULL, + _e_mod_config_windows_select_vkbd, NULL, NULL); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, _("Match Window Class"), + &_e_illume_cfg->policy.vkbd.match.class); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Name"), + &_e_illume_cfg->policy.vkbd.match.name); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Title"), + &_e_illume_cfg->policy.vkbd.match.title); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Type"), + &_e_illume_cfg->policy.vkbd.match.type); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + of = e_widget_framelist_add(evas, _("Softkey"), 0); + ow = e_widget_button_add(evas, _("Select Window"), NULL, + _e_mod_config_windows_select_softkey, NULL, NULL); + e_widget_framelist_object_append(of, ow); + ow = e_widget_check_add(evas, _("Match Window Class"), + &_e_illume_cfg->policy.softkey.match.class); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Name"), + &_e_illume_cfg->policy.softkey.match.name); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Title"), + &_e_illume_cfg->policy.softkey.match.title); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + ow = e_widget_check_add(evas, _("Match Window Type"), + &_e_illume_cfg->policy.softkey.match.type); + e_widget_framelist_object_append(of, ow); + evas_object_smart_callback_add(ow, "changed", + _e_mod_config_windows_check_changed, NULL); + e_widget_list_object_append(list, of, 1, 0, 0.0); + + return list; +} + +static void +_e_mod_config_windows_check_changed(void *data, Evas_Object *obj, void *event) +{ + _e_mod_config_windows_change(data, obj, event); +} + +static void +_e_mod_config_windows_change(void *data, Evas_Object *obj, void *event) +{ + if (_windows_change_timer) ecore_timer_del(_windows_change_timer); + _windows_change_timer = + ecore_timer_add(0.5, _e_mod_config_windows_change_timeout, data); +} + +static int +_e_mod_config_windows_change_timeout(void *data) +{ + e_config_save_queue(); + _windows_change_timer = NULL; + return 0; +} + +static void +_e_mod_config_windows_select_home(void *data, void *data2) +{ + if (e_config_dialog_find("E", "_config_illume_select_window")) return; + e_mod_config_select_window(E_ILLUME_SELECT_WINDOW_TYPE_HOME); +} + +static void +_e_mod_config_windows_select_vkbd(void *data, void *data2) +{ + if (e_config_dialog_find("E", "_config_illume_select_window")) return; + e_mod_config_select_window(E_ILLUME_SELECT_WINDOW_TYPE_VKBD); +} + +static void +_e_mod_config_windows_select_softkey(void *data, void *data2) +{ + if (e_config_dialog_find("E", "_config_illume_select_window")) return; + e_mod_config_select_window(E_ILLUME_SELECT_WINDOW_TYPE_SOFTKEY); +} + +static void +_e_mod_config_windows_select_indicator(void *data, void *data2) +{ + if (e_config_dialog_find("E", "_config_illume_select_window")) return; + e_mod_config_select_window(E_ILLUME_SELECT_WINDOW_TYPE_INDICATOR); +} diff --git a/src/modules/illume2/e_mod_config_windows.h b/src/modules/illume2/e_mod_config_windows.h new file mode 100644 index 000000000..abfd01f88 --- /dev/null +++ b/src/modules/illume2/e_mod_config_windows.h @@ -0,0 +1,6 @@ +#ifndef E_MOD_CONFIG_WINDOWS_H +# define E_MOD_CONFIG_WINDOWS_H + +void e_mod_config_windows_show(E_Container *con, const char *params __UNUSED__); + +#endif diff --git a/src/modules/illume2/e_mod_kbd.c b/src/modules/illume2/e_mod_kbd.c new file mode 100644 index 000000000..1865897f3 --- /dev/null +++ b/src/modules/illume2/e_mod_kbd.c @@ -0,0 +1,564 @@ +#include "e_illume_private.h" +#include "e_mod_kbd.h" +#include "e_mod_kbd_dbus.h" + +/* local function prototypes */ +static int _e_mod_kbd_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_kbd_cb_border_remove(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_kbd_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_kbd_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_kbd_cb_border_property(void *data __UNUSED__, int type __UNUSED__, void *event); +static void _e_mod_kbd_cb_border_pre_post_fetch(void *data __UNUSED__, void *data2); +static void _e_mod_kbd_cb_free(E_Illume_Keyboard *kbd); +static int _e_mod_kbd_cb_delay_hide(void *data __UNUSED__); +static void _e_mod_kbd_hide(void); +static void _e_mod_kbd_slide(int visible, double len); +static int _e_mod_kbd_cb_animate(void *data __UNUSED__); +static E_Illume_Keyboard *_e_mod_kbd_by_border_get(E_Border *bd); +static void _e_mod_kbd_border_adopt(E_Border *bd); + +/* local variables */ +static Eina_List *_kbd_hdls = NULL; +static E_Border_Hook *_kbd_hook = NULL; +static Ecore_X_Atom _focused_state = 0; +static E_Border *_focused_border = NULL; + +int +e_mod_kbd_init(void) +{ + /* add handlers for events we are interested in */ + _kbd_hdls = + eina_list_append(_kbd_hdls, + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + _e_mod_kbd_cb_client_message, + NULL)); + _kbd_hdls = + eina_list_append(_kbd_hdls, + ecore_event_handler_add(E_EVENT_BORDER_REMOVE, + _e_mod_kbd_cb_border_remove, + NULL)); + _kbd_hdls = + eina_list_append(_kbd_hdls, + ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN, + _e_mod_kbd_cb_border_focus_in, + NULL)); + _kbd_hdls = + eina_list_append(_kbd_hdls, + ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, + _e_mod_kbd_cb_border_focus_out, + NULL)); + _kbd_hdls = + eina_list_append(_kbd_hdls, + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _e_mod_kbd_cb_border_property, + NULL)); + + /* add hooks for events we are interested in */ + _kbd_hook = e_border_hook_add(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, + _e_mod_kbd_cb_border_pre_post_fetch, NULL); + + /* initialize the dbus subsystem */ + e_mod_kbd_dbus_init(); + + return 1; +} + +int +e_mod_kbd_shutdown(void) +{ + Ecore_Event_Handler *hdl; + + /* shutdown the dbus subsystem */ + e_mod_kbd_dbus_shutdown(); + + /* destroy the hook */ + e_border_hook_del(_kbd_hook); + + /* destroy the handlers and free the list */ + EINA_LIST_FREE(_kbd_hdls, hdl) + ecore_event_handler_del(hdl); + + return 1; +} + +E_Illume_Keyboard * +e_mod_kbd_new(void) +{ + E_Illume_Keyboard *kbd; + + /* try to allocate our new keyboard object */ + kbd = E_OBJECT_ALLOC(E_Illume_Keyboard, E_ILLUME_KBD_TYPE, _e_mod_kbd_cb_free); + if (!kbd) return NULL; + + /* set default layout on new keyboard */ + kbd->layout = E_ILLUME_KEYBOARD_LAYOUT_ALPHA; + kbd->visible = 1; + + return kbd; +} + +void +e_mod_kbd_enable(void) +{ + /* don't try to enable a keyboard that is already enabled */ + if (!_e_illume_kbd->disabled) return; + + /* set keyboard to enabled */ + _e_illume_kbd->disabled = 0; + + /* show it if we need to */ + if (!_e_illume_kbd->visible) e_mod_kbd_show(); +} + +void +e_mod_kbd_disable(void) +{ + /* don't try to disable a keyboard that is already disabled */ + if (_e_illume_kbd->disabled) return; + + /* hide it if we need to */ + if (_e_illume_kbd->visible) e_mod_kbd_hide(); + + /* set keyboard to disabled */ + _e_illume_kbd->disabled = 1; +} + +void +e_mod_kbd_show(void) +{ + /* destroy existing timer */ + if (_e_illume_kbd->timer) ecore_timer_del(_e_illume_kbd->timer); + _e_illume_kbd->timer = NULL; + + /* destroy the animator if it exists */ + if (_e_illume_kbd->animator) ecore_animator_del(_e_illume_kbd->animator); + _e_illume_kbd->animator = NULL; + + if (_focused_border) + { +// printf("Focused Border: %s\n", _focused_border->client.icccm.name); + if (_e_illume_kbd->border->zone != _focused_border->zone) + { + e_border_zone_set(_e_illume_kbd->border, _focused_border->zone); + } + } + + /* if it's disabled, get out */ + if (_e_illume_kbd->disabled) return; + + /* TODO: Layout send */ + + /* if we are not animating, just show it */ + if (_e_illume_cfg->animation.vkbd.duration <= 0) + { + /* show the border */ + if (_e_illume_kbd->border) + { + e_border_fx_offset(_e_illume_kbd->border, 0, 0); + if (!_e_illume_kbd->border->visible) + e_border_show(_e_illume_kbd->border); + e_border_raise(_e_illume_kbd->border); + } + _e_illume_kbd->visible = 1; + } + else + { + /* show the border */ + if (_e_illume_kbd->border) + { + if (!_e_illume_kbd->border->visible) + e_border_show(_e_illume_kbd->border); + e_border_raise(_e_illume_kbd->border); + } + + /* animate it */ + _e_mod_kbd_slide(1, (double)_e_illume_cfg->animation.vkbd.duration / 1000.0); + } +} + +void +e_mod_kbd_hide(void) +{ + /* cannot hide keyboard that is not visible */ + if (!_e_illume_kbd->visible) return; + + /* create new hide timer if it doesn't exist */ + if (!_e_illume_kbd->timer) + { + _e_illume_kbd->timer = + ecore_timer_add(0.2, _e_mod_kbd_cb_delay_hide, NULL); + } +} + +void +e_mod_kbd_toggle(void) +{ + if (_e_illume_kbd->visible) e_mod_kbd_hide(); + else e_mod_kbd_show(); +} + +void +e_mod_kbd_fullscreen_set(E_Zone *zone, int fullscreen) +{ + if (!_e_illume_kbd->border) return; + if (_e_illume_kbd->border->zone != zone) return; + printf("Kbd Fullscreen Set: %d\n", fullscreen); + printf("\tCurrent: %d\n", _e_illume_kbd->fullscreen); + if ((!!fullscreen) != _e_illume_kbd->fullscreen) + _e_illume_kbd->fullscreen = fullscreen; +} + +void +e_mod_kbd_layout_set(E_Illume_Keyboard *kbd, E_Illume_Keyboard_Layout layout) +{ + +} + +/* local functions */ +static int +_e_mod_kbd_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_X_Event_Client_Message *ev; + + ev = event; + if (ev->win != ecore_x_window_root_first_get()) return 1; + + /* legacy illume 1 code */ + if ((ev->message_type == ecore_x_atom_get("_MB_IM_INVOKER_COMMAND")) || + (ev->message_type == ecore_x_atom_get("_MTP_IM_INVOKER_COMMAND"))) + { + if (ev->data.l[0] == 1) e_mod_kbd_show(); + else if (ev->data.l[0] == 2) e_mod_kbd_hide(); + else if (ev->data.l[0] == 3) e_mod_kbd_toggle(); + } + return 1; +} + +static int +_e_mod_kbd_cb_border_remove(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Remove *ev; + E_Illume_Keyboard *kbd; + + ev = event; + + /* if we removed the focused border, reset some variables */ + if ((_focused_border) && (_focused_border == ev->border)) + { + e_mod_kbd_hide(); + _focused_border = NULL; + _focused_state = 0; + return 1; + } + + /* try to find the keyboard for this border */ + if (!(kbd = _e_mod_kbd_by_border_get(ev->border))) return 1; + + if ((kbd->border) && (kbd->border == ev->border)) + { + kbd->border = NULL; + if (kbd->waiting_borders) + { + E_Border *bd; + + bd = kbd->waiting_borders->data; + kbd->waiting_borders = + eina_list_remove_list(kbd->waiting_borders, kbd->waiting_borders); + + _e_mod_kbd_border_adopt(bd); + } + if (kbd->visible) + { + e_border_hide(ev->border, 2); + e_mod_kbd_hide(); + } + } + else if (!kbd->border) + { + kbd->waiting_borders = + eina_list_remove(kbd->waiting_borders, ev->border); + } + + return 1; +} + +static int +_e_mod_kbd_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Focus_In *ev; + + ev = event; + if (_e_mod_kbd_by_border_get(ev->border)) return 1; + +// printf("Kbd Focus in: %s\n", ev->border->client.icccm.name); + + /* set focused border for kbd */ + _focused_border = ev->border; + _focused_state = ev->border->client.vkbd.state; + + if (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) + e_mod_kbd_hide(); + else + e_mod_kbd_show(); + + return 1; +} + +static int +_e_mod_kbd_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Focus_Out *ev; + + ev = event; + if (_e_mod_kbd_by_border_get(ev->border)) return 1; + +// printf("Kbd Focus Out: %s\n", ev->border->client.icccm.name); + + /* tell this border it changed so layout gets updated for hidden + * keyboard */ + if (!e_illume_border_is_conformant(ev->border)) + { + ev->border->changes.size = 1; + ev->border->changed = 1; + } + + /* hide the keyboard */ + e_mod_kbd_hide(); + + /* reset some variables */ + _focused_border = NULL; + _focused_state = 0; + + return 1; +} + +static int +_e_mod_kbd_cb_border_property(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_X_Event_Window_Property *ev; + E_Border *bd; + int fullscreen = 0; + + ev = event; + + /* only interested in vkbd state changes here */ + if (ev->atom != ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE) return 1; + + /* make sure we have a border */ + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + +// printf("Kbd Border Property Change: %s\n", bd->client.icccm.name); + + /* if it's not focused, we don't care */ + if ((!bd->focused) || (_e_mod_kbd_by_border_get(bd))) return 1; + + /* NB: Not sure why, but we seem to need to fetch kbd state here. This could + * be a result of filtering the container_hook_layout. Not real happy + * with this because it is an X round-trip, but it is here because this + * needs more time to investigate. */ + e_hints_window_virtual_keyboard_state_get(bd); + + if ((_focused_border) && (_focused_border == bd)) + { + /* if focused state is the same, get out */ + if (_focused_state == bd->client.vkbd.state) return 1; + } + + /* set our variables */ + _focused_border = bd; + _focused_state = bd->client.vkbd.state; + + /* handle a border needing fullscreen keyboard */ + if ((bd->need_fullscreen) || (bd->fullscreen)) fullscreen = 1; + if (_e_illume_kbd->fullscreen != fullscreen) + e_mod_kbd_fullscreen_set(bd->zone, fullscreen); + + if (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF) + e_mod_kbd_hide(); + else + { + // Layout set + e_mod_kbd_show(); + } + + return 1; +} + +static void +_e_mod_kbd_cb_border_pre_post_fetch(void *data __UNUSED__, void *data2) +{ + E_Border *bd; + + if (!(bd = data2)) return; + if (!bd->new_client) return; + if (_e_mod_kbd_by_border_get(bd)) return; + if (e_illume_border_is_keyboard(bd)) + { + if (!_e_illume_kbd->border) + _e_mod_kbd_border_adopt(bd); + else + { + _e_illume_kbd->waiting_borders = + eina_list_append(_e_illume_kbd->waiting_borders, bd); + } + bd->stolen = 1; + } +} + +static void +_e_mod_kbd_cb_free(E_Illume_Keyboard *kbd) +{ + E_Border *bd; + + /* destroy the animator if it exists */ + if (kbd->animator) ecore_animator_del(kbd->animator); + kbd->animator = NULL; + + /* destroy the timer if it exists */ + if (kbd->timer) ecore_timer_del(kbd->timer); + kbd->timer = NULL; + + /* free the list of waiting borders */ + EINA_LIST_FREE(kbd->waiting_borders, bd) + bd->stolen = 0; + + /* free the keyboard structure */ + E_FREE(kbd); +} + +static int +_e_mod_kbd_cb_delay_hide(void *data __UNUSED__) +{ + _e_mod_kbd_hide(); + _e_illume_kbd->timer = NULL; + return 0; +} + +static void +_e_mod_kbd_hide(void) +{ + /* destroy existing timer */ + if (_e_illume_kbd->timer) ecore_timer_del(_e_illume_kbd->timer); + _e_illume_kbd->timer = NULL; + + /* can't hide keyboard if it's not visible, or disabled */ + if ((!_e_illume_kbd->visible) || (_e_illume_kbd->disabled)) return; + + /* if we are not animating, just hide it */ + if (_e_illume_cfg->animation.vkbd.duration <= 0) + { + if (_e_illume_kbd->border) + { + e_border_fx_offset(_e_illume_kbd->border, 0, + _e_illume_kbd->border->h); + e_border_hide(_e_illume_kbd->border, 2); + } + _e_illume_kbd->visible = 0; + } + else + _e_mod_kbd_slide(0, (double)_e_illume_cfg->animation.vkbd.duration / 1000.0); +} + +static void +_e_mod_kbd_slide(int visible, double len) +{ + _e_illume_kbd->start = ecore_loop_time_get(); + _e_illume_kbd->len = len; + _e_illume_kbd->adjust_start = _e_illume_kbd->adjust; + _e_illume_kbd->adjust_end = 0; + if ((visible) && (_e_illume_kbd->border)) + _e_illume_kbd->adjust_end = _e_illume_kbd->border->h; + if (!_e_illume_kbd->animator) + _e_illume_kbd->animator = ecore_animator_add(_e_mod_kbd_cb_animate, NULL); +} + +static int +_e_mod_kbd_cb_animate(void *data __UNUSED__) +{ + double t, v; + + t = (ecore_loop_time_get() - _e_illume_kbd->start); + if (t > _e_illume_kbd->len) t = _e_illume_kbd->len; + if (_e_illume_kbd->len > 0.0) + { + v = (t / _e_illume_kbd->len); + v = (1.0 - v); + v = (v * v * v * v); + v = (1.0 - v); + } + else + { + t = _e_illume_kbd->len; + v = 1.0; + } + _e_illume_kbd->adjust = ((_e_illume_kbd->adjust_end * v) + + (_e_illume_kbd->adjust_start * (1.0 - v))); + + if (_e_illume_kbd->border) + { + e_border_fx_offset(_e_illume_kbd->border, 0, + (_e_illume_kbd->border->h - _e_illume_kbd->adjust)); + } + + if (t == _e_illume_kbd->len) + { + _e_illume_kbd->animator = NULL; + if ((_e_illume_kbd->visible) && + (_focused_state <= ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)) + { + if (_e_illume_kbd->border) + e_border_hide(_e_illume_kbd->border, 2); + _e_illume_kbd->visible = 0; + } + else + _e_illume_kbd->visible = 1; + + /* layout send */ + + /* tell the focused border it changed so layout gets udpated */ + if (_focused_border) + { + if (!e_illume_border_is_conformant(_focused_border)) + { + _focused_border->changes.size = 1; + _focused_border->changed = 1; + } + } + + return 0; + } + + return 1; +} + +static E_Illume_Keyboard * +_e_mod_kbd_by_border_get(E_Border *bd) +{ + Eina_List *l; + E_Border *over; + + if ((!bd) || (!bd->stolen)) return NULL; + + /* if this border is the one that vkbd is working with, return the kbd */ + if (_e_illume_kbd->border == bd) return _e_illume_kbd; + + /* loop the waiting borders */ + EINA_LIST_FOREACH(_e_illume_kbd->waiting_borders, l, over) + if (over == bd) return _e_illume_kbd; + + return NULL; +} + +static void +_e_mod_kbd_border_adopt(E_Border *bd) +{ + if ((!_e_illume_kbd) || (!bd)) return; + + _e_illume_kbd->border = bd; + + if (!_e_illume_kbd->visible) + { + e_border_fx_offset(bd, 0, bd->h); + /* layout send */ + } +} diff --git a/src/modules/illume2/e_mod_kbd.h b/src/modules/illume2/e_mod_kbd.h new file mode 100644 index 000000000..ebcd9df1c --- /dev/null +++ b/src/modules/illume2/e_mod_kbd.h @@ -0,0 +1,19 @@ +#ifndef E_MOD_KBD_H +# define E_MOD_KBD_H + +/* define keyboard object type */ +# define E_ILLUME_KBD_TYPE 0xE1b0988 + +int e_mod_kbd_init(void); +int e_mod_kbd_shutdown(void); + +E_Illume_Keyboard *e_mod_kbd_new(void); +void e_mod_kbd_enable(void); +void e_mod_kbd_disable(void); +void e_mod_kbd_show(void); +void e_mod_kbd_hide(void); +void e_mod_kbd_toggle(void); +void e_mod_kbd_fullscreen_set(E_Zone *zone, int fullscreen); +void e_mod_kbd_layout_set(E_Illume_Keyboard *kbd, E_Illume_Keyboard_Layout layout); + +#endif diff --git a/src/modules/illume2/e_mod_kbd_dbus.c b/src/modules/illume2/e_mod_kbd_dbus.c new file mode 100644 index 000000000..cdcb86488 --- /dev/null +++ b/src/modules/illume2/e_mod_kbd_dbus.c @@ -0,0 +1,279 @@ +#include "e_illume_private.h" +#include "e_mod_kbd_dbus.h" + +/* local function prototypes */ +static void _e_mod_kbd_dbus_ignore_load(void); +static void _e_mod_kbd_dbus_ignore_load_file(const char *file); +static void _e_mod_kbd_dbus_cb_input_kbd(void *data, void *reply, DBusError *err); +static void _e_mod_kbd_dbus_cb_input_kbd_is(void *data, void *reply, DBusError *err); +static void _e_mod_kbd_dbus_kbd_add(const char *udi); +static void _e_mod_kbd_dbus_kbd_del(const char *udi); +static void _e_mod_kbd_dbus_kbd_eval(void); +static void _e_mod_kbd_dbus_dev_add(void *data, DBusMessage *msg); +static void _e_mod_kbd_dbus_dev_del(void *data, DBusMessage *msg); +static void _e_mod_kbd_dbus_dev_chg(void *data, DBusMessage *msg); + +/* local variables */ +static int have_real_kbd = 0; +static E_DBus_Connection *_dbus_conn = NULL; +static E_DBus_Signal_Handler *_dev_add = NULL; +static E_DBus_Signal_Handler *_dev_del = NULL; +static E_DBus_Signal_Handler *_dev_chg = NULL; +static Eina_List *_dbus_kbds = NULL, *_ignore_kbds = NULL; + +void +e_mod_kbd_dbus_init(void) +{ + /* load the 'ignored' keyboard file */ + _e_mod_kbd_dbus_ignore_load(); + + /* try to attach to the system dbus */ + if (!(_dbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM))) return; + + /* ask HAL for any input keyboards */ + e_hal_manager_find_device_by_capability(_dbus_conn, "input.keyboard", + _e_mod_kbd_dbus_cb_input_kbd, NULL); + + /* setup dbus signal handlers for when a device gets added/removed/changed */ + _dev_add = + e_dbus_signal_handler_add(_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceAdded", _e_mod_kbd_dbus_dev_add, NULL); + _dev_del = + e_dbus_signal_handler_add(_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "DeviceRemoved", _e_mod_kbd_dbus_dev_del, NULL); + _dev_chg = + e_dbus_signal_handler_add(_dbus_conn, "org.freedesktop.Hal", + "/org/freedesktop/Hal/Manager", + "org.freedesktop.Hal.Manager", + "NewCapability", _e_mod_kbd_dbus_dev_chg, NULL); +} + +void +e_mod_kbd_dbus_shutdown(void) +{ + char *str; + + /* remove the dbus signal handlers if we can */ + if (_dev_add) e_dbus_signal_handler_del(_dbus_conn, _dev_add); + if (_dev_del) e_dbus_signal_handler_del(_dbus_conn, _dev_del); + if (_dev_chg) e_dbus_signal_handler_del(_dbus_conn, _dev_chg); + + /* free the list of ignored keyboards */ + EINA_LIST_FREE(_ignore_kbds, str) + eina_stringshare_del(str); + + /* free the list of keyboards */ + EINA_LIST_FREE(_dbus_kbds, str) + eina_stringshare_del(str); +} + +/* local functions */ +static void +_e_mod_kbd_dbus_ignore_load(void) +{ + char buff[PATH_MAX]; + + /* load the 'ignore' file from the user's home dir */ + e_user_dir_concat_static(buff, "keyboards/ignore_built_in_keyboards"); + _e_mod_kbd_dbus_ignore_load_file(buff); + + /* load the 'ignore' file from the system/module dir */ + snprintf(buff, sizeof(buff), + "%s/ignore_built_in_keyboards", _e_illume_mod_dir); + _e_mod_kbd_dbus_ignore_load_file(buff); +} + +static void +_e_mod_kbd_dbus_ignore_load_file(const char *file) +{ + char buff[PATH_MAX]; + FILE *f; + + /* can this file be opened */ + if (!(f = fopen(file, "r"))) return; + + /* parse out the info in the ignore file */ + while (fgets(buff, sizeof(buff), f)) + { + char *p; + int len; + + if (buff[0] == '#') continue; + len = strlen(buff); + if (len > 0) + { + if (buff[len - 1] == '\n') buff[len - 1] = 0; + } + p = buff; + while (isspace(*p)) p++; + + /* append this kbd to the ignore list */ + if (*p) + { + _ignore_kbds = + eina_list_append(_ignore_kbds, eina_stringshare_add(p)); + } + } + fclose(f); +} + +static void +_e_mod_kbd_dbus_cb_input_kbd(void *data, void *reply, DBusError *err) +{ + E_Hal_Manager_Find_Device_By_Capability_Return *ret = reply; + Eina_List *l; + char *dev; + + if ((!ret) || (!ret->strings)) return; + + /* if dbus errored then cleanup and get out */ + if (dbus_error_is_set(err)) + { + dbus_error_free(err); + return; + } + + /* for each returned keyboard, add it and evaluate it */ + EINA_LIST_FOREACH(ret->strings, l, dev) + { + _e_mod_kbd_dbus_kbd_add(dev); + _e_mod_kbd_dbus_kbd_eval(); + } +} + +static void +_e_mod_kbd_dbus_cb_input_kbd_is(void *data, void *reply, DBusError *err) +{ + E_Hal_Device_Query_Capability_Return *ret = reply; + char *udi = data; + + /* if dbus errored then cleanup and get out */ + if (dbus_error_is_set(err)) + { + dbus_error_free(err); + if (udi) free(udi); + return; + } + + /* if it's an input keyboard, than add it and eval */ + if ((ret) && (ret->boolean)) + { + if (udi) + { + _e_mod_kbd_dbus_kbd_add(udi); + _e_mod_kbd_dbus_kbd_eval(); + free(udi); + } + } +} + +static void +_e_mod_kbd_dbus_kbd_add(const char *udi) +{ + const char *str; + Eina_List *l; + + if (!udi) return; + EINA_LIST_FOREACH(_dbus_kbds, l, str) + if (!strcmp(str, udi)) return; + _dbus_kbds = eina_list_append(_dbus_kbds, eina_stringshare_add(udi)); +} + +static void +_e_mod_kbd_dbus_kbd_del(const char *udi) +{ + const char *str; + Eina_List *l; + + if (!udi) return; + EINA_LIST_FOREACH(_dbus_kbds, l, str) + if (!strcmp(str, udi)) + { + eina_stringshare_del(str); + _dbus_kbds = eina_list_remove_list(_dbus_kbds, l); + return; + } +} + +static void +_e_mod_kbd_dbus_kbd_eval(void) +{ + Eina_List *l, *ll; + const char *g, *gg; + int have_real = 0; + + have_real = eina_list_count(_dbus_kbds); + EINA_LIST_FOREACH(_dbus_kbds, l, g) + EINA_LIST_FOREACH(_ignore_kbds, ll, gg) + if (e_util_glob_match(g, gg)) + { + have_real--; + break; + } + + if (have_real != have_real_kbd) + { + have_real_kbd = have_real; +#if 0 +// if (have_real_kbd) e_kbd_all_disable(); + else +#endif +// e_kbd_all_enable(); + } +} + +static void +_e_mod_kbd_dbus_dev_add(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); + e_hal_device_query_capability(_dbus_conn, udi, "input.keyboard", + _e_mod_kbd_dbus_cb_input_kbd_is, udi); +} + +static void +_e_mod_kbd_dbus_dev_del(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); + if (udi) + { + _e_mod_kbd_dbus_kbd_del(udi); + _e_mod_kbd_dbus_kbd_eval(); + free(udi); + } +} + +static void +_e_mod_kbd_dbus_dev_chg(void *data, DBusMessage *msg) +{ + DBusError err; + char *udi, *cap; + + dbus_error_init(&err); + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, + DBUS_TYPE_STRING, &cap, DBUS_TYPE_INVALID); + if (cap) + { + if (!strcmp(cap, "input.keyboard")) + { + if (udi) + { + _e_mod_kbd_dbus_kbd_add(udi); + _e_mod_kbd_dbus_kbd_eval(); + free(udi); + } + } + free(cap); + } +} diff --git a/src/modules/illume2/e_mod_kbd_dbus.h b/src/modules/illume2/e_mod_kbd_dbus.h new file mode 100644 index 000000000..071d244e2 --- /dev/null +++ b/src/modules/illume2/e_mod_kbd_dbus.h @@ -0,0 +1,7 @@ +#ifndef E_MOD_KBD_DBUS_H +# define E_MOD_KBD_DBUS_H + +void e_mod_kbd_dbus_init(void); +void e_mod_kbd_dbus_shutdown(void); + +#endif diff --git a/src/modules/illume2/e_mod_main.c b/src/modules/illume2/e_mod_main.c new file mode 100644 index 000000000..44581d02b --- /dev/null +++ b/src/modules/illume2/e_mod_main.c @@ -0,0 +1,127 @@ +#include "e_illume_private.h" +#include "e_mod_main.h" +#include "e_mod_config.h" +#include "e_mod_policy.h" +#include "e_mod_kbd.h" +#include "e_mod_quickpanel.h" + +/* NB: Initially I had done this rewrite with eina_logging enabled, but it + * degraded performance so much that it was just not worth it. So now this + * module just uses printfs on the console to report things */ + +/* external variables */ +const char *_e_illume_mod_dir = NULL; +E_Illume_Keyboard *_e_illume_kbd = NULL; +Eina_List *_e_illume_qps = NULL; + +EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Illume2" }; + +EAPI void * +e_modapi_init(E_Module *m) +{ + Eina_List *ml; + E_Manager *man; + + /* set module priority so we load first */ + e_module_priority_set(m, 100); + + /* set module directory variable */ + _e_illume_mod_dir = eina_stringshare_add(m->dir); + + /* try to initialize the config subsystem */ + if (!e_mod_config_init()) + { + /* clear module directory variable */ + if (_e_illume_mod_dir) eina_stringshare_del(_e_illume_mod_dir); + _e_illume_mod_dir = NULL; + + return NULL; + } + + /* try to initialize the policy subsystem */ + if (!e_mod_policy_init()) + { + /* shutdown the config subsystem */ + e_mod_config_shutdown(); + + /* clear module directory variable */ + if (_e_illume_mod_dir) eina_stringshare_del(_e_illume_mod_dir); + _e_illume_mod_dir = NULL; + + return NULL; + } + + /* initialize the keyboard subsystem */ + e_mod_kbd_init(); + + /* initialize the quickpanel subsystem */ + e_mod_quickpanel_init(); + + /* create a new vkbd & hide it initially */ + _e_illume_kbd = e_mod_kbd_new(); + e_mod_kbd_hide(); + + /* loop the zones and create quickpanels for each one */ + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + Eina_List *cl; + E_Container *con; + + EINA_LIST_FOREACH(man->containers, cl, con) + { + Eina_List *zl; + E_Zone *zone; + + EINA_LIST_FOREACH(con->zones, zl, zone) + { + E_Illume_Quickpanel *qp; + + /* try to create a new quickpanel for this zone */ + if (!(qp = e_mod_quickpanel_new(zone))) continue; + + /* append new qp to list */ + _e_illume_qps = eina_list_append(_e_illume_qps, qp); + } + } + } + + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + E_Illume_Quickpanel *qp; + + /* delete the quickpanels */ + EINA_LIST_FREE(_e_illume_qps, qp) + e_object_del(E_OBJECT(qp)); + + /* shutdown the quickpanel subsystem */ + e_mod_quickpanel_shutdown(); + + /* delete the keyboard object */ + if (_e_illume_kbd) e_object_del(E_OBJECT(_e_illume_kbd)); + _e_illume_kbd = NULL; + + /* shutdown the keyboard subsystem */ + e_mod_kbd_shutdown(); + + /* shutdown the policy subsystem */ + e_mod_policy_shutdown(); + + /* shutdown the config subsystem */ + e_mod_config_shutdown(); + + /* clear module directory variable */ + if (_e_illume_mod_dir) eina_stringshare_del(_e_illume_mod_dir); + _e_illume_mod_dir = NULL; + + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return e_mod_config_save(); +} diff --git a/src/modules/illume2/e_mod_main.h b/src/modules/illume2/e_mod_main.h new file mode 100644 index 000000000..f415823c6 --- /dev/null +++ b/src/modules/illume2/e_mod_main.h @@ -0,0 +1,10 @@ +#ifndef E_MOD_MAIN_H +# define E_MOD_MAIN_H + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init(E_Module *m); +EAPI int e_modapi_shutdown(E_Module *m); +EAPI int e_modapi_save(E_Module *m); + +#endif diff --git a/src/modules/illume2/e_mod_policy.c b/src/modules/illume2/e_mod_policy.c new file mode 100644 index 000000000..568a43a48 --- /dev/null +++ b/src/modules/illume2/e_mod_policy.c @@ -0,0 +1,520 @@ +#include "e_illume_private.h" +#include "e_mod_policy.h" + +/* local function prototypes */ +static char *_e_mod_policy_find(void); +static int _e_mod_policy_load(char *file); +static void _e_mod_policy_handlers_add(void); +static void _e_mod_policy_hooks_add(void); +static void _e_mod_policy_cb_free(E_Illume_Policy *p); +static int _e_mod_policy_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_policy_cb_policy_change(void *data __UNUSED__, int type, void *event __UNUSED__); +static void _e_mod_policy_cb_hook_post_fetch(void *data __UNUSED__, void *data2); +static void _e_mod_policy_cb_hook_post_assign(void *data __UNUSED__, void *data2); +static void _e_mod_policy_cb_hook_layout(void *data __UNUSED__, void *data2 __UNUSED__); + +/* local variables */ +static E_Illume_Policy *_policy = NULL; +static Eina_List *_policy_hdls = NULL, *_policy_hooks = NULL; + +/* external variables */ +int E_ILLUME_POLICY_EVENT_CHANGE = 0; + +int +e_mod_policy_init(void) +{ + Eina_List *ml; + E_Manager *man; + char *file; + + /* try to find the policy specified in config */ + if (!(file = _e_mod_policy_find())) + { + printf("Cannot find policy\n"); + return 0; + } + + /* attempt to load policy */ + if (!_e_mod_policy_load(file)) + { + /* loading policy failed, bail out */ + printf("Cannot load policy: %s\n", file); + if (file) free(file); + return 0; + } + + /* create new event for policy changes */ + E_ILLUME_POLICY_EVENT_CHANGE = ecore_event_type_new(); + + /* add our event handlers */ + _e_mod_policy_handlers_add(); + + /* add our border hooks */ + _e_mod_policy_hooks_add(); + + /* loop the root windows */ + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + Eina_List *cl; + E_Container *con; + + /* loop the containers */ + EINA_LIST_FOREACH(man->containers, cl, con) + { + Eina_List *zl; + E_Zone *zone; + + /* loop the zones */ + EINA_LIST_FOREACH(con->zones, zl, zone) + { + E_Illume_Config_Zone *cz; + Ecore_X_Illume_Mode mode; + + /* check for zone config */ + if (!(cz = e_illume_zone_config_get(zone->id))) + continue; + + /* set mode on this zone */ + if (cz->mode.dual == 0) + mode = ECORE_X_ILLUME_MODE_SINGLE; + else + { + if ((cz->mode.dual == 1) && (cz->mode.side == 0)) + mode = ECORE_X_ILLUME_MODE_DUAL_TOP; + else if ((cz->mode.dual == 1) && (cz->mode.side == 1)) + mode = ECORE_X_ILLUME_MODE_DUAL_LEFT; + } + ecore_x_e_illume_mode_set(zone->black_win, mode); + } + } + } + + return 1; +} + +int +e_mod_policy_shutdown(void) +{ + Ecore_Event_Handler *hdl; + E_Border_Hook *hook; + + /* remove the ecore event handlers */ + EINA_LIST_FREE(_policy_hdls, hdl) + ecore_event_handler_del(hdl); + + /* remove the border hooks */ + EINA_LIST_FREE(_policy_hooks, hook) + e_border_hook_del(hook); + + /* destroy the policy if it exists */ + if (_policy) e_object_del(E_OBJECT(_policy)); + + /* reset event type */ + E_ILLUME_POLICY_EVENT_CHANGE = 0; + + return 1; +} + +/* local functions */ +static char * +_e_mod_policy_find(void) +{ + Eina_List *files; + char buff[PATH_MAX], dir[PATH_MAX], *file; + + snprintf(buff, sizeof(buff), "%s.so", _e_illume_cfg->policy.name); + snprintf(dir, sizeof(dir), "%s/policies", _e_illume_mod_dir); + + /* try to list all files in this directory */ + if (!(files = ecore_file_ls(dir))) return NULL; + + /* loop the returned files */ + EINA_LIST_FREE(files, file) + { + /* compare file with needed .so */ + if (!strcmp(file, buff)) + { + snprintf(dir, sizeof(dir), "%s/policies/%s", + _e_illume_mod_dir, file); + break; + } + free(file); + } + if (file) free(file); + else + { + /* if we did not find the requested policy, use a fallback */ + snprintf(dir, sizeof(dir), "%s/policies/illume.so", _e_illume_mod_dir); + } + + return strdup(dir); +} + +static int +_e_mod_policy_load(char *file) +{ + /* safety check */ + if (!file) return 0; + + /* delete existing policy first */ + if (_policy) e_object_del(E_OBJECT(_policy)); + + /* try to create our new policy object */ + _policy = + E_OBJECT_ALLOC(E_Illume_Policy, E_ILLUME_POLICY_TYPE, + _e_mod_policy_cb_free); + if (!_policy) + { + printf("Failed to allocate new policy object\n"); + return 0; + } + + /* attempt to open the .so */ + if (!(_policy->handle = dlopen(file, (RTLD_NOW | RTLD_GLOBAL)))) + { + /* cannot open the .so file, bail out */ + printf("Cannot open policy: %s\n", ecore_file_file_get(file)); + printf("\tError: %s\n", dlerror()); + e_object_del(E_OBJECT(_policy)); + return 0; + } + + /* clear any existing errors in dynamic loader */ + dlerror(); + + /* try to link to the needed policy api functions */ + _policy->api = dlsym(_policy->handle, "e_illume_policy_api"); + _policy->funcs.init = dlsym(_policy->handle, "e_illume_policy_init"); + _policy->funcs.shutdown = dlsym(_policy->handle, "e_illume_policy_shutdown"); + + /* check that policy supports needed functions */ + if ((!_policy->api) || (!_policy->funcs.init) || (!_policy->funcs.shutdown)) + { + /* policy doesn't support needed functions, bail out */ + printf("Policy does not support needed functions: %s\n", + ecore_file_file_get(file)); + printf("\tError: %s\n", dlerror()); + e_object_del(E_OBJECT(_policy)); + return 0; + } + + /* check policy api version */ + if (_policy->api->version < E_ILLUME_POLICY_API_VERSION) + { + /* policy is too old, bail out */ + printf("Policy is too old: %s\n", ecore_file_file_get(file)); + e_object_del(E_OBJECT(_policy)); + return 0; + } + + /* try to initialize the policy */ + if (!_policy->funcs.init(_policy)) + { + /* init failed, bail out */ + printf("Policy failed to initialize: %s\n", ecore_file_file_get(file)); + e_object_del(E_OBJECT(_policy)); + return 0; + } + + return 1; +} + +static void +_e_mod_policy_handlers_add(void) +{ + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_EVENT_BORDER_ADD, + _e_mod_policy_cb_border_add, NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_EVENT_BORDER_REMOVE, + _e_mod_policy_cb_border_del, NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN, + _e_mod_policy_cb_border_focus_in, + NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, + _e_mod_policy_cb_border_focus_out, + NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_EVENT_ZONE_MOVE_RESIZE, + _e_mod_policy_cb_zone_move_resize, + NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + _e_mod_policy_cb_client_message, + NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, + _e_mod_policy_cb_window_property, + NULL)); + _policy_hdls = + eina_list_append(_policy_hdls, + ecore_event_handler_add(E_ILLUME_POLICY_EVENT_CHANGE, + _e_mod_policy_cb_policy_change, + NULL)); +} + +static void +_e_mod_policy_hooks_add(void) +{ + _policy_hooks = + eina_list_append(_policy_hooks, + e_border_hook_add(E_BORDER_HOOK_EVAL_POST_FETCH, + _e_mod_policy_cb_hook_post_fetch, NULL)); + _policy_hooks = + eina_list_append(_policy_hooks, + e_border_hook_add(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, + _e_mod_policy_cb_hook_post_assign, NULL)); + _policy_hooks = + eina_list_append(_policy_hooks, + e_border_hook_add(E_BORDER_HOOK_CONTAINER_LAYOUT, + _e_mod_policy_cb_hook_layout, NULL)); +} + +static void +_e_mod_policy_cb_free(E_Illume_Policy *p) +{ + /* tell the policy to shutdown */ + if (p->funcs.shutdown) p->funcs.shutdown(p); + p->funcs.shutdown = NULL; + + p->funcs.init = NULL; + p->api = NULL; + + /* close the linked .so */ + if (p->handle) dlclose(p->handle); + p->handle = NULL; + + E_FREE(p); +} + +static int +_e_mod_policy_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Add *ev; + + ev = event; + if ((_policy) && (_policy->funcs.border_add)) + _policy->funcs.border_add(ev->border); + + return 1; +} + +static int +_e_mod_policy_cb_border_del(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Remove *ev; + + ev = event; + if ((_policy) && (_policy->funcs.border_del)) + _policy->funcs.border_del(ev->border); + + return 1; +} + +static int +_e_mod_policy_cb_border_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Focus_In *ev; + + ev = event; + if ((_policy) && (_policy->funcs.border_focus_in)) + _policy->funcs.border_focus_in(ev->border); + + return 1; +} + +static int +_e_mod_policy_cb_border_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Focus_Out *ev; + + ev = event; + if ((_policy) && (_policy->funcs.border_focus_out)) + _policy->funcs.border_focus_out(ev->border); + + return 1; +} + +static int +_e_mod_policy_cb_zone_move_resize(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Zone_Move_Resize *ev; + + ev = event; + if ((_policy) && (_policy->funcs.zone_move_resize)) + _policy->funcs.zone_move_resize(ev->zone); + + return 1; +} + +static int +_e_mod_policy_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_X_Event_Client_Message *ev; + + ev = event; + if (ev->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW) + { + E_Border *bd; + + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + if ((_policy) && (_policy->funcs.border_activate)) + _policy->funcs.border_activate(bd); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_MODE) + { + E_Zone *zone; + + if (!(zone = e_util_zone_window_find(ev->win))) return 1; + if ((_policy) && (_policy->funcs.zone_mode_change)) + _policy->funcs.zone_mode_change(zone, ev->data.l[0]); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_CLOSE) + { + E_Zone *zone; + + if (!(zone = e_util_zone_window_find(ev->win))) return 1; + if ((_policy) && (_policy->funcs.zone_close)) + _policy->funcs.zone_close(zone); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_FOCUS_BACK) + { + E_Zone *zone; + + if (!(zone = e_util_zone_window_find(ev->win))) return 1; + if ((_policy) && (_policy->funcs.focus_back)) + _policy->funcs.focus_back(zone); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_FOCUS_FORWARD) + { + E_Zone *zone; + + if (!(zone = e_util_zone_window_find(ev->win))) return 1; + if ((_policy) && (_policy->funcs.focus_forward)) + _policy->funcs.focus_forward(zone); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_FOCUS_HOME) + { + E_Zone *zone; + + if (!(zone = e_util_zone_window_find(ev->win))) return 1; + if ((_policy) && (_policy->funcs.focus_home)) + _policy->funcs.focus_home(zone); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_DRAG_START) + { + E_Border *bd; + + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + if ((_policy) && (_policy->funcs.drag_start)) + _policy->funcs.drag_start(bd); + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_DRAG_END) + { + E_Border *bd; + + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + if ((_policy) && (_policy->funcs.drag_end)) + _policy->funcs.drag_end(bd); + } +// else +// printf("Client Message: %s\n", ecore_x_atom_name_get(ev->message_type)); + + return 1; +} + +static int +_e_mod_policy_cb_window_property(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_X_Event_Window_Property *ev; + + ev = event; + if ((_policy) && (_policy->funcs.property_change)) + _policy->funcs.property_change(ev); + + return 1; +} + +static int +_e_mod_policy_cb_policy_change(void *data __UNUSED__, int type, void *event __UNUSED__) +{ + char *file; + + if (type != E_ILLUME_POLICY_EVENT_CHANGE) return 1; + + /* find policy specified in config */ + if (!(file = _e_mod_policy_find())) return 1; + + /* try to load the policy */ + _e_mod_policy_load(file); + + if (file) free(file); + + return 1; +} + +static void +_e_mod_policy_cb_hook_post_fetch(void *data __UNUSED__, void *data2) +{ + E_Border *bd; + + if (!(bd = data2)) return; + if ((_policy) && (_policy->funcs.border_post_fetch)) + _policy->funcs.border_post_fetch(bd); +} + +static void +_e_mod_policy_cb_hook_post_assign(void *data __UNUSED__, void *data2) +{ + E_Border *bd; + + if (!(bd = data2)) return; + if ((_policy) && (_policy->funcs.border_post_assign)) + _policy->funcs.border_post_assign(bd); +} + +static void +_e_mod_policy_cb_hook_layout(void *data __UNUSED__, void *data2 __UNUSED__) +{ + E_Zone *zone; + E_Border *bd; + Eina_List *zl = NULL, *l; + + /* loop through border list and find what changed */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + if ((bd->new_client) || (bd->pending_move_resize) || + (bd->changes.pos) || (bd->changes.size) || (bd->changes.visible)) + { + /* NB: this border changed. add it's zone to list of what needs + * updating. This is done so we do not waste cpu cycles + * updating zones where nothing changed */ + if (!eina_list_data_find(zl, bd->zone)) + zl = eina_list_append(zl, bd->zone); + } + } + l = eina_list_free(l); + + /* loop the zones that need updating and call the policy update function */ + EINA_LIST_FREE(zl, zone) + { + if ((_policy) && (_policy->funcs.zone_layout)) + _policy->funcs.zone_layout(zone); + } + zl = eina_list_free(zl); +} diff --git a/src/modules/illume2/e_mod_policy.h b/src/modules/illume2/e_mod_policy.h new file mode 100644 index 000000000..29b61e5b3 --- /dev/null +++ b/src/modules/illume2/e_mod_policy.h @@ -0,0 +1,7 @@ +#ifndef E_MOD_POLICY_H +# define E_MOD_POLICY_H + +int e_mod_policy_init(void); +int e_mod_policy_shutdown(void); + +#endif diff --git a/src/modules/illume2/e_mod_quickpanel.c b/src/modules/illume2/e_mod_quickpanel.c new file mode 100644 index 000000000..14dcc3054 --- /dev/null +++ b/src/modules/illume2/e_mod_quickpanel.c @@ -0,0 +1,415 @@ +#include "e_illume_private.h" +#include "e_mod_quickpanel.h" + +/* local function prototypes */ +static int _e_mod_quickpanel_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_quickpanel_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event); +static int _e_mod_quickpanel_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event); +static void _e_mod_quickpanel_cb_post_fetch(void *data __UNUSED__, void *data2); +static void _e_mod_quickpanel_cb_free(E_Illume_Quickpanel *qp); +static int _e_mod_quickpanel_cb_delay_hide(void *data); +static void _e_mod_quickpanel_slide(E_Illume_Quickpanel *qp, int visible, double len); +static void _e_mod_quickpanel_hide(E_Illume_Quickpanel *qp); +static int _e_mod_quickpanel_cb_animate(void *data); +static void _e_mod_quickpanel_position_update(E_Illume_Quickpanel *qp); + +/* local variables */ +static Eina_List *_qp_hdls = NULL; +static E_Border_Hook *_qp_hook = NULL; +static Ecore_X_Window _qp_input_win = 0; + +int +e_mod_quickpanel_init(void) +{ + /* add handlers for messages we are interested in */ + _qp_hdls = + eina_list_append(_qp_hdls, + ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, + _e_mod_quickpanel_cb_client_message, + NULL)); + _qp_hdls = + eina_list_append(_qp_hdls, + ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, + _e_mod_quickpanel_cb_mouse_down, + NULL)); + _qp_hdls = + eina_list_append(_qp_hdls, + ecore_event_handler_add(E_EVENT_BORDER_ADD, + _e_mod_quickpanel_cb_border_add, + NULL)); + + /* add hook for new borders so we can test for qp borders */ + _qp_hook = e_border_hook_add(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, + _e_mod_quickpanel_cb_post_fetch, NULL); + + return 1; +} + +int +e_mod_quickpanel_shutdown(void) +{ + Ecore_Event_Handler *hdl; + + /* delete the event handlers */ + EINA_LIST_FREE(_qp_hdls, hdl) + ecore_event_handler_del(hdl); + + /* delete the border hook */ + if (_qp_hook) e_border_hook_del(_qp_hook); + _qp_hook = NULL; + + return 1; +} + +E_Illume_Quickpanel * +e_mod_quickpanel_new(E_Zone *zone) +{ + E_Illume_Quickpanel *qp; + + /* try to allocate a new quickpanel object */ + qp = E_OBJECT_ALLOC(E_Illume_Quickpanel, E_ILLUME_QP_TYPE, + _e_mod_quickpanel_cb_free); + if (!qp) return NULL; + + /* set quickpanel zone */ + qp->zone = zone; + + return qp; +} + +void +e_mod_quickpanel_show(E_Illume_Quickpanel *qp) +{ + E_Illume_Config_Zone *cz; + int duration; + + /* delete the animator if it exists */ + if (qp->animator) ecore_animator_del(qp->animator); + qp->animator = NULL; + + /* delete any existing timer */ + if (qp->timer) ecore_timer_del(qp->timer); + qp->timer = NULL; + + /* if it's already visible, or has no borders to show, then get out */ + if ((qp->visible) || (!qp->borders)) return; + + duration = _e_illume_cfg->animation.quickpanel.duration; + cz = e_illume_zone_config_get(qp->zone->id); + qp->ih = cz->indicator.size; + + if (!_qp_input_win) + { + /* create a new input window to catch clicks */ + _qp_input_win = + ecore_x_window_input_new(qp->zone->container->win, + qp->zone->x, qp->zone->y, + qp->zone->w, qp->zone->h); + ecore_x_window_show(_qp_input_win); + + /* grab mouse */ + if (!e_grabinput_get(_qp_input_win, 1, _qp_input_win)) + { + ecore_x_window_free(_qp_input_win); + _qp_input_win = 0; + return; + } + } + + /* check animation duration */ + if (duration <= 0) + { + Eina_List *l; + E_Border *bd; + int ny = 0; + + ny = qp->ih; + + /* if we are not animating, just show the borders */ + EINA_LIST_FOREACH(qp->borders, l, bd) + { + if (!bd->visible) e_illume_border_show(bd); + e_border_fx_offset(bd, 0, ny); + ny += bd->h; + } + qp->visible = 1; + } + else + _e_mod_quickpanel_slide(qp, 1, (double)duration / 1000.0); +} + +void +e_mod_quickpanel_hide(E_Illume_Quickpanel *qp) +{ + if (!qp->visible) return; + if (!qp->timer) + qp->timer = ecore_timer_add(0.2, _e_mod_quickpanel_cb_delay_hide, qp); +} + +/* local functions */ +static int +_e_mod_quickpanel_cb_client_message(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_X_Event_Client_Message *ev; + + ev = event; + if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) + { + E_Zone *zone; + + if (zone = e_util_zone_window_find(ev->win)) + { + E_Illume_Quickpanel *qp; + + if (qp = e_illume_quickpanel_by_zone_get(zone)) + { + if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF) + e_mod_quickpanel_hide(qp); + else + e_mod_quickpanel_show(qp); + } + } + } + else if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_POSITION_UPDATE) + { + E_Border *bd; + E_Illume_Quickpanel *qp; + + if (!(bd = e_border_find_by_client_window(ev->win))) return 1; + if (!(qp = e_illume_quickpanel_by_zone_get(bd->zone))) return 1; + _e_mod_quickpanel_position_update(qp); + } + + return 1; +} + +static int +_e_mod_quickpanel_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Event_Mouse_Button *ev; + Eina_List *l; + E_Illume_Quickpanel *qp; + + ev = event; + if (ev->event_window != _qp_input_win) return 1; + EINA_LIST_FOREACH(_e_illume_qps, l, qp) + if (qp->visible) + ecore_x_e_illume_quickpanel_state_send(qp->zone->black_win, + ECORE_X_ILLUME_QUICKPANEL_STATE_OFF); + + return 1; +} + +static int +_e_mod_quickpanel_cb_border_add(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + E_Event_Border_Add *ev; + E_Illume_Quickpanel *qp; + E_Zone *zone; + int iy; + + ev = event; + if (!ev->border->client.illume.quickpanel.quickpanel) return 1; + + zone = ev->border->zone; + + /* if this border should be on a different zone, get requested zone */ + if (zone->num != ev->border->client.illume.quickpanel.zone) + { + E_Container *con; + int zn = 0; + + /* find this zone */ + con = e_container_current_get(e_manager_current_get()); + zn = ev->border->client.illume.quickpanel.zone; + zone = e_util_container_zone_number_get(con->num, zn); + if (!zone) return 1; + } + + if (!(qp = e_illume_quickpanel_by_zone_get(zone))) return 1; + + /* set position and zone */ + e_illume_border_indicator_pos_get(zone, NULL, &iy); + if ((ev->border->x != zone->x) || (ev->border->y != iy)) + e_border_move(ev->border, zone->x, iy); + if (ev->border->zone != zone) + e_border_zone_set(ev->border, zone); + + /* hide this border */ + e_illume_border_hide(ev->border); + + qp->h += ev->border->h; + + /* add this border to QP border collection */ + qp->borders = eina_list_append(qp->borders, ev->border); + + return 1; +} + +static void +_e_mod_quickpanel_cb_post_fetch(void *data __UNUSED__, void *data2) +{ + E_Border *bd; + + if (!(bd = data2)) return; + if (!bd->client.illume.quickpanel.quickpanel) return; + bd->stolen = 1; +} + +static void +_e_mod_quickpanel_cb_free(E_Illume_Quickpanel *qp) +{ + E_Border *bd; + + /* delete the animator if it exists */ + if (qp->animator) ecore_animator_del(qp->animator); + qp->animator = NULL; + + /* delete the timer if it exists */ + if (qp->timer) ecore_timer_del(qp->timer); + qp->timer = NULL; + + /* set the borders of this quickpanel to not stolen */ + EINA_LIST_FREE(qp->borders, bd) + bd->stolen = 0; + + /* free the structure */ + E_FREE(qp); +} + +static int +_e_mod_quickpanel_cb_delay_hide(void *data) +{ + E_Illume_Quickpanel *qp; + + if (!(qp = data)) return 0; + _e_mod_quickpanel_hide(qp); + return 0; +} + +static void +_e_mod_quickpanel_slide(E_Illume_Quickpanel *qp, int visible, double len) +{ + qp->start = ecore_loop_time_get(); + qp->len = len; + qp->adjust_start = qp->adjust; + qp->adjust_end = 0; + if (visible) qp->adjust_end = qp->h; + if (!qp->animator) + qp->animator = ecore_animator_add(_e_mod_quickpanel_cb_animate, qp); +} + +static void +_e_mod_quickpanel_hide(E_Illume_Quickpanel *qp) +{ + int duration; + + /* delete the animator if it exists */ + if (qp->animator) ecore_animator_del(qp->animator); + qp->animator = NULL; + + /* delete the timer if it exists */ + if (qp->timer) ecore_timer_del(qp->timer); + qp->timer = NULL; + + /* if it's not visible, we can't hide it */ + if (!qp->visible) return; + + duration = _e_illume_cfg->animation.quickpanel.duration; + + /* destroy the input window */ + if (_qp_input_win) + { + ecore_x_window_free(_qp_input_win); + e_grabinput_release(_qp_input_win, _qp_input_win); + _qp_input_win = 0; + } + + if (duration <= 0) + { + Eina_List *l; + E_Border *bd; + + /* if we are not animating, hide the qp borders */ + EINA_LIST_REVERSE_FOREACH(qp->borders, l, bd) + { + e_border_fx_offset(bd, 0, 0); + if (bd->visible) e_illume_border_hide(bd); + } + qp->visible = 0; + } + else + _e_mod_quickpanel_slide(qp, 0, (double)duration / 1000.0); +} + +static int +_e_mod_quickpanel_cb_animate(void *data) +{ + E_Illume_Quickpanel *qp; + Eina_List *l; + E_Border *bd; + int pbh = 0; + double t, v = 1.0; + + if (!(qp = data)) return 0; + t = (ecore_loop_time_get() - qp->start); + if (t > qp->len) t = qp->len; + if (qp->len > 0.0) + { + v = (t / qp->len); + v = (1.0 - v); + v = (v * v * v * v); + v = (1.0 - v); + } + else + t = qp->len; + + qp->adjust = (qp->adjust_end * v) + (qp->adjust_start * (1.0 - v)); + + pbh = (qp->ih - qp->h); + EINA_LIST_FOREACH(qp->borders, l, bd) + { + /* don't adjust borders that are being deleted */ + if (e_object_is_del(E_OBJECT(bd))) continue; + if (bd->fx.y != (qp->adjust + pbh)) + e_border_fx_offset(bd, 0, (qp->adjust + pbh)); + pbh += bd->h; + if (!qp->visible) + { + if (bd->fx.y > 0) + { + if (!bd->visible) e_illume_border_show(bd); + } + } + else + { + if (bd->fx.y <= 10) + { + if (bd->visible) e_illume_border_hide(bd); + } + } + } + + if (t == qp->len) + { + qp->animator = NULL; + if (qp->visible) qp->visible = 0; + else qp->visible = 1; + return 0; + } + + return 1; +} + +static void +_e_mod_quickpanel_position_update(E_Illume_Quickpanel *qp) +{ + Eina_List *l; + E_Border *bd; + int iy = 0; + + e_mod_quickpanel_hide(qp); + e_illume_border_indicator_pos_get(qp->zone, NULL, &iy); + EINA_LIST_FOREACH(qp->borders, l, bd) + e_border_move(bd, qp->zone->x, iy); +} diff --git a/src/modules/illume2/e_mod_quickpanel.h b/src/modules/illume2/e_mod_quickpanel.h new file mode 100644 index 000000000..b3eb3f15c --- /dev/null +++ b/src/modules/illume2/e_mod_quickpanel.h @@ -0,0 +1,13 @@ +#ifndef E_MOD_QUICKPANEL_H +# define E_MOD_QUICKPANEL_H + +# define E_ILLUME_QP_TYPE 0xE1b0990 + +int e_mod_quickpanel_init(void); +int e_mod_quickpanel_shutdown(void); + +E_Illume_Quickpanel *e_mod_quickpanel_new(E_Zone *zone); +void e_mod_quickpanel_show(E_Illume_Quickpanel *qp); +void e_mod_quickpanel_hide(E_Illume_Quickpanel *qp); + +#endif diff --git a/src/modules/illume2/e_mod_select_window.c b/src/modules/illume2/e_mod_select_window.c new file mode 100644 index 000000000..962f5f781 --- /dev/null +++ b/src/modules/illume2/e_mod_select_window.c @@ -0,0 +1,277 @@ +#include "e_illume_private.h" +#include "e_mod_select_window.h" + +/* local function prototypes */ +static void *_e_mod_config_select_window_create_data(E_Config_Dialog *cfd); +static void _e_mod_config_select_window_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); +static Evas_Object *_e_mod_config_select_window_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata); +static void _e_mod_config_select_window_list_changed(void *data); +static int _e_mod_config_select_window_change_timeout(void *data); +static int _e_mod_config_select_window_match(E_Border *bd); + +/* local variables */ +E_Illume_Select_Window_Type stype; +Ecore_Timer *_sw_change_timer = NULL; + +/* public functions */ +void +e_mod_config_select_window(E_Illume_Select_Window_Type type) +{ + E_Config_Dialog *cfd; + E_Config_Dialog_View *v; + + if (e_config_dialog_find("E", "_config_illume_select_window")) return; + + v = E_NEW(E_Config_Dialog_View, 1); + if (!v) return; + + v->create_cfdata = _e_mod_config_select_window_create_data; + v->free_cfdata = _e_mod_config_select_window_free_data; + v->basic.create_widgets = _e_mod_config_select_window_create; + v->basic_only = 1; + v->normal_win = 1; + v->scroll = 1; + cfd = e_config_dialog_new(e_container_current_get(e_manager_current_get()), + _("Select Home Window"), "E", + "_config_illume_select_window", + "enlightenment/windows", 0, v, NULL); + if (!cfd) return; + e_dialog_resizable_set(cfd->dia, 1); + stype = type; +} + +static void * +_e_mod_config_select_window_create_data(E_Config_Dialog *cfd) +{ + return NULL; +} + +static void +_e_mod_config_select_window_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +{ + +} + +static Evas_Object * +_e_mod_config_select_window_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +{ + Evas_Object *list, *ow; + Eina_List *bds, *l; + int i = 0, sel = -1; + + list = e_widget_list_add(evas, 0, 0); + ow = e_widget_ilist_add(evas, 24, 24, NULL); + e_widget_ilist_selector_set(ow, 1); + evas_event_freeze(evas); + edje_freeze(); + e_widget_ilist_freeze(ow); + e_widget_ilist_clear(ow); + e_widget_ilist_go(ow); + + bds = e_border_client_list(); + if (bds) + { + for (i = 0, l = bds; l; l = l->next, i++) + { + E_Border *bd; + const char *name; + + if (!(bd = l->data)) continue; + if (e_object_is_del(E_OBJECT(bd))) continue; + if (_e_mod_config_select_window_match(bd)) sel = i; + if (!(name = e_border_name_get(bd))) continue; + e_widget_ilist_append(ow, NULL, name, + _e_mod_config_select_window_list_changed, + bd, name); + } + } + + e_widget_size_min_set(ow, 100, 200); + e_widget_ilist_go(ow); + if (sel >= 0) e_widget_ilist_selected_set(ow, sel); + e_widget_ilist_thaw(ow); + edje_thaw(); + evas_event_thaw(evas); + e_widget_list_object_append(list, ow, 1, 0, 0.0); + return list; +} + +static void +_e_mod_config_select_window_list_changed(void *data) +{ + E_Border *bd; + Ecore_X_Window_Type wtype; + char *title, *name, *class; + + if (!(bd = data)) return; + title = ecore_x_icccm_title_get(bd->client.win); + ecore_x_icccm_name_class_get(bd->client.win, &name, &class); + ecore_x_netwm_window_type_get(bd->client.win, &wtype); + + switch (stype) + { + case E_ILLUME_SELECT_WINDOW_TYPE_HOME: + if (_e_illume_cfg->policy.home.title) + eina_stringshare_del(_e_illume_cfg->policy.home.title); + if (title) _e_illume_cfg->policy.home.title = eina_stringshare_add(title); + if (_e_illume_cfg->policy.home.class) + eina_stringshare_del(_e_illume_cfg->policy.home.class); + if (class) _e_illume_cfg->policy.home.class = eina_stringshare_add(class); + if (_e_illume_cfg->policy.home.name) + eina_stringshare_del(_e_illume_cfg->policy.home.name); + if (name) _e_illume_cfg->policy.home.name = eina_stringshare_add(name); + break; + case E_ILLUME_SELECT_WINDOW_TYPE_VKBD: + if (_e_illume_cfg->policy.vkbd.title) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.title); + if (title) _e_illume_cfg->policy.vkbd.title = eina_stringshare_add(title); + if (_e_illume_cfg->policy.vkbd.class) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.class); + if (class) _e_illume_cfg->policy.vkbd.class = eina_stringshare_add(class); + if (_e_illume_cfg->policy.vkbd.name) + eina_stringshare_del(_e_illume_cfg->policy.vkbd.name); + if (name) _e_illume_cfg->policy.vkbd.name = eina_stringshare_add(name); + break; + case E_ILLUME_SELECT_WINDOW_TYPE_SOFTKEY: + if (_e_illume_cfg->policy.softkey.title) + eina_stringshare_del(_e_illume_cfg->policy.softkey.title); + if (title) _e_illume_cfg->policy.softkey.title = eina_stringshare_add(title); + if (_e_illume_cfg->policy.softkey.class) + eina_stringshare_del(_e_illume_cfg->policy.softkey.class); + if (class) _e_illume_cfg->policy.softkey.class = eina_stringshare_add(class); + if (_e_illume_cfg->policy.softkey.name) + eina_stringshare_del(_e_illume_cfg->policy.softkey.name); + if (name) _e_illume_cfg->policy.softkey.name = eina_stringshare_add(name); + break; + case E_ILLUME_SELECT_WINDOW_TYPE_INDICATOR: + if (_e_illume_cfg->policy.indicator.title) + eina_stringshare_del(_e_illume_cfg->policy.indicator.title); + if (title) _e_illume_cfg->policy.indicator.title = eina_stringshare_add(title); + if (_e_illume_cfg->policy.indicator.class) + eina_stringshare_del(_e_illume_cfg->policy.indicator.class); + if (class) _e_illume_cfg->policy.indicator.class = eina_stringshare_add(class); + if (_e_illume_cfg->policy.indicator.name) + eina_stringshare_del(_e_illume_cfg->policy.indicator.name); + if (name) _e_illume_cfg->policy.indicator.name = eina_stringshare_add(name); + break; + } + + if (title) free(title); + if (name) free(name); + if (class) free(class); + + if (_sw_change_timer) ecore_timer_del(_sw_change_timer); + _sw_change_timer = + ecore_timer_add(0.5, _e_mod_config_select_window_change_timeout, data); +} + +static int +_e_mod_config_select_window_change_timeout(void *data) +{ + e_config_save_queue(); + _sw_change_timer = NULL; + return 0; +} + +static int +_e_mod_config_select_window_match(E_Border *bd) +{ + Ecore_X_Window_Type wtype; + char *title, *name, *class; + int match = 0; + + if (!bd) return 0; + title = ecore_x_icccm_title_get(bd->client.win); + ecore_x_icccm_name_class_get(bd->client.win, &name, &class); + ecore_x_netwm_window_type_get(bd->client.win, &wtype); + + switch (stype) + { + case E_ILLUME_SELECT_WINDOW_TYPE_HOME: + if (_e_illume_cfg->policy.home.match.title) + { + if ((title) && (!strcmp(title, _e_illume_cfg->policy.home.title))) + match = 1; + break; + } + if (_e_illume_cfg->policy.home.match.name) + { + if ((name) && (!strcmp(name, _e_illume_cfg->policy.home.name))) + match = 1; + break; + } + if (_e_illume_cfg->policy.home.match.class) + { + if ((class) && (!strcmp(class, _e_illume_cfg->policy.home.class))) + match = 1; + break; + } + break; + case E_ILLUME_SELECT_WINDOW_TYPE_VKBD: + if (_e_illume_cfg->policy.vkbd.match.title) + { + if ((title) && (!strcmp(title, _e_illume_cfg->policy.vkbd.title))) + match = 1; + break; + } + if (_e_illume_cfg->policy.vkbd.match.name) + { + if ((name) && (!strcmp(name, _e_illume_cfg->policy.vkbd.name))) + match = 1; + break; + } + if (_e_illume_cfg->policy.vkbd.match.class) + { + if ((class) && (!strcmp(class, _e_illume_cfg->policy.vkbd.class))) + match = 1; + break; + } + break; + case E_ILLUME_SELECT_WINDOW_TYPE_SOFTKEY: + if (_e_illume_cfg->policy.softkey.match.title) + { + if ((title) && (!strcmp(title, _e_illume_cfg->policy.softkey.title))) + match = 1; + break; + } + if (_e_illume_cfg->policy.softkey.match.name) + { + if ((name) && (!strcmp(name, _e_illume_cfg->policy.softkey.name))) + match = 1; + break; + } + if (_e_illume_cfg->policy.softkey.match.class) + { + if ((class) && (!strcmp(class, _e_illume_cfg->policy.softkey.class))) + match = 1; + break; + } + break; + case E_ILLUME_SELECT_WINDOW_TYPE_INDICATOR: + if (_e_illume_cfg->policy.indicator.match.title) + { + if ((title) && (!strcmp(title, _e_illume_cfg->policy.indicator.title))) + match = 1; + break; + } + if (_e_illume_cfg->policy.indicator.match.name) + { + if ((name) && (!strcmp(name, _e_illume_cfg->policy.indicator.name))) + match = 1; + break; + } + if (_e_illume_cfg->policy.indicator.match.class) + { + if ((class) && (!strcmp(class, _e_illume_cfg->policy.indicator.class))) + match = 1; + break; + } + break; + } + + if (title) free(title); + if (name) free(name); + if (class) free(class); + + return match; +} diff --git a/src/modules/illume2/e_mod_select_window.h b/src/modules/illume2/e_mod_select_window.h new file mode 100644 index 000000000..a4c2ca764 --- /dev/null +++ b/src/modules/illume2/e_mod_select_window.h @@ -0,0 +1,15 @@ +#ifndef E_MOD_SELECT_WINDOW_H +#define E_MOD_SELECT_WINDOW_H + +typedef enum _E_Illume_Select_Window_Type E_Illume_Select_Window_Type; +enum _E_Illume_Select_Window_Type +{ + E_ILLUME_SELECT_WINDOW_TYPE_HOME, + E_ILLUME_SELECT_WINDOW_TYPE_VKBD, + E_ILLUME_SELECT_WINDOW_TYPE_SOFTKEY, + E_ILLUME_SELECT_WINDOW_TYPE_INDICATOR +}; + +void e_mod_config_select_window(E_Illume_Select_Window_Type type); + +#endif diff --git a/src/modules/illume2/images/Makefile.am b/src/modules/illume2/images/Makefile.am new file mode 100644 index 000000000..6093afd3b --- /dev/null +++ b/src/modules/illume2/images/Makefile.am @@ -0,0 +1,3 @@ +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = module_icon.png diff --git a/src/modules/illume2/images/module_icon.png b/src/modules/illume2/images/module_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..babb896340d75a930262a5d2aacc025302bf0209 GIT binary patch literal 2814 zcmVF&Dlu%||!YkMxX#|}Yhsnk8) z?W#K8Ip;g4PPKs-$BW~|@#1)KJewngphF1ySJwuUKnK z=Ugf05JDJ^Mx#MhRYxI&qpGTohQr}+0Q~;E=VmShWu<IXpbx=olXb+e!seL*FE7`GQHY-$QZf2d*;xn7Zgc4Vx~O+Z_4Dl^1K4zFUDxqCf>z79kn0@4 zcf~3S88drkVUS}!0k8?+WdR}*)*u1GiC|*@>bmwyDJSh+rOoYnsLrV39K#0nN%7PC$7@#>%B-XNhKd0p=ek@`g;LOTt8VJZUKq*jR5cs@_k3%V)X!-3W z8eAg)PQ?ZK6xvVC|5dq{%f#Zu56GvF=zbJF{%-2Jw%&Wb=Lw*g_BNDE9RgUAv2)4^ zPMjE-GirZBv=8xBOOqeT`<7z5rsq*u-84;8*R>_L@MJx;^sS{uZdnm4*pRU@X(vjL z%_+4X{eLUz$I3fLl)Vi|7)1a?a8Om14IwlX_XB|$Ehv}2>4?BFFW3U`FUmAk2tm!e zNIH!LMD4GO7Gk<;3Hbw=Oef(2O<^v&3!XfA(z$f$5(ofC*C3ORRuJ8wCmgg+Zeq{N z1r$vnh9X4^8)ol;Tz5r#QQ$~am4H(Nz~0_oXqqNV0C1E<1+f57id{>8U75=+xq+Y8 z4b%zDKbn0hsDE1qzYO3d0VXCZ2Xeh8%iCxjnP_cY`np6G6OtU^DXk+Q<7DI#2NZ^P z0sH~Lj)cw{fSbn+%n7uw2;pmlaP&QpFqOE)KpMYW)555th0?L~IC&oX?UE}+qFoWC zTobS}BHObAkdU7iZ7-2Y$B8Op=(vhIq-YSIcjSGW0N`oT94h1T`GDr(DQAe5uqwrv zDq7<_WN1zi{$8fZX5^<)kdZtqiI@VpNI_Mhk^J3=EFdJI(i3<&xveH^T9$sV0N5i= zS_lcU_WNRnj-E3Bhhzv?K$?+IQJ{h%0|TX!zjH)>9SN_omf%AOS}En{1|X@@b_CIqQ0D85CLMEy9#wKu z?Jo-mg zIwb+fnlC7!$;iJ!R@G38b%mj9itLMaj|gN%u8_%G)~T|LN!w{=hVZ3mX-U{WZc$y9 zx?IcxS4d#4?Q7zQEIBg(zJ&*TvM6H92ogH?gz$D{(`1+WS{BmOoQ$O)mc zgbc$M3L;eW$Rz?S$;$7ivJ=yz-59RNo5T&W37VM60aaDOS{wHE_VD1r0~AFOwAQ{X zOTV(R;@8&JT%PByEK4^*=$clD0|0*o@LK@?lw~s)OMDvunv#|n_m?H?y(ycY*9d@4 z5)RD_5Zbt)jRX9_!2x!5cA%8Z^)m2UeZ% zj2Qs5rNxr~I`;fDA5AXoqvHwN(&`jrhI#HS>WlFU`NzpQ!NMXxgP-^KFN8SYr?xk* QuK)l507*qoM6N<$g6PaOy8r+H literal 0 HcmV?d00001 diff --git a/src/modules/illume2/keyboards/Makefile.am b/src/modules/illume2/keyboards/Makefile.am new file mode 100644 index 000000000..57f0a2643 --- /dev/null +++ b/src/modules/illume2/keyboards/Makefile.am @@ -0,0 +1,11 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume3 + +filesdir = $(libdir)/enlightenment/modules/$(MODULE)/keyboards +files_DATA = ignore_built_in_keyboards + +EXTRA_DIST = $(files_DATA) + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)/keyboards + diff --git a/src/modules/illume2/keyboards/ignore_built_in_keyboards b/src/modules/illume2/keyboards/ignore_built_in_keyboards new file mode 100644 index 000000000..bdb9d6bbb --- /dev/null +++ b/src/modules/illume2/keyboards/ignore_built_in_keyboards @@ -0,0 +1 @@ +/org/freedesktop/Hal/devices/platform_* diff --git a/src/modules/illume2/module.desktop.in b/src/modules/illume2/module.desktop.in new file mode 100644 index 000000000..bbacd7507 --- /dev/null +++ b/src/modules/illume2/module.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Link +Name=Illume2 +Icon=e-module-illume2 +X-Enlightenment-ModuleType=system +Comment=Illume2 for Embedded diff --git a/src/modules/illume2/policies/Makefile.am b/src/modules/illume2/policies/Makefile.am new file mode 100644 index 000000000..e433fcee7 --- /dev/null +++ b/src/modules/illume2/policies/Makefile.am @@ -0,0 +1,2 @@ +MAINTAINERCLEANFILES = Makefile.in +SUBDIRS = illume diff --git a/src/modules/illume2/policies/illume/Makefile.am b/src/modules/illume2/policies/illume/Makefile.am new file mode 100644 index 000000000..75fecc51e --- /dev/null +++ b/src/modules/illume2/policies/illume/Makefile.am @@ -0,0 +1,27 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = illume2 +POLICY = illume + +# the module .so file +INCLUDES = -I.. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/modules/$(MODULE)/policies/$(POLICY) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ + +plugindir = $(libdir)/enlightenment/modules/$(MODULE)/policies + +illumedir = $(plugindir) +illume_LTLIBRARIES = illume.la +illume_la_SOURCES = \ + policy.h \ + policy.c \ + illume.h \ + illume.c + +illume_la_LIBADD = @e_libs@ +illume_la_LDFLAGS = -no-undefined -module -avoid-version +illume_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/src/modules/illume2/policies/illume/illume.c b/src/modules/illume2/policies/illume/illume.c new file mode 100644 index 000000000..62ac5c884 --- /dev/null +++ b/src/modules/illume2/policies/illume/illume.c @@ -0,0 +1,58 @@ +#include "e_illume.h" +#include "illume.h" +#include "policy.h" + +EAPI E_Illume_Policy_Api e_illume_policy_api = +{ + /* version, name, label */ + E_ILLUME_POLICY_API_VERSION, "illume", "Illume" +}; + +EAPI int +e_illume_policy_init(E_Illume_Policy *p) +{ + /* tell the policy what functions we support */ + p->funcs.border_add = _policy_border_add; + p->funcs.border_del = _policy_border_del; + p->funcs.border_focus_in = _policy_border_focus_in; + p->funcs.border_focus_out = _policy_border_focus_out; + p->funcs.border_activate = _policy_border_activate; + p->funcs.border_post_fetch = _policy_border_post_fetch; + p->funcs.border_post_assign = _policy_border_post_assign; + p->funcs.zone_layout = _policy_zone_layout; + p->funcs.zone_move_resize = _policy_zone_move_resize; + p->funcs.zone_mode_change = _policy_zone_mode_change; + p->funcs.zone_close = _policy_zone_close; + p->funcs.drag_start = _policy_drag_start; + p->funcs.drag_end = _policy_drag_end; + p->funcs.focus_back = _policy_focus_back; + p->funcs.focus_forward = _policy_focus_forward; + p->funcs.focus_home = _policy_focus_home; + p->funcs.property_change = _policy_property_change; + + return 1; +} + +EAPI int +e_illume_policy_shutdown(E_Illume_Policy *p) +{ + p->funcs.border_add = NULL; + p->funcs.border_del = NULL; + p->funcs.border_focus_in = NULL; + p->funcs.border_focus_out = NULL; + p->funcs.border_activate = NULL; + p->funcs.border_post_fetch = NULL; + p->funcs.border_post_assign = NULL; + p->funcs.zone_layout = NULL; + p->funcs.zone_move_resize = NULL; + p->funcs.zone_mode_change = NULL; + p->funcs.zone_close = NULL; + p->funcs.drag_start = NULL; + p->funcs.drag_end = NULL; + p->funcs.focus_back = NULL; + p->funcs.focus_forward = NULL; + p->funcs.focus_home = NULL; + p->funcs.property_change = NULL; + + return 1; +} diff --git a/src/modules/illume2/policies/illume/illume.h b/src/modules/illume2/policies/illume/illume.h new file mode 100644 index 000000000..d7d975b61 --- /dev/null +++ b/src/modules/illume2/policies/illume/illume.h @@ -0,0 +1,9 @@ +#ifndef _ILLUME_H +# define _ILLUME_H + +EAPI extern E_Illume_Policy_Api e_illume_policy_api; + +EAPI int e_illume_policy_init(E_Illume_Policy *p); +EAPI int e_illume_policy_shutdown(E_Illume_Policy *p); + +#endif diff --git a/src/modules/illume2/policies/illume/policy.c b/src/modules/illume2/policies/illume/policy.c new file mode 100644 index 000000000..8bc1c3db1 --- /dev/null +++ b/src/modules/illume2/policies/illume/policy.c @@ -0,0 +1,1607 @@ +#include "e_illume.h" +#include "policy.h" + +/* NB: DIALOG_USES_PIXEL_BORDER is an experiment in setting dialog windows + * to use the 'pixel' type border. This is done because some dialogs, + * when shown, blend into other windows too much. Pixel border adds a + * little distinction between the dialog window and an app window. + * Disable if this is not wanted */ +#define DIALOG_USES_PIXEL_BORDER 1 + +/* local function prototypes */ +static void _policy_border_set_focus(E_Border *bd); +static void _policy_border_move(E_Border *bd, int x, int y); +static void _policy_border_resize(E_Border *bd, int w, int h); +static void _policy_border_hide_below(E_Border *bd); +static void _policy_border_show_below(E_Border *bd); +static void _policy_zone_layout_update(E_Zone *zone); +static void _policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_quickpanel(E_Border *bd); +static void _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_home_dual_top(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_home_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_home_dual_left(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_fullscreen(E_Border *bd); +static void _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz); +static void _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz); + +/* local functions */ +static void +_policy_border_set_focus(E_Border *bd) +{ + /* if focus is locked out then get out */ + if (bd->lock_focus_out) return; + + /* make sure the border can accept or take focus */ + if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus)) + { + /* check E's focus settings */ + if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || + ((bd->parent) && + ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) || + ((bd->parent->focused) && + (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED))))) + { + /* if the border is iconified then uniconify */ + if (bd->iconic) + { + /* if the user is allowed to uniconify, then do it */ + if (!bd->lock_user_iconify) e_border_uniconify(bd); + } + + /* if we can raise the border do it */ + if (!bd->lock_user_stacking) e_border_raise(bd); + + /* focus the border */ + e_border_focus_set(bd, 1, 1); + + /* NB: since we skip needless border evals when container layout + * is called (to save cpu cycles), we need to + * signal this border that it's focused so that the edj gets + * updated. + * + * This is potentially useless as THIS policy + * makes all windows borderless anyway, but it's in here for + * completeness */ + e_border_focus_latest_set(bd); + if (bd->bg_object) + edje_object_signal_emit(bd->bg_object, "e,state,focused", "e"); + if (bd->icon_object) + edje_object_signal_emit(bd->icon_object, "e,state,focused", "e"); + e_focus_event_focus_in(bd); + } + } +} + +static void +_policy_border_move(E_Border *bd, int x, int y) +{ + /* NB: Qt uses a weird window type called 'VCLSalFrame' that needs to + * have bd->placed set else it doesn't position correctly... + * this could be a result of E honoring the icccm request position, + * not sure */ + + /* NB: Seems something similiar happens with elementary windows also + * so for now just set bd->placed on all windows until this + * gets investigated */ + bd->placed = 1; + bd->x = x; + bd->y = y; + bd->changes.pos = 1; + bd->changed = 1; +} + +static void +_policy_border_resize(E_Border *bd, int w, int h) +{ + bd->w = w; + bd->h = h; + bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r)); + bd->client.h = (bd->h - (bd->client_inset.t + bd->client_inset.b)); + bd->changes.size = 1; + bd->changed = 1; +} + +static void +_policy_border_hide_below(E_Border *bd) +{ + int pos = 0, i; + +// printf("Hide Borders Below: %s %d %d\n", +// bd->client.icccm.class, bd->x, bd->y); + + /* determine layering position */ + if (bd->layer <= 0) pos = 0; + else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1; + else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2; + else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3; + else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4; + else pos = 5; + + /* Find the windows below this one */ + for (i = pos; i >= 0; i--) + { + Eina_List *l; + E_Border *b; + + EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b) + { + /* skip if it's not on this zone */ + if (b->zone != bd->zone) continue; + + /* skip if it's the same border */ + if (b == bd) continue; + + /* skip special borders */ + if (e_illume_border_is_indicator(b)) continue; + if (e_illume_border_is_softkey(b)) continue; + if (e_illume_border_is_keyboard(b)) continue; + if (e_illume_border_is_quickpanel(b)) continue; + + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + if (b->visible) e_border_hide(b, 2); + } + else + { + /* we need to check x/y position */ + if ((b->x == bd->x) && (b->y == bd->y)) + { + if (b->visible) e_border_hide(b, 2); + } + } + } + } +} + +static void +_policy_border_show_below(E_Border *bd) +{ + int pos = 0, i; + +// printf("Show Borders Below: %s %d %d\n", +// bd->client.icccm.name, bd->x, bd->y); + + /* determine layering position */ + if (bd->layer <= 0) pos = 0; + else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1; + else if ((bd->layer > 50) && (bd->layer <= 100)) pos = 2; + else if ((bd->layer > 100) && (bd->layer <= 150)) pos = 3; + else if ((bd->layer > 150) && (bd->layer <= 200)) pos = 4; + else pos = 5; + + /* Find the windows below this one */ + for (i = pos; i >= 0; i--) + { + Eina_List *l; + E_Border *b; + + EINA_LIST_REVERSE_FOREACH(bd->zone->container->layers[i].clients, l, b) + { + /* skip if it's not on this zone */ + if (b->zone != bd->zone) continue; + + /* skip if it's the same border */ + if (b == bd) continue; + + /* skip special borders */ + if (e_illume_border_is_indicator(b)) continue; + if (e_illume_border_is_softkey(b)) continue; + if (e_illume_border_is_keyboard(b)) continue; + if (e_illume_border_is_quickpanel(b)) continue; + + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + if (!b->visible) e_border_show(b); + } + else + { + /* need to check x/y position */ + if ((b->x == bd->x) && (b->y == bd->y)) + { + if (!b->visible) e_border_show(b); + } + } + } + } +} + +static void +_policy_zone_layout_update(E_Zone *zone) +{ + Eina_List *l; + E_Border *bd; + + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip special windows */ + /* NB: We trigger a layout update on indicator windows so that + * quickpanel position gets updated so don't include indicators here */ +// if (e_illume_border_is_indicator(bd)) continue; + if (e_illume_border_is_softkey(bd)) continue; + if (e_illume_border_is_keyboard(bd)) continue; + if (e_illume_border_is_quickpanel(bd)) continue; + + /* signal a changed pos here so layout gets updated */ + bd->changes.pos = 1; + bd->changed = 1; + } +} + +static void +_policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz) +{ + /* grab minimum indicator size */ + e_illume_border_min_get(bd, NULL, &cz->indicator.size); + + /* no point in doing anything here if indicator is hidden */ + if (!bd->visible) return; + + /* if we are dragging, then skip it for now */ + if (bd->client.illume.drag.drag) + { + /* when dragging indicator, we need to trigger a layout update */ + _policy_zone_layout_update(bd->zone); + return; + } + +// printf("\tLayout Indicator: %d\n", bd->zone->id); + + /* lock indicator window from dragging if we need to */ + if ((cz->mode.dual == 1) && (cz->mode.side == 0)) + ecore_x_e_illume_drag_locked_set(bd->client.win, 0); + else + ecore_x_e_illume_drag_locked_set(bd->client.win, 1); + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != cz->indicator.size)) + _policy_border_resize(bd, bd->zone->w, cz->indicator.size); + + /* are we in single mode ? */ + if (!cz->mode.dual) + { + /* move to 0, 0 (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y)) + { + _policy_border_move(bd, bd->zone->x, bd->zone->y); + ecore_x_e_illume_quickpanel_position_update_send(bd->client.win); + } + } + else + { + /* dual app mode top */ + if (cz->mode.side == 0) + { + /* top mode...indicator is draggable so just set X */ + if (bd->x != bd->zone->x) + _policy_border_move(bd, bd->zone->x, bd->y); + } + else + { + /* move to 0, 0 (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y)) + { + _policy_border_move(bd, bd->zone->x, bd->zone->y); + ecore_x_e_illume_quickpanel_position_update_send(bd->client.win); + } + } + } + + /* set layer if needed */ + if (bd->layer != POL_INDICATOR_LAYER) + e_border_layer_set(bd, POL_INDICATOR_LAYER); +} + +static void +_policy_zone_layout_quickpanel(E_Border *bd) +{ + int mh; + + /* grab minimum size */ + e_illume_border_min_get(bd, NULL, &mh); + + /* resize if needed */ + if ((bd->w != bd->zone->w) || (bd->h != mh)) + _policy_border_resize(bd, bd->zone->w, mh); + + /* set layer if needed */ + if (bd->layer != POL_QUICKPANEL_LAYER) + e_border_layer_set(bd, POL_QUICKPANEL_LAYER); +} + +static void +_policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int ny; + +// printf("\tLayout Softkey\n"); + + /* grab minimum softkey size */ + e_illume_border_min_get(bd, NULL, &cz->softkey.size); + + /* no point in doing anything here if softkey is hidden */ + if (!bd->visible) return; + + /* if we are dragging, then skip it for now */ + /* NB: Disabled currently until we confirm that softkey should be draggable */ +// if (bd->client.illume.drag.drag) return; + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != cz->softkey.size)) + _policy_border_resize(bd, bd->zone->w, cz->softkey.size); + + /* make sure it's in the correct position */ + ny = ((bd->zone->y + bd->zone->h) - cz->softkey.size); + + /* NB: not sure why yet, but on startup the border->y is reporting + * that it is already in this position...but it's actually not. + * So for now, just disable the ny check until this gets sorted out */ +// if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_SOFTKEY_LAYER) + e_border_layer_set(bd, POL_SOFTKEY_LAYER); +} + +static void +_policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int ny, layer; + +// printf("\tLayout Keyboard\n"); + + /* grab minimum keyboard size */ + e_illume_border_min_get(bd, NULL, &cz->vkbd.size); + + /* no point in adjusting size or position if it's not visible */ + if (!bd->visible) return; + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != cz->vkbd.size)) + _policy_border_resize(bd, bd->zone->w, cz->vkbd.size); + + /* make sure it's in the correct position */ + ny = ((bd->zone->y + bd->zone->h) - cz->vkbd.size); + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* check layer according to fullscreen state */ + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + printf("Keyboard needs fullscreen\n"); + layer = POL_FULLSCREEN_LAYER; + } + else + layer = POL_KEYBOARD_LAYER; + + /* set layer if needed */ + if (bd->layer != layer) + e_border_layer_set(bd, layer); +} + +static void +_policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int ny, nh; + +// printf("\tLayout Home Single: %s\n", bd->client.icccm.class); + + /* no point in adjusting size or position if it's not visible */ + if ((!bd->new_client) && (!bd->visible)) return; + + /* make sure it's the required width & height */ + nh = (bd->zone->h - cz->indicator.size - cz->softkey.size); + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + ny = (bd->zone->y + cz->indicator.size); + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_HOME_LAYER) + e_border_layer_set(bd, POL_HOME_LAYER); +} + +static void +_policy_zone_layout_home_dual_top(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *home; + int ny, nh; + + /* no point in adjusting size or position if it's not visible */ + if ((!bd->new_client) && (!bd->visible)) return; + + /* set some defaults */ + ny = (bd->zone->y + cz->indicator.size); + nh = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2); + + /* see if there are any other home windows */ + home = e_illume_border_home_get(bd->zone); + if (home) + { + if (bd != home) ny = (home->y + nh); + } + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_HOME_LAYER) + e_border_layer_set(bd, POL_HOME_LAYER); +} + +static void +_policy_zone_layout_home_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *home; + int iy, ny, nh; + +// printf("\tLayout Home Dual Custom: %s\n", bd->client.icccm.class); + + /* no point in adjusting size or position if it's not visible */ + if ((!bd->new_client) && (!bd->visible)) return; + + /* grab indicator position */ + e_illume_border_indicator_pos_get(bd->zone, NULL, &iy); + + /* set some defaults */ + ny = bd->zone->y; + nh = iy; + + /* see if there are any other home windows */ + home = e_illume_border_home_get(bd->zone); + if (home) + { + if (bd != home) + { + ny = (iy + cz->indicator.size); + nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size); + } + } + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_HOME_LAYER) + e_border_layer_set(bd, POL_HOME_LAYER); +} + +static void +_policy_zone_layout_home_dual_left(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *home; + int nx, nw, nh; + +// printf("\tLayout Home Dual Left: %s\n", bd->client.icccm.class); + + /* no point in adjusting size or position if it's not visible */ + if ((!bd->new_client) && (!bd->visible)) return; + + nh = (bd->zone->h - cz->indicator.size - cz->softkey.size); + + /* set some defaults */ + nx = bd->zone->x; + nw = (bd->zone->w / 2); + + /* see if there are any other home windows */ + home = e_illume_border_home_get(bd->zone); + if (home) + { + if (bd != home) nx = (home->x + nw); + } + + /* make sure it's the required width & height */ + if ((bd->w != nw) || (bd->h != nh)) + _policy_border_resize(bd, nw, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != nx) || (bd->y != (bd->zone->y + cz->indicator.size))) + _policy_border_move(bd, nx, (bd->zone->y + cz->indicator.size)); + + /* set layer if needed */ + if (bd->layer != POL_HOME_LAYER) + e_border_layer_set(bd, POL_HOME_LAYER); +} + +static void +_policy_zone_layout_fullscreen(E_Border *bd) +{ + int kh, ny, nh; + +// printf("\tLayout Fullscreen: %s\n", bd->client.icccm.name); + + /* grab keyboard safe region */ + e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh); + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != kh)) + _policy_border_resize(bd, bd->zone->w, kh); + + /* set layer if needed */ + if (bd->layer != POL_FULLSCREEN_LAYER) + e_border_layer_set(bd, POL_FULLSCREEN_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *home; + int ky, kh, ny, nh; + +// printf("\tLayout App Single: %s\n", bd->client.icccm.name); + + if ((!bd->new_client) && (!bd->visible)) return; + + /* grab keyboard safe region */ + e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh); + + /* make sure it's the required width & height */ + if (kh >= bd->zone->h) + nh = (kh - cz->indicator.size - cz->softkey.size); + else + nh = (kh - cz->indicator.size); + + /* resize if needed */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + ny = (bd->zone->y + cz->indicator.size); + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_APP_LAYER) + e_border_layer_set(bd, POL_APP_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *b; + int kh, ny, nh; + +// printf("\tLayout App Dual Top: %s\n", bd->client.icccm.name); + + if ((!bd->new_client) && (!bd->visible)) return; + + /* set a default Y position */ + ny = (bd->zone->y + cz->indicator.size); + + if ((bd->focused) && + (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)) + { + /* grab keyboard safe region */ + e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh); + + nh = (kh - cz->indicator.size); + } + else + { + /* make sure it's the required width & height */ + nh = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2); + } + + /* see if there is a border already there. if so, check placement based on + * virtual keyboard usage */ + b = e_illume_border_at_xy_get(bd->zone, bd->zone->x, ny); + if (b) + { + if (b != bd) + { + /* does this border need keyboard ? */ + if ((bd->focused) && + (bd->client.vkbd.state > ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)) + { + int h; + + /* move existing border to bottom if needed */ + h = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2); + if ((b->x != b->zone->x) || (b->y != (ny + h))) + _policy_border_move(b, b->zone->x, (ny + h)); + + /* resize existing border if needed */ + if ((b->w != b->zone->w) || (b->h != h)) + _policy_border_resize(b, b->zone->w, h); + } + else + ny = b->y + nh; + } + } + + /* resize if needed */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_APP_LAYER) + e_border_layer_set(bd, POL_APP_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *app; + int iy, ny, nh; + +// printf("\tLayout App Dual Custom: %s\n", bd->client.icccm.class); + + if ((!bd->new_client) && (!bd->visible)) return; + + /* grab indicator position */ + e_illume_border_indicator_pos_get(bd->zone, NULL, &iy); + + /* set a default position */ + ny = bd->zone->y; + nh = iy; + + app = e_illume_border_at_xy_get(bd->zone, bd->zone->x, bd->zone->y); + if (app) + { + if (bd != app) + { + ny = (iy + cz->indicator.size); + nh = ((bd->zone->y + bd->zone->h) - ny - cz->softkey.size); + } + } + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_APP_LAYER) + e_border_layer_set(bd, POL_APP_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *b; + int ky, kh, nx, nw; + +// printf("\tLayout App Dual Left: %s\n", bd->client.icccm.name); + + if ((!bd->new_client) && (!bd->visible)) return; + + /* grab keyboard safe region */ + e_illume_keyboard_safe_app_region_get(bd->zone, NULL, &ky, NULL, &kh); + + if (kh >= bd->zone->h) + kh = (kh - cz->indicator.size - cz->softkey.size); + else + kh = (kh - cz->indicator.size); + + /* set some defaults */ + nx = bd->zone->x; + nw = (bd->zone->w / 2); + + /* see if there is a border already there. if so, place at right */ + b = e_illume_border_at_xy_get(bd->zone, nx, (ky + cz->indicator.size)); + if (b) + { + if (bd != b) nx = b->x + nw; + } + + /* resize if needed */ + if ((bd->w != nw) || (bd->h != kh)) + _policy_border_resize(bd, nw, kh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != nx) || (bd->y != (ky + cz->indicator.size))) + _policy_border_move(bd, nx, (ky + cz->indicator.size)); + + /* set layer if needed */ + if (bd->layer != POL_APP_LAYER) + e_border_layer_set(bd, POL_APP_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *parent; + int mw, mh, nx, ny; + +// printf("\tLayout Dialog: %s\n", bd->client.icccm.name); + + /* NB: This policy ignores any ICCCM requested positions and centers the + * dialog on it's parent (if it exists) or on the zone */ + + /* grab minimum size */ + e_illume_border_min_get(bd, &mw, &mh); + + /* make sure it fits in this zone */ + if (mw > bd->zone->w) mw = bd->zone->w; + if (mh > bd->zone->h) mh = bd->zone->h; + + /* try to get this dialog's parent if it exists */ + parent = e_illume_border_parent_get(bd); + + /* if we have no parent, or we are in dual mode, then center on zone */ + /* NB: we check dual mode because if we are in dual mode, dialogs tend to + * be too small to be useful when positioned on the parent, so center + * on zone. We could check their size first here tho */ + if ((!parent) || (cz->mode.dual == 1)) + { + /* no parent or dual mode, center on screen */ + nx = (bd->zone->x + ((bd->zone->w - mw) / 2)); + ny = (bd->zone->y + ((bd->zone->h - mh) / 2)); + } + else + { + /* NB: there is an assumption here that the parent has already been + * layed out on screen. This could be bad. Needs Testing */ + + /* make sure we are not larger than the parent window */ + if (mw > parent->w) mw = parent->w; + if (mh > parent->h) mh = parent->h; + + /* center on parent */ + nx = (parent->x + ((parent->w - mw) / 2)); + ny = (parent->y + ((parent->h - mh) / 2)); + } + + /* make sure it's the required width & height */ + if ((bd->w != mw) || (bd->h != mh)) + _policy_border_resize(bd, mw, mh); + + /* make sure it's in the correct position */ + if ((bd->x != nx) || (bd->y != ny)) + _policy_border_move(bd, nx, ny); + + /* set layer if needed */ + if (bd->layer != POL_DIALOG_LAYER) + e_border_layer_set(bd, POL_DIALOG_LAYER); +} + +static void +_policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz) +{ + E_Border *parent; + int mw, mh, nx, ny; + + /* NB: This code is almost exactly the same as the dialog layout code + * (_policy_zone_layout_dialog) except for setting a different layer */ + +// printf("\tLayout Splash: %s\n", bd->client.icccm.name); + + /* NB: This policy ignores any ICCCM requested positions and centers the + * splash screen on it's parent (if it exists) or on the zone */ + + /* grab minimum size */ + e_illume_border_min_get(bd, &mw, &mh); + + /* make sure it fits in this zone */ + if (mw > bd->zone->w) mw = bd->zone->w; + if (mh > bd->zone->h) mh = bd->zone->h; + + /* if we have no parent, or we are in dual mode, then center on zone */ + /* NB: we check dual mode because if we are in dual mode, dialogs tend to + * be too small to be useful when positioned on the parent, + * so center on zone instead */ + if ((!parent) || (cz->mode.dual == 1)) + { + /* no parent or in dual mode, center on screen */ + nx = (bd->zone->x + ((bd->zone->w - mw) / 2)); + ny = (bd->zone->y + ((bd->zone->h - mh) / 2)); + } + else + { + /* NB: there is an assumption here that the parent has already been + * layed out on screen. This could be bad. Needs Testing */ + + /* make sure we are not larger than the parent window */ + if (mw > parent->w) mw = parent->w; + if (mh > parent->h) mh = parent->h; + + /* center on parent */ + nx = (parent->x + ((parent->w - mw) / 2)); + ny = (parent->y + ((parent->h - mh) / 2)); + } + + /* make sure it's the required width & height */ + if ((bd->w != mw) || (bd->h != mh)) + _policy_border_resize(bd, mw, mh); + + /* make sure it's in the correct position */ + if ((bd->x != nx) || (bd->y != ny)) + _policy_border_move(bd, nx, ny); + + /* set layer if needed */ + if (bd->layer != POL_SPLASH_LAYER) + e_border_layer_set(bd, POL_SPLASH_LAYER); +} + +static void +_policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz) +{ + if ((!bd->new_client) && (!bd->visible)) return; + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != bd->zone->h)) + _policy_border_resize(bd, bd->zone->w, bd->zone->h); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != bd->zone->y)) + _policy_border_move(bd, bd->zone->x, bd->zone->y); + + /* set layer if needed */ + if (bd->layer != POL_CONFORMANT_LAYER) + e_border_layer_set(bd, POL_CONFORMANT_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int nh, ny; + + /* according to the docs I have, conformant windows are always on the + * bottom in dual-top mode */ + + if ((!bd->new_client) && (!bd->visible)) return; + + /* set some defaults */ + nh = ((bd->zone->h - cz->indicator.size - cz->softkey.size) / 2); + ny = (bd->zone->y + cz->indicator.size) + nh; + nh += cz->softkey.size; + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != ny)) + _policy_border_move(bd, bd->zone->x, ny); + + /* set layer if needed */ + if (bd->layer != POL_CONFORMANT_LAYER) + e_border_layer_set(bd, POL_CONFORMANT_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int iy, nh; + +// printf("\tLayout Conformant Dual Custom: %s\n", bd->client.icccm.class); + + if ((!bd->new_client) && (!bd->visible)) return; + + /* grab indicator position */ + e_illume_border_indicator_pos_get(bd->zone, NULL, &iy); + + /* set some defaults */ + nh = ((bd->zone->y + bd->zone->h) - iy); + + /* make sure it's the required width & height */ + if ((bd->w != bd->zone->w) || (bd->h != nh)) + _policy_border_resize(bd, bd->zone->w, nh); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != bd->zone->x) || (bd->y != iy)) + _policy_border_move(bd, bd->zone->x, iy); + + /* set layer if needed */ + if (bd->layer != POL_CONFORMANT_LAYER) + e_border_layer_set(bd, POL_CONFORMANT_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + +static void +_policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz) +{ + int nw, nx; + + /* according to the docs I have, conformant windows are always on the + * left in dual-left mode */ + + if ((!bd->new_client) && (!bd->visible)) return; + + /* set some defaults */ + nw = (bd->zone->w / 2); + nx = (bd->zone->x); + + /* make sure it's the required width & height */ + if ((bd->w != nw) || (bd->h != bd->zone->h)) + _policy_border_resize(bd, nw, bd->zone->h); + + /* move to correct position (relative to zone) if needed */ + if ((bd->x != nx) || (bd->y != bd->zone->y)) + _policy_border_move(bd, nx, bd->zone->y); + + /* set layer if needed */ + if (bd->layer != POL_CONFORMANT_LAYER) + e_border_layer_set(bd, POL_CONFORMANT_LAYER); + + /* hide any apps/windows below this one */ + _policy_border_hide_below(bd); +} + + +/* policy functions */ +void +_policy_border_add(E_Border *bd) +{ +// printf("Border added: %s\n", bd->client.icccm.class); + + /* NB: this call sets an atom on the window that specifices the zone. + * the logic here is that any new windows created can access the zone + * window by a 'get' call. This is useful for elementary apps as they + * normally would not have access to the zone window. Typical use case + * is for indicator & softkey windows so that they can send messages + * that apply to their respective zone only. Example: softkey sends close + * messages (or back messages to cycle focus) that should pertain just + * to it's current zone */ + ecore_x_e_illume_zone_set(bd->client.win, bd->zone->black_win); + + /* ignore stolen borders. These are typically quickpanel or keyboards */ + if (bd->stolen) return; + + /* if this is a fullscreen window, than we need to hide indicator window */ + /* NB: we could use the e_illume_border_is_fullscreen function here + * but we save ourselves a function call this way */ + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + E_Border *ind; + + /* try to get the Indicator on this zone */ + if (ind = e_illume_border_indicator_get(bd->zone)) + { + /* we have the indicator, hide it if needed */ + if (ind->visible) e_border_hide(ind, 2); + } + } + + /* set focus on new border if we can */ + _policy_border_set_focus(bd); +} + +void +_policy_border_del(E_Border *bd) +{ +// printf("Border deleted: %s\n", bd->client.icccm.class); + + /* if this is a fullscreen window, than we need to show indicator window */ + /* NB: we could use the e_illume_border_is_fullscreen function here + * but we save ourselves a function call this way */ + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + E_Border *ind; + + /* try to get the Indicator on this zone */ + if (ind = e_illume_border_indicator_get(bd->zone)) + { + /* we have the indicator, show it if needed */ + if (!ind->visible) e_border_show(ind); + } + } + + /* show borders below this one */ + _policy_border_show_below(bd); +} + +void +_policy_border_focus_in(E_Border *bd) +{ +// printf("Border focus in: %s\n", bd->client.icccm.name); +} + +void +_policy_border_focus_out(E_Border *bd) +{ +// printf("Border focus out: %s\n", bd->client.icccm.name); + + /* NB: if we got this focus_out event on a deleted border, we check if + * it is a transient (child) of another window. If it is, then we + * transfer focus back to the parent window */ + if (e_object_is_del(E_OBJECT(bd))) + { + if (e_illume_border_is_dialog(bd)) + { + E_Border *parent; + + parent = e_illume_border_parent_get(bd); + if (parent) _policy_border_set_focus(parent); + } + } +} + +void +_policy_border_activate(E_Border *bd) +{ + E_Border *sft; + +// printf("Border Activate: %s\n", bd->client.icccm.name); + + /* NB: stolen borders may or may not need focus call...have to test */ +// if (bd->stolen) return; + + /* conformant windows hide the softkey */ + sft = e_illume_border_softkey_get(bd->zone); + if (sft) + { + if (e_illume_border_is_conformant(bd)) + { + if (sft->visible) e_border_hide(sft, 2); + } + else + { + if (!sft->visible) e_border_show(sft); + } + } + + /* set focus on new border is we can */ + _policy_border_set_focus(bd); +} + +void +_policy_border_post_fetch(E_Border *bd) +{ +// printf("Border post fetch\n"); + + /* NB: for this policy we disable all remembers set on a border */ + if (bd->remember) e_remember_del(bd->remember); + bd->remember = NULL; + + /* set this border to borderless */ +#ifdef DIALOG_USES_PIXEL_BORDER + if ((e_illume_border_is_dialog(bd)) && + (e_illume_border_parent_get(bd))) + eina_stringshare_replace(&bd->bordername, "pixel"); + else + bd->borderless = 1; +#else + bd->borderless = 1; +#endif + + /* tell E the border has changed */ + bd->client.border.changed = 1; +} + +void +_policy_border_post_assign(E_Border *bd) +{ +// printf("Border post assign\n"); + + bd->internal_no_remember = 1; + + /* do not allow client to change these properties */ + bd->lock_client_size = 1; + bd->lock_client_shade = 1; + bd->lock_client_maximize = 1; + bd->lock_client_location = 1; + bd->lock_client_stacking = 1; + + /* do not allow the user to change these properties */ + bd->lock_user_location = 1; + bd->lock_user_size = 1; + bd->lock_user_shade = 1; + + /* clear any centered states */ + /* NB: this is mainly needed for E's main config dialog */ + bd->client.e.state.centered = 0; + + /* lock the border type so user/client cannot change */ + bd->lock_border = 1; +} + +void +_policy_zone_layout(E_Zone *zone) +{ + E_Illume_Config_Zone *cz; + Eina_List *l; + E_Border *bd; + +// printf("Zone Layout: %d\n", zone->id); + + /* get the config for this zone */ + cz = e_illume_zone_config_get(zone->id); + + /* loop through border list and update layout */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + /* skip borders not on this zone */ + if (bd->zone != zone) continue; + + /* skip borders that are being deleted */ + if (e_object_is_del(E_OBJECT(bd))) continue; + + /* only update layout for this border if it really needs it */ + if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) && + (!bd->changes.visible) && (!bd->pending_move_resize)) continue; + + /* are we laying out an indicator ? */ + if (e_illume_border_is_indicator(bd)) + _policy_zone_layout_indicator(bd, cz); + + /* are we layout out a quickpanel ? */ + else if (e_illume_border_is_quickpanel(bd)) + _policy_zone_layout_quickpanel(bd); + + /* are we laying out a softkey ? */ + else if (e_illume_border_is_softkey(bd)) + _policy_zone_layout_softkey(bd, cz); + + /* are we laying out a keyboard ? */ + else if (e_illume_border_is_keyboard(bd)) + _policy_zone_layout_keyboard(bd, cz); + + /* are we layout out a home window ? */ + else if (e_illume_border_is_home(bd)) + { + if (!cz->mode.dual) + _policy_zone_layout_home_single(bd, cz); + else + { + /* we are in dual-mode, check orientation */ + if (cz->mode.side == 0) + { + int ty; + + e_illume_border_indicator_pos_get(bd->zone, NULL, &ty); + if (ty <= bd->zone->y) + _policy_zone_layout_home_dual_top(bd, cz); + else + _policy_zone_layout_home_dual_custom(bd, cz); + } + else + _policy_zone_layout_home_dual_left(bd, cz); + } + } + + /* are we laying out a fullscreen window ? */ + /* NB: we could use the e_illume_border_is_fullscreen function here + * but we save ourselves a function call this way. */ + else if ((bd->fullscreen) || (bd->need_fullscreen)) + _policy_zone_layout_fullscreen(bd); + + /* are we laying out a splash screen ? */ + /* NB: we check splash before dialog so if a splash screen does not + * register as a splash, than the dialog trap should catch it */ + else if (e_illume_border_is_splash(bd)) + _policy_zone_layout_splash(bd, cz); + + /* are we laying out a dialog ? */ + else if (e_illume_border_is_dialog(bd)) + _policy_zone_layout_dialog(bd, cz); + + /* are we layout out a conformant window ? */ + else if (e_illume_border_is_conformant(bd)) + { + if (!cz->mode.dual) + _policy_zone_layout_conformant_single(bd, cz); + else + { + /* we are in dual-mode, check orientation */ + if (cz->mode.side == 0) + { + int ty; + + e_illume_border_indicator_pos_get(bd->zone, NULL, &ty); + if (ty <= bd->zone->y) + _policy_zone_layout_conformant_dual_top(bd, cz); + else + _policy_zone_layout_conformant_dual_custom(bd, cz); + } + else + _policy_zone_layout_conformant_dual_left(bd, cz); + } + } + + /* must be an app */ + else + { + /* are we in single mode ? */ + if (!cz->mode.dual) + _policy_zone_layout_app_single(bd, cz); + else + { + /* we are in dual-mode, check orientation */ + if (cz->mode.side == 0) + { + int ty; + + /* grab the indicator position so we can tell if it + * is in a custom position or not (user dragged it) */ + e_illume_border_indicator_pos_get(bd->zone, NULL, &ty); + if (ty <= bd->zone->y) + _policy_zone_layout_app_dual_top(bd, cz); + else + _policy_zone_layout_app_dual_custom(bd, cz); + } + else + _policy_zone_layout_app_dual_left(bd, cz); + } + } + + } +} + +void +_policy_zone_move_resize(E_Zone *zone) +{ + printf("Zone move resize\n"); + + /* zone size or position changed, tell layout to update */ + _policy_zone_layout(zone); +} + +void +_policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode) +{ + E_Illume_Config_Zone *cz; + E_Border *bd; + int count; + +// printf("Zone mode change\n"); + + /* get the config for this zone */ + cz = e_illume_zone_config_get(zone->id); + + /* update config with new mode */ + if (mode == ECORE_X_ATOM_E_ILLUME_MODE_SINGLE) + cz->mode.dual = 0; + else + { + cz->mode.dual = 1; + if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_TOP) + cz->mode.side = 0; + else if (mode == ECORE_X_ATOM_E_ILLUME_MODE_DUAL_LEFT) + cz->mode.side = 1; + } + e_config_save_queue(); + + /* lock indicator window from dragging if we need to */ + bd = e_illume_border_indicator_get(zone); + if (bd) + { + /* only dual-top mode can drag */ + if ((cz->mode.dual == 1) && (cz->mode.side == 0)) + { + /* only set locked if we need to */ + if (bd->client.illume.drag.locked != 0) + ecore_x_e_illume_drag_locked_set(bd->client.win, 0); + } + else + { + /* only set locked if we need to */ + if (bd->client.illume.drag.locked != 1) + ecore_x_e_illume_drag_locked_set(bd->client.win, 1); + } + } + + count = eina_list_count(e_illume_border_home_borders_get(zone)); + + /* create a new home window (if needed) for dual mode */ + if (cz->mode.dual == 1) + { + if (count < 2) + ecore_x_e_illume_home_new_send(zone->black_win); + } + else if (cz->mode.dual == 0) + { + /* if we went to single mode, delete any extra home windows */ + if (count >= 2) + { + E_Border *home; + + /* try to get a home window on this zone and remove it */ + if (home = e_illume_border_home_get(zone)) + ecore_x_e_illume_home_del_send(home->client.win); + } + } + + /* Need to trigger a layout update here */ + _policy_zone_layout_update(zone); +} + +void +_policy_zone_close(E_Zone *zone) +{ + E_Border *bd; + +// printf("Zone close\n"); + + /* make sure we have a focused border */ + if (!(bd = e_border_focused_get())) return; + + /* make sure focused border is on this zone */ + if (bd->zone != zone) return; + + /* close this border */ + e_border_act_close_begin(bd); + + /* revert focus to previous border (if possible) */ + _policy_focus_back(zone); +} + +void +_policy_drag_start(E_Border *bd) +{ +// printf("Drag start\n"); + + /* ignore stolen borders */ + if (bd->stolen) return; + + /* set property on this border to say we are dragging */ + ecore_x_e_illume_drag_set(bd->client.win, 1); + + /* set property on zone window that a drag is happening */ + ecore_x_e_illume_drag_set(bd->zone->black_win, 1); +} + +void +_policy_drag_end(E_Border *bd) +{ +// printf("Drag end\n"); + + /* ignore stolen borders */ + if (bd->stolen) return; + + /* set property on this border to say we are done dragging */ + ecore_x_e_illume_drag_set(bd->client.win, 0); + + /* set property on zone window that a drag is finished */ + ecore_x_e_illume_drag_set(bd->zone->black_win, 0); +} + +void +_policy_focus_back(E_Zone *zone) +{ + Eina_List *l, *fl = NULL; + E_Border *bd; + +// printf("Focus back\n"); + + /* loop the focus stack and check for borders on this zone */ + EINA_LIST_FOREACH(e_border_focus_stack_get(), l, bd) + { + /* not on this zone, skip */ + if (bd->zone != zone) continue; + + /* on this zone but being deleted, skip it */ + if (e_object_is_del(E_OBJECT(bd))) continue; + + /* doesn't accept or take focus, skip it */ + if ((!bd->client.icccm.accepts_focus) && + (!bd->client.icccm.take_focus)) continue; + + /* doesn't show in taskbar, skip it */ + if (bd->client.netwm.state.skip_taskbar) continue; + + /* add it to our list */ + fl = eina_list_append(fl, bd); + } + + /* if there are none on this zone then get out */ + if (!fl) return; + + /* if there is only one border then focus it and get out */ + if (eina_list_count(fl) < 2) + { + E_Border *fbd; + + if (fbd = fl->data) _policy_border_set_focus(fbd); + + /* cleanup our list variable */ + fl = eina_list_free(fl); + + return; + } + + /* loop focused borders on this zone */ + /* NB: This is done in reverse order so we get the most recently focused + * border first....saves time and iterations */ + EINA_LIST_REVERSE_FOREACH(fl, l, bd) + { + /* is this the currently focused border ? */ + if (bd == e_border_focused_get()) + { + E_Border *fbd; + + /* see if we have another border previous to this one */ + if (!(fbd = fl->next->data)) continue; + + /* focus the previous border */ + _policy_border_set_focus(fbd); + + /* we're done, get out */ + break; + } + } + + /* cleanup our list variable */ + fl = eina_list_free(fl); +} + +void +_policy_focus_forward(E_Zone *zone) +{ + printf("Focus forward\n"); +} + +void +_policy_focus_home(E_Zone *zone) +{ + E_Border *bd; + +// printf("Focus home\n"); + if (!(bd = e_illume_border_home_get(zone))) return; + + if (!bd->visible) e_border_show(bd); + + /* no point in calling set_focus here as home windows do not accept it + * anyway, so just raise */ + e_border_raise(bd); +} + +void +_policy_property_change(Ecore_X_Event_Window_Property *event) +{ +// printf("Property Change\n"); + + /* we are interested in state changes here */ + if (event->atom == ECORE_X_ATOM_NET_WM_STATE) + { + E_Border *bd, *ind; + + if (!(bd = e_border_find_by_client_window(event->win))) return; + + /* not interested in stolen or invisible borders */ + if ((bd->stolen) || (!bd->visible)) return; + + /* make sure the border has a name or class */ + /* NB: this check is here because some E borders get State Changes + * but do not have a name/class associated with them. Not entirely sure + * which ones they are, but I would guess Managers, Containers, or Zones. + * At any rate, we're not interested in those types of borders */ + if ((!bd->client.icccm.name) || (!bd->client.icccm.class)) return; + + /* NB: If we have reached this point, then it should be a fullscreen + * border that has toggled fullscreen on/off */ + + /* try to get the Indicator on this zone */ + if (!(ind = e_illume_border_indicator_get(bd->zone))) return; + + /* if we are fullscreen, hide the indicator...else we show it */ + /* NB: we could use the e_illume_border_is_fullscreen function here + * but we save ourselves a function call this way */ + if ((bd->fullscreen) || (bd->need_fullscreen)) + { + if (ind->visible) e_border_hide(ind, 2); + } + else + { + if (!ind->visible) e_border_show(ind); + } + } + else if (event->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY) + { + Eina_List *l; + E_Zone *zone; + E_Border *bd; + int x, y, w, h; + + /* make sure this property changed on a zone */ + if (!(zone = e_util_zone_window_find(event->win))) return; + + /* get the geometry. This is X round-trip :( */ + ecore_x_e_illume_indicator_geometry_get(zone->black_win, &x, &y, &w, &h); + + /* look for conformant borders */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + if (bd->zone != zone) continue; + if (!e_illume_border_is_conformant(bd)) continue; + /* set indicator geometry on conformant window */ + /* NB: This is needed so that conformant apps get told about + * the indicator size/position...else they have no way of + * knowing that the geometry has been updated */ + ecore_x_e_illume_indicator_geometry_set(bd->client.win, x, y, w, h); + } + } + else if (event->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY) + { + Eina_List *l; + E_Zone *zone; + E_Border *bd; + int x, y, w, h; + + /* make sure this property changed on a zone */ + if (!(zone = e_util_zone_window_find(event->win))) return; + + /* get the geometry. This is X round-trip :( */ + ecore_x_e_illume_softkey_geometry_get(zone->black_win, &x, &y, &w, &h); + + /* look for conformant borders */ + EINA_LIST_FOREACH(e_border_client_list(), l, bd) + { + if (bd->zone != zone) continue; + if (!e_illume_border_is_conformant(bd)) continue; + /* set softkey geometry on conformant window */ + /* NB: This is needed so that conformant apps get told about + * the softkey size/position...else they have no way of + * knowing that the geometry has been updated */ + ecore_x_e_illume_softkey_geometry_set(bd->client.win, x, y, w, h); + } + } + else if (!(strcmp(ecore_x_atom_name_get(event->atom), "ENLIGHTENMENT_SCALE"))) + { + Eina_List *ml; + E_Manager *man; + + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + Eina_List *cl; + E_Container *con; + + if (event->win != man->root) continue; + EINA_LIST_FOREACH(man->containers, cl, con) + { + Eina_List *zl; + E_Zone *zone; + + EINA_LIST_FOREACH(con->zones, zl, zone) + _policy_zone_layout_update(zone); + } + } + } +} diff --git a/src/modules/illume2/policies/illume/policy.h b/src/modules/illume2/policies/illume/policy.h new file mode 100644 index 000000000..8675bd660 --- /dev/null +++ b/src/modules/illume2/policies/illume/policy.h @@ -0,0 +1,34 @@ +#ifndef _POLICY_H +# define _POLICY_H + +/* define layer values here so we don't have to grep through code to change */ +# define POL_INDICATOR_LAYER 200 +# define POL_QUICKPANEL_LAYER 160 +# define POL_KEYBOARD_LAYER 150 +# define POL_FULLSCREEN_LAYER 140 +# define POL_DIALOG_LAYER 120 +# define POL_SPLASH_LAYER 120 +# define POL_SOFTKEY_LAYER 110 +# define POL_CONFORMANT_LAYER 100 +# define POL_APP_LAYER 100 +# define POL_HOME_LAYER 90 + +void _policy_border_add(E_Border *bd); +void _policy_border_del(E_Border *bd); +void _policy_border_focus_in(E_Border *bd); +void _policy_border_focus_out(E_Border *bd); +void _policy_border_activate(E_Border *bd); +void _policy_border_post_fetch(E_Border *bd); +void _policy_border_post_assign(E_Border *bd); +void _policy_zone_layout(E_Zone *zone); +void _policy_zone_move_resize(E_Zone *zone); +void _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode); +void _policy_zone_close(E_Zone *zone); +void _policy_drag_start(E_Border *bd); +void _policy_drag_end(E_Border *bd); +void _policy_focus_back(E_Zone *zone); +void _policy_focus_forward(E_Zone *zone); +void _policy_focus_home(E_Zone *zone); +void _policy_property_change(Ecore_X_Event_Window_Property *event); + +#endif