2 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
17 * @file FShell_AppWidgetLayer.cpp
18 * @brief This is the implementation file for the _AppWidgetLayer class.
26 #include <X11/extensions/XShm.h>
27 #include <X11/Xutil.h>
31 #include <provider_buffer.h>
32 #include <FBaseSysLog.h>
33 #include <FBase_StringConverter.h>
34 #include <FGrpRectangle.h>
35 #include "FUi_Window.h"
36 #include "FShell_AppWidgetBuffer.h"
37 #include "FShell_AppWidgetLayer.h"
38 #include "FShell_AppWidgetProviderManagerImpl.h"
40 //#define _BUFFER_TEST
43 using namespace Tizen::Base;
44 using namespace Tizen::Graphics;
45 using namespace Tizen::Ui::Animations;
46 using namespace Tizen::Ui;
47 using namespace Tizen::Shell;
53 AllocRenderBuffer(void* pData, int size)
55 _AppWidgetLayer* pAppWidgetLayer = static_cast<_AppWidgetLayer*>(pData);
56 SysTryReturn(NID_SHELL, pAppWidgetLayer, null, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
58 return pAppWidgetLayer->AllocCanvas(size);
62 FreeRenderBuffer(void* pData, void* pCanvas)
64 SysTryReturnVoidResult(NID_SHELL, pCanvas, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
66 _AppWidgetLayer* pAppWidgetLayer = static_cast<_AppWidgetLayer*>(pData);
67 SysTryReturnVoidResult(NID_SHELL, pAppWidgetLayer, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
69 pAppWidgetLayer->FreeCanvas(pCanvas);
73 PostRender(void* pData, Evas* pEvas, void* pEventInfo)
75 SysLog(NID_SHELL, "ENTER");
77 _AppWidgetLayer* pAppWidgetLayer = static_cast<_AppWidgetLayer*>(pData);
78 SysTryReturnVoidResult(NID_SHELL, pAppWidgetLayer, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
80 pAppWidgetLayer->OnRendered();
85 namespace Tizen { namespace Shell
88 _AppWidgetLayer::_AppWidgetLayer(const Tizen::Base::String& providerId, const FloatDimension& size)
93 , __providerId(providerId)
94 , __pRenderBuffer(null)
98 , __pAppWidgetBuffer(new (std::nothrow) _AppWidgetBuffer)
102 _AppWidgetLayer::~_AppWidgetLayer(void)
104 __pRenderBuffer = null;
105 __pTempBuffer = null;
110 _AppWidgetLayer::OnConstructed(void)
112 result r = E_SUCCESS;
114 __pAppWidgetBuffer->Initialize();
116 unique_ptr<Ecore_Evas, _EcoreEvasDeleter> pEcoreEvas(ecore_evas_buffer_allocfunc_new(__size.width, __size.height, AllocRenderBuffer, FreeRenderBuffer, this));
117 SysTryReturn(NID_SHELL, pEcoreEvas, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
119 ecore_evas_alpha_set(pEcoreEvas.get(), EINA_TRUE);
120 ecore_evas_manual_render_set(pEcoreEvas.get(), EINA_FALSE);
121 ecore_evas_resize(pEcoreEvas.get(), __size.width, __size.height);
122 ecore_evas_activate(pEcoreEvas.get());
124 Evas* pEvas = ecore_evas_get(pEcoreEvas.get());
125 SysTryReturn(NID_SHELL, pEvas, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
127 // evas_event_callback_add(pEvas, EVAS_CALLBACK_RENDER_POST, PostRender, this);
129 unique_ptr<Evas_Object, _EvasObjectDeleter> pEvasObject(evas_object_rectangle_add(pEvas));
130 SysTryReturn(NID_SHELL, pEvasObject, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
132 evas_object_resize(pEvasObject.get(), __size.width, __size.height);
133 evas_object_color_set(pEvasObject.get(), 0, 0, 0, 255);
135 r = Initialize(pEvasObject.get());
136 SysTryReturn(NID_SHELL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
138 __pEcoreEvas = move(pEcoreEvas);
139 __pEvasObject = move(pEvasObject);
141 ecore_evas_alpha_set(__pEcoreEvas.get(), EINA_TRUE);
142 evas_object_color_set(__pEvasObject.get(), 0, 0, 0, 0);
144 if (!__providerId.IsEmpty())
146 r = RegisterTouchEventListener();
147 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
154 _AppWidgetLayer::SetProviderId(const String& providerId)
156 __providerId = providerId;
158 __pixmapId = AcquirePixmap();
159 SysTryReturn(NID_SHELL, __pixmapId != -1, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
161 SysLog(NID_SHELL, "pixmapId (%d)", __pixmapId);
163 result r = RegisterTouchEventListener();
164 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
170 _AppWidgetLayer::GetProviderId(void) const
176 _AppWidgetLayer::GetPixmapId(void) const
182 _AppWidgetLayer::SetLayerBounds(const FloatRectangle& bounds)
184 __size = FloatDimension(bounds.width, bounds.height);
186 ecore_evas_resize(__pEcoreEvas.get(), __size.width, __size.height);
192 _AppWidgetLayer::AllocCanvas(int size)
194 SysTryReturn(NID_SHELL, size > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
197 void* pBuffer = null;
199 if (__providerId.IsEmpty())
201 __pTempBuffer = malloc(__bufferSize);
202 SysTryReturn(NID_SHELL, __pTempBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
204 pBuffer = __pTempBuffer;
208 if (__pixmapId == -1)
210 __pixmapId = AcquirePixmap();
211 SysTryReturn(NID_SHELL, __pixmapId != -1, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
214 __pRenderBuffer = __pAppWidgetBuffer->AllocBuffer(__pixmapId, __size);
215 pBuffer = __pRenderBuffer;
216 __pAppWidgetBuffer->UnlockBuffer();
219 SysLog(NID_SHELL, "buffer (0x%x 0x%x) size (%d) pixmap (%d)", __pTempBuffer, __pRenderBuffer, __bufferSize, __pixmapId);
221 __isReleased = false;
227 _AppWidgetLayer::FreeCanvas(void* pCanvas)
229 SysLog(NID_SHELL, "buffer (0x%x 0x%x 0x%x) size (%d)", __pTempBuffer, __pRenderBuffer, pCanvas, __bufferSize);
234 __pTempBuffer = null;
238 if (__pAppWidgetBuffer)
240 __pAppWidgetBuffer->DeallocBuffer();
251 __pRenderBuffer = null;
255 _AppWidgetLayer::SyncPixmap(const FloatDimension& size)
257 SysTryReturn(NID_SHELL, __pRenderBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
258 SysTryReturn(NID_SHELL, __pAppWidgetBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
260 SysLog(NID_SHELL, "buffer (0x%x) size (%d) pixmapId (%d) width(%f) height(%f)", __pRenderBuffer, __bufferSize, __pixmapId, size.width, size.height);
262 XShmPutImage(__pAppWidgetBuffer->GetDisplay(), static_cast<Pixmap>(__pixmapId), __pAppWidgetBuffer->GetGc(), __pAppWidgetBuffer->GetXImage(), 0, 0, 0, 0, size.width, size.height, False);
263 XSync(__pAppWidgetBuffer->GetDisplay(), False);
269 _AppWidgetLayer::OnRendered(void)
271 result r = E_SUCCESS;
273 if (!__pAppWidgetBuffer->IsGemBufferEnabled())
275 if (__pixmapId == -1)
277 __pixmapId = AcquirePixmap();
278 SysTryReturnVoidResult(NID_SHELL, __pixmapId >= 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
281 r = SyncPixmap(__size);
282 SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
286 SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
290 _AppWidgetLayer::RegisterTouchEventListener(void)
292 result r = _AppWidgetProviderManagerImpl::GetInstance()->SetAppWidgetTouchEventListener(__providerId, *this);
293 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
299 _AppWidgetLayer::AcquirePixmap(void)
301 SysTryReturn(NID_SHELL, !__providerId.IsEmpty(), -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
305 result r = _AppWidgetProviderManagerImpl::GetInstance()->RequestSharedMemoryId(__providerId, __size.width, __size.height, pixmapId);
306 SysTryReturn(NID_SHELL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
308 SysLog(NID_SHELL, "pixmapId(%d) size(%f %f)", pixmapId, __size.width, __size.height);
314 _AppWidgetLayer::Sync(const FloatDimension& size)
316 SysTryReturn(NID_SHELL, !__providerId.IsEmpty(), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
318 result r = _AppWidgetProviderManagerImpl::GetInstance()->RequestSyncSharedMemory(__providerId, size.width, size.height);
319 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
325 _AppWidgetLayer::ReleasePixmap(void)
327 SysTryReturnVoidResult(NID_SHELL, !__providerId.IsEmpty(), E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
329 _AppWidgetProviderManagerImpl::GetInstance()->RequestReleaseSharedMemory(__providerId);
333 _AppWidgetLayer::OnTouchEventRecevied(int eventType, double timestamp, double x, double y)
335 SysLog(NID_SHELL, "eventType (%d) timestamp (%f) (%f, %f)", eventType, timestamp, x, y);
337 int xPos = __size.width * x;
338 int yPos = __size.height * y;
340 Evas* pEvas = ecore_evas_get(__pEcoreEvas.get());
341 SysTryReturn(NID_SHELL, pEvas, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
345 case BUFFER_EVENT_ENTER:
346 evas_event_feed_mouse_in(pEvas, timestamp, null);
349 case BUFFER_EVENT_LEAVE:
350 evas_event_feed_mouse_out(pEvas, timestamp, null);
353 case BUFFER_EVENT_DOWN:
354 evas_event_feed_mouse_in(pEvas, timestamp, null);
355 evas_event_feed_mouse_move(pEvas, xPos, yPos, timestamp + 0.01f, null);
356 evas_event_feed_mouse_down(pEvas, 1, EVAS_BUTTON_NONE, timestamp + 0.02f, null);
359 case BUFFER_EVENT_MOVE:
360 evas_event_feed_mouse_move(pEvas, xPos, yPos, timestamp, null);
363 case BUFFER_EVENT_UP:
364 evas_event_feed_mouse_up(pEvas, 1, EVAS_BUTTON_NONE, timestamp, null);
365 evas_event_feed_mouse_out(pEvas, timestamp + 0.01f, null);
376 _AppWidgetLayer::Flush(void)
378 SysLog(NID_SHELL, "ENTER");
380 bool needed = IsFlushNeeded();
384 __pAppWidgetBuffer->LockBuffer();
386 Evas* pEvas = ecore_evas_get(__pEcoreEvas.get());
387 SysTryReturnVoidResult(NID_SHELL, pEvas, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(E_OUT_OF_MEMORY));
389 evas_damage_rectangle_add(pEvas, 0, 0, __size.width, __size.height);
396 void* pBuffer = const_cast<void*>(ecore_evas_buffer_pixels_get(__pEcoreEvas.get()));
\r
397 SysTryReturnVoidResult(NID_SHELL, pBuffer, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(E_OUT_OF_MEMORY));
\r
399 evas_data_argb_unpremul(static_cast<unsigned int*>(pBuffer), __size.width * __size.height);
403 __pAppWidgetBuffer->UnlockBuffer();