added mobile policy module

Summary: mobile policy module provides user interface for small mobile devices like phones.

Test Plan: N/A

Reviewers: raster, devilhorns, zmike

Subscribers: seoz, zmike, cedric

Differential Revision: https://phab.enlightenment.org/D817
This commit is contained in:
Gwanglim Lee 2014-08-29 13:48:01 -04:00 committed by Mike Blumenkrantz
parent e3f4f0f976
commit 00690dab17
9 changed files with 1337 additions and 0 deletions

View File

@ -971,6 +971,7 @@ AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, $wl_x11)
AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
#AC_E_OPTIONAL_MODULE([wl_screenshot], true, [CHECK_MODULE_WL_SCREENSHOT])
AC_E_OPTIONAL_MODULE([policy_mobile], true)
HALT="/sbin/shutdown -h now"
REBOOT="/sbin/shutdown -r now"

View File

@ -938,6 +938,7 @@ _e_module_whitelist_check(void)
"music-control",
"appmenu",
"packagekit",
"policy_mobile",
NULL // end marker
};

View File

@ -130,3 +130,5 @@ include src/modules/Makefile_wl_fb.mk
#if HAVE_WAYLAND_SCREENSHOT
#include src/modules/Makefile_wl_screenshot.mk
include src/modules/Makefile_policy_mobile.mk

View File

@ -0,0 +1,21 @@
EXTRA_DIST += src/modules/policy_mobile/e-module-policy-mobile.edj
if USE_MODULE_POLICY_MOBILE
policy_mobiledir = $(MDIR)/policy_mobile
policy_mobile_DATA = src/modules/policy_mobile/e-module-policy-mobile.edj
policy_mobilepkgdir = $(MDIR)/policy_mobile/$(MODULE_ARCH)
policy_mobilepkg_LTLIBRARIES = src/modules/policy_mobile/module.la
src_modules_policy_mobile_module_la_LIBADD = $(MOD_LIBS)
src_modules_policy_mobile_module_la_CPPFLAGS = $(MOD_CPPFLAGS)
src_modules_policy_mobile_module_la_LDFLAGS = $(MOD_LDFLAGS)
src_modules_policy_mobile_module_la_SOURCES = \
src/modules/policy_mobile/e_mod_main.h \
src/modules/policy_mobile/e_mod_config.c \
src/modules/policy_mobile/e_mod_softkey.c \
src/modules/policy_mobile/e_mod_main.c
PHONIES += policy_mobile install-policy_mobile
policy_mobile: $(policy_mobilepkg_LTLIBRARIES) $(policy_mobile_DATA)
install-policy_mobile: install-policy_mobileDATA install-policy_mobilepkgLTLIBRARIES
endif

Binary file not shown.

View File

