Krolyxon
Commit 75e3693

Branches

Refs →

nsxiv75e3693

Much better drag()

No more need to pass XEvent* to handler functions
Author
Bert
Date
2011-08-12 12:27 +0200
Parent
2b7192b
Commit
75e36939a1cf3205b56f45ca34802cffb8e140a5

+106 −101

3 files changed

  1. M Makefile +1 −1
  2. M events.c +85 −80
  3. M events.h +20 −20
M Makefile View
@@ -1,6 +1,6 @@
11 all: sxiv
22
3−VERSION = git-20110805
3+VERSION = git-20110812
44
55 CC = gcc
66 DESTDIR =
M events.c View
@@ -38,7 +38,6 @@
3838 /* timeouts in milliseconds: */
3939 enum {
4040 TO_WIN_RESIZE = 75,
41− TO_IMAGE_DRAG = 1,
4241 TO_CURSOR_HIDE = 1500,
4342 TO_THUMBS_LOAD = 200
4443 };
@@ -58,8 +57,6 @@ extern int filecnt, fileidx;
5857
5958 int timo_cursor;
6059 int timo_redraw;
61−unsigned char dragging;
62−int mox, moy;
6360
6461 int run_command(const char *cline, Bool reload) {
6562 int fncnt, fnlen;
@@ -122,7 +119,7 @@ void redraw() {
122119 img_render(&img, &win);
123120 if (timo_cursor)
124121 win_set_cursor(&win, CURSOR_ARROW);
125− else if (!dragging)
122+ else
126123 win_set_cursor(&win, CURSOR_NONE);
127124 } else {
128125 tns_render(&tns, &win);
@@ -131,16 +128,14 @@ void redraw() {
131128 timo_redraw = 0;
132129 }
133130
134−void on_keypress(XEvent *ev) {
131+void on_keypress(XKeyEvent *kev) {
135132 int i;
136− XKeyEvent *kev;
137133 KeySym ksym;
138134 char key;
139135
140− if (!ev || ev->type != KeyPress)
136+ if (!kev)
141137 return;
142−
143− kev = &ev->xkey;
138+
144139 XLookupString(kev, &key, 1, &ksym, NULL);
145140
146141 if (EXT_COMMANDS && (CLEANMASK(kev->state) & ControlMask)) {
@@ -174,39 +169,34 @@ void on_keypress(XEvent *ev) {
174169
175170 for (i = 0; i < LEN(keys); i++) {
176171 if (ksym == keys[i].ksym && keys[i].handler) {
177− if (keys[i].handler(ev, keys[i].arg))
172+ if (keys[i].handler(keys[i].arg))
178173 redraw();
179174 return;
180175 }
181176 }
182177 }
183178
184−void on_buttonpress(XEvent *ev) {
179+void on_buttonpress(XButtonEvent *bev) {
185180 int i, sel;
186− XButtonEvent *bev;
187181
188− if (!ev || ev->type != ButtonPress)
182+ if (!bev)
189183 return;
190184
191− bev = &ev->xbutton;
192−
193185 if (mode == MODE_NORMAL) {
194− if (!dragging) {
195− win_set_cursor(&win, CURSOR_ARROW);
196− timo_cursor = TO_CURSOR_HIDE;
197− }
186+ win_set_cursor(&win, CURSOR_ARROW);
187+ timo_cursor = TO_CURSOR_HIDE;
198188
199189 for (i = 0; i < LEN(buttons); i++) {
200190 if (CLEANMASK(bev->state) == CLEANMASK(buttons[i].mod) &&
201191 bev->button == buttons[i].button && buttons[i].handler)
202192 {
203− if (buttons[i].handler(ev, buttons[i].arg))
193+ if (buttons[i].handler(buttons[i].arg))
204194 redraw();
205195 return;
206196 }
207197 }
208198 } else {
209− /* thumbnail mode */
199+ /* thumbnail mode (hard-coded) */
210200 switch (bev->button) {
211201 case Button1:
212202 if ((sel = tns_translate(&tns, bev->x, bev->y)) >= 0) {
@@ -232,29 +222,12 @@ void on_buttonpress(XEvent *ev) {
232222 }
233223 }
234224
235−void on_motionnotify(XEvent *ev) {
236− XMotionEvent *mev;
237−
238− if (!ev || ev->type != MotionNotify)
239− return;
240−
241− mev = &ev->xmotion;
242−
243− if (mev->x >= 0 && mev->x <= win.w && mev->y >= 0 && mev->y <= win.h) {
244− if (img_move(&img, &win, mev->x - mox, mev->y - moy))
245− timo_redraw = TO_IMAGE_DRAG;
246− mox = mev->x;
247− moy = mev->y;
248− }
249−}
250−
251225 void run() {
252226 int xfd, timeout;
253227 fd_set fds;
254228 struct timeval tt, t0, t1;
255229 XEvent ev;
256230
257− dragging = 0;
258231 timo_cursor = mode == MODE_NORMAL ? TO_CURSOR_HIDE : 0;
259232
260233 redraw();
@@ -312,18 +285,10 @@ void run() {
312285 }
313286
314287 if (!XNextEvent(win.env.dpy, &ev)) {
288+ /* handle events */
315289 switch (ev.type) {
316290 case ButtonPress:
317− on_buttonpress(&ev);
318− break;
319− case ButtonRelease:
320− if (dragging) {
321− dragging = 0;
322− if (mode == MODE_NORMAL) {
323− win_set_cursor(&win, CURSOR_ARROW);
324− timo_cursor = TO_CURSOR_HIDE;
325− }
326− }
291+ on_buttonpress(&ev.xbutton);
327292 break;
328293 case ClientMessage:
329294 if ((Atom) ev.xclient.data.l[0] == wm_delete_win)
@@ -339,16 +304,12 @@ void run() {
339304 }
340305 break;
341306 case KeyPress:
342− on_keypress(&ev);
307+ on_keypress(&ev.xkey);
343308 break;
344309 case MotionNotify:
345− if (dragging) {
346− on_motionnotify(&ev);
347− } else if (mode == MODE_NORMAL) {
348− if (!timo_cursor)
349− win_set_cursor(&win, CURSOR_ARROW);
350− timo_cursor = TO_CURSOR_HIDE;
351− }
310+ if (!timo_cursor)
311+ win_set_cursor(&win, CURSOR_ARROW);
312+ timo_cursor = TO_CURSOR_HIDE;
352313 break;
353314 }
354315 }
@@ -358,12 +319,12 @@ void run() {
358319
359320 /* handler functions for key and button mappings: */
360321
361−int quit(XEvent *e, arg_t a) {
322+int quit(arg_t a) {
362323 cleanup();
363324 exit(0);
364325 }
365326
366−int reload(XEvent *e, arg_t a) {
327+int reload(arg_t a) {
367328 if (mode == MODE_NORMAL) {
368329 load_image(fileidx);
369330 return 1;
@@ -372,7 +333,7 @@ int reload(XEvent *e, arg_t a) {
372333 }
373334 }
374335
375−int toggle_fullscreen(XEvent *e, arg_t a) {
336+int toggle_fullscreen(arg_t a) {
376337 win_toggle_fullscreen(&win);
377338 if (mode == MODE_NORMAL)
378339 img.checkpan = 1;
@@ -382,7 +343,7 @@ int toggle_fullscreen(XEvent *e, arg_t a) {
382343 return 0;
383344 }
384345
385−int toggle_antialias(XEvent *e, arg_t a) {
346+int toggle_antialias(arg_t a) {
386347 if (mode == MODE_NORMAL) {
387348 img_toggle_antialias(&img);
388349 return 1;
@@ -391,7 +352,7 @@ int toggle_antialias(XEvent *e, arg_t a) {
391352 }
392353 }
393354
394−int toggle_alpha(XEvent *e, arg_t a) {
355+int toggle_alpha(arg_t a) {
395356 if (mode == MODE_NORMAL) {
396357 img.alpha ^= 1;
397358 return 1;
@@ -400,7 +361,7 @@ int toggle_alpha(XEvent *e, arg_t a) {
400361 }
401362 }
402363
403−int switch_mode(XEvent *e, arg_t a) {
364+int switch_mode(arg_t a) {
404365 if (mode == MODE_NORMAL) {
405366 if (!tns.thumbs)
406367 tns_init(&tns, filecnt);
@@ -418,7 +379,7 @@ int switch_mode(XEvent *e, arg_t a) {
418379 return 1;
419380 }
420381
421−int navigate(XEvent *e, arg_t n) {
382+int navigate(arg_t n) {
422383 if (mode == MODE_NORMAL) {
423384 n += fileidx;
424385 if (n < 0)
@@ -434,7 +395,7 @@ int navigate(XEvent *e, arg_t n) {
434395 return 0;
435396 }
436397
437−int first(XEvent *e, arg_t a) {
398+int first(arg_t a) {
438399 if (mode == MODE_NORMAL && fileidx != 0) {
439400 load_image(0);
440401 return 1;
@@ -447,7 +408,7 @@ int first(XEvent *e, arg_t a) {
447408 }
448409 }
449410
450−int last(XEvent *e, arg_t a) {
411+int last(arg_t a) {
451412 if (mode == MODE_NORMAL && fileidx != filecnt - 1) {
452413 load_image(filecnt - 1);
453414 return 1;
@@ -460,7 +421,7 @@ int last(XEvent *e, arg_t a) {
460421 }
461422 }
462423
463−int remove_image(XEvent *e, arg_t a) {
424+int remove_image(arg_t a) {
464425 if (mode == MODE_NORMAL) {
465426 remove_file(fileidx, 1);
466427 load_image(fileidx >= filecnt ? filecnt - 1 : fileidx);
@@ -476,39 +437,83 @@ int remove_image(XEvent *e, arg_t a) {
476437 }
477438 }
478439
479−int move(XEvent *e, arg_t dir) {
440+int move(arg_t dir) {
480441 if (mode == MODE_NORMAL)
481442 return img_pan(&img, &win, dir, 0);
482443 else
483444 return tns_move_selection(&tns, &win, dir);
484445 }
485446
486−int pan_screen(XEvent *e, arg_t dir) {
447+int pan_screen(arg_t dir) {
487448 if (mode == MODE_NORMAL)
488449 return img_pan(&img, &win, dir, 1);
489450 else
490451 return 0;
491452 }
492453
493−int pan_edge(XEvent *e, arg_t dir) {
454+int pan_edge(arg_t dir) {
494455 if (mode == MODE_NORMAL)
495456 return img_pan_edge(&img, &win, dir);
496457 else
497458 return 0;
498459 }
499460
500−int drag(XEvent *e, arg_t a) {
501− if (mode == MODE_NORMAL) {
502− mox = e->xbutton.x;
503− moy = e->xbutton.y;
504− win_set_cursor(&win, CURSOR_HAND);
505− timo_cursor = 0;
506− dragging = 1;
461+/* Xlib helper function for drag() */
462+Bool ismnotify(Display *d, XEvent *e, XPointer a) {
463+ return e != NULL && e->type == MotionNotify;
464+}
465+
466+int drag(arg_t a) {
467+ int dx = 0, dy = 0, i, ox, oy, x, y;
468+ unsigned int ui;
469+ Bool dragging = True, next = False;
470+ XEvent e;
471+ Window w;
472+
473+ if (mode != MODE_NORMAL)
474+ return 0;
475+ if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &ox, &oy, &ui))
476+ return 0;
477+
478+ win_set_cursor(&win, CURSOR_HAND);
479+
480+ while (dragging) {
481+ if (!next)
482+ XMaskEvent(win.env.dpy,
483+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e);
484+ switch (e.type) {
485+ case ButtonPress:
486+ case ButtonRelease:
487+ dragging = False;
488+ break;
489+ case MotionNotify:
490+ x = e.xmotion.x;
491+ y = e.xmotion.y;
492+ if (x >= 0 && x <= win.w && y >= 0 && y <= win.h) {
493+ dx += x - ox;
494+ dy += y - oy;
495+ }
496+ ox = x;
497+ oy = y;
498+ break;
499+ }
500+ if (dragging)
501+ next = XCheckIfEvent(win.env.dpy, &e, ismnotify, None);
502+ if ((!dragging || !next) && (dx != 0 || dy != 0)) {
503+ if (img_move(&img, &win, dx, dy))
504+ img_render(&img, &win);
505+ dx = dy = 0;
506+ }
507507 }
508+
509+ win_set_cursor(&win, CURSOR_ARROW);
510+ timo_cursor = TO_CURSOR_HIDE;
511+ timo_redraw = 0;
512+
508513 return 0;
509514 }
510515
511−int rotate(XEvent *e, arg_t dir) {
516+int rotate(arg_t dir) {
512517 if (mode == MODE_NORMAL) {
513518 if (dir == DIR_LEFT) {
514519 img_rotate_left(&img, &win);
@@ -521,7 +526,7 @@ int rotate(XEvent *e, arg_t dir) {
521526 return 0;
522527 }
523528
524−int zoom(XEvent *e, arg_t scale) {
529+int zoom(arg_t scale) {
525530 if (mode != MODE_NORMAL)
526531 return 0;
527532 if (scale > 0)
@@ -532,7 +537,7 @@ int zoom(XEvent *e, arg_t scale) {
532537 return img_zoom(&img, &win, 1.0);
533538 }
534539
535−int fit_to_win(XEvent *e, arg_t ret) {
540+int fit_to_win(arg_t ret) {
536541 if (mode == MODE_NORMAL) {
537542 if ((ret = img_fit_win(&img, &win)))
538543 img_center(&img, &win);
@@ -542,7 +547,7 @@ int fit_to_win(XEvent *e, arg_t ret) {
542547 }
543548 }
544549
545−int fit_to_img(XEvent *e, arg_t ret) {
550+int fit_to_img(arg_t ret) {
546551 int x, y;
547552 unsigned int w, h;
548553
M events.h View
@@ -31,37 +31,37 @@ typedef int arg_t;
3131
3232 typedef struct {
3333 KeySym ksym;
34− int (*handler)(XEvent*, arg_t);
34+ int (*handler)(arg_t);
3535 arg_t arg;
3636 } keymap_t;
3737
3838 typedef struct {
3939 unsigned int mod;
4040 unsigned int button;
41− int (*handler)(XEvent*, arg_t);
41+ int (*handler)(arg_t);
4242 arg_t arg;
4343 } button_t;
4444
4545 void run();
4646
4747 /* handler functions for key and button mappings: */
48−int quit(XEvent*, arg_t);
49−int reload(XEvent*, arg_t);
50−int toggle_fullscreen(XEvent*, arg_t);
51−int toggle_antialias(XEvent*, arg_t);
52−int toggle_alpha(XEvent*, arg_t);
53−int switch_mode(XEvent*, arg_t);
54−int navigate(XEvent*, arg_t);
55−int first(XEvent*, arg_t);
56−int last(XEvent*, arg_t);
57−int remove_image(XEvent*, arg_t);
58−int move(XEvent*, arg_t);
59−int pan_screen(XEvent*, arg_t);
60−int pan_edge(XEvent*, arg_t);
61−int drag(XEvent*, arg_t);
62−int rotate(XEvent*, arg_t);
63−int zoom(XEvent*, arg_t);
64−int fit_to_win(XEvent*, arg_t);
65−int fit_to_img(XEvent*, arg_t);
48+int quit(arg_t);
49+int reload(arg_t);
50+int toggle_fullscreen(arg_t);
51+int toggle_antialias(arg_t);
52+int toggle_alpha(arg_t);
53+int switch_mode(arg_t);
54+int navigate(arg_t);
55+int first(arg_t);
56+int last(arg_t);
57+int remove_image(arg_t);
58+int move(arg_t);
59+int pan_screen(arg_t);
60+int pan_edge(arg_t);
61+int drag(arg_t);
62+int rotate(arg_t);
63+int zoom(arg_t);
64+int fit_to_win(arg_t);
65+int fit_to_img(arg_t);
6666
6767 #endif /* EVENTS_H */