Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}