Fix Svace issue
[platform/core/uifw/pepper-dali.git] / pepper-dali / internal / shell-client-impl.cpp
1 /*
2  * Copyright (c) 2016 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 <pepper-dali/internal/shell-client-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <pepper-dali/internal/compositor-impl.h>
23
24 // EXTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <xdg-shell-server-protocol.h>
27
28 namespace Dali
29 {
30
31 namespace Pepper
32 {
33
34 namespace Internal
35 {
36
37 namespace
38 {
39
40 #if defined(DEBUG_ENABLED)
41 Integration::Log::Filter* gPepperShellClientLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_SHELL_CLIENT" );
42 #endif
43
44 static void XdgShellClientDestroy( struct wl_client* client, struct wl_resource* resource)
45 {
46 }
47
48 static void XdgShellClientUseUnstableVersion( struct wl_client* client, struct wl_resource* resource, int32_t version )
49 {
50 }
51
52 static void XdgShellClientGetSurface( struct wl_client* client, struct wl_resource* resource, uint32_t id, struct wl_resource* surfaceResource )
53 {
54   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
55
56   shellClient->GetSurface( client, id, surfaceResource );
57 }
58
59 static void XdgShellClientGetPopup( struct wl_client* client, struct wl_resource* resource, uint32_t id, struct wl_resource* surfaceResource,
60                               struct wl_resource* parentResource, struct wl_resource* seatResource, uint32_t serial, int32_t x, int32_t y )
61 {
62 }
63
64 static void XdgShellClientPong( struct wl_client* client, struct wl_resource* resource, uint32_t serial )
65 {
66 }
67
68 static const struct xdg_shell_interface xdgImpl = {
69   XdgShellClientDestroy,
70   XdgShellClientUseUnstableVersion,
71   XdgShellClientGetSurface,
72   XdgShellClientGetPopup,
73   XdgShellClientPong
74 };
75
76 static void XdgSurfaceDestroy( struct wl_client* client, struct wl_resource* resource )
77 {
78   wl_resource_destroy( resource );
79 }
80
81 static void XdgSurfaceSetParent( struct wl_client* client, struct wl_resource* resource, struct wl_resource* parentResource )
82 {
83 }
84
85 static void XdgSurfaceSetTitle( struct wl_client* client, struct wl_resource* resource, const char* title )
86 {
87   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
88
89   shellClient->SetTitle( title );
90 }
91
92 static void XdgSurfaceSetAppId( struct wl_client* client, struct wl_resource* resource, const char* appId )
93 {
94   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
95
96   shellClient->SetAppId( appId );
97 }
98
99 static void XdgSurfaceShowWindowMenu( struct wl_client* client, struct wl_resource* surfaceResource, struct wl_resource* seatResource, uint32_t serial, int32_t x, int32_t y )
100 {
101 }
102
103 static void XdgSurfaceMove( struct wl_client* client, struct wl_resource* resource, struct wl_resource* seatResource, uint32_t serial )
104 {
105 }
106
107 static void XdgSurfaceResize( struct wl_client* client, struct wl_resource* resource, struct wl_resource* seatResource, uint32_t serial, uint32_t edges )
108 {
109 }
110
111 static void XdgSurfaceAckConfigure( struct wl_client* client, struct wl_resource* resource, uint32_t serial )
112 {
113   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
114
115   shellClient->AckConfigure();
116 }
117
118 static void XdgSurfaceSetWindowGeometry( struct wl_client* client, struct wl_resource* resource, int32_t x, int32_t y, int32_t width, int32_t height )
119 {
120 }
121
122 static void XdgSurfaceSetMaximized( struct wl_client* client, struct wl_resource* resource )
123 {
124 }
125
126 static void XdgSurfaceUnsetMaximized( struct wl_client* client, struct wl_resource* resource )
127 {
128 }
129
130 static void XdgSurfaceSetFullScreen( struct wl_client* client, struct wl_resource* resource, struct wl_resource* outputResource )
131 {
132 }
133
134 static void XdgSurfaceUnsetFullScreen( struct wl_client* client, struct wl_resource* resource )
135 {
136 }
137
138 static void XdgSurfaceSetMinimized( struct wl_client* client, struct wl_resource* resource )
139 {
140 }
141
142 static const struct xdg_surface_interface xdgSurfaceImplementation =
143 {
144    XdgSurfaceDestroy,
145    XdgSurfaceSetParent,
146    XdgSurfaceSetTitle,
147    XdgSurfaceSetAppId,
148    XdgSurfaceShowWindowMenu,
149    XdgSurfaceMove,
150    XdgSurfaceResize,
151    XdgSurfaceAckConfigure,
152    XdgSurfaceSetWindowGeometry,
153    XdgSurfaceSetMaximized,
154    XdgSurfaceUnsetMaximized,
155    XdgSurfaceSetFullScreen,
156    XdgSurfaceUnsetFullScreen,
157    XdgSurfaceSetMinimized,
158 };
159
160 } // unnamed namespace
161
162 ShellClientPtr ShellClient::New( Pepper::Compositor compositor, struct wl_client* client, uint32_t version, uint32_t id )
163 {
164   ShellClientPtr impl = new ShellClient();
165
166   // Second-phase init of the implementation
167   impl->Initialize( compositor, client, version, id );
168
169   return impl;
170 }
171
172 ShellClient::ShellClient()
173 : mClient( NULL ),
174   mSurfaceResource( NULL ),
175   mSurface( NULL ),
176   mView( NULL ),
177   mSurfaceDestroyListener( NULL ),
178   mSurfaceCommitListener( NULL ),
179   mTitle(),
180   mAppId(),
181   mNeedSurfaceMap( false ),
182   mAckConfigure( false ),
183   mConfigureCallback( NULL ),
184   mConfigureCallbackData( NULL ),
185   mWidth( 0 ),
186   mHeight( 0 )
187 {
188 }
189
190 ShellClient::~ShellClient()
191 {
192   if( mClient )
193   {
194     wl_resource_destroy( mClient );
195   }
196
197   if( mSurfaceResource )
198   {
199     wl_resource_destroy( mSurfaceResource );
200   }
201
202   if( mView )
203   {
204     pepper_view_destroy( mView );
205   }
206 }
207
208 void ShellClient::Initialize( Pepper::Compositor compositor, struct wl_client* client, uint32_t version, uint32_t id )
209 {
210   mCompositor = compositor;
211
212   mClient = wl_resource_create( client, &xdg_shell_interface, version, id );
213   if( !mClient )
214   {
215     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "ShellClient::Initialize: wl_resource_create is failed\n" );
216     return;
217   }
218
219   wl_resource_set_implementation( mClient, &xdgImpl, this, NULL );
220
221   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::Initialize: success\n" );
222 }
223
224 void ShellClient::Configure( int width, int height, ConfigureCallback callback, void* data )
225 {
226   struct wl_display* display;
227   struct wl_array states;
228   uint32_t *state;
229   uint32_t serial;
230
231   wl_array_init( &states );
232
233   state = (uint32_t*)wl_array_add( &states, sizeof( uint32_t ) );
234   *state = XDG_SURFACE_STATE_ACTIVATED; // this is arbitary.
235
236   display = pepper_compositor_get_display( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ) );
237   serial = wl_display_next_serial( display );
238
239   xdg_surface_send_configure( mSurfaceResource, width, height, &states, serial );
240
241   wl_array_release( &states );
242
243   mAckConfigure = false;
244
245   mWidth = width;
246   mHeight = height;
247   mConfigureCallback = callback;
248   mConfigureCallbackData = data;
249 }
250
251 void ShellClient::AckConfigure()
252 {
253   mAckConfigure = true;
254
255   if( mConfigureCallback )
256   {
257     mConfigureCallback( mConfigureCallbackData, mWidth, mHeight );
258
259     mConfigureCallback = NULL;
260     mConfigureCallbackData = NULL;
261   }
262 }
263
264 pepper_view_t* ShellClient::GetView()
265 {
266   return mView;
267 }
268
269 void ShellClient::GetSurface( wl_client* client, unsigned int id, wl_resource* surfaceResource )
270 {
271   mSurface = static_cast< pepper_surface_t* >( wl_resource_get_user_data( surfaceResource ) );
272
273   mSurfaceResource = wl_resource_create( client, &xdg_surface_interface, 1, id );
274   if( !mSurfaceResource )
275   {
276     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "ShellClient::GetSurface: wl_resource_create is failed\n" );
277     return;
278   }
279
280   mView = pepper_compositor_add_view( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ) );
281   if( !mView )
282   {
283     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_compositor_add_view is failed\n" );
284     wl_client_post_no_memory( client );
285     return;
286   }
287
288   if( !pepper_view_set_surface( mView, mSurface ) )
289   {
290     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_view_set_surface is failed\n" );
291     wl_client_post_no_memory( client );
292     return;
293   }
294
295   wl_resource_set_implementation( mSurfaceResource, &xdgSurfaceImplementation, this, ShellClient::SurfaceResourceDestroy );
296
297   mSurfaceDestroyListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_OBJECT_DESTROY, 0, ShellClient::OnSurfaceDestroy, this );
298
299   mSurfaceCommitListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_SURFACE_COMMIT, 0, ShellClient::OnSurfaceCommit, this );
300
301   mNeedSurfaceMap = true;
302
303   pepper_surface_set_role( mSurface, "xdg_surface" );
304
305   pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( mSurface ), pepper_surface_get_role( mSurface ), this, NULL );
306
307   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::GetSurface: success. surface = %p\n", mSurface );
308 }
309
310 void ShellClient::SetTitle( const std::string& title )
311 {
312   mTitle = title;
313 }
314
315 const std::string& ShellClient::GetTitle() const
316 {
317   return mTitle;
318 }
319
320 void ShellClient::SetAppId( const std::string& appId )
321 {
322   mAppId = appId;
323 }
324
325 const std::string& ShellClient::GetAppId() const
326 {
327   return mAppId;
328 }
329
330 void ShellClient::MapSurface()
331 {
332   if( !mNeedSurfaceMap )
333   {
334     pepper_view_map( mView );
335     mNeedSurfaceMap = true;
336
337     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::MapSurface: view is mapped.\n" );
338   }
339 }
340
341 void ShellClient::UnmapSurface()
342 {
343   if( mNeedSurfaceMap )
344   {
345     pepper_view_unmap( mView );
346     mNeedSurfaceMap = false;
347
348     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::UnmapSurface: view is unmapped.\n" );
349   }
350 }
351
352 void ShellClient::SurfaceResourceDestroy( struct wl_resource* resource )
353 {
354   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
355
356   pepper_event_listener_remove( shellClient->mSurfaceDestroyListener );
357
358   if( !shellClient->mTitle.empty() )
359   {
360     shellClient->mTitle.clear();
361   }
362
363   if( !shellClient->mAppId.empty() )
364   {
365     shellClient->mAppId.clear();
366   }
367
368   if( shellClient->mSurface )
369   {
370     pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( shellClient->mSurface ), pepper_surface_get_role( shellClient->mSurface ), NULL, NULL );
371   }
372
373   shellClient->mSurfaceResource = NULL;
374
375   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::SurfaceResourceDestroy: surface = %p\n", shellClient->mSurface );
376 }
377
378 void ShellClient::OnSurfaceDestroy( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
379 {
380   ShellClient* shellClient = static_cast< ShellClient* >( data );
381
382   shellClient->mSurface = NULL;
383
384   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceDestroy: surface = %p\n", surface );
385 }
386
387 void ShellClient::OnSurfaceCommit( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
388 {
389   ShellClient* shellClient = static_cast< ShellClient* >( data );
390
391   if( shellClient->mNeedSurfaceMap && !pepper_view_is_mapped( shellClient->mView ) )
392   {
393     pepper_view_map( shellClient->mView );
394
395     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceCommit: view is mapped.\n" );
396   }
397 }
398
399 } // namespace Internal
400
401 } // namespace Pepper
402
403 } // namespace Dali