153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB 653a5a1b3Sopenharmony_ci 753a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 853a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 953a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 1053a5a1b3Sopenharmony_ci or (at your option) any later version. 1153a5a1b3Sopenharmony_ci 1253a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1353a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1453a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1553a5a1b3Sopenharmony_ci General Public License for more details. 1653a5a1b3Sopenharmony_ci 1753a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1853a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1953a5a1b3Sopenharmony_ci***/ 2053a5a1b3Sopenharmony_ci 2153a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2253a5a1b3Sopenharmony_ci#include <config.h> 2353a5a1b3Sopenharmony_ci#endif 2453a5a1b3Sopenharmony_ci 2553a5a1b3Sopenharmony_ci#include <stdio.h> 2653a5a1b3Sopenharmony_ci#include <stdlib.h> 2753a5a1b3Sopenharmony_ci#include <string.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 3053a5a1b3Sopenharmony_ci#include <pulse/util.h> 3153a5a1b3Sopenharmony_ci 3253a5a1b3Sopenharmony_ci#include <pulsecore/core-subscribe.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/log.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3553a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3653a5a1b3Sopenharmony_ci 3753a5a1b3Sopenharmony_ci#include "client.h" 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_cipa_client_new_data* pa_client_new_data_init(pa_client_new_data *data) { 4053a5a1b3Sopenharmony_ci pa_assert(data); 4153a5a1b3Sopenharmony_ci 4253a5a1b3Sopenharmony_ci memset(data, 0, sizeof(*data)); 4353a5a1b3Sopenharmony_ci data->proplist = pa_proplist_new(); 4453a5a1b3Sopenharmony_ci 4553a5a1b3Sopenharmony_ci return data; 4653a5a1b3Sopenharmony_ci} 4753a5a1b3Sopenharmony_ci 4853a5a1b3Sopenharmony_civoid pa_client_new_data_done(pa_client_new_data *data) { 4953a5a1b3Sopenharmony_ci pa_assert(data); 5053a5a1b3Sopenharmony_ci 5153a5a1b3Sopenharmony_ci pa_proplist_free(data->proplist); 5253a5a1b3Sopenharmony_ci} 5353a5a1b3Sopenharmony_ci 5453a5a1b3Sopenharmony_cipa_client *pa_client_new(pa_core *core, pa_client_new_data *data) { 5553a5a1b3Sopenharmony_ci pa_client *c; 5653a5a1b3Sopenharmony_ci 5753a5a1b3Sopenharmony_ci pa_core_assert_ref(core); 5853a5a1b3Sopenharmony_ci pa_assert(data); 5953a5a1b3Sopenharmony_ci 6053a5a1b3Sopenharmony_ci if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_NEW], data) < 0) 6153a5a1b3Sopenharmony_ci return NULL; 6253a5a1b3Sopenharmony_ci 6353a5a1b3Sopenharmony_ci c = pa_xnew0(pa_client, 1); 6453a5a1b3Sopenharmony_ci c->core = core; 6553a5a1b3Sopenharmony_ci c->proplist = pa_proplist_copy(data->proplist); 6653a5a1b3Sopenharmony_ci c->driver = pa_xstrdup(pa_path_get_filename(data->driver)); 6753a5a1b3Sopenharmony_ci c->module = data->module; 6853a5a1b3Sopenharmony_ci 6953a5a1b3Sopenharmony_ci c->sink_inputs = pa_idxset_new(NULL, NULL); 7053a5a1b3Sopenharmony_ci c->source_outputs = pa_idxset_new(NULL, NULL); 7153a5a1b3Sopenharmony_ci 7253a5a1b3Sopenharmony_ci pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0); 7353a5a1b3Sopenharmony_ci 7453a5a1b3Sopenharmony_ci pa_log_info("Created %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); 7553a5a1b3Sopenharmony_ci pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); 7653a5a1b3Sopenharmony_ci 7753a5a1b3Sopenharmony_ci pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], c); 7853a5a1b3Sopenharmony_ci 7953a5a1b3Sopenharmony_ci pa_core_check_idle(core); 8053a5a1b3Sopenharmony_ci 8153a5a1b3Sopenharmony_ci return c; 8253a5a1b3Sopenharmony_ci} 8353a5a1b3Sopenharmony_ci 8453a5a1b3Sopenharmony_civoid pa_client_free(pa_client *c) { 8553a5a1b3Sopenharmony_ci pa_core *core; 8653a5a1b3Sopenharmony_ci 8753a5a1b3Sopenharmony_ci pa_assert(c); 8853a5a1b3Sopenharmony_ci pa_assert(c->core); 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ci core = c->core; 9153a5a1b3Sopenharmony_ci 9253a5a1b3Sopenharmony_ci pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], c); 9353a5a1b3Sopenharmony_ci 9453a5a1b3Sopenharmony_ci pa_idxset_remove_by_data(c->core->clients, c, NULL); 9553a5a1b3Sopenharmony_ci 9653a5a1b3Sopenharmony_ci pa_log_info("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME))); 9753a5a1b3Sopenharmony_ci pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); 9853a5a1b3Sopenharmony_ci 9953a5a1b3Sopenharmony_ci pa_assert(pa_idxset_isempty(c->sink_inputs)); 10053a5a1b3Sopenharmony_ci pa_idxset_free(c->sink_inputs, NULL); 10153a5a1b3Sopenharmony_ci pa_assert(pa_idxset_isempty(c->source_outputs)); 10253a5a1b3Sopenharmony_ci pa_idxset_free(c->source_outputs, NULL); 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci pa_proplist_free(c->proplist); 10553a5a1b3Sopenharmony_ci pa_xfree(c->driver); 10653a5a1b3Sopenharmony_ci pa_xfree(c); 10753a5a1b3Sopenharmony_ci 10853a5a1b3Sopenharmony_ci pa_core_check_idle(core); 10953a5a1b3Sopenharmony_ci} 11053a5a1b3Sopenharmony_ci 11153a5a1b3Sopenharmony_civoid pa_client_kill(pa_client *c) { 11253a5a1b3Sopenharmony_ci pa_assert(c); 11353a5a1b3Sopenharmony_ci 11453a5a1b3Sopenharmony_ci if (!c->kill) { 11553a5a1b3Sopenharmony_ci pa_log_warn("kill() operation not implemented for client %u", c->index); 11653a5a1b3Sopenharmony_ci return; 11753a5a1b3Sopenharmony_ci } 11853a5a1b3Sopenharmony_ci 11953a5a1b3Sopenharmony_ci c->kill(c); 12053a5a1b3Sopenharmony_ci} 12153a5a1b3Sopenharmony_ci 12253a5a1b3Sopenharmony_civoid pa_client_set_name(pa_client *c, const char *name) { 12353a5a1b3Sopenharmony_ci pa_assert(c); 12453a5a1b3Sopenharmony_ci pa_assert(name); 12553a5a1b3Sopenharmony_ci 12653a5a1b3Sopenharmony_ci pa_log_info("Client %u changed name from \"%s\" to \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)), name); 12753a5a1b3Sopenharmony_ci pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); 12853a5a1b3Sopenharmony_ci 12953a5a1b3Sopenharmony_ci pa_client_update_proplist(c, 0, NULL); 13053a5a1b3Sopenharmony_ci} 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_civoid pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p) { 13353a5a1b3Sopenharmony_ci pa_assert(c); 13453a5a1b3Sopenharmony_ci 13553a5a1b3Sopenharmony_ci if (p) 13653a5a1b3Sopenharmony_ci pa_proplist_update(c->proplist, mode, p); 13753a5a1b3Sopenharmony_ci 13853a5a1b3Sopenharmony_ci pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c); 13953a5a1b3Sopenharmony_ci pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index); 14053a5a1b3Sopenharmony_ci} 14153a5a1b3Sopenharmony_ci 14253a5a1b3Sopenharmony_civoid pa_client_send_event(pa_client *c, const char *event, pa_proplist *data) { 14353a5a1b3Sopenharmony_ci pa_proplist *pl = NULL; 14453a5a1b3Sopenharmony_ci pa_client_send_event_hook_data hook_data; 14553a5a1b3Sopenharmony_ci 14653a5a1b3Sopenharmony_ci pa_assert(c); 14753a5a1b3Sopenharmony_ci pa_assert(event); 14853a5a1b3Sopenharmony_ci 14953a5a1b3Sopenharmony_ci if (!c->send_event) 15053a5a1b3Sopenharmony_ci return; 15153a5a1b3Sopenharmony_ci 15253a5a1b3Sopenharmony_ci if (!data) 15353a5a1b3Sopenharmony_ci data = pl = pa_proplist_new(); 15453a5a1b3Sopenharmony_ci 15553a5a1b3Sopenharmony_ci hook_data.client = c; 15653a5a1b3Sopenharmony_ci hook_data.data = data; 15753a5a1b3Sopenharmony_ci hook_data.event = event; 15853a5a1b3Sopenharmony_ci 15953a5a1b3Sopenharmony_ci if (pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_SEND_EVENT], &hook_data) < 0) 16053a5a1b3Sopenharmony_ci goto finish; 16153a5a1b3Sopenharmony_ci 16253a5a1b3Sopenharmony_ci c->send_event(c, event, data); 16353a5a1b3Sopenharmony_ci 16453a5a1b3Sopenharmony_cifinish: 16553a5a1b3Sopenharmony_ci 16653a5a1b3Sopenharmony_ci if (pl) 16753a5a1b3Sopenharmony_ci pa_proplist_free(pl); 16853a5a1b3Sopenharmony_ci} 169