From 147af79c0ea8ac696b1521b253670605be74dd23 Mon Sep 17 00:00:00 2001 From: Julian Schuler <31921487+julianschuler@users.noreply.github.com> Date: Thu, 9 Dec 2021 22:34:35 +0100 Subject: [PATCH 1/2] Add basic pulse audio source support Added conky objects $if_pa_source_running and $if_pa_source_muted to query the status of the default pulse audio source. --- doc/variables.yaml | 9 +++++++++ src/core.cc | 6 ++++++ src/pulseaudio.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/pulseaudio.h | 11 ++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/doc/variables.yaml b/doc/variables.yaml index fb991ac3e..efdb7241d 100644 --- a/doc/variables.yaml +++ b/doc/variables.yaml @@ -951,6 +951,15 @@ values: desc: |- If Pulseaudio's default sink is muted, display everything between $if_pa_sink_muted and the corresponding $else or $endif. + - name: if_pa_source_running + desc: |- + If Pulseaudio's default source is running (e.g. a program is accessing + your microphone), display everything between $if_pa_source_running and + the corresponding $else or $endif. + - name: if_pa_source_muted + desc: |- + If Pulseaudio's default source (e.g. your microphone) is muted, display + everything between $if_pa_source_muted and the corresponding $else or $endif. - name: if_running desc: "If PROCESS is running, display everything between\n$if_running and the corresponding\ diff --git a/src/core.cc b/src/core.cc index aecce44ae..9424d77b3 100644 --- a/src/core.cc +++ b/src/core.cc @@ -2013,6 +2013,12 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(pa_card_name, 0) obj->callbacks.print = &print_puau_card_name; obj->callbacks.free = &free_pulseaudio; init_pulseaudio(obj); + END OBJ_IF(if_pa_source_running, 0) obj->callbacks.iftest = &puau_source_running; + obj->callbacks.free = &free_pulseaudio; + init_pulseaudio(obj); + END OBJ_IF(if_pa_source_muted, 0) obj->callbacks.iftest = &puau_source_muted; + obj->callbacks.free = &free_pulseaudio; + init_pulseaudio(obj); #endif /* BUILD_PULSEAUDIO */ #ifdef BUILD_INTEL_BACKLIGHT END OBJ(intel_backlight, 0) obj->callbacks.print = &print_intel_backlight; diff --git a/src/pulseaudio.cc b/src/pulseaudio.cc index 020b977b6..457e0ec31 100644 --- a/src/pulseaudio.cc +++ b/src/pulseaudio.cc @@ -49,6 +49,9 @@ const struct pulseaudio_default_results pulseaudio_result0 = {std::string(), 0, 0, std::string(), + PA_SOURCE_SUSPENDED, + 0, + std::string(), std::string(), 0}; pulseaudio_c *pulseaudio = nullptr; @@ -77,12 +80,27 @@ void pa_sink_info_callback(pa_context *c, const pa_sink_info *i, int eol, ++eol; } + +void pa_source_info_callback(pa_context *c, const pa_source_info *i, int eol, + void *data) { + if (i != nullptr && data) { + struct pulseaudio_default_results *pdr = + (struct pulseaudio_default_results *)data; + pdr->source_state = i->state; + pdr->source_mute = i->mute; + pa_threaded_mainloop_signal(pulseaudio->mainloop, 0); + } + (void)c; + ++eol; +} + void pa_server_info_callback(pa_context *c, const pa_server_info *i, void *userdata) { if (i != nullptr) { struct pulseaudio_default_results *pdr = (struct pulseaudio_default_results *)userdata; pdr->sink_name.assign(i->default_sink_name); + pdr->source_name.assign(i->default_source_name); pa_threaded_mainloop_signal(pulseaudio->mainloop, 0); } (void)c; @@ -165,6 +183,14 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, "pa_context_get_sink_info_by_name failed"); } break; + case PA_SUBSCRIPTION_EVENT_SOURCE: { + if (res->source_name.empty()) return; + pa_operation *op; + PULSEAUDIO_OP(pa_context_get_source_info_by_name( + c, res->source_name.c_str(), pa_source_info_callback, res), + "pa_context_get_source_info_by_name failed"); + } break; + case PA_SUBSCRIPTION_EVENT_CARD: if (index == res->card_index && res->card_index != (uint32_t)-1) { pa_operation *op; @@ -252,6 +278,16 @@ void init_pulseaudio(struct text_object *obj) { return; } + if (pulseaudio->result.source_name.empty()) return; + + PULSEAUDIO_WAIT(pa_context_get_source_info_by_name( + pulseaudio->context, pulseaudio->result.source_name.c_str(), + pa_source_info_callback, &pulseaudio->result)); + + if (pulseaudio->result.source_name.empty()) { + NORM_ERR("Incorrect pulseaudio source information."); + return; + } if (pulseaudio->result.sink_card != (uint32_t)-1) PULSEAUDIO_WAIT(pa_context_get_card_info_by_index( pulseaudio->context, pulseaudio->result.sink_card, @@ -264,6 +300,7 @@ void init_pulseaudio(struct text_object *obj) { if (!(op = pa_context_subscribe( pulseaudio->context, (pa_subscription_mask_t)(PA_SUBSCRIPTION_MASK_SINK | + PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_CARD), nullptr, NULL))) { @@ -313,6 +350,14 @@ int puau_muted(struct text_object *obj) { return get_pulseaudio(obj).sink_mute; } +int puau_source_running(struct text_object *obj) { + return get_pulseaudio(obj).source_state == PA_SOURCE_RUNNING; +} + +int puau_source_muted(struct text_object *obj) { + return get_pulseaudio(obj).source_mute; +} + void print_puau_sink_description(struct text_object *obj, char *p, unsigned int p_max_size) { snprintf(p, p_max_size, "%s", get_pulseaudio(obj).sink_description.c_str()); diff --git a/src/pulseaudio.h b/src/pulseaudio.h index 4a7e20b79..9df07ae05 100644 --- a/src/pulseaudio.h +++ b/src/pulseaudio.h @@ -31,6 +31,7 @@ #define _PULSEAUDIO_H #include +#include #include "text_object.h" void init_pulseaudio(struct text_object *obj); @@ -48,6 +49,8 @@ void print_puau_card_active_profile(struct text_object *obj, char *p, unsigned int p_max_size); double puau_volumebarval(struct text_object *obj); int puau_muted(struct text_object *obj); +int puau_source_running(struct text_object *obj); +int puau_source_muted(struct text_object *obj); struct pulseaudio_default_results { // default sink @@ -60,6 +63,11 @@ struct pulseaudio_default_results { uint32_t sink_index; unsigned int sink_volume; // percentage + // default source + std::string source_name; + pa_source_state source_state; + int source_mute; + // default card std::string card_active_profile_description; std::string card_name; @@ -87,7 +95,8 @@ class pulseaudio_c { cstate(PULSE_CONTEXT_INITIALIZING), ninits(0), result({std::string(), std::string(), std::string(), std::string(), 0, - 0, 0, 0, std::string(), std::string(), 0}){}; + 0, 0, 0, std::string(), PA_SOURCE_SUSPENDED, 0, std::string(), + std::string(), 0}){}; }; #endif /* _PULSEAUDIO_H */ From 1f6544d0416ea7c632bc694dae03f04fe5cb32cd Mon Sep 17 00:00:00 2001 From: Julian Schuler <31921487+julianschuler@users.noreply.github.com> Date: Thu, 9 Dec 2021 22:52:07 +0100 Subject: [PATCH 2/2] Format code using 'make clang-format' --- src/core.cc | 11 ++++------- src/pulseaudio.cc | 39 ++++++++++++++++++++------------------- src/top.cc | 4 +--- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/core.cc b/src/core.cc index 9424d77b3..cabd0327f 100644 --- a/src/core.cc +++ b/src/core.cc @@ -660,12 +660,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, EQUAL) { obj->data.i = PB_BATT_STATUS; } - else if (strcmp(arg, "percent") == EQUAL) { - obj->data.i = PB_BATT_PERCENT; - } - else if (strcmp(arg, "time") == EQUAL) { - obj->data.i = PB_BATT_TIME; - } + else if (strcmp(arg, "percent") == EQUAL) { obj->data.i = PB_BATT_PERCENT; } + else if (strcmp(arg, "time") == EQUAL) { obj->data.i = PB_BATT_TIME; } else { NORM_ERR("pb_battery: illegal argument '%s', defaulting to status", arg); obj->data.i = PB_BATT_STATUS; @@ -2013,7 +2009,8 @@ struct text_object *construct_text_object(char *s, const char *arg, long line, END OBJ(pa_card_name, 0) obj->callbacks.print = &print_puau_card_name; obj->callbacks.free = &free_pulseaudio; init_pulseaudio(obj); - END OBJ_IF(if_pa_source_running, 0) obj->callbacks.iftest = &puau_source_running; + END OBJ_IF(if_pa_source_running, 0) obj->callbacks.iftest = + &puau_source_running; obj->callbacks.free = &free_pulseaudio; init_pulseaudio(obj); END OBJ_IF(if_pa_source_muted, 0) obj->callbacks.iftest = &puau_source_muted; diff --git a/src/pulseaudio.cc b/src/pulseaudio.cc index 457e0ec31..0869ed0ab 100644 --- a/src/pulseaudio.cc +++ b/src/pulseaudio.cc @@ -40,20 +40,21 @@ struct pulseaudio_default_results get_result_copy(); -const struct pulseaudio_default_results pulseaudio_result0 = {std::string(), - std::string(), - std::string(), - std::string(), - 0, - 0, - 0, - 0, - std::string(), - PA_SOURCE_SUSPENDED, - 0, - std::string(), - std::string(), - 0}; +const struct pulseaudio_default_results pulseaudio_result0 = { + std::string(), + std::string(), + std::string(), + std::string(), + 0, + 0, + 0, + 0, + std::string(), + PA_SOURCE_SUSPENDED, + 0, + std::string(), + std::string(), + 0}; pulseaudio_c *pulseaudio = nullptr; void pa_sink_info_callback(pa_context *c, const pa_sink_info *i, int eol, @@ -80,9 +81,8 @@ void pa_sink_info_callback(pa_context *c, const pa_sink_info *i, int eol, ++eol; } - void pa_source_info_callback(pa_context *c, const pa_source_info *i, int eol, - void *data) { + void *data) { if (i != nullptr && data) { struct pulseaudio_default_results *pdr = (struct pulseaudio_default_results *)data; @@ -186,9 +186,10 @@ void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, case PA_SUBSCRIPTION_EVENT_SOURCE: { if (res->source_name.empty()) return; pa_operation *op; - PULSEAUDIO_OP(pa_context_get_source_info_by_name( - c, res->source_name.c_str(), pa_source_info_callback, res), - "pa_context_get_source_info_by_name failed"); + PULSEAUDIO_OP( + pa_context_get_source_info_by_name(c, res->source_name.c_str(), + pa_source_info_callback, res), + "pa_context_get_source_info_by_name failed"); } break; case PA_SUBSCRIPTION_EVENT_CARD: diff --git a/src/top.cc b/src/top.cc index 3c2f1d82f..493e8b152 100644 --- a/src/top.cc +++ b/src/top.cc @@ -99,9 +99,7 @@ static void unhash_all_processes() { } } -struct process *get_first_process() { - return first_process; -} +struct process *get_first_process() { return first_process; } void free_all_processes() { struct process *next = nullptr, *pr = first_process;