Serenity Operating System
1/*
2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/Badge.h>
8#include <AK/HashMap.h>
9#include <LibGUI/ConnectionToWindowServer.h>
10#include <LibGUI/DisplayLink.h>
11
12namespace GUI {
13
14class DisplayLinkCallback : public RefCounted<DisplayLinkCallback> {
15public:
16 DisplayLinkCallback(i32 link_id, Function<void(i32)> callback)
17 : m_link_id(link_id)
18 , m_callback(move(callback))
19 {
20 }
21
22 void invoke()
23 {
24 m_callback(m_link_id);
25 }
26
27private:
28 i32 m_link_id { 0 };
29 Function<void(i32)> m_callback;
30};
31
32static HashMap<i32, RefPtr<DisplayLinkCallback>>& callbacks()
33{
34 static HashMap<i32, RefPtr<DisplayLinkCallback>> s_map;
35 return s_map;
36}
37
38static i32 s_next_callback_id = 1;
39
40i32 DisplayLink::register_callback(Function<void(i32)> callback)
41{
42 if (callbacks().is_empty())
43 ConnectionToWindowServer::the().async_enable_display_link();
44
45 i32 callback_id = s_next_callback_id++;
46 callbacks().set(callback_id, adopt_ref(*new DisplayLinkCallback(callback_id, move(callback))));
47
48 return callback_id;
49}
50
51bool DisplayLink::unregister_callback(i32 callback_id)
52{
53 VERIFY(callbacks().contains(callback_id));
54 callbacks().remove(callback_id);
55
56 if (callbacks().is_empty())
57 ConnectionToWindowServer::the().async_disable_display_link();
58
59 return true;
60}
61
62void DisplayLink::notify(Badge<ConnectionToWindowServer>)
63{
64 auto copy_of_callbacks = callbacks();
65 for (auto& it : copy_of_callbacks)
66 it.value->invoke();
67}
68
69}