static void handle_client_events(pa_core *c,pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; uint32_t et = t & PA_SUBSCRIPTION_EVENT_TYPE_MASK; struct pa_client *client; pa_assert(u); switch (et) { case PA_SUBSCRIPTION_EVENT_NEW: if ((client = pa_idxset_get_by_index(c->clients, idx)) != NULL) { handle_new_or_modified_client(u, client); } break; case PA_SUBSCRIPTION_EVENT_CHANGE: if ((client = pa_idxset_get_by_index(c->clients, idx)) != NULL) { handle_new_or_modified_client(u, client); } break; case PA_SUBSCRIPTION_EVENT_REMOVE: handle_removed_client(u, idx); break; default: pa_log("unknown client event type %d", et); break; } }
static int object_assert(struct userdata *u, struct pa_policy_object *object) { void *ptr; pa_assert(u); pa_assert(u->core); if (object->ptr != NULL && object->index != PA_IDXSET_INVALID) { switch (object->type) { case pa_policy_object_module: ptr = pa_idxset_get_by_index(u->core->modules, object->index); if (ptr != object->ptr) break; return true; case pa_policy_object_card: case pa_policy_object_sink: case pa_policy_object_source: case pa_policy_object_sink_input: case pa_policy_object_source_output: return true; default: break; } } pa_log("%s() failed", __FUNCTION__); return false; }
static void master_source_state_subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; pa_assert(c); pa_assert(u); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE) return; if (!u->master_source) return; if (u->master_source != pa_idxset_get_by_index(c->sources, idx)) return; if (pa_source_get_state(u->master_source) == u->previous_master_source_state) return; u->previous_master_source_state = pa_source_get_state(u->master_source); if (u->previous_master_source_state == PA_SOURCE_SUSPENDED) { meego_algorithm_hook_fire(u->hooks[HOOK_SOURCE_RESET], NULL); pa_log_debug("VOICE_HOOK_SOURCE_RESET fired"); voice_aep_ear_ref_loop_reset(u); } }
void pa_module_unload_request_by_index(pa_core *c, uint32_t idx, pa_bool_t force) { pa_module *m; pa_assert(c); if (!(m = pa_idxset_get_by_index(c->modules, idx))) return; pa_module_unload_request(m, force); }
const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id) { pa_scache_entry *e; pa_assert(c); pa_assert(id != PA_IDXSET_INVALID); if (!c->scache || !(e = pa_idxset_get_by_index(c->scache, id))) return NULL; return e->name; }
const pa_autoload_entry* pa_autoload_get_by_index(pa_core *c, uint32_t idx) { pa_autoload_entry *e; pa_core_assert_ref(c); pa_assert(idx != PA_IDXSET_INVALID); if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) return NULL; return e; }
int pa_autoload_remove_by_index(pa_core *c, uint32_t idx) { pa_autoload_entry *e; pa_assert(c); pa_assert(idx != PA_IDXSET_INVALID); if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) return -1; entry_remove_and_free(e); return 0; }
static void sink_subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = (struct userdata *)userdata; if (t == PA_SUBSCRIPTION_EVENT_CHANGE) { pa_sink *sink = PA_SINK(pa_idxset_get_by_index(c->sinks, idx)); if (sink) { if (u->master_sink == sink) { const pa_cvolume *vol = pa_sink_get_volume(sink, 0, 0); int aep_step; u->linear_q15_master_volume_L = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0); if (vol->channels == 1) u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0); else u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[1]) * 32767.0); aep_step = voice_pa_vol_to_aep_step(u, vol->values[0]); if (voice_cmt_ul_is_active_iothread(u) || (u->voip_source && PA_SOURCE_IS_LINKED(u->voip_source->state) && pa_source_used_by(u->voip_source))) { if (aep_step <= 0) { voice_update_aep_volume(0); voice_update_sidetone_gain(0); } else { voice_update_aep_volume(aep_step - 1); voice_update_sidetone_gain(aep_step - 1); } } xprot_change_volume(u->xprot, u->linear_q15_master_volume_L, u->linear_q15_master_volume_R); } } } }
static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; pa_sink_input *si = NULL; pa_source_output *so = NULL; struct rule *r; char *name; pa_assert(c); pa_assert(u); if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW) && t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) && t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW) && t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE)) return; if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) { if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx))) return; if (!si->client || !(name = client_name(si->client))) return; } else { pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT); if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) return; if (!so->client || !(name = client_name(so->client))) return; } if ((r = pa_hashmap_get(u->hashmap, name))) { pa_xfree(name); if (si) { if (!r->volume_is_set || !pa_cvolume_equal(pa_sink_input_get_volume(si), &r->volume)) { pa_log_info("Saving volume for <%s>", r->name); r->volume = *pa_sink_input_get_volume(si); r->volume_is_set = TRUE; u->modified = TRUE; } if (!r->sink || strcmp(si->sink->name, r->sink) != 0) { pa_log_info("Saving sink for <%s>", r->name); pa_xfree(r->sink); r->sink = pa_xstrdup(si->sink->name); u->modified = TRUE; } } else { pa_assert(so); if (!r->source || strcmp(so->source->name, r->source) != 0) { pa_log_info("Saving source for <%s>", r->name); pa_xfree(r->source); r->source = pa_xstrdup(so->source->name); u->modified = TRUE; } } } else { pa_log_info("Creating new entry for <%s>", name); r = pa_xnew(struct rule, 1); r->name = name; if (si) { r->volume = *pa_sink_input_get_volume(si); r->volume_is_set = TRUE; r->sink = pa_xstrdup(si->sink->name); r->source = NULL; } else { pa_assert(so); r->volume_is_set = FALSE; r->sink = NULL; r->source = pa_xstrdup(so->source->name); } pa_hashmap_put(u->hashmap, r->name, r); u->modified = TRUE; } if (u->modified && !u->save_time_event) { struct timeval tv; pa_gettimeofday(&tv); tv.tv_sec += SAVE_INTERVAL; u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u); } }
static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; struct entry entry, *old; char *name; pa_datum key, data; pa_assert(c); pa_assert(u); if (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW) && t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE) && t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW) && t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE)) return; pa_zero(entry); entry.version = ENTRY_VERSION; if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) { pa_sink *sink; if (!(sink = pa_idxset_get_by_index(c->sinks, idx))) return; name = pa_sprintf_malloc("sink:%s", sink->name); if ((old = read_entry(u, name))) entry = *old; if (sink->save_volume) { entry.channel_map = sink->channel_map; entry.volume = *pa_sink_get_volume(sink, FALSE); entry.volume_valid = TRUE; } if (sink->save_muted) { entry.muted = pa_sink_get_mute(sink, FALSE); entry.muted_valid = TRUE; } if (sink->save_port) { pa_strlcpy(entry.port, sink->active_port ? sink->active_port->name : "", sizeof(entry.port)); entry.port_valid = TRUE; } } else { pa_source *source; pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE); if (!(source = pa_idxset_get_by_index(c->sources, idx))) return; name = pa_sprintf_malloc("source:%s", source->name); if ((old = read_entry(u, name))) entry = *old; if (source->save_volume) { entry.channel_map = source->channel_map; entry.volume = *pa_source_get_volume(source, FALSE); entry.volume_valid = TRUE; } if (source->save_muted) { entry.muted = pa_source_get_mute(source, FALSE); entry.muted_valid = TRUE; } if (source->save_port) { pa_strlcpy(entry.port, source->active_port ? source->active_port->name : "", sizeof(entry.port)); entry.port_valid = TRUE; } } if (old) { if (entries_equal(old, &entry)) { pa_xfree(old); pa_xfree(name); return; } pa_xfree(old); } key.data = name; key.size = strlen(name); data.data = &entry; data.size = sizeof(entry); pa_log_info("Storing volume/mute/port for device %s.", name); pa_database_set(u->database, &key, &data, TRUE); pa_xfree(name); trigger_save(u); }