void feh_filelist_image_remove(winwidget winwid, char do_delete) { if (winwid->type == WIN_TYPE_SLIDESHOW) { char *s; gib_list *doomed; doomed = current_file; slideshow_change_image(winwid, SLIDE_NEXT, 0); if (do_delete) filelist = feh_file_rm_and_free(filelist, doomed); else filelist = feh_file_remove_from_list(filelist, doomed); if (!filelist) { /* No more images. Game over ;-) */ winwidget_destroy(winwid); return; } s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid); winwidget_rename(winwid, s); free(s); winwidget_render_image(winwid, 1, 0); } else if ((winwid->type == WIN_TYPE_SINGLE) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { if (do_delete) filelist = feh_file_rm_and_free(filelist, winwid->file); else filelist = feh_file_remove_from_list(filelist, winwid->file); winwidget_destroy(winwid); } }
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; }
winwidget winwidget_create_from_file(gib_list * list, char *name, char type) { winwidget ret = NULL; feh_file *file = FEH_FILE(list->data); if (!file || !file->filename) return(NULL); ret = winwidget_allocate(); ret->file = list; ret->type = type; if (name) ret->name = estrdup(name); else ret->name = estrdup(file->filename); if (winwidget_loadimage(ret, file) == 0) { winwidget_destroy(ret); return(NULL); } if (!ret->win) { ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); D(("image is %dx%d pixels, format %s\n", ret->w, ret->h, gib_imlib_image_format(ret->im))); if (opt.full_screen) ret->full_screen = True; winwidget_create_window(ret, ret->w, ret->h); winwidget_render_image(ret, 1, 0); } return(ret); }
winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type) { winwidget ret = NULL; if (im == NULL) return(NULL); ret = winwidget_allocate(); ret->type = type; ret->im = im; ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); if (name) ret->name = estrdup(name); else ret->name = estrdup(PACKAGE); if (opt.full_screen && (type != WIN_TYPE_THUMBNAIL)) ret->full_screen = True; winwidget_create_window(ret, ret->w, ret->h); winwidget_render_image(ret, 1, 0); return(ret); }
void feh_edit_inplace(winwidget w, int op) { int tmp; Imlib_Image old = NULL; Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; if (!w->file || !w->file->data || !FEH_FILE(w->file->data)->filename) return; if (!strcmp(gib_imlib_image_format(w->im), "jpeg") && !path_is_url(FEH_FILE(w->file->data)->filename)) { feh_edit_inplace_lossless(w, op); feh_reload_image(w, 1, 1); return; } old = imlib_load_image_with_error_return(FEH_FILE(w->file->data)->filename, &err); if ((old != NULL) && (err == IMLIB_LOAD_ERROR_NONE)) { imlib_context_set_image(old); if (op == INPLACE_EDIT_FLIP) imlib_image_flip_vertical(); else if (op == INPLACE_EDIT_MIRROR) imlib_image_flip_horizontal(); else imlib_image_orientate(op); gib_imlib_save_image_with_error_return(old, FEH_FILE(w->file->data)->filename, &err); gib_imlib_free_image(old); if (err) feh_imlib_print_load_error(FEH_FILE(w->file->data)->filename, w, err); feh_reload_image(w, 1, 1); } else { /* * Image was opened using curl/magick or has been deleted after * opening it */ imlib_context_set_image(w->im); if (op == INPLACE_EDIT_FLIP) imlib_image_flip_vertical(); else if (op == INPLACE_EDIT_MIRROR) imlib_image_flip_horizontal(); else { imlib_image_orientate(op); tmp = w->im_w; FEH_FILE(w->file->data)->info->width = w->im_w = w->im_h; FEH_FILE(w->file->data)->info->height = w->im_h = tmp; } im_weprintf(w, "unable to edit in place. Changes have not been saved."); winwidget_render_image(w, 1, 0); } return; }
void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i) { int curr_screen = 0; MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) m->fehwin->full_screen = TRUE; else m->fehwin->full_screen = FALSE; #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { int i, rect[4]; winwidget_get_geometry(m->fehwin, 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; } } if (getenv("XINERAMA_SCREEN")) curr_screen = xinerama_screen = atoi(getenv("XINERAMA_SCREEN")); } #endif /* HAVE_LIBXINERAMA */ winwidget_destroy_xwin(m->fehwin); winwidget_create_window(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); winwidget_render_image(m->fehwin, 1, 1); winwidget_show(m->fehwin); #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 (m->fehwin->full_screen == TRUE && opt.xinerama && xinerama_screens) { xinerama_screen = curr_screen; winwidget_move(m->fehwin, xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org); } #endif /* HAVE_LIBXINERAMA */ }
void feh_filelist_image_remove(winwidget winwid, char do_delete) { if (winwid->type == WIN_TYPE_SLIDESHOW) { char *s; gib_list *doomed; doomed = current_file; /* * work around feh_list_jump exiting if cycle_once is enabled * and no further files are left (we need to delete first) */ if (opt.cycle_once && ! doomed->next && do_delete) { feh_file_rm_and_free(filelist, doomed); exit(0); } if (doomed->next) { slideshow_change_image(winwid, SLIDE_NEXT, 0); } else { slideshow_change_image(winwid, SLIDE_PREV, 0); } if (do_delete) filelist = feh_file_rm_and_free(filelist, doomed); else filelist = feh_file_remove_from_list(filelist, doomed); if (!filelist) { /* No more images. Game over ;-) */ winwidget_destroy(winwid); return; } s = slideshow_create_name(FEH_FILE(winwid->file->data), winwid); winwidget_rename(winwid, s); free(s); winwidget_render_image(winwid, 1, 0); } else if ((winwid->type == WIN_TYPE_SINGLE) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { if (do_delete) filelist = feh_file_rm_and_free(filelist, winwid->file); else filelist = feh_file_remove_from_list(filelist, winwid->file); winwidget_destroy(winwid); } }
void feh_filelist_image_remove(winwidget winwid, char do_delete) { if (winwid->type == WIN_TYPE_SLIDESHOW) { gib_list *doomed; doomed = current_file; /* * work around feh_list_jump exiting if ON_LAST_SLIDE_QUIT is set * and no further files are left (we need to delete first) */ if (opt.on_last_slide == ON_LAST_SLIDE_QUIT && ! doomed->next && do_delete) { feh_file_rm_and_free(filelist, doomed); exit(0); } if (doomed->next) { slideshow_change_image(winwid, SLIDE_NEXT, 0); } else { slideshow_change_image(winwid, SLIDE_PREV, 0); } if (do_delete) filelist = feh_file_rm_and_free(filelist, doomed); else filelist = feh_file_remove_from_list(filelist, doomed); if (!filelist) { /* No more images. Game over ;-) */ winwidget_destroy(winwid); return; } winwidget_render_image(winwid, 1, 0); } else if ((winwid->type == WIN_TYPE_SINGLE) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { if (do_delete) filelist = feh_file_rm_and_free(filelist, winwid->file); else filelist = feh_file_remove_from_list(filelist, winwid->file); winwid->file = NULL; winwidget_destroy(winwid); } }
void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysym, unsigned int button) { int curr_screen = 0; if (winwid->caption_entry && (keysym != NoSymbol)) { 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; } if (feh_is_kp(EVENT_next_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_NEXT, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 1); } else if (feh_is_kp(EVENT_prev_img, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_PREV, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 1); } else if (feh_is_kp(EVENT_scroll_right, state, keysym, button)) { winwid->im_x -= opt.scroll_step;; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } else if (feh_is_kp(EVENT_scroll_left, state, keysym, button)) { winwid->im_x += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } else if (feh_is_kp(EVENT_scroll_down, state, keysym, button)) { winwid->im_y -= opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } else if (feh_is_kp(EVENT_scroll_up, state, keysym, button)) { winwid->im_y += opt.scroll_step; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 1); } else if (feh_is_kp(EVENT_scroll_right_page, state, keysym, button)) { winwid->im_x -= winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_scroll_left_page, state, keysym, button)) { winwid->im_x += winwid->w; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_scroll_down_page, state, keysym, button)) { winwid->im_y -= winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_scroll_up_page, state, keysym, button)) { winwid->im_y += winwid->h; winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_jump_back, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_BACK, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_prev(winwid, 10); } else if (feh_is_kp(EVENT_jump_fwd, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_FWD, 1); else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 10); } else if (feh_is_kp(EVENT_next_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1); } else if (feh_is_kp(EVENT_prev_dir, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1); } else if (feh_is_kp(EVENT_quit, state, keysym, button)) { winwidget_destroy_all(); } else if (feh_is_kp(EVENT_delete, state, keysym, button)) { 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 (feh_is_kp(EVENT_remove, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); feh_filelist_image_remove(winwid, 0); } else if (feh_is_kp(EVENT_jump_first, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_FIRST, 1); } else if (feh_is_kp(EVENT_jump_last, state, keysym, button)) { if (opt.slideshow) slideshow_change_image(winwid, SLIDE_LAST, 1); } else if (feh_is_kp(EVENT_action_0, state, keysym, button)) { feh_event_invoke_action(winwid, 0); } else if (feh_is_kp(EVENT_action_1, state, keysym, button)) { feh_event_invoke_action(winwid, 1); } else if (feh_is_kp(EVENT_action_2, state, keysym, button)) { feh_event_invoke_action(winwid, 2); } else if (feh_is_kp(EVENT_action_3, state, keysym, button)) { feh_event_invoke_action(winwid, 3); } else if (feh_is_kp(EVENT_action_4, state, keysym, button)) { feh_event_invoke_action(winwid, 4); } else if (feh_is_kp(EVENT_action_5, state, keysym, button)) { feh_event_invoke_action(winwid, 5); } else if (feh_is_kp(EVENT_action_6, state, keysym, button)) { feh_event_invoke_action(winwid, 6); } else if (feh_is_kp(EVENT_action_7, state, keysym, button)) { feh_event_invoke_action(winwid, 7); } else if (feh_is_kp(EVENT_action_8, state, keysym, button)) { feh_event_invoke_action(winwid, 8); } else if (feh_is_kp(EVENT_action_9, state, keysym, button)) { feh_event_invoke_action(winwid, 9); } else if (feh_is_kp(EVENT_zoom_in, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 1.25; if (winwid->zoom > ZOOM_MAX) winwid->zoom = ZOOM_MAX; winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) / winwid->old_zoom * winwid->zoom); winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) / winwid->old_zoom * winwid->zoom); winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_zoom_out, state, keysym, button)) { winwid->old_zoom = winwid->zoom; winwid->zoom = winwid->zoom * 0.80; if (winwid->zoom < ZOOM_MIN) winwid->zoom = ZOOM_MIN; winwid->im_x = (winwid->w / 2) - (((winwid->w / 2) - winwid->im_x) / winwid->old_zoom * winwid->zoom); winwid->im_y = (winwid->h / 2) - (((winwid->h / 2) - winwid->im_y) / winwid->old_zoom * winwid->zoom); winwidget_sanitise_offsets(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_zoom_default, state, keysym, button)) { winwid->zoom = 1.0; winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_zoom_fit, state, keysym, button)) { feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_zoom_fill, state, keysym, button)) { int save_zoom = opt.zoom_mode; opt.zoom_mode = ZOOM_MODE_FILL; feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); opt.zoom_mode = save_zoom; } else if (feh_is_kp(EVENT_render, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_show_selected(); else winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_toggle_actions, state, keysym, button)) { opt.draw_actions = !opt.draw_actions; winwidget_rerender_all(0); } else if (feh_is_kp(EVENT_toggle_aliasing, state, keysym, button)) { opt.force_aliasing = !opt.force_aliasing; winwid->force_aliasing = !winwid->force_aliasing; winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_toggle_auto_zoom, state, keysym, button)) { opt.zoom_mode = (opt.zoom_mode == 0 ? ZOOM_MODE_MAX : 0); winwidget_rerender_all(1); } else if (feh_is_kp(EVENT_toggle_filenames, state, keysym, button)) { opt.draw_filename = !opt.draw_filename; winwidget_rerender_all(0); } #ifdef HAVE_LIBEXIF else if (feh_is_kp(EVENT_toggle_exif, state, keysym, button)) { opt.draw_exif = !opt.draw_exif; winwidget_rerender_all(0); } #endif else if (feh_is_kp(EVENT_toggle_info, state, keysym, button)) { opt.draw_info = !opt.draw_info; winwidget_rerender_all(0); } else if (feh_is_kp(EVENT_toggle_pointer, state, keysym, button)) { winwidget_set_pointer(winwid, opt.hide_pointer); opt.hide_pointer = !opt.hide_pointer; } else if (feh_is_kp(EVENT_jump_random, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, random() % (filelist_len - 1)); else slideshow_change_image(winwid, SLIDE_RAND, 1); } else if (feh_is_kp(EVENT_toggle_caption, state, keysym, button)) { if (opt.caption_path) { /* * editing captions in slideshow mode does not make any sense * at all; this is just in case someone accidentally does it... */ if (opt.slideshow_delay) opt.paused = 1; winwid->caption_entry = 1; } winwidget_render_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_reload_image, state, keysym, button)) { feh_reload_image(winwid, 0, 0); } else if (feh_is_kp(EVENT_toggle_pause, state, keysym, button)) { slideshow_pause_toggle(winwid); } else if (feh_is_kp(EVENT_save_image, state, keysym, button)) { slideshow_save_image(winwid); } else if (feh_is_kp(EVENT_save_filelist, state, keysym, button)) { if ((winwid->type == WIN_TYPE_THUMBNAIL) || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) weprintf("Filelist saving is not supported in thumbnail mode"); else feh_save_filelist(); } else if (feh_is_kp(EVENT_size_to_image, state, keysym, button)) { winwidget_size_to_image(winwid); } else if (!opt.no_menus && feh_is_kp(EVENT_toggle_menu, state, keysym, button)) { winwidget_show_menu(winwid); } else if (feh_is_kp(EVENT_close, state, keysym, button)) { winwidget_destroy(winwid); } else if (feh_is_kp(EVENT_orient_1, state, keysym, button)) { feh_edit_inplace(winwid, 1); } else if (feh_is_kp(EVENT_orient_3, state, keysym, button)) { feh_edit_inplace(winwid, 3); } else if (feh_is_kp(EVENT_flip, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_FLIP); } else if (feh_is_kp(EVENT_mirror, state, keysym, button)) { feh_edit_inplace(winwid, INPLACE_EDIT_MIRROR); } else if (feh_is_kp(EVENT_toggle_fullscreen, state, keysym, button)) { #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { int i, rect[4]; winwidget_get_geometry(winwid, rect); for (i = 0; i < num_xinerama_screens; i++) { xinerama_screen = 0; 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; } } if (opt.xinerama_index >= 0) curr_screen = xinerama_screen = opt.xinerama_index; } #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, 0); 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 */ } else if (feh_is_kp(EVENT_reload_plus, state, keysym, button)){ if (opt.reload < SLIDESHOW_RELOAD_MAX) opt.reload++; else if (opt.verbose) weprintf("Cannot set RELOAD higher than %f seconds.", opt.reload); } else if (feh_is_kp(EVENT_reload_minus, state, keysym, button)) { if (opt.reload > 1) opt.reload--; else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); } else if (feh_is_kp(EVENT_toggle_keep_vp, state, keysym, button)) { opt.keep_zoom_vp = !opt.keep_zoom_vp; } else if (feh_is_kp(EVENT_toggle_fixed_geometry, state, keysym, button)) { if (opt.geom_flags & ((WidthValue | HeightValue))) { opt.geom_flags &= ~(WidthValue | HeightValue); } else { opt.geom_flags |= (WidthValue | HeightValue); opt.geom_w = winwid->w; opt.geom_h = winwid->h; } winwidget_render_image(winwid, 1, 0); } 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; }
/* TODO s/bit/lot */ void init_thumbnail_mode(void) { /* moved to thumbnail_data: Imlib_Image im_main; Imlib_Image bg_im = NULL; Imlib_Font fn = NULL; Imlib_Font title_fn = NULL; int w = 800, h = 600; int bg_w = 0, bg_h = 0; int text_area_w, text_area_h; int max_column_w = 0; */ Imlib_Image im_temp; int ww = 0, hh = 0, www, hhh, xxx, yyy; int x = 0, y = 0; winwidget winwid = NULL; Imlib_Image im_thumb = NULL; unsigned char trans_bg = 0; int title_area_h = 0; int tw = 0, th = 0; int fw_name, fw_size, fw_dim, fh; int thumbnailcount = 0; feh_file *file = NULL; gib_list *l, *last = NULL; int lines; int index_image_width, index_image_height; int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0; char *s; unsigned int thumb_counter = 0; /* initialize thumbnail mode data */ td.im_main = NULL; td.im_bg = NULL; td.font_main = NULL; td.font_title = NULL; td.w = 640; td.h = 480; td.bg_w = 0; td.bg_h = 0; td.thumb_tot_h = 0; td.text_area_w = 0; td.text_area_h = 0; td.vertical = 0; td.max_column_w = 0; mode = "thumbnail"; if (opt.font) td.font_main = gib_imlib_load_font(opt.font); if (!td.font_main) td.font_main = gib_imlib_load_font(DEFAULT_FONT); if (opt.title_font) { int fh, fw; td.font_title = gib_imlib_load_font(opt.title_font); gib_imlib_get_text_size(td.font_title, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); title_area_h = fh + 4; } else td.font_title = imlib_load_font(DEFAULT_FONT_TITLE); if ((!td.font_main) || (!td.font_title)) eprintf("Error loading fonts"); /* Work out how tall the font is */ gib_imlib_get_text_size(td.font_main, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); /* For now, allow room for the right number of lines with small gaps */ td.text_area_h = ((th + 2) * (opt.index_show_name + opt.index_show_size + opt.index_show_dim)) + 5; /* This includes the text area for index data */ td.thumb_tot_h = opt.thumb_h + td.text_area_h; /* Use bg image dimensions for default size */ if (opt.bg && opt.bg_file) { if (!strcmp(opt.bg_file, "trans")) trans_bg = 1; else { D(3, ("Time to apply a background to blend onto\n")); if (feh_load_image_char(&td.im_bg, opt.bg_file) != 0) { td.bg_w = gib_imlib_image_get_width(td.im_bg); td.bg_h = gib_imlib_image_get_height(td.im_bg); } } } /* figure out geometry for the main window and entries */ feh_thumbnail_calculate_geometry(); index_image_width = td.w; index_image_height = td.h + title_area_h; td.im_main = imlib_create_image(index_image_width, index_image_height); gib_imlib_image_set_has_alpha(td.im_main, 1); if (!td.im_main) eprintf("Imlib error creating index image, are you low on RAM?"); if (td.im_bg) gib_imlib_blend_image_onto_image(td.im_main, td.im_bg, gib_imlib_image_has_alpha (td.im_bg), 0, 0, td.bg_w, td.bg_h, 0, 0, td.w, td.h, 1, 0, 0); else if (trans_bg) { gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, 0, 0); gib_imlib_image_set_has_alpha(td.im_main, 1); } else { /* Colour the background */ gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, 0, 255); } /* Create title now */ if (!opt.title) s = estrdup(PACKAGE " [thumbnail mode]"); else s = estrdup(feh_printf(opt.title, NULL)); if (opt.display) { winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL); winwidget_show(winwid); } /* make sure we have an ~/.thumbnails/normal directory for storing permanent thumbnails */ td.cache_thumbnails = opt.cache_thumbnails; if (td.cache_thumbnails) { if (opt.thumb_w > opt.thumb_h) td.cache_dim = opt.thumb_w; else td.cache_dim = opt.thumb_h; if (td.cache_dim > 256) { /* No caching as specified by standard. Sort of. */ td.cache_thumbnails = 0; } else if (td.cache_dim > 128) { td.cache_dim = 256; td.cache_dir = estrdup("large"); } else { td.cache_dim = 128; td.cache_dir = estrdup("normal"); } feh_thumbnail_setup_thumbnail_dir(); } for (l = filelist; l; l = l->next) { file = FEH_FILE(l->data); if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } D(4, ("About to load image %s\n", file->filename)); /* if (feh_load_image(&im_temp, file) != 0) */ if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) { if (opt.verbose) feh_display_status('.'); D(4, ("Successfully loaded %s\n", file->filename)); www = opt.thumb_w; hhh = opt.thumb_h; ww = gib_imlib_image_get_width(im_temp); hh = gib_imlib_image_get_height(im_temp); thumbnailcount++; if (gib_imlib_image_has_alpha(im_temp)) imlib_context_set_blend(1); else imlib_context_set_blend(0); if (opt.aspect) { double ratio = 0.0; /* Keep the aspect ratio for the thumbnail */ ratio = ((double) ww / hh) / ((double) www / hhh); if (ratio > 1.0) hhh = opt.thumb_h / ratio; else if (ratio != 1.0) www = opt.thumb_w * ratio; } if ((!opt.stretch) && ((www > ww) || (hhh > hh))) { /* Don't make the image larger unless stretch is specified */ www = ww; hhh = hh; } im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, hhh, 1); gib_imlib_free_image_and_decache(im_temp); if (opt.alpha) { DATA8 atab[256]; D(3, ("Applying alpha options\n")); gib_imlib_image_set_has_alpha(im_thumb, 1); memset(atab, opt.alpha_level, sizeof(atab)); gib_imlib_apply_color_modifier_to_rectangle (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab); } td.text_area_w = opt.thumb_w; /* Now draw on the info text */ if (opt.index_show_name) { gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw_name, &fh, IMLIB_TEXT_TO_RIGHT); if (fw_name > td.text_area_w) td.text_area_w = fw_name; } if (opt.index_show_dim) { gib_imlib_get_text_size(td.font_main, create_index_dimension_string(ww, hh), NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT); if (fw_dim > td.text_area_w) td.text_area_w = fw_dim; } if (opt.index_show_size) { gib_imlib_get_text_size(td.font_main, create_index_size_string(file->filename), NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT); if (fw_size > td.text_area_w) td.text_area_w = fw_size; } if (td.text_area_w > opt.thumb_w) td.text_area_w += 5; /* offsets for centering text */ x_offset_name = (td.text_area_w - fw_name) / 2; x_offset_dim = (td.text_area_w - fw_dim) / 2; x_offset_size = (td.text_area_w - fw_size) / 2; if (td.vertical) { if (td.text_area_w > td.max_column_w) td.max_column_w = td.text_area_w; if (y > td.h - td.thumb_tot_h) { y = 0; x += td.max_column_w; td.max_column_w = 0; } if (x > td.w - td.text_area_w) break; } else { if (x > td.w - td.text_area_w) { x = 0; y += td.thumb_tot_h; } if (y > td.h - td.thumb_tot_h) break; } /* center image relative to the text below it (if any) */ xxx = x + ((td.text_area_w - www) / 2); yyy = y; if (opt.aspect) yyy += (opt.thumb_h - hhh) / 2; /* Draw now */ gib_imlib_blend_image_onto_image(td.im_main, im_thumb, gib_imlib_image_has_alpha (im_thumb), 0, 0, www, hhh, xxx, yyy, www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0); thumbnails = gib_list_add_front(thumbnails, feh_thumbnail_new(file, xxx, yyy, www, hhh)); gib_imlib_free_image_and_decache(im_thumb); lines = 0; if (opt.index_show_name) gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_name, y + opt.thumb_h + (lines++ * (th + 2)) + 2, file->name, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); if (opt.index_show_dim) gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_dim, y + opt.thumb_h + (lines++ * (th + 2)) + 2, create_index_dimension_string(ww, hh), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); if (opt.index_show_size) gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_size, y + opt.thumb_h + (lines++ * (th + 2)) + 2, create_index_size_string(file->filename), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); if (td.vertical) y += td.thumb_tot_h; else x += td.text_area_w; } else { if (opt.verbose) feh_display_status('x'); last = l; } if (opt.display) { /* thumb_counter is unsigned, so no need to catch overflows */ if (++thumb_counter == opt.thumb_redraw) { winwidget_render_image(winwid, 0, 0); thumb_counter = 0; } if (!feh_main_iteration(0)) exit(0); } } if (thumb_counter != 0) winwidget_render_image(winwid, 0, 0); if (opt.verbose) fprintf(stdout, "\n"); if (opt.title_font) { int fw, fh, fx, fy; char *s; s = create_index_title_string(thumbnailcount, td.w, td.h); gib_imlib_get_text_size(td.font_title, s, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); fx = (index_image_width - fw) >> 1; fy = index_image_height - fh - 2; gib_imlib_text_draw(td.im_main, td.font_title, NULL, fx, fy, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); }
void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; int i = 0; int jmp = 1; /* We can't use filelist_len in the for loop, since that changes when we * encounter invalid images. */ int our_filelist_len = filelist_len; char *s; unsigned char tmode =0; int tim_x =0; int tim_y =0; double tzoom =0; /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ if (filelist_len < 2 && opt.cycle_once == 0) return; /* Ok. I do this in such an odd way to ensure that if the last or first * image is not loadable, it will go through in the right direction to * find the correct one. Otherwise SLIDE_LAST would try the last file, * then loop forward to find a loadable one. */ if (change == SLIDE_FIRST) { current_file = gib_list_last(filelist); change = SLIDE_NEXT; } else if (change == SLIDE_LAST) { current_file = filelist; change = SLIDE_PREV; } /* The for loop prevents us looping infinitely */ for (i = 0; i < our_filelist_len; i++) { winwidget_free_image(winwid); switch (change) { case SLIDE_NEXT: current_file = feh_list_jump(filelist, current_file, FORWARD, 1); break; case SLIDE_PREV: current_file = feh_list_jump(filelist, current_file, BACK, 1); break; case SLIDE_RAND: if (filelist_len > 1) { current_file = feh_list_jump(filelist, current_file, FORWARD, (rand() % (filelist_len - 1)) + 1); change = SLIDE_NEXT; } break; case SLIDE_JUMP_FWD: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); /* important. if the load fails, we only want to step on ONCE to try the next file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_BACK: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, BACK, jmp); /* important. if the load fails, we only want to step back ONCE to try the previous file, not another jmp */ change = SLIDE_NEXT; break; default: eprintf("BUG!\n"); break; } if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } if (opt.keep_zoom_vp) { /* pre loadimage - record settings */ tmode = winwid->mode; tim_x = winwid->im_x; tim_y = winwid->im_y; tzoom = winwid->zoom; } if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) != 0) { winwid->mode = MODE_NORMAL; winwid->file = current_file; if ((winwid->im_w != gib_imlib_image_get_width(winwid->im)) || (winwid->im_h != gib_imlib_image_get_height(winwid->im))) winwid->had_resize = 1; winwidget_reset_image(winwid); winwid->im_w = gib_imlib_image_get_width(winwid->im); winwid->im_h = gib_imlib_image_get_height(winwid->im); if (opt.keep_zoom_vp) { /* put back in: */ winwid->mode = tmode; winwid->im_x = tim_x; winwid->im_y = tim_y; winwid->zoom = tzoom; } if (render) { if (opt.keep_zoom_vp) { winwidget_render_image(winwid, 0, 0); } else { winwidget_render_image(winwid, 1, 0); } } s = slideshow_create_name(FEH_FILE(current_file->data), winwid); winwidget_rename(winwid, s); free(s); break; } else last = current_file; } if (last) filelist = feh_file_remove_from_list(filelist, last); if (filelist_len == 0) eprintf("No more slides in show"); if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, "SLIDE_CHANGE"); return; }
void feh_reload_image(winwidget w, int resize, int force_new) { char *title, *new_title; int len; Imlib_Image tmp; int old_w, old_h; unsigned char tmode =0; int tim_x =0; int tim_y =0; double tzoom =0; tmode = w->mode; tim_x = w->im_x; tim_y = w->im_y; tzoom = w->zoom; if (!w->file) { im_weprintf(w, "couldn't reload, this image has no file associated with it."); winwidget_render_image(w, 0, 0); return; } D(("resize %d, force_new %d\n", resize, force_new)); free(FEH_FILE(w->file->data)->caption); FEH_FILE(w->file->data)->caption = NULL; len = strlen(w->name) + sizeof("Reloading: ") + 1; new_title = emalloc(len); snprintf(new_title, len, "Reloading: %s", w->name); title = estrdup(w->name); winwidget_rename(w, new_title); old_w = gib_imlib_image_get_width(w->im); old_h = gib_imlib_image_get_height(w->im); /* * If we don't free the old image before loading the new one, Imlib2's * caching will get in our way. * However, if --reload is used (force_new == 0), we want to continue if * the new image cannot be loaded, so we must not free the old image yet. */ if (force_new) winwidget_free_image(w); if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { if (force_new) eprintf("failed to reload image\n"); else { im_weprintf(w, "Couldn't reload image. Is it still there?"); winwidget_render_image(w, 0, 0); } winwidget_rename(w, title); free(title); free(new_title); return; } if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) || (old_h != gib_imlib_image_get_height(tmp)))) resize = 1; if (!force_new) winwidget_free_image(w); w->im = tmp; winwidget_reset_image(w); w->mode = MODE_NORMAL; if ((w->im_w != gib_imlib_image_get_width(w->im)) || (w->im_h != gib_imlib_image_get_height(w->im))) w->had_resize = 1; if (w->has_rotated) { Imlib_Image temp; temp = gib_imlib_create_rotated_image(w->im, 0.0); w->im_w = gib_imlib_image_get_width(temp); w->im_h = gib_imlib_image_get_height(temp); gib_imlib_free_image_and_decache(temp); } else { w->im_w = gib_imlib_image_get_width(w->im); w->im_h = gib_imlib_image_get_height(w->im); } if (opt.keep_zoom_vp) { /* put back in: */ w->mode = tmode; w->im_x = tim_x; w->im_y = tim_y; w->zoom = tzoom; winwidget_render_image(w, 0, 0); } else { winwidget_render_image(w, resize, 0); } winwidget_rename(w, title); free(title); free(new_title); return; }
void init_collage_mode(void) { Imlib_Image im_main; Imlib_Image im_temp; int ww, hh, www, hhh, xxx, yyy; int w = 800, h = 600; int bg_w = 0, bg_h = 0; winwidget winwid = NULL; Imlib_Image bg_im = NULL, im_thumb = NULL; feh_file *file = NULL; unsigned char trans_bg = 0; gib_list *l, *last = NULL; char *s; D_ENTER(4); mode = "collage"; /* Use bg image dimensions for default size */ if (opt.bg && opt.bg_file) { if (!strcmp(opt.bg_file, "trans")) trans_bg = 1; else { D(4, ("Time to apply a background to blend onto\n")); if (feh_load_image_char(&bg_im, opt.bg_file) != 0) { bg_w = gib_imlib_image_get_width(bg_im); bg_h = gib_imlib_image_get_height(bg_im); } } } if (!opt.limit_w || !opt.limit_h) { if (bg_im) { if (opt.verbose) fprintf(stdout, PACKAGE " - No size restriction specified for collage.\n" " You did specify a background however, so the\n" " collage size has defaulted to the size of the image\n"); opt.limit_w = bg_w; opt.limit_h = bg_h; } else { if (opt.verbose) fprintf(stdout, PACKAGE " - No size restriction specified for collage.\n" " - For collage mode, you need to specify width and height.\n" " Using defaults (width 800, height 600)\n"); opt.limit_w = 800; opt.limit_h = 600; } } w = opt.limit_w; h = opt.limit_h; D(4, ("Limiting width to %d and height to %d\n", w, h)); im_main = imlib_create_image(w, h); if (!im_main) eprintf("Imlib error creating image"); if (bg_im) gib_imlib_blend_image_onto_image(im_main, bg_im, gib_imlib_image_has_alpha(bg_im), 0, 0, bg_w, bg_h, 0, 0, w, h, 1, 0, 0); else if (trans_bg) { gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 0); gib_imlib_image_set_has_alpha(im_main, 1); } else { /* Colour the background */ gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255); } /* Create the title string */ if (!opt.title) s = estrdup(PACKAGE " [collage mode]"); else s = estrdup(feh_printf(opt.title, NULL)); if (opt.display) { winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); winwidget_show(winwid); } for (l = filelist; l; l = l->next) { file = FEH_FILE(l->data); if (last) { filelist = feh_file_remove_from_list(filelist, last); filelist_len--; last = NULL; } D(3, ("About to load image %s\n", file->filename)); if (feh_load_image(&im_temp, file) != 0) { D(3, ("Successfully loaded %s\n", file->filename)); if (opt.verbose) feh_display_status('.'); www = opt.thumb_w; hhh = opt.thumb_h; ww = gib_imlib_image_get_width(im_temp); hh = gib_imlib_image_get_height(im_temp); if (opt.aspect) { double ratio = 0.0; /* Keep the aspect ratio for the thumbnail */ ratio = ((double) ww / hh) / ((double) www / hhh); if (ratio > 1.0) hhh = opt.thumb_h / ratio; else if (ratio != 1.0) www = opt.thumb_w * ratio; } if ((!opt.stretch) && ((www > ww) || (hhh > hh))) { /* Don't make the image larger unless stretch is specified */ www = ww; hhh = hh; } /* pick random coords for thumbnail */ xxx = ((w - www) * ((double) rand() / RAND_MAX)); yyy = ((h - hhh) * ((double) rand() / RAND_MAX)); D(5, ("image going on at x=%d, y=%d\n", xxx, yyy)); im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, hhh, 1); gib_imlib_free_image_and_decache(im_temp); if (opt.alpha) { DATA8 atab[256]; D(4, ("Applying alpha options\n")); gib_imlib_image_set_has_alpha(im_thumb, 1); memset(atab, opt.alpha_level, sizeof(atab)); gib_imlib_apply_color_modifier_to_rectangle(im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab); } gib_imlib_blend_image_onto_image(im_main, im_thumb, gib_imlib_image_has_alpha(im_thumb), 0, 0, www, hhh, xxx, yyy,www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0); gib_imlib_free_image_and_decache(im_thumb); } else { last = l; if (opt.verbose) feh_display_status('x'); } if (opt.display) { winwidget_render_image(winwid, 0, 0); if (!feh_main_iteration(0)) exit(0); } } if (opt.verbose) fprintf(stdout, "\n"); if (opt.output && opt.output_file) { char output_buf[1024]; if (opt.output_dir) snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); else strncpy(output_buf, opt.output_file, 1024); gib_imlib_save_image(im_main, output_buf); if (opt.verbose) { int tw, th; tw = gib_imlib_image_get_width(im_main); th = gib_imlib_image_get_height(im_main); fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); fprintf(stdout, " - Image is %dx%d pixels and contains %d thumbnails\n", tw, th, (tw / opt.thumb_w) * (th / opt.thumb_h)); } } if (!opt.display) gib_imlib_free_image_and_decache(im_main); free(s); D_RETURN_(4); }
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; }
void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, void *data) { char *path; Imlib_Image im; winwidget winwid; switch (action) { case CB_BG_TILED: path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); feh_wm_set_bg(path, m->fehwin->im, 0, 0, 0, (int) data, 1); free(path); break; case CB_BG_SCALED: path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); feh_wm_set_bg(path, m->fehwin->im, 0, 1, 0, (int) data, 1); free(path); break; case CB_BG_CENTERED: path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); feh_wm_set_bg(path, m->fehwin->im, 1, 0, 0, (int) data, 1); free(path); break; case CB_BG_FILLED: path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); feh_wm_set_bg(path, m->fehwin->im, 0, 0, 1, (int) data, 1); free(path); break; case CB_BG_TILED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 0, (int) data, 1); break; case CB_BG_SCALED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, 0, (int) data, 1); break; case CB_BG_CENTERED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, 0, (int) data, 1); break; case CB_BG_FILLED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 1, (int) data, 1); break; case CB_ABOUT: if (feh_load_image_char(&im, PREFIX "/share/feh/images/about.png") != 0) { winwid = winwidget_create_from_image(im, "About " PACKAGE, WIN_TYPE_ABOUT); winwid->file = gib_list_add_front(NULL, feh_file_new(PREFIX "/share/feh/images/about.png")); winwidget_show(winwid); } break; case CB_CLOSE: winwidget_destroy(m->fehwin); break; case CB_EXIT: winwidget_destroy_all(); break; case CB_RESET: if (m->fehwin->has_rotated) { m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im); m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im); winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); } winwidget_reset_image(m->fehwin); winwidget_render_image(m->fehwin, 1, 1); break; case CB_RELOAD: feh_reload_image(m->fehwin, 0, 0); break; case CB_REMOVE: feh_filelist_image_remove(m->fehwin, 0); break; case CB_DELETE: feh_filelist_image_remove(m->fehwin, 1); break; case CB_REMOVE_THUMB: feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0); feh_filelist_image_remove(m->fehwin, 0); break; case CB_DELETE_THUMB: feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1); feh_filelist_image_remove(m->fehwin, 1); break; case CB_SORT_FILENAME: filelist = gib_list_sort(filelist, feh_cmp_filename); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST); } break; case CB_SORT_IMAGENAME: filelist = gib_list_sort(filelist, feh_cmp_name); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST); } break; case CB_SORT_FILESIZE: filelist = gib_list_sort(filelist, feh_cmp_size); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST); } break; case CB_SORT_RANDOMIZE: filelist = gib_list_randomize(filelist); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST); } break; case CB_FIT: winwidget_size_to_image(m->fehwin); break; case CB_EDIT_ROTATE: feh_edit_inplace_orient(m->fehwin, (int) data); break; case CB_SAVE_IMAGE: slideshow_save_image(m->fehwin); break; case CB_SAVE_FILELIST: feh_save_filelist(); break; case CB_OPT_DRAW_FILENAME: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.draw_filename = TRUE; else opt.draw_filename = FALSE; winwidget_rerender_all(0, 1); break; case CB_OPT_DRAW_ACTIONS: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.draw_actions = TRUE; else opt.draw_actions = FALSE; winwidget_rerender_all(0, 1); break; case CB_OPT_KEEP_HTTP: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.keep_http = TRUE; else opt.keep_http = FALSE; break; case CB_OPT_FREEZE_WINDOW: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) { opt.geom_flags = (WidthValue | HeightValue); opt.geom_w = m->fehwin->w; opt.geom_h = m->fehwin->h; } else { opt.geom_flags = 0; } break; case CB_OPT_FULLSCREEN: feh_menu_cb_opt_fullscreen(m, i); break; case CB_OPT_AUTO_ZOOM: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.zoom_mode = ZOOM_MODE_FILL; else opt.zoom_mode = 0; winwidget_rerender_all(1, 1); break; } 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); }
void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short data) { char *path; switch (action) { case CB_BG_TILED: path = FEH_FILE(m->fehwin->file->data)->filename; feh_wm_set_bg(path, m->fehwin->im, 0, 0, 0, data, 0); break; case CB_BG_SCALED: path = FEH_FILE(m->fehwin->file->data)->filename; feh_wm_set_bg(path, m->fehwin->im, 0, 1, 0, data, 0); break; case CB_BG_CENTERED: path = FEH_FILE(m->fehwin->file->data)->filename; feh_wm_set_bg(path, m->fehwin->im, 1, 0, 0, data, 0); break; case CB_BG_FILLED: path = FEH_FILE(m->fehwin->file->data)->filename; feh_wm_set_bg(path, m->fehwin->im, 0, 0, 1, data, 0); break; case CB_BG_TILED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 0, data, 0); break; case CB_BG_SCALED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, 0, data, 0); break; case CB_BG_CENTERED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, 0, data, 0); break; case CB_BG_FILLED_NOFILE: feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, 1, data, 0); break; case CB_CLOSE: winwidget_destroy(m->fehwin); break; case CB_EXIT: winwidget_destroy_all(); break; case CB_RESET: if (m->fehwin->has_rotated) { m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im); m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im); winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); } winwidget_reset_image(m->fehwin); winwidget_render_image(m->fehwin, 1, 0); break; case CB_RELOAD: feh_reload_image(m->fehwin, 0, 1); break; case CB_REMOVE: feh_filelist_image_remove(m->fehwin, 0); break; case CB_DELETE: feh_filelist_image_remove(m->fehwin, 1); break; case CB_REMOVE_THUMB: feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0); feh_filelist_image_remove(m->fehwin, 0); break; case CB_DELETE_THUMB: feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1); feh_filelist_image_remove(m->fehwin, 1); break; case CB_SORT_FILENAME: filelist = gib_list_sort(filelist, feh_cmp_filename); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); } break; case CB_SORT_IMAGENAME: filelist = gib_list_sort(filelist, feh_cmp_name); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); } break; case CB_SORT_FILESIZE: filelist = gib_list_sort(filelist, feh_cmp_size); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); } break; case CB_SORT_RANDOMIZE: filelist = gib_list_randomize(filelist); if (opt.jump_on_resort) { slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); } break; case CB_FIT: winwidget_size_to_image(m->fehwin); break; case CB_EDIT_ROTATE: feh_edit_inplace(m->fehwin, data); break; case CB_SAVE_IMAGE: slideshow_save_image(m->fehwin); break; case CB_SAVE_FILELIST: feh_save_filelist(); break; case CB_OPT_DRAW_FILENAME: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.draw_filename = TRUE; else opt.draw_filename = FALSE; winwidget_rerender_all(0); break; case CB_OPT_DRAW_ACTIONS: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.draw_actions = TRUE; else opt.draw_actions = FALSE; winwidget_rerender_all(0); break; case CB_OPT_KEEP_HTTP: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.keep_http = TRUE; else opt.keep_http = FALSE; break; case CB_OPT_FREEZE_WINDOW: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) { opt.geom_flags = (WidthValue | HeightValue); opt.geom_w = m->fehwin->w; opt.geom_h = m->fehwin->h; } else { opt.geom_flags = 0; } break; case CB_OPT_FULLSCREEN: feh_menu_cb_opt_fullscreen(m, i); break; case CB_OPT_AUTO_ZOOM: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.zoom_mode = ZOOM_MODE_MAX; else opt.zoom_mode = 0; winwidget_rerender_all(1); break; case CB_OPT_KEEP_ZOOM_VP: MENU_ITEM_TOGGLE(i); if (MENU_ITEM_IS_ON(i)) opt.keep_zoom_vp = 1; else opt.keep_zoom_vp = 0; break; } return; }
void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; gib_list *previous_file = current_file; int i = 0; int jmp = 1; /* We can't use filelist_len in the for loop, since that changes when we * encounter invalid images. */ int our_filelist_len = filelist_len; if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, "SLIDE_CHANGE"); /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ if (filelist_len < 2 && opt.on_last_slide != ON_LAST_SLIDE_QUIT) return; /* Ok. I do this in such an odd way to ensure that if the last or first * image is not loadable, it will go through in the right direction to * find the correct one. Otherwise SLIDE_LAST would try the last file, * then loop forward to find a loadable one. */ if (change == SLIDE_FIRST) { current_file = gib_list_last(filelist); change = SLIDE_NEXT; previous_file = NULL; } else if (change == SLIDE_LAST) { current_file = filelist; change = SLIDE_PREV; previous_file = NULL; } /* The for loop prevents us looping infinitely */ for (i = 0; i < our_filelist_len; i++) { winwidget_free_image(winwid); switch (change) { case SLIDE_NEXT: current_file = feh_list_jump(filelist, current_file, FORWARD, 1); break; case SLIDE_PREV: current_file = feh_list_jump(filelist, current_file, BACK, 1); break; case SLIDE_RAND: if (filelist_len > 1) { current_file = feh_list_jump(filelist, current_file, FORWARD, (random() % (filelist_len - 1)) + 1); change = SLIDE_NEXT; } break; case SLIDE_JUMP_FWD: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); /* important. if the load fails, we only want to step on ONCE to try the next file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_BACK: if (filelist_len < 5) jmp = 1; else if (filelist_len < 40) jmp = 2; else jmp = filelist_len / 20; if (!jmp) jmp = 2; current_file = feh_list_jump(filelist, current_file, BACK, jmp); /* important. if the load fails, we only want to step back ONCE to try the previous file, not another jmp */ change = SLIDE_NEXT; break; case SLIDE_JUMP_NEXT_DIR: { char old_dir[PATH_MAX], new_dir[PATH_MAX]; int j; feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); for (j = 0; j < our_filelist_len; j++) { current_file = feh_list_jump(filelist, current_file, FORWARD, 1); feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); if (strcmp(old_dir, new_dir) != 0) break; } } change = SLIDE_NEXT; break; case SLIDE_JUMP_PREV_DIR: { char old_dir[PATH_MAX], new_dir[PATH_MAX]; int j; /* Start the search from the previous file in case we are on the first file of a directory */ current_file = feh_list_jump(filelist, current_file, BACK, 1); feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); for (j = 0; j < our_filelist_len; j++) { current_file = feh_list_jump(filelist, current_file, BACK, 1); feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); if (strcmp(old_dir, new_dir) != 0) break; } /* Next file is the first entry of prev_dir */ current_file = feh_list_jump(filelist, current_file, FORWARD, 1); } change = SLIDE_NEXT; break; default: eprintf("BUG!\n"); break; } if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } if (opt.on_last_slide == ON_LAST_SLIDE_HOLD && previous_file && ((current_file == filelist && change == SLIDE_NEXT) || (previous_file == filelist && change == SLIDE_PREV))) { current_file = previous_file; } if (winwidget_loadimage(winwid, FEH_FILE(current_file->data))) { int w = gib_imlib_image_get_width(winwid->im); int h = gib_imlib_image_get_height(winwid->im); if (feh_should_ignore_image(winwid->im)) { last = current_file; continue; } winwid->mode = MODE_NORMAL; winwid->file = current_file; if ((winwid->im_w != w) || (winwid->im_h != h)) winwid->had_resize = 1; winwidget_reset_image(winwid); winwid->im_w = w; winwid->im_h = h; if (render) { winwidget_render_image(winwid, 1, 0); } break; } else last = current_file; } if (last) filelist = feh_file_remove_from_list(filelist, last); if (filelist_len == 0) eprintf("No more slides in show"); return; }
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; }