netstar pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=b0b298495310e2c99ed0c2481128b79d2124b378

commit b0b298495310e2c99ed0c2481128b79d2124b378
Author: Pau Espin Pedrol <pes...@espeweb.net>
Date:   Tue Mar 2 08:35:21 2021 +0000

    emixer: pulse: Use description as name for sources
    
    Summary:
    Same is already done for sinks.
    
    emixer: Add support to set default sink
    
    emixer: Add support to set default source
    
    emixer: gadget: Update UI to follow pulseaudio default sink changes
    
    Reviewers: devilhorns
    
    Subscribers: abrouwers, netstar, cedric, zmike
    
    Tags: #enlightenment-git
    
    Differential Revision: https://phab.enlightenment.org/D12247
---
 src/modules/mixer/backend.c                       |   4 +
 src/modules/mixer/e_mod_config.c                  |  10 ++
 src/modules/mixer/emixer.c                        |  51 +++++++++
 src/modules/mixer/lib/backends/alsa/alsa.c        |   5 +-
 src/modules/mixer/lib/backends/pulseaudio/pulse.c | 120 +++++++++++++++++++++-
 src/modules/mixer/lib/emix.c                      |  30 +++++-
 src/modules/mixer/lib/emix.h                      |   8 ++
 7 files changed, 220 insertions(+), 8 deletions(-)

diff --git a/src/modules/mixer/backend.c b/src/modules/mixer/backend.c
index 7fcb2c73c..e705b964a 100644
--- a/src/modules/mixer/backend.c
+++ b/src/modules/mixer/backend.c
@@ -358,6 +358,10 @@ _sink_event(int type, void *info)
      }
    else if (type == EMIX_SINK_CHANGED_EVENT)
      {
+        /* If pulseaudio changed the default sink, swap the UI to display it
+           instead of previously selected sink */
+        if (sink->default_sink)
+          _sink_default = sink;
         if (_sink_default == sink)
           {
              static int prev_vol = -1;
diff --git a/src/modules/mixer/e_mod_config.c b/src/modules/mixer/e_mod_config.c
index e426c3ca1..445bb3a21 100644
--- a/src/modules/mixer/e_mod_config.c
+++ b/src/modules/mixer/e_mod_config.c
@@ -25,6 +25,7 @@ typedef struct _Emix_Config_Sink
    Eina_List *ports;
    int mute;
    int volume;
+   int default_sink;
 } Emix_Config_Sink;
 
 typedef struct _Emix_Config_Source
@@ -32,6 +33,7 @@ typedef struct _Emix_Config_Source
    const char *name;
    int mute;
    int volume;
+   int default_source;
 } Emix_Config_Source;
 
 typedef struct _Emix_Config_Port
@@ -63,11 +65,13 @@ _emix_config_dd_new(void)
    E_CONFIG_LIST(c_sinkd, Emix_Config_Sink, ports, c_portd);
    E_CONFIG_VAL(c_sinkd, Emix_Config_Sink, mute, INT);
    E_CONFIG_VAL(c_sinkd, Emix_Config_Sink, volume, INT);
+   E_CONFIG_VAL(c_sinkd, Emix_Config_Sink, default_sink, INT);
 
    c_sourced = E_CONFIG_DD_NEW("Emix_Config_Source", Emix_Config_Source);
    E_CONFIG_VAL(c_sourced, Emix_Config_Source, name, STR);
    E_CONFIG_VAL(c_sourced, Emix_Config_Source, mute, INT);
    E_CONFIG_VAL(c_sourced, Emix_Config_Source, volume, INT);
+   E_CONFIG_VAL(c_sourced, Emix_Config_Source, default_source, INT);
 
    cd = E_CONFIG_DD_NEW("Emix_Config", Emix_Config);
 
@@ -260,6 +264,7 @@ emix_config_save_state_get(void)
              if (emsink->volume.channel_count > 0)
                sink->volume = emsink->volume.volumes[0];
              sink->mute = emsink->mute;
+             sink->default_sink = emsink->default_sink;
              _config->sinks = eina_list_append(_config->sinks, sink);
           }
      }
