Merge "Test harness sync" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / clipboard / ubuntu-x11 / clipboard-impl-x.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/clipboard/common/clipboard-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/internal/system/linux/dali-ecore-x.h>
24 #include <dali/public-api/adaptor-framework/timer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/public-api/object/type-registry.h>
27
28 // INTERNAL INCLUDES
29 #include <dali/devel-api/common/singleton-service.h>
30 #include <dali/internal/adaptor/common/adaptor-impl.h>
31 #include <dali/internal/window-system/ubuntu-x11/window-interface-ecore-x.h>
32
33 namespace Dali
34 {
35 namespace Internal
36 {
37 namespace Adaptor
38 {
39 struct Clipboard::Impl
40 {
41   Impl(Ecore_X_Window ecoreXwin)
42   {
43     mApplicationWindow = ecoreXwin;
44   }
45
46   bool SetData(const Dali::Clipboard::ClipData& clipData)
47   {
48     mMimeType = clipData.GetMimeType();
49     mData     = clipData.GetData();
50
51     if(mData.empty())
52     {
53       return false;
54     }
55
56     mDataSentSignal.Emit(mMimeType.c_str(), mData.c_str());
57
58     return true;
59   }
60
61   uint32_t GetData(const std::string &mimeType)
62   {
63     if(!mMimeType.compare(mimeType.c_str()))
64     {
65       mDataId++;
66       // For consistency of operation with tizen Wl2, a fake callback is occurs using a timer.
67       if(mDataReceiveTimer.IsRunning())
68       {
69         mDataReceiveTimer.Stop();
70       }
71       mDataReceiveTimer.Start();
72       DALI_LOG_RELEASE_INFO("request data, id:%u, request type:%s\n", mDataId, mimeType.c_str());
73       return mDataId;
74     }
75     return 0u;
76   }
77
78   bool OnReceiveData()
79   {
80     DALI_LOG_RELEASE_INFO("receive data, success signal emit, id:%u, type:%s, data:%s\n", mDataId, mMimeType.c_str(), mData.c_str());
81     mDataReceivedSignal.Emit(mDataId, mMimeType.c_str(), mData.c_str());
82     return false;
83   }
84
85   Ecore_X_Window mApplicationWindow;
86   std::string    mMimeType;
87   std::string    mData;
88   uint32_t       mDataId{0};
89
90   Dali::Clipboard::DataSentSignalType     mDataSentSignal;
91   Dali::Clipboard::DataReceivedSignalType mDataReceivedSignal;
92
93   Dali::Timer mDataReceiveTimer;
94 };
95
96 Clipboard::Clipboard(Impl* impl)
97 : mImpl(impl)
98 {
99   mImpl->mDataReceiveTimer = Dali::Timer::New(10);
100   mImpl->mDataReceiveTimer.TickSignal().Connect(this, &Clipboard::OnReceiveData);
101 }
102
103 Clipboard::~Clipboard()
104 {
105   delete mImpl;
106 }
107
108 Dali::Clipboard Clipboard::Get()
109 {
110   Dali::Clipboard clipboard;
111
112   Dali::SingletonService service(SingletonService::Get());
113   if(service)
114   {
115     // Check whether the singleton is already created
116     Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::Clipboard));
117     if(handle)
118     {
119       // If so, downcast the handle
120       clipboard = Dali::Clipboard(dynamic_cast<Clipboard*>(handle.GetObjectPtr()));
121     }
122     else
123     {
124       Adaptor& adaptorImpl(Adaptor::GetImplementation(Adaptor::Get()));
125       Any      nativewindow = adaptorImpl.GetNativeWindowHandle();
126
127       // The Ecore_X_Window needs to use the Clipboard.
128       // Only when the render surface is window, we can get the Ecore_X_Window.
129       Ecore_X_Window ecoreXwin(AnyCast<Ecore_X_Window>(nativewindow));
130       if(ecoreXwin)
131       {
132         // If we fail to get Ecore_X_Window, we can't use the Clipboard correctly.
133         // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
134         // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
135         Clipboard::Impl* impl(new Clipboard::Impl(ecoreXwin));
136         clipboard = Dali::Clipboard(new Clipboard(impl));
137         service.Register(typeid(clipboard), clipboard);
138       }
139     }
140   }
141
142   return clipboard;
143 }
144
145 bool Clipboard::IsAvailable()
146 {
147   Dali::SingletonService service(SingletonService::Get());
148   if(service)
149   {
150     Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::Clipboard));
151     if(handle)
152     {
153       return true;
154     }
155   }
156   return false;
157 }
158
159 Dali::Clipboard::DataSentSignalType& Clipboard::DataSentSignal()
160 {
161   return mImpl->mDataSentSignal;
162 }
163
164 Dali::Clipboard::DataReceivedSignalType& Clipboard::DataReceivedSignal()
165 {
166   return mImpl->mDataReceivedSignal;
167 }
168
169 bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
170 {
171   return mImpl->SetData(clipData);
172 }
173
174 uint32_t Clipboard::GetData(const std::string &mimeType)
175 {
176   return mImpl->GetData(mimeType);
177 }
178
179 size_t Clipboard::NumberOfItems()
180 {
181   // TODO: We should to check if the data is empty in the clipboard service.
182   return 1u;
183 }
184
185 void Clipboard::ShowClipboard()
186 {
187 }
188
189 void Clipboard::HideClipboard(bool skipFirstHide)
190 {
191 }
192
193 bool Clipboard::IsVisible() const
194 {
195   return false;
196 }
197
198 bool Clipboard::OnReceiveData()
199 {
200   return mImpl->OnReceiveData();
201 }
202
203 } // namespace Adaptor
204
205 } // namespace Internal
206
207 } // namespace Dali