Add sigabort and print image name into stderr.
[gfxprim.git] / demos / fbshow / fbshow.c
blob8b399ed8c34ac3c459be6824f8b4dfb01ba05037
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 fprintf(stderr, "Loading '%s'\n", img_path);
74 if (clear) {
75 char buf[100];
76 snprintf(buf, sizeof(buf), "Loading '%s'", img_path);
77 GP_Fill(&fb->context, black_pixel);
78 GP_BoxCenteredText(&fb->context, NULL, 0, 0,
79 fb->context.w, fb->context.h,
80 buf, white_pixel);
83 if (GP_LoadImage(img_path, &img) == 0) {
84 GP_Context *img2 = image_to_display(img, fb->context.w, fb->context.h);
86 GP_ContextFree(img);
88 if (img2 == NULL)
89 return 1;
91 uint32_t cx = (fb->context.w - img2->w)/2;
92 uint32_t cy = (fb->context.h - img2->h)/2;
94 GP_Fill(&fb->context, black_pixel);
96 GP_Blit(img2, 0, 0, img2->w, img2->h, &fb->context, cx, cy);
98 GP_ContextFree(img2);
101 return 0;
104 int main(int argc, char *argv[])
106 GP_InputDriverLinux *drv = NULL;
107 char *input_dev = NULL;
108 int sleep_sec = 0;
110 int opt;
112 while ((opt = getopt(argc, argv, "i:s:")) != -1) {
113 switch (opt) {
114 case 'i':
115 input_dev = optarg;
116 break;
117 case 's':
118 sleep_sec = atoi(optarg);
119 break;
120 default:
121 fprintf(stderr, "Invalid paramter '%c'\n", opt);
125 GP_SetDebugLevel(10);
127 if (input_dev == NULL) {
128 sleep_sec = 1;
129 } else {
130 drv = GP_InputDriverLinuxOpen(input_dev);
132 if (drv == NULL) {
133 fprintf(stderr, "Failed to initalize input device '%s'\n",
134 input_dev);
135 return 1;
139 signal(SIGINT, sighandler);
140 signal(SIGSEGV, sighandler);
141 signal(SIGBUS, sighandler);
142 signal(SIGABRT, sighandler);
144 fb = GP_FramebufferInit("/dev/fb0");
146 if (fb == NULL) {
147 fprintf(stderr, "Failed to initalize framebuffer\n");
148 return 1;
151 GP_EventSetScreenSize(fb->context.w, fb->context.h);
153 black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, &fb->context);
154 white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, &fb->context);
156 int argf = optind;
157 int argn = argf;
159 show_image(fb, argv[argf], 1);
161 /* Initalize select */
162 fd_set rfds;
163 FD_ZERO(&rfds);
164 FD_SET(drv->fd, &rfds);
165 struct timeval tv = {.tv_sec = sleep_sec, .tv_usec = 0};
166 struct timeval *tvp = sleep_sec ? &tv : NULL;
168 for (;;) {
169 int ret;
171 if (drv != NULL) {
172 ret = select(drv->fd + 1, &rfds, NULL, NULL, tvp);
174 tv.tv_sec = sleep_sec;
176 switch (ret) {
177 case -1:
178 GP_FramebufferExit(fb);
179 return 0;
180 break;
181 case 0:
182 argn++;
183 if (argn >= argc)
184 argn = argf;
186 show_image(fb, argv[argn], 0);
187 break;
188 default:
189 while (GP_InputDriverLinuxRead(drv));
192 FD_SET(drv->fd, &rfds);
193 } else {
194 sleep(sleep_sec);
196 argn++;
197 if (argn >= argc)
198 argn = argf;
200 show_image(fb, argv[argn], 0);
203 /* Read and parse events */
204 GP_Event ev;
206 while (GP_EventGet(&ev)) {
208 GP_EventDump(&ev);
210 switch (ev.type) {
211 case GP_EV_KEY:
212 if (ev.code != GP_EV_KEY_DOWN)
213 continue;
215 switch (ev.val.key.key) {
216 case GP_KEY_ESC:
217 case GP_KEY_ENTER:
218 case GP_KEY_Q:
219 GP_FramebufferExit(fb);
220 return 0;
221 break;
222 case GP_KEY_SPACE:
223 argn++;
224 if (argn >= argc)
225 argn = argf;
226 show_image(fb, argv[argn], 1);
227 break;
229 break;
234 GP_FramebufferExit(fb);
236 return 0;