@ -0,0 +1,387 @@
#include "e_mod_main.h"
static void _pol_conf_desk_add(Config *conf, E_Desk *desk);
static void _pol_conf_desk_del(Config *conf, Config_Desk *d);
static Config_Desk *_pol_conf_desk_get(Config *conf, Config_Desk *d);
static void *_pol_cfd_data_create(E_Config_Dialog *cfd);
static void _pol_cfd_data_free(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata);
static int _pol_cfd_data_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata);
static void _pol_cfd_desk_list_update(E_Config_Dialog_Data *cfdata, E_Zone *zone);
static void _pol_cfd_hook_zone_change(void *data, Evas_Object *obj);
static Evas_Object *_pol_cfd_data_basic_widgets_create(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata);
static void
_pol_conf_desk_add(Config *conf, E_Desk *desk)
{
Config_Desk *d;
d = E_NEW(Config_Desk, 1);
d->comp_num = desk->zone->comp->num;
d->zone_num = desk->zone->num;
d->x = desk->x;
d->y = desk->y;
d->enable = 1;
conf->desks = eina_list_append(conf->desks, d);
}
static void
_pol_conf_desk_del(Config *conf, Config_Desk *d)
{
conf->desks = eina_list_remove(conf->desks, d);
free(d);
}
static Config_Desk *
_pol_conf_desk_get(Config *conf, Config_Desk *d)
{
Eina_List *l;
Config_Desk *d2;
EINA_LIST_FOREACH(conf->desks, l, d2)
{
if ((d2->comp_num == d->comp_num) &&
(d2->zone_num == d->zone_num) &&
(d2->x == d->x) && (d2->y == d->y))
{
return d2;
}
}
return NULL;
}
static void *
_pol_cfd_data_create(E_Config_Dialog *cfd)
{
E_Config_Dialog_Data *cfdata = NULL;
cfdata = E_NEW(E_Config_Dialog_Data, 1);
cfdata->conf = E_NEW(Config, 1);
cfdata->conf->launcher.title = eina_stringshare_ref(_pol_mod->conf->launcher.title);
cfdata->conf->launcher.clas = eina_stringshare_ref(_pol_mod->conf->launcher.clas);
cfdata->conf->launcher.type = _pol_mod->conf->launcher.type;
cfdata->conf->use_softkey = _pol_mod->conf->use_softkey;
cfdata->conf->softkey_size = _pol_mod->conf->softkey_size;
_pol_mod->conf_dialog = cfd;
return cfdata;
}
static void
_pol_cfd_data_free(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
_pol_mod->conf_dialog = NULL;
E_FREE_LIST(cfdata->conf->desks, free);
eina_stringshare_del(cfdata->conf->launcher.title);
eina_stringshare_del(cfdata->conf->launcher.clas);
free(cfdata->conf);
free(cfdata);
}
static int
_pol_cfd_data_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
E_Comp *comp;
E_Zone *zone;
E_Desk *desk;
Pol_Softkey *softkey;
Pol_Desk *pd;
Config_Desk *d, *d2;
Eina_Bool changed = EINA_FALSE;
const Eina_List *l;
Eina_Inlist *il;
Eina_Iterator *it;
if (_pol_mod->conf->use_softkey != cfdata->conf->use_softkey)
{
_pol_mod->conf->use_softkey = cfdata->conf->use_softkey;
if (_pol_mod->conf->use_softkey)
{
it = eina_hash_iterator_data_new(hash_pol_desks);
while (eina_iterator_next(it, (void **)&pd))
{
softkey = e_mod_pol_softkey_get(pd->zone);
if (!softkey)
softkey = e_mod_pol_softkey_add(pd->zone);
if (e_desk_current_get(pd->zone) == pd->desk)
e_mod_pol_softkey_show(softkey);
}
eina_iterator_free(it);
}
else
{
EINA_INLIST_FOREACH_SAFE(_pol_mod->softkeys, il, softkey)
e_mod_pol_softkey_del(softkey);
}
changed = EINA_TRUE;
}
if (_pol_mod->conf->softkey_size != cfdata->conf->softkey_size)
{
_pol_mod->conf->softkey_size = cfdata->conf->softkey_size;
if (_pol_mod->conf->use_softkey)
{
EINA_INLIST_FOREACH(_pol_mod->softkeys, softkey)
e_mod_pol_softkey_update(softkey);
}
changed = EINA_TRUE;
}
EINA_LIST_FOREACH(cfdata->conf->desks, l, d)
{
comp = e_comp_number_get(d->comp_num);
zone = e_comp_zone_number_get(comp, d->zone_num);
desk = e_desk_at_xy_get(zone, d->x, d->y);
if (!desk) continue;
d2 = _pol_conf_desk_get(_pol_mod->conf, d);
if (d2)
{
/* disable policy for this desktop */
if (d2->enable != d->enable)
{
pd = eina_hash_find(hash_pol_desks, &desk);
if (pd) e_mod_pol_desk_del(pd);
_pol_conf_desk_del(_pol_mod->conf, d2);
changed = EINA_TRUE;
}
}
else
{
/* apply policy for all clients in this desk,
* and add desk to configuration list and desk hash */
if (d->enable)
{
e_mod_pol_desk_add(desk);
_pol_conf_desk_add(_pol_mod->conf, desk);
changed = EINA_TRUE;
}
}
}
if (changed)
e_config_save_queue();
return 1;
}
static void
_pol_cfd_desk_list_update(E_Config_Dialog_Data *cfdata, E_Zone *zone)
{
Evas_Object *o, *ch;
Evas *evas;
E_Desk *desk;
Config_Desk *d, *d2;
int i, n;
evas = evas_object_evas_get(cfdata->o_list);
evas_object_del(cfdata->o_desks);
E_FREE_LIST(cfdata->conf->desks, free);
o = e_widget_list_add(evas, 1, 0);
cfdata->o_desks = o;
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
desk = zone->desks[i];
d = E_NEW(Config_Desk, 1);
d->comp_num = zone->comp->num;
d->zone_num = zone->num;
d->x = desk->x;
d->y = desk->y;
d->enable = 0;
d2 = _pol_conf_desk_get(_pol_mod->conf, d);
if (d2)
d->enable = d2->enable;
ch = e_widget_check_add(evas, desk->name, &d->enable);
e_widget_list_object_append(o, ch, 1, 1, 0.5);
cfdata->conf->desks = eina_list_append(cfdata->conf->desks, d);
}
e_widget_list_object_append(cfdata->o_list, o, 1, 1, 0.5);
}
static void
_pol_cfd_hook_zone_change(void *data, Evas_Object *obj)
{
E_Config_Dialog_Data *cfdata;
E_Zone *zone;
int n;
cfdata = data;
n = e_widget_ilist_selected_get(obj);
zone = e_widget_ilist_nth_data_get(obj, n);
if (zone)
_pol_cfd_desk_list_update(cfdata, zone);
}
static Evas_Object *
_pol_cfd_data_basic_widgets_create(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata)
{
Evas_Object *base, *fl, *lb, *lo, *o;
E_Comp *comp;
E_Zone *zone;
Eina_List *l;
comp = e_comp_get(NULL);
base = e_widget_list_add(evas, 0, 0);
fl = e_widget_framelist_add(evas, _("Softkey"), 0);
o = e_widget_check_add(evas, _("Use softkey for navigation among the windows"),
&cfdata->conf->use_softkey);
e_widget_framelist_object_append(fl, o);
o = e_widget_label_add(evas, _("Icon Size"));
e_widget_framelist_object_append(fl, o);
o = e_widget_slider_add(evas, 1, 0, "%1.0f", 32, 256, 1, 0, NULL,
&(cfdata->conf->softkey_size), 150);
e_widget_framelist_object_append(fl, o);
e_widget_list_object_append(base, fl, 1, 1, 0.5);
fl = e_widget_framelist_add(evas, _("Virtual Desktops"), 0);
lb = e_widget_label_add(evas, _("Enable mobile policy per desktop"));
e_widget_framelist_object_append(fl, lb);
lo = e_widget_list_add(evas, 0, 1);
cfdata->o_list = lo;
o = e_widget_ilist_add(evas, 0, 0, NULL);
e_widget_ilist_multi_select_set(o, EINA_FALSE);
e_widget_size_min_set(o, 100, 100);
e_widget_on_change_hook_set(o, _pol_cfd_hook_zone_change, cfdata);
EINA_LIST_REVERSE_FOREACH(comp->zones, l, zone)
e_widget_ilist_append(o, NULL, zone->name, NULL, zone, NULL);
e_widget_ilist_go(o);
e_widget_ilist_selected_set(o, 0);
e_widget_list_object_append(lo, o, 1, 1, 0.5);
/* update virtual desktops of first zone */
zone = eina_list_data_get(comp->zones);
_pol_cfd_desk_list_update(cfdata, zone);
e_widget_framelist_object_append(fl, lo);
e_widget_list_object_append(base, fl, 1, 1, 0.5);
return base;
}
void
e_mod_pol_conf_init(Mod *mod)
{
E_Comp *comp;
E_Zone *zone;
E_Desk *desk;
Config *conf;
mod->conf_desk_edd = E_CONFIG_DD_NEW("Policy_Mobile_Config_Desk", Config_Desk);
#undef T
#undef D
#define T Config_Desk
#define D mod->conf_desk_edd
E_CONFIG_VAL(D, T, comp_num, INT);
E_CONFIG_VAL(D, T, zone_num, UINT);
E_CONFIG_VAL(D, T, x, INT);
E_CONFIG_VAL(D, T, y, INT);
E_CONFIG_VAL(D, T, enable, INT);
mod->conf_edd = E_CONFIG_DD_NEW("Policy_Mobile_Config", Config);
#undef T
#undef D
#define T Config
#define D mod->conf_edd
E_CONFIG_VAL(D, T, launcher.title, STR);
E_CONFIG_VAL(D, T, launcher.clas, STR);
E_CONFIG_VAL(D, T, launcher.type, UINT);
E_CONFIG_LIST(D, T, desks, mod->conf_desk_edd);
E_CONFIG_VAL(D, T, use_softkey, INT);
E_CONFIG_VAL(D, T, softkey_size, INT);
#undef T
#undef D
mod->conf = e_config_domain_load("module.policy-mobile", mod->conf_edd);
if (!mod->conf)
{
conf = E_NEW(Config, 1);
mod->conf = conf;
conf->launcher.title = eina_stringshare_add("Illume Home");
conf->launcher.clas = eina_stringshare_add("Illume-Home");
conf->launcher.type = E_WINDOW_TYPE_NORMAL;
conf->use_softkey = 1;
conf->softkey_size = 42;
comp = e_comp_get(NULL);
zone = e_zone_current_get(comp);
desk = e_desk_current_get(zone);
_pol_conf_desk_add(conf, desk);
}
}
void
e_mod_pol_conf_shutdown(Mod *mod)
{
Config *conf;
if (mod->conf)
{
conf = mod->conf;
E_FREE_LIST(conf->desks, free);
eina_stringshare_del(conf->launcher.title);
eina_stringshare_del(conf->launcher.clas);
free(mod->conf);
}
E_CONFIG_DD_FREE(mod->conf_desk_edd);
E_CONFIG_DD_FREE(mod->conf_edd);
}
Config_Desk *
e_mod_pol_conf_desk_get_by_nums(Config *conf, unsigned int comp_num, unsigned int zone_num, int x, int y)
{
Eina_List *l;
Config_Desk *d2;
EINA_LIST_FOREACH(conf->desks, l, d2)
{
if ((d2->comp_num == comp_num) &&
(d2->zone_num == zone_num) &&
(d2->x == x) && (d2->y == y))
{
return d2;
}
}
return NULL;
}
E_Config_Dialog *
e_int_config_pol_mobile(E_Comp *comp, const char *params EINA_UNUSED)
{
E_Config_Dialog *cfd;
E_Config_Dialog_View *v;
char buf[PATH_MAX];
if (e_config_dialog_find("E", "windows/policy-mobile"))
return NULL;
v = E_NEW(E_Config_Dialog_View, 1);
v->create_cfdata = _pol_cfd_data_create;
v->free_cfdata = _pol_cfd_data_free;
v->basic.apply_cfdata = _pol_cfd_data_basic_apply;
v->basic.create_widgets = _pol_cfd_data_basic_widgets_create;
snprintf(buf, sizeof(buf), "%s/e-module-policy-mobile.edj",
e_module_dir_get(_pol_mod->module));
cfd = e_config_dialog_new(comp, _("Mobile Policy Configuration"), "E",
"windows/policy-mobile", buf, 0, v, NULL);
return cfd;
}

