Merge "RemoveItem fix for ContextMenu Signed-off-by: vipul <vipul.kumar@samsung.com...
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_OverlayAgent.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FUiCtrl_OverlayAgent.cpp
20  * @brief               This file contains implementation of _OverlayAgent class
21  */
22
23 #include <new>
24 #include <sys/shm.h>
25 #include <unique_ptr.h>
26 #include <Ecore_Evas.h>
27
28 #include <FBaseResult.h>
29 #include <FUiIOrientationEventListener.h>
30 #include <FUiAnimDisplayContext.h>
31 #include <FGrp_BufferInfoImpl.h>
32 #include <FGrp_Screen.h>
33 #include <FIo_RegistryImpl.h>
34 #include <FMedia_ImageUtil.h>
35 #include "FUi_Control.h"
36 #include "FUi_CoordinateSystemUtils.h"
37 #include "FUi_EcoreEvas.h"
38 #include "FUi_EcoreEvasMgr.h"
39 #include "FUi_Window.h"
40 #include "FUiAnim_EflNode.h"
41 #include "FUiAnim_ControlVisualElement.h"
42 #include "FUiAnim_VisualElementSurfaceImpl.h"
43 #include "FUiAnim_VisualElementImpl.h"
44 #include "FUiCtrl_OverlayAgent.h"
45
46 #define B(c,s) ((((unsigned int)(c)) & 0xff) << (s))
47 #define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0))
48
49 using namespace std;
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::Graphics;
53 using namespace Tizen::Io;
54 using namespace Tizen::Media;
55 using namespace Tizen::System;
56 using namespace Tizen::Ui::Controls;
57 using namespace Tizen::Ui::Animations;
58
59 namespace
60 {
61 bool
62 CheckXvExtension(Display* pDisplay, int* pFirstPort, int* pCountPort)
63 {
64         unsigned int version = 0;
65         unsigned int release = 0;
66         unsigned int requestBase = 0;
67         unsigned int eventBase = 0;
68         unsigned int errorBase = 0;
69
70         // Query and print Xvideo properties
71         int returnValue = XvQueryExtension(pDisplay, &version, &release, &requestBase, &eventBase, &errorBase);
72         if (returnValue != Success)
73         {
74                 if (returnValue == XvBadExtension)
75                 {
76                         SysSecureLog(NID_UI_CTRL, "XvBadExtension returned at XvQueryExtension!");
77                 }
78                 else if (returnValue == XvBadAlloc)
79                 {
80                         SysSecureLog(NID_UI_CTRL, "XvBadAlloc returned at XvQueryExtension!");
81                 }
82                 else
83                 {
84                         SysSecureLog(NID_UI_CTRL, "Other error happened at XvQueryExtension!");
85                 }
86
87                 return false;
88         }
89
90         unsigned int adaptors = 0;
91         XvAdaptorInfo* pAdaptorInfo = null;
92         returnValue = XvQueryAdaptors(pDisplay, DefaultRootWindow(pDisplay), &adaptors, &pAdaptorInfo);
93         if (returnValue != Success)
94         {
95                 if (returnValue == XvBadExtension)
96                 {
97                         SysSecureLog(NID_UI_CTRL, "XvBadExtension returned at XvQueryExtension.");
98                 }
99                 else if (returnValue == XvBadAlloc)
100                 {
101                         SysSecureLog(NID_UI_CTRL, "XvBadAlloc returned at XvQueryExtension.");
102                 }
103                 else
104                 {
105                         SysSecureLog(NID_UI_CTRL, "Other error happaned at XvQueryAdaptors.");
106                 }
107
108                 if (pAdaptorInfo != null)
109                 {
110                         XvFreeAdaptorInfo(pAdaptorInfo);
111                 }
112
113                 return false;
114         }
115
116         int port = -1;
117         if (adaptors > 0 && pAdaptorInfo != null)
118         {
119                 for (unsigned int i = 0; i < adaptors; i++)
120                 {
121                         for (unsigned int j = 0; j < pAdaptorInfo[i].num_formats; j++)
122                         {
123                                 SysSecureLog(NID_UI_CTRL, "The current value of depth is %d and visual is %ld.", pAdaptorInfo[i].formats[j].depth, pAdaptorInfo[i].formats[j].visual_id);
124                         }
125                 }
126
127                 port = pAdaptorInfo[0].base_id;
128
129                 *pFirstPort = port;
130                 *pCountPort = pAdaptorInfo[0].num_ports;
131                 SysSecureLog(NID_UI_CTRL, "The current value of port is %d", port);
132         }
133
134         if (pAdaptorInfo != null)
135         {
136                 XvFreeAdaptorInfo(pAdaptorInfo);
137         }
138
139         if (port == -1)
140         {
141                 return false;
142         }
143
144         return true;
145 }
146
147 Eina_Bool
148 OnPixmapDamaged(void* pData, int type, void* pEvent)
149 {
150         Ecore_X_Event_Damage* pDamageEvent = (Ecore_X_Event_Damage*)pEvent;
151         SysTryReturn(NID_UI_CTRL, pDamageEvent != null, ECORE_CALLBACK_PASS_ON, E_INVALID_DATA, "[E_INVALID_DATA] The current value of DamageEvent is invalid.");
152
153         Tizen::Ui::Controls::_OverlayAgent* pOverlayAgent = static_cast<Tizen::Ui::Controls::_OverlayAgent*>(pData);
154         SysTryReturn(NID_UI_CTRL, pOverlayAgent != null, ECORE_CALLBACK_PASS_ON, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get OverlayAgent from DamagedEvent.");
155
156         if (pDamageEvent->drawable != pOverlayAgent->GetPixmap())
157         {
158                 return ECORE_CALLBACK_PASS_ON;
159         }
160
161         pOverlayAgent->SetRendererFlushNeeded();
162
163         return ECORE_CALLBACK_DONE;
164 }
165
166 void
167 OnEvasImageDamaged(void* pData, Evas_Object* pImageObject)
168 {
169         Tizen::Ui::Controls::_OverlayAgent* pOverlayAgent = static_cast<Tizen::Ui::Controls::_OverlayAgent*>(pData);
170         SysTryReturnVoidResult(NID_UI_CTRL, pOverlayAgent != null, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get OverlayAgent from DamagedEvent.");
171
172         Evas_Object* pRendererImageObject = pOverlayAgent->GetRendererImageObject();
173         SysTryReturnVoidResult(NID_UI_CTRL, pRendererImageObject != null, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get Renderer ImageObject of OverlayAgent.");
174
175         if (pRendererImageObject != pImageObject)
176         {
177                 return;
178         }
179
180         Dimension newImageSize(0,0);
181         evas_object_image_size_get(pImageObject, &newImageSize.width, &newImageSize.height);
182
183         Dimension rendererImageSize(0,0);
184         evas_object_image_size_get(pRendererImageObject, &rendererImageSize.width, &rendererImageSize.height);
185
186         if (!newImageSize.Equals(rendererImageSize))
187         {
188                 SysSecureLog(NID_UI_CTRL,"newImageSize [%d, %d] rendererImageSize [%d, %d]", newImageSize.width, newImageSize.height, rendererImageSize.width, rendererImageSize.height);
189                 pOverlayAgent->SetDestination(FloatDimension(static_cast<float>(newImageSize.width), static_cast<float>(newImageSize.height)));
190         }
191 }
192 } // Anonymous
193
194 namespace Tizen { namespace Ui { namespace Controls
195 {
196
197 int _OverlayAgent::__baseXvPort = 0;
198 bool _OverlayAgent::__isPortGrabbed[]={false,};
199
200 int _OverlayAgent::__overlayAgentCount = 0;
201 int _OverlayAgent::__dstRectMinWidth = -1;
202 int _OverlayAgent::__dstRectMinHegith = -1;
203 int _OverlayAgent::__srcRectMinWidth = -1;
204 int _OverlayAgent::__srcRectMinHegith = -1;
205 int _OverlayAgent::__overlayWidthUnit = -1;
206 int _OverlayAgent::__overlayHeightUnit = -1;
207 int _OverlayAgent::__overlayMaxCount = -1;
208 bool _OverlayAgent::__OverlayAgentBufferPixelFormat[] = {false, };
209
210 struct visualElementDeleter
211 {
212         void operator()(_VisualElement* pVisualElement)
213         {
214                 pVisualElement->Destroy();
215         }
216 };
217
218 _OverlayAgent*
219 _OverlayAgent::CreateInstanceN(_OverlayAgentStyle style, const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
220 {
221         unique_ptr<_OverlayAgent> pOverlayAgent(new (std::nothrow) _OverlayAgent(style, parentControl, logicalBounds, physicalBounds));
222         SysTryReturn(NID_UI_CTRL, pOverlayAgent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
223
224         result r = GetLastResult();
225         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
226
227         return pOverlayAgent.release();
228 }
229
230 _OverlayAgent::_OverlayAgent(_OverlayAgentStyle style, const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
231         : __pParentVE(null)
232         , __pRendererVE(null)
233         , __pImageObject(null)
234         , __style(style)
235         , __currentRotation(_OVERLAY_AGENT_ROTATION_NONE)
236         , __savedColorFormat(FOURCC('R','G','B','4'))
237         , __currentColorFormat(_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888)
238         , __currentSourceBufferSize(0,0)
239         , __standardRendererBounds(0.0f, 0.0f, 0.0f, 0.0f)
240         , __standardParentBounds(0.0f, 0.0f, 0.0f, 0.0f)
241         , __needToRellaocImage(false)
242         , __pCurrentSourceBuffer(null)
243         , __pConvertedSourceBuffer(null)
244         , __pixmapDamageHandle(0)
245         , __pPixmapEventHandler(null)
246         , __pixmap(0)
247         , __xvPort(-1)
248         , __pXvImage(null)
249         , __pShmInfo(null)
250 {
251         result r = CreateRendererVisualElement(parentControl, logicalBounds, physicalBounds);
252
253         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
254         SysTryReturnVoidResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "[E_SYSTEM] The Renderer VisualElement is null.");
255         SysTryReturnVoidResult(NID_UI_CTRL, __pImageObject!= null, E_SYSTEM, "[E_SYSTEM] The Renderder ImageObject is null.");
256
257         __overlayAgentCount++;
258         SysLog(NID_UI_CTRL, "The current count of OverlayAgent is %d", __overlayAgentCount);
259 }
260
261 _OverlayAgent::~_OverlayAgent(void)
262 {
263         SysLog(NID_UI_CTRL, "The %dth OverlayAgent is deleted.", __overlayAgentCount);
264         __overlayAgentCount--;
265
266         if (__xvPort > 0)
267         {
268                 UngrabXvPort();
269         }
270
271         if (__pPixmapEventHandler)
272         {
273                 ecore_event_handler_del(__pPixmapEventHandler);
274                 __pPixmapEventHandler = null;
275         }
276
277         if (__pixmapDamageHandle)
278         {
279                 ecore_x_damage_free(__pixmapDamageHandle);
280                 __pixmapDamageHandle = 0;
281         }
282
283         if (__pixmap != 0)
284         {
285                 XFreePixmap((Display*)ecore_x_display_get(), __pixmap);
286                 __pixmap = 0;
287         }
288
289         if (__pShmInfo)
290         {
291                 XShmDetach((Display*)ecore_x_display_get(), __pShmInfo);
292                 shmdt(__pShmInfo->shmaddr);
293                 shmctl(__pShmInfo->shmid, IPC_RMID, NULL);
294                 __pShmInfo = null;
295         }
296
297         if (__pXvImage)
298         {
299                 XFree(__pXvImage);
300                 __pXvImage = null;
301         }
302
303         if (__pConvertedSourceBuffer)
304         {
305                 delete __pConvertedSourceBuffer;
306                 __pConvertedSourceBuffer = null;
307         }
308
309         if (__pCurrentSourceBuffer)
310         {
311                 delete __pCurrentSourceBuffer;
312                 __pCurrentSourceBuffer = null;
313         }
314
315         if (__pRendererVE != null)
316         {
317                 __pRendererVE->SetSurface(null);
318                 __pRendererVE->Destroy();
319                 __pRendererVE = null;
320         }
321
322         if (__pImageObject)
323         {
324                 evas_object_del(__pImageObject);
325                 __pImageObject = null;
326         }
327 }
328
329 result
330 _OverlayAgent::GetBufferInfo(BufferInfo& bufferInfo) const
331 {
332         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "The Renderer ImageObject is null.");
333         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null.");
334
335         int width = 0;
336         int height = 0;
337         evas_object_geometry_get(__pImageObject, NULL, NULL, &width, &height);
338
339         bufferInfo.width = width;
340         bufferInfo.pitch = width;
341         bufferInfo.height = height;
342         bufferInfo.bitsPerPixel = 32;
343         bufferInfo.pixelFormat = PIXEL_FORMAT_ARGB8888;
344
345         _BufferInfoImpl* pBufferInfoImpl = _BufferInfoImpl::GetInstance(bufferInfo);
346         SysTryReturnResult(NID_UI_CTRL, pBufferInfoImpl != null, E_SYSTEM, "Failed to get instance of buffer info.");
347
348         result r = E_SUCCESS;
349
350         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
351         {
352                 pBufferInfoImpl->SetHandle(_BufferInfoImpl::HANDLE_TYPE_VE_SURFACE, reinterpret_cast<Handle>(__pImageObject));
353                 SysSecureLog(NID_UI_CTRL,"The returned handle of BufferInfo is a evas image object (HANDLE_TYPE_VE_SURFACE)");
354         }
355         else
356         {
357                 pBufferInfoImpl->SetHandle(_BufferInfoImpl::HANDLE_TYPE_OVERLAY_REGION, __pixmap);
358                 SysSecureLog(NID_UI_CTRL,"The returned handle of BufferInfo is a pixmap (HANDLE_TYPE_OVERLAY_REGION)");
359         }
360
361         pBufferInfoImpl->SetBounds(Rectangle(0, 0, width, height));
362
363         return r;
364 }
365
366 result
367 _OverlayAgent::SetInputBuffer(const ByteBuffer& srcBuffer, const Dimension& srcDim, _OverlayAgentBufferPixelFormat srcFormat)
368 {
369         SysTryReturnResult(NID_UI_CTRL, srcBuffer.GetPointer() != null, E_INVALID_ARG, "The current value of input source buffer is invalid.");
370         SysTryReturnResult(NID_UI_CTRL, srcBuffer.GetCapacity() > 0, E_INVALID_ARG, "The current size of input source buffer is invalid.");
371         SysTryReturnResult(NID_UI_CTRL, srcDim.width >= GetSrcRectMinWidth(), E_INVALID_ARG, "The width of dimension [%d] is under the minimum size.", srcDim.width);
372         SysTryReturnResult(NID_UI_CTRL, srcDim.height >= GetSrcRectMinHeight(), E_INVALID_ARG, "The height of dimension [%d] is under the minimum size.", srcDim.height);
373
374         if (__currentColorFormat != srcFormat)
375         {
376                 unsigned int colorFormat = 0;
377
378                 switch (srcFormat)
379                 {
380                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888:
381                         colorFormat = FOURCC('R','G','B','4');
382                         break;
383                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565:
384                         colorFormat = FOURCC('R','G','B','P');
385                         break;
386                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR:
387                         colorFormat = FOURCC('I','4','2','0');
388                         break;
389                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12:
390                         colorFormat = FOURCC('N','V','1','2');
391                         break;
392                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY:
393                         colorFormat = FOURCC('U','Y','V','Y');
394                         break;
395                 default:
396                         SysLogException(NID_UI_CTRL, E_UNSUPPORTED_FORMAT, "The specified pixel format is not supported.");
397                         return E_UNSUPPORTED_FORMAT;
398                 }
399
400                 __savedColorFormat = colorFormat;
401                 __currentColorFormat = srcFormat;
402                 __needToRellaocImage = true;
403         }
404
405         if (!srcDim.Equals(__currentSourceBufferSize))
406         {
407                 __currentSourceBufferSize.width = srcDim.width;
408                 __currentSourceBufferSize.height = srcDim.height;
409                 __needToRellaocImage = true;
410         }
411
412         __pCurrentSourceBuffer = &srcBuffer;
413
414         if (__needToRellaocImage)
415         {
416                 SysSecureLog(NID_UI_CTRL,"The current buffer pointer is %x, size is %d, color format is %d",
417                         __pCurrentSourceBuffer->GetPointer(), __pCurrentSourceBuffer->GetCapacity(), __savedColorFormat);
418         }
419
420         return E_SUCCESS;
421 }
422
423 result
424 _OverlayAgent::Draw(void)
425 {
426         SysTryReturnResult(NID_UI_CTRL, __pCurrentSourceBuffer->GetPointer() != null, E_SYSTEM, "The current input user buffer is null. (nothing to draw)");
427
428         result r = E_SUCCESS;
429
430         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
431         {
432                 r = PutEvasImage();
433         }
434         else
435         {
436                 r = PutXvImage();
437         }
438
439         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
440
441         return r;
442 }
443
444
445 result
446 _OverlayAgent::GrabXvPort(void)
447 {
448         Display* pDisplay = (Display*)ecore_x_display_get();
449         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
450
451         int baseXvPort = -1;
452         int portCount = -1;
453         if (!CheckXvExtension(pDisplay, &baseXvPort, &portCount))
454         {
455                 SysTryReturnResult(NID_UI_CTRL, false, E_SYSTEM, "Failed to check XvExtension");
456         }
457
458         SysTryReturnResult(NID_UI_CTRL, baseXvPort > 0, E_SYSTEM, "The current value of base XvPort is invalid.");
459         SysTryReturnResult(NID_UI_CTRL, portCount >= 1 && portCount <= _OVERLAYAGENT_XV_PORT, E_SYSTEM, "The current count of available XvPort[%d] is invalid.", portCount);
460
461         _OverlayAgent::__baseXvPort = baseXvPort;
462
463         for (int index = 0; index < portCount; index++)
464         {
465                 if(!__isPortGrabbed[index])
466                 {
467                         int tempPort = __baseXvPort + index;
468                         if (XvGrabPort(pDisplay, tempPort, 0) != Success)
469                         {
470                                 SysSecureLog(NID_UI_CTRL, "The current XvPort[%d] has been alreadly used by another process", tempPort);
471                         }
472                         else
473                         {
474                                 __xvPort = tempPort;
475                                 __isPortGrabbed[index] = true;
476                                 break;
477                         }
478                 }
479         }
480
481         SysTryReturnResult(NID_UI_CTRL, __xvPort > 0, E_SYSTEM, "Failed to grab pixmap[%d]", __pixmap);
482         SysSecureLog(NID_UI_CTRL, "The current value of grabbed XvPort is [%d] and pixmap is [%d]", __xvPort, __pixmap);
483
484         return E_SUCCESS;
485 }
486
487 void
488 _OverlayAgent::UngrabXvPort(void)
489 {
490         ClearLastResult();
491
492         if (__xvPort > 0 && (__xvPort - __baseXvPort) >= 0 && __isPortGrabbed[__xvPort - __baseXvPort])
493         {
494                 Display* pDisplay = (Display*) ecore_x_display_get();
495                 Atom atom = XInternAtom(pDisplay, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
496                 XvSetPortAttribute(pDisplay, __xvPort, atom, 1);
497                 XvUngrabPort(pDisplay, __xvPort, 0);
498
499                 SysSecureLog(NID_UI_CTRL, "The current value of ungrabbed XvPort is %d, and pixmap is %d", __xvPort, __pixmap);
500
501                 __isPortGrabbed[__xvPort - __baseXvPort] = false;
502                 __xvPort = -1;
503         }
504 }
505
506 result
507 _OverlayAgent::PutXvImage(void)
508 {
509         SysTryReturnResult(NID_UI_CTRL, __pixmap != 0, E_SYSTEM, "The current value of pixmap is null");
510
511         Display* pDisplay = (Display*)ecore_x_display_get();
512         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
513
514         if (__pXvImage == null || __needToRellaocImage)
515                 //||(__pXvImage && __pXvImage->data_size != currentSourceBufferSize->GetCapacity()) )
516         {
517                 if (__xvPort != -1)
518                 {
519                         UngrabXvPort();
520                 }
521
522                 if (__pXvImage != null)
523                 {
524                         if (__pShmInfo)
525                         {
526                                 XShmDetach(pDisplay, __pShmInfo);
527                                 shmdt(__pShmInfo->shmaddr);
528                                 shmctl(__pShmInfo->shmid, IPC_RMID, NULL);
529                                 delete __pShmInfo;
530                                 __pShmInfo = null;
531                         }
532
533                         if (__pXvImage)
534                         {
535                                 XFree(__pXvImage);
536                                 __pXvImage = null;
537                         }
538                 }
539         }
540
541         if (__xvPort == -1)
542         {
543                 result r = GrabXvPort();
544                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
545         }
546
547         if (__needToRellaocImage)
548         {
549                 XShmSegmentInfo* pShmInfo = new (std::nothrow) XShmSegmentInfo();
550                 SysTryReturnResult(NID_UI_CTRL, pShmInfo != null, E_SYSTEM, "Failed to create XShmSegmentInfo");
551
552                 XvImage* pXvImage = XvShmCreateImage(pDisplay, __xvPort, __savedColorFormat, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height, pShmInfo);
553                 SysTryReturnResult(NID_UI_CTRL, pXvImage != null, E_SYSTEM, "Failed to create XvImage");
554
555                 pShmInfo->shmid = shmget(IPC_PRIVATE, pXvImage->data_size, IPC_CREAT | 0777);
556                 pShmInfo->shmaddr = pXvImage->data = (char*)shmat(pShmInfo->shmid, 0, 0);
557                 pShmInfo->readOnly = False;
558
559                 if (!XShmAttach(pDisplay, pShmInfo))
560                 {
561                         XFree(pXvImage);
562                         SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Failed to XShmAttach.");
563                         return E_SYSTEM;
564                 }
565
566                 __pXvImage = pXvImage;
567                 __pShmInfo = pShmInfo;
568         }
569
570         if (__pXvImage == null)
571         {
572                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Failed to get XvImage");
573                 return E_SYSTEM;
574         }
575
576         memcpy(__pXvImage->data, __pCurrentSourceBuffer->GetPointer(), __pXvImage->data_size);
577         __pCurrentSourceBuffer = null;
578
579         int imageWidth = 0;
580         int imageHeight = 0;
581         evas_object_image_size_get(__pImageObject, &imageWidth, &imageHeight);
582
583         GC gc= DefaultGCOfScreen(DefaultScreenOfDisplay(pDisplay));
584         XvShmPutImage(pDisplay, __xvPort, __pixmap, gc, __pXvImage, 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height, 0, 0, imageWidth, imageHeight, False);
585         XSync(pDisplay, 0);
586
587         if (__needToRellaocImage)
588         {
589                 SysSecureLog(NID_UI_CTRL, "The current value of source buffer size is [%d,%d]", __currentSourceBufferSize.width, __currentSourceBufferSize.height);
590                 SysSecureLog(NID_UI_CTRL, "The current value of destination XvImage size is [%d,%d]", imageWidth, imageHeight);
591                 __needToRellaocImage = false;
592         }
593
594         result r = __pRendererVE->SetFlushNeeded();
595         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"[%s] Propagating.", GetErrorMessage(r));
596
597         return r;
598 }
599
600 result
601 _OverlayAgent::PutEvasImage(void)
602 {
603         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "The current value of Renderer ImageObject is null");
604         SysTryReturnResult(NID_UI_CTRL, __pCurrentSourceBuffer->GetPointer() != null, E_SYSTEM, "The current value of Renderer byte buffer is null");
605
606         result r = E_SUCCESS;
607
608         // Create new buffer to convert pixel format
609         if (__needToRellaocImage || __pConvertedSourceBuffer == null ||
610                 !(__pConvertedSourceBuffer && (__pConvertedSourceBuffer->GetCapacity() == __pCurrentSourceBuffer->GetCapacity())))
611         {
612                 if (__pConvertedSourceBuffer != null)
613                 {
614                         __pConvertedSourceBuffer->SetPosition(0);
615                         delete __pConvertedSourceBuffer;
616                         __pConvertedSourceBuffer = null;
617                 }
618
619                 __pConvertedSourceBuffer = new (std::nothrow) ByteBuffer;
620                 SysTryReturnResult(NID_UI_CTRL, __pConvertedSourceBuffer != null, E_OUT_OF_MEMORY, "Failed to create a ByteBuffer for Evas Image Object.");
621
622                 r = __pConvertedSourceBuffer->Construct(__currentSourceBufferSize.width * __currentSourceBufferSize.height * 4);
623                 if (r != E_SUCCESS)
624                 {
625                         delete __pConvertedSourceBuffer;
626                         __pConvertedSourceBuffer = null;
627                         SysLogException(NID_UI_CTRL, r, "[%s] Failed to construct a byte buffer for EvasImageObject.", GetErrorMessage(r));
628
629                         return r;
630                 }
631         }
632
633         __pConvertedSourceBuffer->SetPosition(0);
634
635         switch (__currentColorFormat)
636         {
637         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888:
638                 r = __pConvertedSourceBuffer->SetArray(__pCurrentSourceBuffer->GetPointer(), 0, __pConvertedSourceBuffer->GetCapacity());
639                 break;
640         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565:
641                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_RGB565LE, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
642                 break;
643         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR:
644                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_YUV420P, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
645                 break;
646         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12:
647                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_NV12, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
648                 break;
649         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY:
650                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_UYVY422, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
651                 break;
652         default:
653                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The specified pixel format is not supported.");
654                 return E_UNSUPPORTED_FORMAT;
655         }
656
657         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"Propagating.");
658
659         __pCurrentSourceBuffer = null;
660         void* pImageData = (void*)(__pConvertedSourceBuffer->GetPointer());
661         SysTryReturnResult(NID_UI_CTRL, pImageData != null, E_SYSTEM, "The converted image data for Overlay Renderer VisualElement is invalid.");
662
663         evas_object_image_size_set(__pImageObject, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
664         evas_object_image_data_set(__pImageObject, pImageData);
665         evas_object_image_data_update_add(__pImageObject, 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
666         evas_object_show(__pImageObject);
667
668         if (__needToRellaocImage)
669         {
670                 SysSecureLog(NID_UI_CTRL, "The current value of source buffer bounds is [%d,%d,%d, %d]", 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
671                 __needToRellaocImage = false;
672         }
673
674         r = __pRendererVE->SetFlushNeeded();
675         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"[%s] Propagating.", GetErrorMessage(r));
676
677         return r;
678 }
679
680 result
681 _OverlayAgent::SetRendererFlushNeeded(void)
682 {
683         return __pRendererVE->SetFlushNeeded();
684 }
685
686 result
687 _OverlayAgent::SetRotation(_OverlayAgentRotation rotation)
688 {
689         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null");
690         SysTryReturnResult(NID_UI_CTRL, rotation < _OVERLAY_AGENT_ROTATION_MAX, E_INVALID_ARG, "The value of input rotation [%d] is invalid.", rotation);
691
692         if (rotation == __currentRotation)
693         {
694                 return E_SUCCESS;
695         }
696
697         float initialZAngle = __pRendererVE->GetProperty(L"transform.rotation.z").ToFloat();
698         float rotatedZAngle = initialZAngle;
699
700         switch (rotation)
701         {
702         case _OVERLAY_AGENT_ROTATION_NONE: // fall through
703         case _OVERLAY_AGENT_ROTATION_NONE_LR: // fall through
704         case _OVERLAY_AGENT_ROTATION_NONE_UD:
705                 rotatedZAngle = 0.0f;
706                 break;
707
708         case _OVERLAY_AGENT_ROTATION_90: // fall through
709         case _OVERLAY_AGENT_ROTATION_90_LR: // fall through
710         case _OVERLAY_AGENT_ROTATION_90_UD:
711                 rotatedZAngle = 90.0f;
712                 break;
713
714         case _OVERLAY_AGENT_ROTATION_180: // fall through
715         case _OVERLAY_AGENT_ROTATION_180_LR: // fall through
716         case _OVERLAY_AGENT_ROTATION_180_UD:
717                 rotatedZAngle = 180.0f;
718                 break;
719
720         case _OVERLAY_AGENT_ROTATION_270: // fall through
721         case _OVERLAY_AGENT_ROTATION_270_LR: // fall through
722         case _OVERLAY_AGENT_ROTATION_270_UD:
723                 rotatedZAngle = 270.0f;
724                 break;
725
726         default:
727                 break;
728         }
729
730         //Set bounds of rotated renderer
731         FloatRectangle rendererBounds = __standardRendererBounds;
732         if (rotatedZAngle == 90.0f || rotatedZAngle == 270.0f )
733         {
734                 rendererBounds.x = __standardRendererBounds.x - ((__standardRendererBounds.height - __standardRendererBounds.width) / 2.0f);
735                 rendererBounds.y = __standardRendererBounds.y + ((__standardRendererBounds.height - __standardRendererBounds.width) / 2.0f);
736                 std::swap(rendererBounds.height, rendererBounds.width);
737         }
738
739         result r = __pRendererVE->SetBounds(rendererBounds);
740         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
741
742         r = __pRendererVE->SetProperty(L"transform.rotation.z", rotatedZAngle);
743         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
744         SysLog(NID_UI_CTRL, "The current Overlay Renderer is rotated (%d -> %d)", static_cast<int>(initialZAngle), static_cast<int>(rotatedZAngle));
745
746         switch (rotation)
747         {
748         case _OVERLAY_AGENT_ROTATION_NONE: // fall through
749         case _OVERLAY_AGENT_ROTATION_90: // fall through
750         case _OVERLAY_AGENT_ROTATION_180: // fall through
751         case _OVERLAY_AGENT_ROTATION_270:
752                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 0.0f);
753                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 0.0f);
754                 break;
755
756         case _OVERLAY_AGENT_ROTATION_NONE_UD: // fall through
757         case _OVERLAY_AGENT_ROTATION_180_UD: // fall through
758         case _OVERLAY_AGENT_ROTATION_90_LR: // fall through
759         case _OVERLAY_AGENT_ROTATION_270_LR:
760                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 180.0f);
761                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 0.0f);
762                 SysLog(NID_UI_CTRL, "The current Overlay Renderer is flipped over up side down.");
763                 break;
764
765         case _OVERLAY_AGENT_ROTATION_NONE_LR: // fall through
766         case _OVERLAY_AGENT_ROTATION_180_LR: // fall through
767         case _OVERLAY_AGENT_ROTATION_90_UD: // fall through
768         case _OVERLAY_AGENT_ROTATION_270_UD:
769                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 0.0f);
770                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 180.0f);
771                 SysLog(NID_UI_CTRL, "The current Overlay Renderer is flipped over left side right.");
772                 break;
773
774         default:
775                 break;
776         }
777         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
778
779         __currentRotation = rotation;
780
781         r = __pRendererVE->SetFlushNeeded();
782         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
783
784         return r;
785 }
786
787 result
788 _OverlayAgent::SetDestination(const FloatDimension& dimension)
789 {
790         SysTryReturnResult(NID_UI_CTRL, __pParentVE != null, E_SYSTEM, "The Renderer Visual Element is null");
791         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null");
792         if (__standardRendererBounds.width == dimension.width && __standardRendererBounds.height == dimension.height &&
793                 __standardParentBounds.width == __pParentVE->GetBounds().width && __standardParentBounds.height == __pParentVE->GetBounds().height)
794         {
795                 return E_SUCCESS;
796         }
797
798         //Set bounds of saved renderer
799         FloatRectangle parentBounds= __pParentVE->GetBounds();
800
801         if (parentBounds.width >= dimension.width)
802         {
803                 __standardRendererBounds.x = (parentBounds.width - dimension.width) / 2.0f;
804                 __standardRendererBounds.width = dimension.width;
805         }
806         else
807         {
808                 __standardRendererBounds.x = 0.0f;
809                 __standardRendererBounds.width = parentBounds.width;
810         }
811
812         if (parentBounds.height >= dimension.height)
813         {
814                 __standardRendererBounds.y = (parentBounds.height - dimension.height) / 2.0f;
815                 __standardRendererBounds.height = dimension.height;
816         }
817         else
818         {
819                 __standardRendererBounds.y = 0.0f;
820                 __standardRendererBounds.height = parentBounds.height;
821         }
822
823         //Set bounds of resizing renderer
824         float parentWidth = parentBounds.width;
825         float parentHeight = parentBounds.height;
826         FloatDimension inputDimension(dimension.width, dimension.height);
827
828         Variant rotationAngle = __pRendererVE->GetProperty(L"transform.rotation.z");
829         if(rotationAngle.ToFloat() == 90.0f || rotationAngle.ToFloat() == 270.0f)
830         {
831                 std::swap(parentWidth, parentHeight);
832                 std::swap(inputDimension.width, inputDimension.height);
833         }
834
835         FloatRectangle rendererBounds = __standardRendererBounds;
836
837         if (parentWidth >= inputDimension.width)
838         {
839                 rendererBounds.x = (parentBounds.width - inputDimension.width) / 2.0f;
840                 rendererBounds.width = inputDimension.width;
841         }
842         else
843         {
844                 rendererBounds.x = 0.0f;
845                 rendererBounds.width = parentBounds.width;
846         }
847
848         if (parentHeight >= inputDimension.height)
849         {
850                 rendererBounds.y = (parentBounds.height - inputDimension.height) / 2.0f;
851                 rendererBounds.height = inputDimension.height;
852         }
853         else
854         {
855                 rendererBounds.y = 0.0f;
856                 rendererBounds.height = parentBounds.height;
857         }
858         SysLog(NID_UI_CTRL, "The current bounds of resized renderer is [%.3f, %.3f, %.3f, %.3f]",
859                 __standardRendererBounds.x, __standardRendererBounds.y, __standardRendererBounds.width, __standardRendererBounds.height);
860
861         result r = __pRendererVE->SetBounds(rendererBounds);
862         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
863
864         r = __pRendererVE->SetFlushNeeded();
865         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
866
867         __standardParentBounds = __pParentVE->GetBounds();
868
869         return r;
870 }
871
872 result
873 _OverlayAgent::SetAspectRatio(bool enable)
874 {
875         return E_SUCCESS;
876 }
877
878 FloatRectangle
879 _OverlayAgent::GetBounds(void) const
880 {
881         SysTryReturn(NID_UI_CTRL, __pRendererVE != null, FloatRectangle(0.0f, 0.0f, 0.1f, 0.1f), E_SYSTEM, "The Renderer Visual Element is null");
882         return __standardRendererBounds;
883 }
884
885 result
886 _OverlayAgent::CreateRendererVisualElement(const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
887 {
888         //Create new VisualElement and insert it to Parent's VisualElement
889         unique_ptr<_VisualElement, visualElementDeleter> pRendererVE(new (std::nothrow) _VisualElement());
890         SysTryReturnResult(NID_UI_CTRL, pRendererVE != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient");
891
892         result r = pRendererVE->Construct();
893         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
894
895         pRendererVE->SetName("OverlayRenderer");
896         pRendererVE->SetShowState(true);
897         //pRendererVE->SetImplicitAnimationEnabled(true);
898         pRendererVE->SetImplicitAnimationEnabled(false);
899         pRendererVE->SetZOrderGroup(_CONTROL_LAYER_OVERLAY);
900
901         FloatPoint logicalPoint(0.0f, 0.0f);
902         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_REGION_GL)
903         {
904                 logicalPoint.x = logicalBounds.x;
905                 logicalPoint.y = logicalBounds.y;
906         }
907         pRendererVE->SetBounds(FloatRectangle(logicalPoint.x, logicalPoint.y, logicalBounds.width, logicalBounds.height));
908
909
910         __pParentVE = parentControl.GetVisualElement();
911         SysTryReturnResult(NID_UI_CTRL, __pParentVE != null, E_SYSTEM, "[E_SYSTEM] The current value of OverlayPanel's VisualElement is null.");
912
913         __pParentVE->SetName("OverlayPanel");
914         r = __pParentVE->InsertChild(pRendererVE.get(), null, true);
915         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
916
917         r = __pParentVE->SetSurfaceOpaque(true);
918         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
919
920
921         // Get and Set ImageObject of Renderer VisualElement
922         _EflNode* pEflNode = dynamic_cast<_EflNode*>(pRendererVE->GetNativeNode());
923         SysTryReturnResult(NID_UI_CTRL, pEflNode != null, E_SYSTEM, "Failed to get EflNode from Renderer VisualElement.");
924
925         Evas_Object* pSmartObject = (Evas_Object*) pEflNode->GetGroupContainer();
926         SysTryReturnResult(NID_UI_CTRL, pSmartObject != null, E_SYSTEM, "Failed to get Group Container of Renderer VisualElement.");
927
928         Evas* pEvas = evas_object_evas_get(pSmartObject);
929         SysTryReturnResult(NID_UI_CTRL, pEvas != null, E_SYSTEM, "Failed to get Evas of Renderer VisualElement.");
930
931         Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
932         SysTryReturnResult(NID_UI_CTRL, pEcoreEvas != null, E_SYSTEM, "Failed to get Ecore Evas of Renderer VisualElement.");
933
934         __pImageObject = evas_object_image_add(pEvas);
935         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "Failed to get Renderer Image Object.");
936
937         evas_object_name_set(__pImageObject, "OverlayRenderer");
938         evas_object_image_size_set(__pImageObject, physicalBounds.width, physicalBounds.height);
939         evas_object_image_alpha_set(__pImageObject, false);
940         evas_object_image_filled_set(__pImageObject, EINA_TRUE);
941         evas_object_resize(__pImageObject, physicalBounds.width, physicalBounds.height);
942         evas_object_move(__pImageObject, physicalBounds.x, physicalBounds.y);
943         evas_object_show(__pImageObject);
944
945         DisplayContext* pDisplayContext = parentControl.GetRootWindow()->GetDisplayContext();
946         SysTryReturnResult(NID_UI_CTRL, pDisplayContext != null, E_SYSTEM, "[E_SYSTEM] The current value of RootWindow's DisplayContext is null.");
947
948         unique_ptr<VisualElementSurface> pRendererSurface(_VisualElementSurfaceImpl::CreateSurfaceUsingExistingObjectN(*pDisplayContext, (Handle)__pImageObject, Dimension(physicalBounds.width, physicalBounds.height)));
949         SysTryReturnResult(NID_UI_CTRL, pRendererSurface != null, E_SYSTEM, "[E_SYSTEM] The current value of RootWindow's DisplayContext is null.");
950
951         r = pRendererVE->SetSurface(pRendererSurface.release());
952         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
953
954         r = pRendererVE->SetFlushNeeded();
955         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
956
957         pRendererVE->SetAnchor(FloatPoint(0.5f, 0.5f));
958         __pRendererVE = pRendererVE.release();
959         __standardRendererBounds = __pRendererVE->GetBounds();
960
961         if (__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
962         {
963                 evas_object_image_pixels_get_callback_set(__pImageObject, OnEvasImageDamaged,(void*)this);
964         }
965
966         return r;
967 }
968
969 result
970 _OverlayAgent::CreatePixmap(const Rectangle& physicalBounds)
971 {
972         //Set size of pixmap
973         Dimension pixmapSize(physicalBounds.width, physicalBounds.height);
974         SysTryReturnResult(NID_UI_CTRL, (pixmapSize.width >= GetDstRectMinWidth()) && (pixmapSize.height >= GetDstRectMinHeight()),
975                 E_SYSTEM, "input size (%d, %d) is too small to create a pixmap",pixmapSize.width, pixmapSize.height);
976
977         // Create pixmap
978         Display *pDisplay = (Display*)ecore_x_display_get();
979         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
980
981         __pixmap = XCreatePixmap(pDisplay, DefaultRootWindow(pDisplay), pixmapSize.width, pixmapSize.height, DefaultDepth(pDisplay, DefaultScreen(pDisplay)));
982         SysTryReturnResult(NID_UI_CTRL, __pixmap != 0, E_SYSTEM, "Failed to create a pixmap of Overlay Agent");
983
984         GC gc = XCreateGC(pDisplay, __pixmap, 0,0);
985         SysTryReturnResult(NID_UI_CTRL, gc > 0, E_SYSTEM, "Failed to create Graphic Contexts");
986
987         //Set initial color
988         XSetForeground(pDisplay, gc, (long unsigned int)(Color(0xff000000).GetRGB32()));
989         XFillRectangle(pDisplay, __pixmap, gc, 0, 0, pixmapSize.width, pixmapSize.height);
990         XSync(pDisplay, 0);
991         XFreeGC(pDisplay, gc);
992
993         //Set evas native surface
994         Evas_Native_Surface evasNativeSuface = {0,};
995
996         evasNativeSuface.version = EVAS_NATIVE_SURFACE_VERSION;
997         evasNativeSuface.type = EVAS_NATIVE_SURFACE_X11;
998         evasNativeSuface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
999         evasNativeSuface.data.x11.pixmap = __pixmap;
1000
1001         evas_object_lower(__pImageObject);
1002         evas_object_image_native_surface_set(__pImageObject, &evasNativeSuface);
1003
1004         __pixmapDamageHandle = ecore_x_damage_new(__pixmap, ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES);
1005         SysTryCatch(NID_UI_CTRL, __pixmapDamageHandle != 0, , E_SYSTEM, "[E_SYSTEM] Failed to create a damage object");
1006
1007         __pPixmapEventHandler = ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY, OnPixmapDamaged, (void*)this);
1008         SysTryCatch(NID_UI_CTRL, __pPixmapEventHandler != null, , E_SYSTEM, "[E_SYSTEM] Failed to add a pixmap damage event handle");
1009
1010         return E_SUCCESS;
1011
1012 CATCH:
1013         if (__pPixmapEventHandler)
1014         {
1015                 ecore_event_handler_del(__pPixmapEventHandler);
1016                 __pPixmapEventHandler = null;
1017         }
1018
1019         if (__pixmapDamageHandle)
1020         {
1021                 ecore_x_damage_free(__pixmapDamageHandle);
1022                 __pixmapDamageHandle = 0;
1023         }
1024
1025         if (__pixmap)
1026         {
1027                 XFreePixmap((Display*)ecore_x_display_get(), __pixmap);
1028                 __pixmap = 0;
1029         }
1030
1031         return E_SYSTEM;
1032 }
1033
1034 Pixmap
1035 _OverlayAgent::GetPixmap(void) const
1036 {
1037         return __pixmap;
1038 }
1039
1040 Evas_Object*
1041 _OverlayAgent::GetRendererImageObject(void) const
1042 {
1043         return __pImageObject;
1044 }
1045
1046 bool
1047 _OverlayAgent::IsValidDestinationDimension(const FloatDimension& dimension) const
1048 {
1049         FloatDimension physicalDimensionF = _CoordinateSystemUtils::Transform(dimension);
1050         Dimension physicalDimension = _CoordinateSystemUtils::ConvertToInteger(physicalDimensionF);
1051         SysTryReturn(NID_UI_CTRL, (physicalDimension.width >= GetDstRectMinWidth() && physicalDimension.height >= GetDstRectMinHeight()), false, E_INVALID_ARG,
1052                         "[E_INVALID_ARG] The size of input dimension (logical size : [%.3f, %.3f], physical size : [%d,%d]) is under minimun size."
1053                         ,dimension.width, dimension.height, physicalDimension.width, physicalDimension.height);
1054
1055         FloatRectangle parentBounds = __pParentVE->GetBounds();
1056         SysTryReturn(NID_UI_CTRL, (dimension.width <= parentBounds.width || dimension.height <= parentBounds.height), false, E_INVALID_ARG,
1057                         "[E_INVALID_ARG] The size of input dimension[%.3f, %.3f] is over maximum size[%.3f,%.3f]."
1058                         ,dimension.width, dimension.height, parentBounds.width, parentBounds.height);
1059
1060         return true;
1061 }
1062
1063 int
1064 _OverlayAgent::GetOverlayAgentCount(void)
1065 {
1066         return __overlayAgentCount;
1067 }
1068
1069 IListT<bool>*
1070 _OverlayAgent::GetPixelFormatListN(void)
1071 {
1072         if (!__OverlayAgentBufferPixelFormat[0])
1073         {
1074                 const wchar_t* _UI_REGISTRY_PATH = L"/usr/etc/system-info.ini";
1075                 const wchar_t* _UI_INFO_SESSION = L"UiControlInfo";
1076
1077                 _RegistryImpl registry;
1078                 result r = registry.Construct(_UI_REGISTRY_PATH, REG_OPEN_READ_ONLY, null);
1079                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1080
1081                 String pixelFormatList(null);
1082                 r = registry.GetValue(_UI_INFO_SESSION, L"OverlayRegionBufferPixelFormat", pixelFormatList);
1083                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1084
1085                 bool set = false;
1086                 if (pixelFormatList.Contains(L"ARGB8888"))
1087                 {
1088                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888] = true;
1089                         set = true;
1090                 }
1091
1092                 if (pixelFormatList.Contains(L"RGB565"))
1093                 {
1094                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565] = true;
1095                         set = true;
1096                 }
1097
1098                 if (pixelFormatList.Contains(L"YCbCr420P"))
1099                 {
1100                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR] = true;
1101                         set = true;
1102                 }
1103
1104                 if (pixelFormatList.Contains(L"NV12"))
1105                 {
1106                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12] = true;
1107                         set = true;
1108                 }
1109
1110                 if (pixelFormatList.Contains(L"UYVY"))
1111                 {
1112                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY] = true;
1113                         set = true;
1114                 }
1115
1116                 SysAssertf(set, "The registry file is an invalid.");
1117
1118                 __OverlayAgentBufferPixelFormat[0] = set;
1119         }
1120
1121         std::unique_ptr< ArrayListT<bool> > pFormatList( new (std::nothrow) ArrayListT<bool>());
1122         SysTryReturn(NID_UI_CTRL, pFormatList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] failed to create a list instance");
1123
1124         result r = pFormatList->Construct();
1125         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1126
1127         for (int index = _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888; index <= _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY; index++)
1128         {
1129                 r = pFormatList->Add(__OverlayAgentBufferPixelFormat[index]);
1130         }
1131         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1132
1133         return pFormatList.release();
1134 }
1135
1136 result
1137 _OverlayAgent::EvaluateBounds(OverlayAgentEvaluationOption option, FloatRectangle& rect, bool& modified)
1138 {
1139         modified = false;
1140         SysTryReturnResult(NID_UI_CTRL, rect.width > 0.0f && rect.height > 0.0f,
1141                 E_INVALID_ARG, "The size of input rectangle(%.3f, %.3f) is invalid.", rect.width, rect.height);
1142
1143         Rectangle logicalEvaluatingBounds = _CoordinateSystemUtils::ConvertToInteger(rect);
1144         SysTryReturnResult(NID_UI_CTRL, logicalEvaluatingBounds.width > 0 && logicalEvaluatingBounds.height > 0,
1145                 E_INVALID_ARG, "The size of logical rectangle(%d, %d) is invalid.", logicalEvaluatingBounds.width, logicalEvaluatingBounds.height);
1146
1147         Rectangle physicalRect(_CoordinateSystemUtils::Transform(logicalEvaluatingBounds));
1148         SysTryReturnResult(NID_UI_CTRL, physicalRect.width > 0 && physicalRect.height > 0,
1149                 E_INVALID_ARG, "The size of physical rectangle(%d, %d) is invalid.", physicalRect.width, physicalRect.height);
1150
1151         int physicalMinWidth = GetDstRectMinWidth();
1152         int physicalMinHeight = GetDstRectMinHeight();
1153         SysTryReturnResult(NID_UI_CTRL, physicalMinWidth > 0 && physicalMinHeight > 0, E_SYSTEM, "The value of overlay control's Min width and Min height are invalid.");
1154
1155         const int widthUnit = GetWidthUnit();
1156         const int heightUnit = GetHeightUnit();
1157         SysTryReturnResult(NID_UI_CTRL, widthUnit > 0 && heightUnit > 0, E_SYSTEM, "The value of overlay control's width Unit and height Unit are invalid.");
1158
1159         int screenWidth = _Screen::GetWidth();
1160         int screenHeight = _Screen::GetHeight();
1161         SysTryReturnResult(NID_UI_CTRL, screenWidth > 0 && screenHeight > 0, E_SYSTEM, "The value of screen size is invalid.");
1162
1163         //If orientation status of screen is landscape mode, swap width and height.
1164         {
1165                 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
1166                 int orientation = ecore_evas_rotation_get(pEcoreEvas->GetEcoreEvas());
1167
1168                 if (orientation == 90 || orientation == 270)
1169                 {
1170                         int temp = screenWidth;
1171                         screenWidth = screenHeight;
1172                         screenHeight = temp;
1173                         SysSecureLog(NID_UI_CTRL, "The current value of device screen width is %d, device screen height is %d and orientation is %d", screenWidth, screenHeight, orientation);
1174                 }
1175         }
1176
1177         int physicalMaxWidth= screenWidth - (screenWidth % widthUnit);
1178         int physicalMaxHeight = screenHeight - (screenHeight % heightUnit);
1179         int logicalMaxWidth = _CoordinateSystemUtils::InverseHorizontalTransform(physicalMaxWidth);
1180         int logicalMaxHeight = _CoordinateSystemUtils::InverseVerticalTransform(physicalMaxHeight);
1181
1182         int widthReminder = physicalRect.width % widthUnit;
1183         int heightReminder = physicalRect.height % heightUnit;
1184
1185         //Fix one pixel error when coordinate system transform
1186         if (widthReminder == 1)
1187         {
1188                 physicalRect.width -= 1;
1189                 widthReminder = physicalRect.width % widthUnit;
1190         }
1191
1192         if (heightReminder == 1)
1193         {
1194                 physicalRect.height -= 1;
1195                 heightReminder = physicalRect.height % heightUnit;
1196         }
1197
1198         switch (option)
1199         {
1200         case OVERLAY_AGENT_EVALUATION_OPTION_GREATER_THAN:
1201                 {
1202                         if (logicalEvaluatingBounds.width > logicalMaxWidth || logicalEvaluatingBounds.height > logicalMaxHeight)
1203                         {
1204                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect exceeds logical maximun size.");
1205                                 return E_UNSUPPORTED_OPTION;
1206                         }
1207
1208                         if (physicalRect.width > physicalMaxWidth || physicalRect.height > physicalMaxHeight)
1209                         {
1210                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect exceeds physical maximun size.");
1211                                 return E_UNSUPPORTED_OPTION;
1212                         }
1213
1214                         if (widthReminder != 0)
1215                         {
1216                                 widthReminder -= widthUnit;
1217                         }
1218
1219                         if (heightReminder != 0)
1220                         {
1221                                 heightReminder -= heightUnit;
1222                         }
1223
1224                         physicalRect.width -= widthReminder;
1225                         physicalRect.height -= heightReminder;
1226
1227                         if (physicalRect.width < physicalMinWidth)
1228                         {
1229                                 physicalRect.width = physicalMinWidth;
1230                         }
1231
1232                         if (physicalRect.height < physicalMinHeight)
1233                         {
1234                                 physicalRect.height = physicalMinHeight;
1235                         }
1236                 }
1237                 break;
1238         case OVERLAY_AGENT_EVALUATION_OPTION_LESS_THAN:
1239                 {
1240                         if (physicalRect.width < physicalMinWidth || physicalRect.height < physicalMinHeight)
1241                         {
1242                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect is under minimun size.");
1243
1244                                 return E_UNSUPPORTED_OPTION;
1245                         }
1246
1247                         if (physicalRect.width > physicalMaxWidth)
1248                         {
1249                                 physicalRect.width = physicalMaxWidth + widthReminder;
1250                         }
1251
1252                         if (physicalRect.height > physicalMaxHeight)
1253                         {
1254                                 physicalRect.height = physicalMaxHeight + heightReminder;
1255                         }
1256
1257                         physicalRect.width -= widthReminder;
1258                         physicalRect.height -= heightReminder;
1259                 }
1260                 break;
1261         default:
1262                 {
1263                         SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The input option is an invalid.");
1264
1265                         return E_UNSUPPORTED_OPTION;
1266                 }
1267         }
1268
1269         FloatRectangle originalInputRect(rect);
1270         rect = _CoordinateSystemUtils::ConvertToFloat(_CoordinateSystemUtils::InverseTransform(physicalRect));
1271
1272         if (rect != originalInputRect)
1273         {
1274                 modified = true;
1275                 SysLog(NID_UI_CTRL, "The input bounds [%.3f, %.3f, %.3f, %.3f] is modified to [%.3f, %.3f, %.3f, %.3f]",
1276                                 originalInputRect.x, originalInputRect.y, originalInputRect.width, originalInputRect.height,
1277                                 rect.x, rect.y, rect.width, rect.height);
1278         }
1279         else
1280         {
1281                 SysLog(NID_UI_CTRL, "The evaluated bounds [%.3f, %.3f, %.3f, %.3f] is valid.",
1282                         rect.x, rect.y, rect.width, rect.height);
1283         }
1284
1285         result r = GetLastResult();
1286         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
1287
1288         return r;
1289 }
1290
1291 int
1292 _OverlayAgent::GetValueFromRegistry(const String& key)
1293 {
1294         const wchar_t* _UI_REGISTRY_PATH = L"/usr/etc/system-info.ini";
1295         const wchar_t* _UI_INFO_SESSION = L"UiControlInfo";
1296
1297         _RegistryImpl registry;
1298         result r = registry.Construct(_UI_REGISTRY_PATH, REG_OPEN_READ_ONLY, null);
1299         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1300
1301         String strValue(null);
1302         r = registry.GetValue(_UI_INFO_SESSION, key, strValue);
1303         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1304
1305         int value;
1306         r = Integer::Parse(strValue, value);
1307         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1308
1309         return value;
1310 }
1311
1312 int
1313 _OverlayAgent::GetDstRectMinWidth(void)
1314 {
1315         if (__dstRectMinWidth < 0)
1316         {
1317                 int value = GetValueFromRegistry(L"OverlayDstMinWidth");
1318                 SysTryReturn(NID_UI_CTRL, value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1319
1320                 __dstRectMinWidth = value;
1321                 SysLog(NID_UI_CTRL, "The overlay control's minimum width of destination is [%d]", __dstRectMinWidth);
1322         }
1323
1324         SetLastResult(E_SUCCESS);
1325
1326         return __dstRectMinWidth;
1327 }
1328
1329 int
1330 _OverlayAgent::GetDstRectMinHeight(void)
1331 {
1332         if (__dstRectMinHegith < 0)
1333         {
1334                 int value = GetValueFromRegistry(L"OverlayDstMinHeight");
1335                 SysTryReturn(NID_UI_CTRL, value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1336
1337                 __dstRectMinHegith = value;
1338                 SysLog(NID_UI_CTRL, "The overlay control's minimum height of destination is [%d]", __dstRectMinHegith);
1339         }
1340
1341         SetLastResult(E_SUCCESS);
1342
1343         return __dstRectMinHegith;
1344 }
1345
1346 int
1347 _OverlayAgent::GetSrcRectMinWidth(void)
1348 {
1349         if (__srcRectMinWidth < 0)
1350         {
1351                 int value = GetValueFromRegistry(L"OverlaySrcMinWidth");
1352                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1353
1354                 __srcRectMinWidth = value;
1355                 SysLog(NID_UI_CTRL, "The overlay control's minimum width of source buffer is [%d]", __srcRectMinWidth);
1356         }
1357
1358         SetLastResult(E_SUCCESS);
1359
1360         return __srcRectMinWidth;
1361 }
1362
1363 int
1364 _OverlayAgent::GetSrcRectMinHeight(void)
1365 {
1366         if (__srcRectMinHegith < 0)
1367         {
1368                 int value = GetValueFromRegistry(L"OverlaySrcMinHeight");
1369                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1370
1371                 __srcRectMinHegith = value;
1372                 SysLog(NID_UI_CTRL, "The overlay control's minimum height of source buffer is [%d]", __srcRectMinHegith);
1373         }
1374
1375         SetLastResult(E_SUCCESS);
1376
1377         return __srcRectMinHegith;
1378 }
1379
1380 int
1381 _OverlayAgent::GetWidthUnit(void)
1382 {
1383         if (__overlayWidthUnit < 0)
1384         {
1385                 int value = GetValueFromRegistry(L"OverlayRegionWidthUnit");
1386                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1387
1388                 __overlayWidthUnit = value;
1389                 SysLog(NID_UI_CTRL, "The overlay control's unit width is [%d]", __overlayWidthUnit);
1390         }
1391
1392         SetLastResult(E_SUCCESS);
1393
1394         return __overlayWidthUnit;
1395 }
1396
1397 int
1398 _OverlayAgent::GetHeightUnit(void)
1399 {
1400         if (__overlayHeightUnit < 0)
1401         {
1402                 int value = GetValueFromRegistry(L"OverlayRegionHeightUnit");
1403                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1404
1405                 __overlayHeightUnit = value;
1406                 SysLog(NID_UI_CTRL, "The overlay control's unit height is [%d]", __overlayHeightUnit);
1407         }
1408
1409         SetLastResult(E_SUCCESS);
1410
1411         return __overlayHeightUnit;
1412 }
1413
1414 int
1415 _OverlayAgent::GetMaxCount(void)
1416 {
1417         if (__overlayMaxCount < 0)
1418         {
1419                 int value = GetValueFromRegistry(L"MaxOverlayRegionCount");
1420                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1421
1422                 __overlayMaxCount = value;
1423                 SysLog(NID_UI_CTRL, "The overlay control's maximum count is [%d]", __overlayMaxCount);
1424         }
1425
1426         SetLastResult(E_SUCCESS);
1427
1428         return __overlayMaxCount;
1429 }
1430 }}} // Tizen::Ui
1431