summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--image.c26
-rw-r--r--image.h9
-rw-r--r--main.c62
-rw-r--r--thumbs.c113
-rw-r--r--thumbs.h49
-rw-r--r--window.c16
-rw-r--r--window.h3
8 files changed, 191 insertions, 89 deletions
diff --git a/Makefile b/Makefile
index 46eb750..de784ab 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
all: sxiv
-VERSION=git-20110215
+VERSION=git-20110216
CC?=gcc
PREFIX?=/usr/local
diff --git a/image.c b/image.c
index d299013..64225b1 100644
--- a/image.c
+++ b/image.c
@@ -110,32 +110,6 @@ int img_load(img_t *img, const char *filename) {
return 1;
}
-int img_load_thumb(thumb_t *tn, const char *filename) {
- int w, h;
- float z, zw, zh;
-
- if (!tn)
- return 0;
-
- if (!_imlib_load_image(filename))
- return 0;
-
- w = imlib_image_get_width();
- h = imlib_image_get_height();
- zw = (float) THUMB_SIZE / (float) w;
- zh = (float) THUMB_SIZE / (float) h;
- z = MIN(zw, zh);
- tn->w = z * w;
- tn->h = z * h;
-
- imlib_context_set_drawable(tn->pm);
- imlib_render_image_part_on_drawable_at_size(0, 0, w, h,
- 0, 0, tn->w, tn->h);
- imlib_free_image();
-
- return 1;
-}
-
void img_check_pan(img_t *img, win_t *win) {
if (!img || !win)
return;
diff --git a/image.h b/image.h
index 49ce70e..fd5b0fe 100644
--- a/image.h
+++ b/image.h
@@ -49,20 +49,11 @@ typedef struct img_s {
int h;
} img_t;
-typedef struct thumb_s {
- int x;
- int y;
- int w;
- int h;
- Pixmap pm;
-} thumb_t;
-
void img_init(img_t*, win_t*);
void img_free(img_t*);
int img_check(const char*);
int img_load(img_t*, const char*);
-int img_load_thumb(thumb_t*, const char*);
void img_render(img_t*, win_t*);
diff --git a/main.c b/main.c
index f4afcf0..4d66595 100644
--- a/main.c
+++ b/main.c
@@ -27,9 +27,9 @@
#include <X11/Xutil.h>
#include <X11/keysym.h>
-#include "config.h"
#include "image.h"
#include "options.h"
+#include "thumbs.h"
#include "util.h"
#include "window.h"
@@ -39,13 +39,13 @@ typedef enum appmode_e {
} appmode_t;
void update_title();
-void render_thumbs();
int check_append(const char*);
void read_dir_rec(const char*);
void run();
appmode_t mode;
img_t img;
+tns_t tns;
win_t win;
#define DNAME_CNT 512
@@ -54,9 +54,6 @@ const char **filenames;
int filecnt, fileidx;
size_t filesize;
-thumb_t *thumbs;
-int tvis, tcols, trows;
-
#define TITLE_LEN 256
char win_title[TITLE_LEN];
@@ -65,6 +62,7 @@ void cleanup() {
if (!in++) {
img_free(&img);
+ tns_free(&tns, &win);
win_close(&win);
}
}
@@ -130,17 +128,13 @@ int main(int argc, char **argv) {
win_open(&win);
img_init(&img, &win);
- if (options->thumbnails) {
- thumbs = (thumb_t*) s_malloc(filecnt * sizeof(thumb_t));
- for (i = 0; i < filecnt; ++i) {
- thumbs[i].pm = win_create_pixmap(&win);
- img_load_thumb(&thumbs[i], filenames[i]);
- }
- }
+ if (options->thumbnails)
+ tns_load(&tns, &win, filenames, filecnt);
if (options->thumbnails == 2) {
mode = MODE_THUMBS;
- render_thumbs();
+ tns.first = tns.sel = 0;
+ tns_render(&tns, &win);
} else {
mode = MODE_NORMAL;
load_image();
@@ -179,35 +173,6 @@ void update_title() {
win_set_title(&win, win_title);
}
-void render_thumbs() {
- int i, cnt, x, y;
-
- tcols = win.w / (THUMB_SIZE + 10);
- trows = win.h / (THUMB_SIZE + 10);
-
- x = win.w - tcols * (THUMB_SIZE + 10) + 5;
- y = win.h - trows * (THUMB_SIZE + 10) + 5;
- cnt = MIN(tcols * trows, filecnt);
-
- win_clear(&win);
-
- i = 0;
- while (i < cnt) {
- thumbs[i].x = x + (THUMB_SIZE - thumbs[i].w) / 2;
- thumbs[i].y = y + (THUMB_SIZE - thumbs[i].h) / 2;
- win_draw_pixmap(&win, thumbs[i].pm, thumbs[i].x, thumbs[i].y, thumbs[i].w,
- thumbs[i].h);
- if (++i % tcols == 0) {
- x = win.w - tcols * (THUMB_SIZE + 10) + 5;
- y += THUMB_SIZE + 10;
- } else {
- x += THUMB_SIZE + 10;
- }
- }
-
- win_draw(&win);
-}
-
int check_append(const char *filename) {
if (!filename)
return 0;
@@ -287,7 +252,10 @@ unsigned char timeout;
int mox, moy;
void redraw() {
- img_render(&img, &win);
+ if (mode == MODE_NORMAL)
+ img_render(&img, &win);
+ else
+ tns_render(&tns, &win);
update_title();
timeout = 0;
}
@@ -513,8 +481,11 @@ void run() {
FD_SET(xfd, &fds);
if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) {
- img_render(&img, &win);
timeout = 0;
+ if (mode == MODE_NORMAL)
+ img_render(&img, &win);
+ else
+ tns_render(&tns, &win);
}
}
@@ -535,8 +506,9 @@ void run() {
break;
case ConfigureNotify:
if (win_configure(&win, &ev.xconfigure)) {
- img.checkpan = 1;
timeout = 1;
+ if (mode == MODE_NORMAL)
+ img.checkpan = 1;
}
break;
case ClientMessage:
diff --git a/thumbs.c b/thumbs.c
new file mode 100644
index 0000000..a1e0fdf
--- /dev/null
+++ b/thumbs.c
@@ -0,0 +1,113 @@
+/* sxiv: thumbs.c
+ * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+
+#include <Imlib2.h>
+
+#include "config.h"
+#include "thumbs.h"
+#include "util.h"
+
+const int thumb_dim = THUMB_SIZE + 10;
+
+void tns_load(tns_t *tns, win_t *win, const char **fnames, int fcnt) {
+ int i, w, h;
+ float z, zw, zh;
+ thumb_t *t;
+ Imlib_Image *im;
+
+ if (!tns || !win || !fnames || !fcnt)
+ return;
+
+ tns->thumbs = (thumb_t*) s_malloc(fcnt * sizeof(thumb_t));
+ tns->cnt = fcnt;
+ tns->loaded = 0;
+
+ for (i = 0; i < fcnt; ++i) {
+ if (!(im = imlib_load_image(fnames[i])))
+ continue;
+
+ imlib_context_set_image(im);
+
+ w = imlib_image_get_width();
+ h = imlib_image_get_height();
+ zw = (float) THUMB_SIZE / (float) w;
+ zh = (float) THUMB_SIZE / (float) h;
+ z = MIN(zw, zh);
+
+ t = &tns->thumbs[i];
+ t->w = z * w;
+ t->h = z * h;
+
+ t->pm = win_create_pixmap(win, t->w, t->h);
+ imlib_context_set_drawable(t->pm);
+ imlib_render_image_part_on_drawable_at_size(0, 0, w, h,
+ 0, 0, t->w, t->h);
+ imlib_free_image();
+ }
+}
+
+void tns_free(tns_t *tns, win_t *win) {
+ int i;
+
+ if (!tns)
+ return;
+
+ for (i = 0; i < tns->cnt; ++i)
+ win_free_pixmap(win, tns->thumbs[i].pm);
+
+ free(tns->thumbs);
+ tns->thumbs = NULL;
+}
+
+void tns_render(tns_t *tns, win_t *win) {
+ int i, cnt, x, y;
+
+ if (!tns || !win)
+ return;
+
+ tns->cols = win->w / thumb_dim;
+ tns->rows = win->h / thumb_dim;
+
+ cnt = tns->cols * tns->rows;
+ if (tns->first && tns->first + cnt > tns->cnt)
+ tns->first = MAX(0, tns->cnt - cnt);
+ cnt = MIN(tns->first + cnt, tns->cnt);
+
+ win_clear(win);
+
+ x = y = 5;
+ i = tns->first;
+
+ while (i < cnt) {
+ tns->thumbs[i].x = x + (THUMB_SIZE - tns->thumbs[i].w) / 2;
+ tns->thumbs[i].y = y + (THUMB_SIZE - tns->thumbs[i].h) / 2;
+ win_draw_pixmap(win, tns->thumbs[i].pm, tns->thumbs[i].x,
+ tns->thumbs[i].y, tns->thumbs[i].w, tns->thumbs[i].h);
+ if (++i % tns->cols == 0) {
+ x = 5;
+ y += thumb_dim;
+ } else {
+ x += thumb_dim;
+ }
+ }
+
+ win_draw(win);
+}
+
diff --git a/thumbs.h b/thumbs.h
new file mode 100644
index 0000000..ae6faa7
--- /dev/null
+++ b/thumbs.h
@@ -0,0 +1,49 @@
+/* sxiv: thumbs.h
+ * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef THUMBS_H
+#define THUMBS_H
+
+#include "window.h"
+
+typedef struct thumb_s {
+ int x;
+ int y;
+ int w;
+ int h;
+ Pixmap pm;
+} thumb_t;
+
+typedef struct tns_s {
+ thumb_t *thumbs;
+ unsigned char loaded;
+ int cnt;
+ int cols;
+ int rows;
+ int first;
+ int sel;
+} tns_t;
+
+extern const int thumb_dim;
+
+void tns_load(tns_t*, win_t*, const char**, int);
+void tns_free(tns_t*, win_t*);
+
+void tns_render(tns_t*, win_t*);
+
+#endif /* THUMBS_H */
diff --git a/window.c b/window.c
index d585c55..0ea3fba 100644
--- a/window.c
+++ b/window.c
@@ -211,19 +211,21 @@ void win_toggle_fullscreen(win_t *win) {
SubstructureNotifyMask, &ev);
}
-Pixmap win_create_pixmap(win_t *win) {
+Pixmap win_create_pixmap(win_t *win, int w, int h) {
if (!win)
return 0;
- return XCreatePixmap(win->env.dpy, win->xwin, THUMB_SIZE, THUMB_SIZE,
- win->env.depth);
+ return XCreatePixmap(win->env.dpy, win->xwin, w, h, win->env.depth);
}
-void win_draw_pixmap(win_t *win, Pixmap pm, int x, int y, int w, int h) {
- if (!win)
- return;
+void win_free_pixmap(win_t *win, Pixmap pm) {
+ if (win && pm)
+ XFreePixmap(win->env.dpy, pm);
+}
- XCopyArea(win->env.dpy, pm, win->pm, bgc, 0, 0, w, h, x, y);
+void win_draw_pixmap(win_t *win, Pixmap pm, int x, int y, int w, int h) {
+ if (win)
+ XCopyArea(win->env.dpy, pm, win->pm, bgc, 0, 0, w, h, x, y);
}
void win_clear(win_t *win) {
diff --git a/window.h b/window.h
index 5ca4eba..c51a26e 100644
--- a/window.h
+++ b/window.h
@@ -63,7 +63,8 @@ int win_moveresize(win_t*, int, int, unsigned int, unsigned int);
void win_toggle_fullscreen(win_t*);
-Pixmap win_create_pixmap(win_t*);
+Pixmap win_create_pixmap(win_t*, int, int);
+void win_free_pixmap(win_t*, Pixmap);
void win_draw_pixmap(win_t*, Pixmap, int, int, int, int);
void win_clear(win_t*);