1 #pragma once 2 3 #include <pulse/pulseaudio.h> 4 #include <queue> 5 6 #include "common.hpp" 7 #include "settings.hpp" 8 #include "errors.hpp" 9 10 #include "utils/math.hpp" 11 // fwd 12 struct pa_context; 13 struct pa_threaded_mainloop; 14 struct pa_cvolume; 15 typedef struct pa_context pa_context; 16 typedef struct pa_threaded_mainloop pa_threaded_mainloop; 17 18 POLYBAR_NS 19 class logger; 20 21 DEFINE_ERROR(pulseaudio_error); 22 23 class pulseaudio { 24 // events to add to our queue 25 enum class evtype { NEW = 0, CHANGE, REMOVE, SERVER }; 26 using queue = std::queue<evtype>; 27 28 public: 29 explicit pulseaudio(const logger& logger, string&& sink_name, bool m_max_volume); 30 ~pulseaudio(); 31 32 pulseaudio(const pulseaudio& o) = delete; 33 pulseaudio& operator=(const pulseaudio& o) = delete; 34 35 const string& get_name(); 36 37 bool wait(); 38 int process_events(); 39 40 int get_volume(); 41 double get_decibels(); 42 void set_volume(float percentage); 43 void inc_volume(int delta_perc); 44 void set_mute(bool mode); 45 void toggle_mute(); 46 bool is_muted(); 47 48 private: 49 void update_volume(pa_operation *o); 50 static void check_mute_callback(pa_context *context, const pa_sink_info *info, int eol, void *userdata); 51 static void get_sink_volume_callback(pa_context *context, const pa_sink_info *info, int is_last, void *userdata); 52 static void subscribe_callback(pa_context* context, pa_subscription_event_type_t t, uint32_t idx, void* userdata); 53 static void simple_callback(pa_context *context, int success, void *userdata); 54 static void sink_info_callback(pa_context *context, const pa_sink_info *info, int eol, void *userdata); 55 static void context_state_callback(pa_context *context, void *userdata); 56 57 inline void wait_loop(pa_operation *op, pa_threaded_mainloop *loop); 58 59 const logger& m_log; 60 61 // used for temporary callback results 62 int success{0}; 63 pa_cvolume cv; 64 bool muted{false}; 65 // default sink name 66 static constexpr auto DEFAULT_SINK = "@DEFAULT_SINK@"; 67 68 pa_context* m_context{nullptr}; 69 pa_threaded_mainloop* m_mainloop{nullptr}; 70 71 queue m_events; 72 73 // specified sink name 74 string spec_s_name; 75 string s_name; 76 uint32_t m_index{0}; 77 78 pa_volume_t m_max_volume{PA_VOLUME_UI_MAX}; 79 }; 80 81 POLYBAR_NS_END 82