@@ -274,6 +279,7 @@ emix_config_save_state_get(void)
              if (emsource->volume.channel_count > 0)
                source->volume = emsource->volume.volumes[0];
              source->mute = emsource->mute;
+             source->default_source = emsource->default_source;
              _config->sources = eina_list_append(_config->sources, source);
           }
      }
@@ -351,6 +357,8 @@ emix_config_save_state_restore(void)
              free(v.volumes);
           }
         emix_sink_mute_set(emsink, sink->mute);
+        if (sink->default_sink)
+          emix_sink_default_set(emsink);
         EINA_LIST_FOREACH(sink->ports, ll, port)
           {
              if (!port->name) continue;
@@ -377,6 +385,8 @@ emix_config_save_state_restore(void)
              free(v.volumes);
           }
         emix_source_mute_set(emsource, source->mute);
+        if (source->default_source)
+          emix_source_default_set(emsource);
      }
 }
 
diff --git a/src/modules/mixer/emixer.c b/src/modules/mixer/emixer.c
index 322d5398f..fa5bc2a8c 100644
--- a/src/modules/mixer/emixer.c
+++ b/src/modules/mixer/emixer.c
@@ -121,6 +121,20 @@ _cb_sink_lock_change(void *data,
    _emix_sink_volume_fill(sink, fr, bx, lock);
 }
 
+static void
+_cb_sink_default_change(void *data,
+                     Evas_Object *obj,
+                     void *event_info EINA_UNUSED)
+{
+   Evas_Object *fr = data;
+   Emix_Sink *sink = evas_object_data_get(fr, "sink");
+   Eina_Bool is_default = elm_check_state_get(obj);
+   if (is_default) {
+     emix_sink_default_set(sink);
+     elm_object_disabled_set(obj, EINA_TRUE);
+  }
+}
+
 static void
 _emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *fr, Evas_Object *bx, 
Eina_Bool locked)
 {
@@ -195,6 +209,14 @@ _emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *fr, 
Evas_Object *bx, Eina_B
    elm_box_pack_end(bx, bxhv);
    evas_object_show(bxhv);
 
+   ck = elm_check_add(bx);
+   evas_object_data_set(fr, "default", ck);
+   elm_object_text_set(ck, "Default");
+   elm_check_state_set(ck, sink->default_sink);
+   elm_box_pack_end(bxhv, ck);
+   evas_object_show(ck);
+   evas_object_smart_callback_add(ck, "changed", _cb_sink_default_change, fr);
+
    ck = elm_check_add(bx);
    evas_object_data_set(fr, "mute", ck);
    elm_object_text_set(ck, "Mute");
@@ -368,6 +390,9 @@ _emix_sink_change(Emix_Sink *sink)
         elm_object_disabled_set(sl, sink->mute);
      }
 
+     ck = evas_object_data_get(fr, "default");
+     elm_check_state_set(ck, sink->default_sink);
+     elm_object_disabled_set(ck, sink->default_sink);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -845,6 +870,20 @@ _cb_source_lock_change(void *data,
    _emix_source_volume_fill(source, fr, bx, lock);
 }
 
