]> code.delx.au - pulseaudio/blobdiff - src/modules/module-stream-restore.c
move flat volume logic into the core. while doing so add n_volume_steps field to...
[pulseaudio] / src / modules / module-stream-restore.c
index 5b9922eca8bf368c0d27ba024f438b2343e3f859..464ff2da9866a1019f38fecc373e26a8ffcd8cd4 100644 (file)
@@ -134,18 +134,18 @@ static char *get_name(pa_proplist *p, const char *prefix) {
     else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
         return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
 
-    return NULL;
+    return pa_sprintf_malloc("%s-fallback:%s", prefix, r);
 }
 
-static struct entry* read_entry(struct userdata *u, char *name) {
+static struct entry* read_entry(struct userdata *u, const char *name) {
     datum key, data;
     struct entry *e;
 
     pa_assert(u);
     pa_assert(name);
 
-    key.dptr = name;
-    key.dsize = strlen(name);
+    key.dptr = (char*) name;
+    key.dsize = (int) strlen(name);
 
     data = gdbm_fetch(u->gdbm_file, key);
 
@@ -266,7 +266,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
 
         if (pa_cvolume_equal(pa_cvolume_remap(&old->volume, &old->channel_map, &entry.channel_map), &entry.volume) &&
             !old->muted == !entry.muted &&
-            strcmp(old->device, entry.device) == 0) {
+            strncmp(old->device, entry.device, sizeof(entry.device)) == 0) {
 
             pa_xfree(old);
             pa_xfree(name);
@@ -277,7 +277,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
     }
 
     key.dptr = name;
-    key.dsize = strlen(name);
+    key.dsize = (int) strlen(name);
 
     data.dptr = (void*) &entry;
     data.dsize = sizeof(entry);
@@ -304,10 +304,13 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
         pa_sink *s;
 
         if (u->restore_device &&
-            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK, TRUE))) {
+            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK))) {
 
-            pa_log_info("Restoring device for stream %s.", name);
-            new_data->sink = s;
+            if (!new_data->sink) {
+                pa_log_info("Restoring device for stream %s.", name);
+                new_data->sink = s;
+            } else
+                pa_log_info("Not restore device for stream %s, because already set.", name);
         }
 
         pa_xfree(e);
@@ -330,13 +333,20 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
     if ((e = read_entry(u, name))) {
 
         if (u->restore_volume) {
-            pa_log_info("Restoring volume for sink input %s.", name);
-            pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+
+            if (!new_data->virtual_volume_is_set) {
+                pa_log_info("Restoring volume for sink input %s.", name);
+                pa_sink_input_new_data_set_virtual_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+            } else
+                pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
         }
 
         if (u->restore_muted) {
-            pa_log_info("Restoring mute state for sink input %s.", name);
-            pa_sink_input_new_data_set_muted(new_data, e->muted);
+            if (!new_data->muted_is_set) {
+                pa_log_info("Restoring mute state for sink input %s.", name);
+                pa_sink_input_new_data_set_muted(new_data, e->muted);
+            } else
+                pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
         }
 
         pa_xfree(e);
@@ -361,10 +371,13 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
 
         if (u->restore_device &&
             !new_data->direct_on_input &&
-            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE, TRUE))) {
+            (s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE))) {
 
-            pa_log_info("Restoring device for stream %s.", name);
-            new_data->source = s;
+            if (!new_data->source) {
+                pa_log_info("Restoring device for stream %s.", name);
+                new_data->source = s;
+            } else
+                pa_log_info("Not restoring device for stream %s, because already set", name);
         }
 
         pa_xfree(e);
@@ -429,7 +442,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
 
         if (u->restore_device &&
-            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) {
+            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
 
             pa_log_info("Restoring device for stream %s.", name);
             pa_sink_input_move_to(si, s);
@@ -449,7 +462,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
 
         if (u->restore_device &&
-            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE, TRUE))) {
+            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
 
             pa_log_info("Restoring device for stream %s.", name);
             pa_source_output_move_to(so, s);
@@ -531,7 +544,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 next_key = gdbm_nextkey(u->gdbm_file, key);
 
-                name = pa_xstrndup(key.dptr, key.dsize);
+                name = pa_xstrndup(key.dptr, (size_t) key.dsize);
                 pa_xfree(key.dptr);
 
                 if ((e = read_entry(u, name))) {
@@ -554,7 +567,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
         case SUBCOMMAND_WRITE: {
             uint32_t mode;
-            pa_bool_t apply_immediately;
+            pa_bool_t apply_immediately = FALSE;
 
             if (pa_tagstruct_getu32(t, &mode) < 0 ||
                 pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
@@ -573,6 +586,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 pa_bool_t muted;
                 struct entry entry;
                 datum key, data;
+                int k;
 
                 memset(&entry, 0, sizeof(entry));
 
@@ -590,12 +604,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 pa_strlcpy(entry.device, device, sizeof(entry.device));
 
                 key.dptr = (void*) name;
-                key.dsize = strlen(name);
+                key.dsize = (int) strlen(name);
 
                 data.dptr = (void*) &entry;
                 data.dsize = sizeof(entry);
 
-                if (gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT) == 1)
+                if ((k = gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT)) == 0)
                     if (apply_immediately)
                         apply_entry(u, name, &entry);
             }
@@ -615,7 +629,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     goto fail;
 
                 key.dptr = (void*) name;
-                key.dsize = strlen(name);
+                key.dsize = (int) strlen(name);
 
                 gdbm_delete(u->gdbm_file, key);
             }
@@ -672,6 +686,7 @@ int pa__init(pa_module*m) {
     pa_source_output *so;
     uint32_t idx;
     pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE;
+    int gdbm_cache_size;
 
     pa_assert(m);
 
@@ -726,12 +741,16 @@ int pa__init(pa_module*m) {
     if (!fname)
         goto fail;
 
-    if (!(u->gdbm_file = gdbm_open(fname, 0, GDBM_WRCREAT, 0600, NULL))) {
+    if (!(u->gdbm_file = gdbm_open(fname, 0, GDBM_WRCREAT|GDBM_NOLOCK, 0600, NULL))) {
         pa_log("Failed to open volume database '%s': %s", fname, gdbm_strerror(gdbm_errno));
         pa_xfree(fname);
         goto fail;
     }
 
+    /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
+    gdbm_cache_size = 10;
+    gdbm_setopt(u->gdbm_file, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));
+
     pa_log_info("Sucessfully opened database file '%s'.", fname);
     pa_xfree(fname);