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