+static void
+_cb_source_default_change(void *data,
+                     Evas_Object *obj,
+                     void *event_info EINA_UNUSED)
+{
+   Evas_Object *fr = data;
+   Emix_Source *source = evas_object_data_get(fr, "source");
+   Eina_Bool is_default = elm_check_state_get(obj);
+   if (is_default) {
+     emix_source_default_set(source);
+     elm_object_disabled_set(obj, EINA_TRUE);
+  }
+}
+
 static void
 _emix_source_volume_fill(Emix_Source *source, Evas_Object *fr, Evas_Object 
*bx, Eina_Bool locked)
 {
@@ -925,6 +964,14 @@ _emix_source_volume_fill(Emix_Source *source, Evas_Object 
*fr, Evas_Object *bx,
    elm_box_pack_end(bx, bxhv);
    evas_object_show(bxhv);
 
+   ck = elm_check_add(bx);
+   evas_object_data_set(fr, "default", ck);
+   elm_object_text_set(ck, "Default");
+   elm_check_state_set(ck, source->default_source);
+   elm_box_pack_end(bxhv, ck);
+   evas_object_show(ck);
+   evas_object_smart_callback_add(ck, "changed", _cb_source_default_change, 
fr);
+
    ck = elm_check_add(bx);
    evas_object_data_set(fr, "mute", ck);
    elm_object_text_set(ck, "Mute");
@@ -1071,6 +1118,10 @@ _emix_source_change(Emix_Source *source)
         elm_slider_value_set(sl, source->volume.volumes[0]);
         elm_object_disabled_set(sl, source->mute);
      }
+
+   ck = evas_object_data_get(fr, "default");
+   elm_check_state_set(ck, source->default_source);
+   elm_object_disabled_set(ck, source->default_source);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/modules/mixer/lib/backends/alsa/alsa.c 
b/src/modules/mixer/lib/backends/alsa/alsa.c
index 0d12d03a9..894b1115e 100644
--- a/src/modules/mixer/lib/backends/alsa/alsa.c
+++ b/src/modules/mixer/lib/backends/alsa/alsa.c
@@ -518,7 +518,7 @@ _alsa_backend =
    _alsa_shutdown,
    _max_volume,
    _alsa_sinks_get,
-   _alsa_support, /*default support*/
+   _alsa_support, /*sink default support*/
    NULL, /*get*/
    NULL, /*set*/
    _alsa_sink_mute_set, /*mute_set*/
@@ -530,6 +530,9 @@ _alsa_backend =
    NULL,/*sink input volume set*/
    NULL,/*sink input sink change*/
    _alsa_sources_get,/*source*/
+   _alsa_support, /* source default support*/
+   NULL, /*get*/
+   NULL, /*set*/
    _alsa_sources_mute_set,/* source mute set */
    _alsa_sources_volume_set, /* source volume set */
    NULL, /* advanced options */
diff --git a/src/modules/mixer/lib/backends/pulseaudio/pulse.c 
b/src/modules/mixer/lib/backends/pulseaudio/pulse.c
index fc5b17346..23d446feb 100644
--- a/src/modules/mixer/lib/backends/pulseaudio/pulse.c
+++ b/src/modules/mixer/lib/backends/pulseaudio/pulse.c
@@ -25,7 +25,6 @@ typedef struct _Context
    Emix_Event_Cb cb;
    const void *userdata;
    Ecore_Timer *connect;
-   int default_sink;
 
    Eina_List *sinks, *sources, *inputs, *cards;
    Eina_Bool connected;
@@ -35,6 +34,7 @@ typedef struct _Sink
 {
    Emix_Sink base;
    int idx;
+   const char *pulse_name;
 } Sink;
 
 typedef struct _Sink_Input
@@ -47,6 +47,7 @@ typedef struct _Source
 {
    Emix_Source base;
    int idx;
+   const char *pulse_name;
 } Source;
 
 typedef struct _Profile
@@ -114,6 +115,7 @@ _sink_del(Sink *sink)
      eina_stringshare_del(sink->base.volume.channel_names[i]);
    free(sink->base.volume.channel_names);
    eina_stringshare_del(sink->base.name);
+   eina_stringshare_del(sink->pulse_name);
    free(sink);
 }
 
@@ -143,6 +145,7 @@ _source_del(Source *source)
      eina_stringshare_del(source->base.volume.channel_names[i]);
    free(source->base.volume.channel_names);
    eina_stringshare_del(source->base.name);
+   eina_stringshare_del(source->pulse_name);
    free(source);
 }
 
@@ -187,6 +190,7 @@ _sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info 
*info, int eol,
 
    sink = calloc(1, sizeof(Sink));
    sink->idx = info->index;
+   sink->pulse_name = eina_stringshare_add(info->name);
    sink->base.name = eina_stringshare_add(info->description);
    _pa_cvolume_convert(&info->volume, &sink->base.volume);
    sink->base.volume.channel_names = calloc(sink->base.volume.channel_count, 
sizeof(Emix_Channel));
@@ -543,7 +547,8 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info 
*info,
    EINA_SAFETY_ON_NULL_RETURN(source);
 
    source->idx = info->index;
-   source->base.name = eina_stringshare_add(info->name);
+   source->pulse_name = eina_stringshare_add(info->name);
+   source->base.name = eina_stringshare_add(info->description);
    _pa_cvolume_convert(&info->volume, &source->base.volume);
    source->base.volume.channel_names = 
