Compare commits

..

No commits in common. "1d28627868f5133a25a0197af21a187799ffa98e" and "a75411567e6670a1ce37f0db5d7d79bd19a21d3b" have entirely different histories.

9 changed files with 114 additions and 76 deletions

View File

@ -1,4 +1,4 @@
version = 26
version = 25+
srcdir = .
VPATH = $(srcdir)

View File

@ -32,27 +32,9 @@ Screenshots
![Thumb](http://muennich.github.com/sxiv/img/thumb.png "Thumb mode")
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)*

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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;

View File

@ -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
View File

@ -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);
}