enjoy: single instance using DBus name org.enlightenment.enjoy
Also provide minor Control interface, later to be extended with DB management. SVN revision: 63180
This commit is contained in:
parent
862f5dd781
commit
74ca53a96f
14
TODO
14
TODO
|
@ -9,24 +9,22 @@ Consider the following order to implement this todo:
|
|||
- window geometry
|
||||
- volume
|
||||
- repeat and shuffle states
|
||||
3. Single instance with dbus:
|
||||
- just get a name
|
||||
4. Create preferences infrastructure:
|
||||
3. Create preferences infrastructure:
|
||||
- new elm_layout style (in Elementary) for preferences
|
||||
- choose media backend (xine, gstreamer)
|
||||
5. Create library manager preferences:
|
||||
4. Create library manager preferences:
|
||||
- add/remove directories (or at least choose folder)
|
||||
- rescan, stop-scan. with progress feedback
|
||||
- option to choose rescan schedule
|
||||
- remove command line scan
|
||||
6. Refactor some features into plugins
|
||||
5. Refactor some features into plugins
|
||||
- define ecore_events and plugin interface
|
||||
- coverart-lastfm
|
||||
- cover art local fs lookup
|
||||
7. Modular plugins (elm_module)
|
||||
6. Modular plugins (elm_module)
|
||||
- selection saved in eet
|
||||
- gui to select enabled plugins
|
||||
8. Save/Resume between runs (list, nowplaying and navigation)
|
||||
7. Save/Resume between runs (list, nowplaying and navigation)
|
||||
|
||||
|
||||
Library (from "Preferences")
|
||||
|
@ -90,8 +88,6 @@ Work to cover the above cases:
|
|||
|
||||
More
|
||||
----
|
||||
* Single instance using dbus (otherwise configuration will be screwed with
|
||||
multiple processes writing it);
|
||||
* Save/Resume state between runs (start from the same place as last time);
|
||||
- window geometry
|
||||
- volume
|
||||
|
|
|
@ -43,6 +43,9 @@ VMIC=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $3);}'`
|
|||
SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
|
||||
version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
|
||||
m4_ifdef([v_rev], , [m4_define([v_rev], [0])])
|
||||
AC_DEFINE_UNQUOTED(VMAJ, [v_maj], [Major version])
|
||||
AC_DEFINE_UNQUOTED(VMIN, [v_min], [Minor version])
|
||||
AC_DEFINE_UNQUOTED(VMIC, [v_mic], [Micro version])
|
||||
AC_DEFINE_UNQUOTED(VREV, [v_rev], [Revison])
|
||||
AC_SUBST(VMAJ)
|
||||
AC_SUBST(version_info)
|
||||
|
|
|
@ -20,7 +20,7 @@ endif
|
|||
|
||||
enjoy_LDADD = @ELEMENTARY_LIBS@ @EMOTION_LIBS@ @LMS_LIBS@ @SQLITE3_LIBS@ @EDBUS_LIBS@
|
||||
enjoy_CFLAGS = -rdynamic
|
||||
enjoy_SOURCES = main.c win.c db.c list.c page.c cover.c nowplaying.c libmanager.c coverart-lastfm.c
|
||||
enjoy_SOURCES = main.c win.c db.c list.c page.c cover.c nowplaying.c libmanager.c coverart-lastfm.c dbus.c
|
||||
|
||||
if BUILD_QUICKLAUNCH
|
||||
############################################################################
|
||||
|
|
|
@ -26,6 +26,7 @@ struct _LastFM_Cover_Request {
|
|||
};
|
||||
|
||||
static char *_local_cache_dir = NULL;
|
||||
static Eina_Bool _lastfm_inited = EINA_FALSE;
|
||||
|
||||
/*
|
||||
* This API Key belongs to leandro@profusion.mobi -- do not use it for commercial
|
||||
|
@ -281,6 +282,9 @@ lastfm_cover_init(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (_lastfm_inited) return;
|
||||
_lastfm_inited = EINA_TRUE;
|
||||
|
||||
ecore_init();
|
||||
ecore_file_init();
|
||||
ecore_con_url_init();
|
||||
|
@ -320,6 +324,7 @@ lastfm_cover_shutdown(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!_lastfm_inited) return;
|
||||
for (i = 0; disc_number_regexes[i].str; i++)
|
||||
{
|
||||
regfree(disc_number_regexes[i].exp);
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "private.h"
|
||||
#include <E_DBus.h>
|
||||
|
||||
#define DBUS_NAME "org.enlightenment.enjoy"
|
||||
#define DBUS_IFACE "org.enlightenment.enjoy.Control"
|
||||
#define DBUS_PATH "/org/enlightenment/enjoy/Control"
|
||||
|
||||
static E_DBus_Connection *conn = NULL;
|
||||
static E_DBus_Object *dbus_obj = NULL;
|
||||
static E_DBus_Interface *dbus_iface = NULL;
|
||||
|
||||
typedef struct _Enjoy_DBus_Method Enjoy_DBus_Method;
|
||||
struct _Enjoy_DBus_Method {
|
||||
const char *name;
|
||||
const char *par;
|
||||
const char *ret;
|
||||
E_DBus_Method_Cb cb;
|
||||
};
|
||||
|
||||
static DBusMessage *
|
||||
_cb_dbus_quit(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
||||
{
|
||||
enjoy_quit();
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
static DBusMessage *
|
||||
_cb_dbus_version(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
||||
{
|
||||
DBusMessage *reply = dbus_message_new_method_return(msg);
|
||||
DBusMessageIter iter, siter;
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &siter);
|
||||
|
||||
#define APPEND_UINT16(val) \
|
||||
do { \
|
||||
unsigned short _tmp_val = val; \
|
||||
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT16, &_tmp_val); \
|
||||
} while (0)
|
||||
APPEND_UINT16(VMAJ);
|
||||
APPEND_UINT16(VMIN);
|
||||
APPEND_UINT16(VMIC);
|
||||
#undef APPEND_UINT16
|
||||
|
||||
dbus_message_iter_close_container(&iter, &siter);
|
||||
return reply;
|
||||
}
|
||||
|
||||
/* Avoid duplicating MPRIS -- see src/plugins/mpris */
|
||||
static const Enjoy_DBus_Method control_methods[] = {
|
||||
{"Quit", "", "", _cb_dbus_quit},
|
||||
{"Version", "", "(qqq)", _cb_dbus_version},
|
||||
/* TODO: DB management */
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static void
|
||||
_dbus_methods_add(E_DBus_Interface *iface, const Enjoy_DBus_Method desc[])
|
||||
{
|
||||
const Enjoy_DBus_Method *itr = desc;
|
||||
for (; itr->name; itr++)
|
||||
e_dbus_interface_method_add(iface, itr->name, itr->par, itr->ret, itr->cb);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
||||
{
|
||||
DBusError new_err;
|
||||
dbus_uint32_t msgtype;
|
||||
E_DBus_Interface *iface;
|
||||
|
||||
if (dbus_error_is_set(err))
|
||||
{
|
||||
ERR("Could not get DBus name: %s", err->message);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dbus_error_init(&new_err);
|
||||
dbus_message_get_args
|
||||
(msg, &new_err, DBUS_TYPE_UINT32, &msgtype, DBUS_TYPE_INVALID);
|
||||
if (msgtype != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
ERR("Could not get the DBus name: reply=%d", msgtype);
|
||||
goto error;
|
||||
}
|
||||
|
||||
INF("Got DBus name - unique instance running.");
|
||||
|
||||
dbus_obj = e_dbus_object_add(conn, DBUS_PATH, NULL);
|
||||
if (!dbus_obj)
|
||||
{
|
||||
ERR("Could not create Control DBus object.");
|
||||
goto error;
|
||||
}
|
||||
dbus_iface = e_dbus_interface_new(DBUS_IFACE);
|
||||
e_dbus_object_interface_attach(dbus_obj, dbus_iface);
|
||||
_dbus_methods_add(dbus_iface, control_methods);
|
||||
|
||||
/* will run after other events run, in the main loop */
|
||||
ecore_event_add(ENJOY_EVENT_STARTED, NULL, NULL, NULL);
|
||||
return;
|
||||
|
||||
error:
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
enjoy_dbus_init(void)
|
||||
{
|
||||
e_dbus_init();
|
||||
conn = e_dbus_bus_get(DBUS_BUS_SESSION);
|
||||
if (!conn)
|
||||
{
|
||||
ERR("Could not get DBus session bus");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
e_dbus_request_name
|
||||
(conn, DBUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
_cb_dbus_request_name, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
enjoy_dbus_shutdown(void)
|
||||
{
|
||||
if (dbus_obj) e_dbus_object_free(dbus_obj);
|
||||
if (dbus_iface) e_dbus_interface_unref(dbus_iface);
|
||||
conn = NULL;
|
||||
e_dbus_shutdown();
|
||||
}
|
|
@ -319,6 +319,7 @@ enjoy_module_load(void)
|
|||
static void
|
||||
enjoy_module_unload(void)
|
||||
{
|
||||
if (!app.modules) return;
|
||||
while (eina_array_count_get(app.modules))
|
||||
eina_module_unload(eina_array_pop(app.modules));
|
||||
eina_array_free(app.modules);
|
||||
|
@ -370,6 +371,17 @@ _cb_started(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
|||
{
|
||||
Enjoy_Plugin *p;
|
||||
|
||||
app.win = win_new(&app);
|
||||
if (!app.win)
|
||||
{
|
||||
ERR("Could not create main window");
|
||||
enjoy_quit();
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
cover_init();
|
||||
enjoy_module_load();
|
||||
|
||||
enjoy_plugins_walk();
|
||||
EINA_INLIST_FOREACH(plugins_registry, p)
|
||||
enjoy_plugin_enable(p);
|
||||
|
@ -378,6 +390,35 @@ _cb_started(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
|||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static DBusMessage *
|
||||
_cb_dbus_quit(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
||||
{
|
||||
enjoy_quit();
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
|
||||
static DBusMessage *
|
||||
_cb_dbus_version(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
|
||||
{
|
||||
DBusMessage *reply = dbus_message_new_method_return(msg);
|
||||
DBusMessageIter iter, siter;
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL, &siter);
|
||||
|
||||
#define APPEND_UINT16(val) \
|
||||
do { \
|
||||
unsigned short _tmp_val = val; \
|
||||
dbus_message_iter_append_basic(&siter, DBUS_TYPE_UINT16, &_tmp_val); \
|
||||
} while (0)
|
||||
APPEND_UINT16(VMAJ);
|
||||
APPEND_UINT16(VMIN);
|
||||
APPEND_UINT16(VMIC);
|
||||
#undef APPEND_UINT16
|
||||
|
||||
dbus_message_iter_close_container(&iter, &siter);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
|
@ -396,6 +437,8 @@ elm_main(int argc, char **argv)
|
|||
ECORE_GETOPT_VALUE_NONE
|
||||
};
|
||||
|
||||
memset(&app, 0, sizeof(app));
|
||||
|
||||
#if ENABLE_NLS
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
||||
|
@ -442,28 +485,31 @@ elm_main(int argc, char **argv)
|
|||
goto end;
|
||||
}
|
||||
|
||||
app.win = win_new(&app);
|
||||
if (!app.win) goto end;
|
||||
|
||||
cover_init();
|
||||
enjoy_event_id_init();
|
||||
ecore_event_handler_add(ENJOY_EVENT_STARTED, _cb_started, NULL);
|
||||
|
||||
enjoy_module_load();
|
||||
/* will call ENJOY_EVENT_STARTED whenever it's ready */
|
||||
if (!enjoy_dbus_init())
|
||||
{
|
||||
ERR("Could not start Enjoy's DBus subsystem");
|
||||
r = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* will run after other events run, in the main loop */
|
||||
ecore_event_add(ENJOY_EVENT_STARTED, NULL, NULL, NULL);
|
||||
elm_run();
|
||||
|
||||
end:
|
||||
EINA_LIST_FREE(app.add_dirs, s) free(s);
|
||||
EINA_LIST_FREE(app.del_dirs, s) free(s);
|
||||
|
||||
enjoy_module_unload();
|
||||
cover_shutdown();
|
||||
|
||||
enjoy_dbus_shutdown();
|
||||
|
||||
eina_log_domain_unregister(_log_domain);
|
||||
_log_domain = -1;
|
||||
elm_shutdown();
|
||||
enjoy_module_unload();
|
||||
cover_shutdown();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -181,5 +181,7 @@ void db_nameid_free(NameID *nameid);
|
|||
Eina_Bool enjoy_plugin_enable(Enjoy_Plugin *p);
|
||||
Eina_Bool enjoy_plugin_disable(Enjoy_Plugin *p);
|
||||
|
||||
Eina_Bool enjoy_dbus_init(void);
|
||||
void enjoy_dbus_shutdown(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -244,7 +244,8 @@ mpris_enable(Enjoy_Plugin *p __UNUSED__)
|
|||
_cb_player_tracklist_change, NULL);
|
||||
#undef EV_HANDLER
|
||||
|
||||
e_dbus_request_name(conn, APPLICATION_NAME, 0, _cb_dbus_request_name, NULL);
|
||||
e_dbus_request_name(conn, APPLICATION_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE,
|
||||
_cb_dbus_request_name, NULL);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -337,10 +338,11 @@ _cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
|||
{
|
||||
DBusError new_err;
|
||||
dbus_uint32_t msgtype;
|
||||
int i;
|
||||
|
||||
if (dbus_error_is_set(err))
|
||||
{
|
||||
dbus_error_free(err);
|
||||
ERR("Could not get DBus name: %s", err->message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -357,22 +359,22 @@ _cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
|||
}
|
||||
|
||||
dbus_error_init(&new_err);
|
||||
dbus_message_get_args(msg, &new_err, DBUS_TYPE_UINT32, &msgtype, DBUS_TYPE_INVALID);
|
||||
|
||||
if (msgtype == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ||
|
||||
msgtype == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)
|
||||
dbus_message_get_args
|
||||
(msg, &new_err, DBUS_TYPE_UINT32, &msgtype, DBUS_TYPE_INVALID);
|
||||
if (msgtype != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
int i;
|
||||
|
||||
interface_list = eina_hash_string_small_new((Eina_Free_Cb)e_dbus_interface_unref);
|
||||
ERR("Could not get the DBus name: reply=%d", msgtype);
|
||||
return;
|
||||
}
|
||||
|
||||
interface_list = eina_hash_string_small_new
|
||||
((Eina_Free_Cb)e_dbus_interface_unref);
|
||||
for (i = 0; object_list[i]; i++)
|
||||
{
|
||||
bus_obj = e_dbus_object_add(conn, object_list[i], NULL);
|
||||
E_DBus_Interface *interface = e_dbus_interface_new(PLAYER_INTERFACE_NAME);
|
||||
e_dbus_object_interface_attach(bus_obj, interface);
|
||||
|
||||
eina_hash_add(interface_list, object_list[i], interface);
|
||||
E_DBus_Interface *iface = e_dbus_interface_new(PLAYER_INTERFACE_NAME);
|
||||
e_dbus_object_interface_attach(bus_obj, iface);
|
||||
eina_hash_add(interface_list, object_list[i], iface);
|
||||
}
|
||||
|
||||
_mpris_signals_add(PLAYER_NAME, mpris_player_signals);
|
||||
|
@ -382,7 +384,6 @@ _cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
|||
_mpris_methods_add(PLAYER_NAME, mpris_player_methods);
|
||||
_mpris_methods_add(TRACKLIST_NAME, mpris_tracklist_methods);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_mpris_signals_add(const char *root, const MPRIS_Signal *signals)
|
||||
|
|
Loading…
Reference in New Issue