f57ee5ae2ddbd1db7761f74c5a414bf1e3260d84
[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
275   mView = pepper_compositor_add_view( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ) );
276   if( !mView )
277   {
278     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_compositor_add_view is failed\n" );
279     wl_client_post_no_memory( client );
280     return;
281   }
282
283   if( !pepper_view_set_surface( mView, mSurface ) )
284   {
285     DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_view_set_surface is failed\n" );
286     wl_client_post_no_memory( client );
287     return;
288   }
289
290   wl_resource_set_implementation( mSurfaceResource, &xdgSurfaceImplementation, this, ShellClient::SurfaceResourceDestroy );
291
292   mSurfaceDestroyListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_OBJECT_DESTROY, 0, ShellClient::OnSurfaceDestroy, this );
293
294   mSurfaceCommitListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_SURFACE_COMMIT, 0, ShellClient::OnSurfaceCommit, this );
295
296   mNeedSurfaceMap = true;
297
298   pepper_surface_set_role( mSurface, "xdg_surface" );
299
300   pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( mSurface ), pepper_surface_get_role( mSurface ), this, NULL );
301
302   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::GetSurface: success. surface = %p\n", mSurface );
303 }
304
305 void ShellClient::SetTitle( const std::string& title )
306 {
307   mTitle = title;
308 }
309
310 const std::string& ShellClient::GetTitle() const
311 {
312   return mTitle;
313 }
314
315 void ShellClient::SetAppId( const std::string& appId )
316 {
317   mAppId = appId;
318 }
319
320 const std::string& ShellClient::GetAppId() const
321 {
322   return mAppId;
323 }
324
325 void ShellClient::MapSurface()
326 {
327   if( !mNeedSurfaceMap )
328   {
329     pepper_view_map( mView );
330     mNeedSurfaceMap = true;
331
332     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::MapSurface: view is mapped.\n" );
333   }
334 }
335
336 void ShellClient::UnmapSurface()
337 {
338   if( mNeedSurfaceMap )
339   {
340     pepper_view_unmap( mView );
341     mNeedSurfaceMap = false;
342
343     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::UnmapSurface: view is unmapped.\n" );
344   }
345 }
346
347 void ShellClient::SurfaceResourceDestroy( struct wl_resource* resource )
348 {
349   ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
350
351   pepper_event_listener_remove( shellClient->mSurfaceDestroyListener );
352
353   if( !shellClient->mTitle.empty() )
354   {
355     shellClient->mTitle.clear();
356   }
357
358   if( !shellClient->mAppId.empty() )
359   {
360     shellClient->mAppId.clear();
361   }
362
363   if( shellClient->mSurface )
364   {
365     pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( shellClient->mSurface ), pepper_surface_get_role( shellClient->mSurface ), NULL, NULL );
366   }
367
368   shellClient->mSurfaceResource = NULL;
369
370   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::SurfaceResourceDestroy: surface = %p\n", shellClient->mSurface );
371 }
372
373 void ShellClient::OnSurfaceDestroy( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
374 {
375   ShellClient* shellClient = static_cast< ShellClient* >( data );
376
377   shellClient->mSurface = NULL;
378
379   DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceDestroy: surface = %p\n", surface );
380 }
381
382 void ShellClient::OnSurfaceCommit( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
383 {
384   ShellClient* shellClient = static_cast< ShellClient* >( data );
385
386   if( shellClient->mNeedSurfaceMap && !pepper_view_is_mapped( shellClient->mView ) )
387   {
388     pepper_view_map( shellClient->mView );
389
390     DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceCommit: view is mapped.\n" );
391   }
392 }
393
394 } // namespace Internal
395
396 } // namespace Pepper
397
398 } // namespace Dali