View File

@ -0,0 +1,646 @@
#include "e_mod_main.h"
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Policy-Mobile" };
Mod *_pol_mod = NULL;
Eina_Hash *hash_pol_desks = NULL;
Eina_Hash *hash_pol_clients = NULL;
static Eina_List *handlers = NULL;
static Eina_List *hooks = NULL;
static Pol_Client *_pol_client_add(E_Client *ec);
static void _pol_client_del(Pol_Client *pc);
static Eina_Bool _pol_client_normal_check(E_Client *ec);
static void _pol_client_update(Pol_Client *pc);
static void _pol_client_launcher_set(Pol_Client *pc);
static void _pol_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec);
static void _pol_hook_client_desk_set(void *d EINA_UNUSED, E_Client *ec);
static void _pol_cb_desk_data_free(void *data);
static void _pol_cb_client_data_free(void *data);
static Eina_Bool _pol_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
static Eina_Bool _pol_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
static Eina_Bool _pol_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
static Eina_Bool _pol_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
static Eina_Bool _pol_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
static Eina_Bool _pol_cb_client_remove(void *data EINA_UNUSED, int type, void *event);
static void
_pol_client_launcher_set(Pol_Client *pc)
{
Pol_Client *pc2;
pc2 = e_mod_pol_client_launcher_get(pc->ec->zone);
if (pc2) return;
if (pc->ec->netwm.type != _pol_mod->conf->launcher.type)
return;
if (e_util_strcmp(pc->ec->icccm.class,
_pol_mod->conf->launcher.clas))
return;
if (e_util_strcmp(pc->ec->icccm.title,
_pol_mod->conf->launcher.title))
{
/* check netwm name instead, because comp_x had ignored
* icccm name when fetching */
if (e_util_strcmp(pc->ec->netwm.name,
_pol_mod->conf->launcher.title))
{
return;
}
}
_pol_mod->launchers = eina_list_append(_pol_mod->launchers, pc);
}
static Pol_Client *
_pol_client_add(E_Client *ec)
{
Pol_Client *pc;
Pol_Desk *pd;
if (e_object_is_del(E_OBJECT(ec))) return NULL;
if (!_pol_client_normal_check(ec)) return NULL;
pc = eina_hash_find(hash_pol_clients, &ec);
if (pc) return NULL;
pd = eina_hash_find(hash_pol_desks, &ec->desk);
if (!pd) return NULL;
pc = E_NEW(Pol_Client, 1);
pc->ec = ec;
#undef _SET
# define _SET(a) pc->orig.a = ec->a
_SET(borderless);
_SET(fullscreen);
_SET(maximized);
_SET(lock_user_location);
_SET(lock_client_location);
_SET(lock_user_size);
_SET(lock_client_size);
_SET(lock_client_stacking);
_SET(lock_user_shade);
_SET(lock_client_shade);
_SET(lock_user_maximize);
_SET(lock_client_maximize);
#undef _SET
_pol_client_launcher_set(pc);
eina_hash_add(hash_pol_clients, &ec, pc);
_pol_client_update(pc);
return pc;
}
static void
_pol_client_del(Pol_Client *pc)
{
E_Client *ec;
Eina_Bool changed = EINA_FALSE;
ec = pc->ec;
if (pc->orig.borderless != ec->borderless)
{
ec->border.changed = 1;
changed = EINA_TRUE;
}
if ((pc->orig.fullscreen != ec->fullscreen) &&
(pc->orig.fullscreen))
{
ec->need_fullscreen = 1;
changed = EINA_TRUE;
}
if (pc->orig.maximized != ec->maximized)
{
if (pc->orig.maximized)
ec->changes.need_maximize = 1;
else
ec->changes.need_unmaximize = 1;
changed = EINA_TRUE;
}
#undef _SET
# define _SET(a) ec->a = pc->orig.a
_SET(borderless);
_SET(fullscreen);
_SET(maximized);
_SET(lock_user_location);
_SET(lock_client_location);
_SET(lock_user_size);
_SET(lock_client_size);
_SET(lock_client_stacking);
_SET(lock_user_shade);
_SET(lock_client_shade);
_SET(lock_user_maximize);
_SET(lock_client_maximize);
#undef _SET
/* only set it if the border is changed or fullscreen/maximize has changed */
if (changed)
EC_CHANGED(pc->ec);
_pol_mod->launchers = eina_list_remove(_pol_mod->launchers, pc);
eina_hash_del_by_key(hash_pol_clients, &pc->ec);
}
static Eina_Bool
_pol_client_normal_check(E_Client *ec)
{
if ((e_client_util_ignored_get(ec)) ||
(!ec->pixmap))
{
return EINA_FALSE;
}
if ((ec->netwm.type == E_WINDOW_TYPE_NORMAL) ||
(ec->netwm.type == E_WINDOW_TYPE_UNKNOWN))
{
return EINA_TRUE;
}
return EINA_FALSE;
}
static void
_pol_client_update(Pol_Client *pc)
{
E_Client *ec;
ec = pc->ec;
if (ec->remember)
{
e_remember_del(ec->remember);
ec->remember = NULL;
}
/* skip hooks of e_remeber for eval_pre_post_fetch and eval_post_new_client */
ec->internal_no_remember = 1;
if (!ec->borderless)
{
ec->borderless = 1;
ec->border.changed = 1;
EC_CHANGED(pc->ec);
}
if (!ec->maximized)
e_client_maximize(ec, E_MAXIMIZE_EXPAND | E_MAXIMIZE_BOTH);
/* do not allow client to change these properties */
ec->lock_user_location = 1;
ec->lock_client_location = 1;
ec->lock_user_size = 1;
ec->lock_client_size = 1;
ec->lock_client_stacking = 1;
ec->lock_user_shade = 1;
ec->lock_client_shade = 1;
ec->lock_user_maximize = 1;
ec->lock_client_maximize = 1;
}
static void
_pol_hook_client_eval_post_fetch(void *d EINA_UNUSED, E_Client *ec)
{
Pol_Client *pc;
Pol_Desk *pd;
if (e_object_is_del(E_OBJECT(ec))) return;
if (!_pol_client_normal_check(ec)) return;
if (ec->new_client) return;
pd = eina_hash_find(hash_pol_desks, &ec->desk);
if (!pd) return;
pc = eina_hash_find(hash_pol_clients, &ec);
if (pc)
{
_pol_client_launcher_set(pc);
return;
}
_pol_client_add(ec);
}
static void
_pol_hook_client_desk_set(void *d EINA_UNUSED, E_Client *ec)
{
Pol_Client *pc;
Pol_Desk *pd;
if (e_object_is_del(E_OBJECT(ec))) return;
if (!_pol_client_normal_check(ec)) return;
pc = eina_hash_find(hash_pol_clients, &ec);
pd = eina_hash_find(hash_pol_desks, &ec->desk);
if ((!pc) && (pd))
_pol_client_add(ec);
else if ((pc) && (!pd))
_pol_client_del(pc);
}
static void
_pol_cb_desk_data_free(void *data)
{
free(data);
}
static void
_pol_cb_client_data_free(void *data)
{
free(data);
}
static Eina_Bool
_pol_cb_zone_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Zone_Add *ev;
E_Zone *zone;
Config_Desk *d;
int i, n;
ev = event;
zone = ev->zone;
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
zone->comp->num,
zone->num,
zone->desks[i]->x,
zone->desks[i]->y);
if (d)
e_mod_pol_desk_add(zone->desks[i]);
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_pol_cb_zone_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Zone_Del *ev;
E_Zone *zone;
Pol_Desk *pd;
int i, n;
ev = event;
zone = ev->zone;
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
pd = eina_hash_find(hash_pol_desks, &zone->desks[i]);
if (pd) e_mod_pol_desk_del(pd);
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_pol_cb_zone_move_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Zone_Move_Resize *ev;
Pol_Softkey *softkey;
ev = event;
if (_pol_mod->conf->use_softkey)
{
softkey = e_mod_pol_softkey_get(ev->zone);
e_mod_pol_softkey_update(softkey);
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_pol_cb_zone_desk_count_set(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Zone_Desk_Count_Set *ev;
E_Zone *zone;
E_Desk *desk;
Eina_Iterator *it;
Pol_Desk *pd;
Config_Desk *d;
int i, n;
Eina_Bool found;
Eina_List *desks_del = NULL;
ev = event;
zone = ev->zone;
/* remove deleted desk from hash */
it = eina_hash_iterator_data_new(hash_pol_desks);
while (eina_iterator_next(it, (void **)&pd))
{
if (pd->zone != zone) continue;
found = EINA_FALSE;
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
if (pd->desk == zone->desks[i])
{
found = EINA_TRUE;
break;
}
}
if (!found)
desks_del = eina_list_append(desks_del, pd->desk);
}
eina_iterator_free(it);
EINA_LIST_FREE(desks_del, desk)
{
pd = eina_hash_find(hash_pol_desks, &desk);
if (pd) e_mod_pol_desk_del(pd);
}
/* add newly added desk to hash */
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
zone->comp->num,
zone->num,
zone->desks[i]->x,
zone->desks[i]->y);
if (d)
e_mod_pol_desk_add(zone->desks[i]);
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_pol_cb_desk_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Desk_Show *ev;
Pol_Softkey *softkey;
ev = event;
if (_pol_mod->conf->use_softkey)
{
softkey = e_mod_pol_softkey_get(ev->desk->zone);
if (eina_hash_find(hash_pol_desks, &ev->desk))
e_mod_pol_softkey_show(softkey);
else
e_mod_pol_softkey_hide(softkey);
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_pol_cb_client_remove(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Client *ev;
Pol_Client *pc;
ev = event;
pc = eina_hash_find(hash_pol_clients, &ev->ec);
if (!pc) return ECORE_CALLBACK_PASS_ON;
eina_hash_del_by_key(hash_pol_clients, &ev->ec);
return ECORE_CALLBACK_PASS_ON;
}
void
e_mod_pol_desk_add(E_Desk *desk)
{
Pol_Desk *pd;
E_Comp *comp;
E_Client *ec;
Pol_Softkey *softkey;
const Eina_List *l;
pd = eina_hash_find(hash_pol_desks, &desk);
if (pd) return;
pd = E_NEW(Pol_Desk, 1);
pd->desk = desk;
pd->zone = desk->zone;
eina_hash_add(hash_pol_desks, &desk, pd);
/* add clients */
EINA_LIST_FOREACH(e_comp_list(), l, comp)
E_CLIENT_FOREACH(comp, ec)
{
if (pd->desk == ec->desk)
_pol_client_add(ec);
}
/* add and show softkey */
if (_pol_mod->conf->use_softkey)
{
softkey = e_mod_pol_softkey_get(desk->zone);
if (!softkey)
softkey = e_mod_pol_softkey_add(desk->zone);
if (e_desk_current_get(desk->zone) == desk)
e_mod_pol_softkey_show(softkey);
}
}
void
e_mod_pol_desk_del(Pol_Desk *pd)
{
Eina_Iterator *it;
Pol_Client *pc;
E_Client *ec;
Eina_List *clients_del = NULL;
Pol_Softkey *softkey;
Eina_Bool keep = EINA_FALSE;
int i, n;
/* hide and delete softkey */
if (_pol_mod->conf->use_softkey)
{
softkey = e_mod_pol_softkey_get(pd->zone);
if (e_desk_current_get(pd->zone) == pd->desk)
e_mod_pol_softkey_hide(softkey);
n = pd->zone->desk_y_count * pd->zone->desk_x_count;
for (i = 0; i < n; i++)
{
if (eina_hash_find(hash_pol_desks, &pd->zone->desks[i]))
{
keep = EINA_TRUE;
break;
}
}
if (!keep)
e_mod_pol_softkey_del(softkey);
}
/* remove clients */
it = eina_hash_iterator_data_new(hash_pol_clients);
while (eina_iterator_next(it, (void **)&pc))
{
if (pc->ec->desk == pd->desk)
clients_del = eina_list_append(clients_del, pc->ec);
}
eina_iterator_free(it);
EINA_LIST_FREE(clients_del, ec)
{
pc = eina_hash_find(hash_pol_clients, &ec);
if (pc) _pol_client_del(pc);
}
eina_hash_del_by_key(hash_pol_desks, &pd->desk);
}
Pol_Client *
e_mod_pol_client_launcher_get(E_Zone *zone)
{
Pol_Client *pc;
Eina_List *l;
EINA_LIST_FOREACH(_pol_mod->launchers, l, pc)
{
if (pc->ec->zone == zone)
return pc;
}
return NULL;
}
#undef E_CLIENT_HOOK_APPEND
#define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
do \
{ \
E_Client_Hook *_h; \
_h = e_client_hook_add(t, cb, d); \
assert(_h); \
l = eina_list_append(l, _h); \
} \
while (0)
EAPI void *
e_modapi_init(E_Module *m)
{
Mod *mod;
E_Comp *comp;
E_Zone *zone;
Config_Desk *d;
const Eina_List *l, *ll;
int i, n;
char buf[PATH_MAX];
mod = E_NEW(Mod, 1);
mod->module = m;
_pol_mod = mod;
hash_pol_clients = eina_hash_pointer_new(_pol_cb_client_data_free);
hash_pol_desks = eina_hash_pointer_new(_pol_cb_desk_data_free);
/* initialize configure and config data type */
snprintf(buf, sizeof(buf), "%s/e-module-policy-mobile.edj",
e_module_dir_get(m));
e_configure_registry_category_add("windows", 50, _("Windows"), NULL,
"preferences-system-windows");
e_configure_registry_item_add("windows/policy-mobile", 150,
_("Mobile Policy"), NULL, buf,
e_int_config_pol_mobile);
e_mod_pol_conf_init(mod);
EINA_LIST_FOREACH(e_comp_list(), l, comp)
EINA_LIST_FOREACH(comp->zones, ll, zone)
{
//Eina_Bool home_add = EINA_FALSE;
n = zone->desk_y_count * zone->desk_x_count;
for (i = 0; i < n; i++)
{
d = e_mod_pol_conf_desk_get_by_nums(_pol_mod->conf,
comp->num,
zone->num,
zone->desks[i]->x,
zone->desks[i]->y);
if (d)
{
e_mod_pol_desk_add(zone->desks[i]);
//home_add = EINA_TRUE;
}
}
/* FIXME: should consider the case that illume-home module
* is not loaded yet and make it configurable.
* and also, this code will be enabled when e_policy stuff lands in e.
*/
//if (home_add)
// e_policy_zone_home_add_request(zone);
}
E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _pol_cb_zone_add, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _pol_cb_zone_del, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _pol_cb_zone_move_resize, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DESK_COUNT_SET, _pol_cb_zone_desk_count_set, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_SHOW, _pol_cb_desk_show, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_REMOVE, _pol_cb_client_remove, NULL);
E_CLIENT_HOOK_APPEND(hooks, E_CLIENT_HOOK_EVAL_POST_FETCH,
_pol_hook_client_eval_post_fetch, NULL);
E_CLIENT_HOOK_APPEND(hooks, E_CLIENT_HOOK_DESK_SET,
_pol_hook_client_desk_set, NULL);
return mod;
}
EAPI int
e_modapi_shutdown(E_Module *m)
{
Mod *mod = m->data;
Eina_Inlist *l;
Pol_Softkey *softkey;
eina_list_free(mod->launchers);
EINA_INLIST_FOREACH_SAFE(mod->softkeys, l, softkey)
e_mod_pol_softkey_del(softkey);
E_FREE_LIST(hooks, e_client_hook_del);
E_FREE_LIST(handlers, ecore_event_handler_del);
E_FREE_FUNC(hash_pol_desks, eina_hash_free);
E_FREE_FUNC(hash_pol_clients, eina_hash_free);
e_configure_registry_item_del("windows/policy-mobile");
e_configure_registry_category_del("windows");
if (mod->conf_dialog)
{
e_object_del(E_OBJECT(mod->conf_dialog));
mod->conf_dialog = NULL;
}
e_mod_pol_conf_shutdown(mod);
E_FREE(mod);
_pol_mod = NULL;
return 1;
}
EAPI int
e_modapi_save(E_Module *m)
{
Mod *mod = m->data;
e_config_domain_save("module.policy-mobile",
mod->conf_edd,
mod->conf);
return 1;
}

