diff options
| -rw-r--r-- | config.h | 145 | ||||
| -rw-r--r-- | events.c | 233 | ||||
| -rw-r--r-- | events.h | 14 | 
3 files changed, 208 insertions, 184 deletions
@@ -1,9 +1,3 @@ -#ifdef _GENERAL_CONFIG - -/* enable external commands (defined below)? 0 = off, 1 = on:  */ -enum { EXT_COMMANDS = 0 }; - -#endif  #ifdef _WINDOW_CONFIG  /* default window dimensions (overwritten via -g option):      */ @@ -42,79 +36,80 @@ enum { THUMB_SIZE = 60 };  /* keyboard mappings for image and thumbnail mode:             */  static const keymap_t keys[] = { -	/* key              function            argument */ -	{ XK_q,             quit,               None }, -	{ XK_r,             reload,             None }, -	{ XK_f,             toggle_fullscreen,  None }, -	{ XK_a,             toggle_antialias,   None }, -	{ XK_A,             toggle_alpha,       None }, -	{ XK_Return,        switch_mode,        None }, - -	{ XK_g,             first,              None }, -	{ XK_G,             last,               None }, -	{ XK_n,             navigate,           +1 }, -	{ XK_space,         navigate,           +1 }, -	{ XK_p,             navigate,           -1 }, -	{ XK_BackSpace,     navigate,           -1 }, -	{ XK_bracketright,  navigate,           +10 }, -	{ XK_bracketleft,   navigate,           -10 }, - -	{ XK_D,             remove_image,       None }, - -	{ XK_h,             move,               DIR_LEFT }, -	{ XK_Left,          move,               DIR_LEFT }, -	{ XK_j,             move,               DIR_DOWN }, -	{ XK_Down,          move,               DIR_DOWN }, -	{ XK_k,             move,               DIR_UP }, -	{ XK_Up,            move,               DIR_UP }, -	{ XK_l,             move,               DIR_RIGHT }, -	{ XK_Right,         move,               DIR_RIGHT }, - -	{ XK_braceleft,     pan_screen,         DIR_LEFT }, -	{ XK_Next,          pan_screen,         DIR_DOWN }, -	{ XK_Prior,         pan_screen,         DIR_UP }, -	{ XK_braceright,    pan_screen,         DIR_RIGHT }, - -	{ XK_H,             pan_edge,           DIR_LEFT }, -	{ XK_J,             pan_edge,           DIR_DOWN }, -	{ XK_K,             pan_edge,           DIR_UP }, -	{ XK_L,             pan_edge,           DIR_RIGHT }, - -	{ XK_plus,          zoom,               +1 }, -	{ XK_equal,         zoom,               +1 }, -	{ XK_KP_Add,        zoom,               +1 }, -	{ XK_minus,         zoom,               -1 }, -	{ XK_KP_Subtract,   zoom,               -1 }, -	{ XK_0,             zoom,               0 }, -	{ XK_KP_0,          zoom,               0 }, -	{ XK_w,             fit_to_win,         None }, -	{ XK_W,             fit_to_img,         None }, - -	{ XK_less,          rotate,             DIR_LEFT }, -	{ XK_greater,       rotate,             DIR_RIGHT }, -}; - -/* external commands and corresponding key mappings:           */ -static const command_t commands[] = { -	/* ctrl-...    reload?  command, '#' is replaced by filename */ -	{ XK_comma,    True,    "jpegtran -rotate 270 -copy all -outfile # #" }, -	{ XK_period,   True,    "jpegtran -rotate 90 -copy all -outfile # #" }, -	{ XK_less,     True,    "mogrify -rotate -90 #" }, -	{ XK_greater,  True,    "mogrify -rotate +90 #" } +	/* ctrl    key              function           argument      */ +	{ False,   XK_q,            quit,              (arg_t) None }, +	{ False,   XK_r,            reload,            (arg_t) None }, +	{ False,   XK_f,            toggle_fullscreen, (arg_t) None }, +	{ False,   XK_a,            toggle_antialias,  (arg_t) None }, +	{ False,   XK_A,            toggle_alpha,      (arg_t) None }, +	{ False,   XK_Return,       switch_mode,       (arg_t) None }, + +	{ False,   XK_g,            first,             (arg_t) None }, +	{ False,   XK_G,            last,              (arg_t) None }, +	{ False,   XK_n,            navigate,          (arg_t) +1 }, +	{ False,   XK_space,        navigate,          (arg_t) +1 }, +	{ False,   XK_p,            navigate,          (arg_t) -1 }, +	{ False,   XK_BackSpace,    navigate,          (arg_t) -1 }, +	{ False,   XK_bracketright, navigate,          (arg_t) +10 }, +	{ False,   XK_bracketleft,  navigate,          (arg_t) -10 }, + +	{ False,   XK_D,            remove_image,      (arg_t) None }, + +	{ False,   XK_h,            move,              (arg_t) DIR_LEFT }, +	{ False,   XK_Left,         move,              (arg_t) DIR_LEFT }, +	{ False,   XK_j,            move,              (arg_t) DIR_DOWN }, +	{ False,   XK_Down,         move,              (arg_t) DIR_DOWN }, +	{ False,   XK_k,            move,              (arg_t) DIR_UP }, +	{ False,   XK_Up,           move,              (arg_t) DIR_UP }, +	{ False,   XK_l,            move,              (arg_t) DIR_RIGHT }, +	{ False,   XK_Right,        move,              (arg_t) DIR_RIGHT }, + +	{ False,   XK_braceleft,    pan_screen,        (arg_t) DIR_LEFT }, +	{ False,   XK_Next,         pan_screen,        (arg_t) DIR_DOWN }, +	{ False,   XK_Prior,        pan_screen,        (arg_t) DIR_UP }, +	{ False,   XK_braceright,   pan_screen,        (arg_t) DIR_RIGHT }, + +	{ False,   XK_H,            pan_edge,          (arg_t) DIR_LEFT }, +	{ False,   XK_J,            pan_edge,          (arg_t) DIR_DOWN }, +	{ False,   XK_K,            pan_edge,          (arg_t) DIR_UP }, +	{ False,   XK_L,            pan_edge,          (arg_t) DIR_RIGHT }, + +	{ False,   XK_plus,         zoom,              (arg_t) +1 }, +	{ False,   XK_equal,        zoom,              (arg_t) +1 }, +	{ False,   XK_KP_Add,       zoom,              (arg_t) +1 }, +	{ False,   XK_minus,        zoom,              (arg_t) -1 }, +	{ False,   XK_KP_Subtract,  zoom,              (arg_t) -1 }, +	{ False,   XK_0,            zoom,              (arg_t) None }, +	{ False,   XK_KP_0,         zoom,              (arg_t) None }, +	{ False,   XK_w,            fit_to_win,        (arg_t) None }, +	{ False,   XK_W,            fit_to_img,        (arg_t) None }, + +	{ False,   XK_less,         rotate,            (arg_t) DIR_LEFT }, +	{ False,   XK_greater,      rotate,            (arg_t) DIR_RIGHT }, + +	                            /* open the current image with given program:  */ +	{ True,    XK_g,            open_with,         (arg_t) "gimp" }, + +	                            /* run shell command line on the current file, +	                             * '#' is replaced by filename:                */ +	{ True,    XK_less,         run_command,       (arg_t) "mogrify -rotate -90 #" }, +	{ True,    XK_greater,      run_command,       (arg_t) "mogrify -rotate +90 #" }, +	{ True,    XK_comma,        run_command,       (arg_t) "jpegtran -rotate 270 -copy all -outfile # #" }, +	{ True,    XK_period,       run_command,       (arg_t) "jpegtran -rotate 90 -copy all -outfile # #" },  };  /* mouse button mappings for image mode:                       */  static const button_t buttons[] = { -	/* modifier     button       function    argument            */ -	{ None,         Button1,     navigate,   +1 }, -	{ None,         Button3,     navigate,   -1 }, -	{ None,         Button2,     drag,       None }, -	{ None,         Button4,     move,       DIR_UP }, -	{ None,         Button5,     move,       DIR_DOWN }, -	{ ShiftMask,    Button4,     move,       DIR_LEFT }, -	{ ShiftMask,    Button5,     move,       DIR_RIGHT }, -	{ ControlMask,  Button4,     zoom,       +1 }, -	{ ControlMask,  Button5,     zoom,       -1 }, +	/* ctrl    shift    button       function      argument      */ +	{ False,   False,   Button1,     navigate,     (arg_t) +1 }, +	{ False,   False,   Button3,     navigate,     (arg_t) -1 }, +	{ False,   False,   Button2,     drag,         (arg_t) None }, +	{ False,   False,   Button4,     move,         (arg_t) DIR_UP }, +	{ False,   False,   Button5,     move,         (arg_t) DIR_DOWN }, +	{ False,   True,    Button4,     move,         (arg_t) DIR_LEFT }, +	{ False,   True,    Button5,     move,         (arg_t) DIR_RIGHT }, +	{ True,    False,   Button4,     zoom,         (arg_t) +1 }, +	{ True,    False,   Button5,     zoom,         (arg_t) -1 },  };  #endif @@ -58,62 +58,6 @@ extern int filecnt, fileidx;  int timo_cursor;  int timo_redraw; -int run_command(const char *cline, Bool reload) { -	int fncnt, fnlen; -	char *cn, *cmdline; -	const char *co, *fname; -	pid_t pid; -	int ret, status; - -	if (!cline || !*cline) -		return 0; - -	fncnt = 0; -	co = cline - 1; -	while ((co = strchr(co + 1, '#'))) -		fncnt++; - -	if (!fncnt) -		return 0; - -	ret = 0; -	fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; -	fnlen = strlen(fname); -	cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) * -	                                sizeof(char)); - -	/* replace all '#' with filename */ -	for (co = cline; *co; co++) { -		if (*co == '#') { -			*cn++ = '"'; -			strcpy(cn, fname); -			cn += fnlen; -			*cn++ = '"'; -		} else { -			*cn++ = *co; -		} -	} -	*cn = '\0'; - -	if ((pid = fork()) == 0) { -		execlp("/bin/sh", "/bin/sh", "-c", cmdline, NULL); -		warn("could not exec: /bin/sh"); -		exit(1); -	} else if (pid < 0) { -		warn("could not fork. command line was: %s", cmdline); -	} else if (reload) { -		waitpid(pid, &status, 0); -		if (WIFEXITED(status) && WEXITSTATUS(status) == 0) -			ret = 1; -		else -			warn("child exited with non-zero return value: %d. command line was: %s", -			     WEXITSTATUS(status), cmdline); -	} -	 -	free(cmdline); -	return ret; -} -  void redraw() {  	if (mode == MODE_NORMAL) {  		img_render(&img, &win); @@ -128,6 +72,15 @@ void redraw() {  	timo_redraw = 0;  } +Bool keymask(const keymap_t *k, unsigned int state) { +	return (k->ctrl ? ControlMask : 0) == (state & ControlMask); +} + +Bool buttonmask(const button_t *b, unsigned int state) { +	return ((b->ctrl ? ControlMask : 0) | (b->shift ? ShiftMask : 0)) == +	       (state & (ControlMask | ShiftMask)); +} +  void on_keypress(XKeyEvent *kev) {  	int i;  	KeySym ksym; @@ -138,38 +91,9 @@ void on_keypress(XKeyEvent *kev) {  	XLookupString(kev, &key, 1, &ksym, NULL); -	if (EXT_COMMANDS && (CLEANMASK(kev->state) & ControlMask)) { -		for (i = 0; i < LEN(commands); i++) { -			if (commands[i].ksym == ksym) { -				win_set_cursor(&win, CURSOR_WATCH); -				if (run_command(commands[i].cmdline, commands[i].reload)) { -					if (mode == MODE_NORMAL) { -						if (fileidx < tns.cnt) -							tns_load(&tns, fileidx, filenames[fileidx], 1); -						img_close(&img, 1); -						load_image(fileidx); -					} else { -						if (!tns_load(&tns, tns.sel, filenames[tns.sel], 0)) { -							remove_file(tns.sel, 0); -							tns.dirty = 1; -							if (tns.sel >= tns.cnt) -								tns.sel = tns.cnt - 1; -						} -					} -					redraw(); -				} -				if (mode == MODE_THUMBS) -					win_set_cursor(&win, CURSOR_ARROW); -				else if (!timo_cursor) -					win_set_cursor(&win, CURSOR_NONE); -				return; -			} -		} -	} -  	for (i = 0; i < LEN(keys); i++) { -		if (ksym == keys[i].ksym && keys[i].handler) { -			if (keys[i].handler(keys[i].arg)) +		if (keymask(&keys[i], kev->state) && ksym == keys[i].ksym) { +			if (keys[i].handler && keys[i].handler(keys[i].arg))  				redraw();  			return;  		} @@ -187,10 +111,10 @@ void on_buttonpress(XButtonEvent *bev) {  		timo_cursor = TO_CURSOR_HIDE;  		for (i = 0; i < LEN(buttons); i++) { -			if (CLEANMASK(bev->state) == CLEANMASK(buttons[i].mod) && -			    bev->button == buttons[i].button && buttons[i].handler) +			if (buttonmask(&buttons[i], bev->state) && +			    bev->button == buttons[i].button)  			{ -				if (buttons[i].handler(buttons[i].arg)) +				if (buttons[i].handler && buttons[i].handler(buttons[i].arg))  					redraw();  				return;  			} @@ -379,7 +303,9 @@ int switch_mode(arg_t a) {  	return 1;  } -int navigate(arg_t n) { +int navigate(arg_t a) { +	int n = (int) a; +  	if (mode == MODE_NORMAL) {  		n += fileidx;  		if (n < 0) @@ -437,21 +363,27 @@ int remove_image(arg_t a) {  	}  } -int move(arg_t dir) { +int move(arg_t a) { +	direction_t dir = (direction_t) a; +  	if (mode == MODE_NORMAL)  		return img_pan(&img, &win, dir, 0);  	else  		return tns_move_selection(&tns, &win, dir);  } -int pan_screen(arg_t dir) { +int pan_screen(arg_t a) { +	direction_t dir = (direction_t) a; +  	if (mode == MODE_NORMAL)  		return img_pan(&img, &win, dir, 1);  	else  		return 0;  } -int pan_edge(arg_t dir) { +int pan_edge(arg_t a) { +	direction_t dir = (direction_t) a; +  	if (mode == MODE_NORMAL)  		return img_pan_edge(&img, &win, dir);  	else @@ -459,7 +391,7 @@ int pan_edge(arg_t dir) {  }  /* Xlib helper function for drag() */ -Bool ismnotify(Display *d, XEvent *e, XPointer a) { +Bool is_motionnotify(Display *d, XEvent *e, XPointer a) {  	return e != NULL && e->type == MotionNotify;  } @@ -498,7 +430,7 @@ int drag(arg_t a) {  				break;  		}  		if (dragging) -			next = XCheckIfEvent(win.env.dpy, &e, ismnotify, None); +			next = XCheckIfEvent(win.env.dpy, &e, is_motionnotify, None);  		if ((!dragging || !next) && (dx != 0 || dy != 0)) {  			if (img_move(&img, &win, dx, dy))  				img_render(&img, &win); @@ -513,7 +445,9 @@ int drag(arg_t a) {  	return 0;  } -int rotate(arg_t dir) { +int rotate(arg_t a) { +	direction_t dir = (direction_t) a; +  	if (mode == MODE_NORMAL) {  		if (dir == DIR_LEFT) {  			img_rotate_left(&img, &win); @@ -526,7 +460,9 @@ int rotate(arg_t dir) {  	return 0;  } -int zoom(arg_t scale) { +int zoom(arg_t a) { +	int scale = (int) a; +  	if (mode != MODE_NORMAL)  		return 0;  	if (scale > 0) @@ -537,7 +473,9 @@ int zoom(arg_t scale) {  		return img_zoom(&img, &win, 1.0);  } -int fit_to_win(arg_t ret) { +int fit_to_win(arg_t a) { +	int ret; +  	if (mode == MODE_NORMAL) {  		if ((ret = img_fit_win(&img, &win)))  			img_center(&img, &win); @@ -547,8 +485,8 @@ int fit_to_win(arg_t ret) {  	}  } -int fit_to_img(arg_t ret) { -	int x, y; +int fit_to_img(arg_t a) { +	int ret, x, y;  	unsigned int w, h;  	if (mode == MODE_NORMAL) { @@ -565,3 +503,96 @@ int fit_to_img(arg_t ret) {  		return 0;  	}  } + +int open_with(arg_t a) { +	const char *prog = (const char*) a; +	pid_t pid; + +	if (!prog || !*prog) +		return 0; + +	if((pid = fork()) == 0) { +		execlp(prog, prog, +		       filenames[mode == MODE_NORMAL ? fileidx : tns.sel], NULL); +		warn("could not exec: %s", prog); +		exit(1); +	} else if (pid < 0) { +		warn("could not for. program was: %s", prog); +	} +	 +	return 0; +} + +int run_command(arg_t a) { +	const char *cline = (const char*) a; +	char *cn, *cmdline; +	const char *co, *fname; +	int fncnt, fnlen, status; +	pid_t pid; + +	if (!cline || !*cline) +		return 0; + +	/* build command line: */ +	fncnt = 0; +	co = cline - 1; +	while ((co = strchr(co + 1, '#'))) +		fncnt++; +	if (!fncnt) +		return 0; +	fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel]; +	fnlen = strlen(fname); +	cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) * +	                                sizeof(char)); +	/* replace all '#' with filename: */ +	for (co = cline; *co; co++) { +		if (*co == '#') { +			*cn++ = '"'; +			strcpy(cn, fname); +			cn += fnlen; +			*cn++ = '"'; +		} else { +			*cn++ = *co; +		} +	} +	*cn = '\0'; + +	win_set_cursor(&win, CURSOR_WATCH); + +	if ((pid = fork()) == 0) { +		execl("/bin/sh", "/bin/sh", "-c", cmdline, NULL); +		warn("could not exec: /bin/sh"); +		exit(1); +	} else if (pid < 0) { +		warn("could not fork. command line was: %s", cmdline); +		goto end; +	} + +	waitpid(pid, &status, 0); +	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) +		warn("child exited with non-zero return value: %d. command line was: %s", +		     WEXITSTATUS(status), cmdline); +	 +	if (mode == MODE_NORMAL) { +		if (fileidx < tns.cnt) +			tns_load(&tns, fileidx, filenames[fileidx], 1); +		img_close(&img, 1); +		load_image(fileidx); +	} else { +		if (!tns_load(&tns, tns.sel, filenames[tns.sel], 0)) { +			remove_file(tns.sel, 0); +			tns.dirty = 1; +			if (tns.sel >= tns.cnt) +				tns.sel = tns.cnt - 1; +		} +	} + +end: +	if (mode == MODE_THUMBS) +		win_set_cursor(&win, CURSOR_ARROW); +	/* else: cursor is reset in redraw() */ + +	free(cmdline); + +	return 1; +} @@ -21,22 +21,18 @@  #include <X11/Xlib.h> -typedef struct { -	KeySym ksym; -	Bool reload; -	const char *cmdline; -} command_t; - -typedef int arg_t; +typedef void* arg_t;  typedef struct { +	Bool ctrl;  	KeySym ksym;  	int (*handler)(arg_t);  	arg_t arg;  } keymap_t;  typedef struct { -	unsigned int mod; +	Bool ctrl; +	Bool shift;  	unsigned int button;  	int (*handler)(arg_t);  	arg_t arg; @@ -63,5 +59,7 @@ int rotate(arg_t);  int zoom(arg_t);  int fit_to_win(arg_t);  int fit_to_img(arg_t); +int open_with(arg_t); +int run_command(arg_t);  #endif /* EVENTS_H */  | 
