enjoy: improved plugin infrastructure.
Plugins can now be disabled and enabled (at least in infrastructure terms, no UI or code to filter out enabled plugins). Two new signals will be emitted to main loop: - ENJOY_EVENT_STARTED - ENJOY_EVENT_QUIT Plugins will be enabled on start, disabled on quit. Quit will also preserve the main loop until everything is done using it. It is required for stuff like FSO that needs to talk to DBus to re-enable the CPU policy. SVN revision: 63163
This commit is contained in:
parent
416b55125d
commit
cdc69191ba
227
src/bin/main.c
227
src/bin/main.c
|
@ -38,13 +38,175 @@ static const Ecore_Getopt options = {
|
|||
}
|
||||
};
|
||||
|
||||
uint32_t
|
||||
struct _Enjoy_Plugin {
|
||||
EINA_INLIST;
|
||||
const char *name;
|
||||
const Enjoy_Plugin_Api *api;
|
||||
int priority;
|
||||
Eina_Bool deleted:1;
|
||||
Eina_Bool enabled:1;
|
||||
};
|
||||
static int plugins_walking = 0;
|
||||
static int plugins_deleted = 0;
|
||||
static Eina_Inlist *plugins_registry = NULL;
|
||||
|
||||
static int
|
||||
_plugin_priority_cmp(const void *pa, const void *pb)
|
||||
{
|
||||
const Enjoy_Plugin *a = pa;
|
||||
const Enjoy_Plugin *b = pb;
|
||||
int r = a->priority - b->priority;
|
||||
if (r) return r;
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
EAPI Enjoy_Plugin *
|
||||
enjoy_plugin_register(const char *name, const Enjoy_Plugin_Api *api, int priority)
|
||||
{
|
||||
Enjoy_Plugin *p;
|
||||
if (!name)
|
||||
{
|
||||
ERR("Missing plugin name");
|
||||
return NULL;
|
||||
}
|
||||
if (!api)
|
||||
{
|
||||
ERR("Missing plugin api");
|
||||
return NULL;
|
||||
}
|
||||
if (api->version != ENJOY_PLUGIN_API_VERSION)
|
||||
{
|
||||
ERR("Invalid Enjoy_Plugin_Api version: plugin=%u, enjoy=%u",
|
||||
api->version, ENJOY_PLUGIN_API_VERSION);
|
||||
return NULL;
|
||||
}
|
||||
if (!api->enable)
|
||||
{
|
||||
ERR("%s: api->enable == NULL", name);
|
||||
return NULL;
|
||||
}
|
||||
if (!api->disable)
|
||||
{
|
||||
ERR("%s: api->disable == NULL", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = calloc(1, sizeof(Enjoy_Plugin));
|
||||
if (!p)
|
||||
{
|
||||
ERR("Could not allocate plugin structure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->name = eina_stringshare_add(name);
|
||||
p->api = api;
|
||||
p->priority = priority;
|
||||
|
||||
plugins_registry = eina_inlist_sorted_insert
|
||||
(plugins_registry, EINA_INLIST_GET(p), _plugin_priority_cmp);
|
||||
|
||||
DBG("plugin %s registered %p", name, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
enjoy_plugins_walk(void)
|
||||
{
|
||||
plugins_walking++;
|
||||
}
|
||||
|
||||
void
|
||||
enjoy_plugins_unwalk(void)
|
||||
{
|
||||
Eina_Inlist *l;
|
||||
|
||||
plugins_walking--;
|
||||
if (plugins_walking > 0) return;
|
||||
plugins_walking = 0;
|
||||
|
||||
DBG("delete pending %d plugins", plugins_deleted);
|
||||
for (l = plugins_registry; l != NULL && plugins_deleted > 0;)
|
||||
{
|
||||
Enjoy_Plugin *p = EINA_INLIST_CONTAINER_GET(l, Enjoy_Plugin);
|
||||
|
||||
l = l->next;
|
||||
if (!p->deleted) continue;
|
||||
|
||||
DBG("deleted pending %s", p->name);
|
||||
plugins_registry = eina_inlist_remove
|
||||
(plugins_registry, EINA_INLIST_GET(p));
|
||||
eina_stringshare_del(p->name);
|
||||
free(p);
|
||||
plugins_deleted--;
|
||||
}
|
||||
}
|
||||
|
||||
EAPI void
|
||||
enjoy_plugin_unregister(Enjoy_Plugin *p)
|
||||
{
|
||||
if (!p)
|
||||
{
|
||||
ERR("No plugin given");
|
||||
return;
|
||||
}
|
||||
if (p->deleted) return;
|
||||
p->deleted = EINA_TRUE;
|
||||
|
||||
if (p->enabled) enjoy_plugin_disable(p);
|
||||
|
||||
DBG("plugin %s unregistered %p", p->name, p);
|
||||
if (plugins_walking > 0)
|
||||
{
|
||||
plugins_deleted++;
|
||||
return;
|
||||
}
|
||||
|
||||
plugins_registry = eina_inlist_remove(plugins_registry, EINA_INLIST_GET(p));
|
||||
eina_stringshare_del(p->name);
|
||||
free(p);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
enjoy_plugin_enable(Enjoy_Plugin *p)
|
||||
{
|
||||
Eina_Bool r;
|
||||
if (!p)
|
||||
{
|
||||
ERR("No plugin given");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (p->enabled) return EINA_TRUE;
|
||||
DBG("Enable plugin '%s'", p->name);
|
||||
r = p->api->enable(p);
|
||||
if (!r) ERR("Failed to enable plugin '%s'", p->name);
|
||||
else p->enabled = EINA_TRUE;
|
||||
return r;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
enjoy_plugin_disable(Enjoy_Plugin *p)
|
||||
{
|
||||
Eina_Bool r;
|
||||
if (!p)
|
||||
{
|
||||
ERR("No plugin given");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
if (!p->enabled) return EINA_TRUE;
|
||||
DBG("Disable plugin '%s'", p->name);
|
||||
r = p->api->disable(p);
|
||||
if (!r) ERR("Failed to disable plugin '%s'", p->name);
|
||||
p->enabled = EINA_FALSE;
|
||||
return r;
|
||||
}
|
||||
|
||||
EAPI uint32_t
|
||||
enjoy_abi_version(void)
|
||||
{
|
||||
return ENJOY_ABI_VERSION;
|
||||
}
|
||||
|
||||
char *
|
||||
EAPI char *
|
||||
enjoy_cache_dir_get(void)
|
||||
{
|
||||
static char *cache = NULL;
|
||||
|
@ -88,6 +250,8 @@ enjoy_cache_dir_get(void)
|
|||
return cache;
|
||||
}
|
||||
|
||||
EAPI int ENJOY_EVENT_STARTED = -1;
|
||||
EAPI int ENJOY_EVENT_QUIT = -1;
|
||||
EAPI int ENJOY_EVENT_PLAYER_CAPS_CHANGE = -1;
|
||||
EAPI int ENJOY_EVENT_PLAYER_STATUS_CHANGE = -1;
|
||||
EAPI int ENJOY_EVENT_PLAYER_TRACK_CHANGE = -1;
|
||||
|
@ -96,6 +260,8 @@ EAPI int ENJOY_EVENT_TRACKLIST_TRACKLIST_CHANGE = -1;
|
|||
static void
|
||||
enjoy_event_id_init(void)
|
||||
{
|
||||
ENJOY_EVENT_STARTED = ecore_event_type_new();
|
||||
ENJOY_EVENT_QUIT = ecore_event_type_new();
|
||||
ENJOY_EVENT_PLAYER_CAPS_CHANGE = ecore_event_type_new();
|
||||
ENJOY_EVENT_PLAYER_STATUS_CHANGE = ecore_event_type_new();
|
||||
ENJOY_EVENT_PLAYER_TRACK_CHANGE = ecore_event_type_new();
|
||||
|
@ -153,6 +319,59 @@ enjoy_module_unload(void)
|
|||
app.modules = NULL;
|
||||
}
|
||||
|
||||
static int _quit_count = 0;
|
||||
|
||||
static void
|
||||
_enjoy_event_quit_done(void *a __UNUSED__, void *b __UNUSED__)
|
||||
{
|
||||
if (_quit_count > 0) return;
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
EAPI void
|
||||
enjoy_quit(void)
|
||||
{
|
||||
static Eina_Bool _called = EINA_FALSE;
|
||||
Enjoy_Plugin *p;
|
||||
|
||||
if (_called) return;
|
||||
_called = EINA_TRUE;
|
||||
|
||||
enjoy_plugins_walk();
|
||||
EINA_INLIST_FOREACH(plugins_registry, p)
|
||||
enjoy_plugin_disable(p);
|
||||
enjoy_plugins_unwalk();
|
||||
|
||||
ecore_event_add(ENJOY_EVENT_QUIT, NULL, _enjoy_event_quit_done, NULL);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
enjoy_quit_freeze(void)
|
||||
{
|
||||
_quit_count++;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
enjoy_quit_thaw(void)
|
||||
{
|
||||
_quit_count--;
|
||||
if (_quit_count > 0) return;
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_started(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
|
||||
{
|
||||
Enjoy_Plugin *p;
|
||||
|
||||
enjoy_plugins_walk();
|
||||
EINA_INLIST_FOREACH(plugins_registry, p)
|
||||
enjoy_plugin_enable(p);
|
||||
enjoy_plugins_unwalk();
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
|
@ -222,8 +441,12 @@ elm_main(int argc, char **argv)
|
|||
|
||||
cover_init();
|
||||
enjoy_event_id_init();
|
||||
ecore_event_handler_add(ENJOY_EVENT_STARTED, _cb_started, NULL);
|
||||
|
||||
enjoy_module_load();
|
||||
|
||||
/* will run after other events run, in the main loop */
|
||||
ecore_event_add(ENJOY_EVENT_STARTED, NULL, NULL, NULL);
|
||||
elm_run();
|
||||
|
||||
end:
|
||||
|
|
|
@ -11,6 +11,27 @@ typedef struct _Song Song;
|
|||
typedef struct _Enjoy_Player_Status Enjoy_Player_Status;
|
||||
typedef struct _Enjoy_Player_Caps Enjoy_Player_Caps;
|
||||
|
||||
/**
|
||||
* Enjoy was started.
|
||||
*
|
||||
* Plugins that called enjoy_plugin_register() will be called from here,
|
||||
* as well as when they are enabled/disabled.
|
||||
*/
|
||||
EAPI extern int ENJOY_EVENT_STARTED;
|
||||
/**
|
||||
* Enjoy is about to quit
|
||||
*
|
||||
* Plugins that called enjoy_plugin_register() will be called from here,
|
||||
* as well as when they are enabled/disabled.
|
||||
*
|
||||
* Plugins should finalize its stuff. If mainloop is required any
|
||||
* further, call enjoy_quit_freeze(), do its stuff and then
|
||||
* enjoy_quit_thaw().
|
||||
*
|
||||
* When this is called, don't trust any of GUI is live. Just finish
|
||||
* your stuff.
|
||||
*/
|
||||
EAPI extern int ENJOY_EVENT_QUIT;
|
||||
/**
|
||||
* Capabilities changed. Use enjoy_player_caps_get() for value.
|
||||
*/
|
||||
|
@ -19,7 +40,14 @@ EAPI extern int ENJOY_EVENT_PLAYER_CAPS_CHANGE;
|
|||
* Status changed. Use enjoy_player_status_get() for value.
|
||||
*/
|
||||
EAPI extern int ENJOY_EVENT_PLAYER_STATUS_CHANGE;
|
||||
/**
|
||||
* Current track (song) changed. Use enjoy_song_current_get() for new song.
|
||||
*/
|
||||
EAPI extern int ENJOY_EVENT_PLAYER_TRACK_CHANGE;
|
||||
/**
|
||||
* Current list view (playlist) changed. Use enjoy_playlist_count() and
|
||||
* enjoy_playlist_current_position_get() for new values.
|
||||
*/
|
||||
EAPI extern int ENJOY_EVENT_TRACKLIST_TRACKLIST_CHANGE;
|
||||
|
||||
struct _Enjoy_Player_Caps {
|
||||
|
@ -45,19 +73,16 @@ struct _Enjoy_Player_Status {
|
|||
Eina_Bool endless:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* When you're loaded use ENJOY_ABI_CHECK() to see if you're okay or not.
|
||||
*/
|
||||
#define ENJOY_ABI_VERSION (1U)
|
||||
EAPI uint32_t enjoy_abi_version(void) EINA_CONST;
|
||||
#define ENJOY_ABI_CHECK() (ENJOY_ABI_VERSION == enjoy_abi_version())
|
||||
EAPI void enjoy_quit(void);
|
||||
EAPI void enjoy_quit_freeze(void);
|
||||
EAPI void enjoy_quit_thaw(void);
|
||||
|
||||
EAPI char *enjoy_cache_dir_get(void);
|
||||
EAPI Eina_Bool enjoy_repeat_get(void);
|
||||
EAPI int32_t enjoy_playlist_current_position_get(void);
|
||||
EAPI int32_t enjoy_position_get(void);
|
||||
EAPI int32_t enjoy_volume_get(void);
|
||||
EAPI int32_t enjoy_playlist_count(void);
|
||||
EAPI int32_t enjoy_playlist_current_position_get(void);
|
||||
EAPI const Song*enjoy_playlist_song_position_get(int32_t position);
|
||||
EAPI const Song*enjoy_song_current_get(void);
|
||||
EAPI const Song*enjoy_song_position_get(int32_t position);
|
||||
|
@ -70,11 +95,43 @@ EAPI void enjoy_control_seek(uint64_t position);
|
|||
EAPI void enjoy_control_shuffle_set(Eina_Bool param);
|
||||
EAPI void enjoy_control_stop(void);
|
||||
EAPI void enjoy_position_set(int32_t position);
|
||||
EAPI void enjoy_quit(void);
|
||||
EAPI void enjoy_repeat_set(Eina_Bool repeat);
|
||||
EAPI void enjoy_volume_set(int32_t volume);
|
||||
|
||||
EAPI Enjoy_Player_Caps enjoy_player_caps_get(void);
|
||||
EAPI Enjoy_Player_Status enjoy_player_status_get(void);
|
||||
|
||||
/**
|
||||
* When you're loaded use ENJOY_ABI_CHECK() to see if you're okay or not.
|
||||
*/
|
||||
#define ENJOY_ABI_VERSION (1U)
|
||||
EAPI uint32_t enjoy_abi_version(void) EINA_CONST;
|
||||
#define ENJOY_ABI_CHECK() (ENJOY_ABI_VERSION == enjoy_abi_version())
|
||||
|
||||
typedef struct _Enjoy_Plugin Enjoy_Plugin;
|
||||
typedef struct _Enjoy_Plugin_Api Enjoy_Plugin_Api;
|
||||
|
||||
struct _Enjoy_Plugin_Api {
|
||||
#define ENJOY_PLUGIN_API_VERSION (1U)
|
||||
unsigned int version;
|
||||
Eina_Bool (*enable)(Enjoy_Plugin *plugin);
|
||||
Eina_Bool (*disable)(Enjoy_Plugin *plugin);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
ENJOY_PLUGIN_PRIORITY_HIGH = -1000,
|
||||
ENJOY_PLUGIN_PRIORITY_NORMAL = 0,
|
||||
ENJOY_PLUGIN_PRIORITY_LOW = 1000
|
||||
} Enjoy_Plugin_Priority;
|
||||
|
||||
/**
|
||||
* Register the given plugin name with api at priority.
|
||||
*
|
||||
* Priority will define plugin order, but it will also consider the
|
||||
* name, so relative positioning based on name is possible (use
|
||||
* namespaces!)
|
||||
*/
|
||||
EAPI Enjoy_Plugin *enjoy_plugin_register(const char *name, const Enjoy_Plugin_Api *api, int priority);
|
||||
EAPI void enjoy_plugin_unregister(Enjoy_Plugin *plugin);
|
||||
|
||||
#endif /* __PLUGIN_H__ */
|
||||
|
|
|
@ -178,4 +178,8 @@ void db_nameid_free(NameID *nameid);
|
|||
#define db_artist_free(v) db_nameid_free(v)
|
||||
#define db_genre_free(v) db_nameid_free(v)
|
||||
|
||||
Eina_Bool enjoy_plugin_enable(Enjoy_Plugin *p);
|
||||
Eina_Bool enjoy_plugin_disable(Enjoy_Plugin *p);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -301,6 +301,13 @@ _win_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_
|
|||
if (w->db_path) eina_stringshare_del(w->db_path);
|
||||
}
|
||||
|
||||
static void
|
||||
_win_del_request(void *data __UNUSED__, Evas_Object *o, void *event_info __UNUSED__)
|
||||
{
|
||||
evas_object_hide(o);
|
||||
enjoy_quit();
|
||||
}
|
||||
|
||||
static void
|
||||
_win_prev(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
||||
{
|
||||
|
@ -547,12 +554,6 @@ enjoy_control_seek(uint64_t position)
|
|||
emotion_object_position_set(w->emotion, w->play.position);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
enjoy_quit(void)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
}
|
||||
|
||||
EAPI Enjoy_Player_Caps
|
||||
enjoy_player_caps_get(void)
|
||||
{
|
||||
|
@ -742,8 +743,9 @@ win_new(App *app)
|
|||
elm_win_resize_object_add(w->win, w->bg);
|
||||
evas_object_show(w->bg);
|
||||
|
||||
elm_win_autodel_set(w->win, 1); // TODO
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
elm_win_autodel_set(w->win, EINA_FALSE);
|
||||
evas_object_smart_callback_add
|
||||
(w->win, "delete,request", _win_del_request, w);
|
||||
|
||||
snprintf(path, sizeof(path), "%s/media.db", app->configdir);
|
||||
w->db_path = eina_stringshare_add(path);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <Eina.h>
|
||||
#include <E_DBus.h>
|
||||
#include <Ecore.h>
|
||||
#include "plugin.h"
|
||||
|
||||
static int _fso_log_domain = -1;
|
||||
|
@ -30,53 +31,130 @@ static int _fso_log_domain = -1;
|
|||
#define FSO_OUSAGED_OBJECT_PATH "/org/freesmartphone/Usage"
|
||||
#define FSO_OUSAGED_INTERFACE "org.freesmartphone.Usage"
|
||||
|
||||
static E_DBus_Connection *sysconn = NULL;
|
||||
static E_DBus_Connection *conn = NULL;
|
||||
|
||||
/* callbacks */
|
||||
typedef struct _FSO_Cb_Data
|
||||
{
|
||||
void (*func)(void *data, Eina_Bool error);
|
||||
void *data;
|
||||
} FSO_Cb_Data;
|
||||
|
||||
static void
|
||||
fso_request_reource_cb(void *data, DBusMessage *replymsg, DBusError *error)
|
||||
fso_request_resource_cb(void *data, DBusMessage *replymsg __UNUSED__, DBusError *error)
|
||||
{
|
||||
FSO_Cb_Data *d = data;
|
||||
Eina_Bool e = EINA_FALSE;
|
||||
|
||||
DBG("Request sent to fsousaged to enable resource.");
|
||||
|
||||
if (error && dbus_error_is_set(error))
|
||||
ERR("Error requesting FSO resource: %s - %s", error->name, error->message);
|
||||
{
|
||||
ERR("Error requesting FSO resource: %s - %s",
|
||||
error->name, error->message);
|
||||
e = EINA_TRUE;
|
||||
}
|
||||
|
||||
if ((d) && (d->func))
|
||||
d->func(d->data, e);
|
||||
free(d);
|
||||
}
|
||||
|
||||
static void
|
||||
fso_release_reource_cb(void *data, DBusMessage *replymsg, DBusError *error)
|
||||
fso_release_resource_cb(void *data, DBusMessage *replymsg __UNUSED__, DBusError *error)
|
||||
{
|
||||
FSO_Cb_Data *d = data;
|
||||
Eina_Bool e = EINA_FALSE;
|
||||
|
||||
DBG("Request sent to fsousaged to disable resource.");
|
||||
|
||||
if (error && dbus_error_is_set(error))
|
||||
ERR("Error releasing FSO resource: %s - %s", error->name, error->message);
|
||||
{
|
||||
ERR("Error releasing FSO resource: %s - %s",
|
||||
error->name, error->message);
|
||||
e = EINA_TRUE;
|
||||
}
|
||||
|
||||
if ((d) && (d->func))
|
||||
d->func(d->data, e);
|
||||
free(d);
|
||||
}
|
||||
|
||||
static void
|
||||
fso_request_resource(const char *resource)
|
||||
fso_request_resource(const char *resource, void (*func)(void *data, Eina_Bool error), const void *data)
|
||||
{
|
||||
FSO_Cb_Data *d = NULL;
|
||||
DBusMessage *msg = dbus_message_new_method_call
|
||||
(FSO_OUSAGED_SERVICE, FSO_OUSAGED_OBJECT_PATH, FSO_OUSAGED_INTERFACE,
|
||||
"RequestResource");
|
||||
dbus_message_append_args
|
||||
(msg, DBUS_TYPE_STRING, &resource, DBUS_TYPE_INVALID);
|
||||
e_dbus_message_send(sysconn, msg, fso_request_reource_cb, -1, NULL);
|
||||
|
||||
if (func)
|
||||
{
|
||||
d = malloc(sizeof(FSO_Cb_Data));
|
||||
if (d)
|
||||
{
|
||||
d->func = func;
|
||||
d->data = (void *)data;
|
||||
}
|
||||
}
|
||||
|
||||
e_dbus_message_send(conn, msg, fso_request_resource_cb, -1, d);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fso_release_resource(const char *resource)
|
||||
fso_release_resource(const char *resource, void (*func)(void *data, Eina_Bool error), const void *data)
|
||||
{
|
||||
FSO_Cb_Data *d = NULL;
|
||||
DBusMessage *msg = dbus_message_new_method_call
|
||||
(FSO_OUSAGED_SERVICE, FSO_OUSAGED_OBJECT_PATH, FSO_OUSAGED_INTERFACE,
|
||||
"ReleaseResource");
|
||||
dbus_message_append_args
|
||||
(msg, DBUS_TYPE_STRING, &resource, DBUS_TYPE_INVALID);
|
||||
e_dbus_message_send(sysconn, msg, fso_release_reource_cb, -1, NULL);
|
||||
|
||||
if (func)
|
||||
{
|
||||
d = malloc(sizeof(FSO_Cb_Data));
|
||||
if (d)
|
||||
{
|
||||
d->func = func;
|
||||
d->data = (void *)data;
|
||||
}
|
||||
}
|
||||
|
||||
e_dbus_message_send(conn, msg, fso_release_resource_cb, -1, d);
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
fso_enable(Enjoy_Plugin *p __UNUSED__)
|
||||
{
|
||||
fso_request_resource("CPU", NULL, NULL);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_fso_release_resource_done(void *data __UNUSED__, Eina_Bool error __UNUSED__)
|
||||
{
|
||||
enjoy_quit_thaw();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
fso_disable(Enjoy_Plugin *p __UNUSED__)
|
||||
{
|
||||
enjoy_quit_freeze();
|
||||
fso_release_resource("CPU", _cb_fso_release_resource_done, NULL);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static const Enjoy_Plugin_Api api = {
|
||||
ENJOY_PLUGIN_API_VERSION,
|
||||
fso_enable,
|
||||
fso_disable
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
fso_init(void)
|
||||
{
|
||||
|
@ -95,26 +173,36 @@ fso_init(void)
|
|||
{
|
||||
ERR("ABI versions differ: enjoy=%u, fso=%u",
|
||||
enjoy_abi_version(), ENJOY_ABI_VERSION);
|
||||
eina_log_domain_unregister(_fso_log_domain);
|
||||
_fso_log_domain = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sysconn) return EINA_TRUE;
|
||||
if (conn) return EINA_TRUE;
|
||||
|
||||
e_dbus_init();
|
||||
sysconn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
|
||||
fso_request_resource("CPU");
|
||||
conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
|
||||
if (!conn)
|
||||
{
|
||||
ERR("Could not get DBus session bus");
|
||||
goto error;
|
||||
}
|
||||
|
||||
enjoy_plugin_register("sys/fso", &api, ENJOY_PLUGIN_PRIORITY_NORMAL);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
eina_log_domain_unregister(_fso_log_domain);
|
||||
_fso_log_domain = -1;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fso_shutdown(void)
|
||||
{
|
||||
if (!sysconn) return;
|
||||
fso_release_resource("CPU");
|
||||
if (!conn) return;
|
||||
|
||||
e_dbus_shutdown();
|
||||
sysconn = NULL;
|
||||
conn = NULL;
|
||||
if (_fso_log_domain >= 0)
|
||||
{
|
||||
eina_log_domain_unregister(_fso_log_domain);
|
||||
|
|
|
@ -106,11 +106,9 @@ struct _MPRIS_Signal {
|
|||
|
||||
|
||||
static E_DBus_Connection *conn = NULL;
|
||||
static E_DBus_Object *bus_obj = NULL;
|
||||
static Eina_Hash *interface_list = NULL;
|
||||
static Ecore_Event_Handler *event_handler_caps_change,
|
||||
*event_handler_status_change,
|
||||
*event_handler_track_change,
|
||||
*event_handler_tracklist_change;
|
||||
static Eina_List *ev_handlers = NULL;
|
||||
|
||||
|
||||
static const char *object_list[] = { ROOT_NAME, TRACKLIST_NAME, PLAYER_NAME, NULL };
|
||||
|
@ -232,6 +230,52 @@ _cb_player_tracklist_change(void *data __UNUSED__, int type __UNUSED__, void *ev
|
|||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
mpris_enable(Enjoy_Plugin *p __UNUSED__)
|
||||
{
|
||||
#define EV_HANDLER(ev, func, data) \
|
||||
ev_handlers = eina_list_append \
|
||||
(ev_handlers, ecore_event_handler_add(ev, func, data))
|
||||
|
||||
EV_HANDLER(ENJOY_EVENT_PLAYER_CAPS_CHANGE, _cb_player_caps_change, NULL);
|
||||
EV_HANDLER(ENJOY_EVENT_PLAYER_STATUS_CHANGE, _cb_player_status_change, NULL);
|
||||
EV_HANDLER(ENJOY_EVENT_PLAYER_TRACK_CHANGE, _cb_player_track_change, NULL);
|
||||
EV_HANDLER(ENJOY_EVENT_TRACKLIST_TRACKLIST_CHANGE,
|
||||
_cb_player_tracklist_change, NULL);
|
||||
#undef EV_HANDLER
|
||||
|
||||
e_dbus_request_name(conn, APPLICATION_NAME, 0, _cb_dbus_request_name, NULL);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
mpris_disable(Enjoy_Plugin *p __UNUSED__)
|
||||
{
|
||||
Ecore_Event_Handler *eh;
|
||||
|
||||
if (interface_list)
|
||||
{
|
||||
eina_hash_free(interface_list);
|
||||
interface_list = NULL;
|
||||
}
|
||||
if (bus_obj)
|
||||
{
|
||||
e_dbus_object_free(bus_obj);
|
||||
bus_obj = NULL;
|
||||
}
|
||||
|
||||
EINA_LIST_FREE(ev_handlers, eh)
|
||||
ecore_event_handler_del(eh);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static const Enjoy_Plugin_Api api = {
|
||||
ENJOY_PLUGIN_API_VERSION,
|
||||
mpris_enable,
|
||||
mpris_disable
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
mpris_init(void)
|
||||
{
|
||||
|
@ -250,34 +294,36 @@ mpris_init(void)
|
|||
{
|
||||
ERR("ABI versions differ: enjoy=%u, mpris=%u",
|
||||
enjoy_abi_version(), ENJOY_ABI_VERSION);
|
||||
eina_log_domain_unregister(_mpris_log_domain);
|
||||
_mpris_log_domain = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn) return EINA_TRUE;
|
||||
|
||||
e_dbus_init();
|
||||
conn = e_dbus_bus_get(DBUS_BUS_SESSION);
|
||||
if (conn)
|
||||
e_dbus_request_name(conn, APPLICATION_NAME, 0, _cb_dbus_request_name, NULL);
|
||||
event_handler_caps_change = ecore_event_handler_add(ENJOY_EVENT_PLAYER_CAPS_CHANGE, _cb_player_caps_change, NULL);
|
||||
event_handler_status_change = ecore_event_handler_add(ENJOY_EVENT_PLAYER_STATUS_CHANGE, _cb_player_status_change, NULL);
|
||||
event_handler_track_change = ecore_event_handler_add(ENJOY_EVENT_PLAYER_TRACK_CHANGE, _cb_player_track_change, NULL);
|
||||
event_handler_tracklist_change = ecore_event_handler_add(ENJOY_EVENT_TRACKLIST_TRACKLIST_CHANGE, _cb_player_tracklist_change, NULL);
|
||||
if (!conn)
|
||||
{
|
||||
ERR("Could not get DBus session bus");
|
||||
goto error;
|
||||
}
|
||||
|
||||
enjoy_plugin_register("listener/mpris", &api, ENJOY_PLUGIN_PRIORITY_HIGH);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
eina_log_domain_unregister(_mpris_log_domain);
|
||||
_mpris_log_domain = -1;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
mpris_shutdown(void)
|
||||
{
|
||||
if (!conn) return;
|
||||
ecore_event_handler_del(event_handler_caps_change);
|
||||
ecore_event_handler_del(event_handler_status_change);
|
||||
ecore_event_handler_del(event_handler_track_change);
|
||||
ecore_event_handler_del(event_handler_tracklist_change);
|
||||
eina_hash_free(interface_list);
|
||||
|
||||
e_dbus_shutdown();
|
||||
conn = NULL;
|
||||
interface_list = NULL;
|
||||
|
||||
if (_mpris_log_domain >= 0)
|
||||
{
|
||||
|
@ -297,6 +343,18 @@ _cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
|||
dbus_error_free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface_list)
|
||||
{
|
||||
eina_hash_free(interface_list);
|
||||
interface_list = NULL;
|
||||
}
|
||||
|
||||
if (bus_obj)
|
||||
{
|
||||
e_dbus_object_free(bus_obj);
|
||||
bus_obj = NULL;
|
||||
}
|
||||
|
||||
dbus_error_init(&new_err);
|
||||
dbus_message_get_args(msg, &new_err, DBUS_TYPE_UINT32, &msgtype, DBUS_TYPE_INVALID);
|
||||
|
@ -310,9 +368,9 @@ _cb_dbus_request_name(void *data __UNUSED__, DBusMessage *msg, DBusError *err)
|
|||
|
||||
for (i = 0; object_list[i]; i++)
|
||||
{
|
||||
E_DBus_Object *object = e_dbus_object_add(conn, object_list[i], NULL);
|
||||
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(object, interface);
|
||||
e_dbus_object_interface_attach(bus_obj, interface);
|
||||
|
||||
eina_hash_add(interface_list, object_list[i], interface);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue