diff --git a/meson.build b/meson.build index 07a658d..29e7f35 100644 --- a/meson.build +++ b/meson.build @@ -40,6 +40,7 @@ executable( 'sway-audio-idle-inhibit', [ './src/main.cpp', + './src/pulse.cpp', './src/idle.cpp', ], dependencies: [ diff --git a/src/main.cpp b/src/main.cpp index fc75118..11b4c25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,281 +1,15 @@ -#include -#include -#include -#include +#include -#include - -#include "./idle.cpp" - -using namespace std; - -enum SubscriptionType { - SUBSCRIPTION_TYPE_IDLE, - SUBSCRIPTION_TYPE_DRY_BOTH, - SUBSCRIPTION_TYPE_DRY_SINK, - SUBSCRIPTION_TYPE_DRY_SOURCE, -}; -enum EventType { - EVENT_TYPE_IDLE, - EVENT_TYPE_DRY_BOTH, - EVENT_TYPE_DRY_SINK, - EVENT_TYPE_DRY_SOURCE, - EVENT_TYPE_NONE, -}; - -struct Data { - pa_threaded_mainloop *mainloop; - pa_mainloop_api *mainloop_api; - pa_context *context; - - EventType eventCalled = EVENT_TYPE_NONE; - bool activeSource = false; - bool activeSink = false; - - SubscriptionType subscriptionType; - pa_subscription_mask_t pa_subscriptionType; - - Idle *idle = NULL; - - Data(pa_threaded_mainloop *mainloop, pa_mainloop_api *mainloop_api, - SubscriptionType subscriptionType, - pa_subscription_mask_t pa_subscriptionType) { - this->mainloop = mainloop; - this->mainloop_api = mainloop_api; - this->subscriptionType = subscriptionType; - this->pa_subscriptionType = pa_subscriptionType; - - if (subscriptionType == SUBSCRIPTION_TYPE_IDLE) idle = new Idle(); - } - - void quit(int returnValue = 0) { - mainloop_api->quit(mainloop_api, returnValue); - pa_threaded_mainloop_stop(mainloop); - pa_threaded_mainloop_free(mainloop); - } - - void handleAction() { - switch (subscriptionType) { - case SUBSCRIPTION_TYPE_IDLE: - idle->update(activeSink || activeSource); - break; - case SUBSCRIPTION_TYPE_DRY_BOTH: - this->print(activeSink || activeSource); - break; - case SUBSCRIPTION_TYPE_DRY_SINK: - this->print(activeSink); - break; - case SUBSCRIPTION_TYPE_DRY_SOURCE: - this->print(activeSource); - break; - } - } - - private: - void print(bool isRunning) { - cout << (isRunning ? "RUNNING" : "NOT RUNNING") << endl; - } -}; - -void sink_input_info_callback(pa_context *, const pa_sink_input_info *i, int, - void *userdata) { - Data *data = (Data *)userdata; - if (i && !i->corked) data->activeSink = true; - pa_threaded_mainloop_signal(data->mainloop, 0); -} - -void source_output_info_callback(pa_context *, const pa_source_output_info *i, - int, void *userdata) { - Data *data = (Data *)userdata; - if (i && !i->corked) data->activeSource = true; - pa_threaded_mainloop_signal(data->mainloop, 0); -} - -void getRunning(EventType eventType, Data *data, pa_context *context) { - pa_threaded_mainloop_lock(data->mainloop); - pa_operation *op = NULL; - switch (eventType) { - case EVENT_TYPE_DRY_SINK: - data->activeSink = false; - op = pa_context_get_sink_input_info_list(context, - sink_input_info_callback, data); - break; - case EVENT_TYPE_DRY_SOURCE: - data->activeSource = false; - op = pa_context_get_source_output_info_list( - context, source_output_info_callback, data); - break; - default: - fprintf(stderr, "Operation Default!\n"); - pa_threaded_mainloop_unlock(data->mainloop); - return; - } - if (!op) { - pa_threaded_mainloop_unlock(data->mainloop); - fprintf(stderr, "Operation failed!\n"); - return; - } - while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) { - pa_threaded_mainloop_wait(data->mainloop); - } - pa_operation_unref(op); - pa_threaded_mainloop_unlock(data->mainloop); -} - -void subscribe_callback(pa_context *, pa_subscription_event_type_t type, - uint32_t, void *userdata) { - Data *data = (Data *)userdata; - EventType eventType; - switch (type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK: - eventType = EVENT_TYPE_DRY_SINK; - break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - eventType = EVENT_TYPE_DRY_SOURCE; - break; - default: - return; - } - if(data->subscriptionType == SUBSCRIPTION_TYPE_IDLE) { - eventType = EVENT_TYPE_IDLE; - } else if(data->subscriptionType == SUBSCRIPTION_TYPE_DRY_BOTH) { - eventType = EVENT_TYPE_DRY_BOTH; - } - data->eventCalled = eventType; - pa_threaded_mainloop_signal(data->mainloop, 0); -} - -void context_state_callback(pa_context *c, void *userdata) { - Data *data = (Data *)userdata; - switch (pa_context_get_state(c)) { - case PA_CONTEXT_CONNECTING: - case PA_CONTEXT_AUTHORIZING: - case PA_CONTEXT_SETTING_NAME: - break; - case PA_CONTEXT_READY: - pa_threaded_mainloop_signal(data->mainloop, 0); - break; - case PA_CONTEXT_TERMINATED: - pa_threaded_mainloop_signal(data->mainloop, 1); - data->quit(0); - fprintf(stderr, "PulseAudio connection terminated.\n"); - break; - case PA_CONTEXT_FAILED: - default: - pa_threaded_mainloop_signal(data->mainloop, 1); - fprintf(stderr, "Connection failure: %s\n", - pa_strerror(pa_context_errno(c))); - data->quit(1); - break; - } -} - -void connect(pa_threaded_mainloop *mainloop, pa_mainloop_api *mainloop_api, - SubscriptionType subscriptionType, - pa_subscription_mask_t pa_subscriptionType) { - Data *data = - new Data(mainloop, mainloop_api, subscriptionType, pa_subscriptionType); - - pa_context *context = pa_context_new(mainloop_api, "PulseAudio Test"); - if (!context) { - fprintf(stderr, "pa_context_new() failed\n"); - exit(1); - } - - pa_threaded_mainloop_lock(mainloop); - if (pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) { - fprintf(stderr, "pa_context_connect() failed: %s\n", - pa_strerror(pa_context_errno(context))); - exit(1); - } - pa_context_set_state_callback(context, context_state_callback, data); - while (pa_context_get_state(context) != PA_CONTEXT_READY) { - pa_threaded_mainloop_wait(mainloop); - } - pa_threaded_mainloop_unlock(mainloop); - - pa_context_set_subscribe_callback(context, subscribe_callback, data); - pa_context_subscribe(context, data->pa_subscriptionType, NULL, data); - - // print when started - switch (subscriptionType) { - case SUBSCRIPTION_TYPE_IDLE: - data->eventCalled = EVENT_TYPE_IDLE; - break; - case SUBSCRIPTION_TYPE_DRY_BOTH: - data->eventCalled = EVENT_TYPE_DRY_BOTH; - break; - case SUBSCRIPTION_TYPE_DRY_SINK: - data->eventCalled = EVENT_TYPE_DRY_SINK; - break; - case SUBSCRIPTION_TYPE_DRY_SOURCE: - data->eventCalled = EVENT_TYPE_DRY_SOURCE; - break; - } - - for (;;) { - switch (data->eventCalled) { - case EVENT_TYPE_IDLE: - case EVENT_TYPE_DRY_BOTH: - getRunning(EVENT_TYPE_DRY_SINK, data, context); - getRunning(EVENT_TYPE_DRY_SOURCE, data, context); - data->handleAction(); - data->eventCalled = EVENT_TYPE_NONE; - break; - case EVENT_TYPE_DRY_SINK: - getRunning(data->eventCalled, data, context); - data->handleAction(); - data->eventCalled = EVENT_TYPE_NONE; - break; - case EVENT_TYPE_DRY_SOURCE: - getRunning(data->eventCalled, data, context); - data->handleAction(); - data->eventCalled = EVENT_TYPE_NONE; - break; - case EVENT_TYPE_NONE: - pa_threaded_mainloop_lock(mainloop); - pa_threaded_mainloop_wait(mainloop); - pa_threaded_mainloop_unlock(mainloop); - break; - } - } -} +#include "./pulse.cpp" void showHelp(char **argv) { cout << "Usage:" << endl; cout << "\t" << argv[0] << "