diff options
Diffstat (limited to 'src/events.c')
-rw-r--r-- | src/events.c | 202 |
1 files changed, 110 insertions, 92 deletions
diff --git a/src/events.c b/src/events.c index c5032a1..bafc517 100644 --- a/src/events.c +++ b/src/events.c @@ -1,7 +1,7 @@ /* events.c Copyright (C) 1999-2003 Tom Gilbert. -Copyright (C) 2010-2011 Daniel Friesel. +Copyright (C) 2010-2024 Birte Kristina Friesel. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -35,7 +35,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define FEH_JITTER_OFFSET 2 #define FEH_JITTER_TIME 1 -fehbb buttons; +extern struct __fehkey keys[EVENT_LIST_END]; +fehkey *feh_str_to_kb(char *action); feh_event_handler *ev_handler[LASTEvent]; @@ -45,13 +46,13 @@ static void feh_event_handle_LeaveNotify(XEvent * ev); static void feh_event_handle_MotionNotify(XEvent * ev); static void feh_event_handle_ClientMessage(XEvent * ev); -static void feh_set_bb(fehbutton *bb, int modifier, char button) +static void feh_set_bb(unsigned int bb_index, int modifier, char button) { - bb->modifier = modifier; - bb->button = button; + keys[bb_index].state = modifier; + keys[bb_index].button = button; } -static void feh_set_parse_bb_partial(fehbutton *button, char *binding) +static void feh_set_parse_bb_partial(fehkey *button, char *binding) { char *cur = binding; int mod = 0; @@ -83,9 +84,22 @@ static void feh_set_parse_bb_partial(fehbutton *button, char *binding) } button->button = atoi(cur); - button->modifier = mod; + button->state = mod; + + if (button->button == 0) { + /* + * Mod3 is unused on today's keyboards. If Mod3 is unset and button==0, + * we are dealing with an uninitialized or unset binding. If Mod3 is set + * and button==0, it refers to mouse movement. + */ + button->state |= Mod3Mask; + } } +/* + * Called after init_keyevents in keyevents.c + * -> no need to memset + */ void init_buttonbindings(void) { char *home = NULL; @@ -93,20 +107,17 @@ void init_buttonbindings(void) char *confpath = NULL; char line[128]; char action[32], button[8]; - struct __fehbutton *cur_bb = NULL; + struct __fehkey *cur_bb = NULL; FILE *conf = NULL; int read = 0; - memset(&buttons, 0, sizeof(buttons)); - - feh_set_bb(&buttons.reload, 0, 0); - feh_set_bb(&buttons.pan, 0, 1); - feh_set_bb(&buttons.zoom, 0, 2); - feh_set_bb(&buttons.menu, 0, 3); - feh_set_bb(&buttons.prev, 0, 4); - feh_set_bb(&buttons.next, 0, 5); - feh_set_bb(&buttons.blur, 4, 1); - feh_set_bb(&buttons.rotate, 4, 2); + feh_set_bb(EVENT_pan, 0, 1); + feh_set_bb(EVENT_zoom, 0, 2); + feh_set_bb(EVENT_toggle_menu, 0, 3); + feh_set_bb(EVENT_prev_img, 0, 4); + feh_set_bb(EVENT_next_img, 0, 5); + feh_set_bb(EVENT_blur, 4, 1); + feh_set_bb(EVENT_rotate, 4, 2); home = getenv("HOME"); confhome = getenv("XDG_CONFIG_HOME"); @@ -128,44 +139,35 @@ void init_buttonbindings(void) while (fgets(line, sizeof(line), conf)) { *action = '\0'; *button = '\0'; + cur_bb = NULL; read = sscanf(line, "%31s %7s\n", (char *) &action, (char *) &button); if ((read == EOF) || (read == 0) || (line[0] == '#')) continue; - if (!strcmp(action, "reload")) - cur_bb = &buttons.reload; - else if (!strcmp(action, "pan")) - cur_bb = &buttons.pan; - else if (!strcmp(action, "zoom")) - cur_bb = &buttons.zoom; - else if (!strcmp(action, "menu")) - cur_bb = &buttons.menu; - else if (!strcmp(action, "prev")) - cur_bb = &buttons.prev; - else if (!strcmp(action, "next")) - cur_bb = &buttons.next; - else if (!strcmp(action, "blur")) - cur_bb = &buttons.blur; - else if (!strcmp(action, "rotate")) - cur_bb = &buttons.rotate; - else if (!strcmp(action, "zoom_in")) - cur_bb = &buttons.zoom_in; - else if (!strcmp(action, "zoom_out")) - cur_bb = &buttons.zoom_out; - else - weprintf("buttons: Invalid action: %s", action); - + cur_bb = feh_str_to_kb(action); + if (cur_bb == NULL) { + if (!strcmp(action, "reload")) + cur_bb = &keys[EVENT_reload_image]; + else if (!strcmp(action, "menu")) + cur_bb = &keys[EVENT_toggle_menu]; + else if (!strcmp(action, "prev")) + cur_bb = &keys[EVENT_prev_img]; + else if (!strcmp(action, "next")) + cur_bb = &keys[EVENT_next_img]; + } if (cur_bb) feh_set_parse_bb_partial(cur_bb, button); + else + weprintf("buttons: Invalid action: %s", action); } fclose(conf); } -static short feh_is_bb(fehbutton *bb, int button, int mod) +static short feh_is_bb(unsigned int key_index, unsigned int button, unsigned int mod) { - if ((bb->modifier == mod) && (bb->button == button)) + if ((keys[key_index].state == mod) && (keys[key_index].button == button)) return 1; return 0; } @@ -192,7 +194,7 @@ void feh_event_init(void) static void feh_event_handle_ButtonPress(XEvent * ev) { winwidget winwid = NULL; - int state, button; + unsigned int state, button; /* get the heck out if it's a mouse-click on the cover, we'll hide the menus on release */ @@ -208,23 +210,23 @@ static void feh_event_handle_ButtonPress(XEvent * ev) state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); button = ev->xbutton.button; - if (!opt.no_menus && feh_is_bb(&buttons.menu, button, state)) { + if (!opt.no_menus && feh_is_bb(EVENT_toggle_menu, button, state)) { D(("Menu Button Press event\n")); winwidget_show_menu(winwid); - } else if (feh_is_bb(&buttons.rotate, button, state) + } else if (feh_is_bb(EVENT_rotate, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_ROTATE; winwid->mode = MODE_ROTATE; D(("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&buttons.blur, button, state) + } else if (feh_is_bb(EVENT_blur, button, state) && (winwid->type != WIN_TYPE_THUMBNAIL)) { opt.mode = MODE_BLUR; winwid->mode = MODE_BLUR; D(("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } else if (feh_is_bb(&buttons.pan, button, state)) { + } else if (feh_is_bb(EVENT_pan, button, state)) { D(("Next button, but could be pan mode\n")); opt.mode = MODE_NEXT; winwid->mode = MODE_NEXT; @@ -233,7 +235,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->click_offset_y = ev->xbutton.y - winwid->im_y; winwid->click_start_time = time(NULL); - } else if (feh_is_bb(&buttons.zoom, button, state)) { + } else if (feh_is_bb(EVENT_zoom, button, state)) { D(("Zoom Button Press event\n")); opt.mode = MODE_ZOOM; winwid->mode = MODE_ZOOM; @@ -248,7 +250,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwid->im_click_offset_y = (winwid->click_offset_y - winwid->im_y) / winwid->old_zoom; - } else if (feh_is_bb(&buttons.zoom_in, button, state)) { + } else if (feh_is_bb(EVENT_zoom_in, button, state)) { D(("Zoom_In Button Press event\n")); D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x; @@ -262,7 +264,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) - winwid->im_y) / winwid->old_zoom; /* copied from zoom_in, keyevents.c */ - winwid->zoom = winwid->zoom * 1.25; + winwid->zoom = winwid->zoom * opt.zoom_rate; if (winwid->zoom > ZOOM_MAX) winwid->zoom = ZOOM_MAX; @@ -276,7 +278,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&buttons.zoom_out, button, state)) { + } else if (feh_is_bb(EVENT_zoom_out, button, state)) { D(("Zoom_Out Button Press event\n")); D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x; @@ -290,7 +292,7 @@ static void feh_event_handle_ButtonPress(XEvent * ev) - winwid->im_y) / winwid->old_zoom; /* copied from zoom_out, keyevents.c */ - winwid->zoom = winwid->zoom * 0.80; + winwid->zoom = winwid->zoom / opt.zoom_rate; if (winwid->zoom < ZOOM_MIN) winwid->zoom = ZOOM_MIN; @@ -304,22 +306,23 @@ static void feh_event_handle_ButtonPress(XEvent * ev) winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&buttons.reload, button, state)) { + } else if (feh_is_bb(EVENT_reload_image, button, state)) { D(("Reload Button Press event\n")); feh_reload_image(winwid, 0, 1); - } else if (feh_is_bb(&buttons.prev, button, state)) { + } else if (feh_is_bb(EVENT_prev_img, button, state)) { D(("Prev Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_PREV, 1); - } else if (feh_is_bb(&buttons.next, button, state)) { + } else if (feh_is_bb(EVENT_next_img, button, state)) { D(("Next Button Press event\n")); if (winwid->type == WIN_TYPE_SLIDESHOW) slideshow_change_image(winwid, SLIDE_NEXT, 1); } else { D(("Received other ButtonPress event\n")); + feh_event_handle_generic(winwid, state, NoSymbol, button); } return; } @@ -327,8 +330,8 @@ static void feh_event_handle_ButtonPress(XEvent * ev) static void feh_event_handle_ButtonRelease(XEvent * ev) { winwidget winwid = NULL; - int state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); - int button = ev->xbutton.button; + unsigned int state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); + unsigned int button = ev->xbutton.button; if (menu_root) { /* if menus are open, close them, and execute action if needed */ @@ -353,7 +356,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) return; } - if (feh_is_bb(&buttons.pan, button, state)) { + if (feh_is_bb(EVENT_pan, button, state)) { if (opt.mode == MODE_PAN) { D(("Disabling pan mode\n")); opt.mode = MODE_NORMAL; @@ -363,9 +366,12 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) } else if (opt.mode == MODE_NEXT) { opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; - if (winwid->type == WIN_TYPE_SLIDESHOW) - slideshow_change_image(winwid, SLIDE_NEXT, 1); - else if (winwid->type == WIN_TYPE_THUMBNAIL) { + if (winwid->type == WIN_TYPE_SLIDESHOW) { + if (opt.tap_zones && ev->xbutton.x < winwid->w / 2) + slideshow_change_image(winwid, SLIDE_PREV, 1); + else + slideshow_change_image(winwid, SLIDE_NEXT, 1); + } else if (winwid->type == WIN_TYPE_THUMBNAIL) { feh_file *thumbfile; int x, y; @@ -378,7 +384,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) thumbfile = feh_thumbnail_get_file_from_coords(x, y); if (thumbfile) { if (opt.actions[0]) { - feh_action_run(thumbfile, opt.actions[0]); + feh_action_run(thumbfile, opt.actions[0], winwid); if (!opt.hold_actions[0]) feh_thumbnail_mark_removed(thumbfile, 0); } else { @@ -391,13 +397,13 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwid->mode = MODE_NORMAL; } - } else if (feh_is_bb(&buttons.rotate, button, state) - || feh_is_bb(&buttons.zoom, button, state)) { + } else if (feh_is_bb(EVENT_rotate, button, state) + || feh_is_bb(EVENT_zoom, button, state)) { D(("Disabling mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; - if ((feh_is_bb(&buttons.zoom, button, state)) + if ((feh_is_bb(EVENT_zoom, button, state)) && (ev->xbutton.x == winwid->click_offset_x) && (ev->xbutton.y == winwid->click_offset_y)) { winwid->zoom = 1.0; @@ -407,7 +413,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) winwidget_render_image(winwid, 0, 0); - } else if (feh_is_bb(&buttons.blur, button, state)) { + } else if (feh_is_bb(EVENT_blur, button, state)) { D(("Disabling Blur mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; @@ -515,6 +521,8 @@ static void feh_event_handle_MotionNotify(XEvent * ev) dy = scr_height - (m->y + m->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; + dx = m->x + dx < 0 ? -m->x : dx; + dy = m->y + dy < 0 ? -m->y : dy; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } @@ -527,6 +535,8 @@ static void feh_event_handle_MotionNotify(XEvent * ev) dy = scr->height - (m->next->y + m->next->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; + dx = m->x + dx < 0 ? -m->x : dx; + dy = m->y + dy < 0 ? -m->y : dy; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } @@ -634,12 +644,14 @@ static void feh_event_handle_MotionNotify(XEvent * ev) Imlib_Image temp; temp = gib_imlib_create_rotated_image(winwid->im, 0.0); - winwid->im_w = gib_imlib_image_get_width(temp); - winwid->im_h = gib_imlib_image_get_height(temp); - gib_imlib_free_image_and_decache(temp); - if (!winwid->full_screen && !opt.geom_flags) - winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); - winwid->has_rotated = 1; + if (temp != NULL) { + winwid->im_w = gib_imlib_image_get_width(temp); + winwid->im_h = gib_imlib_image_get_height(temp); + gib_imlib_free_image_and_decache(temp); + if (!winwid->full_screen && !opt.geom_flags) + winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); + winwid->has_rotated = 1; + } } winwid->im_angle = (ev->xmotion.x - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535; D(("angle: %f\n", winwid->im_angle)); @@ -655,29 +667,35 @@ static void feh_event_handle_MotionNotify(XEvent * ev) D(("Blurring\n")); temp = gib_imlib_clone_image(winwid->im); - blur_radius = (((double) ev->xmotion.x / winwid->w) * 20) - 10; - D(("angle: %d\n", blur_radius)); - if (blur_radius > 0) - gib_imlib_image_sharpen(temp, blur_radius); - else - gib_imlib_image_blur(temp, 0 - blur_radius); - ptr = winwid->im; - winwid->im = temp; - winwidget_render_image(winwid, 0, 1); - gib_imlib_free_image_and_decache(winwid->im); - winwid->im = ptr; + if (temp != NULL) { + blur_radius = (((double) ev->xmotion.x / winwid->w) * 20) - 10; + D(("angle: %d\n", blur_radius)); + if (blur_radius > 0) + gib_imlib_image_sharpen(temp, blur_radius); + else + gib_imlib_image_blur(temp, 0 - blur_radius); + ptr = winwid->im; + winwid->im = temp; + winwidget_render_image(winwid, 0, 1); + gib_imlib_free_image_and_decache(winwid->im); + winwid->im = ptr; + } } } else { while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); winwid = winwidget_get_from_window(ev->xmotion.window); - if ((winwid != NULL) && (winwid->type == WIN_TYPE_THUMBNAIL)) { - feh_thumbnail *thumbnail; - int x, y; - - x = (ev->xbutton.x - winwid->im_x) / winwid->zoom; - y = (ev->xbutton.y - winwid->im_y) / winwid->zoom; - thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y); - feh_thumbnail_select(winwid, thumbnail); + if (winwid != NULL) { + if (winwid->type == WIN_TYPE_THUMBNAIL) { + feh_thumbnail *thumbnail; + int x, y; + + x = (ev->xbutton.x - winwid->im_x) / winwid->zoom; + y = (ev->xbutton.y - winwid->im_y) / winwid->zoom; + thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y); + feh_thumbnail_select(winwid, thumbnail); + } else { + feh_event_handle_generic(winwid, ev->xmotion.state | Mod3Mask, NoSymbol, 0); + } } } return; |