calloc(source->base.volume.channel_count, sizeof(Emix_Channel));
    for (i = 0; i < source->base.volume.channel_count; ++i)
@@ -642,6 +647,9 @@ static void
 _sink_default_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
                  void *userdata EINA_UNUSED)
 {
+   Sink *sink;
+   Eina_List *l;
+
    if (eol < 0)
      {
         if (pa_context_errno(c) == PA_ERR_NOENTITY)
@@ -657,7 +665,50 @@ _sink_default_cb(pa_context *c EINA_UNUSED, const 
pa_sink_info *info, int eol,
    DBG("sink index: %d\nsink name: %s", info->index,
        info->name);
 
-   ctx->default_sink = info->index;
+   EINA_LIST_FOREACH(ctx->sinks, l, sink)
+   {
+     Eina_Bool prev_default = sink->base.default_sink;
+     sink->base.default_sink = (uint32_t)sink->idx == info->index;
+     if (ctx->cb && prev_default != sink->base.default_sink)
+       ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,
+                    (Emix_Sink *)sink);
+   }
+
+   if (ctx->cb)
+      ctx->cb((void *)ctx->userdata, EMIX_READY_EVENT, NULL);
+}
+
+static void
+_source_default_cb(pa_context *c EINA_UNUSED, const pa_source_info *info, int 
eol,
+                 void *userdata EINA_UNUSED)
+{
+   Source *source;
+   Eina_List *l;
+
+   if (eol < 0)
+     {
+        if (pa_context_errno(c) == PA_ERR_NOENTITY)
+           return;
+
+        ERR("Source callback failure");
+        return;
+     }
+
+   if (eol > 0)
+      return;
+
+   DBG("source index: %d\nsource name: %s", info->index,
+       info->name);
+
+   EINA_LIST_FOREACH(ctx->sources, l, source)
+   {
+     Eina_Bool prev_default = source->base.default_source;
+     source->base.default_source = (uint32_t)source->idx == info->index;
+     if (ctx->cb && prev_default != source->base.default_source)
+       ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
+                    (Emix_Source *)source);
+   }
+
    if (ctx->cb)
       ctx->cb((void *)ctx->userdata, EMIX_READY_EVENT, NULL);
 }
@@ -683,6 +734,14 @@ _server_info_cb(pa_context *c, const pa_server_info *info,
         return;
      }
    pa_operation_unref(o);
+
+   if (!(o = pa_context_get_source_info_by_name(c, info->default_source_name,
+                                              _source_default_cb, userdata)))
+     {
+        ERR("pa_context_get_source_info_by_name() failed");
+        return;
+     }
+   pa_operation_unref(o);
 }
 
 static int
@@ -1369,12 +1428,60 @@ _sink_default_get(void)
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
    EINA_LIST_FOREACH(ctx->sinks, l, s)
-      if (s->idx == ctx->default_sink)
+      if (s->base.default_sink)
         return (Emix_Sink *)s;
 
    return NULL;
 }
 
+static void
+_sink_default_set(Emix_Sink *sink)
+{
+  Sink *s = (Sink *)sink;
+  pa_operation* o;
+
+  DBG("Set default sink: %s", sink->name);
+  if (!(o = pa_context_set_default_sink(ctx->context, s->pulse_name, NULL, 
NULL))) {
+      ERR("pa_context_set_default_sink() failed");
+      return;
+  }
+  pa_operation_unref(o);
+}
+
+static Eina_Bool
+_source_default_support(void)
+{
+   return EINA_TRUE;
+}
+
+static const Emix_Source *
+_source_default_get(void)
+{
+   Source *s;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
+   EINA_LIST_FOREACH(ctx->sources, l, s)
+      if (s->base.default_source)
+        return (Emix_Source *)s;
+
+   return NULL;
+}
+
+static void
+_source_default_set(Emix_Source *source)
+{
+  Source *s = (Source *)source;
+  pa_operation* o;
+
+  DBG("Set default sink: %s", source->name);
+  if (!(o = pa_context_set_default_source(ctx->context, s->pulse_name, NULL, 
NULL))) {
+      ERR("pa_context_set_default_source() failed");
+      return;
+  }
+  pa_operation_unref(o);
+}
+
 static Eina_Bool
 _sink_change_support(void)
 {
@@ -1424,7 +1531,7 @@ _pulseaudio_backend =
    _sinks_get,
    _sink_default_support,
    _sink_default_get,
-   NULL,
+   _sink_default_set,
    _sink_mute_set,
    _sink_volume_set,
    _sink_port_set,
@@ -1434,6 +1541,9 @@ _pulseaudio_backend =
    _sink_input_volume_set,
    _sink_input_move,
    _sources_get,
+   _source_default_support,
+   _source_default_get,
+   _source_default_set,
    _source_mute_set,
    _source_volume_set,
    NULL,
diff --git a/src/modules/mixer/lib/emix.c b/src/modules/mixer/lib/emix.c
index ba2436d55..962e7e535 100644
--- a/src/modules/mixer/lib/emix.c
+++ b/src/modules/mixer/lib/emix.c
@@ -347,6 +347,34 @@ emix_sources_get(void)
    return ctx->loaded->ebackend_sources_get();
 }
 
