Git init
[framework/multimedia/pulseaudio.git] / src / pulsecore / client.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7   PulseAudio is free software; you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as published
9   by the Free Software Foundation; either version 2.1 of the License,
10   or (at your option) any later version.
11
12   PulseAudio is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with PulseAudio; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20   USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <pulse/xmalloc.h>
32 #include <pulse/util.h>
33
34 #include <pulsecore/core-subscribe.h>
35 #include <pulsecore/log.h>
36 #include <pulsecore/macro.h>
37 #include <pulsecore/core-util.h>
38
39 #include "client.h"
40
41 pa_client_new_data* pa_client_new_data_init(pa_client_new_data *data) {
42     pa_assert(data);
43
44     memset(data, 0, sizeof(*data));
45     data->proplist = pa_proplist_new();
46
47     return data;
48 }
49
50 void pa_client_new_data_done(pa_client_new_data *data) {
51     pa_assert(data);
52
53     pa_proplist_free(data->proplist);
54 }
55
56 pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) {
57     pa_client *c;
58
59     pa_core_assert_ref(core);
60     pa_assert(data);
61
62     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_NEW], data) < 0)
63         return NULL;
64
65     c = pa_xnew(pa_client, 1);
66     c->core = core;
67     c->proplist = pa_proplist_copy(data->proplist);
68     c->driver = pa_xstrdup(pa_path_get_filename(data->driver));
69     c->module = data->module;
70
71     c->sink_inputs = pa_idxset_new(NULL, NULL);
72     c->source_outputs = pa_idxset_new(NULL, NULL);
73
74     c->userdata = NULL;
75     c->kill = NULL;
76     c->send_event = NULL;
77
78     pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0);
79
80     pa_log_info("Created %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)));
81     pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index);
82
83     pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], c);
84
85     pa_core_check_idle(core);
86
87     return c;
88 }
89
90 void pa_client_free(pa_client *c) {
91     pa_core *core;
92
93     pa_assert(c);
94     pa_assert(c->core);
95
96     core = c->core;
97
98     pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], c);
99
100     pa_idxset_remove_by_data(c->core->clients, c, NULL);
101
102     pa_log_info("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)));
103     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
104
105     pa_assert(pa_idxset_isempty(c->sink_inputs));
106     pa_idxset_free(c->sink_inputs, NULL, NULL);
107     pa_assert(pa_idxset_isempty(c->source_outputs));
108     pa_idxset_free(c->source_outputs, NULL, NULL);
109
110     pa_proplist_free(c->proplist);
111     pa_xfree(c->driver);
112     pa_xfree(c);
113
114     pa_core_check_idle(core);
115 }
116
117 void pa_client_kill(pa_client *c) {
118     pa_assert(c);
119
120     if (!c->kill) {
121         pa_log_warn("kill() operation not implemented for client %u", c->index);
122         return;
123     }
124
125     c->kill(c);
126 }
127
128 void pa_client_set_name(pa_client *c, const char *name) {
129     pa_assert(c);
130     pa_assert(name);
131
132     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);
133     pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
134
135     pa_client_update_proplist(c, 0, NULL);
136 }
137
138 void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p) {
139     pa_assert(c);
140
141     if (p)
142         pa_proplist_update(c->proplist, mode, p);
143
144     pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], c);
145     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index);
146 }
147
148 void pa_client_send_event(pa_client *c, const char *event, pa_proplist *data) {
149     pa_proplist *pl = NULL;
150     pa_client_send_event_hook_data hook_data;
151
152     pa_assert(c);
153     pa_assert(event);
154
155     if (!c->send_event)
156         return;
157
158     if (!data)
159         data = pl = pa_proplist_new();
160
161     hook_data.client = c;
162     hook_data.data = data;
163     hook_data.event = event;
164
165     if (pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CLIENT_SEND_EVENT], &hook_data) < 0)
166         goto finish;
167
168     c->send_event(c, event, data);
169
170 finish:
171
172     if (pl)
173         pa_proplist_free(pl);
174 }