1 /*****************************************************************************
2 * This file is part of gfxprim library. *
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. *
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. *
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 *
19 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
26 #include "spiv_config.h"
27 #include "spiv_help.h"
36 static struct key_help help_keys
[] = {
37 {"Esc, Enter, Q", "Quit spiv"},
38 {"Space", "Move to the next image"},
39 {"BackSpace", "Move to the prev image"},
40 {"PgDown", "Move to the start of directory"},
41 {"PgUp", "Move to the end of directory"},
42 {"Home", "Move to the first image"},
43 {"End", "Move to the last image"},
44 {"R", "Rotate by 90 degrees clockwise"},
45 {"E", "Rotate by 90 degrees counterclockwise"},
46 {"W", "Toggle fixed, resizable window"},
47 {"D", "Turn on/off downscale when image is larger than win"},
48 {"U", "Turn on/off upscale when image is smaller than win"},
50 {"I", "Toggle show info box"},
51 {"P", "Toggle show progress"},
52 {"S", "Start/stop slideshow"},
54 {"F1-F10", "Execute action 1 - 10"},
56 {"<, KP Minus", "Zoom out by 50% (by 10% with Shift)"},
57 {">, KP Plus", "Zoom in by 50% (by 10% with Shift)"},
58 {"1", "Resize to the image size"},
59 {"2", "Resize to a half of the image size"},
60 {"3", "Resize to one third of the image size"},
61 {"9", "Resize to one ninth of the image size"},
63 {"0", "Resize to one tenth of the image size"},
64 {"Shift 2", "Resize twice of the image size"},
65 {"Shift 3", "Resize three times of the image size"},
67 {"Up", "Move image by 10px up (by 1 with Shift)"},
68 {"Down", "Move image by 10px down (by 1 with Shift)"},
69 {"Left", "Move image by 10px left (by 1 with Shift)"},
70 {"Right", "Move image by 10px right (by 1 with Shift)"},
72 {"]", "Change to next resampling method"},
73 {"[", "Change to prev resampling method"},
74 {"L", "Toggle low pass filter"},
75 {"C", "Drop image cache"},
78 static const int help_keys_len
= sizeof(help_keys
) / sizeof(*help_keys
);
85 static const struct examples examples
[] = {
87 "Shows all jpeg images in current directory"},
89 "Shows all images stored in zip file"},
91 "Shows all loadable images in current directory"},
92 {"spiv -s 5 vacation/",
93 "Runs slideshow with 5 second delay"},
94 {"spiv -1 'cp %F sorted' images/",
95 "Copies currently loaded image into directory 'sorted/' on pressing F1"},
96 {"spiv -e G1 -d images/",
97 "Emulates 1-bit Grayscale display and turns on Floyd-Steinberg dithering"},
98 {"spiv -b 'X11:use_root' -t 10 images/",
99 "Runs slideshow using X root window as backend window"},
100 {"spiv -b 'X11:create_root' -t 10 images/",
101 "Same as above but works in KDE\n"}
104 static const int examples_len
= sizeof(examples
) / sizeof(*examples
);
111 static struct actions actions
[] = {
112 {'f', "Path to current image"},
113 {'F', "Shell escaped path to current image"},
114 {'n', "Current image filename without extension"},
115 {'N', "Shell escaped image filename without extension"},
116 {'e', "Current image file extension"},
119 static const int actions_len
= sizeof(actions
) / sizeof(*actions
);
121 void print_help(void)
125 printf("Usage: spiv [opts] images or dirs with images\n");
126 spiv_config_print_help();
128 printf(" Action shell command modifiers:\n");
130 for (i
= 0; i
< actions_len
; i
++)
131 printf(" %%%c %s\n", actions
[i
].modifier
, actions
[i
].desc
);
135 printf("Keyboard controls:\n\n");
137 for (i
= 0; i
< help_keys_len
; i
++) {
138 if (help_keys
[i
].desc
[0] == '\0') {
139 printf(" %s\n", help_keys
[i
].keys
);
141 printf(" %-"KEYS_MAX
"s - %s\n",
142 help_keys
[i
].keys
, help_keys
[i
].desc
);
148 printf("Example usage:\n\n");
150 for (i
= 0; i
< examples_len
; i
++)
151 printf("%s\n\t%s\n", examples
[i
].example
, examples
[i
].desc
);
154 const char *man_head
=
155 ".TH spiv 1 2013 GFXprim \"Simple yet Powerful Image Viewer\"\n\n"
157 "spiv \\- Simple yet Powerful Image Viewer\n"
160 "[options] images|dirs\n"
163 "is a fast, lightweight and minimalistic image viewer build on the\n"
164 "top of the GFXprim library.\n"
166 "Spiv supports wide range of image formats, currently supported are\n"
167 "JPEG, PNG, GIF, BMP, TIFF, PSP, PSD, PNM, PCX, JPEG2000 and CBZ\n"
168 "(as well general ZIP archives with images), and more will come in\n"
171 "Spiv supports variety of video backends (via GFXprim backends)\n"
172 "currently these are X11, Linux Framebuffer, SDL and AAlib. Spiv also\n"
173 "supports wide range of backend pixel types from 1bit Grayscale to 32bit RGB\n"
174 "with optional Floyd-Steinberg dithering (even, for example, from RGB888 to RGB565).\n"
176 "Spiv implements feh-like image actions, which are short shell scripts with\n"
177 "printf-like modifiers.\n"
178 "See\n.B ACTIONS\nbelow for further information.\n";
180 static const char *man_tail
=
182 "Bugs happen. If you find one, report it on the GFXprim mailing list at\n"
183 ".I gfxprim@ucw.cz\n"
185 "Spiv is developed by Cyril Hrubis <metan@ucw.cz>\n"
186 ".PP\nGFXprim was/is developed by:\n"
187 ".PP\n.nf\nCyril Hrubis <metan@ucw.cz>\n"
188 ".nf\nJiri \"BlueBear\" Dluhos <jiri.bluebear.dluhos@gmail.com>\n"
189 ".nf\nTomas Gavenciak <gavento@ucw.cz>\n";
191 static const char *actions_help
=
193 "Actions are short shell scripts with printf-like modifiers, the \n"
194 "modifiers are substituted to current image path, name, etc. and executed\n"
195 "by pressing function keys).\n"
197 "Actions could be set via command line parameters or written into the\n"
198 "configuration file and support following modifiers:\n";
206 printf(".SH KEYBOARD CONTROL\n");
208 for (i
= 0; i
< help_keys_len
; i
++) {
209 if (help_keys
[i
].desc
[0] != '\0') {
210 printf(".IP \"%s\"\n", help_keys
[i
].keys
);
211 printf("%s\n", help_keys
[i
].desc
);
215 spiv_config_print_man();
217 puts(".PP\nConfiguration is loaded from /etc/spiv.conf");
218 puts("then ~/.spiv and overriden by command line parameters.\n");
222 for (i
= 0; i
< actions_len
; i
++)
223 printf(".PP\n.B %%%c\n%s\n", actions
[i
].modifier
, actions
[i
].desc
);
225 puts(".SH EXAMPLES");
227 for (i
= 0; i
< examples_len
; i
++)
228 printf(".PP\n.B %s\n.nf\n%s\n\n", examples
[i
].desc
, examples
[i
].example
);
233 static int last_line
;
235 static int redraw_help(GP_Backend
*backend
, unsigned int loff
, GP_Coord xoff
)
237 GP_Pixmap
*c
= backend
->pixmap
;
238 GP_Pixel black
= GP_RGBToPixmapPixel(0x00, 0x00, 0x00, c
);
239 GP_Pixel white
= GP_RGBToPixmapPixel(0xff, 0xff, 0xff, c
);
242 int spacing
= GP_TextHeight(config
.style
)/10 + 2;
243 int height
= GP_TextHeight(config
.style
);
247 GP_Print(c
, config
.style
, 20 + 10 * xoff
, 2, GP_ALIGN_RIGHT
|GP_VALIGN_BOTTOM
,
248 white
, black
, "%s", "Keyboard Controls:");
250 unsigned int max
= 0;
252 for (i
= 0; i
< help_keys_len
; i
++)
253 max
= GP_MAX(max
, GP_TextWidth(config
.style
, help_keys
[i
].keys
));
255 for (i
= loff
; i
< help_keys_len
; i
++) {
256 GP_Coord h
= spacing
+ (i
- loff
+ 1) * (height
+ spacing
);
258 if (h
+ height
+ spacing
> (GP_Coord
)c
->h
) {
263 GP_Print(c
, config
.style
, 20 + 10 * xoff
, h
, GP_ALIGN_RIGHT
|GP_VALIGN_BOTTOM
,
264 white
, black
, "%s", help_keys
[i
].keys
);
265 GP_Print(c
, config
.style
, 20 + 10 * xoff
+ max
, h
, GP_ALIGN_RIGHT
|GP_VALIGN_BOTTOM
,
266 white
, black
, " - %s", help_keys
[i
].desc
);
271 GP_BackendFlip(backend
);
275 void draw_help(GP_Backend
*backend
)
277 int loff
= 0, last
, xoff
= 0;
279 last
= redraw_help(backend
, loff
, xoff
);
284 while (GP_BackendWaitEvent(backend
, &ev
)) {
287 if (ev
.code
!= GP_EV_KEY_DOWN
)
290 switch (ev
.val
.key
.key
) {
292 if (last
< help_keys_len
)
293 last
= redraw_help(backend
, ++loff
, xoff
);
297 last
= redraw_help(backend
, --loff
, xoff
);
300 last
= redraw_help(backend
, loff
, --xoff
);
303 last
= redraw_help(backend
, loff
, ++xoff
);
305 case GP_KEY_PAGE_DOWN
:
306 if (last
< help_keys_len
) {
311 last
= redraw_help(backend
, loff
, xoff
);
319 last
= redraw_help(backend
, loff
, xoff
);
328 case GP_EV_SYS_RESIZE
:
329 GP_BackendResizeAck(backend
);
330 last
= redraw_help(backend
, loff
, xoff
);
333 GP_BackendPutEventBack(backend
, &ev
);