summaryrefslogtreecommitdiffstats
path: root/src/ServerInfo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ServerInfo.cc')
-rw-r--r--src/ServerInfo.cc398
1 files changed, 398 insertions, 0 deletions
diff --git a/src/ServerInfo.cc b/src/ServerInfo.cc
new file mode 100644
index 0000000..fc7fe4e
--- /dev/null
+++ b/src/ServerInfo.cc
@@ -0,0 +1,398 @@
+#include <iostream>
+#include <polyp/polyplib-error.h>
+
+#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);
+ g_assert(mainWindow);
+ mainWindow->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);
+ g_assert(mainWindow);
+ mainWindow->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);
+
+ g_assert(mainWindow);
+ mainWindow->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);
+ g_assert(mainWindow);
+ mainWindow->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 (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 (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 (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 (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_operation_unref(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_operation_unref(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_operation_unref(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_operation_unref(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_operation_unref(pa_context_get_server_info(&c, server_info_callback, this));
+ pa_operation_unref(pa_context_get_sink_info_list(&c, sink_info_callback, this));
+ pa_operation_unref(pa_context_get_source_info_list(&c, source_info_callback, this));
+ pa_operation_unref(pa_context_get_module_info_list(&c, module_info_callback, this));
+ pa_operation_unref(pa_context_get_client_info_list(&c, client_info_callback, this));
+
+ pa_context_set_subscribe_callback(&c, subscribe_callback, this);
+
+ pa_operation_unref(pa_context_subscribe(&c, (enum pa_subscription_mask)
+ (PA_SUBSCRIPTION_MASK_SINK|
+ PA_SUBSCRIPTION_MASK_SOURCE|
+ PA_SUBSCRIPTION_MASK_MODULE|
+ PA_SUBSCRIPTION_MASK_SINK_INPUT|
+ PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT|
+ PA_SUBSCRIPTION_MASK_CLIENT), NULL, NULL));
+}
+
+
+ServerInfoManager::~ServerInfoManager() {
+ for (std::map<int, SinkInfo*>::iterator i = sinks.begin(); i != sinks.end(); i++)
+ delete i->second;
+
+ for (std::map<int, SourceInfo*>::iterator i = sources.begin(); i != sources.end(); i++)
+ delete i->second;
+
+ for (std::map<int, ClientInfo*>::iterator i = clients.begin(); i != clients.end(); i++)
+ delete i->second;
+
+ for (std::map<int, ModuleInfo*>::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 *ci;
+
+ if ((ci = clients[i.index]))
+ ci->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;
+
+ 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;
+ }
+}
+
+void ServerInfoManager::setSinkVolume(uint32_t index, uint32_t volume) {
+ pa_operation_unref(pa_context_set_sink_volume_by_index(&context, index, volume, NULL, NULL));
+}