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