blue4 - remove. obsolete now and bluez5 has replaced it
This commit is contained in:
parent
b4cfada8e8
commit
14a30c74b0
1
TODO
1
TODO
|
@ -1,5 +1,4 @@
|
|||
TODO:
|
||||
* bluez4: remove as it's obsolete
|
||||
* scriptlets: stdin/out module that provides gui services to some
|
||||
back-end script or process where e just talks via stdin/out.
|
||||
things to provide:
|
||||
|
|
|
@ -107,10 +107,6 @@ option('battery',
|
|||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'enable battery module: (default=true)')
|
||||
option('bluez4',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'enable bluez4 module: (default=true)')
|
||||
option('bluez5',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
|
|
|
@ -878,7 +878,6 @@ _e_module_whitelist_check(void)
|
|||
{
|
||||
"backlight",
|
||||
"battery",
|
||||
"bluez4",
|
||||
"bluez5",
|
||||
"clock",
|
||||
"conf",
|
||||
|
|
|
@ -1,261 +0,0 @@
|
|||
#include <inttypes.h>
|
||||
#include "e.h"
|
||||
#include "ebluez4.h"
|
||||
#include "agent.h"
|
||||
|
||||
#define AGENT_INTERFACE "org.bluez.Agent"
|
||||
#define BLUEZ_ERROR_FAILED "org.bluez.Error.Failed"
|
||||
#define GET_ERROR_MSG "eldbus_message_arguments_get() error"
|
||||
#define BLUEZ_ERROR_REJECTED "org.bluez.Error.Rejected"
|
||||
#define REJECTED_MSG "Request was rejected"
|
||||
|
||||
static Eldbus_Connection *bluez_conn;
|
||||
static char buf[1024];
|
||||
|
||||
/* Local Functions */
|
||||
static void
|
||||
_reply(Eldbus_Message *message, Eldbus_Message *reply)
|
||||
{
|
||||
eldbus_connection_send(bluez_conn, reply, NULL, NULL, -1);
|
||||
eldbus_message_unref(message);
|
||||
}
|
||||
|
||||
static void
|
||||
_pincode_ok(void *data, char *text)
|
||||
{
|
||||
Eldbus_Message *message = data;
|
||||
Eldbus_Message *reply = eldbus_message_method_return_new(message);
|
||||
eldbus_message_arguments_append(reply, "s", text);
|
||||
_reply(message, reply);
|
||||
}
|
||||
|
||||
static void
|
||||
_passkey_ok(void *data, char *text)
|
||||
{
|
||||
Eldbus_Message *message = data;
|
||||
uint32_t passkey = (uint32_t)atoi(text);
|
||||
Eldbus_Message *reply = eldbus_message_method_return_new(message);
|
||||
eldbus_message_arguments_append(reply, "u", passkey);
|
||||
_reply(message, reply);
|
||||
}
|
||||
|
||||
static void
|
||||
_cancel(void *data)
|
||||
{
|
||||
Eldbus_Message *message = data;
|
||||
Eldbus_Message *reply = eldbus_message_error_new(message,
|
||||
BLUEZ_ERROR_REJECTED, REJECTED_MSG);
|
||||
_reply(message, reply);
|
||||
}
|
||||
|
||||
static E_Dialog *
|
||||
_create_dialog(const char *title, const char *msg,
|
||||
const char *icon, const char *class)
|
||||
{
|
||||
E_Dialog *dialog;
|
||||
|
||||
dialog = e_dialog_new(NULL, title, class);
|
||||
e_dialog_title_set(dialog, _(title));
|
||||
e_dialog_icon_set(dialog, icon, 64);
|
||||
e_dialog_text_set(dialog, msg);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
static void
|
||||
_display_msg(const char *title, const char *msg)
|
||||
{
|
||||
E_Dialog *dialog = _create_dialog(title, msg, "view-hidden-files",
|
||||
"display");
|
||||
e_dialog_button_add(dialog, _("OK"), NULL, NULL, NULL);
|
||||
e_dialog_show(dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
_reply_and_del_dialog(Eldbus_Message *reply, E_Dialog *dialog)
|
||||
{
|
||||
Eldbus_Message *message;
|
||||
|
||||
if (!dialog) return;
|
||||
if (!(message = dialog->data)) return;
|
||||
_reply(message, reply);
|
||||
e_object_del(E_OBJECT(dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
_reject(void *data EINA_UNUSED, E_Dialog *dialog)
|
||||
{
|
||||
const Eldbus_Message *msg = dialog->data;
|
||||
Eldbus_Message *reply = eldbus_message_error_new(msg, BLUEZ_ERROR_REJECTED,
|
||||
REJECTED_MSG);
|
||||
_reply_and_del_dialog(reply, dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Dialog *dialog = data;
|
||||
_reject(NULL, dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
_ok(void *data EINA_UNUSED, E_Dialog *dialog)
|
||||
{
|
||||
const Eldbus_Message *msg = dialog->data;
|
||||
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
|
||||
evas_object_event_callback_del_full(dialog->win, EVAS_CALLBACK_DEL, _close, dialog);
|
||||
_reply_and_del_dialog(reply, dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
_ask(const char *title, const char *ask_msg, const char *ok_label,
|
||||
Eldbus_Message *eldbus_message)
|
||||
{
|
||||
E_Dialog *dialog = _create_dialog(title, ask_msg, "dialog-ask", "ask");
|
||||
dialog->data = eldbus_message;
|
||||
evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _close, dialog);
|
||||
e_dialog_button_add(dialog, ok_label, NULL, _ok, NULL);
|
||||
e_dialog_button_add(dialog, _("Reject"), NULL, _reject, NULL);
|
||||
e_dialog_show(dialog);
|
||||
}
|
||||
|
||||
/* Implementation of agent API */
|
||||
static Eldbus_Message *
|
||||
_agent_release(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
DBG("Agent Released.");
|
||||
return eldbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_request_pin_code(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
Eldbus_Message *msg = (Eldbus_Message *)message;
|
||||
eldbus_message_ref(msg);
|
||||
e_entry_dialog_show(_("Pin Code Requested"), NULL,
|
||||
_("Enter the PinCode above. It should have 1-16 "
|
||||
"characters and can be alphanumeric."), "0000",
|
||||
_("OK"), _("Cancel"), _pincode_ok, _cancel, msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_request_passkey(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
Eldbus_Message *msg = (Eldbus_Message *)message;
|
||||
eldbus_message_ref(msg);
|
||||
e_entry_dialog_show(_("Passkey Requested"), NULL,
|
||||
_("Enter the Passkey above. "
|
||||
"It should be a numeric value between 0-999999."),
|
||||
"0", _("OK"), _("Cancel"), _passkey_ok, _cancel, msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_display_passkey(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
const char *device;
|
||||
uint32_t passkey;
|
||||
uint16_t entered;
|
||||
Device *dev;
|
||||
|
||||
if(!eldbus_message_arguments_get(message, "ouq", &device, &passkey, &entered))
|
||||
return eldbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
dev = eina_list_search_unsorted(ctxt->devices, ebluez4_dev_path_cmp, device);
|
||||
snprintf(buf, sizeof(buf), _("%d keys were typed on %s. Passkey is %06d"),
|
||||
entered, dev->name, passkey);
|
||||
_display_msg(N_("Display Passkey"), buf);
|
||||
return eldbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_display_pin_code(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
const char *device, *pincode;
|
||||
Device *dev;
|
||||
|
||||
if(!eldbus_message_arguments_get(message, "os", &device, &pincode))
|
||||
return eldbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
dev = eina_list_search_unsorted(ctxt->devices, ebluez4_dev_path_cmp, device);
|
||||
snprintf(buf, sizeof(buf), _("Pincode for %s is %s"), dev->name, pincode);
|
||||
_display_msg(N_("Display Pincode"), buf);
|
||||
return eldbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_request_confirmation(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
const char *device;
|
||||
uint32_t passkey;
|
||||
Device *dev;
|
||||
|
||||
if(!eldbus_message_arguments_get(message, "ou", &device, &passkey))
|
||||
return eldbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
dev = eina_list_search_unsorted(ctxt->devices, ebluez4_dev_path_cmp, device);
|
||||
snprintf(buf, sizeof(buf), _("%06d is the passkey presented in %s?"),
|
||||
passkey, dev->name);
|
||||
eldbus_message_ref((Eldbus_Message *)message);
|
||||
_ask(N_("Confirm Request"), buf, _("Confirm"), (Eldbus_Message *)message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_authorize(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
const char *device, *uuid;
|
||||
Device *dev;
|
||||
|
||||
if(!eldbus_message_arguments_get(message, "os", &device, &uuid))
|
||||
return eldbus_message_error_new(message, BLUEZ_ERROR_FAILED, GET_ERROR_MSG);
|
||||
dev = eina_list_search_unsorted(ctxt->devices, ebluez4_dev_path_cmp, device);
|
||||
snprintf(buf, sizeof(buf), _("Grant permission for %s to connect?"),
|
||||
dev->name);
|
||||
eldbus_message_ref((Eldbus_Message *)message);
|
||||
_ask(N_("Authorize Connection"), buf, _("Grant"), (Eldbus_Message *)message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Eldbus_Message *
|
||||
_agent_cancel(const Eldbus_Service_Interface *iface EINA_UNUSED,
|
||||
const Eldbus_Message *message)
|
||||
{
|
||||
DBG("Request canceled.");
|
||||
return eldbus_message_method_return_new(message);
|
||||
}
|
||||
|
||||
static const Eldbus_Method agent_methods[] = {
|
||||
{ "Release", NULL, NULL, _agent_release, 0 },
|
||||
{ "RequestPinCode", ELDBUS_ARGS({"o", "device"}),
|
||||
ELDBUS_ARGS({"s", "pincode"}), _agent_request_pin_code, 0 },
|
||||
{ "RequestPasskey", ELDBUS_ARGS({"o", "device"}),
|
||||
ELDBUS_ARGS({"u", "passkey"}), _agent_request_passkey, 0 },
|
||||
{ "DisplayPasskey",
|
||||
ELDBUS_ARGS({"o", "device"},{"u", "passkey"},{"q", "entered"}),
|
||||
NULL, _agent_display_passkey, 0 },
|
||||
{ "DisplayPinCode", ELDBUS_ARGS({"o", "device"},{"s", "pincode"}),
|
||||
NULL, _agent_display_pin_code, 0 },
|
||||
{ "RequestConfirmation", ELDBUS_ARGS({"o", "device"},{"u", "passkey"}),
|
||||
NULL, _agent_request_confirmation, 0 },
|
||||
{ "Authorize", ELDBUS_ARGS({"o", "device"},{"s", "uuid"}),
|
||||
NULL, _agent_authorize, 0 },
|
||||
{ "Cancel", NULL, NULL, _agent_cancel, 0 },
|
||||
{ NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static const Eldbus_Service_Interface_Desc agent_iface = {
|
||||
AGENT_INTERFACE, agent_methods, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
void ebluez4_register_agent_interfaces(Eldbus_Connection *conn)
|
||||
{
|
||||
bluez_conn = conn;
|
||||
eldbus_service_interface_register(conn, AGENT_PATH, &agent_iface);
|
||||
eldbus_service_interface_register(conn, REMOTE_AGENT_PATH, &agent_iface);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#define AGENT_PATH "/org/bluez/Agent"
|
||||
#define REMOTE_AGENT_PATH "/org/bluez/RemoteAgent"
|
||||
|
||||
void ebluez4_register_agent_interfaces(Eldbus_Connection *conn);
|
Binary file not shown.
|
@ -1,837 +0,0 @@
|
|||
#include <e.h>
|
||||
#include <Eldbus.h>
|
||||
#include "e_mod_main.h"
|
||||
#include "ebluez4.h"
|
||||
|
||||
/* Local Variables */
|
||||
static Ecore_Exe *autolock_exe = NULL;
|
||||
static Ecore_Poller *autolock_poller = NULL;
|
||||
static Ecore_Event_Handler *autolock_die = NULL;
|
||||
static Ecore_Event_Handler *autolock_out = NULL;
|
||||
static Ecore_Event_Handler *autolock_desklock = NULL;
|
||||
static Eina_Bool autolock_initted = EINA_FALSE;
|
||||
static Eina_Bool autolock_waiting = EINA_TRUE;
|
||||
|
||||
static Eina_List *instances = NULL;
|
||||
static E_Module *mod = NULL;
|
||||
static char tmpbuf[1024];
|
||||
|
||||
/* Local config */
|
||||
static E_Config_DD *conf_edd = NULL;
|
||||
Config *ebluez4_config = NULL;
|
||||
|
||||
E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, "Bluez4"};
|
||||
|
||||
/* Local Functions */
|
||||
static Eina_Bool
|
||||
_ebluez_l2ping_poller(void *data EINA_UNUSED)
|
||||
{
|
||||
Eina_Strbuf *buf;
|
||||
const char *tmp = NULL;
|
||||
|
||||
autolock_poller = NULL;
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
if (e_desklock_state_get())
|
||||
{
|
||||
if (!autolock_waiting)
|
||||
tmp = ebluez4_config->unlock_dev_addr;
|
||||
else
|
||||
tmp = ebluez4_config->lock_dev_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!autolock_waiting)
|
||||
tmp = ebluez4_config->lock_dev_addr;
|
||||
else
|
||||
tmp = ebluez4_config->unlock_dev_addr;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
eina_strbuf_append_printf(buf, "%s/enlightenment/utils/enlightenment_sys l2ping %s",
|
||||
e_prefix_lib_get(), tmp);
|
||||
autolock_exe = ecore_exe_run(eina_strbuf_string_get(buf), NULL);
|
||||
}
|
||||
|
||||
eina_strbuf_free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_search_dialog_del(Instance *inst)
|
||||
{
|
||||
if (!inst->search_dialog) return;
|
||||
e_object_del(E_OBJECT(inst->search_dialog));
|
||||
inst->search_dialog = NULL;
|
||||
inst->found_list = NULL;
|
||||
|
||||
if (ctxt->adap_obj)
|
||||
{
|
||||
ebluez4_stop_discovery();
|
||||
DBG("Stopping discovery...");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_search_dialog_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Dialog *dialog = data;
|
||||
_ebluez4_search_dialog_del(dialog->data);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_paired(void *data, Eina_Bool success, const char *err_msg)
|
||||
{
|
||||
Instance *inst = data;
|
||||
if (success)
|
||||
_ebluez4_search_dialog_del(inst);
|
||||
else
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_pair(void *data)
|
||||
{
|
||||
Instance *inst = data;
|
||||
const char *addr = e_widget_ilist_selected_value_get(inst->found_list);
|
||||
|
||||
if(!addr)
|
||||
return;
|
||||
ebluez4_pair_with_device(addr, _ebluez4_cb_paired, inst);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_search(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
E_Dialog *dialog;
|
||||
Evas *evas;
|
||||
|
||||
if (inst->search_dialog)
|
||||
_ebluez4_search_dialog_del(inst);
|
||||
|
||||
dialog = e_dialog_new(NULL, "Search Dialog", "search");
|
||||
e_dialog_title_set(dialog, _("Searching for Devices..."));
|
||||
evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _ebluez4_cb_search_dialog_del, dialog);
|
||||
e_dialog_resizable_set(dialog, EINA_TRUE);
|
||||
|
||||
evas = evas_object_evas_get(dialog->win);
|
||||
|
||||
inst->found_list = e_widget_ilist_add(evas, 100, 0, NULL);
|
||||
|
||||
e_dialog_content_set(dialog, inst->found_list, 300, 200);
|
||||
|
||||
e_dialog_show(dialog);
|
||||
|
||||
dialog->data = inst;
|
||||
inst->search_dialog = dialog;
|
||||
|
||||
ebluez4_start_discovery();
|
||||
DBG("Starting discovery...");
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_adap_settings_dialog_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Dialog *dialog = data;
|
||||
ebluez4_adapter_settings_del(dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_check_changed(void *data, Evas_Object *obj, const char *prop_name)
|
||||
{
|
||||
Adapter *adap = data;
|
||||
Eina_Bool value = e_widget_check_checked_get(obj);
|
||||
ebluez4_adapter_property_set(adap, prop_name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_powered_changed(void *data, Evas_Object *obj, void *info EINA_UNUSED)
|
||||
{
|
||||
_ebluez4_check_changed(data, obj, "Powered");
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_visible_changed(void *data, Evas_Object *obj, void *info EINA_UNUSED)
|
||||
{
|
||||
_ebluez4_check_changed(data, obj, "Discoverable");
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_pairable_changed(void *data, Evas_Object *obj, void *info EINA_UNUSED)
|
||||
{
|
||||
_ebluez4_check_changed(data, obj, "Pairable");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_ebluez4_cb_adap_settings(void *data)
|
||||
{
|
||||
Adapter *adap = data;
|
||||
E_Dialog *dialog;
|
||||
Evas *evas;
|
||||
Evas_Object *list;
|
||||
Evas_Object *ck;
|
||||
int mw, mh;
|
||||
Eina_List *ck_list = NULL;
|
||||
|
||||
if (adap->dialog)
|
||||
ebluez4_adapter_settings_del(adap->dialog);
|
||||
|
||||
dialog = e_dialog_new(NULL, "Adapter Dialog", "adapter");
|
||||
e_dialog_title_set(dialog, _("Adapter Settings"));
|
||||
evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _ebluez4_cb_adap_settings_dialog_del, dialog);
|
||||
e_dialog_resizable_set(dialog, EINA_TRUE);
|
||||
|
||||
evas = evas_object_evas_get(dialog->win);
|
||||
|
||||
list = e_widget_list_add(evas, 0, 0);
|
||||
|
||||
ck = e_widget_check_add(evas, _("Default"), NULL);
|
||||
e_widget_check_checked_set(ck, adap->is_default);
|
||||
e_widget_list_object_append(list, ck, 0, 0, 0);
|
||||
|
||||
ck = e_widget_check_add(evas, _("Powered"), &(adap->powered_checked));
|
||||
e_widget_check_checked_set(ck, adap->powered);
|
||||
e_widget_list_object_append(list, ck, 0, 0, 0);
|
||||
evas_object_smart_callback_add(ck, "changed", _ebluez4_powered_changed,
|
||||
adap);
|
||||
ck_list = eina_list_append(ck_list, ck);
|
||||
|
||||
|
||||
ck = e_widget_check_add(evas, _("Visible"), &(adap->visible_checked));
|
||||
e_widget_check_checked_set(ck, adap->visible);
|
||||
e_widget_list_object_append(list, ck, 0, 0, 0);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_ebluez4_visible_changed, adap);
|
||||
ck_list = eina_list_append(ck_list, ck);
|
||||
|
||||
ck = e_widget_check_add(evas, _("Pairable"), &(adap->pairable_checked));
|
||||
e_widget_check_checked_set(ck, adap->pairable);
|
||||
e_widget_list_object_append(list, ck, 0, 0, 0);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_ebluez4_pairable_changed, adap);
|
||||
ck_list = eina_list_append(ck_list, ck);
|
||||
|
||||
e_dialog_show(dialog);
|
||||
e_widget_size_min_get(list, &mw, &mh);
|
||||
if(mw < 150) mw = 150;
|
||||
e_dialog_content_set(dialog, list, mw, mh);
|
||||
|
||||
dialog->data = adap;
|
||||
adap->dialog = dialog;
|
||||
e_object_data_set(E_OBJECT(dialog), ck_list);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_adap_list_dialog_del(Instance *inst)
|
||||
{
|
||||
if (!inst->adapters_dialog) return;
|
||||
e_object_del(E_OBJECT(inst->adapters_dialog));
|
||||
inst->adapters_dialog = NULL;
|
||||
inst->adap_list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_adap_list_dialog_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
E_Dialog *dialog = data;
|
||||
_ebluez4_adap_list_dialog_del(dialog->data);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_adap_list(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
Instance *inst = data;
|
||||
E_Dialog *dialog;
|
||||
Evas *evas;
|
||||
|
||||
if (inst->adapters_dialog)
|
||||
_ebluez4_adap_list_dialog_del(inst);
|
||||
|
||||
dialog = e_dialog_new(NULL, "Adapters Dialog", "adapters");
|
||||
e_dialog_title_set(dialog, _("Adapters Available"));
|
||||
evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _ebluez4_cb_adap_list_dialog_del, dialog);
|
||||
e_dialog_resizable_set(dialog, EINA_TRUE);
|
||||
|
||||
evas = evas_object_evas_get(dialog->win);
|
||||
|
||||
inst->adap_list = e_widget_ilist_add(evas, 0, 0, NULL);
|
||||
|
||||
e_dialog_content_set(dialog, inst->adap_list, 250, 220);
|
||||
ebluez4_update_instances(ctxt->adapters);
|
||||
|
||||
e_dialog_show(dialog);
|
||||
|
||||
dialog->data = inst;
|
||||
inst->adapters_dialog = dialog;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_connect(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
ebluez4_connect_to_device(data);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_disconnect(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
ebluez4_disconnect_device(data);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_forget(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
Device *dev = data;
|
||||
ebluez4_remove_device(dev->obj);
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUETOOTH
|
||||
static void
|
||||
_ebluez4_cb_lock(void *data,
|
||||
E_Menu *m EINA_UNUSED,
|
||||
E_Menu_Item *mi)
|
||||
{
|
||||
Device *dev = data;
|
||||
int tog;
|
||||
|
||||
tog = e_menu_item_toggle_get(mi);
|
||||
eina_stringshare_replace(&ebluez4_config->lock_dev_addr,
|
||||
tog ? dev->addr : NULL);
|
||||
e_config_save_queue();
|
||||
|
||||
if (autolock_exe)
|
||||
ecore_exe_kill(autolock_exe);
|
||||
autolock_exe = NULL;
|
||||
if (!autolock_poller && (ebluez4_config->lock_dev_addr || ebluez4_config->unlock_dev_addr))
|
||||
autolock_poller = ecore_poller_add(ECORE_POLLER_CORE, 32, _ebluez_l2ping_poller, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_unlock(void *data,
|
||||
E_Menu *m EINA_UNUSED,
|
||||
E_Menu_Item *mi)
|
||||
{
|
||||
Device *dev = data;
|
||||
int tog;
|
||||
|
||||
tog = e_menu_item_toggle_get(mi);
|
||||
eina_stringshare_replace(&ebluez4_config->unlock_dev_addr,
|
||||
tog ? dev->addr : NULL);
|
||||
e_config_save_queue();
|
||||
|
||||
if (autolock_exe)
|
||||
ecore_exe_kill(autolock_exe);
|
||||
autolock_exe = NULL;
|
||||
if (!autolock_poller && (ebluez4_config->lock_dev_addr || ebluez4_config->unlock_dev_addr))
|
||||
autolock_poller = ecore_poller_add(ECORE_POLLER_CORE, 32, _ebluez_l2ping_poller, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_menu_post_deactivate(void *data EINA_UNUSED, E_Menu *m)
|
||||
{
|
||||
Eina_List *iter;
|
||||
E_Menu_Item *mi;
|
||||
Instance *inst = data;
|
||||
|
||||
if (!(m->parent_item) || !(m->parent_item->menu))
|
||||
{
|
||||
e_gadcon_locked_set(inst->gcc->gadcon, 0);
|
||||
inst->menu = NULL;
|
||||
}
|
||||
EINA_LIST_FOREACH(m->items, iter, mi)
|
||||
if (mi->submenu) e_menu_deactivate(mi->submenu);
|
||||
e_object_del(E_OBJECT(m));
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ebluez4_add_devices(Instance *inst)
|
||||
{
|
||||
Device *dev;
|
||||
Eina_List *iter;
|
||||
E_Menu *m, *subm;
|
||||
E_Menu_Item *mi, *submi;
|
||||
Eina_Bool ret = EINA_FALSE;
|
||||
|
||||
m = inst->menu;
|
||||
|
||||
EINA_LIST_FOREACH(ctxt->devices, iter, dev)
|
||||
if (dev->paired)
|
||||
{
|
||||
mi = e_menu_item_new(m);
|
||||
e_menu_item_label_set(mi, _("Paired Devices"));
|
||||
e_menu_item_disabled_set(mi, EINA_TRUE);
|
||||
ret = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(ctxt->devices, iter, dev)
|
||||
if (dev->paired)
|
||||
{
|
||||
#ifdef HAVE_BLUETOOTH
|
||||
Eina_Bool chk;
|
||||
#endif
|
||||
|
||||
mi = e_menu_item_new(m);
|
||||
e_menu_item_label_set(mi, dev->name);
|
||||
e_menu_item_check_set(mi, 1);
|
||||
subm = e_menu_new();
|
||||
e_menu_post_deactivate_callback_set(subm, _menu_post_deactivate,
|
||||
inst);
|
||||
e_menu_item_submenu_set(mi, subm);
|
||||
submi = e_menu_item_new(subm);
|
||||
if (dev->connected)
|
||||
{
|
||||
e_menu_item_toggle_set(mi, 1);
|
||||
e_menu_item_label_set(submi, _("Disconnect"));
|
||||
e_menu_item_callback_set(submi, _ebluez4_cb_disconnect, dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
e_menu_item_toggle_set(mi, 0);
|
||||
e_menu_item_label_set(submi, _("Connect"));
|
||||
e_menu_item_callback_set(submi, _ebluez4_cb_connect, dev);
|
||||
}
|
||||
submi = e_menu_item_new(subm);
|
||||
e_menu_item_label_set(submi, _("Forget"));
|
||||
e_menu_item_callback_set(submi, _ebluez4_cb_forget, dev);
|
||||
|
||||
#ifdef HAVE_BLUETOOTH
|
||||
if (autolock_initted)
|
||||
{
|
||||
/* Auto lock when away */
|
||||
submi = e_menu_item_new(subm);
|
||||
e_menu_item_check_set(submi, 1);
|
||||
e_menu_item_label_set(submi, _("Lock on disconnect"));
|
||||
e_menu_item_callback_set(submi, _ebluez4_cb_lock, dev);
|
||||
chk = ebluez4_config->lock_dev_addr && dev->addr &&
|
||||
!strcmp(dev->addr, ebluez4_config->lock_dev_addr);
|
||||
e_menu_item_toggle_set(submi, !!chk);
|
||||
|
||||
submi = e_menu_item_new(subm);
|
||||
e_menu_item_check_set(submi, 1);
|
||||
e_menu_item_label_set(submi, _("Unlock on disconnect"));
|
||||
e_menu_item_callback_set(submi, _ebluez4_cb_unlock, dev);
|
||||
chk = ebluez4_config->unlock_dev_addr && dev->addr &&
|
||||
!strcmp(dev->addr, ebluez4_config->unlock_dev_addr);
|
||||
e_menu_item_toggle_set(submi, !!chk);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_menu_new(Instance *inst)
|
||||
{
|
||||
E_Menu *m;
|
||||
E_Menu_Item *mi;
|
||||
|
||||
m = e_menu_new();
|
||||
e_menu_post_deactivate_callback_set(m, _menu_post_deactivate, inst);
|
||||
e_menu_title_set(m, _("Bluez4"));
|
||||
inst->menu = m;
|
||||
|
||||
if (_ebluez4_add_devices(inst))
|
||||
{
|
||||
mi = e_menu_item_new(m);
|
||||
e_menu_item_separator_set(mi, 1);
|
||||
}
|
||||
|
||||
mi = e_menu_item_new(m);
|
||||
e_menu_item_label_set(mi, _("Search New Devices"));
|
||||
e_menu_item_callback_set(mi, _ebluez4_cb_search, inst);
|
||||
|
||||
mi = e_menu_item_new(m);
|
||||
e_menu_item_label_set(mi, _("Adapter Settings"));
|
||||
e_menu_item_callback_set(mi, _ebluez4_cb_adap_list, inst);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_cb_mouse_down(void *data, Evas *evas EINA_UNUSED,
|
||||
Evas_Object *obj EINA_UNUSED, void *event)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
Evas_Event_Mouse_Down *ev = event;
|
||||
int x, y;
|
||||
|
||||
if (!(inst = data)) return;
|
||||
if (ev->button != 1) return;
|
||||
if (!ctxt->adap_obj) return;
|
||||
|
||||
_ebluez4_menu_new(inst);
|
||||
|
||||
e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
|
||||
e_menu_activate_mouse(inst->menu,
|
||||
e_zone_current_get(),
|
||||
x + ev->output.x, y + ev->output.y, 1, 1,
|
||||
E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
|
||||
evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
|
||||
EVAS_BUTTON_NONE, ev->timestamp, NULL);
|
||||
|
||||
e_gadcon_locked_set(inst->gcc->gadcon, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_ebluez4_set_mod_icon(Evas_Object *base)
|
||||
{
|
||||
char edj_path[4096];
|
||||
char *group;
|
||||
|
||||
snprintf(edj_path, sizeof(edj_path), "%s/e-module-bluez4.edj", mod->dir);
|
||||
if (ctxt->adap_obj)
|
||||
group = "e/modules/bluez4/main";
|
||||
else
|
||||
group = "e/modules/bluez4/inactive";
|
||||
|
||||
if (!e_theme_edje_object_set(base, "base/theme/modules/bluez4", group))
|
||||
edje_object_file_set(base, edj_path, group);
|
||||
}
|
||||
|
||||
/* Gadcon */
|
||||
static E_Gadcon_Client *
|
||||
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
|
||||
inst = E_NEW(Instance, 1);
|
||||
|
||||
inst->o_bluez4 = edje_object_add(gc->evas);
|
||||
_ebluez4_set_mod_icon(inst->o_bluez4);
|
||||
|
||||
inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->o_bluez4);
|
||||
inst->gcc->data = inst;
|
||||
|
||||
e_gadcon_client_util_menu_attach(inst->gcc);
|
||||
evas_object_event_callback_add(inst->o_bluez4, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_ebluez4_cb_mouse_down, inst);
|
||||
|
||||
instances = eina_list_append(instances, inst);
|
||||
|
||||
return inst->gcc;
|
||||
}
|
||||
|
||||
static void
|
||||
_gc_shutdown(E_Gadcon_Client *gcc)
|
||||
{
|
||||
Instance *inst = NULL;
|
||||
|
||||
if (!(inst = gcc->data)) return;
|
||||
instances = eina_list_remove(instances, inst);
|
||||
|
||||
if (inst->o_bluez4)
|
||||
{
|
||||
evas_object_event_callback_del(inst->o_bluez4, EVAS_CALLBACK_MOUSE_DOWN,
|
||||
_ebluez4_cb_mouse_down);
|
||||
evas_object_del(inst->o_bluez4);
|
||||
}
|
||||
|
||||
if (inst->menu) e_menu_deactivate(inst->menu);
|
||||
_ebluez4_search_dialog_del(inst);
|
||||
_ebluez4_adap_list_dialog_del(inst);
|
||||
|
||||
E_FREE(inst);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
|
||||
{
|
||||
snprintf(tmpbuf, sizeof(tmpbuf), "bluez4.%d", eina_list_count(instances));
|
||||
return tmpbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED)
|
||||
{
|
||||
e_gadcon_client_aspect_set(gcc, 16, 16);
|
||||
e_gadcon_client_min_size_set(gcc, 16, 16);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
|
||||
{
|
||||
return _("Bluez4");
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas)
|
||||
{
|
||||
Evas_Object *o = NULL;
|
||||
char buf[4096];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/e-module-bluez4.edj", mod->dir);
|
||||
|
||||
o = edje_object_add(evas);
|
||||
|
||||
edje_object_file_set(o, buf, "icon");
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static const E_Gadcon_Client_Class _gc_class =
|
||||
{
|
||||
GADCON_CLIENT_CLASS_VERSION, "bluez4",
|
||||
{_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon,
|
||||
_gc_id_new, NULL, NULL},
|
||||
E_GADCON_CLIENT_STYLE_PLAIN
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_ebluez_exe_die(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event_info)
|
||||
{
|
||||
Ecore_Exe_Event_Del *ev = event_info;
|
||||
|
||||
if (ev->exe != autolock_exe)
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
if (!autolock_initted)
|
||||
{
|
||||
if (ev->exit_code == 0)
|
||||
{
|
||||
autolock_initted = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e_desklock_state_get()) // Locked state ?
|
||||
{
|
||||
if (!autolock_waiting)
|
||||
{
|
||||
// Not waiting yet for the auto unlock device to appear before unlock
|
||||
if (ev->exit_code == 0 && ebluez4_config->unlock_dev_addr)
|
||||
{
|
||||
e_desklock_hide();
|
||||
}
|
||||
}
|
||||
else if (ev->exit_code == 1)
|
||||
{
|
||||
// The device just disapeared, now we can wait for it to disapear
|
||||
autolock_waiting = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!autolock_waiting)
|
||||
{
|
||||
// Not waiting yet for the auto lock device to disappear before locking
|
||||
if (ev->exit_code == 1 && ebluez4_config->lock_dev_addr)
|
||||
{
|
||||
e_desklock_show(EINA_FALSE);
|
||||
}
|
||||
}
|
||||
else if (ev->exit_code == 0)
|
||||
{
|
||||
// The device just appeared, now we can wait for it to disapear
|
||||
autolock_waiting = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (autolock_initted)
|
||||
autolock_poller = ecore_poller_add(ECORE_POLLER_CORE, 32, _ebluez_l2ping_poller, NULL);
|
||||
|
||||
autolock_exe = NULL;
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ebluez_exe_out(void *data EINA_UNUSED, int ev_type EINA_UNUSED,
|
||||
void *ev EINA_UNUSED)
|
||||
{
|
||||
/* FIXME: Need experiment, but we should be able to use latency to somehow estimate distance, right ? */
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ebluez_desklock(void *data EINA_UNUSED, int ev_type EINA_UNUSED,
|
||||
void *ev EINA_UNUSED)
|
||||
{
|
||||
if (autolock_exe)
|
||||
ecore_exe_kill(autolock_exe);
|
||||
autolock_exe = NULL;
|
||||
|
||||
if (!autolock_poller && autolock_initted && (ebluez4_config->lock_dev_addr || ebluez4_config->unlock_dev_addr))
|
||||
autolock_poller = ecore_poller_add(ECORE_POLLER_CORE, 32, _ebluez_l2ping_poller, NULL);
|
||||
|
||||
autolock_waiting = EINA_TRUE;
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
/* Module Functions */
|
||||
E_API void *
|
||||
e_modapi_init(E_Module *m)
|
||||
{
|
||||
Eina_Strbuf *buf;
|
||||
|
||||
mod = m;
|
||||
|
||||
conf_edd = E_CONFIG_DD_NEW("Config", Config);
|
||||
#undef T
|
||||
#undef D
|
||||
#define T Config
|
||||
#define D conf_edd
|
||||
E_CONFIG_VAL(D, T, lock_dev_addr, STR);
|
||||
E_CONFIG_VAL(D, T, unlock_dev_addr, STR);
|
||||
|
||||
ebluez4_config = e_config_domain_load("module.ebluez4", conf_edd);
|
||||
if (!ebluez4_config)
|
||||
ebluez4_config = E_NEW(Config, 1);
|
||||
|
||||
ebluez4_eldbus_init();
|
||||
|
||||
e_gadcon_provider_register(&_gc_class);
|
||||
|
||||
autolock_die = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _ebluez_exe_die, NULL);
|
||||
autolock_out = ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _ebluez_exe_out, NULL);
|
||||
autolock_desklock = ecore_event_handler_add(E_EVENT_DESKLOCK, _ebluez_desklock, NULL);
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
eina_strbuf_append_printf(buf, "%s/enlightenment/utils/enlightenment_sys -t l2ping",
|
||||
e_prefix_lib_get());
|
||||
autolock_exe = ecore_exe_run(eina_strbuf_string_get(buf), NULL);
|
||||
eina_strbuf_free(buf);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
E_CONFIG_DD_FREE(conf_edd);
|
||||
|
||||
if (autolock_exe) ecore_exe_kill(autolock_exe);
|
||||
autolock_exe = NULL;
|
||||
E_FREE_FUNC(autolock_poller, ecore_poller_del);
|
||||
|
||||
ecore_event_handler_del(autolock_die);
|
||||
ecore_event_handler_del(autolock_out);
|
||||
ecore_event_handler_del(autolock_desklock);
|
||||
|
||||
eina_stringshare_del(ebluez4_config->lock_dev_addr);
|
||||
eina_stringshare_del(ebluez4_config->unlock_dev_addr);
|
||||
free(ebluez4_config);
|
||||
ebluez4_config = NULL;
|
||||
|
||||
ebluez4_eldbus_shutdown();
|
||||
e_gadcon_provider_unregister(&_gc_class);
|
||||
return 1;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_save(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
e_config_domain_save("module.ebluez4",
|
||||
conf_edd, ebluez4_config);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
void
|
||||
ebluez4_update_inst(Evas_Object *dest, Eina_List *src, Instance *inst)
|
||||
{
|
||||
Device *dev;
|
||||
Evas_Object *o_type;
|
||||
Adapter *adap;
|
||||
Eina_List *iter;
|
||||
|
||||
e_widget_ilist_freeze(dest);
|
||||
e_widget_ilist_clear(dest);
|
||||
|
||||
if (src == ctxt->found_devices)
|
||||
{
|
||||
EINA_LIST_FOREACH(src, iter, dev)
|
||||
if (!dev->paired)
|
||||
{
|
||||
o_type = e_widget_label_add(evas_object_evas_get(dest),
|
||||
dev->type);
|
||||
e_widget_ilist_append_full(dest, NULL, o_type, dev->name,
|
||||
_ebluez4_cb_pair, inst, dev->addr);
|
||||
|
||||
}
|
||||
}
|
||||
else if (src == ctxt->adapters)
|
||||
{
|
||||
EINA_LIST_FOREACH(src, iter, adap)
|
||||
e_widget_ilist_append(dest, NULL, adap->name,
|
||||
_ebluez4_cb_adap_settings, adap, NULL);
|
||||
}
|
||||
|
||||
e_widget_ilist_go(dest);
|
||||
e_widget_ilist_thaw(dest);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_update_instances(Eina_List *src)
|
||||
{
|
||||
Eina_List *iter;
|
||||
Instance *inst;
|
||||
|
||||
EINA_LIST_FOREACH(instances, iter, inst)
|
||||
if (src == ctxt->found_devices && inst->found_list)
|
||||
ebluez4_update_inst(inst->found_list, src, inst);
|
||||
else if (src == ctxt->adapters && inst->adap_list)
|
||||
ebluez4_update_inst(inst->adap_list, src, inst);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_update_all_gadgets_visibility(void)
|
||||
{
|
||||
Eina_List *iter;
|
||||
Instance *inst;
|
||||
|
||||
if (ctxt->adap_obj)
|
||||
EINA_LIST_FOREACH(instances, iter, inst)
|
||||
_ebluez4_set_mod_icon(inst->o_bluez4);
|
||||
else
|
||||
EINA_LIST_FOREACH(instances, iter, inst)
|
||||
{
|
||||
_ebluez4_set_mod_icon(inst->o_bluez4);
|
||||
if (inst->menu) e_menu_deactivate(inst->menu);
|
||||
_ebluez4_search_dialog_del(inst);
|
||||
_ebluez4_adap_list_dialog_del(inst);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_show_error(const char *err_name, const char *err_msg)
|
||||
{
|
||||
snprintf(tmpbuf, sizeof(tmpbuf), "%s: %s.", err_name, err_msg);
|
||||
e_util_dialog_internal(_("An error has ocurred"), tmpbuf);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_adapter_settings_del(E_Dialog *dialog)
|
||||
{
|
||||
Adapter *adap;
|
||||
Eina_List *ck_list;
|
||||
|
||||
if (!dialog) return;
|
||||
adap = dialog->data;
|
||||
ck_list = e_object_data_get(E_OBJECT(dialog));
|
||||
eina_list_free(ck_list);
|
||||
e_object_del(E_OBJECT(dialog));
|
||||
adap->dialog = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_adapter_properties_update(void *data)
|
||||
{
|
||||
Eina_List *ck_list;
|
||||
Evas_Object *ck;
|
||||
Adapter *adap = data;
|
||||
|
||||
if (!adap->dialog) return;
|
||||
ck_list = e_object_data_get(E_OBJECT(adap->dialog));
|
||||
ck = eina_list_nth(ck_list, 0);
|
||||
e_widget_check_checked_set(ck, adap->powered);
|
||||
ck = eina_list_nth(ck_list, 1);
|
||||
e_widget_check_checked_set(ck, adap->visible);
|
||||
ck = eina_list_nth(ck_list, 2);
|
||||
e_widget_check_checked_set(ck, adap->pairable);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef E_MOD_MAIN_H
|
||||
#define E_MOD_MAIN_H
|
||||
|
||||
typedef struct _Instance Instance;
|
||||
struct _Instance
|
||||
{
|
||||
E_Gadcon_Client *gcc;
|
||||
E_Menu *menu;
|
||||
Evas_Object *o_bluez4;
|
||||
Evas_Object *found_list;
|
||||
E_Dialog *search_dialog;
|
||||
Evas_Object *adap_list;
|
||||
E_Dialog *adapters_dialog;
|
||||
};
|
||||
|
||||
typedef struct _Config Config;
|
||||
struct _Config
|
||||
{
|
||||
const char *lock_dev_addr;
|
||||
const char *unlock_dev_addr;
|
||||
};
|
||||
|
||||
extern Config *ebluez4_config;
|
||||
|
||||
E_API extern E_Module_Api e_modapi;
|
||||
|
||||
E_API void *e_modapi_init(E_Module *m);
|
||||
E_API int e_modapi_shutdown(E_Module *m);
|
||||
E_API int e_modapi_save(E_Module *m);
|
||||
|
||||
void ebluez4_update_inst(Evas_Object *dest, Eina_List *src, Instance *inst);
|
||||
void ebluez4_update_instances(Eina_List *src);
|
||||
void ebluez4_update_all_gadgets_visibility(void);
|
||||
void ebluez4_show_error(const char *err_name, const char *err_msg);
|
||||
void ebluez4_adapter_settings_del(E_Dialog *dialog);
|
||||
void ebluez4_adapter_properties_update(void *data);
|
||||
|
||||
#endif
|
|
@ -1,843 +0,0 @@
|
|||
#include <unistd.h>
|
||||
#include "e.h"
|
||||
#include "agent.h"
|
||||
#include "e_mod_main.h"
|
||||
#include "ebluez4.h"
|
||||
|
||||
Context *ctxt = NULL;
|
||||
|
||||
typedef struct _Pair_Cb
|
||||
{
|
||||
void (*cb)(void *, Eina_Bool, const char *);
|
||||
void *data;
|
||||
} Pair_Cb;
|
||||
|
||||
Service services[] = {
|
||||
{ HumanInterfaceDevice_UUID, INPUT },
|
||||
{ AudioSource_UUID, AUDIO_SOURCE },
|
||||
{ AudioSink_UUID, AUDIO_SINK },
|
||||
{ NULL, NONE }
|
||||
};
|
||||
|
||||
static int
|
||||
_dev_addr_cmp(const void *d1, const void *d2)
|
||||
{
|
||||
const Device *dev = d1;
|
||||
const char *addr = d2;
|
||||
|
||||
return strcmp(dev->addr, addr);
|
||||
}
|
||||
|
||||
int
|
||||
_adap_path_cmp(const void *d1, const void *d2)
|
||||
{
|
||||
const Adapter *adap = d1;
|
||||
const char *path = d2;
|
||||
|
||||
return strcmp(eldbus_object_path_get(adap->obj), path);
|
||||
}
|
||||
|
||||
static struct icon_type
|
||||
{
|
||||
const char *icon;
|
||||
const char *type;
|
||||
} icon_type_table[] = {
|
||||
{ "audio-card", "Audio" },
|
||||
{ "camera-photo", "Photo Camera" },
|
||||
{ "camera-video", "Video Camera" },
|
||||
{ "computer", "Computer" },
|
||||
{ "input-gaming", "Game Controller" },
|
||||
{ "input-keyboard", "Keyboard" },
|
||||
{ "input-mouse", "Mouse" },
|
||||
{ "input-tablet", "Tablet" },
|
||||
{ "modem", "Modem" },
|
||||
{ "network-wireless", "Wireless" },
|
||||
{ "phone", "Phone" },
|
||||
{ "printer", "Printer" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const char *
|
||||
_icon_to_type(const char *icon)
|
||||
{
|
||||
struct icon_type *it;
|
||||
|
||||
for (it = &icon_type_table[0]; it && it->icon; it++)
|
||||
{
|
||||
if (strcmp(icon, it->icon))
|
||||
return it->type;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_dev(Device *dev)
|
||||
{
|
||||
if (dev->proxy.input) eldbus_proxy_unref(dev->proxy.input);
|
||||
if (dev->proxy.audio_source) eldbus_proxy_unref(dev->proxy.audio_source);
|
||||
if (dev->proxy.audio_sink) eldbus_proxy_unref(dev->proxy.audio_sink);
|
||||
|
||||
if (dev->obj)
|
||||
eldbus_object_unref(dev->obj);
|
||||
eina_stringshare_del(dev->addr);
|
||||
dev->addr = NULL;
|
||||
eina_stringshare_del(dev->name);
|
||||
dev->name = NULL;
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_free_adap(Adapter *adap)
|
||||
{
|
||||
eldbus_proxy_unref(adap->proxy);
|
||||
eldbus_object_unref(adap->obj);
|
||||
eina_stringshare_del(adap->name);
|
||||
adap->name = NULL;
|
||||
ebluez4_adapter_settings_del(adap->dialog);
|
||||
free(adap);
|
||||
}
|
||||
|
||||
static void
|
||||
_free_dev_list(Eina_List **list)
|
||||
{
|
||||
Device *dev;
|
||||
|
||||
EINA_LIST_FREE(*list, dev)
|
||||
_free_dev(dev);
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_adap_list(void)
|
||||
{
|
||||
Adapter *adap;
|
||||
|
||||
EINA_LIST_FREE(ctxt->adapters, adap)
|
||||
_free_adap(adap);
|
||||
ctxt->adapters = NULL;
|
||||
}
|
||||
|
||||
static Profile
|
||||
_uuid_to_profile(const char *uuid)
|
||||
{
|
||||
Service *service;
|
||||
|
||||
for (service = (Service *)services; service && service->uuid; service++)
|
||||
if (!strcmp(service->uuid, uuid))
|
||||
return service->profile;
|
||||
return NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
_set_dev_services(Device *dev, Eldbus_Message_Iter *uuids)
|
||||
{
|
||||
const char *uuid;
|
||||
|
||||
while (eldbus_message_iter_get_and_next(uuids, 's', &uuid))
|
||||
switch (_uuid_to_profile(uuid))
|
||||
{
|
||||
case INPUT:
|
||||
if (!dev->proxy.input)
|
||||
dev->proxy.input = eldbus_proxy_get(dev->obj, INPUT_INTERFACE);
|
||||
break;
|
||||
case AUDIO_SOURCE:
|
||||
if (!dev->proxy.audio_source)
|
||||
dev->proxy.audio_source = eldbus_proxy_get(dev->obj,
|
||||
AUDIO_SOURCE_INTERFACE);
|
||||
break;
|
||||
case AUDIO_SINK:
|
||||
if (!dev->proxy.audio_sink)
|
||||
dev->proxy.audio_sink = eldbus_proxy_get(dev->obj,
|
||||
AUDIO_SINK_INTERFACE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_retrieve_properties(Eldbus_Message_Iter *dict, const char **addr,
|
||||
const char **name, const char **icon, Eina_Bool *paired,
|
||||
Eina_Bool *connected, Eldbus_Message_Iter **uuids)
|
||||
{
|
||||
Eldbus_Message_Iter *entry, *variant;
|
||||
const char *key;
|
||||
|
||||
*icon = NULL;
|
||||
|
||||
while (eldbus_message_iter_get_and_next(dict, 'e', &entry))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &variant))
|
||||
return;
|
||||
|
||||
if (!strcmp(key, "Address"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", addr))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Name"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", name))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Icon"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", icon))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Paired"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", paired))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Connected"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", connected))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "UUIDs"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "as", uuids))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_on_dev_property_changed(void *context, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *key, *name, *icon;
|
||||
char err_msg[4096];
|
||||
Eina_Bool paired, connected;
|
||||
Eldbus_Message_Iter *variant, *uuids;
|
||||
Device *dev = context;
|
||||
Device *found_dev = eina_list_search_unsorted(ctxt->found_devices,
|
||||
_dev_addr_cmp, dev->addr);
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sv", &key, &variant))
|
||||
{
|
||||
snprintf(err_msg, sizeof(err_msg),
|
||||
_("Property of %s changed, but could not be read"),
|
||||
dev->name);
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "Name"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", &name))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %s", key, dev->name, name);
|
||||
eina_stringshare_replace(&dev->name, name);
|
||||
|
||||
if (found_dev)
|
||||
{
|
||||
eina_stringshare_replace(&found_dev->name, name);
|
||||
ebluez4_update_instances(ctxt->found_devices);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(key, "Icon"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", &icon))
|
||||
return;
|
||||
if (!found_dev) return;
|
||||
DBG("'%s' property of %s changed to %s", key, found_dev->name, icon);
|
||||
found_dev->type = _icon_to_type(icon);
|
||||
ebluez4_update_instances(ctxt->found_devices);
|
||||
}
|
||||
else if (!strcmp(key, "Paired"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &paired))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %d", key, dev->name, paired);
|
||||
dev->paired = paired;
|
||||
|
||||
if (found_dev)
|
||||
{
|
||||
found_dev->paired = paired;
|
||||
ebluez4_update_instances(ctxt->found_devices);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(key, "Connected"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &connected))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %d", key, dev->name, connected);
|
||||
dev->connected = connected;
|
||||
}
|
||||
else if (!strcmp(key, "UUIDs"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "as", &uuids))
|
||||
return;
|
||||
_set_dev_services(dev, uuids);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_on_connected(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *err_name, *err_msg;
|
||||
|
||||
if (eldbus_message_error_get(msg, &err_name, &err_msg))
|
||||
{
|
||||
ERR("%s: %s", err_name, err_msg);
|
||||
ebluez4_show_error(err_name, err_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_try_to_connect(Eldbus_Proxy *proxy)
|
||||
{
|
||||
if (proxy)
|
||||
eldbus_proxy_call(proxy, "Connect", _on_connected, NULL, -1, "");
|
||||
}
|
||||
|
||||
static void
|
||||
_on_disconnected(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *err_name, *err_msg;
|
||||
|
||||
if (eldbus_message_error_get(msg, &err_name, &err_msg))
|
||||
{
|
||||
ERR("%s: %s", err_name, err_msg);
|
||||
ebluez4_show_error(err_name, err_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_try_to_disconnect(Eldbus_Proxy *proxy)
|
||||
{
|
||||
if (proxy)
|
||||
eldbus_proxy_call(proxy, "Disconnect", _on_disconnected, NULL, -1, "");
|
||||
}
|
||||
|
||||
static void
|
||||
_on_paired(void *data, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *err_name, *err_msg;
|
||||
Pair_Cb *d = data;
|
||||
Eina_Bool success = EINA_TRUE;
|
||||
|
||||
if (eldbus_message_error_get(msg, &err_name, &err_msg))
|
||||
{
|
||||
ERR("%s: %s", err_name, err_msg);
|
||||
success = EINA_FALSE;
|
||||
}
|
||||
if (d->cb) d->cb(d->data, success, err_msg);
|
||||
free(d);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_dev_properties(void *data, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *dict, *uuids;
|
||||
const char *addr, *name, *icon;
|
||||
Eina_Bool paired;
|
||||
Eina_Bool connected;
|
||||
Device *dev = data;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "a{sv}", &dict))
|
||||
return;
|
||||
|
||||
_retrieve_properties(dict, &addr, &name, &icon, &paired, &connected, &uuids);
|
||||
|
||||
dev->addr = eina_stringshare_add(addr);
|
||||
dev->name = eina_stringshare_add(name);
|
||||
dev->paired = paired;
|
||||
dev->connected = connected;
|
||||
_set_dev_services(dev, uuids);
|
||||
}
|
||||
|
||||
static void
|
||||
_unset_dev(Device *dev, Eina_List **list)
|
||||
{
|
||||
if (!dev || !list)
|
||||
return;
|
||||
|
||||
*list = eina_list_remove(*list, dev);
|
||||
_free_dev(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_dev(const char *path)
|
||||
{
|
||||
Device *dev = calloc(1, sizeof(Device));
|
||||
|
||||
dev->obj = eldbus_object_get(ctxt->conn, BLUEZ_BUS, path);
|
||||
dev->proxy.dev = eldbus_proxy_get(dev->obj, DEVICE_INTERFACE);
|
||||
eldbus_proxy_call(dev->proxy.dev, "GetProperties", _on_dev_properties, dev,
|
||||
-1, "");
|
||||
eldbus_proxy_signal_handler_add(dev->proxy.dev, "PropertyChanged",
|
||||
_on_dev_property_changed, dev);
|
||||
ctxt->devices = eina_list_append(ctxt->devices, dev);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_removed(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *path;
|
||||
Device *dev, *fdev;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "o", &path))
|
||||
return;
|
||||
|
||||
dev = eina_list_search_unsorted(ctxt->devices, ebluez4_dev_path_cmp, path);
|
||||
fdev = eina_list_search_unsorted(ctxt->found_devices, _dev_addr_cmp,
|
||||
dev->addr);
|
||||
|
||||
_unset_dev(dev, &ctxt->devices);
|
||||
_unset_dev(fdev, &ctxt->found_devices);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_created(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "o", &path))
|
||||
return;
|
||||
|
||||
_set_dev(path);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_device_found(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
Eldbus_Message_Iter *dict, *uuids;
|
||||
const char *addr, *name, *icon;
|
||||
Eina_Bool paired, connected;
|
||||
Device *dev;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sa{sv}", &addr, &dict))
|
||||
return;
|
||||
|
||||
if (eina_list_search_unsorted(ctxt->found_devices, _dev_addr_cmp, addr))
|
||||
return;
|
||||
|
||||
_retrieve_properties(dict, &addr, &name, &icon, &paired, &connected, &uuids);
|
||||
|
||||
dev = calloc(1, sizeof(Device));
|
||||
dev->addr = eina_stringshare_add(addr);
|
||||
dev->name = eina_stringshare_add(name);
|
||||
if (icon) dev->type = _icon_to_type(icon);
|
||||
dev->paired = paired;
|
||||
ctxt->found_devices = eina_list_append(ctxt->found_devices, dev);
|
||||
|
||||
ebluez4_update_instances(ctxt->found_devices);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_list_devices(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *array;
|
||||
const char *path;
|
||||
const char *err_msg = _("Error reading list of devices");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "ao", &array))
|
||||
{
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(array, 'o', &path))
|
||||
_set_dev(path);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adap_property_changed(void *context, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *key, *name;
|
||||
char err_msg[1096];
|
||||
Eina_Bool visible, pairable, powered;
|
||||
Eldbus_Message_Iter *variant;
|
||||
Adapter *adap = context;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "sv", &key, &variant))
|
||||
{
|
||||
snprintf(err_msg, sizeof(err_msg),
|
||||
_("Property of %s changed, but could not be read"), adap->name);
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(key, "Name"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", &name))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %s", key, adap->name, name);
|
||||
eina_stringshare_del(adap->name);
|
||||
adap->name = eina_stringshare_add(name);
|
||||
ebluez4_update_instances(ctxt->adapters);
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Discoverable"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &visible))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %d", key, adap->name, visible);
|
||||
adap->visible = visible;
|
||||
}
|
||||
else if (!strcmp(key, "Pairable"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &pairable))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %d", key, adap->name, pairable);
|
||||
adap->pairable = pairable;
|
||||
}
|
||||
else if (!strcmp(key, "Powered"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &powered))
|
||||
return;
|
||||
DBG("'%s' property of %s changed to %d", key, adap->name, powered);
|
||||
adap->powered = powered;
|
||||
}
|
||||
|
||||
ebluez4_adapter_properties_update(adap);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adap_properties(void *data, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *dict, *entry, *variant;
|
||||
const char *name, *key;
|
||||
Eina_Bool visible, pairable, powered;
|
||||
Adapter *adap = data;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "a{sv}", &dict))
|
||||
return;
|
||||
|
||||
while (eldbus_message_iter_get_and_next(dict, 'e', &entry))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(entry, "sv", &key, &variant))
|
||||
return;
|
||||
|
||||
else if (!strcmp(key, "Name"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "s", &name))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Discoverable"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &visible))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Pairable"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &pairable))
|
||||
return;
|
||||
}
|
||||
else if (!strcmp(key, "Powered"))
|
||||
{
|
||||
if (!eldbus_message_iter_arguments_get(variant, "b", &powered))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
adap->name = eina_stringshare_add(name);
|
||||
adap->visible = visible;
|
||||
adap->pairable = pairable;
|
||||
adap->powered = powered;
|
||||
ebluez4_update_instances(ctxt->adapters);
|
||||
}
|
||||
|
||||
static void
|
||||
_unset_default_adapter(void)
|
||||
{
|
||||
DBG("Remove default adapter %s", eldbus_object_path_get(ctxt->adap_obj));
|
||||
_free_dev_list(&ctxt->devices);
|
||||
ctxt->devices = NULL;
|
||||
_free_dev_list(&ctxt->found_devices);
|
||||
ctxt->found_devices = NULL;
|
||||
eldbus_object_unref(ctxt->adap_obj);
|
||||
ctxt->adap_obj = NULL;
|
||||
ebluez4_update_all_gadgets_visibility();
|
||||
}
|
||||
|
||||
static void
|
||||
_unset_adapter(const char *path)
|
||||
{
|
||||
Adapter *adap = eina_list_search_unsorted(ctxt->adapters, _adap_path_cmp,
|
||||
path);
|
||||
|
||||
if (!adap)
|
||||
return;
|
||||
|
||||
if (!strcmp(eldbus_object_path_get(ctxt->adap_obj), path))
|
||||
_unset_default_adapter();
|
||||
ctxt->adapters = eina_list_remove(ctxt->adapters, adap);
|
||||
_free_adap(adap);
|
||||
ebluez4_update_instances(ctxt->adapters);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_adapter(const char *path)
|
||||
{
|
||||
Adapter *adap = calloc(1, sizeof(Adapter));
|
||||
|
||||
adap->obj = eldbus_object_get(ctxt->conn, BLUEZ_BUS, path);
|
||||
if (ctxt->adap_obj && adap->obj == ctxt->adap_obj)
|
||||
adap->is_default = EINA_TRUE;
|
||||
else
|
||||
adap->is_default = EINA_FALSE;
|
||||
adap->proxy = eldbus_proxy_get(adap->obj, ADAPTER_INTERFACE);
|
||||
eldbus_proxy_call(adap->proxy, "GetProperties", _on_adap_properties, adap, -1,
|
||||
"");
|
||||
eldbus_proxy_signal_handler_add(adap->proxy, "PropertyChanged",
|
||||
_on_adap_property_changed, adap);
|
||||
ctxt->adapters = eina_list_append(ctxt->adapters, adap);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_list_adapters(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *array;
|
||||
const char *path;
|
||||
const char *err_msg = _("Error reading list of adapters");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "ao", &array))
|
||||
{
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
while (eldbus_message_iter_get_and_next(array, 'o', &path))
|
||||
_set_adapter(path);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_default_adapter(const Eldbus_Message *msg)
|
||||
{
|
||||
Adapter *adap;
|
||||
const char *adap_path;
|
||||
const char *err_msg = _("Error reading path of Default Adapter");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "o", &adap_path))
|
||||
{
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("Setting default adapter to %s", adap_path);
|
||||
|
||||
if (ctxt->adap_obj)
|
||||
_unset_default_adapter();
|
||||
|
||||
adap = eina_list_search_unsorted(ctxt->adapters, _adap_path_cmp, adap_path);
|
||||
if (adap)
|
||||
adap->is_default = EINA_TRUE;
|
||||
|
||||
ctxt->adap_obj = eldbus_object_get(ctxt->conn, BLUEZ_BUS, adap_path);
|
||||
ctxt->adap_proxy = eldbus_proxy_get(ctxt->adap_obj, ADAPTER_INTERFACE);
|
||||
|
||||
eldbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceFound",
|
||||
_on_device_found, NULL);
|
||||
eldbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceCreated",
|
||||
_on_created, NULL);
|
||||
eldbus_proxy_signal_handler_add(ctxt->adap_proxy, "DeviceRemoved",
|
||||
_on_removed, NULL);
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "ListDevices", _on_list_devices, NULL, -1,
|
||||
"");
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "RegisterAgent", NULL, NULL, -1, "os",
|
||||
REMOTE_AGENT_PATH, "KeyboardDisplay");
|
||||
ebluez4_update_all_gadgets_visibility();
|
||||
}
|
||||
|
||||
static void
|
||||
_default_adapter_get(void *data EINA_UNUSED, const Eldbus_Message *msg,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
const char *err_name, *err_msg;
|
||||
|
||||
/*
|
||||
* If bluetoothd is starting up, we can fail here and wait for the
|
||||
* DefaultAdapterChanged signal later
|
||||
*/
|
||||
if (eldbus_message_error_get(msg, &err_name, &err_msg))
|
||||
return;
|
||||
|
||||
if (!ctxt->adap_obj)
|
||||
_set_default_adapter(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_default_adapter_changed(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
_set_default_adapter(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adapter_removed(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *adap_path;
|
||||
const char *err_msg = _("Error reading path of Removed Adapter");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "o", &adap_path))
|
||||
{
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
_unset_adapter(adap_path);
|
||||
}
|
||||
|
||||
static void
|
||||
_on_adapter_added(void *context EINA_UNUSED, const Eldbus_Message *msg)
|
||||
{
|
||||
const char *adap_path;
|
||||
const char *err_msg = _("Error reading path of Added Adapter");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "o", &adap_path))
|
||||
{
|
||||
ERR("%s", err_msg);
|
||||
ebluez4_show_error(_("Bluez Error"), err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
_set_adapter(adap_path);
|
||||
}
|
||||
|
||||
static void
|
||||
_bluez_monitor(void *data EINA_UNUSED, const char *bus EINA_UNUSED,
|
||||
const char *old_id, const char *new_id)
|
||||
{
|
||||
if (!strcmp(old_id,"") && strcmp(new_id,""))
|
||||
{
|
||||
// Bluez up
|
||||
eldbus_proxy_call(ctxt->man_proxy, "DefaultAdapter",
|
||||
_default_adapter_get, NULL, -1, "");
|
||||
eldbus_proxy_call(ctxt->man_proxy, "ListAdapters",
|
||||
_on_list_adapters, NULL, -1, "");
|
||||
}
|
||||
else if (strcmp(old_id,"") && !strcmp(new_id,""))
|
||||
{
|
||||
// Bluez down
|
||||
_unset_default_adapter();
|
||||
_free_adap_list();
|
||||
}
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
void
|
||||
ebluez4_eldbus_init(void)
|
||||
{
|
||||
Eldbus_Object *obj;
|
||||
|
||||
ctxt = calloc(1, sizeof(Context));
|
||||
|
||||
ctxt->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
obj = eldbus_object_get(ctxt->conn, BLUEZ_BUS, MANAGER_PATH);
|
||||
ctxt->man_proxy = eldbus_proxy_get(obj, MANAGER_INTERFACE);
|
||||
|
||||
ebluez4_register_agent_interfaces(ctxt->conn);
|
||||
|
||||
eldbus_proxy_signal_handler_add(ctxt->man_proxy, "DefaultAdapterChanged",
|
||||
_on_default_adapter_changed, NULL);
|
||||
eldbus_proxy_signal_handler_add(ctxt->man_proxy, "AdapterRemoved",
|
||||
_on_adapter_removed, NULL);
|
||||
eldbus_proxy_signal_handler_add(ctxt->man_proxy, "AdapterAdded",
|
||||
_on_adapter_added, NULL);
|
||||
|
||||
eldbus_name_owner_changed_callback_add(ctxt->conn, BLUEZ_BUS, _bluez_monitor,
|
||||
NULL, EINA_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_eldbus_shutdown(void)
|
||||
{
|
||||
if (ctxt->adap_obj)
|
||||
_unset_default_adapter();
|
||||
_free_adap_list();
|
||||
eldbus_object_unref(eldbus_proxy_object_get(ctxt->man_proxy));
|
||||
eldbus_connection_unref(ctxt->conn);
|
||||
free(ctxt);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_start_discovery(void)
|
||||
{
|
||||
_free_dev_list(&ctxt->found_devices);
|
||||
ebluez4_update_instances(ctxt->found_devices);
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "StartDiscovery", NULL, NULL, -1, "");
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_stop_discovery(void)
|
||||
{
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "StopDiscovery", NULL, NULL, -1, "");
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_connect_to_device(Device *dev)
|
||||
{
|
||||
_try_to_connect(dev->proxy.input);
|
||||
_try_to_connect(dev->proxy.audio_source);
|
||||
_try_to_connect(dev->proxy.audio_sink);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_disconnect_device(Device *dev)
|
||||
{
|
||||
_try_to_disconnect(dev->proxy.input);
|
||||
_try_to_disconnect(dev->proxy.audio_source);
|
||||
_try_to_disconnect(dev->proxy.audio_sink);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_pair_with_device(const char *addr, void (*cb)(void *, Eina_Bool, const char *), void *data)
|
||||
{
|
||||
Pair_Cb *d = malloc(sizeof(Pair_Cb));
|
||||
EINA_SAFETY_ON_NULL_RETURN(d);
|
||||
d->cb = cb;
|
||||
d->data = data;
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "CreatePairedDevice", _on_paired, d,
|
||||
-1, "sos", addr, AGENT_PATH, "KeyboardDisplay");
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_remove_device(Eldbus_Object *obj)
|
||||
{
|
||||
eldbus_proxy_call(ctxt->adap_proxy, "RemoveDevice", NULL, NULL, -1, "o",
|
||||
eldbus_object_path_get(obj));
|
||||
}
|
||||
|
||||
int
|
||||
ebluez4_dev_path_cmp(const void *d1, const void *d2)
|
||||
{
|
||||
const Device *dev = d1;
|
||||
const char *path = d2;
|
||||
|
||||
return strcmp(eldbus_object_path_get(dev->obj), path);
|
||||
}
|
||||
|
||||
void
|
||||
ebluez4_adapter_property_set(Adapter *adap, const char *prop_name, Eina_Bool value)
|
||||
{
|
||||
Eldbus_Message_Iter *variant, *iter;
|
||||
Eldbus_Message *new_msg;
|
||||
|
||||
if (!adap) return;
|
||||
if (!adap->obj) return;
|
||||
new_msg = eldbus_proxy_method_call_new(adap->proxy, "SetProperty");
|
||||
iter = eldbus_message_iter_get(new_msg);
|
||||
eldbus_message_iter_basic_append(iter, 's', prop_name);
|
||||
variant = eldbus_message_iter_container_new(iter, 'v', "b");
|
||||
eldbus_message_iter_basic_append(variant, 'b', value);
|
||||
eldbus_message_iter_container_close(iter, variant);
|
||||
eldbus_proxy_send(adap->proxy, new_msg, NULL, NULL, -1);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
#include "Eldbus.h"
|
||||
|
||||
#define BLUEZ_BUS "org.bluez"
|
||||
#define MANAGER_PATH "/"
|
||||
#define INPUT_INTERFACE "org.bluez.Input"
|
||||
#define AUDIO_SOURCE_INTERFACE "org.bluez.AudioSource"
|
||||
#define AUDIO_SINK_INTERFACE "org.bluez.AudioSink"
|
||||
#define DEVICE_INTERFACE "org.bluez.Device"
|
||||
#define ADAPTER_INTERFACE "org.bluez.Adapter"
|
||||
#define MANAGER_INTERFACE "org.bluez.Manager"
|
||||
|
||||
#define HumanInterfaceDevice_UUID "00001124-0000-1000-8000-00805f9b34fb"
|
||||
#define AudioSource_UUID "0000110a-0000-1000-8000-00805f9b34fb"
|
||||
#define AudioSink_UUID "0000110b-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
typedef enum _Profile
|
||||
{
|
||||
INPUT,
|
||||
AUDIO_SOURCE,
|
||||
AUDIO_SINK,
|
||||
NONE
|
||||
} Profile;
|
||||
|
||||
typedef struct _Service
|
||||
{
|
||||
const char *uuid;
|
||||
Profile profile;
|
||||
} Service;
|
||||
|
||||
typedef struct _Device
|
||||
{
|
||||
const char *addr;
|
||||
const char *name;
|
||||
const char *type;
|
||||
Eina_Bool paired;
|
||||
Eina_Bool connected;
|
||||
Eldbus_Object *obj;
|
||||
struct
|
||||
{
|
||||
Eldbus_Proxy *dev;
|
||||
Eldbus_Proxy *input;
|
||||
Eldbus_Proxy *audio_sink;
|
||||
Eldbus_Proxy *audio_source;
|
||||
} proxy;
|
||||
} Device;
|
||||
|
||||
typedef struct _Adapter
|
||||
{
|
||||
const char *name;
|
||||
Eina_Bool visible;
|
||||
Eina_Bool pairable;
|
||||
Eina_Bool powered;
|
||||
int visible_checked;
|
||||
int pairable_checked;
|
||||
int powered_checked;
|
||||
Eina_Bool is_default;
|
||||
E_Dialog *dialog;
|
||||
Eldbus_Object *obj;
|
||||
Eldbus_Proxy *proxy;
|
||||
} Adapter;
|
||||
|
||||
typedef struct _Context
|
||||
{
|
||||
Eldbus_Connection *conn;
|
||||
Eldbus_Object *adap_obj;
|
||||
Eldbus_Proxy *man_proxy;
|
||||
Eldbus_Proxy *adap_proxy;
|
||||
Eina_List *devices;
|
||||
Eina_List *found_devices;
|
||||
Eina_List *adapters;
|
||||
} Context;
|
||||
|
||||
extern Context *ctxt;
|
||||
|
||||
void ebluez4_eldbus_init(void);
|
||||
void ebluez4_eldbus_shutdown(void);
|
||||
void ebluez4_start_discovery(void);
|
||||
void ebluez4_stop_discovery(void);
|
||||
void ebluez4_connect_to_device(Device *dev);
|
||||
void ebluez4_disconnect_device(Device *dev);
|
||||
void ebluez4_pair_with_device(const char *addr, void (*cb)(void *, Eina_Bool, const char *), void *data);
|
||||
void ebluez4_remove_device(Eldbus_Object *obj);
|
||||
int ebluez4_dev_path_cmp(const void *d1, const void *d2);
|
||||
void ebluez4_adapter_property_set(Adapter *adap, const char *prop_name, Eina_Bool value);
|
|
@ -1,5 +0,0 @@
|
|||
src = files(
|
||||
'e_mod_main.c',
|
||||
'agent.c',
|
||||
'ebluez4.c'
|
||||
)
|
|
@ -1,13 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Type=Link
|
||||
Name=Bluez4
|
||||
Name[ca]=Bluez4
|
||||
Name[de]=Bluez4
|
||||
Name[fi]=Bluez4
|
||||
Name[gl]=Bluez4
|
||||
Name[ja]=Bluez4
|
||||
Name[ms]=Bluez4
|
||||
Name[sr]=Блуез4
|
||||
Name[tr]=Bluetooth
|
||||
Icon=e-module-bluez4
|
||||
X-Enlightenment-ModuleType=utils
|
|
@ -33,7 +33,6 @@ mods = [
|
|||
'gadman',
|
||||
'geolocation',
|
||||
'connman',
|
||||
'bluez4',
|
||||
'bluez5',
|
||||
'syscon',
|
||||
'systray',
|
||||
|
|
Loading…
Reference in New Issue