Compare commits
	
		
			No commits in common. "1d28627868f5133a25a0197af21a187799ffa98e" and "a75411567e6670a1ce37f0db5d7d79bd19a21d3b" have entirely different histories.
		
	
	
		
			1d28627868
			...
			a75411567e
		
	
		
							
								
								
									
										25
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								README.md
									
									
									
									
									
								
							| @ -32,27 +32,9 @@ Screenshots | ||||
|  | ||||
| 
 | ||||
| 
 | ||||
| Dependencies | ||||
| Installation | ||||
| ------------ | ||||
| 
 | ||||
| sxiv requires the following software to be installed: | ||||
| 
 | ||||
|   * Imlib2 | ||||
|   * X11 | ||||
|   * Xft | ||||
|   * freetype2 | ||||
|   * fontconfig | ||||
|   * giflib (optional, disabled with `HAVE_GIFLIB=0`) | ||||
|   * libexif (optional, disabled with `HAVE_LIBEXIF=0`) | ||||
| 
 | ||||
| Please make sure to install the corresponding development packages in case that | ||||
| you want to build sxiv on a distribution with separate runtime and development | ||||
| packages (e.g. *-dev on Debian). | ||||
| 
 | ||||
| 
 | ||||
| Building | ||||
| -------- | ||||
| 
 | ||||
| sxiv is built using the commands: | ||||
| 
 | ||||
|     $ make | ||||
| @ -92,11 +74,6 @@ on GitHub or get a copy using git with the following command: | ||||
| 
 | ||||
| **Stable releases** | ||||
| 
 | ||||
| **[v26](https://github.com/muennich/sxiv/archive/v26.tar.gz)** | ||||
| *(January 16, 2020)* | ||||
| 
 | ||||
|   * Maintenance release | ||||
| 
 | ||||
| **[v25](https://github.com/muennich/sxiv/archive/v25.tar.gz)** | ||||
| *(January 26, 2019)* | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										13
									
								
								config.def.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								config.def.h
									
									
									
									
									
								
							| @ -6,10 +6,17 @@ enum { | ||||
| 	WIN_HEIGHT = 600 | ||||
| }; | ||||
| 
 | ||||
| /* colors and font are configured with 'background', 'foreground' and
 | ||||
|  * 'font' X resource properties. | ||||
|  * See X(7) section Resources and xrdb(1) for more information. | ||||
| /* bar font:
 | ||||
|  * (see fonts-conf(5) subsection "FONT NAMES" for valid values) | ||||
|  */ | ||||
| static const char * const BAR_FONT = "monospace:size=8"; | ||||
| 
 | ||||
| /* colors:
 | ||||
|  * overwritten by 'background' and 'foreground' X resource properties. | ||||
|  * (see X(7) section "COLOR NAMES" for valid values) | ||||
|  */ | ||||
| static const char * const BG_COLOR = "#ffffea"; | ||||
| static const char * const FG_COLOR = "#555555"; | ||||
| 
 | ||||
| #endif | ||||
| #ifdef _IMAGE_CONFIG | ||||
|  | ||||
							
								
								
									
										2
									
								
								image.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								image.c
									
									
									
									
									
								
							| @ -497,7 +497,7 @@ void img_render(img_t *img) | ||||
| 			} | ||||
| 			imlib_image_put_back_data(data); | ||||
| 		} else { | ||||
| 			c = win->bg.pixel; | ||||
| 			c = win->fullscreen ? win->black.pixel : win->bg.pixel; | ||||
| 			imlib_context_set_color(c >> 16 & 0xFF, c >> 8 & 0xFF, c & 0xFF, 0xFF); | ||||
| 			imlib_image_fill_rectangle(0, 0, dw, dh); | ||||
| 		} | ||||
|  | ||||
							
								
								
									
										10
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.c
									
									
									
									
									
								
							| @ -70,10 +70,10 @@ typedef struct { | ||||
| } extcmd_t; | ||||
| 
 | ||||
| struct { | ||||
| 	extcmd_t f; | ||||
| 	int fd; | ||||
| 	unsigned int i, lastsep; | ||||
| 	pid_t pid; | ||||
|   extcmd_t f; | ||||
|   int fd; | ||||
|   unsigned int i, lastsep; | ||||
|   pid_t pid; | ||||
| } info; | ||||
| 
 | ||||
