GClipboard.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include <LibC/SharedBuffer.h>
  2. #include <LibGUI/GClipboard.h>
  3. #include <LibGUI/GWindowServerConnection.h>
  4. GClipboard& GClipboard::the()
  5. {
  6. static GClipboard* s_the;
  7. if (!s_the)
  8. s_the = new GClipboard;
  9. return *s_the;
  10. }
  11. GClipboard::GClipboard()
  12. {
  13. }
  14. GClipboard::DataAndType GClipboard::data_and_type() const
  15. {
  16. auto response = GWindowServerConnection::the().send_sync<WindowServer::GetClipboardContents>();
  17. if (response->shared_buffer_id() < 0)
  18. return {};
  19. auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(response->shared_buffer_id());
  20. if (!shared_buffer) {
  21. dbgprintf("GClipboard::data() failed to attach to the shared buffer\n");
  22. return {};
  23. }
  24. if (response->content_size() > shared_buffer->size()) {
  25. dbgprintf("GClipboard::data() clipping contents size is greater than shared buffer size\n");
  26. return {};
  27. }
  28. auto data = String((const char*)shared_buffer->data(), response->content_size());
  29. auto type = response->content_type();
  30. return { data, type };
  31. }
  32. void GClipboard::set_data(const StringView& data, const String& type)
  33. {
  34. auto shared_buffer = SharedBuffer::create_with_size(data.length() + 1);
  35. if (!shared_buffer) {
  36. dbgprintf("GClipboard::set_data() failed to create a shared buffer\n");
  37. return;
  38. }
  39. if (!data.is_empty())
  40. memcpy(shared_buffer->data(), data.characters_without_null_termination(), data.length() + 1);
  41. else
  42. ((u8*)shared_buffer->data())[0] = '\0';
  43. shared_buffer->seal();
  44. shared_buffer->share_with(GWindowServerConnection::the().server_pid());
  45. GWindowServerConnection::the().send_sync<WindowServer::SetClipboardContents>(shared_buffer->shared_buffer_id(), data.length(), type);
  46. }
  47. void GClipboard::did_receive_clipboard_contents_changed(Badge<GWindowServerConnection>, const String& data_type)
  48. {
  49. if (on_content_change)
  50. on_content_change(data_type);
  51. }