1 /* Copyright 2011 Bert Muennich
2  *
3  * This file is part of sxiv.
4  *
5  * sxiv is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published
7  * by the Free Software Foundation; either version 2 of the License,
8  * or (at your option) any later version.
9  *
10  * sxiv is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with sxiv.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef SXIV_H
20 #define SXIV_H
21 
22 #include <stdarg.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <Imlib2.h>
28 #include <X11/Xlib.h>
29 
30 /*
31  * Annotation for functions called in cleanup().
32  * These functions are not allowed to call error(!0, ...) or exit().
33  */
34 #define CLEANUP
35 
36 #ifndef MIN
37 #define MIN(a,b) ((a) < (b) ? (a) : (b))
38 #endif
39 #ifndef MAX
40 #define MAX(a,b) ((a) > (b) ? (a) : (b))
41 #endif
42 
43 #define ARRLEN(a) (sizeof(a) / sizeof((a)[0]))
44 
45 #define STREQ(s1,s2) (strcmp((s1), (s2)) == 0)
46 
47 #define TV_DIFF(t1,t2) (((t1)->tv_sec  - (t2)->tv_sec ) * 1000 + \
48                         ((t1)->tv_usec - (t2)->tv_usec) / 1000)
49 
50 #define TV_SET_MSEC(tv,t) {             \
51   (tv)->tv_sec  = (t) / 1000;           \
52   (tv)->tv_usec = (t) % 1000 * 1000;    \
53 }
54 
55 #define TV_ADD_MSEC(tv,t) {             \
56   (tv)->tv_sec  += (t) / 1000;          \
57   (tv)->tv_usec += (t) % 1000 * 1000;   \
58 }
59 
60 typedef enum {
61 	BO_BIG_ENDIAN,
62 	BO_LITTLE_ENDIAN
63 } byteorder_t;
64 
65 typedef enum {
66 	MODE_IMAGE,
67 	MODE_THUMB
68 } appmode_t;
69 
70 typedef enum {
71 	DIR_LEFT  = 1,
72 	DIR_RIGHT = 2,
73 	DIR_UP    = 4,
74 	DIR_DOWN  = 8
75 } direction_t;
76 
77 typedef enum {
78 	DEGREE_90  = 1,
79 	DEGREE_180 = 2,
80 	DEGREE_270 = 3
81 } degree_t;
82 
83 typedef enum {
84 	FLIP_HORIZONTAL = 1,
85 	FLIP_VERTICAL   = 2
86 } flipdir_t;
87 
88 typedef enum {
89 	SCALE_DOWN,
90 	SCALE_FIT,
91 	SCALE_WIDTH,
92 	SCALE_HEIGHT,
93 	SCALE_ZOOM
94 } scalemode_t;
95 
96 typedef enum {
97 	DRAG_RELATIVE,
98 	DRAG_ABSOLUTE
99 } dragmode_t;
100 
101 typedef enum {
102 	CURSOR_ARROW,
103 	CURSOR_DRAG,
104 	CURSOR_WATCH,
105 	CURSOR_LEFT,
106 	CURSOR_RIGHT,
107 	CURSOR_NONE,
108 
109 	CURSOR_COUNT
110 } cursor_t;
111 
112 typedef enum {
113 	FF_WARN    = 1,
114 	FF_MARK    = 2,
115 	FF_TN_INIT = 4
116 } fileflags_t;
117 
118 typedef struct {
119 	const char *name; /* as given by user */
120 	const char *path; /* always absolute */
121 	fileflags_t flags;
122 } fileinfo_t;
123 
124 /* timeouts in milliseconds: */
125 enum {
126 	TO_REDRAW_RESIZE = 75,
127 	TO_REDRAW_THUMBS = 200,
128 	TO_CURSOR_HIDE   = 1200,
129 	TO_DOUBLE_CLICK  = 300
130 };
131 
132 typedef void (*timeout_f)(void);
133 
134 typedef struct arl arl_t;
135 typedef struct img img_t;
136 typedef struct opt opt_t;
137 typedef struct tns tns_t;
138 typedef struct win win_t;
139 
140 
141 /* autoreload.c */
142 
143 struct arl {
144 	int fd;
145 	int wd_dir;
146 	int wd_file;
147 	char *filename;
148 };
149 
150 void arl_init(arl_t*);
151 void arl_cleanup(arl_t*);
152 void arl_setup(arl_t*, const char* /* result of realpath(3) */);
153 bool arl_handle(arl_t*);
154 
155 
156 /* commands.c */
157 
158 typedef int arg_t;
159 typedef bool (*cmd_f)(arg_t);
160 
161 #define G_CMD(c) g_##c,
162 #define I_CMD(c) i_##c,
163 #define T_CMD(c) t_##c,
164 
165 typedef enum {
166 #include "commands.lst"
167 	CMD_COUNT
168 } cmd_id_t;
169 
170 typedef struct {
171 	int mode;
172 	cmd_f func;
173 } cmd_t;
174 
175 typedef struct {
176 	unsigned int mask;
177 	KeySym ksym;
178 	cmd_id_t cmd;
179 	arg_t arg;
180 } keymap_t;
181 
182 typedef struct {
183 	unsigned int mask;
184 	unsigned int button;
185 	cmd_id_t cmd;
186 	arg_t arg;
187 } button_t;
188 
189 extern const cmd_t cmds[CMD_COUNT];
190 
191 
192 /* image.c */
193 
194 typedef struct {
195 	Imlib_Image im;
196 	unsigned int delay;
197 } img_frame_t;
198 
199 typedef struct {
200 	img_frame_t *frames;
201 	int cap;
202 	int cnt;
203 	int sel;
204 	bool animate;
205 	int framedelay;
206 	int length;
207 } multi_img_t;
208 
209 struct img {
210 	Imlib_Image im;
211 	int w;
212 	int h;
213 
214 	win_t *win;
215 	float x;
216 	float y;
217 
218 	scalemode_t scalemode;
219 	float zoom;
220 
221 	bool checkpan;
222 	bool dirty;
223 	bool aa;
224 	bool alpha;
225 
226 	Imlib_Color_Modifier cmod;
227 	int gamma;
228 
229 	struct {
230 		bool on;
231 		int delay;
232 	} ss;
233 
234 	multi_img_t multi;
235 };
236 
237 void img_init(img_t*, win_t*);
238 bool img_load(img_t*, const fileinfo_t*);
239 CLEANUP void img_close(img_t*, bool);
240 void img_render(img_t*);
241 bool img_fit_win(img_t*, scalemode_t);
242 bool img_zoom(img_t*, float);
243 bool img_zoom_in(img_t*);
244 bool img_zoom_out(img_t*);
245 bool img_pos(img_t*, float, float);
246 bool img_move(img_t*, float, float);
247 bool img_pan(img_t*, direction_t, int);
248 bool img_pan_edge(img_t*, direction_t);
249 void img_rotate(img_t*, degree_t);
250 void img_flip(img_t*, flipdir_t);
251 void img_toggle_antialias(img_t*);
252 bool img_change_gamma(img_t*, int);
253 bool img_frame_navigate(img_t*, int);
254 bool img_frame_animate(img_t*);
255 
256 
257 /* options.c */
258 
259 struct opt {
260 	/* file list: */
261 	char **filenames;
262 	bool from_stdin;
263 	bool to_stdout;
264 	bool recursive;
265 	int filecnt;
266 	int startnum;
267 
268 	/* image: */
269 	scalemode_t scalemode;
270 	float zoom;
271 	bool animate;
272 	int gamma;
273 	int slideshow;
274 	int framerate;
275 
276 	/* window: */
277 	bool fullscreen;
278 	bool hide_bar;
279 	long embed;
280 	char *geometry;
281 	char *res_name;
282 
283 	/* misc flags: */
284 	bool quiet;
285 	bool thumb_mode;
286 	bool clean_cache;
287 	bool private_mode;
288 };
289 
290 extern const opt_t *options;
291 
292 void print_usage(void);
293 void print_version(void);
294 void parse_options(int, char**);
295 
296 
297 /* thumbs.c */
298 
299 typedef struct {
300 	Imlib_Image im;
301 	int w;
302 	int h;
303 	int x;
304 	int y;
305 } thumb_t;
306 
307 struct tns {
308 	fileinfo_t *files;
309 	thumb_t *thumbs;
310 	const int *cnt;
311 	int *sel;
312 	int initnext;
313 	int loadnext;
314 	int first, end;
315 	int r_first, r_end;
316 
317 	win_t *win;
318 	int x;
319 	int y;
320 	int cols;
321 	int rows;
322 	int zl;
323 	int bw;
324 	int dim;
325 
326 	bool dirty;
327 };
328 
329 void tns_clean_cache(tns_t*);
330 void tns_init(tns_t*, fileinfo_t*, const int*, int*, win_t*);
331 CLEANUP void tns_free(tns_t*);
332 bool tns_load(tns_t*, int, bool, bool);
333 void tns_unload(tns_t*, int);
334 void tns_render(tns_t*);
335 void tns_mark(tns_t*, int, bool);
336 void tns_highlight(tns_t*, int, bool);
337 bool tns_move_selection(tns_t*, direction_t, int);
338 bool tns_scroll(tns_t*, direction_t, bool);
339 bool tns_zoom(tns_t*, int);
340 int tns_translate(tns_t*, int, int);
341 
342 
343 /* util.c */
344 
345 #include <dirent.h>
346 
347 typedef struct {
348 	DIR *dir;
349 	char *name;
350 	int d;
351 	bool recursive;
352 
353 	char **stack;
354 	int stcap;
355 	int stlen;
356 } r_dir_t;
357 
358 extern const char *progname;
359 
360 void* emalloc(size_t);
361 void* erealloc(void*, size_t);
362 char* estrdup(const char*);
363 void error(int, int, const char*, ...);
364 void size_readable(float*, const char**);
365 int r_opendir(r_dir_t*, const char*, bool);
366 int r_closedir(r_dir_t*);
367 char* r_readdir(r_dir_t*, bool);
368 int r_mkdir(char*);
369 
370 
371 /* window.c */
372 
373 #include <X11/Xutil.h>
374 #include <X11/Xft/Xft.h>
375 
376 enum {
377 	BAR_L_LEN = 512,
378 	BAR_R_LEN = 64
379 };
380 
381 enum {
382 	ATOM_WM_DELETE_WINDOW,
383 	ATOM__NET_WM_NAME,
384 	ATOM__NET_WM_ICON_NAME,
385 	ATOM__NET_WM_ICON,
386 	ATOM__NET_WM_STATE,
387 	ATOM__NET_WM_STATE_FULLSCREEN,
388 	ATOM_COUNT
389 };
390 
391 typedef struct {
392 	Display *dpy;
393 	int scr;
394 	int scrw, scrh;
395 	Visual *vis;
396 	Colormap cmap;
397 	int depth;
398 } win_env_t;
399 
400 typedef struct {
401 	size_t size;
402 	char *p;
403 	char *buf;
404 } win_bar_t;
405 
406 struct win {
407 	Window xwin;
408 	win_env_t env;
409 
410 	XftColor bg;
411 	XftColor fg;
412 
413 	int x;
414 	int y;
415 	unsigned int w;
416 	unsigned int h; /* = win height - bar height */
417 	unsigned int bw;
418 
419 	struct {
420 		int w;
421 		int h;
422 		Pixmap pm;
423 	} buf;
424 
425 	struct {
426 		unsigned int h;
427 		win_bar_t l;
428 		win_bar_t r;
429 	} bar;
430 };
431 
432 extern Atom atoms[ATOM_COUNT];
433 
434 void win_init(win_t*);
435 void win_open(win_t*);
436 CLEANUP void win_close(win_t*);
437 bool win_configure(win_t*, XConfigureEvent*);
438 void win_toggle_fullscreen(win_t*);
439 void win_toggle_bar(win_t*);
440 void win_clear(win_t*);
441 void win_draw(win_t*);
442 void win_draw_rect(win_t*, int, int, int, int, bool, int, unsigned long);
443 void win_set_title(win_t*, const char*);
444 void win_set_cursor(win_t*, cursor_t);
445 void win_cursor_pos(win_t*, int*, int*);
446 
447 #endif /* SXIV_H */
448 
449