enlightenment-module-empris/src/e_mod_main.c

1049 lines
26 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include <e.h>
#include "e_mod_main.h"
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#define MAX_SONG_LENGTH 255
typedef struct _Instance Instance;
struct _Instance
{
E_Gadcon_Client *gcc;
Evas_Object *empris;
Evas_Object *o_popup;
Config_Item *ci;
E_Gadcon_Popup *popup;
int cur_track;
/* E_DBus_Signal_Handler *cb_tracklist_change = NULL; */
E_DBus_Signal_Handler *cb_player_track_change;
E_DBus_Signal_Handler *cb_player_status_change;
};
/* Func Proto Requirements for Gadcon */
static E_Gadcon_Client *_gc_init (E_Gadcon * gc, const char *name,
const char *id, const char *style);
static void _gc_shutdown (E_Gadcon_Client * gcc);
static void _gc_orient (E_Gadcon_Client * gcc, E_Gadcon_Orient orient);
static char *_gc_label (E_Gadcon_Client_Class *client_class);
static Evas_Object *_gc_icon (E_Gadcon_Client_Class *client_class, Evas * evas);
static const char *_gc_id_new (E_Gadcon_Client_Class *client_class);
/* Module Protos */
static void _empris_cb_mouse_down (void *data, Evas * e, Evas_Object * obj, void *event_info);
static void _empris_cb_mouse_in (void *data, Evas * e, Evas_Object * obj, void *event_info);
static void _empris_cb_mouse_out (void *data, Evas * e, Evas_Object * obj, void *event_info);
static void _empris_menu_cb_configure (void *data, E_Menu * m, E_Menu_Item * mi);
static void _empris_menu_cb_post (void *data, E_Menu * m);
static void _empris_cb_play (void *data, Evas_Object * obj, const char *emission, const char *source);
static void _empris_cb_stop (void *data, Evas_Object * obj, const char *emission, const char *source);
static void _empris_cb_pause (void *data, Evas_Object * obj, const char *emission, const char *source);
static void _empris_cb_next (void *data, Evas_Object * obj, const char *emission, const char *source);
static void _empris_cb_previous (void *data, Evas_Object * obj, const char *emission, const char *source);
static Config_Item *_empris_config_item_get (const char *id);
static void _set_status(Instance *inst, DBusMessage *msg);
static void _dbus_cb_tracklist_metadata(void *data, DBusMessage *reply, DBusError *error);
static void _dbus_cb_get_status(void *data, DBusMessage *reply, DBusError *error);
static void _dbus_cb_track_change(void *data, DBusMessage *msg);
static void _dbus_cb_current_track(void *data, DBusMessage *reply, DBusError *error);
static void _dbus_cb_list_names(void *data, DBusMessage *msg, DBusError *err);
static void _dbus_cb_name_owner_changed(void *data, DBusMessage *msg);
static void _dbus_cb_status_change(void *data, DBusMessage *msg);
static DBusPendingCall *_dbus_send_msg(const char *path, const char *method, E_DBus_Method_Return_Cb _cb, void *data);
static char * _util_unescape(const char *string, int length);
static E_Config_DD *conf_edd = NULL;
static E_Config_DD *conf_item_edd = NULL;
static E_DBus_Connection *conn = NULL;
static DBusPendingCall *pending_get_name_owner = NULL;
static E_DBus_Signal_Handler *cb_name_owner_changed = NULL;
static const char *bus_name = NULL;
static const char mpris_interface[] = "org.freedesktop.MediaPlayer";
static const char fdo_bus_name[] = "org.freedesktop.DBus";
static const char fdo_interface[] = "org.freedesktop.DBus";
static const char fdo_path[] = "/org/freedesktop/DBus";
static Eina_List *players = NULL;
static Eina_Bool active = EINA_FALSE;
Config *empris_config = NULL;
/* Define the class and gadcon functions this module provides */
static const E_Gadcon_Client_Class _gc_class = {
GADCON_CLIENT_CLASS_VERSION,
"empris", {_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon,
_gc_id_new, NULL, e_gadcon_site_is_not_toolbar},
E_GADCON_CLIENT_STYLE_PLAIN
};
static void _empris_popup_destroy (Instance * inst);
static void _empris_popup_create (Instance * inst, const char *dir);
static E_Gadcon_Client *
_gc_init (E_Gadcon * gc, const char *name, const char *id, const char *style)
{
Evas_Object *o;
E_Gadcon_Client *gcc;
Evas *evas;
Instance *inst;
char buf[4096];
inst = E_NEW (Instance, 1);
inst->ci = _empris_config_item_get (id);
if (!inst->ci->id)
inst->ci->id = eina_stringshare_add (id);
o = edje_object_add (gc->evas);
snprintf (buf, sizeof (buf), "%s/empris.edj",
e_module_dir_get (empris_config->module));
if (!e_theme_edje_object_set
(o, "base/theme/modules/empris", "modules/empris/main"))
edje_object_file_set (o, buf, "modules/empris/main");
evas_object_show (o);
gcc = e_gadcon_client_new (gc, name, id, style, o);
gcc->data = inst;
inst->gcc = gcc;
inst->empris = o;
_empris_popup_create(inst, buf);
evas_object_event_callback_add (o, EVAS_CALLBACK_MOUSE_DOWN,
_empris_cb_mouse_down, inst);
evas_object_event_callback_add (inst->empris, EVAS_CALLBACK_MOUSE_IN,
_empris_cb_mouse_in, inst);
evas_object_event_callback_add (inst->empris, EVAS_CALLBACK_MOUSE_OUT,
_empris_cb_mouse_out, inst);
edje_object_signal_callback_add (o, "empris,play", "", _empris_cb_play,
inst);
edje_object_signal_callback_add (o, "empris,stop", "", _empris_cb_stop,
inst);
edje_object_signal_callback_add (o, "empris,pause", "", _empris_cb_pause,
inst);
edje_object_signal_callback_add (o, "empris,next", "", _empris_cb_next,
inst);
edje_object_signal_callback_add (o, "empris,previous", "",
_empris_cb_previous, inst);
inst->cb_player_track_change = e_dbus_signal_handler_add
(conn, bus_name, "/Player", mpris_interface, "TrackChange",
_dbus_cb_track_change, inst);
inst->cb_player_status_change = e_dbus_signal_handler_add
(conn, bus_name, "/Player", mpris_interface, "StatusChange",
_dbus_cb_status_change, inst);
_dbus_send_msg("/TrackList", "GetCurrentTrack", _dbus_cb_current_track, inst);
empris_config->instances = eina_list_append (empris_config->instances, inst);
return gcc;
}
static void
_gc_shutdown (E_Gadcon_Client * gcc)
{
Instance *inst;
inst = gcc->data;
if (inst->cb_player_track_change)
e_dbus_signal_handler_del(conn, inst->cb_player_track_change);
if (inst->cb_player_status_change)
e_dbus_signal_handler_del(conn, inst->cb_player_status_change);
empris_config->instances = eina_list_remove (empris_config->instances, inst);
evas_object_event_callback_del (inst->empris, EVAS_CALLBACK_MOUSE_DOWN,
_empris_cb_mouse_down);
evas_object_event_callback_del (inst->empris, EVAS_CALLBACK_MOUSE_IN,
_empris_cb_mouse_in);
evas_object_event_callback_del (inst->empris, EVAS_CALLBACK_MOUSE_OUT,
_empris_cb_mouse_out);
_empris_popup_destroy (inst);
evas_object_del (inst->empris);
free (inst);
inst = NULL;
}
static void
_gc_orient (E_Gadcon_Client * gcc, E_Gadcon_Orient orient)
{
Instance *inst;
Evas_Coord mw, mh;
inst = gcc->data;
edje_object_size_min_calc (inst->empris, &mw, &mh);
e_gadcon_client_min_size_set (gcc, mw, mh);
}
static char *
_gc_label (E_Gadcon_Client_Class *client_class)
{
return D_ ("Empris");
}
static Evas_Object *
_gc_icon (E_Gadcon_Client_Class *client_class, Evas * evas)
{
Evas_Object *o;
char buf[4096];
o = edje_object_add (evas);
snprintf (buf, sizeof (buf), "%s/e-module-empris.edj",
e_module_dir_get (empris_config->module));
edje_object_file_set (o, buf, "icon");
return o;
}
static const char *
_gc_id_new (E_Gadcon_Client_Class *client_class)
{
Config_Item *ci;
ci = _empris_config_item_get (NULL);
return ci->id;
}
static void
_empris_cb_mouse_down (void *data, Evas * e, Evas_Object * obj,
void *event_info)
{
Instance *inst;
Evas_Event_Mouse_Down *ev;
inst = data;
ev = event_info;
if ((ev->button == 3) && (!empris_config->menu))
{
E_Menu *mn;
E_Menu_Item *mi;
int x, y, w, h;
mn = e_menu_new ();
e_menu_post_deactivate_callback_set (mn, _empris_menu_cb_post, inst);
empris_config->menu = mn;
mi = e_menu_item_new (mn);
e_menu_item_label_set (mi, D_ ("Configuration"));
e_util_menu_item_theme_icon_set(mi, "preferences-system");
e_menu_item_callback_set (mi, _empris_menu_cb_configure, inst);
mi = e_menu_item_new (mn);
e_menu_item_separator_set (mi, 1);
e_gadcon_client_util_menu_items_append (inst->gcc, mn, 0);
e_gadcon_canvas_zone_geometry_get (inst->gcc->gadcon, &x, &y, &w, &h);
e_menu_activate_mouse (mn,
e_util_zone_current_get (e_manager_current_get
()), x + ev->output.x,
y + ev->output.y, 1, 1,
E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
evas_event_feed_mouse_up (inst->gcc->gadcon->evas, ev->button,
EVAS_BUTTON_NONE, ev->timestamp, NULL);
}
else if (ev->button == 1)
{
//e_gadcon_popup_toggle_pinned(inst->popup);
}
}
static void
_empris_cb_mouse_in (void *data, Evas * e, Evas_Object * obj,
void *event_info)
{
Instance *inst;
if ((!(inst = data)) || (!inst->ci->show_popup) || (!inst->popup))
return;
e_gadcon_popup_show (inst->popup);
}
static void
_empris_cb_mouse_out (void *data, Evas * e, Evas_Object * obj,
void *event_info)
{
Instance *inst;
if ((!(inst = data)) || ((!inst->ci->show_popup) && (inst->popup)))
return;
e_gadcon_popup_hide (inst->popup);
}
static void
_empris_menu_cb_post (void *data, E_Menu * m)
{
if (!empris_config->menu)
return;
e_object_del (E_OBJECT (empris_config->menu));
empris_config->menu = NULL;
}
static void
_empris_menu_cb_configure (void *data, E_Menu * m, E_Menu_Item * mi)
{
Instance *inst;
inst = data;
_config_empris_module (inst->ci);
}
void
_empris_config_updated (Config_Item * ci)
{
Eina_List *l;
if (!empris_config)
return;
for (l = empris_config->instances; l; l = l->next)
{
Instance *inst;
inst = l->data;
if (inst->ci != ci)
continue;
/* TODO choose player */
if (inst->ci->show_popup)
{
if (!inst->popup)
{
_empris_popup_create(inst, NULL);
}
}
else
{
if (inst->popup)
{
_empris_popup_destroy(inst);
}
}
break;
}
}
static void
_empris_cb_play (void *data, Evas_Object * obj, const char *emission, const char *source)
{
_dbus_send_msg("/Player", "Play", NULL, NULL);
}
static void
_empris_cb_previous (void *data, Evas_Object * obj, const char *emission, const char *source)
{
_dbus_send_msg("/Player", "Prev", NULL, NULL);
}
static void
_empris_cb_next (void *data, Evas_Object * obj, const char *emission, const char *source)
{
_dbus_send_msg("/Player", "Next", NULL, NULL);
}
static void
_empris_cb_stop (void *data, Evas_Object * obj, const char *emission, const char *source)
{
_dbus_send_msg("/Player", "Stop", NULL, NULL);
}
static void
_empris_cb_pause (void *data, Evas_Object * obj, const char *emission, const char *source)
{
_dbus_send_msg("/Player", "Pause", NULL, NULL);
}
static Config_Item *
_empris_config_item_get (const char *id)
{
Eina_List *l;
Config_Item *ci;
char buf[128];
if (!id)
{
int num = 0;
/* Create id */
if (empris_config->items)
{
const char *p;
ci = eina_list_last (empris_config->items)->data;
p = strrchr (ci->id, '.');
if (p)
num = atoi (p + 1) + 1;
}
snprintf (buf, sizeof (buf), "%s.%d", _gc_class.name, num);
id = buf;
}
else
{
for (l = empris_config->items; l; l = l->next)
{
ci = l->data;
if (!ci->id)
continue;
if (!strcmp (ci->id, id))
return ci;
}
}
ci = E_NEW (Config_Item, 1);
ci->id = eina_stringshare_add (id);
ci->player = eina_stringshare_add ("");
ci->show_popup = 1;
empris_config->items = eina_list_append (empris_config->items, ci);
return ci;
}
EAPI E_Module_Api e_modapi = {
E_MODULE_API_VERSION,
"Empris"
};
EAPI void *
e_modapi_init (E_Module * m)
{
char buf[4096];
snprintf (buf, sizeof (buf), "%s/locale", e_module_dir_get (m));
bindtextdomain (PACKAGE, buf);
bind_textdomain_codeset (PACKAGE, "UTF-8");
conf_item_edd = E_CONFIG_DD_NEW ("Empris_Config_Item", Config_Item);
#undef T
#undef D
#define T Config_Item
#define D conf_item_edd
E_CONFIG_VAL (D, T, id, STR);
E_CONFIG_VAL (D, T, player, STR);
E_CONFIG_VAL (D, T, show_popup, UCHAR);
conf_edd = E_CONFIG_DD_NEW ("Empris_Config", Config);
#undef T
#undef D
#define T Config
#define D conf_edd
E_CONFIG_LIST (D, T, items, conf_item_edd);
empris_config = e_config_domain_load ("module.empris", conf_edd);
if (!empris_config)
{
Config_Item *ci;
empris_config = E_NEW (Config, 1);
ci = E_NEW (Config_Item, 1);
ci->id = eina_stringshare_add ("0");
ci->player = eina_stringshare_add ("");
ci->show_popup = 1;
empris_config->items = eina_list_append (empris_config->items, ci);
}
empris_config->module = m;
conn = e_dbus_bus_get(DBUS_BUS_SESSION);
if (!conn) return NULL;
cb_name_owner_changed = e_dbus_signal_handler_add
(conn, fdo_bus_name, fdo_path, fdo_interface, "NameOwnerChanged",
_dbus_cb_name_owner_changed, NULL);
e_dbus_list_names(conn, _dbus_cb_list_names, NULL);
e_gadcon_provider_register (&_gc_class);
e_module_delayed_set(m, 1);
return m;
}
EAPI int
e_modapi_shutdown (E_Module * m)
{
char *player;
empris_config->module = NULL;
e_gadcon_provider_unregister (&_gc_class);
if (conn)
{
if (cb_name_owner_changed) e_dbus_signal_handler_del(conn, cb_name_owner_changed);
e_dbus_connection_close(conn);
}
EINA_LIST_FREE(players, player)
eina_stringshare_del(player);
if (empris_config->config_dialog)
e_object_del (E_OBJECT (empris_config->config_dialog));
if (empris_config->menu)
{
e_menu_post_deactivate_callback_set (empris_config->menu, NULL, NULL);
e_object_del (E_OBJECT (empris_config->menu));
empris_config->menu = NULL;
}
while (empris_config->items)
{
Config_Item *ci;
ci = empris_config->items->data;
empris_config->items =
eina_list_remove_list (empris_config->items, empris_config->items);
if (ci->id)
eina_stringshare_del (ci->id);
free (ci);
ci = NULL;
}
free (empris_config);
empris_config = NULL;
E_CONFIG_DD_FREE (conf_item_edd);
E_CONFIG_DD_FREE (conf_edd);
return 1;
}
EAPI int
e_modapi_save (E_Module * m)
{
e_config_domain_save ("module.empris", conf_edd, empris_config);
return 1;
}
static void
_empris_popup_destroy (Instance * inst)
{
if (inst->popup)
e_object_del (E_OBJECT (inst->popup));
inst->popup = NULL;
if (inst->o_popup)
evas_object_del(inst->o_popup);
inst->o_popup = NULL;
}
static void
_empris_popup_create (Instance * inst, const char *dir)
{
Evas *evas;
Evas_Object *o_popup;
char buf[4096];
if (inst->ci->show_popup)
{
inst->popup = e_gadcon_popup_new (inst->gcc);
evas = inst->popup->win->evas;
o_popup = edje_object_add (evas);
if (!e_theme_edje_object_set
(o_popup, "base/theme/modules/empris", "modules/empris/popup"))
{
if (dir)
{
edje_object_file_set (o_popup, dir, "modules/empris/popup");
}
else
{
snprintf(buf, sizeof(buf), "%s/empris.edj",
e_module_dir_get(empris_config->module));
edje_object_file_set(o_popup, buf, "modules/empris/popup");
}
}
evas_object_show (o_popup);
e_gadcon_popup_content_set (inst->popup, o_popup);
edje_object_size_min_calc (o_popup, NULL, NULL);
inst->o_popup = o_popup;
edje_object_signal_callback_add (o_popup, "empris,play", "",
_empris_cb_play, inst);
edje_object_signal_callback_add (o_popup, "empris,stop", "",
_empris_cb_stop, inst);
edje_object_signal_callback_add (o_popup, "empris,pause", "",
_empris_cb_pause, inst);
edje_object_signal_callback_add (o_popup, "empris,next", "",
_empris_cb_next, inst);
edje_object_signal_callback_add (o_popup, "empris,previous", "",
_empris_cb_previous, inst);
}
else
{
inst->popup = NULL;
inst->o_popup = NULL;
}
}
static int
_dbus_check_msg(DBusMessage *reply, DBusError *error)
{
if (error && dbus_error_is_set(error))
{
printf("Error: %s - %s\n", error->name, error->message);
return 0;
}
return (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);
}
static DBusPendingCall *
_dbus_send_msg(const char *path, const char *method,
E_DBus_Method_Return_Cb _cb, void *data)
{
DBusMessage *msg;
DBusPendingCall *pnd;
if (!active) return NULL;
msg = dbus_message_new_method_call(bus_name, path,
mpris_interface,
method);
pnd = e_dbus_message_send(conn, msg, _cb, -1, data);
dbus_message_unref(msg);
return pnd;
}
static DBusPendingCall *
_dbus_send_msg_int(const char *path, const char *method,
E_DBus_Method_Return_Cb _cb, void *data, int num)
{
DBusMessage *msg;
DBusPendingCall *pnd;
if (!active) return NULL;
msg = dbus_message_new_method_call(bus_name, path,
mpris_interface,
method);
dbus_message_append_args(msg,
DBUS_TYPE_INT32, &num,
DBUS_TYPE_INVALID);
pnd = e_dbus_message_send(conn, msg, _cb, -1, data);
dbus_message_unref(msg);
return pnd;
}
static void
_dbus_cb_current_track(void *data, DBusMessage *reply, DBusError *error)
{
Instance *inst = data;
DBusMessage *msg;
int num;
if (!_dbus_check_msg(reply, error)) return;
dbus_message_get_args(reply, error,
DBUS_TYPE_INT32, (dbus_int32_t*) &(num),
DBUS_TYPE_INVALID);
/* XXX inst->pnd*/
_dbus_send_msg_int("/TrackList", "GetMetadata",
_dbus_cb_tracklist_metadata, inst, num);
}
static void
_dbus_cb_status_change(void *data, DBusMessage *msg)
{
DBusMessageIter iter, array;
dbus_message_iter_init(msg, &iter);
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRUCT)
{
_set_status(data, msg);
}
else if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32)
{
/* XXX audacious.. */
_dbus_send_msg("/Player", "GetStatus", _dbus_cb_get_status, data);
}
_dbus_send_msg("/TrackList", "GetCurrentTrack", _dbus_cb_current_track, data);
}
static void
_dbus_cb_track_change(void *data, DBusMessage *msg)
{
_dbus_cb_tracklist_metadata(data, msg, NULL);
}
static void
_dbus_cb_tracklist_metadata(void *data, DBusMessage *reply, DBusError *error)
{
DBusMessageIter array, item, iter, iter_val;
Instance *inst = data;
int type, cnt = 0;
char *key, *tmp, *location = NULL;
int title = 0;
Evas_Object *empris = inst->empris;
Evas_Object *o_popup = inst->o_popup;
if (error)
{
if (!_dbus_check_msg(reply, error))
{
printf("dbus garbage!\n");
goto error;
}
}
edje_object_part_text_set (empris, "empris.artist", "");
edje_object_part_text_set (o_popup, "empris.artist", "");
edje_object_part_text_set (empris, "empris.title", "");
edje_object_part_text_set (o_popup, "empris.title", "");
edje_object_part_text_set (empris, "empris.album", "");
edje_object_part_text_set (o_popup, "empris.album", "");
dbus_message_iter_init(reply, &array);
if(dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY)
{
dbus_message_iter_recurse(&array, &item);
while(dbus_message_iter_get_arg_type(&item) == DBUS_TYPE_DICT_ENTRY)
{
dbus_message_iter_recurse(&item, &iter);
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING)
{
dbus_message_iter_get_basic(&iter, &key);
}
else
{
printf("not string{n");
goto error;
}
dbus_message_iter_next(&iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
{
printf("not variant\n");
goto error;
}
if (!strcmp(key, "artist"))
{
dbus_message_iter_recurse (&iter, &iter_val);
dbus_message_iter_get_basic (&iter_val, &tmp);
if (tmp && tmp[0])
{
edje_object_part_text_set (empris, "empris.artist", tmp);
edje_object_part_text_set (o_popup, "empris.artist", tmp);
}
}
else if (!strcmp(key, "title"))
{
dbus_message_iter_recurse (&iter, &iter_val);
dbus_message_iter_get_basic (&iter_val, &tmp);
if (tmp && tmp[0])
{
edje_object_part_text_set (empris, "empris.title", tmp);
edje_object_part_text_set (o_popup, "empris.title", tmp);
title = 1;
}
}
else if (!strcmp(key, "location"))
{
dbus_message_iter_recurse (&iter, &iter_val);
dbus_message_iter_get_basic (&iter_val, &tmp);
if (tmp && tmp[0])
{
location = strdup(tmp);
}
}
else if (!strcmp(key, "album"))
{
dbus_message_iter_recurse (&iter, &iter_val);
dbus_message_iter_get_basic (&iter_val, &tmp);
if (tmp && tmp[0])
{
edje_object_part_text_set (empris, "empris.album", tmp);
edje_object_part_text_set (o_popup, "empris.album", tmp);
}
}
/* else if (!strcmp(key, "mtime"))
* {
* dbus_message_iter_recurse (&iter, &iter_val);
* dbus_message_iter_get_basic (&iter_val, &(t->length));
* } */
dbus_message_iter_next(&item);
}
}
if (!title && location)
{
char *tmp = _util_unescape(ecore_file_file_get(location), 0);
if (tmp)
{
edje_object_part_text_set (empris, "empris.title", tmp);
edje_object_part_text_set (o_popup, "empris.title", tmp);
free(tmp);
}
free(location);
}
error:
return;
}
static void
_set_status(Instance *inst, DBusMessage *msg)
{
DBusMessageIter iter, array;
int status;
dbus_message_iter_init(msg, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRUCT)
{
edje_object_part_text_set (inst->empris, "empris.status",
D_ ("Unknown"));
edje_object_part_text_set (inst->o_popup, "empris.status",
D_ ("Unknown"));
printf("no dbus struct\n");
return;
}
dbus_message_iter_recurse(&iter, &array);
dbus_message_iter_get_basic(&array, &status);
/* dbus_message_iter_next(&array); */
/* dbus_message_iter_get_basic(&array, &(p->status.random));
* dbus_message_iter_next(&array);
* dbus_message_iter_get_basic(&array, &(p->status.repeat));
* dbus_message_iter_next(&array);
* dbus_message_iter_get_basic(&array, &(p->status.loop));
* DBG("status %d", p->status.playing); */
if (status == 0)
{
edje_object_part_text_set (inst->empris, "empris.status",
D_ ("Stopped"));
edje_object_part_text_set (inst->o_popup, "empris.status",
D_ ("Stopped"));
}
else if (status == 2)
{
edje_object_part_text_set (inst->empris, "empris.status",
D_ ("Playing"));
edje_object_part_text_set (inst->o_popup, "empris.status",
D_ ("Playing"));
}
else if (status == 1)
{
edje_object_part_text_set (inst->empris, "empris.status",
D_ ("Paused"));
edje_object_part_text_set (inst->o_popup, "empris.status",
D_ ("Paused"));
}
else
{
edje_object_part_text_set (inst->empris, "empris.status",
D_ ("Unknown"));
edje_object_part_text_set (inst->o_popup, "empris.status",
D_ ("Unknown"));
}
}
static void
_dbus_cb_get_status(void *data, DBusMessage *reply, DBusError *error)
{
if (!_dbus_check_msg(reply, error)) return;
_set_status(data, reply);
}
static void
_dbus_cb_name_owner_changed(void *data, DBusMessage *msg)
{
DBusError err;
Eina_List *l;
const char *tmp;
const char *name, *from, *to;
if (!conn) return;
dbus_error_init(&err);
if (!dbus_message_get_args(msg, &err,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &from,
DBUS_TYPE_STRING, &to,
DBUS_TYPE_INVALID))
{
printf("could not get NameOwnerChanged arguments: %s: %s\n",
err.name, err.message);
dbus_error_free(&err);
return;
}
if (strncmp(name, "org.mpris.", 10) != 0)
return;
printf("NameOwnerChanged from=[%s] to=[%s]\n", from, to);
tmp = eina_stringshare_add(name);
if (to[0] == '\0')
{
players = eina_list_remove(players, tmp);
/* vanished player was current? */
if (tmp == bus_name)
{
/* make another player current */
if (eina_list_count(players) > 0)
{
bus_name = players->data;
printf("use::%s", bus_name);
active = EINA_TRUE;
}
else
{
active = EINA_FALSE;
}
}
eina_stringshare_del(tmp);
}
else
{
/* new player appeared? */
if (!eina_list_data_find(players, tmp))
{
eina_stringshare_ref(tmp);
players = eina_list_append(players, tmp);
}
/* no active player - make player current */
if (!active)
{
bus_name = tmp;
active = EINA_TRUE;
}
}
eina_stringshare_del(tmp);
}
static void
_dbus_cb_list_names(void *data, DBusMessage *msg, DBusError *err)
{
DBusMessageIter array, iter, item, iter_val;
char *name;
if (!_dbus_check_msg(msg, err)) return;
dbus_message_iter_init(msg, &array);
if(dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_ARRAY)
{
dbus_message_iter_recurse(&array, &item);
while(dbus_message_iter_get_arg_type(&item) == DBUS_TYPE_STRING)
{
dbus_message_iter_get_basic(&item, &name);
if (strncmp(name, "org.mpris.", 10) == 0)
{
printf("found %s", name);
players = eina_list_append(players, eina_stringshare_add(name));
}
dbus_message_iter_next(&item);
}
}
if (eina_list_count(players) > 0)
{
bus_name = players->data;
printf("use::%s", bus_name);
active = EINA_TRUE;
}
}
/* taken from curl:
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et
* al.
*
* Unescapes the given URL escaped string of given length. Returns a
* pointer to a malloced string with length given in *olen.
* If length == 0, the length is assumed to be strlen(string).
* If olen == NULL, no output length is stored.
*/
#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
static char *
_util_unescape(const char *string, int length)
{
int alloc = (length?length:(int)strlen(string))+1;
char *ns = malloc(alloc);
unsigned char in;
int strindex=0;
unsigned long hex;
if( !ns )
return NULL;
while(--alloc > 0) {
in = *string;
if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
char hexstr[3];
char *ptr;
hexstr[0] = string[1];
hexstr[1] = string[2];
hexstr[2] = 0;
hex = strtoul(hexstr, &ptr, 16);
in = (unsigned char)(hex & (unsigned long) 0xFF);
// in = ultouc(hex); /* this long is never bigger than 255 anyway */
string+=2;
alloc-=2;
}
ns[strindex++] = in;
string++;
}
ns[strindex]=0; /* terminate it */
return ns;
}
#undef ISXDIGIT