Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions man/feh.pre
Original file line number Diff line number Diff line change
Expand Up @@ -1003,12 +1003,19 @@ zoom the image like the
.Cm --bg-fill
mode.
.
.It Cm --zoom-step Ar percent
.It Cm --zoom-step Ar index
.
Zoom images in and out by
.Ar percent
.Pq default: 25
when using the zoom keys and buttons.
Zoom images in and out by a factor of the nth root
.Pq Ar index
of 2 when using the zoom keys and buttons. The default is the 3rd root,
which means that there will be 3 steps between powers of 2.
.
.It Cm --zoom-rate Ar index
.
Zoom images in and out by a factor of the nth root
.Pq Ar index
of 2 upon entering zoom mode. The default is the 128th root,
which means that there will be 128 pixels between powers of 2.
.
.El
.
Expand Down
53 changes: 28 additions & 25 deletions src/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,29 +242,31 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
winwid->click_offset_x = ev->xbutton.x;
winwid->click_offset_y = ev->xbutton.y;
winwid->old_zoom = winwid->zoom;
winwid->old_step = round(log(winwid->zoom) / opt.zoom_rate);

/* required to adjust the image position in zoom mode */
winwid->im_click_offset_x = (winwid->click_offset_x
- winwid->im_x) / winwid->old_zoom;
- winwid->im_x) / winwid->zoom;
winwid->im_click_offset_y = (winwid->click_offset_y
- winwid->im_y) / winwid->old_zoom;
- winwid->im_y) / winwid->zoom;

} else if (feh_is_bb(EVENT_zoom_in, button, state)) {
D(("Zoom_In Button Press event\n"));
D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
if (winwid->zoom >= ZOOM_MAX || opt.step_rate <= 0)
return;

winwid->click_offset_x = ev->xbutton.x;
winwid->click_offset_y = ev->xbutton.y;
winwid->old_zoom = winwid->zoom;

/* required to adjust the image position in zoom mode */
winwid->im_click_offset_x = (winwid->click_offset_x
- winwid->im_x) / winwid->old_zoom;
- winwid->im_x) / winwid->zoom;
winwid->im_click_offset_y = (winwid->click_offset_y
- winwid->im_y) / winwid->old_zoom;
- winwid->im_y) / winwid->zoom;

/* copied from zoom_in, keyevents.c */
winwid->zoom = winwid->zoom * opt.zoom_rate;
winwid->zoom = exp(++winwid->zoom_step * opt.step_rate);

if (winwid->zoom > ZOOM_MAX)
winwid->zoom = ZOOM_MAX;
Expand All @@ -281,18 +283,20 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
} else if (feh_is_bb(EVENT_zoom_out, button, state)) {
D(("Zoom_Out Button Press event\n"));
D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y));
if (winwid->zoom <= ZOOM_MIN || opt.step_rate <= 0)
return;

winwid->click_offset_x = ev->xbutton.x;
winwid->click_offset_y = ev->xbutton.y;
winwid->old_zoom = winwid->zoom;

/* required to adjust the image position in zoom mode */
winwid->im_click_offset_x = (winwid->click_offset_x
- winwid->im_x) / winwid->old_zoom;
- winwid->im_x) / winwid->zoom;
winwid->im_click_offset_y = (winwid->click_offset_y
- winwid->im_y) / winwid->old_zoom;
- winwid->im_y) / winwid->zoom;

/* copied from zoom_out, keyevents.c */
winwid->zoom = winwid->zoom / opt.zoom_rate;
winwid->zoom = exp(--winwid->zoom_step * opt.step_rate);

if (winwid->zoom < ZOOM_MIN)
winwid->zoom = ZOOM_MIN;
Expand Down Expand Up @@ -400,11 +404,16 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
opt.mode = MODE_NORMAL;
winwid->mode = MODE_NORMAL;

