DisplayLink.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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>>* map;
  29. if (!map)
  30. map = new HashMap<i32, RefPtr<DisplayLinkCallback>>;
  31. return *map;
  32. }
  33. static i32 s_next_callback_id = 1;
  34. i32 DisplayLink::register_callback(Function<void(i32)> callback)
  35. {
  36. if (callbacks().is_empty())
  37. WindowServerConnection::the().async_enable_display_link();
  38. i32 callback_id = s_next_callback_id++;
  39. callbacks().set(callback_id, adopt_ref(*new DisplayLinkCallback(callback_id, move(callback))));
  40. return callback_id;
  41. }
  42. bool DisplayLink::unregister_callback(i32 callback_id)
  43. {
  44. VERIFY(callbacks().contains(callback_id));
  45. callbacks().remove(callback_id);
  46. if (callbacks().is_empty())
  47. WindowServerConnection::the().async_disable_display_link();
  48. return true;
  49. }
  50. void DisplayLink::notify(Badge<WindowServerConnection>)
  51. {
  52. auto copy_of_callbacks = callbacks();
  53. for (auto& it : copy_of_callbacks)
  54. it.value->invoke();
  55. }
  56. }