diff --git a/data/themes/default.edc b/data/themes/default.edc
index 38260cd5e..e73c41f1c 100644
--- a/data/themes/default.edc
+++ b/data/themes/default.edc
@@ -6891,6 +6891,50 @@ collections { /* begin the collection of edje groups that are in this file */
// FIXME: do proper gadget and artwork
+// ICONS: receive the following signals, all with source being "e"
+// e,favorite,{yes,no}
+// e,auto_connect,{yes,no}
+// e,pass_required,{yes,no}
+// e,state,{idle,association,configuration,ready,disconnect,failure}
+// e,mode,{managed,adhoc,gprs,edge,umts}
+// e,security,{none,wep,psk,ieee8021x,wpa,rsn}
+// and also the following message:
+// id=1, type=MSG_INT, description=strength (0-100)
+ group { name: "e/modules/connman/icon/ethernet";
+ max: 128 128;
+ min: 16 16;
+ parts {
+ part { name: "icon";
+ type: IMAGE;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.image: "connman-ethernet.png" COMP;
+ image.normal: "connman-ethernet.png";
+ }
+ }
+ }
+ }
+ group { name: "e/modules/connman/icon/wifi";
+ max: 128 128;
+ min: 16 16;
+ parts {
+ part { name: "icon";
+ type: IMAGE;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.image: "connman-wifi.png" COMP;
+ image.normal: "connman-wifi.png";
+ }
+ }
+ }
+ }
+
group { name: "e/modules/connman/main";
images {
image: "connman-disconnect.png" COMP;
diff --git a/src/modules/connman/e_mod_main.c b/src/modules/connman/e_mod_main.c
index af2afcae3..9646a9f76 100644
--- a/src/modules/connman/e_mod_main.c
+++ b/src/modules/connman/e_mod_main.c
@@ -13,9 +13,7 @@
* TODO:
*
* MUST:
- * 1. popup with list of services, allows connecting + offline mode
- * 2. improve gadget ui
- * 3. fix stringshare usage errors (probably in e_connman itself)
+ * 1. improve gadget ui
*
* GOOD:
* 1. mouse over popup with information such as IP and AP name
@@ -67,14 +65,21 @@ e_connman_theme_path(void)
static inline void
_connman_dbus_error_show(const char *msg, const DBusError *error)
{
+ const char *name;
+
if ((!error) || (!dbus_error_is_set(error)))
return;
+ name = error->name;
+ if (strncmp(name, "org.moblin.connman.Error.",
+ sizeof("org.moblin.connman.Error.") - 1) == 0)
+ name += sizeof("org.moblin.connman.Error.") - 1;
+
e_util_dialog_show(_("Connman Server Operation Failed"),
_("Could not execute remote operation:
"
"%s
"
- "Server Error %s: %s"),
- msg, error->name, error->message);
+ "Server Error %s: %s"),
+ msg, name, error->message);
}
static inline void
@@ -86,8 +91,19 @@ _connman_operation_error_show(const char *msg)
}
static void
-_connman_toggle_offline_mode_cb(void *data __UNUSED__, DBusMessage *msg __UNUSED__, DBusError *error)
+_connman_toggle_offline_mode_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error)
{
+ E_Connman_Module_Context *ctxt = data;
+
+ if ((!error) || (!dbus_error_is_set(error)))
+ {
+ printf("DBG CONNMAN: successfuly toggled to offline mode\n");
+ // XXX hack: connman does not emit propertychanged for this, they need to fix it
+ e_connman_element_properties_sync(e_connman_manager_get());
+ _connman_default_service_changed_delayed(ctxt);
+ return;
+ }
+
_connman_dbus_error_show(_("Cannot toggle system's offline mode."), error);
dbus_error_free(error);
}
@@ -106,13 +122,13 @@ _connman_toggle_offline_mode(E_Connman_Module_Context *ctxt)
if (!e_connman_manager_offline_mode_get(&offline))
{
_connman_operation_error_show
- (_("Cannot query system's offline mode."));
+ (_("Query system's offline mode."));
return;
}
offline = !offline;
if (!e_connman_manager_offline_mode_set
- (offline, _connman_toggle_offline_mode_cb, NULL))
+ (offline, _connman_toggle_offline_mode_cb, ctxt))
{
_connman_operation_error_show
(_("Cannot toggle system's offline mode."));
@@ -146,7 +162,6 @@ _connman_service_free(E_Connman_Service *service)
eina_stringshare_del(service->ipv4_address);
eina_stringshare_del(service->ipv4_netmask);
- e_connman_element_unref(service->element);
E_FREE(service);
}
@@ -292,6 +307,36 @@ _connman_service_new(E_Connman_Module_Context *ctxt, E_Connman_Element *element)
return service;
}
+static void
+_connman_service_ask_pass_and_connect(E_Connman_Service *service)
+{
+ e_util_dialog_show("TODO", "TODO!");
+}
+
+static void
+_connman_service_connect_cb(void *data, DBusMessage *msg __UNUSED__, DBusError *error)
+{
+ E_Connman_Module_Context *ctxt = data;
+
+ if (error && dbus_error_is_set(error))
+ {
+ if (strcmp(error->message,
+ "org.moblin.connman.Error.AlreadyConnected") != 0)
+ _connman_dbus_error_show(_("Connect to network service."), error);
+ dbus_error_free(error);
+ }
+
+ _connman_default_service_changed_delayed(ctxt);
+}
+
+static void
+_connman_service_connect(E_Connman_Service *service)
+{
+ if (!e_connman_service_connect
+ (service->element, _connman_service_connect_cb, service->ctxt))
+ _connman_operation_error_show(_("Connect to network service."));
+}
+
static void
_connman_services_free(E_Connman_Module_Context *ctxt)
{
@@ -379,6 +424,9 @@ _connman_default_service_changed(E_Connman_Module_Context *ctxt)
eina_stringshare_replace(&ctxt->technology, tech);
printf("DBG CONNMAN: manager technology is '%s'\n", tech);
+ if (!e_connman_manager_offline_mode_get(&ctxt->offline_mode))
+ ctxt->offline_mode = EINA_FALSE;
+
ctxt->default_service = def;
EINA_LIST_FOREACH(ctxt->instances, l, inst)
_connman_gadget_update(inst);
@@ -415,7 +463,7 @@ _connman_default_service_changed_delayed(E_Connman_Module_Context *ctxt)
static void _connman_popup_del(E_Connman_Instance *inst);
static int
-_connman_popup_input_window_mouse_up_cb(void *data, int type, void *event)
+_connman_popup_input_window_mouse_up_cb(void *data, int type __UNUSED__, void *event)
{
Ecore_Event_Mouse_Button *ev = event;
E_Connman_Instance *inst = data;
@@ -429,7 +477,7 @@ _connman_popup_input_window_mouse_up_cb(void *data, int type, void *event)
}
static int
-_connman_popup_input_window_key_down_cb(void *data, int type, void *event)
+_connman_popup_input_window_key_down_cb(void *data, int type __UNUSED__, void *event)
{
Ecore_Event_Key *ev = event;
E_Connman_Instance *inst = data;
@@ -465,8 +513,6 @@ _connman_popup_input_window_create(E_Connman_Instance *inst)
Ecore_X_Window w, popup_w;
E_Manager *man;
- return; // TODO
-
man = e_manager_current_get();
w = ecore_x_window_input_new(man->root, 0, 0, man->w, man->h);
@@ -488,9 +534,160 @@ _connman_popup_input_window_create(E_Connman_Instance *inst)
inst->ui.input.win = w;
}
+static void
+_connman_popup_cb_offline_mode_changed(void *data, Evas_Object *obj, void *event __UNUSED__)
+{
+ E_Connman_Instance *inst = data;
+ E_Connman_Module_Context *ctxt = inst->ctxt;
+ Eina_Bool offline = e_widget_check_checked_get(obj);
+
+ if ((!ctxt) || (!ctxt->has_manager))
+ {
+ _connman_operation_error_show(_("ConnMan Daemon is not running."));
+ return;
+ }
+
+ printf(">>>> OFFLINE=%hhu\n", offline);
+
+ if (!e_connman_manager_offline_mode_set
+ (offline, _connman_toggle_offline_mode_cb, ctxt))
+ {
+ _connman_operation_error_show
+ (_("Cannot toggle system's offline mode."));
+ return;
+ }
+}
+
+static void
+_connman_popup_cb_controls(void *data, void *data2 __UNUSED__)
+{
+ E_Connman_Instance *inst = data;
+
+ _connman_popup_del(inst);
+
+ e_util_dialog_show("TODO", "TODO!");
+}
+
+static void
+_connman_popup_service_selected(void *data)
+{
+ E_Connman_Instance *inst = data;
+ E_Connman_Module_Context *ctxt = inst->ctxt;
+ E_Connman_Service *service;
+
+ if (inst->first_selection)
+ {
+ inst->first_selection = EINA_FALSE;
+ return;
+ }
+
+ if (!inst->service_path)
+ return;
+
+ EINA_INLIST_FOREACH(ctxt->services, service)
+ {
+ if (service->path == inst->service_path)
+ {
+ _connman_popup_del(inst);
+
+ if (service->pass_required)
+ _connman_service_ask_pass_and_connect(service);
+ else
+ _connman_service_connect(service);
+ return;
+ }
+ }
+}
+
+static void
+_connman_popup_update(E_Connman_Instance *inst)
+{
+ Evas_Object *list = inst->ui.list;
+ E_Connman_Service *service;
+ const char *default_path;
+ Evas *evas = evas_object_evas_get(list);
+ int i, selected;
+ char buf[128];
+
+ default_path = inst->ctxt->default_service ?
+ inst->ctxt->default_service->path : NULL;
+
+ /* TODO: replace this with a scroller + list of edje
+ * objects that are more full of features
+ */
+ e_widget_ilist_freeze(list);
+ e_widget_ilist_clear(list);
+ i = 0;
+ selected = -1;
+ EINA_INLIST_FOREACH(inst->ctxt->services, service)
+ {
+ Evas_Object *icon;
+ Edje_Message_Int msg;
+
+ if (service->path == default_path)
+ selected = i;
+ i++;
+
+ snprintf(buf, sizeof(buf), "e/modules/connman/icon/%s", service->type);
+ icon = edje_object_add(evas);
+ e_theme_edje_object_set(icon, "base/theme/modules/connman", buf);
+
+ snprintf(buf, sizeof(buf), "e,state,%s", service->state);
+ edje_object_signal_emit(icon, buf, "e");
+
+ if (service->mode)
+ {
+ snprintf(buf, sizeof(buf), "e,mode,%s", service->mode);
+ edje_object_signal_emit(icon, buf, "e");
+ }
+
+ if (service->security)
+ {
+ snprintf(buf, sizeof(buf), "e,security,%s", service->security);
+ edje_object_signal_emit(icon, buf, "e");
+ }
+
+ if (service->favorite)
+ edje_object_signal_emit(icon, "e,favorite,yes", "e");
+ else
+ edje_object_signal_emit(icon, "e,favorite,no", "e");
+
+ if (service->auto_connect)
+ edje_object_signal_emit(icon, "e,auto_connect,yes", "e");
+ else
+ edje_object_signal_emit(icon, "e,auto_connect,no", "e");
+
+ if (service->pass_required)
+ edje_object_signal_emit(icon, "e,pass_required,yes", "e");
+ else
+ edje_object_signal_emit(icon, "e,pass_required,no", "e");
+
+ msg.val = service->strength;
+ edje_object_message_send(icon, EDJE_MESSAGE_INT, 1, &msg);
+
+ e_widget_ilist_append
+ (list, icon, service->name, _connman_popup_service_selected,
+ inst, service->path);
+ }
+
+ if (selected >= 0)
+ {
+ inst->first_selection = EINA_TRUE;
+ e_widget_ilist_selected_set(list, selected);
+ }
+ else
+ inst->first_selection = EINA_FALSE;
+
+ e_widget_ilist_thaw(list);
+ e_widget_ilist_go(list);
+
+ e_widget_check_checked_set(inst->ui.offline_mode, inst->ctxt->offline_mode);
+}
+
static void
_connman_popup_del(E_Connman_Instance *inst)
{
+ eina_stringshare_replace(&inst->service_path, NULL);
_connman_popup_input_window_destroy(inst);
e_object_del(E_OBJECT(inst->popup));
inst->popup = NULL;
@@ -499,14 +696,52 @@ _connman_popup_del(E_Connman_Instance *inst)
static void
_connman_popup_new(E_Connman_Instance *inst)
{
+ E_Connman_Module_Context *ctxt = inst->ctxt;
Evas *evas;
Evas_Coord mw, mh;
- // TODO
+ if (inst->popup)
+ {
+ e_gadcon_popup_show(inst->popup);
+ return;
+ }
+
+ inst->popup = e_gadcon_popup_new(inst->gcc);
+ evas = inst->popup->win->evas;
+
+ inst->ui.table = e_widget_table_add(evas, 0);
+
+ if (ctxt->default_service)
+ eina_stringshare_replace(&inst->service_path, ctxt->default_service->path);
+
+ // TODO: get this size from edj
+ inst->ui.list = e_widget_ilist_add(evas, 32, 32, &inst->service_path);
+ e_widget_size_min_set(inst->ui.list, 180, 100);
+ e_widget_table_object_append(inst->ui.table, inst->ui.list,
+ 0, 0, 1, 5, 1, 1, 1, 1);
+
+ inst->offline_mode = ctxt->offline_mode;
+ inst->ui.offline_mode = e_widget_check_add
+ (evas, _("Offline mode"), &inst->offline_mode);
+
+ evas_object_show(inst->ui.offline_mode);
+ e_widget_table_object_append(inst->ui.table, inst->ui.offline_mode,
+ 0, 5, 1, 1, 1, 1, 1, 0);
+ evas_object_smart_callback_add
+ (inst->ui.offline_mode, "changed",
+ _connman_popup_cb_offline_mode_changed, inst);
+
+ inst->ui.button = e_widget_button_add
+ (evas, _("Controls"), NULL,
+ _connman_popup_cb_controls, inst, NULL);
+ e_widget_table_object_append(inst->ui.table, inst->ui.button,
+ 0, 6, 1, 1, 1, 1, 1, 0);
+
+ _connman_popup_update(inst);
e_widget_size_min_get(inst->ui.table, &mw, &mh);
if (mh < 208) mh = 208;
- if (mw < 68) mw = 68;
+ if (mw < 200) mw = 200;
e_widget_size_min_set(inst->ui.table, mw, mh);
e_gadcon_popup_content_set(inst->popup, inst->ui.table);
@@ -515,11 +750,9 @@ _connman_popup_new(E_Connman_Instance *inst)
}
static void
-_connman_menu_cb_post(void *data, E_Menu *menu)
+_connman_menu_cb_post(void *data, E_Menu *menu __UNUSED__)
{
- E_Connman_Instance *inst;
-
- inst = data;
+ E_Connman_Instance *inst = data;
if ((!inst) || (!inst->menu))
return;
if (inst->menu)
@@ -570,7 +803,7 @@ _connman_menu_new(E_Connman_Instance *inst, Evas_Event_Mouse_Down *ev)
}
static void
-_connman_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event)
+_connman_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
{
E_Connman_Instance *inst;
Evas_Event_Mouse_Down *ev;
@@ -606,12 +839,18 @@ _connman_gadget_update(E_Connman_Instance *inst)
if (!ctxt->has_manager)
{
+ if (inst->popup)
+ _connman_popup_del(inst);
+
edje_object_signal_emit(gadget, "e,unavailable", "e");
edje_object_part_text_set(gadget, "e.text.name", _("No ConnMan"));
edje_object_part_text_set(gadget, "e.text.error",
_("No ConnMan server found."));
}
+ if (inst->popup)
+ _connman_popup_update(inst);
+
edje_object_signal_emit(gadget, "e,available", "e");
if (ctxt->offline_mode)
@@ -619,6 +858,7 @@ _connman_gadget_update(E_Connman_Instance *inst)
else
edje_object_signal_emit(gadget, "e,changed,offline_mode,no", "e");
+
printf("DBG CONNMAN: technology: %s\n", ctxt->technology);
if (ctxt->technology)
@@ -876,7 +1116,7 @@ _connman_manager_changed(void *data, const E_Connman_Element *element __UNUSED__
if (ctxt->poller.manager_changed)
ecore_poller_del(ctxt->poller.manager_changed);
ctxt->poller.manager_changed = ecore_poller_add
- (ECORE_POLLER_CORE, 2, _connman_manager_changed_do, ctxt);
+ (ECORE_POLLER_CORE, 1, _connman_manager_changed_do, ctxt);
}
static int
diff --git a/src/modules/connman/e_mod_main.h b/src/modules/connman/e_mod_main.h
index 4eca1959a..306e71196 100644
--- a/src/modules/connman/e_mod_main.h
+++ b/src/modules/connman/e_mod_main.h
@@ -22,10 +22,16 @@ struct E_Connman_Instance
E_Gadcon_Popup *popup;
E_Menu *menu;
+ /* used by popup */
+ int offline_mode;
+ const char *service_path;
+ Eina_Bool first_selection;
+
struct
{
Evas_Object *gadget;
- Evas_Object *toggle_offline;
+ Evas_Object *list;
+ Evas_Object *offline_mode;
Evas_Object *button;
Evas_Object *table;
struct
@@ -80,7 +86,7 @@ struct E_Connman_Module_Context
} poller;
Eina_Bool has_manager:1;
- Eina_Bool offline_mode;
+ bool offline_mode;
const char *technology;
const E_Connman_Service *default_service;
Eina_Inlist *services;