Support GL Client
[platform/core/uifw/pepper-dali.git] / pepper-dali / internal / object-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/object-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <pepper-dali/internal/shell-client-impl.h>
23 #include <pepper-dali/internal/object-view-impl.h>
24
25 // EXTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/images/buffer-image.h>
28 #include <dali/public-api/events/touch-event.h>
29 #include <dali/public-api/adaptor-framework/native-image-source.h>
30 #include <wayland-tbm-server.h>
31
32 namespace Dali
33 {
34
35 namespace Pepper
36 {
37
38 namespace Internal
39 {
40
41 namespace
42 {
43
44 #if defined(DEBUG_ENABLED)
45 Integration::Log::Filter* gPepperObjectLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_OBJECT" );
46 #endif
47
48 } // unnamed namespace
49
50 ObjectPtr Object::New( pepper_surface_t* surface, Pepper::Input input )
51 {
52   ObjectPtr impl = new Object();
53
54   // Second-phase init of the implementation
55   impl->Initialize( surface, input );
56
57   return impl;
58 }
59
60 Object::Object()
61 : mSurface( NULL ),
62   mBuffer( NULL ),
63   mPointer( NULL ),
64   mKeyboard( NULL ),
65   mTouch( NULL ),
66   mShmBuffer( NULL ),
67   mTbmSurface( 0 ),
68   mSurfaceDestroyListener( NULL ),
69   mBufferDestroyListener( NULL ),
70   mWidth( 0 ),
71   mHeight( 0 )
72 {
73 }
74
75 Object::~Object()
76 {
77   if( mBuffer )
78   {
79     pepper_buffer_unreference( mBuffer );
80     pepper_event_listener_remove( mBufferDestroyListener );
81   }
82
83   if( mSurfaceDestroyListener )
84   {
85     pepper_event_listener_remove( mSurfaceDestroyListener );
86   }
87 }
88
89 void Object::Initialize( pepper_surface_t* surface, Pepper::Input input )
90 {
91   mSurface = surface;
92
93   mPointer = input.GetPointer();
94   mKeyboard = input.GetKeyboard();
95   mTouch = input.GetTouch();
96
97   mSurfaceDestroyListener = pepper_object_add_event_listener( (pepper_object_t*)surface, PEPPER_EVENT_OBJECT_DESTROY, 0, Object::OnDestroySurface, this );
98
99   DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::Initialize: success\n" );
100 }
101
102 bool Object::AttchBuffer( int* width, int* height )
103 {
104   pepper_buffer_t* buffer;
105   wl_resource* bufferResource;
106   wl_shm_buffer* shmBuffer = NULL;
107   tbm_surface_h tbmSurface = NULL;
108   int bufWidth, bufHeight;
109
110   buffer = pepper_surface_get_buffer( mSurface );
111   if( !buffer )
112   {
113     DALI_LOG_INFO( gPepperObjectLogging, Debug::General, "Object::AttchBuffer: pepper_surface_get_buffer is failed\n" );
114     return false;
115   }
116
117   if( mBuffer )
118   {
119     pepper_buffer_unreference( mBuffer );
120     pepper_event_listener_remove( mBufferDestroyListener );
121   }
122
123   pepper_buffer_reference( buffer );
124
125   mBuffer = buffer;
126   mBufferDestroyListener = pepper_object_add_event_listener( (pepper_object_t*)buffer, PEPPER_EVENT_OBJECT_DESTROY, 0, Object::OnDestroyBuffer, this );
127
128   bufferResource = pepper_buffer_get_resource( buffer );
129
130   if( !mObjectView )
131   {
132     mObjectView = Pepper::ObjectView::New();
133
134     mObjectView.TouchedSignal().Connect( this, &Object::OnTouched );
135
136     // Set surface
137     Pepper::GetImplementation( mObjectView ).SetSurface( mSurface );
138
139     // TODO: support multi touch, focus in/out, mouse in/out
140
141     // TODO: resize callback
142
143     Pepper::Object handle( this );
144     mObjectViewAddedSignal.Emit( handle, mObjectView );
145   }
146
147   shmBuffer = wl_shm_buffer_get( bufferResource );
148   if( shmBuffer )
149   {
150     bufWidth = wl_shm_buffer_get_width( shmBuffer );
151     bufHeight = wl_shm_buffer_get_height( shmBuffer );
152
153     if( shmBuffer != mShmBuffer )
154     {
155       // create a new image
156       PixelBuffer* pixelBuffer = static_cast< PixelBuffer* >( wl_shm_buffer_get_data( shmBuffer ) );
157       mBufferImage = BufferImage::New( pixelBuffer, bufWidth, bufHeight );
158
159       mObjectView.SetImage( mBufferImage );
160
161       mShmBuffer = shmBuffer;
162     }
163   }
164   else
165   {
166     tbmSurface = wayland_tbm_server_get_surface( NULL, bufferResource );
167     if( tbmSurface )
168     {
169       bufWidth = tbm_surface_get_width( tbmSurface );
170       bufHeight = tbm_surface_get_height( tbmSurface );
171
172       if ( tbmSurface != mTbmSurface )
173       {
174         // create a new image
175         NativeImageSourcePtr nativeImageSource = NativeImageSource::New( tbmSurface );
176         mNativeImage = NativeImage::New( *nativeImageSource );
177
178         mObjectView.SetImage( mNativeImage );
179
180         mTbmSurface = tbmSurface;
181       }
182     }
183     else
184     {
185       DALI_LOG_INFO( gPepperObjectLogging, Debug::General, "Object::AttchBuffer: Failed to get buffer\n" );
186       return false;
187     }
188   }
189
190   if( ( mWidth != bufWidth ) || ( mHeight != bufHeight ) )
191   {
192     mWidth = bufWidth;
193     mHeight = bufHeight;
194
195     // resize actor
196     mObjectView.SetSize( mWidth, mHeight );
197   }
198
199   if( width )
200   {
201     *width = bufWidth;
202   }
203
204   if( height )
205   {
206     *height = bufHeight;
207   }
208
209   DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::AttchBuffer: this = %p, width = %d, height = %d", this, bufWidth, bufHeight );
210
211   return true;
212 }
213
214 Pepper::Object::ObjectSignalType& Object::ObjectViewAddedSignal()
215 {
216   return mObjectViewAddedSignal;
217 }
218
219 Pepper::Object::ObjectSignalType& Object::ObjectViewDeletedSignal()
220 {
221   return mObjectViewDeletedSignal;
222 }
223
224 bool Object::OnTouched( Actor actor, const TouchEvent& touchEvent )
225 {
226   const TouchPoint& point = touchEvent.GetPoint(0);
227
228   Pepper::Internal::ShellClientPtr shellClient = reinterpret_cast< Pepper::Internal::ShellClient* >( pepper_object_get_user_data( reinterpret_cast< pepper_object_t* >( mSurface ), pepper_surface_get_role( mSurface ) ) );
229   if( !shellClient )
230   {
231     DALI_LOG_INFO( gPepperObjectLogging, Debug::General, "Object::OnTouched: shellClient is null. mSurface = %p\n", mSurface );
232     return false;
233   }
234
235   switch( point.state )
236   {
237     case TouchPoint::Down:
238     {
239       pepper_touch_add_point( mTouch, point.deviceId, point.local.x, point.local.y );
240       pepper_touch_send_down( mTouch, shellClient->GetView(), touchEvent.time, point.deviceId, point.local.x, point.local.y );
241
242       DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::OnTouched: Touch Down (%.2f, %.2f) device = %d surface = %p\n", point.local.x, point.local.y, point.deviceId, mSurface );
243       return true;
244     }
245     case TouchPoint::Up:
246     {
247       pepper_touch_send_up( mTouch, shellClient->GetView(), touchEvent.time, point.deviceId );
248       pepper_touch_remove_point( mTouch, point.deviceId );
249
250       DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::OnTouched: Touch Up (%.2f, %.2f) surface = %p\n", point.local.x, point.local.y, mSurface );
251       return true;
252     }
253     case TouchPoint::Motion:
254     {
255       pepper_touch_send_motion( mTouch, shellClient->GetView(), touchEvent.time, point.deviceId, point.local.x, point.local.y );
256
257 //      DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::OnTouched: Touch Motion (%.2f, %.2f)\n", point.local.x, point.local.y );
258       return true;
259     }
260     default:
261     {
262       return false;
263     }
264   }
265
266   return false;
267 }
268
269 void Object::OnDestroySurface( pepper_event_listener_t* listener, pepper_object_t* pepperObject, uint32_t id, void* info, void* data )
270 {
271   Object* object = static_cast< Object* >( data );
272
273   Pepper::Object handle( object );
274   object->mObjectViewDeletedSignal.Emit( handle, object->mObjectView );
275
276   object->mSurface = NULL;
277   object->mTbmSurface = NULL;
278
279   if( object->mSurfaceDestroyListener )
280   {
281     pepper_event_listener_remove( object->mSurfaceDestroyListener );
282   }
283 }
284
285 void Object::OnDestroyBuffer( pepper_event_listener_t* listener, pepper_object_t* pepperObject, uint32_t id, void* info, void* data )
286 {
287   Object* object = static_cast< Object* >( data );
288
289   if( object->mBuffer )
290   {
291     pepper_buffer_unreference( object->mBuffer );
292     pepper_event_listener_remove( object->mBufferDestroyListener );
293   }
294
295 #if 0
296   if( object->mShmBuffer )
297   {
298     void* shmData = wl_shm_buffer_get_data( object->mShmBuffer );
299
300     object->mBufferImage = BufferImage::New( object->mWidth, object->mHeight );
301
302     PixelBuffer* buffer = object->mBufferImage.GetBuffer();
303     memcpy(buffer, shmData, object->mWidth * object->mHeight * 4);
304
305     object->mBufferImage.Update();
306
307     object->mObjectView.SetImage( object->mBufferImage );
308   }
309   else if( object->mTbmSurface )
310   {
311   }
312 #endif
313 }
314
315 } // namespace Internal
316
317 } // namespace Pepper
318
319 } // namespace Dali