enlightenment/src/modules/bluez5/e_mod_popup.c

1097 lines
33 KiB
C

#include "e_mod_main.h"
static Elm_Genlist_Item_Class *adapt_itc = NULL;
static Elm_Genlist_Item_Class *dev_itc = NULL;
static Elm_Genlist_Item_Class *group_itc = NULL;
static Eina_List *lists = NULL;
static Eina_List *adapters = NULL;
static Eina_List *devices = NULL;
static int unlock_count = 0;
static int unlock_do = 0;
static Eina_Bool unlock_block = EINA_FALSE;
static Config_Device *
_devices_conifg_find(const char *address)
{
Config_Device *dev;
Eina_List *l;
if (!ebluez5_config) return NULL;
if (!address) return NULL;
EINA_LIST_FOREACH(ebluez5_config->devices, l, dev)
{
if ((dev->addr) && (!strcmp(address, dev->addr))) return dev;
}
return NULL;
}
static void
_devices_eval(void)
{
Obj *o;
Eina_List *l;
Config_Device *dev;
int unlock_count_prev = 0;
unlock_count_prev = unlock_count;
unlock_count = 0;
unlock_do = 0;
printf("=== _devices_eval...\n");
EINA_LIST_FOREACH(devices, l, o)
{
if (o->paired)
{
Eina_Bool need_ping = EINA_FALSE;
dev = _devices_conifg_find(o->address);
if (dev)
{
printf("=== dev: %s|%s [%s]\n", dev->addr, o->address, o->name);
if ((dev->force_connect) && (!o->connected))
{
printf("=== %s force con, not conn, ping ok=%i\n", o->address, o->ping_ok);
if (o->ping_ok)
{
printf("=== %s force con, not conn, ping ok=%i\n", o->address, o->ping_ok);
bz_obj_connect(o);
}
else need_ping = EINA_TRUE;
}
if (dev->unlock)
{
printf("=== unlock...\n");
// if a device on our list needs an unlock, then
// add to our possible unlock counts needed
unlock_count++;
#if 0
// if the device is connected then assume it unlocks
if (o->connected)
{
printf("=== don't need ping1\n");
unlock_do++;
}
else
#endif
{
printf("=== need ping2\n");
need_ping = EINA_TRUE;
if (o->ping_ok) unlock_do++;
}
}
}
printf("=== %s need_ping=%i conn=%i ping_ok=%i\n", o->address, need_ping, o->connected, o->ping_ok);
if (need_ping) bz_obj_ping_begin(o);
else bz_obj_ping_end(o);
}
}
printf("=================== unlock: %i/%i\n", unlock_do, unlock_count);
if (unlock_count > 0)
{
if (unlock_do == 0)
{
if (unlock_block)
{
unlock_block = EINA_FALSE;
printf("=== DESKLOCK UNBLOCK\n");
e_desklock_unblock();
printf("=== DESLOCK SHOW\n");
e_desklock_show(EINA_FALSE);
}
}
else
{
if (!unlock_block)
{
unlock_block = EINA_TRUE;
printf("=== DESKLOCK BLOCK\n");
e_desklock_block();
}
}
}
else
{
if (unlock_count_prev != unlock_count)
{
if (!e_desklock_manual_get())
{
if (e_desklock_state_get())
{
printf("=== DESKLOCK HIDE\n");
e_desklock_hide();
}
}
}
if (unlock_block)
{
unlock_block = EINA_FALSE;
printf("=== DESKLOCK UNBLOCK\n");
e_desklock_unblock();
}
}
}
static void
_adapter_add(Evas_Object *gl, Obj *o)
{
Elm_Object_Item *it = evas_object_data_get(gl, "adapters_item");;
elm_genlist_item_append(gl, adapt_itc, o, it, ELM_GENLIST_ITEM_NONE,
NULL, NULL);
}
static int
_cb_insert_cmp(const void *ai, const void *bi)
{
Obj *a = elm_object_item_data_get(ai);
Obj *b = elm_object_item_data_get(bi);
Eina_Bool apub = EINA_FALSE, bpub = EINA_FALSE;
if ((!a) || (!a->address)) return -1;
if ((!b) || (!b->address)) return 1;
// prefer paired at top
if ((a->paired) && (!b->paired)) return -1;
if ((!a->paired) && (b->paired)) return 1;
// prefer public addresses next after being paired
if ((a->address_type) && (!strcmp(a->address_type, "public")))
apub = EINA_TRUE;
if ((b->address_type) && (!strcmp(b->address_type, "public")))
bpub = EINA_TRUE;
if ((apub) && (!bpub)) return -1;
if ((!apub) && (bpub)) return 1;
// and sort by address
return strcmp(a->address, b->address);
}
static void
_device_add(Evas_Object *gl, Obj *o)
{
Elm_Object_Item *it = evas_object_data_get(gl, "devices_item");;
elm_genlist_item_sorted_insert(gl, dev_itc, o, it,
ELM_GENLIST_ITEM_NONE,
_cb_insert_cmp, NULL, NULL);
}
static void
_cb_power(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Obj *o = data;
if (elm_check_state_get(obj))
{
if (o->path)
{
const char *s = strrchr(o->path, '/');
if (s) ebluez5_rfkill_unblock(s + 1);
}
bz_obj_power_on(o);
}
else bz_obj_power_off(o);
}
static void
_cb_scan(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Obj *o = data;
if (elm_check_state_get(obj)) bz_obj_discover_start(o);
else bz_obj_discover_stop(o);
}
static void
_cb_visible(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Obj *o = data;
if (elm_check_state_get(obj)) bz_obj_discoverable(o);
else bz_obj_undiscoverable(o);
}
static void
_unflip(Obj *o, Evas_Object *obj)
{
Evas_Object *gl = evas_object_data_get(obj, "genlist");
Elm_Object_Item *it;
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
if (elm_genlist_item_flip_get(it))
elm_genlist_item_flip_set(it, EINA_FALSE);
break;
}
}
}
static void
_cb_pairable(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
if (elm_check_state_get(obj)) bz_obj_pairable(o);
else bz_obj_unpairable(o);
_unflip(o, obj);
}
static void
_cb_connect(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_connect(o);
_unflip(o, obj);
}
static void
_cb_disconnect(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_disconnect(o);
_unflip(o, obj);
}
static void
_cb_trust(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_trust(o);
_unflip(o, obj);
}
static void
_cb_distrust(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_distrust(o);
_unflip(o, obj);
}
static void
_cb_pair(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_pair(o);
_unflip(o, obj);
}
static void
_cb_unpair(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
bz_obj_remove(o);
_unflip(o, obj);
}
static void
_cb_unlock_start(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
printf("unlock start %s\n", o->address);
ebluez5_device_prop_unlock_set(o->address, EINA_TRUE);
ebluez5_popup_device_change(o);
_unflip(o, obj);
}
static void
_cb_unlock_stop(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
printf("unlock stop %s\n", o->address);
ebluez5_device_prop_unlock_set(o->address, EINA_FALSE);
ebluez5_popup_device_change(o);
_unflip(o, obj);
}
static void
_cb_force_connect_start(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
ebluez5_device_prop_force_connect_set(o->address, EINA_TRUE);
ebluez5_popup_adapter_change(o);
_unflip(o, obj);
}
static void
_cb_force_connect_stop(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
ebluez5_device_prop_force_connect_set(o->address, EINA_FALSE);
ebluez5_popup_adapter_change(o);
_unflip(o, obj);
}
static void
_cb_flip(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
Evas_Object *gl = evas_object_data_get(obj, "genlist");
Elm_Object_Item *it;
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
if (elm_genlist_item_flip_get(it))
elm_genlist_item_flip_set(it, EINA_FALSE);
else
elm_genlist_item_flip_set(it, EINA_TRUE);
break;
}
}
}
static void
_agent_done(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
Elm_Object_Item *it;
if (o->agent_request)
{
eina_stringshare_del(o->agent_request);
o->agent_request = NULL;
}
EINA_LIST_FOREACH(lists, l, gl)
{
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
elm_genlist_item_update(it);
break;
}
}
}
}
static void
_cb_agent_ok(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Obj *o = data;
if ((o->agent_entry_fn) && (o->agent_msg_ok))
{
Evas_Object *en = evas_object_data_get(obj, "entry");
if (en)
{
const char *s = elm_object_text_get(en);
if (s) o->agent_entry_fn(o->agent_msg_ok, s);
}
}
if (o->agent_msg_err)
{
bz_agent_msg_drop(o->agent_msg_err);
o->agent_msg_err = NULL;
}
if (o->agent_msg_ok)
{
bz_agent_msg_reply(o->agent_msg_ok);
o->agent_msg_ok = NULL;
}
_agent_done(o);
}
static void
_cb_agent_cancel(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Obj *o = data;
if (o->agent_msg_ok)
{
bz_agent_msg_drop(o->agent_msg_ok);
o->agent_msg_ok = NULL;
}
if (o->agent_msg_err)
{
bz_agent_msg_reply(o->agent_msg_err);
o->agent_msg_err = NULL;
}
_agent_done(o);
}
static char *
_cb_group_text_get(void *data, Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
if (!data) return strdup(_("Adapters"));
return strdup(_("Devices"));
}
static Evas_Object *
_cb_group_content_get(void *data EINA_UNUSED, Evas_Object *obj,
const char *part EINA_UNUSED)
{
if (!strcmp(part, "elm.swallow.icon"))
{
Evas_Object *ic = elm_icon_add(obj);
if (!data)
elm_icon_standard_set(ic, "computer");
else
elm_icon_standard_set(ic, "system-run");
evas_object_size_hint_min_set(ic,
ELM_SCALE_SIZE(16),
ELM_SCALE_SIZE(16));
return ic;
}
return NULL;
}
static char *
_cb_adapt_text_get(void *data, Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
Obj *o = data;
if (!strcmp(part, "elm.text"))
{
return strdup(util_obj_name_get(o));
}
else if (!strcmp(part, "elm.text.sub"))
{
if (o->address) return strdup(o->address);
return strdup(_("Unknown Address"));
}
return NULL;
}
static Evas_Object *
_cb_adapt_content_get(void *data EINA_UNUSED, Evas_Object *obj,
const char *part EINA_UNUSED)
{
Obj *o = data;
if (!strcmp(part, "elm.swallow.icon"))
{
return util_obj_icon_add(obj, o, 48);
}
else if (!strcmp(part, "elm.swallow.end"))
{
Evas_Object *tab, *ck;
tab = elm_table_add(obj);
evas_object_size_hint_weight_set(tab, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(tab, EVAS_HINT_FILL, 0.0);
ck = util_check_add(obj, _("Power"), _("Enable power for this adapter"),
o->powered);
evas_object_smart_callback_add(ck, "changed", _cb_power, o);
elm_table_pack(tab, ck, 0, 0, 1, 1);
evas_object_show(ck);
ck = util_check_add(obj, _("Visible"), _("Make this adapter visible to other devices"),
o->discoverable);
evas_object_smart_callback_add(ck, "changed", _cb_visible, o);
elm_table_pack(tab, ck, 1, 0, 1, 1);
evas_object_show(ck);
ck = util_check_add(obj, _("Scan"), _("Scan for other devices"),
o->discovering);
evas_object_smart_callback_add(ck, "changed", _cb_scan, o);
elm_table_pack(tab, ck, 0, 1, 1, 1);
evas_object_show(ck);
ck = util_check_add(obj, _("Pairable"), _("Allow this adapter to have other devices request to pair with it"),
o->pairable);
evas_object_smart_callback_add(ck, "changed", _cb_pairable, o);
elm_table_pack(tab, ck, 1, 1, 1, 1);
evas_object_show(ck);
return tab;
}
return NULL;
}
static char *
_cb_dev_text_get(void *data, Evas_Object *obj EINA_UNUSED,
const char *part EINA_UNUSED)
{
Obj *o = data;
return strdup(util_obj_name_get(o));
}
static Evas_Object *
_cb_dev_content_get(void *data, Evas_Object *obj,
const char *part)
{
Obj *o = data;
char buf[512];
if (!strcmp(part, "elm.swallow.icon"))
{
Evas_Object *ic, *bx;
bx = elm_box_add(obj);
ic = util_obj_icon_add(obj, o, 24);
snprintf(buf, sizeof(buf),
_("Address: %s (%s)<br>"
"Services: %s%s%s%s%s%s%s%s%s<br>"
"Trusted: %s<br>"
"Blocked: %s<br>"
)
,
(o->address) ? o->address : _("Unknown"),
(o->address_type) ? o->address_type : _("Unknown"),
(o->klass & BZ_OBJ_CLASS_SERVICE_LIMITED_DISCOVERABLE) ? _("Limited-Discoverable ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_POSITIONING_BIT) ? _("Positioning ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_NETWORKING_BIT) ? _("Networking ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_RENDERING_BIT) ? _("Rendering ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_CAPTURING_BIT) ? _("Capture ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_OBJECT_TRANSFER_BIT) ? _("OBEX ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_AUDIO_BIT) ? _("Audio ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_TELEPHONY_BIT) ? _("Telephony ") : "",
(o->klass & BZ_OBJ_CLASS_SERVICE_INFORMATION_BIT) ? _("Information ") : "",
(o->trusted) ? _("Yes") : _("No"),
(o->blocked) ? _("Yes") : _("No")
);
elm_object_tooltip_text_set(ic, buf);
elm_box_pack_end(bx, ic);
evas_object_show(ic);
return bx;
}
else if (!strcmp(part, "elm.text.flip"))
{
Evas_Object *bx, *bt, *ic;
bx = elm_box_add(obj);
elm_box_horizontal_set(bx, EINA_TRUE);
elm_box_align_set(bx, 1.0, 0.5);
if (o->paired)
{
if (o->paired)
{
Config_Device *dev = ebluez5_device_prop_find(o->address);
if ((dev) && (dev->unlock))
{
bt = util_button_icon_add(obj, "changes-allow-symbolic",
_("Stop this from being an unlock device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_unlock_stop, o);
}
else
{
bt = util_button_icon_add(obj, "channel-insecure-symbolic",
_("Make this auto unlock when detected (and lock when not)"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_unlock_start, o);
}
elm_box_pack_end(bx, bt);
evas_object_show(bt);
if ((dev) && (dev->force_connect))
{
bt = util_button_icon_add(obj, "checkbox-symbolic",
_("Stop this device from being forcefullty connected"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_force_connect_stop, o);
}
else
{
bt = util_button_icon_add(obj, "checkbox-checked-symbolic",
_("Force this device to be connected when detected"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_force_connect_start, o);
}
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
if (o->connected)
{
bt = util_button_icon_add(obj, "network-offline",
_("Disconnect this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_disconnect, o);
}
else
{
bt = util_button_icon_add(obj, "network-transmit-receive",
_("Connect this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_connect, o);
}
elm_box_pack_end(bx, bt);
evas_object_show(bt);
if (o->trusted)
{
bt = util_button_icon_add(obj, "security-low",
_("Disrust this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_distrust, o);
}
else
{
bt = util_button_icon_add(obj, "security-high",
_("Trust this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_trust, o);
}
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
if (!o->paired)
{
if (!o->agent_request)
{
bt = util_button_icon_add(obj, "list-add",
_("Pair with this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_pair, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
}
else
{
bt = util_button_icon_add(obj, "list-remove",
_("Unpair with this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_unpair, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
bt = util_button_icon_add(obj, "view-more-horizontal",
_("Cancel"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_flip, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
ic = util_obj_icon_rssi_add(obj, o, 24);
elm_box_pack_end(bx, ic);
evas_object_show(ic);
return bx;
}
else if (!strcmp(part, "elm.swallow.end"))
{
Evas_Object *bx, *ic, *bt, *lb, *tb, *en, *rec;
bx = elm_box_add(obj);
elm_box_horizontal_set(bx, EINA_TRUE);
if (o->agent_request)
{
if (o->agent_entry_fn)
{
tb = elm_table_add(obj);
rec = evas_object_rectangle_add(evas_object_evas_get(obj));
evas_object_size_hint_min_set(rec, ELM_SCALE_SIZE(80), ELM_SCALE_SIZE(1));
elm_table_pack(tb, rec, 0, 0, 1, 1);
en = elm_entry_add(obj);
elm_entry_single_line_set(en, EINA_TRUE);
elm_entry_scrollable_set(en, EINA_TRUE);
elm_scroller_policy_set(en, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
elm_object_part_text_set(en, "guide", o->agent_request);
// elm_entry_password_set(en, EINA_TRUE);
evas_object_smart_callback_add(en, "activated", _cb_agent_ok, o);
evas_object_smart_callback_add(en, "aborted", _cb_agent_cancel, o);
elm_table_pack(tb, en, 0, 0, 1, 1);
evas_object_show(en);
elm_box_pack_end(bx, tb);
evas_object_show(tb);
bt = util_button_icon_add(obj, "list-add",
_("Pair with this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_data_set(bt, "entry", en);
evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
bt = util_button_icon_add(obj, "list-remove",
_("Reject pairing"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
else
{
lb = elm_label_add(obj);
elm_layout_text_set(lb, NULL, o->agent_request);
elm_box_pack_end(bx, lb);
evas_object_show(lb);
bt = util_button_icon_add(obj, "list-add",
_("Pair with this device"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_agent_ok, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
bt = util_button_icon_add(obj, "list-remove",
_("Reject pairing"));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_agent_cancel, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
}
bt = util_button_icon_add(obj, "view-more-horizontal",
_("Options for device like connect, pair etc."));
evas_object_data_set(bt, "genlist", obj);
evas_object_smart_callback_add(bt, "clicked", _cb_flip, o);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
ic = util_obj_icon_rssi_add(obj, o, 24);
elm_box_pack_end(bx, ic);
evas_object_show(ic);
return bx;
}
return NULL;
}
static void
_cb_list_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
lists = eina_list_remove(lists, obj);
}
/*
static void
_cb_settings(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Instance *inst = data;
ebluez5_popup_hide(inst);
if (e_configure_registry_exists("extensions/bluez5"))
e_configure_registry_call("extensions/bluez5", NULL, NULL);
}
*/
Evas_Object *
ebluez5_popup_content_add(Evas_Object *base, Instance *inst)
{
Evas_Object *o, *box, *tab, *gl;
Eina_List *l;
Elm_Object_Item *it;
Obj *oo;
o = box = elm_box_add(base);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
tab = o = elm_table_add(base);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
o = evas_object_rectangle_add(evas_object_evas_get(base));
evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(320), ELM_SCALE_SIZE(240));
evas_object_size_hint_max_set(o, ELM_SCALE_SIZE(560), ELM_SCALE_SIZE(400));
elm_table_pack(tab, o, 0, 0, 1, 1);
o = gl = elm_genlist_add(base);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_genlist_mode_set(o, ELM_LIST_LIMIT);
elm_genlist_select_mode_set(o, ELM_OBJECT_SELECT_MODE_NONE);
lists = eina_list_append(lists, gl);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _cb_list_del, inst);
it = elm_genlist_item_append(gl, group_itc, NULL, NULL,
ELM_GENLIST_ITEM_GROUP, NULL, NULL);
evas_object_data_set(gl, "adapters_item", it);
it = elm_genlist_item_append(gl, group_itc, gl, NULL,
ELM_GENLIST_ITEM_GROUP, NULL, NULL);
evas_object_data_set(gl, "devices_item", it);
EINA_LIST_FOREACH(adapters, l, oo)
{
_adapter_add(gl, oo);
}
EINA_LIST_FOREACH(devices, l, oo)
{
_device_add(gl, oo);
}
elm_table_pack(tab, o, 0, 0, 1, 1);
evas_object_show(o);
elm_box_pack_end(box, tab);
evas_object_show(tab);
/*
o = elm_separator_add(base);
elm_separator_horizontal_set(o, EINA_TRUE);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, o);
evas_object_show(o);
o = elm_button_add(base);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_layout_text_set(o, NULL, _("Settings"));
elm_object_tooltip_text_set(o, _("Bring up more detailed Bluetooth settings"));
evas_object_smart_callback_add(o, "clicked", _cb_settings, inst);
elm_box_pack_end(box, o);
evas_object_show(o);
*/
return box;
}
void
ebluze5_popup_init(void)
{
adapt_itc = elm_genlist_item_class_new();
adapt_itc->item_style = "double_label";
adapt_itc->func.text_get = _cb_adapt_text_get;
adapt_itc->func.content_get = _cb_adapt_content_get;
adapt_itc->func.state_get = NULL;
adapt_itc->func.del = NULL;
dev_itc = elm_genlist_item_class_new();
dev_itc->item_style = "default";
dev_itc->func.text_get = _cb_dev_text_get;
dev_itc->func.content_get = _cb_dev_content_get;
dev_itc->func.state_get = NULL;
dev_itc->func.del = NULL;
group_itc = elm_genlist_item_class_new();
group_itc->item_style = "group_index";
group_itc->func.text_get = _cb_group_text_get;
group_itc->func.content_get = _cb_group_content_get;
group_itc->func.state_get = NULL;
group_itc->func.del = NULL;
}
void
ebluze5_popup_shutdown(void)
{
if (unlock_block)
{
unlock_block = EINA_FALSE;
e_desklock_unblock();
}
ebluze5_popup_clear();
elm_genlist_item_class_free(group_itc);
elm_genlist_item_class_free(dev_itc);
elm_genlist_item_class_free(adapt_itc);
group_itc = NULL;
dev_itc = NULL;
adapt_itc = NULL;
}
void
ebluze5_popup_clear(void)
{
Eina_List *l;
Evas_Object *gl;
adapters = eina_list_free(adapters);
devices = eina_list_free(devices);
EINA_LIST_FOREACH(lists, l, gl)
{
elm_genlist_clear(gl);
}
}
static Eina_Bool
_cb_adapter_add_delayed_setup(void *data)
{
char *path = data;
Obj *o;
if (!path) return EINA_FALSE;
o = bz_obj_find(path);
if ((o) && (o->address))
{
Eina_List *l;
Config_Adapter *ad;
EINA_LIST_FOREACH(ebluez5_config->adapters, l, ad)
{
if (!ad->addr) continue;
if (!strcmp(ad->addr, o->address))
{
if (ad->powered)
{
printf("==== BZ INIT REQ POWER ON %s\n", o->address);
if (o->path)
{
const char *s = strrchr(o->path, '/');
if (s) ebluez5_rfkill_unblock(s + 1);
}
bz_obj_power_on(o);
}
else
{
printf("==== BZ INIT REQ POWER OFF %s\n", o->address);
bz_obj_power_off(o);
}
if (ad->pairable) bz_obj_pairable(o);
else bz_obj_unpairable(o);
}
}
}
free(path);
return EINA_FALSE;
}
void
ebluez5_popup_adapter_add(Obj *o)
{
Eina_List *l;
Config_Adapter *ad;
Evas_Object *gl;
adapters = eina_list_append(adapters, o);
EINA_LIST_FOREACH(lists, l, gl)
{
_adapter_add(gl, o);
}
if ((ebluez5_config) && (o->address))
{
EINA_LIST_FOREACH(ebluez5_config->adapters, l, ad)
{
if (!ad->addr) continue;
if (!strcmp(ad->addr, o->address))
ecore_timer_add(1.0, _cb_adapter_add_delayed_setup,
strdup(o->path));
}
}
ebluez5_instances_update();
}
void
ebluez5_popup_adapter_del(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
Elm_Object_Item *it;
EINA_LIST_FOREACH(lists, l, gl)
{
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
elm_object_item_del(it);
break;
}
}
}
adapters = eina_list_remove(adapters, o);
ebluez5_instances_update();
}
void
ebluez5_popup_adapter_change(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
Elm_Object_Item *it;
EINA_LIST_FOREACH(lists, l, gl)
{
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
elm_genlist_item_update(it);
if (o->address)
ebluez5_conf_adapter_add(o->address, o->powered,
o->pairable);
break;
}
}
}
ebluez5_instances_update();
}
void
ebluez5_popup_device_add(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
devices = eina_list_append(devices, o);
EINA_LIST_FOREACH(lists, l, gl)
{
_device_add(gl, o);
}
_devices_eval();
}
void
ebluez5_popup_device_del(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
Elm_Object_Item *it;
EINA_LIST_FOREACH(lists, l, gl)
{
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
elm_object_item_del(it);
break;
}
}
}
devices = eina_list_remove(devices, o);
_devices_eval();
}
void
ebluez5_popup_device_change(Obj *o)
{
Eina_List *l;
Evas_Object *gl;
Elm_Object_Item *it;
Eina_Bool alert = EINA_FALSE;
if (o->agent_alert)
{
alert = EINA_TRUE;
o->agent_alert = EINA_FALSE;
if (!lists) ebluez5_popups_show();
}
EINA_LIST_FOREACH(lists, l, gl)
{
for (it = elm_genlist_first_item_get(gl); it;
it = elm_genlist_item_next_get(it))
{
if (o == elm_object_item_data_get(it))
{
// if this is a change for the obj for an "initial"
// request to the user for ok/pin etc. then change it
// and do the updates
if (alert)
{
elm_genlist_item_update(it);
elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
}
// otherwise only do changes to items with no agent
// requests pending so we dont delete focused widgets
// or entry widgets etc.
else if (!o->agent_request)
elm_genlist_item_update(it);
break;
}
}
}
_devices_eval();
}
const Eina_List *
ebluez5_popup_adapters_get(void)
{
return (const Eina_List *)adapters;
}