| struct { | ||||
| @ -774,7 +774,7 @@ void run(void) | ||||
| 					} else { | ||||
| 						tns.dirty = true; | ||||
| 					} | ||||
| 					if (!resized) { | ||||
| 					if (!resized || win.fullscreen) { | ||||
| 						redraw(); | ||||
| 						set_timeout(clear_resize, TO_REDRAW_RESIZE, false); | ||||
| 						resized = true; | ||||
|  | ||||
							
								
								
									
										17
									
								
								sxiv.1
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								sxiv.1
									
									
									
									
									
								
							| @ -375,19 +375,6 @@ Zoom in. | ||||
| .TP | ||||
| .B ScrollDown | ||||
| Zoom out. | ||||
| .SH CONFIGURATION | ||||
| The following X resources are supported: | ||||
| .TP | ||||
| .B background | ||||
| Color of the window background and bar foreground | ||||
| .TP | ||||
| .B foreground | ||||
| Color of the window foreground and bar background | ||||
| .TP | ||||
| .B font | ||||
| Name of Xft bar font | ||||
| .TP | ||||
| Please see xrdb(1) on how to change them. | ||||
| .SH STATUS BAR | ||||
| The information displayed on the left side of the status bar can be replaced | ||||
| with the output of a user-provided script, which is called by sxiv whenever an | ||||
| @ -444,5 +431,5 @@ Max Voit        <mvdev at with-eyes.net> | ||||
| https://github.com/muennich/sxiv | ||||
| .EE | ||||
| .SH SEE ALSO | ||||
| .BR X (7), | ||||
| .BR xrdb (1) | ||||
| .BR feh (1), | ||||
| .BR qiv (1) | ||||
|  | ||||
							
								
								
									
										5
									
								
								sxiv.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								sxiv.h
									
									
									
									
									
								
							| @ -385,6 +385,7 @@ enum { | ||||
| 	ATOM__NET_WM_ICON, | ||||
| 	ATOM__NET_WM_STATE, | ||||
| 	ATOM__NET_WM_STATE_FULLSCREEN, | ||||
| 	ATOM__NET_SUPPORTED, | ||||
| 	ATOM_COUNT | ||||
| }; | ||||
| 
 | ||||
| @ -407,8 +408,10 @@ struct win { | ||||
| 	Window xwin; | ||||
| 	win_env_t env; | ||||
| 
 | ||||
| 	bool light; /* bg is lighter than fg */ | ||||
| 	XftColor bg; | ||||
| 	XftColor fg; | ||||
| 	XftColor black; | ||||
| 
 | ||||
| 	int x; | ||||
| 	int y; | ||||
| @ -416,6 +419,8 @@ struct win { | ||||
| 	unsigned int h; /* = win height - bar height */ | ||||
| 	unsigned int bw; | ||||
| 
 | ||||
| 	bool fullscreen; | ||||
| 
 | ||||
| 	struct { | ||||
| 		int w; | ||||
| 		int h; | ||||
|  | ||||
							
								
								
									
										11
									
								
								thumbs.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								thumbs.c
									
									
									
									
									
								
							| @ -469,14 +469,14 @@ void tns_mark(tns_t *tns, int n, bool mark) | ||||
| 	if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) { | ||||
| 		win_t *win = tns->win; | ||||
| 		thumb_t *t = &tns->thumbs[n]; | ||||
| 		unsigned long col = win->bg.pixel; | ||||
| 		unsigned long col = win->fullscreen ? win->black.pixel : win->bg.pixel; | ||||
| 		int x = t->x + t->w, y = t->y + t->h; | ||||
| 
 | ||||
| 		win_draw_rect(win, x - 1, y + 1, 1, tns->bw, true, 1, col); | ||||
| 		win_draw_rect(win, x + 1, y - 1, tns->bw, 1, true, 1, col); | ||||
| 
 | ||||
| 		if (mark) | ||||
| 			col = win->fg.pixel; | ||||
| 			col = win->fullscreen && win->light ? win->bg.pixel : win->fg.pixel; | ||||
| 
 | ||||
| 		win_draw_rect(win, x, y, tns->bw + 2, tns->bw + 2, true, 1, col); | ||||
| 
 | ||||
| @ -490,9 +490,14 @@ void tns_highlight(tns_t *tns, int n, bool hl) | ||||
| 	if (n >= 0 && n < *tns->cnt && tns->thumbs[n].im != NULL) { | ||||
| 		win_t *win = tns->win; | ||||
| 		thumb_t *t = &tns->thumbs[n]; | ||||
| 		unsigned long col = hl ? win->fg.pixel : win->bg.pixel; | ||||
| 		unsigned long col; | ||||
| 		int oxy = (tns->bw + 1) / 2 + 1, owh = tns->bw + 2; | ||||
| 
 | ||||
| 		if (hl) | ||||
| 			col = win->fullscreen && win->light ? win->bg.pixel : win->fg.pixel; | ||||
| 		else | ||||
| 			col = win->fullscreen ? win->black.pixel : win->bg.pixel; | ||||
| 
 | ||||
| 		win_draw_rect(win, t->x - oxy, t->y - oxy, t->w + owh, t->h + owh, | ||||
| 		              false, tns->bw, col); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										105
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								window.c
									
									
									
									
									
								
							| @ -53,6 +53,9 @@ static int barheight; | ||||
| 
 | ||||
| Atom atoms[ATOM_COUNT]; | ||||
| 
 | ||||
| static Bool fs_support; | ||||
| static Bool fs_warned; | ||||
| 
 | ||||
| void win_init_font(const win_env_t *e, const char *fontstr) | ||||
| { | ||||
| 	if ((font = XftFontOpenName(e->dpy, e->scr, fontstr)) == NULL) | ||||
| @ -71,14 +74,48 @@ void win_alloc_color(const win_env_t *e, const char *name, XftColor *col) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const char* win_res(XrmDatabase db, const char *name, const char *def) | ||||
| void win_check_wm_support(Display *dpy, Window root) | ||||
| { | ||||
| 	int format; | ||||
| 	long offset = 0, length = 16; | ||||
| 	Atom *data, type; | ||||
| 	unsigned long i, nitems, bytes_left; | ||||
| 	Bool found = False; | ||||
| 
 | ||||
| 	while (!found && length > 0) { | ||||
| 		if (XGetWindowProperty(dpy, root, atoms[ATOM__NET_SUPPORTED], | ||||
| 		                       offset, length, False, XA_ATOM, &type, &format, | ||||
| 		                       &nitems, &bytes_left, (unsigned char**) &data)) | ||||
| 		{ | ||||
| 			break; | ||||
| 		} | ||||
| 		if (type == XA_ATOM && format == 32) { | ||||
| 			for (i = 0; i < nitems; i++) { | ||||
| 				if (data[i] == atoms[ATOM__NET_WM_STATE_FULLSCREEN]) { | ||||
| 					found = True; | ||||
| 					fs_support = True; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		XFree(data); | ||||
| 		offset += nitems; | ||||
| 		length = MIN(length, bytes_left / 4); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const char* win_res(Display *dpy, const char *name, const char *def) | ||||
| { | ||||
| 	char *type; | ||||
| 	XrmValue ret; | ||||
| 	XrmDatabase db; | ||||
| 	char *res_man; | ||||
| 
 | ||||
| 	if (db != None && | ||||
| 	    XrmGetResource(db, name, name, &type, &ret) && | ||||
| 	    STREQ(type, "String")) | ||||
| 	XrmInitialize(); | ||||
| 
 | ||||
| 	if ((res_man = XResourceManagerString(dpy)) != NULL && | ||||
| 	    (db = XrmGetStringDatabase(res_man)) != NULL && | ||||
| 	    XrmGetResource(db, name, name, &type, &ret) && STREQ(type, "String")) | ||||
| 	{ | ||||
| 		return ret.addr; | ||||
| 	} else { | ||||
| @ -86,15 +123,18 @@ const char* win_res(XrmDatabase db, const char *name, const char *def) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| unsigned int win_luminance(const XftColor *col) | ||||
| { | ||||
| 	return (col->color.red + col->color.green + col->color.blue) / 3; | ||||
| } | ||||
| 
 | ||||
| #define INIT_ATOM_(atom) \ | ||||
| 	atoms[ATOM_##atom] = XInternAtom(e->dpy, #atom, False); | ||||
| 
 | ||||
| void win_init(win_t *win) | ||||
| { | ||||
| 	win_env_t *e; | ||||
| 	const char *bg, *fg, *f; | ||||
| 	char *res_man; | ||||
| 	XrmDatabase db; | ||||
| 	const char *bg, *fg; | ||||
| 
 | ||||
| 	memset(win, 0, sizeof(win_t)); | ||||
| 
 | ||||
| @ -112,17 +152,14 @@ void win_init(win_t *win) | ||||
| 	if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0) | ||||
| 		error(0, 0, "No locale support"); | ||||
| 
 | ||||
| 	XrmInitialize(); | ||||
| 	res_man = XResourceManagerString(e->dpy); | ||||
| 	db = res_man != NULL ? XrmGetStringDatabase(res_man) : None; | ||||
| 	win_init_font(e, BAR_FONT); | ||||
| 
 | ||||
| 	f = win_res(db, RES_CLASS ".font", "monospace-8"); | ||||
| 	win_init_font(e, f); | ||||
| 
 | ||||
| 	bg = win_res(db, RES_CLASS ".background", "white"); | ||||
| 	fg = win_res(db, RES_CLASS ".foreground", "black"); | ||||
| 	bg = win_res(e->dpy, RES_CLASS ".background", BG_COLOR); | ||||
| 	fg = win_res(e->dpy, RES_CLASS ".foreground", FG_COLOR); | ||||
| 	win_alloc_color(e, bg, &win->bg); | ||||
| 	win_alloc_color(e, fg, &win->fg); | ||||
| 	win_alloc_color(e, "black", &win->black); | ||||
| 	win->light = win_luminance(&win->bg) > win_luminance(&win->fg); | ||||
| 
 | ||||
| 	win->bar.l.size = BAR_L_LEN; | ||||
| 	win->bar.r.size = BAR_R_LEN; | ||||
| @ -139,6 +176,9 @@ void win_init(win_t *win) | ||||
| 	INIT_ATOM_(_NET_WM_ICON); | ||||
| 	INIT_ATOM_(_NET_WM_STATE); | ||||
| 	INIT_ATOM_(_NET_WM_STATE_FULLSCREEN); | ||||
| 	INIT_ATOM_(_NET_SUPPORTED); | ||||
| 
 | ||||
| 	win_check_wm_support(e->dpy, RootWindow(e->dpy, e->scr)); | ||||
| } | ||||
| 
 | ||||
| void win_open(win_t *win) | ||||
| @ -154,6 +194,7 @@ void win_open(win_t *win) | ||||
| 	Pixmap none; | ||||
| 	int gmask; | ||||
| 	XSizeHints sizehints; | ||||
| 	Bool fullscreen = options->fullscreen && fs_support; | ||||
| 
 | ||||
| 	e = &win->env; | ||||
| 	parent = options->embed != 0 ? options->embed : RootWindow(e->dpy, e->scr); | ||||
| @ -258,14 +299,14 @@ void win_open(win_t *win) | ||||
| 	win->buf.h = e->scrh; | ||||
| 	win->buf.pm = XCreatePixmap(e->dpy, win->xwin, | ||||
| 	                            win->buf.w, win->buf.h, e->depth); | ||||
| 	XSetForeground(e->dpy, gc, win->bg.pixel); | ||||
| 	XSetForeground(e->dpy, gc, fullscreen ? win->black.pixel : win->bg.pixel); | ||||
| 	XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); | ||||
| 	XSetWindowBackgroundPixmap(e->dpy, win->xwin, win->buf.pm); | ||||
| 
 | ||||
| 	XMapWindow(e->dpy, win->xwin); | ||||
| 	XFlush(e->dpy); | ||||
| 
 | ||||
| 	if (options->fullscreen) | ||||
| 	if (fullscreen) | ||||
| 		win_toggle_fullscreen(win); | ||||
| } | ||||
| 
 | ||||
| @ -302,6 +343,15 @@ void win_toggle_fullscreen(win_t *win) | ||||
| 	XEvent ev; | ||||
| 	XClientMessageEvent *cm; | ||||
| 
 | ||||
| 	if (!fs_support) { | ||||
| 		if (!fs_warned) { | ||||
| 			error(0, 0, "No fullscreen support"); | ||||
| 			fs_warned = True; | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 	win->fullscreen = !win->fullscreen; | ||||
| 
 | ||||
| 	memset(&ev, 0, sizeof(ev)); | ||||
| 	ev.type = ClientMessage; | ||||
| 
 | ||||
| @ -309,8 +359,9 @@ void win_toggle_fullscreen(win_t *win) | ||||
| 	cm->window = win->xwin; | ||||
| 	cm->message_type = atoms[ATOM__NET_WM_STATE]; | ||||
| 	cm->format = 32; | ||||
| 	cm->data.l[0] = 2; // toggle
 | ||||
| 	cm->data.l[0] = win->fullscreen; | ||||
| 	cm->data.l[1] = atoms[ATOM__NET_WM_STATE_FULLSCREEN]; | ||||
| 	cm->data.l[2] = cm->data.l[3] = 0; | ||||
| 
 | ||||
| 	XSendEvent(win->env.dpy, DefaultRootWindow(win->env.dpy), False, | ||||
| 	           SubstructureNotifyMask | SubstructureRedirectMask, &ev); | ||||
| @ -340,7 +391,7 @@ void win_clear(win_t *win) | ||||
| 		win->buf.pm = XCreatePixmap(e->dpy, win->xwin, | ||||
| 		                            win->buf.w, win->buf.h, e->depth); | ||||
| 	} | ||||
| 	XSetForeground(e->dpy, gc, win->bg.pixel); | ||||
| 	XSetForeground(e->dpy, gc, win->fullscreen ? win->black.pixel : win->bg.pixel); | ||||
| 	XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); | ||||
| } | ||||
| 
 | ||||
| @ -387,6 +438,7 @@ void win_draw_bar(win_t *win) | ||||
| 	win_env_t *e; | ||||
| 	win_bar_t *l, *r; | ||||
| 	XftDraw *d; | ||||
| 	const XftColor *bg, *fg; | ||||
| 
 | ||||
| 	if ((l = &win->bar.l)->buf == NULL || (r = &win->bar.r)->buf == NULL) | ||||
| 		return; | ||||
| @ -397,23 +449,28 @@ void win_draw_bar(win_t *win) | ||||
| 	d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr), | ||||
| 	                  DefaultColormap(e->dpy, e->scr)); | ||||
| 
 | ||||
| 	XSetForeground(e->dpy, gc, win->fg.pixel); | ||||
| 	if (win->fullscreen && !win->light) | ||||
| 		bg = &win->bg, fg = &win->fg; | ||||
| 	else | ||||
| 		bg = &win->fg, fg = &win->bg; | ||||
| 
 | ||||
| 	XSetForeground(e->dpy, gc, bg->pixel); | ||||
| 	XFillRectangle(e->dpy, win->buf.pm, gc, 0, win->h, win->w, win->bar.h); | ||||
| 
 | ||||
| 	XSetForeground(e->dpy, gc, win->bg.pixel); | ||||
| 	XSetBackground(e->dpy, gc, win->fg.pixel); | ||||
| 	XSetForeground(e->dpy, gc, fg->pixel); | ||||
| 	XSetBackground(e->dpy, gc, bg->pixel); | ||||
| 
 | ||||
| 	if ((len = strlen(r->buf)) > 0) { | ||||
| 		if ((tw = TEXTWIDTH(win, r->buf, len)) > w) | ||||
| 			return; | ||||
| 		x = win->w - tw - H_TEXT_PAD; | ||||
| 		w -= tw; | ||||
| 		win_draw_text(win, d, &win->bg, x, y, r->buf, len, tw); | ||||
| 		win_draw_text(win, d, fg, x, y, r->buf, len, tw); | ||||
| 	} | ||||
| 	if ((len = strlen(l->buf)) > 0) { | ||||
| 		x = H_TEXT_PAD; | ||||
| 		w -= 2 * H_TEXT_PAD; /* gap between left and right parts */ | ||||
| 		win_draw_text(win, d, &win->bg, x, y, l->buf, len, w); | ||||
| 		win_draw_text(win, d, fg, x, y, l->buf, len, w); | ||||
| 	} | ||||
| 	XftDrawDestroy(d); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user