Add copy & paste to clipboard 86/293586/2
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 31 May 2023 10:46:23 +0000 (19:46 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Thu, 1 Jun 2023 02:43:15 +0000 (11:43 +0900)
It looks ECORE_WL2_EVENT_SELECTION_DATA_READY has been deprecated since a very long time ago.
Change to ECORE_WL2_EVENT_OFFER_DATA_READY for Paste operation.

+ Depending on the environment, such as whether cbhm is used or not,
the length received as an event may be string length or buffer length.
Add null validation to the event handler to ensure it works.

Currently known exception cases are resolved,
but this logic may need to be modified if another exception appears.

This reverts commit 9900645a13deda1aa7cdbe35ceab1c84d97cb60d.

Change-Id: Idf99fec07524bab8b6338b7abc7c235f3ddc6d17

dali/internal/clipboard/common/clipboard-impl.h
dali/internal/clipboard/generic/clipboard-impl-generic.cpp
dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
dali/internal/window-system/common/event-handler.cpp
dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp

index ec10c59..eeaae38 100644 (file)
@@ -92,13 +92,20 @@ public:
   bool IsVisible() const;
 
   /**
-  * @brief exchange either sending or receiving buffered data
+  * @brief sending buffered data
   *
-  * @param[in] type true for send buffered data, false for receive data to buffer
   * @param[in] event information pointer
-  * @return The buffer pointer for send or receive data
   */
-  char* ExcuteBuffered(bool type, void* event);
+  void ExcuteSend(void* event);
+
+  /**
+  * @brief receiving buffered data
+  *
+  * @param[in] event information pointer
+  * @param[out] data The buffer pointer for receive data
+  * @param[out] length The buffer length for receive data
+  */
+  void ExcuteReceive(void* event, char*& data, int& length);
 
 private:
   // Undefined
index 43713af..74b911e 100644 (file)
@@ -106,9 +106,12 @@ bool Clipboard::IsVisible() const
   return false;
 }
 
-char* Clipboard::ExcuteBuffered(bool type, void* event)
+void Clipboard::ExcuteSend(void* event)
+{
+}
+
+void Clipboard::ExcuteReceive(void* event, char*& data, int& length)
 {
-  return NULL;
 }
 
 } // namespace Adaptor
index 1cd452b..c3dc462 100644 (file)
@@ -117,50 +117,48 @@ struct Clipboard::Impl
     Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(ecore_wl2_connected_display_get(NULL));
     mSerial                = ecore_wl2_dnd_selection_set(input, types);
 #else
-    mSerial               = ecore_wl_dnd_selection_set(ecore_wl_input_get(), types);
+    mSerial                = ecore_wl_dnd_selection_set(ecore_wl_input_get(), types);
 #endif
   }
 
   void RequestItem()
   {
-#ifdef ECORE_WAYLAND2
-    Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(ecore_wl2_connected_display_get(NULL));
-    ecore_wl2_dnd_selection_get(input);
-#else
     const char* types[10] = {
       0,
     };
     int i = -1;
 
     types[++i] = "text/plain;charset=utf-8";
+
+#ifdef ECORE_WAYLAND2
+    Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
+    Ecore_Wl2_Input*   input   = ecore_wl2_input_default_input_get(display);
+    Ecore_Wl2_Offer*   offer   = ecore_wl2_dnd_selection_get(input);
+
+    ecore_wl2_offer_receive(offer, const_cast<char*>(*types));
+    ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+#else
     ecore_wl_dnd_selection_get(ecore_wl_input_get(), *types);
 #endif
-
-    Dali::ClipboardEventNotifier clipboardEventNotifier(Dali::ClipboardEventNotifier::Get());
-    if(clipboardEventNotifier)
-    {
-      clipboardEventNotifier.SetContent(mSendBuffer);
-      clipboardEventNotifier.EmitContentSelectedSignal();
-    }
   }
 
-  char* ExcuteSend(void* event)
+  void ExcuteSend(void* event)
   {
 #ifdef ECORE_WAYLAND2
     Ecore_Wl2_Event_Data_Source_Send* ev = reinterpret_cast<Ecore_Wl2_Event_Data_Source_Send*>(event);
 #else
-    Ecore_Wl_Event_Data_Source_Send*     ev = reinterpret_cast<Ecore_Wl_Event_Data_Source_Send*>(event);
+    Ecore_Wl_Event_Data_Source_Send*  ev = reinterpret_cast<Ecore_Wl_Event_Data_Source_Send*>(event);
 #endif
 
     if(ev->serial != mSerial)
     {
-      return NULL;
+      return;
     }
 
-    int         len_buf      = mSendBuffer.length();
+    int         len_buf      = mSendBuffer.length() + 1; // we should consider the char* buffer length
     int         len_remained = len_buf;
     int         len_written  = 0, ret;
-    const char* buf          = mSendBuffer.c_str();
+    const char* buf          = mSendBuffer.c_str(); // last char in the buffer must be \0
 
     while(len_written < len_buf)
     {
@@ -171,18 +169,17 @@ struct Clipboard::Impl
       len_remained -= ret;
     }
     close(ev->fd);
-    return NULL;
   }
 
