From 7eb9d73e908d3c10c06521bb211dc571cb3a8e35 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 16 Sep 2017 20:36:52 +0200 Subject: Add toggle_fixed_geometry ("g") keybinding to enable/disable window auto-resize Closes #326 --- src/options.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/options.h') diff --git a/src/options.h b/src/options.h index 5a5ce84..ef7f471 100644 --- a/src/options.h +++ b/src/options.h @@ -208,6 +208,7 @@ struct __fehkb { struct __fehkey reload; struct __fehkey blur; struct __fehkey rotate; + struct __fehkey toggle_fixed_geometry; }; void init_parse_options(int argc, char **argv); -- cgit v1.2.3 From 1ed8c69012eb238082dc4bb6befa10fc7b9426fa Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 24 Sep 2017 19:15:25 +0200 Subject: Replace keybinding struct with an array of named bindings --- src/events.c | 96 ++++++------- src/keyevents.c | 433 +++++++++++++++++++++----------------------------------- src/options.h | 143 +++++++++---------- 3 files changed, 272 insertions(+), 400 deletions(-) (limited to 'src/options.h') diff --git a/src/events.c b/src/events.c index b20fd4f..947e69f 100644 --- a/src/events.c +++ b/src/events.c @@ -35,7 +35,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define FEH_JITTER_OFFSET 2 #define FEH_JITTER_TIME 1 -extern fehkb keys; +extern struct __fehkey keys[EVENT_LIST_END]; +fehkey *feh_str_to_kb(char *action); feh_event_handler *ev_handler[LASTEvent]; @@ -45,10 +46,10 @@ static void feh_event_handle_LeaveNotify(XEvent * ev); static void feh_event_handle_MotionNotify(XEvent * ev); static void feh_event_handle_ClientMessage(XEvent * ev); -static void feh_set_bb(fehkey *bb, int modifier, char button) +static void feh_set_bb(unsigned int bb_index, int modifier, char button) { - bb->state = modifier; - bb->button = button; + keys[bb_index].state = modifier; + keys[bb_index].button = button; } static void feh_set_parse_bb_partial(fehkey *button, char *binding) @@ -101,13 +102,13 @@ void init_buttonbindings(void) FILE *conf = NULL; int read = 0; - feh_set_bb(&keys.pan, 0, 1); - feh_set_bb(&keys.zoom, 0, 2); - feh_set_bb(&keys.toggle_menu, 0, 3); - feh_set_bb(&keys.prev_img, 0, 4); - feh_set_bb(&keys.next_img, 0, 5); - feh_set_bb(&keys.blur, 4, 1); - feh_set_bb(&keys.rotate, 4, 2); + feh_set_bb(EVENT_pan, 0, 1); + feh_set_bb(EVENT_zoom, 0, 2); + feh_set_bb(EVENT_toggle_menu, 0, 3); + feh_set_bb(EVENT_prev_img, 0, 4); + feh_set_bb(EVENT_next_img, 0, 5); + feh_set_bb(EVENT_blur, 4, 1); + feh_set_bb(EVENT_rotate, 4, 2); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -136,34 +137,17 @@ void init_buttonbindings(void) if ((read == EOF) || (read == 0) || (line[0] == '#')) continue; - /* - * Note: This isn't really good code. But it works, and since it only - * runs once for each button config line the runtime penalty compared to - * e.g. a hash table is negligible in this case. - */ - if (!strcmp(action, "reload")) - cur_bb = &keys.reload; - else if (!strcmp(action, "pan")) - cur_bb = &keys.pan; - else if (!strcmp(action, "zoom")) - cur_bb = &keys.zoom; - else if (!strcmp(action, "menu") || !strcmp(action, "toggle_menu")) - cur_bb = &keys.toggle_menu; - else if (!strcmp(action, "prev") || !strcmp(action, "prev_img")) - cur_bb = &keys.prev_img; - else if (!strcmp(action, "next") || !strcmp(action, "next_img")) - cur_bb = &keys.next_img; - else if (!strcmp(action, "blur")) - cur_bb = &keys.blur; - else if (!strcmp(action, "rotate")) - cur_bb = &keys.rotate; - else if (!strcmp(action, "zoom_in")) - cur_bb = &keys.zoom_in; - else if (!strcmp(action, "zoom_out")) - cur_bb = &keys.zoom_out; - else - cur_bb = feh_str_to_kb(action); - + cur_bb = feh_str_to_kb(action); + if (cur_bb == NULL) { + if (!strcmp(action, "reload")) + cur_bb = &keys[EVENT_reload_image]; + else if (!strcmp(action, "menu")) + cur_bb = &keys[EVENT_toggle_menu]; + else if (!strcmp(action, "prev")) + cur_bb = &keys[EVENT_prev_img]; + else if (!strcmp(action, "next")) + cur_bb = &keys[EVENT_next_img]; + } if (cur_bb) feh_set_parse_bb_partial(cur_bb, button); else @@ -172,9 +156,9 @@ void init_buttonbindings(void) fclose(conf); } -static short feh_is_bb(fehkey *bb, unsigned int button, unsigned int mod) +static short feh_is_bb(unsigned int key_index, unsigned int button, unsigned int mod) { - if ((bb->state == mod) && (bb->button == button)) + if ((keys[key_index].state == mod) && (keys[key_index].button == button)) return 1; return 0; } @@ -217,23 +201,23 @@ static void feh_event_handle_ButtonPress(XEvent * ev) state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); button = ev->xbutton.button; - if (!opt.no_menus && feh_is_bb(&keys.toggle_menu, button, state)) { + if (!opt.no_menus && feh_is_bb(EVENT_toggle_menu, button, state)) { D(("Menu Button Press event\n")); winwidget_show_menu(winwid); - } else if (feh_is_bb(&keys.rotate, button, state) + } else if (feh_is_bb(EVENT_rotate, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_ROTATE; winwid->mode = MODE_ROTATE; D(("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&keys.blur, button, state) + } else if (feh_is_bb(EVENT_blur, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_BLUR; winwid->mode = MODE_BLUR; D(("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&keys.pan, button, state)) { + } else if (feh_is_bb(EVENT_pan, button, state)) { D(("Next button, but could be pan mode\n")); opt.mode = MODE_NEXT; winwid->mode = MODE_NEXT; @@ -242,7 +226,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->click_offset_y = ev->xbutton.y - winwid->im_y; winwid->click_start_time = time(NULL); - } else if (feh_is_bb(&keys.zoom, button, state)) { + } else if (feh_is_bb(EVENT_zoom, button, state)) { D(("Zoom Button Press event\n")); opt.mode = MODE_ZOOM; winwid->mode = MODE_ZOOM; @@ -257,7 +241,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->im_click_offset_y = (winwid->click_offset_y - winwid->im_y) / winwid->old_zoom; - } else if (feh_is_bb(&keys.zoom_in, button, state)) { + } 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)); winwid->click_offset_x = ev->xbutton.x; @@ -285,7 +269,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.zoom_out, button, state)) { + } 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)); winwid->click_offset_x = ev->xbutton.x; @@ -313,16 +297,16 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.reload, button, state)) { + } else if (feh_is_bb(EVENT_reload_image, button, state)) { D(("Reload Button Press event\n")); feh_reload_image(winwid, 0, 1); - } else if (feh_is_bb(&keys.prev_img, button, state)) { + } else if (feh_is_bb(EVENT_prev_img, button, state)) { D(("Prev Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_PREV, 1); - } else if (feh_is_bb(&keys.next_img, button, state)) { + } else if (feh_is_bb(EVENT_next_img, button, state)) { D(("Next Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_NEXT, 1); @@ -363,7 +347,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) return; } - if (feh_is_bb(&keys.pan, button, state)) { + if (feh_is_bb(EVENT_pan, button, state)) { if (opt.mode == MODE_PAN) { D(("Disabling pan mode\n")); opt.mode = MODE_NORMAL; @@ -401,13 +385,13 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwid->mode = MODE_NORMAL; } - } else if (feh_is_bb(&keys.rotate, button, state) - || feh_is_bb(&keys.zoom, button, state)) { + } else if (feh_is_bb(EVENT_rotate, button, state) + || feh_is_bb(EVENT_zoom, button, state)) { D(("Disabling mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; - if ((feh_is_bb(&keys.zoom, button, state)) + 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; @@ -417,7 +401,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&keys.blur, button, state)) { + } else if (feh_is_bb(EVENT_blur, button, state)) { D(("Disabling Blur mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; diff --git a/src/keyevents.c b/src/keyevents.c index d478a5a..f082a78 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" #include -fehkb keys; +struct __fehkey keys[EVENT_LIST_END]; struct termios old_term_settings; unsigned char control_via_stdin = 0; @@ -60,14 +60,20 @@ void restore_stdin() { eprintf("tcsetattr failed"); } -static void feh_set_kb(fehkey *key, unsigned int s0, unsigned int y0, unsigned - int s1, unsigned int y1, unsigned int s2, unsigned int y2) { +static void feh_set_kb(char *name, unsigned int s0, unsigned int y0, + unsigned int s1, unsigned int y1, unsigned int s2, unsigned int y2) { + static int key_index = 0; + fehkey *key = &keys[key_index]; key->keystates[0] = s0; key->keystates[1] = s1; key->keystates[2] = s2; key->keysyms[0] = y0; key->keysyms[1] = y1; key->keysyms[2] = y2; + key->state = 0; + key->button = 0; + key->name = name; + key_index++; } static inline int ignore_space(int keysym) { @@ -128,75 +134,82 @@ void init_keyevents(void) { FILE *conf = NULL; int read = 0; - memset(&keys, 0, sizeof(keys)); - - feh_set_kb(&keys.menu_close, 0, XK_Escape , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_parent,0, XK_Left , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_down , 0, XK_Down , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_up , 0, XK_Up , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_child, 0, XK_Right , 0, 0 , 0, 0); - feh_set_kb(&keys.menu_select,0, XK_Return , 0, XK_space , 0, 0); - feh_set_kb(&keys.scroll_left,0, XK_KP_Left , 4, XK_Left , 0, 0); - feh_set_kb(&keys.scroll_right,0,XK_KP_Right , 4, XK_Right , 0, 0); - feh_set_kb(&keys.scroll_down,0, XK_KP_Down , 4, XK_Down , 0, 0); - feh_set_kb(&keys.scroll_up , 0, XK_KP_Up , 4, XK_Up , 0, 0); - feh_set_kb(&keys.scroll_left_page , 8, XK_Left , 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_right_page, 8, XK_Right, 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_down_page , 8, XK_Down , 0, 0 , 0, 0); - feh_set_kb(&keys.scroll_up_page , 8, XK_Up , 0, 0 , 0, 0); - feh_set_kb(&keys.prev_img , 0, XK_Left , 0, XK_p , 0, XK_BackSpace); - feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space); - feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0); - feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); - feh_set_kb(&keys.prev_dir , 0, XK_bracketleft, 0, 0 , 0, 0); - feh_set_kb(&keys.next_dir , 0, XK_bracketright, 0, 0 , 0, 0); - feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0); - feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0); - feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0); - feh_set_kb(&keys.remove , 0, XK_Delete , 0, 0 , 0, 0); - feh_set_kb(&keys.delete , 4, XK_Delete , 0, 0 , 0, 0); - feh_set_kb(&keys.jump_first, 0, XK_Home , 0, XK_KP_Home , 0, 0); - feh_set_kb(&keys.jump_last , 0, XK_End , 0, XK_KP_End , 0, 0); - feh_set_kb(&keys.action_0 , 0, XK_Return , 0, XK_0 , 0, XK_KP_0); - feh_set_kb(&keys.action_1 , 0, XK_1 , 0, XK_KP_1 , 0, 0); - feh_set_kb(&keys.action_2 , 0, XK_2 , 0, XK_KP_2 , 0, 0); - feh_set_kb(&keys.action_3 , 0, XK_3 , 0, XK_KP_3 , 0, 0); - feh_set_kb(&keys.action_4 , 0, XK_4 , 0, XK_KP_4 , 0, 0); - feh_set_kb(&keys.action_5 , 0, XK_5 , 0, XK_KP_5 , 0, 0); - feh_set_kb(&keys.action_6 , 0, XK_6 , 0, XK_KP_6 , 0, 0); - feh_set_kb(&keys.action_7 , 0, XK_7 , 0, XK_KP_7 , 0, 0); - feh_set_kb(&keys.action_8 , 0, XK_8 , 0, XK_KP_8 , 0, 0); - feh_set_kb(&keys.action_9 , 0, XK_9 , 0, XK_KP_9 , 0, 0); - feh_set_kb(&keys.zoom_in , 0, XK_Up , 0, XK_KP_Add , 0, 0); - feh_set_kb(&keys.zoom_out , 0, XK_Down , 0, XK_KP_Subtract,0, 0); - feh_set_kb(&keys.zoom_default, 0, XK_KP_Multiply, 0, XK_asterisk,0, 0); - feh_set_kb(&keys.zoom_fit , 0, XK_KP_Divide , 0, XK_slash , 0, 0); - feh_set_kb(&keys.zoom_fill , 0, XK_exclam , 0, 0 , 0, 0); - feh_set_kb(&keys.size_to_image, 0, XK_w , 0, 0 , 0, 0); - feh_set_kb(&keys.render , 0, XK_KP_Begin , 0, XK_R , 0, 0); - feh_set_kb(&keys.toggle_actions, 0, XK_a, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_aliasing, 0, XK_A, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_filenames, 0, XK_d, 0, 0, 0, 0); + /* + * The feh_set_kb statements must have the same order as the key_action + * enum. + */ + + feh_set_kb("menu_close" , 0, XK_Escape , 0, 0 , 0, 0); + feh_set_kb("menu_parent", 0, XK_Left , 0, 0 , 0, 0); + feh_set_kb("menu_down", 0, XK_Down , 0, 0 , 0, 0); + feh_set_kb("menu_up", 0, XK_Up , 0, 0 , 0, 0); + feh_set_kb("menu_child", 0, XK_Right , 0, 0 , 0, 0); + feh_set_kb("menu_select", 0, XK_Return , 0, XK_space , 0, 0); + feh_set_kb("scroll_left",0, XK_KP_Left , 4, XK_Left , 0, 0); + feh_set_kb("scroll_right", 0,XK_KP_Right , 4, XK_Right , 0, 0); + feh_set_kb("scroll_down",0, XK_KP_Down , 4, XK_Down , 0, 0); + feh_set_kb("scroll_up", 0, XK_KP_Up , 4, XK_Up , 0, 0); + feh_set_kb("scroll_left_page" , 8, XK_Left , 0, 0 , 0, 0); + feh_set_kb("scroll_right_page", 8, XK_Right, 0, 0 , 0, 0); + feh_set_kb("scroll_down_page" , 8, XK_Down , 0, 0 , 0, 0); + feh_set_kb("scroll_up_page" , 8, XK_Up , 0, 0 , 0, 0); + feh_set_kb("prev_img" , 0, XK_Left , 0, XK_p , 0, XK_BackSpace); + feh_set_kb("next_img" , 0, XK_Right , 0, XK_n , 0, XK_space); + feh_set_kb("jump_back" , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0); + feh_set_kb("jump_fwd" , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); + feh_set_kb("prev_dir" , 0, XK_bracketleft, 0, 0 , 0, 0); + feh_set_kb("next_dir" , 0, XK_bracketright, 0, 0 , 0, 0); + feh_set_kb("jump_random" ,0, XK_z , 0, 0 , 0, 0); + feh_set_kb("quit" , 0, XK_Escape , 0, XK_q , 0, 0); + feh_set_kb("close" , 0, XK_x , 0, 0 , 0, 0); + feh_set_kb("remove" , 0, XK_Delete , 0, 0 , 0, 0); + feh_set_kb("delete" , 4, XK_Delete , 0, 0 , 0, 0); + feh_set_kb("jump_first" , 0, XK_Home , 0, XK_KP_Home , 0, 0); + feh_set_kb("jump_last" , 0, XK_End , 0, XK_KP_End , 0, 0); + feh_set_kb("action_0" , 0, XK_Return , 0, XK_0 , 0, XK_KP_0); + feh_set_kb("action_1" , 0, XK_1 , 0, XK_KP_1 , 0, 0); + feh_set_kb("action_2" , 0, XK_2 , 0, XK_KP_2 , 0, 0); + feh_set_kb("action_3" , 0, XK_3 , 0, XK_KP_3 , 0, 0); + feh_set_kb("action_4" , 0, XK_4 , 0, XK_KP_4 , 0, 0); + feh_set_kb("action_5" , 0, XK_5 , 0, XK_KP_5 , 0, 0); + feh_set_kb("action_6" , 0, XK_6 , 0, XK_KP_6 , 0, 0); + feh_set_kb("action_7" , 0, XK_7 , 0, XK_KP_7 , 0, 0); + feh_set_kb("action_8" , 0, XK_8 , 0, XK_KP_8 , 0, 0); + feh_set_kb("action_9" , 0, XK_9 , 0, XK_KP_9 , 0, 0); + feh_set_kb("zoom_in" , 0, XK_Up , 0, XK_KP_Add , 0, 0); + feh_set_kb("zoom_out" , 0, XK_Down , 0, XK_KP_Subtract,0, 0); + feh_set_kb("zoom_default" , 0, XK_KP_Multiply, 0, XK_asterisk,0, 0); + feh_set_kb("zoom_fit" , 0, XK_KP_Divide , 0, XK_slash , 0, 0); + feh_set_kb("zoom_fill" , 0, XK_exclam , 0, 0 , 0, 0); + feh_set_kb("size_to_image" , 0, XK_w , 0, 0 , 0, 0); + feh_set_kb("render" , 0, XK_KP_Begin , 0, XK_R , 0, 0); + feh_set_kb("toggle_actions" , 0, XK_a, 0, 0, 0, 0); + feh_set_kb("toggle_aliasing" , 0, XK_A, 0, 0, 0, 0); #ifdef HAVE_LIBEXIF - feh_set_kb(&keys.toggle_exif, 0, XK_e, 0, 0, 0, 0); + feh_set_kb("toggle_exif" , 0, XK_e, 0, 0, 0, 0); #endif - feh_set_kb(&keys.toggle_info, 0, XK_i, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_pointer, 0, XK_o, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_caption, 0, XK_c, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_pause, 0, XK_h, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_menu, 0, XK_m, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_fullscreen, 0, XK_v, 0, 0, 0, 0); - feh_set_kb(&keys.reload_image, 0, XK_r, 0, 0, 0, 0); - feh_set_kb(&keys.save_image, 0, XK_s, 0, 0, 0, 0); - feh_set_kb(&keys.save_filelist, 0, XK_f, 0, 0, 0, 0); - feh_set_kb(&keys.orient_1, 0, XK_greater, 0, 0, 0, 0); - feh_set_kb(&keys.orient_3, 0, XK_less, 0, 0, 0, 0); - feh_set_kb(&keys.flip, 0, XK_underscore, 0, 0, 0, 0); - feh_set_kb(&keys.mirror, 0, XK_bar, 0, 0, 0, 0); - feh_set_kb(&keys.reload_minus, 0, XK_minus, 0, 0, 0, 0); - feh_set_kb(&keys.reload_plus, 0, XK_plus, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_keep_vp, 0, XK_k, 0, 0, 0, 0); - feh_set_kb(&keys.toggle_fixed_geometry, 0, XK_g, 0, 0, 0, 0); + feh_set_kb("toggle_filenames" , 0, XK_d, 0, 0, 0, 0); + feh_set_kb("toggle_info" , 0, XK_i, 0, 0, 0, 0); + feh_set_kb("toggle_pointer" , 0, XK_o, 0, 0, 0, 0); + feh_set_kb("toggle_caption" , 0, XK_c, 0, 0, 0, 0); + feh_set_kb("toggle_pause" , 0, XK_h, 0, 0, 0, 0); + feh_set_kb("toggle_menu" , 0, XK_m, 0, 0, 0, 0); + feh_set_kb("toggle_fullscreen" , 0, XK_v, 0, 0, 0, 0); + feh_set_kb("reload_image" , 0, XK_r, 0, 0, 0, 0); + feh_set_kb("save_image" , 0, XK_s, 0, 0, 0, 0); + feh_set_kb("save_filelist" , 0, XK_f, 0, 0, 0, 0); + feh_set_kb("orient_1" , 0, XK_greater, 0, 0, 0, 0); + feh_set_kb("orient_3" , 0, XK_less, 0, 0, 0, 0); + feh_set_kb("flip" , 0, XK_underscore, 0, 0, 0, 0); + feh_set_kb("mirror" , 0, XK_bar, 0, 0, 0, 0); + feh_set_kb("reload_minus" , 0, XK_minus, 0, 0, 0, 0); + feh_set_kb("reload_plus" , 0, XK_plus, 0, 0, 0, 0); + feh_set_kb("toggle_keep_vp" , 0, XK_k, 0, 0, 0, 0); + feh_set_kb("toggle_fixed_geometry" , 0, XK_g, 0, 0, 0, 0); + feh_set_kb("pan" , 0, 0, 0, 0, 0, 0); + feh_set_kb("zoom" , 0, 0, 0, 0, 0, 0); + feh_set_kb("blur" , 0, 0, 0, 0, 0, 0); + feh_set_kb("rotate" , 0, 0, 0, 0, 0, 0); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -241,21 +254,23 @@ void init_keyevents(void) { fclose(conf); } -static short feh_is_kp(fehkey *key, unsigned int state, unsigned int sym, unsigned int button) { +static short feh_is_kp(unsigned int key_index, unsigned int state, + unsigned int sym, unsigned int button) { int i; if (sym != NoSymbol) { for (i = 0; i < 3; i++) { if ( - (key->keysyms[i] == sym) && - (key->keystates[i] == state)) + (keys[key_index].keysyms[i] == sym) && + (keys[key_index].keystates[i] == state)) return 1; - else if (key->keysyms[i] == 0) + else if (keys[key_index].keysyms[i] == 0) return 0; } return 0; } - if ((key->state == state) && (key->button == button)) { + if ((keys[key_index].state == state) + && (keys[key_index].button == button)) { return 1; } return 0; @@ -352,17 +367,17 @@ void feh_event_handle_keypress(XEvent * ev) /* menus are showing, so this is a menu control keypress */ if (ev->xbutton.window == menu_cover) { selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); - if (feh_is_kp(&keys.menu_close, state, keysym, 0)) + if (feh_is_kp(EVENT_menu_close, state, keysym, 0)) feh_menu_hide(menu_root, True); - else if (feh_is_kp(&keys.menu_parent, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_parent, state, keysym, 0)) feh_menu_select_parent(selected_menu); - else if (feh_is_kp(&keys.menu_down, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_down, state, keysym, 0)) feh_menu_select_next(selected_menu, selected_item); - else if (feh_is_kp(&keys.menu_up, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_up, state, keysym, 0)) feh_menu_select_prev(selected_menu, selected_item); - else if (feh_is_kp(&keys.menu_child, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_child, state, keysym, 0)) feh_menu_select_submenu(selected_menu); - else if (feh_is_kp(&keys.menu_select, state, keysym, 0)) + else if (feh_is_kp(EVENT_menu_select, state, keysym, 0)) feh_menu_item_activate(selected_menu, selected_item); return; } @@ -375,139 +390,11 @@ void feh_event_handle_keypress(XEvent * ev) fehkey *feh_str_to_kb(char *action) { - if (!strcmp(action, "menu_close")) - return &keys.menu_close; - else if (!strcmp(action, "menu_parent")) - return &keys.menu_parent; - else if (!strcmp(action, "menu_down")) - return &keys.menu_down; - else if (!strcmp(action, "menu_up")) - return &keys.menu_up; - else if (!strcmp(action, "menu_child")) - return &keys.menu_child; - else if (!strcmp(action, "menu_select")) - return &keys.menu_select; - else if (!strcmp(action, "scroll_right")) - return &keys.scroll_right; - else if (!strcmp(action, "scroll_left")) - return &keys.scroll_left; - else if (!strcmp(action, "scroll_up")) - return &keys.scroll_up; - else if (!strcmp(action, "scroll_down")) - return &keys.scroll_down; - else if (!strcmp(action, "scroll_right_page")) - return &keys.scroll_right_page; - else if (!strcmp(action, "scroll_left_page")) - return &keys.scroll_left_page; - else if (!strcmp(action, "scroll_up_page")) - return &keys.scroll_up_page; - else if (!strcmp(action, "scroll_down_page")) - return &keys.scroll_down_page; - else if (!strcmp(action, "prev_img")) - return &keys.prev_img; - else if (!strcmp(action, "next_img")) - return &keys.next_img; - else if (!strcmp(action, "jump_back")) - return &keys.jump_back; - else if (!strcmp(action, "jump_fwd")) - return &keys.jump_fwd; - else if (!strcmp(action, "prev_dir")) - return &keys.prev_dir; - else if (!strcmp(action, "next_dir")) - return &keys.next_dir; - else if (!strcmp(action, "jump_random")) - return &keys.jump_random; - else if (!strcmp(action, "quit")) - return &keys.quit; - else if (!strcmp(action, "close")) - return &keys.close; - else if (!strcmp(action, "remove")) - return &keys.remove; - else if (!strcmp(action, "delete")) - return &keys.delete; - else if (!strcmp(action, "jump_first")) - return &keys.jump_first; - else if (!strcmp(action, "jump_last")) - return &keys.jump_last; - else if (!strcmp(action, "action_0")) - return &keys.action_0; - else if (!strcmp(action, "action_1")) - return &keys.action_1; - else if (!strcmp(action, "action_2")) - return &keys.action_2; - else if (!strcmp(action, "action_3")) - return &keys.action_3; - else if (!strcmp(action, "action_4")) - return &keys.action_4; - else if (!strcmp(action, "action_5")) - return &keys.action_5; - else if (!strcmp(action, "action_6")) - return &keys.action_6; - else if (!strcmp(action, "action_7")) - return &keys.action_7; - else if (!strcmp(action, "action_8")) - return &keys.action_8; - else if (!strcmp(action, "action_9")) - return &keys.action_9; - else if (!strcmp(action, "zoom_in")) - return &keys.zoom_in; - else if (!strcmp(action, "zoom_out")) - return &keys.zoom_out; - else if (!strcmp(action, "zoom_default")) - return &keys.zoom_default; - else if (!strcmp(action, "zoom_fit")) - return &keys.zoom_fit; - else if (!strcmp(action, "zoom_fill")) - return &keys.zoom_fill; - else if (!strcmp(action, "size_to_image")) - return &keys.size_to_image; - else if (!strcmp(action, "render")) - return &keys.render; - else if (!strcmp(action, "toggle_actions")) - return &keys.toggle_actions; - else if (!strcmp(action, "toggle_aliasing")) - return &keys.toggle_aliasing; - else if (!strcmp(action, "toggle_filenames")) - return &keys.toggle_filenames; -#ifdef HAVE_LIBEXIF - else if (!strcmp(action, "toggle_exif")) - return &keys.toggle_exif; -#endif - else if (!strcmp(action, "toggle_info")) - return &keys.toggle_info; - else if (!strcmp(action, "toggle_pointer")) - return &keys.toggle_pointer; - else if (!strcmp(action, "toggle_caption")) - return &keys.toggle_caption; - else if (!strcmp(action, "toggle_pause")) - return &keys.toggle_pause; - else if (!strcmp(action, "toggle_menu")) - return &keys.toggle_menu; - else if (!strcmp(action, "toggle_fullscreen")) - return &keys.toggle_fullscreen; - else if (!strcmp(action, "reload_image")) - return &keys.reload_image; - else if (!strcmp(action, "save_image")) - return &keys.save_image; - else if (!strcmp(action, "save_filelist")) - return &keys.save_filelist; - else if (!strcmp(action, "orient_1")) - return &keys.orient_1; - else if (!strcmp(action, "orient_3")) - return &keys.orient_3; - else if (!strcmp(action, "flip")) - return &keys.flip; - else if (!strcmp(action, "mirror")) - return &keys.mirror; - else if (!strcmp(action, "reload_minus")) - return &keys.reload_minus; - else if (!strcmp(action, "reload_plus")) - return &keys.reload_plus; - else if (!strcmp(action, "toggle_keep_vp")) - return &keys.toggle_keep_vp; - else if (!strcmp(action, "toggle_fixed_geometry")) - return &keys.toggle_fixed_geometry; - + for (unsigned int i = 0; i < EVENT_LIST_END; i++) { + if (!strcmp(action, keys[i].name)) { + return &keys[i]; + } + } return NULL; } @@ -566,130 +453,130 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy return; } - if (feh_is_kp(&keys.next_img, state, keysym, button)) { + if (feh_is_kp(EVENT_next_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 1); } - else if (feh_is_kp(&keys.prev_img, state, keysym, button)) { + else if (feh_is_kp(EVENT_prev_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 1); } - else if (feh_is_kp(&keys.scroll_right, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_right, state, keysym, button)) { winwid->im_x -= opt.scroll_step;; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_left, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_left, state, keysym, button)) { winwid->im_x += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_down, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_down, state, keysym, button)) { winwid->im_y -= opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_up, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_up, state, keysym, button)) { winwid->im_y += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } - else if (feh_is_kp(&keys.scroll_right_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_right_page, state, keysym, button)) { winwid->im_x -= winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_left_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_left_page, state, keysym, button)) { winwid->im_x += winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_down_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_down_page, state, keysym, button)) { winwid->im_y -= winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.scroll_up_page, state, keysym, button)) { + else if (feh_is_kp(EVENT_scroll_up_page, state, keysym, button)) { winwid->im_y += winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.jump_back, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_back, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_BACK, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 10); } - else if (feh_is_kp(&keys.jump_fwd, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_fwd, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_FWD, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 10); } - else if (feh_is_kp(&keys.next_dir, state, keysym, button)) { + else if (feh_is_kp(EVENT_next_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1); } - else if (feh_is_kp(&keys.prev_dir, state, keysym, button)) { + else if (feh_is_kp(EVENT_prev_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1); } - else if (feh_is_kp(&keys.quit, state, keysym, button)) { + else if (feh_is_kp(EVENT_quit, state, keysym, button)) { winwidget_destroy_all(); } - else if (feh_is_kp(&keys.delete, state, keysym, button)) { + else if (feh_is_kp(EVENT_delete, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1); feh_filelist_image_remove(winwid, 1); } - else if (feh_is_kp(&keys.remove, state, keysym, button)) { + else if (feh_is_kp(EVENT_remove, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); feh_filelist_image_remove(winwid, 0); } - else if (feh_is_kp(&keys.jump_first, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_first, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_FIRST, 1); } - else if (feh_is_kp(&keys.jump_last, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_last, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_LAST, 1); } - else if (feh_is_kp(&keys.action_0, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_0, state, keysym, button)) { feh_event_invoke_action(winwid, 0); } - else if (feh_is_kp(&keys.action_1, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_1, state, keysym, button)) { feh_event_invoke_action(winwid, 1); } - else if (feh_is_kp(&keys.action_2, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_2, state, keysym, button)) { feh_event_invoke_action(winwid, 2); } - else if (feh_is_kp(&keys.action_3, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_3, state, keysym, button)) { feh_event_invoke_action(winwid, 3); } - else if (feh_is_kp(&keys.action_4, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_4, state, keysym, button)) { feh_event_invoke_action(winwid, 4); } - else if (feh_is_kp(&keys.action_5, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_5, state, keysym, button)) { feh_event_invoke_action(winwid, 5); } - else if (feh_is_kp(&keys.action_6, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_6, state, keysym, button)) { feh_event_invoke_action(winwid, 6); } - else if (feh_is_kp(&keys.action_7, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_7, state, keysym, button)) { feh_event_invoke_action(winwid, 7); } - else if (feh_is_kp(&keys.action_8, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_8, state, keysym, button)) { feh_event_invoke_action(winwid, 8); } - else if (feh_is_kp(&keys.action_9, state, keysym, button)) { + else if (feh_is_kp(EVENT_action_9, state, keysym, button)) { feh_event_invoke_action(winwid, 9); } - else if (feh_is_kp(&keys.zoom_in, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 1.25; @@ -703,7 +590,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_out, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 0.80; @@ -717,17 +604,17 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_default, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_default, state, keysym, button)) { winwid->zoom = 1.0; winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_fit, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_fit, state, keysym, button)) { feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.zoom_fill, state, keysym, button)) { + else if (feh_is_kp(EVENT_zoom_fill, state, keysym, button)) { int save_zoom = opt.zoom_mode; opt.zoom_mode = ZOOM_MODE_FILL; feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); @@ -735,46 +622,46 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwidget_render_image(winwid, 0, 0); opt.zoom_mode = save_zoom; } - else if (feh_is_kp(&keys.render, state, keysym, button)) { + else if (feh_is_kp(EVENT_render, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_show_selected(); else winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_actions, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_actions, state, keysym, button)) { opt.draw_actions = !opt.draw_actions; winwidget_rerender_all(0); } - else if (feh_is_kp(&keys.toggle_aliasing, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_aliasing, state, keysym, button)) { opt.force_aliasing = !opt.force_aliasing; winwid->force_aliasing = !winwid->force_aliasing; winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_filenames, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) { opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0); } #ifdef HAVE_LIBEXIF - else if (feh_is_kp(&keys.toggle_exif, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_exif, state, keysym, button)) { opt.draw_exif = !opt.draw_exif; winwidget_rerender_all(0); } #endif - else if (feh_is_kp(&keys.toggle_info, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_info, state, keysym, button)) { opt.draw_info = !opt.draw_info; winwidget_rerender_all(0); } - else if (feh_is_kp(&keys.toggle_pointer, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_pointer, state, keysym, button)) { winwidget_set_pointer(winwid, opt.hide_pointer); opt.hide_pointer = !opt.hide_pointer; } - else if (feh_is_kp(&keys.jump_random, state, keysym, button)) { + else if (feh_is_kp(EVENT_jump_random, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, rand() % (filelist_len - 1)); else slideshow_change_image(winwid, SLIDE_RAND, 1); } - else if (feh_is_kp(&keys.toggle_caption, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_caption, state, keysym, button)) { if (opt.caption_path) { /* * editing captions in slideshow mode does not make any sense @@ -786,44 +673,44 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy } winwidget_render_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.reload_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_reload_image, state, keysym, button)) { feh_reload_image(winwid, 0, 0); } - else if (feh_is_kp(&keys.toggle_pause, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_pause, state, keysym, button)) { slideshow_pause_toggle(winwid); } - else if (feh_is_kp(&keys.save_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_save_image, state, keysym, button)) { slideshow_save_image(winwid); } - else if (feh_is_kp(&keys.save_filelist, state, keysym, button)) { + else if (feh_is_kp(EVENT_save_filelist, state, keysym, button)) { if ((winwid->type == WIN_TYPE_THUMBNAIL) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) weprintf("Filelist saving is not supported in thumbnail mode"); else feh_save_filelist(); } - else if (feh_is_kp(&keys.size_to_image, state, keysym, button)) { + else if (feh_is_kp(EVENT_size_to_image, state, keysym, button)) { winwidget_size_to_image(winwid); } - else if (!opt.no_menus && feh_is_kp(&keys.toggle_menu, state, keysym, button)) { + else if (!opt.no_menus && feh_is_kp(EVENT_toggle_menu, state, keysym, button)) { winwidget_show_menu(winwid); } - else if (feh_is_kp(&keys.close, state, keysym, button)) { + else if (feh_is_kp(EVENT_close, state, keysym, button)) { winwidget_destroy(winwid); } - else if (feh_is_kp(&keys.orient_1, state, keysym, button)) { + else if (feh_is_kp(EVENT_orient_1, state, keysym, button)) { feh_edit_inplace(winwid, 1); } - else if (feh_is_kp(&keys.orient_3, state, keysym, button)) { + else if (feh_is_kp(EVENT_orient_3, state, keysym, button)) { feh_edit_inplace(winwid, 3); } - else if (feh_is_kp(&keys.flip, state, keysym, button)) { + else if (feh_is_kp(EVENT_flip, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_FLIP); } - else if (feh_is_kp(&keys.mirror, state, keysym, button)) { + else if (feh_is_kp(EVENT_mirror, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_MIRROR); } - else if (feh_is_kp(&keys.toggle_fullscreen, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_fullscreen, state, keysym, button)) { #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { int i, rect[4]; @@ -859,22 +746,22 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy } #endif /* HAVE_LIBXINERAMA */ } - else if (feh_is_kp(&keys.reload_plus, state, keysym, button)){ + else if (feh_is_kp(EVENT_reload_plus, state, keysym, button)){ if (opt.reload < SLIDESHOW_RELOAD_MAX) opt.reload++; else if (opt.verbose) weprintf("Cannot set RELOAD higher than %f seconds.", opt.reload); } - else if (feh_is_kp(&keys.reload_minus, state, keysym, button)) { + else if (feh_is_kp(EVENT_reload_minus, state, keysym, button)) { if (opt.reload > 1) opt.reload--; else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); } - else if (feh_is_kp(&keys.toggle_keep_vp, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_keep_vp, state, keysym, button)) { opt.keep_zoom_vp = !opt.keep_zoom_vp; } - else if (feh_is_kp(&keys.toggle_fixed_geometry, state, keysym, button)) { + else if (feh_is_kp(EVENT_toggle_fixed_geometry, state, keysym, button)) { if (opt.geom_flags & ((WidthValue | HeightValue))) { opt.geom_flags &= ~(WidthValue | HeightValue); } else { diff --git a/src/options.h b/src/options.h index ef7f471..4e2703e 100644 --- a/src/options.h +++ b/src/options.h @@ -134,81 +134,82 @@ struct __fehkey { unsigned int keystates[3]; unsigned int state; unsigned int button; + char *name; }; -struct __fehkb { - struct __fehkey menu_close; - struct __fehkey menu_parent; - struct __fehkey menu_down; - struct __fehkey menu_up; - struct __fehkey menu_child; - struct __fehkey menu_select; - struct __fehkey scroll_right; - struct __fehkey prev_img; - struct __fehkey scroll_left; - struct __fehkey next_img; - struct __fehkey scroll_up; - struct __fehkey scroll_down; - struct __fehkey scroll_right_page; - struct __fehkey scroll_left_page; - struct __fehkey scroll_up_page; - struct __fehkey scroll_down_page; - struct __fehkey jump_back; - struct __fehkey quit; - struct __fehkey jump_fwd; - struct __fehkey prev_dir; - struct __fehkey next_dir; - struct __fehkey remove; - struct __fehkey delete; - struct __fehkey jump_first; - struct __fehkey jump_last; - struct __fehkey action_0; - struct __fehkey action_1; - struct __fehkey action_2; - struct __fehkey action_3; - struct __fehkey action_4; - struct __fehkey action_5; - struct __fehkey action_6; - struct __fehkey action_7; - struct __fehkey action_8; - struct __fehkey action_9; - struct __fehkey zoom_in; - struct __fehkey zoom_out; - struct __fehkey zoom_default; - struct __fehkey zoom_fit; - struct __fehkey zoom_fill; - struct __fehkey render; - struct __fehkey toggle_actions; - struct __fehkey toggle_filenames; +enum key_action { + EVENT_menu_close = 0, + EVENT_menu_parent, + EVENT_menu_down, + EVENT_menu_up, + EVENT_menu_child, + EVENT_menu_select, + EVENT_scroll_left, + EVENT_scroll_right, + EVENT_scroll_down, + EVENT_scroll_up, + EVENT_scroll_left_page, + EVENT_scroll_right_page, + EVENT_scroll_down_page, + EVENT_scroll_up_page, + EVENT_prev_img, + EVENT_next_img, + EVENT_jump_back, + EVENT_jump_fwd, + EVENT_prev_dir, + EVENT_next_dir, + EVENT_jump_random, + EVENT_quit, + EVENT_close, + EVENT_remove, + EVENT_delete, + EVENT_jump_first, + EVENT_jump_last, + EVENT_action_0, + EVENT_action_1, + EVENT_action_2, + EVENT_action_3, + EVENT_action_4, + EVENT_action_5, + EVENT_action_6, + EVENT_action_7, + EVENT_action_8, + EVENT_action_9, + EVENT_zoom_in, + EVENT_zoom_out, + EVENT_zoom_default, + EVENT_zoom_fit, + EVENT_zoom_fill, + EVENT_size_to_image, + EVENT_render, + EVENT_toggle_actions, + EVENT_toggle_aliasing, #ifdef HAVE_LIBEXIF - struct __fehkey toggle_exif; + EVENT_toggle_exif, #endif - struct __fehkey toggle_info; - struct __fehkey toggle_pointer; - struct __fehkey toggle_aliasing; - struct __fehkey jump_random; - struct __fehkey toggle_caption; - struct __fehkey toggle_pause; - struct __fehkey reload_image; - struct __fehkey save_image; - struct __fehkey save_filelist; - struct __fehkey size_to_image; - struct __fehkey toggle_menu; - struct __fehkey close; - struct __fehkey orient_1; - struct __fehkey orient_3; - struct __fehkey flip; - struct __fehkey mirror; - struct __fehkey toggle_fullscreen; - struct __fehkey reload_minus; - struct __fehkey reload_plus; - struct __fehkey toggle_keep_vp; - struct __fehkey pan; - struct __fehkey zoom; - struct __fehkey reload; - struct __fehkey blur; - struct __fehkey rotate; - struct __fehkey toggle_fixed_geometry; + EVENT_toggle_filenames, + EVENT_toggle_info, + EVENT_toggle_pointer, + EVENT_toggle_caption, + EVENT_toggle_pause, + EVENT_toggle_menu, + EVENT_toggle_fullscreen, + EVENT_reload_image, + EVENT_save_image, + EVENT_save_filelist, + EVENT_orient_1, + EVENT_orient_3, + EVENT_flip, + EVENT_mirror, + EVENT_reload_minus, + EVENT_reload_plus, + EVENT_toggle_keep_vp, + EVENT_toggle_fixed_geometry, + EVENT_pan, + EVENT_zoom, + EVENT_blur, + EVENT_rotate, + EVENT_LIST_END }; void init_parse_options(int argc, char **argv); -- cgit v1.2.3 From 0a006ed6767e42bbc1608400faf0fa9e008ff49c Mon Sep 17 00:00:00 2001 From: ulteq Date: Wed, 27 Dec 2017 19:03:03 +0100 Subject: Add option to change the imlib cache size This option allows you to change the default imlib2 image cache size of 4 MiB. --- src/help.raw | 1 + src/imlib.c | 2 ++ src/options.c | 10 ++++++++++ src/options.h | 3 +++ 4 files changed, 16 insertions(+) (limited to 'src/options.h') diff --git a/src/help.raw b/src/help.raw index 2bc5986..37e0e71 100644 --- a/src/help.raw +++ b/src/help.raw @@ -94,6 +94,7 @@ OPTIONS --min-dimension WxH Only show images with width >= W and height >= H --max-dimension WxH Only show images with width <= W and height <= H --scroll-step COUNT scroll COUNT pixels when movement key is pressed + --cache-size NUM imlib cache size in mebibytes (0 .. 2048) MONTAGE MODE OPTIONS -X, --ignore-aspect Set thumbnail to specified width/height without diff --git a/src/imlib.c b/src/imlib.c index 5b96e8a..48808a1 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -131,6 +131,8 @@ void init_x_and_imlib(void) imlib_context_set_operation(IMLIB_OP_COPY); wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False); + imlib_set_cache_size(opt.cache_size * 1024 * 1024); + /* Initialise random numbers */ srand(getpid() * time(NULL) % ((unsigned int) -1)); diff --git a/src/options.c b/src/options.c index 1ed5b54..c874832 100644 --- a/src/options.c +++ b/src/options.c @@ -68,6 +68,7 @@ void init_parse_options(int argc, char **argv) opt.jump_on_resort = 1; opt.screen_clip = 1; + opt.cache_size = 4; #ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; @@ -410,6 +411,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"xinerama-index", 1, 0, 239}, {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, + {"cache-size" , 1, 0, 243}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -772,6 +774,14 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; case 241: opt.recursive = 0; + break; + case 243: + opt.cache_size = atoi(optarg); + if (opt.cache_size < 0) + opt.cache_size = 0; + if (opt.cache_size > 2048) + opt.cache_size = 2048; + break; default: break; } diff --git a/src/options.h b/src/options.h index 4e2703e..c6959c8 100644 --- a/src/options.h +++ b/src/options.h @@ -117,6 +117,9 @@ struct __fehoptions { /* signed in case someone wants to invert scrolling real quick */ int scroll_step; + // imlib cache size in mebibytes + int cache_size; + unsigned int min_width, min_height, max_width, max_height; unsigned char mode; -- cgit v1.2.3 From 5965739a0aa6e1f91989a011746c2709cb4e92dc Mon Sep 17 00:00:00 2001 From: Paul O'Day Date: Tue, 26 Mar 2013 20:52:14 -0700 Subject: Allow any XColor values as --image-bg argument --- man/feh.pre | 2 +- src/feh.h | 2 -- src/help.raw | 2 +- src/options.c | 9 +-------- src/options.h | 2 +- src/wallpaper.c | 29 ++++++++++++----------------- src/winwidget.c | 26 ++++++++++++++------------ 7 files changed, 30 insertions(+), 42 deletions(-) (limited to 'src/options.h') diff --git a/man/feh.pre b/man/feh.pre index c2a4cd1..90e6b20 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -379,7 +379,7 @@ Hide the pointer .It Cm -B , --image-bg Ar style . Use style as background for transparent image parts and the like. -Accepted values: checks, white, black. +Accepted values: default, checks, or a XColor (eg. #428bdd). . The default for windowed mode is checks, while fullscreen defaults to black. . diff --git a/src/feh.h b/src/feh.h index a4a0a7b..3f0ce0c 100644 --- a/src/feh.h +++ b/src/feh.h @@ -107,8 +107,6 @@ enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST, SLIDE_JUMP_PREV_DIR }; -enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE }; - #define INPLACE_EDIT_FLIP -1 #define INPLACE_EDIT_MIRROR -2 diff --git a/src/help.raw b/src/help.raw index 37e0e71..8b244c1 100644 --- a/src/help.raw +++ b/src/help.raw @@ -84,7 +84,7 @@ OPTIONS can be used multiple times to add multiple paths. -M, --menu-font FONT Use FONT for the font in menus. -B, --image-bg STYLE Set background for transparent images and the like. - Accepted values: white, black, default + Accepted values: default, checks, or a XColor (eg. #428bdd) -N, --no-menus Don't load or show any menus. --no-xinerama Disable Xinerama support --no-screen-clip Do not limit window size to screen size diff --git a/src/options.c b/src/options.c index c874832..03f5ae3 100644 --- a/src/options.c +++ b/src/options.c @@ -449,14 +449,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.actions[0] = estrdup(optarg); break; case 'B': - if (!strcmp(optarg, "checks")) - opt.image_bg = IMAGE_BG_CHECKS; - else if (!strcmp(optarg, "white")) - opt.image_bg = IMAGE_BG_WHITE; - else if (!strcmp(optarg, "black")) - opt.image_bg = IMAGE_BG_BLACK; - else - weprintf("Unknown argument to --image-bg: %s", optarg); + opt.image_bg = estrdup(optarg); break; case 'C': D(("adding fontpath %s\n", optarg)); diff --git a/src/options.h b/src/options.h index c6959c8..fc9774e 100644 --- a/src/options.h +++ b/src/options.h @@ -71,7 +71,6 @@ struct __fehoptions { unsigned char cycle_once; unsigned char hold_actions[10]; unsigned char text_bg; - unsigned char image_bg; unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl; @@ -79,6 +78,7 @@ struct __fehoptions { char *output_file; char *output_dir; char *bg_file; + char *image_bg; char *font; char *title_font; char *title; diff --git a/src/wallpaper.c b/src/wallpaper.c index c9a3a05..5c50ad8 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -305,15 +305,19 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, D(("Falling back to XSetRootWindowPixmap\n")); + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + if (opt.image_bg) + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + else + XAllocNamedColor(disp, cmap, "black", &color, &color); + if (scaled) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); #ifdef HAVE_LIBXINERAMA if (opt.xinerama_index >= 0) { - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); XFreeGC(disp, gc); @@ -337,10 +341,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, D(("centering\n")); pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); @@ -367,10 +368,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, #ifdef HAVE_LIBXINERAMA if (opt.xinerama_index >= 0) { - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); XFreeGC(disp, gc); @@ -393,10 +391,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, } else if (filled == 2) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); - if (opt.image_bg == IMAGE_BG_WHITE) - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); - else - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gcval.foreground = color.pixel; gc = XCreateGC(disp, root, GCForeground, &gcval); XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); @@ -472,7 +467,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, free(path); } } - + /* create new display, copy pixmap to new display */ disp2 = XOpenDisplay(NULL); if (!disp2) diff --git a/src/winwidget.c b/src/winwidget.c index d636a85..e0796fa 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -391,17 +391,18 @@ void winwidget_setup_pixmaps(winwidget winwid) if (winwid->gc == None) { XGCValues gcval; - if (opt.image_bg == IMAGE_BG_WHITE) { - gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); + if (!opt.image_bg || !strcmp(opt.image_bg, "default")) { + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); - } - else if (opt.image_bg == IMAGE_BG_CHECKS) { + } else if (!strcmp(opt.image_bg, "checks")) { gcval.tile = feh_create_checks(); gcval.fill_style = FillTiled; winwid->gc = XCreateGC(disp, winwid->win, GCTile | GCFillStyle, &gcval); - } - else { - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + } else { + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + gcval.foreground = color.pixel; winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); } } @@ -700,14 +701,15 @@ Pixmap feh_create_checks(void) if (!checks) eprintf("Unable to create a teeny weeny imlib image. I detect problems"); - if (opt.image_bg == IMAGE_BG_WHITE) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 255, 255, 255, 255); - else if (opt.image_bg == IMAGE_BG_BLACK) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 0, 0, 0, 255); - else { + if (!opt.image_bg || !strcmp(opt.image_bg, "default") || !strcmp(opt.image_bg, "checks")) { gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 144, 144, 144, 255); gib_imlib_image_fill_rectangle(checks, 0, 0, 8, 8, 100, 100, 100, 255); gib_imlib_image_fill_rectangle(checks, 8, 8, 8, 8, 100, 100, 100, 255); + } else { + XColor color; + Colormap cmap = DefaultColormap(disp, DefaultScreen(disp)); + XAllocNamedColor(disp, cmap, (char*) opt.image_bg, &color, &color); + gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, color.red, color.green, color.blue, 255); } checks_pmap = XCreatePixmap(disp, root, 16, 16, depth); -- cgit v1.2.3 From 7acf83ea6d6f36e418f43a3408632944fbb7bcde Mon Sep 17 00:00:00 2001 From: ulteq Date: Thu, 18 Jan 2018 11:07:45 +0100 Subject: Add natural sort of (version) numbers --- src/feh.h | 1 + src/filelist.c | 19 +++++++++++++++---- src/help.raw | 1 + src/options.c | 4 ++++ src/options.h | 1 + 5 files changed, 22 insertions(+), 4 deletions(-) (limited to 'src/options.h') diff --git a/src/feh.h b/src/feh.h index a4a0a7b..da08aba 100644 --- a/src/feh.h +++ b/src/feh.h @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef FEH_H #define FEH_H +#define _GNU_SOURCE #include #include #include diff --git a/src/filelist.c b/src/filelist.c index b569b8a..3157e32 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -399,12 +399,18 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen) int feh_cmp_filename(void *file1, void *file2) { - return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + if (!opt.version_sort) + return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + else + return(strverscmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); } int feh_cmp_name(void *file1, void *file2) { - return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + if (!opt.version_sort) + return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + else + return(strverscmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } int feh_cmp_dirname(void *file1, void *file2) @@ -413,8 +419,13 @@ int feh_cmp_dirname(void *file1, void *file2) int cmp; feh_file_dirname(dir1, FEH_FILE(file1), PATH_MAX); feh_file_dirname(dir2, FEH_FILE(file2), PATH_MAX); - if ((cmp = strcmp(dir1, dir2)) != 0) - return(cmp); + if (!opt.version_sort) { + if ((cmp = strcmp(dir1, dir2)) != 0) + return(cmp); + } else { + if ((cmp = strverscmp(dir1, dir2)) != 0) + return(cmp); + } return(feh_cmp_name(file1, file2)); } diff --git a/src/help.raw b/src/help.raw index 37e0e71..8c83b5b 100644 --- a/src/help.raw +++ b/src/help.raw @@ -52,6 +52,7 @@ OPTIONS name, filename, mtime, width, height, pixels, size, or format -n, --reverse Reverse sort order + --version-sort Natural sort of (version) numbers within text -A, --action [;]ACTION Specify action to perform when pressing . Executed by /bin/sh, may contain FORMAT SPECIFIERS reloads image with \";\", switches to next otherwise diff --git a/src/options.c b/src/options.c index c874832..3fcbdef 100644 --- a/src/options.c +++ b/src/options.c @@ -412,6 +412,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"version-sort" , 0, 0, 246}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -782,6 +783,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 246: + opt.version_sort = 1; + break; default: break; } diff --git a/src/options.h b/src/options.h index c6959c8..277cede 100644 --- a/src/options.h +++ b/src/options.h @@ -103,6 +103,7 @@ struct __fehoptions { unsigned int thumb_redraw; double reload; int sort; + int version_sort; int debug; int geom_flags; int geom_x; -- cgit v1.2.3 From 5e75b5ef3e7d0270913c04645398bc3596c2a90a Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 14 Feb 2018 22:33:38 +0100 Subject: Only check image dimensions on the fly in multiwindow and slideshow mode This introduces a new feh_should_ignore_image function which is called at appropriate places in those modes to skip images which are loadable but undesired. --- src/feh.h | 1 + src/filelist.c | 12 +++++++++++- src/imlib.c | 12 ++++++++++++ src/options.c | 2 ++ src/options.h | 1 + src/slideshow.c | 14 ++++++-------- src/winwidget.c | 2 +- 7 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src/options.h') diff --git a/src/feh.h b/src/feh.h index bfd71db..60baade 100644 --- a/src/feh.h +++ b/src/feh.h @@ -133,6 +133,7 @@ void init_list_mode(void); void init_loadables_mode(void); void init_unloadables_mode(void); void feh_clean_exit(void); +int feh_should_ignore_image(Imlib_Image * im); int feh_load_image(Imlib_Image * im, feh_file * file); void show_mini_usage(void); void slideshow_change_image(winwidget winwid, int change, int render); diff --git a/src/filelist.c b/src/filelist.c index 0066efd..9a4af27 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -464,7 +464,17 @@ int feh_cmp_format(void *file1, void *file2) void feh_prepare_filelist(void) { - if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME)) { + /* + * list and customlist mode as well as the somewhat more fancy sort modes + * need access to file infos. Preloading them is also useful for + * list/customlist as --min-dimension/--max-dimension may filter images + * which should not be processed. + * Finally, if --min-dimension/--max-dimension (-> opt.filter_by_dimensions) + * is set and we're in thumbnail mode, we need to filter images first so + * we can create a properly sized thumbnail list. + */ + if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME) + || (opt.filter_by_dimensions && (opt.index || opt.collage || opt.thumbs || opt.bgmode))) { /* For these sort options, we have to preload images */ filelist = feh_file_info_preload(filelist); if (!gib_list_length(filelist)) diff --git a/src/imlib.c b/src/imlib.c index 6de6bdb..d9c5cd0 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -139,6 +139,18 @@ void init_x_and_imlib(void) return; } +int feh_should_ignore_image(Imlib_Image * im) +{ + if (opt.filter_by_dimensions) { + unsigned int w = gib_imlib_image_get_width(im); + unsigned int h = gib_imlib_image_get_height(im); + if (w < opt.min_width || w > opt.max_width || h < opt.min_height || h > opt.max_height) { + return 1; + } + } + return 0; +} + int feh_load_image_char(Imlib_Image * im, char *filename) { feh_file *file; diff --git a/src/options.c b/src/options.c index bf5c67c..76d70c5 100644 --- a/src/options.c +++ b/src/options.c @@ -433,6 +433,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.debug = 1; break; case '<': + opt.filter_by_dimensions = 1; XParseGeometry(optarg, &discard, &discard, &opt.max_width, &opt.max_height); if (opt.max_width == 0) opt.max_width = UINT_MAX; @@ -440,6 +441,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.max_height = UINT_MAX; break; case '>': + opt.filter_by_dimensions = 1; XParseGeometry(optarg, &discard, &discard, &opt.min_width, &opt.min_height); break; case '.': diff --git a/src/options.h b/src/options.h index c6959c8..9bf2763 100644 --- a/src/options.h +++ b/src/options.h @@ -75,6 +75,7 @@ struct __fehoptions { unsigned char no_fehbg; unsigned char keep_zoom_vp; unsigned char insecure_ssl; + unsigned char filter_by_dimensions; char *output_file; char *output_dir; diff --git a/src/slideshow.c b/src/slideshow.c index 6ab56fa..d56c1b6 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -361,17 +361,15 @@ void slideshow_change_image(winwidget winwid, int change, int render) } if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { - unsigned int w = gib_imlib_image_get_width(winwid->im); - unsigned int h = gib_imlib_image_get_height(winwid->im); - if (opt.min_width || opt.min_height || (opt.max_width != UINT_MAX) || (opt.max_height != UINT_MAX)) { - if (w < opt.min_width || w > opt.max_width || h < opt.min_height || h > opt.max_height) { - last = current_file; - continue; - } + int w = gib_imlib_image_get_width(winwid->im); + int h = gib_imlib_image_get_height(winwid->im); + if (feh_should_ignore_image(winwid->im)) { + last = current_file; + continue; } winwid->mode = MODE_NORMAL; winwid->file = current_file; - if ((winwid->im_w != (int)w) || (winwid->im_h != (int)h)) + if ((winwid->im_w != w) || (winwid->im_h != h)) winwid->had_resize = 1; winwidget_reset_image(winwid); winwid->im_w = w; diff --git a/src/winwidget.c b/src/winwidget.c index 3311383..9600465 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -115,7 +115,7 @@ winwidget winwidget_create_from_file(gib_list * list, char type) ret->file = list; ret->type = type; - if (winwidget_loadimage(ret, file) == 0) { + if ((winwidget_loadimage(ret, file) == 0) || feh_should_ignore_image(ret->im)) { winwidget_destroy(ret); return(NULL); } -- cgit v1.2.3 From d03fc61a268048e1bcef04fb00883c6cd339027b Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 28 Feb 2018 20:06:33 +0100 Subject: Add toggle_auto_zoom key binding, defaulting to Z Closes #218 --- man/feh.pre | 4 ++++ src/keyevents.c | 5 +++++ src/options.h | 1 + 3 files changed, 10 insertions(+) (limited to 'src/options.h') diff --git a/man/feh.pre b/man/feh.pre index 6c619cd..d90c880 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1376,6 +1376,10 @@ Close current window . Jump to a random position in the current filelist . +.It Z Bq toggle_auto_zoom +. +Toggle auto-zoom. +. .It \&[, \&] Bq prev_dir, next_dir . Jump to the first image of the previous or next sequence of images sharing diff --git a/src/keyevents.c b/src/keyevents.c index f082a78..793767b 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -185,6 +185,7 @@ void init_keyevents(void) { feh_set_kb("render" , 0, XK_KP_Begin , 0, XK_R , 0, 0); feh_set_kb("toggle_actions" , 0, XK_a, 0, 0, 0, 0); feh_set_kb("toggle_aliasing" , 0, XK_A, 0, 0, 0, 0); + feh_set_kb("toggle_auto_zoom" , 0, XK_Z, 0, 0, 0, 0); #ifdef HAVE_LIBEXIF feh_set_kb("toggle_exif" , 0, XK_e, 0, 0, 0, 0); #endif @@ -637,6 +638,10 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy winwid->force_aliasing = !winwid->force_aliasing; winwidget_render_image(winwid, 0, 0); } + else if (feh_is_kp(EVENT_toggle_auto_zoom, state, keysym, button)) { + opt.zoom_mode = (opt.zoom_mode == 0 ? ZOOM_MODE_MAX : 0); + winwidget_rerender_all(1); + } else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) { opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0); diff --git a/src/options.h b/src/options.h index c6b4e0e..d4de3c5 100644 --- a/src/options.h +++ b/src/options.h @@ -189,6 +189,7 @@ enum key_action { EVENT_render, EVENT_toggle_actions, EVENT_toggle_aliasing, + EVENT_toggle_auto_zoom, #ifdef HAVE_LIBEXIF EVENT_toggle_exif, #endif -- cgit v1.2.3 From 05e745a519248c1907340c7f5b0b7bc65f0409eb Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 19 Jan 2018 12:22:09 +0100 Subject: Utilize dcraw to preview RAW files Uses the camera-generated thumbnail to display RAW images that could otherwise not be loaded. --- src/imlib.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/options.c | 5 +++ src/options.h | 1 + 3 files changed, 108 insertions(+), 8 deletions(-) (limited to 'src/options.h') diff --git a/src/imlib.c b/src/imlib.c index d9c5cd0..b6041fc 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -61,7 +61,9 @@ int num_xinerama_screens; int childpid = 0; +static int feh_file_is_raw(char *filename); static char *feh_http_load_image(char *url); +static char *feh_dcraw_load_image(char *filename); static char *feh_magick_load_image(char *filename); #ifdef HAVE_LIBXINERAMA @@ -216,8 +218,7 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err) int feh_load_image(Imlib_Image * im, feh_file * file) { Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; - enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK } image_source = - SRC_IMLIB; + enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_DCRAW } image_source = SRC_IMLIB; char *tmpname = NULL; char *real_filename = NULL; @@ -232,16 +233,23 @@ int feh_load_image(Imlib_Image * im, feh_file * file) if ((tmpname = feh_http_load_image(file->filename)) == NULL) err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST; } + else if (opt.dcraw_timeout >= 0 && feh_file_is_raw(file->filename)) { + image_source = SRC_DCRAW; + tmpname = feh_dcraw_load_image(file->filename); + if (!tmpname) + err = IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT; + } else *im = imlib_load_image_with_error_return(file->filename, &err); - if ((err == IMLIB_LOAD_ERROR_UNKNOWN) - || (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT)) { + if (opt.magick_timeout >= 0 && ( + (err == IMLIB_LOAD_ERROR_UNKNOWN) || + (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) { image_source = SRC_MAGICK; tmpname = feh_magick_load_image(file->filename); } - if ((image_source != SRC_IMLIB) && tmpname) { + if (tmpname) { *im = imlib_load_image_with_error_return(tmpname, &err); if (!err && im) { real_filename = file->filename; @@ -301,6 +309,95 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(1); } +static int feh_file_is_raw(char *filename) +{ + childpid = fork(); + if (childpid == -1) { + perror("fork"); + return 0; + } + + if (childpid == 0) { + if (opt.quiet) { + int devnull = open("/dev/null", O_WRONLY); + dup2(devnull, 1); + dup2(devnull, 2); + } + execlp("dcraw", "dcraw", "-i", filename, NULL); + _exit(1); + } else { + int status; + do { + waitpid(childpid, &status, WUNTRACED); + if (WIFEXITED(status)) { + return !WEXITSTATUS(status); + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + + return 0; +} + +static char *feh_dcraw_load_image(char *filename) +{ + char *basename; + char *tmpname; + char *sfn; + int fd = -1; + + basename = strrchr(filename, '/'); + + if (basename == NULL) + basename = filename; + else + basename++; + + tmpname = feh_unique_filename("/tmp/", basename); + + if (strlen(tmpname) > (NAME_MAX-6)) + tmpname[NAME_MAX-7] = '\0'; + + sfn = estrjoin("_", tmpname, "XXXXXX", NULL); + free(tmpname); + + fd = mkstemp(sfn); + + if (fd == -1) { + free(sfn); + return NULL; + } + + childpid = fork(); + if (childpid == -1) { + weprintf("%s: Can't load with dcraw. Fork failed:", filename); + unlink(sfn); + free(sfn); + close(fd); + return NULL; + } else if (childpid == 0) { + + close(1); + dup(fd); + close(fd); + + alarm(opt.dcraw_timeout); + execlp("dcraw", "dcraw", "-c", "-e", filename, NULL); + _exit(1); + } + + int status; + waitpid(-1, &status, 0); + if (WIFSIGNALED(status)) { + unlink(sfn); + free(sfn); + sfn = NULL; + if (!opt.quiet) + weprintf("%s - Conversion took too long, skipping", filename); + } + + return sfn; +} + static char *feh_magick_load_image(char *filename) { char *argv_fn; @@ -310,9 +407,6 @@ static char *feh_magick_load_image(char *filename) int fd = -1, devnull = -1; int status; - if (opt.magick_timeout < 0) - return NULL; - basename = strrchr(filename, '/'); if (basename == NULL) diff --git a/src/options.c b/src/options.c index 3d11482..29ce836 100644 --- a/src/options.c +++ b/src/options.c @@ -55,6 +55,7 @@ void init_parse_options(int argc, char **argv) opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; + opt.dcraw_timeout = -1; opt.magick_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; @@ -415,6 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"dcraw-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {0, 0, 0, 0} }; @@ -781,6 +783,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 245: + opt.dcraw_timeout = atoi(optarg); + break; case 246: opt.version_sort = 1; break; diff --git a/src/options.h b/src/options.h index d4de3c5..88121e6 100644 --- a/src/options.h +++ b/src/options.h @@ -129,6 +129,7 @@ struct __fehoptions { double slideshow_delay; + signed short dcraw_timeout; signed short magick_timeout; Imlib_Font menu_fn; -- cgit v1.2.3 From 81963c7b44194be63479299f217e97e2d0c48db5 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Thu, 8 Mar 2018 19:42:35 +0100 Subject: add (experimental and still slightly buggy) --inner-geometry feature See #278 --- src/options.c | 5 +++++ src/options.h | 5 +++++ src/winwidget.c | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) (limited to 'src/options.h') diff --git a/src/options.c b/src/options.c index 3d11482..0db5aae 100644 --- a/src/options.c +++ b/src/options.c @@ -416,6 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, {"version-sort" , 0, 0, 246}, + {"inner-geometry", 1, 0, 247}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -784,6 +785,10 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 246: opt.version_sort = 1; break; + case 247: + opt.inner_geom_flags = XParseGeometry(optarg, &opt.inner_geom_x, + &opt.inner_geom_y, &opt.inner_geom_w, &opt.inner_geom_h); + break; default: break; } diff --git a/src/options.h b/src/options.h index d4de3c5..d4ffbeb 100644 --- a/src/options.h +++ b/src/options.h @@ -111,6 +111,11 @@ struct __fehoptions { int geom_y; unsigned int geom_w; unsigned int geom_h; + int inner_geom_flags; + int inner_geom_x; + int inner_geom_y; + unsigned int inner_geom_w; + unsigned int inner_geom_h; int default_zoom; int zoom_mode; unsigned char adjust_reload; diff --git a/src/winwidget.c b/src/winwidget.c index bb6181a..7b8a9dc 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -555,6 +555,32 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } + /* + * Adjust X/Y offset if the image is larger than the window and + * --inner-geometry is set. This will cause odd behaviour when + * zooming an already large image in --inner-geometry mode, but in most + * cases this should be what the user wants. Plus, it doesn't require + * fiddling around in two or three places above, so it's the best + * solution considering a future refactoring of this function. + */ + + if (need_center || resize) { + if ((opt.inner_geom_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { + if (opt.inner_geom_flags & XNegative) { + winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.inner_geom_x; + } else { + winwid->im_x = - opt.inner_geom_x * winwid->zoom; + } + } + if ((opt.inner_geom_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { + if (opt.inner_geom_flags & YNegative) { + winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.inner_geom_y; + } else { + winwid->im_y = - opt.inner_geom_y * winwid->zoom; + } + } + } + /* Now we ensure only to render the area we're looking at */ dx = winwid->im_x; dy = winwid->im_y; -- cgit v1.2.3 From e522c4ea04e9d899907deb5d0304f7de0823e9da Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 9 Mar 2018 17:07:52 +0100 Subject: rename --inner-geometry to --offset, discard width and height values --- src/options.c | 6 +++--- src/options.h | 8 +++----- src/winwidget.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) (limited to 'src/options.h') diff --git a/src/options.c b/src/options.c index 0db5aae..bc95604 100644 --- a/src/options.c +++ b/src/options.c @@ -416,7 +416,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, {"version-sort" , 0, 0, 246}, - {"inner-geometry", 1, 0, 247}, + {"offset" , 1, 0, 247}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -786,8 +786,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.version_sort = 1; break; case 247: - opt.inner_geom_flags = XParseGeometry(optarg, &opt.inner_geom_x, - &opt.inner_geom_y, &opt.inner_geom_w, &opt.inner_geom_h); + opt.offset_flags = XParseGeometry(optarg, &opt.offset_x, + &opt.offset_y, (unsigned int *)&discard, (unsigned int *)&discard); break; default: break; diff --git a/src/options.h b/src/options.h index d4ffbeb..ed8641a 100644 --- a/src/options.h +++ b/src/options.h @@ -111,11 +111,9 @@ struct __fehoptions { int geom_y; unsigned int geom_w; unsigned int geom_h; - int inner_geom_flags; - int inner_geom_x; - int inner_geom_y; - unsigned int inner_geom_w; - unsigned int inner_geom_h; + int offset_flags; + int offset_x; + int offset_y; int default_zoom; int zoom_mode; unsigned char adjust_reload; diff --git a/src/winwidget.c b/src/winwidget.c index 7b8a9dc..beae9fa 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -565,18 +565,18 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) */ if (need_center || resize) { - if ((opt.inner_geom_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { - if (opt.inner_geom_flags & XNegative) { - winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.inner_geom_x; + if ((opt.offset_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { + if (opt.offset_flags & XNegative) { + winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x; } else { - winwid->im_x = - opt.inner_geom_x * winwid->zoom; + winwid->im_x = - opt.offset_x * winwid->zoom; } } - if ((opt.inner_geom_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { - if (opt.inner_geom_flags & YNegative) { - winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.inner_geom_y; + if ((opt.offset_flags & YValue) && (winwid->im_h * winwid->zoom) > winwid->h) { + if (opt.offset_flags & YNegative) { + winwid->im_y = winwid->h - (winwid->im_h * winwid->zoom) - opt.offset_y; } else { - winwid->im_y = - opt.inner_geom_y * winwid->zoom; + winwid->im_y = - opt.offset_y * winwid->zoom; } } } -- cgit v1.2.3 From acada1a7153a43f4fd18cfb15ac7b0278e0d4727 Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 9 Mar 2018 16:21:06 +0100 Subject: Allow empty string as --geometry argument Passing an empty string to the --geometry option will enable fixed geometry mode without having to specify anything else --- src/options.c | 1 + src/options.h | 1 + src/winwidget.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/options.h') diff --git a/src/options.c b/src/options.c index bc95604..1e75c6b 100644 --- a/src/options.c +++ b/src/options.c @@ -592,6 +592,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.filelistfile = estrdup(optarg); break; case 'g': + opt.geom_enabled = 1; opt.geom_flags = XParseGeometry(optarg, &opt.geom_x, &opt.geom_y, &opt.geom_w, &opt.geom_h); break; diff --git a/src/options.h b/src/options.h index ed8641a..6ad8a44 100644 --- a/src/options.h +++ b/src/options.h @@ -106,6 +106,7 @@ struct __fehoptions { int sort; int version_sort; int debug; + int geom_enabled; int geom_flags; int geom_x; int geom_y; diff --git a/src/winwidget.c b/src/winwidget.c index a8bcc0a..1ce7e61 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -323,7 +323,7 @@ void winwidget_create_window(winwidget ret, int w, int h) winwidget_register(ret); /* do not scale down a thumbnail list window, only those created from it */ - if (opt.scale_down && (ret->type != WIN_TYPE_THUMBNAIL)) { + if (opt.geom_enabled && (ret->type != WIN_TYPE_THUMBNAIL)) { opt.geom_w = w; opt.geom_h = h; opt.geom_flags |= WidthValue | HeightValue; -- cgit v1.2.3 From 3c675a64a5842f0fe824a22bc9d3af025c1d17fe Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 11 May 2018 20:51:24 +0200 Subject: Update copyright notice --- man/feh.pre | 2 +- src/collage.c | 2 +- src/debug.h | 2 +- src/events.c | 2 +- src/feh.h | 2 +- src/filelist.c | 2 +- src/imlib.c | 2 +- src/index.c | 2 +- src/index.h | 2 +- src/keyevents.c | 2 +- src/list.c | 2 +- src/main.c | 2 +- src/menu.c | 2 +- src/menu.h | 2 +- src/options.c | 2 +- src/options.h | 2 +- src/signals.c | 2 +- src/slideshow.c | 2 +- src/structs.h | 2 +- src/thumbnail.c | 2 +- src/thumbnail.h | 2 +- src/timers.c | 2 +- src/wallpaper.c | 2 +- src/wallpaper.h | 2 +- src/winwidget.c | 2 +- src/winwidget.h | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/options.h') diff --git a/man/feh.pre b/man/feh.pre index a358714..d2c2cea 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -1943,7 +1943,7 @@ Make zoom options more intuitive . Copyright (C) 1999, 2000 by Paul Duncan. Copyright (C) 1999, 2000 by Tom Gilbert (and various contributors). -Copyright (C) 2010-2016 by Daniel Friesel (and even more contributors). +Copyright (C) 2010-2018 by Daniel Friesel (and even more contributors). . .Pp . diff --git a/src/collage.c b/src/collage.c index 431d3b6..2a4d9f9 100644 --- a/src/collage.c +++ b/src/collage.c @@ -1,7 +1,7 @@ /* collage.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/debug.h b/src/debug.h index eb929e3..38cf83f 100644 --- a/src/debug.h +++ b/src/debug.h @@ -1,7 +1,7 @@ /* debug.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/events.c b/src/events.c index 947e69f..4a24935 100644 --- a/src/events.c +++ b/src/events.c @@ -1,7 +1,7 @@ /* events.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/feh.h b/src/feh.h index 3e0cdda..009f45b 100644 --- a/src/feh.h +++ b/src/feh.h @@ -1,7 +1,7 @@ /* feh.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/filelist.c b/src/filelist.c index 08da331..eb8e294 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -1,7 +1,7 @@ /* filelist.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/imlib.c b/src/imlib.c index 28dc1a6..5be0539 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -1,7 +1,7 @@ /* imlib.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/index.c b/src/index.c index c8c34c5..ca1664b 100644 --- a/src/index.c +++ b/src/index.c @@ -1,7 +1,7 @@ /* index.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/index.h b/src/index.h index 08ab337..b022f1a 100644 --- a/src/index.h +++ b/src/index.h @@ -1,6 +1,6 @@ /* index.h -Copyright (C) 2011 Daniel Friesel. +Copyright (C) 2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/keyevents.c b/src/keyevents.c index 12a8eb9..689aebd 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -1,7 +1,7 @@ /* keyevents.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/list.c b/src/list.c index 09b23f4..2f6cf76 100644 --- a/src/list.c +++ b/src/list.c @@ -1,7 +1,7 @@ /* list.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/main.c b/src/main.c index 534b89e..f1fca24 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /* main.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/menu.c b/src/menu.c index ddb2db1..2f8875d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1,7 +1,7 @@ /* menu.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/menu.h b/src/menu.h index 403728f..b53b32f 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,7 +1,7 @@ /* menu.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/options.c b/src/options.c index bc95604..8ddf2fa 100644 --- a/src/options.c +++ b/src/options.c @@ -1,7 +1,7 @@ /* options.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/options.h b/src/options.h index ed8641a..61de5dc 100644 --- a/src/options.h +++ b/src/options.h @@ -1,7 +1,7 @@ /* options.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/signals.c b/src/signals.c index 8a3a8f7..c08d5df 100644 --- a/src/signals.c +++ b/src/signals.c @@ -1,6 +1,6 @@ /* signals.c -Copyright (C) 2010 by Daniel Friesel +Copyright (C) 2010-2018 by Daniel Friesel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/slideshow.c b/src/slideshow.c index 7bad2c9..0e560d8 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -1,7 +1,7 @@ /* slideshow.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/structs.h b/src/structs.h index 3942bc0..ce30eb9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,7 +1,7 @@ /* structs.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/thumbnail.c b/src/thumbnail.c index 3e99bfb..cf38cfc 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -1,7 +1,7 @@ /* thumbnail.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/thumbnail.h b/src/thumbnail.h index f22ff77..09cd771 100644 --- a/src/thumbnail.h +++ b/src/thumbnail.h @@ -1,7 +1,7 @@ /* thumbnail.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/timers.c b/src/timers.c index 1cac94b..95fc9f8 100644 --- a/src/timers.c +++ b/src/timers.c @@ -1,7 +1,7 @@ /* timers.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/wallpaper.c b/src/wallpaper.c index 6aa5c6d..7cf2468 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -1,7 +1,7 @@ /* wallpaper.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/wallpaper.h b/src/wallpaper.h index 0921129..02a6997 100644 --- a/src/wallpaper.h +++ b/src/wallpaper.h @@ -1,7 +1,7 @@ /* wallpaper.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/winwidget.c b/src/winwidget.c index 7aae191..cd5a745 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -1,7 +1,7 @@ /* winwidget.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/src/winwidget.h b/src/winwidget.h index dd8489a..3d998b4 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -1,7 +1,7 @@ /* winwidget.h Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2018 Daniel Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to -- cgit v1.2.3 From 607374d4c7f7a133d3d1c5c012a6a5af9e2e60bf Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 5 Aug 2018 13:57:45 +0200 Subject: Merge --dcraw-timeout and --magick-timeout into --conversion-timeout --- src/filelist.c | 8 ++++---- src/imlib.c | 10 +++++----- src/options.c | 10 +++++----- src/options.h | 3 +-- 4 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src/options.h') diff --git a/src/filelist.c b/src/filelist.c index eb8e294..b492965 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -574,7 +574,7 @@ gib_list *feh_read_filelist(char *filename) Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; Imlib_Image tmp_im; struct stat st; - signed short tmp_magick_timeout; + signed short tmp_conversion_timeout; if (!filename) return(NULL); @@ -582,8 +582,8 @@ gib_list *feh_read_filelist(char *filename) /* * feh_load_image will fail horribly if filename is not seekable */ - tmp_magick_timeout = opt.magick_timeout; - opt.magick_timeout = -1; + tmp_conversion_timeout = opt.conversion_timeout; + opt.conversion_timeout = -1; if (!stat(filename, &st) && S_ISREG(st.st_mode)) { tmp_im = imlib_load_image_with_error_return(filename, &err); if (err == IMLIB_LOAD_ERROR_NONE) { @@ -594,7 +594,7 @@ gib_list *feh_read_filelist(char *filename) return NULL; } } - opt.magick_timeout = tmp_magick_timeout; + opt.conversion_timeout = tmp_conversion_timeout; errno = 0; diff --git a/src/imlib.c b/src/imlib.c index 2d1b47a..f41cdcd 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -230,7 +230,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) if ((tmpname = feh_http_load_image(file->filename)) == NULL) err = IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST; } - else if (opt.dcraw_timeout >= 0 && feh_file_is_raw(file->filename)) { + else if (opt.conversion_timeout >= 0 && feh_file_is_raw(file->filename)) { image_source = SRC_DCRAW; tmpname = feh_dcraw_load_image(file->filename); if (!tmpname) @@ -239,7 +239,7 @@ int feh_load_image(Imlib_Image * im, feh_file * file) else *im = imlib_load_image_with_error_return(file->filename, &err); - if (opt.magick_timeout >= 0 && ( + if (opt.conversion_timeout >= 0 && ( (err == IMLIB_LOAD_ERROR_UNKNOWN) || (err == IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT))) { image_source = SRC_MAGICK; @@ -377,7 +377,7 @@ static char *feh_dcraw_load_image(char *filename) dup(fd); close(fd); - alarm(opt.dcraw_timeout); + alarm(opt.conversion_timeout); execlp("dcraw", "dcraw", "-c", "-e", filename, NULL); _exit(1); } @@ -481,10 +481,10 @@ static char *feh_magick_load_image(char *filename) _exit(1); } else { - alarm(opt.magick_timeout); + alarm(opt.conversion_timeout); waitpid(childpid, &status, 0); kill(childpid, SIGKILL); - if (opt.magick_timeout > 0 && !alarm(0)) { + if (opt.conversion_timeout > 0 && !alarm(0)) { unlink(sfn); free(sfn); sfn = NULL; diff --git a/src/options.c b/src/options.c index b0d67cd..af0f07d 100644 --- a/src/options.c +++ b/src/options.c @@ -55,8 +55,7 @@ void init_parse_options(int argc, char **argv) opt.display = 1; opt.aspect = 1; opt.slideshow_delay = 0.0; - opt.dcraw_timeout = -1; - opt.magick_timeout = -1; + opt.conversion_timeout = -1; opt.thumb_w = 60; opt.thumb_h = 60; opt.thumb_redraw = 10; @@ -416,7 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, - {"dcraw-timeout" , 1, 0, 245}, + {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, {0, 0, 0, 0} @@ -695,7 +694,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.index_info = estrdup(optarg); break; case 208: - opt.magick_timeout = atoi(optarg); + weprintf("--magick-timeout is deprecated, please use --conversion-timeout instead"); + opt.conversion_timeout = atoi(optarg); break; case 209: opt.actions[1] = estrdup(optarg); @@ -786,7 +786,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.cache_size = 2048; break; case 245: - opt.dcraw_timeout = atoi(optarg); + opt.conversion_timeout = atoi(optarg); break; case 246: opt.version_sort = 1; diff --git a/src/options.h b/src/options.h index 741b0c7..936b4bd 100644 --- a/src/options.h +++ b/src/options.h @@ -133,8 +133,7 @@ struct __fehoptions { double slideshow_delay; - signed short dcraw_timeout; - signed short magick_timeout; + signed int conversion_timeout; Imlib_Font menu_fn; }; -- cgit v1.2.3 From f3ea5c887e034f08d2735c7a32876f94ee9ef60a Mon Sep 17 00:00:00 2001 From: ulteq Date: Mon, 1 Jan 2018 15:37:32 +0100 Subject: Add --no-cycle option Closes: #124 --- src/help.raw | 1 + src/options.c | 4 ++++ src/options.h | 1 + src/slideshow.c | 7 +++++++ 4 files changed, 13 insertions(+) (limited to 'src/options.h') diff --git a/src/help.raw b/src/help.raw index 86bb617..52d06bf 100644 --- a/src/help.raw +++ b/src/help.raw @@ -38,6 +38,7 @@ OPTIONS --auto-rotate Rotate images according to Exif info (if compiled with exif=1) -^, --title TITLE Set window title (see FORMAT SPECIFIERS) -D, --slideshow-delay NUM Set delay between automatically changing slides + --no-cycle Stop at both ends of the filelist --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -k, --keep-http Keep local copies when viewing HTTP/FTP files diff --git a/src/options.c b/src/options.c index af0f07d..1a47a39 100644 --- a/src/options.c +++ b/src/options.c @@ -415,6 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, + {"no-cycle" , 0, 0, 244}, {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, @@ -785,6 +786,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) if (opt.cache_size > 2048) opt.cache_size = 2048; break; + case 244: + opt.no_cycle = 1; + break; case 245: opt.conversion_timeout = atoi(optarg); break; diff --git a/src/options.h b/src/options.h index 936b4bd..122d39e 100644 --- a/src/options.h +++ b/src/options.h @@ -69,6 +69,7 @@ struct __fehoptions { unsigned char draw_info; unsigned char cache_thumbnails; unsigned char cycle_once; + unsigned char no_cycle; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char no_fehbg; diff --git a/src/slideshow.c b/src/slideshow.c index b27a7e8..77f5a82 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -215,6 +215,7 @@ void feh_reload_image(winwidget w, int resize, int force_new) void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; + gib_list *previous_file = current_file; int i = 0; int jmp = 1; /* We can't use filelist_len in the for loop, since that changes when we @@ -332,6 +333,12 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } + if (opt.no_cycle && + ((current_file == filelist && change == SLIDE_NEXT) || + (previous_file == filelist && change == SLIDE_PREV))) { + current_file = previous_file; + } + if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { int w = gib_imlib_image_get_width(winwid->im); int h = gib_imlib_image_get_height(winwid->im); -- cgit v1.2.3 From dbc8dc8ceabdab55c5c8c74708af7788ade1c151 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sat, 18 Aug 2018 19:43:32 +0200 Subject: combine --no-cycle and --cycle-once into --on-last-slide={quit,hold} --- src/help.raw | 4 ++-- src/options.c | 16 +++++++++++++--- src/options.h | 9 +++++++-- src/slideshow.c | 10 +++++----- 4 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src/options.h') diff --git a/src/help.raw b/src/help.raw index 52d06bf..ebffae3 100644 --- a/src/help.raw +++ b/src/help.raw @@ -38,8 +38,8 @@ OPTIONS --auto-rotate Rotate images according to Exif info (if compiled with exif=1) -^, --title TITLE Set window title (see FORMAT SPECIFIERS) -D, --slideshow-delay NUM Set delay between automatically changing slides - --no-cycle Stop at both ends of the filelist - --cycle-once Exit after one loop through the slideshow + --on-last-slide quit Exit after one loop through the slide show + --on-last-slide hold Stop at both ends of the filelist -R, --reload NUM Reload images after NUM seconds -k, --keep-http Keep local copies when viewing HTTP/FTP files --insecure Disable peer/host verification when using HTTPS. diff --git a/src/options.c b/src/options.c index 1a47a39..38d2568 100644 --- a/src/options.c +++ b/src/options.c @@ -415,7 +415,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"insecure" , 0, 0, 240}, {"no-recursive" , 0, 0, 241}, {"cache-size" , 1, 0, 243}, - {"no-cycle" , 0, 0, 244}, + {"on-last-slide" , 1, 0, 244}, {"conversion-timeout" , 1, 0, 245}, {"version-sort" , 0, 0, 246}, {"offset" , 1, 0, 247}, @@ -743,7 +743,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; #endif case 224: - opt.cycle_once = 1; + weprintf("--cycle-once is deprecated, please use --on-last-slide=quit instead"); + opt.on_last_slide = ON_LAST_SLIDE_QUIT; break; case 225: opt.xinerama = 0; @@ -787,7 +788,16 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.cache_size = 2048; break; case 244: - opt.no_cycle = 1; + if (!strcmp(optarg, "quit")) { + opt.on_last_slide = ON_LAST_SLIDE_QUIT; + } else if (!strcmp(optarg, "hold")) { + opt.on_last_slide = ON_LAST_SLIDE_HOLD; + } else if (!strcmp(optarg, "resume")) { + opt.on_last_slide = ON_LAST_SLIDE_RESUME; + } else { + weprintf("Unrecognized on-last-slide action \"%s\"." + "Supported actions: hold, resume, quit\n", optarg); + } break; case 245: opt.conversion_timeout = atoi(optarg); diff --git a/src/options.h b/src/options.h index 122d39e..606b8e6 100644 --- a/src/options.h +++ b/src/options.h @@ -27,6 +27,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef OPTIONS_H #define OPTIONS_H +enum on_last_slide_action { + ON_LAST_SLIDE_RESUME = 0, + ON_LAST_SLIDE_QUIT, + ON_LAST_SLIDE_HOLD +}; + struct __fehoptions { unsigned char multiwindow; unsigned char montage; @@ -68,8 +74,7 @@ struct __fehoptions { unsigned char draw_actions; unsigned char draw_info; unsigned char cache_thumbnails; - unsigned char cycle_once; - unsigned char no_cycle; + unsigned char on_last_slide; unsigned char hold_actions[10]; unsigned char text_bg; unsigned char no_fehbg; diff --git a/src/slideshow.c b/src/slideshow.c index 77f5a82..6f622b4 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -225,7 +225,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ - if (filelist_len < 2 && opt.cycle_once == 0) + if (filelist_len < 2 && opt.on_last_slide != ON_LAST_SLIDE_QUIT) return; /* Ok. I do this in such an odd way to ensure that if the last or first * @@ -333,7 +333,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } - if (opt.no_cycle && + if (opt.on_last_slide == ON_LAST_SLIDE_HOLD && ((current_file == filelist && change == SLIDE_NEXT) || (previous_file == filelist && change == SLIDE_PREV))) { current_file = previous_file; @@ -574,10 +574,10 @@ void feh_filelist_image_remove(winwidget winwid, char do_delete) doomed = current_file; /* - * work around feh_list_jump exiting if cycle_once is enabled + * work around feh_list_jump exiting if ON_LAST_SLIDE_QUIT is set * and no further files are left (we need to delete first) */ - if (opt.cycle_once && ! doomed->next && do_delete) { + if (opt.on_last_slide == ON_LAST_SLIDE_QUIT && ! doomed->next && do_delete) { feh_file_rm_and_free(filelist, doomed); exit(0); } @@ -653,7 +653,7 @@ gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num) if (ret->next) { ret = ret->next; } else { - if (opt.cycle_once) { + if (opt.on_last_slide == ON_LAST_SLIDE_QUIT) { exit(0); } if (opt.randomize) { -- cgit v1.2.3