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 PreRender(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->OnNativeCanvasPreRendered();
84 PostRender(void* pData, Evas* pEvas, void* pEventInfo)
86 SysLog(NID_SHELL, "ENTER");
88 _AppWidgetLayer* pAppWidgetLayer = static_cast<_AppWidgetLayer*>(pData);
89 SysTryReturnVoidResult(NID_SHELL, pAppWidgetLayer, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
91 pAppWidgetLayer->OnNativeCanvasPostRendered();
96 namespace Tizen { namespace Shell
99 _AppWidgetLayer::_AppWidgetLayer(const Tizen::Base::String& providerId, const FloatDimension& size)
100 : __isReleased(false)
103 , __pEvasObject(null)
104 , __providerId(providerId)
105 , __pRenderBuffer(null)
106 , __pTempBuffer(null)
109 , __pAppWidgetBuffer(new (std::nothrow) _AppWidgetBuffer)
113 _AppWidgetLayer::~_AppWidgetLayer(void)
115 __pRenderBuffer = null;
116 __pTempBuffer = null;
121 _AppWidgetLayer::OnConstructed(void)
123 result r = E_SUCCESS;
125 __pAppWidgetBuffer->Initialize();
127 unique_ptr<Ecore_Evas, _EcoreEvasDeleter> pEcoreEvas(ecore_evas_buffer_allocfunc_new(__size.width, __size.height, AllocRenderBuffer, FreeRenderBuffer, this));
128 SysTryReturn(NID_SHELL, pEcoreEvas, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
130 ecore_evas_alpha_set(pEcoreEvas.get(), EINA_TRUE);
131 ecore_evas_manual_render_set(pEcoreEvas.get(), EINA_FALSE);
132 ecore_evas_resize(pEcoreEvas.get(), __size.width, __size.height);
133 ecore_evas_activate(pEcoreEvas.get());
135 Evas* pEvas = ecore_evas_get(pEcoreEvas.get());
136 SysTryReturn(NID_SHELL, pEvas, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
138 evas_event_callback_add(pEvas, EVAS_CALLBACK_RENDER_PRE, PreRender, this);
139 // evas_event_callback_add(pEvas, EVAS_CALLBACK_RENDER_POST, PostRender, this);
141 unique_ptr<Evas_Object, _EvasObjectDeleter> pEvasObject(evas_object_rectangle_add(pEvas));
142 SysTryReturn(NID_SHELL, pEvasObject, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
144 evas_object_resize(pEvasObject.get(), __size.width, __size.height);
145 evas_object_color_set(pEvasObject.get(), 0, 0, 0, 255);
147 r = Initialize(pEvasObject.get());
148 SysTryReturn(NID_SHELL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
150 __pEcoreEvas = move(pEcoreEvas);
151 __pEvasObject = move(pEvasObject);
153 ecore_evas_alpha_set(__pEcoreEvas.get(), EINA_TRUE);
154 evas_object_color_set(__pEvasObject.get(), 0, 0, 0, 0);
156 if (!__providerId.IsEmpty())
158 r = RegisterTouchEventListener();
159 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
166 _AppWidgetLayer::SetProviderId(const String& providerId)
168 __providerId = providerId;
170 result r = RegisterTouchEventListener();
171 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
177 _AppWidgetLayer::GetProviderId(void) const
183 _AppWidgetLayer::GetPixmapId(void) const
189 _AppWidgetLayer::SetLayerBounds(const FloatRectangle& bounds)
191 __size = FloatDimension(bounds.width, bounds.height);
193 ecore_evas_resize(__pEcoreEvas.get(), __size.width, __size.height);
199 _AppWidgetLayer::AllocCanvas(int size)
201 SysTryReturn(NID_SHELL, size > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
204 void* pBuffer = null;
206 if (__providerId.IsEmpty())
208 __pTempBuffer = malloc(__bufferSize);
209 SysTryReturn(NID_SHELL, __pTempBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
211 pBuffer = __pTempBuffer;
215 if (__pixmapId == -1)
217 __pixmapId = AcquirePixmap();
218 SysTryReturn(NID_SHELL, __pixmapId != -1, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
221 __pRenderBuffer = __pAppWidgetBuffer->AllocBuffer(__pixmapId, __size);
222 pBuffer = __pRenderBuffer;
223 __pAppWidgetBuffer->UnlockBuffer();
226 SysLog(NID_SHELL, "buffer (0x%x 0x%x) size (%d) pixmap (%d)", __pTempBuffer, __pRenderBuffer, __bufferSize, __pixmapId);
228 __isReleased = false;
234 _AppWidgetLayer::FreeCanvas(void* pCanvas)
236 SysLog(NID_SHELL, "buffer (0x%x 0x%x 0x%x) size (%d)", __pTempBuffer, __pRenderBuffer, pCanvas, __bufferSize);
241 __pTempBuffer = null;
245 if (__pAppWidgetBuffer)
247 __pAppWidgetBuffer->DeallocBuffer();
258 __pRenderBuffer = null;
262 _AppWidgetLayer::SyncPixmap(const FloatDimension& size)
264 SysTryReturn(NID_SHELL, __pRenderBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
265 SysTryReturn(NID_SHELL, __pAppWidgetBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
267 SysLog(NID_SHELL, "buffer (0x%x) size (%d) pixmapId (%d) width(%f) height(%f)", __pRenderBuffer, __bufferSize, __pixmapId, size.width, size.height);
269 XShmPutImage(__pAppWidgetBuffer->GetDisplay(), static_cast<Pixmap>(__pixmapId), __pAppWidgetBuffer->GetGc(), __pAppWidgetBuffer->GetXImage(), 0, 0, 0, 0, size.width, size.height, False);
270 XSync(__pAppWidgetBuffer->GetDisplay(), False);
276 _AppWidgetLayer::OnRendered(void)
278 result r = E_SUCCESS;
280 if (!__pAppWidgetBuffer->IsGemBufferEnabled())
282 if (__pixmapId == -1)
284 __pixmapId = AcquirePixmap();
285 SysTryReturnVoidResult(NID_SHELL, __pixmapId >= 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
288 r = SyncPixmap(__size);
289 SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
292 SysLog(NID_SHELL, "ENTER");
295 SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
299 _AppWidgetLayer::OnNativeCanvasPreRendered(void)
301 SysLog(NID_SHELL, "ENTER");
303 __pAppWidgetBuffer->LockBuffer();
307 _AppWidgetLayer::OnNativeCanvasPostRendered(void)
312 _AppWidgetLayer::RegisterTouchEventListener(void)
314 result r = _AppWidgetProviderManagerImpl::GetInstance()->SetAppWidgetTouchEventListener(__providerId, *this);
315 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
321 _AppWidgetLayer::AcquirePixmap(void)
323 SysTryReturn(NID_SHELL, !__providerId.IsEmpty(), -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
327 result r = _AppWidgetProviderManagerImpl::GetInstance()->RequestSharedMemoryId(__providerId, __size.width, __size.height, pixmapId);
328 SysTryReturn(NID_SHELL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
330 SysLog(NID_SHELL, "pixmapId(%d) size(%f %f)", pixmapId, __size.width, __size.height);
336 _AppWidgetLayer::Sync(const FloatDimension& size)
338 SysTryReturn(NID_SHELL, !__providerId.IsEmpty(), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
340 result r = _AppWidgetProviderManagerImpl::GetInstance()->RequestSyncSharedMemory(__providerId, size.width, size.height);
341 SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
347 _AppWidgetLayer::ReleasePixmap(void)
349 SysTryReturnVoidResult(NID_SHELL, !__providerId.IsEmpty(), E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
351 _AppWidgetProviderManagerImpl::GetInstance()->RequestReleaseSharedMemory(__providerId);
355 _AppWidgetLayer::OnTouchEventRecevied(int eventType, double timestamp, double x, double y)
357 SysLog(NID_SHELL, "eventType (%d) timestamp (%f) (%f, %f)", eventType, timestamp, x, y);
359 int xPos = __size.width * x;
360 int yPos = __size.height * y;
362 Evas* pEvas = ecore_evas_get(__pEcoreEvas.get());
363 SysTryReturn(NID_SHELL, pEvas, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
367 case BUFFER_EVENT_ENTER:
368 evas_event_feed_mouse_in(pEvas, timestamp, null);
371 case BUFFER_EVENT_LEAVE:
372 evas_event_feed_mouse_out(pEvas, timestamp, null);
375 case BUFFER_EVENT_DOWN:
376 evas_event_feed_mouse_in(pEvas, timestamp, null);
377 evas_event_feed_mouse_move(pEvas, xPos, yPos, timestamp + 0.01f, null);
378 evas_event_feed_mouse_down(pEvas, 1, EVAS_BUTTON_NONE, timestamp + 0.02f, null);
381 case BUFFER_EVENT_MOVE:
382 evas_event_feed_mouse_move(pEvas, xPos, yPos, timestamp, null);
385 case BUFFER_EVENT_UP:
386 evas_event_feed_mouse_up(pEvas, 1, EVAS_BUTTON_NONE, timestamp, null);
387 evas_event_feed_mouse_out(pEvas, timestamp + 0.01f, null);
398 _AppWidgetLayer::Flush(void)
400 bool needed = IsFlushNeeded();
404 Evas* pEvas = ecore_evas_get(__pEcoreEvas.get());
405 SysTryReturnVoidResult(NID_SHELL, pEvas, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(E_OUT_OF_MEMORY));
407 evas_damage_rectangle_add(pEvas, 0, 0, __size.width, __size.height);
414 void* pBuffer = const_cast<void*>(ecore_evas_buffer_pixels_get(__pEcoreEvas.get()));
415 SysTryReturnVoidResult(NID_SHELL, pBuffer, E_OUT_OF_MEMORY, "[%s] Propagating.", GetErrorMessage(E_OUT_OF_MEMORY));
417 evas_data_argb_unpremul(static_cast<unsigned int*>(pBuffer), __size.width * __size.height);
422 __pAppWidgetBuffer->UnlockBuffer();