309a07a00ee04eebf48b44e68b30ed87484c77fa
[platform/core/uifw/dali-adaptor.git] / dali / internal / clipboard / tizen-wayland / ecore-wl2 / clipboard-impl-ecore-wl2.cpp
1 /*
2  * Copyright (c) 2017 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 // Ecore is littered with C style cast
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #include <Ecore.h>
26 #include <dali/public-api/object/any.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/integration-api/debug.h>
29 #include <unistd.h>
30
31 #ifdef DALI_ELDBUS_AVAILABLE
32 #include <Eldbus.h>
33 #endif // DALI_ELDBUS_AVAILABLE
34 #include <Ecore_Wl2.h>
35
36 // INTERNAL INCLUDES
37 #include <dali/internal/system/common/singleton-service-impl.h>
38
39 #define CBHM_DBUS_OBJPATH "/org/tizen/cbhm/dbus"
40 #ifndef CBHM_DBUS_INTERFACE
41 #define CBHM_DBUS_INTERFACE "org.tizen.cbhm.dbus"
42 #endif /* CBHM_DBUS_INTERFACE */
43 #define CBHM_COUNT_ALL 0    // ATOM_INDEX_CBHM_COUNT_ALL
44
45 ///////////////////////////////////////////////////////////////////////////////////////////////////
46 // Clipboard
47 ///////////////////////////////////////////////////////////////////////////////////////////////////
48
49 namespace Dali
50 {
51
52 namespace Internal
53 {
54
55 namespace Adaptor
56 {
57
58 struct Clipboard::Impl
59 {
60   Impl()
61   {
62     Eldbus_Object *eldbus_obj;
63     cbhm_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
64     eldbus_obj = eldbus_object_get(cbhm_conn, CBHM_DBUS_INTERFACE, CBHM_DBUS_OBJPATH);
65     eldbus_proxy = eldbus_proxy_get(eldbus_obj, CBHM_DBUS_INTERFACE);
66     eldbus_name_owner_changed_callback_add(cbhm_conn, CBHM_DBUS_INTERFACE, NULL, cbhm_conn, EINA_TRUE);
67     eldbus_proxy_signal_handler_add(eldbus_proxy, "ItemClicked", _on_item_clicked, this);
68     mVisible = false;
69     mIsFirstTimeHidden = true;
70     ecore_wl2_display = ecore_wl2_connected_display_get(NULL);
71     ecore_wl2_input = ecore_wl2_input_default_input_get(ecore_wl2_display);
72   }
73
74   ~Impl()
75   {
76     if (cbhm_conn)
77       eldbus_connection_unref(cbhm_conn);
78   }
79
80   Eldbus_Proxy* cbhm_proxy_get()
81   {
82     return eldbus_proxy;
83   }
84
85   Eldbus_Connection* cbhm_connection_get()
86   {
87     return cbhm_conn;
88   }
89
90   void SetItem( const std::string &itemData )
91   {
92     const char *types[10] = {0, };
93     int i = -1;
94
95     if (itemData.length() == 0)
96     {
97       return;
98     }
99     mSendBuffer = itemData;
100
101     // ELM_SEL_TYPE_CLIPBOARD - To distinguish clipboard selection in cbhm
102     types[++i] = "CLIPBOARD_BEGIN";
103
104     types[++i] = "text/plain;charset=utf-8";
105
106     // ELM_SEL_TYPE_CLIPBOARD - To distinguish clipboard selection in cbhm
107     types[++i] = "CLIPBOARD_END";
108     ecore_wl2_dnd_selection_set(ecore_wl2_input, types);
109   }
110
111   void RequestItem()
112   {      
113     ecore_wl2_dnd_selection_get(ecore_wl2_input);
114   }
115
116   char *ExcuteSend( void *event )
117   {
118     Ecore_Wl2_Event_Data_Source_Send *ev = (Ecore_Wl2_Event_Data_Source_Send *)event;
119     int len_buf = mSendBuffer.length();
120     int len_remained = len_buf;
121     int len_written = 0, ret;
122     const char *buf = mSendBuffer.c_str();
123
124     while (len_written < len_buf)
125     {
126        ret = write(ev->fd, buf, len_remained);
127        if (ret == -1) break;
128        buf += ret;
129        len_written += ret;
130        len_remained -= ret;
131     }
132     close(ev->fd);
133     return NULL;
134   }
135
136   char *ExcuteReceive( void *event )
137   {
138     Ecore_Wl2_Event_Selection_Data_Ready *ev = (Ecore_Wl2_Event_Selection_Data_Ready *)event;
139
140     return (char *)ev->data;
141   }
142
143   int GetCount()
144   {
145     Eldbus_Message *reply, *req;
146     const char *errname = NULL, *errmsg = NULL;
147     int count = -1;
148
149     if (!(req = eldbus_proxy_method_call_new(eldbus_proxy, "CbhmGetCount")))
150     {
151       DALI_LOG_ERROR("Failed to create method call on org.freedesktop.DBus.Properties.Get");
152       return -1;
153     }
154
155     eldbus_message_ref(req);
156     eldbus_message_arguments_append(req, "i", CBHM_COUNT_ALL) ;
157     reply = eldbus_proxy_send_and_block(eldbus_proxy, req, 100);
158     if (!reply || eldbus_message_error_get(reply, &errname, &errmsg))
159     {
160       DALI_LOG_ERROR("Unable to call method org.freedesktop.DBus.Properties.Get: %s %s",
161       errname, errmsg);
162       eldbus_message_unref(req);
163       if( reply )
164       {
165         eldbus_message_unref(reply);
166       }
167       return -1;
168     }
169
170     if (!eldbus_message_arguments_get(reply, "i", &count))
171     {
172       DALI_LOG_ERROR("Cannot get arguments from eldbus");
173       eldbus_message_unref(req);
174       eldbus_message_unref(reply);
175       return -1;
176     }
177
178     eldbus_message_unref(req);
179     eldbus_message_unref(reply);
180     DALI_LOG_ERROR("cbhm item count(%d)", count);
181     return count;
182   }
183
184   void ShowClipboard()
185   {
186     eldbus_proxy_call(cbhm_proxy_get(), "CbhmShow", NULL, NULL, -1, "s", "0");
187     mIsFirstTimeHidden = true;
188     mVisible = true;
189   }
190
191   void HideClipboard( bool skipFirstHide )
192   {
193     if ( skipFirstHide && mIsFirstTimeHidden )
194     {
195       mIsFirstTimeHidden = false;
196       return;
197     }
198     eldbus_proxy_call(cbhm_proxy_get(), "CbhmHide", NULL, NULL, -1, "");
199     mIsFirstTimeHidden = false;
200     mVisible = false;
201   }
202
203   bool IsVisible() const
204   {
205     return mVisible;
206   }
207
208   static void _on_item_clicked(void *data, const Eldbus_Message *msg EINA_UNUSED)
209   {
210     static_cast<Clipboard::Impl*>(data)->RequestItem();
211   }
212
213   Eldbus_Proxy *eldbus_proxy;
214   Eldbus_Connection *cbhm_conn;
215
216   std::string mSendBuffer;
217   bool mVisible;
218   bool mIsFirstTimeHidden;
219
220   Ecore_Wl2_Display* ecore_wl2_display;
221   Ecore_Wl2_Input* ecore_wl2_input;
222 };
223
224 Clipboard::Clipboard(Impl* impl)
225 : mImpl(impl)
226 {
227 }
228
229 Clipboard::~Clipboard()
230 {
231   delete mImpl;
232 }
233
234 Dali::Clipboard Clipboard::Get()
235 {
236   Dali::Clipboard clipboard;
237
238   Dali::SingletonService service( SingletonService::Get() );
239   if ( service )
240   {
241     // Check whether the singleton is already created
242     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::Clipboard ) );
243     if(handle)
244     {
245       // If so, downcast the handle
246       clipboard = Dali::Clipboard( dynamic_cast< Clipboard* >( handle.GetObjectPtr() ) );
247     }
248     else
249     {
250       Clipboard::Impl* impl( new Clipboard::Impl() );
251       clipboard = Dali::Clipboard( new Clipboard(impl) );
252       service.Register( typeid(Dali::Clipboard), clipboard );
253     }
254   }
255
256   return clipboard;
257 }
258
259 bool Clipboard::SetItem(const std::string &itemData )
260 {
261   mImpl->SetItem( itemData );
262   return true;
263 }
264
265 /*
266  * Request clipboard service to give an item
267  */
268 void Clipboard::RequestItem()
269 {
270   mImpl->RequestItem();
271 }
272
273 /*
274  * Get number of items in clipboard
275  */
276 unsigned int Clipboard::NumberOfItems()
277 {
278   return mImpl->GetCount();
279 }
280
281 void Clipboard::ShowClipboard()
282 {
283   mImpl->ShowClipboard();
284 }
285
286 void Clipboard::HideClipboard(bool skipFirstHide)
287 {
288   mImpl->HideClipboard(skipFirstHide);
289 }
290
291 bool Clipboard::IsVisible() const
292 {
293   return mImpl->IsVisible();
294 }
295
296 char* Clipboard::ExcuteBuffered( bool type, void *event )
297 {
298   return (type ?  mImpl->ExcuteSend( event ) : mImpl->ExcuteReceive( event ));
299 }
300
301 } // namespace Adaptor
302
303 } // namespace Internal
304
305 } // namespace Dali
306
307 #pragma GCC diagnostic pop