Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / FGrp_BitmapScreenCapture.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_BitmapScreenCapture.cpp
20  * @brief       This is the cpp file for BitmapScreenCapture.
21  *
22  */
23
24 #include <new>
25 #include <string.h>
26
27 #include <Ecore_Evas.h>
28 #include <Ecore.h>
29 #include <Ecore_X.h>
30
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/extensions/XShm.h>
34 #include <X11/Xatom.h>
35
36 #include <sys/types.h>
37 #include <sys/shm.h>
38
39 #include "FGrp_Callback.h"
40
41
42 namespace // unnamed
43 {
44         Window
45         GetEvasWindow(void)
46         {
47                 Ecore_Evas* pEcoreEvas = static_cast<Ecore_Evas*>(Tizen::Graphics::_GetDefaultFrameEcoreEvasHandle());
48
49                 if (pEcoreEvas == null)
50                 {
51                         return BadWindow;
52                 }
53
54                 return (Window) ecore_evas_window_get(pEcoreEvas);
55         }
56 }
57
58 namespace Tizen { namespace Graphics
59 {
60
61 bool
62 _GetScreenShot(int depth, unsigned char*& pOutBuffer, int& screenWidth, int& screenHeight)
63 {
64         // check input parameter
65         {
66                 switch (depth)
67                 {
68                 case 32:
69                         break;
70                 case 16:
71                 default:
72                         return false;
73                 }
74
75                 // pBuffer should be NULL pointer
76                 if (pOutBuffer != NULL)
77                 {
78                         return false;
79                 }
80         }
81
82         unsigned char* pTempBuffer = 0;
83
84         Display* pDisplay = XOpenDisplay(NULL);
85         int displayWidth = DisplayWidth(pDisplay, DefaultScreen(pDisplay));
86         int displayHeight = DisplayHeight(pDisplay, DefaultScreen(pDisplay));
87
88         // Can not use a root window --> RootWindow(pDisplay, DefaultScreen(pDisplay))
89         Window root = GetEvasWindow();
90
91         XShmSegmentInfo shmInfo;
92         XImage* pXimage = XShmCreateImage(pDisplay, DefaultVisualOfScreen(DefaultScreenOfDisplay(pDisplay)), 24, ZPixmap,
93                                                                           NULL, &shmInfo, (unsigned int) displayWidth, (unsigned int) displayHeight);
94         if (pXimage == NULL)
95         {
96                 goto CLEAN_UP;
97         }
98
99         shmInfo.shmid = shmget(IPC_PRIVATE, pXimage->bytes_per_line * pXimage->height, IPC_CREAT | 0777);
100
101         pXimage->data = (char*) shmat(shmInfo.shmid, 0, 0);
102         shmInfo.shmaddr = pXimage->data;
103         shmInfo.readOnly = False;
104
105         if (!XShmAttach(pDisplay, &shmInfo))
106         {
107                 goto CLEAN_UP;
108         }
109
110         if (!XShmGetImage(pDisplay, root, pXimage, 0, 0, AllPlanes))
111         {
112                 goto CLEAN_UP;
113         }
114
115         XSync(pDisplay, False);
116
117         // Apply screen rotation
118         {
119 #if 0
120                 char* rot_buffer;
121                 Atom atom_rotaion;
122                 int rotate;
123
124                 atom_rotaion = XInternAtom(dpy, "X_SCREEN_ROTATION", True);
125
126                 if (!atom_rotaion || !getXwindowProperty(root, atom_rotaion, XA_CARDINAL, (unsigned char*) &rotate, 1))
127                 {
128                         rotate = RR_Rotate_0;
129                 }
130
131                 if (rotate == RR_Rotate_90 || rotate == RR_Rotate_270)
132                 {
133                         rot_buffer = calloc(ximage->bytes_per_line * ximage->height, 1);
134
135                         convert_image((uint32_t*) ximage->data,
136                                                   (uint32_t*) rot_buffer,
137                                                   PIXMAN_x8b8g8r8, PIXMAN_x8b8g8r8,
138                                                   height, width, width, height,
139                                                   (rotate == RR_Rotate_90) ? 90 : 270);
140
141                         ret = rot_buffer;
142                 }
143
144                 // assign buffer
145                 {
146                         //??
147                 }
148
149                 // release
150                 if (rot_buffer)
151                 {
152                         free(rot_buffer);
153                         rot_buffer = NULL;
154                 }
155 #endif
156         }
157
158         // copy from the captured buffer
159         {
160                 int bufferSize = pXimage->bytes_per_line * pXimage->height;
161
162                 pTempBuffer = new (std::nothrow) unsigned char[bufferSize];
163
164                 if (pTempBuffer == NULL)
165                 {
166                         goto CLEAN_UP;
167                 }
168
169                 memcpy(pTempBuffer, pXimage->data, bufferSize);
170         }
171
172         // result
173         pOutBuffer = pTempBuffer;
174         screenWidth = pXimage->width;
175         screenHeight = pXimage->height;
176
177         // release the captured buffer
178         {
179                 XShmDetach(pDisplay, &shmInfo);
180                 shmdt(shmInfo.shmaddr);
181                 shmctl(shmInfo.shmid, IPC_RMID, NULL);
182
183                 XDestroyImage(pXimage);
184                 pXimage = NULL;
185
186                 XCloseDisplay(pDisplay);
187         }
188
189         return true;
190
191 CLEAN_UP:
192         delete[] pTempBuffer;
193
194         if (pXimage)
195         {
196                 XShmDetach(pDisplay, &shmInfo);
197                 shmdt(shmInfo.shmaddr);
198                 shmctl(shmInfo.shmid, IPC_RMID, NULL);
199
200                 XDestroyImage(pXimage);
201                 pXimage = NULL;
202         }
203
204         XCloseDisplay(pDisplay);
205
206         return false;
207 }
208
209 }} // Tizen::Graphics