4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11 * Anastasia Lyupa <a.lyupa@samsung.com>
13 * This library is free software; you can redistribute it and/or modify it under
14 * the terms of the GNU Lesser General Public License as published by the
15 * Free Software Foundation; either version 2.1 of the License, or (at your option)
18 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
19 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
21 * License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this library; if not, write to the Free Software Foundation, Inc., 51
25 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 * - Samsung RnD Institute Russia
33 #include <stdlib.h> // for system
34 #include <sys/types.h> // for stat
35 #include <sys/stat.h> // fot stat
36 #include <unistd.h> // fot stat
37 #include <sys/shm.h> // for shmget, shmat
40 #include <X11/Xutil.h>
41 #include <X11/extensions/XShm.h>
45 #include <Evas_Engine_Buffer.h>
50 #define SCREENSHOT_DIRECTORY "/tmp/da"
52 #define MAX_HEIGHT 720
53 #define CAPTURE_TIMEOUT 2.0
55 typedef struct _screenshot_data
59 XShmSegmentInfo x_shm_info;
63 int convert_image( void* srcbuf, void* dstbuf,
64 pixman_format_code_t src_format,
65 pixman_format_code_t dst_format,
66 int src_width, int src_height,
67 int dst_width, int dst_height,
70 pixman_image_t * src_img;
71 pixman_image_t * dst_img;
72 pixman_transform_t transform;
74 int src_stride, dst_stride;
81 return_val_if_fail (srcbuf != NULL, False);
82 return_val_if_fail (dstbuf != NULL, False);
83 return_val_if_fail (rotate <= 360 && rotate >= -360, False);
87 src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
88 return_val_if_fail (src_bpp > 0, False);
90 dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
91 return_val_if_fail (dst_bpp > 0, False);
93 rotate_step = (rotate + 360) / 90 % 4;
95 src_stride = src_width * src_bpp;
96 dst_stride = dst_width * dst_bpp;
98 src_img = pixman_image_create_bits (src_format, src_width, src_height, srcbuf, src_stride);
99 dst_img = pixman_image_create_bits (dst_format, dst_width, dst_height, dstbuf, dst_stride);
101 goto_if_fail (src_img != NULL, CANT_CONVERT);
102 goto_if_fail (dst_img != NULL, CANT_CONVERT);
104 pixman_transform_init_identity (&transform);
108 int c, s, tx = 0, ty = 0;
115 ty = pixman_int_to_fixed (dst_width);
121 tx = pixman_int_to_fixed (dst_width);
122 ty = pixman_int_to_fixed (dst_height);
128 tx = pixman_int_to_fixed (dst_height);
136 pixman_transform_rotate (&transform, NULL, c, s);
137 pixman_transform_translate (&transform, NULL, tx, ty);
140 pixman_image_set_transform (src_img, &transform);
142 pixman_image_composite (op, src_img, NULL, dst_img,
143 0, 0, 0, 0, 0, 0, dst_width, dst_height);
149 pixman_image_unref (src_img);
151 pixman_image_unref (dst_img);
157 static char* captureScreenShotX(int* pwidth, int* pheight, screenshot_data* sdata)
160 // Atom atom_rotation;
162 sdata->dpy = XOpenDisplay(NULL);
163 if(unlikely(sdata->dpy == NULL))
165 // XOpenDisplay failed!
169 *pwidth = DisplayWidth(sdata->dpy, DefaultScreen(sdata->dpy));
170 *pheight = DisplayHeight(sdata->dpy, DefaultScreen(sdata->dpy));
172 root = RootWindow(sdata->dpy, DefaultScreen(sdata->dpy));
174 sdata->ximage = XShmCreateImage(sdata->dpy, DefaultVisualOfScreen (DefaultScreenOfDisplay (sdata->dpy)), 24,
175 ZPixmap, NULL, &sdata->x_shm_info, (unsigned int)*pwidth, (unsigned int)*pheight);
177 if(sdata->ximage != NULL)
179 sdata->x_shm_info.shmid = shmget(IPC_PRIVATE, sdata->ximage->bytes_per_line * sdata->ximage->height, IPC_CREAT | 0777);
180 sdata->x_shm_info.shmaddr = sdata->ximage->data = shmat(sdata->x_shm_info.shmid, 0, 0);
181 sdata->x_shm_info.readOnly = False;
183 if(XShmAttach(sdata->dpy, &sdata->x_shm_info))
185 if(XShmGetImage(sdata->dpy, root, sdata->ximage, 0, 0, AllPlanes))
187 XSync (sdata->dpy, False);
188 return sdata->ximage->data;
192 ; // XShmGetImage failed !
195 XShmDetach (sdata->dpy, &sdata->x_shm_info);
199 ; // XShmAttach failed !
202 shmdt (sdata->x_shm_info.shmaddr);
203 shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL);
204 XDestroyImage(sdata->ximage);
205 sdata->ximage = NULL;
209 ; // XShmCreateImage failed!
215 static void releaseScreenShotX(screenshot_data* sdata)
219 XShmDetach (sdata->dpy, &sdata->x_shm_info);
220 shmdt (sdata->x_shm_info.shmaddr);
221 shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL);
222 XDestroyImage(sdata->ximage);
228 XCloseDisplay(sdata->dpy);
232 static Evas* create_canvas(int width, int height)
235 Evas_Engine_Info_Buffer* einfo;
239 method = evas_render_method_lookup("buffer");
240 if(unlikely(method <= 0))
242 // ERROR: evas was not compiled with 'buffer' engine!
247 if(unlikely(canvas == NULL))
249 // ERROR: could not instantiate new evas canvas.
253 evas_output_method_set(canvas, method);
254 evas_output_size_set(canvas, width, height);
255 evas_output_viewport_set(canvas, 0, 0, width, height);
257 einfo = (Evas_Engine_Info_Buffer*)evas_engine_info_get(canvas);
258 if(unlikely(einfo == NULL))
260 // ERROR: could not get evas engine info!
265 // ARGB32 is sizeof(int), that is 4 bytes, per pixel
266 pixels = malloc(width * height * sizeof(int));
267 if(unlikely(pixels == NULL))
269 // ERROR: could not allocate canvas pixels!
274 einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
275 einfo->info.dest_buffer = pixels;
276 einfo->info.dest_buffer_row_bytes = width * sizeof(int);
277 einfo->info.use_color_key = 0;
278 einfo->info.alpha_threshold = 0;
279 einfo->info.func.new_update_region = NULL;
280 einfo->info.func.free_update_region = NULL;
281 evas_engine_info_set(canvas, (Evas_Engine_Info*)einfo);
286 static void destroy_canvas(Evas* canvas)
288 Evas_Engine_Info_Buffer* einfo;
290 einfo = (Evas_Engine_Info_Buffer*)evas_engine_info_get(canvas);
291 if(unlikely(einfo == NULL))
293 ; // ERROR: could not get evas engine info!
297 free(einfo->info.dest_buffer);
309 screenshot_data sdata;
310 probeInfo_t probeInfo;
315 setProbePoint(&probeInfo);
317 scrimage = captureScreenShotX(&width, &height, &sdata);
320 ev = create_canvas(width, height);
321 if(likely(ev != NULL))
323 sprintf(dstpath, SCREENSHOT_DIRECTORY "/%d.png", probeInfo.eventIndex);
326 if((img = evas_object_image_add(ev)) != NULL)
329 evas_object_image_data_set(img, NULL);
330 evas_object_image_size_set(img, width, height);
331 evas_object_image_data_set(img, scrimage);
334 if(height > MAX_HEIGHT)
336 width = width * MAX_HEIGHT / height;
338 evas_object_resize(img, width, height);
339 evas_object_image_fill_set(img, 0, 0, width, height);
341 evas_object_image_data_update_add(img, 0, 0, width, height);
344 if(evas_object_image_save(img, dstpath, NULL, "compress=5") != 0)
350 // captureScreen : evas_object_image_save failed
356 // captureScreen : evas_object_image_add failed
362 // captureScreen : create canvas failed
368 // captureScreen : captureScreenShotX failed
373 releaseScreenShotX(&sdata);
382 int initialize_screencapture()
384 // remove all previous screenshot in dir
385 // remove_indir(SCREENSHOT_DIRECTORY);
387 // make screenshot directory
388 // mkdir(SCREENSHOT_DIRECTORY, 0777);
393 int finalize_screencapture()
398 // =======================================================================
399 // screen shot manipulation functions
400 // =======================================================================
402 static Eina_Bool _captureTimer(void* data)
408 return ECORE_CALLBACK_CANCEL;
411 int activateCaptureTimer()
413 ecore_timer_add(CAPTURE_TIMEOUT, _captureTimer, NULL);
417 void _cb_render_post(void* data, Evas* e, void* eventinfo)