#include #include #include "ServerInfo.hh" #include "paman.hh" SinkInfo::SinkInfo(const struct pa_sink_info &i) : name(i.name), description(i.description), index(i.index), sample_spec(i.sample_spec), monitor_source(i.monitor_source), owner_module(i.owner_module), volume(i.volume), latency(i.latency), window(NULL) { } SinkInfo::~SinkInfo() { if (window) delete window; } void SinkInfo::update(const struct pa_sink_info &i) { name = Glib::ustring(i.name); description = i.description; index = i.index; sample_spec = i.sample_spec; monitor_source = i.monitor_source; owner_module = i.owner_module; volume = i.volume; latency = i.latency; if (window) window->updateInfo(*this); } void SinkInfo::showWindow() { if (window) window->present(); else { window = SinkWindow::create(); window->updateInfo(*this); window->show(); } } SourceInfo::SourceInfo(const struct pa_source_info &i) : name(i.name), description(i.description), index(i.index), sample_spec(i.sample_spec), owner_module(i.owner_module), monitor_of_sink(i.monitor_of_sink), window(NULL) { } SourceInfo::~SourceInfo() { if (window) delete window; } void SourceInfo::update(const struct pa_source_info &i) { name = i.name; description = i.description; index = i.index; sample_spec = i.sample_spec; owner_module = i.owner_module; monitor_of_sink = i.monitor_of_sink; if (window) window->updateInfo(*this); } void SourceInfo::showWindow() { if (window) window->present(); else { window = SourceWindow::create(); window->updateInfo(*this); window->show(); } } ClientInfo::ClientInfo(const struct pa_client_info &i) : index(i.index), name(i.name), protocol_name(i.protocol_name), owner_module(i.owner_module), window(NULL) { } ClientInfo::~ClientInfo() { if (window) delete window; } void ClientInfo::update(const struct pa_client_info &i) { name = i.name; protocol_name = i.protocol_name; index = i.index; owner_module = i.owner_module; if (window) window->updateInfo(*this); } void ClientInfo::showWindow() { if (window) window->present(); else { window = ClientWindow::create(); window->updateInfo(*this); window->show(); } } ModuleInfo::ModuleInfo(const struct pa_module_info &i) : index(i.index), name(i.name), argument(i.argument), autoloaded(i.auto_unload), used(i.n_used), window(NULL) { } ModuleInfo::~ModuleInfo() { if (window) delete window; } void ModuleInfo::update(const struct pa_module_info &i) { name = i.name; argument = i.argument; index = i.index; autoloaded = i.auto_unload; used = i.n_used; if (window) window->updateInfo(*this); } void ModuleInfo::showWindow() { if (window) window->present(); else { window = ModuleWindow::create(); window->updateInfo(*this); window->show(); } } static void server_info_callback(struct pa_context *c, const struct pa_server_info *i, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; if (!i) { mainWindow->showFailure(pa_strerror(pa_context_errno(c))); return; } mainWindow->updateInfo(*i); } static void sink_info_callback(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; if (!is_last && i) si->updateInfo(*i); } static void source_info_callback(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; if (!is_last && i) si->updateInfo(*i); } static void client_info_callback(struct pa_context *c, const struct pa_client_info *i, int is_last, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; if (!is_last && i) si->updateInfo(*i); } static void module_info_callback(struct pa_context *c, const struct pa_module_info *i, int is_last, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; if (!is_last && i) si->updateInfo(*i); } static void subscribe_callback(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) { ServerInfoManager *si = (ServerInfoManager*) userdata; // fprintf(stderr, "EV: %u %u\n", t, index); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { case PA_SUBSCRIPTION_EVENT_SINK: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) si->removeSinkInfo(index); else pa_context_get_sink_info_by_index(c, index, sink_info_callback, si); break; case PA_SUBSCRIPTION_EVENT_SOURCE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) si->removeSourceInfo(index); else pa_context_get_source_info_by_index(c, index, source_info_callback, si); break; case PA_SUBSCRIPTION_EVENT_MODULE: if ((t && PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) si->removeModuleInfo(index); else pa_context_get_module_info(c, index, module_info_callback, si); break; case PA_SUBSCRIPTION_EVENT_CLIENT: if ((t && PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) si->removeClientInfo(index); else pa_context_get_client_info(c, index, client_info_callback, si); break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: // fprintf(stderr, "SINK INPUT EVENT\n"); break; case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: // fprintf(stderr, "SOURCE OUTPUT EVENT\n"); break; default: // fprintf(stderr, "OTHER EVENT\n"); break; } } ServerInfoManager::ServerInfoManager(struct pa_context &c) : context(c) { pa_context_get_server_info(&c, server_info_callback, this); pa_context_get_sink_info_list(&c, sink_info_callback, this); pa_context_get_source_info_list(&c, source_info_callback, this); pa_context_get_module_info_list(&c, module_info_callback, this); pa_context_get_client_info_list(&c, client_info_callback, this); pa_context_subscribe(&c, (enum pa_subscription_mask) (PA_SUBSCRIPTION_FACILITY_SINK|PA_SUBSCRIPTION_FACILITY_SOURCE|PA_SUBSCRIPTION_FACILITY_MODULE|PA_SUBSCRIPTION_FACILITY_SINK_INPUT|PA_SUBSCRIPTION_FACILITY_SOURCE_OUTPUT|PA_SUBSCRIPTION_FACILITY_CLIENT), subscribe_callback, this); } ServerInfoManager::~ServerInfoManager() { for (std::map::iterator i = sinks.begin(); i != sinks.end(); i++) delete i->second; for (std::map::iterator i = sources.begin(); i != sources.end(); i++) delete i->second; for (std::map::iterator i = clients.begin(); i != clients.end(); i++) delete i->second; for (std::map::iterator i = modules.begin(); i != modules.end(); i++) delete i->second; } void ServerInfoManager::updateInfo(const struct pa_sink_info &i) { SinkInfo *si; if ((si = sinks[i.index])) si->update(i); else { SinkInfo *n = new SinkInfo(i); sinks[i.index] = n; mainWindow->updateInfo(*n); } } void ServerInfoManager::updateInfo(const struct pa_source_info &i) { SourceInfo *si; if ((si = sources[i.index])) si->update(i); else { SourceInfo *n = new SourceInfo(i); sources[i.index] = n; mainWindow->updateInfo(*n); } } void ServerInfoManager::updateInfo(const struct pa_client_info &i) { ClientInfo *si; if ((si = clients[i.index])) si->update(i); else { ClientInfo *n = new ClientInfo(i); clients[i.index] = n; mainWindow->updateInfo(*n); } } void ServerInfoManager::updateInfo(const struct pa_module_info &i) { ModuleInfo *si; if ((si = modules[i.index])) si->update(i); else { ModuleInfo *n = new ModuleInfo(i); modules[i.index] = n; mainWindow->updateInfo(*n); } } void ServerInfoManager::showSinkWindow(uint32_t index) { SinkInfo *i; if ((i = sinks[index])) i->showWindow(); } void ServerInfoManager::showSourceWindow(uint32_t index) { SourceInfo *i; if ((i = sources[index])) i->showWindow(); } void ServerInfoManager::showClientWindow(uint32_t index) { ClientInfo *i; if ((i = clients[index])) i->showWindow(); } void ServerInfoManager::showModuleWindow(uint32_t index) { ModuleInfo *i; if ((i = modules[index])) i->showWindow(); } SourceInfo* ServerInfoManager::getSourceInfo(uint32_t index) { return sources[index]; } SinkInfo* ServerInfoManager::getSinkInfo(uint32_t index) { return sinks[index]; } ClientInfo* ServerInfoManager::getClientInfo(uint32_t index) { return clients[index]; } ModuleInfo* ServerInfoManager::getModuleInfo(uint32_t index) { return modules[index]; } void ServerInfoManager::removeSinkInfo(uint32_t index) { SinkInfo *i; fprintf(stderr, "REMOVE %i\n", index); if ((i = sinks[index])) { sinks.erase(index); mainWindow->removeInfo(*i); delete i; } } void ServerInfoManager::removeSourceInfo(uint32_t index) { SourceInfo *i; if ((i = sources[index])) { sources.erase(index); mainWindow->removeInfo(*i); delete i; } } void ServerInfoManager::removeClientInfo(uint32_t index) { ClientInfo *i; if ((i = clients[index])) { clients.erase(index); mainWindow->removeInfo(*i); delete i; } } void ServerInfoManager::removeModuleInfo(uint32_t index) { ModuleInfo *i; if ((i = modules[index])) { modules.erase(index); mainWindow->removeInfo(*i); delete i; } }