static void feh_event_handle_ConfigureNotify(XEvent * ev) { while (XCheckTypedWindowEvent(disp, ev->xconfigure.window, ConfigureNotify, ev)); if (!menu_root) { winwidget w = winwidget_get_from_window(ev->xconfigure.window); if (w) { D(("configure size %dx%d\n", ev->xconfigure.width, ev->xconfigure.height)); if ((w->w != ev->xconfigure.width) || (w->h != ev->xconfigure.height)) { D(("assigning size and rerendering\n")); w->w = ev->xconfigure.width; w->h = ev->xconfigure.height; w->had_resize = 1; if (opt.geom_flags & WidthValue || opt.geom_flags & HeightValue) { opt.geom_w = w->w; opt.geom_h = w->h; } winwidget_render_image(w, 0, 0); } } } return; }
static void feh_event_handle_ClientMessage(XEvent * ev) { winwidget winwid = NULL; if (ev->xclient.format == 32 && ev->xclient.data.l[0] == (signed) wmDeleteWindow) { winwid = winwidget_get_from_window(ev->xclient.window); if (winwid) winwidget_destroy(winwid); } return; }
void feh_event_handle_keypress(XEvent * ev) { int state; char kbuf[20]; KeySym keysym; XKeyEvent *kev; winwidget winwid = NULL; feh_menu_item *selected_item; feh_menu *selected_menu; winwid = winwidget_get_from_window(ev->xkey.window); /* nuke dupe events, unless we're typing text */ if (winwid && !winwid->caption_entry) { while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev)); } kev = (XKeyEvent *) ev; XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); state = kev->state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); if (ignore_space(keysym)) state &= ~ShiftMask; /* menus are showing, so this is a menu control keypress */ if (ev->xbutton.window == menu_cover) { selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); if (feh_is_kp(EVENT_menu_close, state, keysym, 0)) feh_menu_hide(menu_root, True); else if (feh_is_kp(EVENT_menu_parent, state, keysym, 0)) feh_menu_select_parent(selected_menu); else if (feh_is_kp(EVENT_menu_down, state, keysym, 0)) feh_menu_select_next(selected_menu, selected_item); else if (feh_is_kp(EVENT_menu_up, state, keysym, 0)) feh_menu_select_prev(selected_menu, selected_item); else if (feh_is_kp(EVENT_menu_child, state, keysym, 0)) feh_menu_select_submenu(selected_menu); else if (feh_is_kp(EVENT_menu_select, state, keysym, 0)) feh_menu_item_activate(selected_menu, selected_item); return; } if (winwid == NULL) return; feh_event_handle_generic(winwid, state, keysym, 0); }
void feh_event_handle_keypress(XEvent * ev) { int state; char kbuf[20]; KeySym keysym; XKeyEvent *kev; winwidget winwid = NULL; feh_menu_item *selected_item; feh_menu *selected_menu; winwid = winwidget_get_from_window(ev->xkey.window); /* nuke dupe events, unless we're typing text */ if (winwid && !winwid->caption_entry) { while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev)); } kev = (XKeyEvent *) ev; XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); state = kev->state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); if (isascii(keysym)) state &= ~ShiftMask; /* menus are showing, so this is a menu control keypress */ if (ev->xbutton.window == menu_cover) { selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); if (feh_is_kp(&keys.menu_close, state, keysym, 0)) feh_menu_hide(menu_root, True); else if (feh_is_kp(&keys.menu_parent, state, keysym, 0)) feh_menu_select_parent(selected_menu); else if (feh_is_kp(&keys.menu_down, state, keysym, 0)) feh_menu_select_next(selected_menu, selected_item); else if (feh_is_kp(&keys.menu_up, state, keysym, 0)) feh_menu_select_prev(selected_menu, selected_item); else if (feh_is_kp(&keys.menu_child, state, keysym, 0)) feh_menu_select_submenu(selected_menu); else if (feh_is_kp(&keys.menu_select, state, keysym, 0)) feh_menu_item_activate(selected_menu, selected_item); return; } if (winwid == NULL) return; if (winwid->caption_entry) { switch (keysym) { case XK_Return: if (state & ControlMask) { /* insert actual newline */ ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); winwidget_render_image_cached(winwid); } else { /* finish caption entry, write to captions file */ FILE *fp; char *caption_filename; caption_filename = build_caption_filename(FEH_FILE(winwid->file->data), 1); winwid->caption_entry = 0; winwidget_render_image_cached(winwid); XFreePixmap(disp, winwid->bg_pmap_cache); winwid->bg_pmap_cache = 0; fp = fopen(caption_filename, "w"); if (!fp) { eprintf("couldn't write to captions file %s:", caption_filename); return; } fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); free(caption_filename); fclose(fp); } break; case XK_Escape: /* cancel, revert caption */ winwid->caption_entry = 0; free(FEH_FILE(winwid->file->data)->caption); FEH_FILE(winwid->file->data)->caption = NULL; winwidget_render_image_cached(winwid); XFreePixmap(disp, winwid->bg_pmap_cache); winwid->bg_pmap_cache = 0; break; case XK_BackSpace: /* backspace */ ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); winwidget_render_image_cached(winwid); break; default: if (isascii(keysym)) { /* append to caption */ ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); winwidget_render_image_cached(winwid); } break; } return; } feh_event_handle_generic(winwid, state, keysym, 0); }
static void feh_event_handle_MotionNotify(XEvent * ev) { winwidget winwid = NULL; int dx, dy; int scr_width, scr_height; scr_width = scr->width; scr_height = scr->height; #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { scr_width = xinerama_screens[xinerama_screen].width; scr_height = xinerama_screens[xinerama_screen].height; } #endif /* HAVE_LIBXINERAMA */ if (menu_root) { feh_menu *m; feh_menu_item *selected_item, *mouseover_item; D(("motion notify with menus open\n")); while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); if (ev->xmotion.window == menu_cover) { return; } else if ((m = feh_menu_get_from_window(ev->xmotion.window))) { selected_item = feh_menu_find_selected(m); mouseover_item = feh_menu_find_at_xy(m, ev->xmotion.x, ev->xmotion.y); if (selected_item != mouseover_item) { D(("selecting a menu item\n")); if (selected_item) feh_menu_deselect_selected(m); if ((mouseover_item) && ((mouseover_item->action) || (mouseover_item->submenu) || (mouseover_item->func_gen_sub))) feh_menu_select(m, mouseover_item); } /* check if we are close to the right and/or the bottom edge of the * screen. If so, and if the menu we are currently over is partially * hidden, slide the menu to the left and/or up until it is * fully visible */ /* FIXME: get this working nicely with xinerama screen edges -- * at the moment it does really funky stuff with * scr_{width,height} instead of scr->{width,height} -- pabs*/ if (mouseover_item && ((scr->width - (ev->xmotion.x + m->x)) < m->w || (scr->height - (ev->xmotion.y + m->y)) < m->w)) { dx = scr_width - (m->x + m->w); dy = scr_height - (m->y + m->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } /* if a submenu is open we want to see that also */ if (mouseover_item && m->next && ((scr->width - (ev->xmotion.x + m->next->x)) < m->next->w || (scr->height - (ev->xmotion.y + m->next->y)) < m->next->w)) { dx = scr->width - (m->next->x + m->next->w); dy = scr->height - (m->next->y + m->next->h); dx = dx < 0 ? dx : 0; dy = dy < 0 ? dy : 0; if (dx || dy) feh_menu_slide_all_menus_relative(dx, dy); } } } else if (opt.mode == MODE_ZOOM) { while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); winwid = winwidget_get_from_window(ev->xmotion.window); if (winwid) { if (ev->xmotion.x > winwid->click_offset_x) winwid->zoom = winwid->old_zoom + ( ((double) ev->xmotion.x - (double) winwid->click_offset_x) / 128.0); else winwid->zoom = winwid->old_zoom - ( ((double) winwid->click_offset_x - (double) ev->xmotion.x) / 128.0); if (winwid->zoom < ZOOM_MIN) winwid->zoom = ZOOM_MIN; else if (winwid->zoom > ZOOM_MAX) winwid->zoom = ZOOM_MAX; /* center around click_offset */ winwid->im_x = winwid->click_offset_x - (winwid->im_click_offset_x * winwid->zoom); winwid->im_y = winwid->click_offset_y - (winwid->im_click_offset_y * winwid->zoom); winwidget_render_image(winwid, 0, 1); } } else if ((opt.mode == MODE_PAN) || (opt.mode == MODE_NEXT)) { int orig_x, orig_y; while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); winwid = winwidget_get_from_window(ev->xmotion.window); if (winwid) { if (opt.mode == MODE_NEXT) { if ((abs(winwid->click_offset_x - (ev->xmotion.x - winwid->im_x)) > FEH_JITTER_OFFSET) || (abs(winwid->click_offset_y - (ev->xmotion.y - winwid->im_y)) > FEH_JITTER_OFFSET) || (time(NULL) - winwid->click_start_time > FEH_JITTER_TIME)) { opt.mode = MODE_PAN; winwid->mode = MODE_PAN; } else return; } D(("Panning\n")); orig_x = winwid->im_x; orig_y = winwid->im_y; winwid->im_x = ev->xmotion.x - winwid->click_offset_x; winwid->im_y = ev->xmotion.y - winwid->click_offset_y; winwidget_sanitise_offsets(winwid); D(("im_x %d, im_w %d, off %d, mx %d, my %d\n", winwid->im_x, winwid->im_w, winwid->click_offset_x, ev->xmotion.x, ev->xmotion.y)); /* XWarpPointer generates a MotionNotify event which we will * parse. Since that event would undo the effect of the pointer * warp, we need to change the click_offset to compensate this. */ if ((winwid->w - ev->xmotion.x <= 1) && (winwid->im_x < 0)) { XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0, 3, ev->xmotion.y); winwid->click_offset_x -= winwid->w - 4; } // TODO needlessly warps for certain zoom levels else if ((ev->xmotion.x <= 1) && (winwid->im_x > (winwid->w - winwid->im_w * winwid->zoom))) { XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0, winwid->w - 4, ev->xmotion.y); winwid->click_offset_x += winwid->w - 4; } else if ((winwid->h - ev->xmotion.y <= 1) && (winwid->im_y < 0)) { XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0, ev->xmotion.x, 3); winwid->click_offset_y -= winwid->h - 4; } // TODO needlessly warps for certain zoomlevels else if ((ev->xmotion.y <= 1) && (winwid->im_y > (winwid->h - winwid->im_h * winwid->zoom))) { XWarpPointer(disp, None, winwid->win, 0, 0, 0, 0, ev->xmotion.x, winwid->h - 4); winwid->click_offset_y += winwid->h - 4; } if ((winwid->im_x != orig_x) || (winwid->im_y != orig_y)) winwidget_render_image(winwid, 0, 1); } } else if (opt.mode == MODE_ROTATE) { while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); winwid = winwidget_get_from_window(ev->xmotion.window); if (winwid) { D(("Rotating\n")); if (!winwid->has_rotated) { 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); 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)); winwidget_render_image(winwid, 0, 1); } } else if (opt.mode == MODE_BLUR) { while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); winwid = winwidget_get_from_window(ev->xmotion.window); if (winwid) { Imlib_Image temp, ptr; signed int blur_radius; 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; } } 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); } } return; }
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; if (menu_root) { /* if menus are open, close them, and execute action if needed */ if (ev->xbutton.window == menu_cover) { feh_menu_hide(menu_root, True); } else if (menu_root) { feh_menu *m; if ((m = feh_menu_get_from_window(ev->xbutton.window))) { feh_menu_item *i = NULL; i = feh_menu_find_selected(m); feh_menu_item_activate(m, i); } } return; } winwid = winwidget_get_from_window(ev->xbutton.window); if (winwid == NULL || winwid->caption_entry) { return; } if (feh_is_bb(&buttons.pan, button, state)) { if (opt.mode == MODE_PAN) { D(("Disabling pan mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } 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) { feh_file *thumbfile; int x, y; x = ev->xbutton.x; y = ev->xbutton.y; x -= winwid->im_x; y -= winwid->im_y; x /= winwid->zoom; y /= winwid->zoom; thumbfile = feh_thumbnail_get_file_from_coords(x, y); if (thumbfile) { if (opt.actions[0]) feh_action_run(thumbfile, opt.actions[0]); else feh_thumbnail_show_fullsize(thumbfile); } } } else { opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; } } else if (feh_is_bb(&buttons.rotate, button, state) || feh_is_bb(&buttons.zoom, button, state)) { D(("Disabling mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; if ((feh_is_bb(&buttons.zoom, button, state)) && (ev->xbutton.x == winwid->click_offset_x) && (ev->xbutton.y == winwid->click_offset_y)) { winwid->zoom = 1.0; winwidget_center_image(winwid); } else winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_bb(&buttons.blur, button, state)) { D(("Disabling Blur mode\n")); opt.mode = MODE_NORMAL; winwid->mode = MODE_NORMAL; } return; }
static void feh_event_handle_ButtonPress(XEvent * ev) { winwidget winwid = NULL; int state, button; /* get the heck out if it's a mouse-click on the cover, we'll hide the menus on release */ if (ev->xbutton.window == menu_cover) { return; } winwid = winwidget_get_from_window(ev->xbutton.window); if (winwid == NULL || winwid->caption_entry) { return; } state = ev->xbutton.state & (ControlMask | ShiftMask | Mod1Mask | Mod4Mask); button = ev->xbutton.button; if (!opt.no_menus && feh_is_bb(&buttons.menu, button, state)) { D(("Menu Button Press event\n")); winwidget_show_menu(winwid); } else if (feh_is_bb(&buttons.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) && (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)) { D(("Next button, but could be pan mode\n")); opt.mode = MODE_NEXT; winwid->mode = MODE_NEXT; D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x - winwid->im_x; 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)) { D(("Zoom Button Press event\n")); opt.mode = MODE_ZOOM; winwid->mode = MODE_ZOOM; D(("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); winwid->click_offset_x = ev->xbutton.x; winwid->click_offset_y = ev->xbutton.y; winwid->old_zoom = winwid->zoom; /* required to adjust the image position in zoom mode */ winwid->im_click_offset_x = (winwid->click_offset_x - winwid->im_x) / winwid->old_zoom; 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)) { 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; winwid->click_offset_y = ev->xbutton.y; winwid->old_zoom = winwid->zoom; /* required to adjust the image position in zoom mode */ winwid->im_click_offset_x = (winwid->click_offset_x - winwid->im_x) / winwid->old_zoom; winwid->im_click_offset_y = (winwid->click_offset_y - winwid->im_y) / winwid->old_zoom; /* copied from zoom_in, keyevents.c */ winwid->zoom = winwid->zoom * 1.25; if (winwid->zoom > ZOOM_MAX) winwid->zoom = ZOOM_MAX; /* copied from below (ZOOM, feh_event_handle_MotionNotify) */ winwid->im_x = winwid->click_offset_x - (winwid->im_click_offset_x * winwid->zoom); winwid->im_y = winwid->click_offset_y - (winwid->im_click_offset_y * winwid->zoom); winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_bb(&buttons.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; winwid->click_offset_y = ev->xbutton.y; winwid->old_zoom = winwid->zoom; /* required to adjust the image position in zoom mode */ winwid->im_click_offset_x = (winwid->click_offset_x - winwid->im_x) / winwid->old_zoom; winwid->im_click_offset_y = (winwid->click_offset_y - winwid->im_y) / winwid->old_zoom; /* copied from zoom_out, keyevents.c */ winwid->zoom = winwid->zoom * 0.80; if (winwid->zoom < ZOOM_MIN) winwid->zoom = ZOOM_MIN; /* copied from below (ZOOM, feh_event_handle_MotionNotify) */ winwid->im_x = winwid->click_offset_x - (winwid->im_click_offset_x * winwid->zoom); winwid->im_y = winwid->click_offset_y - (winwid->im_click_offset_y * winwid->zoom); winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_bb(&buttons.reload, button, state)) { D(("Reload Button Press event\n")); feh_reload_image(winwid, 0, 1); } else if (feh_is_bb(&buttons.prev, 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)) { 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")); } return; }
void feh_event_handle_keypress(XEvent * ev) { int len; char kbuf[20]; KeySym keysym; XKeyEvent *kev; winwidget winwid = NULL; int curr_screen = 0; feh_menu_item *selected_item; feh_menu *selected_menu; D_ENTER(4); winwid = winwidget_get_from_window(ev->xkey.window); /* nuke dupe events, unless we're typing text */ if (winwid && !winwid->caption_entry) { while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev)); } kev = (XKeyEvent *) ev; len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); /* menus are showing, so this is a menu control keypress */ if (ev->xbutton.window == menu_cover) { selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); switch (keysym) { case XK_Escape: feh_menu_hide(menu_root, True); break; case XK_Left: feh_menu_select_parent(selected_menu, selected_item); break; case XK_Down: feh_menu_select_next(selected_menu, selected_item); break; case XK_Up: feh_menu_select_prev(selected_menu, selected_item); break; case XK_Right: feh_menu_select_submenu(selected_menu, selected_item); break; case XK_Return: feh_menu_item_activate(selected_menu, selected_item); break; default: break; } if (len <= 0 || len > (int) sizeof(kbuf)) D_RETURN_(4); kbuf[len] = '\0'; switch (*kbuf) { case 'h': feh_menu_select_parent(selected_menu, selected_item); break; case 'j': feh_menu_select_next(selected_menu, selected_item); break; case 'k': feh_menu_select_prev(selected_menu, selected_item); break; case 'l': feh_menu_select_submenu(selected_menu, selected_item); break; case ' ': feh_menu_item_activate(selected_menu, selected_item); break; default: break; } D_RETURN_(4); } if (winwid == NULL) D_RETURN_(4); if (winwid->caption_entry) { switch (keysym) { case XK_Return: if (kev->state & ControlMask) { /* insert actual newline */ ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); winwidget_render_image_cached(winwid); } else { /* finish caption entry, write to captions file */ FILE *fp; char *caption_filename; caption_filename = build_caption_filename(FEH_FILE(winwid->file->data)); winwid->caption_entry = 0; winwidget_render_image_cached(winwid); XFreePixmap(disp, winwid->bg_pmap_cache); winwid->bg_pmap_cache = 0; fp = fopen(caption_filename, "w"); if (!fp) { weprintf("couldn't write to captions file %s:", caption_filename); D_RETURN_(4); } fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); free(caption_filename); fclose(fp); } break; case XK_Escape: /* cancel, revert caption */ winwid->caption_entry = 0; free(FEH_FILE(winwid->file->data)->caption); FEH_FILE(winwid->file->data)->caption = NULL; winwidget_render_image_cached(winwid); XFreePixmap(disp, winwid->bg_pmap_cache); winwid->bg_pmap_cache = 0; break; case XK_BackSpace: /* backspace */ ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); winwidget_render_image_cached(winwid); break; default: if (isascii(keysym)) { /* append to caption */ ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); winwidget_render_image_cached(winwid); } break; } D_RETURN_(4); } switch (keysym) { case XK_Left: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV); break; case XK_Right: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT); break; case XK_Page_Up: case XK_KP_Page_Up: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_BACK); break; case XK_Escape: winwidget_destroy_all(); break; case XK_Page_Down: case XK_KP_Page_Down: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_FWD); break; case XK_Delete: /* Holding ctrl gets you a filesystem deletion and removal from the * filelist. Just DEL gets you filelist removal only. */ if (kev->state & ControlMask) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1); feh_filelist_image_remove(winwid, 1); } else { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); feh_filelist_image_remove(winwid, 0); } break; case XK_Home: case XK_KP_Home: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_FIRST); break; case XK_End: case XK_KP_End: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_LAST); break; case XK_Return: feh_event_invoke_action(winwid, opt.actions[0]); break; case XK_0: feh_event_invoke_action(winwid, opt.actions[0]); break; case XK_1: feh_event_invoke_action(winwid, opt.actions[1]); break; case XK_2: feh_event_invoke_action(winwid, opt.actions[2]); break; case XK_3: feh_event_invoke_action(winwid, opt.actions[3]); break; case XK_4: feh_event_invoke_action(winwid, opt.actions[4]); break; case XK_5: feh_event_invoke_action(winwid, opt.actions[5]); break; case XK_6: feh_event_invoke_action(winwid, opt.actions[6]); break; case XK_7: feh_event_invoke_action(winwid, opt.actions[7]); break; case XK_8: feh_event_invoke_action(winwid, opt.actions[8]); break; case XK_9: feh_event_invoke_action(winwid, opt.actions[9]); break; case XK_KP_Left: winwid->im_x = winwid->im_x - 10; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Right: winwid->im_x = winwid->im_x + 10; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Up: winwid->im_y = winwid->im_y - 10; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Down: winwid->im_y = winwid->im_y + 10; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Add: /* erroneously recognized as '+' in the *kbuf switch. Work around this. */ len = 0; winwid->zoom = winwid->zoom * 1.25; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Subtract: len = 0; winwid->zoom = winwid->zoom * 0.75; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Multiply: len = 0; winwid->zoom = 1; winwidget_render_image(winwid, 0, 0); break; case XK_KP_Divide: len = 0; feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); winwidget_render_image(winwid, 0, 1); break; case XK_KP_Begin: winwidget_render_image(winwid, 0, 1); break; default: break; } if (len <= 0 || len > (int) sizeof(kbuf)) D_RETURN_(4); kbuf[len] = '\0'; switch (*kbuf) { case 'a': case 'A': opt.draw_actions = !opt.draw_actions; winwidget_rerender_all(0, 1); break; case 'd': case 'D': opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0, 1); break; case 'n': case 'N': case ' ': if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT); break; case 'p': case 'P': case '\b': if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV); break; case 'z': case 'Z': if (opt.slideshow) slideshow_change_image(winwid, SLIDE_RAND); break; case 'q': case 'Q': winwidget_destroy_all(); break; case 'c': case 'C': if (opt.caption_path) winwid->caption_entry = 1; winwidget_render_image(winwid, 0, 1); break; case 'r': case 'R': feh_reload_image(winwid, 0, 0); break; case 'h': case 'H': slideshow_pause_toggle(winwid); break; case 's': case 'S': slideshow_save_image(winwid); break; case 'f': case 'F': feh_save_filelist(); break; case 'w': case 'W': winwidget_size_to_image(winwid); break; case 'm': case 'M': winwidget_show_menu(winwid); break; case 'x': case 'X': winwidget_destroy(winwid); break; case '>': feh_edit_inplace_orient(winwid, 1); break; case '<': feh_edit_inplace_orient(winwid, 3); break; case 'v': case 'V': #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { int i, rect[4]; winwidget_get_geometry(winwid, rect); /* printf("window: (%d, %d)\n", rect[0], rect[1]); printf("found %d screens.\n", num_xinerama_screens); */ for (i = 0; i < num_xinerama_screens; i++) { xinerama_screen = 0; /* printf("%d: [%d, %d, %d, %d] (%d, %d)\n", i, xinerama_screens[i].x_org, xinerama_screens[i].y_org, xinerama_screens[i].width, xinerama_screens[i].height, rect[0], rect[1]); */ if (XY_IN_RECT(rect[0], rect[1], xinerama_screens[i].x_org, xinerama_screens[i].y_org, xinerama_screens[i].width, xinerama_screens[i].height)) { curr_screen = xinerama_screen = i; break; } } } #endif /* HAVE_LIBXINERAMA */ winwid->full_screen = !winwid->full_screen; winwidget_destroy_xwin(winwid); winwidget_create_window(winwid, winwid->im_w, winwid->im_h); winwidget_render_image(winwid, 1, 1); winwidget_show(winwid); #ifdef HAVE_LIBXINERAMA /* if we have xinerama and we're using it, then full screen the window * on the head that the window was active on */ if (winwid->full_screen == TRUE && opt.xinerama && xinerama_screens) { xinerama_screen = curr_screen; winwidget_move(winwid, xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org); } #endif /* HAVE_LIBXINERAMA */ case '=': case '+': if (opt.reload < SLIDESHOW_RELOAD_MAX) opt.reload++; else if (opt.verbose) weprintf("Cannot set RELOAD higher than %d seconds.", opt.reload); break; case '-': case '_': if (opt.reload > 1) opt.reload--; else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); break; default: break; } D_RETURN_(4); }