Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <LibAudio/ClientConnection.h>
28#include <LibGUI/Application.h>
29#include <LibGUI/Painter.h>
30#include <LibGUI/Widget.h>
31#include <LibGUI/Window.h>
32#include <LibGfx/Bitmap.h>
33#include <LibGfx/Font.h>
34
35class AudioWidget final : public GUI::Widget {
36 C_OBJECT(AudioWidget)
37public:
38 AudioWidget()
39 {
40 m_audio_client = make<Audio::ClientConnection>();
41 m_audio_client->on_muted_state_change = [this](bool muted) {
42 if (m_audio_muted == muted)
43 return;
44 m_audio_muted = muted;
45 update();
46 };
47 m_unmuted_bitmap = Gfx::Bitmap::load_from_file("/res/icons/audio-unmuted.png");
48 m_muted_bitmap = Gfx::Bitmap::load_from_file("/res/icons/audio-muted.png");
49 }
50
51 virtual ~AudioWidget() override {}
52
53private:
54 virtual void mousedown_event(GUI::MouseEvent& event) override
55 {
56 if (event.button() != GUI::MouseButton::Left)
57 return;
58 m_audio_client->set_muted(!m_audio_muted);
59 update();
60 }
61
62 virtual void paint_event(GUI::PaintEvent& event) override
63 {
64 GUI::Painter painter(*this);
65 painter.add_clip_rect(event.rect());
66 painter.clear_rect(event.rect(), Color::from_rgba(0));
67 auto& audio_bitmap = m_audio_muted ? *m_muted_bitmap : *m_unmuted_bitmap;
68 painter.blit({}, audio_bitmap, audio_bitmap.rect());
69 }
70
71 OwnPtr<Audio::ClientConnection> m_audio_client;
72 RefPtr<Gfx::Bitmap> m_muted_bitmap;
73 RefPtr<Gfx::Bitmap> m_unmuted_bitmap;
74 bool m_audio_muted { false };
75};
76
77int main(int argc, char** argv)
78{
79 if (pledge("stdio shared_buffer accept rpath unix cpath fattr", nullptr) < 0) {
80 perror("pledge");
81 return 1;
82 }
83
84 GUI::Application app(argc, argv);
85
86 if (pledge("stdio shared_buffer accept rpath unix", nullptr) < 0) {
87 perror("pledge");
88 return 1;
89 }
90
91 auto window = GUI::Window::construct();
92 window->set_has_alpha_channel(true);
93 window->set_title("Audio");
94 window->set_window_type(GUI::WindowType::MenuApplet);
95 window->resize(12, 16);
96
97 auto widget = AudioWidget::construct();
98 window->set_main_widget(widget);
99 window->show();
100
101 if (unveil("/res", "r") < 0) {
102 perror("unveil");
103 return 1;
104 }
105
106 unveil(nullptr, nullptr);
107
108 if (pledge("stdio shared_buffer accept rpath", nullptr) < 0) {
109 perror("pledge");
110 return 1;
111 }
112
113 return app.exec();
114}