source: libcaca/trunk/examples/view.c @ 233

Last change on this file since 233 was 233, checked in by Sam Hocevar, 17 years ago
  • examples/view.c: + Added top and bottom status lines, like in mutt and slrn. + Added a status string when loading an image or upon error. + Can load multiple files; use 'n' and 'p' for next and previous. + Clip zoom between -48 and +48.
  • Property svn:keywords set to Id
File size: 9.0 KB
Line 
1/*
2 *   view          image viewer for libcaca
3 *   Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   $Id: view.c 233 2003-11-29 17:36:00Z sam $
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU Lesser General Public
10 *   License as published by the Free Software Foundation; either
11 *   version 2 of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 *   Lesser General Public License for more details.
17 *
18 *   You should have received a copy of the GNU Lesser General Public
19 *   License along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 *   02111-1307  USA
22 */
23
24#include "config.h"
25
26#include <stdio.h>
27#include <string.h>
28#include <malloc.h>
29
30#define X_DISPLAY_MISSING 1
31#include <Imlib2.h>
32
33#include "caca.h"
34
35Imlib_Image image = NULL;
36char *pixels = NULL;
37struct caca_bitmap *bitmap = NULL;
38int x, y, w, h;
39
40int dithering = 1;
41const enum caca_dithering dithering_list[] =
42    { CACA_DITHER_NONE, CACA_DITHER_ORDERED, CACA_DITHER_RANDOM };
43
44static void load_image(const char *);
45
46int main(int argc, char **argv)
47{
48    int quit = 0, update = 1, help = 0, reload = 0;
49    int i, zoom = 0;
50
51    char **list = NULL;
52    int current = 0, items = 0, opts = 1;
53
54    /* Initialise libcaca */
55    if(caca_init())
56    {
57        fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
58        return 1;
59    }
60
61    /* Load items into playlist */
62    for(i = 1; i < argc; i++)
63    {
64        /* Skip options except after `--' */
65        if(opts && argv[i][0] == '-')
66        {
67            if(argv[i][1] == '-' && argv[i][2] == '\0')
68                opts = 0;
69            continue;
70        }
71
72        /* Add argv[i] to the list */
73        if(items)
74            list = realloc(list, (items + 1) * sizeof(char *));
75        else
76            list = malloc(sizeof(char *));
77        list[items] = argv[i];
78        items++;
79
80        reload = 1;
81    }
82
83    /* Go ! */
84    while(!quit)
85    {
86        int ww = caca_get_width();
87        int wh = caca_get_height();
88
89        int event;
90
91        while((event = caca_get_event()))
92        {
93            switch(event)
94            {
95            case CACA_EVENT_KEY_PRESS | 'n':
96            case CACA_EVENT_KEY_PRESS | 'N':
97                if(items) current = (current + 1) % items;
98                reload = 1;
99                break;
100            case CACA_EVENT_KEY_PRESS | 'p':
101            case CACA_EVENT_KEY_PRESS | 'P':
102                if(items) current = (items + current - 1) % items;
103                reload = 1;
104                break;
105            case CACA_EVENT_KEY_PRESS | 'd':
106            case CACA_EVENT_KEY_PRESS | 'D':
107                dithering = (dithering + 1) % 3;
108                update = 1;
109                break;
110            case CACA_EVENT_KEY_PRESS | '+':
111                zoom++;
112                if(zoom > 48) zoom = 48; else update = 1;
113                break;
114            case CACA_EVENT_KEY_PRESS | '-':
115                zoom--;
116                if(zoom < -48) zoom = -48; else update = 1;
117                break;
118            case CACA_EVENT_KEY_PRESS | 'x':
119            case CACA_EVENT_KEY_PRESS | 'X':
120                zoom = 0;
121                update = 1;
122                break;
123            case CACA_EVENT_KEY_PRESS | 'k':
124            case CACA_EVENT_KEY_PRESS | 'K':
125            case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
126                if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
127                update = 1;
128                break;
129            case CACA_EVENT_KEY_PRESS | 'j':
130            case CACA_EVENT_KEY_PRESS | 'J':
131            case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
132                if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
133                update = 1;
134                break;
135            case CACA_EVENT_KEY_PRESS | 'h':
136            case CACA_EVENT_KEY_PRESS | 'H':
137            case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
138                if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
139                update = 1;
140                break;
141            case CACA_EVENT_KEY_PRESS | 'l':
142            case CACA_EVENT_KEY_PRESS | 'L':
143            case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
144                if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
145                update = 1;
146                break;
147            case CACA_EVENT_KEY_PRESS | '?':
148                help = !help;
149                update = 1;
150                break;
151            case CACA_EVENT_KEY_PRESS | 'q':
152            case CACA_EVENT_KEY_PRESS | 'Q':
153                quit = 1;
154                break;
155            }
156        }
157
158        if(items && reload)
159        {
160            char *buffer = malloc(ww + 1);
161
162            /* Reset image-specific runtime variables */
163            zoom = 0;
164
165            snprintf(buffer, ww, " Loading `%s'... ", list[current]);
166            buffer[ww] = '\0';
167            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
168            caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
169            caca_refresh();
170
171            load_image(list[current]);
172            reload = 0;
173            update = 1;
174
175            free(buffer);
176        }
177
178        if(update)
179        {
180            caca_clear();
181            caca_set_dithering(dithering_list[dithering]);
182            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
183
184            if(!items)
185                caca_printf(ww / 2 - 5, wh / 2, " No image. ");
186            else if(!image)
187            {
188                char *buffer = malloc(ww + 1);
189                snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
190                buffer[ww] = '\0';
191                caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
192                free(buffer);
193            }
194            else if(zoom < 0)
195            {
196                int xo = (ww - 1) / 2;
197                int yo = (wh - 1) / 2;
198                int xn = (ww - 1) / (2 - zoom);
199                int yn = (wh - 1) / (2 - zoom);
200                caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
201                                 bitmap, pixels);
202            }
203            else if(zoom > 0)
204            {
205                struct caca_bitmap *newbitmap;
206                int xn = w / (2 + zoom);
207                int yn = h / (2 + zoom);
208                if(x < xn) x = xn;
209                if(y < yn) y = yn;
210                if(xn + x > w) x = w - xn;
211                if(yn + y > h) y = h - yn;
212                newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
213                                           0x00ff0000, 0x0000ff00, 0x000000ff);
214                caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap,
215                                 pixels + 4 * (x - xn) + 4 * w * (y - yn));
216                caca_free_bitmap(newbitmap);
217            }
218            else
219            {
220                caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels);
221            }
222
223            caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
224            caca_draw_line(0, 0, ww - 1, 0, ' ');
225            caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
226            caca_putstr(0, 0, "q:Quit  +/-/x:Zoom  h/j/k/l: Move  "
227                              "d:Dithering  ?:Help");
228            caca_printf(3, wh - 1, "cacaview %s", VERSION);
229            caca_printf(ww - 14, wh - 1,
230                        "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
231
232            if(help)
233            {
234                caca_putstr(2, 2,  " +: zoom in          ");
235                caca_putstr(2, 3,  " -: zoom out         ");
236                caca_putstr(2, 4,  " x: reset zoom       ");
237                caca_putstr(2, 5,  " ------------------- ");
238                caca_putstr(2, 6,  " hjkl: move view     ");
239                caca_putstr(2, 7,  " arrows: move view   ");
240                caca_putstr(2, 8,  " ------------------- ");
241                caca_putstr(2, 9,  " d: dithering method ");
242                caca_putstr(2, 10, " ------------------- ");
243                caca_putstr(2, 11, " ?: help             ");
244                caca_putstr(2, 12, " q: quit             ");
245
246                help = 0;
247            }
248
249            caca_refresh();
250            update = 0;
251        }
252    }
253
254    if(bitmap)
255        caca_free_bitmap(bitmap);
256    if(image)
257        imlib_free_image();
258
259    /* Clean up */
260    caca_end();
261
262    return 0;
263}
264
265static void load_image(const char *name)
266{
267    /* Empty previous data */
268    if(image)
269        imlib_free_image();
270
271    if(bitmap)
272        caca_free_bitmap(bitmap);
273
274    image = NULL;
275    bitmap = NULL;
276
277    /* Load the new image */
278    image = imlib_load_image(name);
279
280    if(!image)
281    {
282        return;
283    }
284
285    imlib_context_set_image(image);
286    pixels = (char *)imlib_image_get_data_for_reading_only();
287    w = imlib_image_get_width();
288    h = imlib_image_get_height();
289    x = w / 2;
290    y = h / 2;
291
292    /* Create the libcaca bitmap */
293    bitmap = caca_create_bitmap(32, w, h, 4 * w,
294                                0x00ff0000, 0x0000ff00, 0x000000ff);
295    if(!bitmap)
296    {
297        imlib_free_image();
298        image = NULL;
299    }
300}
301
Note: See TracBrowser for help on using the repository browser.