+Eina_Bool
+emix_source_default_support(void)
+{
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((ctx && ctx->loaded &&
+                                    
ctx->loaded->ebackend_source_default_support),
+                                   EINA_FALSE);
+   return ctx->loaded->ebackend_source_default_support();
+}
+
+const Emix_Source*
+emix_source_default_get(void)
+{
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((ctx && ctx->loaded &&
+                                    ctx->loaded->ebackend_source_default_get),
+                                   NULL);
+   return ctx->loaded->ebackend_source_default_get();
+}
+
+void
+emix_source_default_set(Emix_Source *source)
+{
+   EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
+                                ctx->loaded->ebackend_source_default_set &&
+                                source));
+
+   ctx->loaded->ebackend_source_default_set(source);
+}
+
 void
 emix_source_mute_set(Emix_Source *source, Eina_Bool mute)
 {
@@ -428,5 +456,3 @@ emix_card_profile_set(Emix_Card *card, Emix_Profile 
*profile)
 
    return ctx->loaded->ebackend_card_profile_set(card, profile);
 }
-
-
diff --git a/src/modules/mixer/lib/emix.h b/src/modules/mixer/lib/emix.h
index 6b1e67094..5f2512310 100644
--- a/src/modules/mixer/lib/emix.h
+++ b/src/modules/mixer/lib/emix.h
@@ -62,6 +62,7 @@ typedef struct _Emix_Sink {
    const char *name;
    Emix_Volume volume;
    Eina_Bool mute;
+   Eina_Bool default_sink;
    Eina_List *ports;
 } Emix_Sink;
 
@@ -78,6 +79,7 @@ typedef struct _Emix_Source {
    const char *name;
    Emix_Volume volume;
    Eina_Bool mute;
+   Eina_Bool default_source;
 } Emix_Source;
 
 typedef struct _Emix_Profile {
@@ -122,6 +124,9 @@ typedef struct _Emix_Backend {
                                        Emix_Sink_Input *input, Emix_Sink 
*sink);
 
    const Eina_List*      (*ebackend_sources_get)(void);
+   Eina_Bool             (*ebackend_source_default_support)(void);
+   const Emix_Source*    (*ebackend_source_default_get)(void);
+   void                  (*ebackend_source_default_set)(Emix_Source *source);
    void                  (*ebackend_source_mute_set)(Emix_Source *source,
                                                      Eina_Bool mute);
    void                  (*ebackend_source_volume_set)(Emix_Source *source,
@@ -179,6 +184,9 @@ E_API void                
emix_sink_input_sink_change(Emix_Sink_Input *input,
                                                      Emix_Sink *sink);
 
 E_API const Eina_List*    emix_sources_get(void);
+E_API Eina_Bool           emix_source_default_support(void);
+E_API const Emix_Source*  emix_source_default_get(void);
+E_API void                emix_source_default_set(Emix_Source *source);
 E_API void                emix_source_mute_set(Emix_Source *source,
                                                   Eina_Bool mute);
 E_API void                emix_source_volume_set(Emix_Source *source,

-- 


Reply via email to