summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Bialogonski <adam.b@samsung.com>2024-06-14 09:33:10 +0100
committerAdam Bialogonski <adam.b@samsung.com>2024-06-14 09:33:10 +0100
commit5d68e3ce8353a047929eb39945094fc57f3d870e (patch)
tree34bb7d94248b26a518c6c81ca0f9489b7ad113f2
parent407aa99cd1a18e5667370eb8f428dabd0511ceb5 (diff)
parent0b0845f2e84aafa2d10e4e62b17f8751e5db2369 (diff)
downloaddali-adaptor-master.tar.gz
dali-adaptor-master.tar.bz2
dali-adaptor-master.zip
[dali_2.3.28] Merge branch 'devel/master'HEADmaster
Change-Id: Idc13f1b9a14d50de4696694c3f945d56df189d88
-rw-r--r--dali/internal/adaptor/tizen-wayland/framework-tizen.cpp76
-rw-r--r--dali/internal/application-model/normal/appmodel-normal-tizen.cpp77
-rw-r--r--dali/internal/application-model/watch/appmodel-watch-tizen.cpp97
-rw-r--r--dali/internal/application-model/widget/appmodel-widget-tizen.cpp81
-rw-r--r--dali/internal/clipboard/common/clipboard-impl.h6
-rw-r--r--dali/internal/clipboard/generic/clipboard-impl-generic.cpp16
-rw-r--r--dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp296
-rw-r--r--dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp120
-rw-r--r--dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp24
-rw-r--r--dali/internal/graphics/gles-impl/gles-graphics-program.cpp6
-rw-r--r--dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp3
-rw-r--r--dali/public-api/dali-adaptor-version.cpp2
-rw-r--r--packaging/dali-adaptor.spec2
13 files changed, 535 insertions, 271 deletions
diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp
index 8a24537d1..d0154dd77 100644
--- a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp
+++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -42,8 +42,8 @@ namespace Adaptor
{
namespace
{
-constexpr char const* const kApplicationNamePrefix = "libdali2-adaptor-application-";
-constexpr char const* const kApplicationNamePostfix = ".so";
+constexpr char const* const kApplicationNamePrefix = "libdali2-adaptor-application-";
+constexpr char const* const kApplicationNamePostfix = ".so";
std::string MakePluginName(const char* appModelName)
{
@@ -72,7 +72,7 @@ struct FrameworkTizen::Impl
Impl(void* data, Type type, bool isUiThread)
{
mFramework = static_cast<FrameworkTizen*>(data);
- mUiThread = isUiThread;
+ mUiThread = isUiThread;
#ifndef APPCORE_WATCH_AVAILABLE
if(type == WATCH)
{
@@ -116,27 +116,27 @@ struct FrameworkTizen::Impl
mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
if(mHandle == nullptr)
{
- print_log(DLOG_INFO, "DALI", "error : %s", dlerror() );
+ print_log(DLOG_INFO, "DALI", "error : %s", dlerror());
return;
}
createFunctionPtr = reinterpret_cast<CreateFunction>(dlsym(mHandle, "Create"));
- if(createFunctionPtr == nullptr)
+ if(DALI_UNLIKELY(createFunctionPtr == nullptr))
{
DALI_LOG_ERROR("createFunctionPtr is null\n");
}
destroyFunctionPtr = reinterpret_cast<DestroyFunction>(dlsym(mHandle, "Destroy"));
- if(destroyFunctionPtr == nullptr)
+ if(DALI_UNLIKELY(destroyFunctionPtr == nullptr))
{
DALI_LOG_ERROR("destroyFunctionPtr is null\n");
}
appMainFunctionPtr = reinterpret_cast<AppMainFunction>(dlsym(mHandle, "AppMain"));
- if(appMainFunctionPtr == nullptr)
+ if(DALI_UNLIKELY(appMainFunctionPtr == nullptr))
{
DALI_LOG_ERROR("appMainFunctionPtr is null\n");
}
appExitFunctionPtr = reinterpret_cast<AppExitFunction>(dlsym(mHandle, "AppExit"));
- if(appExitFunctionPtr == nullptr)
+ if(DALI_UNLIKELY(appExitFunctionPtr == nullptr))
{
DALI_LOG_ERROR("appExitFunctionPtr is null\n");
}
@@ -146,10 +146,14 @@ struct FrameworkTizen::Impl
{
if(mHandle != NULL)
{
- if(destroyFunctionPtr != NULL)
+ if(DALI_LIKELY(destroyFunctionPtr != nullptr))
{
destroyFunctionPtr(baseAppPtr);
}
+ else
+ {
+ DALI_LOG_ERROR("destroyFunctionPtr is null\n");
+ }
dlclose(mHandle);
}
@@ -163,10 +167,14 @@ struct FrameworkTizen::Impl
return TIZEN_ERROR_NOT_SUPPORTED;
}
- if(createFunctionPtr != nullptr)
+ if(DALI_LIKELY(createFunctionPtr != nullptr))
{
baseAppPtr = createFunctionPtr();
}
+ else
+ {
+ DALI_LOG_ERROR("createFunctionPtr is null\n");
+ }
if(baseAppPtr == nullptr)
{
@@ -175,10 +183,15 @@ struct FrameworkTizen::Impl
}
int ret = 0;
- if(appMainFunctionPtr != nullptr)
+ if(DALI_LIKELY(appMainFunctionPtr != nullptr))
{
ret = appMainFunctionPtr(mUiThread, mFramework, baseAppPtr);
}
+ else
+ {
+ DALI_LOG_ERROR("appMainFunctionPtr is null\n");
+ ret = TIZEN_ERROR_NOT_SUPPORTED;
+ }
return ret;
}
@@ -189,7 +202,14 @@ struct FrameworkTizen::Impl
DALI_LOG_ERROR("baseAppPtr is null\n");
return;
}
- appExitFunctionPtr(baseAppPtr);
+ if(DALI_LIKELY(appExitFunctionPtr != nullptr))
+ {
+ appExitFunctionPtr(baseAppPtr);
+ }
+ else
+ {
+ DALI_LOG_ERROR("appExitFunctionPtr is null\n");
+ }
}
void SetLanguage(const std::string& language)
@@ -234,26 +254,26 @@ struct FrameworkTizen::Impl
return mRegion;
}
- using CreateFunction = void* (*)();
- using DestroyFunction = void (*)(void*);
+ using CreateFunction = void* (*)();
+ using DestroyFunction = void (*)(void*);
- using AppMainFunction = int (*)(bool, void*, void*);
- using AppExitFunction = void (*)(void*);
+ using AppMainFunction = int (*)(bool, void*, void*);
+ using AppExitFunction = void (*)(void*);
- void* mHandle{nullptr};
- CreateFunction createFunctionPtr;
- DestroyFunction destroyFunctionPtr;
- AppMainFunction appMainFunctionPtr;
- AppExitFunction appExitFunctionPtr;
- void* baseAppPtr = nullptr;
- bool mUiThread;
+ void* mHandle{nullptr};
+ CreateFunction createFunctionPtr{nullptr};
+ DestroyFunction destroyFunctionPtr{nullptr};
+ AppMainFunction appMainFunctionPtr{nullptr};
+ AppExitFunction appExitFunctionPtr{nullptr};
+ void* baseAppPtr{nullptr};
+ bool mUiThread;
// Data
- Type mApplicationType;
- std::string mLanguage{};
- std::string mRegion{};
+ Type mApplicationType;
+ std::string mLanguage{};
+ std::string mRegion{};
- FrameworkTizen* mFramework;
+ FrameworkTizen* mFramework{nullptr};
private:
// Undefined
diff --git a/dali/internal/application-model/normal/appmodel-normal-tizen.cpp b/dali/internal/application-model/normal/appmodel-normal-tizen.cpp
index 80b75d01e..8d634f722 100644
--- a/dali/internal/application-model/normal/appmodel-normal-tizen.cpp
+++ b/dali/internal/application-model/normal/appmodel-normal-tizen.cpp
@@ -28,8 +28,8 @@
#include <glib.h>
#include <system_info.h>
#include <system_settings.h>
-#include <app_core_ui_base.hh>
#include <app_core_task_base.hh>
+#include <app_core_ui_base.hh>
#include <app_event_internal.hh>
// CONDITIONAL INCLUDES
@@ -39,9 +39,9 @@
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
-#include <dali/internal/system/linux/dali-ecore.h>
#include <dali/internal/adaptor/common/framework.h>
#include <dali/internal/adaptor/tizen-wayland/framework-tizen.h>
+#include <dali/internal/system/linux/dali-ecore.h>
using namespace tizen_cpp;
@@ -51,19 +51,22 @@ namespace Internal
{
namespace Adaptor
{
-extern "C" DALI_ADAPTOR_API AppModelNormal* Create() {
+extern "C" DALI_ADAPTOR_API AppModelNormal* Create()
+{
return new AppModelNormal(false);
}
-extern "C" DALI_ADAPTOR_API void Destroy(void* p) {
+extern "C" DALI_ADAPTOR_API void Destroy(void* p)
+{
AppModelNormal* appNormal = static_cast<AppModelNormal*>(p);
delete appNormal;
}
-extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) {
+extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData)
+{
AppModelNormal* appNormal = static_cast<AppModelNormal*>(pData);
- int ret = 0;
- if (appNormal != nullptr)
+ int ret = 0;
+ if(appNormal != nullptr)
{
ret = appNormal->AppMain(data);
}
@@ -74,7 +77,8 @@ extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData
return ret;
}
-extern "C" DALI_ADAPTOR_API void AppExit(AppModelNormal* p) {
+extern "C" DALI_ADAPTOR_API void AppExit(AppModelNormal* p)
+{
p->AppExit();
}
@@ -87,7 +91,6 @@ Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::No
namespace AppCore
{
-
typedef enum
{
LOW_MEMORY, //< The low memory event
@@ -100,7 +103,7 @@ typedef enum
} AppEventType;
static int AppEventConverter[APPCORE_BASE_EVENT_MAX] =
-{
+ {
[LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
[LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
[LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
@@ -149,22 +152,19 @@ int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType,
AppEventHandlerPtr handler;
handler = static_cast<AppEventHandlerPtr>(calloc(1, sizeof(struct AppEventHandler)));
- if(!handler)
+ if(DALI_UNLIKELY(!handler))
{
- DALI_LOG_ERROR("failed to create handler");
+ DALI_LOG_ERROR("failed to create handler. calloc size : %zu\n", sizeof(struct AppEventHandler));
return TIZEN_ERROR_UNKNOWN;
}
- else
- {
- handler->type = eventType;
- handler->cb = callback;
- handler->data = userData;
- handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
+ handler->type = eventType;
+ handler->cb = callback;
+ handler->data = userData;
+ handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
- *eventHandler = handler;
+ *eventHandler = handler;
- return TIZEN_ERROR_NONE;
- }
+ return TIZEN_ERROR_NONE;
}
DeviceStatus::Memory::Status GetMemoryStatus(app_event_low_memory_status_e memoryStatus)
@@ -231,7 +231,7 @@ DeviceStatus::Orientation::Status GetOrientationStatus(app_device_orientation_e
}
}
}
-}
+} // namespace AppCore
struct DALI_ADAPTOR_API AppModelNormal::Impl
{
@@ -586,8 +586,8 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
private:
static void OnLanguageChanged(app_event_info_h event_info, void* user_data)
{
- auto* context = static_cast<UiAppContext*>(user_data);
- auto* framework = context->mFramework;
+ auto* context = static_cast<UiAppContext*>(user_data);
+ auto* framework = context->mFramework;
Framework::Observer* observer = &framework->GetObserver();
char* lang = nullptr;
@@ -606,8 +606,8 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
static void OnRegionFormatChanged(app_event_info_h event_info, void* user_data)
{
- auto* context = static_cast<UiAppContext*>(user_data);
- auto* framework = context->mFramework;
+ auto* context = static_cast<UiAppContext*>(user_data);
+ auto* framework = context->mFramework;
Framework::Observer* observer = &framework->GetObserver();
char* region = nullptr;
@@ -626,8 +626,8 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
static void OnLowBattery(app_event_info_h event_info, void* user_data)
{
- auto* context = static_cast<UiAppContext*>(user_data);
- auto* framework = context->mFramework;
+ auto* context = static_cast<UiAppContext*>(user_data);
+ auto* framework = context->mFramework;
Framework::Observer* observer = &framework->GetObserver();
app_event_low_battery_status_e status;
@@ -645,8 +645,8 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
static void OnLowMemory(app_event_info_h event_info, void* user_data)
{
- auto* context = static_cast<UiAppContext*>(user_data);
- auto* framework = context->mFramework;
+ auto* context = static_cast<UiAppContext*>(user_data);
+ auto* framework = context->mFramework;
Framework::Observer* observer = &framework->GetObserver();
app_event_low_memory_status_e status;
@@ -664,8 +664,8 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
static void OnDeviceOrientationChanged(app_event_info_h event_info, void* user_data)
{
- auto* context = static_cast<UiAppContext*>(user_data);
- auto* framework = context->mFramework;
+ auto* context = static_cast<UiAppContext*>(user_data);
+ auto* framework = context->mFramework;
Framework::Observer* observer = &framework->GetObserver();
app_device_orientation_e status;
@@ -773,9 +773,9 @@ struct DALI_ADAPTOR_API AppModelNormal::Impl
{
}
- AppModelNormal* mAppModelNormal;
- std::unique_ptr<UiAppContext> mUiAppContext{nullptr};
- bool mUseUiThread{false};
+ AppModelNormal* mAppModelNormal;
+ std::unique_ptr<UiAppContext> mUiAppContext{nullptr};
+ bool mUseUiThread{false};
};
AppModelNormal::AppModelNormal(bool isUiThread)
@@ -798,7 +798,6 @@ void AppModelNormal::AppExit()
mImpl->AppExit();
}
-} // Adaptor
-} // Internal
-} // Dali
-
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
diff --git a/dali/internal/application-model/watch/appmodel-watch-tizen.cpp b/dali/internal/application-model/watch/appmodel-watch-tizen.cpp
index b29c3474d..53a5b9a4a 100644
--- a/dali/internal/application-model/watch/appmodel-watch-tizen.cpp
+++ b/dali/internal/application-model/watch/appmodel-watch-tizen.cpp
@@ -25,18 +25,18 @@
// EXTERNAL INCLUDES
#include <app_common.h>
+#include <app_control_internal.h>
#include <appcore_base.h>
-#include <tizen.h>
#include <bundle.h>
-#include <dlog.h>
#include <bundle_internal.h>
-#include <app_control_internal.h>
+#include <dlog.h>
+#include <tizen.h>
// INTERNAL INCLUDES
-#include <dali/public-api/watch/watch-time.h>
#include <dali/integration-api/debug.h>
#include <dali/internal/adaptor/common/framework.h>
#include <dali/internal/adaptor/tizen-wayland/framework-tizen.h>
+#include <dali/public-api/watch/watch-time.h>
namespace Dali
{
@@ -44,19 +44,22 @@ namespace Internal
{
namespace Adaptor
{
-extern "C" DALI_ADAPTOR_API AppModelWatch* Create() {
+extern "C" DALI_ADAPTOR_API AppModelWatch* Create()
+{
return new AppModelWatch;
}
-extern "C" DALI_ADAPTOR_API void Destroy(void* p) {
+extern "C" DALI_ADAPTOR_API void Destroy(void* p)
+{
AppModelWatch* appWatch = static_cast<AppModelWatch*>(p);
delete appWatch;
}
-extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) {
+extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData)
+{
AppModelWatch* appWatch = static_cast<AppModelWatch*>(pData);
- int ret = 0;
- if (appWatch != nullptr)
+ int ret = 0;
+ if(appWatch != nullptr)
{
ret = appWatch->AppMain(data);
}
@@ -67,7 +70,8 @@ extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData
return ret;
}
-extern "C" DALI_ADAPTOR_API void AppExit(AppModelWatch* p) {
+extern "C" DALI_ADAPTOR_API void AppExit(AppModelWatch* p)
+{
p->AppExit();
}
@@ -85,7 +89,7 @@ typedef enum
} AppEventType;
static int AppEventConverter[APPCORE_BASE_EVENT_MAX] =
-{
+ {
[LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
[LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
[LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
@@ -134,27 +138,23 @@ int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType,
AppEventHandlerPtr handler;
handler = static_cast<AppEventHandlerPtr>(calloc(1, sizeof(struct AppEventHandler)));
- if(!handler)
+ if(DALI_UNLIKELY(!handler))
{
- DALI_LOG_ERROR("failed to create handler");
+ DALI_LOG_ERROR("failed to create handler. calloc size : %zu\n", sizeof(struct AppEventHandler));
return TIZEN_ERROR_UNKNOWN;
}
- else
- {
- handler->type = eventType;
- handler->cb = callback;
- handler->data = userData;
- handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
+ handler->type = eventType;
+ handler->cb = callback;
+ handler->data = userData;
+ handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
- *eventHandler = handler;
+ *eventHandler = handler;
- return TIZEN_ERROR_NONE;
- }
-}
+ return TIZEN_ERROR_NONE;
}
+} // namespace AppCoreWatch
struct DALI_ADAPTOR_API AppModelWatch::Impl
{
-
#ifdef APPCORE_WATCH_AVAILABLE
static bool WatchAppCreate(int width, int height, void* data)
{
@@ -164,7 +164,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void WatchAppTimeTick(watch_time_h time, void* data)
{
Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
- WatchTime curTime(time);
+ WatchTime curTime(time);
observer->OnTimeTick(curTime);
}
@@ -172,7 +172,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void WatchAppAmbientTick(watch_time_h time, void* data)
{
Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
- WatchTime curTime(time);
+ WatchTime curTime(time);
observer->OnAmbientTick(curTime);
}
@@ -186,9 +186,9 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void WatchAppControl(app_control_h app_control, void* data)
{
- FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
- Framework::Observer* observer = &framework->GetObserver();
- bundle* bundleData = NULL;
+ FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
+ Framework::Observer* observer = &framework->GetObserver();
+ bundle* bundleData = NULL;
app_control_to_bundle(app_control, &bundleData);
ProcessBundle(framework, bundleData);
@@ -243,8 +243,8 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void AppLanguageChanged(AppCoreWatch::AppEventInfoPtr event, void* data)
{
- FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
- Framework::Observer* observer = &framework->GetObserver();
+ FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
+ Framework::Observer* observer = &framework->GetObserver();
if(event && event->value)
{
@@ -259,8 +259,8 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void AppRegionChanged(AppCoreWatch::AppEventInfoPtr event, void* data)
{
- FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
- Framework::Observer* observer = &framework->GetObserver();
+ FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
+ Framework::Observer* observer = &framework->GetObserver();
if(event && event->value)
{
@@ -275,7 +275,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void AppBatteryLow(AppCoreWatch::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::Status::NORMAL;
@@ -300,7 +300,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void AppMemoryLow(AppCoreWatch::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::Status::NORMAL;
@@ -330,7 +330,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
static void AppDeviceOrientationChanged(AppCoreWatch::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Orientation::Status result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0;
@@ -368,7 +368,7 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
int ret = TIZEN_ERROR_NOT_SUPPORTED;
#ifdef APPCORE_WATCH_AVAILABLE
- FrameworkTizen* mFramework = static_cast<FrameworkTizen*>(data);
+ FrameworkTizen* mFramework = static_cast<FrameworkTizen*>(data);
mWatchCallback.create = WatchAppCreate;
mWatchCallback.app_control = WatchAppControl;
mWatchCallback.terminate = WatchAppTerminate;
@@ -397,23 +397,25 @@ struct DALI_ADAPTOR_API AppModelWatch::Impl
#endif
}
-
Impl(void* data)
- : handlers{nullptr, nullptr, nullptr, nullptr, nullptr}
+ : handlers
+ {
+ nullptr, nullptr, nullptr, nullptr, nullptr
+ }
#ifdef APPCORE_WATCH_AVAILABLE
,
- mWatchCallback()
+ mWatchCallback()
#endif
{
- mAppModelWatch = static_cast<AppModelWatch*>(data);
+ mAppModelWatch = static_cast<AppModelWatch*>(data);
}
~Impl()
{
}
- AppModelWatch* mAppModelWatch;
- AppCoreWatch::AppEventHandlerPtr handlers[5];
+ AppModelWatch* mAppModelWatch;
+ AppCoreWatch::AppEventHandlerPtr handlers[5];
#ifdef APPCORE_WATCH_AVAILABLE
watch_app_lifecycle_callback_s mWatchCallback;
#endif
@@ -429,7 +431,7 @@ AppModelWatch::~AppModelWatch()
delete mImpl;
}
-int AppModelWatch::AppMain(void *data)
+int AppModelWatch::AppMain(void* data)
{
return mImpl->AppMain(data);
}
@@ -439,7 +441,6 @@ void AppModelWatch::AppExit()
mImpl->AppExit();
}
-} // Adaptor
-} // Internal
-} // Dali
-
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
diff --git a/dali/internal/application-model/widget/appmodel-widget-tizen.cpp b/dali/internal/application-model/widget/appmodel-widget-tizen.cpp
index efbef24dc..b30ff7a3d 100644
--- a/dali/internal/application-model/widget/appmodel-widget-tizen.cpp
+++ b/dali/internal/application-model/widget/appmodel-widget-tizen.cpp
@@ -19,14 +19,14 @@
#include <dali/internal/application-model/widget/appmodel-widget-tizen.h>
// EXTERNAL INCLUDES
-#include <tizen.h>
#include <bundle.h>
#include <bundle_internal.h>
#include <dlog.h>
-#include <widget_base.h>
#include <glib.h>
#include <system_info.h>
#include <system_settings.h>
+#include <tizen.h>
+#include <widget_base.h>
#ifdef DALI_ELDBUS_AVAILABLE
#include <Eldbus.h>
@@ -35,9 +35,9 @@
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
#include <dali/integration-api/trace.h>
-#include <dali/internal/system/linux/dali-ecore.h>
#include <dali/internal/adaptor/common/framework.h>
#include <dali/internal/adaptor/tizen-wayland/framework-tizen.h>
+#include <dali/internal/system/linux/dali-ecore.h>
#define DEBUG_PRINTF(fmt, arg...) LOGD(" " fmt, ##arg)
@@ -47,20 +47,22 @@ namespace Internal
{
namespace Adaptor
{
-
-extern "C" DALI_ADAPTOR_API AppModelWidget* Create() {
+extern "C" DALI_ADAPTOR_API AppModelWidget* Create()
+{
return new AppModelWidget();
}
-extern "C" DALI_ADAPTOR_API void Destroy(void* p) {
+extern "C" DALI_ADAPTOR_API void Destroy(void* p)
+{
AppModelWidget* appWidget = static_cast<AppModelWidget*>(p);
delete appWidget;
}
-extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) {
+extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData)
+{
AppModelWidget* appWidget = static_cast<AppModelWidget*>(pData);
- int ret = 0;
- if (appWidget != nullptr)
+ int ret = 0;
+ if(appWidget != nullptr)
{
ret = appWidget->AppMain(data);
}
@@ -71,7 +73,8 @@ extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData
return ret;
}
-extern "C" DALI_ADAPTOR_API void AppExit(AppModelWidget* p) {
+extern "C" DALI_ADAPTOR_API void AppExit(AppModelWidget* p)
+{
p->AppExit();
}
@@ -97,7 +100,7 @@ typedef enum
} AppEventType;
static int AppEventConverter[APPCORE_BASE_EVENT_MAX] =
-{
+ {
[LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
[LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
[LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
@@ -146,24 +149,21 @@ int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType,
AppEventHandlerPtr handler;
handler = static_cast<AppEventHandlerPtr>(calloc(1, sizeof(struct AppEventHandler)));
- if(!handler)
+ if(DALI_UNLIKELY(!handler))
{
- DALI_LOG_ERROR("failed to create handler");
+ DALI_LOG_ERROR("failed to create handler. calloc size : %zu\n", sizeof(struct AppEventHandler));
return TIZEN_ERROR_UNKNOWN;
}
- else
- {
- handler->type = eventType;
- handler->cb = callback;
- handler->data = userData;
- handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
+ handler->type = eventType;
+ handler->cb = callback;
+ handler->data = userData;
+ handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
- *eventHandler = handler;
+ *eventHandler = handler;
- return TIZEN_ERROR_NONE;
- }
-}
+ return TIZEN_ERROR_NONE;
}
+} // namespace AppCoreWidget
struct DALI_ADAPTOR_API AppModelWidget::Impl
{
@@ -211,17 +211,17 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
static void AppInit(int argc, char** argv, void* data)
{
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
ecore_init();
ecore_app_args_set(argc, (const char**)argv);
- #pragma GCC diagnostic pop
+#pragma GCC diagnostic pop
- #ifdef DALI_ELDBUS_AVAILABLE
+#ifdef DALI_ELDBUS_AVAILABLE
// Initialize ElDBus.
DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
eldbus_init();
- #endif
+#endif
}
static void AppFinish(void)
@@ -234,11 +234,11 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
ecore_shutdown();
}
- #ifdef DALI_ELDBUS_AVAILABLE
+#ifdef DALI_ELDBUS_AVAILABLE
// Shutdown ELDBus.
DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
eldbus_shutdown();
- #endif
+#endif
}
static void AppRun(void* data)
@@ -251,11 +251,10 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
ecore_main_loop_quit();
}
-
static void AppLanguageChanged(AppCoreWidget::AppEventInfoPtr event, void* data)
{
- FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
- Framework::Observer* observer = &framework->GetObserver();
+ FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
+ Framework::Observer* observer = &framework->GetObserver();
if(event && event->value)
{
@@ -270,8 +269,8 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
static void AppRegionChanged(AppCoreWidget::AppEventInfoPtr event, void* data)
{
- FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
- Framework::Observer* observer = &framework->GetObserver();
+ FrameworkTizen* framework = static_cast<FrameworkTizen*>(data);
+ Framework::Observer* observer = &framework->GetObserver();
if(event && event->value)
{
@@ -286,7 +285,7 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
static void AppBatteryLow(AppCoreWidget::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::Status::NORMAL;
@@ -311,7 +310,7 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
static void AppMemoryLow(AppCoreWidget::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::Status::NORMAL;
@@ -341,7 +340,7 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
static void AppDeviceOrientationChanged(AppCoreWidget::AppEventInfoPtr event, void* data)
{
- Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
+ Framework::Observer* observer = &static_cast<FrameworkTizen*>(data)->GetObserver();
int status = *static_cast<int*>(event->value);
Dali::DeviceStatus::Orientation::Status result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0;
@@ -418,8 +417,8 @@ struct DALI_ADAPTOR_API AppModelWidget::Impl
{
}
- AppModelWidget* mAppModelWidget;
- AppCoreWidget::AppEventHandlerPtr handlers[5];
+ AppModelWidget* mAppModelWidget;
+ AppCoreWidget::AppEventHandlerPtr handlers[5];
}; // Impl
AppModelWidget::AppModelWidget()
@@ -432,7 +431,7 @@ AppModelWidget::~AppModelWidget()
delete mImpl;
}
-int AppModelWidget::AppMain(void *data)
+int AppModelWidget::AppMain(void* data)
{
return mImpl->AppMain(data);
}
diff --git a/dali/internal/clipboard/common/clipboard-impl.h b/dali/internal/clipboard/common/clipboard-impl.h
index cf508ea36..a7a2eea1a 100644
--- a/dali/internal/clipboard/common/clipboard-impl.h
+++ b/dali/internal/clipboard/common/clipboard-impl.h
@@ -119,6 +119,12 @@ public:
*/
bool OnReceiveData();
+ /**
+ * This is called after a timeout when no new data set.
+ * @return will return false; one-shot timer.
+ */
+ bool OnMultiSelectionTimeout();
+
private:
// Undefined
Clipboard(const Clipboard&);
diff --git a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
index ce788bd87..7c5559e8a 100644
--- a/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
+++ b/dali/internal/clipboard/generic/clipboard-impl-generic.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -29,9 +29,9 @@ namespace Adaptor
{
struct Clipboard::Impl
{
- Dali::Clipboard::DataSentSignalType mDataSentSignal;
- Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal;
- Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal;
+ Dali::Clipboard::DataSentSignalType mDataSentSignal{};
+ Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal{};
+ Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal{};
};
Clipboard::Clipboard(Impl* impl)
@@ -41,6 +41,7 @@ Clipboard::Clipboard(Impl* impl)
Clipboard::~Clipboard()
{
+ delete mImpl;
}
Dali::Clipboard Clipboard::Get()
@@ -107,7 +108,7 @@ bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
return true;
}
-uint32_t Clipboard::GetData(const std::string &mimeType)
+uint32_t Clipboard::GetData(const std::string& mimeType)
{
return 0u;
}
@@ -135,6 +136,11 @@ bool Clipboard::OnReceiveData()
return false;
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return false;
+}
+
} // namespace Adaptor
} // namespace Internal
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 0dc294958..a7754510b 100644
--- a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
+++ b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -19,11 +19,13 @@
#include <dali/internal/clipboard/common/clipboard-impl.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
#include <dali/devel-api/common/singleton-service.h>
-#include <dali/internal/adaptor/tizen-wayland/dali-ecore-wl2.h>
#include <dali/integration-api/debug.h>
+#include <dali/internal/adaptor/tizen-wayland/dali-ecore-wl2.h>
+#include <dali/public-api/adaptor-framework/timer.h>
#include <unistd.h>
-#include <unordered_map>
+#include <map>
namespace Dali
{
@@ -31,6 +33,12 @@ namespace Internal
{
namespace Adaptor
{
+namespace
+{
+const char* DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT("DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT");
+const uint32_t DEFAULT_MULTI_SELECTION_TIMEOUT = 500u;
+} // namespace
+
static Eina_Bool EcoreEventDataSend(void* data, int type, void* event);
static Eina_Bool EcoreEventOfferDataReady(void* data, int type, void* event);
static Eina_Bool EcoreEventSelectionOffer(void* data, int type, void* event);
@@ -63,11 +71,11 @@ struct Clipboard::Impl
}
Eina_Array* availableTypes = ecore_wl2_offer_mimes_get(offer);
- unsigned int typeCount = (unsigned int)eina_array_count((Eina_Array *)availableTypes);
+ unsigned int typeCount = (unsigned int)eina_array_count((Eina_Array*)availableTypes);
for(unsigned int i = 0; i < typeCount; ++i)
{
- char* availableType = (char*)eina_array_data_get((Eina_Array *)availableTypes, i);
+ char* availableType = (char*)eina_array_data_get((Eina_Array*)availableTypes, i);
if(!mimeType.compare(availableType))
{
return true;
@@ -78,28 +86,83 @@ struct Clipboard::Impl
bool SetData(const Dali::Clipboard::ClipData& clipData)
{
- mMimeType = clipData.GetMimeType();
- mData = clipData.GetData();
+ std::string mimeType = clipData.GetMimeType();
+ std::string data = clipData.GetData();
- if(mData.empty())
+ if(data.empty())
{
DALI_LOG_ERROR("ClipData is empty, return false.\n");
return false;
}
const char* mimeTypes[2];
- mimeTypes[0] = mMimeType.c_str();
+ mimeTypes[0] = mimeType.c_str();
mimeTypes[1] = nullptr;
+ mSetDatas[mimeType] = data;
+
Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
- Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
- mSerial = ecore_wl2_dnd_selection_set(input, mimeTypes);
- DALI_LOG_RELEASE_INFO("selection_set success, serial:%u, type:%s, data:%s\n", mSerial, mMimeType.c_str(), mData.c_str());
+ Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
+
+ uint32_t serial = ecore_wl2_dnd_selection_set(input, mimeTypes);
+ DALI_LOG_RELEASE_INFO("selection_set success, serial:%u, type:%s, data:%s\n", serial, mimeType.c_str(), data.c_str());
+
+ // If the serial is the same, it is the same source.
+ // If the type is the same, it is a separate copy.
+ if(mSerial == serial && mLastType != mimeType && !mMultiSelectionTimeout)
+ {
+ // Checks whether there is an identical type requested from one source.
+ bool typeExists = false;
+ for(const auto& type : mSetTypes)
+ {
+ if(type == mimeType)
+ {
+ typeExists = true;
+ break;
+ }
+ }
+
+ if(!typeExists) // Same copy.
+ {
+ // It requests all types of copies requested from one source at once.
+ // EcoreEventDataSend callback is called as many as the number of requested types.
+ mSetTypes.push_back(mimeType);
+
+ size_t typeCount = mSetTypes.size();
+ const char* types[typeCount + 1];
+ for(size_t i = 0; i < typeCount; i++)
+ {
+ types[i] = mSetTypes[i].c_str();
+ DALI_LOG_RELEASE_INFO("selection_set multi types, serial:%u, type:%s\n", serial, types[i]);
+ }
+ types[typeCount] = nullptr;
+
+ // TODO : At this point, it is impossible to avoid duplicate calls,
+ // because we cannot know how many more times the copy will be called for the same source.
+ serial = ecore_wl2_dnd_selection_set(input, types);
+ }
+ else // Separate copy.
+ {
+ mSetTypes.clear();
+ mSetTypes.push_back(mimeType);
+ }
+ }
+ else
+ {
+ mSetTypes.clear();
+ mSetTypes.push_back(mimeType);
+ }
+
+ // Store the last serial and type.
+ mSerial = serial;
+ mLastType = mimeType;
+
+ SetMultiSelectionTimeout();
return true;
}
- uint32_t GetData(const std::string &mimeType)
+ uint32_t GetData(const std::string& mimeType)
{
const char* type = mimeType.c_str();
if(!type)
@@ -115,16 +178,17 @@ struct Clipboard::Impl
if(!offer)
{
DALI_LOG_ERROR("selection_get fail, request type:%s\n", mimeType.c_str());
+ mLastOffer = nullptr;
return 0u;
}
Eina_Array* availableTypes = ecore_wl2_offer_mimes_get(offer);
char* selectedType = nullptr;
- unsigned int typeCount = (unsigned int)eina_array_count((Eina_Array *)availableTypes);
+ unsigned int typeCount = (unsigned int)eina_array_count((Eina_Array*)availableTypes);
for(unsigned int i = 0; i < typeCount && !selectedType; ++i)
{
- char* availableType = (char*)eina_array_data_get((Eina_Array *)availableTypes, i);
+ char* availableType = (char*)eina_array_data_get((Eina_Array*)availableTypes, i);
if(!mimeType.compare(availableType))
{
selectedType = availableType;
@@ -137,18 +201,38 @@ struct Clipboard::Impl
DALI_LOG_ERROR("no matching type, num of available types:%u, request type:%s\n", typeCount, mimeType.c_str());
for(unsigned int i = 0; i < typeCount && !selectedType; ++i)
{
- DALI_LOG_ERROR("available type[%u]:%s\n", i, (char*)eina_array_data_get((Eina_Array *)availableTypes, i));
+ DALI_LOG_ERROR("available type[%u]:%s\n", i, (char*)eina_array_data_get((Eina_Array*)availableTypes, i));
}
return 0u;
}
+ uint32_t lastDataId = mDataId;
mDataId++;
mDataRequestIds.push_back(mDataId);
mDataRequestItems[mDataId] = std::make_pair(mimeType, offer);
- DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", mDataId, mimeType.c_str());
- ecore_wl2_offer_receive(offer, const_cast<char*>(type));
- ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ // Not yet received a callback for the recent offer receive.
+ if(mLastOffer == offer && mDataRequestItems.count(lastDataId))
+ {
+ // A receive request for the same offer and type is made only once.
+ if(std::find(mGetTypes.begin(), mGetTypes.end(), mimeType) == mGetTypes.end())
+ {
+ mGetTypes.push_back(mimeType);
+ mReservedOfferReceives[lastDataId] = mDataId;
+ } // else do nothing.
+ }
+ else
+ {
+ mGetTypes.clear();
+ mGetTypes.push_back(mimeType);
+
+ DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", mDataId, mimeType.c_str());
+ ecore_wl2_offer_receive(offer, const_cast<char*>(type));
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+
+ mLastOffer = offer;
+
return mDataId;
}
@@ -158,37 +242,20 @@ struct Clipboard::Impl
if(ev->serial != mSerial)
{
+ DALI_LOG_ERROR("ev->serial:%u, mSerial:%u, type:%s\n", ev->serial, mSerial, ev->type);
return;
}
- // no matching mime type.
- if(mMimeType.compare(ev->type))
+ // Check whether the hash has data of the requested type.
+ // If there is no data of the requested type, something has already gone wrong.
+ std::string type = ev->type;
+ std::string data = "";
+ if(mSetDatas.count(type))
{
- auto it = mDataRequestIds.begin();
- while(it != mDataRequestIds.end())
- {
- uint32_t dataRequestId = *it;
- auto item = mDataRequestItems.find(dataRequestId);
- if(item != mDataRequestItems.end())
- {
- std::string mimeType = static_cast<std::string>(item->second.first);
- if(!mimeType.compare(ev->type))
- {
- mDataRequestItems.erase(dataRequestId);
- it = mDataRequestIds.erase(it);
- DALI_LOG_ERROR("no matching type, empty signal emit, request type:%s, available type:%s\n", ev->type, mMimeType.c_str());
- mDataReceivedSignal.Emit(dataRequestId, "", "");
- }
- else
- {
- ++it;
- }
- }
- }
- return;
+ data = mSetDatas[type];
}
- size_t dataLength = strlen(mData.c_str());
+ size_t dataLength = strlen(data.c_str());
size_t bufferSize = dataLength + 1u;
char* buffer = new char[bufferSize];
@@ -197,7 +264,7 @@ struct Clipboard::Impl
return;
}
- memcpy(buffer, mData.c_str(), dataLength);
+ memcpy(buffer, data.c_str(), dataLength);
buffer[dataLength] = '\0';
auto ret = write(ev->fd, buffer, bufferSize);
@@ -209,8 +276,8 @@ struct Clipboard::Impl
close(ev->fd);
delete[] buffer;
- DALI_LOG_RELEASE_INFO("send data, type:%s, data:%s \n", mMimeType.c_str(), mData.c_str());
- mDataSentSignal.Emit(ev->type, mData.c_str());
+ DALI_LOG_RELEASE_INFO("send data, type:%s, data:%s \n", ev->type, data.c_str());
+ mDataSentSignal.Emit(ev->type, data.c_str());
}
void ReceiveData(void* event)
@@ -244,33 +311,78 @@ struct Clipboard::Impl
DALI_LOG_RELEASE_INFO("receive data, type:%s, data:%s\n", ev->mimetype, content.c_str());
- auto it = mDataRequestIds.begin();
- while(it != mDataRequestIds.end())
+ // Retrieve request id list.
+ for(auto it = mDataRequestIds.begin(); it != mDataRequestIds.end();)
{
uint32_t dataRequestId = *it;
- auto item = mDataRequestItems.find(dataRequestId);
- if(item != mDataRequestItems.end())
+ if(mDataRequestItems.count(dataRequestId))
{
- Ecore_Wl2_Offer* offer = static_cast<Ecore_Wl2_Offer*>(item->second.second);
- if(offer == ev->offer)
+ const auto& item = mDataRequestItems[dataRequestId];
+ std::string mimeType = static_cast<std::string>(item.first);
+ Ecore_Wl2_Offer* offer = static_cast<Ecore_Wl2_Offer*>(item.second);
+
+ // Processes all the same types stored in the request list.
+ if(!mimeType.compare(ev->mimetype))
{
- std::string mimeType = static_cast<std::string>(item->second.first);
mDataRequestItems.erase(dataRequestId);
it = mDataRequestIds.erase(it);
- DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s\n", dataRequestId, mimeType.c_str());
- mDataReceivedSignal.Emit(dataRequestId, mimeType.c_str(), content.c_str());
+
+ // A change in an offer means a change in the clipboard's data.
+ // Old offers are not always invalid, but at least in Dali it is unknown whether they are valid or not.
+ // For safe processing, old offers are considered invalid offers.
+ if(offer && offer == ev->offer && mLastOffer == offer)
+ {
+ DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s\n", dataRequestId, mimeType.c_str());
+ mDataReceivedSignal.Emit(dataRequestId, mimeType.c_str(), content.c_str());
+
+ if(mReservedOfferReceives.count(dataRequestId))
+ {
+ uint32_t reservedId = mReservedOfferReceives[dataRequestId];
+ if(mDataRequestItems.count(reservedId))
+ {
+ const auto& reservedItem = mDataRequestItems[reservedId];
+ std::string reservedType = static_cast<std::string>(reservedItem.first);
+ Ecore_Wl2_Offer* reservedOffer = static_cast<Ecore_Wl2_Offer*>(reservedItem.second);
+
+ if(reservedOffer)
+ {
+ Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
+ Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
+
+ DALI_LOG_RELEASE_INFO("offer_receive, id:%u, request type:%s\n", reservedId, reservedType.c_str());
+ ecore_wl2_offer_receive(reservedOffer, const_cast<char*>(reservedType.c_str()));
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+ }
+ mReservedOfferReceives.erase(dataRequestId);
+ }
+ }
+ else // null or invalid offer.
+ {
+ DALI_LOG_RELEASE_INFO("invalid offer, id:%u, request type:%s\n", dataRequestId, mimeType.c_str());
+ mDataReceivedSignal.Emit(dataRequestId, "", "");
+
+ if(mReservedOfferReceives.count(dataRequestId))
+ {
+ mReservedOfferReceives.erase(dataRequestId);
+ }
+ }
}
- else
+ else // item's type and event data's type are different.
{
++it;
}
}
+ else // There is no id in request items.
+ {
+ it = mDataRequestIds.erase(it);
+ }
}
}
void SelectionOffer(void* event)
{
- Ecore_Wl2_Event_Seat_Selection *ev = reinterpret_cast<Ecore_Wl2_Event_Seat_Selection*>(event);
+ Ecore_Wl2_Event_Seat_Selection* ev = reinterpret_cast<Ecore_Wl2_Event_Seat_Selection*>(event);
if(ev == nullptr)
{
@@ -295,16 +407,15 @@ struct Clipboard::Impl
for(int i = 0; i < ev->num_types; i++)
{
- DALI_LOG_RELEASE_INFO("mime type(%s)", ev->types[i]);
if(!formatMarkup.compare(ev->types[i]))
{
+ // Ignore elementary markup from efl.
continue;
}
- if(!selectedType)
- {
- selectedType = ev->types[i];
- }
+ selectedType = ev->types[i];
+ DALI_LOG_RELEASE_INFO("data selected signal emit, type:%s\n", selectedType);
+ mDataSelectedSignal.Emit(selectedType);
}
if(!selectedType)
@@ -312,25 +423,48 @@ struct Clipboard::Impl
DALI_LOG_ERROR("mime type is invalid.\n");
return;
}
+ }
+
+ void SetMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = false;
+ if(mMultiSelectionTimeoutTimer.IsRunning())
+ {
+ mMultiSelectionTimeoutTimer.Stop();
+ }
+ mMultiSelectionTimeoutTimer.Start();
+ }
- DALI_LOG_RELEASE_INFO("data selected signal emit, type:%s\n", selectedType);
- mDataSelectedSignal.Emit(selectedType);
+ bool OnMultiSelectionTimeout()
+ {
+ DALI_LOG_RELEASE_INFO("multi-selection end\n");
+ mMultiSelectionTimeout = true;
+ return false;
}
- uint32_t mSerial{std::numeric_limits<uint32_t>::max()};
- std::string mMimeType;
- std::string mData;
+ uint32_t mSerial{std::numeric_limits<uint32_t>::max()};
+ std::string mLastType{}; // mime type used in last copy.
+ Ecore_Wl2_Offer* mLastOffer{nullptr}; // offer used in last paste.
+
Ecore_Event_Handler* mSendHandler{nullptr};
Ecore_Event_Handler* mReceiveHandler{nullptr};
Ecore_Event_Handler* mSelectionHanlder{nullptr};
- Dali::Clipboard::DataSentSignalType mDataSentSignal;
- Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal;
- Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal;
+ Dali::Clipboard::DataSentSignalType mDataSentSignal{};
+ Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal{};
+ Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal{};
+
+ uint32_t mDataId{0};
+ std::vector<uint32_t> mDataRequestIds{};
+ std::map<uint32_t, std::pair<std::string, Ecore_Wl2_Offer*>> mDataRequestItems{};
+
+ std::vector<std::string> mSetTypes{}; // types for the same source (one user copy).
+ std::map<std::string, std::string> mSetDatas{}; // datas for the same source (one user copy), key is mime type, value is data.
+ std::vector<std::string> mGetTypes{}; // types requested to receive for the same offer.
+ std::map<uint32_t, uint32_t> mReservedOfferReceives{}; // in order to process offer receive sequentially, key is current id, value is reserved id.
- uint32_t mDataId{0};
- std::vector<uint32_t> mDataRequestIds;
- std::unordered_map<uint32_t, std::pair<std::string, Ecore_Wl2_Offer*>> mDataRequestItems;
+ Dali::Timer mMultiSelectionTimeoutTimer{};
+ bool mMultiSelectionTimeout{false};
};
static Eina_Bool EcoreEventDataSend(void* data, int type, void* event)
@@ -360,6 +494,13 @@ static Eina_Bool EcoreEventSelectionOffer(void* data, int type, void* event)
Clipboard::Clipboard(Impl* impl)
: mImpl(impl)
{
+ // Check environment variable for DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT
+ auto timeoutString = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_CLIPBOARD_MULTI_SELECTION_TIMEOUT);
+ uint32_t multiSelectionTimeout = timeoutString ? static_cast<uint32_t>(std::atoi(timeoutString)) : DEFAULT_MULTI_SELECTION_TIMEOUT;
+
+ DALI_LOG_RELEASE_INFO("multi-selection timeout set:%u\n", multiSelectionTimeout);
+ mImpl->mMultiSelectionTimeoutTimer = Dali::Timer::New(multiSelectionTimeout);
+ mImpl->mMultiSelectionTimeoutTimer.TickSignal().Connect(this, &Clipboard::OnMultiSelectionTimeout);
}
Clipboard::~Clipboard()
@@ -431,7 +572,7 @@ bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
return mImpl->SetData(clipData);
}
-uint32_t Clipboard::GetData(const std::string &mimeType)
+uint32_t Clipboard::GetData(const std::string& mimeType)
{
return mImpl->GetData(mimeType);
}
@@ -460,6 +601,11 @@ bool Clipboard::OnReceiveData()
return false;
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return mImpl->OnMultiSelectionTimeout();
+}
+
} // namespace Adaptor
} // namespace Internal
diff --git a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
index 9c15021c3..06ab1cd8b 100644
--- a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
+++ b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -29,6 +29,8 @@
#include <dali/devel-api/common/singleton-service.h>
#include <dali/internal/adaptor/common/adaptor-impl.h>
#include <dali/internal/window-system/ubuntu-x11/window-interface-ecore-x.h>
+#include <map>
+#include <queue>
namespace Dali
{
@@ -45,30 +47,64 @@ struct Clipboard::Impl
bool HasType(const std::string& mimeType)
{
- return mMimeType == mimeType ? true : false;
+ for(const auto& type : mMimeTypes)
+ {
+ if(type == mimeType)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void UpdateData(std::string& mimeType, std::string& data, bool clearBuffer)
+ {
+ if(clearBuffer)
+ {
+ mMimeTypes.clear();
+ mDatas.clear();
+ }
+ mMimeTypes.push_back(mimeType);
+ mDatas[mimeType] = data;
}
bool SetData(const Dali::Clipboard::ClipData& clipData)
{
- mMimeType = clipData.GetMimeType();
- mData = clipData.GetData();
+ std::string mimeType = clipData.GetMimeType();
+ std::string data = clipData.GetData();
- if(mData.empty())
+ if(mimeType.empty() || data.empty())
{
return false;
}
- mDataSentSignal.Emit(mMimeType.c_str(), mData.c_str());
- mDataSelectedSignal.Emit(mMimeType.c_str());
+ if(mLastType != mimeType && !mMultiSelectionTimeout)
+ {
+ bool clearBuffer = HasType(mimeType);
+ UpdateData(mimeType, data, clearBuffer);
+ }
+ else
+ {
+ UpdateData(mimeType, data, true);
+ }
+
+ mLastType = mimeType;
+
+ mDataSentSignal.Emit(mimeType.c_str(), data.c_str());
+ mDataSelectedSignal.Emit(mimeType.c_str());
+
+ SetMultiSelectionTimeout();
return true;
}
- uint32_t GetData(const std::string &mimeType)
+ uint32_t GetData(const std::string& mimeType)
{
- if(!mMimeType.compare(mimeType.c_str()))
+ if(mDatas.count(mimeType))
{
mDataId++;
+ mDataReceiveQueue.push(std::make_pair(mDataId, mimeType));
+
// For consistency of operation with tizen Wl2, a fake callback is occurs using a timer.
if(mDataReceiveTimer.IsRunning())
{
@@ -83,28 +119,67 @@ struct Clipboard::Impl
bool OnReceiveData()
{
- DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s, data:%s\n", mDataId, mMimeType.c_str(), mData.c_str());
- mDataReceivedSignal.Emit(mDataId, mMimeType.c_str(), mData.c_str());
+ while(!mDataReceiveQueue.empty())
+ {
+ auto item = mDataReceiveQueue.front();
+ mDataReceiveQueue.pop();
+
+ uint32_t requestId = item.first;
+ std::string requestType = item.second;
+ std::string data = "";
+
+ if(mDatas.count(requestType))
+ {
+ data = mDatas[requestType];
+ }
+
+ DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s, data:%s\n", requestId, requestType.c_str(), data.c_str());
+ mDataReceivedSignal.Emit(requestId, requestType.c_str(), data.c_str());
+ }
+ return false;
+ }
+
+ void SetMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = false;
+ if(mMultiSelectionTimeoutTimer.IsRunning())
+ {
+ mMultiSelectionTimeoutTimer.Stop();
+ }
+ mMultiSelectionTimeoutTimer.Start();
+ }
+
+ bool OnMultiSelectionTimeout()
+ {
+ mMultiSelectionTimeout = true;
return false;
}
- Ecore_X_Window mApplicationWindow;
- std::string mMimeType;
- std::string mData;
+ Ecore_X_Window mApplicationWindow{};
uint32_t mDataId{0};
+ std::string mLastType{};
- Dali::Clipboard::DataSentSignalType mDataSentSignal;
- Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal;
- Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal;
+ std::vector<std::string> mMimeTypes{};
+ std::map<std::string, std::string> mDatas{}; // type, data
+ std::queue<std::pair<uint32_t, std::string>> mDataReceiveQueue{}; // id, type
- Dali::Timer mDataReceiveTimer;
+ Dali::Clipboard::DataSentSignalType mDataSentSignal{};
+ Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal{};
+ Dali::Clipboard::DataSelectedSignalType mDataSelectedSignal{};
+
+ Dali::Timer mDataReceiveTimer{};
+ Dali::Timer mMultiSelectionTimeoutTimer{};
+ bool mMultiSelectionTimeout{false};
};
Clipboard::Clipboard(Impl* impl)
: mImpl(impl)
{
- mImpl->mDataReceiveTimer = Dali::Timer::New(10);
+ mImpl->mDataReceiveTimer = Dali::Timer::New(10u);
mImpl->mDataReceiveTimer.TickSignal().Connect(this, &Clipboard::OnReceiveData);
+
+ mImpl->mMultiSelectionTimeoutTimer = Dali::Timer::New(500u);
+ mImpl->mMultiSelectionTimeoutTimer.TickSignal().Connect(this, &Clipboard::OnMultiSelectionTimeout);
}
Clipboard::~Clipboard()
@@ -188,7 +263,7 @@ bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
return mImpl->SetData(clipData);
}
-uint32_t Clipboard::GetData(const std::string &mimeType)
+uint32_t Clipboard::GetData(const std::string& mimeType)
{
return mImpl->GetData(mimeType);
}
@@ -217,6 +292,11 @@ bool Clipboard::OnReceiveData()
return mImpl->OnReceiveData();
}
+bool Clipboard::OnMultiSelectionTimeout()
+{
+ return mImpl->OnMultiSelectionTimeout();
+}
+
} // namespace Adaptor
} // namespace Internal
diff --git a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp
index e57f437ac..7e6d3722a 100644
--- a/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp
+++ b/dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -411,6 +411,13 @@ void DragAndDropEcoreWl::SendData(void* event)
return;
}
+ DelayedWritingData* data = (DelayedWritingData*)calloc(1, sizeof(DelayedWritingData));
+ if(DALI_UNLIKELY(!data))
+ {
+ DALI_LOG_ERROR("Failed to allocate DelayedWritingData. calloc size : %zu\n", sizeof(DelayedWritingData));
+ return;
+ }
+
int dataLength = strlen(mData.c_str());
int bufferSize = dataLength;
if((mMimeType.find("text") != std::string::npos) ||
@@ -420,9 +427,8 @@ void DragAndDropEcoreWl::SendData(void* event)
bufferSize += 1;
}
- DelayedWritingData* data = (DelayedWritingData*)calloc(1, sizeof(DelayedWritingData));
- data->slice.mem = new char[bufferSize];
- data->slice.len = bufferSize;
+ data->slice.mem = new char[bufferSize];
+ data->slice.len = bufferSize;
memcpy(data->slice.mem, mData.c_str(), dataLength);
((char*)data->slice.mem)[dataLength] = '\0';
@@ -512,8 +518,8 @@ bool DragAndDropEcoreWl::CalculateDragEvent(void* event)
Dali::DragAndDrop::DragEvent dragEvent;
- Eina_Array *mimes = NULL;
- mimes = ecore_wl2_offer_mimes_get(ev->offer);
+ Eina_Array* mimes = NULL;
+ mimes = ecore_wl2_offer_mimes_get(ev->offer);
if(mimes == NULL)
{
dragEvent.SetMimeType("");
@@ -523,7 +529,7 @@ bool DragAndDropEcoreWl::CalculateDragEvent(void* event)
dragEvent.SetMimeType((const char*)eina_array_data_get(mimes, 0));
}
- Dali::Vector2 curPosition(ev->x, ev->y);
+ Dali::Vector2 curPosition(ev->x, ev->y);
for(std::size_t i = 0; i < mDropTargets.size(); i++)
{
@@ -628,8 +634,8 @@ bool DragAndDropEcoreWl::CalculateViewRegion(void* event)
mTargetIndex = -1;
mWindowTargetIndex = -1;
- Eina_Array *mimes = NULL;
- mimes = ecore_wl2_offer_mimes_get(ev->offer);
+ Eina_Array* mimes = NULL;
+ mimes = ecore_wl2_offer_mimes_get(ev->offer);
if(mimes == NULL)
{
return false;
diff --git a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp
index 06b742ffa..dcd09669f 100644
--- a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp
+++ b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp
@@ -147,7 +147,7 @@ bool ProgramImpl::Create()
auto program = gl->CreateProgram();
- DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] create program id : %u\n", mImpl->name.c_str(), program);
+ DALI_LOG_DEBUG_INFO("Program[%s] create program id : %u\n", mImpl->name.c_str(), program);
const auto& info = mImpl->createInfo;
for(const auto& state : *info.shaderState)
@@ -158,12 +158,12 @@ bool ProgramImpl::Create()
if(shader->GetImplementation()->Compile())
{
auto shaderId = shader->GetImplementation()->GetGLShader();
- DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] attach shader : %u\n", mImpl->name.c_str(), shaderId);
+ DALI_LOG_DEBUG_INFO("Program[%s] attach shader : %u\n", mImpl->name.c_str(), shaderId);
gl->AttachShader(program, shaderId);
}
}
- DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] call glLinkProgram\n", mImpl->name.c_str());
+ DALI_LOG_DEBUG_INFO("Program[%s] call glLinkProgram\n", mImpl->name.c_str());
gl->LinkProgram(program);
GLint status{0};
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 e263c327c..7ebaa1d4f 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
@@ -1979,8 +1979,9 @@ void WindowBaseEcoreWl2::TizenPolicyConformantArea(void* data, struct tizen_poli
{
Ecore_Wl2_Event_Conformant_Change* ev = static_cast<Ecore_Wl2_Event_Conformant_Change*>(calloc(1, sizeof(Ecore_Wl2_Event_Conformant_Change)));
- if(!ev)
+ if(DALI_UNLIKELY(!ev))
{
+ DALI_LOG_ERROR("Failed to allocate Ecore_Wl2_Event_Conformant_Change. calloc size : %zu\n", sizeof(Ecore_Wl2_Event_Conformant_Change));
return;
}
ev->win = GetNativeWindowId();
diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp
index d6d44b1c8..cfd8b47a7 100644
--- a/dali/public-api/dali-adaptor-version.cpp
+++ b/dali/public-api/dali-adaptor-version.cpp
@@ -27,7 +27,7 @@ namespace Dali
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 3;
-const unsigned int ADAPTOR_MICRO_VERSION = 27;
+const unsigned int ADAPTOR_MICRO_VERSION = 28;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec
index 2b31ca5ad..567e0b82e 100644
--- a/packaging/dali-adaptor.spec
+++ b/packaging/dali-adaptor.spec
@@ -17,7 +17,7 @@
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.3.27
+Version: 2.3.28
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT