forked from enlightenment/enlightenment
E_Client: add an abstraction api to control volume by app
This api give the possibility to add sink to an E_Client and control the volume or the mute state of the sinks associated with this E_Client. @features
This commit is contained in:
parent
1943cee080
commit
06ea6cadbd
|
@ -72,6 +72,7 @@ src/bin/e_bg.h \
|
|||
src/bin/e_bindings.h \
|
||||
src/bin/e_bryce.h \
|
||||
src/bin/e_client.h \
|
||||
src/bin/e_client_volume.h \
|
||||
src/bin/e_client.x \
|
||||
src/bin/e_color_dialog.h \
|
||||
src/bin/e_color.h \
|
||||
|
@ -243,6 +244,7 @@ src/bin/e_bindings.c \
|
|||
src/bin/e_bryce.c \
|
||||
src/bin/e_bryce_editor.c \
|
||||
src/bin/e_client.c \
|
||||
src/bin/e_client_volume.c \
|
||||
src/bin/e_color.c \
|
||||
src/bin/e_color_dialog.c \
|
||||
src/bin/e_comp.c \
|
||||
|
|
|
@ -578,6 +578,7 @@ static void
|
|||
_e_client_del(E_Client *ec)
|
||||
{
|
||||
E_Client *child;
|
||||
E_Client_Volume_Sink *sink;
|
||||
|
||||
ec->changed = 0;
|
||||
focus_stack = eina_list_remove(focus_stack, ec);
|
||||
|
@ -661,6 +662,9 @@ _e_client_del(E_Client *ec)
|
|||
|
||||
e_comp->clients = eina_list_remove(e_comp->clients, ec);
|
||||
e_comp_object_render_update_del(ec->frame);
|
||||
|
||||
EINA_LIST_FREE(ec->sinks, sink)
|
||||
sink->clients = eina_list_remove(sink->clients, ec);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
@ -5113,3 +5117,4 @@ e_client_layout_cb_set(E_Client_Layout_Cb cb)
|
|||
CRI("ATTEMPTING TO OVERWRITE EXISTING CLIENT LAYOUT HOOK!!!");
|
||||
_e_client_layout_cb = cb;
|
||||
}
|
||||
|
||||
|
|
|
@ -689,6 +689,13 @@ struct E_Client
|
|||
|
||||
Eina_Stringshare *uuid;
|
||||
|
||||
Eina_List *sinks;
|
||||
int volume;
|
||||
int volume_min;
|
||||
int volume_max;
|
||||
unsigned char mute : 1;
|
||||
unsigned char volume_control_enabled : 1;
|
||||
|
||||
Eina_Bool override : 1;
|
||||
Eina_Bool input_only : 1;
|
||||
Eina_Bool dialog : 1;
|
||||
|
@ -747,6 +754,7 @@ E_API extern int E_EVENT_CLIENT_FULLSCREEN;
|
|||
E_API extern int E_EVENT_CLIENT_UNFULLSCREEN;
|
||||
|
||||
|
||||
|
||||
EINTERN void e_client_idler_before(void);
|
||||
EINTERN Eina_Bool e_client_init(void);
|
||||
EINTERN void e_client_shutdown(void);
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
#include "e.h"
|
||||
|
||||
E_API int E_EVENT_CLIENT_VOLUME = -1;
|
||||
E_API int E_EVENT_CLIENT_MUTE = -1;
|
||||
E_API int E_EVENT_CLIENT_UNMUTE = -1;
|
||||
|
||||
static void
|
||||
_e_client_volume_event_simple_free(void *d EINA_UNUSED, E_Event_Client *ev)
|
||||
{
|
||||
UNREFD(ev->ec, 3);
|
||||
e_object_unref(E_OBJECT(ev->ec));
|
||||
free(ev);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_client_volume_event_simple(E_Client *ec, int type)
|
||||
{
|
||||
E_Event_Client *ev;
|
||||
|
||||
ev = E_NEW(E_Event_Client, 1);
|
||||
ev->ec = ec;
|
||||
REFD(ec, 3);
|
||||
e_object_ref(E_OBJECT(ec));
|
||||
ecore_event_add(type, ev,
|
||||
(Ecore_End_Cb)_e_client_volume_event_simple_free, NULL);
|
||||
}
|
||||
|
||||
|
||||
EINTERN int
|
||||
e_client_volume_init(void)
|
||||
{
|
||||
E_EVENT_CLIENT_VOLUME = ecore_event_type_new();
|
||||
E_EVENT_CLIENT_MUTE = ecore_event_type_new();
|
||||
E_EVENT_CLIENT_UNMUTE = ecore_event_type_new();
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
e_client_volume_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
E_API E_Client_Volume_Sink *
|
||||
e_client_volume_sink_new(E_Client_Volume_Sink_Get func_get, E_Client_Volume_Sink_Set func_set, E_Client_Volume_Sink_Min_Get func_min_get, E_Client_Volume_Sink_Max_Get func_max_get, void *data)
|
||||
{
|
||||
E_Client_Volume_Sink *sink;
|
||||
|
||||
sink = E_NEW(E_Client_Volume_Sink, 1);
|
||||
sink->func_set = func_set;
|
||||
sink->func_get = func_get;
|
||||
sink->func_min_get = func_min_get;
|
||||
sink->func_max_get = func_max_get;
|
||||
sink->data = data;
|
||||
|
||||
return sink;
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_del(E_Client_Volume_Sink *sink)
|
||||
{
|
||||
E_Client *ec;
|
||||
|
||||
EINA_LIST_FREE(sink->clients, ec)
|
||||
{
|
||||
ec->sinks = eina_list_remove(ec->sinks, sink);
|
||||
}
|
||||
free(sink);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_set(E_Client_Volume_Sink *sink, int volume, Eina_Bool mute)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(sink);
|
||||
if (sink->func_set)
|
||||
sink->func_set(volume, mute, sink->data);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_get(const E_Client_Volume_Sink *sink, int *volume, Eina_Bool *mute)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(sink);
|
||||
if (sink->func_get)
|
||||
sink->func_get(volume, mute, sink->data);
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_client_volume_sink_min_get(const E_Client_Volume_Sink *sink)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sink, 0);
|
||||
if (sink->func_min_get)
|
||||
return sink->func_min_get(sink->data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_client_volume_sink_max_get(const E_Client_Volume_Sink *sink)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(sink, 0);
|
||||
if (sink->func_max_get)
|
||||
return sink->func_max_get(sink->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_append(E_Client *ec, E_Client_Volume_Sink *sink)
|
||||
{
|
||||
int volume_min;
|
||||
int volume_max;
|
||||
int volume;
|
||||
Eina_Bool mute;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(ec);
|
||||
|
||||
ec->sinks = eina_list_append(ec->sinks, sink);
|
||||
sink->clients = eina_list_append(sink->clients, ec);
|
||||
if (ec->volume_control_enabled)
|
||||
{
|
||||
volume_min = e_client_volume_sink_min_get(sink);
|
||||
if (ec->volume_min < volume_min)
|
||||
ec->volume_min = volume_min;
|
||||
volume_max = e_client_volume_sink_max_get(sink);
|
||||
if (ec->volume_max > volume_max)
|
||||
ec->volume_max = volume_max;
|
||||
if ((ec->volume_min > ec->volume)
|
||||
|| (ec->volume_max < ec->volume))
|
||||
e_client_volume_set(ec, ec->volume);
|
||||
e_client_volume_sink_get(sink, &volume, &mute);
|
||||
if ((ec->volume != volume) || (ec->mute != mute))
|
||||
{
|
||||
e_client_volume_sink_set(sink, ec->volume, ec->mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ec->volume_min = e_client_volume_sink_min_get(sink);
|
||||
ec->volume_max = e_client_volume_sink_max_get(sink);
|
||||
e_client_volume_sink_get(sink, &volume, &mute);
|
||||
ec->volume = volume;
|
||||
ec->mute = !!mute;
|
||||
ec->volume_control_enabled = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_remove(E_Client *ec, E_Client_Volume_Sink *sink)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(ec);
|
||||
ec->sinks = eina_list_remove(ec->sinks, sink);
|
||||
sink->clients = eina_list_remove(sink->clients, ec);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_sink_update(E_Client_Volume_Sink *sink)
|
||||
{
|
||||
Eina_List *l;
|
||||
int volume;
|
||||
Eina_Bool mute;
|
||||
E_Client *ec;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(sink);
|
||||
|
||||
e_client_volume_sink_get(sink, &volume, &mute);
|
||||
EINA_LIST_FOREACH(sink->clients, l, ec)
|
||||
{
|
||||
e_client_volume_set(ec, volume);
|
||||
e_client_volume_mute_set(ec, mute);
|
||||
}
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_set(E_Client *ec, int volume)
|
||||
{
|
||||
Eina_List *l;
|
||||
E_Client_Volume_Sink *sink;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(ec);
|
||||
if (volume < ec->volume_min) volume = ec->volume_min;
|
||||
if (volume > ec->volume_max) volume = ec->volume_max;
|
||||
if (volume == ec->volume) return;
|
||||
ec->volume = volume;
|
||||
|
||||
EINA_LIST_FOREACH(ec->sinks, l, sink)
|
||||
{
|
||||
e_client_volume_sink_set(sink, ec->volume, ec->mute);
|
||||
}
|
||||
|
||||
_e_client_volume_event_simple(ec, E_EVENT_CLIENT_VOLUME);
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_client_volume_mute_set(E_Client *ec, Eina_Bool mute)
|
||||
{
|
||||
Eina_List *l;
|
||||
E_Client_Volume_Sink *sink;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(ec);
|
||||
if (!!mute == ec->mute) return;
|
||||
ec->mute = !!mute;
|
||||
|
||||
EINA_LIST_FOREACH(ec->sinks, l, sink)
|
||||
{
|
||||
if (sink->func_set)
|
||||
sink->func_set(ec->volume, ec->mute, sink->data);
|
||||
}
|
||||
if (mute)
|
||||
_e_client_volume_event_simple(ec, E_EVENT_CLIENT_MUTE);
|
||||
else
|
||||
_e_client_volume_event_simple(ec, E_EVENT_CLIENT_UNMUTE);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef E_CLIENT_VOLUME_H_
|
||||
#define E_CLIENT_VOLUME_H_
|
||||
|
||||
typedef struct _E_Client_Volume_Sink E_Client_Volume_Sink;
|
||||
|
||||
typedef void (*E_Client_Volume_Sink_Get)(int *volume, Eina_Bool *mute, void *data);
|
||||
typedef void (*E_Client_Volume_Sink_Set)(int volume, Eina_Bool mute, void *data);
|
||||
typedef int (*E_Client_Volume_Sink_Min_Get)(void *data);
|
||||
typedef int (*E_Client_Volume_Sink_Max_Get)(void *data);
|
||||
|
||||
E_API extern int E_EVENT_CLIENT_VOLUME;
|
||||
E_API extern int E_EVENT_CLIENT_MUTE;
|
||||
E_API extern int E_EVENT_CLIENT_UNMUTE;
|
||||
|
||||
struct _E_Client_Volume_Sink
|
||||
{
|
||||
E_Client_Volume_Sink_Get func_get;
|
||||
E_Client_Volume_Sink_Set func_set;
|
||||
E_Client_Volume_Sink_Min_Get func_min_get;
|
||||
E_Client_Volume_Sink_Max_Get func_max_get;
|
||||
void *data;
|
||||
Eina_List *clients;
|
||||
};
|
||||
|
||||
|
||||
EINTERN int e_client_volume_init(void);
|
||||
EINTERN void e_client_volume_shutdown(void);
|
||||
|
||||
E_API void e_client_volume_set(E_Client *ec, int volume);
|
||||
E_API void e_client_volume_mute_set(E_Client *ec, Eina_Bool mute);
|
||||
|
||||
E_API Evas_Object *e_client_volume_object_add(E_Client *ec, Evas *evas);
|
||||
|
||||
E_API E_Client_Volume_Sink *e_client_volume_sink_new(E_Client_Volume_Sink_Get func_get, E_Client_Volume_Sink_Set func_set, E_Client_Volume_Sink_Min_Get func_min_get, E_Client_Volume_Sink_Max_Get func_max_get, void *data);
|
||||
E_API void e_client_volume_sink_del(E_Client_Volume_Sink *mixer);
|
||||
E_API void e_client_volume_sink_set(E_Client_Volume_Sink *mixer, int volume, Eina_Bool mute);
|
||||
E_API void e_client_volume_sink_get(const E_Client_Volume_Sink *mixer, int *volume, Eina_Bool *mute);
|
||||
E_API int e_client_volume_sink_min_get(const E_Client_Volume_Sink *mixer);
|
||||
E_API int e_client_volume_sink_max_get(const E_Client_Volume_Sink *mixer);
|
||||
E_API void e_client_volume_sink_append(E_Client *ec, E_Client_Volume_Sink *mixer);
|
||||
E_API void e_client_volume_sink_remove(E_Client *ec, E_Client_Volume_Sink *mixer);
|
||||
E_API void e_client_volume_sink_update(E_Client_Volume_Sink *mixer);
|
||||
|
||||
#endif
|
|
@ -14,6 +14,7 @@
|
|||
#include "e_pixmap.h"
|
||||
#include "e_comp_object.h"
|
||||
#include "e_client.h"
|
||||
#include "e_client_volume.h"
|
||||
#include "e_pointer.h"
|
||||
#include "e_config.h"
|
||||
#include "e_config_data.h"
|
||||
|
|
|
@ -1613,6 +1613,8 @@ _e_main_screens_init(void)
|
|||
{
|
||||
TS("\tscreens: client");
|
||||
if (!e_client_init()) return 0;
|
||||
TS("\tscreens: client volume");
|
||||
if (!e_client_volume_init()) return 0;
|
||||
TS("\tscreens: win");
|
||||
if (!e_win_init()) return 0;
|
||||
TS("Compositor Init");
|
||||
|
@ -1647,6 +1649,7 @@ _e_main_screens_shutdown(void)
|
|||
e_menu_shutdown();
|
||||
e_shelf_shutdown();
|
||||
e_comp_shutdown();
|
||||
e_client_volume_shutdown();
|
||||
e_client_shutdown();
|
||||
e_exehist_shutdown();
|
||||
e_backlight_shutdown();
|
||||
|
|
Loading…
Reference in New Issue