View File

@ -0,0 +1,108 @@
#ifndef E_MOD_MAIN_H
#define E_MOD_MAIN_H
#include <e.h>
typedef struct _Pol_Desk Pol_Desk;
typedef struct _Pol_Client Pol_Client;
typedef struct _Pol_Softkey Pol_Softkey;
typedef struct _Config_Match Config_Match;
typedef struct _Config_Desk Config_Desk;
typedef struct _Config Config;
typedef struct _Mod Mod;
struct _Pol_Desk
{
E_Desk *desk;
E_Zone *zone;
};
struct _Pol_Client
{
E_Client *ec;
struct
{
E_Maximize maximized;
unsigned int fullscreen : 1;
unsigned char borderless : 1;
unsigned int lock_user_location : 1;
unsigned int lock_client_location : 1;
unsigned int lock_user_size : 1;
unsigned int lock_client_size : 1;
unsigned int lock_client_stacking : 1;
unsigned int lock_user_shade : 1;
unsigned int lock_client_shade : 1;
unsigned int lock_user_maximize : 1;
unsigned int lock_client_maximize : 1;
} orig;
};
struct _Pol_Softkey
{
EINA_INLIST;
E_Zone *zone;
Evas_Object *home;
Evas_Object *back;
};
struct _Config_Match
{
const char *title; /* icccm.title or netwm.name */
const char *clas; /* icccm.class */
unsigned int type; /* netwm.type */
};
struct _Config_Desk
{
unsigned int comp_num;
unsigned int zone_num;
int x, y;
int enable;
};
struct _Config
{
Config_Match launcher;
Eina_List *desks;
int use_softkey;
int softkey_size;
};
struct _Mod
{
E_Module *module;
E_Config_DD *conf_edd;
E_Config_DD *conf_desk_edd;
Config *conf;
E_Config_Dialog *conf_dialog;
Eina_List *launchers; /* launcher window per zone */
Eina_Inlist *softkeys; /* softkey ui object per zone */
};
struct _E_Config_Dialog_Data
{
Config *conf;
Evas_Object *o_list;
Evas_Object *o_desks;
};
extern Mod *_pol_mod;
extern Eina_Hash *hash_pol_desks;
extern Eina_Hash *hash_pol_clients;
EINTERN void e_mod_pol_conf_init(Mod *mod);
EINTERN void e_mod_pol_conf_shutdown(Mod *mod);
EINTERN Config_Desk *e_mod_pol_conf_desk_get_by_nums(Config *conf, unsigned int comp_num, unsigned int zone_num, int x, int y);
EINTERN E_Config_Dialog *e_int_config_pol_mobile(E_Comp *comp, const char *params EINA_UNUSED);
EINTERN void e_mod_pol_desk_add(E_Desk *desk);
EINTERN void e_mod_pol_desk_del(Pol_Desk *pd);
EINTERN Pol_Client *e_mod_pol_client_launcher_get(E_Zone *zone);
EINTERN Pol_Softkey *e_mod_pol_softkey_add(E_Zone *zone);
EINTERN void e_mod_pol_softkey_del(Pol_Softkey *softkey);
EINTERN void e_mod_pol_softkey_show(Pol_Softkey *softkey);
EINTERN void e_mod_pol_softkey_hide(Pol_Softkey *softkey);
EINTERN void e_mod_pol_softkey_update(Pol_Softkey *softkey);
EINTERN Pol_Softkey *e_mod_pol_softkey_get(E_Zone *zone);
#endif

