GClipboard.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include <LibGUI/GClipboard.h>
  2. #include <LibGUI/GEventLoop.h>
  3. #include <WindowServer/WSAPITypes.h>
  4. #include <LibC/SharedBuffer.h>
  5. GClipboard& GClipboard::the()
  6. {
  7. static GClipboard* s_the;
  8. if (!s_the)
  9. s_the = new GClipboard;
  10. return *s_the;
  11. }
  12. GClipboard::GClipboard()
  13. {
  14. }
  15. String GClipboard::data() const
  16. {
  17. WSAPI_ClientMessage request;
  18. request.type = WSAPI_ClientMessage::Type::GetClipboardContents;
  19. auto response = GEventLoop::current().sync_request(request, WSAPI_ServerMessage::Type::DidGetClipboardContents);
  20. if (response.clipboard.shared_buffer_id < 0)
  21. return { };
  22. auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(response.clipboard.shared_buffer_id);
  23. if (!shared_buffer) {
  24. dbgprintf("GClipboard::data() failed to attach to the shared buffer\n");
  25. return { };
  26. }
  27. if (response.clipboard.contents_size > shared_buffer->size()) {
  28. dbgprintf("GClipboard::data() clipping contents size is greater than shared buffer size\n");
  29. return { };
  30. }
  31. return String((const char*)shared_buffer->data(), response.clipboard.contents_size);
  32. }
  33. void GClipboard::set_data(const String& data)
  34. {
  35. WSAPI_ClientMessage request;
  36. request.type = WSAPI_ClientMessage::Type::SetClipboardContents;
  37. auto shared_buffer = SharedBuffer::create(GEventLoop::current().server_pid(), data.length() + 1);
  38. if (!shared_buffer) {
  39. dbgprintf("GClipboard::set_data() failed to create a shared buffer\n");
  40. return;
  41. }
  42. if (!data.is_empty())
  43. memcpy(shared_buffer->data(), data.characters(), data.length() + 1);
  44. else
  45. ((byte*)shared_buffer->data())[0] = '\0';
  46. shared_buffer->seal();
  47. request.clipboard.shared_buffer_id = shared_buffer->shared_buffer_id();
  48. request.clipboard.contents_size = data.length();
  49. auto response = GEventLoop::current().sync_request(request, WSAPI_ServerMessage::Type::DidSetClipboardContents);
  50. ASSERT(response.clipboard.shared_buffer_id == shared_buffer->shared_buffer_id());
  51. }