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