View File

@ -0,0 +1,171 @@
#include "e_mod_main.h"
static void _pol_cb_softkey(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED);
static void _pol_softkey_iconify(E_Zone *zone, Eina_Bool all);
static Evas_Object *_pol_softkey_icon_add(E_Zone *zone, const char *name);
static void _pol_softkey_icon_del(Evas_Object *comp_obj);
static void
_pol_cb_softkey(void *data, Evas_Object *obj EINA_UNUSED, const char *emission, const char *source EINA_UNUSED)
{
E_Zone *zone;
Eina_Bool all;
zone = data;
if (!e_util_strcmp(emission, "e,action,softkey,home"))
all = EINA_TRUE;
else if (!e_util_strcmp(emission, "e,action,softkey,back"))
all = EINA_FALSE;
else
return;
_pol_softkey_iconify(zone, all);
}
static void
_pol_softkey_iconify(E_Zone *zone, Eina_Bool all)
{
E_Desk *desk;
E_Client *ec;
Pol_Client *launcher;
desk = e_desk_current_get(zone);
launcher = e_mod_pol_client_launcher_get(zone);
E_CLIENT_REVERSE_FOREACH(e_comp_get(desk), ec)
{
if (e_client_util_ignored_get(ec)) continue;
if (!e_client_util_desk_visible(ec, desk)) continue;
if (!evas_object_visible_get(ec->frame)) continue;
if ((launcher) && (launcher->ec == ec))
return;
e_client_iconify(ec);
if (!all) return;
}
}
static Evas_Object *
_pol_softkey_icon_add(E_Zone *zone, const char *name)
{
Evas_Object *obj, *comp_obj;
char path[PATH_MAX], group[PATH_MAX];
obj = edje_object_add(e_comp_get(NULL)->evas);
snprintf(group, sizeof(group), "e/modules/policy-mobile/softkey/%s", name);
snprintf(path, sizeof(path), "%s/e-module-policy-mobile.edj",
e_module_dir_get(_pol_mod->module));
if (!e_theme_edje_object_set(obj, NULL, group))
edje_object_file_set(obj, path, group);
edje_object_signal_callback_add(obj, "e,action,softkey,*", "e",
_pol_cb_softkey, zone);
/* use TYPE_NONE to disable shadow for softkey object */
comp_obj = e_comp_object_util_add(obj, E_COMP_OBJECT_TYPE_NONE);
evas_object_layer_set(comp_obj, E_LAYER_POPUP);
evas_object_data_set(comp_obj, "policy_mobile_obj", obj);
return comp_obj;
}
static void
_pol_softkey_icon_del(Evas_Object *comp_obj)
{
Evas_Object *obj;
obj = evas_object_data_get(comp_obj, "policy_mobile_obj");
edje_object_signal_callback_del(obj, "e,action,softkey,*",
"e", _pol_cb_softkey);
evas_object_hide(comp_obj);
evas_object_del(comp_obj);
}
Pol_Softkey *
e_mod_pol_softkey_add(E_Zone *zone)
{
Pol_Softkey *softkey;
softkey = E_NEW(Pol_Softkey, 1);
softkey->zone = zone;
softkey->home = _pol_softkey_icon_add(zone, "home");
softkey->back = _pol_softkey_icon_add(zone, "back");
_pol_mod->softkeys = eina_inlist_append(_pol_mod->softkeys, EINA_INLIST_GET(softkey));
return softkey;
}
void
e_mod_pol_softkey_del(Pol_Softkey *softkey)
{
if (!softkey) return;
_pol_softkey_icon_del(softkey->home);
_pol_softkey_icon_del(softkey->back);
_pol_mod->softkeys = eina_inlist_remove(_pol_mod->softkeys, EINA_INLIST_GET(softkey));
free(softkey);
}
void
e_mod_pol_softkey_show(Pol_Softkey *softkey)
{
if (!softkey) return;
e_mod_pol_softkey_update(softkey);
evas_object_show(softkey->home);
evas_object_show(softkey->back);
}
void
e_mod_pol_softkey_hide(Pol_Softkey *softkey)
{
if (!softkey) return;
evas_object_hide(softkey->home);
evas_object_hide(softkey->back);
}
void
e_mod_pol_softkey_update(Pol_Softkey *softkey)
{
int x, y, w, h, ow, oh, space;
if (!softkey) return;
e_zone_useful_geometry_get(softkey->zone, &x, &y, &w, &h);
ow = oh = _pol_mod->conf->softkey_size;
x = x + (w - ow) / 2;
y = h - oh;
space = ow * 4;
evas_object_geometry_set(softkey->home, x - space, y, ow, oh);
evas_object_geometry_set(softkey->back, x + space, y, ow, oh);
}
Pol_Softkey *
e_mod_pol_softkey_get(E_Zone *zone)
{
Pol_Softkey *softkey;
EINA_INLIST_FOREACH(_pol_mod->softkeys, softkey)
{
if (softkey->zone == zone)
return softkey;
}
return NULL;
}