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 abowe 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, PPM, JP2 and CBZ (as well general\n"
168 "ZIP archives with images), and more will come in the near future.\n"
170 "Spiv supports variety of video backends (via GFXprim backends)\n"
171 "currently these are X11, Linux Framebuffer, SDL and AAlib. Spiv also\n"
172 "supports wide range of backend pixel types from 1bit Grayscale to 32bit RGB\n"
173 "with optional Floyd-Steinberg dithering (even, for example, from RGB888 to RGB565).\n"
175 "Spiv implements feh-like image actions, which are short shell scripts with\n"
176 "printf-like modifiers.\n"
177 "See\n.B ACTIONS\nbellow for further information.\n";
179 static const char *man_tail
=
181 "Bugs happen. If you find one, report it on the GFXprim mailing list at\n"
182 ".I gfxprim@ucw.cz\n"
184 "Spiv is developed by Cyril Hrubis <chrubis@ucw.cz>\n"
185 ".PP\nGFXprim was/is developed by:\n"
186 ".PP\n.nf\nCyril Hrubis <chrubis@ucw.cz>\n"
187 ".nf\nJiri \"BlueBear\" Dluhos <jiri.bluebear.dluhos@gmail.com>\n"
188 ".nf\nTomas Gavenciak <gavento@ucw.cz>\n";
190 static const char *actions_help
=
192 "Actions are short shell scripts with printf-like modifiers, the \n"
193 "modifiers are substituted to current image path, name, etc. and executed\n"
194 "by pressing function keys).\n"
196 "Actions could be set via command line parameters or written into the\n"
197 "configuration file and support following modifiers:\n";
205 printf(".SH KEYBOARD CONTROL\n");
207 for (i
= 0; i
< help_keys_len
; i
++) {
208 if (help_keys
[i
].desc
[0] != '\0') {
209 printf(".IP \"%s\"\n", help_keys
[i
].keys
);
210 printf("%s\n", help_keys
[i
].desc
);
214 spiv_config_print_man();
216 puts(".PP\nConfiguration is loaded from /etc/spiv.conf");
217 puts("then ~/.spiv and overriden by command line parameters.\n");
221 for (i
= 0; i
< actions_len
; i
++)
222 printf(".PP\n.B %%%c\n%s\n", actions
[i
].modifier
, actions
[i
].desc
);
224 puts(".SH EXAMPLES");
226 for (i
= 0; i
< examples_len
; i
++)
227 printf(".PP\n.B %s\n.nf\n%s\n\n", examples
[i
].desc
, examples
[i
].example
);
232 static int redraw_help(GP_Backend
*backend
, unsigned int loff
, GP_Coord xoff
)
234 GP_Context
*c
= backend
->context
;
235 GP_Pixel black
= GP_ColorToContextPixel(GP_COL_BLACK
, c
);
236 GP_Pixel white
= GP_ColorToContextPixel(GP_COL_WHITE
, c
);
241 GP_Print(c
, NULL
, 20 + 10 * xoff
, 2, GP_ALIGN_RIGHT
|GP_VALIGN_BOTTOM
,
242 white
, black
, "%s", "Keyboard Controls:");
244 for (i
= loff
; i
< help_keys_len
; i
++) {
245 GP_Coord h
= 2 + (i
- loff
+ 1) * 15;
247 if (h
+ 2 >= (GP_Coord
)c
->h
)
250 GP_Print(c
, NULL
, 20 + 10 * xoff
, h
, GP_ALIGN_RIGHT
|GP_VALIGN_BOTTOM
,
251 white
, black
, "%-"KEYS_MAX
"s - %s", help_keys
[i
].keys
, help_keys
[i
].desc
);
255 GP_BackendFlip(backend
);
259 static int max_lines(GP_Backend
*backend
)
261 return (backend
->context
->h
- 4) / 15;
264 void draw_help(GP_Backend
*backend
)
266 int loff
= 0, last
, xoff
= 0;
268 last
= redraw_help(backend
, loff
, xoff
);
273 while (GP_BackendWaitEvent(backend
, &ev
)) {
276 if (ev
.code
!= GP_EV_KEY_DOWN
)
279 switch (ev
.val
.key
.key
) {
281 if (last
< help_keys_len
)
282 last
= redraw_help(backend
, ++loff
, xoff
);
286 last
= redraw_help(backend
, --loff
, xoff
);
289 last
= redraw_help(backend
, loff
, --xoff
);
292 last
= redraw_help(backend
, loff
, ++xoff
);
294 case GP_KEY_PAGE_DOWN
:
295 if (last
< help_keys_len
) {
296 if (loff
+ max_lines(backend
) >= help_keys_len
)
299 loff
+= max_lines(backend
);
301 last
= redraw_help(backend
, loff
, xoff
);
306 loff
-= max_lines(backend
);
309 last
= redraw_help(backend
, loff
, xoff
);
318 case GP_EV_SYS_RESIZE
:
319 GP_BackendResizeAck(backend
);
320 last
= redraw_help(backend
, loff
, xoff
);
323 GP_BackendPutEventBack(backend
, &ev
);