nsxiv26c2179
Refactored thumbs, new files thumbs.[ch]
+191 −89
8 files changed
- M Makefile +1 −1
- M image.c +0 −26
- M image.h +0 −9
- M main.c +17 −45
- A thumbs.c +113 −0
- A thumbs.h +49 −0
- M window.c +9 −7
- M window.h +2 −1
| @@ -1,6 +1,6 @@ | |||
| 1 | 1 | all: sxiv | |
| 2 | 2 | ||
| 3 | − | VERSION=git-20110215 | |
| 3 | + | VERSION=git-20110216 | |
| 4 | 4 | ||
| 5 | 5 | CC?=gcc | |
| 6 | 6 | PREFIX?=/usr/local | |
| @@ -110,32 +110,6 @@ int img_load(img_t *img, const char *filename) { | |||
| 110 | 110 | return 1; | |
| 111 | 111 | } | |
| 112 | 112 | ||
| 113 | − | int img_load_thumb(thumb_t *tn, const char *filename) { | |
| 114 | − | int w, h; | |
| 115 | − | float z, zw, zh; | |
| 116 | − | ||
| 117 | − | if (!tn) | |
| 118 | − | return 0; | |
| 119 | − | ||
| 120 | − | if (!_imlib_load_image(filename)) | |
| 121 | − | return 0; | |
| 122 | − | ||
| 123 | − | w = imlib_image_get_width(); | |
| 124 | − | h = imlib_image_get_height(); | |
| 125 | − | zw = (float) THUMB_SIZE / (float) w; | |
| 126 | − | zh = (float) THUMB_SIZE / (float) h; | |
| 127 | − | z = MIN(zw, zh); | |
| 128 | − | tn->w = z * w; | |
| 129 | − | tn->h = z * h; | |
| 130 | − | ||
| 131 | − | imlib_context_set_drawable(tn->pm); | |
| 132 | − | imlib_render_image_part_on_drawable_at_size(0, 0, w, h, | |
| 133 | − | 0, 0, tn->w, tn->h); | |
| 134 | − | imlib_free_image(); | |
| 135 | − | ||
| 136 | − | return 1; | |
| 137 | − | } | |
| 138 | − | ||
| 139 | 113 | void img_check_pan(img_t *img, win_t *win) { | |
| 140 | 114 | if (!img || !win) | |
| 141 | 115 | return; | |
| @@ -49,20 +49,11 @@ typedef struct img_s { | |||
| 49 | 49 | int h; | |
| 50 | 50 | } img_t; | |
| 51 | 51 | ||
| 52 | − | typedef struct thumb_s { | |
| 53 | − | int x; | |
| 54 | − | int y; | |
| 55 | − | int w; | |
| 56 | − | int h; | |
| 57 | − | Pixmap pm; | |
| 58 | − | } thumb_t; | |
| 59 | − | ||
| 60 | 52 | void img_init(img_t*, win_t*); | |
| 61 | 53 | void img_free(img_t*); | |
| 62 | 54 | ||
| 63 | 55 | int img_check(const char*); | |
| 64 | 56 | int img_load(img_t*, const char*); | |
| 65 | − | int img_load_thumb(thumb_t*, const char*); | |
| 66 | 57 | ||
| 67 | 58 | void img_render(img_t*, win_t*); | |
| 68 | 59 | ||
| @@ -27,9 +27,9 @@ | |||
| 27 | 27 | #include <X11/Xutil.h> | |
| 28 | 28 | #include <X11/keysym.h> | |
| 29 | 29 | ||
| 30 | − | #include "config.h" | |
| 31 | 30 | #include "image.h" | |
| 32 | 31 | #include "options.h" | |
| 32 | + | #include "thumbs.h" | |
| 33 | 33 | #include "util.h" | |
| 34 | 34 | #include "window.h" | |
| 35 | 35 | ||
| @@ -39,13 +39,13 @@ typedef enum appmode_e { | |||
| 39 | 39 | } appmode_t; | |
| 40 | 40 | ||
| 41 | 41 | void update_title(); | |
| 42 | − | void render_thumbs(); | |
| 43 | 42 | int check_append(const char*); | |
| 44 | 43 | void read_dir_rec(const char*); | |
| 45 | 44 | void run(); | |
| 46 | 45 | ||
| 47 | 46 | appmode_t mode; | |
| 48 | 47 | img_t img; | |
| 48 | + | tns_t tns; | |
| 49 | 49 | win_t win; | |
| 50 | 50 | ||
| 51 | 51 | #define DNAME_CNT 512 | |
| @@ -54,9 +54,6 @@ const char **filenames; | |||
| 54 | 54 | int filecnt, fileidx; | |
| 55 | 55 | size_t filesize; | |
| 56 | 56 | ||
| 57 | − | thumb_t *thumbs; | |
| 58 | − | int tvis, tcols, trows; | |
| 59 | − | ||
| 60 | 57 | #define TITLE_LEN 256 | |
| 61 | 58 | char win_title[TITLE_LEN]; | |
| 62 | 59 | ||
| @@ -65,6 +62,7 @@ void cleanup() { | |||
| 65 | 62 | ||
| 66 | 63 | if (!in++) { | |
| 67 | 64 | img_free(&img); | |
| 65 | + | tns_free(&tns, &win); | |
| 68 | 66 | win_close(&win); | |
| 69 | 67 | } | |
| 70 | 68 | } | |
| @@ -130,17 +128,13 @@ int main(int argc, char **argv) { | |||
| 130 | 128 | win_open(&win); | |
| 131 | 129 | img_init(&img, &win); | |
| 132 | 130 | ||
| 133 | − | if (options->thumbnails) { | |
| 134 | − | thumbs = (thumb_t*) s_malloc(filecnt * sizeof(thumb_t)); | |
| 135 | − | for (i = 0; i < filecnt; ++i) { | |
| 136 | − | thumbs[i].pm = win_create_pixmap(&win); | |
| 137 | − | img_load_thumb(&thumbs[i], filenames[i]); | |
| 138 | − | } | |
| 139 | − | } | |
| 131 | + | if (options->thumbnails) | |
| 132 | + | tns_load(&tns, &win, filenames, filecnt); | |
| 140 | 133 | ||
| 141 | 134 | if (options->thumbnails == 2) { | |
| 142 | 135 | mode = MODE_THUMBS; | |
| 143 | − | render_thumbs(); | |
| 136 | + | tns.first = tns.sel = 0; | |
| 137 | + | tns_render(&tns, &win); | |
| 144 | 138 | } else { | |
| 145 | 139 | mode = MODE_NORMAL; | |
| 146 | 140 | load_image(); | |
| @@ -179,35 +173,6 @@ void update_title() { | |||
| 179 | 173 | win_set_title(&win, win_title); | |
| 180 | 174 | } | |
| 181 | 175 | ||
| 182 | − | void render_thumbs() { | |
| 183 | − | int i, cnt, x, y; | |
| 184 | − | ||
| 185 | − | tcols = win.w / (THUMB_SIZE + 10); | |
| 186 | − | trows = win.h / (THUMB_SIZE + 10); | |
| 187 | − | ||
| 188 | − | x = win.w - tcols * (THUMB_SIZE + 10) + 5; | |
| 189 | − | y = win.h - trows * (THUMB_SIZE + 10) + 5; | |
| 190 | − | cnt = MIN(tcols * trows, filecnt); | |
| 191 | − | ||
| 192 | − | win_clear(&win); | |
| 193 | − | ||
| 194 | − | i = 0; | |
| 195 | − | while (i < cnt) { | |
| 196 | − | thumbs[i].x = x + (THUMB_SIZE - thumbs[i].w) / 2; | |
| 197 | − | thumbs[i].y = y + (THUMB_SIZE - thumbs[i].h) / 2; | |
| 198 | − | win_draw_pixmap(&win, thumbs[i].pm, thumbs[i].x, thumbs[i].y, thumbs[i].w, | |
| 199 | − | thumbs[i].h); | |
| 200 | − | if (++i % tcols == 0) { | |
| 201 | − | x = win.w - tcols * (THUMB_SIZE + 10) + 5; | |
| 202 | − | y += THUMB_SIZE + 10; | |
| 203 | − | } else { | |
| 204 | − | x += THUMB_SIZE + 10; | |
| 205 | − | } | |
| 206 | − | } | |
| 207 | − | ||
| 208 | − | win_draw(&win); | |
| 209 | − | } | |
| 210 | − | ||
| 211 | 176 | int check_append(const char *filename) { | |
| 212 | 177 | if (!filename) | |
| 213 | 178 | return 0; | |
| @@ -287,7 +252,10 @@ unsigned char timeout; | |||
| 287 | 252 | int mox, moy; | |
| 288 | 253 | ||
| 289 | 254 | void redraw() { | |
| 290 | − | img_render(&img, &win); | |
| 255 | + | if (mode == MODE_NORMAL) | |
| 256 | + | img_render(&img, &win); | |
| 257 | + | else | |
| 258 | + | tns_render(&tns, &win); | |
| 291 | 259 | update_title(); | |
| 292 | 260 | timeout = 0; | |
| 293 | 261 | } | |
| @@ -513,8 +481,11 @@ void run() { | |||
| 513 | 481 | FD_SET(xfd, &fds); | |
| 514 | 482 | ||
| 515 | 483 | if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) { | |
| 516 | − | img_render(&img, &win); | |
| 517 | 484 | timeout = 0; | |
| 485 | + | if (mode == MODE_NORMAL) | |
| 486 | + | img_render(&img, &win); | |
| 487 | + | else | |
| 488 | + | tns_render(&tns, &win); | |
| 518 | 489 | } | |
| 519 | 490 | } | |
| 520 | 491 | ||
| @@ -535,8 +506,9 @@ void run() { | |||
| 535 | 506 | break; | |
| 536 | 507 | case ConfigureNotify: | |
| 537 | 508 | if (win_configure(&win, &ev.xconfigure)) { | |
| 538 | − | img.checkpan = 1; | |
| 539 | 509 | timeout = 1; | |
| 510 | + | if (mode == MODE_NORMAL) | |
| 511 | + | img.checkpan = 1; | |
| 540 | 512 | } | |
| 541 | 513 | break; | |
| 542 | 514 | case ClientMessage: | |
| @@ -0,0 +1,113 @@ | |||
| 1 | + | /* sxiv: thumbs.c | |
| 2 | + | * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de> | |
| 3 | + | * | |
| 4 | + | * This program is free software; you can redistribute it and/or modify | |
| 5 | + | * it under the terms of the GNU General Public License as published by | |
| 6 | + | * the Free Software Foundation; either version 2 of the License, or | |
| 7 | + | * (at your option) any later version. | |
| 8 | + | * | |
| 9 | + | * This program 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 | |
| 12 | + | * GNU General Public License for more details. | |
| 13 | + | * | |
| 14 | + | * You should have received a copy of the GNU General Public License | |
| 15 | + | * along with this program; if not, write to the Free Software | |
| 16 | + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| 17 | + | */ | |
| 18 | + | ||
| 19 | + | #include <stdlib.h> | |
| 20 | + | ||
| 21 | + | #include <Imlib2.h> | |
| 22 | + | ||
| 23 | + | #include "config.h" | |
| 24 | + | #include "thumbs.h" | |
| 25 | + | #include "util.h" | |
| 26 | + | ||
| 27 | + | const int thumb_dim = THUMB_SIZE + 10; | |
| 28 | + | ||
| 29 | + | void tns_load(tns_t *tns, win_t *win, const char **fnames, int fcnt) { | |
| 30 | + | int i, w, h; | |
| 31 | + | float z, zw, zh; | |
| 32 | + | thumb_t *t; | |
| 33 | + | Imlib_Image *im; | |
| 34 | + | ||
| 35 | + | if (!tns || !win || !fnames || !fcnt) | |
| 36 | + | return; | |
| 37 | + | ||
| 38 | + | tns->thumbs = (thumb_t*) s_malloc(fcnt * sizeof(thumb_t)); | |
| 39 | + | tns->cnt = fcnt; | |
| 40 | + | tns->loaded = 0; | |
| 41 | + | ||
| 42 | + | for (i = 0; i < fcnt; ++i) { | |
| 43 | + | if (!(im = imlib_load_image(fnames[i]))) | |
| 44 | + | continue; | |
| 45 | + | ||
| 46 | + | imlib_context_set_image(im); | |
| 47 | + | ||
| 48 | + | w = imlib_image_get_width(); | |
| 49 | + | h = imlib_image_get_height(); | |
| 50 | + | zw = (float) THUMB_SIZE / (float) w; | |
| 51 | + | zh = (float) THUMB_SIZE / (float) h; | |
| 52 | + | z = MIN(zw, zh); | |
| 53 | + | ||
| 54 | + | t = &tns->thumbs[i]; | |
| 55 | + | t->w = z * w; | |
| 56 | + | t->h = z * h; | |
| 57 | + | ||
| 58 | + | t->pm = win_create_pixmap(win, t->w, t->h); | |
| 59 | + | imlib_context_set_drawable(t->pm); | |
| 60 | + | imlib_render_image_part_on_drawable_at_size(0, 0, w, h, | |
| 61 | + | 0, 0, t->w, t->h); | |
| 62 | + | imlib_free_image(); | |
| 63 | + | } | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | void tns_free(tns_t *tns, win_t *win) { | |
| 67 | + | int i; | |
| 68 | + | ||
| 69 | + | if (!tns) | |
| 70 | + | return; | |
| 71 | + | ||
| 72 | + | for (i = 0; i < tns->cnt; ++i) | |
| 73 | + | win_free_pixmap(win, tns->thumbs[i].pm); | |
| 74 | + | ||
| 75 | + | free(tns->thumbs); | |
| 76 | + | tns->thumbs = NULL; | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | void tns_render(tns_t *tns, win_t *win) { | |
| 80 | + | int i, cnt, x, y; | |
| 81 | + | ||
| 82 | + | if (!tns || !win) | |
| 83 | + | return; | |
| 84 | + | ||
| 85 | + | tns->cols = win->w / thumb_dim; | |
| 86 | + | tns->rows = win->h / thumb_dim; | |
| 87 | + | ||
| 88 | + | cnt = tns->cols * tns->rows; | |
| 89 | + | if (tns->first && tns->first + cnt > tns->cnt) | |
| 90 | + | tns->first = MAX(0, tns->cnt - cnt); | |
| 91 | + | cnt = MIN(tns->first + cnt, tns->cnt); | |
| 92 | + | ||
| 93 | + | win_clear(win); | |
| 94 | + | ||
| 95 | + | x = y = 5; | |
| 96 | + | i = tns->first; | |
| 97 | + | ||
| 98 | + | while (i < cnt) { | |
| 99 | + | tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2; | |
| 100 | + | tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2; | |
| 101 | + | win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x, | |
| 102 | + | tns->thumbs[i].y, tns->thumbs[i].w, tns->thumbs[i].h); | |
| 103 | + | if (++i % tns->cols == 0) { | |
| 104 | + | x = 5; | |
| 105 | + | y += thumb_dim; | |
| 106 | + | } else { | |
| 107 | + | x += thumb_dim; | |
| 108 | + | } | |
| 109 | + | } | |
| 110 | + | ||
| 111 | + | win_draw(win); | |
| 112 | + | } | |
| 113 | + | ||
| @@ -0,0 +1,49 @@ | |||
| 1 | + | /* sxiv: thumbs.h | |
| 2 | + | * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de> | |
| 3 | + | * | |
| 4 | + | * This program is free software; you can redistribute it and/or modify | |
| 5 | + | * it under the terms of the GNU General Public License as published by | |
| 6 | + | * the Free Software Foundation; either version 2 of the License, or | |
| 7 | + | * (at your option) any later version. | |
| 8 | + | * | |
| 9 | + | * This program 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 | |
| 12 | + | * GNU General Public License for more details. | |
| 13 | + | * | |
| 14 | + | * You should have received a copy of the GNU General Public License | |
| 15 | + | * along with this program; if not, write to the Free Software | |
| 16 | + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| 17 | + | */ | |
| 18 | + | ||
| 19 | + | #ifndef THUMBS_H | |
| 20 | + | #define THUMBS_H | |
| 21 | + | ||
| 22 | + | #include "window.h" | |
| 23 | + | ||
| 24 | + | typedef struct thumb_s { | |
| 25 | + | int x; | |
| 26 | + | int y; | |
| 27 | + | int w; | |
| 28 | + | int h; | |
| 29 | + | Pixmap pm; | |
| 30 | + | } thumb_t; | |
| 31 | + | ||
| 32 | + | typedef struct tns_s { | |
| 33 | + | thumb_t *thumbs; | |
| 34 | + | unsigned char loaded; | |
| 35 | + | int cnt; | |
| 36 | + | int cols; | |
| 37 | + | int rows; | |
| 38 | + | int first; | |
| 39 | + | int sel; | |
| 40 | + | } tns_t; | |
| 41 | + | ||
| 42 | + | extern const int thumb_dim; | |
| 43 | + | ||
| 44 | + | void tns_load(tns_t*, win_t*, const char**, int); | |
| 45 | + | void tns_free(tns_t*, win_t*); | |
| 46 | + | ||
| 47 | + | void tns_render(tns_t*, win_t*); | |
| 48 | + | ||
| 49 | + | #endif /* THUMBS_H */ | |
| @@ -211,19 +211,21 @@ void win_toggle_fullscreen(win_t *win) { | |||
| 211 | 211 | SubstructureNotifyMask, &ev); | |
| 212 | 212 | } | |
| 213 | 213 | ||
| 214 | − | Pixmap win_create_pixmap(win_t *win) { | |
| 214 | + | Pixmap win_create_pixmap(win_t *win, int w, int h) { | |
| 215 | 215 | if (!win) | |
| 216 | 216 | return 0; | |
| 217 | 217 | ||
| 218 | − | return XCreatePixmap(win->env.dpy, win->xwin, THUMB_SIZE, THUMB_SIZE, | |
| 219 | − | win->env.depth); | |
| 218 | + | return XCreatePixmap(win->env.dpy, win->xwin, w, h, win->env.depth); | |
| 220 | 219 | } | |
| 221 | 220 | ||
| 222 | − | void win_draw_pixmap(win_t *win, Pixmap pm, int x, int y, int w, int h) { | |
| 223 | − | if (!win) | |
| 224 | − | return; | |
| 221 | + | void win_free_pixmap(win_t *win, Pixmap pm) { | |
| 222 | + | if (win && pm) | |
| 223 | + | XFreePixmap(win->env.dpy, pm); | |
| 224 | + | } | |
| 225 | 225 | ||
| 226 | − | XCopyArea(win->env.dpy, pm, win->pm, bgc, 0, 0, w, h, x, y); | |
| 226 | + | void win_draw_pixmap(win_t *win, Pixmap pm, int x, int y, int w, int h) { | |
| 227 | + | if (win) | |
| 228 | + | XCopyArea(win->env.dpy, pm, win->pm, bgc, 0, 0, w, h, x, y); | |
| 227 | 229 | } | |
| 228 | 230 | ||
| 229 | 231 | void win_clear(win_t *win) { | |
| @@ -63,7 +63,8 @@ int win_moveresize(win_t*, int, int, unsigned int, unsigned int); | |||
| 63 | 63 | ||
| 64 | 64 | void win_toggle_fullscreen(win_t*); | |
| 65 | 65 | ||
| 66 | − | Pixmap win_create_pixmap(win_t*); | |
| 66 | + | Pixmap win_create_pixmap(win_t*, int, int); | |
| 67 | + | void win_free_pixmap(win_t*, Pixmap); | |
| 67 | 68 | void win_draw_pixmap(win_t*, Pixmap, int, int, int, int); | |
| 68 | 69 | ||
| 69 | 70 | void win_clear(win_t*); | |