diff options
| author | Sven Willner <sven.willner@gmail.com> | 2018-09-13 15:47:18 +0200 | 
|---|---|---|
| committer | Sven Willner <sven.willner@gmail.com> | 2018-09-13 15:47:18 +0200 | 
| commit | 4ca5b177bbaf656611dd253d7c8e37317b5b186f (patch) | |
| tree | 5f66934df56dfcbe11364bda57899d078511c3c8 /src/keyevents.c | |
| parent | 3671b53046afbeced26162fc413fcfb7971116b9 (diff) | |
| parent | 9241e8faa78cc02c08537ed0bd7b236d172c3ed7 (diff) | |
Merge branch 'master' of github.com:derf/feh
Diffstat (limited to 'src/keyevents.c')
| -rw-r--r-- | src/keyevents.c | 533 | 
1 files changed, 250 insertions, 283 deletions
diff --git a/src/keyevents.c b/src/keyevents.c index b5c1949..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 @@ -29,17 +29,51 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "filelist.h"  #include "winwidget.h"  #include "options.h" +#include <termios.h> -fehkb keys; +struct __fehkey keys[EVENT_LIST_END]; +struct termios old_term_settings; +unsigned char control_via_stdin = 0; -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) { +void setup_stdin() { +	struct termios ctrl; + +	control_via_stdin = 1; + +	if (tcgetattr(STDIN_FILENO, &old_term_settings) == -1) +		eprintf("tcgetattr failed"); +	if (tcgetattr(STDIN_FILENO, &ctrl) == -1) +		eprintf("tcgetattr failed"); + +	ctrl.c_iflag &= ~(PARMRK | ISTRIP +			| INLCR | IGNCR | IXON); +	ctrl.c_lflag &= ~(ECHO | ICANON | IEXTEN); +	ctrl.c_cflag &= ~(CSIZE | PARENB); +	ctrl.c_cflag |= CS8; + +	if (tcsetattr(STDIN_FILENO, TCSANOW, &ctrl) == -1) +		eprintf("tcsetattr failed"); +} + +void restore_stdin() { +	if (tcsetattr(STDIN_FILENO, TCSANOW, &old_term_settings) == -1) +		eprintf("tcsetattr failed"); +} + +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) { @@ -100,74 +134,83 @@ 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); +	feh_set_kb("toggle_auto_zoom" , 0, XK_Z, 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("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"); @@ -212,21 +255,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; @@ -234,12 +279,15 @@ static short feh_is_kp(fehkey *key, unsigned int state, unsigned int sym, unsign  void feh_event_invoke_action(winwidget winwid, unsigned char action)  { +	struct stat st;  	if (opt.actions[action]) {  		if (opt.slideshow) {  			feh_action_run(FEH_FILE(winwid->file->data), opt.actions[action], winwid);  			if (opt.hold_actions[action])  				feh_reload_image(winwid, 1, 1); +			else if (stat(FEH_FILE(winwid->file->data)->filename, &st) == -1) +				feh_filelist_image_remove(winwid, 0);  			else  				slideshow_change_image(winwid, SLIDE_NEXT, 1); @@ -269,22 +317,52 @@ void feh_event_invoke_action(winwidget winwid, unsigned char action)  void feh_event_handle_stdin()  {  	char stdin_buf[2]; +	static char is_esc = 0;  	KeySym keysym = NoSymbol;  	if (read(STDIN_FILENO, &stdin_buf, 1) == -1) { -		weprintf("reading a command from stdin failed"); +		control_via_stdin = 0; +		if (isatty(STDIN_FILENO) && getpgrp() == (tcgetpgrp(STDIN_FILENO))) { +			weprintf("reading a command from stdin failed - disabling control via stdin"); +			restore_stdin(); +		}  		return;  	}  	stdin_buf[1] = '\0'; +	// escape? +	if (stdin_buf[0] == 0x1b) { +		is_esc = 1; +		return; +	} +	if ((is_esc == 1) && (stdin_buf[0] == '[')) { +		is_esc = 2; +		return; +	} +  	if (stdin_buf[0] == ' ')  		keysym = XK_space;  	else if (stdin_buf[0] == '\n')  		keysym = XK_Return; +	else if ((stdin_buf[0] == '\b') || (stdin_buf[0] == 127)) +		keysym = XK_BackSpace; +	else if (is_esc == 2) { +		if (stdin_buf[0] == 'A') +			keysym = XK_Up; +		else if (stdin_buf[0] == 'B') +			keysym = XK_Down; +		else if (stdin_buf[0] == 'C') +			keysym = XK_Right; +		else if (stdin_buf[0] == 'D') +			keysym = XK_Left; +		is_esc = 0; +	}  	else  		keysym = XStringToKeysym(stdin_buf);  	if (window_num) -		feh_event_handle_generic(windows[0], 0, keysym, 0); +		feh_event_handle_generic(windows[0], is_esc * Mod1Mask, keysym, 0); + +	is_esc = 0;  }  void feh_event_handle_keypress(XEvent * ev) @@ -314,17 +392,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;  	} @@ -332,7 +410,23 @@ void feh_event_handle_keypress(XEvent * ev)  	if (winwid == NULL)  		return; -	if (winwid->caption_entry) { +	feh_event_handle_generic(winwid, state, keysym, 0); +} + +fehkey *feh_str_to_kb(char *action) +{ +	for (unsigned int i = 0; i < EVENT_LIST_END; i++) { +		if (!strcmp(action, keys[i].name)) { +			return &keys[i]; +		} +	} +	return NULL; +} + +void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) { +	int curr_screen = 0; + +	if (winwid->caption_entry && (keysym != NoSymbol)) {  		switch (keysym) {  		case XK_Return:  			if (state & ControlMask) { @@ -383,272 +477,131 @@ void feh_event_handle_keypress(XEvent * ev)  		}  		return;  	} -	feh_event_handle_generic(winwid, state, keysym, 0); -} -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; - -	return NULL; -} - -void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) { -	int curr_screen = 0; - -	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; @@ -662,7 +615,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; @@ -676,17 +629,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); @@ -694,46 +647,50 @@ 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_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);  	}  #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 @@ -745,44 +702,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 (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]; @@ -818,20 +775,30 @@ 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(EVENT_toggle_fixed_geometry, state, keysym, button)) { +		if (opt.geom_flags & ((WidthValue | HeightValue))) { +			opt.geom_flags &= ~(WidthValue | HeightValue); +		} else { +			opt.geom_flags |= (WidthValue | HeightValue); +			opt.geom_w = winwid->w; +			opt.geom_h = winwid->h; +		} +		winwidget_render_image(winwid, 1, 0); +	}  	return;  }  | 
