Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / FGrp_CanvasShow.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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        FGrp_CanvasShow.cpp
20  * @brief       This is the implementation file for internal Canvas class.
21  *
22  */
23
24 #include <string.h>
25
26 #include <Ecore_Evas.h>
27 #include <Ecore.h>
28 #include <Ecore_X.h>
29
30 #include <X11/Xlib.h>
31 #include <X11/Xutil.h>
32 #include <X11/extensions/XShm.h>
33 #include <X11/Xatom.h>
34
35 #include <sys/types.h>
36 #include <sys/shm.h>
37
38 #include "FGrp_Callback.h"
39
40 #include <FBaseSysLog.h>
41
42
43 namespace Tizen { namespace Graphics
44 {
45
46 void
47 _FlushCanvas(void)
48 {
49         Ecore_Evas* pEcoreEvas = static_cast<Ecore_Evas*>(_GetDefaultFrameEcoreEvasHandle());
50
51         if (pEcoreEvas)
52         {
53                 ecore_evas_manual_render(pEcoreEvas);
54         }
55 }
56
57 bool
58 _CanvasShowFromMemory(int xDest, int yDest, int xSour, int ySour, int wSour, int hSour, void* pMemory, int width, int height,
59                                           int depth,
60                                           int bytesPerLine)
61 {
62         // check input parameter
63         {
64                 switch (depth)
65                 {
66                 case 32:
67                         break;
68                 case 16:
69                 default:
70                         return false;
71                 }
72                 // pBuffer should be NULL pointer
73                 if (pMemory == null || width <= 0 || height <= 0)
74                 {
75                         return false;
76                 }
77         }
78
79         Ecore_Evas* pEcoreEvas = static_cast<Ecore_Evas*>(_GetDefaultFrameEcoreEvasHandle());
80
81         if (pEcoreEvas == null)
82         {
83                 return false;
84         }
85
86         int xSrc = 0;
87         int ySrc = 0;
88
89         Display* pHdisplay = XOpenDisplay(NULL);
90         int displayWidth = DisplayWidth(pHdisplay, DefaultScreen(pHdisplay));
91         int displayHeight = DisplayHeight(pHdisplay, DefaultScreen(pHdisplay));
92
93         //Window root       = RootWindow(pHdisplay, DefaultScreen(pHdisplay));
94         Window root = (Window) ecore_evas_window_get(pEcoreEvas);
95
96         XShmSegmentInfo shmInfo;
97         XImage* pXimage = XShmCreateImage(pHdisplay, DefaultVisualOfScreen(DefaultScreenOfDisplay(pHdisplay)), 24, ZPixmap,
98                                                                           NULL, &shmInfo, (unsigned int) displayWidth, (unsigned int) displayHeight);
99         if (pXimage == NULL)
100         {
101                 goto CLEAN_UP;
102         }
103
104         // EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync);
105         ecore_evas_comp_sync_set(pEcoreEvas, EINA_FALSE);
106
107         shmInfo.shmid = shmget(IPC_PRIVATE, pXimage->bytes_per_line * pXimage->height, IPC_CREAT | 0777);
108
109         pXimage->data = (char*) shmat(shmInfo.shmid, 0, 0);
110         shmInfo.shmaddr = pXimage->data;
111         shmInfo.readOnly = False;
112
113         // copy to image buffer
114         {
115                 typedef unsigned long Pixel;
116
117                 Pixel* pSrc = reinterpret_cast <Pixel*>(pMemory);
118                 Pixel* pDst = reinterpret_cast <Pixel*>(pXimage->data);
119                 int srcPitch = (bytesPerLine * 8 / depth);
120                 int dstPitch = (pXimage->bytes_per_line * 8 / depth);
121
122                 for (int y = 0; y < height; y++)
123                 {
124                         memcpy(pDst, pSrc, width * sizeof(Pixel));
125                         pSrc += srcPitch;
126                         pDst += dstPitch;
127                 }
128         }
129
130         if (!XShmAttach(pHdisplay, &shmInfo))
131         {
132                 goto CLEAN_UP;
133         }
134
135         XShmPutImage(pHdisplay, root, DefaultGCOfScreen(DefaultScreenOfDisplay(pHdisplay)),
136                                  pXimage,
137                                  xSrc, ySrc, xDest, yDest, width, height, false);
138
139         XSync(pHdisplay, False);
140
141         ecore_evas_comp_sync_set(pEcoreEvas, EINA_TRUE);
142
143         // release the captured buffer
144         {
145                 XShmDetach(pHdisplay, &shmInfo);
146                 shmdt(shmInfo.shmaddr);
147                 shmctl(shmInfo.shmid, IPC_RMID, NULL);
148
149                 XDestroyImage(pXimage);
150                 pXimage = NULL;
151
152                 XCloseDisplay(pHdisplay);
153         }
154
155         // no effect yet
156         {
157                 Evas* pEvas = static_cast<Evas*>(_GetDefaultFrameEvasHandle());
158
159                 if (pEvas)
160                 {
161                         evas_object_image_pixels_dirty_set((Evas_Object*) pEvas, true);
162                         evas_object_show((Evas_Object*) pEvas);
163                 }
164         }
165
166         return true;
167
168 CLEAN_UP:
169         if (pXimage)
170         {
171                 XShmDetach(pHdisplay, &shmInfo);
172                 shmdt(shmInfo.shmaddr);
173                 shmctl(shmInfo.shmid, IPC_RMID, NULL);
174
175                 XDestroyImage(pXimage);
176                 pXimage = NULL;
177         }
178
179         XCloseDisplay(pHdisplay);
180
181         return false;
182 }
183
184 }} // Tizen::Graphics