Reset the framebuffer on ctrl+c.
[gfxprim.git] / demos / fbshow / fbshow.c
blob3b8fb504369aa591fd0adc48de581f60338e9b28
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2011 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
25 Simple framebuffer image viewer.
29 #include <signal.h>
30 #include <unistd.h>
32 #include <GP.h>
33 #include <backends/GP_Framebuffer.h>
34 #include <input/GP_InputDriverLinux.h>
36 static GP_Pixel black_pixel;
37 static GP_Pixel white_pixel;
40 static GP_Framebuffer *fb = NULL;
42 static void sighandler(int signo __attribute__((unused)))
44 if (fb != NULL)
45 GP_FramebufferExit(fb);
47 exit(1);
50 static float calc_img_size(uint32_t img_w, uint32_t img_h,
51 uint32_t src_w, uint32_t src_h)
53 float w_rat = 1.00 * src_w / img_w;
54 float h_rat = 1.00 * src_h / img_h;
56 return GP_MIN(w_rat, h_rat);
59 static GP_Context *image_to_display(GP_Context *img, uint32_t w, uint32_t h)
61 float rat = calc_img_size(img->w, img->h, w, h);
63 // GP_FilterGaussianBlur(img, img, 1, 1, NULL);
65 return GP_FilterResize(img, NULL, GP_INTERP_CUBIC, img->w * rat, img->h * rat, NULL);
68 static int show_image(GP_Framebuffer *fb, const char *img_path, int clear)
70 GP_Context *img;
72 if (clear) {
73 char buf[100];
74 snprintf(buf, sizeof(buf), "Loading '%s'", img_path);
75 GP_Fill(&fb->context, black_pixel);
76 GP_BoxCenteredText(&fb->context, NULL, 0, 0,
77 fb->context.w, fb->context.h,
78 buf, white_pixel);
81 if (GP_LoadImage(img_path, &img) == 0) {
82 GP_Context *img2 = image_to_display(img, fb->context.w, fb->context.h);
84 GP_ContextFree(img);
86 if (img2 == NULL)
87 return 1;
89 uint32_t cx = (fb->context.w - img2->w)/2;
90 uint32_t cy = (fb->context.h - img2->h)/2;
92 GP_Fill(&fb->context, black_pixel);
94 GP_Blit(img2, 0, 0, img2->w, img2->h, &fb->context, cx, cy);
96 GP_ContextFree(img2);
99 return 0;
102 int main(int argc, char *argv[])
104 GP_InputDriverLinux *drv = NULL;
105 char *input_dev = NULL;
106 int sleep_sec = 0;
108 int opt;
110 while ((opt = getopt(argc, argv, "i:s:")) != -1) {
111 switch (opt) {
112 case 'i':
113 input_dev = optarg;
114 break;
115 case 's':
116 sleep_sec = atoi(optarg);
117 break;
118 default:
119 fprintf(stderr, "Invalid paramter '%c'\n", opt);
123 GP_SetDebugLevel(10);
125 if (input_dev == NULL) {
126 sleep_sec = 1;
127 } else {
128 drv = GP_InputDriverLinuxOpen(input_dev);
130 if (drv == NULL) {
131 fprintf(stderr, "Failed to initalize input device '%s'\n",
132 input_dev);
133 return 1;
137 signal(SIGINT, sighandler);
139 fb = GP_FramebufferInit("/dev/fb0");
141 if (fb == NULL) {
142 fprintf(stderr, "Failed to initalize framebuffer\n");
143 return 1;
146 GP_EventSetScreenSize(fb->context.w, fb->context.h);
148 black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, &fb->context);
149 white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, &fb->context);
151 int argf = optind;
152 int argn = argf;
154 show_image(fb, argv[argf], 1);
156 /* Initalize select */
157 fd_set rfds;
158 FD_ZERO(&rfds);
159 FD_SET(drv->fd, &rfds);
160 struct timeval tv = {.tv_sec = sleep_sec, .tv_usec = 0};
161 struct timeval *tvp = sleep_sec ? &tv : NULL;
163 for (;;) {
164 int ret;
166 if (drv != NULL) {
167 ret = select(drv->fd + 1, &rfds, NULL, NULL, tvp);
169 tv.tv_sec = sleep_sec;
171 switch (ret) {
172 case -1:
173 GP_FramebufferExit(fb);
174 return 0;
175 break;
176 case 0:
177 argn++;
178 if (argn >= argc)
179 argn = argf;
181 show_image(fb, argv[argn], 0);
182 break;
183 default:
184 while (GP_InputDriverLinuxRead(drv));
187 FD_SET(drv->fd, &rfds);
188 } else {
189 sleep(sleep_sec);
191 argn++;
192 if (argn >= argc)
193 argn = argf;
195 show_image(fb, argv[argn], 0);
198 /* Read and parse events */
199 GP_Event ev;
201 while (GP_EventGet(&ev)) {
203 GP_EventDump(&ev);
205 switch (ev.type) {
206 case GP_EV_KEY:
207 if (ev.code != GP_EV_KEY_DOWN)
208 continue;
210 switch (ev.val.key.key) {
211 case GP_KEY_ENTER:
212 GP_FramebufferExit(fb);
213 return 0;
214 break;
215 case GP_KEY_ESC:
216 case GP_KEY_SPACE:
217 case GP_KEY_Q:
218 argn++;
219 if (argn >= argc)
220 argn = argf;
221 show_image(fb, argv[argn], 1);
222 break;
224 break;
229 GP_FramebufferExit(fb);
231 return 0;