void winwidget_create_window(winwidget ret, int w, int h) { XSetWindowAttributes attr; XEvent ev; XClassHint *xch; MWMHints mwmhints; Atom prop = None; int x = 0; int y = 0; char *tmpname; D(("winwidget_create_window %dx%d\n", w, h)); if (ret->full_screen) { w = scr->width; h = scr->height; #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { w = xinerama_screens[xinerama_screen].width; h = xinerama_screens[xinerama_screen].height; x = xinerama_screens[xinerama_screen].x_org; y = xinerama_screens[xinerama_screen].y_org; } #endif /* HAVE_LIBXINERAMA */ } else if (opt.geom_flags) { if (opt.geom_flags & WidthValue) { w = opt.geom_w; } if (opt.geom_flags & HeightValue) { h = opt.geom_h; } if (opt.geom_flags & XValue) { if (opt.geom_flags & XNegative) { x = scr->width - opt.geom_x; } else { x = opt.geom_x; } } if (opt.geom_flags & YValue) { if (opt.geom_flags & YNegative) { y = scr->height - opt.geom_y; } else { y = opt.geom_y; } } } else if (opt.screen_clip) { if (w > scr->width) w = scr->width; if (h > scr->height) h = scr->height; #ifdef HAVE_LIBXINERAMA if (opt.xinerama && xinerama_screens) { if (w > xinerama_screens[xinerama_screen].width) w = xinerama_screens[xinerama_screen].width; if (h > xinerama_screens[xinerama_screen].height) h = xinerama_screens[xinerama_screen].height; } #endif /* HAVE_LIBXINERAMA */ } if (opt.paused) { printf("name %s\n", ret->name); tmpname = estrjoin(" ", ret->name, "[Paused]", NULL); free(ret->name); ret->name = tmpname; } ret->x = x; ret->y = y; ret->w = w; ret->h = h; ret->visible = False; attr.backing_store = NotUseful; attr.override_redirect = False; attr.colormap = cm; attr.border_pixel = 0; attr.background_pixel = 0; attr.save_under = False; attr.event_mask = StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonMotionMask | ExposureMask | FocusChangeMask | PropertyChangeMask | VisibilityChangeMask; if (opt.borderless || ret->full_screen) { prop = XInternAtom(disp, "_MOTIF_WM_HINTS", True); if (prop == None) { weprintf ("Window Manager does not support MWM hints. " "To get a borderless window I have to bypass your wm."); attr.override_redirect = True; mwmhints.flags = 0; } else { mwmhints.flags = MWM_HINTS_DECORATIONS; mwmhints.decorations = 0; } } else mwmhints.flags = 0; ret->win = XCreateWindow(disp, DefaultRootWindow(disp), x, y, w, h, 0, depth, InputOutput, vis, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap | CWBackPixel | CWBorderPixel | CWEventMask, &attr); if (mwmhints.flags) { XChangeProperty(disp, ret->win, prop, prop, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); } if (ret->full_screen) { Atom prop_fs = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); Atom prop_state = XInternAtom(disp, "_NET_WM_STATE", False); memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.message_type = prop_state; ev.xclient.display = disp; ev.xclient.window = ret->win; ev.xclient.format = 32; ev.xclient.data.l[0] = 1; ev.xclient.data.l[1] = prop_fs; XChangeProperty(disp, ret->win, prop_state, XA_ATOM, 32, PropModeReplace, (unsigned char *) &prop_fs, 1); } XSetWMProtocols(disp, ret->win, &wmDeleteWindow, 1); winwidget_update_title(ret); xch = XAllocClassHint(); xch->res_name = "feh"; xch->res_class = "feh"; XSetClassHint(disp, ret->win, xch); XFree(xch); /* Size hints */ if (ret->full_screen || opt.geom_flags) { XSizeHints xsz; xsz.flags = USPosition; xsz.x = x; xsz.y = y; XSetWMNormalHints(disp, ret->win, &xsz); XMoveWindow(disp, ret->win, x, y); } if (opt.hide_pointer) winwidget_set_pointer(ret, 0); /* set the icon name property */ XSetIconName(disp, ret->win, "feh"); /* set the command hint */ XSetCommand(disp, ret->win, cmdargv, cmdargc); winwidget_register(ret); return; }
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; }