-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Starting from Tizen 8.0, the cbhm package is not distributed. Therefore, support the platform's clipboard feature using the ecore_wl2 APIs. ecore_wl2_offer_receive() and ecore_wl2_offer_mimes_get() can be found in Tizen 5.5 rootstrap, but are not distributed in the actual ecore_wl2 header. Therefore, this feature is supported starting from tizen 6.5. This feature supports TV profiles of Tizen 6.5 or higher. However, in Tizen 6.0 and below, copy&paste is supported only for data within the application.
- Loading branch information
Showing
5 changed files
with
261 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
// Copyright 2024 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "tizen_clipboard.h" | ||
|
||
#include "flutter/shell/platform/tizen/logger.h" | ||
#include "flutter/shell/platform/tizen/tizen_window.h" | ||
#include "flutter/shell/platform/tizen/tizen_window_ecore_wl2.h" | ||
|
||
namespace flutter { | ||
|
||
namespace { | ||
|
||
constexpr char kMimeTypeTextPlain[] = "text/plain;charset=utf-8"; | ||
|
||
} // namespace | ||
|
||
TizenClipboard::TizenClipboard(TizenViewBase* view) { | ||
if (auto* window = dynamic_cast<TizenWindowEcoreWl2*>(view)) { | ||
auto* ecore_wl2_window = | ||
static_cast<Ecore_Wl2_Window*>(window->GetNativeHandle()); | ||
display_ = ecore_wl2_window_display_get(ecore_wl2_window); | ||
} else { | ||
display_ = ecore_wl2_connected_display_get(NULL); | ||
} | ||
|
||
send_handler = ecore_event_handler_add( | ||
ECORE_WL2_EVENT_DATA_SOURCE_SEND, | ||
[](void* data, int type, void* event) -> Eina_Bool { | ||
auto* self = reinterpret_cast<TizenClipboard*>(data); | ||
self->SendData(event); | ||
return ECORE_CALLBACK_PASS_ON; | ||
}, | ||
this); | ||
receive_handler = ecore_event_handler_add( | ||
ECORE_WL2_EVENT_OFFER_DATA_READY, | ||
[](void* data, int type, void* event) -> Eina_Bool { | ||
auto* self = reinterpret_cast<TizenClipboard*>(data); | ||
self->ReceiveData(event); | ||
return ECORE_CALLBACK_PASS_ON; | ||
}, | ||
this); | ||
} | ||
|
||
TizenClipboard::~TizenClipboard() { | ||
ecore_event_handler_del(send_handler); | ||
ecore_event_handler_del(receive_handler); | ||
} | ||
|
||
void TizenClipboard::SendData(void* event) { | ||
auto* send_event = reinterpret_cast<Ecore_Wl2_Event_Data_Source_Send*>(event); | ||
if (!send_event->type || strcmp(send_event->type, kMimeTypeTextPlain)) { | ||
FT_LOG(Error) << "Invaild mime type."; | ||
return; | ||
} | ||
|
||
if (send_event->serial != selection_serial_) { | ||
FT_LOG(Error) << "The serial doesn't match."; | ||
return; | ||
} | ||
|
||
write(send_event->fd, data_.c_str(), data_.length()); | ||
close(send_event->fd); | ||
} | ||
|
||
void TizenClipboard::ReceiveData(void* event) { | ||
auto* ready_event = | ||
reinterpret_cast<Ecore_Wl2_Event_Offer_Data_Ready*>(event); | ||
if (ready_event->data == nullptr || ready_event->len < 1) { | ||
FT_LOG(Info) << "No data available."; | ||
if (on_data_callback_) { | ||
on_data_callback_(""); | ||
on_data_callback_ = nullptr; | ||
} | ||
return; | ||
} | ||
|
||
if (ready_event->offer != selection_offer_) { | ||
FT_LOG(Error) << "The offer doesn't match."; | ||
if (on_data_callback_) { | ||
on_data_callback_(std::nullopt); | ||
on_data_callback_ = nullptr; | ||
} | ||
return; | ||
} | ||
|
||
size_t data_length = strlen(ready_event->data); | ||
size_t buffer_size = ready_event->len; | ||
std::string content; | ||
|
||
if (data_length < buffer_size) { | ||
content.append(ready_event->data, data_length); | ||
} else { | ||
content.append(ready_event->data, buffer_size); | ||
} | ||
|
||
if (on_data_callback_) { | ||
on_data_callback_(content); | ||
on_data_callback_ = nullptr; | ||
} | ||
} | ||
|
||
void TizenClipboard::SetData(const std::string& data) { | ||
data_ = data; | ||
|
||
const char* mime_types[3]; | ||
mime_types[0] = kMimeTypeTextPlain; | ||
// TODO(jsuya): There is an issue where ECORE_WL2_EVENT_DATA_SOURCE_SEND event | ||
// does not work properly even if ecore_wl2_dnd_selection_set() is called in | ||
// Tizen 6.5 or lower. Therefore, add empty mimetype for event call from the | ||
// cbhm module. Since it works normally from Tizen 8.0, this part may be | ||
// modified in the future. | ||
mime_types[1] = ""; | ||
mime_types[2] = nullptr; | ||
|
||
Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display_); | ||
selection_serial_ = ecore_wl2_dnd_selection_set(input, mime_types); | ||
ecore_wl2_display_flush(display_); | ||
} | ||
|
||
bool TizenClipboard::GetData(ClipboardCallback on_data_callback) { | ||
on_data_callback_ = std::move(on_data_callback); | ||
|
||
Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display_); | ||
selection_offer_ = ecore_wl2_dnd_selection_get(input); | ||
|
||
if (!selection_offer_) { | ||
FT_LOG(Error) << "ecore_wl2_dnd_selection_get() failed."; | ||
return false; | ||
} | ||
|
||
ecore_wl2_offer_receive(selection_offer_, | ||
const_cast<char*>(kMimeTypeTextPlain)); | ||
return true; | ||
} | ||
|
||
bool TizenClipboard::HasStrings() { | ||
Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display_); | ||
selection_offer_ = ecore_wl2_dnd_selection_get(input); | ||
|
||
if (!selection_offer_) { | ||
FT_LOG(Error) << "ecore_wl2_dnd_selection_get() failed."; | ||
return false; | ||
} | ||
|
||
Eina_Array* available_types = ecore_wl2_offer_mimes_get(selection_offer_); | ||
unsigned int type_count = eina_array_count(available_types); | ||
|
||
for (unsigned int i = 0; i < type_count; ++i) { | ||
auto* available_type = | ||
static_cast<char*>(eina_array_data_get(available_types, i)); | ||
if (!strcmp(kMimeTypeTextPlain, available_type)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2024 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef EMBEDDER_TIZEN_CLIPBOARD_H_ | ||
#define EMBEDDER_TIZEN_CLIPBOARD_H_ | ||
|
||
#define EFL_BETA_API_SUPPORT | ||
#include <Ecore_Wl2.h> | ||
|
||
#include <functional> | ||
#include <optional> | ||
#include <string> | ||
|
||
#include "flutter/shell/platform/tizen/tizen_view_base.h" | ||
|
||
namespace flutter { | ||
|
||
class TizenClipboard { | ||
public: | ||
using ClipboardCallback = | ||
std::function<void(std::optional<std::string> data)>; | ||
|
||
TizenClipboard(TizenViewBase* view); | ||
virtual ~TizenClipboard(); | ||
|
||
void SetData(const std::string& data); | ||
bool GetData(ClipboardCallback on_data_callback); | ||
bool HasStrings(); | ||
|
||
private: | ||
void SendData(void* event); | ||
void ReceiveData(void* event); | ||
|
||
std::string data_; | ||
ClipboardCallback on_data_callback_; | ||
uint32_t selection_serial_ = 0; | ||
Ecore_Wl2_Offer* selection_offer_ = nullptr; | ||
Ecore_Wl2_Display* display_ = nullptr; | ||
Ecore_Event_Handler* send_handler = nullptr; | ||
Ecore_Event_Handler* receive_handler = nullptr; | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // EMBEDDER_TIZEN_CLIPBOARD_H_ |