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