diff options
author | Bert <ber.t@gmx.com> | 2011-08-19 15:02:10 +0200 |
---|---|---|
committer | Bert <ber.t@gmx.com> | 2011-08-19 15:02:10 +0200 |
commit | 1d749382f00bb0bfdb900b6ddb0bb8b3743b99d0 (patch) | |
tree | ae38c4e106c771229719c6b4aa87eb2fffbbbc35 /commands.c | |
parent | 1d7849efc1fe85d20b8aa4916e75cb3eb658dba9 (diff) |
Put event handling back into main.c; events -> commands
Diffstat (limited to 'commands.c')
-rw-r--r-- | commands.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/commands.c b/commands.c new file mode 100644 index 0000000..7dbd019 --- /dev/null +++ b/commands.c @@ -0,0 +1,400 @@ +/* sxiv: commands.c + * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301, USA. + */ + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/wait.h> + +#include "commands.h" +#include "image.h" +#include "thumbs.h" +#include "types.h" +#include "util.h" + +void cleanup(); +void remove_file(int, unsigned char); +void load_image(int); + +extern appmode_t mode; +extern img_t img; +extern tns_t tns; +extern win_t win; + +extern fileinfo_t *files; +extern int filecnt, fileidx; + +extern int timo_cursor; +extern int timo_redraw; + +int it_quit(arg_t a) { + cleanup(); + exit(0); +} + +int it_switch_mode(arg_t a) { + if (mode == MODE_IMAGE) { + if (!tns.thumbs) + tns_init(&tns, filecnt); + img_close(&img, 0); + win_set_cursor(&win, CURSOR_ARROW); + timo_cursor = 0; + tns.sel = fileidx; + tns.dirty = 1; + mode = MODE_THUMB; + } else { + timo_cursor = TO_CURSOR_HIDE; + load_image(tns.sel); + mode = MODE_IMAGE; + } + return 1; +} + +int it_toggle_fullscreen(arg_t a) { + win_toggle_fullscreen(&win); + if (mode == MODE_IMAGE) + img.checkpan = 1; + else + tns.dirty = 1; + timo_redraw = TO_WIN_RESIZE; + return 0; +} + +int it_reload_image(arg_t a) { + if (mode == MODE_IMAGE) { + load_image(fileidx); + } else if (!tns_load(&tns, tns.sel, &files[tns.sel], True, False)) { + remove_file(tns.sel, 0); + tns.dirty = 1; + if (tns.sel >= tns.cnt) + tns.sel = tns.cnt - 1; + } + return 1; +} + +int it_remove_image(arg_t a) { + if (mode == MODE_IMAGE) { + remove_file(fileidx, 1); + load_image(fileidx >= filecnt ? filecnt - 1 : fileidx); + return 1; + } else if (tns.sel < tns.cnt) { + remove_file(tns.sel, 1); + tns.dirty = 1; + if (tns.sel >= tns.cnt) + tns.sel = tns.cnt - 1; + return 1; + } else { + return 0; + } +} + +int i_navigate(arg_t a) { + int n = (int) a; + + if (mode == MODE_IMAGE) { + n += fileidx; + if (n < 0) + n = 0; + if (n >= filecnt) + n = filecnt - 1; + + if (n != fileidx) { + load_image(n); + return 1; + } + } + return 0; +} + +int it_first(arg_t a) { + if (mode == MODE_IMAGE && fileidx != 0) { + load_image(0); + return 1; + } else if (mode == MODE_THUMB && tns.sel != 0) { + tns.sel = 0; + tns.dirty = 1; + return 1; + } else { + return 0; + } +} + +int it_last(arg_t a) { + if (mode == MODE_IMAGE && fileidx != filecnt - 1) { + load_image(filecnt - 1); + return 1; + } else if (mode == MODE_THUMB && tns.sel != tns.cnt - 1) { + tns.sel = tns.cnt - 1; + tns.dirty = 1; + return 1; + } else { + return 0; + } +} + +int it_move(arg_t a) { + direction_t dir = (direction_t) a; + + if (mode == MODE_IMAGE) + return img_pan(&img, &win, dir, 0); + else + return tns_move_selection(&tns, &win, dir); +} + +int i_pan_screen(arg_t a) { + direction_t dir = (direction_t) a; + + if (mode == MODE_IMAGE) + return img_pan(&img, &win, dir, 1); + else + return 0; +} + +int i_pan_edge(arg_t a) { + direction_t dir = (direction_t) a; + + if (mode == MODE_IMAGE) + return img_pan_edge(&img, &win, dir); + else + return 0; +} + +/* Xlib helper function for i_drag() */ +Bool is_motionnotify(Display *d, XEvent *e, XPointer a) { + return e != NULL && e->type == MotionNotify; +} + +int i_drag(arg_t a) { + int dx = 0, dy = 0, i, ox, oy, x, y; + unsigned int ui; + Bool dragging = True, next = False; + XEvent e; + Window w; + + if (mode != MODE_IMAGE) + return 0; + if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &ox, &oy, &ui)) + return 0; + + win_set_cursor(&win, CURSOR_HAND); + + while (dragging) { + if (!next) + XMaskEvent(win.env.dpy, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e); + switch (e.type) { + case ButtonPress: + case ButtonRelease: + dragging = False; + break; + case MotionNotify: + x = e.xmotion.x; + y = e.xmotion.y; + if (x >= 0 && x <= win.w && y >= 0 && y <= win.h) { + dx += x - ox; + dy += y - oy; + } + ox = x; + oy = y; + break; + } + if (dragging) + 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); + dx = dy = 0; + } + } + + win_set_cursor(&win, CURSOR_ARROW); + timo_cursor = TO_CURSOR_HIDE; + timo_redraw = 0; + + return 0; +} + +int i_zoom(arg_t a) { + int scale = (int) a; + + if (mode != MODE_IMAGE) + return 0; + if (scale > 0) + return img_zoom_in(&img, &win); + else if (scale < 0) + return img_zoom_out(&img, &win); + else + return img_zoom(&img, &win, 1.0); +} + +int i_fit_to_win(arg_t a) { + int ret; + + if (mode == MODE_IMAGE) { + if ((ret = img_fit_win(&img, &win))) + img_center(&img, &win); + return ret; + } else { + return 0; + } +} + +int i_fit_to_img(arg_t a) { + int ret, x, y; + unsigned int w, h; + + if (mode == MODE_IMAGE) { + x = MAX(0, win.x + img.x); + y = MAX(0, win.y + img.y); + w = img.w * img.zoom; + h = img.h * img.zoom; + if ((ret = win_moveresize(&win, x, y, w, h))) { + img.x = x - win.x; + img.y = y - win.y; + } + return ret; + } else { + return 0; + } +} + +int i_rotate(arg_t a) { + direction_t dir = (direction_t) a; + + if (mode == MODE_IMAGE) { + if (dir == DIR_LEFT) { + img_rotate_left(&img, &win); + return 1; + } else if (dir == DIR_RIGHT) { + img_rotate_right(&img, &win); + return 1; + } + } + return 0; +} + +int i_toggle_antialias(arg_t a) { + if (mode == MODE_IMAGE) { + img_toggle_antialias(&img); + return 1; + } else { + return 0; + } +} + +int i_toggle_alpha(arg_t a) { + if (mode == MODE_IMAGE) { + img.alpha ^= 1; + return 1; + } else { + return 0; + } +} + +int it_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, + files[mode == MODE_IMAGE ? fileidx : tns.sel].path, NULL); + warn("could not exec: %s", prog); + exit(1); + } else if (pid < 0) { + warn("could not for. program was: %s", prog); + } + + return 0; +} + +int it_shell_cmd(arg_t a) { + const char *cline = (const char*) a; + char *cn, *cmdline; + const char *co, *fpath; + int fpcnt, fplen, status; + pid_t pid; + + if (!cline || !*cline) + return 0; + + /* build command line: */ + fpcnt = 0; + co = cline - 1; + while ((co = strchr(co + 1, '#'))) + fpcnt++; + if (!fpcnt) + return 0; + fpath = files[mode == MODE_IMAGE ? fileidx : tns.sel].path; + fplen = strlen(fpath); + cn = cmdline = (char*) s_malloc((strlen(cline) + fpcnt * (fplen + 2)) * + sizeof(char)); + /* replace all '#' with filename: */ + for (co = cline; *co; co++) { + if (*co == '#') { + *cn++ = '"'; + strcpy(cn, fpath); + cn += fplen; + *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_IMAGE) { + if (fileidx < tns.cnt) + tns_load(&tns, fileidx, &files[fileidx], False, True); + img_close(&img, 1); + load_image(fileidx); + } else { + if (!tns_load(&tns, tns.sel, &files[tns.sel], True, False)) { + remove_file(tns.sel, 0); + tns.dirty = 1; + if (tns.sel >= tns.cnt) + tns.sel = tns.cnt - 1; + } + } + +end: + if (mode == MODE_THUMB) + win_set_cursor(&win, CURSOR_ARROW); + /* else: cursor gets reset in redraw() */ + + free(cmdline); + + return 1; +} |