Add screen capturing functionality
[test/tools/screenshooter.git] / src / main.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16 /**
17  * @file        src/main.cpp
18  * @author      Adam Malinowski <a.malinowsk2@partner.samsung.com>
19  * @brief       Main source file of screenshooter
20  */
21
22 #include <cairo.h>
23 #include <efl_util.h>
24 #include <popt.h>
25 #include <stdlib.h>
26 #include <tbm_surface.h>
27
28 const char *DEFAULT_SCREENSHOT_FILENAME = "screenshot.png";
29 const int DEFAULT_SCREENSHOT_WITDH  = 1920;
30 const int DEFAULT_SCREENSHOT_HEIGHT = 1080;
31
32 typedef enum {
33   Capture,
34   Version,
35   Error
36 } Command;
37
38 Command parseArguments(int argc, const char **argv, int *width, int *height, char **filename) {
39   Command ret = Capture;
40   poptContext optCon;
41   int c;
42
43   struct poptOption optionsTable[] = {
44     // Commands
45     { "version", 'v', POPT_ARG_NONE, NULL, 'v', "show version of this binary and exit", NULL },
46     // Options
47     { "width", 'w', POPT_ARG_INT, width, 'w', "set width of captured image", NULL },
48     { "height", 'h', POPT_ARG_INT, height, 'h', "set height of captured image", NULL },
49     { "file", 'f', POPT_ARG_STRING, filename, 'f', "file name to store captured image in", NULL },
50     POPT_AUTOHELP
51     { NULL, 0, 0, NULL, 0, NULL, NULL }
52   };
53
54   optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
55   poptSetOtherOptionHelp(optCon, "command");
56
57   while ((c = poptGetNextOpt(optCon)) >= 0) {
58     switch (c) {
59       case 'v':
60         ret = Version;
61         break;
62     }
63   }
64
65   if (c < -1) {
66     fprintf(stderr, "%s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c));
67     ret = Error;
68   }
69
70   poptFreeContext(optCon);
71
72   return ret;
73 }
74
75 void showVersion(void) {
76   printf("screenshooter %s\n", VERSION);
77 }
78
79 int capture(int width, int height, char *filename) {
80   efl_util_screenshot_h screenshot = NULL;
81   tbm_surface_h tbm_surface = NULL;
82   int ret = EXIT_SUCCESS;
83
84   screenshot = efl_util_screenshot_initialize(width, height);
85   if (screenshot == NULL) {
86     fprintf(stderr, "Screenshot initialization failed!\n");
87     return EXIT_FAILURE;
88   }
89
90   tbm_surface = efl_util_screenshot_take_tbm_surface(screenshot);
91   if (!tbm_surface) {
92     fprintf(stderr, "Taking surface failed!\n");
93     ret = EXIT_FAILURE;
94     goto deinitialize_screenshot;
95   }
96
97   tbm_surface_info_s surface_info;
98   ret = tbm_surface_get_info(tbm_surface, &surface_info);
99   if (ret != TBM_SURFACE_ERROR_NONE) {
100     fprintf(stderr, "Get surface info failed!\n");
101     ret = EXIT_FAILURE;
102     goto destroy_surface;
103   }
104
105   int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
106   cairo_surface_t *surface = cairo_image_surface_create_for_data(surface_info.planes[0].ptr,
107                                                                  CAIRO_FORMAT_ARGB32,
108                                                                  width, height, stride);
109   if (!surface) {
110     fprintf(stderr, "Create cairo surface failed!\n");
111     ret = EXIT_FAILURE;
112     goto destroy_surface;
113   }
114
115   cairo_surface_write_to_png(surface, filename);
116   cairo_surface_destroy(surface);
117   fprintf(stdout, "Captured image: width = %d, height = %d, filename = %s\n", width, height, filename);
118
119 destroy_surface:
120   tbm_surface_destroy(tbm_surface);
121
122 deinitialize_screenshot:
123   efl_util_screenshot_deinitialize(screenshot);
124
125   return ret;
126 }
127
128 int main(int argc, const char **argv) {
129   int ret = EXIT_SUCCESS;
130   int width = DEFAULT_SCREENSHOT_WITDH;
131   int height = DEFAULT_SCREENSHOT_HEIGHT;
132   char *filename = (char *)DEFAULT_SCREENSHOT_FILENAME;
133
134   Command command = parseArguments(argc, argv, &width, &height, &filename);
135   switch (command) {
136     case Capture:
137       ret = capture(width, height, filename);
138       break;
139     case Version:
140       showVersion();
141       break;
142     case Error:
143       ret = EXIT_FAILURE;
144       break;
145   }
146
147   return ret;
148 }