2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <pepper-dali/internal/shell-client-impl.h>
22 #include <pepper-dali/internal/compositor-impl.h>
25 #include <dali/integration-api/debug.h>
26 #include <xdg-shell-server-protocol.h>
40 #if defined(DEBUG_ENABLED)
41 Integration::Log::Filter* gPepperShellClientLogging = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_SHELL_CLIENT" );
44 static void XdgShellClientDestroy( struct wl_client* client, struct wl_resource* resource)
48 static void XdgShellClientUseUnstableVersion( struct wl_client* client, struct wl_resource* resource, int32_t version )
52 static void XdgShellClientGetSurface( struct wl_client* client, struct wl_resource* resource, uint32_t id, struct wl_resource* surfaceResource )
54 ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
56 shellClient->GetSurface( client, id, surfaceResource );
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 )
64 static void XdgShellClientPong( struct wl_client* client, struct wl_resource* resource, uint32_t serial )
68 static const struct xdg_shell_interface xdgImpl = {
69 XdgShellClientDestroy,
70 XdgShellClientUseUnstableVersion,
71 XdgShellClientGetSurface,
72 XdgShellClientGetPopup,
76 static void XdgSurfaceDestroy( struct wl_client* client, struct wl_resource* resource )
78 wl_resource_destroy( resource );
81 static void XdgSurfaceSetParent( struct wl_client* client, struct wl_resource* resource, struct wl_resource* parentResource )
85 static void XdgSurfaceSetTitle( struct wl_client* client, struct wl_resource* resource, const char* title )
87 ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
89 shellClient->SetTitle( title );
92 static void XdgSurfaceSetAppId( struct wl_client* client, struct wl_resource* resource, const char* appId )
94 ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
96 shellClient->SetAppId( appId );
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 )
103 static void XdgSurfaceMove( struct wl_client* client, struct wl_resource* resource, struct wl_resource* seatResource, uint32_t serial )
107 static void XdgSurfaceResize( struct wl_client* client, struct wl_resource* resource, struct wl_resource* seatResource, uint32_t serial, uint32_t edges )
111 static void XdgSurfaceAckConfigure( struct wl_client* client, struct wl_resource* resource, uint32_t serial )
113 ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
115 shellClient->AckConfigure();
118 static void XdgSurfaceSetWindowGeometry( struct wl_client* client, struct wl_resource* resource, int32_t x, int32_t y, int32_t width, int32_t height )
122 static void XdgSurfaceSetMaximized( struct wl_client* client, struct wl_resource* resource )
126 static void XdgSurfaceUnsetMaximized( struct wl_client* client, struct wl_resource* resource )
130 static void XdgSurfaceSetFullScreen( struct wl_client* client, struct wl_resource* resource, struct wl_resource* outputResource )
134 static void XdgSurfaceUnsetFullScreen( struct wl_client* client, struct wl_resource* resource )
138 static void XdgSurfaceSetMinimized( struct wl_client* client, struct wl_resource* resource )
142 static const struct xdg_surface_interface xdgSurfaceImplementation =
148 XdgSurfaceShowWindowMenu,
151 XdgSurfaceAckConfigure,
152 XdgSurfaceSetWindowGeometry,
153 XdgSurfaceSetMaximized,
154 XdgSurfaceUnsetMaximized,
155 XdgSurfaceSetFullScreen,
156 XdgSurfaceUnsetFullScreen,
157 XdgSurfaceSetMinimized,
160 } // unnamed namespace
162 ShellClientPtr ShellClient::New( Pepper::Compositor compositor, struct wl_client* client, uint32_t version, uint32_t id )
164 ShellClientPtr impl = new ShellClient();
166 // Second-phase init of the implementation
167 impl->Initialize( compositor, client, version, id );
172 ShellClient::ShellClient()
174 mSurfaceResource( NULL ),
177 mSurfaceDestroyListener( NULL ),
178 mSurfaceCommitListener( NULL ),
181 mNeedSurfaceMap( false ),
182 mAckConfigure( false ),
183 mConfigureCallback( NULL ),
184 mConfigureCallbackData( NULL ),
190 ShellClient::~ShellClient()
194 wl_resource_destroy( mClient );
197 if( mSurfaceResource )
199 wl_resource_destroy( mSurfaceResource );
204 pepper_view_destroy( mView );
208 void ShellClient::Initialize( Pepper::Compositor compositor, struct wl_client* client, uint32_t version, uint32_t id )
210 mCompositor = compositor;
212 mClient = wl_resource_create( client, &xdg_shell_interface, version, id );
215 DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "ShellClient::Initialize: wl_resource_create is failed\n" );
219 wl_resource_set_implementation( mClient, &xdgImpl, this, NULL );
221 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::Initialize: success\n" );
224 void ShellClient::Configure( int width, int height, ConfigureCallback callback, void* data )
226 struct wl_display* display;
227 struct wl_array states;
231 wl_array_init( &states );
233 state = (uint32_t*)wl_array_add( &states, sizeof( uint32_t ) );
234 *state = XDG_SURFACE_STATE_ACTIVATED; // this is arbitary.
236 display = pepper_compositor_get_display( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ) );
237 serial = wl_display_next_serial( display );
239 xdg_surface_send_configure( mSurfaceResource, width, height, &states, serial );
241 wl_array_release( &states );
243 mAckConfigure = false;
247 mConfigureCallback = callback;
248 mConfigureCallbackData = data;
251 void ShellClient::AckConfigure()
253 mAckConfigure = true;
255 if( mConfigureCallback )
257 mConfigureCallback( mConfigureCallbackData, mWidth, mHeight );
259 mConfigureCallback = NULL;
260 mConfigureCallbackData = NULL;
264 pepper_view_t* ShellClient::GetView()
269 void ShellClient::GetSurface( wl_client* client, unsigned int id, wl_resource* surfaceResource )
271 mSurface = static_cast< pepper_surface_t* >( wl_resource_get_user_data( surfaceResource ) );
273 mSurfaceResource = wl_resource_create( client, &xdg_surface_interface, 1, id );
275 mView = pepper_compositor_add_view( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ) );
278 DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_compositor_add_view is failed\n" );
279 wl_client_post_no_memory( client );
283 if( !pepper_view_set_surface( mView, mSurface ) )
285 DALI_LOG_INFO( gPepperShellClientLogging, Debug::General, "pepper_view_set_surface is failed\n" );
286 wl_client_post_no_memory( client );
290 wl_resource_set_implementation( mSurfaceResource, &xdgSurfaceImplementation, this, ShellClient::SurfaceResourceDestroy );
292 mSurfaceDestroyListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_OBJECT_DESTROY, 0, ShellClient::OnSurfaceDestroy, this );
294 mSurfaceCommitListener = pepper_object_add_event_listener( reinterpret_cast< pepper_object_t* >( mSurface ), PEPPER_EVENT_SURFACE_COMMIT, 0, ShellClient::OnSurfaceCommit, this );
296 mNeedSurfaceMap = true;
298 pepper_surface_set_role( mSurface, "xdg_surface" );
300 pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( mSurface ), pepper_surface_get_role( mSurface ), this, NULL );
302 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::GetSurface: success. surface = %p\n", mSurface );
305 void ShellClient::SetTitle( const std::string& title )
310 const std::string& ShellClient::GetTitle() const
315 void ShellClient::SetAppId( const std::string& appId )
320 const std::string& ShellClient::GetAppId() const
325 void ShellClient::MapSurface()
327 if( !mNeedSurfaceMap )
329 pepper_view_map( mView );
330 mNeedSurfaceMap = true;
332 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::MapSurface: view is mapped.\n" );
336 void ShellClient::UnmapSurface()
338 if( mNeedSurfaceMap )
340 pepper_view_unmap( mView );
341 mNeedSurfaceMap = false;
343 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::UnmapSurface: view is unmapped.\n" );
347 void ShellClient::SurfaceResourceDestroy( struct wl_resource* resource )
349 ShellClient* shellClient = static_cast< ShellClient* >( wl_resource_get_user_data( resource ) );
351 pepper_event_listener_remove( shellClient->mSurfaceDestroyListener );
353 if( !shellClient->mTitle.empty() )
355 shellClient->mTitle.clear();
358 if( !shellClient->mAppId.empty() )
360 shellClient->mAppId.clear();
363 if( shellClient->mSurface )
365 pepper_object_set_user_data( reinterpret_cast< pepper_object_t* >( shellClient->mSurface ), pepper_surface_get_role( shellClient->mSurface ), NULL, NULL );
368 shellClient->mSurfaceResource = NULL;
370 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::SurfaceResourceDestroy: surface = %p\n", shellClient->mSurface );
373 void ShellClient::OnSurfaceDestroy( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
375 ShellClient* shellClient = static_cast< ShellClient* >( data );
377 shellClient->mSurface = NULL;
379 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceDestroy: surface = %p\n", surface );
382 void ShellClient::OnSurfaceCommit( pepper_event_listener_t* listener, pepper_object_t* surface, uint32_t id, void* info, void* data )
384 ShellClient* shellClient = static_cast< ShellClient* >( data );
386 if( shellClient->mNeedSurfaceMap && !pepper_view_is_mapped( shellClient->mView ) )
388 pepper_view_map( shellClient->mView );
390 DALI_LOG_INFO( gPepperShellClientLogging, Debug::Verbose, "ShellClient::OnSurfaceCommit: view is mapped.\n" );
394 } // namespace Internal
396 } // namespace Pepper