[Tizen] Fix clipboard paste issue
[platform/core/uifw/dali-adaptor.git] / dali / internal / clipboard / tizen-wayland / clipboard-impl-ecore-wl.cpp
index 15aa6a5..c3dc462 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -58,6 +58,7 @@ struct Clipboard::Impl
 {
   Impl()
   {
+#ifdef DALI_ELDBUS_AVAILABLE
     Eldbus_Object* eldbus_obj;
     eldbus_init();
     cbhm_conn    = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
@@ -65,17 +66,21 @@ struct Clipboard::Impl
     eldbus_proxy = eldbus_proxy_get(eldbus_obj, CBHM_DBUS_INTERFACE);
     eldbus_name_owner_changed_callback_add(cbhm_conn, CBHM_DBUS_INTERFACE, NULL, cbhm_conn, EINA_TRUE);
     eldbus_proxy_signal_handler_add(eldbus_proxy, "ItemClicked", _on_item_clicked, this);
+#endif // DALI_ELDBUS_AVAILABLE
     mVisible           = false;
     mIsFirstTimeHidden = true;
   }
 
   ~Impl()
   {
+#ifdef DALI_ELDBUS_AVAILABLE
     if(cbhm_conn)
       eldbus_connection_unref(cbhm_conn);
     eldbus_shutdown();
+#endif // DALI_ELDBUS_AVAILABLE
   }
 
+#ifdef DALI_ELDBUS_AVAILABLE
   Eldbus_Proxy* cbhm_proxy_get()
   {
     return eldbus_proxy;
@@ -85,6 +90,7 @@ struct Clipboard::Impl
   {
     return cbhm_conn;
   }
+#endif // DALI_ELDBUS_AVAILABLE
 
   void SetItem(const std::string& itemData)
   {
@@ -109,47 +115,50 @@ struct Clipboard::Impl
 
 #ifdef ECORE_WAYLAND2
     Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(ecore_wl2_connected_display_get(NULL));
-    ecore_wl2_dnd_selection_set(input, types);
+    mSerial                = ecore_wl2_dnd_selection_set(input, types);
 #else
-    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
 
-    int         len_buf      = mSendBuffer.length();
+    if(ev->serial != mSerial)
+    {
+      return;
+    }
+
+    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)
     {
@@ -160,26 +169,28 @@ 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()
   {
+#ifdef DALI_ELDBUS_AVAILABLE
     Eldbus_Message *reply, *req;
     const char *    errname = NULL, *errmsg = NULL;
-    int             count = -1;
+#endif // DALI_ELDBUS_AVAILABLE
+    int count = -1;
 
+#ifdef DALI_ELDBUS_AVAILABLE
     if(!(req = eldbus_proxy_method_call_new(eldbus_proxy, "CbhmGetCount")))
     {
       DALI_LOG_ERROR("Failed to create method call on org.freedesktop.DBus.Properties.Get");
@@ -213,12 +224,15 @@ struct Clipboard::Impl
     eldbus_message_unref(req);
     eldbus_message_unref(reply);
     DALI_LOG_ERROR("cbhm item count(%d)", count);
+#endif // DALI_ELDBUS_AVAILABLE
     return count;
   }
 
   void ShowClipboard()
   {
+#ifdef DALI_ELDBUS_AVAILABLE
     eldbus_proxy_call(cbhm_proxy_get(), "CbhmShow", NULL, NULL, -1, "s", "0");
+#endif // DALI_ELDBUS_AVAILABLE
     mIsFirstTimeHidden = true;
     mVisible           = true;
   }
@@ -230,7 +244,9 @@ struct Clipboard::Impl
       mIsFirstTimeHidden = false;
       return;
     }
+#ifdef DALI_ELDBUS_AVAILABLE
     eldbus_proxy_call(cbhm_proxy_get(), "CbhmHide", NULL, NULL, -1, "");
+#endif // DALI_ELDBUS_AVAILABLE
     mIsFirstTimeHidden = false;
     mVisible           = false;
   }
@@ -240,6 +256,7 @@ struct Clipboard::Impl
     return mVisible;
   }
 
+#ifdef DALI_ELDBUS_AVAILABLE
   static void _on_item_clicked(void* data, const Eldbus_Message* msg EINA_UNUSED)
   {
     static_cast<Clipboard::Impl*>(data)->RequestItem();
@@ -247,10 +264,12 @@ struct Clipboard::Impl
 
   Eldbus_Proxy*      eldbus_proxy;
   Eldbus_Connection* cbhm_conn;
+#endif // DALI_ELDBUS_AVAILABLE
 
   std::string mSendBuffer;
   bool        mVisible;
   bool        mIsFirstTimeHidden;
+  uint32_t    mSerial{0u};
 };
 
 Clipboard::Clipboard(Impl* impl)
@@ -288,6 +307,20 @@ Dali::Clipboard Clipboard::Get()
   return clipboard;
 }
 
+bool Clipboard::IsAvailable()
+{
+  Dali::SingletonService service(SingletonService::Get());
+  if(service)
+  {
+    Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::Clipboard));
+    if(handle)
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
 bool Clipboard::SetItem(const std::string& itemData)
 {
   mImpl->SetItem(itemData);
@@ -307,7 +340,8 @@ void Clipboard::RequestItem()
  */
 unsigned int Clipboard::NumberOfItems()
 {
-  return mImpl->GetCount();
+  int count = mImpl->GetCount();
+  return (count < 0 ? 0 : count);
 }
 
 void Clipboard::ShowClipboard()
@@ -325,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