Krolyxon
Commit d86c95d

Branches

Refs →

nsxivd86c95d

Made run_command() a normal key/button handler

Author
Bert
Date
2011-08-12 17:14 +0200
Parent
75e3693
Commit
d86c95d7951236199d9b11314e262d8ed71ad449

+208 −184

3 files changed

  1. M config.h +70 −75
  2. M events.c +132 −101
  3. M events.h +6 −8
M config.h View
@@ -1,9 +1,3 @@
1−#ifdef _GENERAL_CONFIG
2−
3−/* enable external commands (defined below)? 0 = off, 1 = on: */
4−enum { EXT_COMMANDS = 0 };
5−
6−#endif
71 #ifdef _WINDOW_CONFIG
82
93 /* default window dimensions (overwritten via -g option): */
@@ -42,79 +36,80 @@ enum { THUMB_SIZE = 60 };
4236
4337 /* keyboard mappings for image and thumbnail mode: */
4438 static const keymap_t keys[] = {
45− /* key function argument */
46− { XK_q, quit, None },
47− { XK_r, reload, None },
48− { XK_f, toggle_fullscreen, None },
49− { XK_a, toggle_antialias, None },
50− { XK_A, toggle_alpha, None },
51− { XK_Return, switch_mode, None },
52−
53− { XK_g, first, None },
54− { XK_G, last, None },
55− { XK_n, navigate, +1 },
56− { XK_space, navigate, +1 },
57− { XK_p, navigate, -1 },
58− { XK_BackSpace, navigate, -1 },
59− { XK_bracketright, navigate, +10 },
60− { XK_bracketleft, navigate, -10 },
61−
62− { XK_D, remove_image, None },
63−
64− { XK_h, move, DIR_LEFT },
65− { XK_Left, move, DIR_LEFT },
66− { XK_j, move, DIR_DOWN },
67− { XK_Down, move, DIR_DOWN },
68− { XK_k, move, DIR_UP },
69− { XK_Up, move, DIR_UP },
70− { XK_l, move, DIR_RIGHT },
71− { XK_Right, move, DIR_RIGHT },
72−
73− { XK_braceleft, pan_screen, DIR_LEFT },
74− { XK_Next, pan_screen, DIR_DOWN },
75− { XK_Prior, pan_screen, DIR_UP },
76− { XK_braceright, pan_screen, DIR_RIGHT },
77−
78− { XK_H, pan_edge, DIR_LEFT },
79− { XK_J, pan_edge, DIR_DOWN },
80− { XK_K, pan_edge, DIR_UP },
81− { XK_L, pan_edge, DIR_RIGHT },
82−
83− { XK_plus, zoom, +1 },
84− { XK_equal, zoom, +1 },
85− { XK_KP_Add, zoom, +1 },
86− { XK_minus, zoom, -1 },
87− { XK_KP_Subtract, zoom, -1 },
88− { XK_0, zoom, 0 },
89− { XK_KP_0, zoom, 0 },
90− { XK_w, fit_to_win, None },
91− { XK_W, fit_to_img, None },
92−
93− { XK_less, rotate, DIR_LEFT },
94− { XK_greater, rotate, DIR_RIGHT },
95−};
96−
97−/* external commands and corresponding key mappings: */
98−static const command_t commands[] = {
99− /* ctrl-... reload? command, '#' is replaced by filename */
100− { XK_comma, True, "jpegtran -rotate 270 -copy all -outfile # #" },
101− { XK_period, True, "jpegtran -rotate 90 -copy all -outfile # #" },
102− { XK_less, True, "mogrify -rotate -90 #" },
103− { XK_greater, True, "mogrify -rotate +90 #" }
39+ /* ctrl key function argument */
40+ { False, XK_q, quit, (arg_t) None },
41+ { False, XK_r, reload, (arg_t) None },
42+ { False, XK_f, toggle_fullscreen, (arg_t) None },
43+ { False, XK_a, toggle_antialias, (arg_t) None },
44+ { False, XK_A, toggle_alpha, (arg_t) None },
45+ { False, XK_Return, switch_mode, (arg_t) None },
46+
47+ { False, XK_g, first, (arg_t) None },
48+ { False, XK_G, last, (arg_t) None },
49+ { False, XK_n, navigate, (arg_t) +1 },
50+ { False, XK_space, navigate, (arg_t) +1 },
51+ { False, XK_p, navigate, (arg_t) -1 },
52+ { False, XK_BackSpace, navigate, (arg_t) -1 },
53+ { False, XK_bracketright, navigate, (arg_t) +10 },
54+ { False, XK_bracketleft, navigate, (arg_t) -10 },
55+
56+ { False, XK_D, remove_image, (arg_t) None },
57+
58+ { False, XK_h, move, (arg_t) DIR_LEFT },
59+ { False, XK_Left, move, (arg_t) DIR_LEFT },
60+ { False, XK_j, move, (arg_t) DIR_DOWN },
61+ { False, XK_Down, move, (arg_t) DIR_DOWN },
62+ { False, XK_k, move, (arg_t) DIR_UP },
63+ { False, XK_Up, move, (arg_t) DIR_UP },
64+ { False, XK_l, move, (arg_t) DIR_RIGHT },
65+ { False, XK_Right, move, (arg_t) DIR_RIGHT },
66+
67+ { False, XK_braceleft, pan_screen, (arg_t) DIR_LEFT },
68+ { False, XK_Next, pan_screen, (arg_t) DIR_DOWN },
69+ { False, XK_Prior, pan_screen, (arg_t) DIR_UP },
70+ { False, XK_braceright, pan_screen, (arg_t) DIR_RIGHT },
71+
72+ { False, XK_H, pan_edge, (arg_t) DIR_LEFT },
73+ { False, XK_J, pan_edge, (arg_t) DIR_DOWN },
74+ { False, XK_K, pan_edge, (arg_t) DIR_UP },
75+ { False, XK_L, pan_edge, (arg_t) DIR_RIGHT },
76+
77+ { False, XK_plus, zoom, (arg_t) +1 },
78+ { False, XK_equal, zoom, (arg_t) +1 },
79+ { False, XK_KP_Add, zoom, (arg_t) +1 },
80+ { False, XK_minus, zoom, (arg_t) -1 },
81+ { False, XK_KP_Subtract, zoom, (arg_t) -1 },
82+ { False, XK_0, zoom, (arg_t) None },
83+ { False, XK_KP_0, zoom, (arg_t) None },
84+ { False, XK_w, fit_to_win, (arg_t) None },
85+ { False, XK_W, fit_to_img, (arg_t) None },
86+
87+ { False, XK_less, rotate, (arg_t) DIR_LEFT },
88+ { False, XK_greater, rotate, (arg_t) DIR_RIGHT },
89+
90+ /* open the current image with given program: */
91+ { True, XK_g, open_with, (arg_t) "gimp" },
92+
93+ /* run shell command line on the current file,
94+ * '#' is replaced by filename: */
95+ { True, XK_less, run_command, (arg_t) "mogrify -rotate -90 #" },
96+ { True, XK_greater, run_command, (arg_t) "mogrify -rotate +90 #" },
97+ { True, XK_comma, run_command, (arg_t) "jpegtran -rotate 270 -copy all -outfile # #" },
98+ { True, XK_period, run_command, (arg_t) "jpegtran -rotate 90 -copy all -outfile # #" },
10499 };
105100
106101 /* mouse button mappings for image mode: */
107102 static const button_t buttons[] = {
108− /* modifier button function argument */
109− { None, Button1, navigate, +1 },
110− { None, Button3, navigate, -1 },
111− { None, Button2, drag, None },
112− { None, Button4, move, DIR_UP },
113− { None, Button5, move, DIR_DOWN },
114− { ShiftMask, Button4, move, DIR_LEFT },
115− { ShiftMask, Button5, move, DIR_RIGHT },
116− { ControlMask, Button4, zoom, +1 },
117− { ControlMask, Button5, zoom, -1 },
103+ /* ctrl shift button function argument */
104+ { False, False, Button1, navigate, (arg_t) +1 },
105+ { False, False, Button3, navigate, (arg_t) -1 },
106+ { False, False, Button2, drag, (arg_t) None },
107+ { False, False, Button4, move, (arg_t) DIR_UP },
108+ { False, False, Button5, move, (arg_t) DIR_DOWN },
109+ { False, True, Button4, move, (arg_t) DIR_LEFT },
110+ { False, True, Button5, move, (arg_t) DIR_RIGHT },
111+ { True, False, Button4, zoom, (arg_t) +1 },
112+ { True, False, Button5, zoom, (arg_t) -1 },
118113 };
119114
120115 #endif
M events.c View
@@ -58,62 +58,6 @@ extern int filecnt, fileidx;
5858 int timo_cursor;
5959 int timo_redraw;
6060
61−int run_command(const char *cline, Bool reload) {
62− int fncnt, fnlen;
63− char *cn, *cmdline;
64− const char *co, *fname;
65− pid_t pid;
66− int ret, status;
67−
68− if (!cline || !*cline)
69− return 0;
70−
71− fncnt = 0;
72− co = cline - 1;
73− while ((co = strchr(co + 1, '#')))
74− fncnt++;
75−
76− if (!fncnt)
77− return 0;
78−
79− ret = 0;
80− fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
81− fnlen = strlen(fname);
82− cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) *
83− sizeof(char));
84−
85− /* replace all '#' with filename */
86− for (co = cline; *co; co++) {
87− if (*co == '#') {
88− *cn++ = '"';
89− strcpy(cn, fname);
90− cn += fnlen;
91− *cn++ = '"';
92− } else {
93− *cn++ = *co;
94− }
95− }
96− *cn = '\0';
97−
98− if ((pid = fork()) == 0) {
99− execlp("/bin/sh", "/bin/sh", "-c", cmdline, NULL);
100− warn("could not exec: /bin/sh");
101− exit(1);
102− } else if (pid < 0) {
103− warn("could not fork. command line was: %s", cmdline);
104− } else if (reload) {
105− waitpid(pid, &status, 0);
106− if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
107− ret = 1;
108− else
109− warn("child exited with non-zero return value: %d. command line was: %s",
110− WEXITSTATUS(status), cmdline);
111− }
112−
113− free(cmdline);
114− return ret;
115−}
116−
11761 void redraw() {
11862 if (mode == MODE_NORMAL) {
11963 img_render(&img, &win);
@@ -128,6 +72,15 @@ void redraw() {
12872 timo_redraw = 0;
12973 }
13074
75+Bool keymask(const keymap_t *k, unsigned int state) {
76+ return (k->ctrl ? ControlMask : 0) == (state & ControlMask);
77+}
78+
79+Bool buttonmask(const button_t *b, unsigned int state) {
80+ return ((b->ctrl ? ControlMask : 0) | (b->shift ? ShiftMask : 0)) ==
81+ (state & (ControlMask | ShiftMask));
82+}
83+
13184 void on_keypress(XKeyEvent *kev) {
13285 int i;
13386 KeySym ksym;
@@ -138,38 +91,9 @@ void on_keypress(XKeyEvent *kev) {
13891
13992 XLookupString(kev, &key, 1, &ksym, NULL);
14093
141− if (EXT_COMMANDS && (CLEANMASK(kev->state) & ControlMask)) {
142− for (i = 0; i < LEN(commands); i++) {
143− if (commands[i].ksym == ksym) {
144− win_set_cursor(&win, CURSOR_WATCH);
145− if (run_command(commands[i].cmdline, commands[i].reload)) {
146− if (mode == MODE_NORMAL) {
147− if (fileidx < tns.cnt)
148− tns_load(&tns, fileidx, filenames[fileidx], 1);
149− img_close(&img, 1);
150− load_image(fileidx);
151− } else {
152− if (!tns_load(&tns, tns.sel, filenames[tns.sel], 0)) {
153− remove_file(tns.sel, 0);
154− tns.dirty = 1;
155− if (tns.sel >= tns.cnt)
156− tns.sel = tns.cnt - 1;
157− }
158− }
159− redraw();
160− }
161− if (mode == MODE_THUMBS)
162− win_set_cursor(&win, CURSOR_ARROW);
163− else if (!timo_cursor)
164− win_set_cursor(&win, CURSOR_NONE);
165− return;
166− }
167− }
168− }
169−
17094 for (i = 0; i < LEN(keys); i++) {
171− if (ksym == keys[i].ksym && keys[i].handler) {
172− if (keys[i].handler(keys[i].arg))
95+ if (keymask(&keys[i], kev->state) && ksym == keys[i].ksym) {
96+ if (keys[i].handler && keys[i].handler(keys[i].arg))
17397 redraw();
17498 return;
17599 }
@@ -187,10 +111,10 @@ void on_buttonpress(XButtonEvent *bev) {
187111 timo_cursor = TO_CURSOR_HIDE;
188112
189113 for (i = 0; i < LEN(buttons); i++) {
190− if (CLEANMASK(bev->state) == CLEANMASK(buttons[i].mod) &&
191− bev->button == buttons[i].button && buttons[i].handler)
114+ if (buttonmask(&buttons[i], bev->state) &&
115+ bev->button == buttons[i].button)
192116 {
193− if (buttons[i].handler(buttons[i].arg))
117+ if (buttons[i].handler && buttons[i].handler(buttons[i].arg))
194118 redraw();
195119 return;
196120 }
@@ -379,7 +303,9 @@ int switch_mode(arg_t a) {
379303 return 1;
380304 }
381305
382−int navigate(arg_t n) {
306+int navigate(arg_t a) {
307+ int n = (int) a;
308+
383309 if (mode == MODE_NORMAL) {
384310 n += fileidx;
385311 if (n < 0)
@@ -437,21 +363,27 @@ int remove_image(arg_t a) {
437363 }
438364 }
439365
440−int move(arg_t dir) {
366+int move(arg_t a) {
367+ direction_t dir = (direction_t) a;
368+
441369 if (mode == MODE_NORMAL)
442370 return img_pan(&img, &win, dir, 0);
443371 else
444372 return tns_move_selection(&tns, &win, dir);
445373 }
446374
447−int pan_screen(arg_t dir) {
375+int pan_screen(arg_t a) {
376+ direction_t dir = (direction_t) a;
377+
448378 if (mode == MODE_NORMAL)
449379 return img_pan(&img, &win, dir, 1);
450380 else
451381 return 0;
452382 }
453383
454−int pan_edge(arg_t dir) {
384+int pan_edge(arg_t a) {
385+ direction_t dir = (direction_t) a;
386+
455387 if (mode == MODE_NORMAL)
456388 return img_pan_edge(&img, &win, dir);
457389 else
@@ -459,7 +391,7 @@ int pan_edge(arg_t dir) {
459391 }
460392
461393 /* Xlib helper function for drag() */
462−Bool ismnotify(Display *d, XEvent *e, XPointer a) {
394+Bool is_motionnotify(Display *d, XEvent *e, XPointer a) {
463395 return e != NULL && e->type == MotionNotify;
464396 }
465397
@@ -498,7 +430,7 @@ int drag(arg_t a) {
498430 break;
499431 }
500432 if (dragging)
501− next = XCheckIfEvent(win.env.dpy, &e, ismnotify, None);
433+ next = XCheckIfEvent(win.env.dpy, &e, is_motionnotify, None);
502434 if ((!dragging || !next) && (dx != 0 || dy != 0)) {
503435 if (img_move(&img, &win, dx, dy))
504436 img_render(&img, &win);
@@ -513,7 +445,9 @@ int drag(arg_t a) {
513445 return 0;
514446 }
515447
516−int rotate(arg_t dir) {
448+int rotate(arg_t a) {
449+ direction_t dir = (direction_t) a;
450+
517451 if (mode == MODE_NORMAL) {
518452 if (dir == DIR_LEFT) {
519453 img_rotate_left(&img, &win);
@@ -526,7 +460,9 @@ int rotate(arg_t dir) {
526460 return 0;
527461 }
528462
529−int zoom(arg_t scale) {
463+int zoom(arg_t a) {
464+ int scale = (int) a;
465+
530466 if (mode != MODE_NORMAL)
531467 return 0;
532468 if (scale > 0)
@@ -537,7 +473,9 @@ int zoom(arg_t scale) {
537473 return img_zoom(&img, &win, 1.0);
538474 }
539475
540−int fit_to_win(arg_t ret) {
476+int fit_to_win(arg_t a) {
477+ int ret;
478+
541479 if (mode == MODE_NORMAL) {
542480 if ((ret = img_fit_win(&img, &win)))
543481 img_center(&img, &win);
@@ -547,8 +485,8 @@ int fit_to_win(arg_t ret) {
547485 }
548486 }
549487
550−int fit_to_img(arg_t ret) {
551− int x, y;
488+int fit_to_img(arg_t a) {
489+ int ret, x, y;
552490 unsigned int w, h;
553491
554492 if (mode == MODE_NORMAL) {
@@ -565,3 +503,96 @@ int fit_to_img(arg_t ret) {
565503 return 0;
566504 }
567505 }
506+
507+int open_with(arg_t a) {
508+ const char *prog = (const char*) a;
509+ pid_t pid;
510+
511+ if (!prog || !*prog)
512+ return 0;
513+
514+ if((pid = fork()) == 0) {
515+ execlp(prog, prog,
516+ filenames[mode == MODE_NORMAL ? fileidx : tns.sel], NULL);
517+ warn("could not exec: %s", prog);
518+ exit(1);
519+ } else if (pid < 0) {
520+ warn("could not for. program was: %s", prog);
521+ }
522+
523+ return 0;
524+}
525+
526+int run_command(arg_t a) {
527+ const char *cline = (const char*) a;
528+ char *cn, *cmdline;
529+ const char *co, *fname;
530+ int fncnt, fnlen, status;
531+ pid_t pid;
532+
533+ if (!cline || !*cline)
534+ return 0;
535+
536+ /* build command line: */
537+ fncnt = 0;
538+ co = cline - 1;
539+ while ((co = strchr(co + 1, '#')))
540+ fncnt++;
541+ if (!fncnt)
542+ return 0;
543+ fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
544+ fnlen = strlen(fname);
545+ cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) *
546+ sizeof(char));
547+ /* replace all '#' with filename: */
548+ for (co = cline; *co; co++) {
549+ if (*co == '#') {
550+ *cn++ = '"';
551+ strcpy(cn, fname);
552+ cn += fnlen;
553+ *cn++ = '"';
554+ } else {
555+ *cn++ = *co;
556+ }
557+ }
558+ *cn = '\0';
559+
560+ win_set_cursor(&win, CURSOR_WATCH);
561+
562+ if ((pid = fork()) == 0) {
563+ execl("/bin/sh", "/bin/sh", "-c", cmdline, NULL);
564+ warn("could not exec: /bin/sh");
565+ exit(1);
566+ } else if (pid < 0) {
567+ warn("could not fork. command line was: %s", cmdline);
568+ goto end;
569+ }
570+
571+ waitpid(pid, &status, 0);
572+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
573+ warn("child exited with non-zero return value: %d. command line was: %s",
574+ WEXITSTATUS(status), cmdline);
575+
576+ if (mode == MODE_NORMAL) {
577+ if (fileidx < tns.cnt)
578+ tns_load(&tns, fileidx, filenames[fileidx], 1);
579+ img_close(&img, 1);
580+ load_image(fileidx);
581+ } else {
582+ if (!tns_load(&tns, tns.sel, filenames[tns.sel], 0)) {
583+ remove_file(tns.sel, 0);
584+ tns.dirty = 1;
585+ if (tns.sel >= tns.cnt)
586+ tns.sel = tns.cnt - 1;
587+ }
588+ }
589+
590+end:
591+ if (mode == MODE_THUMBS)
592+ win_set_cursor(&win, CURSOR_ARROW);
593+ /* else: cursor is reset in redraw() */
594+
595+ free(cmdline);
596+
597+ return 1;
598+}
M events.h View
@@ -21,22 +21,18 @@
2121
2222 #include <X11/Xlib.h>
2323
24−typedef struct {
25− KeySym ksym;
26− Bool reload;
27− const char *cmdline;
28−} command_t;
29−
30−typedef int arg_t;
24+typedef void* arg_t;
3125
3226 typedef struct {
27+ Bool ctrl;
3328 KeySym ksym;
3429 int (*handler)(arg_t);
3530 arg_t arg;
3631 } keymap_t;
3732
3833 typedef struct {
39− unsigned int mod;
34+ Bool ctrl;
35+ Bool shift;
4036 unsigned int button;
4137 int (*handler)(arg_t);
4238 arg_t arg;
@@ -63,5 +59,7 @@ int rotate(arg_t);
6359 int zoom(arg_t);
6460 int fit_to_win(arg_t);
6561 int fit_to_img(arg_t);
62+int open_with(arg_t);
63+int run_command(arg_t);
6664
6765 #endif /* EVENTS_H */