From 56821877427fe6f9317eeef66de548130ec3374f Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Wed, 31 May 2023 19:46:23 +0900 Subject: [PATCH] Add copy & paste to clipboard 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 | 15 +++++-- .../clipboard/generic/clipboard-impl-generic.cpp | 7 ++- .../tizen-wayland/clipboard-impl-ecore-wl.cpp | 50 +++++++++++----------- .../clipboard/ubuntu-x11/clipboard-impl-x.cpp | 30 ++++++------- .../window-system/common/event-handler.cpp | 24 ++++++++--- .../ecore-wl2/window-base-ecore-wl2.cpp | 2 +- 6 files changed, 77 insertions(+), 51 deletions(-) diff --git a/dali/internal/clipboard/common/clipboard-impl.h b/dali/internal/clipboard/common/clipboard-impl.h index ec10c59..eeaae38 100644 --- a/dali/internal/clipboard/common/clipboard-impl.h +++ b/dali/internal/clipboard/common/clipboard-impl.h @@ -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 diff --git a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp index 43713af..74b911e 100644 --- a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp +++ b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp @@ -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 diff --git a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp index 1cd452b..c3dc462 100644 --- a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp +++ b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp @@ -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(*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(event); #else - Ecore_Wl_Event_Data_Source_Send* ev = reinterpret_cast(event); + Ecore_Wl_Event_Data_Source_Send* ev = reinterpret_cast(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(event); + Ecore_Wl2_Event_Offer_Data_Ready* ev = reinterpret_cast(event); #else Ecore_Wl_Event_Selection_Data_Ready* ev = reinterpret_cast(event); #endif - - return reinterpret_cast(ev->data); + data = reinterpret_cast(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 diff --git a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp index 070974f..807f9db 100644 --- a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp +++ b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp @@ -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(event); +} - Ecore_X_Selection_Data* selectionData = static_cast(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(event); - return (reinterpret_cast(selectionData->data)); - } + Ecore_X_Selection_Data* selectionData = static_cast(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(selectionData->data); + length = selectionData->length; } } - return NULL; } } // namespace Adaptor diff --git a/dali/internal/window-system/common/event-handler.cpp b/dali/internal/window-system/common/event-handler.cpp index cf1fb78..397fcb3 100644 --- a/dali/internal/window-system/common/event-handler.cpp +++ b/dali/internal/window-system/common/event-handler.cpp @@ -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(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); } } diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp index 812ecfe..278d13b 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp @@ -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)); -- 2.7.4