-  char* ExcuteReceive(void* event)
+  void ExcuteReceive(void* event, char*& data, int& length)
   {
 #ifdef ECORE_WAYLAND2
-    Ecore_Wl2_Event_Selection_Data_Ready* ev = reinterpret_cast<Ecore_Wl2_Event_Selection_Data_Ready*>(event);
+    Ecore_Wl2_Event_Offer_Data_Ready* ev = reinterpret_cast<Ecore_Wl2_Event_Offer_Data_Ready*>(event);
 #else
     Ecore_Wl_Event_Selection_Data_Ready* ev = reinterpret_cast<Ecore_Wl_Event_Selection_Data_Ready*>(event);
 #endif
-
-    return reinterpret_cast<char*>(ev->data);
+    data   = reinterpret_cast<char*>(ev->data);
+    length = ev->len;
   }
 
   int GetCount()
@@ -362,9 +359,14 @@ bool Clipboard::IsVisible() const
   return mImpl->IsVisible();
 }
 
-char* Clipboard::ExcuteBuffered(bool type, void* event)
+void Clipboard::ExcuteSend(void* event)
+{
+  mImpl->ExcuteSend(event);
+}
+
+void Clipboard::ExcuteReceive(void* event, char*& data, int& length)
 {
-  return (type ? mImpl->ExcuteSend(event) : mImpl->ExcuteReceive(event));
+  mImpl->ExcuteReceive(event, data, length);
 }
 
 } // namespace Adaptor
index 070974f..807f9db 100644 (file)
@@ -222,26 +222,26 @@ bool Clipboard::IsVisible() const
   return false;
 }
 
-char* Clipboard::ExcuteBuffered(bool type, void* event)
+void Clipboard::ExcuteSend(void* event)
 {
-  if(!type)
-  {
-    // Receive
-    Ecore_X_Event_Selection_Notify* selectionNotifyEvent = static_cast<Ecore_X_Event_Selection_Notify*>(event);
+}
 
-    Ecore_X_Selection_Data* selectionData = static_cast<Ecore_X_Selection_Data*>(selectionNotifyEvent->data);
-    if(selectionData->data)
-    {
-      if(selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY)
-      {
-        // Claim the ownership of the SECONDARY selection.
-        ecore_x_selection_secondary_set(mImpl->mApplicationWindow, "", 1);
+void Clipboard::ExcuteReceive(void* event, char*& data, int& length)
+{
+  // Receive
+  Ecore_X_Event_Selection_Notify* selectionNotifyEvent = static_cast<Ecore_X_Event_Selection_Notify*>(event);
 
-        return (reinterpret_cast<char*>(selectionData->data));
-      }
+  Ecore_X_Selection_Data* selectionData = static_cast<Ecore_X_Selection_Data*>(selectionNotifyEvent->data);
+  if(selectionData->data)
+  {
+    if(selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY)
+    {
+      // Claim the ownership of the SECONDARY selection.
+      ecore_x_selection_secondary_set(mImpl->mApplicationWindow, "", 1);
+      data = reinterpret_cast<char*>(selectionData->data);
+      length = selectionData->length;
     }
   }
-  return NULL;
 }
 
 } // namespace Adaptor
index cf1fb78..397fcb3 100644 (file)
@@ -168,7 +168,7 @@ void EventHandler::OnSelectionDataSend(void* event)
   if(clipboard)
   {
     Clipboard& clipBoardImpl(GetImplementation(clipboard));
-    clipBoardImpl.ExcuteBuffered(true, event);
+    clipBoardImpl.ExcuteSend(event);
   }
 }
 
@@ -177,10 +177,14 @@ void EventHandler::OnSelectionDataReceived(void* event)
   // We have got the selected content, inform the clipboard event listener (if we have one).
   Dali::Clipboard clipboard     = Clipboard::Get();
   char*           selectionData = NULL;
+  size_t          dataLength    = 0u;
+
   if(clipboard)
   {
+    int len = 0;
     Clipboard& clipBoardImpl(GetImplementation(clipboard));
-    selectionData = clipBoardImpl.ExcuteBuffered(false, event);
+    clipBoardImpl.ExcuteReceive(event, selectionData, len);
+    dataLength = static_cast<size_t>(len);
   }
 
   if(!mClipboardEventNotifier)
@@ -188,15 +192,25 @@ void EventHandler::OnSelectionDataReceived(void* event)
     mClipboardEventNotifier = ClipboardEventNotifier::Get();
   }
 
-  if(selectionData && mClipboardEventNotifier)
+  if(selectionData && mClipboardEventNotifier && dataLength > 0)
   {
     ClipboardEventNotifier& clipboardEventNotifier(ClipboardEventNotifier::GetImplementation(mClipboardEventNotifier));
-    std::string             content(selectionData, strlen(selectionData));
+    std::string             content;
+    size_t                  stringLength = strlen(selectionData);
+
+    if(stringLength < dataLength)
+    {
+      content.append(selectionData, stringLength);
+    }
+    else
+    {
+      content.append(selectionData, dataLength);
+    }
 
     clipboardEventNotifier.SetContent(content);
     clipboardEventNotifier.EmitContentSelectedSignal();
 
-    DALI_LOG_INFO(gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d): %s\n", strlen(selectionData), selectionData);
+    DALI_LOG_INFO(gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%s) strlen(%d) dataLength(%d)\n", selectionData, strlen(selectionData), dataLength);
   }
 }
 
index 812ecfe..278d13b 100644 (file)
@@ -964,7 +964,7 @@ void WindowBaseEcoreWl2::Initialize(PositionSize positionSize, Any surface, bool
 
   // Register Selection event - clipboard selection
   mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, this));
-  mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, this));
+  mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, EcoreEventDataReceive, this));
 
   // Register Effect Start/End event
   mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_EFFECT_START, EcoreEventEffectStart, this));