if ((feh_is_bb(EVENT_zoom, button, state))
&& (ev->xbutton.x == winwid->click_offset_x)
&& (ev->xbutton.y == winwid->click_offset_y)) {
winwid->zoom = 1.0;
winwidget_center_image(winwid);
if ((feh_is_bb(EVENT_zoom, button, state))) {
if ((ev->xbutton.x == winwid->click_offset_x)
&& (ev->xbutton.y == winwid->click_offset_y)) {
winwid->zoom = 1.0;
winwid->zoom_step = 0;
winwidget_center_image(winwid);
} else {
winwid->zoom_step = round(log(winwid->zoom) / opt.step_rate);
winwidget_sanitise_offsets(winwid);
}
} else
winwidget_sanitise_offsets(winwid);

Expand Down Expand Up @@ -542,15 +551,9 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev));

winwid = winwidget_get_from_window(ev->xmotion.window);
if (winwid) {
if (ev->xmotion.x > winwid->click_offset_x)
winwid->zoom = winwid->old_zoom + (
((double) ev->xmotion.x - (double) winwid->click_offset_x)
/ 128.0);
else
winwid->zoom = winwid->old_zoom - (
((double) winwid->click_offset_x - (double) ev->xmotion.x)
/ 128.0);
if (winwid && opt.zoom_rate > 0) {
int step = winwid->old_step + ev->xmotion.x - winwid->click_offset_x;
winwid->zoom = exp(step * opt.zoom_rate);

if (winwid->zoom < ZOOM_MIN)
winwid->zoom = ZOOM_MIN;
Expand Down
23 changes: 15 additions & 8 deletions src/keyevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,35 +602,42 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy
feh_event_invoke_action(winwid, 9);
}
else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) {
winwid->old_zoom = winwid->zoom;
winwid->zoom = winwid->zoom * opt.zoom_rate;
if (winwid->zoom >= ZOOM_MAX || opt.step_rate <= 0)
return;

double old_zoom = winwid->zoom;
winwid->zoom = exp(++winwid->zoom_step * opt.step_rate);

if (winwid->zoom > ZOOM_MAX)
winwid->zoom = ZOOM_MAX;

winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
winwid->old_zoom * winwid->zoom);
old_zoom * winwid->zoom);
winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
winwid->old_zoom * winwid->zoom);
old_zoom * winwid->zoom);
winwidget_sanitise_offsets(winwid);
winwidget_render_image(winwid, 0, 0);
}
else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) {
winwid->old_zoom = winwid->zoom;
winwid->zoom = winwid->zoom / opt.zoom_rate;
if (winwid->zoom <= ZOOM_MIN || opt.step_rate <= 0)
return;

double old_zoom = winwid->zoom;
winwid->zoom = exp(--winwid->zoom_step * opt.step_rate);

if (winwid->zoom < ZOOM_MIN)
winwid->zoom = ZOOM_MIN;

winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) /
winwid->old_zoom * winwid->zoom);
old_zoom * winwid->zoom);
winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) /
winwid->old_zoom * winwid->zoom);
old_zoom * winwid->zoom);
winwidget_sanitise_offsets(winwid);
winwidget_render_image(winwid, 0, 0);
}
else if (feh_is_kp(EVENT_zoom_default, state, keysym, button)) {
winwid->zoom = 1.0;
winwid->zoom_step = 0;
winwidget_center_image(winwid);
winwidget_render_image(winwid, 0, 0);
}
Expand Down
21 changes: 16 additions & 5 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ void init_parse_options(int argc, char **argv)
opt.font = NULL;
opt.max_height = opt.max_width = UINT_MAX;

opt.zoom_rate = 1.25;
opt.zoom_rate = M_LN2 / 128.0;
opt.step_rate = M_LN2 / 3.0;

