blob: 96f6449624ccd484e24fa1594fb4d97f597d25bd [file] [log] [blame]
Vojtech Bocek03fd6c52014-03-13 18:46:34 +01001/*
2 * Copyright (C) 2007 The Android Open Source Project
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#include <stdio.h>
18#include <png.h>
19#include <pixelflinger/pixelflinger.h>
20#include <linux/fb.h>
21
22#include "minui.h"
23
24struct fb_var_screeninfo vi;
25GGLSurface gr_mem_surface;
26
27int gr_save_screenshot(const char *dest)
28{
29 uint32_t y, stride_bytes;
30 int res = -1;
31 GGLContext *gl = NULL;
32 GGLSurface surface;
33 uint8_t * volatile img_data = NULL;
34 uint8_t *ptr;
35 FILE *fp = NULL;
36 png_structp png_ptr = NULL;
37 png_infop info_ptr = NULL;
38
39 fp = fopen(dest, "wb");
40 if(!fp)
41 goto exit;
42
43 img_data = malloc(vi.xres * vi.yres * 3);
44 surface.version = sizeof(surface);
45 surface.width = gr_mem_surface.width;
46 surface.height = gr_mem_surface.height;
47 surface.stride = gr_mem_surface.width;
48 surface.data = img_data;
49 surface.format = GGL_PIXEL_FORMAT_RGB_888;
50
51 gglInit(&gl);
52 gl->colorBuffer(gl, &surface);
53 gl->activeTexture(gl, 0);
54
55 gl->bindTexture(gl, &gr_mem_surface);
56 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
57 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
58 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
59 gl->enable(gl, GGL_TEXTURE_2D);
60 gl->texCoord2i(gl, 0, 0);
61 gl->recti(gl, 0, 0, gr_mem_surface.width, gr_mem_surface.height);
62
63 gglUninit(gl);
64 gl = NULL;
65
66 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
67 if (!png_ptr)
68 goto exit;
69
70 info_ptr = png_create_info_struct(png_ptr);
71 if (info_ptr == NULL)
72 goto exit;
73
74 if (setjmp(png_jmpbuf(png_ptr)))
75 goto exit;
76
77 png_init_io(png_ptr, fp);
78 png_set_IHDR(png_ptr, info_ptr, surface.width, surface.height,
79 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
80 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
81 png_write_info(png_ptr, info_ptr);
82
83 ptr = img_data;
84 stride_bytes = surface.width*3;
85 for(y = 0; y < surface.height; ++y)
86 {
87 png_write_row(png_ptr, ptr);
88 ptr += stride_bytes;
89 }
90
91 png_write_end(png_ptr, NULL);
92
93 res = 0;
94exit:
95 if(info_ptr)
96 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
97 if(png_ptr)
98 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
99 if(gl)
100 gglUninit(gl);
101 if(img_data)
102 free(img_data);
103 if(fp)
104 fclose(fp);
105 return res;
106}