@@ -65,6 +65,9 @@ int img_load(img_t *img, const char *filename) { | |||||
imlib_context_set_image(im); | imlib_context_set_image(im); | ||||
img->re = 0; | img->re = 0; | ||||
img->checkpan = 0; | |||||
img->zoomed = 0; | |||||
img->w = imlib_image_get_width(); | img->w = imlib_image_get_width(); | ||||
img->h = imlib_image_get_height(); | img->h = imlib_image_get_height(); | ||||
@@ -101,32 +104,32 @@ void img_render(img_t *img, win_t *win) { | |||||
if (!img || !win || !imlib_context_get_image()) | if (!img || !win || !imlib_context_get_image()) | ||||
return; | return; | ||||
if (!img->re) { | |||||
/* rendered for the first time */ | |||||
img->re = 1; | |||||
if ((!img->re || !img->zoomed) && SCALE_MODE != SCALE_ZOOM) { | |||||
/* set zoom level to fit image into window */ | /* set zoom level to fit image into window */ | ||||
if (SCALE_MODE != SCALE_ZOOM) { | |||||
zw = (float) win->w / (float) img->w; | |||||
zh = (float) win->h / (float) img->h; | |||||
img->zoom = MIN(zw, zh); | |||||
zw = (float) win->w / (float) img->w; | |||||
zh = (float) win->h / (float) img->h; | |||||
img->zoom = MIN(zw, zh); | |||||
if (img->zoom < zoom_min) | |||||
img->zoom = zoom_min; | |||||
else if (img->zoom > zoom_max) | |||||
img->zoom = zoom_max; | |||||
if (img->zoom < zoom_min) | |||||
img->zoom = zoom_min; | |||||
else if (img->zoom > zoom_max) | |||||
img->zoom = zoom_max; | |||||
if (SCALE_MODE == SCALE_DOWN && img->zoom > 1.0) | |||||
img->zoom = 1.0; | |||||
} | |||||
if (SCALE_MODE == SCALE_DOWN && img->zoom > 1.0) | |||||
img->zoom = 1.0; | |||||
} | |||||
if (!img->re) { | |||||
/* rendered for the first time */ | |||||
img->re = 1; | |||||
/* center image in window */ | /* center image in window */ | ||||
img->x = (win->w - img->w * img->zoom) / 2; | img->x = (win->w - img->w * img->zoom) / 2; | ||||
img->y = (win->h - img->h * img->zoom) / 2; | img->y = (win->h - img->h * img->zoom) / 2; | ||||
} else if (img->cp) { | |||||
/* only useful after zooming */ | |||||
} | |||||
if (img->checkpan) { | |||||
img_check_pan(img, win); | img_check_pan(img, win); | ||||
img->cp = 0; | |||||
img->checkpan = 0; | |||||
} | } | ||||
/* calculate source and destination offsets */ | /* calculate source and destination offsets */ | ||||
@@ -174,7 +177,8 @@ int img_zoom(img_t *img, float z) { | |||||
img->x -= (img->w * z - img->w * img->zoom) / 2; | img->x -= (img->w * z - img->w * img->zoom) / 2; | ||||
img->y -= (img->h * z - img->h * img->zoom) / 2; | img->y -= (img->h * z - img->h * img->zoom) / 2; | ||||
img->zoom = z; | img->zoom = z; | ||||
img->cp = 1; | |||||
img->checkpan = 1; | |||||
img->zoomed = 1; | |||||
return 1; | return 1; | ||||
} else { | } else { | ||||
return 0; | return 0; | ||||
@@ -37,7 +37,8 @@ typedef enum pandir_e { | |||||
typedef struct img_s { | typedef struct img_s { | ||||
float zoom; | float zoom; | ||||
unsigned char re; | unsigned char re; | ||||
unsigned char cp; | |||||
unsigned char checkpan; | |||||
unsigned char zoomed; | |||||
int x; | int x; | ||||
int y; | int y; | ||||
int w; | int w; | ||||
@@ -18,6 +18,7 @@ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <sys/select.h> | |||||
#include <X11/Xlib.h> | #include <X11/Xlib.h> | ||||
#include <X11/Xutil.h> | #include <X11/Xutil.h> | ||||
@@ -45,14 +46,34 @@ const char **filenames; | |||||
unsigned int filecnt; | unsigned int filecnt; | ||||
unsigned int fileidx; | unsigned int fileidx; | ||||
unsigned char timeout; | |||||
#define TITLE_LEN 256 | #define TITLE_LEN 256 | ||||
char win_title[TITLE_LEN]; | char win_title[TITLE_LEN]; | ||||
void run() { | void run() { | ||||
int xfd; | |||||
fd_set fds; | |||||
struct timeval t; | |||||
XEvent ev; | XEvent ev; | ||||
while (!XNextEvent(win.env.dpy, &ev)) { | |||||
if (handler[ev.type]) | |||||
timeout = 0; | |||||
while (1) { | |||||
if (timeout) { | |||||
t.tv_sec = 0; | |||||
t.tv_usec = 250; | |||||
xfd = ConnectionNumber(win.env.dpy); | |||||
FD_ZERO(&fds); | |||||
FD_SET(xfd, &fds); | |||||
if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) { | |||||
img_render(&img, &win); | |||||
timeout = 0; | |||||
} | |||||
} | |||||
if (!XNextEvent(win.env.dpy, &ev) && handler[ev.type]) | |||||
handler[ev.type](&ev); | handler[ev.type](&ev); | ||||
} | } | ||||
} | } | ||||
@@ -175,14 +196,18 @@ void on_keypress(XEvent *ev) { | |||||
if (changed) { | if (changed) { | ||||
img_render(&img, &win); | img_render(&img, &win); | ||||
update_title(); | update_title(); | ||||
timeout = 0; | |||||
} | } | ||||
} | } | ||||
void on_configurenotify(XEvent *ev) { | void on_configurenotify(XEvent *ev) { | ||||
if (!ev) | if (!ev) | ||||
return; | return; | ||||
win_configure(&win, &ev->xconfigure); | |||||
if (win_configure(&win, &ev->xconfigure)) { | |||||
img.checkpan = 1; | |||||
timeout = 1; | |||||
} | |||||
} | } | ||||
void update_title() { | void update_title() { | ||||
@@ -102,19 +102,20 @@ void win_set_title(win_t *win, const char *title) { | |||||
XSetIconName(win->env.dpy, win->xwin, title); | XSetIconName(win->env.dpy, win->xwin, title); | ||||
} | } | ||||
int win_configure(win_t *win, XConfigureEvent *cev) { | |||||
int win_configure(win_t *win, XConfigureEvent *c) { | |||||
int changed; | int changed; | ||||
if (!win) | if (!win) | ||||
return 0; | return 0; | ||||
changed = win->x != cev->x || win->y != cev->y || | |||||
win->w != cev->width || win->h != cev->height; | |||||
win->x = cev->x; | |||||
win->y = cev->y; | |||||
win->w = cev->width; | |||||
win->h = cev->height; | |||||
win->bw = cev->border_width; | |||||
changed = win->w != c->width || win->h != c->height; | |||||
win->x = c->x; | |||||
win->y = c->y; | |||||
win->w = c->width; | |||||
win->h = c->height; | |||||
win->bw = c->border_width; | |||||
return changed; | return changed; | ||||
} | } | ||||