opt.start_list_at = NULL;
opt.jump_on_resort = 1;
Expand Down Expand Up @@ -395,6 +396,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
{"bg-center" , 0, 0, OPTION_bg_center},
{"bg-scale" , 0, 0, OPTION_bg_scale},
{"zoom" , 1, 0, OPTION_zoom},
{"zoom-rate" , 1, 0, OPTION_zoom_rate},
{"zoom-step" , 1, 0, OPTION_zoom_step},
{"no-screen-clip", 0, 0, OPTION_no_screen_clip},
{"index-info" , 1, 0, OPTION_index_info},
Expand Down Expand Up @@ -847,13 +849,22 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
case OPTION_window_id:
opt.x11_windowid = strtol(optarg, NULL, 0);
break;
case OPTION_zoom_step:
case OPTION_zoom_rate:
opt.zoom_rate = atof(optarg);
if ((opt.zoom_rate <= 0)) {
weprintf("Zooming disabled due to --zoom-step=%f", opt.zoom_rate);
opt.zoom_rate = 1.0;
weprintf("Zoom mode disabled due to --zoom-rate=%f", opt.zoom_rate);
opt.zoom_rate = 0.0;
} else {
opt.zoom_rate = M_LN2 / opt.zoom_rate;
}
break;
case OPTION_zoom_step:
opt.step_rate = atof(optarg);
if ((opt.step_rate <= 0)) {
weprintf("Zoom steps disabled due to --zoom-step=%f", opt.step_rate);
opt.step_rate = 0.0;
} else {
opt.zoom_rate = 1 + ((float)opt.zoom_rate / 100);
opt.step_rate = M_LN2 / opt.step_rate;
}
break;
default:
Expand Down
2 changes: 2 additions & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct __fehoptions {
int default_zoom;
int zoom_mode;
double zoom_rate;
double step_rate;
unsigned char adjust_reload;
int xinerama_index;
char *x11_class;
Expand Down Expand Up @@ -216,6 +217,7 @@ OPTION_bg_scale,
OPTION_bg_fill,
OPTION_bg_max,
OPTION_zoom,
OPTION_zoom_rate,
OPTION_zoom_step,
OPTION_zoom_in_rate,
OPTION_zoom_out_rate,
Expand Down
13 changes: 8 additions & 5 deletions src/winwidget.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ static winwidget winwidget_allocate(void)
ret->im_x = 0;
ret->im_y = 0;
ret->zoom = 1.0;
ret->old_zoom = 1.0;
ret->zoom_step = 0;
ret->old_step = 0;

ret->click_offset_x = 0;
ret->click_offset_y = 0;
Expand Down Expand Up @@ -494,6 +495,8 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias)
&& (!opt.default_zoom || required_zoom < winwid->zoom))
winwid->zoom = required_zoom;

winwid->zoom_step = round(log(winwid->zoom) / opt.step_rate);

if (opt.offset_flags & XValue) {
if (opt.offset_flags & XNegative) {
winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x;
Expand Down Expand Up @@ -1065,20 +1068,20 @@ void feh_debug_print_winwid(winwidget w)
"h = %d\n" "im_w = %d\n" "im_h = %d\n" "im_angle = %f\n"
"type = %d\n" "had_resize = %d\n" "im = %p\n" "GC = %p\n"
"pixmap = %ld\n" "name = %s\n" "file = %p\n" "mode = %d\n"
"im_x = %d\n" "im_y = %d\n" "zoom = %f\n" "old_zoom = %f\n"
"click_offset_x = %d\n" "click_offset_y = %d\n"
"im_x = %d\n" "im_y = %d\n" "zoom = %f\n" "zoom_step = %d\n"
"old_step = %d" "click_offset_x = %d\n" "click_offset_y = %d\n"
"has_rotated = %d\n", (void *)w, w->win, w->w, w->h, w->im_w,
w->im_h, w->im_angle, w->type, w->had_resize, w->im, (void *)w->gc,
w->bg_pmap, w->name, (void *)w->file, w->mode, w->im_x, w->im_y,
w->zoom, w->old_zoom, w->click_offset_x, w->click_offset_y,
w->zoom, w->zoom_step, w->old_step, w->click_offset_x, w->click_offset_y,
w->has_rotated);
}

void winwidget_reset_image(winwidget winwid)
{
if (!opt.keep_zoom_vp) {
winwid->zoom = 1.0;
winwid->old_zoom = 1.0;
winwid->zoom_step = 0;
winwid->im_x = 0;
winwid->im_y = 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/winwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ struct __winwidget {
* all the way up to INT_MAX (eww)
*/
double zoom;
double old_zoom;
int zoom_step;
int old_step;

int click_offset_x;
int click_offset_y;
Expand Down