DisplayLink.cpp 1.5 KB

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