1/*** 2 This file is part of PulseAudio. 3 4 Copyright 2009 Tanu Kaskinen 5 6 PulseAudio is free software; you can redistribute it and/or modify 7 it under the terms of the GNU Lesser General Public License as published 8 by the Free Software Foundation; either version 2.1 of the License, 9 or (at your option) any later version. 10 11 PulseAudio is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#ifdef HAVE_CONFIG_H 21#include <config.h> 22#endif 23 24#include <dbus/dbus.h> 25 26#include <pulsecore/core-util.h> 27#include <pulsecore/dbus-util.h> 28 29#include "iface-card-profile.h" 30 31#define OBJECT_NAME "profile" 32 33static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata); 34static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 35static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata); 36static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata); 37static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata); 38static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata); 39static void handle_get_available(DBusConnection *conn, DBusMessage *msg, void *userdata); 40 41static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata); 42 43struct pa_dbusiface_card_profile { 44 uint32_t index; 45 pa_card_profile *profile; 46 char *path; 47 pa_dbus_protocol *dbus_protocol; 48}; 49 50enum property_handler_index { 51 PROPERTY_HANDLER_INDEX, 52 PROPERTY_HANDLER_NAME, 53 PROPERTY_HANDLER_DESCRIPTION, 54 PROPERTY_HANDLER_SINKS, 55 PROPERTY_HANDLER_SOURCES, 56 PROPERTY_HANDLER_PRIORITY, 57 PROPERTY_HANDLER_AVAILABLE, 58 PROPERTY_HANDLER_MAX 59}; 60 61static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = { 62 [PROPERTY_HANDLER_INDEX] = { .property_name = "Index", .type = "u", .get_cb = handle_get_index, .set_cb = NULL }, 63 [PROPERTY_HANDLER_NAME] = { .property_name = "Name", .type = "s", .get_cb = handle_get_name, .set_cb = NULL }, 64 [PROPERTY_HANDLER_DESCRIPTION] = { .property_name = "Description", .type = "s", .get_cb = handle_get_description, .set_cb = NULL }, 65 [PROPERTY_HANDLER_SINKS] = { .property_name = "Sinks", .type = "u", .get_cb = handle_get_sinks, .set_cb = NULL }, 66 [PROPERTY_HANDLER_SOURCES] = { .property_name = "Sources", .type = "u", .get_cb = handle_get_sources, .set_cb = NULL }, 67 [PROPERTY_HANDLER_PRIORITY] = { .property_name = "Priority", .type = "u", .get_cb = handle_get_priority, .set_cb = NULL }, 68 [PROPERTY_HANDLER_AVAILABLE] = { .property_name = "Available", .type = "b", .get_cb = handle_get_available, .set_cb = NULL }, 69}; 70 71static pa_dbus_interface_info profile_interface_info = { 72 .name = PA_DBUSIFACE_CARD_PROFILE_INTERFACE, 73 .method_handlers = NULL, 74 .n_method_handlers = 0, 75 .property_handlers = property_handlers, 76 .n_property_handlers = PROPERTY_HANDLER_MAX, 77 .get_all_properties_cb = handle_get_all, 78 .signals = NULL, 79 .n_signals = 0 80}; 81 82static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) { 83 pa_dbusiface_card_profile *p = userdata; 84 85 pa_assert(conn); 86 pa_assert(msg); 87 pa_assert(p); 88 89 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &p->index); 90} 91 92static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 93 pa_dbusiface_card_profile *p = userdata; 94 95 pa_assert(conn); 96 pa_assert(msg); 97 pa_assert(p); 98 99 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->profile->name); 100} 101 102static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata) { 103 pa_dbusiface_card_profile *p = userdata; 104 105 pa_assert(conn); 106 pa_assert(msg); 107 pa_assert(p); 108 109 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->profile->description); 110} 111 112static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) { 113 pa_dbusiface_card_profile *p = userdata; 114 dbus_uint32_t sinks = 0; 115 116 pa_assert(conn); 117 pa_assert(msg); 118 pa_assert(p); 119 120 sinks = p->profile->n_sinks; 121 122 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sinks); 123} 124 125static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) { 126 pa_dbusiface_card_profile *p = userdata; 127 dbus_uint32_t sources = 0; 128 129 pa_assert(conn); 130 pa_assert(msg); 131 pa_assert(p); 132 133 sources = p->profile->n_sources; 134 135 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sources); 136} 137 138static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata) { 139 pa_dbusiface_card_profile *p = userdata; 140 dbus_uint32_t priority = 0; 141 142 pa_assert(conn); 143 pa_assert(msg); 144 pa_assert(p); 145 146 priority = p->profile->priority; 147 148 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &priority); 149} 150 151static void handle_get_available(DBusConnection *conn, DBusMessage *msg, void *userdata) { 152 pa_dbusiface_card_profile *p = userdata; 153 dbus_bool_t available; 154 155 pa_assert(conn); 156 pa_assert(msg); 157 pa_assert(p); 158 159 available = p->profile->available != PA_AVAILABLE_NO; 160 161 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &available); 162} 163 164static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) { 165 pa_dbusiface_card_profile *p = userdata; 166 DBusMessage *reply = NULL; 167 DBusMessageIter msg_iter; 168 DBusMessageIter dict_iter; 169 dbus_uint32_t sinks = 0; 170 dbus_uint32_t sources = 0; 171 dbus_uint32_t priority = 0; 172 dbus_bool_t available; 173 174 pa_assert(conn); 175 pa_assert(msg); 176 pa_assert(p); 177 178 sinks = p->profile->n_sinks; 179 sources = p->profile->n_sources; 180 priority = p->profile->priority; 181 available = p->profile->available != PA_AVAILABLE_NO; 182 183 pa_assert_se((reply = dbus_message_new_method_return(msg))); 184 185 dbus_message_iter_init_append(reply, &msg_iter); 186 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)); 187 188 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &p->index); 189 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &p->profile->name); 190 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DESCRIPTION].property_name, DBUS_TYPE_STRING, &p->profile->description); 191 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_UINT32, &sinks); 192 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_UINT32, &sources); 193 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PRIORITY].property_name, DBUS_TYPE_UINT32, &priority); 194 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_AVAILABLE].property_name, DBUS_TYPE_BOOLEAN, &available); 195 196 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter)); 197 198 pa_assert_se(dbus_connection_send(conn, reply, NULL)); 199 dbus_message_unref(reply); 200} 201 202pa_dbusiface_card_profile *pa_dbusiface_card_profile_new( 203 pa_dbusiface_card *card, 204 pa_core *core, 205 pa_card_profile *profile, 206 uint32_t idx) { 207 pa_dbusiface_card_profile *p = NULL; 208 209 pa_assert(card); 210 pa_assert(core); 211 pa_assert(profile); 212 213 p = pa_xnew(pa_dbusiface_card_profile, 1); 214 p->index = idx; 215 p->profile = profile; 216 p->path = pa_sprintf_malloc("%s/%s%u", pa_dbusiface_card_get_path(card), OBJECT_NAME, idx); 217 p->dbus_protocol = pa_dbus_protocol_get(core); 218 219 pa_assert_se(pa_dbus_protocol_add_interface(p->dbus_protocol, p->path, &profile_interface_info, p) >= 0); 220 221 return p; 222} 223 224void pa_dbusiface_card_profile_free(pa_dbusiface_card_profile *p) { 225 pa_assert(p); 226 227 pa_assert_se(pa_dbus_protocol_remove_interface(p->dbus_protocol, p->path, profile_interface_info.name) >= 0); 228 229 pa_dbus_protocol_unref(p->dbus_protocol); 230 231 pa_xfree(p->path); 232 pa_xfree(p); 233} 234 235const char *pa_dbusiface_card_profile_get_path(pa_dbusiface_card_profile *p) { 236 pa_assert(p); 237 238 return p->path; 239} 240 241const char *pa_dbusiface_card_profile_get_name(pa_dbusiface_card_profile *p) { 242 pa_assert(p); 243 244 return p->profile->name; 245} 246 247pa_card_profile *pa_dbusiface_card_profile_get_profile(pa_dbusiface_card_profile *p) { 248 pa_assert(p); 249 250 return p->profile; 251} 252