Add pepper-dali
[platform/core/uifw/pepper-dali.git] / pepper-dali / internal / compositor-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/compositor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <wayland-server.h>
24 #include <tizen-extension-client-protocol.h>
25 #include <Ecore_Wayland.h>
26
27 namespace Dali
28 {
29
30 namespace Pepper
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 #if defined(DEBUG_ENABLED)
40 Integration::Log::Filter* gPepperCompositorLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_COMPOSITOR" );
41 #endif
42
43 static void EmbeddedCompositorGetSocket( void* data, struct tizen_embedded_compositor* embeddedCompositor, int fd )
44 {
45   int* socketFd = (int*)data;
46
47   *socketFd = fd;
48   return;
49 }
50
51 static const struct tizen_embedded_compositor_listener tizenEmbeddedCompositorListener =
52 {
53   EmbeddedCompositorGetSocket
54 };
55
56 } // unnamed namespace
57
58 CompositorPtr Compositor::New( Application application, const std::string& name )
59 {
60   CompositorPtr impl = new Compositor();
61
62   // Second-phase init of the implementation
63   impl->Initialize( application, name );
64
65   return impl;
66 }
67
68 Compositor::Compositor()
69 : mCompositor( NULL ),
70   mDisplay( NULL ),
71   mEventLoop( NULL ),
72   mFdHandler( NULL ),
73   mTbmServer( NULL ),
74   mShell( NULL ),
75   mInput( NULL ),
76   mOutput( NULL ),
77   mSocketName()
78 {
79 }
80
81 Compositor::~Compositor()
82 {
83   if( mTbmServer )
84   {
85     wayland_tbm_server_deinit( mTbmServer );
86   }
87
88   if( mCompositor )
89   {
90     pepper_compositor_destroy( mCompositor );
91   }
92
93   if( mFdHandler )
94   {
95     ecore_main_fd_handler_del( mFdHandler );
96   }
97 }
98
99 void* Compositor::GetCompositorHandle()
100 {
101   return static_cast< void* >( mCompositor );
102 }
103
104 void Compositor::Initialize( Application application, const std::string& name )
105 {
106   // Get socket fd from server
107   int socketFd = GetSocketFdFromServer();
108   if( socketFd == -1 )
109   {
110     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: socket fd is invalid.\n" );
111     return;
112   }
113
114   // create compositor
115   mCompositor = pepper_compositor_create_fd( name.c_str(), socketFd );
116   if( !mCompositor )
117   {
118     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: pepper_compositor_create_fd is failed. [%d]\n", socketFd );
119     return;
120   }
121
122   mDisplay = pepper_compositor_get_display( mCompositor );
123
124 #if 0
125   mTbmServer = wayland_tbm_server_init( mDisplay, NULL, -1, 0 );
126   if( !mTbmServer )
127   {
128     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: wayland_tbm_server_init is failed.\n" );
129     pepper_compositor_destroy( mCompositor );
130     mCompositor = NULL;
131     return;
132   }
133 #endif
134
135   // create shell
136   mShell = Pepper::Shell::New( Pepper::Compositor( this ) );
137   if( !mShell )
138   {
139     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create shell.\n" );
140     wayland_tbm_server_deinit( mTbmServer );
141     mTbmServer = NULL;
142     pepper_compositor_destroy( mCompositor );
143     mCompositor = NULL;
144     return;
145   }
146
147   // create input
148   mInput = Pepper::Input::New( Pepper::Compositor( this ) );
149   if( !mInput )
150   {
151     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create input.\n" );
152     wayland_tbm_server_deinit( mTbmServer );
153     mTbmServer = NULL;
154     pepper_compositor_destroy( mCompositor );
155     mCompositor = NULL;
156     return;
157   }
158
159   mSocketName = pepper_compositor_get_socket_name( mCompositor );
160
161   mEventLoop = wl_display_get_event_loop( mDisplay );
162
163   int loopFd = wl_event_loop_get_fd( mEventLoop );
164
165   mFdHandler = ecore_main_fd_handler_add( loopFd, (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), Compositor::FdReadCallback, this, NULL, NULL );
166
167   ecore_main_fd_handler_prepare_callback_set( mFdHandler, Compositor::FdPrepareCallback, this );
168
169   // create output
170   mOutput = Pepper::Output::New( Pepper::Compositor( this ), application, mInput );
171   if( !mOutput )
172   {
173     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create output.\n" );
174
175     ecore_main_fd_handler_del( mFdHandler );
176     mFdHandler = NULL;
177     wayland_tbm_server_deinit( mTbmServer );
178     mTbmServer = NULL;
179     pepper_compositor_destroy( mCompositor );
180     mCompositor = NULL;
181     return;
182   }
183
184   mOutput.ObjectViewAddedSignal().Connect( this, &Compositor::OnObjectViewAdded );
185   mOutput.ObjectViewDeletedSignal().Connect( this, &Compositor::OnObjectViewDeleted );
186
187   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::Initialize: success. socket name = %s\n", mSocketName.c_str() );
188
189   // TODO: temp
190   setenv("WAYLAND_DISPLAY", mSocketName.c_str(), 1);
191 }
192
193 int Compositor::GetSocketFdFromServer()
194 {
195   Eina_Inlist* list;
196   Eina_Inlist* tmp;
197   Ecore_Wl_Global* global;
198   struct tizen_embedded_compositor* embeddedCompositor = NULL;
199   int fd = -1;
200
201   list = ecore_wl_globals_get();
202   if( !list )
203   {
204     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: ecore_wl_globals_get returns NULL.\n" );
205     return -1;
206   }
207
208   EINA_INLIST_FOREACH_SAFE( list, tmp, global )
209   {
210     if( !strcmp( global->interface, "tizen_embedded_compositor" ) )
211     {
212       embeddedCompositor = static_cast< struct tizen_embedded_compositor* >( wl_registry_bind( ecore_wl_registry_get(), global->id, &tizen_embedded_compositor_interface, 1 ) );
213
214       tizen_embedded_compositor_add_listener( embeddedCompositor, &tizenEmbeddedCompositorListener, &fd );
215       break;
216     }
217   }
218
219   if( !embeddedCompositor )
220   {
221     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: tizen_embedded_compositor is not supported.\n" );
222     return -1;
223   }
224
225   tizen_embedded_compositor_get_socket( embeddedCompositor );
226   ecore_wl_sync();
227
228   tizen_embedded_compositor_destroy( embeddedCompositor );
229
230   return fd;
231 }
232
233 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewAddedSignal()
234 {
235   return mObjectViewAddedSignal;
236 }
237
238 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewDeletedSignal()
239 {
240   return mObjectViewDeletedSignal;
241 }
242
243 void Compositor::OnObjectViewAdded( Pepper::Output output, Pepper::ObjectView objectView )
244 {
245   Pepper::Compositor handle( this );
246   mObjectViewAddedSignal.Emit( handle, objectView );
247
248   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewAddedSignal: ObjectView is added!\n" );
249 }
250
251 void Compositor::OnObjectViewDeleted( Pepper::Output output, Pepper::ObjectView objectView )
252 {
253   Pepper::Compositor handle( this );
254   mObjectViewDeletedSignal.Emit( handle, objectView );
255
256   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewDeletedSignal: ObjectView is deleted!\n" );
257 }
258
259 Eina_Bool Compositor::FdReadCallback( void* data, Ecore_Fd_Handler* handler )
260 {
261   Compositor* compositor = static_cast< Compositor* >( data );
262
263   wl_event_loop_dispatch( compositor->mEventLoop, 0 );
264
265   return ECORE_CALLBACK_RENEW;
266 }
267
268 void Compositor::FdPrepareCallback( void* data, Ecore_Fd_Handler* handler )
269 {
270   Compositor* compositor = static_cast< Compositor* >( data );
271
272   wl_display_flush_clients( compositor->mDisplay );
273 }
274
275 } // namespace Internal
276
277 } // namespace Pepper
278
279 } // namespace Dali